package com.estate.expert.admin.io.processor.impl.standard; import com.estate.expert.admin.domain.standard.problem.Problem; import com.estate.expert.admin.domain.standard.problem.detail.NumberFactor; import com.estate.expert.admin.domain.standard.problem.detail.ScaleFactor; import com.estate.expert.admin.domain.standard.problem.enums.IncidentType; import com.estate.expert.admin.io.processor.RowDataProcessorBase; import com.estate.expert.admin.service.HierarchyService; import com.estate.expert.admin.utils.ExcelParseUtils; import lombok.AllArgsConstructor; import org.apache.commons.lang3.StringUtils; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; /** * 问题处理器 * * 用于处理问题信息的读取和写入 * - 综合体系(ID=1):第6层叶子节点 * - 其他体系(ID!=1):第4层叶子节点 * * Excel 格式(参考 ImportProblemJob.java,共41列): * 0-9列:基础信息(10列) * 10-14列:数量因子名称(5列) * 15-19列:数量因子对应数值(5列) * 20-24列:数量因子扣除分数(5列) * 25-29列:数量因子附加分数(5列) * 30-34列:预留(5列) * 35-37列:比例因子名称(3列) * 38-40列:比例因子系数(3列) */ @AllArgsConstructor public class ProblemProcessor extends RowDataProcessorBase { private HierarchyService hierarchyService; private Integer hierarchyId; @Override protected String[] getHeaders() { return new String[]{ // 基础信息(0-9列) "描述", "规范与条款", "建议措施", "数值", "事故类型", "点评范式", "责任人", "责任部门", "事故案例", "正确做法", // 数量因子(10-29列) // 问题数量集合(10-14列) "问题数量集合", "问题数量集合", "问题数量集合", "问题数量集合", "问题数量集合", // 对应数值(Rn)(15-19列) "对应数值(Rn)", "对应数值(Rn)", "对应数值(Rn)", "对应数值(Rn)", "对应数值(Rn)", // 扣除分数(20-24列) "扣除分数", "扣除分数", "扣除分数", "扣除分数", "扣除分数", // 附加分数(25-29列) "附加分数", "附加分数", "附加分数", "附加分数", "附加分数", // 预留(30-34列) "", "", "", "", "", // 比例因子(35-40列) // 对应规模集合/规模名称(35-37列) "规模名称", "规模名称", "规模名称", // 对应规模系数(38-40列) "对应规模系数", "对应规模系数", "对应规模系数" }; } @Override public String getName() { return "问题信息"; } @Override protected List buildRowData(Problem data) { List row = new ArrayList<>(); // 基础信息(0-9列) row.add(data.getDescription() != null ? data.getDescription() : ""); row.add(data.getSpecificTerms() != null && !data.getSpecificTerms().isEmpty() ? String.join("; ", data.getSpecificTerms()) : ""); row.add(data.getSuggestActions() != null && !data.getSuggestActions().isEmpty() ? String.join("; ", data.getSuggestActions()) : ""); row.add(data.getNumValue() != null ? data.getNumValue().toString() : ""); row.add(data.getIncidentTypes() != null && !data.getIncidentTypes().isEmpty() ? data.getIncidentTypes().stream().map(IncidentType::getName).collect(Collectors.joining("; ")) : ""); row.add(data.getReviewParadigm() != null ? data.getReviewParadigm() : ""); row.add(data.getResponsiblePerson() != null ? data.getResponsiblePerson() : ""); row.add(data.getResponsibleDepartment() != null ? data.getResponsibleDepartment() : ""); row.add(""); // 事故案例(暂不支持) row.add(data.getCorrectPractice() != null ? data.getCorrectPractice() : ""); // 数量因子(10-29列)- 最多5组 List numberFactors = data.getNumberFactors() != null ? data.getNumberFactors() : new ArrayList<>(); // 名称(10-14列) for(int i = 0; i < 5; i++) { row.add(i < numberFactors.size() ? numberFactors.get(i).getName() : ""); } // 对应数值(15-19列) for(int i = 0; i < 5; i++) { row.add(i < numberFactors.size() ? String.valueOf(numberFactors.get(i).getValue()) : ""); } // 扣除分数(20-24列) for(int i = 0; i < 5; i++) { row.add(i < numberFactors.size() ? String.valueOf(numberFactors.get(i).getDeductPoint()) : ""); } // 附加分数(25-29列) for(int i = 0; i < 5; i++) { row.add(i < numberFactors.size() ? String.valueOf(numberFactors.get(i).getAdditionPoint()) : ""); } // 预留(30-34列) for(int i = 0; i < 5; i++) { row.add(""); } // 比例因子(35-40列)- 最多3组 List scaleFactors = data.getScaleFactors() != null ? data.getScaleFactors() : new ArrayList<>(); // 名称(35-37列) for(int i = 0; i < 3; i++) { row.add(i < scaleFactors.size() ? scaleFactors.get(i).getName() : ""); } // 系数(38-40列) for(int i = 0; i < 3; i++) { row.add(i < scaleFactors.size() ? String.valueOf(scaleFactors.get(i).getFactor()) : ""); } return row; } @Override protected Problem parseRowData(int rowIndex, List rowData) { var index = 0; var problem = new Problem(); // 基础信息(0-9列) problem.setDescription(ExcelParseUtils.parseString(rowData.get(index++))); // 规范与条款(支持分号分隔多个) String specificTerms = ExcelParseUtils.parseString(rowData.get(index++)); if(StringUtils.isNotBlank(specificTerms)) { problem.setSpecificTerms(List.of(specificTerms.split(";"))); } // 建议措施(支持分号分隔多个) String suggestActions = ExcelParseUtils.parseString(rowData.get(index++)); if(StringUtils.isNotBlank(suggestActions)) { problem.setSuggestActions(List.of(suggestActions.split(";"))); } // 数值 String numValueStr = ExcelParseUtils.parseString(rowData.get(index++)); if(StringUtils.isNotBlank(numValueStr)) { try { problem.setNumValue(Float.parseFloat(numValueStr)); } catch (NumberFormatException e) { problem.setNumValue(1.0f); // 默认为1 } } else { problem.setNumValue(1.0f); } // 事故类型 String incidentTypes = ExcelParseUtils.parseString(rowData.get(index++)); if(StringUtils.isNotBlank(incidentTypes)) { problem.setIncidentTypes(IncidentType.parse(incidentTypes)); } problem.setReviewParadigm(ExcelParseUtils.parseString(rowData.get(index++))); problem.setResponsiblePerson(ExcelParseUtils.parseString(rowData.get(index++))); problem.setResponsibleDepartment(ExcelParseUtils.parseString(rowData.get(index++))); // 事故案例(跳过) index++; problem.setCorrectPractice(ExcelParseUtils.parseString(rowData.get(index++))); // 数量因子(10-29列)- 最多5组 List numberFactors = new ArrayList<>(); // 先读取所有名称(10-14列) String[] factorNames = new String[5]; for(int i = 0; i < 5; i++) { factorNames[i] = ExcelParseUtils.parseString(rowData.get(index++)); } // 读取对应数值(15-19列) Float[] factorValues = new Float[5]; for(int i = 0; i < 5; i++) { String val = ExcelParseUtils.parseString(rowData.get(index++)); if(StringUtils.isNotBlank(val)) { try { factorValues[i] = Float.parseFloat(val); } catch (NumberFormatException e) { factorValues[i] = null; } } } // 读取扣除分数(20-24列) Float[] deductPoints = new Float[5]; for(int i = 0; i < 5; i++) { String val = ExcelParseUtils.parseString(rowData.get(index++)); if(StringUtils.isNotBlank(val)) { try { deductPoints[i] = Float.parseFloat(val); } catch (NumberFormatException e) { deductPoints[i] = null; } } } // 读取附加分数(25-29列) Float[] additionPoints = new Float[5]; for(int i = 0; i < 5; i++) { String val = ExcelParseUtils.parseString(rowData.get(index++)); if(StringUtils.isNotBlank(val)) { try { additionPoints[i] = Float.parseFloat(val); } catch (NumberFormatException e) { additionPoints[i] = null; } } } // 组装数量因子 for(int i = 0; i < 5; i++) { if(StringUtils.isNotBlank(factorNames[i])) { NumberFactor factor = new NumberFactor(); factor.setName(factorNames[i]); factor.setValue(factorValues[i] != null ? factorValues[i] : 0f); factor.setDeductPoint(deductPoints[i] != null ? deductPoints[i] : 0f); factor.setAdditionPoint(additionPoints[i] != null ? additionPoints[i] : 0f); numberFactors.add(factor); } } problem.setNumberFactors(numberFactors); // 预留(30-34列) for(int i = 0; i < 5; i++) { index++; } // 比例因子(35-40列)- 最多3组 List scaleFactors = new ArrayList<>(); // 先读取所有名称(35-37列) String[] scaleNames = new String[3]; for(int i = 0; i < 3; i++) { scaleNames[i] = ExcelParseUtils.parseString(rowData.get(index++)); } // 读取系数(38-40列) Float[] scaleValues = new Float[3]; for(int i = 0; i < 3; i++) { String val = ExcelParseUtils.parseString(rowData.get(index++)); if(StringUtils.isNotBlank(val)) { try { scaleValues[i] = Float.parseFloat(val); } catch (NumberFormatException e) { scaleValues[i] = null; } } } // 组装比例因子 for(int i = 0; i < 3; i++) { if(StringUtils.isNotBlank(scaleNames[i])) { ScaleFactor factor = new ScaleFactor(); factor.setName(scaleNames[i]); factor.setFactor(scaleValues[i] != null ? scaleValues[i] : 1f); scaleFactors.add(factor); } } problem.setScaleFactors(scaleFactors); // 设置体系信息(不从Excel读取,由参数指定) problem.setHierarchyId(hierarchyId); return problem; } }