# 访前准备拜访卡 API（完整版）

## 端点

`POST /api/visit-card` — `Content-Type: application/json`

```json
{"customer": "圣湘生物"}
```

## 响应

```json
{
  "ok": true,
  "customer": "圣湘生物",
  "web": [{"url": "https://baike.baidu.com/...", "title": "圣湘生物百科", "snippet": "科创板688289..."}],
  "ima_kb": [{"title": "检验立项指南...", "kb": "fwEO41E0Ef"}],
  "ima_notes": [{"title": "...", "summary": "..."}],
  "note_saved": {"code": 0, "msg": "success", "data": {"note_id": "7487515225249521"}},
  "generated_at": "2026-07-27T22:13:22"
}
```

## 处理流水线（2026-07-27 终版）

```
POST /api/visit-card?customer=圣湘
  ├── 🌐 互联网搜索: 缓存优先 → DuckDuckGo 降级（6s timeout）
  ├── 📚 IMA 知识库搜索: 两个 KB 的 search_knowledge（5s）
  ├── 📝 IMA 笔记搜索: search_note_book search_type=1 全文（5s）
  └── 💾 IMA 笔记保存: import_doc → 积累调研笔记
```

**所有步骤独立 try/except，单个失败不阻塞其他步骤。**

## 互联网搜索缓存模式（2026-07-27 新增）

DuckDuckGo 从国内频繁超时。解决方案：**缓存优先 + Hermes 预热**。

### 缓存文件
`数据/web_cache/web_search_cache.json` — 按客户名 key：
```json
{
  "圣湘生物": {
    "updated": "2026-07-27",
    "results": [
      {"title": "圣湘生物百科", "url": "https://baike.baidu.com/...", "snippet": "科创板688289..."}
    ]
  }
}
```

### API 内读取流程
```python
# 1. 优先读缓存
cache_file = os.path.join(ROOT, '数据', 'web_cache', 'web_search_cache.json')
if os.path.exists(cache_file):
    with open(cache_file) as f: wcache = json.load(f)
    if customer in wcache:
        web_results = wcache[customer].get('results', [])
# 2. 缓存未命中 → DuckDuckGo 降级（6s timeout）
if not web_results:
    try:
        # ... DuckDuckGo 搜索 ...
        # 成功则自动写入缓存
    except: pass
```

### Hermes 预热方式
在对话中调用 `web_search("客户名 生物 诊断")` → Python 写缓存 JSON。下次 API 调用直接命中。

## IMA 笔记保存（2026-07-27 已验证）

POST `https://ima.qq.com/openapi/note/v1/import_doc`

```python
note_md = f'# 客户调研：{name}{YYYYMMDD}\n\n> 生成时间...\n\n## 🌐 互联网搜索\n\n- [结果1](url)\n\n---\n*由宝锐销售工作台自动生成*'
note_req = urllib.request.Request(
    'https://ima.qq.com/openapi/note/v1/import_doc',
    data=json.dumps({'content_format': 1, 'content': note_md[:5000]}).encode(),
    headers={'ima-openapi-clientid': IMA_CLIENT_ID, 'ima-openapi-apikey': IMA_API_KEY, 'Content-Type': 'application/json'},
    method='POST')
# 返回 note_id 供后续引用
```

**命名规范**：`客户调研：{客户名}{YYYYMMDD}`（如 `客户调研：圣湘生物20260727`）

⚠️ **变量名陷阱**：`import_doc` 的 Request 对象必须用不同变量名（如 `note_req`），不能复用前面 `search_note_book` 的 `req`——否则请求发错了。

## IMA API 能力边界（2026-07-27 实测）

| 接口 | 搜索方式 | 读内容 |
|------|---------|:--:|
| 知识库 search_knowledge | 标题搜索 | ❌ |
| 笔记 search_note_book | 标题+**正文全文** | ✅ get_doc_content |
| 笔记 import_doc | — (写入) | — |

**结论**：调研价值：笔记全文搜索 > 知识库标题 > 互联网（取决于缓存）

知识库当前只有 10 条（诊断原料 5 + 生命科学 5）。用户笔记当前为空，需持续积累。

## 实现位置

- 后端：`脚本/销售工作台服务.py` → `do_POST` → `path == '/api/visit-card'`
- 前端：`工具/index.html` → `vpDoResearch(customer)` → `VISIT_CARD_API`
- `VISIT_CARD_API` = `https://macbook-air-2.tail6864e8.ts.net/api/visit-card`

## 服务重启与验证

```bash
lsof -ti:8000 | xargs kill
cd ~/Desktop/Hermes输出-工作类
python3 -u 脚本/销售工作台服务.py &
# 验证
curl -s --max-time 12 http://127.0.0.1:8000/api/visit-card \
  -X POST -H "Content-Type: application/json" -d '{"customer":"圣湘"}'
# 应返回 {"ok": true, ...}
```

## 关联技能

- **`baoyu-visit-card`**：完整的四 Tab 交互式 HTML 拜访卡生成器（LTC 方法论），可独立生成静态 HTML 文件到 `客户管理/拜访卡/`。比工作台内嵌版本更强大。
- **`ima-skill`**：IMA API 凭证管理和调用模板。
