|
|
|
|
# 客户模块接口汇总(票 13)
|
|
|
|
|
|
|
|
|
|
> **载体**:本文为速查汇总;完整契约以 knife4j 在线文档为准(`http://<host>:8080/doc.html`,`@Schema`/`@Operation` 注解齐全,与实现签名一致)。
|
|
|
|
|
> **范围**:crm-customer 全部 REST 端点 + 跨模块依赖(crm-rule 提醒配置 / crm-preference saved-view)。按原型界面分组(票 12 逐页对齐同源)。
|
|
|
|
|
> **状态**:票 12 对齐后同步版(含不符②③④⑤修复);「已知缺口」见 §5。
|
|
|
|
|
|
|
|
|
|
## 0. 通用约定
|
|
|
|
|
|
|
|
|
|
- **认证**:`Authorization: Bearer <token>`(网关注入用户上下文;`SecurityUtils.getRequiredUserId()`)。
|
|
|
|
|
- **统一响应**:`Result<T>` = `{code, success, message, data}`;`code=0` 成功,非 0 业务错误(§2 错误码)。
|
|
|
|
|
- **分页**:请求继承 `BaseParam`(`current`/`size`,非 pageNo/pageSize);响应 `PageResult<T>` = `{content, total, ...}`,取列表 `getContent()`。
|
|
|
|
|
- **ID 精度**:雪花 Long 在 JSON 中**序列化为字符串**(前端勿做 Number 运算)。
|
|
|
|
|
- **权限**:
|
|
|
|
|
- RBAC 功能权限:`ApiPermissionInterceptor` 注册规则匹配;**未匹配规则 fail-open 放行**(新端点无需登记即生效)。
|
|
|
|
|
- 数据范围:`overview` 列表/看板等查询经 `@DataScope` 注入可见范围(我的客户=负责人或协同人;公海=无归属)。
|
|
|
|
|
- **脱敏现状**:查重相似命中 `CustomerSimilarHitDTO.masked`;详情敏感信息三档(手机号/证件等分档脱敏)**V1 未纳入**(issues-07 定稿划出,§5)。
|
|
|
|
|
- **时间**:`yyyy-MM-dd HH:mm:ss`;日志日期分组由前端按日渲染。
|
|
|
|
|
|
|
|
|
|
## 1. 错误码总表(67xxx,`CustomerConstants`)
|
|
|
|
|
|
|
|
|
|
| 码 | 常量 | 含义 |
|
|
|
|
|
|---|---|---|
|
|
|
|
|
| 67001 | CODE_CUST_INVALID | 客户入参非法(必填缺失/格式错误) |
|
|
|
|
|
| 67002 | CODE_CUST_NOT_EXIST | 客户不存在或已被删除 |
|
|
|
|
|
| 67003 | CODE_CREDIT_CODE_DUP | 统一社会信用代码已被占用(L3 硬拦) |
|
|
|
|
|
| 67004 | CODE_STATUS_NOT_ALLOWED | 当前状态不允许此操作(归档/恢复/抛公海守卫) |
|
|
|
|
|
| 67005 | CODE_CAS_FAIL | 乐观锁 CAS 冲突 |
|
|
|
|
|
| 67006 | CODE_ARCHIVE_BLOCKED | 归档被阻断:存在进行中商机 |
|
|
|
|
|
| 67007 | CODE_POOL_BLOCKED | 抛公海被阻断:存在进行中商机 |
|
|
|
|
|
| 67008 | CODE_CONTACT_INVALID | 联系人入参非法/不属于该客户 |
|
|
|
|
|
| 67009 | CODE_FOLLOW_INVALID | 跟进入参非法(内容缺失/下次跟进时间早于本次) |
|
|
|
|
|
| 67010 | CODE_TRANSFER_DUP_RUNNING | 交割被阻断:存在未完成交接单(防重入) |
|
|
|
|
|
| 67011 | CODE_TRANSFER_FORBIDDEN | 交割被阻断:无可交接客户/接收总监不合法/非本人发起 |
|
|
|
|
|
| 67012 | CODE_ASSIGN_INVALID | 分配非法:明细已分配/对象越权/为发起人本人/为当前负责人 |
|
|
|
|
|
| 67013 | CODE_IMPORT_PRECHECK_FAIL | 导入预校验失败(文件/表头/行数/模板版本) |
|
|
|
|
|
| 67014 | CODE_IMPORT_STATUS_NOT_ALLOWED | 导入任务状态不允许此操作 |
|
|
|
|
|
| 67015 | CODE_DEDUP_RULE_MISSING | 查重设置单例缺失 |
|
|
|
|
|
| 67016 | CODE_MEMBER_INVALID | 成员管理非法:名单空/含负责人/重复加入/用户停用/成员不存在 |
|
|
|
|
|
|
|
|
|
|
## 2. 按原型界面接口清单
|
|
|
|
|
|
|
|
|
|
### 2.1 A4-2-1 客户总览 / A4-2-2 我的客户(`CustomerWorkspaceController /api/customer/workspace`)
|
|
|
|
|
|
|
|
|
|
| 方法 | 路径 | 说明 | 关键入参 | 主要错误码 |
|
|
|
|
|
|---|---|---|---|---|
|
|
|
|
|
| POST | `/{workspace}/page` | 列表分页(saved-view 过滤器接入,票 10) | workspace=`overview`/`mine`/`pool`;`CustomerPageParam`(viewType:ASSIGNED/COLLABORATING/FOCUSED…;BaseParam 分页) | 67002 |
|
|
|
|
|
| POST | `/{workspace}/board/summary` | 看板三分组数量汇总(D20) | viewType、分组维度(stage/customerStar/relationStar) | — |
|
|
|
|
|
| POST | `/{workspace}/board/cards` | 看板单组卡片 | 同上 + 分组键值 + 分页 | — |
|
|
|
|
|
|
|
|
|
|
出参 `CustomerListRowDTO`:主表快照 + 关联业务计数(opportunityCount 真算 / projectCount 恒 null 显 "--")。
|
|
|
|
|
|
|
|
|
|
### 2.2 A4-1-1 客户公海列表(同上 Controller + `CustomerOwnershipController /api/customer`)
|
|
|
|
|
|
|
|
|
|
| 方法 | 路径 | 说明 | 主要错误码 |
|
|
|
|
|
|---|---|---|---|
|
|
|
|
|
| POST | `/api/customer/workspace/pool/page` | 公海分页(检索:类型/行业;排序:进入公海时间 grill Q19) | — |
|
|
|
|
|
| POST | `/api/customer/claim?id=` | 领取(幂等口径见实现) | 67002/67004 |
|
|
|
|
|
| POST | `/api/customer/claim-batch?ids=` | 批量领取 → `BatchResult{successes,failures[]}` | 同上 |
|
|
|
|
|
| POST | `/api/customer/assign?id=&userId=` | 分配(校验启用在职,口径同 validateTargetUser) | 67002/67012 |
|
|
|
|
|
| POST | `/api/customer/assign-batch?ids=&userId=` | 批量分配 | 同上 |
|
|
|
|
|
| POST | `/api/customer/release-pool?id=` | 抛公海(前置:无进行中商机;软删 team_member) | 67002/67007 |
|
|
|
|
|
| POST | `/api/customer/release-pool-batch?ids=` | 批量抛公海(逐条独立事务,部分成功 → `BatchResult{successes,failures[]}`) | 67002/67007 |
|
|
|
|
|
|
|
|
|
|
### 2.3 A4-3-3-1 新增/编辑客户 + 查重(`CustomerController /api/customer`)
|
|
|
|
|
|
|
|
|
|
| 方法 | 路径 | 说明 | 主要错误码 |
|
|
|
|
|
|---|---|---|---|
|
|
|
|
|
| POST | `/api/customer` | 新增(form 绑定 `CustomerCreateDTO`;三层查重内建;ownerUserId 空=进公海记 enter_pool_time) | 67001/67003/67015 |
|
|
|
|
|
| PUT | `/api/customer/{id}` | 编辑(CAS:version 带回;归属字段不可改) | 67001/67002/67003/67005 |
|
|
|
|
|
| GET | `/api/customer/{id}` | 详情(编辑页全字段回显,字典回显名) | 67002 |
|
|
|
|
|
| POST | `/api/customer/page` | 基础分页(keyword/阶段/档案/类型;DataScope) | — |
|
|
|
|
|
| GET | `/api/customer/check-name?name=&excludeId=` | 名称相似查重(L2,ngram 阈值 70/80/90;D21) | 67015 |
|
|
|
|
|
| GET | `/api/customer/check-credit-code?creditCode=` | 信用代码查重(L3 硬拦预检) | 67003 |
|
|
|
|
|
| GET | `/api/customer/company-lookup?keyword=` | 工商联想(企查查 seam,V1 可空实现) | — |
|
|
|
|
|
|
|
|
|
|
**查重弹窗返回结构**:`CustomerSaveResultDTO{needConfirm=true, similarHits:[{customerId, customerName, ownerName, customerStage, archiveStatus, masked}]}`(未落库);确认后带 `confirmSimilar=true` 重发(create / quick-create 均支持,customer-rework 票 04)。
|
|
|
|
|
|
|
|
|
|
### 2.4 商机弹窗快建 + 商机侧硬依赖(票 03,`/api/customer`)
|
|
|
|
|
|
|
|
|
|
| 方法 | 路径 | 说明 | 主要错误码 |
|
|
|
|
|
|---|---|---|---|
|
|
|
|
|
| POST | `/api/customer/quick-create` | 快建(`CustomerQuickCreateDTO` 最小集 + `confirmSimilar` 透传(customer-rework 票 04);服务端默认 owner=当前用户、is_child=否、isBizNegotiated=否) | 67001/67003 |
|
|
|
|
|
| POST | `/api/customer/search` | 商机侧客户搜索(名称/联系人/电话三维模糊 + 类型精确;DataScope) | — |
|
|
|
|
|
| GET | `/api/customer/{customerId}/contacts` | 商机详情带出联系人(票 11 跨模块 port 消费方) | 67002 |
|
|
|
|
|
|
|
|
|
|
### 2.5 A4-4-1 客户详情:公共头部 + 8 页签(`CustomerDetailController /api/customer`)
|
|
|
|
|
|
|
|
|
|
| 方法 | 路径 | 说明 | 主要错误码 |
|
|
|
|
|
|---|---|---|---|
|
|
|
|
|
| GET | `/{id}/detail-head` | 公共头部聚合(快照+跟进摘要+待跟进提醒+关联业务计数;**汇总卡 5 字段恒 null 显 "--"**:wonProjectAmount/planEstimateAmount/ongoingOpportunityAmount/contractAmount/paidAmount,grill Q18 契约=前端渲染 4 卡不显 0) | 67002 |
|
|
|
|
|
| GET | `/{id}` | 页签 1 客户信息(=编辑页 detail) | 67002 |
|
|
|
|
|
| GET | `/{customerId}/contacts` | 页签 2 联系人 | — |
|
|
|
|
|
| GET | `/{id}/follow/page` | 页签 3 跟进记录(时间倒序+日期分组前端;过滤 follow_way/keyword/时间范围) | 67002 |
|
|
|
|
|
| GET | `/{id}/opportunities` | 页签 4 关联商机(port 反查;失败前端显 "--") | 67002 |
|
|
|
|
|
| — | 页签 5/6 | 关联项目/战略协议:V1 骨架显 "--"(A5/战略协议子域未建) | — |
|
|
|
|
|
| GET | `/{id}/members` | 页签 7 团队成员(负责人+协同人,ROLE_OWNER 在前) | 67002 |
|
|
|
|
|
| GET | `/{id}/oplog/page` | 页签 8 操作日志(§2.6) | 67002 |
|
|
|
|
|
|
|
|
|
|
**写跟进**:`POST /{id}/follow`(`FollowCreateDTO`:followWay/followContent/nextFollowTime;append-only 不可改删;副作用刷新 `last_valid_follow_time` 超期锚点)——67002/67009。
|
|
|
|
|
|
|
|
|
|
### 2.6 A4-4-8 操作日志(append-only,无限期保留 §5.5)
|
|
|
|
|
|
|
|
|
|
`GET /api/customer/{id}/oplog/page`(`OplogPageParam`:startTime/endTime/**action**/keyword 匹配 detail)。
|
|
|
|
|
|
|
|
|
|
**action 值域(11 种)**:`CREATE/UPDATE/FOLLOW/ARCHIVE/RESTORE/TRANSFER/CLAIM/POOL/STAGE_CHANGE/MEMBER_ADD/MEMBER_REMOVE`;detail 叙事形态 `把 {字段} 从 {旧} 修改为 {新}`(D13);阶段变化 operator=系统;导入记 CREATE+UPDATE(§E 值域无 IMPORT)。
|
|
|
|
|
|
|
|
|
|
### 2.7 团队成员管理(票 12 不符②补实现)
|
|
|
|
|
|
|
|
|
|
| 方法 | 路径 | 说明 | 主要错误码 |
|
|
|
|
|
|---|---|---|---|
|
|
|
|
|
| POST | `/{id}/members` | 添加协同人(form `MemberAddDTO{memberUserIds[]}`;两阶段校验整批拒绝;批内幂等去重;姓名快照;oplog MEMBER_ADD) | 67002/67016 |
|
|
|
|
|
| DELETE | `/{id}/members/{memberUserId}` | 移除协同人(软删 delete_key=id 可重复加入;oplog MEMBER_REMOVE) | 67002/67016 |
|
|
|
|
|
|
|
|
|
|
### 2.8 关注 / 重点客户标记(票 12 不符③补实现,`CustomerFocusController /api/customer`)
|
|
|
|
|
|
|
|
|
|
| 方法 | 路径 | 说明 | 主要错误码 |
|
|
|
|
|
|---|---|---|---|
|
|
|
|
|
| POST | `/{id}/focus` | 关注(幂等;行存在性=关注态) | 67002 |
|
|
|
|
|
| POST | `/{id}/unfocus` | 取关(物理删行,连带清重点标记) | — |
|
|
|
|
|
| POST | `/{id}/star` | 标记重点客户(未关注自动建行 starred=1;幂等) | 67002 |
|
|
|
|
|
| POST | `/{id}/unstar` | 取消重点标记(保留行仅置 starred=0;幂等) | — |
|
|
|
|
|
| POST | `/focus-batch?ids=` | 批量关注(逐个幂等;对称商机) | 67002 |
|
|
|
|
|
|
|
|
|
|
一行两态语义:`customer_focus` 行存在=关注,`starred` 列=重点标记;均不写 oplog。
|
|
|
|
|
|
|
|
|
|
### 2.9 归档 / 恢复(`CustomerOwnershipController /api/customer`)
|
|
|
|
|
|
|
|
|
|
`POST /archive?id=`(前置无进行中商机;归档=删除语义 D19)、`POST /archive-batch?ids=`、`POST /restore?id=`——67002/67004/67006。
|
|
|
|
|
|
|
|
|
|
### 2.10 A4-7-1 客户交割(`CustomerTransferController /api/customer/transfer`)
|
|
|
|
|
|
|
|
|
|
| 方法 | 路径 | 说明 | 主要错误码 |
|
|
|
|
|
|---|---|---|---|
|
|
|
|
|
| GET | `/preview` | 待交接客户预览(离职总监名下有效客户) | — |
|
|
|
|
|
| POST | `/initiate` | 发起交接(`TransferInitiateDTO`:reason 三选一 resign/transfer_post/region_adjust 必填;整批原子 @Transactional;owner 联动商机/项目 port;oplog TRANSFER 系统操作含交接编号) | 67010/67011/67012 |
|
|
|
|
|
| GET | `/{id}` | 交接单详情(进度=assignedCount/totalCount) | — |
|
|
|
|
|
| GET | `/page` | 交接单分页 | — |
|
|
|
|
|
| GET | `/{id}/assignable` | 可分配销售列表 | — |
|
|
|
|
|
| POST | `/{id}/assign` | 明细分配(`BatchResult` 行级部分成功) | 67012 |
|
|
|
|
|
|
|
|
|
|
状态:交接单 0 待分配→1 已完成(全分配自动置位 D23);明细 0/1。
|
|
|
|
|
|
|
|
|
|
### 2.11 A4-3-2 客户导入(`CustomerImportController /api/customer/import`)
|
|
|
|
|
|
|
|
|
|
| 方法 | 路径 | 说明 | 主要错误码 |
|
|
|
|
|
|---|---|---|---|
|
|
|
|
|
| POST | `/upload` | 上传预校验(MultipartFile + importMode:APPEND_ONLY/UPDATE_ONLY/UPSERT;DRAFT 落库待确认) | 67013 |
|
|
|
|
|
| GET | `/template` | 下载模板(版本 V1 锚点) | — |
|
|
|
|
|
| POST | `/{taskId}/confirm` | 确认执行(两段式) | 67014 |
|
|
|
|
|
| GET | `/{taskId}` | 结果(行级部分成功:总数/成功/失败) | — |
|
|
|
|
|
| GET | `/{taskId}/failures` | 失败明细 | 67014 |
|
|
|
|
|
| GET | `/page` | 任务分页 | — |
|
|
|
|
|
|
|
|
|
|
状态机:0 DRAFT→1 RUNNING→2 DONE/3 FAILED(重复确认 67014)。
|
|
|
|
|
|
|
|
|
|
### 2.12 A7-3-3 客户规则设置(跨模块:crm-rule)
|
|
|
|
|
|
|
|
|
|
| 方法 | 路径 | 说明 |
|
|
|
|
|
|---|---|---|
|
|
|
|
|
| GET | `/api/rule/customer/reminder` | 超期提醒当前单例配置(总开关/首次 30 天/二次 7 天/独立开关) |
|
|
|
|
|
| POST | `/api/rule/customer/reminder/save` | 保存(表单绑定;customer-rework 票 02 扁平动词化,原 PUT @RequestBody 已废) |
|
|
|
|
|
| GET | `/api/rule/customer/dedup` | 查重设置当前单例配置(总开关/名称开关+匹配方式+阈值/电话开关;customer-rework 票 04 补) |
|
|
|
|
|
| POST | `/api/rule/customer/dedup/save` | 查重设置保存(表单绑定;开关缺省视为关、方式/阈值缺省回出厂模糊/80;信用代码系统强制无配置项;64023) |
|
|
|
|
|
|
|
|
|
|
### 2.13 saved-view / 列偏好(跨模块:crm-preference,票 10)
|
|
|
|
|
|
|
|
|
|
`/api/preference/view` CRUD(scope_key:`customer.overview`/`customer.mine`/`customer.pool`,三 workspace 互斥)+ `/api/preference` 列偏好。过滤器在 workspace/page 生效(saved-view 接入)。
|
|
|
|
|
|
|
|
|
|
### 2.14 健康检查
|
|
|
|
|
|
|
|
|
|
`CustomerPingController /api/customer`:GET ping(联通性,无业务)。
|
|
|
|
|
|
|
|
|
|
## 3. 状态/值域附录
|
|
|
|
|
|
|
|
|
|
- **archive_status**:1 有效 / 2 已归档(无合并态 D19);**customer_stage**:1 潜在 / 2 重潜(D20 seam 不触发)/ 3 已成交(三态只前进,CAS)。
|
|
|
|
|
- **编号**:客户 `KH+yyyyMMdd+4 位`;交割 `JG+yyyyMMdd+4 位`。
|
|
|
|
|
- **viewType**(workspace/mine):ASSIGNED 我负责的 / COLLABORATING 我协同的 / FOCUSED 我关注的(customer_focus EXISTS)等内置视图。
|
|
|
|
|
- **导入模式**:APPEND_ONLY / UPDATE_ONLY / UPSERT;任务状态 0/1/2/3。
|
|
|
|
|
- **通知**(票 09 内部):FOLLOW_OVERDUE;状态 0 待发/1 已发/2 已失效。
|
|
|
|
|
|
|
|
|
|
## 4. 联调速查
|
|
|
|
|
|
|
|
|
|
- knife4j:`http://localhost:8080/doc.html`;token 放 `Authorization: Bearer`。
|
|
|
|
|
- 写端点均为 **form 绑定**(无 @RequestBody),除 crm-rule 提醒配置 PUT 为 JSON。
|
|
|
|
|
- 冒烟脚本范式:`tmp/smoke-t12m.py`(python urllib + pymysql autocommit 查库,坑㉕)。
|
|
|
|
|
|
|
|
|
|
## 5. 已知缺口与范围外(如实记录,避免联调踩坑)
|
|
|
|
|
|
|
|
|
|
1. ~~QuickCreateDTO 无 confirmSimilar 字段~~ **已补齐(customer-rework 票 04)**:`CustomerQuickCreateDTO.confirmSimilar`(默认 false)透传主表 create;命中相似未确认 → needConfirm=true + similarHits(未落库,沿用既有提示口径),确认后带 confirmSimilar=true 重发。
|
|
|
|
|
2. ~~查重设置页(A7-3-3-2)无对外端点~~ **已补齐(customer-rework 票 04)**:crm-rule `customer_dedup_rule` 单例(`CustomerDedupRuleInitializer` 服务端种子化:全开关启用/模糊匹配/标准 80%)+ `GET /api/rule/customer/dedup` + `POST /api/rule/customer/dedup/save`(表单绑定,§2.12);crm-customer `RuleBackedCustomerDedupSettingProvider`(@Primary)读单例驱动新增/编辑内建查重(D4-rev2 消费口径),单例缺失回退出厂值。
|
|
|
|
|
3. **详情页签 5/6**(关联项目/战略协议)恒显 "--";**汇总卡 5 字段恒 null**(进行中商机总额可经 port 扩展后切真值)。
|
|
|
|
|
4. **敏感信息三档脱敏 + 查看日志**、**合并客户**、**客户导出**:定稿划出(范围外)。
|
|
|
|
|
5. 联系人子表导入:原型 9.2-9 提及,按 REVIEW-HANDOFF 划出 V1。
|