From 6635ce44972debcd734f3d2cc0e089031a9404a3 Mon Sep 17 00:00:00 2001 From: FCL Date: Thu, 12 Mar 2026 16:25:48 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=B7=A5=E6=AE=B5=E6=8A=A5=E5=91=8A?= =?UTF-8?q?=E7=94=9F=E6=88=90=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/ReportDocumentDataController.java | 12 ++ .../service/ReportDocumentAssistService.java | 42 +++-- .../service/ReportDocumentDataService.java | 3 + .../ReportDocumentDataServiceImpl.java | 161 +++++++++++++++++- 4 files changed, 199 insertions(+), 19 deletions(-) diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/controller/admin/ReportDocumentDataController.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/controller/admin/ReportDocumentDataController.java index e7009053..01debfcc 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/controller/admin/ReportDocumentDataController.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/controller/admin/ReportDocumentDataController.java @@ -13,6 +13,7 @@ import com.zt.plat.framework.common.pojo.vo.BatchDeleteReqVO; import com.zt.plat.framework.common.util.object.BeanUtils; import com.zt.plat.framework.datapermission.core.annotation.DeptDataPermissionIgnore; import com.zt.plat.framework.excel.core.util.ExcelUtils; +import com.zt.plat.module.qms.business.bus.dal.dataobject.BusinessAssayReportDataDO; import com.zt.plat.module.qms.business.reportdoc.controller.vo.ReportDocumentDataPageReqVO; import com.zt.plat.module.qms.business.reportdoc.controller.vo.ReportDocumentDataRespVO; import com.zt.plat.module.qms.business.reportdoc.controller.vo.ReportDocumentDataSaveReqVO; @@ -60,6 +61,17 @@ public class ReportDocumentDataController extends AbstractFileUploadController i @Resource private ReportDocumentMainService reportDocumentMainService; @Resource private ReportDocumentTypeService reportDocumentTypeService; + + @PostMapping("/assembleByReportData") + @Operation(summary = "创建检测报告明细") + //@PreAuthorize("@ss.hasPermission('qms:report-document-data:create')") + public CommonResult assembleByReportData(@RequestBody JSONObject jsonObject) { +// Long mainId = jsonObject.getLong("mainId"); + List assayReportDataList = jsonObject.getJSONArray("assayReportDataList").toJavaList(BusinessAssayReportDataDO.class); + List itemNameList = jsonObject.getJSONArray("itemNameList").toJavaList(String.class); + return reportDocumentDataService.assembleByReportData(assayReportDataList, itemNameList); + } + /* * 查询报告明细数据,返回结果包含表头、数据、检出限等。会按报告配置进行“换行”处理。*/ @GetMapping("/queryReportDetail") diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/service/ReportDocumentAssistService.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/service/ReportDocumentAssistService.java index c5b485c0..092a79e4 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/service/ReportDocumentAssistService.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/service/ReportDocumentAssistService.java @@ -28,7 +28,7 @@ import com.zt.plat.module.system.api.iwork.dto.IWorkOperationRespDTO; import com.zt.plat.module.system.api.iwork.dto.IWorkWorkflowCreateReqDTO; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.compress.utils.IOUtils; +import org.apache.commons.io.IOUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -124,6 +124,27 @@ public class ReportDocumentAssistService { return iWorkIntegrationApi.createWorkflow(dto); } + /* + * 通过处理后的数据和模板id,生成pdf + * */ + public byte[] generateReportPDF(JSONArray data, Long templateId) throws IOException { + DataTemplateDO templateDO = dataTemplateService.getDataTemplate(templateId); + String templateContent = templateDO.getFormContent(); + JSONObject bodyJson = new JSONObject(); + bodyJson.put("Template", templateContent); + bodyJson.put("Data", data.toJSONString()); + String bodyStr = bodyJson.toJSONString(); +// log.info("html2pdf body: " + bodyStr); + log.info("html2pdf--start at {}", LocalDateTime.now()); + HttpResponse response = HttpUtil.createPost(html2pdfAddr) + .body(bodyStr) + .timeout(15000) + .execute(); + log.info("html2pdf--end at {}", LocalDateTime.now()); + InputStream inputStream = response.bodyStream(); + return IOUtils.toByteArray(inputStream); + } + /* * 生成新版pdf文件 * 在reportDocumentFile创建新pdf文件 @@ -133,22 +154,11 @@ public class ReportDocumentAssistService { String pageFlag = "1"; //分页处理 Long typeId = mainDO.getReportDocumentTypeId(); ReportDocumentTypeDO typeDO = reportDocumentTypeService.getReportDocumentType(typeId); - DataTemplateDO templateDO = dataTemplateService.getDataTemplate(mainDO.getDataTemplateId()); + Long templateId = mainDO.getDataTemplateId(); + CommonResult result = reportDocumentDataService.assembleDynamicData(mainDO, typeDO, pageFlag); JSONArray data = result.getData(); - String templateContent = templateDO.getFormContent(); - JSONObject bodyJson = new JSONObject(); - bodyJson.put("Template", templateContent); - bodyJson.put("Data", data.toJSONString()); - String bodyStr = bodyJson.toJSONString(); - log.info("html2pdf body: " + bodyStr); - log.info("html2pdf--start at {}", LocalDateTime.now()); - HttpResponse response = HttpUtil.createPost(html2pdfAddr) - .body(bodyStr) - .timeout(15000) - .execute(); - log.info("html2pdf--end at {}", LocalDateTime.now()); - InputStream inputStream = response.bodyStream(); // 关键:返回原始 InputStream + byte[] fileBytes = generateReportPDF(data, templateId); String formDataStr = mainDO.getFormData(); JSONObject formData = JSONObject.parseObject(formDataStr); String entrustCode = ""; @@ -163,8 +173,6 @@ public class ReportDocumentAssistService { filename = filename + "(" + sampleCategory + ")"; } filename += ".pdf"; - byte[] fileBytes = IOUtils.toByteArray(inputStream); - //上传到文件服务 FileCreateReqDTO fileCreateReqDTO = new FileCreateReqDTO(); fileCreateReqDTO.setName(filename); diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/service/ReportDocumentDataService.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/service/ReportDocumentDataService.java index b92169ff..819b7bdc 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/service/ReportDocumentDataService.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/service/ReportDocumentDataService.java @@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.zt.plat.framework.common.pojo.CommonResult; import com.zt.plat.framework.common.pojo.PageResult; +import com.zt.plat.module.qms.business.bus.dal.dataobject.BusinessAssayReportDataDO; import com.zt.plat.module.qms.business.reportdoc.controller.vo.*; import com.zt.plat.module.qms.business.reportdoc.dal.dataobject.ReportDocumentDataDO; import com.zt.plat.module.qms.business.reportdoc.dal.dataobject.ReportDocumentMainDO; @@ -21,6 +22,8 @@ public interface ReportDocumentDataService { CommonResult assembleDynamicData(ReportDocumentMainDO mainData, ReportDocumentTypeDO reportConfig, String pageFlag); + CommonResult assembleByReportData(List assayReportDataList, List itemNameList); + CommonResult> listByMainDataId(Long mainDataId); CommonResult countMainDataId(Long mainDataId); CommonResult removeByMainIdAndDetailIds(Long mainDataId, List detailIds); diff --git a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/service/ReportDocumentDataServiceImpl.java b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/service/ReportDocumentDataServiceImpl.java index c5952968..d14bc903 100644 --- a/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/service/ReportDocumentDataServiceImpl.java +++ b/zt-module-qms/zt-module-qms-server/src/main/java/com/zt/plat/module/qms/business/reportdoc/service/ReportDocumentDataServiceImpl.java @@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.zt.plat.framework.common.pojo.CommonResult; import com.zt.plat.framework.common.pojo.PageResult; import com.zt.plat.framework.common.util.object.BeanUtils; +import com.zt.plat.module.qms.business.bus.dal.dataobject.BusinessAssayReportDataDO; import com.zt.plat.module.qms.business.config.controller.vo.ConfigReportFieldPageReqVO; import com.zt.plat.module.qms.business.config.dal.dataobject.ConfigReportFieldDO; import com.zt.plat.module.qms.business.config.dal.dataobject.ConfigUserSignatureDO; @@ -17,6 +18,9 @@ import com.zt.plat.module.qms.business.reportdoc.dal.dataobject.ReportDocumentMa import com.zt.plat.module.qms.business.reportdoc.dal.dataobject.ReportDocumentTypeDO; import com.zt.plat.module.qms.business.reportdoc.dal.mapper.ReportDocumentDataMapper; import com.zt.plat.module.qms.business.reportdoc.dal.dataobject.ReportDocumentDataDO; +import com.zt.plat.module.qms.common.dic.controller.vo.DictionaryBusinessRespVO; +import com.zt.plat.module.qms.common.dic.dal.dataobject.DictionaryBusinessDO; +import com.zt.plat.module.qms.common.dic.service.DictionaryBusinessService; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -47,7 +51,7 @@ public class ReportDocumentDataServiceImpl implements ReportDocumentDataService @Resource private ReportDocumentDataMapper reportDocumentDataMapper; @Resource private ConfigReportFieldService configReportFieldService; @Resource private ConfigUserSignatureService configUserSignatureService; - @Resource private ReportDocumentTypeService reportDocumentTypeService; + @Resource private DictionaryBusinessService dictionaryBusinessService; private final String colPrefix = "col"; private final String sampleCodeKey = "SMP_CD"; private final String sampleNameKey = "SMP_NAME"; @@ -284,7 +288,7 @@ public class ReportDocumentDataServiceImpl implements ReportDocumentDataService JSONObject resultData = assembleResultData(mainData, rows, firstDataDO); result.add(resultData); } - log.error("assemblePageRowList result: {}", result.toJSONString()); +// log.error("assemblePageRowList result: {}", result.toJSONString()); return result; } @@ -860,6 +864,159 @@ public class ReportDocumentDataServiceImpl implements ReportDocumentDataService return rowList; } + /** + * 传入报表数据、检测项。生成报告数据 + * + * */ + @Override + public CommonResult assembleByReportData(List assayReportDataList, List itemNameList) { + if(assayReportDataList.isEmpty() || itemNameList.isEmpty()) + return CommonResult.success(new JSONArray()); + String pageFlag = "1"; + String reportConfigStr = "{\n" + + " \"dynamicColCount\": 3,\n" + + " \"fixedCol\": [\n" + + " \"SMP_NAME_CD\"\n" + + " ],\n" + + " \"maxRowCount\": 25,\n" + + " \"hasRemark\": \"1\",\n" + + " \"hasRange\": \"0\",\n" + + " \"verticalFlag\":\"0\",\n" + + " \"defaultConclusion\": \"\"\n" + + "}"; + DictionaryBusinessRespVO dictConf = dictionaryBusinessService.getDataByDataKey("工段报告表单编辑模板参数").getData(); + if(dictConf != null && !ObjectUtils.isEmpty(dictConf.getCustomConfig())) + reportConfigStr = dictConf.getCustomConfig(); + ReportDocumentMainDO mainData = new ReportDocumentMainDO(); + mainData.builder().formData("").documentSignature("").documentConfig(""); + JSONObject configJson = JSONObject.parseObject(reportConfigStr); + String verticalFlag = configJson.getString("verticalFlag"); + String maxRowCountStr = configJson.getString("maxRowCount"); //最大行数 + Integer maxRowCount = 3; + if(!ObjectUtils.isEmpty(maxRowCountStr)) + maxRowCount = Integer.parseInt(maxRowCountStr); + //组装报表字段 + List fieldListAll = new ArrayList<>(); + for(String itemName : itemNameList){ + ConfigReportFieldDO fieldDO = ConfigReportFieldDO.builder().fieldName(itemName).fieldType(FIELD_DYNAMIC).build(); + fieldListAll.add(fieldDO); + } + //通过数据反推field、组装报表数据 + List dataList = new ArrayList<>(); + for(BusinessAssayReportDataDO assayReportData : assayReportDataList){ + String assayData = assayReportData.getAssayData(); + if(ObjectUtils.isEmpty(assayData)) + continue; + JSONObject assayDataJson = JSONObject.parseObject(assayData); + for(String dataKey : assayDataJson.keySet()){ + JSONObject dataJson = assayDataJson.getJSONObject(dataKey); + String dataFieldName = dataJson.getString("fieldName"); + for(ConfigReportFieldDO fieldDO : fieldListAll){ + String fieldName = fieldDO.getFieldName(); + if(fieldName.equals(dataFieldName)){ + fieldDO.setField(dataKey); + break; + } + } + } + ReportDocumentDataDO dataDO = ReportDocumentDataDO.builder() + .sampleCode(assayReportData.getSampleCode()) + .sampleName(assayReportData.getSampleName()) + .baseSampleName(assayReportData.getBaseSampleName()) + .documentContent(assayData) + .sampleTypeKey(assayReportData.getSampleTypeKey()) + .entrustSampleName(assayReportData.getEntrustSampleName()) + .entrustSampleCode(assayReportData.getEntrustSampleCode()) + .sort(assayReportData.getEntrustDetailSort()) + .build(); + dataList.add(dataDO); + } + //增加固定列 + ConfigReportFieldDO fixedFieldDO = ConfigReportFieldDO.builder().field(sampleNameAndCodeKey).fieldName("样品名称及编号").fieldType(FIELD_FIXED).build(); + fieldListAll.add(0, fixedFieldDO); + + ReportDocumentDataDO firstDataDO = null; + if(!dataList.isEmpty()) + firstDataDO = dataList.get(0); + //拆分dataList,按样品分类key拆分 + List> dataListGroup = new ArrayList<>(); + String[] sampleTypeKeys = new String[]{"inspectionAnalysisSample", "comprehensiveInspectionSample"}; //商检分析样、商检综合样 + for(String sampleTypeKey : sampleTypeKeys){ + List dataListByKey = new ArrayList<>(); + for(ReportDocumentDataDO dataDO: dataList){ + if(sampleTypeKey.equals(dataDO.getSampleTypeKey())){ + dataListByKey.add(dataDO); + } + } + if(!dataListByKey.isEmpty()) + dataListGroup.add(dataListByKey); + } + if(dataListGroup.isEmpty() && !dataList.isEmpty()) + dataListGroup.add(dataList); + JSONArray rowList = new JSONArray(); + for(int i = 0; i < dataListGroup.size(); i++){ + List dataListByKey = dataListGroup.get(i); + //处理字段,提取有数据的字段 + List fieldList = new ArrayList<>(); + List hasFields = new ArrayList<>(); + for(ConfigReportFieldDO fieldDO : fieldListAll){ + String field = fieldDO.getField(); + String fieldName = fieldDO.getFieldName(); + String fieldType = fieldDO.getFieldType(); + //先处理固定列 + if(FIELD_FIXED.equals(fieldType)){ + if(!hasFields.contains( field)){ + fieldList.add(fieldDO); + hasFields.add(field); + } + continue; + } + for(ReportDocumentDataDO dataDO : dataListByKey){ + String documentContent = dataDO.getDocumentContent(); + JSONObject dataJson = JSONObject.parseObject(documentContent); + if(dataJson == null) + continue; + if(!dataJson.containsKey(field)) + continue; + if(!hasFields.contains( fieldName)){ + JSONObject valueJson = dataJson.getJSONObject(field); + String usage = valueJson.getString("usage"); + if(!"report".equals( usage) && ! "ingredient_report".equals(usage)) + continue; + fieldList.add(fieldDO); + hasFields.add(fieldName); + } + } + } + assembleStep1(rowList, fieldList, dataListByKey, reportConfigStr, i); //处理后的组数对象 + } + if(!"1".equals(verticalFlag)){ + //处理空数据,填充/ + rowList = assembleEmpty(configJson, rowList); + //处理数据分页 + if("1".equals(pageFlag)){ + JSONArray pageRowList = assemblePageRowList(rowList, configJson, mainData, firstDataDO); + return CommonResult.success(pageRowList); + } + } + //以下为空白 + if(rowList.size() < maxRowCount && !rowList.isEmpty()){ + JSONObject t = new JSONObject(); + t.put(colPrefix + "01", emptyText); + putEmptyData(t, 2,10); + rowList.add(t.clone()); + } + while(rowList.size() < maxRowCount){ + JSONObject t = new JSONObject(); + putEmptyData(t, 1,10); + rowList.add(t.clone()); + } + JSONArray result = new JSONArray(); + JSONObject resultData = assembleResultData(mainData, rowList, firstDataDO); + result.add(resultData); + return CommonResult.success(result); + } + @Override public CommonResult> listByMainDataId(Long mainDataId) { QueryWrapper queryWrapper = new QueryWrapper<>();