zhangherong
2025-07-07 18016ce1447b85d5ccbb873ef58c0ac79245b464
Merge remote-tracking branch 'origin/master'
已添加6个文件
已修改3个文件
1032 ■■■■■ 文件已修改
db/template/生产设备三级保养规范.docx 补丁 | 查看 | 原始文档 | blame | 历史
db/template/生产设备二级保养规范.docx 补丁 | 查看 | 原始文档 | blame | 历史
db/template/设备台账导入模板.xls 补丁 | 查看 | 原始文档 | blame | 历史
db/template/设备点检标准导入模板.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/constant/EamMaintenanceStandardDetailCategory.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/request/ImportException.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam/src/main/java/org/jeecg/modules/eam/controller/EamMaintenanceStandardController.java 490 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam/src/main/java/org/jeecg/modules/eam/service/IEamMaintenanceStandardService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam/src/main/java/org/jeecg/modules/eam/service/impl/EamMaintenanceStandardServiceImpl.java 523 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
db/template/Éú²úÉ豸Èý¼¶±£Ñø¹æ·¶.docx
Binary files differ
db/template/Éú²úÉ豸¶þ¼¶±£Ñø¹æ·¶.docx
Binary files differ
db/template/É豸̨Õ˵¼ÈëÄ£°å.xls
Binary files differ
db/template/É豸µã¼ì±ê×¼µ¼ÈëÄ£°å.xlsx
Binary files differ
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/constant/EamMaintenanceStandardDetailCategory.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,8 @@
package org.jeecg.modules.eam.constant;
public enum EamMaintenanceStandardDetailCategory {
    DAY_INSPECTION,  //日点检
    WEEK_INSPECTION, //周点检
    OPERATOR_MAINTENANCE, //操作工
    REPAIRER_MAINTENANCE //维修工
}
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/request/ImportException.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,7 @@
package org.jeecg.modules.eam.request;
public class ImportException extends RuntimeException {
    public ImportException(String message) {
        super(message);
    }
}
lxzn-module-eam/src/main/java/org/jeecg/modules/eam/controller/EamMaintenanceStandardController.java
@@ -6,31 +6,22 @@
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.modules.eam.constant.BusinessCodeConst;
import org.jeecg.modules.eam.constant.MaintenanceCategoryEnum;
import org.jeecg.modules.eam.constant.MaintenanceStandardStatusEnum;
import org.jeecg.modules.eam.dto.MaintenanceStandardImport;
import org.jeecg.modules.eam.dto.SecondMaintenanceStandardImport;
import org.jeecg.modules.eam.dto.ThirdMaintenanceStandardImport;
import org.jeecg.modules.eam.dto.WeekMaintenanceStandardImport;
import org.jeecg.modules.eam.entity.EamEquipment;
import org.jeecg.modules.eam.entity.EamMaintenanceStandard;
import org.jeecg.modules.eam.entity.EamMaintenanceStandardDetail;
import org.jeecg.modules.eam.request.EamMaintenanceStandardRequest;
import org.jeecg.modules.eam.service.IEamEquipmentService;
import org.jeecg.modules.eam.service.IEamMaintenanceStandardService;
import org.jeecg.modules.eam.vo.EamMaintenanceStandardVo;
import org.jeecg.modules.system.service.ISysBusinessCodeRuleService;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@@ -38,10 +29,7 @@
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
/**
 * @Description: ä¿å…»æ ‡å‡†
@@ -63,23 +51,25 @@
    /**
     * æµç¨‹å¯åЍ,保存对应的数据
     *
     * @param id
     * @return
     */
    @ApiOperation(value = "保养标准-流程启动保存对应的数据", notes = "保养标准-流程启动保存对应的数据")
    @GetMapping(value = "/saveEamMaintenanceStandardProcess")
    public Result<?> saveEamMaintenanceStandardProcess(String id){
    public Result<?> saveEamMaintenanceStandardProcess(String id) {
        return eamMaintenanceStandardService.saveEamMaintenanceStandardProcess(id);
    }
    /**
     * æµç¨‹å®¡æ ¸
     *
     * @param eamMaintenanceStandardVo
     * @return
     */
    @ApiOperation(value = "保养标准-流程审核", notes = "保养标准-流程审核")
    @PostMapping(value = "/audit")
    public Result<?> auditEamMaintenanceStandard(@RequestBody EamMaintenanceStandardVo eamMaintenanceStandardVo){
    public Result<?> auditEamMaintenanceStandard(@RequestBody EamMaintenanceStandardVo eamMaintenanceStandardVo) {
        return eamMaintenanceStandardService.auditEamMaintenanceStandard(eamMaintenanceStandardVo);
    }
@@ -179,7 +169,8 @@
    /**
     * æŸ¥è¯¢æ ‡å‡†åˆ—表-前端展示该用户拥有的标准
     * @param keyword è®¾å¤‡ç¼–号
     *
     * @param keyword             è®¾å¤‡ç¼–号
     * @param maintenanceCategory ä¿å…»ç±»åž‹
     * @return
     */
@@ -243,7 +234,8 @@
        List<String> list = Arrays.asList(ids.split(","));
        list.forEach(id -> {
            EamMaintenanceStandard entity = eamMaintenanceStandardService.getById(id);
            if (entity != null) {
            if (entity != null&&entity.getStandardStatus().equals(MaintenanceStandardStatusEnum.WAIT_SUBMIT.name())) {
                //只删除状态为待提交的
                entity.setDelFlag(CommonConstant.DEL_FLAG_1);
                eamMaintenanceStandardService.updateById(entity);
            }
@@ -275,358 +267,150 @@
        return super.exportXls(request, eamMaintenanceStandard, EamMaintenanceStandard.class, "保养标准");
    }
    @PostMapping("/import")
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
            // èŽ·å–ä¸Šä¼ æ–‡ä»¶å¯¹è±¡
            MultipartFile file = entity.getValue();
            eamMaintenanceStandardService.importPointInspectionExcel(file);
        }
        return Result.ok("导入成功");
    }
    /**
     * é€šè¿‡excel导入数据
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/inspectionImportExcel", method = RequestMethod.POST)
    public Result<?> inspectionImportExcel(HttpServletRequest request, HttpServletResponse response) {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
            // èŽ·å–ä¸Šä¼ æ–‡ä»¶å¯¹è±¡
            MultipartFile file = entity.getValue();
            ImportParams params = new ImportParams();
            params.setTitleRows(2);
            params.setHeadRows(1);
            params.setSheetNum(1);
            params.setNeedSave(true);
            EamMaintenanceStandardRequest standardRequest = new EamMaintenanceStandardRequest();
            try {
                //读取设备编号,图片等
                readExcel(file, standardRequest);
                EamEquipment equipment = eamEquipmentService.selectByEquipmentCode(standardRequest.getEquipmentCode());
                if(equipment == null) {
                    log.error("设备不存在:{}", standardRequest.getEquipmentCode());
                    continue;
                }
                standardRequest.setStandardName(standardRequest.getEquipmentName() + "点检标准");
                standardRequest.setMaintenanceCategory(MaintenanceCategoryEnum.POINT_INSPECTION.name());
                standardRequest.setEquipmentId(equipment.getId());
                //读取保养明细内容
                List<MaintenanceStandardImport> list = ExcelImportUtil.importExcel(file.getInputStream(), MaintenanceStandardImport.class, params);
                //明细项
                List<EamMaintenanceStandardDetail> tableList = list.stream().map(EamMaintenanceStandardDetail::new).collect(Collectors.toList());
                standardRequest.setTableDetailList(tableList);
                String codeSeq = businessCodeRuleService.generateBusinessCodeSeq(BusinessCodeConst.MAINTENANCE_STANDARD_CODE_RULE);
                standardRequest.setStandardCode(codeSeq);
                boolean b = eamMaintenanceStandardService.addMaintenanceStandard(standardRequest);
                if (!b) {
                    log.error("保存失败! {}", standardRequest.getEquipmentCode());
                }
            } catch (Exception e) {
                //update-begin-author:taoyan date:20211124 for: å¯¼å…¥æ•°æ®é‡å¤å¢žåŠ æç¤º
                String msg = e.getMessage();
                log.error("文件 {} å¤„理异常: {}", file.getOriginalFilename(), msg, e);
                //update-end-author:taoyan date:20211124 for: å¯¼å…¥æ•°æ®é‡å¤å¢žåŠ æç¤º
            } finally {
                try {
                    file.getInputStream().close();
                } catch (IOException e) {
                    log.error(e.getMessage(), e);
                }
            }
        }
        return Result.ok("文件导入完成!");
    }
    /**
     * é€šè¿‡excel导入数据
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/weekMaintenanceImportExcel", method = RequestMethod.POST)
    public Result<?> weekMaintenanceImportExcel(HttpServletRequest request, HttpServletResponse response) {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
            // èŽ·å–ä¸Šä¼ æ–‡ä»¶å¯¹è±¡
            MultipartFile file = entity.getValue();
            ImportParams params = new ImportParams();
            params.setTitleRows(2);
            params.setHeadRows(1);
            params.setSheetNum(1);
            params.setNeedSave(true);
            EamMaintenanceStandardRequest standardRequest = new EamMaintenanceStandardRequest();
            try {
                //读取设备编号,图片等
                readWeekExcel(file, standardRequest);
                EamEquipment equipment = eamEquipmentService.selectByEquipmentCode(standardRequest.getEquipmentCode());
                if(equipment == null) {
                    log.error("设备不存在:{}", standardRequest.getEquipmentCode());
                    continue;
                }
                standardRequest.setStandardName(standardRequest.getEquipmentName() + "周保标准");
                standardRequest.setMaintenanceCategory(MaintenanceCategoryEnum.WEEK_MAINTENANCE.name());
                standardRequest.setEquipmentId(equipment.getId());
                //读取保养明细内容
                List<WeekMaintenanceStandardImport> list = ExcelImportUtil.importExcel(file.getInputStream(), WeekMaintenanceStandardImport.class, params);
                //明细项
                List<EamMaintenanceStandardDetail> tableList = list.stream().map(EamMaintenanceStandardDetail::new).collect(Collectors.toList());
                standardRequest.setTableDetailList(tableList);
                String codeSeq = businessCodeRuleService.generateBusinessCodeSeq(BusinessCodeConst.MAINTENANCE_STANDARD_CODE_RULE);
                standardRequest.setStandardCode(codeSeq);
                boolean b = eamMaintenanceStandardService.addMaintenanceStandard(standardRequest);
                if (!b) {
                    log.error("保存失败! {}", standardRequest.getEquipmentCode());
                }
            } catch (Exception e) {
                //update-begin-author:taoyan date:20211124 for: å¯¼å…¥æ•°æ®é‡å¤å¢žåŠ æç¤º
                String msg = e.getMessage();
                log.error("文件 {} å¤„理异常: {}", file.getOriginalFilename(), msg, e);
                //update-end-author:taoyan date:20211124 for: å¯¼å…¥æ•°æ®é‡å¤å¢žåŠ æç¤º
            } finally {
                try {
                    file.getInputStream().close();
                } catch (IOException e) {
                    log.error(e.getMessage(), e);
                }
            }
        }
        return Result.ok("文件导入完成!");
    }
    /**
     * é€šè¿‡excel导入数据
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/secondMaintenanceImportExcel", method = RequestMethod.POST)
    public Result<?> secondMaintenanceImportExcel(HttpServletRequest request, HttpServletResponse response) {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
            // èŽ·å–ä¸Šä¼ æ–‡ä»¶å¯¹è±¡
            MultipartFile file = entity.getValue();
            ImportParams params = new ImportParams();
            params.setTitleRows(2);
            params.setHeadRows(1);
            params.setSheetNum(1);
            params.setNeedSave(true);
            EamMaintenanceStandardRequest standardRequest = new EamMaintenanceStandardRequest();
            try {
                //读取设备编号,图片等
                readWeekExcel(file, standardRequest);
                EamEquipment equipment = eamEquipmentService.selectByEquipmentCode(standardRequest.getEquipmentCode());
                if(equipment == null) {
                    log.error("设备不存在:{}", standardRequest.getEquipmentCode());
                    continue;
                }
                standardRequest.setStandardName(standardRequest.getEquipmentName() + "二保标准");
                standardRequest.setMaintenanceCategory(MaintenanceCategoryEnum.SECOND_MAINTENANCE.name());
                standardRequest.setEquipmentId(equipment.getId());
                //读取保养明细内容
                List<SecondMaintenanceStandardImport> list = ExcelImportUtil.importExcel(file.getInputStream(), SecondMaintenanceStandardImport.class, params);
                //明细项
                List<EamMaintenanceStandardDetail> tableList = list.stream().map(EamMaintenanceStandardDetail::new).collect(Collectors.toList());
                standardRequest.setTableDetailList(tableList);
                String codeSeq = businessCodeRuleService.generateBusinessCodeSeq(BusinessCodeConst.MAINTENANCE_STANDARD_CODE_RULE);
                standardRequest.setStandardCode(codeSeq);
                boolean b = eamMaintenanceStandardService.addMaintenanceStandard(standardRequest);
                if (!b) {
                    log.error("保存失败! {}", standardRequest.getEquipmentCode());
                }
            } catch (Exception e) {
                //update-begin-author:taoyan date:20211124 for: å¯¼å…¥æ•°æ®é‡å¤å¢žåŠ æç¤º
                String msg = e.getMessage();
                log.error("文件 {} å¤„理异常: {}", file.getOriginalFilename(), msg, e);
                //update-end-author:taoyan date:20211124 for: å¯¼å…¥æ•°æ®é‡å¤å¢žåŠ æç¤º
            } finally {
                try {
                    file.getInputStream().close();
                } catch (IOException e) {
                    log.error(e.getMessage(), e);
                }
            }
        }
        return Result.ok("文件导入完成!");
    }
    /**
     * é€šè¿‡excel导入数据
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/thirdMaintenanceImportExcel", method = RequestMethod.POST)
    public Result<?> thirdMaintenanceImportExcel(HttpServletRequest request, HttpServletResponse response) {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
            // èŽ·å–ä¸Šä¼ æ–‡ä»¶å¯¹è±¡
            MultipartFile file = entity.getValue();
            ImportParams params = new ImportParams();
            params.setTitleRows(2);
            params.setHeadRows(1);
            params.setSheetNum(1);
            params.setNeedSave(true);
            EamMaintenanceStandardRequest standardRequest = new EamMaintenanceStandardRequest();
            try {
                //读取设备编号,图片等
                readWeekExcel(file, standardRequest);
                EamEquipment equipment = eamEquipmentService.selectByEquipmentCode(standardRequest.getEquipmentCode());
                if(equipment == null) {
                    log.error("设备不存在:{}", standardRequest.getEquipmentCode());
                    continue;
                }
                standardRequest.setStandardName(standardRequest.getEquipmentName() + "三保标准");
                standardRequest.setMaintenanceCategory(MaintenanceCategoryEnum.THIRD_MAINTENANCE.name());
                standardRequest.setEquipmentId(equipment.getId());
                //读取保养明细内容
                List<ThirdMaintenanceStandardImport> list = ExcelImportUtil.importExcel(file.getInputStream(), ThirdMaintenanceStandardImport.class, params);
                //明细项
                List<EamMaintenanceStandardDetail> tableList = list.stream().map(EamMaintenanceStandardDetail::new).collect(Collectors.toList());
                standardRequest.setTableDetailList(tableList);
                String codeSeq = businessCodeRuleService.generateBusinessCodeSeq(BusinessCodeConst.MAINTENANCE_STANDARD_CODE_RULE);
                standardRequest.setStandardCode(codeSeq);
                boolean b = eamMaintenanceStandardService.addMaintenanceStandard(standardRequest);
                if (!b) {
                    log.error("保存失败! {}", standardRequest.getEquipmentCode());
                }
            } catch (Exception e) {
                //update-begin-author:taoyan date:20211124 for: å¯¼å…¥æ•°æ®é‡å¤å¢žåŠ æç¤º
                String msg = e.getMessage();
                log.error("文件 {} å¤„理异常: {}", file.getOriginalFilename(), msg, e);
                //update-end-author:taoyan date:20211124 for: å¯¼å…¥æ•°æ®é‡å¤å¢žåŠ æç¤º
            } finally {
                try {
                    file.getInputStream().close();
                } catch (IOException e) {
                    log.error(e.getMessage(), e);
                }
            }
        }
        return Result.ok("文件导入完成!");
    }
    /**
     * è¯»å–Excel ç¬¬ä¸€è¡Œï¼Œ ç¬¬äºŒè¡Œçš„信息,包括图片信息
     * @param file
     * @param request
     */
    private void readExcel(MultipartFile file, EamMaintenanceStandardRequest request) {
        Workbook book = null;
        boolean isXSSFWorkbook = false;
     * ç‚¹æ£€å¯¼å…¥
    */
    @PostMapping("/importPointInspection")
    public Result<?> importPointInspectionExcel(HttpServletRequest request) {
        try {
            book = WorkbookFactory.create(file.getInputStream());
            if (book instanceof XSSFWorkbook) {
                isXSSFWorkbook = true;
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
            Map<String, String> results = new LinkedHashMap<>();
            int successCount = 0;
            int failureCount = 0;
            for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
                MultipartFile file = entity.getValue();
                String fileName = file.getOriginalFilename();
                Result<?> importResult = eamMaintenanceStandardService.importPointInspectionExcel(file);
                if (importResult.isSuccess()) {
                    results.put(fileName, "成功: " + importResult.getMessage());
                    successCount++;
                } else {
                    results.put(fileName, "失败: " + importResult.getMessage());
                    failureCount++;
                }
            }
            Sheet sheet = book.getSheetAt(0);
            //第一行读取
            Row row = sheet.getRow(0);
            //设备编码
            Cell equipmentCode = row.getCell(15);
            if(CellType.NUMERIC.equals(equipmentCode.getCellType())) {
                request.setEquipmentCode(String.valueOf((int) equipmentCode.getNumericCellValue()));
            }else if(CellType.STRING.equals(equipmentCode.getCellType())) {
                request.setEquipmentCode(equipmentCode.getStringCellValue());
            }
            if (StringUtils.isBlank(request.getEquipmentCode())) {
                throw new JeecgBootException("Excel【 " + file.getOriginalFilename() + "】没有读取到设备编号,导入失败!");
            }
            //初始日期
            Cell initialDate = row.getCell(11);
            if (DateUtil.isCellDateFormatted(initialDate)) {
                request.setInitialDate(initialDate.getDateCellValue());
            } else {
                request.setInitialDate(new Date());
            }
            //设备名称
            Cell equipmentName = row.getCell(13);
            request.setEquipmentName(equipmentName.getStringCellValue());
            // æž„建响应
            Map<String, Object> response = new HashMap<>();
            response.put("results", results);
            response.put("totalFiles", fileMap.size());
            response.put("successCount", successCount);
            response.put("failureCount", failureCount);
            //第二行读取
            row = sheet.getRow(1);
            //保养周期
            Cell period = row.getCell(11);
            if (CellType.NUMERIC.equals(period.getCellType())) {
                request.setMaintenancePeriod((int) period.getNumericCellValue());
            if (failureCount == 0) {
                return Result.ok("所有点检文件导入成功"+response);
            } else if (successCount == 0) {
                return Result.error("所有点检文件导入失败", response);
            } else {
                //默认点检周期 1
                request.setMaintenancePeriod(1);
                return Result.error("部分点检文件导入失败", response);
            }
            //文件编码
            Cell fileCode = row.getCell(13);
            request.setFileCode(fileCode.getStringCellValue());
        } catch (Exception e) {
            log.error("读取Excel信息失败:{}", e.getMessage(), e);
            log.error("点检导入处理异常", e);
            return Result.error("点检导入处理失败: " + e.getMessage());
        }
    }
    /**
     * äºŒä¿å¯¼å…¥
     */
    @PostMapping("/importSecondMaintenanceStandard")
    public Result<?> importSecondMaintenanceStandard(HttpServletRequest request) {
        try {
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            Map<String, String> results = new LinkedHashMap<>();
            Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
            // ç»Ÿè®¡å¯¼å…¥ç»“æžœ
            int successCount = 0;
            int failureCount = 0;
            for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
                MultipartFile file = entity.getValue();
                String fileName = file.getOriginalFilename();
                Result<?> importResult = eamMaintenanceStandardService.importMaintenanceStandard(file, "SECOND");
                if (importResult.isSuccess()) {
                    results.put(fileName, "成功: " + importResult.getMessage());
                    successCount++;
                } else {
                    results.put(fileName, "失败: " + importResult.getMessage());
                    failureCount++;
                }
            }
            // æž„建最终响应
            Map<String, Object> response = new HashMap<>();
            response.put("results", results);
            response.put("totalFiles", fileMap.size());
            response.put("successCount", successCount);
            response.put("failureCount", failureCount);
            if (failureCount > 0) {
                return Result.error("部分文件导入失败", response);
            }
            return Result.ok("所有文件导入成功"+response);
        } catch (Exception e) {
            log.error("导入处理异常", e);
            return Result.error("导入处理失败: " + e.getMessage());
        }
    }
    /**
     * è¯»å–Excel ç¬¬ä¸€è¡Œï¼Œ ç¬¬äºŒè¡Œçš„信息
     * @param file
     * @param request
     * ä¸‰ä¿å¯¼å…¥
     */
    public void readWeekExcel(MultipartFile file, EamMaintenanceStandardRequest request) {
        Workbook book = null;
        boolean isXSSFWorkbook = false;
    @PostMapping("/importThirdMaintenanceStandard")
    public Result<?> importThirdMaintenanceStandard(HttpServletRequest request) {
        try {
            book = WorkbookFactory.create(file.getInputStream());
            if (book instanceof XSSFWorkbook) {
                isXSSFWorkbook = true;
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            Map<String, String> results = new LinkedHashMap<>();
            Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
            // ç»Ÿè®¡å¯¼å…¥ç»“æžœ
            int successCount = 0;
            int failureCount = 0;
            for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
                MultipartFile file = entity.getValue();
                String fileName = file.getOriginalFilename();
                Result<?> importResult = eamMaintenanceStandardService.importMaintenanceStandard(file, "THIRD");
                if (importResult.isSuccess()) {
                    results.put(fileName, "成功: " + importResult.getMessage());
                    successCount++;
                } else {
                    results.put(fileName, "失败: " + importResult.getMessage());
                    failureCount++;
                }
            }
            Sheet sheet = book.getSheetAt(0);
            //第一行读取
            Row row = sheet.getRow(0);
            //设备编码
            Cell equipmentCode = row.getCell(10);
            if(CellType.NUMERIC.equals(equipmentCode.getCellType())) {
                request.setEquipmentCode(String.valueOf((int) equipmentCode.getNumericCellValue()));
            }else if(CellType.STRING.equals(equipmentCode.getCellType())) {
                request.setEquipmentCode(equipmentCode.getStringCellValue());
            }
            if (StringUtils.isBlank(request.getEquipmentCode())) {
                throw new JeecgBootException("Excel【 " + file.getOriginalFilename() + "】没有读取到设备编号,导入失败!");
            }
            //初始日期
            Cell initialDate = row.getCell(6);
            if (DateUtil.isCellDateFormatted(initialDate)) {
                request.setInitialDate(initialDate.getDateCellValue());
            } else {
                request.setInitialDate(new Date());
            }
            //设备名称
            Cell equipmentName = row.getCell(8);
            request.setEquipmentName(equipmentName.getStringCellValue());
            // æž„建最终响应
            Map<String, Object> response = new HashMap<>();
            response.put("results", results);
            response.put("totalFiles", fileMap.size());
            response.put("successCount", successCount);
            response.put("failureCount", failureCount);
            //第二行读取
            row = sheet.getRow(1);
            //保养周期
            Cell period = row.getCell(6);
            if (CellType.NUMERIC.equals(period.getCellType())) {
                request.setMaintenancePeriod((int) period.getNumericCellValue());
            } else {
                request.setMaintenancePeriod(null);
            if (failureCount > 0) {
                return Result.error("部分文件导入失败", response);
            }
            //文件编码
            Cell fileCode = row.getCell(8);
            request.setFileCode(fileCode.getStringCellValue());
            return Result.ok("所有文件导入成功"+response);
        } catch (Exception e) {
            log.error("读取Excel信息失败:{}", e.getMessage(), e);
            log.error("导入处理异常", e);
            return Result.error("导入处理失败: " + e.getMessage());
        }
    }
}
lxzn-module-eam/src/main/java/org/jeecg/modules/eam/service/IEamMaintenanceStandardService.java
@@ -9,6 +9,7 @@
import org.jeecg.modules.eam.vo.EamMaintenanceStandardVo;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
/**
@@ -87,4 +88,7 @@
     * ç‚¹æ£€è¡¨å¯¼å…¥å…¥å£
     */
    public Result<?> importPointInspectionExcel(MultipartFile file);
    Result<?> importMaintenanceStandard(MultipartFile file, String type);
}
lxzn-module-eam/src/main/java/org/jeecg/modules/eam/service/impl/EamMaintenanceStandardServiceImpl.java
@@ -10,8 +10,13 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jeecg.weibo.exception.BusinessException;
import liquibase.pro.packaged.R;
import liquibase.pro.packaged.S;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.shiro.SecurityUtils;
import org.flowable.engine.TaskService;
import org.flowable.task.api.Task;
@@ -24,12 +29,16 @@
import org.jeecg.modules.eam.base.service.IBaseFactoryService;
import org.jeecg.modules.eam.base.service.IBaseFactoryUserService;
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.entity.EamEquipment;
import org.jeecg.modules.eam.entity.EamEquipmentExtend;
import org.jeecg.modules.eam.entity.EamMaintenanceStandard;
import org.jeecg.modules.eam.entity.EamMaintenanceStandardDetail;
import org.jeecg.modules.eam.mapper.EamMaintenanceStandardMapper;
import org.jeecg.modules.eam.request.EamMaintenanceStandardRequest;
import org.jeecg.modules.eam.request.ImportException;
import org.jeecg.modules.eam.service.IEamEquipmentExtendService;
import org.jeecg.modules.eam.service.IEamEquipmentService;
import org.jeecg.modules.eam.service.IEamMaintenanceStandardDetailService;
import org.jeecg.modules.eam.service.IEamMaintenanceStandardService;
@@ -40,15 +49,18 @@
import org.jeecg.modules.flowable.apithird.service.FlowCommonService;
import org.jeecg.modules.flowable.service.IFlowDefinitionService;
import org.jeecg.modules.flowable.service.IFlowTaskService;
import org.jeecg.modules.system.service.ISysBusinessCodeRuleService;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecg.modules.system.vo.UserSelector;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.commons.ConfigDataMissingEnvironmentPostProcessor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
@@ -87,6 +99,22 @@
    private ISysUserService sysUserService;
    @Autowired
    private IEamEquipmentService eamEquipmentService;
    @Autowired
    private IEamEquipmentExtendService eamEquipmentExtendService;
    @Autowired
    private ISysBusinessCodeRuleService businessCodeRuleService;
    // å¸¸é‡å®šä¹‰
    private static final String REPAIR_TITLE = "维修人员保养内容";
    private static final String OPERATOR_TITLE = "操作人员保养内容";
    private static final Map<String, EamMaintenanceStandardDetailCategory> SECOND_CATEGORY_MAPPING = new HashMap<>();
    // æžšä¸¾æ˜ å°„初始化
    static {
        SECOND_CATEGORY_MAPPING.put(REPAIR_TITLE, EamMaintenanceStandardDetailCategory.REPAIRER_MAINTENANCE);
        SECOND_CATEGORY_MAPPING.put(OPERATOR_TITLE, EamMaintenanceStandardDetailCategory.OPERATOR_MAINTENANCE);
    }
    @Override
    public IPage<EamMaintenanceStandard> queryPageList(Page<EamMaintenanceStandard> page, EamMaintenanceStandard eamMaintenanceStandard) {
        QueryWrapper<EamMaintenanceStandard> queryWrapper = new QueryWrapper<>();
@@ -520,7 +548,7 @@
    /*流程业务代码--------------------------结束*/
    /*导入文件--------------------------开始*/
    /*导入点检文件Excel--------------------------开始*/
    /**
        * ç‚¹æ£€è¡¨å¯¼å…¥å…¥å£
    */
@@ -536,7 +564,7 @@
            // 1. æå–设备信息
            EamMaintenanceStandard eamMaintenanceStandard = extractDeviceInfo(sheet);
            if (eamMaintenanceStandard == null) {
                throw new BusinessException("设备信息提取失败");
                return Result.error("设备信息提取失败");
            }
            eamMaintenanceStandard.setStandardName(name);
@@ -544,9 +572,15 @@
            // 2. æå–每日点检项目
            List<EamMaintenanceStandardDetail> dailyDetails = extractDailyItems(sheet, eamMaintenanceStandard);
            if(dailyDetails.isEmpty()){
                return Result.error("未找到每日点检项目");
            }
            // 3. æå–周保养项目
            List<EamMaintenanceStandardDetail> weeklyDetails = extractWeeklyItems(sheet, eamMaintenanceStandard);
            if(weeklyDetails.isEmpty()){
                return Result.error("未找到周保养项目");
            }
            // åˆå¹¶å¹¶ä¿å­˜æ‰€æœ‰é¡¹ç›®
            List<EamMaintenanceStandardDetail> allDetails = new ArrayList<>();
@@ -618,7 +652,7 @@
        EamMaintenanceStandard standard = new EamMaintenanceStandard();
        standard.setEquipmentName(extractField(headerText, "设备名称[::]\\s*(\\S+)"));
        standard.setEquipmentId(extractField(headerText, "设备型号[::]\\s*(\\S+)"));
        standard.setStandardCode(extractField(headerText, "统一编号[::]\\s*(\\S+)"));
        // æ—¥æœŸå¤„理
        String dateStr = extractField(headerText, "日期[::]\\s*(\\S+)");
@@ -633,11 +667,31 @@
            }
        }
        // å…³è”设备ID
        if (isNotBlank(standard.getEquipmentCode()) &&
                isNotBlank(standard.getEquipmentName())) {
            List<EamEquipment> equipments = eamEquipmentService.list(
                    new QueryWrapper<EamEquipment>()
                            .eq("equipment_code", standard.getEquipmentCode())
                            .eq("equipment_name", standard.getEquipmentName())
            );
            if (!equipments.isEmpty()) {
                standard.setEquipmentId(equipments.get(0).getId());
            }else {
                return null;
            }
        }
        String codeSeq = businessCodeRuleService.generateBusinessCodeSeq(BusinessCodeConst.MAINTENANCE_STANDARD_CODE_RULE);
        standard.setStandardCode(codeSeq);
        standard.setMaintenanceCategory("POINT_INSPECTION");
        standard.setPeriodUnit("天");
        standard.setStandardStatus(MaintenanceStandardStatusEnum.START.name());
        standard.setStandardVersion("v" + CommonConstant.OPERATE_TYPE_1);
        standard.setDelFlag(0);
        standard.setMaintenancePeriod(1);
        return standard;
    }
@@ -800,7 +854,7 @@
    }
    /**
        * è¯†åˆ«æ–°è¡¨å¤´å¼€å§‹
     * è¯†åˆ«æ–°è¡¨å¤´å¼€å§‹
    */
    private boolean isNewHeaderStart(Row row) {
        for (int colIdx = 0; colIdx < row.getLastCellNum(); colIdx++) {
@@ -837,7 +891,6 @@
    */
    private String extractField(String text, String regex) {
        if (StringUtils.isBlank(text)) return "";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(text);
        return matcher.find() ? matcher.group(1) : "";
@@ -848,7 +901,6 @@
    */
    private String getCellStringValue(Cell cell) {
        if (cell == null) return "";
        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue().trim();
@@ -886,5 +938,462 @@
            return "";
        }
    }
    /*导入文件--------------------------结束*/
    /*导入点检文件Excel--------------------------结束*/
    /*导入二保三保文件Excel--------------------------开始*/
    /**
     * ç»Ÿä¸€ä¿å…»è§„范导入入口
     * @param file ä¸Šä¼ æ–‡ä»¶
     * @param type ä¿å…»ç±»åž‹ (SECOND/THIRD)
     * @return å¯¼å…¥ç»“果(包含成功/失败信息)
     */
    @Override
    @Transactional
    public Result<?> importMaintenanceStandard(MultipartFile file, String type) {
        String fileName = file.getOriginalFilename();
        try (XWPFDocument doc = new XWPFDocument(file.getInputStream())) {
            // åŸºç¡€éªŒè¯
            if (doc.getTables().isEmpty()) {
                return Result.error(fileName + ": æ–‡æ¡£ä¸­æœªæ‰¾åˆ°è¡¨æ ¼");
            }
            XWPFTable table = doc.getTables().get(0);
            // æ–‡æ¡£ç±»åž‹æ ¡éªŒ - é˜²æ­¢äºŒä¿ä¼ å…¥ä¸‰ä¿æˆ–反之
            if (isWrongDocumentType(table, type)) {
                return Result.error(fileName + ": æ–‡æ¡£ç±»åž‹ä¸åŒ¹é… - " +
                        ("SECOND".equals(type) ? "请导入二级保养文档" : "请导入三级保养文档"));
            }
            EamMaintenanceStandard standard = extractDeviceInfo(table);
            if (standard == null) {
                return Result.error(fileName + ": è®¾å¤‡ä¿¡æ¯æå–失败");
            }
            // é…ç½®ç±»åž‹ç›¸å…³å‚æ•°
            configureStandard(standard, type, file);
            eamMaintenanceStandardMapper.insert(standard);
            String standardId = standard.getId();
            // æå–保养项目
            List<EamMaintenanceStandardDetail> items;
            if ("SECOND".equals(type)) {
                items = extractSecondMaintenanceItems(table, standardId);
            } else if ("THIRD".equals(type)) {
                items = extractThirdMaintenanceItems(table, standardId);
            } else {
                return Result.error(fileName + ": ä¸æ”¯æŒçš„保养类型: " + type);
            }
            // é¡¹ç›®éªŒè¯
            if (items.isEmpty()) {
                return Result.error(fileName + ": æœªæå–到任何保养项目");
            }
            // ä¿å­˜é¡¹ç›®
            eamMaintenanceStandardDetailService.saveBatch(items);
            return Result.ok(fileName + ": å¯¼å…¥æˆåŠŸ, é¡¹ç›®æ•°: " + items.size());
        } catch (ImportException e) {
            return Result.error(e.getMessage());
        } catch (Exception e) {
            return Result.error(fileName + ": ç³»ç»Ÿé”™è¯¯ - " + e.getClass().getSimpleName());
        }
    }
    /**
     * æ–‡æ¡£ç±»åž‹æ ¡éªŒ - é˜²æ­¢äºŒä¿ä¼ å…¥ä¸‰ä¿æˆ–反之
    */
    private boolean isWrongDocumentType(XWPFTable table, String requestedType) {
        boolean hasRepairTitle = false;
        boolean hasOperatorTitle = false;
        boolean hasMaintenancePart = false;
        // åªæ£€æŸ¥å‰10行(通常标题在前几行)
        int maxRows = Math.min(table.getNumberOfRows(), 10);
        for (int i = 0; i < maxRows; i++) {
            XWPFTableRow row = table.getRow(i);
            if (row == null) continue;
            // æ£€æŸ¥æ‰€æœ‰å•元格内容
            for (int j = 0; j < row.getTableCells().size(); j++) {
                String cellText = getCellText(row.getCell(j));
                // æ£€æŸ¥äºŒçº§ä¿å…»ç‰¹å¾
                if (cellText.contains(REPAIR_TITLE)) {
                    hasRepairTitle = true;
                }
                if (cellText.contains(OPERATOR_TITLE)) {
                    hasOperatorTitle = true;
                }
                // æ£€æŸ¥ä¸‰çº§ä¿å…»ç‰¹å¾
                if (cellText.contains("保养部位")) {
                    hasMaintenancePart = true;
                }
            }
        }
        // é€»è¾‘判断
        if ("SECOND".equals(requestedType)) {
            // å¦‚果请求导入二级保养,但文档中有三级保养特征
            return !(hasRepairTitle || hasOperatorTitle) || hasMaintenancePart;
        } else if ("THIRD".equals(requestedType)) {
            // å¦‚果请求导入三级保养,但文档中有二级保养特征
            return !hasMaintenancePart || (hasRepairTitle || hasOperatorTitle);
        }
        return false;
    }
    /**
     * æå–设备基本信息
     */
    private EamMaintenanceStandard extractDeviceInfo(XWPFTable table) {
        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 (isNotBlank(standard.getEquipmentCode()) &&
                isNotBlank(standard.getEquipmentName())) {
            List<EamEquipment> equipments = eamEquipmentService.list(
                    new QueryWrapper<EamEquipment>()
                            .eq("equipment_code", standard.getEquipmentCode())
                            .eq("equipment_name", standard.getEquipmentName())
            );
            if (!equipments.isEmpty()) {
                standard.setEquipmentId(equipments.get(0).getId());
            }else {
                return null;
            }
        }
        return standard;
    }
    // ç®€æ˜“版字符串非空判断
    private boolean isNotBlank(String str) {
        return str != null && !str.trim().isEmpty();
    }
    /**
     * è¡¨æ ¼è¡Œæ•°æ®è§£æž
     */
    private Map<String, String> extractRowData(XWPFTableRow row) {
        Map<String, String> data = new HashMap<>();
        int cellCount = row.getTableCells().size();
        try {
            // é”®å€¼å¯¹æ¨¡å¼ (标签|值|标签|值)
            if (cellCount >= 4 && cellCount % 2 == 0) {
                for (int i = 0; i < cellCount; i += 2) {
                    String key = cleanKey(getCellText(row.getCell(i)));
                    String value = getCellText(row.getCell(i + 1));
                    if (!key.isEmpty()) data.put(key, value);
                }
            }
            // è¿žç»­å•元格模式
            else {
                for (int i = 0; i < cellCount; i++) {
                    String text = getCellText(row.getCell(i));
                    int colonIndex = text.indexOf(':');
                    if (colonIndex > 0) {
                        String key = cleanKey(text.substring(0, colonIndex));
                        String value = text.substring(colonIndex + 1);
                        data.put(key, value);
                    }
                }
            }
        } catch (Exception e) {
            log.error("行数据解析异常", e);
        }
        return data;
    }
    /**
     * é”®åæ ‡å‡†åŒ–处理
     */
    private String cleanKey(String key) {
        if (key == null) return "";
        // ç§»é™¤ç©ºæ ¼å’Œä¸­æ–‡å†’号
        return key.replaceAll("\\s", "").replace(":", "");
    }
    /**
     * é…ç½®ä¿å…»æ ‡å‡†å‚æ•°
     */
    private void configureStandard(EamMaintenanceStandard standard, String type, MultipartFile file) {
        // åŸºç¡€å‚æ•°
        String filename = file.getOriginalFilename();
        if (filename != null && filename.contains(".")) {
            filename = filename.substring(0, filename.lastIndexOf('.'));
        }
        standard.setStandardName(filename)
                .setInitialDate(new Date())
                .setStandardStatus(MaintenanceStandardStatusEnum.START.name())
                .setStandardVersion("v1.0")
                .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());
                }
            }
        }
    }
    /**
     * æå–二级保养项目
     */
    private List<EamMaintenanceStandardDetail> extractSecondMaintenanceItems(
            XWPFTable table, String standardId) {
        List<EamMaintenanceStandardDetail> items = new ArrayList<>();
        EamMaintenanceStandardDetailCategory currentCategory = null;
        for (int i = 0; i < table.getNumberOfRows(); i++) {
            XWPFTableRow row = table.getRow(i);
            if (row == null) continue;
            // æ£€æŸ¥æ˜¯å¦æ˜¯æ ‡é¢˜è¡Œï¼ˆç»´ä¿®äººå‘˜ä¿å…»å†…容或操作人员保养内容)
            String firstCell = getCellText(row.getCell(0));
            if (firstCell != null) {
                for (String title : SECOND_CATEGORY_MAPPING.keySet()) {
                    if (firstCell.contains(title)) {
                        currentCategory = SECOND_CATEGORY_MAPPING.get(title);
                        // æ£€æŸ¥ç¬¬äºŒåˆ—和第三列是否是"序号"和"保养内容"
                        if (row.getTableCells().size() > 2) {
                            String secondCell = getCellText(row.getCell(1));
                            String thirdCell = getCellText(row.getCell(2));
                            // æ˜Žç¡®è·³è¿‡æ ‡é¢˜è¡Œ
                            if ("序号".equals(secondCell) && "保养内容".equals(thirdCell)) {
                                continue; // è·³è¿‡è¿™ä¸€è¡Œ
                            }
                        }
                        // å°è¯•提取标题行中的项目(如果存在)
                        if (row.getTableCells().size() > 2) {
                            String content = getCellText(row.getCell(2));
                            if (content != null && !content.trim().isEmpty() &&
                                    !"保养内容".equals(content.trim())) { // è¿‡æ»¤æ— æ•ˆå†…容
                                items.add(createItem(currentCategory, content.trim(), standardId));
                            }
                        }
                        continue;
                    }
                }
            }
            // å¤„理普通项目行
            if (currentCategory != null && isValidItemRow(row)) {
                // èŽ·å–å†…å®¹
                String content = row.getTableCells().size() > 2 ?
                        getCellText(row.getCell(2)) : "";
                // æŽ’除标题内容
                if ("保养内容".equals(content) ||
                        "序号".equals(content) ||
                        content.contains("维修人员保养内容") ||
                        content.contains("操作人员保养内容")) {
                    continue;
                }
                EamMaintenanceStandardDetail item = new EamMaintenanceStandardDetail();
                item.setItemCategory(String.valueOf(currentCategory));
                item.setStandardId(standardId);
                item.setItemName(cleanContent(content));
                // å¤„理序号(第二列)
                if (row.getTableCells().size() > 1) {
                    String seqText = getCellText(row.getCell(1));
                    try {
                        if (seqText != null && !seqText.trim().isEmpty()) {
                            item.setItemCode(Integer.parseInt(seqText.trim()));
                        }
                    } catch (NumberFormatException e) {
                        // å¿½ç•¥åºå·è§£æžé”™è¯¯
                    }
                }
                items.add(item);
            }
        }
        return items;
    }
    /**
     * åˆ›å»ºä¿å…»é¡¹ç›®
     */
    private EamMaintenanceStandardDetail createItem(
            EamMaintenanceStandardDetailCategory category,
            String content,
            String standardId) {
        EamMaintenanceStandardDetail item = new EamMaintenanceStandardDetail();
        item.setItemCategory(category.name());
        item.setStandardId(standardId);
        item.setItemName(cleanContent(content));
        return item;
    }
    /**
     * æå–三级保养项目(无类型)
     */
    private List<EamMaintenanceStandardDetail> extractThirdMaintenanceItems(
            XWPFTable table, String standardId) {
        List<EamMaintenanceStandardDetail> items = new ArrayList<>();
        String currentPart = "";
        int itemCount = 1;
        // ä»Žç¬¬ä¸‰è¡Œå¼€å§‹ï¼ˆè·³è¿‡è¡¨å¤´å’Œè®¾å¤‡ä¿¡æ¯ï¼‰
        for (int i = 2; i < table.getNumberOfRows(); i++) {
            XWPFTableRow row = table.getRow(i);
            if (row == null || isRowEmpty(row)) continue;
            // è·³è¿‡"保养部位"标题行
            String firstCell = getCellText(row.getCell(0));
            if ("保养部位".equals(firstCell)) {
                continue;
            }
            EamMaintenanceStandardDetail item = new EamMaintenanceStandardDetail();
            // ä¸‰çº§ä¿å…»ä¸éœ€è¦ç±»åž‹ï¼Œä¸è®¾ç½®itemCategory
            item.setStandardId(standardId);
            item.setItemCode(itemCount++);
            // å¤„理部位列
            if (!row.getTableCells().isEmpty()) {
                String partCell = getCellText(row.getCell(0));
                if (!partCell.trim().isEmpty()) {
                    currentPart = partCell.trim();
                }
            }
            item.setItemPart(currentPart);
            // æ ¹æ®åˆ—数确定内容和标准的位置
            int cellCount = row.getTableCells().size();
            if (cellCount == 3) { // éƒ¨ä½|内容|标准
                item.setItemName(getCellText(row.getCell(1)));
                item.setItemDemand(getCellText(row.getCell(2)));
            }
            else if (cellCount == 2) { // å†…容|标准
                item.setItemName(getCellText(row.getCell(0)));
                item.setItemDemand(getCellText(row.getCell(1)));
            }
            else if (cellCount == 1) { // å•列内容
                item.setItemName(getCellText(row.getCell(0)));
            }
            else if (cellCount > 3) { // å¤šåˆ—处理
                // å–第2列作为内容,最后一列作为标准
                item.setItemName(getCellText(row.getCell(1)));
                item.setItemDemand(getCellText(row.getCell(cellCount - 1)));
            }
            items.add(item);
        }
        return items;
    }
    /**
     * å…¼å®¹ç‰ˆå•元格文本提取
     */
    private String getCellText(XWPFTableCell cell) {
        if (cell == null) return "";
        StringBuilder text = new StringBuilder();
        for (XWPFParagraph para : cell.getParagraphs()) {
            if (para != null) {
                for (XWPFRun run : para.getRuns()) {
                    if (run != null) {
                        String runText = run.getText(0);
                        if (runText != null) {
                            text.append(runText);
                        }
                    }
                }
            }
        }
        return text.toString();
    }
    /**
     * å†…容清理
     */
    private String cleanContent(String text) {
        if (text == null) return "";
        // æ›¿æ¢ç‰¹æ®Šç©ºæ ¼å’Œåˆå¹¶è¿žç»­ç©ºæ ¼
        text = text.replace('\u00A0', ' ')
                .replace('\u2007', ' ')
                .replace('\u202F', ' ')
                .replaceAll("\\s+", " ");
        // è§„范标点符号
        return text.replace(',', '、')
                .replace(',', '、')
                .replace(';', ';')
                .replace(';', ';')
                .replace(':', ':')
                .replace(':', ':')
                .trim();
    }
    /**
     * éªŒè¯æœ‰æ•ˆé¡¹ç›®è¡Œ
     */
    private boolean isValidItemRow(XWPFTableRow row) {
        return row != null &&
                row.getTableCells().size() >= 2 &&
                !getCellText(row.getCell(1)).trim().isEmpty();
    }
    /**
     * ç©ºè¡Œæ£€æµ‹
     */
    private boolean isRowEmpty(XWPFTableRow row) {
        if (row == null) return true;
        for (XWPFTableCell cell : row.getTableCells()) {
            String text = getCellText(cell);
            if (text != null && !text.trim().isEmpty()) {
                return false;
            }
        }
        return true;
    }
    /*导入二保三保文件Excel--------------------------结束*/
}