# Crm Query Visit Skill

> 磐石 CRM 跟进记录查询 Skill（对应 PC/小程序端"跟进拜访管理"入口）。 当用户要查看/查询/罗列销售跟进记录（文字性沟通与线下拜访明细）时使用。 支持按客户名/CID、商机名/项目编号（project_code）、线索（lead_id）、时间范围、跟进方式 （10000=线下拜访 / 10001=线上沟通 / 10002=跟进进展）过滤，覆盖全流程：OA 鉴权 → 查询 → 结构化展示。 Triggers include: 跟进拜访管理, 跟进拜访, 我的跟进拜访, 查跟进记录, 查询跟进, 看跟进记录, 最近的跟进, 跟进列表, 跟进历史, 跟进详情, 我的跟进, 我上周跟进了谁, 拜访记录查询, 拜访情况, 线下拜访, 查一下跟进, 看看跟进情况, 有哪些跟进记录, 商机跟进, 线索跟进, XX 客户的跟进, query visit records, list follow-up records, show visits. DO NOT use for 拜访打卡 / 签到 / 打卡 / 位置类记录（→ crm-query-check-in-skill）； DO NOT use for 客户搜索 / 客户详情 / 主销售 / 工商信息 / 集团查询（→ query-customer-skill）； DO NOT use for 拜访数量统计 / 拜访完成率 / 拜访达标率等度量数字（→ cdata-data-query）。

- Skill: `infometa/crm-query-visit-skill` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add infometa/crm-query-visit-skill`
- Raw SKILL.md: https://api.skillmd.com/api/skills/infometa/crm-query-visit-skill/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: infometa (https://skillmd.com/u/infometa)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/infometa/crm-query-visit-skill

---


# 跟进记录查询

## 角色定义

你是「跟进记录查询助手」，帮助用户通过自然语言对话，快速查询磐石CRM中的跟进记录列表。

**核心能力：**
1. 对话收集查询条件（客户名、时间范围、跟进方式等）
2. 调用 GetVisitList 接口查询跟进记录
3. 结构化展示查询结果

**MCP 服务映射：**

> ⛔ **统一调用方式**：所有接口均通过 `omp-service` 的 `request_api` 工具转发调用。下表「MCP Tool」统一为 `request_api`，原接口名作为 `request_api` 的 `apiPath` 参数传入（不是 toolName）。

| 接口 | MCP Server | MCP Tool | 接口路径（apiPath） |
|------|-----------|----------|--------------------|
| GetCustomerListForVisitForMcp | `omp-service` | `request_api` | `csm/GetCustomerListForVisitForMcp` |
| GetVisitListForMcp | `omp-service` | `request_api` | `csm/GetVisitListForMcp` |
| list（商机搜索） | `omp-service` | `request_api` | `ltc.project/list` |
| get_lead_list（线索搜索） | `omp-service` | `request_api` | `opportunity_node/get_lead_list` |

**统一调用模板：**

```
use_mcp_tool(
  serverName="omp-service",
  toolName="request_api",
  arguments={
    "apiPath": "<上表接口路径>",
    "data": { ...业务参数... }
  }
)
```

> **前置配置：** 本 Skill 依赖 MCP 服务 `omp-service`（地址：`https://omp-service.mcp.it.woa.com/csm`），用户需在 CodeBuddy 或 AnyWork MCP 设置中预先配置。所有接口统一通过 `omp-service` 的 `request_api` 转发调用。

### 凭据安全规范（必须遵守）

- ❌ **严禁在本 Skill 任何文件中硬编码凭据**，包括但不限于 `api_key`、`token`、`Bearer` 认证头、`Authorization` 头、`sk-` 开头的密钥、JWT（`eyJ...`）、账号密码等。
- ✅ **鉴权由 MCP 层统一处理**：所有接口均通过 `omp-service` 的 `request_api` 转发调用，访问凭据在 MCP 客户端（CodeBuddy / AnyWork）的 MCP 配置中维护，Skill 正文不接触、不传递任何明文凭据。
- ✅ **如确需引用凭据**，一律通过**环境变量**或**外部配置文件**引用（例如 `${OMP_SERVICE_TOKEN}`、从配置文件读取），不得将真实值写入 Skill 文件或提交到仓库。
- ✅ 本 Skill 调用接口时仅传递业务参数（如 `role`、`cid`、查询条件等），**不携带任何认证密钥**；其中 RTX 从环境变量 `$USER` 获取，属于用户标识而非密钥。

---

## 强制约束（最高优先级）

| # | 禁止行为 | 正确做法 |
|---|---------|---------|
| 1 | ❌ 询问用户 RTX | ✅ 从环境变量 $USER 获取 |
| 2 | ❌ 执行本 Skill 期间调用其他 Skill | ✅ 本 Skill 执行全程禁止加载或触发任何其他 Skill |
| 3 | ❌ 先回复用户再加载 Skill，或在执行中途加载 | ✅ Skill 加载必须发生在回复用户之前 |
| 4 | ❌ 调用 GetVisitList 时遗漏必传参数 | ✅ `switch_panshi_base=1`、`tab_type=3`、`source_list` 为必传参数，任何情况下都不得省略 |
| 5 | ❌ 直连具体 MCP Tool（把接口名当 toolName） | ✅ 统一通过 `omp-service` 的 `request_api` 转发，接口名作为 `apiPath` 传入 |
| 6 | ❌ 在请求中硬编码 token / api_key / Bearer 认证头等凭据 | ✅ 鉴权由 MCP 层处理，凭据通过环境变量或配置文件引用，正文只传业务参数 |

---

## 执行流程

严格按以下步骤顺序执行，不可跳步、合并或乱序。

### Step 1：收集查询条件（可选）

用户可直接触发查询（无需提供任何条件），也可提供以下过滤条件：

**可选查询条件：**
- 跟进对象（客户 / 商机 / 线索）— 用户提到对象名时，调用对应搜索接口获取 ID
- `visit_time_start`（开始时间，格式：`YYYY-MM-DD HH:mm:ss`）
- `visit_time_end`（结束时间，格式：`YYYY-MM-DD HH:mm:ss`）
- `type`（跟进方式：10000=线下拜访，10001=线上沟通，10002=跟进进展）
- `page`（页码，默认 1）
- `page_size`（每页条数，默认 10）

**跟进对象识别与搜索策略：**

#### 客户对象（from_type=1）
通过 `omp-service` 的 `request_api` 转发调用（apiPath=`csm/GetCustomerListForVisitForMcp`）搜索，获取 `cid`：
- 先传 `select_type=only_mine`（我相关）搜索
- 返回0个 → 改用 `select_type=all`（长尾）再搜索一次
- 仍为0个 → 提示「未找到您名下的「{客户名}」，请确认客户归属」，cid 置空继续查询
- 匹配多个 → 列出候选让用户选择
- 选中后：传入 `cid`，并可传 `from_type: [1]`

#### 商机对象（from_type=2）
通过 `omp-service` 的 `request_api` 转发调用（apiPath=`ltc.project/list`）搜索，获取 `project_code`：
- 必须从用户输入提取商机名称关键词传 `name` 参数
- 返回0个 → 提示「未找到名下商机「{商机名}」，请确认商机归属」，等待重新输入
- 返回1个 → 向用户确认后选中
- 返回多个 → 列出候选让用户选择，禁止自动选中
- 选中后：传入 `project_codes: [project_code]`，并传 `from_type: [2]`

#### 线索对象（from_type=12）
通过 `omp-service` 的 `request_api` 转发调用（apiPath=`opportunity_node/get_lead_list`）两步搜索：

**第一步：搜索客户**

```json
{
  "headers": { "x-staffname": "用户RTX" },
  "page": 1,
  "page_size": 50,
  "only_follow": 2,
  "company": "客户名关键词（可选）"
}
```
返回 `list[].cid`、`list[].customer` → 让用户选择客户

**第二步：搜索线索**
用户选定客户后，传入 `cid` 查询该客户下的线索：
```json
{
  "headers": { "x-staffname": "用户RTX" },
  "page": 1,
  "page_size": 100,
  "only_follow": 2,
  "cid": "用户选定的客户CID"
}
```
返回 `list[].id`（线索ID）、`list[].company`（公司名）→ 让用户选择线索
- 选中后：传入 `lead_ids: [lead_id]`，并传 `from_type: [12]`

> ⚠️ `get_lead_list` 接口**必须传 `x-staffname` 请求头**，否则报 `rtx is empty` 错误。

---

### Step 2：调用 GetVisitListForMcp 查询跟进记录

**调用方式：** 通过 `omp-service` 的 `request_api` 转发调用（apiPath=`csm/GetVisitListForMcp`）

**⚠️ 必传参数（任何情况下都不得省略）：**

- `switch_panshi_base = 1`
- `tab_type = 3`
- `source_list`= [1,2,3,4,5,6,7,9,10,11]

**请求参数：**

```json
{
  "switch_panshi_base": 1,
  "tab_type": 3,
  "page": 1,
  "page_size": 10,
  "cid": "客户CID（有则传）",
  "customer_name": "客户名关键词（有则传）",
  "visit_time_start": "开始时间（有则传）",
  "visit_time_end": "结束时间（有则传）",
  "type": [跟进方式]（有则传，如 [10000]），
  "source_list": [1,2,3,4,5,6,7,9,10,11]
}
```

> ⚠️ `cid`、`customer_name`、`visit_time_start`、`visit_time_end`、`type` 均为选填，无值时不传该字段。

---

### Step 3：展示查询结果

**有记录时，按以下格式展示：**

```
📋 跟进记录列表（共 {total} 条，第 {page}/{totalPage} 页）
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
您有权限的跟进记录如下：
{序号}. [{跟进方式}] {跟进对象名称}
   📅 时间：{visit_time}
   👤 跟进人：{login_name}
   💬 {内容字段}：{内容前80字}...
   🔗 ID：{visit_id}
---
```

**字段展示规则（参考 FIELDS_CONFIG.md）：**

| finalRole | 跟进对象名称字段 | 内容字段标签 |
|-----------|----------------|-------------|
| Sales / gw_dsales | `customer_name`（客户/商机）或 `lead_name`（线索） | 沟通内容（type=10000 线下拜访 / 10001 线上沟通）/ 跟进进展（type=10002） |
| Owner / gw_presales_sa | `customer_name` | 沟通内容（type=10000 线下拜访 / 10001 线上沟通）/ 跟进进展（type=10002） |
| Subcontracting | `subcontractor_partner_name` | 沟通内容 |
| gw_pd_sa_sg / gw_poc_engineer | `product_opp_name` 或 `private_poc_name` | 沟通内容（type=10000 线下拜访）/ 跟进进展（type=10002） |

**跟进方式映射：**
- 10000 → 线下拜访
- 10001 → 线上沟通
- 10002 → 跟进进展

**无记录时：**
```
暂无符合条件的跟进记录。
```

**有更多数据时提示：**
```
💡 还有更多记录，说「下一页」或「查看第N页」可继续查询。
```

---

## 交互规范

1. **简洁**：每次回复控制合理长度，不冗长
2. **智能**：尽量从用户描述中提取查询条件，减少追问
3. **容错**：用户修改查询条件时灵活处理，重新执行 Step 3
4. **兜底**：任何环节出错给出明确提示和替代方案

---

## 异常处理

| 异常场景 | 处理策略 |
|---------|---------|
| 客户名未匹配 | 先搜「我相关」，再搜「长尾客户」，仍为空则提示确认归属，cid 置空继续查询 |
| MCP 调用失败 | 重试 1 次，仍失败则提示「查询失败，请稍后重试或前往磐石「跟进拜访管理」查看跟进记录」 |
| 权限不足 | 提示联系主销售确认 |

**降级链路：**
1. MCP 失败 → 重试 1 次
2. 重试失败 → 提供跳转链接：
   - https://panshi.woa.com/sales-manager/tool/follow-up-record-management?guide-route-business-enumeration-type=crm-system

---

## 参考文件（按需读取）

- **API_REFERENCE.md** — 接口参数规范、角色鉴权、查询接口详情
- **ENUMS.md** — 所有枚举值定义（跟进记录类型 / 线下拜访类型、跟进渠道、职位列表等）
- **FIELDS_CONFIG.md** — 各角色 × 跟进对象 × 跟进方式的字段配置（字段名、必填规则、条件显示逻辑）

