# CRM 线索中心模块 API 契约（V3 - 员工门户）

## 基础信息

- **服务归属**: hzhub-system (端口 8083)
- **API前缀**: `/crm/lead` (通过 Gateway 路由 `/crm/**` → hzhub-system)
- **前端项目**: hzhub-portal-employee (员工门户)
- **响应格式**: `R<T>` (org.hzhub.common.core.domain.R)
- **分页格式**: `TableDataInfo<T>` (org.hzhub.common.mybatis.core.page.TableDataInfo)

---

## 接口列表

### 1. 线索列表查询

**接口**: `GET /crm/lead/list`

**请求参数** (Query):

```json
{
  "companyName": "XX贸易",        // 公司名称（模糊查询）
  "mobile": "13800000000",        // 手机号
  "intentLevel": "high",          // AI意向等级（字典：crm_intent_level）
  "riskLevel": "low",             // 风险等级（字典：crm_risk_level）
  "ownerUserId": 12345,           // 负责人ID
  "leadStatus": "following",      // 线索状态（字典：crm_lead_status）
  "sourceType": "activity",       // 来源类型（字典：crm_lead_source）
  "customerCode": "C001",         // ERP客户编码
  "pageNum": 1,                   // 页码
  "pageSize": 10                  // 每页大小
}
```

**响应**: `TableDataInfo<CrmLeadVo>`

```json
{
  "code": 200,
  "msg": "查询成功",
  "rows": [
    {
      "leadId": 1001,
      "tenantId": "000000",
      "customerCode": "C001",         // ERP客户编码
      "companyName": "XX贸易有限公司",
      "contactName": "张三",
      "mobile": "138****0000",         // 脱敏
      "wechat": "zhangsan",
      "province": "广东省",
      "city": "深圳市",
      "regionId": 100,
      "regionName": "华南区",          // 翻译
      "sourceType": "activity",
      "sourceTypeName": "活动",        // 翻译
      "industry": "食品",
      "industryName": "食品行业",      // 翻译
      "storeCount": 20,
      "intentLevel": "high",
      "intentLevelName": "高意向",     // 翻译
      "aiScore": 85.5,
      "riskLevel": "low",
      "riskLevelName": "低风险",       // 翻译
      "ownerUserId": 12345,
      "ownerUserName": "李四",         // 翻译
      "leadStatus": "following",
      "leadStatusName": "跟进中",      // 翻译
      "nextFollowTime": "2026-05-20 14:00:00",
      "createBy": 1,
      "createByName": "系统管理员",    // 翻译
      "createTime": "2026-05-15 10:00:00"
    }
  ],
  "total": 100
}
```

---

### 2. 线索详情查询

**接口**: `GET /crm/lead/{leadId}`

**路径参数**: `leadId` (Long)

**响应**: `R<CrmLeadVo>`

```json
{
  "code": 200,
  "msg": "查询成功",
  "data": {
    "leadId": 1001,
    "customerCode": "C001",
    "companyName": "XX贸易有限公司",
    "contactName": "张三",
    "mobile": "13800000000",           // 未脱敏
    // ... 其他字段同列表
  }
}
```

---

### 3. 新增线索

**接口**: `POST /crm/lead`

**请求体**: `CrmLeadBo`

```json
{
  "customerCode": "C001",             // ERP客户编码（可选）
  "companyName": "XX贸易有限公司",
  "contactName": "张三",
  "mobile": "13800000000",
  "wechat": "zhangsan",
  "province": "广东省",
  "city": "深圳市",
  "regionId": 100,                    // 关联 sys_dept
  "sourceType": "activity",
  "activityName": "春季招商会",
  "referrerName": "王五",
  "industry": "食品",
  "companyScale": "50-100人",
  "storeCount": 20,
  "remark": "意向强烈，希望尽快对接"
}
```

**业务逻辑**:

1. 如果提供 `customerCode`，调用 `hzhub-erp:8082/erp/dynamic/v1/customer/detail` 拉取ERP客户信息
2. 自动填充客户基础信息（companyName, contactName, mobile等）
3. 校验手机号是否重复（同租户内）
4. 调用 LangChain4j AI服务分析意向等级（`hzhub-ai:6039/ai/analyze/intent` - **第二阶段实现**）
5. 根据区域规则（sys_dept）分配销售（owner_user_id - **可选**）
6. 返回成功消息

**响应**: `R<Void>`

```json
{
  "code": 200,
  "msg": "新增成功"
}
```

---

### 4. 编辑线索

**接口**: `PUT /crm/lead`

**请求体**: `CrmLeadBo`

```json
{
  "leadId": 1001,
  "companyName": "XX贸易（已改名）",
  "contactName": "张三",
  "mobile": "13800000000",
  // ... 其他可编辑字段
}
```

**响应**: `R<Void>`

```json
{
  "code": 200,
  "msg": "修改成功"
}
```

---

### 5. 删除线索

**接口**: `DELETE /crm/lead/{leadIds}`

**路径参数**: `leadIds` (String，逗号分隔，如 "1001,1002,1003")

**响应**: `R<Void>`

```json
{
  "code": 200,
  "msg": "删除成功"
}
```

---

### 6. 分配线索

**接口**: `PUT /crm/lead/assign`

**请求体**:

```json
{
  "leadId": 1001,
  "ownerUserId": 12345               // 新负责人ID（关联 sys_user）
}
```

**响应**: `R<Void>`

```json
{
  "code": 200,
  "msg": "分配成功"
}
```

---

### 7. 获取跟进记录列表

**接口**: `GET /crm/lead/follow/{leadId}`

**路径参数**: `leadId` (Long)

**响应**: `R<List<CrmLeadFollowVo>>`

```json
{
  "code": 200,
  "msg": "查询成功",
  "data": [
    {
      "followId": 2001,
      "leadId": 1001,
      "followType": "phone",
      "followTypeName": "电话",        // 翻译
      "content": "客户表达了合作意向，希望了解招商政策",
      "aiSummary": "客户意向高，关注返点政策",
      "nextFollowTime": "2026-05-20 14:00:00",
      "followUserId": 12345,
      "followUserName": "李四",        // 翻译
      "createTime": "2026-05-15 15:00:00"
    }
  ]
}
```

---

### 8. 添加跟进记录

**接口**: `POST /crm/lead/follow`

**请求体**: `CrmLeadFollowBo`

```json
{
  "leadId": 1001,
  "followType": "phone",
  "content": "与客户沟通了具体合作细节，客户对返点政策满意",
  "nextFollowTime": "2026-05-20 14:00:00"
}
```

**业务逻辑**:

1. 保存跟进记录
2. 调用 LangChain4j AI生成摘要（`hzhub-ai:6039/ai/summarize` - **第二阶段实现**）
3. 更新线索的 `nextFollowTime`

**响应**: `R<Void>`

```json
{
  "code": 200,
  "msg": "跟进成功"
}
```

---

### 9. 线索转经销商（第二阶段实现）

**接口**: `POST /crm/lead/convert`

**请求体**:

```json
{
  "leadId": 1001,
  "dealerName": "XX贸易",
  "dealerCode": "DL20260001",
  "customerCode": "C001"             // ERP客户编码（可选）
}
```

**响应**: `R<Void>`

```json
{
  "code": 200,
  "msg": "转化成功"
}
```

---

## 数据字典定义

### crm_lead_source（线索来源）

| 字典值 | 字典标签 | 备注 |
|---|---|---|
| activity | 活动 | 线下招商活动 |
| referral | 推荐 | 客户推荐 |
| website | 网站 | 官网咨询 |
| exhibition | 展会 | 行业展会 |
| wecom | 企业微信 | 企业微信咨询 |
| erp | ERP客户 | 从ERP客户转化 |
| other | 其他 | 其他来源 |

### crm_lead_status（线索状态）

| 字典值 | 字典标签 | 备注 |
|---|---|---|
| new | 新线索 | 刚录入，未分配 |
| following | 跟进中 | 已分配，正在跟进 |
| converted | 已转化 | 已转为经销商 |
| invalid | 已作废 | 线索无效 |

### crm_intent_level（AI意向等级）

| 字典值 | 字典标签 | AI评分范围 |
|---|---|---|
| high | 高意向 | >= 80 |
| medium | 中意向 | 60-80 |
| low | 低意向 | < 60 |

### crm_risk_level（风险等级）

| 字典值 | 字典标签 | 备注 |
|---|---|---|
| high | 高风险 | 需重点关注 |
| medium | 中风险 | 需持续跟踪 |
| low | 低风险 | 正常跟进 |

### crm_follow_type（跟进方式）

| 字典值 | 字典标签 |
|---|---|
| phone | 电话 |
| wecom | 企业微信 |
| visit | 拜访 |
| email | 邮件 |
| other | 其他 |

---

## 前端类型定义（TypeScript - 员工门户）

```typescript
// CrmLeadVo
export interface CrmLeadVo {
  leadId: number;
  tenantId: string;
  customerCode?: string;              // ERP客户编码
  companyName: string;
  contactName: string;
  mobile: string;
  wechat?: string;
  province?: string;
  city?: string;
  regionId?: number;
  regionName?: string;
  sourceType?: string;
  sourceTypeName?: string;
  activityName?: string;
  referrerName?: string;
  industry?: string;
  industryName?: string;
  companyScale?: string;
  storeCount?: number;
  intentLevel?: string;
  intentLevelName?: string;
  aiScore?: number;
  riskLevel?: string;
  riskLevelName?: string;
  ownerUserId?: number;
  ownerUserName?: string;
  leadStatus: string;
  leadStatusName?: string;
  convertedDealerId?: number;
  nextFollowTime?: string;
  remark?: string;
  createBy: number;
  createByName?: string;
  createTime: string;
  updateBy?: number;
  updateByName?: string;
  updateTime?: string;
}

// CrmLeadBo
export interface CrmLeadBo {
  leadId?: number;
  customerCode?: string;              // ERP客户编码（可选）
  companyName: string;
  contactName: string;
  mobile: string;
  wechat?: string;
  province?: string;
  city?: string;
  regionId?: number;
  sourceType?: string;
  activityName?: string;
  referrerName?: string;
  industry?: string;
  companyScale?: string;
  storeCount?: number;
  ownerUserId?: number;
  remark?: string;
}

// CrmLeadFollowVo
export interface CrmLeadFollowVo {
  followId: number;
  leadId: number;
  followType: string;
  followTypeName?: string;
  content: string;
  aiSummary?: string;
  nextFollowTime?: string;
  followUserId: number;
  followUserName?: string;
  createTime: string;
}

// CrmLeadFollowBo
export interface CrmLeadFollowBo {
  followId?: number;
  leadId: number;
  followType: string;
  content: string;
  nextFollowTime?: string;
}

// TableDataInfo（员工门户已定义）
export interface TableDataInfo<T> {
  code: number;
  msg: string;
  rows: T[];
  total: number;
}

// R（员工门户已定义）
export interface R<T> {
  code: number;
  msg: string;
  data?: T;
}
```

---

## 注意事项（员工门户适配）

1. **多租户支持**: 所有查询自动过滤租户ID（TenantEntity）
2. **数据权限**: 根据 sys_dept 层级进行数据隔离
3. **敏感字段脱敏**: mobile 字段在列表查询时脱敏
4. **字段翻译**: 字典字段、用户ID、部门ID 自动翻译为名称
5. **操作日志**: 新增、编辑、删除操作记录日志
6. **防重复提交**: 新增操作防重复
7. **逻辑删除**: 使用 @TableLogic，删除时不物理删除
8. **ERP关联**: 如果提供 customerCode，自动拉取ERP客户信息
9. **无需Sa-Token注解**: 员工门户权限由Gateway统一控制

---

## ERP集成接口（hzhub-erp）

### 获取ERP客户详情

**接口**: `GET /erp/dynamic/v1/customer/detail`

**请求参数**: `customerCode`

**响应**: `R<CustomerVO>`

**CustomerVO**（员工门户已定义）:

```typescript
interface CustomerVO {
  customerCode: string;
  customerName: string;
  contactName: string;
  salesAreaName: string;
  brandName: string;
  phone: string;
  province: string;
  city: string;
  // ... 其他字段见 hzhub-portal-employee/src/api/erp/index.ts
}
```

---

## 开发优先级

- **P0（必须实现）**: 接口1-8（基础CRUD + 跟进）
- **P1（第二阶段）**: 接口9（线索转经销商）+ AI意向识别 + AI摘要生成
- **P2（第三阶段）**: AI风险分析 + AI预测模型