From 31ccc9cd47f96cea6e4e13b078187fd3201c4666 Mon Sep 17 00:00:00 2001
From: liding <756868258@qq.com>
Date: 星期五, 04 九月 2026 16:35:24 +0800
Subject: [PATCH] feat(report): 更新检测报告模板并优化报告生成功能 - 优化设备信息展示格式,支持多设备列表显示 - 统一检测报告和检验报告使用新版模板格式
---
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderPlanServiceImpl.java | 189 +++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 175 insertions(+), 14 deletions(-)
diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderPlanServiceImpl.java b/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderPlanServiceImpl.java
index f41d3d0..2c9bf30 100644
--- a/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderPlanServiceImpl.java
+++ b/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderPlanServiceImpl.java
@@ -45,6 +45,7 @@
import com.ruoyi.inspect.pojo.*;
import com.ruoyi.inspect.service.*;
import com.ruoyi.inspect.util.HackLoopTableRenderPolicy;
+import com.ruoyi.inspect.util.PreserveReportPicturePlaceholderHandler;
import com.ruoyi.inspect.vo.InsOrderPlanTaskSwitchVo;
import com.ruoyi.inspect.vo.InsOrderPlanVO;
import com.ruoyi.inspect.vo.InsSampleUserVO;
@@ -781,12 +782,6 @@
InsOrder order = insOrderMapper.selectOne(Wrappers.<InsOrder>lambdaQuery()
.eq(InsOrder::getId, orderId)
.last("FOR UPDATE"));
- InsReport existingReport = insReportMapper.selectOne(Wrappers.<InsReport>lambdaQuery()
- .eq(InsReport::getInsOrderId, orderId));
- if (existingReport != null && existingReport.getReportType() != null
- && !Objects.equals(existingReport.getReportType(), reportType)) {
- throw new ErrorException("鍚屼竴妫�楠岃鍗曞彧鑳戒娇鐢ㄤ竴绉嶆姤鍛婄被鍨�");
- }
boolean isInspectionReport = Objects.equals(INSPECTION_REPORT, reportType);
registerInsResults = isInspectionReport && Boolean.TRUE.equals(registerInsResults);
// 1. 鍒ゆ柇鏄惁鏈夐噸澶嶇紪鍙�, 鏈夐噸澶嶇紪鍙峰仛鎻愰啋
@@ -2497,6 +2492,11 @@
}
}
}
+ // 鏂扮増妫�娴嬫姤鍛婄洿鎺ヤ娇鐢ㄥ浐瀹氬洓鍒楃粨鏋滆锛屼笉鍐嶆瀯閫犳棫鐗堝彲鍙樺垪 TableRenderData銆�
+ // 妫�楠屾姤鍛婁粛娌跨敤涓嬫柟鍘熸湁鐨勫ぇ琛ㄦ牸閫昏緫銆�
+ if (!showResult) {
+ return;
+ }
// 鏀舵牱鏃ユ湡
List<RowRenderData> rows = new ArrayList<>();
List<TextRenderData> text = new ArrayList<>();
@@ -2688,7 +2688,9 @@
for (String s : standardMethod) {
standardMethod2.append("銆�").append(s);
}
- standardMethod2.replace(0, 1, "");
+ if (standardMethod2.length() > 0) {
+ standardMethod2.deleteCharAt(0);
+ }
tables.forEach(table -> {
table.put("tableSize", tables.size() + 1);
});
@@ -2792,10 +2794,13 @@
// 鎶芥牱鏃ユ湡
// 鎴愬搧鏄娊鏍锋椂闂�
LocalDateTime sendTime = insOrder.getSendTime();
- if (insOrder.getTypeSource() != null && insOrder.getTypeSource().equals(1)) {
+ IfsInventoryQuantity reportInventory = null;
+ if (insOrder.getIfsInventoryId() != null) {
+ reportInventory = ifsInventoryQuantityMapper.selectById(insOrder.getIfsInventoryId());
+ }
+ if (insOrder.getTypeSource() != null && insOrder.getTypeSource().equals(1) && reportInventory != null) {
// 鍘熸潗鏂欐敹鏍锋棩鏈熸槸鎶ユ鏃ユ湡
- IfsInventoryQuantity ifsInventoryQuantity = ifsInventoryQuantityMapper.selectById(insOrder.getIfsInventoryId());
- sendTime = ifsInventoryQuantity.getDeclareDate();
+ sendTime = reportInventory.getDeclareDate();
}
// 妫�楠屾椂闂� 鎶芥牱鏃堕棿-鎻愪氦鏃堕棿
@@ -2824,12 +2829,60 @@
List<Map<String, String>> finalDeviceList = deviceList;
String finalModelStr = modelStr;
- InputStream inputStream = this.getClass().getResourceAsStream(showResult ? "/static/report-template.docx" : "/static/detection-report-template.docx");
+ List<Map<String, String>> detectionResultRows = buildDetectionResultRows(samples);
+ String productName = defaultReportText(insOrder.getSampleView(), insOrder.getSample());
+ String customerName = defaultReportText(custom == null ? null : custom.getCompany(), insOrder.getCompany());
+ String detectionCategory = defaultReportText(finalOrderType, "濮旀墭妫�娴�");
+ String sampleCode = samples.stream()
+ .map(SampleProductDto::getSampleCode)
+ .filter(StringUtils::isNotBlank)
+ .distinct()
+ .collect(Collectors.joining("銆�"));
+ String productAndModel = productName;
+ if (StringUtils.isNotBlank(finalModelStr) && !Objects.equals(productName, finalModelStr)) {
+ productAndModel = productName + " " + finalModelStr;
+ }
+ String standardMethodText = "null".equals(standardMethod2.toString()) ? "" : standardMethod2.toString();
+ String productionDate = "/";
+ String batchNo = "/";
+ if (reportInventory != null) {
+ if (reportInventory.getProductDate() != null) {
+ productionDate = reportInventory.getProductDate().format(DateTimeFormatter.ofPattern("yyyy骞碝M鏈坉d鏃�"));
+ }
+ batchNo = defaultReportText(reportInventory.getUpdateBatchNo(), reportInventory.getLotBatchNo());
+ }
+ boolean containsOrganicChlorine = detectionResultRows.stream()
+ .map(row -> row.get("itemName"))
+ .filter(Objects::nonNull)
+ .anyMatch(name -> name.contains("鏈夋満姘�"));
+ String resultRemark = containsOrganicChlorine
+ ? "寰簱浠戞硶锛屾湁鏈烘隘鍚噺灏忎簬0.005%鏃讹紝浠ユ湭妫�鍑烘姤鍑恒��"
+ : defaultReportText(insOrder.getRemark(), "/");
+
+ // 妫�娴嬫姤鍛婂拰妫�楠屾姤鍛婄粺涓�浣跨敤鏂扮増鎶ュ憡妯℃澘
+ String templateName = "/static/detection-report-template-v2.docx";
+ InputStream inputStream = this.getClass().getResourceAsStream(templateName);
+ if (inputStream == null) {
+ throw new RuntimeException("鎵句笉鍒版姤鍛婃ā鏉�: " + templateName);
+ }
Configure configure = Configure.builder()
.bind("deviceList", new HackLoopTableRenderPolicy())
+ .bind("r", new HackLoopTableRenderPolicy(true))
+ .setValidErrorHandler(new PreserveReportPicturePlaceholderHandler())
.useSpringEL(true)
.build();
+ String finalProductAndModel = productAndModel;
+ String finalProductName = productName;
+ String finalCustomerName = customerName;
+ String finalDetectionCategory = detectionCategory;
+ String finalSampleCode = defaultReportText(sampleCode, "/");
+ String finalStandardMethodText = defaultReportText(standardMethodText, "/");
+ String finalProductionDate = productionDate;
+ String finalBatchNo = batchNo;
+ String finalResultRemark = resultRemark;
+ String equipmentText = buildEquipmentText(finalDeviceList);
+ String issueDate = now.format(DateTimeFormatter.ofPattern("yyyy骞碝M鏈坉d鏃�"));
XWPFTemplate template = XWPFTemplate.compile(inputStream, configure).render(
new HashMap<String, Object>() {{
put("order", insOrder);
@@ -2839,7 +2892,7 @@
put("sampleSize", insOrder.getTestQuantity());
put("tables", tables);
put("tableSize", tables.size() + 1);
- put("standardMethod", (standardMethod2.toString().equals("null") ? "" : standardMethod2));
+ put("standardMethod", finalStandardMethodText);
put("deviceList", finalDeviceList);
put("twoCode", null);
put("models", finalModelStr);
@@ -2863,10 +2916,35 @@
put("resultCh", finalResultCh);
put("resultEn", finalResultEn);
put("sampleStatus", sampleStatus);
+ // 鏂扮増妫�娴嬫姤鍛婃ā鏉匡紙鍙傜収銆婃湁鏈烘隘妫�娴嬫姤鍛娿�嬶級浣跨敤鐨勬墎骞冲瓧娈点��
+ put("no", insReport.getCode());
+ put("cover", finalProductAndModel);
+ put("product", finalProductName);
+ put("model", defaultReportText(finalModelStr, "/"));
+ put("customer", finalCustomerName);
+ put("category", finalDetectionCategory);
+ put("date", issueDate);
+ put("maker", defaultReportText(insOrder.getProduction(), "/"));
+ put("env", finalEnvironment);
+ put("qty", defaultReportText(insOrder.getTestQuantity(), "/"));
+ put("receive", finalSendTime.format(DateTimeFormatter.ofPattern("yyyy骞碝M鏈坉d鏃�")));
+ put("sampleNo", finalSampleCode);
+ put("appearance", defaultReportText(sampleStatus, "/"));
+ put("sender", defaultReportText(insOrder.getPrepareUser(), "/"));
+ put("produced", finalProductionDate);
+ put("batch", finalBatchNo);
+ put("phone", defaultReportText(insOrder.getPhone(), "/"));
+ put("testDate", insTime);
+ put("entrustNo", defaultReportText(insOrder.getEntrustCode(), "/"));
+ put("sampling", "/");
+ put("standard", finalStandardMethodText);
+ put("equipment", equipmentText);
+ put("conclusion", "鏍峰搧鎸夊鎵樻柟瑕佹眰杩涜妫�娴嬶紝鏁版嵁瑙佹娴嬬粨鏋溿��");
+ put("remark", "鏈姤鍛婃娴嬬粨鏋滀粎瀵瑰綋鏃ユ墍鎺ユ敹鏍峰搧璐熻矗銆�");
+ put("r", detectionResultRows);
+ put("resultNote", finalResultRemark);
}});
try {
- // 淇敼鎹㈣鍜屽悎骞堕棶棰�
- updaeMerge(template.getXWPFDocument(), false);
String name = insReport.getCode().replace("/", "") + (showResult ? ".docx" : "-C.docx");
Files.createDirectories(Paths.get(wordUrl));
template.writeAndClose(Files.newOutputStream(Paths.get(wordUrl, name)));
@@ -2884,6 +2962,89 @@
}
/**
+ * 鏂扮増妫�娴嬫姤鍛婄殑缁撴灉琛ㄥ浐瀹氫负鍥涘垪锛氬簭鍙枫�佹娴嬮」鐩�佸崟浣嶃�佹娴嬬粨鏋溿��
+ */
+ private static List<Map<String, String>> buildDetectionResultRows(List<SampleProductDto> samples) {
+ List<Map<String, String>> rows = new ArrayList<>();
+ if (CollectionUtils.isEmpty(samples)) {
+ return rows;
+ }
+
+ boolean multipleSamples = samples.size() > 1;
+ int sequence = 1;
+ for (SampleProductDto sample : samples) {
+ if (CollectionUtils.isEmpty(sample.getInsProduct())) {
+ continue;
+ }
+ for (InsProduct product : sample.getInsProduct()) {
+ // 缁戝畾椤圭洰浠呭弬涓庤绠楋紝涓嶅簲鍑虹幇鍦ㄦ姤鍛婁腑銆�
+ if (product == null || Objects.equals(product.getIsBinding(), 1)) {
+ continue;
+ }
+
+ String itemName = defaultReportText(
+ product.getInspectionItemSubclass(),
+ defaultReportText(product.getInspectionItem(), product.getInspectionItemClass()));
+ if (multipleSamples && StringUtils.isNotBlank(sample.getSampleCode())) {
+ itemName = sample.getSampleCode() + " - " + itemName;
+ }
+
+ Map<String, String> row = new LinkedHashMap<>();
+ row.put("seq", String.valueOf(sequence++));
+ row.put("itemName", itemName);
+ row.put("unit", defaultReportText(product.getUnit(), "/"));
+ row.put("result", defaultReportText(product.getLastValue(), "/"));
+ rows.add(row);
+ }
+ }
+ return rows;
+ }
+
+ private static String buildEquipmentText(List<Map<String, String>> deviceList) {
+ if (CollectionUtils.isEmpty(deviceList)) {
+ return "/";
+ }
+ Set<String> lines = new LinkedHashSet<>();
+ int sequence = 1;
+ for (Map<String, String> device : deviceList) {
+ String name = getMapText(device, "deviceName", "device_name");
+ String managementNumber = getMapText(device, "managementNumber", "management_number");
+ String line = sequence++ + ". " + defaultReportText(name, "/");
+ if (StringUtils.isNotBlank(managementNumber)) {
+ line += "锛�" + managementNumber;
+ }
+ lines.add(line);
+ }
+ return String.join("\n", lines);
+ }
+
+ private static String getMapText(Map<String, String> map, String... keys) {
+ if (map == null) {
+ return null;
+ }
+ for (String key : keys) {
+ String value = map.get(key);
+ if (StringUtils.isNotBlank(value)) {
+ return value;
+ }
+ for (Map.Entry<String, String> entry : map.entrySet()) {
+ if (entry.getKey() != null && entry.getKey().equalsIgnoreCase(key)
+ && StringUtils.isNotBlank(entry.getValue())) {
+ return entry.getValue();
+ }
+ }
+ }
+ return null;
+ }
+
+ private static String defaultReportText(String value, String fallback) {
+ if (StringUtils.isNotBlank(value)) {
+ return value;
+ }
+ return StringUtils.isNotBlank(fallback) ? fallback : "/";
+ }
+
+ /**
* 璁$畻琛ㄦ牸鍒楀搴�
* @param max 鏈�澶ф楠屼釜鏁�
* @return
--
Gitblit v1.9.3