需求:
记录一个客户从注册到注销经历的各个生命周期节点,给与查询展示
设计:
1、生命周期节点分为以下几个流程:注册、授信、资料获取...(先开发部分流程,剩余用...表示)流程只有特定流程有顺序,有些流程是交叉进行的,比如授信和资料获取
2、生命周期节点主要信息是:描述、所属流程、失败原因、触发时间 节点有:开始节点、结束节点、流程唯一节点 默认一个流程内节点是可重复的,例如,审核拒绝->补件->审核拒绝->补件->审核成功这种操作 流程唯一节点是在这样的场景:决策提交前,每2分钟查询一次最新征信数据等,不管成功失败都查询 最新不通过无法提交决策,这种数据要求展示最新一次的节点数据,不是连接操作。 有些节点是各个流程公用的,例如税务授权,授信、提额都需要税务授权,针对这种目前是作为公共节点,直挂用户,下一个流程产生时挂载到流程
设计图:
数据库表:
-- 生命周期表 begin CREATE TABLE `supply_chain_dsc`.`scp_dsc_cust_life_cycle_process_node_item` ( `id` bigint(11) NOT NULL AUTO_INCREMENT, `item_no` varchar(20) NOT NULL COMMENT '节点条目编码', `process_no` varchar(20) DEFAULT NULL COMMENT '所属流程编码', `node_no` varchar(20) NOT NULL COMMENT '节点编码', `node_desc` varchar(50) NOT NULL COMMENT '节点描述', `result_no` varchar(50) NOT NULL COMMENT '节点结果', `result_desc` varchar(100) DEFAULT NULL COMMENT '节点条目描述', `is_start_node` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否开始节点:0-否、1-是', `is_complete_node` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否完成节点:0-否、1-是', `is_process_unique` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否流程唯一:0-否、1-是', `is_deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除:0-否、1-是', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用户生命周期流程节点表'; CREATE TABLE `supply_chain_dsc`.`scp_dsc_cust_life_cycle_process_node_record` ( `id` bigint(11) NOT NULL AUTO_INCREMENT, `process_record_id` bigint(11) DEFAULT NULL COMMENT '进程记录id', `life_cycle_record_id` bigint(20) NOT NULL COMMENT '生命周期记录id', `process_no` varchar(20) NOT NULL COMMENT '进程编码', `process_node_no` varchar(20) NOT NULL COMMENT '进程节点编码', `process_node_desc` varchar(50) NOT NULL COMMENT '进程节点描述', `process_node_item_no` varchar(20) DEFAULT NULL COMMENT '流程节点条目编码', `process_node_result` varchar(50) DEFAULT NULL COMMENT '流程节点结果', `completed_time` datetime NOT NULL COMMENT '完成时间', `fail_reason` varchar(500) DEFAULT NULL COMMENT '失败原因', `remark` varchar(255) DEFAULT NULL COMMENT '备注字段', `is_invalid` tinyint(1) DEFAULT '0' COMMENT '是否失效:0-否、1-是', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建日期', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新日期', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='生命周期进程节点记录表'; CREATE TABLE `supply_chain_dsc`.`scp_dsc_cust_life_cycle_process_record` ( `id` bigint(11) NOT NULL AUTO_INCREMENT, `life_cycle_record_id` int(11) NOT NULL COMMENT '用户生命周期id', `process_special_business_data` varchar(2000) DEFAULT '' COMMENT '流程专属业务数据,json。 不同流程结构不一致', `process_no` varchar(20) NOT NULL COMMENT '流程编码', `process_desc` varchar(50) NOT NULL COMMENT '流程描述', `is_invalid` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否失效:0-否、1-是', `is_completed` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否完成:0-否、1-是', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建日期', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新日期', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用户生命周期流程记录表'; CREATE TABLE `supply_chain_dsc`.`scp_dsc_cust_life_cycle_record` ( `id` bigint(11) unsigned NOT NULL AUTO_INCREMENT, `user_id` varchar(12) NOT NULL COMMENT '用户id', `certificate_no` varchar(30) DEFAULT NULL COMMENT '证件号码', `certificate_type` varchar(2) DEFAULT NULL COMMENT '证件类型 01-身份证号、02-社会信用代码', `project_id` varchar(50) DEFAULT NULL COMMENT '项目id', `project_name` varchar(64) DEFAULT NULL COMMENT '项目名称', `cust_name` varchar(128) DEFAULT NULL COMMENT '客户名称', `related_party_name` varchar(128) DEFAULT NULL COMMENT '关联方名称', `process_node_item_no` varchar(20) NOT NULL COMMENT '当前流程节点编码', `process_no` varchar(20) NOT NULL COMMENT '当前流程编码', `process_node_desc` varchar(50) DEFAULT NULL COMMENT '当前节点描述', `is_show` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否展示:0-否、1-是', `register_time` datetime NOT NULL COMMENT '注册时间', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用户生命周期记录表';
主要代码:
1、接收对象转存储对象
/** * 生命周期节点结果Mq接收 * @author zhen * @date 2022/11/28 9:16 * @description */ @Data public class LifeCycleNodeResultMqEvent implements Serializable { /** * 节点Item编码 必填 */ private String processNodeItemNo; /** * 完成时间: yyyy-MM-dd HH:mm:ss 必填 */ private String completeTime; /** * 失败原因 */ private String failReason; /** * 项目id 除了注册流程指定节点之外,必填 */ private String projectId; /** * 证件类型: 01-身份证号、02-社会信用代码 除了注册流程指定节点之外,必填 */ private String certificateType; /** * 证件号 除了注册流程指定节点之外,必填 */ private String certificateNo; /** * 节点属性json */ private String processPropertyJson; } /** * 注册流程属性event * @author zhen * @date 2022/11/28 9:35 * @description */ @Data public class LifeCycleRegisterProcessPropertyEvent implements Serializable { /** * 手机号 */ private String phone; /** * 用户id */ private String userId; /** * 身份证号 */ private String idCardNo; /** * 用户姓名 */ private String userName; /** * 企业名称 */ private String enterpriseName; } /** * 注册流程数据Template * @author zhen * @date 2022/11/28 9:35 * @description */ @Data public class LifeCycleRegisterProcessDataTemplate implements Serializable { /** * 手机号 */ private String phone; /** * 用户id */ private String userId; /** * 身份证号 */ private String idCardNo; /** * 用户姓名 */ private String userName; }
核心代码:
@Override @Transactional(rollbackFor = Exception.class) public void receiptProcessNodeResult(LifeCycleNodeResultMqEvent event) { CustLifeCycleProcessNodeItem nodeItem = lifeCycleProcessNodeItemService.findByNodeItemNo(event.getProcessNodeItemNo()); if (nodeItem == null) { log.info("【客户生命周期】根据节点item编号找不到对应的属性节点 nodeItemNo:{}", event.getProcessNodeItemNo()); return; } if(ProcessSpecialNodeItemEnum.isValidValue(nodeItem.getItemNo())){ nodeSpecialDeal(nodeItem, event); }else { normalNodeDeal(nodeItem, event); } } private String transProcessDataEventValueToTemplateValue(String eventValueJson, String processNo){ if (StringUtils.isEmpty(eventValueJson) || "{}".equals(eventValueJson)){ return "{}"; } ProcessTemplateTransEnum templateTransEnum = ProcessTemplateTransEnum.getByValue(processNo); if (templateTransEnum != null) { try{ Class srcClazz = Class.forName(templateTransEnum.getSrcClazzName()); Class targetClazz = Class.forName(templateTransEnum.getSrcClazzName()); Object srcObj = JSON.parseObject(eventValueJson, srcClazz); Object targetObject = targetClazz.newInstance(); BeanUtils.copyProperties(srcObj, targetObject); return JSON.toJSONString(targetObject); } catch (IllegalAccessException|InstantiationException|ClassNotFoundException e) { log.error("对象转换异常", e); throw new RuntimeException("客户生命周期流程对象转换异常"); } } return "{}"; } private void nodeSpecialDeal(CustLifeCycleProcessNodeItem nodeItem, LifeCycleNodeResultMqEvent event){ Class<LifeCycleNodeItemReceiptBusinessImpl> clazz = LifeCycleNodeItemReceiptBusinessImpl.class; try{ Method invokeMethod = clazz.getMethod("n" + nodeItem.getItemNo() + "Deal", CustLifeCycleProcessNodeItem.class, LifeCycleNodeResultMqEvent.class); invokeMethod.invoke(this, nodeItem, event); }catch (NoSuchMethodException|IllegalAccessException|InvocationTargetException e) { log.error("【LEVEL:LOW】找不到处理此特殊节点结果的执行器, 节点结果编码:{}", nodeItem.getItemNo()); return; } } /** * 常用节点处理 * @param nodeItem * @param event */ private void normalNodeDeal(CustLifeCycleProcessNodeItem nodeItem, LifeCycleNodeResultMqEvent event) { CustLifeCycleRecord nodeLifeCycleRecord = getLifeCycleRecordByBusinessPk(event); if (nodeLifeCycleRecord == null) { return; } normalNodeDealUseLifeCycle(nodeLifeCycleRecord, nodeItem, event); } /** * 已知生命周期情况下常用节点处理 * @param nodeLifeCycleRecord * @param nodeItem * @param event */ private void normalNodeDealUseLifeCycle(CustLifeCycleRecord nodeLifeCycleRecord, CustLifeCycleProcessNodeItem nodeItem, LifeCycleNodeResultMqEvent event){ //生命周期记录更新 normalLifeCycleUpdate(nodeLifeCycleRecord, nodeItem); CustLifeCycleProcessRecord processRecord = lifeCycleProcessRecordService.selectCurrentProcessRecord(nodeLifeCycleRecord.getId(), nodeItem.getProcessNo()); //节点保存 nodeItemSave(nodeLifeCycleRecord.getId(), processRecord == null ? null : processRecord.getId(), nodeItem, event); } /** * 公用节点挂载 * @param processRecord */ private void commonNodeMount(CustLifeCycleProcessRecord processRecord ){ List<CustLifeCycleProcessNodeRecord> nodeRecordList = lifeCycleProcessNodeRecordService.selectUnMountNodeRecordList(processRecord.getLifeCycleRecordId()); for (CustLifeCycleProcessNodeRecord nodeRecord : nodeRecordList) { nodeRecord.setProcessNo(processRecord.getProcessNo()); nodeRecord.setProcessRecordId(processRecord.getId()); } lifeCycleProcessNodeRecordService.updateBatchById(nodeRecordList); } /** * 常用的生命周期更新操作 * @param lifeCycleRecord * @param nodeItem */ private void normalLifeCycleUpdate(CustLifeCycleRecord lifeCycleRecord, CustLifeCycleProcessNodeItem nodeItem){ lifeCycleRecord.setProcessNo(nodeItem.getProcessNo()); lifeCycleRecord.setProcessNodeDesc(nodeItem.getNodeDesc()); lifeCycleRecord.setProcessNodeItemNo(nodeItem.getItemNo()); lifeCycleRecord.setUpdateTime(LocalDateTime.now()); lifeCycleRecordService.updateById(lifeCycleRecord); } /** * 常用的保存节点操作 * @param lifeCycleRecordId * @param processRecordId * @param nodeItem * @param event */ private void nodeItemSave(Long lifeCycleRecordId, Long processRecordId, CustLifeCycleProcessNodeItem nodeItem, LifeCycleNodeResultMqEvent event) { CustLifeCycleProcessRecord processRecord = null; if (processRecordId == null) { if (nodeItem.getIsStartNode() == 1) { //创建流程记录 processRecord = buildNormalProcessRecord(lifeCycleRecordId, nodeItem); processRecord.setProcessSpecialBusinessData(transProcessDataEventValueToTemplateValue(event.getProcessPropertyJson(), nodeItem.getProcessNo())); lifeCycleProcessRecordService.save(processRecord); } }else { processRecord = lifeCycleProcessRecordService.getById(processRecordId); } if (processRecord != null){ processRecordId = processRecord.getId(); //公用节点挂载 commonNodeMount(processRecord); /* * 完成节点特殊处理 */ if (1 == nodeItem.getIsCompleteNode()) { //0 -否、1-是 公用节点不可能是完成节点,因此,不会出现空指针 processRecord.setIsCompleted(1); lifeCycleProcessRecordService.updateById(processRecord); } } if(nodeItem.getIsProcessUnique() == 1){ //保存最新记录的节点操作就死update最新信息 CustLifeCycleProcessNodeRecord processNoRecord = lifeCycleProcessNodeRecordService.findProcessNoRecord(lifeCycleRecordId, processRecordId, nodeItem.getItemNo()); if (processNoRecord != null){ CustLifeCycleProcessNodeRecord nodeRecord = buildNormalUpdateProcessNodeRecord(processNoRecord, event); lifeCycleProcessNodeRecordService.updateById(nodeRecord); }else { CustLifeCycleProcessNodeRecord nodeRecord = buildNormalProcessNodeRecord(lifeCycleRecordId, processRecordId, nodeItem, event); lifeCycleProcessNodeRecordService.save(nodeRecord); } }else { CustLifeCycleProcessNodeRecord nodeRecord = buildNormalProcessNodeRecord(lifeCycleRecordId, processRecordId, nodeItem, event); lifeCycleProcessNodeRecordService.save(nodeRecord); } }View Code
标签:COMMENT,生命周期,varchar,DEFAULT,流程,客户,nodeItem,NULL,节点 From: https://www.cnblogs.com/aigeileshei/p/16955990.html