Commit db54e696 authored by fangxinjiang's avatar fangxinjiang

V24梳理记录-fxj -合并代码前只保留本地

parent 7f3589aa
# EKP 模块 — 提前缴费 / 见费出单相关逻辑梳理
> 对应需求:[HRO-EKP提前缴费商险数据兼容需求.md](./HRO-EKP提前缴费商险数据兼容需求.md)
> HRO 侧既有逻辑见:[HRO-见费出单既有逻辑梳理.md](./HRO-见费出单既有逻辑梳理.md)
> **状态:待梳理**(本文仅建立章节结构,后续按模块补充 EKP 既有实现)
---
## 梳理范围
以下五块为 EKP 侧与 HRO 提前缴费(见费出单)联动的主要触点,与需求文档第三节、第四节对应:
| 序号 | 模块 | 需求关联 | 状态 |
| --- | --- | --- | --- |
| 1 | 收款结算单 | 3.2 收款结算;结算金额为 0 同步 HRO 待投保 | 待梳理 |
| 2 | 商险支出 | 3.1 商险支出(历史+新数据共用) | 待梳理 |
| 3 | 退单 | 收款结算单退回 | 待梳理 |
| 4 | 撤销匹配 | 4. 撤销匹配逻辑;HRO `callBackInsuranceBuyHandleStatus` | 待梳理 |
| 5 | 垫付 | 触发 HRO 待缴费→待投保(与「已收」同等) | 待梳理 |
---
## 1. 收款结算单
> **待梳理**
### 需求要点(来自需求文档)
- 拉取 **未结算** 的提前缴费数据进行结算(需梳理 EKP 既有拉取逻辑)
- **非 BPO**:正常收款结算
- **BPO**:成本归集模式
- **特殊规则**:结算金额为 **0** 时,结算完成后 **直接同步 HRO 为待投保**
### 待确认项
- [ ] 提前缴费/见费出单明细的拉取条件与 SQL/接口
- [ ] BPO / 非 BPO 分支实现位置
- [ ] 结算金额为 0 时回调 HRO 的入口与时序
- [ ] 与 HRO 预估/实缴/差额明细的匹配规则
### 已知 HRO 侧对接
- 结算状态回写:`DoJointInsuranceTask.updateInsurancesSettleStatus`
- 手动拉取:`TInsuranceDetailServiceImpl.pullPaymentStatus``EkpSettleService.getSettleStatusFromEkpAssoByIds`
---
## 2. 商险支出
> **待梳理**
### 需求要点
- **历史数据 + 新数据** 均适用
- 允许对 **未支出** 的提前缴费实缴数据进行正常商险支出
### 待确认项
- [ ] 实缴明细可选条件(提前缴费标识判断)
- [ ] 支出单审核与 HRO 支出状态同步
- [ ] 已支出时 HRO/EKP 退单阻断逻辑
### 已知 HRO 侧对接
- 退保前校验:`ekpSettleService.getSettleStatusFromEkpInsuranceDetail``payStatus` 已结算/结算中则禁止退回
---
## 3. 退单
> **待梳理**
### 需求要点(来自需求文档 4.1 / 4.2)
**存在提前缴费预估数据:**
- 检查 HRO 投保状态,仅 **待投保** 允许退回/撤销
- 其他状态提示联系投保专员
**不存在预估数据:**
- 检查实缴/差额是否 **已支出**,已支出则禁止
**非提前缴费:** 检查实缴是否已支出
### 待确认项
- [ ] 退单触发 HRO 状态回退的接口(见费出单:待投保 → 待缴费)
- [ ] 退单与结算单、商险明细的联动删除/红冲规则
### 已知 HRO 侧对接
- `callBackInsuranceBuyHandleStatus` / `callBackInsuranceBuyHandleStatusSub`
---
## 4. 撤销匹配
> **待梳理**
### 需求要点
- 与退单类似的匹配校验(是否存在预估、投保状态、是否已支出)
- 见费出单待投保时撤销 → HRO 回退 **待缴费**
### 待确认项
- [ ] 撤销匹配与退单的业务差异
- [ ] 回调 HRO 的参数(`EkpStatusParamVo.detailIds``settleNo` 等)
### 已知 HRO 侧对接
- 同 §3:`callBackInsuranceBuyHandleStatusSub`
---
## 5. 垫付
> **待梳理**
### 需求要点
- 垫付与「已收」对 HRO 等价:待缴费 → **待投保**
- 手动拉取与 EKP 回调均识别 `paymentStatus=垫付`
### 待确认项
- [ ] 垫付在 EKP 商险明细上的状态字段
- [ ] 垫付与正常收款的结算单差异
- [ ] 垫付后撤销/退单是否走同一套匹配逻辑
### 已知 HRO 侧对接
- `pullPaymentStatus``"已收".equals(vo.getPaymentStatus()) || "垫付".equals(vo.getPaymentStatus())`
- `DoJointInsuranceTask.updateInsurancesSettleStatus``paymentStatsus=0` 时同步待投保
---
## 附录:EKP 商险明细关键字段(HRO 推送侧)
| 字段 | 含义 | 见费出单典型值 |
| --- | --- | --- |
| fd_jfcd | 是否见费出单 | 是 |
| fd_3b13b2ecc164aa | 是否全部结算 | 是 |
| fd_3af9d11088facc | 实际结算月份 | 空 |
| fd_3af9d1441ef7b6 | 有无预估 | 有 |
| fd_3adfe6e30f2a3c | 应收 | 预估/差额场景见 HRO 文档 |
| fd_3adfe6e3911ffe | 应支 | 实缴场景见 HRO 文档 |
---
## 修订记录
| 日期 | 说明 |
| --- | --- |
| 2026-06-05 | 初稿:建立 EKP 五模块章节结构,标注待梳理 |
# HRO 与 EKP 系统 — 提前缴费商险数据兼容需求
> 需求原型梳理文档
> 涉及系统:HRO 系统、EKP 系统
> 业务场景:商业保险「提前缴费」数据的新旧兼容与收付结算
---
## 一、HRO 系统 — 提前缴费通用规则
### 1.1 标识规则
- 「提前缴费」数据需做明确标识,便于后续流程与 EKP 侧联动处理。
- **新增字段**:标识该条提前缴费数据为 **历史数据** 还是 **新数据**
- **历史数据**:走既有逻辑(兼容原提前缴费流程,含预估/差额等处理方式,见第二节兼容逻辑表中「是」的分支)。
- **新数据**:走新逻辑(本需求定义的规则,见 1.2、1.3 及第二节兼容逻辑表中「否」的分支)。
| 字段标识值 | 含义 | 处理路径 |
| --- | --- | --- |
| 历史数据 | 上线前已存在的提前缴费数据,或按旧规则产生的数据 | 既有逻辑 |
| 新数据 | 本需求上线后新产生的提前缴费数据 | 新逻辑 |
### 1.2 状态流转(**新数据**)
> 以下状态流转仅适用于标识为 **新数据** 的提前缴费记录;**历史数据** 仍按既有逻辑处理。
- 提前缴费订单在 **待缴费** 状态下,**跳过「派单」环节**,直接进入 **待投保(投保专员处)** 处理。
### 1.3 投保后数据处理规则(**新数据**)
> 以下规则仅适用于标识为 **新数据** 的提前缴费记录;**历史数据** 仍按既有逻辑处理。
| 规则项 | 说明 |
| --- | --- |
| 预估数据 | **不生成** 预估数据 |
| 导入实缴数据后 — BPO 项目 | 实际应收 = **0**;实际应付 = **实缴金额** |
| 导入实缴数据后 — 非 BPO 项目 | 实际应收 = **实缴金额**;实际应付 = **实缴金额** |
| 差额数据 | **不生成** 差额数据 |
---
## 二、HRO 与 EKP 系统 — 新旧数据兼容逻辑表
> 根据「是否历史提前缴费」「投保状态」「是否存在预估数据」及「下一步操作」,决定具体处理逻辑。
| 是否历史提前缴费 | 投保状态 | 是否有预估数据 | 下一步操作 | 处理逻辑 / 思路 |
| --- | --- | --- | --- | --- |
| 是 | 待缴费 | 是 | 收付 | 正常匹配预估数据进行收付 |
| 是 | 待缴费 | 是 | 撤销 | 未匹配/未结算时可撤销 |
| 是/否 | 待投保 | 是 | 导出 | — |
| 是 | 待投保 | 是 | 退保 | 生成负数预估数据 |
| 否 | 待投保 | 否 | 退保 | 不生成负数预估数据 |
| 是 | 投保中 | 是 | 投保成功 | — |
| 是 | 投保中 | 是 | 退保 | 生成负数预估数据 |
| 否 | 投保中 | 否 | 退保 | 不生成负数预估数据 |
| 是 | 已投保,无实缴 | 是 | 导入实缴 | 生成实缴数据,再生成差额数据(BPO:应收=0,应付=实缴;非 BPO:应收=应付=实缴) |
| 否 | 已投保,无实缴 | 否 | 导入实缴 | 不生成差额数据;推送实缴至 EKP(BPO:应收=0,应付=实缴;非 BPO:应收=应付=实缴) |
| 是 | 已投保,无实缴 | 是 | 退保 | 生成负数预估数据 |
| 否 | 已投保,无实缴 | 否 | 退保 | 不生成负数预估数据 |
| 是 | 已导入实缴 | 是 | 商险支出 | 未支出时可商险支出;展示成本扣减明细 |
| 否 | 已导入实缴 | 否 | 商险支出 | 查找结算账期,找不到则取当前账期;未支出时可离险支出;展示成本扣减明细 |
| 是 | 已导入实缴 | 是 | 退保 | 检查结算状态:未结算则删除实缴数据;已结算则生成负数差额数据 |
| 否 | 已导入实缴 | 否 | 退保 | 检查结算状态:未结算则删除实缴数据 |
---
## 三、EKP 系统规则
### 3.1 商险支出(**历史数据 + 新数据**)
> 以下规则对 **历史数据** 与 **新数据** 均适用,不区分新旧。
- 允许对 **未支出** 的提前缴费实缴数据进行正常商险支出。
### 3.2 收款结算
- 收款结算时,需正确拉取 **未结算** 的提前缴费数据进行结算(需要梳理 EKP 的既有拉取提前缴费的逻辑):
- **非 BPO 项目**:正常收款结算
- **BPO 项目**:成本归集模式
**特殊规则(结算金额为 0):**
- EKP 收款结算单 **结算金额为 0** 时(典型场景:BPO 项目应收为 0),结算完成后 **直接同步 HRO 侧数据状态为「待投保」**,无需再走派单等环节。
- 与 1.2 新数据状态流转衔接:新数据待缴费跳过派单;BPO 等结算金额为 0 的场景,由 EKP 结算触发同步至待投保。
---
## 四、收款结算单退回 / 撤销匹配逻辑
### 4.1 判断是否存在提前缴费预估数据
**若存在预估数据:**
- 检查 HRO 投保状态
-**待投保** 状态允许退回/撤销
- 其他状态提示用户联系投保专员处理
**若不存在预估数据:**
- 检查是否存在提前缴费实缴数据或差额数据
- 若实缴/差额数据 **已支出**,则 **禁止** 退回/撤销
### 4.2 非提前缴费数据
- 检查实缴数据是否已支出
- 若已支出,则 **禁止** 退回/撤销
---
## 五、实现要点摘要
1. **新旧数据分流**:通过新增字段区分历史/新数据,历史走既有逻辑,新数据走新逻辑。
2. **状态机驱动**:按「是否历史提前缴费 × 投保状态 × 是否有预估数据 × 操作类型」分支处理。
3. **数据生成差异**
- 新提前缴费:不生成预估、不生成差额
- 历史提前缴费:保留预估/差额兼容逻辑,退保时按需生成负数预估或负数差额
4. **BPO / 非 BPO 区分**:实缴数据的应收、应付赋值规则不同,EKP 侧结算模式也不同。
5. **结算金额为 0 的特殊同步**:EKP 收款结算单结算金额为 0 时,结算后直接同步 HRO 数据为 **待投保**
6. **退回/撤销约束**:已支出或投保状态不满足条件时,阻断退回/撤销并给出明确提示。
---
## 附录:关键术语
| 术语 | 说明 |
| --- | --- |
| 提前缴费 | 商险业务中在常规流程前预先缴费的数据类型 |
| 历史数据 / 新数据 | 通过新增字段标识;历史数据走既有逻辑,新数据走本需求新逻辑 |
| 预估数据 | 投保前/投保过程中产生的预估收付数据 |
| 实缴数据 | 实际缴纳/import 后的真实收付数据 |
| 差额数据 | 预估与实缴之间的差异数据 |
| 商险支出 | 员工商险费用支出处理 |
| HRO | 人力资源外包业务模块 |
| MVP | HRO 模块的别称,与 HRO 同义 |
| 收款结算 | EKP 侧对客户/项目的收款结算流程 |
| BPO 项目 | 业务流程外包类项目,应收为 0,走成本归集 |
| 非 BPO 项目 | 常规项目,应收应付均为实缴金额 |
# HRO 侧 — 提前缴费商险数据兼容开发方案
> 对应需求:[HRO-EKP提前缴费商险数据兼容需求.md](./HRO-EKP提前缴费商险数据兼容需求.md)
> 既有逻辑参考:[HRO-见费出单既有逻辑梳理.md](./HRO-见费出单既有逻辑梳理.md)
> 涉及模块:`yifu-insurances`
> 原则:**历史见费出单逻辑原样保留**;新逻辑**独立分支 + 明确注释**;通过新增字段分流,避免改动历史路径引发回归测试。
---
## 一、方案目标与核心策略
### 1.1 业务目标
| 维度 | 历史数据(既有见费出单) | 新数据(本需求) |
| --- | --- | --- |
| 标识 | `isJfcd=0` + `isHistoryAdvancePay=1`(历史) | `isJfcd=0` + `isHistoryAdvancePay=0`(新) |
| 派单后状态 | 待缴费(6) → EKP 收款 → 待投保(1) | **直接待投保(1)**,跳过待缴费收款环节 |
| 预估 | 派单时生成并推送 EKP | **不生成** |
| 实缴 | 登记保单保费后推送 | 登记保单保费后推送(应收/应付规则见下) |
| 差额 | 实缴 ≠ 预估时生成 | **不生成** |
| 收入/管理费/风险金 | 派单时 `createInsuranceInfo` | **延至实缴登记**时生成(见 §4.1、§4.4) |
| 退保 | 红冲预估 + 删 EKP 实缴/差额 | **不生成**负数预估/差额;实缴按结算/支出状态分支(见 §4.5) |
| 删除投保 | **不可删** | **不可删**(与历史一致,见 §4.8) |
### 1.2 技术策略(保历史、少回归)
```
isJfcd=0 ?
/ \
否 是
| |
普通派单流程 isHistoryAdvancePay ?
/ \
是(1)/null 否(0)
| |
【既有逻辑,代码块不动】 【新分支方法,加注释】
```
1. **新增字段**「是否历史提前缴费」区分历史/新,HRO 派单明细与 EKP 推送**同名同义**(见 §2.1)。
2. **分流入口**统一用 `AdvancePaymentHelper.isLegacyJfcdData(detail)`,历史分支**整体迁入私有方法或保持原 if 块不动**,新逻辑进 `*NewAdvancePay*` 方法。
3. **禁止**在历史分支内做「顺手重构」;新分支单独注释块:`// ===== 新提前缴费逻辑(isHistoryAdvancePay=0)=====`.
4. 历史路径的单元/集成测试用例**无需重跑**;测试聚焦新标识 + 边界(BPO/非 BPO、退保、EKP 回调)。
---
## 二、数据模型设计
### 2.1 统一字段:是否历史提前缴费
> **命名原则**:HRO 商险派单明细、推送 EKP 的**预估明细(派单)**与**实缴明细(登记保单保费)**使用**同一业务含义、同一套取值规则**;各层字段名语义一致,仅按各端命名规范转换大小写/前缀。
| 层级 | 字段标识 | 类型 | 取值 | 含义 |
| --- | --- | --- | --- | --- |
| **HRO 表** `t_insurance_detail` | `is_history_advance_pay` | `char(1)` | `1` | **是**,历史提前缴费(走既有见费出单逻辑) |
| | | | `0` | **否**,新提前缴费(走本需求新逻辑) |
| | | | `NULL` | 非提前缴费(`isJfcd=1`)或不适用;若 `isJfcd=0`**视同 `1`(历史)** |
| **Java** Entity / VO / Param | `isHistoryAdvancePay` | String | 同上 | 与库表一一对应 |
| **EKP 表** `ekp_insurances_info` | `fd_is_history_advance_pay` | 文本 | `是` | 历史提前缴费 |
| | | | `否` | 新提前缴费 |
| **推送参数** `EkpInsurancesInfo` / `EkpInteractiveParam` | `isHistoryAdvancePay` → 写入 `fd_is_history_advance_pay` | — | HRO `1`→EKP `是`,HRO `0`→EKP `否` | 转换在 `DoJointInsuranceTask.initValues` 统一封装 |
> EKP 表单侧 `fd_is_history_advance_pay` 的表单字段 ID 需与 EKP 联调确认;**业务名称统一为「是否历史提前缴费」**,与 HRO 字段含义一致。
**写入范围(`fd_jfcd=是` 时必写)**
| 场景 | HRO 写入 | 推送 EKP |
| --- | --- | --- |
| 历史见费出单 — 派单推**预估** | `is_history_advance_pay=1` | `fd_is_history_advance_pay=是` |
| 新提前缴费 — 派单 | `is_history_advance_pay=0` | 无预估推送;明细落库仍为 `0` |
| 历史见费出单 — 登记**实缴** | 读明细 `1` | `fd_is_history_advance_pay=是` |
| 新提前缴费 — 登记**实缴** | 读明细 `0` | `fd_is_history_advance_pay=否` |
| 新提前缴费 — 退保负数**实缴** | 读明细 `0` | `fd_is_history_advance_pay=否` |
| 历史 — 差额 / 红冲 | 读明细 `1` | `fd_is_history_advance_pay=是` |
**同步改造**
- HRO:`TInsuranceDetail`、VO/DTO、Mapper XML、列表/详情出参
- EKP 推送:`DoJointInsuranceTask.initValues``insertInsrancesDetail``EkpInsurancesInfo``EkpInteractiveParam`
- 常量:`InsurancesConstants.IS_HISTORY_ADVANCE_PAY_YES/NO`;EKP 文案 `EKP_IS_HISTORY_ADVANCE_PAY_YES=是` / `NO=否`
**转换工具方法(建议)**
```java
/** HRO → EKP:1→是,0→否 */
String toEkpIsHistoryAdvancePay(String isHistoryAdvancePay);
/** EKP → HRO:是→1,否→0(若 EKP 回调需读) */
String fromEkpIsHistoryAdvancePay(String fdValue);
```
### 2.2 初始化规则
| 场景 | `isJfcd` | `is_history_advance_pay` |
| --- | --- | --- |
| 上线前存量 `isJfcd=0` | 0 | **`1`(是,历史)**(数据脚本) |
| **发布时间之后**新增/批增满足见费出单条件 | 0 | **`0`(否,新)** |
| 非见费出单 | 1 | NULL |
| 替换 | — | 不参与(现有逻辑不变) |
**见费出单触发条件(不变)**:险种「是否见费出单」= 是,且项目 **`bpoEnable=否`(未启用 BPO 结算模式)**
**已确认**:启用 BPO 结算模式的项目**仍不走**见费出单/提前缴费,与现有 `initJfcd` / `initJfcdBatch` 逻辑一致,无需调整。
**改造点**`initJfcd` / `initJfcdBatch` 在满足见费出单条件时:`isJfcd=0`,并按发布时间写 `isHistoryAdvancePay``1``0`)。
### 2.3 上线切点(已确认)
**以发布时间控制** `is_history_advance_pay=0`(新数据)的写入,不使用配置开关。
| 实现方式 | 说明 |
| --- | --- |
| 配置项 | `advance-pay.new-data-launch-time`(如 `2026-07-01 00:00:00`) |
| 写入规则 | 满足见费出单 **且** `当前时间 >= launchTime``isHistoryAdvancePay=0`;否则 → `isHistoryAdvancePay=1` |
| 存量数据 | 上线前执行 §2.4 DDL + §2.5 迁移脚本 |
### 2.4 DDL 脚本(上线前执行)
> HRO 库:`mvp_insurances`;EKP 库:`ekp`(与 `application-*.yml` 双数据源一致)。以下为 **MySQL** 语法。
#### 2.4.1 HRO — `t_insurance_detail` 新增字段
```sql
-- 库:mvp_insurances
ALTER TABLE t_insurance_detail
ADD COLUMN is_history_advance_pay CHAR(1) NULL DEFAULT NULL
COMMENT '是否历史提前缴费:1=是(历史见费出单) 0=否(新提前缴费),仅 is_jfcd=0 时有效'
AFTER is_jfcd;
```
| 列名 | 类型 | 说明 |
| --- | --- | --- |
| `is_history_advance_pay` | `CHAR(1)` | `1` 历史 / `0` 新 / `NULL` 非提前缴费 |
#### 2.4.2 EKP — `ekp_insurances_info` 新增字段
```sql
-- 库:ekp
ALTER TABLE ekp_insurances_info
ADD COLUMN fd_is_history_advance_pay VARCHAR(10) NULL DEFAULT NULL
COMMENT '是否历史提前缴费:是=历史 否=新,与 HRO is_history_advance_pay 对应,fd_jfcd=是 时写入'
AFTER fd_jfcd;
```
| 列名 | 类型 | 说明 |
| --- | --- | --- |
| `fd_is_history_advance_pay` | `VARCHAR(10)` | `是` 历史 / `否` 新;与 HRO `1`/`0` 通过推送逻辑转换 |
> **说明**:若 EKP 侧除 `ekp_insurances_info` 外还有商险明细视图/同步表,需 EKP 侧一并加列;HRO 推送写入以 `ekp_insurances_info.fd_is_history_advance_pay` 为准。表单字段 ID 联调后与物理列名保持一致。
### 2.5 存量数据迁移脚本(DDL 之后执行)
#### 2.5.1 HRO — 历史见费出单刷为「是」
```sql
-- 库:mvp_insurances
UPDATE t_insurance_detail
SET is_history_advance_pay = '1'
WHERE is_jfcd = '0'
AND (is_history_advance_pay IS NULL OR is_history_advance_pay = '');
```
#### 2.5.2 EKP — 既有提前缴费明细刷为「是」
```sql
-- 库:ekp
-- 上线前已存在的见费出单明细(预估/实缴/差额)均视为历史数据
UPDATE ekp_insurances_info
SET fd_is_history_advance_pay = '是'
WHERE fd_jfcd = '是'
AND (fd_is_history_advance_pay IS NULL OR fd_is_history_advance_pay = '');
```
**执行顺序**`§2.4.1``§2.4.2``§2.5.1``§2.5.2` → 应用发版(含 `advance-pay.new-data-launch-time` 配置)。
---
## 三、分流工具类(建议新增)
**类**`AdvancePaymentHelper`(或放在 `InsurancesConstants` 旁的工具包)
```java
/** 是否为见费出单(提前缴费) */
boolean isJfcd(TInsuranceDetail detail);
/** 是否为历史提前缴费 — 走既有逻辑,改动需回归全量见费出单 */
boolean isLegacyJfcdData(TInsuranceDetail detail);
// isJfcd=0 && (isHistoryAdvancePay==null || isHistoryAdvancePay=="1")
/** 是否为新提前缴费 — 走本需求新逻辑 */
boolean isNewJfcdData(TInsuranceDetail detail);
// isJfcd=0 && isHistoryAdvancePay=="0"
```
所有涉及见费出单的分支,**先判 `isJfcd`,再判 `isLegacyJfcdData` / `isNewJfcdData`**,避免误伤非见费出单。
---
## 四、按流程节点的改造清单
### 4.1 派单 / 新增 / 批增
**涉及方法**
- `TInsuranceDetailServiceImpl.addInsurance` / `batchInsurance`
- `initJfcdInfo`
- `updateEmployeeInsurancePre` / `updateEmployeeInsurancePreRenew`
- `createInsuranceInfo`
- `DoJointInsuranceTask.pushEstime`
#### 历史分支(`isLegacyJfcdData`)— **保持现有代码不变**
现有行为(见 [HRO-见费出单既有逻辑梳理.md](./HRO-见费出单既有逻辑梳理.md) 第四章):
1. `initJfcdInfo` → 待缴费(6)、写预估 settle、`defaultSettleId``is_history_advance_pay=1`
2. `pushList``createInsuranceInfo` + `pushEstime`(EKP 预估带 `fd_is_history_advance_pay=是`
3. 待办 `processStatus`**7(待缴费)**
**实施方式**:将 `initJfcdInfo``isJfcd=0`**原样提取**`initLegacyJfcdInfo(...)`,调用处不变;或在 `initJfcdInfo` 顶部:
```java
if (AdvancePaymentHelper.isLegacyJfcdData(detail)) {
// ===== 历史见费出单逻辑(v1.7.x 既有,勿改)=====
... 现有逻辑 ...
return;
}
// ===== 新提前缴费逻辑(isHistoryAdvancePay=0)=====
initNewAdvancePayInfo(...);
```
#### 新分支(`isNewJfcdData`)— **新方法 `initNewAdvancePayInfo`**
| 步骤 | 行为 |
| --- | --- |
| 计费/日期 | **可复用**现有 `preHandleTime`、购买周期、预估保费计算公式(供展示/后续实缴参考),但**不写预估 settle** |
| 投保状态 | **保持待投保(1)**`addInsurance` 已设 1,`initJfcdInfo` 不再改为 6) |
| 缴费状态 | `paymentStatus` 可不设或设已缴费语义外的默认值;**不设待缴费流转** |
| settle | **不创建** `TInsuranceSettle` 预估记录,**不设** `defaultSettleId` |
| 收入/管理费/风险金 | **派单时不调用** `createInsuranceInfo`**延至** `registeredPolicyPremium` 登记实缴时按项目配置生成并推送 EKP(与实缴金额挂钩) |
| EKP 预估 | **不调用** `pushEstime` |
| 待办 | `processStatus`**3(待投保)**,与非见费出单一致 |
| 是否历史 | 落库 `is_history_advance_pay=0`;登记实缴推 EKP 时 `fd_is_history_advance_pay=否` |
`addInsurance` / `batchInsurance` 中现有逻辑:
```java
if (CommonConstants.ZERO_STRING.equals(detail.getIsJfcd())) {
pushList.add(detail);
updateEmployeeInsurancePre(..., SEVEN_STRING); // 待缴费
}
```
改为:
```java
if (AdvancePaymentHelper.isLegacyJfcdData(detail)) {
// 历史:原逻辑不变
} else if (AdvancePaymentHelper.isNewJfcdData(detail)) {
updateEmployeeInsurancePre(..., THREE_STRING); // 直接待投保
}
```
---
### 4.2 缴费完成 → 待投保(EKP 回调 / 手动拉取)
**涉及方法**
- `DoJointInsuranceTask.updateInsuranceSettleStatus`
- `TInsuranceDetailServiceImpl.pullPaymentStatus`
> **新数据结论(已确认)**:新提前缴费派单后**直接进入待投保(1)**,业务流程中**不会出现待缴费(6)**,因此 EKP 回调与手动拉取**均无需对新数据做任何状态更新**。
#### 历史分支(`isLegacyJfcdData`)— **不变**
条件:`isJfcd=0` + 待缴费(6) + EKP 已收/垫付 → 待投保(1)(现有实现)。
#### 新分支(`isNewJfcdData`)— **直接跳过,不做更新**
| 入口 | 处理 |
| --- | --- |
| `updateInsuranceSettleStatus`(EKP 收款已收/垫付回调) | 方法入口判断 `isNewJfcdData`**直接 return**,不更新 `buyHandleStatus` / `paymentStatus` / 待办 |
| `pullPaymentStatus`(手动拉取缴费状态) | 查询条件增加 `isLegacyJfcdData` 过滤,新数据**不出现在待拉取列表**;若按 ID 传入新数据明细,**跳过不处理** |
**说明**:需求文档 EKP 侧「结算金额为 0 时同步 HRO 待投保」针对的是**历史数据**经 EKP 收款结算后由待缴费转待投保的场景;新数据不经待缴费,HRO **无需实现**该同步逻辑。
---
### 4.3 待投保 → 投保中 → 已投保
**涉及方法**`getInsuranceExportOneList``successfulInsurance`
#### 历史 / 新数据 — **导出办理、投保成功主流程相同**
- 导出:待投保(1) → 投保中(2)
- 投保成功:→ 已投保(3)
#### 差异点(`successfulInsurance`)
| | 历史 | 新 |
| --- | --- | --- |
| 跳过重复推预估 | 已有(`successThree` + `isJfcd=0`) | 天然无预估,**保持跳过**即可 |
| 注释 | 标明「历史见费出单:派单已推预估」 | 「新提前缴费:无预估,实缴在登记保单保费处理」 |
---
### 4.4 登记保单保费(实缴 / 差额)— **重点改造**
**涉及方法**
- `registeredPolicyPremiumCheck`
- `registeredPolicyPremium`(差额生成块)
#### 历史分支 — **不变**
- 实缴推送逻辑保持
- `isJfcd=0` 且实缴 ≠ 预估 → 生成差额 settle + 推 EKP
#### 新分支 — **`registerNewAdvancePayActualPremium`**
| 规则 | 实现要点 |
| --- | --- |
| 不生成差额 | **跳过**差额生成逻辑 |
| 实缴推送 EKP | 新建实缴 settle(`settleType` 同明细),推 type=2/4 |
| BPO 项目 | EKP 应收=**0**,应支=**实缴金额** |
| 非 BPO | 应收=应付=**实缴金额** |
| **有无预估** | **固定为「否」**`fd_3af9d1441ef7b6=否`) |
| **是否历史提前缴费** | **固定「否」**`fd_is_history_advance_pay=否`,与 HRO `is_history_advance_pay=0` 一致) |
| 收入/管理费/风险金 | 登记实缴时调用 `createInsuranceInfo`(或等价逻辑),金额基于**实缴保费** |
| 校验 | `registeredPolicyPremiumCheck` 中「EKP 预估结算中/已结算」校验对无 `defaultSettleId` 的新数据**放宽或跳过** |
**EKP 推送改造点**`DoJointInsuranceTask.insertInsrancesDetail` / `initValues`
- 历史:`fd_jfcd=是``fd_is_history_advance_pay=是`,预估/实缴/差额 `有无预估=有`(既有规则)
- 新:`fd_jfcd=是`**`fd_is_history_advance_pay=否`**,实缴 **`有无预估=否`**;应收/应支按 BPO/非 BPO 规则
**`initValues` 改造示例**`fd_jfcd=是` 时写入是否历史,与 HRO 明细一致):
```java
pushParam.setFd_jfcd("是");
pushParam.setFd_is_history_advance_pay(
AdvancePaymentHelper.toEkpIsHistoryAdvancePay(param.getIsHistoryAdvancePay())); // 1→是,0→否
if (AdvancePaymentHelper.isNewJfcdData(param)) {
pushParam.setFd_3af9d1441ef7b6("否"); // 新提前缴费实缴:有无预估=否
} else {
pushParam.setFd_3af9d1441ef7b6("有"); // 历史见费出单:既有逻辑
}
```
---
### 4.5 投保退回 / 退保
**涉及方法**`rollBackInsurance`(约 2108 行见费出单块)
#### 历史分支(`isLegacyJfcdData`)— **不变**
见费出单统一:红冲预估 + `deleteEkpInsuranceDetailAsso`(物理删除 EKP 实缴/差额)。
**前置拦截(历史专用)**:查 EKP 实缴 `payStatus`**已结算****结算中** 时禁止退回(现有实现)。
#### 新分支(`isNewJfcdData`)— **`rollBackNewAdvancePayInsurance`**
> **已确认规则**:新数据**无预估**,退保时不生成负数预估/差额;实缴处理与历史逻辑**不同**,需独立前置校验与 EKP 推送分支。
**前置拦截(新数据专用)— 结算与支出分开判断**
查询接口:`GET /insuranceDetail/getPaymentSettleStatusFromEkp`,返回 `EkpSettleStatusVo`
| 字段 | 含义 |
| --- | --- |
| `settleStatus` | 实缴**结算**状态:未结算 / 结算中 / 已结算 / 无需结算 |
| `payStatus` | 实缴**支出**状态:未支出 / 支出中 / 已支出 等(以实现时 EKP 回传值为准) |
| 条件 | 是否允许退回 |
| --- | --- |
| `payStatus` = **支出中****已支出** | **禁止**,前端提示(可复用 `REDUCE_ROLLBACK_PAY_IS_NOT_ALLOW`) |
| 其他(含 `settleStatus`=结算中/已结算 且 **未支出**) | **允许** |
> **与历史的差异**:历史见费出单沿用现有 `payStatus=已结算/结算中` 即拦截的逻辑(**历史分支不动**);**新数据**仅在**支出中/已支出**时拦截,**结算中/已结算但未支出**仍允许退回。
**前端**:退回前可调 `GET /insuranceDetail/getPaymentSettleStatusFromEkp?id=xxx``payStatus`,支出中/已支出时禁用退回并展示提示。
**按投保状态 × 实缴情况的 EKP/HRO 处理**
| 投保状态 | 实缴情况 | EKP / HRO 处理 |
| --- | --- | --- |
| 待投保 / 投保中 | 无实缴 | 状态→退回(4);**不生成**负数预估、不处理实缴 |
| 已投保 | 无实缴 | 同上 |
| 已投保 | 有实缴,**未结算** | 允许退回;**删除** HRO/EKP 实缴数据(`deleteEkpInsuranceDetailAsso` 或等价逻辑),不推红冲 |
| 已投保 | 有实缴,**结算中 / 已结算****未支出** | 允许退回;**推送负数实缴**至 EKP(参考非见费出单实缴红冲 `pushEstimate` type=6),**不生成**差额 |
| 已投保 | 有实缴,**支出中 / 已支出** | **禁止**退回(见上表) |
**实现要点**
1. `rollBackInsurance` 入口:先 `isLegacyJfcdData` / `isNewJfcdData` 分流,**前置校验逻辑不可共用**
2. 新数据负数实缴:复制实缴 settle 为 `burden``actualPremium` 取负,`pushEstimate(detail, SIX_INT)`;EKP 带 **`fd_is_history_advance_pay=否`**
3. HRO 明细:`actualPremium` 清零;**不**清空 `paymentTime`/`paymentStatus`(新数据不经待缴费)。
4. **不生成**负数预估、**不生成**差额数据。
**状态重置**:新数据若从未进入待缴费,退保时不执行「清空 paymentTime/paymentStatus 回待缴费」的历史逻辑。
---
### 4.6 撤回(待缴费)
**涉及方法**`callBack`
> **已确认(产品)**:新提前缴费派单后**不经待缴费(6)**,页面「撤回」按钮**前端直接禁用**,用户无法触发。**后端 `callBack` 逻辑无需改造**,仅在相关方法处**补充注释**说明即可。
#### 历史分支(`isLegacyJfcdData`)— **不变**
待缴费(6) + EKP 预估未结算 → 物理删除明细/预估/收入。
#### 新分支(`isNewJfcdData`)— **不改逻辑,仅注释**
| 项 | 说明 |
| --- | --- |
| 后端 | **`callBack` 方法体不改动**;在 `callBack``TInsuranceDetailController` 撤回接口处增加注释:新提前缴费无待缴费状态,撤回由前端禁用按钮,后端保持历史实现 |
| 前端 | 新数据(或 `buyHandleStatus≠6`)不展示/禁用「撤回」按钮 |
| 误入请求 | 若极端情况下仍调用接口且非待缴费(6),现有 Controller 前置校验已拒绝,无需新增分支 |
**注释示例**(加在 `callBack` 方法或 Controller 撤回接口上方):
```java
/**
* 撤回 — 仅适用于待缴费(6)的历史见费出单。
* 新提前缴费(isHistoryAdvancePay=0)派单后直接待投保,不经待缴费;前端已禁用撤回按钮,后端无需单独分支。
*/
```
---
### 4.7 EKP 退单 / 撤销匹配
**涉及方法**`callBackInsuranceBuyHandleStatusSub`
#### 历史分支 — **不变**
见费出单 + 待投保(1) → 回退待缴费(6),待办 → 7。
#### 新分支
新数据无「待投保→待缴费」回退场景(未经过 EKP 预估收款);回调时 **跳过****no-op**。EKP 侧撤销规则见 [EKP-提前缴费相关逻辑梳理.md](./EKP-提前缴费相关逻辑梳理.md)
---
### 4.8 删除投保
**涉及方法**`deleteInsurance`
> **已确认(产品)**:新提前缴费与历史见费出单一样,**不可删除投保**。
#### 现有实现(历史 + 新数据共用,**无需改造**)
```java
if (CommonConstants.ZERO_STRING.equals(byId.getIsJfcd())) {
return R.failed(InsurancesConstants.NOT_JFCD_ERROR); // 「投保记录为提前缴费不可删除」
}
```
新数据派单后 `isJfcd=0`,与历史见费出单相同,**现有校验已覆盖新数据**,无需按 `isHistoryAdvancePay` 再开分支。
| 项 | 说明 |
| --- | --- |
| 后端 | **`deleteInsurance` 方法体不改动**;可选在方法注释中补充:含 `isHistoryAdvancePay=0` 的新提前缴费同样适用 `isJfcd=0` 不可删规则 |
| 前端 | 新提前缴费 / 见费出单记录**禁用或隐藏**「删除投保」按钮 |
| 非见费出单 | 不变:须状态为退回(4) 且为创建人本人方可删 |
**注释示例**
```java
/**
* 删除投保 — 非见费出单(isJfcd=1)且退回(4)时可删。
* 提前缴费(isJfcd=0)不可删,含历史(isHistoryAdvancePay=1)与新(isHistoryAdvancePay=0)提前缴费。
*/
```
---
### 4.9 其他约束
| 操作 | 历史 | 新 |
| --- | --- | --- |
| 详情展示 | `premiumType=0` 预估 | 无预估时可展示实缴类型或 0 但 estimate=0 |
| 查询结算状态 | 现有接口 | 无预估 settle 时接口需兼容空 `defaultSettleId` |
| 自动化待办派单 | 同 `addInsurance` | 同 4.1 分流 |
---
## 五、与需求兼容逻辑表的对照(HRO 实现映射)
| 是否历史 | 投保状态 | 操作 | HRO 方法 | 改造方式 |
| --- | --- | --- | --- | --- |
| 是 | 待缴费 | 收付/撤销 | EKP 回调、`callBack` | **历史分支不动** |
| 否 | 待投保/投保中/已投保 | 退保 | `rollBackInsurance` | **新分支**:不生成负数预估/差额 |
| 是 | 已投保 | 导入实缴 | `registeredPolicyPremium` | **历史分支**:实缴+差额 |
| 否 | 已投保 | 导入实缴 | `registeredPolicyPremium` | **新分支**:实缴 only,BPO/非 BPO 规则 |
| 是 | 已导入实缴 | 退保 | `rollBackInsurance` | **历史**:红冲预估 + 删 EKP 实缴/差额 |
| 否 | 已导入实缴,未支出 | 退保 | `rollBackInsurance` | **新**:未结算删实缴;结算中/已结算→负数实缴 |
| 否 | 已导入实缴,支出中/已支出 | 退保 | `rollBackInsurance` | **新**:禁止退回,前端提示 |
---
## 六、代码组织与注释规范
### 6.1 推荐文件结构
```
yifu-insurances-biz/
util/
AdvancePaymentHelper.java // 分流判断
service/insurance/impl/
TInsuranceDetailServiceImpl.java // 入口保留,历史块不动
advance/ // 可选:新逻辑集中
NewAdvancePayDispatchHandler.java // initNewAdvancePayInfo
NewAdvancePaySettleHandler.java // 实缴推送、无差额
NewAdvancePayRollbackHandler.java // 退保
```
若不想拆类,至少在 `TInsuranceDetailServiceImpl` 内用 **private 方法 + 分区注释** 隔离。
### 6.2 注释模板
```java
// ========== 历史见费出单(isHistoryAdvancePay=1)==========
// 逻辑版本:v1.7.x 既有实现,对应文档 HRO-见费出单既有逻辑梳理.md
// 变更原则:仅 bugfix,新需求不得修改此块
if (AdvancePaymentHelper.isLegacyJfcdData(detail)) {
...
}
// ========== 新提前缴费(isHistoryAdvancePay=0)==========
// 需求:HRO-EKP提前缴费商险数据兼容需求.md §1.2、§1.3
// 规则:无预估/差额;派单后直接待投保;实缴按 BPO/非 BPO 推 EKP
else if (AdvancePaymentHelper.isNewJfcdData(detail)) {
...
}
```
### 6.3 常量
`InsurancesConstants` 增加:
```java
/** 是否历史提前缴费:是(历史,走既有逻辑) */
String IS_HISTORY_ADVANCE_PAY_YES = "1";
/** 是否历史提前缴费:否(新数据) */
String IS_HISTORY_ADVANCE_PAY_NO = "0";
/** EKP 推送:是 */
String EKP_IS_HISTORY_ADVANCE_PAY_YES = "是";
/** EKP 推送:否 */
String EKP_IS_HISTORY_ADVANCE_PAY_NO = "否";
```
---
## 七、状态流转对比(便于测试用例设计)
```mermaid
stateDiagram-v2
direction LR
state "历史见费出单" as legacy {
[*] --> 待缴费: 派单+预估推EKP
待缴费 --> 待投保: EKP已收/垫付
待缴费 --> [*]: 撤回
待投保 --> 投保中: 导出
待投保 --> 待缴费: EKP退单
投保中 --> 已投保: 投保成功
已投保 --> 已投保: 登记实缴+差额
}
state "新提前缴费" as newflow {
[*] --> 待投保: 派单(无预估)
待投保 --> 投保中: 导出
投保中 --> 已投保: 投保成功
已投保 --> 已投保: 登记实缴(无差额)
}
```
---
## 八、实施步骤建议
| 阶段 | 内容 | 风险 |
| --- | --- | --- |
| **P0** | §2.4 DDL + §2.5 迁移 + `AdvancePaymentHelper` + 常量 + 发布时间切点 | 低 |
| **P1** | 派单分流(4.1)+ 待办状态 | 中:需验证自动化/续签待办 |
| **P2** | 登记保单保费新分支(4.4)+ EKP 实缴推送规则 | 高:与 EKP 联调 |
| **P3** | 退保/回调分流(4.5、4.7);EKP 回调/手动拉取对新数据入口跳过;撤回(4.6)仅加注释 | 中 |
| **P4** | 校验类、列表查询、详情展示兼容 | 低 |
**上线顺序建议**:先上 HRO 字段 + 历史数据刷数(全走旧逻辑)→ 再上 HRO 新分支 → 最后开 EKP 新拉取/结算规则。
---
## 九、测试范围(控制回归成本)
### 9.1 历史数据 — **冒烟即可**
- 派单 → 待缴费 → EKP 回调 → 待投保 → 投保成功 → 登记实缴+差额 → 退保
- 确认 `isHistoryAdvancePay=1` 后行为与上线前**完全一致**(选 2~3 条典型用例)
### 9.2 新数据 — **全量场景**
| # | 场景 |
| --- | --- |
| 1 | 非 BPO 新增派单 → 直接待投保(**无**收入/管理费/风险金)→ 投保成功 → 登记实缴(应收=应付=实缴,**有无预估=否**,同步生成收入) |
| 2 | BPO 新增派单 → 直接待投保 → 登记实缴(应收=0,应付=实缴,**有无预估=否**) |
| 3 | 待投保/投保中退保(无负数预估、无实缴处理) |
| 4 | 已投保未实缴退保 |
| 5 | 已实缴未结算退保(删除实缴,不推红冲) |
| 6 | 已实缴结算中/已结算、未支出退保(允许,推送负数实缴) |
| 7 | 已实缴支出中/已支出退保(禁止,前端提示) |
| 8 | 自动化商险待办 / 续签待办状态联动 |
| 9 | EKP 回调 / `pullPaymentStatus` 对新数据不触发状态变更(含 BPO 场景) |
| 10 | 前端 `getPaymentSettleStatusFromEkp` 支出中/已支出时禁用退回按钮 |
| 11 | 新提前缴费「删除投保」禁用/隐藏,后端返回 `NOT_JFCD_ERROR`(若误调) |
| 12 | 发布时间切点:`launchTime` 前写 `isHistoryAdvancePay=1`,之后写 `0` |
| 13 | `bpoEnable=是` 项目仍不走见费出单(与现网一致) |
| 14 | EKP 预估/实缴推送均带 `fd_is_history_advance_pay`,与 HRO `is_history_advance_pay` 一致 |
---
## 十、待确认项(实现前与产品/EKP 对齐)
1. ~~**新数据是否永远不经待缴费(6)**~~ **已确认**:新数据派单后直接待投保,**不经待缴费(6)**;EKP 回调/手动拉取无需对新数据做状态更新。
2. ~~**新数据派单时是否生成收入/管理费/风险金**~~ **已确认**:派单**不生成****延至实缴登记**`registeredPolicyPremium`)时按实缴金额生成。
3. ~~**新数据已实缴且 EKP 已结算后退保**~~ **已确认**:结算中/已结算且**未支出**→ 允许退回并**生成负数实缴****支出中/已支出**→ 禁止退回(前端提示)。与历史逻辑(`payStatus=已结算/结算中` 即拦截)**分流处理**
4. ~~**EKP 实缴推送字段**~~ **已确认**:新数据 **`有无预估` 固定「否」**;见费出单条件不变(**`bpoEnable=否`**),启用 BPO 结算模式的项目**仍不走**见费出单。
5. ~~**上线切点**~~ **已确认**:以**发布时间**控制 `isHistoryAdvancePay=0` 写入,不用配置开关。
6. ~~**新数据撤回(待缴费)**~~ **已确认**:前端禁用撤回按钮;后端 `callBack` **不改逻辑**,仅加注释说明。
7. ~~**新数据删除投保**~~ **已确认****不可删**;现有 `isJfcd=0` 校验已覆盖,**不改逻辑**,可选加注释;前端禁用删除按钮。
---
## 十一、关键代码索引(改造锚点)
| 逻辑 | 类 / 方法 | 改造类型 |
| --- | --- | --- |
| 见费出单标识 | `initJfcd` / `initJfcdBatch` | 发布时间切点 + `isHistoryAdvancePay``bpoEnable=否` 不变 |
| 派单核心 | `initJfcdInfo` | **分流**;历史推 EKP 预估带 `fd_is_history_advance_pay=是` |
| 派单后续 | `addInsurance` / `batchInsurance` | 新数据不进 `pushList`、不 `createInsuranceInfo` |
| 是否历史字段 | `TInsuranceDetail.isHistoryAdvancePay` | 派单落库;实缴/预估推送 EKP 同源 |
| 收入/管理费/风险金 | `createInsuranceInfo` | 新数据:**登记实缴时**调用 |
| 推 EKP 预估 | `DoJointInsuranceTask.pushEstime` | 历史专用;带 `fd_is_history_advance_pay=是` |
| EKP 费用规则 | `DoJointInsuranceTask.insertInsrancesDetail` / `initValues` | 实缴:`有无预估` + `fd_is_history_advance_pay` |
| 缴费同步 | `DoJointInsuranceTask.updateInsuranceSettleStatus` | 新数据入口直接跳过 |
| 手动拉取 | `TInsuranceDetailServiceImpl.pullPaymentStatus` | 查询过滤 + 新数据跳过 |
| 登记实缴/差额 | `registeredPolicyPremium` | 新数据跳过差额 |
| 退保 | `rollBackInsurance` | 历史块不动;新分支独立校验 + 负数实缴/删实缴 |
| EKP 退单 | `callBackInsuranceBuyHandleStatusSub` | 新数据 no-op |
| 撤回 | `callBack` | **逻辑不改**;方法/Controller 处加注释 |
| 删除投保 | `deleteInsurance` | **逻辑不改**`isJfcd=0` 已拦截);可选加注释 |
---
## 修订记录
| 日期 | 说明 |
| --- | --- |
| 2026-06-17 | 初稿:HRO 侧提前缴费商险数据兼容开发方案 |
| 2026-06-17 | 明确新数据 EKP 回调/手动拉取无需状态更新(不经待缴费) |
| 2026-06-17 | 明确新数据退保实缴规则:结算中/已结算未支出→负数实缴;支出中/已支出→禁止 |
| 2026-06-17 | 撤回:新数据前端禁用按钮,后端 callBack 不改逻辑,仅加注释 |
| 2026-06-17 | 删除投保:新提前缴费不可删,isJfcd=0 现有校验已覆盖,不改逻辑 |
| 2026-06-17 | 确认:收入延至实缴登记;EKP 有无预估=否;bpoEnable 条件不变;发布时间切点 |
| 2026-06-17 | 统一字段「是否历史提前缴费」:HRO `is_history_advance_pay` ↔ EKP `fd_is_history_advance_pay` |
| 2026-06-17 | 补充 HRO/EKP 加列 DDL 及存量刷数 SQL(§2.4、§2.5) |
# HRO 模块 — 见费出单既有逻辑梳理
> 对应需求:[HRO-EKP提前缴费商险数据兼容需求.md](./HRO-EKP提前缴费商险数据兼容需求.md)
> 梳理范围:**HRO(yifu-insurances)模块** 当前已实现逻辑
> 说明:代码中字段 `isJfcd=0` 表示「见费出单」;业务注释/常量中亦称为「提前缴费」。需求文档中 **历史提前缴费** 走既有逻辑,即本文所述流程。
---
## 一、概念与标识
| 项 | 说明 |
| --- | --- |
| 字段 | `TInsuranceDetail.isJfcd``0`=是见费出单,`1`=否 |
| 触发条件 | **新增/批增****未启用 BPO 结算模式**`bpoEnable=否`)且 **险种配置「是否见费出单」= 是** |
| 初始化 | `initJfcd` / `initJfcdBatch``addInsuranceCheck` / `batchInsuranceCheck` 派单校验时赋值;**替换不参与**) |
| 关联字段 | `paymentStatus`(0 待缴费 / 1 已缴费)、`paymentTime``defaultSettleId`(预估结算 ID)、`balanceId`(差额 settle ID) |
**不满足见费出单条件时**:走普通派单流程,派单后投保状态为 **待投保(1)**,预估在 **投保成功** 时生成。
> **手动派单与自动化派单**:均走 `addInsurance` / `batchInsurance`,见费出单判定与后续流程一致;区别仅在于创建人显示(自动化为「自动化派单-{前端客服}」)。
---
## 二、投保状态枚举(buyHandleStatus)
| 值 | 含义 | 见费出单典型场景 |
| --- | --- | --- |
| 6 | 待缴费 | 派单/新增/批增后初始状态 |
| 1 | 待投保 | EKP 收款已收/垫付后 |
| 2 | 投保中 | 导出办理后 |
| 3 | 已投保 | 投保成功 |
| 4 | 退回 | 投保退回/退保 |
| 5 | — | 减员相关 |
自动化待办 `processStatus` 联动(**投保明细 `buyHandleStatus` 变更时同步回写**):
| 待办类型 | 实体 | 关联投保明细字段 |
| --- | --- | --- |
| 自动化商险待办 | `TEmployeeInsurancePre` | `insurancesId` |
| 商险续签待办 | `TInsurancePreRenewDetail` | `insurancesIdNew` |
`processStatus` 枚举(两表一致;续签待办实体注释仅列到 6,代码实际含 **7**):
| 值 | 含义 |
| --- | --- |
| 0 | 待确认 |
| 1 | 待派单 |
| 2 | 派单失败 |
| 3 | 待投保 |
| 4 | 投保中 |
| 5 | 投保退回 |
| 6 | 已投保 / 已完成 |
| 7 | 待缴费(见费出单派单后) |
与投保状态对应关系(全量):
| 投保明细 buyHandleStatus | processStatus | 触发场景 |
| --- | --- | --- |
| 6 待缴费 | 7 | 见费出单派单后 |
| 1 待投保 | 3 | 缴费完成(EKP 回调 / 手动拉取) |
| 2 投保中 | 4 | 待投保导出办理 |
| 3 已投保 | 6 | 投保成功(`successfulInsurance`) |
| 4 退回 | 5 | 投保退回 / 退保(`rollBackInsurance`) |
> `updateEmployeeInsurancePreById` 更新为 **6(已完成)** 时,若按当前 `processStatus` 查不到待办,会从 **3 / 4 / 7** 中兜底查找再更新。
---
## 三、状态流转总览
```mermaid
stateDiagram-v2
[*] --> 待缴费: 新增/批增派单\n生成预估+推送EKP
待缴费 --> 待投保: EKP已收/垫付\n(回调或手动拉取)
待缴费 --> [*]: 撤回\n(物理删除明细)
待投保 --> 投保中: 导出办理
待投保 --> 待缴费: EKP退单/撤销匹配
投保中 --> 已投保: 投保成功\n(不重复生成预估)
投保中 --> 退回: 投保退回
已投保 --> 退回: 退保\n(红冲/删EKP明细)
已投保 --> 已投保: 登记保单保费\n推送实缴+差额
```
---
## 四、派单 / 新增 / 批增
**入口:** `addInsurance``batchInsurance`
**核心方法:** `initJfcdInfo`
### 4.1 见费出单(isJfcd=0)
1. 计算购买周期、预计办理日期、预估保费(见 **4.1.1**
2. 投保状态 → **待缴费(6)**
3. `paymentStatus`**0(待缴费)**
4. 写入 `TInsuranceSettle`(预估结算记录,`settleType` 同明细),赋值 `defaultSettleId``initJfcdInfo` 内即时 `save`
5. 生成收入数据 `createInsuranceInfo`(含商险收入;按项目配置可能生成**管理费 / 风险金**并推送 EKP)
6. 自动化商险待办 / 商险续签待办 `processStatus`**7(待缴费)**
7. 异步 `pushEstime` → 推送 **预估** 至 EKP(见 **4.1.2**
#### 4.1.1 计费与日期规则(`initJfcdInfo`)
| 项 | 规则 |
| --- | --- |
| 预计办理日期 `preHandleTime` | 派单当日 **15:20 前** 为派单日;15:20 后或非工作日取**最近工作日**(调档案工作日接口) |
| 参保开始日期 | `MAX(保单开始日期, 预计办理日期 + 1 日)` |
| 购买周期 | 保单结束 − 参保开始 + 1(天/月) |
| 按天计费 | 预估保费 = 购买标准 × 天数 / 365 + **5 元** |
| 按月计费 | 预估保费 = 购买标准 × 费率(按购买月数查 `TInsuranceTypeRate`)+ **5 元** |
| 封顶 | 预估保费 > 购买标准时,取购买标准 |
#### 4.1.2 预估推送条件(`pushEstime`)
满足以下**任一**条件即推送预估至 EKP:
- `settleType = 0`(合并结算)
- `isJfcd = 0`(见费出单)
即:**实缴结算模式的见费出单**,派单时也会推送预估。
### 4.2 非见费出单(isJfcd=1)
1. 投保状态 → **待投保(1)**
2. 预估保费置 0,**不**生成预估结算、**不**推送 EKP
3. 自动化待办 `processStatus`**3(待投保)**
### 4.3 自动化商险待办派单(`TEmployeeInsurancePre`)
> 待办表**无 `isJfcd` 字段**;是否见费出单在生成 `TInsuranceDetail` 时由 `initJfcd` / `initJfcdInfo` 判定,逻辑与 4.1 / 4.2 完全相同。
**数据来源:** 入职/档案等流程写入商险待购买列表(`saveInsurancePreInfo``saveOrUpdateInsuranceList` 等)。
**入口:**
| 场景 | 方法 |
| --- | --- |
| 手动批量派单 | `TEmployeeInsurancePreController.batchDispatcherInsurance``batchDispatcherInsurance` |
| 手动批量确认 | `confirm`:待确认(0) → 待派单(1) |
| 定时自动派单 | `pushDisConfrimInsurances`(每天下午 3:20 或上午 11 点):待确认(0) → 待派单(1),再调用 `batchDispatcherInsurance(..., pushQiWeiFlag=true)` |
| 定时推送确认 | `pushWxConfrimMessage`(派单当日 9 点):推送企微待确认提醒 |
**派单组装:**`buyType` 调用既有派单接口(`autoFlag=true`),并传入 `insurancePreId` 用于回写待办:
| buyType | 调用 | 见费出单 |
| --- | --- | --- |
| 1 新增 | `addInsurance` | 走 `initJfcdInfo` |
| 3 批增 | `batchInsurance` | 走 `initJfcdInfo` |
| 4 替换 | `replaceInsurance` | **不参与结算**,不调用 `initJfcdInfo`,待办直接 **3(待投保)** |
**派单成功回写(`updateEmployeeInsurancePre`):**
| 条件 | 待办 processStatus | 其他 |
| --- | --- | --- |
| `isJfcd=0` | **7(待缴费)** | 写入 `insurancesId``isAddress`;清空 `errorInfo` |
| `isJfcd=1` | **3(待投保)** | 同上 |
| 派单失败 | **2(派单失败)** | 写入 `errorInfo``errorTime`;定时任务可推送企微 |
创建人显示为「自动化派单-{前端客服}」。
### 4.4 商险续签待办派单(`TInsurancePreRenewDetail`)
> 与 4.3 相同:**无独立见费出单判断**,复用 `addInsurance` / `batchInsurance` / `replaceInsurance` + `initJfcdInfo`。
**入口:**
| 场景 | 方法 |
| --- | --- |
| 手动批量派单 | `TInsurancePreRenewDetailController.batchDoInsurancePreRenew``batchDoInsurancePreRenew` |
| 单个/批量确认 | `doSure` / `doSureBatch`:待确认(0) → 待派单(1) |
| 定时自动派单 | `autoDoInsurancePreRenew`(工作日每天下午 3:00、3:20):待确认(0) → 待派单(1),再调用 `batchDoInsurancePreRenew(..., pushQiWeiFlag=true)` |
**派单组装:**`buyType` 分流,传入 `insurancePreRenewId`
| buyType | 调用 | 见费出单 |
| --- | --- | --- |
| 1 新增 | `addInsurance` | 走 `initJfcdInfo` |
| 3 批增 | `batchInsurance` | 走 `initJfcdInfo` |
| 4 替换 | `replaceInsurance` | **不参与结算**,待办直接 **3(待投保)** |
**派单成功回写(`updateEmployeeInsurancePreRenew`):**
| 条件 | 待办 processStatus | 其他 |
| --- | --- | --- |
| `isJfcd=0` | **7(待缴费)** | 写入 `insurancesIdNew``isAddress` |
| `isJfcd=1` | **3(待投保)** | 同上 |
| 派单失败 | **2(派单失败)** | 写入 `errorInfo``errorTime` |
**后续状态联动:** 导出办理、投保成功、投保退回等,通过 `updateEmployeeInsurancePreRenewById``insurancesIdNew` 继续同步 `processStatus`(与第七章投保办理流程一致)。
---
## 五、推送 EKP 费用规则(见费出单)
**入口:** `DoJointInsuranceTask.insertInsrancesDetail` / `pushEstime`
**标识:** EKP 字段 `fd_jfcd=是``initValues` 写入),`是否全部结算=是``实际结算月份=空`
| 单据类型 | 非 BPO / 普通项目 | BPO 且未启用 BPO 结算模式 |
| --- | --- | --- |
| 预估 | 应收 = 预估金额,应支 = 0 | 应收 = 0,应支 = 预估金额 |
| 实缴 | 应收 = 0,应支 = 实缴金额 | 应收 = 0,应支 = 实缴金额 |
| 差额 | 应收 = 实缴应支 − 预估应收,应支 = 0 | 应收 = 0,应支 = 实缴应支 − 预估应支 |
> 实缴、差额在 **登记保单保费** 环节生成;预估在派单时即推送。红冲单据(`CORRECT_SETTLE_BILL`)对见费出单同样设置 `fd_jfcd=是`、全部结算=是。
---
## 六、缴费完成 → 待投保
### 6.0 EKP 统一回调入口
**接口:** `POST /insuranceDetail/updateInsuranceSettleStatus``TInsuranceDetailController`
| `callBackFlag` | 路由 | 说明 |
| --- | --- | --- |
| `0` | `callBackInsuranceBuyHandleStatus` | 收款结算单退单 / 撤销匹配 → 回退待缴费(见第十一章) |
| 非 `0` | `updateInsuranceSettleStatus``DoJointInsuranceTask.updateInsuranceSettleStatus` | 收款已收 / 垫付 → 待投保(见 6.1) |
### 6.1 EKP 回调(自动,收款已收/垫付)
**入口:** `DoJointInsuranceTask.updateInsuranceSettleStatus`
**定位:**`settleNo` + `payFlag` 查 EKP 视图,取明细 ID 前 19 位
**条件:**
- `isJfcd=0`
- 当前状态 **待缴费(6)**
- 收入侧预估明细 **已收****垫付**`paymentStatsus=0`,代码字段拼写保留)
**动作:**
- `buyHandleStatus`**1(待投保)**
- `paymentStatus`**1(已缴费)**
- 写入 `paymentTime`
- 自动化商险待办(`TEmployeeInsurancePre`,按 `insurancesId``processStatus`**3(待投保)**
- 商险续签待办(`TInsurancePreRenewDetail`,按 `insurancesIdNew``processStatus`**3(待投保)**
### 6.2 手动拉取
**入口:** `pullPaymentStatus` / `POST .../pullPaymentStatus`
**范围:**
- 无参:当前用户创建的、**待缴费(6)****见费出单** 的记录
- 有参 `idStr`:按指定投保明细 ID(逗号分隔)批量拉取(服务层内部调用)
**逻辑:** 批量查 EKP 结算状态(`getSettleStatusFromEkpAssoByIds`),**已收/垫付** 时同步为待投保(同 6.1),并同步更新上述两类待办的 `processStatus`**3**
---
## 七、待投保 → 投保中 → 已投保
### 7.1 导出办理(待投保 → 投保中)
**入口:** `getInsuranceExportOneList`(待投保导出,`buyHandleStatus=1` 时触发状态变更)
- 状态 **待投保(1)****投保中(2)**
- 写入 `handledBy``handledTime`
- 计算 `policyEffect`(生效日期):
- **新增**:若保单开始 > 导出日+1,取保单开始;否则取导出日+1
- **批增 / 替换**:导出日+1
- 自动化商险待办 / 商险续签待办 `processStatus`**4(投保中)**
- **替换类型**:导出列表合并被替换人 quit 行(附带原保单号等)
### 7.2 投保成功(投保中 → 已投保)
**入口:** `successfulInsurance`
**见费出单特殊点:**
- **不重复生成预估**(派单时已生成并推送),加入 `successThree` 跳过 `pushEstime`
- 预估模式(`settleType=0`):直接置 **已投保(3)**
- 实缴模式(`settleType=1`):置 **已投保(3)**,差额在登记保单保费处处理
**通用后续:**
- 自动化商险待办 / 商险续签待办 `processStatus`**6(已完成)**
- `doJointInsuranceTask.updateEmpInfp` 同步档案商险状态为 **正常(2)**
---
## 八、登记保单保费(实缴 / 差额)
**入口:** `registeredPolicyPremium`(登记保单保费)
**前置校验(`registeredPolicyPremiumCheck`):**
| 条件 | 结果 |
| --- | --- |
| 状态须为 **已投保(3)** | 拒绝:待缴费(6)、待投保(1)、投保中(2)、退回(4) |
| 购买类型为替换(4) | 不可登记 |
| 无商险办理地权限 | 不可登记 |
| EKP 重发中 | 不可登记 |
| EKP 预估结算中 / 已结算 | 不可登记 |
| EKP 支出中 / 已支出 | 不可登记 |
### 8.1 实缴推送
- **合并结算**`settleType=0`**或见费出单**`isJfcd=0`)且有 `defaultSettleId`:在已有 settle 上推送实缴新增(type=2)/ 更新(type=4)至 EKP
- **单独结算**`settleType=1` 且非见费出单路径):无 settle 则新建实缴 settle 再推送
- 实缴金额变更时,实缴模式可能触发**收入红冲**(管理费 / 风险金按项目配置)
### 8.2 差额生成(见费出单专用)
**条件:** `isJfcd=0` 且实缴金额 ≠ 预估金额
1. 删除 EKP 侧已有差额(`callBackBalance`
2. 删除 HRO 侧 `settleType=2` 的差额记录
3. 新建差额 settle,写入 `detail.balanceId`,推送 EKP(`asynchronousEkpInfo`,类型 7)
4. 差额 = 0 时不生成
---
## 九、投保退回 / 退保
**入口:** `rollBackInsurance`
### 9.1 通用校验
- 不允许:已退回(4)、减员相关(5)
- 已投保且减员中/已减员:不允许
- **已支出或支出中**(查 EKP `payStatus`):不允许退回
### 9.2 见费出单特殊处理
**状态置为退回(4) 时:**
- 清空 `paymentTime``paymentStatus`(重置为待缴费)
**结算/EKP 处理(有 `defaultSettleId`):**
| 场景 | 处理 |
| --- | --- |
| 见费出单 | **不区分**待投保/投保中/已投保:统一生成负数预估 **红冲**`pushEstimate` type=3);**直接删除** EKP 实缴及差额(`deleteEkpInsuranceDetailAsso`) |
| 非见费出单 | 按预估/实缴推送状态与 EKP 结算状态,推送作废或红冲(多种分支) |
**已投保退回附加:**
- 清空 `policyEffect`、有效/过期标志、替换标签等;同步清空 `TInsuranceAlert` 替换标签
- 同步收入红冲
**替换类型退回:**
- 替换者 `isEffect` 置空;替换记录置失败
- 被替换人从 `replaceRemarkBak` 恢复标签,重新激活
**待办联动:**
- 自动化商险待办 / 商险续签待办 `processStatus`**5(投保退回)**(从 3 / 4 / 6 / 7 状态匹配更新)
---
## 十、撤回(待缴费)
**入口:** `callBack` / `POST .../callBack?id=`
**Controller 前置:****待缴费(6)** 可进入服务层
**服务层条件:** EKP 预估 **非**「已结算 / 结算中」(`getSettleStatusFromEkpInsuranceDetailAsso`
> **注意:撤回是物理删除投保明细**,不是将状态改回更早阶段。
**动作:**
1. 删除 EKP 预估明细(`deleteEkpInsuranceDetail`
2. **删除 HRO 投保明细**`baseMapper.deleteById`
3. 删除 HRO 预估 settle
4. 删除关联收入、管理费、风险金
5. 自动化商险待办 / 商险续签待办 `processStatus`**1(待派单)****未清空** `insurancesId` / `insurancesIdNew`,明细已不存在)
---
## 十一、EKP 退单 / 撤销匹配(HRO 侧回调)
**入口:** `callBackInsuranceBuyHandleStatus` → 异步 `callBackInsuranceBuyHandleStatusSub`
**触发:** `updateInsuranceSettleStatus` 接口且 `callBackFlag=0`
**定位:**`vo.detailIds`(逗号分隔投保明细 ID)逐条处理(**非**结算单号)
**条件:** 见费出单 且 当前 **待投保(1)**
**动作:**
- 回退 **待缴费(6)**
- 清空 `paymentTime``paymentStatus`
- 自动化商险待办、商险续签待办 `processStatus`**7(待缴费)**(分别按 `insurancesId` / `insurancesIdNew`
> EKP 侧退单/撤销规则详见 [EKP-提前缴费相关逻辑梳理.md](./EKP-提前缴费相关逻辑梳理.md)。
---
## 十二、其他约束
| 操作 | 见费出单限制 / 说明 |
| --- | --- |
| 删除投保 | **见费出单不可删**`NOT_JFCD_ERROR`);非见费出单须状态为 **退回(4)** 且为 **创建人本人** |
| 详情展示 | 见费出单默认 `premiumType=0`(预估);若项目**启用 BPO 结算模式**会覆盖为 `premiumType=1` 并将 `estimatePremium` 置 0 |
| 查询结算状态 | `GET .../getSettleStatusFromEkp`(预估,按 `detailId_settleId`);`GET .../getPaymentSettleStatusFromEkp`(实缴/支出) |
---
## 十三、与需求兼容逻辑表对应(历史提前缴费 = 是)
| 投保状态 | 操作 | 既有见费出单逻辑摘要 |
| --- | --- | --- |
| 待缴费 | 收付 | EKP 收款结算匹配预估;已收/垫付 → 待投保 |
| 待缴费 | 撤销 | 未结算可 `callBack` 撤回(物理删除明细 + 删 EKP 预估) |
| 待投保 | 退保 | 退回(4);红冲预估 + 删 EKP 实缴差额 |
| 投保中 | 退保 | 同见费出单退保:**统一红冲预估** + 删 EKP 实缴差额(不作废分支) |
| 已投保,无实缴 | 导入实缴 | 登记保单保费 → 实缴 + 差额(≠0 时) |
| 已投保,无实缴 | 退保 | 红冲预估 + 删 EKP 实缴差额;已支出则禁止 |
| 已导入实缴 | 商险支出 | 查 EKP 支出状态;未支出可支出(EKP 侧,待梳理) |
| 已导入实缴 | 退保 | 已支出/支出中禁止;否则红冲 + 删 EKP 明细 |
---
## 十四、关键代码索引
| 逻辑 | 类 / 方法 |
| --- | --- |
| 见费出单标识初始化 | `TInsuranceDetailServiceImpl.initJfcd` / `initJfcdBatch` |
| 派单预估与待缴费 | `TInsuranceDetailServiceImpl.initJfcdInfo` |
| 自动化商险待办派单 | `TEmployeeInsurancePreServiceImpl.batchDispatcherInsurance` |
| 自动化商险待办定时派单 | `TEmployeeInsurancePreServiceImpl.pushDisConfrimInsurances` |
| 商险续签待办派单 | `TInsurancePreRenewDetailServiceImpl.batchDoInsurancePreRenew` |
| 商险续签待办定时派单 | `TInsurancePreRenewDetailServiceImpl.autoDoInsurancePreRenew` |
| 待办状态回写(派单) | `TInsuranceDetailServiceImpl.updateEmployeeInsurancePre` / `updateEmployeeInsurancePreRenew` |
| 待办状态回写(办理) | `TInsuranceDetailServiceImpl.updateEmployeeInsurancePreById` / `updateEmployeeInsurancePreRenewById` |
| 收入 / 管理费 / 风险金 | `TInsuranceDetailServiceImpl.createInsuranceInfo` |
| 推送 EKP 预估 | `DoJointInsuranceTask.pushEstime` |
| EKP 费用明细规则 | `DoJointInsuranceTask.insertInsrancesDetail` / `initValues` |
| EKP 统一回调入口 | `TInsuranceDetailController.updateInsuranceSettleStatus` |
| 缴费同步待投保 | `DoJointInsuranceTask.updateInsuranceSettleStatus` |
| 手动拉取缴费 | `TInsuranceDetailServiceImpl.pullPaymentStatus` |
| 投保成功 | `TInsuranceDetailServiceImpl.successfulInsurance` |
| 登记保单保费/差额 | `TInsuranceDetailServiceImpl.registeredPolicyPremium`(约 2650 行起) |
| 登记校验 | `TInsuranceDetailServiceImpl.registeredPolicyPremiumCheck` |
| 投保退回 | `TInsuranceDetailServiceImpl.rollBackInsurance` |
| 待缴费撤回 | `TInsuranceDetailServiceImpl.callBack` |
| EKP 退单回退待缴费 | `TInsuranceDetailServiceImpl.callBackInsuranceBuyHandleStatusSub` |
| 删 EKP 实缴差额 | `EkpSettleServiceImpl.deleteEkpInsuranceDetailAsso` |
---
## 十五、与新提前缴费需求的差异(备忘)
| 项 | 既有见费出单(本文) | 新提前缴费(需求) |
| --- | --- | --- |
| 标识 | `isJfcd=0`(险种+BPO 条件) | 新增历史/新数据字段 |
| 派单后状态 | 待缴费 → 待投保 | 新数据:待缴费 **跳过派单环节** 进待投保 |
| 预估/差额 | 生成预估;实缴后生成差额 | 新数据:**不生成** 预估/差额 |
| EKP 结算金额为 0 | 走既有 EKP 拉取逻辑 | 结算后直接同步 HRO 待投保 |
# 项目配置删除功能接口文档
## 1. 接口概述
本文档描述了项目配置删除功能的相关接口,包括删除预检和实际删除两个主要接口。该功能用于安全地删除项目配置及其关联数据,并在删除前进行必要的检查和待办事项清理。
## 2. 接口详情
### 2.1 删除预检接口
#### 接口信息
- **接口名称**: 删除预检
- **接口路径**: `/tautomainrel/deletePrecheck/{id}`
- **请求方法**: GET
- **功能描述**: 在删除项目配置前,统计该项目下存在的商险续签待办和合同续签待办数量,供前端展示确认
#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| id | String | 是 | 项目配置ID,通过URL路径传递 |
#### 响应参数
```json
{
"code": 0,
"msg": "success",
"data": {
"insuranceCount": 5,
"contractCount": 3,
"deptNo": "DEPT001",
"departName": "测试项目"
}
}
```
| 字段名 | 类型 | 说明 |
|--------|------|------|
| insuranceCount | int | 商险续签待办条数 |
| contractCount | int | 合同续签待办条数 |
| deptNo | String | 项目编码 |
| departName | String | 项目名称 |
#### 业务逻辑
1. 验证项目配置是否存在
2. 查询项目基本信息(项目编码、项目名称)
3. 统计商险续签待办数量(状态为"待确认"、"待派单"的记录)
4. 统计合同续签待办数量(状态为"待确认"、"待发起"的记录)
---
### 2.2 删除项目配置接口
#### 接口信息
- **接口名称**: 通过id删除项目配置表主表
- **接口路径**: `/tautomainrel/{id}`
- **请求方法**: DELETE
- **功能描述**: 删除指定的项目配置及其所有关联的子规则配置,并清除相关的续签待办事项
#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| id | String | 是 | 项目配置ID,通过URL路径传递 |
#### 响应参数
```json
{
"code": 0,
"msg": "success",
"data": true
}
```
| 字段名 | 类型 | 说明 |
|--------|------|------|
| data | Boolean | 删除是否成功 |
#### 业务逻辑
##### 1. 前置校验
- 验证项目配置ID是否为空
- 验证项目配置是否存在
##### 2. 清除商险续签待办
- 调用商险服务清除该项目的商险续签待办事项
- 清除范围:状态为"待确认"(0)、"待派单"(1)的待办
##### 3. 清除合同续签待办
- 删除合同预生成记录(t_employee_contract_pre_new表)
- 条件:项目编码匹配 + 自动化标识为"0" + 流程状态为"待确认"(0)或"待发起"(1)
- 删除合同提醒记录(t_emp_contract_alert表)
- 条件:项目编码匹配 + 自动化标识为"0" + 流程状态为"待确认"(0)或"待发起"(1)
##### 4. 级联删除配置数据
按以下顺序删除关联配置:
**a. 商险规则配置**
- 删除商险标准信息明细(t_auto_standard_info)
- 删除商险购买标准(t_auto_insur_standard)
- 删除商险规则配置(t_auto_insur_rule_info)
**b. 合同规则配置**
- 删除合同签订方案配置(t_auto_contract_scheme)
- 删除合同规则配置(t_auto_contract_rule_info)
**c. 社保公积金规则配置**
- 删除社保规则明细(t_auto_social_rule_rel)
- 删除公积金规则明细(t_auto_fund_rule_rel)
- 删除社保规则配置(t_auto_social_rule_info)
- 删除公积金规则配置(t_auto_fund_rule_info)
**d. 档案规则配置**
- 删除档案管理规则配置(t_auto_emp_rule_info)
**e. 岗位字典配置**
- 删除项目岗位字典项(sys_auto_dict_item)
**f. 主表配置**
- 删除项目配置主表记录(t_auto_main_rel)
##### 5. 事务处理
- 整个删除过程在事务中执行,确保数据一致性
- 任何步骤失败都会回滚所有操作
## 3. 数据表说明
### 3.1 主要涉及的数据表
| 表名 | 说明 |
|------|------|
| t_auto_main_rel | 项目配置主表 |
| t_auto_emp_rule_info | 档案管理规则配置表 |
| t_auto_insur_rule_info | 商险规则配置表 |
| t_auto_insur_standard | 商险购买标准表 |
| t_auto_standard_info | 商险标准信息明细表 |
| t_auto_contract_rule_info | 员工合同签订规则配置表 |
| t_auto_contract_scheme | 员工合同签订规则方案表 |
| t_auto_social_rule_info | 社保规则配置表 |
| t_auto_social_rule_rel | 社保规则配置明细表 |
| t_auto_fund_rule_info | 公积金规则配置表 |
| t_auto_fund_rule_rel | 公积金规则配置明细表 |
| sys_auto_dict_item | 岗位字典项表 |
| t_emp_contract_alert | 合同提醒表 |
| t_employee_contract_pre_new | 合同预生成表 |
### 3.2 关键状态码说明
#### 商险续保状态
- `0`: 待确认
- `1`: 待派单
#### 合同续签状态
- `0`: 待确认
- `1`: 待发起
#### 自动化标识
- `0`: 自动化流程
- `1`: 非自动化流程
## 4. 使用示例
### 4.1 删除预检示例
```javascript
// 前端调用示例
axios.get('/tautomainrel/deletePrecheck/123456789', {
headers: {
'Authorization': 'Bearer YOUR_TOKEN'
}
})
.then(response => {
const { insuranceCount, contractCount, departName } = response.data.data;
if (insuranceCount > 0 || contractCount > 0) {
// 显示确认对话框
confirm(`项目"${departName}"存在未处理的待办事项:\n` +
`商险续签待办:${insuranceCount}条\n` +
`合同续签待办:${contractCount}条\n\n` +
`删除后将自动清除这些待办,是否继续?`);
} else {
// 直接删除
deleteProjectConfig('123456789');
}
});
```
### 4.2 删除项目配置示例
```javascript
// 前端调用示例
function deleteProjectConfig(id) {
axios.delete(`/tautomainrel/${id}`, {
headers: {
'Authorization': 'Bearer YOUR_TOKEN'
}
})
.then(response => {
if (response.data.code === 0) {
message.success('项目配置删除成功');
// 刷新列表
refreshList();
} else {
message.error('删除失败:' + response.data.msg);
}
})
.catch(error => {
message.error('网络异常,请稍后重试');
});
}
```
## 5. 注意事项
### 5.1 安全性考虑
1. **权限控制**: 删除操作需要`demo_tautomainrel_del`权限
2. **二次确认**: 建议前端在删除前调用预检接口,并向用户展示待办统计信息进行二次确认
3. **事务保护**: 删除操作在数据库事务中执行,保证数据一致性
### 5.2 业务影响
1. **不可逆操作**: 删除操作会永久删除项目配置及所有关联数据,无法恢复
2. **待办清除**: 会自动清除该项目下的商险和合同续签待办事项
3. **关联影响**: 删除后,该项目下员工的自动化配置将失效
### 5.3 性能考虑
1. **大数据量**: 如果项目下存在大量待办记录,删除操作可能耗时较长
2. **异步处理**: 商险待办清除通过Dapr调用,可能存在网络延迟
### 5.4 错误处理
常见错误情况:
- 项目配置不存在:返回"项目配置不存在"
- 清除商险待办失败:返回"清除商险续签待办失败:[具体原因]"
- 参数为空:返回"参数不能为空"
## 6. 版本历史
| 版本 | 日期 | 修改内容 | 修改人 |
|------|------|----------|--------|
| V1.0 | 2026-06-09 | 初始版本,包含删除预检和删除接口文档 | - |
## 7. 联系方式
如有问题,请联系开发团队。
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment