将核保函与客户类函件的关系类比为电商系统中的“订单与订单项”,这个类比部分成立,但存在关键差异。下面我将:
- 澄清类比的合理性与局限性
- 提供核保系统的完整、详细、可落地的业务流程图(含状态机)
- 配套一份结构清晰、面向 Java 后端开发者的详细说明文档
一、类比分析:核保函 vs 电商订单
| 维度 | 电商系统 | 核保系统 | 是否类比成立? |
|---|---|---|---|
| 聚合根 | Order(订单) | UnderwritingTask(核保任务) | ✅ 成立 |
| 子项 | OrderItem(订单项) | UnderwritingLetter(核保函件) | ⚠️ 部分成立 |
| 数量关系 | 1 订单 → N 商品项 | 1 核保任务 → N 函件(体检/健康/契调/财务) | ✅ 成立 |
| 生命周期 | 订单项随订单创建,不可独立存在 | 函件随核保任务创建,不可独立存在 | ✅ 成立 |
| 状态独立性 | 订单项通常无独立状态机 | 函件有独立状态机(下发→回销→超时) | ❌ 不成立!关键差异 |
| 业务语义 | 订单项是“购买内容” | 函件是“信息请求+等待响应”的异步交互过程 | ❌ 本质不同 |
✅ 结论:
- 结构上:可以类比为“1 对多”聚合关系(一个核保任务对应多个函件)
- 行为上:函件具有独立生命周期和状态流转,远比“订单项”复杂
- 更准确的类比:
核保任务(UnderwritingTask) ≈ 工单(Ticket)
核保函件(UnderwritingLetter) ≈ 工单下的子任务(Sub-task)或待办事项(To-do)
二、核保系统完整业务流程图(含状态机)
以下流程图分为 主流程 与 函件子流程,采用标准 BPMN + 状态机结合方式,便于开发者理解。
📊 图1:核保主流程(从投保到结论)
📊 图2:单个核保函件状态机(核心!)
三、核保系统详细说明文档(Java 后端开发者版)
1. 核心业务实体与聚合关系
1.1 聚合根:UnderwritingTask(核保任务)
- 来源:由
Application(投保申请)触发创建 - 职责:
- 管理所有关联函件
- 聚合函件状态,判断是否可进入人工复核
- 生成最终核保结论
- 关键字段:
String taskId; String applicationId; UnderwritingStatus status; // PENDING, IN_REVIEW, COMPLETED, REJECTED List<UnderwritingLetter> letters; // 所有函件(值对象或实体)
1.2 子实体:UnderwritingLetter(核保函件)
- 类型:
MEDICAL,HEALTH,INVESTIGATION,FINANCIAL - 独立状态机:如上图所示
- 关键字段:
String letterId; String taskId; // 关联核保任务 LetterType type; LetterStatus status; // CREATED, ISSUED, RESPONDED... LocalDateTime issuedAt; LocalDate dueDate; // = issuedAt + TTL String responseFileId; // 回销材料文件ID String handler; // 处理人(核保员)
✅ DDD 建模建议:
UnderwritingTask是聚合根,UnderwritingLetter是聚合内的实体- 所有对函件的操作必须通过
UnderwritingTask或专用LetterService,禁止直接修改
2. 关键业务流程详解
流程1:函件下发(Issue Letter)
- 自动核保引擎判定需补充信息
- 创建
UnderwritingTask - 根据规则生成1~N个
UnderwritingLetter - 调用通知服务(短信/APP推送)下发函件
- 状态:
letter.status = ISSUED,记录issuedAt和dueDate
流程2:客户回销(Respond Letter)
- 客户通过APP/邮件上传材料
- 系统保存文件,更新
letter.responseFileId - 状态:
letter.status = RESPONDED - 触发事件:
LetterRespondedEvent(taskId)
流程3:超时处理(Handle Expired)
- 定时任务每日扫描
dueDate < today && status = PENDING_RESPONSE - 更新状态为
EXPIRED - 调用策略:
underwritingPolicy.handleExpired(taskId)- 策略1:自动拒保
- 策略2:转人工核保员处理
- 更新
UnderwritingTask.status = EXPIRED_HANDLED
流程4:人工复核(Manual Review)
- 当所有函件状态为
COMPLETED,任务进入IN_REVIEW - 核保员登录系统,查看所有回销材料
- 人工给出最终结论:
STANDARD,SUB_STANDARD,DECLINED等 - 任务状态:
COMPLETED,触发保单生成流程
3. 系统设计关键点(Java 实现建议)
3.1 状态机实现
- 推荐使用 Spring State Machine 或 自定义状态机 + 事件驱动
- 禁止直接 set 状态,必须通过
changeStatus()方法校验合法性
public void respondLetter(String letterId, String fileId) {
UnderwritingLetter letter = letterRepo.findById(letterId);
if (!letter.getStatus().equals(PENDING_RESPONSE)) {
throw new IllegalStateException("函件不在等待回销状态");
}
letter.setResponseFileId(fileId);
letter.setStatus(RESPONDED);
letterRepo.save(letter);
eventPublisher.publish(new LetterRespondedEvent(letter.getTaskId()));
}
3.2 超时处理定时任务
- 使用
@Scheduled+ 分页查询,避免全表扫描 - 支持配置化 TTL(不同函件类型不同)
# application.yml
underwriting:
letter-ttl:
MEDICAL: 15
HEALTH: 10
INVESTIGATION: 20
FINANCIAL: 15
3.3 文件存储与安全
- 回销材料(体检报告、病历)属于敏感个人信息
- 必须:
- 加密存储(如 AES + KMS)
- 访问控制(仅核保员可读)
- 操作日志(谁在何时下载了文件)
4. 高危注意事项(合规与风险)
| 风险点 | 说明 | 开发对策 |
|---|---|---|
| 函件无限期挂起 | 未设超时,核保流程卡死 | 强制 TTL + 自动处理 |
| 材料未校验完整性 | 客户上传空白文件 | 基础校验(文件大小、格式、必填项目) |
| 状态非法跳转 | 直接从 ISSUED → COMPLETED | 状态机严格校验 |
| 隐私泄露 | 体检报告明文存储 | 敏感字段加密 + RBAC 权限控制 |
| 监管无法追溯 | 无操作日志 | 所有关键操作写审计日志(含 traceId) |
四、附录:核保系统核心状态枚举(Java 示例)
// 核保任务状态
public enum UnderwritingTaskStatus {
PENDING("待处理"),
IN_REVIEW("人工复核中"),
COMPLETED("已完成"),
EXPIRED_HANDLED("超时已处理"),
REJECTED("已拒保");
}
// 函件状态
public enum LetterStatus {
CREATED("已创建"),
ISSUED("已下发"),
PENDING_RESPONSE("等待回销"),
RESPONDED("已回销"),
REVIEWED("已审核"),
COMPLETED("已完成"),
REJECTED("材料不全"),
EXPIRED("已超时"),
HANDLED("超时已处理");
}
// 函件类型
public enum LetterType {
MEDICAL_EXAM("体检函"),
HEALTH_INQUIRY("健康函"),
INVESTIGATION("契调函"),
FINANCIAL_VERIFICATION("财务函");
}
五、结语
核保系统不是简单的“发函-收函”流程,而是一个融合规则引擎、异步交互、人工干预、合规审计的复杂业务系统。
你的类比(订单 vs 订单项)帮助理解了聚合关系,但请务必重视:
- 函件的独立状态机
- 超时驱动的自动处理
- 敏感数据的合规要求
建议你在开发中:
- 以
UnderwritingTask为聚合根设计领域模型 - 为每个函件类型配置独立 TTL
- 所有状态变更走事件驱动,便于扩展(如超时通知、材料审核提醒)
1055

被折叠的 条评论
为什么被折叠?



