23 KiB
WorkOrderServiceImpl.saveCustomWorkOrder 中 domain_request 分支梳理
目标:把
saveCustomWorkOrder里if (WorkOrderEnums.Type.domain_request.name().equals(workList.getType()))这一支的整体链路、分支条件、以及涉及的库表操作梳理清楚(包含精确/泛域名、批量/非批量两条线),用于后续重构前的理解与拆分。
0. 入口位置与范围
入口方法:
WorkOrderServiceImpl.saveCustomWorkOrder(…)
cdn-service/src/main/java/com/cmcc/cdn/platform/selfservice/order/WorkOrderServiceImpl.java:2634
本文聚焦分支:
WorkOrderServiceImpl.saveCustomWorkOrder中
if (WorkOrderEnums.Type.domain_request.name().equals(workList.getType())) { … }
WorkOrderServiceImpl.java:2664
1. saveCustomWorkOrder 的前置校验(进入 domain_request 分支之前)
1.1 登录态与企业操作权限校验
- 登录态为空直接失败:
WorkOrderServiceImpl.java:2635-2637 - 校验当前用户是否能操作
workList.enterprise:- 读取当前用户可操作的企业列表:
enterpriseService.getNewCustomDisplay(SecurityUserUtil.getId()) - 若
workList.enterprise != 当前登录企业且也不在可操作企业列表里:抛错
WorkOrderServiceImpl.java:2638-2643
- 读取当前用户可操作的企业列表:
涉及表:这里主要是服务查询,具体表在 enterpriseService 内部(本文不展开)。
1.2 企业信息读取(用于后续显示/通知等)
- 通过
enterpriseInfoDao.findByEnterpriseId(workList.getEnterprise())拿企业名称
WorkOrderServiceImpl.java:2646-2649
enterprise_info(推断)被读;实际表名需以EnterpriseInfo实体为准。
1.3 CP 角色分支:配置校验 + model 文案拼接
如果当前登录角色为企业账号(CP):
checkOrderConfig(workList)校验姓名/手机号/邮箱格式
WorkOrderServiceImpl.java:2650-2652
WorkOrderServiceImpl.java:3038-3049workList.model解析成文案(CustomOrderEnums.ModelVO)
WorkOrderServiceImpl.java:2652-2658
1.4 附件数量限制
workList.md5List(通用附件)最多 5 个
WorkOrderServiceImpl.java:2660-2662
2. domain_request 分支总览(主流程)
核心代码范围:
WorkOrderServiceImpl.java:2664-2734
整体顺序可以理解为:
- 企业惩戒复核(联合惩戒黑名单)
- 调
DomainOrderService.handleWithDomainOrder生成/更新域名配置需求工单(含写库) - 若是修改重提:清理历史“信安附件 file_info + 工单附件关联 log_file_resource”冗余
- 重建本次提交的附件关联(log_file_resource)
- 绑定工单-企业关系(worker_order_enterprise)
- 触发信安/备案号校验与流程流转(WorkOrderManager)
- 拼 domainInfo / enterpriseInfo 写入 request header(疑似用于后续启动 BPM 或审计)
- 特殊:若工单已落 BPM 且为新建(非修改),则覆盖工单下一处理人
下面按步骤拆开。
3. Step 1:联合惩戒复核(企业是否被惩戒)
recheckEnterprisePunishmentStatus(info)
WorkOrderServiceImpl.java:2665-2666
方法本体:WorkOrderServiceImpl.java:2753-2772
逻辑要点:
- info 不存在:仅 warn,不阻断(
2754-2757) - 调用 BBoss 联合惩戒查询:
bBossInteractiveService.queryJointPunish(enterpriseInfo.getEcId())(2759) - 若响应失败或已惩戒:抛
PlatformException阻断(2761-2771)
库表:无直接 DB 写入(是外部接口/服务调用)。
4. Step 2:创建/修改域名配置需求工单(核心入库点)
4.1 是否修改重提
boolean isModify = Objects.nonNull(workList.getId());
WorkOrderServiceImpl.java:2667
这里的
workList.id代表 work_order.id(运营总表主键)。
4.2 调用 DomainOrderService.handleWithDomainOrder(★主入口)
ConfigureDomainOrderPO domainOrderPO = domainOrderService.handleWithDomainOrder(workList, modelStr);
WorkOrderServiceImpl.java:2669
该方法位置:
DomainOrderService.handleWithDomainOrder(…)
cdn-service/src/main/java/com/cmcc/cdn/platform/selfservice/order/DomainOrderService.java:2569
4.2.1 handleWithDomainOrder:域名规模/泛域名/迁移工单校验
- 单次 add/delete 的域名数上限(配置项
MAX_DOMAIN_ADD_SIZE,默认 100)
DomainOrderService.java:2570-2574 - 域名存在性校验(域名表或工单表):
domainStateService.checkDomainExist(domains, workList.getCode(), workList.getRequirement())
DomainOrderService.java:2576-2580 - 新增(add)时泛域名包含关系校验(泛域名之间、与系统已有泛域名)
DomainOrderService.java:2587-2596 - 删除(delete)时校验不能存在未完成的域名迁移工单
domainMigrateService.judgeUnCompleteDomainMigRateOrder(domains)
DomainOrderService.java:2598-2609 - 省份“全国(33)”展开为 31 省
DomainOrderService.java:2612-2617 - 非 delete 时:BSS/THIRD/WEB 来源企业必须上传信安附件
DomainOrderService.java:2625-2632
最后落到:
return checkAndSaveConfigDomain(workList, modelStr);
DomainOrderService.java:2633
4.2.2 checkAndSaveConfigDomain:批量/非批量分流、重复工单校验、入域名表
入口:
DomainOrderService.checkAndSaveConfigDomain(…)
DomainOrderService.java:2328
关键分支:
-
批量单要求必须有
fileId(批量附件)- 若
isBatch=true,把fileIdfallback 为secInfoFileId[0](存在明显历史兼容)
DomainOrderService.java:2333-2338
- 若
-
非批量必须有 speedList;删除时还校验域名状态
DomainOrderService.java:2339-2351 -
修改重提场景:允许同域名的“进行中工单”只排除自己
- 查询
configure_list + speed_configure_domain的进行中工单:
orderRepository.findByDomainAndStatusIsNot(domain, Finish)
DomainOrderService.java:2354-2373 DomainOrderRepository.findByDomainAndStatusIsNot是 native join(见库表章节)
- 查询
-
直播产品不支持冲突域名(cpDomain)场景
DomainOrderService.java:2393-2397
然后真正保存工单子表(configure_list):
ConfigureDomainOrderPO domainOrderPO = saveConfigureDomain(workList, modelStr);
DomainOrderService.java:2398
并且在 domain_request + requirement=CREATE 情况下,会把域名落到域名配置表:
- 批量:从
batch_self_domain生成self_service_domain_config
DomainOrderService.java:2406-2444 - 非批量:从
speed_configure_domain生成self_service_domain_config
DomainOrderService.java:2445-2481
这一步是 “域名入域名表” 的关键点:
selfServiceDomainConfigDao.saveAll(…)。
5. Step 2.3 saveConfigureDomain:work_order / configure_list / 关联表写入(非常关键)
入口:
DomainOrderService.saveConfigureDomain(…)
DomainOrderService.java:509
5.1 “workList.type == domain_request” vs “最终写入 work_order.type”
这里有一个容易踩坑的点:
saveCustomWorkOrder的分支条件看的是workList.getType()(前端传参)- 但
saveConfigureDomain内部会根据是否 CP 账号改写实际工单类型:cpFlag=true⇒workType = WorkOrderEnums.Type.configure- 否则
workType = WorkOrderEnums.Type.domain_request
DomainOrderService.java:510-513
也就是说:同样走 domain_request 分支,落库可能是 configure 或 domain_request 两种工单类型(看当前登录角色)。
5.2 修改重提(isModify)的认定
isModify = workList.id != null && workType == domain_request
DomainOrderService.java:514-515- 修改时:
- 读取旧
work_order:workOrderService.findById(workList.getId())(516) - 用新的域名列表覆盖
work_order.details(517-521) - 同时记录旧的 speedDomains,稍后删除旧关联行
DomainOrderService.java:565-575
- 读取旧
5.3 非批量新建:work_order 复用/创建 & 工单号生成
非批量 !isBatch 时:
- 通过
customService.getWorkOrder(workType, domains, enterprise)获取/复用work_order
DomainOrderService.java:523-528 - 如果
workOrder为空且不是 delete:生成 code- domain_request:调用
workOrderService.getWorkOrderCode(domain_request)
DomainOrderService.java:534-536 - configure:随机 16 位并保证不重复
DomainOrderService.java:537-543
- domain_request:调用
5.4 信安附件内容校验(重要:精确/泛域名都在这里做一致性校验)
- 非 delete 时做校验:
checkUnitInfomation(workList, workOrder.getCode())
DomainOrderService.java:545-548
方法本体:
DomainOrderService.checkUnitInfomation(WorkOrderVO, workId)
DomainOrderService.java:372
关键点:
- 海外产品(ProdTypeEnum.isOverseas)且是 domain_request:跳过信安附件校验
DomainOrderService.java:373-377 - 读取信安 Excel(从
secInfoFileId[0])解析为对象:
excelUtil.convertToObjectFromExcel(…)
DomainOrderService.java:379-384 - 信安信息不允许泛域名(domain 以
*开头直接抛错)
DomainOrderService.java:385-389 - 若是泛域名(EXTENSIVEDOMAIN):
- 校验上传信安域名与页面 subdomain 列表一一对应、备案号一致
DomainOrderService.java:391-403
- 校验上传信安域名与页面 subdomain 列表一一对应、备案号一致
- 若是精确域名(非 EXTENSIVE):
- 校验上传信安域名与页面 speedList 一一对应、备案号一致
DomainOrderService.java:404-416
- 校验上传信安域名与页面 speedList 一一对应、备案号一致
- 校验域名未在域名表中存在:
selfServiceDomainConfigDao.findByDomain(domain)
DomainOrderService.java:420-426 - 给每条信安记录打上
informaionId = workId(这里的 workId 实际是工单 code)
DomainOrderService.java:427-429
这里的校验是“前端页面填写信息”与“上传信安模板内容”的强一致校验,是后续重构时最容易拆坏的点。
5.5 生成 ConfigureDomainOrderPO 并保存(configure_list)
-
非批量:用
ConfigureDomainOrderPO.createDomainOrderPO(…)构造
DomainOrderService.java:579-583
对应实体表:configure_list(ConfigureDomainOrderPO.java:40-41) -
批量:走
createConfigureDomainOrderPOFromBatchDomainFile(…)
DomainOrderService.java:577-579
批量域名表:
BatchSelfDomainPO=>batch_self_domain
BatchSelfDomainPO.java:32-33
关联的“加速域名明细”表:
SpeedConfigureDomainPO=>speed_configure_domain
SpeedConfigureDomainPO.java:26-27
5.6 泛域名(EXTENSIVEDOMAIN):子域名入库(sub_domain + join 表)
如果 workList.domainType == EXTENSIVEDOMAIN:
- 校验每个子域名必须属于该泛域名后缀
domainOrderPO.setSubDomains(…)存子域名列表(SubDomainPO)
DomainOrderService.java:611-625
子域名表:
sub_domain(SubDomainPO.java:20-21)
join 表:
work_order_domain_request_sub(在ConfigureDomainOrderPO的@JoinTable上)
ConfigureDomainOrderPO.java:139-145
5.7 修改重提:删除旧 speed_configure_domain
- 若
preSpeedDomains非空:speedConfigureDomainDao.deleteAll(preSpeedDomains)
DomainOrderService.java:629-633
5.8 保存 configure_list + 追加 domain_history 记录
-
ConfigureDomainOrderPO p = orderRepository.save(domainOrderPO);
DomainOrderService.java:635 -
domain_history:至少写 1 条
- 修改重提:
Button.submit
DomainOrderService.java:637-640 - 普通新建:result 为 null
DomainOrderService.java:641-643
- 修改重提:
此外(非海外 + 创建单)还会写一条“控制信安信息显示/校验状态”的记录:
DomainHistoryPO.create(p.getId(), false, false, submit)
DomainOrderService.java:651-654
6. Step 3:修改重提时的“历史附件清理”(file_info + log_file_resource)
回到 WorkOrderServiceImpl.saveCustomWorkOrder:
如果 isModify=true:
-
查旧 configure_list(通过 work_order.id)拿 orgEnterId:
ConfigureDomainOrderPO orgPo = orderRepository.findByWorkOrderId(workList.getId()).orElse(null);orgEnterId = orgPo.getTenantId();
WorkOrderServiceImpl.java:2671-2672
-
删除历史信安附件(file_info)冗余:
deleteHistoryFileInfo(workList, domainOrderPOId)
WorkOrderServiceImpl.java:2676
方法:WorkOrderServiceImpl.java:3660-3683
其删除策略:
- 新提交的
secInfoFileId为空则不删 - 查当前工单关联的 log_file_resource,取
fileContentType == security_info的 md5 列表 oldMd5.removeAll(newSecInfoFileId)得到“旧有但本次未再使用”的 md5fileInfoDao.findByMd5In(oldMd5)并fileInfoDao.deleteAll(…)
WorkOrderServiceImpl.java:3663-3679
涉及表:
file_info(FileInfoPO.java:30-31)log_file_resource
- 清空该 configure_list 下的所有附件关联:
logFileResourceRepository.deleteAllByOrderId(domainOrderPOId)
WorkOrderServiceImpl.java:2678-2682
repository:LogFileResourceRepository.deleteAllByOrderId
LogFileResourceRepository.java:147-149
7. Step 4:重建本次提交的附件关联(log_file_resource)
无论新建还是修改,都会重新生成附件关联:
7.1 md5List(最多 5 个)
logOrderService.saveFilesToTable(domainOrderPO.getId(), workList.getMd5List(), WorkOrderEnums.Type.configure);
WorkOrderServiceImpl.java:2684-2685
LogOrderService.saveFilesToTable(…):
- 对 list 中每个 md5 插入
LogFileResource(type, md5, orderId)
LogOrderService.java:761-772
7.2 fileId(单文件,标记 domain_config)
logOrderService.saveFiles([LogFileResource.create(…, FileContentTypeEnum.domain_config)])
WorkOrderServiceImpl.java:2686-2689
7.3 secInfoFileId(信安附件,标记 security_info)
- 遍历每个 md5,插入
LogFileResource(…, FileContentTypeEnum.security_info)
WorkOrderServiceImpl.java:2690-2697
LogFileResource 说明:
- repository 的 SQL 指向
log_file_resource。 - 字段
md5注释说明“是 mongodb_Id 值,不是文件 md5 值”(非常重要)
LogFileResource.java:51
8. Step 5:绑定工单与企业关系(worker_order_enterprise)
workOrderService.setNewWorkOrderEnterpriseForDR(workOrderId, newEnterpriseId, orgEnterpriseId)
WorkOrderServiceImpl.java:2698-2701
方法位置:
WorkOrderServiceImpl.setNewWorkOrderEnterpriseForDR(…)
WorkOrderServiceImpl.java:1183-1209
逻辑:
- 若
orgEnterpriseId不为空(修改工单)且企业变更:- 查
worker_order_enterprise记录并更新enterpriseId/enterpriseType
WorkOrderServiceImpl.java:1185-1196
- 查
- 否则(新建):
- 插入一条新的
WorkOrderEnterprise
WorkOrderServiceImpl.java:1197-1208
- 插入一条新的
表:
worker_order_enterprise(注意表名是 worker_order_enterprise)
WorkOrderEnterprise.java:22-23
9. Step 6:触发信安/备案号校验与流程流转(WorkOrderManager)
workOrderManager.handleDomainConfigXinAnInfo(SecurityUserUtil.getId(), domainOrderPO.getId());
WorkOrderServiceImpl.java:2702-2703
方法位置:
WorkOrderManager.handleDomainConfigXinAnInfo(…)
WorkOrderManager.java:58-92
核心逻辑(只说需求类相关):
-
读 configure_list:
orderRepository.findById(orderId)
WorkOrderManager.java:59
-
若 operateType == CREATE:
- 海外产品:直接
updateNextCheckUserInOrderSubmit(…)并返回
WorkOrderManager.java:62-67 - 非海外:先刷新备案号/一致性状态:
domainOrderService.updateCheckedIcpInfo(po)
WorkOrderManager.java:68- 如果
checkDomainIcpEqual(po)为 true:uploadInformation(po)(同步信安系统)
WorkOrderManager.java:71-73 - 最后如果仍然
checkDomainIcpEqual(po)为 true:进入流转
domainOrderService.updateNextCheckUserInOrderSubmit(…)
WorkOrderManager.java:83-85
- 海外产品:直接
-
若 operateType != CREATE:直接
updateNextCheckUserInOrderSubmit(…)
WorkOrderManager.java:86-88
10. Step 7:拼 domainInfo/enterpriseInfo 写入请求头(包含精确+批量域名)
代码位置:
WorkOrderServiceImpl.java:2704-2726
逻辑:
-
先从
domainOrderPO.getSpeedDomains()拿域名(对应speed_configure_domain)
WorkOrderServiceImpl.java:2706-2708 -
如果
domainOrderPO.getBatchId() != null:- 查
batch_self_domain:batchSelfDomainDao.findByBatchId(domainOrderPO.getBatchId())
WorkOrderServiceImpl.java:2709-2713 - 把批量域名也加入 domains
- 查
-
domains 去重(Set)
WorkOrderServiceImpl.java:2716-2719 -
拼成
"a.com,b.com"写入 header:req.putHeader("domainInfo", "…")req.putHeader("enterpriseInfo", domainOrderPO.getTenantId())
WorkOrderServiceImpl.java:2720-2726
11. Step 8:BPM 已存在且是新建(非修改)时的特殊“下一处理人覆盖”
代码:
WorkOrderServiceImpl.java:2726-2733
条件:
BpmTaskPO bpmTaskPO = bpmTaskDao.findByCode(domainOrderPO.getWorkOrder().getCode());if (bpmTaskPO != null && !isModify) { … }
动作:
WorkOrder workOrder = workOrderRepository.findByMyId(domainOrderPO.getId());
WorkOrderServiceImpl.java:2728
这里传入的是
domainOrderPO.getId()(configure_list.id),但方法名findByMyId从语义上更像查 work_order.id。后续重构/排雷建议重点确认。
然后:
orderDao.findByEcId(enter.get().getEcId())找到 BBoss 侧订单- 取
currentUserId找用户,设置为工单审批人:workOrder.setApprovingUser(users);workOrderRepository.save(workOrder);
WorkOrderServiceImpl.java:2729-2733
涉及表(推断/部分不在本文展开):
bpm_task(bpmTaskDao)work_order(workOrderRepository)bboss order相关表(orderDao/OrderInfo)
12. 涉及库表与操作一览(按“表 -> 操作 -> 代码点”)
12.1 work_order(运营总表)
- 新建/复用/修改 details、设置 code、corpName、省份信息、审批人等
DomainOrderService.saveConfigureDomain:DomainOrderService.java:523-563、679-698 - 设置下一审批人(dealer/approvingUser/userTemp)
DomainOrderService.updateNextCheckUserInOrderSubmit:DomainOrderService.java:1130-1168
12.2 configure_list(域名配置需求工单子表)
- 保存 configure_list 主记录
DomainOrderService.saveConfigureDomain:DomainOrderService.java:635 - 保存备案号查询结果 recordNumber(非批量)
DomainOrderService.updateCheckedIcpInfo:DomainOrderService.java:977-982
实体:
ConfigureDomainOrderPO=>configure_list
ConfigureDomainOrderPO.java:40-41
12.3 speed_configure_domain(工单加速域名明细)
- 新建:由
ConfigureDomainOrderPO.createDomainOrderPO生成并随 configure_list 保存
DomainOrderService.java:579-583 - 修改重提:删除旧的 speedDomains 记录
speedConfigureDomainDao.deleteAll(preSpeedDomains)
DomainOrderService.java:629-633
实体:
SpeedConfigureDomainPO=>speed_configure_domain
SpeedConfigureDomainPO.java:26-27
12.4 batch_self_domain(批量域名明细)
- 批量新建时写入(saveBatchDomains / saveAll)
DomainOrderService.createConfigureDomainOrderPOFromBatchDomainFile:DomainOrderService.java:721-723 - ICP 查询后回写 recordNumber/icpEquals
DomainOrderService.updateCheckedIcpInfo:DomainOrderService.java:934-963 - saveCustomWorkOrder 用于拼装 domainInfo(按 batchId 查询)
WorkOrderServiceImpl.java:2709-2713
实体:
BatchSelfDomainPO=>batch_self_domain
BatchSelfDomainPO.java:32-33
12.5 self_service_domain_config(域名配置表/域名主表)
- domain_request 且 requirement=CREATE 时:把域名插入域名表(批量/非批量两条线)
DomainOrderService.checkAndSaveConfigDomain:DomainOrderService.java:2400-2481 - ICP 查询后更新 legal(合法性)
DomainOrderService.updateCheckedIcpInfo:DomainOrderService.java:954-955、975-976、988-989
实体:
SelfServiceDomainConfigPO=>self_service_domain_config
SelfServiceDomainConfigPO.java:79-80
12.6 domain_history(域名配置需求工单历史)
- 保存初始/提交记录、IC P 校验控制记录等
DomainOrderService.saveConfigureDomain:DomainOrderService.java:636-654 - ICP 校验完成标记
DomainOrderService.updateCheckedIcpInfo:DomainOrderService.java:992-999、956-962 - 异常时写 msg(WorkOrderManager 捕获 uploadInformation 异常)
WorkOrderManager.java:75-78
实体:
DomainHistoryPO=>domain_history
DomainHistoryPO.java:21-22
12.7 log_file_resource(工单附件关联表)
- 修改重提时:按 orderId(configure_list.id)清空
logFileResourceRepository.deleteAllByOrderId(domainOrderPOId)
WorkOrderServiceImpl.java:2678-2682 - 新建附件关联:
- md5List:
LogOrderService.saveFilesToTable
WorkOrderServiceImpl.java:2684-2685/LogOrderService.java:761-772 - fileId(domain_config):
WorkOrderServiceImpl.java:2686-2689 - secInfoFileId(security_info):
WorkOrderServiceImpl.java:2690-2697
- md5List:
12.8 file_info(信安附件内容落库)
- 修改重提时:根据“旧的安全信息 md5 列表”删除 file_info 记录
WorkOrderServiceImpl.deleteHistoryFileInfo:WorkOrderServiceImpl.java:3660-3679
实体:
FileInfoPO=>file_info
FileInfoPO.java:30-31
12.9 worker_order_enterprise(工单-企业关系映射)
- 新建工单:插入映射
- 修改且企业变更:更新映射
WorkOrderServiceImpl.setNewWorkOrderEnterpriseForDR:WorkOrderServiceImpl.java:1183-1209
实体:
WorkOrderEnterprise=>worker_order_enterprise
WorkOrderEnterprise.java:22-23
12.10 sub_domain / work_order_domain_request_sub(泛域名子域名)
- EXTENSIVEDOMAIN 时保存子域名集合(SubDomainPO)
- join 表:
work_order_domain_request_sub(配置在 ConfigureDomainOrderPO 上)
ConfigureDomainOrderPO.java:139-145
SubDomainPO.java:20-21
13. 重构前建议你重点“标注/解耦”的风险点(仅提示,不做重构方案)
-
domain_request 分支里实际落库的工单类型可能是 configure 或 domain_request
根因:saveConfigureDomain的cpFlag ? configure : domain_request
DomainOrderService.java:510-513 -
修改重提的附件清理策略:同时删
log_file_resource+file_info,并且LogFileResource.md5实际是 mongodb_id
WorkOrderServiceImpl.java:2673-2682、3660-3679、LogFileResource.java:51 -
BPM 存在时覆盖审批人 的取数链路(
workOrderRepository.findByMyId(domainOrderPO.getId()))参数语义可疑
WorkOrderServiceImpl.java:2726-2733