## 新增功能 ### 商机中心 (/opportunity) - Stats统计卡片(商机总数、金额、赢单、转化率) - Pipeline商机管道(阶段Tab:全部/线索/谈判中/方案/赢单) - 商机列表真实数据渲染(来自crm_opportunity表) - 商机卡片详情(经销商、负责人、金额、概率) - Pipeline计数实时更新 ### 线索中心 (/lead) - 线索列表完整功能(CRUD) - 线索详情Drawer(基础信息 + 跟进记录Timeline) - 新建线索(含ERP客户关联、手机号验证) - 添加跟进记录(跟进方式、内容、下次时间) - 分配负责人(用户选择器,显示真实姓名) - 线索转经销商(自动创建商机) - 删除线索(逻辑删除) ## 后端开发 ### 数据库表 - crm_lead(线索表) - crm_lead_follow(线索跟进记录表) - crm_dealer(经销商表) - crm_opportunity(商机表) - crm_opportunity_follow(商机跟进记录表) - 数据字典初始化 ### API接口 - 线索管理:CRUD、详情、跟进、分配、转化 - 商机管理:列表查询 - 用户选择器:员工门户专用API ### 核心功能 - 线索转化自动创建经销商和商机 - 负责人翻译显示真实姓名(修复) - 手机号前后端双重格式验证(修复) ## 前端开发 ### 页面架构改进 - 商机中心:保留原CRM设计风格(Stats + Pipeline) - 线索中心:独立页面(完整线索管理) - 左侧菜单:独立菜单项(商机中心、线索中心) ### API模块 - src/api/crm/:线索和商机API类型定义和调用方法 - src/api/user/:用户选择器API ### 样式设计 - 商机中心:100%保持原CRM Pipeline设计风格 - 使用CSS变量系统(var(--radius-lg), var(--shadow-sm)等) - Pipeline Tab白色圆角设计 - 商机卡片阴影和hover效果 - 头像堆叠显示 ## 配置修改 - Gateway路由:添加CRM模块路由配置 - Gateway路由:添加system模块路由配置 - Aside菜单:拆分商机中心和线索中心 ## Bug修复 - 修复负责人显示手机号问题(UserNameTranslationImpl返回昵称) - 修复手机号格式验证缺失(前后端双重验证) - 修复商机管道设计风格不一致(完整复制原CRM样式) ## 文档 - CRM销售模块详细设计说明书V3.md - CRM线索转化API契约 - CRM线索转化开发计划 - CRM线索转化测试指引 - CRM线索管理测试指引 - CRM商机管理测试指引 - CRM架构改进报告 - CRM Bug修复报告 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
11 KiB
11 KiB
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):
{
"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>
{
"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>
{
"code": 200,
"msg": "查询成功",
"data": {
"leadId": 1001,
"customerCode": "C001",
"companyName": "XX贸易有限公司",
"contactName": "张三",
"mobile": "13800000000", // 未脱敏
// ... 其他字段同列表
}
}
3. 新增线索
接口: POST /crm/lead
请求体: CrmLeadBo
{
"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": "意向强烈,希望尽快对接"
}
业务逻辑:
- 如果提供
customerCode,调用hzhub-erp:8082/erp/dynamic/v1/customer/detail拉取ERP客户信息 - 自动填充客户基础信息(companyName, contactName, mobile等)
- 校验手机号是否重复(同租户内)
- 调用 LangChain4j AI服务分析意向等级(
hzhub-ai:6039/ai/analyze/intent- 第二阶段实现) - 根据区域规则(sys_dept)分配销售(owner_user_id - 可选)
- 返回成功消息
响应: R<Void>
{
"code": 200,
"msg": "新增成功"
}
4. 编辑线索
接口: PUT /crm/lead
请求体: CrmLeadBo
{
"leadId": 1001,
"companyName": "XX贸易(已改名)",
"contactName": "张三",
"mobile": "13800000000",
// ... 其他可编辑字段
}
响应: R<Void>
{
"code": 200,
"msg": "修改成功"
}
5. 删除线索
接口: DELETE /crm/lead/{leadIds}
路径参数: leadIds (String,逗号分隔,如 "1001,1002,1003")
响应: R<Void>
{
"code": 200,
"msg": "删除成功"
}
6. 分配线索
接口: PUT /crm/lead/assign
请求体:
{
"leadId": 1001,
"ownerUserId": 12345 // 新负责人ID(关联 sys_user)
}
响应: R<Void>
{
"code": 200,
"msg": "分配成功"
}
7. 获取跟进记录列表
接口: GET /crm/lead/follow/{leadId}
路径参数: leadId (Long)
响应: R<List<CrmLeadFollowVo>>
{
"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
{
"leadId": 1001,
"followType": "phone",
"content": "与客户沟通了具体合作细节,客户对返点政策满意",
"nextFollowTime": "2026-05-20 14:00:00"
}
业务逻辑:
- 保存跟进记录
- 调用 LangChain4j AI生成摘要(
hzhub-ai:6039/ai/summarize- 第二阶段实现) - 更新线索的
nextFollowTime
响应: R<Void>
{
"code": 200,
"msg": "跟进成功"
}
9. 线索转经销商(第二阶段实现)
接口: POST /crm/lead/convert
请求体:
{
"leadId": 1001,
"dealerName": "XX贸易",
"dealerCode": "DL20260001",
"customerCode": "C001" // ERP客户编码(可选)
}
响应: R<Void>
{
"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 | 拜访 |
| 邮件 | |
| other | 其他 |
前端类型定义(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;
}
注意事项(员工门户适配)
- 多租户支持: 所有查询自动过滤租户ID(TenantEntity)
- 数据权限: 根据 sys_dept 层级进行数据隔离
- 敏感字段脱敏: mobile 字段在列表查询时脱敏
- 字段翻译: 字典字段、用户ID、部门ID 自动翻译为名称
- 操作日志: 新增、编辑、删除操作记录日志
- 防重复提交: 新增操作防重复
- 逻辑删除: 使用 @TableLogic,删除时不物理删除
- ERP关联: 如果提供 customerCode,自动拉取ERP客户信息
- 无需Sa-Token注解: 员工门户权限由Gateway统一控制
ERP集成接口(hzhub-erp)
获取ERP客户详情
接口: GET /erp/dynamic/v1/customer/detail
请求参数: customerCode
响应: R<CustomerVO>
CustomerVO(员工门户已定义):
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预测模型