You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

49 lines
3.3 KiB

3 weeks ago
# crm-lead 批量操作接口(claim/assign/release/activate/delete-batch)
Type: task
Status: resolved
Depends on: 10
ADR: docs/adr/0023-lead-batch-operations-and-view-stats.md (D1/D2)
## Question(实现目标)
为线索补齐 6 个批量流转接口,非原子、逐条 CAS、部分成功,返回结构化失败明细。
## 交付物
### 领域件(crm-lead)
- `domain/enums/LeadBatchFailReason.java`:语义枚举,各值带 `code`(回指 ResultCode 65xxx)+ `fromCode(int)` 查找 + `UNKNOWN` 兜底。
- `ALREADY_CONVERTED`(65009)、`CONCURRENT_MODIFIED`(65010)、`STATUS_NOT_ALLOWED`(65003)、`NOT_OWNER`(65004)、`OVER_HOLD_LIMIT`(65007)、`OVER_DAILY_LIMIT`(65006)、`UNKNOWN`。
- `domain/dto/LeadBatchFailItem.java`:`Long id` + `LeadBatchFailReason reason` + `String message`,`of(id, reason, message)` 工厂。
### service(crm-lead)
- `ILeadService` 增 6 方法,均返回 `BatchResult<LeadBatchFailItem>`
`claimBatch(ids)` / `assignToPoolBatch(ids, poolId)` / `assignToUserBatch(ids, userId)` / `releaseBatch(ids)` / `activateBatch(ids)` / `deleteBatch(ids)`
- `LeadServiceImpl`
- `@Lazy @Autowired private ILeadService self;`(沿用 `AuthServiceImpl.self` 模式)。
- 私有 `runBatch(List<Long> ids, Consumer<Long> op)`:逐条 `op.accept(id)``self.xxx(id)` 单条方法(各自独立事务);捕 `BusinessErrorException``LeadBatchFailReason.fromCode(e.getCode())`;捕其他 `Exception``UNKNOWN``log.error`
- **批量方法本身不加 `@Transactional`**(保证一条失败不污染已成功条)。
### controller(crm-lead)
- `LeadController` 增 6 个 `@PostMapping`:`/claim-batch`、`/assign-pool-batch`、`/assign-user-batch`、`/release-batch`、`/activate-batch`、`/delete-batch`。
- 入参 `@RequestParam("ids") List<Long> ids`(+ assign 的 `poolId`/`userId`)。
- 返回 `Result<BatchResult<LeadBatchFailItem>>`
## 验收
- 编译:`mvn -q -pl crm-lead -am compile`。无 BOM。
- 单测覆盖 `runBatch`:全成功 / 部分失败(构造单条抛 65003、65010 等)/ 空 ids → 计数与 failures 正确;失败不回滚已成功条(self-proxy 独立事务)。
- 不引入新的上限校验逻辑(`OVER_HOLD_LIMIT`/`OVER_DAILY_LIMIT` 仅预留映射,当前单条未实现该校验,属既有 gap)。
## Comments
## Answer
已交付(ADR-0023 D1/D2):
- `domain/enums/LeadBatchFailReason.java`:7 个业务原因 + `UNKNOWN`,各带 `code` 回指 `LeadConstants` 65xxx(含 65005 CLAIM_RULE_DENIED),`fromCode(Integer)` 未命中返 UNKNOWN。
- `domain/dto/LeadBatchFailItem.java`:id + reason + message + `of(...)`
- `ILeadService` 增 6 方法;`LeadServiceImpl` `@Lazy @Autowired ILeadService self` + `runBatch(ids, Consumer<Long>)`(不加 `@Transactional`,逐条 self 代理调单条、捕 BusinessErrorException 映射 reason、其他异常 UNKNOWN+log.error)。
- `LeadController` 增 6 个 `-batch` 端点(claim/assign-pool/assign-user/release/activate/delete),`@RequestParam("ids") List<Long>`,返 `Result<BatchResult<LeadBatchFailItem>>`
验收:无 BOM;`mvn -pl crm-lead -am compile` BUILD SUCCESS;`LeadBatchServiceTest` 5/5(全成功/部分失败映射/UNKNOWN 兜底/空 ids/assign-user 逐条委派)+ `LeadServiceImplTest` 44/44 无回归。