From 1fb9069acd396eb8bdbd65252f6eb10d3e8362b7 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期二, 02 六月 2026 13:56:57 +0800
Subject: [PATCH] feat(staff): 修改员工入职服务接口增加用户添加标识参数
---
src/main/java/com/ruoyi/quality/utils/QualityInspectTemplateExportHelper.java | 489 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 489 insertions(+), 0 deletions(-)
diff --git a/src/main/java/com/ruoyi/quality/utils/QualityInspectTemplateExportHelper.java b/src/main/java/com/ruoyi/quality/utils/QualityInspectTemplateExportHelper.java
new file mode 100644
index 0000000..54ad922
--- /dev/null
+++ b/src/main/java/com/ruoyi/quality/utils/QualityInspectTemplateExportHelper.java
@@ -0,0 +1,489 @@
+package com.ruoyi.quality.utils;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.quality.mapper.QualityInspectMapper;
+import com.ruoyi.quality.pojo.QualityInspect;
+import com.ruoyi.quality.pojo.QualityInspectParam;
+import com.ruoyi.quality.service.IQualityInspectParamService;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.RequiredArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.hwpf.HWPFDocument;
+import org.apache.poi.hwpf.usermodel.Range;
+import org.apache.poi.hwpf.usermodel.Table;
+import org.apache.poi.hwpf.usermodel.TableCell;
+import org.apache.poi.hwpf.usermodel.TableIterator;
+import org.apache.poi.hwpf.usermodel.TableRow;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Word template export helper for process inspection.
+ */
+@Component
+@RequiredArgsConstructor
+public class QualityInspectTemplateExportHelper {
+
+ private static final String WEILONG_TEMPLATE = "/static/浼熼緳妯$増.doc";
+ private static final String BAISHI_TEMPLATE = "/static/鐧句簨妯$増.doc";
+ private static final String DALI_TEMPLATE = "/static/杈惧埄妯$増.doc";
+
+ private final QualityInspectMapper qualityInspectMapper;
+ private final IQualityInspectParamService qualityInspectParamService;
+
+ public void exportWeiLong(HttpServletResponse response, Long inspectId) {
+ export(response, inspectId, WEILONG_TEMPLATE, "浼熼緳妯$増妫�楠岀粨鏋�");
+ }
+
+ public void exportBaiShi(HttpServletResponse response, Long inspectId) {
+ export(response, inspectId, BAISHI_TEMPLATE, "鐧句簨妯$増妫�楠岀粨鏋�");
+ }
+
+ public void exportDaLi(HttpServletResponse response, Long inspectId) {
+ export(response, inspectId, DALI_TEMPLATE, "杈惧埄妯$増妫�楠岀粨鏋�");
+ }
+
+ private void export(HttpServletResponse response, Long inspectId, String templatePath, String fileName) {
+ if (inspectId == null) {
+ throw new ServiceException("妫�楠屽崟ID涓嶈兘涓虹┖");
+ }
+
+ QualityInspect inspect = qualityInspectMapper.selectById(inspectId);
+ if (inspect == null) {
+ throw new ServiceException("妫�楠屽崟涓嶅瓨鍦�");
+ }
+
+ List<QualityInspectParam> paramList = qualityInspectParamService.list(
+ Wrappers.<QualityInspectParam>lambdaQuery()
+ .eq(QualityInspectParam::getInspectId, inspectId)
+ .orderByAsc(QualityInspectParam::getId));
+ Map<String, String> valueMap = buildValueMap(paramList, inspect);
+
+ try (InputStream inputStream = getClass().getResourceAsStream(templatePath)) {
+ if (inputStream == null) {
+ throw new ServiceException("妯℃澘鏂囦欢涓嶅瓨鍦細" + templatePath);
+ }
+
+ HWPFDocument document = new HWPFDocument(inputStream);
+ fillDocument(document, valueMap);
+
+ response.reset();
+ response.setContentType("application/msword");
+ response.setCharacterEncoding("UTF-8");
+ String encodedName = URLEncoder.encode(fileName, StandardCharsets.UTF_8).replace("+", "%20");
+ response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
+ response.setHeader("Content-Disposition", "attachment;filename=" + encodedName + ".doc");
+
+ try (OutputStream outputStream = response.getOutputStream()) {
+ document.write(outputStream);
+ outputStream.flush();
+ }
+ } catch (IOException e) {
+ throw new RuntimeException("瀵煎嚭澶辫触", e);
+ }
+ }
+
+ private void fillDocument(HWPFDocument document, Map<String, String> valueMap) {
+ Range range = document.getRange();
+ TableIterator iterator = new TableIterator(range);
+ while (iterator.hasNext()) {
+ Table table = iterator.next();
+ fillTable(table, valueMap);
+ }
+ }
+
+ private void fillTable(Table table, Map<String, String> valueMap) {
+ String currentGroupLabel = "";
+ // 璁板綍缁撹鍒楃殑浣嶇疆锛岄伩鍏嶅湪缁撹鍒椾笅闈㈢户缁~鍏�
+ int conclusionCellIndex = -1;
+
+ for (int rowIndex = 0; rowIndex < table.numRows(); rowIndex++) {
+ TableRow row = table.getRow(rowIndex);
+ String firstCellText = getCellText(row, 0);
+ String secondCellText = getCellText(row, 1);
+
+ if (StringUtils.isNotBlank(firstCellText)) {
+ currentGroupLabel = firstCellText;
+ }
+
+ // 鍏堝垽鏂槸鍚︿负缁撹琛�
+ String normalizedFirstCell = normalizeKey(firstCellText);
+ boolean isConclusionRow = matchesSummaryRow(normalizedFirstCell);
+
+ // 濡傛灉鏄粨璁鸿锛岀粨璁哄垪濮嬬粓鏄渶鍚庝竴鍒�
+ if (isConclusionRow) {
+ conclusionCellIndex = row.numCells() - 1;
+ }
+
+ String value = resolveValue(valueMap, currentGroupLabel, firstCellText, secondCellText, isConclusionRow);
+ if (StringUtils.isBlank(value)) {
+ continue;
+ }
+
+ // 鏌ユ壘缁撴灉鍒椾綅缃�
+ int resultCellIndex;
+ if (isConclusionRow) {
+ resultCellIndex = conclusionCellIndex;
+ } else {
+ // 鏅�氳锛氭壘绗竴涓┖鐧藉崟鍏冩牸浣滀负缁撴灉鍒楋紝浣嗚鎺掗櫎缁撹鍒�
+ resultCellIndex = findResultCellIndex(row, conclusionCellIndex);
+ if (resultCellIndex < 0) {
+ // 涓嶄娇鐢ㄦ渶鍚庝竴鍒楋紝閬垮厤涓庣粨璁哄垪鍐茬獊
+ int lastCellIndex = row.numCells() - 1;
+ if (lastCellIndex > 1 && lastCellIndex != conclusionCellIndex) {
+ resultCellIndex = lastCellIndex - 1;
+ }
+ }
+ }
+
+ if (resultCellIndex < 0 || resultCellIndex == conclusionCellIndex && !isConclusionRow) {
+ continue;
+ }
+
+ TableCell resultCell = row.getCell(resultCellIndex);
+ String cellText = cleanCellText(resultCell.text());
+
+ // 涓ユ牸妫�鏌ワ細鍙湁绌虹櫧鎴栧崰浣嶇鎵嶅~鍏�
+ if (!isBlankLike(cellText) && !isPlaceholder(cellText)) {
+ continue;
+ }
+
+ // 浣跨敤鏇村畨鍏ㄧ殑濉厖鏂瑰紡
+ safeWriteCellText(resultCell, value);
+ }
+ }
+
+ /**
+ * 鏌ユ壘缁撴灉鍒楋紝鎺掗櫎缁撹鍒�
+ */
+ private int findResultCellIndex(TableRow row, int excludeIndex) {
+ for (int i = 1; i < row.numCells(); i++) {
+ if (i == excludeIndex) {
+ continue;
+ }
+ String cellText = cleanCellText(row.getCell(i).text());
+ if (isBlankLike(cellText) || isPlaceholder(cellText)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * 瀹夊叏鍐欏叆鍗曞厓鏍兼枃鏈紝閬垮厤褰卞搷鍏朵粬琛�
+ */
+ private void safeWriteCellText(TableCell cell, String value) {
+ if (StringUtils.isBlank(value)) {
+ return;
+ }
+
+ String originalText = cell.text();
+ String cleanedOriginal = cleanCellText(originalText);
+
+ // 濡傛灉鍗曞厓鏍煎凡鏈夊唴瀹逛笖涓嶆槸鍗犱綅绗︼紝涓嶅啓鍏�
+ if (StringUtils.isNotBlank(cleanedOriginal) && !isPlaceholder(cleanedOriginal)) {
+ return;
+ }
+
+ // 鍙娇鐢╮eplaceText锛屼笉浣跨敤insertBefore
+ try {
+ if (StringUtils.isNotBlank(originalText)) {
+ cell.replaceText(originalText, value);
+ } else {
+ // 绌哄崟鍏冩牸鐩存帴璁剧疆鏂囨湰
+ cell.insertBefore(value);
+ }
+ } catch (Exception e) {
+ // 澶囩敤鏂规锛氫娇鐢╣etRange鏂瑰紡
+ try {
+// cell.getRange().insertAfter(value);
+ } catch (Exception ignored) {}
+ }
+ }
+
+ /**
+ * 鍒ゆ柇鏄惁涓哄崰浣嶇
+ */
+ private boolean isPlaceholder(String text) {
+ if (StringUtils.isBlank(text)) {
+ return false;
+ }
+ String cleaned = text.trim();
+ // 甯歌鍗犱綅绗︽ā寮�
+ return cleaned.equals("鈥�") ||
+ cleaned.equals("-") ||
+ cleaned.equals("_") ||
+ cleaned.equals("/") ||
+ cleaned.equals("\\") ||
+ cleaned.equals("鈻�") ||
+ cleaned.equals("鈻�") ||
+ cleaned.equals("鈼�") ||
+ cleaned.equals("鈼�") ||
+ cleaned.equals("鈥�") ||
+ cleaned.equals("*") ||
+ cleaned.matches("^\\.{2,}$") || // 澶氫釜鐐�
+ cleaned.matches("^{2,}$") || // 澶氫釜澶ф嫭鍙�
+ cleaned.equalsIgnoreCase("N/A") ||
+ cleaned.equalsIgnoreCase("NA") ||
+ cleaned.equals("寰呮") ||
+ cleaned.equals("寰呭~") ||
+ cleaned.equals("绌虹櫧");
+ }
+
+ private int findResultCellIndex(TableRow row) {
+ for (int i = 1; i < row.numCells(); i++) {
+ if (isBlankLike(row.getCell(i).text())) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ private String resolveValue(Map<String, String> valueMap,
+ String currentGroupLabel,
+ String firstCellText,
+ String secondCellText,
+ boolean isConclusionRow) {
+ LinkedHashSet<String> candidates = new LinkedHashSet<>();
+ addCandidate(candidates, firstCellText);
+ addCandidate(candidates, secondCellText);
+ addCandidate(candidates, firstCellText + secondCellText);
+ if (StringUtils.isNotBlank(currentGroupLabel) && StringUtils.isNotBlank(secondCellText)) {
+ addCandidate(candidates, currentGroupLabel + secondCellText);
+ }
+ if (StringUtils.isNotBlank(currentGroupLabel)
+ && StringUtils.isNotBlank(firstCellText)
+ && StringUtils.isBlank(secondCellText)) {
+ addCandidate(candidates, currentGroupLabel);
+ }
+
+
+ // 缁撹琛屼笉濉厖锛屼繚鐣欐ā鏉垮師濮嬫暟鎹�
+ if (isConclusionRow) {
+ return null;
+ }
+
+ // 鏅�氳锛氬厛鏌ユ楠屽弬鏁板�硷紝鏈�鍚庢墠鍖归厤缁撹琛屽叧閿瘝
+ for (String candidate : candidates) {
+ String normalized = normalizeKey(candidate);
+ // 鏅�氳璺宠繃缁撹鍏抽敭璇嶅尮閰�
+ if (matchesSummaryRow(normalized)) {
+ continue;
+ }
+ String value = lookupValue(valueMap, normalized);
+ if (StringUtils.isNotBlank(value)) {
+ return value;
+ }
+ }
+
+ return null;
+ }
+
+ private boolean matchesSummaryRow(String normalizedText) {
+ if (StringUtils.isBlank(normalizedText)) {
+ return false;
+ }
+ return normalizedText.contains("璐ㄩ噺璇勫畾")
+ || normalizedText.contains("妫�楠岀粨璁�")
+ || normalizedText.contains("Gradeestimation")
+ || normalizedText.contains("Conclusion")
+ || normalizedText.contains("Evaluation")
+ || normalizedText.contains("璇勫畾")
+ || normalizedText.contains("缁撹");
+ }
+
+ private String lookupValue(Map<String, String> valueMap, String normalizedCandidate) {
+ if (StringUtils.isBlank(normalizedCandidate)) {
+ return null;
+ }
+
+ String value = valueMap.get(normalizedCandidate);
+ if (StringUtils.isNotBlank(value)) {
+ return value;
+ }
+
+ String chineseCandidate = stripEnglishLetters(normalizedCandidate);
+ value = valueMap.get(chineseCandidate);
+ if (StringUtils.isNotBlank(value)) {
+ return value;
+ }
+
+ for (Map.Entry<String, String> entry : valueMap.entrySet()) {
+ String key = entry.getKey();
+ if (StringUtils.contains(key, normalizedCandidate)
+ || StringUtils.contains(normalizedCandidate, key)
+ || StringUtils.contains(key, chineseCandidate)
+ || StringUtils.contains(chineseCandidate, key)) {
+ return entry.getValue();
+ }
+ }
+ return null;
+ }
+
+ private Map<String, String> buildValueMap(List<QualityInspectParam> paramList, QualityInspect inspect) {
+ Map<String, String> valueMap = new LinkedHashMap<>();
+ for (QualityInspectParam param : paramList) {
+ String value = StringUtils.trimToNull(param.getTestValue());
+ if (StringUtils.isBlank(value)) {
+ continue;
+ }
+ putValue(valueMap, param.getParameterItem(), value);
+ }
+
+ String checkResult = StringUtils.trimToNull(inspect.getCheckResult());
+ if (StringUtils.isNotBlank(checkResult)) {
+ putValue(valueMap, "璐ㄩ噺璇勫畾", checkResult);
+ putValue(valueMap, "妫�楠岀粨鏋�", checkResult);
+ putValue(valueMap, "妫�楠岀粨璁�", checkResult);
+ putValue(valueMap, "Grade estimation", checkResult);
+ putValue(valueMap, "Test Results", checkResult);
+ }
+ return valueMap;
+ }
+
+ private void putValue(Map<String, String> valueMap, String key, String value) {
+ String normalizedKey = normalizeKey(key);
+ if (StringUtils.isBlank(normalizedKey)) {
+ return;
+ }
+ valueMap.put(normalizedKey, value);
+
+ String chineseKey = stripEnglishLetters(normalizedKey);
+ if (StringUtils.isNotBlank(chineseKey)) {
+ valueMap.putIfAbsent(chineseKey, value);
+ }
+ }
+
+ private void writeCellText(TableCell cell, String value) {
+ if (StringUtils.isBlank(value)) {
+ return;
+ }
+
+ String originalText = cell.text();
+ try {
+ cell.replaceText(originalText, value);
+ } catch (Exception ignored) {
+ // Fallback below.
+ }
+
+ String cleanedText = cleanCellText(cell.text());
+ if (!cleanedText.contains(value)) {
+ cell.insertBefore(value);
+ }
+ }
+
+ private String getCellText(TableRow row, int index) {
+ if (row.numCells() <= index) {
+ return "";
+ }
+ return cleanCellText(row.getCell(index).text());
+ }
+
+ private String cleanCellText(String text) {
+ if (text == null) {
+ return "";
+ }
+ return text.replace("\u0007", "")
+ .replace("\r", "")
+ .replace("\n", "")
+ .trim();
+ }
+
+ private boolean isBlankLike(String text) {
+ String cleaned = cleanCellText(text);
+ return StringUtils.isBlank(cleaned)
+ || "-".equals(cleaned)
+ || "_".equals(cleaned)
+ || "鈥�".equals(cleaned)
+ || "路".equals(cleaned);
+ }
+
+ private void addCandidate(LinkedHashSet<String> candidates, String text) {
+ if (StringUtils.isBlank(text)) {
+ return;
+ }
+ candidates.add(text);
+ }
+
+ private String normalizeKey(String text) {
+ String value = cleanCellText(text);
+ if (StringUtils.isBlank(value)) {
+ return "";
+ }
+ value = value.replace("\u00A0", "");
+ value = value.replaceAll("\\s+", "");
+ value = value.replace("锛�", "");
+ value = value.replace("锛�", "");
+ value = value.replace("(", "");
+ value = value.replace(")", "");
+ value = value.replace("锛�", "");
+ value = value.replace(",", "");
+ value = value.replace("銆�", "");
+ value = value.replace("锛�", "");
+ value = value.replace(":", "");
+ value = value.replace("锛�", "");
+ value = value.replace(";", "");
+ value = value.replace("銆�", "");
+ value = value.replace("鈥�", "");
+ value = value.replace("鈥�", "");
+ value = value.replace("銆�", "");
+ value = value.replace("銆�", "");
+ value = value.replace("%", "");
+ return value;
+ }
+
+ private String stripEnglishLetters(String text) {
+ if (StringUtils.isBlank(text)) {
+ return "";
+ }
+ return text.replaceAll("[A-Za-z]", "");
+ }
+
+ /**
+ * 璋冭瘯鏂规硶锛氬垎鏋愭ā鏉胯〃鏍肩粨鏋�
+ */
+ public String analyzeTemplate(String templatePath) {
+ StringBuilder sb = new StringBuilder();
+ try (InputStream inputStream = getClass().getResourceAsStream(templatePath)) {
+ if (inputStream == null) {
+ return "妯℃澘鏂囦欢涓嶅瓨鍦細" + templatePath;
+ }
+
+ HWPFDocument document = new HWPFDocument(inputStream);
+ Range range = document.getRange();
+ TableIterator iterator = new TableIterator(range);
+
+ int tableIndex = 0;
+ while (iterator.hasNext()) {
+ Table table = iterator.next();
+ sb.append("=== 琛ㄦ牸 ").append(tableIndex++).append(" ===\n");
+ sb.append("琛屾暟: ").append(table.numRows()).append("\n");
+
+ for (int rowIndex = 0; rowIndex < table.numRows(); rowIndex++) {
+ TableRow row = table.getRow(rowIndex);
+ sb.append("琛�").append(rowIndex).append(": ");
+ for (int cellIndex = 0; cellIndex < row.numCells(); cellIndex++) {
+ String cellText = cleanCellText(row.getCell(cellIndex).text());
+ sb.append("[鍒�").append(cellIndex).append(": ").append(cellText).append("] ");
+ }
+ sb.append("\n");
+ }
+ sb.append("\n");
+ }
+ } catch (Exception e) {
+ sb.append("鍒嗘瀽澶辫触: ").append(e.getMessage());
+ }
+ return sb.toString();
+ }
+}
--
Gitblit v1.9.3