From dd890a133f35b4b21ed00ec557ca83f733ff04dc Mon Sep 17 00:00:00 2001
From: lyh <925863403@qq.com>
Date: 星期三, 03 九月 2025 18:03:24 +0800
Subject: [PATCH] 实现二保三保规范一个Word文档中包含多个保养内容(即多个设备)导入

---
 lxzn-module-eam/src/main/java/org/jeecg/modules/eam/service/impl/EamMaintenanceStandardServiceImpl.java |  805 ++++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 569 insertions(+), 236 deletions(-)

diff --git a/lxzn-module-eam/src/main/java/org/jeecg/modules/eam/service/impl/EamMaintenanceStandardServiceImpl.java b/lxzn-module-eam/src/main/java/org/jeecg/modules/eam/service/impl/EamMaintenanceStandardServiceImpl.java
index 88c86f4..f7a0afa 100644
--- a/lxzn-module-eam/src/main/java/org/jeecg/modules/eam/service/impl/EamMaintenanceStandardServiceImpl.java
+++ b/lxzn-module-eam/src/main/java/org/jeecg/modules/eam/service/impl/EamMaintenanceStandardServiceImpl.java
@@ -11,6 +11,7 @@
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.jeecg.weibo.exception.BusinessException;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.poi.ss.usermodel.*;
 import org.apache.poi.xwpf.usermodel.*;
@@ -24,7 +25,6 @@
 import org.jeecg.modules.eam.constant.BusinessCodeConst;
 import org.jeecg.modules.eam.constant.EamMaintenanceStandardDetailCategory;
 import org.jeecg.modules.eam.constant.MaintenanceStandardStatusEnum;
-import org.jeecg.modules.eam.constant.SecondMaintenanceStatusEnum;
 import org.jeecg.modules.eam.entity.EamEquipment;
 import org.jeecg.modules.eam.entity.EamEquipmentExtend;
 import org.jeecg.modules.eam.entity.EamMaintenanceStandard;
@@ -49,6 +49,8 @@
 import org.jeecg.modules.system.entity.SysParams;
 import org.jeecg.modules.system.service.*;
 import org.jeecg.modules.system.vo.UserSelector;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -70,6 +72,7 @@
  * @Version: V1.0
  */
 @Service("IEamMaintenanceStandardService")
+@Slf4j
 public class EamMaintenanceStandardServiceImpl extends ServiceImpl<EamMaintenanceStandardMapper, EamMaintenanceStandard> implements IEamMaintenanceStandardService, FlowCallBackServiceI {
 
     @Resource
@@ -1302,208 +1305,581 @@
     }
     /*瀵煎叆鐐规鏂囦欢Excel--------------------------缁撴潫*/
 
-    /*瀵煎叆浜屼繚涓変繚鏂囦欢Excel--------------------------寮�濮�*/
-
+    /*瀵煎叆浜屼繚涓変繚鏂囦欢Word--------------------------寮�濮�*/
     /**
-     * 缁熶竴淇濆吇瑙勮寖瀵煎叆鍏ュ彛
-     *
      * @param file 涓婁紶鏂囦欢
      * @param type 淇濆吇绫诲瀷 (SECOND/THIRD)
      * @return 瀵煎叆缁撴灉锛堝寘鍚垚鍔�/澶辫触淇℃伅锛�
      */
     @Override
     @Transactional
-    public Result<?> importMaintenanceStandard(MultipartFile file, String type,String id) {
+    public Result<?> importMaintenanceStandard(MultipartFile file, String type, String id) {
         String fileName = file.getOriginalFilename();
-
         try (XWPFDocument doc = new XWPFDocument(file.getInputStream())) {
-            // 鑾峰彇鏂囨。鏍囬锛堢涓�涓潪绌烘钀斤級
-            String documentTitle = null;
-            for (XWPFParagraph p : doc.getParagraphs()) {
-                String text = p.getText();
-                if (text != null && !text.trim().isEmpty()) {
-                    documentTitle = text.trim();
-                    break; // 鎵惧埌绗竴涓潪绌烘钀藉嵆閫�鍑�
-                }
-            }
-
-            // 鍩虹楠岃瘉
-            if (doc.getTables().isEmpty()) {
-                return Result.error(fileName + ": 鏂囨。涓湭鎵惧埌琛ㄦ牸");
-            }
-
-            // 鍩虹楠岃瘉
-            if (doc.getTables().isEmpty()) {
-                return Result.error(fileName + ": 鏂囨。涓湭鎵惧埌琛ㄦ牸");
-            }
-
             List<XWPFTable> tables = doc.getTables();
-            EamMaintenanceStandard standard = null;
-            List<EamMaintenanceStandardDetail> items = new ArrayList<>();
-            String standardId = null;
+            List<EamMaintenanceStandard> standards = new ArrayList<>();
+            List<EamMaintenanceStandardDetail> allItems = new ArrayList<>();
+            int deviceCount = 0;
+            boolean isRevision = StrUtil.isNotEmpty(id);
+            EamMaintenanceStandard oldStandardForRevision = null;
+            Map<String, Integer> deviceVersionMap = new HashMap<>();
+            Map<String, Integer> compositeVersionMap = new HashMap<>();
 
-            // 1. 澶勭悊鎵�鏈夎〃鏍�
-            for (int i = 0; i < tables.size(); i++) {
+            // 鑾峰彇鏂囨。涓殑鎵�鏈夋钀�
+            List<XWPFParagraph> paragraphs = doc.getParagraphs();
+
+            // 濡傛灉鏄崌鐗堝鍏ワ紝鑾峰彇鍘熸湁鏍囧噯
+            if (isRevision) {
+                oldStandardForRevision = eamMaintenanceStandardMapper.selectById(id);
+                if (oldStandardForRevision == null) {
+                    return Result.error("鍗囩増瀵煎叆澶辫触锛氭湭鎵惧埌ID涓�" + id + "鐨勮澶囨爣鍑�");
+                }
+                // 棰勫姞杞借澶囩増鏈俊鎭紙浣跨敤澶嶅悎閿級
+                loadDeviceMaxVersions(oldStandardForRevision.getEquipmentId(), compositeVersionMap);
+            } else {
+                // 闈炲崌鐗堝鍏ユ椂锛岄鍔犺浇鎵�鏈夎澶囩殑鏈�澶х増鏈紙浣跨敤澶嶅悎閿級
+                loadAllDeviceMaxVersions(compositeVersionMap);
+            }
+
+            // 澶氳澶囧鐞嗕富寰幆
+            for (int i = 0; i < tables.size(); ) {
                 XWPFTable table = tables.get(i);
 
-                if (i == 0) { // 绗竴椤佃〃鏍�
-                    // 楠岃瘉璁惧淇℃伅琛ㄦ牸
-                    if (isWrongDocumentType(table, type)) {
-                        return Result.error(fileName + ": 鏂囨。绫诲瀷涓嶅尮閰� - " +
-                                ("SECOND".equals(type) ? "璇峰鍏ヤ簩绾т繚鍏绘枃妗�" : "璇峰鍏ヤ笁绾т繚鍏绘枃妗�"));
+                // 璇嗗埆璁惧淇℃伅琛ㄦ牸
+                if (isDeviceInfoTable(table)) {
+                    deviceCount++;
+
+                    // 鍗囩増瀵煎叆鍙兘澶勭悊鍗曡澶�
+                    if (isRevision && deviceCount > 1) {
+                        throw new ImportException("鍗囩増瀵煎叆浠呮敮鎸佸崟璁惧鏂囨。");
                     }
 
                     // 鎻愬彇璁惧淇℃伅
-                    standard = extractDeviceInfo(table, type);
+                    EamMaintenanceStandard standard = extractDeviceInfo(table, type);
                     if (standard == null) {
-                        return Result.error(fileName + ": 璁惧淇℃伅鎻愬彇澶辫触");
+                        throw new ImportException("琛ㄦ牸" + (i+1) + "锛氳澶囦俊鎭彁鍙栧け璐�");
                     }
 
-                    EamMaintenanceStandard eamMaintenanceStandardOld=new EamMaintenanceStandard();
-                    if (StrUtil.isNotEmpty(id)){
-                        eamMaintenanceStandardOld=eamMaintenanceStandardMapper.selectById(id);
+                    // 浠庢枃妗d腑鑾峰彇鏍囬锛堣〃鏍煎墠鐨勬钀斤級
+                    String title = extractTitleBeforeTable(table, paragraphs);
+                    if (title != null) {
+                        standard.setStandardName(title);
                     }
 
-                    // 閰嶇疆绫诲瀷鐩稿叧鍙傛暟
-                    configureStandard(standard, type, file);
-                    if (StrUtil.isEmpty(id)){
-                        EamMaintenanceStandard exist = checkDuplicate(standard.getEquipmentId(), standard.getMaintenanceCategory(), MaintenanceStandardStatusEnum.ABOLISH.name());
-                        if (exist != null) {
-                            return Result.error(fileName + ": 璁惧鏍囧噯宸插瓨鍦紝涓嶈兘閲嶅娣诲姞");
-                        }
-                    }
+                    // 澶勭悊閲嶅鍜屽崌鐗堥�昏緫
+                    processStandard(standard, type, file, id, oldStandardForRevision, compositeVersionMap);
 
-                    if (StrUtil.isNotEmpty(id)){
-                        if (eamMaintenanceStandardOld.getEquipmentId().equals(standard.getEquipmentId())
-                                &&eamMaintenanceStandardOld.getMaintenanceCategory().equals(standard.getMaintenanceCategory())) {
-                            //鍒ゆ柇鏄惁鐜版湁寰呮彁浜ゆ暟鎹�
-                            EamMaintenanceStandard maintenanceStandard=eamMaintenanceStandardMapper.selectOne(
-                                    new QueryWrapper<EamMaintenanceStandard>().eq("equipment_id",standard.getEquipmentId())
-                                            .eq("maintenance_category",standard.getMaintenanceCategory())
-                                            .eq("standard_status",MaintenanceStandardStatusEnum.WAIT_SUBMIT.name())
-                                            .eq("del_flag", CommonConstant.DEL_FLAG_0));
-                            if (maintenanceStandard != null) {
-                                //鍒犻櫎鍘熸湁寰呮彁浜�
-                                eamMaintenanceStandardMapper.deleteById(maintenanceStandard.getId());
-                            }
-                            //鏌ヨ鍦ㄦ祦绋嬩腑鐨勬暟鎹�
-                            List<EamMaintenanceStandard> eamMaintenanceStandardList=eamMaintenanceStandardMapper.selectList(
-                                    new QueryWrapper<EamMaintenanceStandard>().eq("equipment_id",standard.getEquipmentId())
-                                            .eq("maintenance_category",standard.getMaintenanceCategory())
-                                            .eq("del_flag", CommonConstant.DEL_FLAG_0)
-                                            .and(it->it.
-                                                    eq("standard_status",MaintenanceStandardStatusEnum.WAIT_REPAIR_DIRECTOR.name())
-                                                    .or()
-                                                    .eq("standard_status",MaintenanceStandardStatusEnum.WAIT_TECHNICAL_DIRECTOR.name())
-                                            ));
-                            if (!eamMaintenanceStandardList.isEmpty()) {
-                                return Result.error("宸插瓨鍦ㄥ浜庡鎵规祦绋嬬殑鏁版嵁锛岃鍒犻櫎鎴栫粨鏉熷悗杩涜鍗囩増瀵煎叆鎿嶄綔");
-                            }
-                            //鍗囩増鎿嶄綔锛屼綔搴熷師鏈�
-                            eamMaintenanceStandardOld.setStandardStatus(MaintenanceStandardStatusEnum.ABOLISH.name());
-                            eamMaintenanceStandardMapper.updateById(eamMaintenanceStandardOld);
-                            //鐗堟湰閫掑鑾峰彇鏁板瓧
-                            Pattern pattern = Pattern.compile("(\\d+)(?:\\.\\d+)*$");
-                            Matcher matcher = pattern.matcher(eamMaintenanceStandardOld.getStandardVersion());
-                            if (matcher.find()) {
-                                try {
-                                    int mainVersion = Integer.parseInt(matcher.group(1));
-                                    standard.setStandardVersion("v" + (mainVersion + 1));
-                                } catch (NumberFormatException ignored) {
-                                }
-                            }
-                        }else {
-                            return Result.error("鍗囩増瀵煎叆鐨勬枃浠朵笌鍘熸湁鏁版嵁鐨勮澶囩紪鍙蜂笉涓�鑷�,璇烽噸鏂扮紪杈戝鍏ユ枃浠�");
-                        }
-                    }
-                    standard.setStandardName(documentTitle);
+                    // 淇濆瓨璁惧鏍囧噯
                     eamMaintenanceStandardMapper.insert(standard);
-                    standardId = standard.getId();
+                    standards.add(standard);
 
-                    // 鎻愬彇绗竴椤电殑淇濆吇椤圭洰
+                    // 鏇存柊璁惧鐗堟湰鏄犲皠
+                    updateDeviceVersionMap(deviceVersionMap, standard);
+
+                    // 鎻愬彇褰撳墠璁惧淇℃伅琛ㄦ牸涓殑淇濆吇椤圭洰
+                    List<EamMaintenanceStandardDetail> items = new ArrayList<>();
                     if ("SECOND".equals(type)) {
-                        items.addAll(extractSecondMaintenanceItems(table, standardId, true));
-                    } else if ("THIRD".equals(type)) {
-                        items.addAll(extractThirdMaintenanceItems(table, standardId, true));
+                        items.addAll(extractSecondMaintenanceItems(table, standard.getId(), true));
+                    } else {
+                        items.addAll(extractThirdMaintenanceItems(table, standard.getId(), true));
                     }
 
-                } else { // 鍚庣画椤甸潰
-                    // 鎻愬彇鍚庣画椤甸潰鐨勪繚鍏婚」鐩�
-                    if ("SECOND".equals(type)) {
-                        items.addAll(extractSecondMaintenanceItems(table, standardId, false));
-                    } else if ("THIRD".equals(type)) {
-                        items.addAll(extractThirdMaintenanceItems(table, standardId, false));
+                    // 鎻愬彇鍚庣画鍏宠仈鐨勪繚鍏婚」鐩〃鏍�
+                    i++; // 绉诲姩鍒颁笅涓�涓〃鏍�
+                    while (i < tables.size() && !isDeviceInfoTable(tables.get(i))) {
+                        XWPFTable itemTable = tables.get(i);
+                        if ("SECOND".equals(type)) {
+                            items.addAll(extractSecondMaintenanceItems(itemTable, standard.getId(), false));
+                        } else {
+                            items.addAll(extractThirdMaintenanceItems(itemTable, standard.getId(), false));
+                        }
+                        i++;
                     }
+
+                    // 椤圭洰鍚庡鐞�
+                    processItemsAfterExtraction(items, type);
+                    allItems.addAll(items);
+
+                    // 濡傛灉鏄渶鍚庝竴涓〃鏍硷紝闇�瑕侀��鍑哄惊鐜�
+                    if (i >= tables.size()) break;
+                } else {
+                    i++; // 濡傛灉涓嶆槸璁惧淇℃伅琛ㄦ牸锛岀户缁笅涓�涓�
                 }
             }
 
-            // 楠岃瘉璁惧淇℃伅鎻愬彇
-            if (standard == null) {
-                return Result.error(fileName + ": 璁惧淇℃伅鎻愬彇澶辫触");
+            // 鏍¢獙璁惧鏁伴噺
+            if (standards.isEmpty()) {
+                return Result.error(fileName + "锛氭湭鎵惧埌鏈夋晥鐨勮澶囦俊鎭〃鏍�");
             }
 
-            // 2. 鍚庡鐞嗭細鏍规嵁涓嶅悓绫诲瀷杩涜澶勭悊
-            processItemsAfterExtraction(items, type);
-
-            // 3. 椤圭洰楠岃瘉
-            if (items.isEmpty()) {
-                return Result.error(fileName + ": 鏈彁鍙栧埌浠讳綍淇濆吇椤圭洰");
+            // 鎵归噺淇濆瓨淇濆吇椤圭洰
+            if (!allItems.isEmpty()) {
+                eamMaintenanceStandardDetailService.saveBatch(allItems);
             }
 
-            // 4. 淇濆瓨椤圭洰
-            eamMaintenanceStandardDetailService.saveBatch(items);
-
-
+            // 鏇存柊娴佺▼鐘舵��
             SysParams sysParams = sysParamsService.getSysPramBySettingKey("maintenance_import_type");
-
-            if (sysParams != null) {
-                if (sysParams.getSettingValue().equals("1")) {
+            if (sysParams != null && "1".equals(sysParams.getSettingValue())) {
+                for (EamMaintenanceStandard standard : standards) {
                     standard.setStandardStatus(MaintenanceStandardStatusEnum.WAIT_SUBMIT.name());
                     eamMaintenanceStandardMapper.updateById(standard);
                 }
-            } else {
-                return Result.error("鏈壘鍒颁繚鍏绘祦绋嬪鍏ョ浉鍏抽厤缃�,璇疯仈绯荤鐞嗗憳");
+            } else if (sysParams == null) {
+                throw new ImportException("鏈厤缃繚鍏绘祦绋嬪鍏ュ弬鏁�");
             }
 
-            return Result.ok(fileName + ": 瀵煎叆鎴愬姛, 椤圭洰鏁�: " + items.size());
+            // 浣滃簾鏃х増鏈紙淇濈暀鏈�鏂扮増鏈級
+            obsoleteOldVersionsByCompositeKey(deviceVersionMap);
+
+            return Result.ok(fileName + "瀵煎叆鎴愬姛锛岃澶囨暟锛�" + standards.size() + "锛岄」鐩暟锛�" + allItems.size());
 
         } catch (ImportException e) {
-            return Result.error(e.getMessage());
+            return Result.error(fileName + "锛�" + e.getMessage());
         } catch (Exception e) {
-            return Result.error(fileName + ": 绯荤粺閿欒 - " + e.getClass().getSimpleName());
+            log.error("瀵煎叆淇濆吇瑙勮寖澶辫触", e);
+            return Result.error(fileName + "锛氱郴缁熼敊璇� - " + e.getMessage());
         }
     }
 
+    // 璁惧淇℃伅琛ㄦ牸璇嗗埆鏂规硶
+    private boolean isDeviceInfoTable(XWPFTable table) {
+        if (table.getNumberOfRows() < 2) return false;
+
+        // 妫�鏌ュ墠涓よ鏄惁鍖呭惈璁惧淇℃伅鐗瑰緛
+        String row1 = getRowText(table.getRow(0));
+        String row2 = getRowText(table.getRow(1));
+        List<String> keywords = Arrays.asList("璁惧绫诲埆", "璁惧缂栧彿", "璁惧鍚嶇О", "璁惧鍨嬪彿");
+        int matchCount = 0;
+
+        for (String keyword : keywords) {
+            if (row1.contains(keyword) || row2.contains(keyword)) {
+                matchCount++;
+            }
+        }
+        return matchCount >= 2; // 鑷冲皯鍖归厤涓や釜鍏抽敭璇�
+    }
+
+    // 鑾峰彇琛ㄦ牸琛岀殑鏂囨湰鍐呭
+    private String getRowText(XWPFTableRow row) {
+        if (row == null) return "";
+        StringBuilder sb = new StringBuilder();
+        for (XWPFTableCell cell : row.getTableCells()) {
+            sb.append(getCellText(cell));
+        }
+        return sb.toString();
+    }
+
+
     /**
-     * 鍚庡鐞嗘柟娉曪細鏍规嵁涓嶅悓绫诲瀷杩涜澶勭悊
+     * 浠庤〃鏍煎墠鐨勬钀戒腑鎻愬彇鏍囬锛堜慨澶嶇増锛�
      */
-    private void processItemsAfterExtraction(List<EamMaintenanceStandardDetail> items, String type) {
-        if ("SECOND".equals(type)) {
-            // 浜岀骇淇濆吇: 鍒犻櫎娌℃湁搴忓彿鐨勬暟鎹�
-            items.removeIf(item -> item.getItemCode() == null);
-        } else {
-            // 涓夌骇淇濆吇:
-            // 1. 鍒犻櫎绗竴鏉℃暟鎹紙閫氬父鏄爣棰樿锛�
-            if (!items.isEmpty()) {
-                items.remove(0);
-            }
-            // 2. 涓虹己澶遍儴浣嶇殑鏁版嵁濉厖鍓嶄竴鏉$殑淇濆吇閮ㄤ綅
-            String lastPart = "";
-            int i = 1;
-            for (EamMaintenanceStandardDetail item : items) {
-                item.setItemCode(i);
-                if (item.getItemPart() != null && !item.getItemPart().isEmpty()) {
-                    lastPart = item.getItemPart();
-                } else if (!lastPart.isEmpty()) {
-                    item.setItemPart(lastPart);
+    private String extractTitleBeforeTable(XWPFTable table, List<XWPFParagraph> paragraphs) {
+        try {
+            // 鑾峰彇琛ㄦ牸鐨凜TTbl瀵硅薄
+            CTTbl ctTbl = table.getCTTbl();
+
+            // 鑾峰彇琛ㄦ牸鎵�鍦ㄧ殑body
+            IBody body = table.getBody();
+
+            // 鑾峰彇body鐨勬墍鏈夊厓绱狅紙娈佃惤鍜岃〃鏍硷級
+            List<IBodyElement> bodyElements = body.getBodyElements();
+
+            // 鎵惧埌褰撳墠琛ㄦ牸鍦╞ody涓殑浣嶇疆
+            int tableIndex = -1;
+            for (int i = 0; i < bodyElements.size(); i++) {
+                IBodyElement element = bodyElements.get(i);
+                if (element instanceof XWPFTable && element.equals(table)) {
+                    tableIndex = i;
+                    break;
                 }
-                i++;
+            }
+
+            // 濡傛灉鎵惧埌琛ㄦ牸浣嶇疆锛屽悜鍓嶆煡鎵炬钀�
+            if (tableIndex > 0) {
+                for (int i = tableIndex - 1; i >= 0; i--) {
+                    IBodyElement element = bodyElements.get(i);
+                    if (element instanceof XWPFParagraph) {
+                        XWPFParagraph paragraph = (XWPFParagraph) element;
+                        String text = paragraph.getText();
+                        if (text != null && !text.trim().isEmpty() && text.contains("淇濆吇瑙勮寖")) {
+                            return text.trim();
+                        }
+                    }
+                }
+            }
+
+            // 濡傛灉涓婃柟娌℃湁鎵惧埌鏍囬锛屽皾璇曚粠琛ㄦ牸鍐呴儴鎻愬彇
+            if (table.getNumberOfRows() > 0) {
+                XWPFTableRow firstRow = table.getRow(0);
+                for (XWPFTableCell cell : firstRow.getTableCells()) {
+                    String text = getCellText(cell);
+                    if (text != null && text.contains("淇濆吇瑙勮寖")) {
+                        return text.trim();
+                    }
+                }
+            }
+        } catch (Exception e) {
+            log.warn("鎻愬彇鏍囬澶辫触", e);
+        }
+
+        return null;
+    }
+
+    /**
+     * 澶勭悊璁惧鏍囧噯鐨勯噸澶嶆牎楠屽拰鍗囩増閫昏緫
+     */
+    private void processStandard(EamMaintenanceStandard standard, String type, MultipartFile file,
+                                 String id, EamMaintenanceStandard oldStandard,
+                                 Map<String, Integer> versionMap) throws ImportException {
+        // 濡傛灉鏍囬涓虹┖锛屼娇鐢ㄨ澶囧悕绉扮敓鎴愰粯璁ゆ爣棰�
+        if (StrUtil.isEmpty(standard.getStandardName())) {
+            String defaultTitle = standard.getEquipmentName() + "鐢熶骇璁惧" +
+                    ("SECOND".equals(type) ? "浜岀骇" : "涓夌骇") + "淇濆吇瑙勮寖";
+            standard.setStandardName(defaultTitle);
+        }
+
+        // 閰嶇疆鍩虹灞炴��
+        configureStandard(standard, type, file);
+
+        if (StrUtil.isNotEmpty(id)) {
+            // 鍗囩増瀵煎叆澶勭悊
+            if (oldStandard == null) {
+                throw new ImportException("鏈壘鍒拌鍗囩増鐨勬爣鍑嗚褰�");
+            }
+
+            // 楠岃瘉璁惧涓�鑷存�э紙璁惧ID鍜屼繚鍏荤被鍒繀椤讳竴鑷达級
+            if (!oldStandard.getEquipmentId().equals(standard.getEquipmentId()) ||
+                    !oldStandard.getMaintenanceCategory().equals(standard.getMaintenanceCategory())) {
+                throw new ImportException("鍗囩増璁惧淇℃伅鎴栦繚鍏荤被鍒笉涓�鑷�");
+            }
+
+            // 妫�鏌ュ緟鍔炴祦绋�
+            List<EamMaintenanceStandard> pendingList = eamMaintenanceStandardMapper.selectList(
+                    new QueryWrapper<EamMaintenanceStandard>()
+                            .eq("equipment_id", standard.getEquipmentId())
+                            .eq("maintenance_category", standard.getMaintenanceCategory())
+                            .in("standard_status",
+                                    MaintenanceStandardStatusEnum.WAIT_SUBMIT.name(),
+                                    MaintenanceStandardStatusEnum.WAIT_REPAIR_DIRECTOR.name(),
+                                    MaintenanceStandardStatusEnum.WAIT_TECHNICAL_DIRECTOR.name())
+                            .eq("del_flag", CommonConstant.DEL_FLAG_0)
+            );
+
+            if (!pendingList.isEmpty()) {
+                throw new ImportException("瀛樺湪寰呭鎵规祦绋嬶紝璇风粨鏉熷悗鍐嶆搷浣�");
+            }
+
+            // 浣滃簾鏃ф爣鍑�
+            oldStandard.setStandardStatus(MaintenanceStandardStatusEnum.ABOLISH.name());
+            eamMaintenanceStandardMapper.updateById(oldStandard);
+
+            // 鐗堟湰鍗囩骇
+            String newVersion = incrementVersion(oldStandard.getStandardVersion());
+            standard.setStandardVersion(newVersion);
+
+            // 鏇存柊鐗堟湰鏄犲皠
+            String compositeKey = generateCompositeKey(
+                    standard.getEquipmentId(),
+                    standard.getMaintenanceCategory()
+            );
+            int newVersionNum = extractVersionNumber(newVersion);
+            versionMap.put(compositeKey, newVersionNum);
+
+        } else {
+            // 鏌ヨ鎵�鏈夊尮閰嶇殑璁惧+淇濆吇绫诲埆鏍囧噯
+            List<EamMaintenanceStandard> existingStandards = eamMaintenanceStandardMapper.selectList(
+                    new QueryWrapper<EamMaintenanceStandard>()
+                            .eq("equipment_id", standard.getEquipmentId())
+                            .eq("maintenance_category", standard.getMaintenanceCategory())
+                            .eq("del_flag", CommonConstant.DEL_FLAG_0)
+            );
+
+            // 濡傛灉瀛樺湪鍖归厤璁板綍锛屾壘鍑烘渶澶х増鏈彿
+            if (!existingStandards.isEmpty()) {
+                // 鎵惧嚭鏈�澶х増鏈彿
+                int maxVersion = existingStandards.stream()
+                        .mapToInt(s -> extractVersionNumber(s.getStandardVersion()))
+                        .max()
+                        .orElse(0);
+
+                // 璁剧疆鏂扮増鏈彿涓烘渶澶х増鏈�+1
+                standard.setStandardVersion("v" + (maxVersion + 1));
+
+                // 鏇存柊鐗堟湰鏄犲皠
+                String compositeKey = generateCompositeKey(
+                        standard.getEquipmentId(),
+                        standard.getMaintenanceCategory()
+                );
+                versionMap.put(compositeKey, maxVersion + 1);
+            } else {
+                // 娌℃湁鍖归厤璁板綍锛屽垵濮嬪寲涓簐1
+                standard.setStandardVersion("v1");
+
+                // 鏇存柊鐗堟湰鏄犲皠
+                String compositeKey = generateCompositeKey(
+                        standard.getEquipmentId(),
+                        standard.getMaintenanceCategory()
+                );
+                versionMap.put(compositeKey, 1);
             }
         }
     }
 
     /**
-     * 鎻愬彇浜岀骇淇濆吇椤圭洰锛堝尯鍒嗙涓�椤靛拰鍚庣画椤甸潰锛�
+     * 閰嶇疆淇濆吇鏍囧噯鍙傛暟
+    */
+    private void configureStandard(EamMaintenanceStandard standard, String type, MultipartFile file) {
+        // 鍩虹鍙傛暟
+        standard.setInitialDate(new Date())
+                .setStandardStatus(MaintenanceStandardStatusEnum.START.name())
+                .setDelFlag(CommonConstant.DEL_FLAG_0)
+                .setStandardCode(businessCodeRuleService.generateBusinessCodeSeq(
+                        BusinessCodeConst.MAINTENANCE_STANDARD_CODE_RULE
+                ));
+
+        // 绫诲瀷鐗瑰畾鍙傛暟
+        if ("SECOND".equals(type)) {
+            standard.setMaintenanceCategory("SECOND_MAINTENANCE")
+                    .setMaintenancePeriod(6)
+                    .setPeriodUnit("鏈�");
+        } else {
+            standard.setMaintenanceCategory("THIRD_MAINTENANCE")
+                    .setPeriodUnit("骞�");
+
+            // 鑾峰彇涓夌骇淇濆吇鍛ㄦ湡
+            if (standard.getEquipmentId() != null) {
+                EamEquipmentExtend extend = eamEquipmentExtendService.getById(standard.getEquipmentId());
+                if (extend != null && extend.getThirdMaintenancePeriod() != null) {
+                    standard.setMaintenancePeriod(extend.getThirdMaintenancePeriod());
+                }
+            }
+
+            // 榛樿涓夌骇淇濆吇鍛ㄦ湡
+            if (standard.getMaintenancePeriod() == null) {
+                standard.setMaintenancePeriod(1);
+            }
+        }
+    }
+
+
+    /**
+     * 鍔犺浇鎸囧畾璁惧鐨勬渶澶х増鏈彿
+     */
+    private void loadDeviceMaxVersions(String equipmentId, Map<String, Integer> compositeVersionMap) {
+        if (StrUtil.isBlank(equipmentId)) return;
+
+        // 鏌ヨ璇ヨ澶囩殑鎵�鏈夋爣鍑�
+        List<EamMaintenanceStandard> standards = eamMaintenanceStandardMapper.selectList(
+                new QueryWrapper<EamMaintenanceStandard>()
+                        .eq("equipment_id", equipmentId)
+                        .eq("del_flag", CommonConstant.DEL_FLAG_0)
+        );
+
+        // 鎸変繚鍏诲垎绫诲垎缁�
+        Map<String, List<EamMaintenanceStandard>> standardsByCategory = standards.stream()
+                .collect(Collectors.groupingBy(EamMaintenanceStandard::getMaintenanceCategory));
+
+        // 瑙f瀽姣忎釜淇濆吇鍒嗙被鐨勬渶澶х増鏈彿
+        for (Map.Entry<String, List<EamMaintenanceStandard>> entry : standardsByCategory.entrySet()) {
+            String maintenanceCategory = entry.getKey();
+            int maxVersion = entry.getValue().stream()
+                    .mapToInt(s -> extractVersionNumber(s.getStandardVersion()))
+                    .max()
+                    .orElse(0);
+
+            String compositeKey = generateCompositeKey(equipmentId, maintenanceCategory);
+            compositeVersionMap.put(compositeKey, maxVersion);
+        }
+    }
+
+    /**
+     * 鍔犺浇鎵�鏈夎澶囩殑鏈�澶х増鏈彿
+     */
+    private void loadAllDeviceMaxVersions(Map<String, Integer> deviceVersionMap) {
+        // 鏌ヨ鎵�鏈夎澶囩殑鏍囧噯
+        List<EamMaintenanceStandard> allStandards = eamMaintenanceStandardMapper.selectList(
+                new QueryWrapper<EamMaintenanceStandard>()
+                        .eq("del_flag", CommonConstant.DEL_FLAG_0)
+        );
+
+        // 鍒涘缓澶嶅悎閿垎缁勶細璁惧ID + 淇濆吇鍒嗙被
+        Map<String, List<EamMaintenanceStandard>> standardsByCompositeKey = new HashMap<>();
+
+        for (EamMaintenanceStandard standard : allStandards) {
+            String compositeKey = generateCompositeKey(
+                    standard.getEquipmentId(),
+                    standard.getMaintenanceCategory()
+            );
+
+            standardsByCompositeKey
+                    .computeIfAbsent(compositeKey, k -> new ArrayList<>())
+                    .add(standard);
+        }
+
+        // 璁$畻姣忎釜澶嶅悎閿殑鏈�澶х増鏈彿
+        for (Map.Entry<String, List<EamMaintenanceStandard>> entry : standardsByCompositeKey.entrySet()) {
+            String compositeKey = entry.getKey();
+            int maxVersion = entry.getValue().stream()
+                    .mapToInt(s -> extractVersionNumber(s.getStandardVersion()))
+                    .max()
+                    .orElse(0);
+
+            deviceVersionMap.put(compositeKey, maxVersion);
+        }
+    }
+
+    /**
+     * 鏇存柊璁惧鐗堟湰鏄犲皠琛�
+     */
+    private void updateDeviceVersionMap(Map<String, Integer> compositeVersionMap,
+                                        EamMaintenanceStandard newStandard) {
+        String compositeKey = generateCompositeKey(
+                newStandard.getEquipmentId(),
+                newStandard.getMaintenanceCategory()
+        );
+
+        int newVersion = extractVersionNumber(newStandard.getStandardVersion());
+
+        // 濡傛灉澶嶅悎閿凡瀛樺湪锛屾瘮杈冪増鏈彿
+        if (compositeVersionMap.containsKey(compositeKey)) {
+            int currentMax = compositeVersionMap.get(compositeKey);
+            if (newVersion > currentMax) {
+                compositeVersionMap.put(compositeKey, newVersion);
+            }
+        } else {
+            compositeVersionMap.put(compositeKey, newVersion);
+        }
+    }
+    /**
+     * 浣滃簾鏃х増鏈�
+     */
+    private void obsoleteOldVersionsByCompositeKey(Map<String, Integer> compositeVersionMap) {
+        for (Map.Entry<String, Integer> entry : compositeVersionMap.entrySet()) {
+            String compositeKey = entry.getKey();
+            String[] parts = compositeKey.split("\\|");
+            if (parts.length != 2) continue;
+
+            String equipmentId = parts[0];
+            String maintenanceCategory = parts[1];
+            int maxVersion = entry.getValue();
+
+            // 浣滃簾鎵�鏈変笉鏄渶鏂扮増鏈殑鏍囧噯锛堢浉鍚岃澶�+鐩稿悓淇濆吇鍒嗙被锛�
+            List<EamMaintenanceStandard> oldStandards = eamMaintenanceStandardMapper.selectList(
+                    new QueryWrapper<EamMaintenanceStandard>()
+                            .eq("equipment_id", equipmentId)
+                            .eq("maintenance_category", maintenanceCategory)
+                            .eq("del_flag", CommonConstant.DEL_FLAG_0)
+            );
+
+            for (EamMaintenanceStandard standard : oldStandards) {
+                int version = extractVersionNumber(standard.getStandardVersion());
+                if (version < maxVersion) {
+                    // 妫�鏌ユ槸鍚﹀湪瀹℃壒娴佺▼涓�
+                    if (isPendingApproval(standard)) {
+                        log.warn("璺宠繃浣滃簾锛氳澶噞}鐨剓}鏍囧噯{}澶勪簬瀹℃壒娴佺▼涓�",
+                                equipmentId, maintenanceCategory, standard.getId());
+                        continue;
+                    }
+
+                    standard.setStandardStatus(MaintenanceStandardStatusEnum.ABOLISH.name());
+                    eamMaintenanceStandardMapper.updateById(standard);
+
+                    log.info("璁惧{}鐨剓}鏃ф爣鍑嗗凡浣滃簾锛歿} (v{})",
+                            equipmentId, maintenanceCategory, standard.getId(), version);
+                }
+            }
+        }
+    }
+
+    /**
+     * 鍒ゆ柇鏍囧噯鏄惁澶勪簬瀹℃壒娴佺▼涓�
+     */
+    private boolean isPendingApproval(EamMaintenanceStandard standard) {
+        return MaintenanceStandardStatusEnum.WAIT_SUBMIT.name().equals(standard.getStandardStatus()) ||
+                MaintenanceStandardStatusEnum.WAIT_REPAIR_DIRECTOR.name().equals(standard.getStandardStatus()) ||
+                MaintenanceStandardStatusEnum.WAIT_TECHNICAL_DIRECTOR.name().equals(standard.getStandardStatus());
+    }
+
+    /**
+     * 浠庣増鏈瓧绗︿覆涓彁鍙栨暟瀛�
+    */
+    private int extractVersionNumber(String versionStr) {
+        if (StrUtil.isBlank(versionStr)) return 0;
+
+        Pattern pattern = Pattern.compile("v?(\\d+)");
+        Matcher matcher = pattern.matcher(versionStr);
+        if (matcher.find()) {
+            try {
+                return Integer.parseInt(matcher.group(1));
+            } catch (NumberFormatException e) {
+                log.warn("鐗堟湰鍙疯В鏋愬け璐�: {}", versionStr);
+            }
+        }
+        return 0;
+    }
+
+    /**
+     * 鐢熸垚璁惧+淇濆吇绫诲埆鐨勫鍚堥敭
+    */
+    private String generateCompositeKey(String equipmentId, String maintenanceCategory) {
+        return equipmentId + "|" + maintenanceCategory;
+    }
+
+    /**
+     * 鐗堟湰鍙烽�掑閫昏緫
+     */
+    private String incrementVersion(String oldVersion) {
+        if (StrUtil.isBlank(oldVersion)) {
+            return "v1";
+        }
+
+        // 灏濊瘯鍖归厤 vX 鏍煎紡
+        Pattern pattern = Pattern.compile("v?(\\d+)");
+        Matcher matcher = pattern.matcher(oldVersion);
+        if (matcher.find()) {
+            try {
+                int verNum = Integer.parseInt(matcher.group(1)) + 1;
+                return "v" + verNum;
+            } catch (NumberFormatException e) {
+                // 鏍煎紡閿欒锛屼娇鐢ㄩ粯璁�
+            }
+        }
+        return "v1";
+    }
+
+    /**
+     * 鎻愬彇璁惧鍩烘湰淇℃伅
+     */
+    private EamMaintenanceStandard extractDeviceInfo(XWPFTable table, String type) {
+        if (table.getNumberOfRows() < 2) return null;
+
+        // 鎻愬彇鍓嶄袱琛屾暟鎹�
+        Map<String, String> row1Data = extractRowData(table.getRow(0));
+        Map<String, String> row2Data = extractRowData(table.getRow(1));
+
+        // 鍒涘缓璁惧鏍囧噯瀵硅薄
+        EamMaintenanceStandard standard = new EamMaintenanceStandard();
+        standard.setEquipmentText(row1Data.get("璁惧绫诲埆"));
+        standard.setEquipmentCode(row1Data.get("璁惧缂栧彿"));
+        standard.setEquipmentName(row2Data.get("璁惧鍚嶇О"));
+        standard.setEquipmentModel(row2Data.get("璁惧鍨嬪彿"));
+
+        // 鍏宠仈璁惧ID
+        if (StrUtil.isNotEmpty(standard.getEquipmentCode())) {
+            EamEquipment equipment = eamEquipmentService.selectByEquipmentCode(standard.getEquipmentCode());
+            if (equipment == null) {
+                log.warn("璁惧缂栫爜鏈壘鍒�: {}", standard.getEquipmentCode());
+                return null;
+            } else {
+                standard.setEquipmentId(equipment.getId());
+            }
+        }
+
+        return standard;
+    }
+
+    /**
+     * 鎻愬彇浜岀骇淇濆吇椤圭洰
      */
     private List<EamMaintenanceStandardDetail> extractSecondMaintenanceItems(
             XWPFTable table, String standardId, boolean isFirstTable) {
@@ -1645,26 +2021,6 @@
     }
 
     /**
-     * 浼樺寲鍚庣殑绌鸿妫�娴嬶紙瑙e喅璺ㄩ〉绌鸿闂锛�
-     */
-    private boolean isRowEmpty(XWPFTableRow row) {
-        if (row == null || row.getTableCells().isEmpty()) {
-            return true;
-        }
-
-        boolean allCellsEmpty = true;
-        for (XWPFTableCell cell : row.getTableCells()) {
-            String text = getCellText(cell).trim();
-            // 淇濈暀鍖呭惈鎹㈣绗︾瓑鐨勫崟鍏冩牸浣滀负闈炵┖琛�
-            if (!text.isEmpty() && !text.replaceAll("\\s+", "").isEmpty()) {
-                allCellsEmpty = false;
-                break;
-            }
-        }
-        return allCellsEmpty;
-    }
-
-    /**
      * 鏂囨。绫诲瀷鏍¢獙 - 闃叉浜屼繚浼犲叆涓変繚鎴栧弽涔�
      */
     private boolean isWrongDocumentType(XWPFTable table, String requestedType) {
@@ -1711,41 +2067,6 @@
     }
 
     /**
-     * 鎻愬彇璁惧鍩烘湰淇℃伅
-     */
-    private EamMaintenanceStandard extractDeviceInfo(XWPFTable table, String type) {
-        if (table.getNumberOfRows() < 2) return null;
-
-        // 鎻愬彇鍓嶄袱琛屾暟鎹�
-        Map<String, String> row1Data = extractRowData(table.getRow(0));
-        Map<String, String> row2Data = extractRowData(table.getRow(1));
-
-        // 鍒涘缓璁惧鏍囧噯瀵硅薄
-        EamMaintenanceStandard standard = new EamMaintenanceStandard();
-        standard.setEquipmentText(row1Data.get("璁惧绫诲埆"));
-        standard.setEquipmentCode(row1Data.get("璁惧缂栧彿"));
-        standard.setEquipmentName(row2Data.get("璁惧鍚嶇О"));
-        standard.setEquipmentModel(row2Data.get("璁惧鍨嬪彿"));
-
-        // 鍏宠仈璁惧ID
-        if (StrUtil.isNotEmpty(standard.getEquipmentCode())) {
-            EamEquipment equipments = eamEquipmentService.selectByEquipmentCode(standard.getEquipmentCode());
-            if (equipments == null) {
-                return null;
-            } else {
-                standard.setEquipmentId(equipments.getId());
-            }
-            if (type.equals("THIRD")) {
-                EamEquipmentExtend eamEquipmentExtend = eamEquipmentExtendService.getById(standard.getEquipmentId());
-                standard.setMaintenancePeriod(eamEquipmentExtend.getThirdMaintenancePeriod());
-            }
-        }
-
-        return standard;
-    }
-
-
-    /**
      * 琛ㄦ牸琛屾暟鎹В鏋�
      */
     private Map<String, String> extractRowData(XWPFTableRow row) {
@@ -1765,7 +2086,10 @@
             else {
                 for (int i = 0; i < cellCount; i++) {
                     String text = getCellText(row.getCell(i));
+                    // 鏀寔涓枃鍐掑彿鍜岃嫳鏂囧啋鍙�
                     int colonIndex = text.indexOf('锛�');
+                    if (colonIndex < 0) colonIndex = text.indexOf(':');
+
                     if (colonIndex > 0) {
                         String key = cleanKey(text.substring(0, colonIndex));
                         String value = text.substring(colonIndex + 1);
@@ -1781,49 +2105,31 @@
 
     /**
      * 閿悕鏍囧噯鍖栧鐞�
-     */
+    */
     private String cleanKey(String key) {
         if (key == null) return "";
         // 绉婚櫎绌烘牸鍜屼腑鏂囧啋鍙�
-        return key.replaceAll("\\s", "").replace("锛�", "");
+        return key.replaceAll("\\s", "").replace("锛�", "").replace(":", "");
     }
 
     /**
-     * 閰嶇疆淇濆吇鏍囧噯鍙傛暟
+     * 绌鸿妫�娴嬶紙瑙e喅璺ㄩ〉绌鸿闂锛�
      */
-    private void configureStandard(EamMaintenanceStandard standard, String type, MultipartFile file) {
-        // 鍩虹鍙傛暟
-        String filename = file.getOriginalFilename();
-        if (filename != null && filename.contains(".")) {
-            filename = filename.substring(0, filename.lastIndexOf('.'));
+    private boolean isRowEmpty(XWPFTableRow row) {
+        if (row == null || row.getTableCells().isEmpty()) {
+            return true;
         }
 
-        standard.setStandardName(filename)
-                .setInitialDate(new Date())
-                .setStandardStatus(MaintenanceStandardStatusEnum.START.name())
-                .setStandardVersion("v" + CommonConstant.OPERATE_TYPE_1)
-                .setDelFlag(0)
-                .setStandardCode(businessCodeRuleService.generateBusinessCodeSeq(
-                        BusinessCodeConst.MAINTENANCE_STANDARD_CODE_RULE
-                ));
-
-        // 绫诲瀷鐗瑰畾鍙傛暟
-        if ("SECOND".equals(type)) {
-            standard.setMaintenanceCategory("SECOND_MAINTENANCE")
-                    .setMaintenancePeriod(6)
-                    .setPeriodUnit("鏈�");
-        } else {
-            standard.setMaintenanceCategory("THIRD_MAINTENANCE")
-                    .setPeriodUnit("骞�");
-
-            // 鑾峰彇涓夌骇淇濆吇鍛ㄦ湡
-            if (standard.getEquipmentId() != null) {
-                EamEquipmentExtend extend = eamEquipmentExtendService.getById(standard.getEquipmentId());
-                if (extend != null) {
-                    standard.setMaintenancePeriod(extend.getThirdMaintenancePeriod());
-                }
+        boolean allCellsEmpty = true;
+        for (XWPFTableCell cell : row.getTableCells()) {
+            String text = getCellText(cell).trim();
+            // 淇濈暀鍖呭惈鎹㈣绗︾瓑鐨勫崟鍏冩牸浣滀负闈炵┖琛�
+            if (!text.isEmpty() && !text.replaceAll("\\s+", "").isEmpty()) {
+                allCellsEmpty = false;
+                break;
             }
         }
+        return allCellsEmpty;
     }
 
     /**
@@ -1857,6 +2163,33 @@
                 !getCellText(row.getCell(1)).trim().isEmpty();
     }
 
-    /*瀵煎叆浜屼繚涓変繚鏂囦欢Excel--------------------------缁撴潫*/
+    /**
+     * 鍚庡鐞嗘柟娉曪細鏍规嵁涓嶅悓绫诲瀷杩涜澶勭悊
+     */
+    private void processItemsAfterExtraction(List<EamMaintenanceStandardDetail> items, String type) {
+        if ("SECOND".equals(type)) {
+            // 浜岀骇淇濆吇: 鍒犻櫎娌℃湁搴忓彿鐨勬暟鎹�
+            items.removeIf(item -> item.getItemCode() == null);
+        } else {
+            // 涓夌骇淇濆吇:
+            // 1. 鍒犻櫎绗竴鏉℃暟鎹紙閫氬父鏄爣棰樿锛�
+            if (!items.isEmpty()) {
+                items.remove(0);
+            }
+            // 2. 涓虹己澶遍儴浣嶇殑鏁版嵁濉厖鍓嶄竴鏉$殑淇濆吇閮ㄤ綅
+            String lastPart = "";
+            int i = 1;
+            for (EamMaintenanceStandardDetail item : items) {
+                item.setItemCode(i);
+                if (item.getItemPart() != null && !item.getItemPart().isEmpty()) {
+                    lastPart = item.getItemPart();
+                } else if (!lastPart.isEmpty()) {
+                    item.setItemPart(lastPart);
+                }
+                i++;
+            }
+        }
+    }
 
+    /*瀵煎叆浜屼繚涓変繚鏂囦欢Word--------------------------缁撴潫*/
 }

--
Gitblit v1.9.3