|
|
@@ -0,0 +1,319 @@
|
|
|
+package cn.start.tz.module.pressure2.service.boilerlegalreport;
|
|
|
+
|
|
|
+import cn.hutool.core.collection.CollUtil;
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
+import cn.start.tz.framework.mybatis.core.query.LambdaQueryWrapperX;
|
|
|
+import cn.start.tz.module.infra.api.config.ConfigApi;
|
|
|
+import cn.start.tz.module.pressure2.controller.admin.boilertaskorder.vo.BoilerOrderItemAddReportV2VO;
|
|
|
+import cn.start.tz.module.pressure2.controller.admin.boilertaskorder.vo.BoilerTaskOrderSyncReportVO;
|
|
|
+import cn.start.tz.module.pressure2.dal.dataobject.boilerconnectrecordreport.BoilerConnectRecordReportDO;
|
|
|
+import cn.start.tz.module.pressure2.dal.dataobject.boilertaskorderitem.BoilerTaskOrderItemDO;
|
|
|
+import cn.start.tz.module.pressure2.dal.dataobject.boilertaskorderitemreport.BoilerTaskOrderItemReportDO;
|
|
|
+import cn.start.tz.module.pressure2.dal.dataobject.boilertaskorderitemreportuser.BoilerTaskOrderItemReportUserDO;
|
|
|
+import cn.start.tz.module.pressure2.dal.dataobject.dynamictb.DynamicTbDO;
|
|
|
+import cn.start.tz.module.pressure2.dal.mysql.boilerconnectrecordreport.BoilerConnectRecordReportMapper;
|
|
|
+import cn.start.tz.module.pressure2.dal.mysql.boilertaskorderitem.BoilerTaskOrderItemMapper;
|
|
|
+import cn.start.tz.module.pressure2.dal.mysql.boilertaskorderitemreport.BoilerTaskOrderItemReportMapper;
|
|
|
+import cn.start.tz.module.pressure2.dal.mysql.boilertaskorderitemreportuser.BoilerTaskOrderItemReportUserMapper;
|
|
|
+import cn.start.tz.module.pressure2.dal.mysql.dynamictb.DynamicTbMapper;
|
|
|
+import cn.start.tz.module.pressure2.enums.TaskOrderStatusEnum;
|
|
|
+import cn.start.tz.module.pressure2.service.boilertaskorder.BoilerTaskOrderService;
|
|
|
+import jakarta.annotation.Resource;
|
|
|
+import lombok.extern.log4j.Log4j2;
|
|
|
+import org.springframework.context.annotation.Lazy;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.validation.annotation.Validated;
|
|
|
+
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Set;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 锅炉委托检验报告生成 Service 实现类
|
|
|
+ *
|
|
|
+ * 定检存在委托收费项目时,每个设备项都需要生成一份委托检验报告。
|
|
|
+ * 配置 key:boiler_legal_report_code,格式 "记录模板tbCode,报告模板tbCode"(逗号分隔)。
|
|
|
+ * 通过 tbCode 找到 DynamicTbDO 模板,再通过模板 id 找到项目类 BoilerConnectRecordReportDO
|
|
|
+ * (项目类的 recordTemplateId/reportTemplateId 匹配这两个模板),用项目类填充参数生成报告。
|
|
|
+ *
|
|
|
+ * @author 特种管理员
|
|
|
+ */
|
|
|
+@Service
|
|
|
+@Validated
|
|
|
+@Log4j2
|
|
|
+public class BoilerLegalReportServiceImpl implements BoilerLegalReportService {
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private ConfigApi configApi;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private DynamicTbMapper dynamicTbMapper;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private BoilerConnectRecordReportMapper boilerConnectRecordReportMapper;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private BoilerTaskOrderItemMapper boilerTaskOrderItemMapper;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private BoilerTaskOrderItemReportMapper taskOrderItemReportMapper;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private BoilerTaskOrderItemReportUserMapper taskOrderItemReportUserMapper;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 反向调用任务单Service同步报表数据,加 @Lazy 避免循环依赖
|
|
|
+ */
|
|
|
+ @Resource
|
|
|
+ @Lazy
|
|
|
+ private BoilerTaskOrderService boilerTaskOrderService;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void generateLegalReport(BoilerOrderItemAddReportV2VO orderItemEnterVO,
|
|
|
+ List<BoilerTaskOrderItemDO> orderItemDOS,
|
|
|
+ String itemPartId) {
|
|
|
+ String orderId = orderItemDOS == null || orderItemDOS.isEmpty() ? null : orderItemDOS.get(0).getOrderId();
|
|
|
+ log.info("[generateLegalReport][开始生成委托检验报告 orderId={} orderItemDOS={} itemPartId={}]", orderId,
|
|
|
+ orderItemDOS == null ? 0 : orderItemDOS.size(), itemPartId);
|
|
|
+
|
|
|
+ if (orderItemEnterVO == null) {
|
|
|
+ log.warn("[generateLegalReport][orderItemEnterVO 为空,直接返回 orderId={}]", orderId);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 1. 解析配置:记录模板tbCode,报告模板tbCode,并通过模板找到项目类
|
|
|
+ BoilerConnectRecordReportDO legalProject = findLegalProjectByConfig();
|
|
|
+ if (legalProject == null) {
|
|
|
+ log.warn("[generateLegalReport][未通过配置找到委托检验项目类,直接返回 orderId={}]", orderId);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ log.info("[generateLegalReport][找到委托检验项目类 projectId={} projectName={} orderId={}]",
|
|
|
+ legalProject.getId(), legalProject.getProjectName(), orderId);
|
|
|
+
|
|
|
+ // 2. 检查任务单下是否存在委托收费项目(feeType=2且fee>0)
|
|
|
+ Set<String> orderItemIds = orderItemDOS.stream().map(BoilerTaskOrderItemDO::getId).collect(Collectors.toSet());
|
|
|
+ List<BoilerTaskOrderItemReportDO> allItemReports = taskOrderItemReportMapper.selectList(
|
|
|
+ new LambdaQueryWrapperX<BoilerTaskOrderItemReportDO>()
|
|
|
+ .in(BoilerTaskOrderItemReportDO::getOrderItemId, orderItemIds)
|
|
|
+ .ne(BoilerTaskOrderItemReportDO::getTaskStatus, TaskOrderStatusEnum.CANCEL.getStatus())
|
|
|
+ );
|
|
|
+ boolean hasLegalFeeItem = allItemReports.stream()
|
|
|
+ .anyMatch(r -> "2".equals(r.getFeeType()) && r.getFee() != null
|
|
|
+ && r.getFee().compareTo(BigDecimal.ZERO) > 0);
|
|
|
+ // 2.1 同时检查本次添加的项目中是否有委托收费项目
|
|
|
+ if (!hasLegalFeeItem && orderItemEnterVO != null) {
|
|
|
+ hasLegalFeeItem = orderItemEnterVO.getItemList().stream()
|
|
|
+ .anyMatch(vo -> "2".equals(vo.getType()) && vo.getFee() != null
|
|
|
+ && vo.getFee().compareTo(BigDecimal.ZERO) > 0);
|
|
|
+ orderItemEnterVO.getItemList().forEach(vo -> log.info(
|
|
|
+ "[generateLegalReport][本次添加项 orderItemId={} type={} fee={} connectId={} templateId={}]",
|
|
|
+ vo.getOrderItemId(), vo.getType(), vo.getFee(), vo.getConnectId(), vo.getTemplateId()));
|
|
|
+ }
|
|
|
+ if (!hasLegalFeeItem) {
|
|
|
+ log.warn("[generateLegalReport][未发现委托收费项目(feeType=2且fee>0),直接返回 orderId={}]", orderId);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ log.info("[generateLegalReport][检测到委托收费项目,继续生成 orderId={}]", orderId);
|
|
|
+
|
|
|
+ // 3. 获取主报告编号
|
|
|
+ String reportNo = getMainReportNo(orderId);
|
|
|
+ log.info("[generateLegalReport][主报告编号 reportNo={} orderId={}]", reportNo, orderId);
|
|
|
+
|
|
|
+ // 4. 解析检验员信息
|
|
|
+ String checkUserId = orderItemEnterVO.getCheckId();
|
|
|
+ Integer userType = orderItemEnterVO.getType();
|
|
|
+ String groupTeamId = orderItemEnterVO.getGroupTeamId();
|
|
|
+
|
|
|
+ // 5. 为每个设备项生成委托检验报告(记录+报告)
|
|
|
+ log.info("[generateLegalReport][开始遍历设备项生成报告 orderItemSize={} orderId={}]",
|
|
|
+ orderItemDOS.size(), orderId);
|
|
|
+ for (BoilerTaskOrderItemDO orderItemDO : orderItemDOS) {
|
|
|
+ String itemCheckUserId = StrUtil.isBlank(checkUserId) ? orderItemDO.getMainChecker() : checkUserId;
|
|
|
+ createLegalReportEntries(orderItemDO, orderId, legalProject,
|
|
|
+ reportNo, itemPartId, itemCheckUserId, userType, groupTeamId);
|
|
|
+ }
|
|
|
+ log.info("[generateLegalReport][委托检验报告生成结束 orderId={}]", orderId);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void generateLegalReportForAuto(String orderId) {
|
|
|
+ log.info("[generateLegalReportForAuto][开始自动生成委托检验报告 orderId={}]", orderId);
|
|
|
+
|
|
|
+ // 1. 解析配置,通过模板找到项目类
|
|
|
+ BoilerConnectRecordReportDO legalProject = findLegalProjectByConfig();
|
|
|
+ if (legalProject == null) {
|
|
|
+ log.warn("[generateLegalReportForAuto][未通过配置找到委托检验项目类 orderId={}]", orderId);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ log.info("[generateLegalReportForAuto][找到委托检验项目类 projectId={} projectName={} orderId={}]",
|
|
|
+ legalProject.getId(), legalProject.getProjectName(), orderId);
|
|
|
+
|
|
|
+ // 2. 获取任务单下所有设备项
|
|
|
+ List<BoilerTaskOrderItemDO> allItems = boilerTaskOrderItemMapper.selectList(
|
|
|
+ BoilerTaskOrderItemDO::getOrderId, orderId);
|
|
|
+ if (CollUtil.isEmpty(allItems)) {
|
|
|
+ log.warn("[generateLegalReportForAuto][任务单下无设备项 orderId={}]", orderId);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ log.info("[generateLegalReportForAuto][设备项数量 size={} orderId={}]", allItems.size(), orderId);
|
|
|
+
|
|
|
+ // 3. 获取主报告编号
|
|
|
+ String reportNo = getMainReportNo(orderId);
|
|
|
+
|
|
|
+ // 4. 为每个设备项生成委托检验报告(记录+报告)
|
|
|
+ for (BoilerTaskOrderItemDO orderItemDO : allItems) {
|
|
|
+ createLegalReportEntries(orderItemDO, orderId, legalProject,
|
|
|
+ reportNo, null, orderItemDO.getMainChecker(), null, null);
|
|
|
+ }
|
|
|
+ log.info("[generateLegalReportForAuto][自动生成委托检验报告结束 orderId={}]", orderId);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 解析配置 boiler_legal_report_code,通过 tbCode 找到模板,再通过模板 id 找到项目类
|
|
|
+ * 配置格式:记录模板tbCode,报告模板tbCode(逗号分隔)
|
|
|
+ *
|
|
|
+ * @return 委托检验项目类;未找到返回 null
|
|
|
+ */
|
|
|
+ private BoilerConnectRecordReportDO findLegalProjectByConfig() {
|
|
|
+ // 1. 读取配置
|
|
|
+ String code;
|
|
|
+ try {
|
|
|
+ code = configApi.getConfigValueByKey("boiler_legal_report_code").getCheckedData();
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("[findLegalProjectByConfig][读取配置 boiler_legal_report_code 异常]", e);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ log.info("[findLegalProjectByConfig][配置原始值 code={}]", code);
|
|
|
+ if (StrUtil.isBlank(code)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 解析 tbCode
|
|
|
+ String[] codes = code.split(",");
|
|
|
+ String recordTbCode = codes[0].trim();
|
|
|
+ String reportTbCode = codes.length > 1 ? codes[1].trim() : "";
|
|
|
+
|
|
|
+ // 3. 按 tbCode 查询 DynamicTbDO 模板,获取模板 id
|
|
|
+ String recordTemplateId = null;
|
|
|
+ String reportTemplateId = null;
|
|
|
+ if (StrUtil.isNotBlank(recordTbCode)) {
|
|
|
+ List<DynamicTbDO> list = dynamicTbMapper.selectList(new LambdaQueryWrapperX<DynamicTbDO>()
|
|
|
+ .eq(DynamicTbDO::getTbCode, recordTbCode));
|
|
|
+ if (CollUtil.isNotEmpty(list)) {
|
|
|
+ recordTemplateId = list.get(0).getId();
|
|
|
+ }
|
|
|
+ log.info("[findLegalProjectByConfig][记录模板查询 tbCode={} id={}]", recordTbCode, recordTemplateId);
|
|
|
+ }
|
|
|
+ if (StrUtil.isNotBlank(reportTbCode)) {
|
|
|
+ List<DynamicTbDO> list = dynamicTbMapper.selectList(new LambdaQueryWrapperX<DynamicTbDO>()
|
|
|
+ .eq(DynamicTbDO::getTbCode, reportTbCode));
|
|
|
+ if (CollUtil.isNotEmpty(list)) {
|
|
|
+ reportTemplateId = list.get(0).getId();
|
|
|
+ }
|
|
|
+ log.info("[findLegalProjectByConfig][报告模板查询 tbCode={} id={}]", reportTbCode, reportTemplateId);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 通过模板 id 查询项目类 BoilerConnectRecordReportDO
|
|
|
+ // 项目类的 recordTemplateId/reportTemplateId 应匹配这两个模板
|
|
|
+ LambdaQueryWrapperX<BoilerConnectRecordReportDO> wrapper = new LambdaQueryWrapperX<>();
|
|
|
+ if (StrUtil.isNotBlank(recordTemplateId)) {
|
|
|
+ wrapper.eq(BoilerConnectRecordReportDO::getRecordTemplateId, recordTemplateId);
|
|
|
+ }
|
|
|
+ if (StrUtil.isNotBlank(reportTemplateId)) {
|
|
|
+ wrapper.eq(BoilerConnectRecordReportDO::getReportTemplateId, reportTemplateId);
|
|
|
+ }
|
|
|
+ if (recordTemplateId == null && reportTemplateId == null) {
|
|
|
+ log.warn("[findLegalProjectByConfig][记录模板和报告模板都未找到,无法查找项目类]");
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ List<BoilerConnectRecordReportDO> projectList = boilerConnectRecordReportMapper.selectList(wrapper);
|
|
|
+ log.info("[findLegalProjectByConfig][项目类查询结果 size={}]", projectList.size());
|
|
|
+ if (CollUtil.isEmpty(projectList)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ BoilerConnectRecordReportDO project = projectList.get(0);
|
|
|
+ log.info("[findLegalProjectByConfig][项目类 projectId={} projectName={} projectType={} recordTemplateId={} reportTemplateId={}]",
|
|
|
+ project.getId(), project.getProjectName(), project.getProjectType(),
|
|
|
+ project.getRecordTemplateId(), project.getReportTemplateId());
|
|
|
+ return project;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取任务单主报告编号
|
|
|
+ */
|
|
|
+ private String getMainReportNo(String orderId) {
|
|
|
+ BoilerTaskOrderItemReportDO mainReport = taskOrderItemReportMapper.selectOne(
|
|
|
+ new LambdaQueryWrapperX<BoilerTaskOrderItemReportDO>()
|
|
|
+ .eq(BoilerTaskOrderItemReportDO::getOrderId, orderId), false);
|
|
|
+ return mainReport != null ? mainReport.getReportNo() : "";
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 为单个设备项创建委托检验报告(记录+报告)
|
|
|
+ * 参考addReportVo的逻辑,用项目类填充参数
|
|
|
+ */
|
|
|
+ private void createLegalReportEntries(BoilerTaskOrderItemDO orderItemDO, String orderId,
|
|
|
+ BoilerConnectRecordReportDO legalProject,
|
|
|
+ String reportNo, String itemPartId,
|
|
|
+ String checkUserId, Integer userType, String groupTeamId) {
|
|
|
+ // 1. 创建记录报告(templateId = 项目类的 recordTemplateId)
|
|
|
+ String recordTemplateId = legalProject.getRecordTemplateId();
|
|
|
+ if (StrUtil.isNotBlank(recordTemplateId)) {
|
|
|
+ // 1.1 按 orderItemId + templateId 查重
|
|
|
+ long existCount = taskOrderItemReportMapper.selectCount(
|
|
|
+ new LambdaQueryWrapperX<BoilerTaskOrderItemReportDO>()
|
|
|
+ .eq(BoilerTaskOrderItemReportDO::getOrderItemId, orderItemDO.getId())
|
|
|
+ .eq(BoilerTaskOrderItemReportDO::getTemplateId, recordTemplateId)
|
|
|
+ .ne(BoilerTaskOrderItemReportDO::getTaskStatus, TaskOrderStatusEnum.CANCEL.getStatus())
|
|
|
+ );
|
|
|
+ log.info("[createLegalReportEntries][记录报告查重 orderItemId={} templateId={} existCount={}]",
|
|
|
+ orderItemDO.getId(), recordTemplateId, existCount);
|
|
|
+ if (existCount == 0) {
|
|
|
+ BoilerTaskOrderItemReportDO recordReport = new BoilerTaskOrderItemReportDO();
|
|
|
+ recordReport.setOrderItemId(orderItemDO.getId());
|
|
|
+ recordReport.setTemplateId(legalProject.getRecordTemplateId());
|
|
|
+ recordReport.setReportTemplateId(legalProject.getReportTemplateId());
|
|
|
+ recordReport.setOrderId(orderId);
|
|
|
+ recordReport.setTaskStatus(TaskOrderStatusEnum.ENTER.getStatus());
|
|
|
+ recordReport.setSort(998);
|
|
|
+ recordReport.setFeeType("2");
|
|
|
+ recordReport.setReportType(200);
|
|
|
+ recordReport.setProjectId(legalProject.getId());
|
|
|
+ recordReport.setReportName(legalProject.getProjectName());
|
|
|
+ recordReport.setReportNo(reportNo);
|
|
|
+ recordReport.setFee(BigDecimal.ZERO);
|
|
|
+
|
|
|
+ taskOrderItemReportMapper.insert(recordReport);
|
|
|
+ log.info("[createLegalReportEntries][记录报告插入成功 reportId={} orderItemId={}]",
|
|
|
+ recordReport.getId(), orderItemDO.getId());
|
|
|
+ insertReportUserAndSyncData(recordReport.getId(), checkUserId, userType, groupTeamId, "record");
|
|
|
+ } else {
|
|
|
+ log.info("[createLegalReportEntries][记录报告已存在,跳过 orderItemId={} templateId={}]", orderItemDO.getId(), recordTemplateId);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ log.info("[createLegalReportEntries][项目类无记录模板(recordTemplateId为空),跳过记录报告 orderItemId={}]", orderItemDO.getId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 添加报告检验员并生成报表数据
|
|
|
+ */
|
|
|
+ private void insertReportUserAndSyncData(String reportId, String checkUserId,
|
|
|
+ Integer userType, String groupTeamId, String reportType) {
|
|
|
+ BoilerTaskOrderItemReportUserDO userDO = new BoilerTaskOrderItemReportUserDO();
|
|
|
+ userDO.setUserId(checkUserId);
|
|
|
+ userDO.setReportId(reportId);
|
|
|
+ userDO.setType(userType);
|
|
|
+ userDO.setGroupTeamId(groupTeamId);
|
|
|
+ taskOrderItemReportUserMapper.insert(userDO);
|
|
|
+
|
|
|
+ BoilerTaskOrderSyncReportVO syncReportVO = new BoilerTaskOrderSyncReportVO();
|
|
|
+ syncReportVO.setRefId(reportId);
|
|
|
+ syncReportVO.setReportType(reportType);
|
|
|
+ com.alibaba.fastjson2.JSONObject params = new com.alibaba.fastjson2.JSONObject();
|
|
|
+ params.put("checkUserId", checkUserId);
|
|
|
+ syncReportVO.setParams(params);
|
|
|
+ boilerTaskOrderService.syncReportData(syncReportVO);
|
|
|
+ }
|
|
|
+}
|