# baoyu-visitor-prep — details

### 步骤

**1. 确认见面对象与客户分级**
- 从已有情报中列出关键研发/决策人，标注角色和当前关系
- 如情报未明确身份，诚实标注推断依据
- 给出客户分级（S/A/B/C），影响拜访深度和资源投入

**2. 提炼必带材料（🔴🟡🟢分级）**

| 优先级 | 说明 |
|--------|------|
| 🔴 必带 | 客户已明确要求的内容（如"梯度报价"），不带=白去 |
| 🟡 带上 | 已知的性能差距或待解决问题，带方案去 |
| 🟢 备着 | 顺手推进的新机会 |

**3. 列出雷区（⚠️格式）**
- 客户的价格敏感度、历史成交价锚点
- 客户内部采购铁律（多头采购、统一平台、账期要求）
- 竞品威胁及应对策略（不贬低竞品，用差异化打）
- 客户自产能力/替代倾向
- 组织架构陷阱（多实体容易搞混的采购/决策流程）

**4. 竞争态势速览**
- 列出主要竞品及其份额占比
- 标注客户对竞品的评价（正面/负面/中性）
- 明确宝锐的差异化优势（硬数据支撑，非抽象话术）

**5. 准备话术（场景→怎么说）**
- 每个关键场景给出具体应对话术
- 话术中嵌入从情报中提取的具体数字（用量、日期、历史价格）
- 避免抽象营销语言，用客户已经说过的话做锚点

**6. 拜访后立即行动（3W1H）**
- Who：谁负责
- What：做什么
- When：什么时间前
- How：交付什么


### 解析方法

**优先用轻量级方法**（避免pandas/openpyxl超时）。**推荐先用 `zf.namelist()` 确认实际sheet文件名，跳过 workbook.xml + rels 联动解析——直接读sheet文件最快且避免命名空间兼容性问题：**

```python
import zipfile, xml.etree.ElementTree as ET

zf = zipfile.ZipFile('活动导出.xlsx')
ns = {'s': 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'}

# 快速诊断：列出所有文件，定位sheet文件
print([f for f in zf.namelist() if 'sheet' in f.lower()])
# → 飞书CRM导出99%在 xl/worksheets/sheet2.xml，直接读取：
sheet_xml = zf.read('xl/worksheets/sheet2.xml')

# 加载共享字符串表
ss_xml = zf.read('xl/sharedStrings.xml')
ss_tree = ET.fromstring(ss_xml)
strings = [si.find('.//s:t', ns).text or '' for si in ss_tree.findall('.//s:si', ns)]

# ⚠️ 必须先确定正确的sheet文件名，不要假设是sheet1.xml！
# 1) 读 workbook.xml 获取 r:id 映射
wb_xml = zf.read('xl/workbook.xml')
wb_tree = ET.fromstring(wb_xml)
sheets = wb_tree.findall('.//s:sheet', ns)
# 2) 读 xl/_rels/workbook.xml.rels 获取 r:id → Target 映射（注意：飞书CRM用 officeDocument ns，ERP可能用 package ns）
rns = {'r': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'}
rels_xml = zf.read('xl/_rels/workbook.xml.rels')
rels_tree = ET.fromstring(rels_xml)
sheet_paths = {}
for rel in rels_tree.findall('.//r:Relationship', rns):
    sheet_paths[rel.get('Id')] = rel.get('Target')
# 3) 拼接正确路径
rid = sheets[0].get('{http://schemas.openxmlformats.org/officeDocument/2006/relationships}id')
correct_path = 'xl/' + sheet_paths[rid]  # 飞书CRM导出常在 sheet2.xml，不要假设 sheet1.xml

# 解析sheet
sheet_xml = zf.read(correct_path)
sheet_tree = ET.fromstring(sheet_xml)
rows = sheet_tree.findall('.//s:row', ns)

def cell_val(c):
    v = c.find('s:v', ns)
    t = c.get('t', '')
    val = v.text if v is not None else ''
    if t == 's' and val.isdigit():
        idx = int(val)
        if idx < len(strings):
            val = strings[idx]
    return val

# 遍历搜索目标公司
for row in rows[1:]:  # 跳过表头
    cells = [cell_val(c) for c in row.findall('s:c', ns)]
    row_text = ' '.join(str(c) for c in cells if c)
    if '目标公司名' in row_text:
        # cells[0]=部门, cells[1]=客户, cells[3]=销售, cells[4]=日期
        # cells[7]=活动描述（拜访纪要）, cells[9]=活动类型
```


### 情报提取重点

从活动描述（cells[7]）中挖掘：

1. **项目进展** — 在测什么产品、哪个阶段（小试/中试/转产）
2. **采购与价格** — 搜索关键词：采购/报价/价格/成本/元/下单/备货/回款
3. **竞品情报** — 客户提到其他厂家的内容
4. **关键决策人** — 研发老师姓名、采购联系人
5. **产品匹配** — 提取产品编码（FE\d+|M\d+|AS\d+|MD\d+）
6. **组织架构** — 研发团队规模、分组、决策链


### 采购/价格情报专项提取

```python
import re

# 提取金额/数量
prices = re.findall(r'(\d+\.?\d*)\s*(元/[Tt人份]|ml|ML|元)', desc)
# 提取产品编码
products = set(re.findall(r'(FE\d+|E\d+|M\d+|AS\d+|FMD\d+|MD\d+)', desc))
# 提取关键上下文
for kw in ['报价', '价格', '成本', '采购', '下单', '回款']:
    if kw in desc:
        idx = desc.find(kw)
        ctx = desc[max(0,idx-30):min(len(desc),idx+80)]
```


### 解析要点
- 赠品（是否赠品=是）不计算销售额
- 测试销售订单（单据类型=测试）价税合计=0，用于送样记录
- 按货号#聚合可得各产品累计销量和销售额
- **客户分级规则**：累计ERP销售额>10万=B级，>50万=A级，>100万=S级
- 解析方法同CRM（zipfile+xml），注意namespace可能是 `package/2006/relationships`


### 档案位置
`~/Desktop/Hermes输出-工作类/客户管理/[公司名]_客户档案.json`


### 档案更新时机
- 每次完成访前背调后 → 创建/更新档案的 qualifications/nmpa_certificates/core_patents/productLines 字段
- 每次完成产品管线分析后 → 更新 products/erpSummary/baoruiOpportunity 字段
- 用户纠正某条信息后 → 立即更新对应字段
- 每次从ERP/CRM提取新数据后 → 更新 erpSummary


### 与拜访卡联动
- 拜访卡中的联系人数据（`allData.contacts`）可通过"📋 导出客户档案"按钮导出为JSON片段
- Agent读取该JSON后合并到客户档案的 `contacts` 字段
- 拜访卡和档案JSON共享 `客户管理/` 目录


### Step 1: 并行信息收集

同时启动：
- `web_search` "[公司名] NMPA 注册证 国械注准" — 查找已获批和审批中的产品
- `web_search` "[公司名] 专利 基因 检测 试剂盒" — 查找技术护城河和产品方向
- `web_search` "[客户所在赛道] 市场 规模 2025 2026 中国" — 赛道规模数据
- 读取已有的客户档案JSON（`~/Desktop/Hermes输出-工作类/客户管理/XX公司_客户档案.json`）
- 读取已有的ERP数据（聚合产品/金额/采购频率）
- 如果用户提供了市场调研PDF，用 `pymupdf` 或 `pdftotext` 提取关键数据


### Step 2: 产品管线推断

从收集的信息中推断客户的三阶段产品路线：

| 阶段 | 信息来源 | 推断逻辑 |
|------|---------|---------|
| 阶段一（已上市） | NMPA注册证 + ERP采购数据 | 已获证产品 → 确认当前原料消耗 |
| 阶段二（报证/即将上市） | 专利（已授权但未见注册证）+ 官网产品页 + 启信宝 | 专利保护的技术方案 → 推断即将报证的产品 |
| 阶段三（研发中） | 企业简介提及但无专利/注册证 + 行业趋势 | 战略方向描述 + 赛道趋势 → 推断远期产品 |


### Step 3: 宝锐产品逐阶段匹配

对每个阶段列出：
- 客户技术需求（多重PCR？直扩？冻干？高灵敏度？）
- 宝锐推荐产品（货号+名称）
- 匹配理由（为什么这个产品适合这个阶段）
- 预估年消耗量（基于ERP历史数据+管线放量预期）
- 竞品原料威胁评估（诺唯赞/Takara/Thermo在该客户场景的威胁等级）


### Step 4.5: 国家采购与政策动态扫描（新增）

针对客户所在赛道，搜索近期（2025-2026）的重大招投标和科研项目机会：

- `web_search` "[客户产品关键词] 政府采购 招标 2025 2026" — 医院/公卫项目采购
- `web_search` "[客户赛道] 国家科技重大专项 重点研发计划 2026" — 国家级科研项目
- `web_search` "[客户赛道] 集采 IVD 试剂 2025 2026" — 集采政策影响

提取内容：
- 直接相关的医院招标项目（客户已有获证产品可参与竞标）
- 国家级科研项目（客户可联合高校/研究所申报，资助强度）
- 集采趋势判断（影响客户产品定价和成本结构）

输出为政策动态表格 + 综合研判（机会窗口/市场窗口/集采窗口）。


### Step 5: 优先行动建议

输出三层优先级：

| 优先级 | 标准 | 时限 |
|--------|------|------|
| 🔴 P0 | 客户当前在用的产品升级（如液→冻干）、注册窗口期锁定 | 立即 |
| 🟡 P1 | 配合下一阶段管线的新产品推荐 | 3个月内 |
| 🟢 P2 | 远期管线布局、战略卡位 | 6个月内 |

每项行动包含具体话术锚点（从已确认的客户事实出发，如"您现在的MD2031已经有UNG防污染了，冻干版同样含UNG……"）。


### 双版本输出（内部版 + 客户展示版）

分析报告默认包含竞品评估和内部行动建议（第5-6章）。用户要求"输出客户展示版"时：
- 删除竞品原料威胁评估章节
- 删除优先行动建议章节
- 删除编辑器工具栏
- 将"宝锐"品牌名替换为中性表述
- 文件名改为 `[公司名]_产品开发方向与市场分析_客户展示版.html`


### Hermes侧约定
- 生成文件后，文件名必须使用可预测的 `custShort` 映射。例如：
  - 珠海丽珠试剂股份有限公司 → `丽珠试剂_客户调研.html`（去掉"珠海""股份有限公司"）
  - 中普康睿河北生物科技有限公司 → `中普康睿_客户调研.html`
- 如果历史文件名不标准，创建软链统一：
  ```bash
  ln -sf "中普康睿_产品开发方向与市场分析_客户展示版.html" "中普康睿_客户调研.html"
  ```
- 存放路径约定：
  - 调研报告：`客户管理/{custShort}_客户调研.html`
  - 拜访卡：`客户管理/拜访卡/{custShort}_拜访卡.html`


### 准备中心自动检测
- 页面加载后自动对每条pending档案发起 `fetch(encodeURI(path), {method:'HEAD'})`
- 文件返回200 → 更新状态为done，添加可点击链接
- 用户可随时点击"刷新检测"重新扫描
- ⚠️ file:// 协议下的陷阱和修复见 `baoyu-visit-card` 技能的 `references/file-detection-mechanism.md`
