Просмотр исходного кода

fit:bug修复 任务流程/表格样式

zzw 3 недель назад
Родитель
Сommit
6e0da0a3ba

+ 588 - 56
assistMg/src/main/java/com/hotent/enterpriseDeclare/controller/material/CostProjectTaskSurveyGenericController.java

@@ -613,33 +613,69 @@ public class CostProjectTaskSurveyGenericController {
                 String sheetName = System.currentTimeMillis() + "_成本调查表";
                 Sheet sheet = workbook.createSheet(sheetName);
 
-                Row headerRow = sheet.createRow(0);
+                // 创建样式
+                CellStyle titleStyle = createTitleStyle(workbook);
+                CellStyle headerStyle = createHeaderStyle(workbook);
+                CellStyle dataStyle = createDataStyle(workbook);
+
+                // 第一行:大标题
+                Row titleRow = sheet.createRow(0);
+                Cell titleCell = titleRow.createCell(0);
+                titleCell.setCellValue(templateName);
+                titleCell.setCellStyle(titleStyle);
+
+                // 计算总列数(包括隐藏列)
+                int totalColumns = headersList.size();
+                boolean needExtraColumns = "2".equals(templateType) || "3".equals(templateType);
+                if (needExtraColumns) {
+                    totalColumns += 2; // rowId + parentId
+                }
+                if ("2".equals(templateType) && auditPeriods != null && auditPeriods.length > 0) {
+                    totalColumns += auditPeriods.length + 1; // 年限列 + 备注列
+                }
+
+                // 合并标题行单元格
+                if (totalColumns > 1) {
+                    sheet.addMergedRegion(new org.apache.poi.ss.util.CellRangeAddress(0, 0, 0, totalColumns - 1));
+                }
+
+                // 第二行:列表头
+                Row headerRow = sheet.createRow(1);
                 int colIndex = 0;
 
                 // 添加原有表头
                 for (int i = 0; i < headersList.size(); i++) {
-                    headerRow.createCell(colIndex++).setCellValue(headersList.get(i).getFieldName());
+                    Cell headerCell = headerRow.createCell(colIndex++);
+                    headerCell.setCellValue(headersList.get(i).getFieldName());
+                    headerCell.setCellStyle(headerStyle);
                 }
 
                 // 如果是固定表或动态表,在最后添加特殊列
                 int rowIdColIndex = -1;
                 int parentIdColIndex = -1;
-                boolean needExtraColumns = "2".equals(templateType) || "3".equals(templateType);
                 if (needExtraColumns) {
                     // 添加 rowId 列(用于标识行)
                     rowIdColIndex = colIndex;
-                    headerRow.createCell(colIndex++).setCellValue("行ID");
+                    Cell rowIdCell = headerRow.createCell(colIndex++);
+                    rowIdCell.setCellValue("行ID");
+                    rowIdCell.setCellStyle(headerStyle);
                     // 添加 parentId 列(用于标识父子关系)
                     parentIdColIndex = colIndex;
-                    headerRow.createCell(colIndex++).setCellValue("父行ID");
+                    Cell parentIdCell = headerRow.createCell(colIndex++);
+                    parentIdCell.setCellValue("父行ID");
+                    parentIdCell.setCellStyle(headerStyle);
                 }
 
                 // 只有固定表需要添加年限列和备注列
                 if ("2".equals(templateType) && auditPeriods != null && auditPeriods.length > 0) {
                     for (String period : auditPeriods) {
-                        headerRow.createCell(colIndex++).setCellValue(period.trim());
+                        Cell periodCell = headerRow.createCell(colIndex++);
+                        periodCell.setCellValue(period.trim());
+                        periodCell.setCellStyle(headerStyle);
                     }
-                    headerRow.createCell(colIndex++).setCellValue("备注");
+                    Cell remarkCell = headerRow.createCell(colIndex++);
+                    remarkCell.setCellValue("备注");
+                    remarkCell.setCellStyle(headerStyle);
                 }
 
                 if (itemsList != null && !itemsList.isEmpty()) {
@@ -647,7 +683,7 @@ public class CostProjectTaskSurveyGenericController {
                     for (int i = 0; i < headersList.size(); i++) {
                         headerIndexMap.put(headersList.get(i).getId(), i);
                     }
-                    fillExcelData(sheet, itemsList, headerIndexMap, templateType, type, rowIdColIndex, parentIdColIndex);
+                    fillExcelData(sheet, itemsList, headerIndexMap, templateType, type, rowIdColIndex, parentIdColIndex, dataStyle);
                 }
 
                 for (int i = 0; i < headersList.size(); i++) {
@@ -734,33 +770,69 @@ public class CostProjectTaskSurveyGenericController {
                 String sheetName = System.currentTimeMillis() + "_财务数据表";
                 Sheet sheet = workbook.createSheet(sheetName);
 
-                Row headerRow = sheet.createRow(0);
+                // 创建样式
+                CellStyle titleStyle = createTitleStyle(workbook);
+                CellStyle headerStyle = createHeaderStyle(workbook);
+                CellStyle dataStyle = createDataStyle(workbook);
+
+                // 第一行:大标题
+                Row titleRow = sheet.createRow(0);
+                Cell titleCell = titleRow.createCell(0);
+                titleCell.setCellValue(templateName);
+                titleCell.setCellStyle(titleStyle);
+
+                // 计算总列数(包括隐藏列)
+                int totalColumns = headersList.size();
+                boolean needExtraColumns = "2".equals(templateType) || "3".equals(templateType);
+                if (needExtraColumns) {
+                    totalColumns += 2; // rowId + parentId
+                }
+                if ("2".equals(templateType) && auditPeriods != null && auditPeriods.length > 0) {
+                    totalColumns += auditPeriods.length + 1; // 年限列 + 备注列
+                }
+
+                // 合并标题行单元格
+                if (totalColumns > 1) {
+                    sheet.addMergedRegion(new org.apache.poi.ss.util.CellRangeAddress(0, 0, 0, totalColumns - 1));
+                }
+
+                // 第二行:列表头
+                Row headerRow = sheet.createRow(1);
                 int colIndex = 0;
 
                 // 添加原有表头
                 for (int i = 0; i < headersList.size(); i++) {
-                    headerRow.createCell(colIndex++).setCellValue(headersList.get(i).getFieldName());
+                    Cell headerCell = headerRow.createCell(colIndex++);
+                    headerCell.setCellValue(headersList.get(i).getFieldName());
+                    headerCell.setCellStyle(headerStyle);
                 }
 
                 // 如果是固定表或动态表,在最后添加特殊列
                 int rowIdColIndex = -1;
                 int parentIdColIndex = -1;
-                boolean needExtraColumns = "2".equals(templateType) || "3".equals(templateType);
                 if (needExtraColumns) {
                     // 添加 rowId 列(用于标识行)
                     rowIdColIndex = colIndex;
-                    headerRow.createCell(colIndex++).setCellValue("行ID");
+                    Cell rowIdCell = headerRow.createCell(colIndex++);
+                    rowIdCell.setCellValue("行ID");
+                    rowIdCell.setCellStyle(headerStyle);
                     // 添加 parentId 列(用于标识父子关系)
                     parentIdColIndex = colIndex;
-                    headerRow.createCell(colIndex++).setCellValue("父行ID");
+                    Cell parentIdCell = headerRow.createCell(colIndex++);
+                    parentIdCell.setCellValue("父行ID");
+                    parentIdCell.setCellStyle(headerStyle);
                 }
 
                 // 只有固定表需要添加年限列和备注列
                 if ("2".equals(templateType) && auditPeriods != null && auditPeriods.length > 0) {
                     for (String period : auditPeriods) {
-                        headerRow.createCell(colIndex++).setCellValue(period.trim());
+                        Cell periodCell = headerRow.createCell(colIndex++);
+                        periodCell.setCellValue(period.trim());
+                        periodCell.setCellStyle(headerStyle);
                     }
-                    headerRow.createCell(colIndex++).setCellValue("备注");
+                    Cell remarkCell = headerRow.createCell(colIndex++);
+                    remarkCell.setCellValue("备注");
+                    remarkCell.setCellStyle(headerStyle);
                 }
 
                 if (itemsList != null && !itemsList.isEmpty()) {
@@ -768,7 +840,7 @@ public class CostProjectTaskSurveyGenericController {
                     for (int i = 0; i < headersList.size(); i++) {
                         headerIndexMap.put(headersList.get(i).getId(), i);
                     }
-                    fillExcelDataFd(sheet, itemsList, headerIndexMap, templateType, rowIdColIndex, parentIdColIndex);
+                    fillExcelDataFd(sheet, itemsList, headerIndexMap, templateType, rowIdColIndex, parentIdColIndex, dataStyle);
                 }
 
                 for (int i = 0; i < headersList.size(); i++) {
@@ -841,24 +913,50 @@ public class CostProjectTaskSurveyGenericController {
                 String sheetName = System.currentTimeMillis() + "_核定表";
                 Sheet sheet = workbook.createSheet(sheetName);
 
-                Row headerRow = sheet.createRow(0);
+                // 创建样式
+                CellStyle titleStyle = createTitleStyle(workbook);
+                CellStyle headerStyle = createHeaderStyle(workbook);
+                CellStyle dataStyle = createDataStyle(workbook);
+
+                // 第一行:大标题
+                Row titleRow = sheet.createRow(0);
+                Cell titleCell = titleRow.createCell(0);
+                titleCell.setCellValue(template.getSurveyTemplateName());
+                titleCell.setCellStyle(titleStyle);
+
+                // 计算总列数(包括隐藏列)
+                int totalColumns = headersList.size() + 2; // 包括行ID和父行ID
+
+                // 合并标题行单元格
+                if (totalColumns > 1) {
+                    sheet.addMergedRegion(new org.apache.poi.ss.util.CellRangeAddress(0, 0, 0, totalColumns - 1));
+                }
+
+                // 第二行:列表头
+                Row headerRow = sheet.createRow(1);
                 int colIndex = 0;
 
                 for (int i = 0; i < headersList.size(); i++) {
-                    headerRow.createCell(colIndex++).setCellValue(headersList.get(i).getFieldName());
+                    Cell headerCell = headerRow.createCell(colIndex++);
+                    headerCell.setCellValue(headersList.get(i).getFieldName());
+                    headerCell.setCellStyle(headerStyle);
                 }
 
                 int rowIdColIndex = colIndex;
-                headerRow.createCell(colIndex++).setCellValue("行ID");
+                Cell rowIdCell = headerRow.createCell(colIndex++);
+                rowIdCell.setCellValue("行ID");
+                rowIdCell.setCellStyle(headerStyle);
                 int parentIdColIndex = colIndex;
-                headerRow.createCell(colIndex++).setCellValue("父行ID");
+                Cell parentIdCell = headerRow.createCell(colIndex++);
+                parentIdCell.setCellValue("父行ID");
+                parentIdCell.setCellStyle(headerStyle);
 
                 if (itemsList != null && !itemsList.isEmpty()) {
                     Map<String, Integer> headerIndexMap = new HashMap<>();
                     for (int i = 0; i < headersList.size(); i++) {
                         headerIndexMap.put(headersList.get(i).getId(), i);
                     }
-                    fillExcelDataVerify(sheet, itemsList, headerIndexMap, rowIdColIndex, parentIdColIndex);
+                    fillExcelDataVerify(sheet, itemsList, headerIndexMap, rowIdColIndex, parentIdColIndex, dataStyle);
                 }
 
                 for (int i = 0; i < headersList.size(); i++) {
@@ -979,7 +1077,8 @@ public class CostProjectTaskSurveyGenericController {
                         return CommonResult.<String>error().message("Excel文件没有数据");
                     }
 
-                    Row headerRow = sheet.getRow(0);
+                    // 第0行是标题,第1行是表头
+                    Row headerRow = sheet.getRow(1);
                     if (headerRow == null) {
                         return CommonResult.<String>error().message("Excel文件第一行为空");
                     }
@@ -1029,11 +1128,21 @@ public class CostProjectTaskSurveyGenericController {
                         }
                     }
 
+//                    // 校验表头是否与导出时一致
+//                    List<String> headerValidationErrors = validateExcelHeaders(
+//                        headerRow, headersList, taskId, templateType, type,
+//                        rowIdColumnIndex, parentIdColumnIndex, auditPeriodColumnMap, remarkColumnIndex);
+//                    if (!headerValidationErrors.isEmpty()) {
+//                        return CommonResult.<String>error().message(
+//                                "导入失败,表头校验不通过:<br>" + String.join("<br>", headerValidationErrors));
+//                    }
+
                     List<CostSurveyTemplateUploadData> dataList = new ArrayList<>();
                     Map<String, Integer> rowIdToExcelRowMap = new HashMap<>();
                     int dataRowCount = 0;
 
-                    for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
+                    // 从第2行开始读取数据(第0行是标题,第1行是表头)
+                    for (int rowIndex = 2; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
                         Row dataRow = sheet.getRow(rowIndex);
                         if (dataRow == null || isEmptyRow(dataRow)) continue;
 
@@ -1047,7 +1156,9 @@ public class CostProjectTaskSurveyGenericController {
                                 currentRowId = excelRowId.trim();
                             } else {
                                 // 固定表和动态表都不支持新增行,行ID不能为空
-                                return CommonResult.<String>error().message(String.format("第%d行 行ID不能为空,请使用系统导出的模板文件", rowIndex + 1));
+                                CommonResult<String> result = CommonResult.<String>error().message(String.format("第%d行 行ID不能为空,请使用系统导出的模板文件", rowIndex + 1));
+                                result.setCode(250);
+                                return result;
                             }
                         } else {
                             return CommonResult.<String>error().message("固定表/动态表导入失败:Excel文件缺少【行ID】列。请使用系统导出的模板,不要删除隐藏列。");
@@ -1196,7 +1307,8 @@ public class CostProjectTaskSurveyGenericController {
                         return CommonResult.<String>error().message("Excel文件没有数据");
                     }
 
-                    Row headerRow = sheet.getRow(0);
+                    // 第0行是标题,第1行是表头
+                    Row headerRow = sheet.getRow(1);
                     if (headerRow == null) {
                         return CommonResult.<String>error().message("Excel文件第一行为空");
                     }
@@ -1236,11 +1348,21 @@ public class CostProjectTaskSurveyGenericController {
                         return CommonResult.<String>error().message("Excel表头与模板表头不匹配");
                     }
 
+                    // 校验表头是否与导出时一致
+//                    List<String> headerValidationErrors = validateExcelHeadersFd(
+//                        headerRow, headersList, taskId, templateType, type,
+//                        rowIdColumnIndex, parentIdColumnIndex, auditPeriodColumnMap, remarkColumnIndex);
+//                    if (!headerValidationErrors.isEmpty()) {
+//                        return CommonResult.<String>error().message(
+//                                "导入失败,表头校验不通过:<br>" + String.join("<br>", headerValidationErrors));
+//                    }
+
                     List<CostSurveyTemplateUploadData> dataList = new ArrayList<>();
                     Map<String, Integer> rowIdToExcelRowMap = new HashMap<>();
                     int dataRowCount = 0;
 
-                    for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
+                    // 从第2行开始读取数据(第0行是标题,第1行是表头)
+                    for (int rowIndex = 2; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
                         Row dataRow = sheet.getRow(rowIndex);
                         if (dataRow == null || isEmptyRow(dataRow)) continue;
 
@@ -1254,7 +1376,9 @@ public class CostProjectTaskSurveyGenericController {
                                 currentRowId = excelRowId.trim();
                             } else {
                                 // 固定表和动态表都不支持新增行,行ID不能为空
-                                return CommonResult.<String>error().message(String.format("第%d行 行ID不能为空,请使用系统导出的模板文件", rowIndex + 1));
+                                CommonResult<String> result = CommonResult.<String>error().message(String.format("第%d行 行ID不能为空,请使用系统导出的模板文件", rowIndex + 1));
+                                result.setCode(250);
+                                return result;
                             }
                         } else {
                             return CommonResult.<String>error().message("固定表/动态表导入失败:Excel文件缺少【行ID】列。请使用系统导出的模板,不要删除隐藏列。");
@@ -1396,7 +1520,8 @@ public class CostProjectTaskSurveyGenericController {
                         return CommonResult.<String>error().message("Excel文件没有数据");
                     }
 
-                    Row headerRow = sheet.getRow(0);
+                    // 第0行是标题,第1行是表头
+                    Row headerRow = sheet.getRow(1);
                     if (headerRow == null) {
                         return CommonResult.<String>error().message("Excel表头行为空");
                     }
@@ -1434,7 +1559,8 @@ public class CostProjectTaskSurveyGenericController {
                     Map<String, Integer> rowIdToExcelRowMap = new HashMap<>();
                     int importRowCount = 0;
 
-                    for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
+                    // 从第2行开始读取数据(第0行是标题,第1行是表头)
+                    for (int rowIndex = 2; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
                         Row dataRow = sheet.getRow(rowIndex);
                         if (dataRow == null || isEmptyRow(dataRow)) continue;
 
@@ -1448,7 +1574,9 @@ public class CostProjectTaskSurveyGenericController {
                                 currentRowId = excelRowId.trim();
                             } else {
                                 // 核定表不支持新增行,行ID不能为空
-                                return CommonResult.<String>error().message(String.format("第%d行 行ID不能为空,请使用系统导出的模板文件", rowIndex + 1));
+                                CommonResult<String> result = CommonResult.<String>error().message(String.format("第%d行 行ID不能为空,请使用系统导出的模板文件", rowIndex + 1));
+                                result.setCode(250);
+                                return result;
                             }
                         } else {
                             // 核定表必须有行ID列
@@ -1493,7 +1621,9 @@ public class CostProjectTaskSurveyGenericController {
                     return CommonResult.<String>ok().message("导入成功,共导入 " + importRowCount + " 行数据");
 
                 } catch (Exception e) {
-                    return CommonResult.<String>error().message("导入失败:" + e.getMessage());
+                    CommonResult<String> result = CommonResult.<String>error().message("导入失败:" + e.getMessage());
+                    result.setCode(250);
+                    return result;
                 } finally {
                     if (workbook != null) workbook.close();
                 }
@@ -1589,7 +1719,12 @@ public class CostProjectTaskSurveyGenericController {
 
                     if (StringUtil.isEmpty(cellCode)) {
                         // rowid 不匹配说明导入的Excel不是从当前模板导出的,添加到错误列表
-                        errors.add(String.format("行[%s] 的行ID在模板中不存在,请使用系统导出的最新模板文件", rowid));
+                        Integer excelRowNum = rowIdToExcelRowMap.get(rowid);
+                        if (excelRowNum != null) {
+                            errors.add(String.format("第%d行的数据在当前模板中不存在,请使用系统导出的最新模板文件", excelRowNum));
+                        } else {
+                            errors.add("存在无法识别的数据行,请使用系统导出的最新模板文件");
+                        }
                         continue;
                     }
 
@@ -1865,8 +2000,11 @@ public class CostProjectTaskSurveyGenericController {
             }
 
             if (!invalidValues.isEmpty()) {
-                throw new IllegalArgumentException(String.format("%s [%s]的值[%s]不在允许的选项范围内",
-                        rowDisplay, fieldName, String.join(", ", invalidValues)));
+                // 构建详细的错误信息,包含允许的选项范围
+                String validOptionsStr = String.join("、", validValues);
+                throw new IllegalArgumentException(String.format(
+                        "%s [%s]的值[%s]不在允许的选项范围内。允许的选项有:%s",
+                        rowDisplay, fieldName, String.join("、", invalidValues), validOptionsStr));
             }
         } catch (IllegalArgumentException e) {
             throw e;
@@ -2252,11 +2390,18 @@ public class CostProjectTaskSurveyGenericController {
         java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("[A-Z]+\\d+");
         java.util.regex.Matcher matcher = pattern.matcher(calculationFormula);
         List<String> referencedCellsDebug = new ArrayList<>();
+        Map<String, String> cellCodeToItemNameMap = new HashMap<>(); // 存储cellCode到项目名称的映射
+
         while (matcher.find()) {
             String referencedCell = matcher.group();
             String mapKey = referencedCell + "_" + period;
             String value = globalCellCodeMap.get(mapKey);
             String displayValue = StringUtil.isNotEmpty(value) ? value : "0";
+
+            // 获取该cellCode对应的项目名称
+            String itemName = getCellCodeItemName(referencedCell, type);
+            cellCodeToItemNameMap.put(referencedCell, itemName);
+
             referencedCellsDebug.add(referencedCell + "=" + displayValue);
             if (StringUtil.isNotEmpty(value)) {
                 hasAnyReferencedValue = true;
@@ -2305,8 +2450,12 @@ public class CostProjectTaskSurveyGenericController {
                 // 获取友好的行号显示
                 Integer excelRow = rowIdToExcelRowMap.get(rowid);
                 String rowDisplay = excelRow != null ? "第" + excelRow + "行" : "行[" + rowid + "]";
-                errors.add(String.format("%s %s年列数据错误:计算结果应为%.2f,实际填写%.2f",
-                        rowDisplay, period, calculatedValue, inputValue));
+
+                // 构建详细的计算过程(包含项目名称)
+                String calculationProcess = buildCalculationProcessWithNames(calculationFormula, referencedCellsDebug, cellCodeToItemNameMap);
+
+                errors.add(String.format("%s %s年列数据错误:<br>计算公式:%s<br>计算过程:%s<br>计算结果:%.2f<br>实际填写:%.2f",
+                        rowDisplay, period, calculationFormula, calculationProcess, calculatedValue, inputValue));
             } else {
                 System.out.println("校验结果: ✓ 通过");
                 System.out.println("========================================");
@@ -2585,13 +2734,15 @@ public class CostProjectTaskSurveyGenericController {
 
     private void fillExcelData(Sheet sheet, List<CostSurveyTemplateItems> itemsList,
                                Map<String, Integer> headerIndexMap, String templateType, String dataType,
-                               int rowIdColIndex, int parentIdColIndex) {
+                               int rowIdColIndex, int parentIdColIndex, CellStyle dataStyle) {
         if ("1".equals(templateType)) {
-            Row dataRow = sheet.createRow(1);
+            Row dataRow = sheet.createRow(2);
             for (CostSurveyTemplateItems item : itemsList) {
                 Integer colIndex = headerIndexMap.get(item.getHeadersId());
                 if (colIndex != null) {
-                    dataRow.createCell(colIndex).setCellValue(item.getRvalue());
+                    Cell cell = dataRow.createCell(colIndex);
+                    cell.setCellValue(item.getRvalue());
+                    cell.setCellStyle(dataStyle);
                 }
             }
         } else {
@@ -2603,7 +2754,11 @@ public class CostProjectTaskSurveyGenericController {
             // 固定表和动态表都需要按父子关系排序
             List<String> sortedRowIds = sortRowIdsByParentChild(itemsByRowId);
 
-            int rowNum = 1;
+            // 获取表头行,计算总列数
+            Row headerRow = sheet.getRow(1);
+            int totalColumns = headerRow != null ? headerRow.getLastCellNum() : 0;
+
+            int rowNum = 2;
             for (String rowId : sortedRowIds) {
                 List<CostSurveyTemplateItems> rowItems = itemsByRowId.get(rowId);
                 if (rowItems != null && !rowItems.isEmpty()) {
@@ -2613,18 +2768,38 @@ public class CostProjectTaskSurveyGenericController {
                     for (CostSurveyTemplateItems item : rowItems) {
                         Integer colIndex = headerIndexMap.get(item.getHeadersId());
                         if (colIndex != null) {
-                            dataRow.createCell(colIndex).setCellValue(item.getRvalue());
+                            Cell cell = dataRow.createCell(colIndex);
+                            cell.setCellValue(item.getRvalue());
+                            cell.setCellStyle(dataStyle);
                         }
                     }
 
                     // 填充 rowId 和 parentId 列
                     if (rowIdColIndex >= 0) {
-                        dataRow.createCell(rowIdColIndex).setCellValue(rowId);
+                        Cell cell = dataRow.createCell(rowIdColIndex);
+                        cell.setCellValue(rowId);
+                        cell.setCellStyle(dataStyle);
                     }
                     if (parentIdColIndex >= 0) {
                         String parentId = rowItems.get(0).getParentid();
                         if (StringUtil.isNotEmpty(parentId)) {
-                            dataRow.createCell(parentIdColIndex).setCellValue(parentId);
+                            Cell cell = dataRow.createCell(parentIdColIndex);
+                            cell.setCellValue(parentId);
+                            cell.setCellStyle(dataStyle);
+                        } else {
+                            // 即使没有值,也要创建单元格并应用样式
+                            Cell cell = dataRow.createCell(parentIdColIndex);
+                            cell.setCellValue("");
+                            cell.setCellStyle(dataStyle);
+                        }
+                    }
+
+                    // 为所有剩余列(年限列和备注列)创建空单元格并应用样式
+                    for (int colIndex = 0; colIndex < totalColumns; colIndex++) {
+                        if (dataRow.getCell(colIndex) == null) {
+                            Cell cell = dataRow.createCell(colIndex);
+                            cell.setCellValue("");
+                            cell.setCellStyle(dataStyle);
                         }
                     }
                 }
@@ -2708,14 +2883,16 @@ public class CostProjectTaskSurveyGenericController {
 
     private void fillExcelDataFd(Sheet sheet, List<CostSurveyFdTemplateItems> itemsList,
                                  Map<String, Integer> headerIndexMap, String templateType,
-                                 int rowIdColIndex, int parentIdColIndex) {
+                                 int rowIdColIndex, int parentIdColIndex, CellStyle dataStyle) {
         if ("1".equals(templateType)) {
             // 单表:所有数据在一行
-            Row dataRow = sheet.createRow(1);
+            Row dataRow = sheet.createRow(2);
             for (CostSurveyFdTemplateItems item : itemsList) {
                 Integer colIndex = headerIndexMap.get(item.getHeadersId());
                 if (colIndex != null) {
-                    dataRow.createCell(colIndex).setCellValue(item.getRvalue());
+                    Cell cell = dataRow.createCell(colIndex);
+                    cell.setCellValue(item.getRvalue());
+                    cell.setCellStyle(dataStyle);
                 }
             }
         } else {
@@ -2727,7 +2904,11 @@ public class CostProjectTaskSurveyGenericController {
             // 固定表和动态表都需要按父子关系排序
             List<String> sortedRowIds = sortRowIdsByParentChildFd(itemsByRowId);
 
-            int rowNum = 1;
+            // 获取表头行,计算总列数
+            Row headerRow = sheet.getRow(1);
+            int totalColumns = headerRow != null ? headerRow.getLastCellNum() : 0;
+
+            int rowNum = 2;
             for (String rowId : sortedRowIds) {
                 List<CostSurveyFdTemplateItems> rowItems = itemsByRowId.get(rowId);
                 if (rowItems != null && !rowItems.isEmpty()) {
@@ -2737,18 +2918,38 @@ public class CostProjectTaskSurveyGenericController {
                     for (CostSurveyFdTemplateItems item : rowItems) {
                         Integer colIndex = headerIndexMap.get(item.getHeadersId());
                         if (colIndex != null) {
-                            dataRow.createCell(colIndex).setCellValue(item.getRvalue());
+                            Cell cell = dataRow.createCell(colIndex);
+                            cell.setCellValue(item.getRvalue());
+                            cell.setCellStyle(dataStyle);
                         }
                     }
 
                     // 填充 rowId 和 parentId 列
                     if (rowIdColIndex >= 0) {
-                        dataRow.createCell(rowIdColIndex).setCellValue(rowId);
+                        Cell cell = dataRow.createCell(rowIdColIndex);
+                        cell.setCellValue(rowId);
+                        cell.setCellStyle(dataStyle);
                     }
                     if (parentIdColIndex >= 0) {
                         String parentId = rowItems.get(0).getParentid();
                         if (StringUtil.isNotEmpty(parentId)) {
-                            dataRow.createCell(parentIdColIndex).setCellValue(parentId);
+                            Cell cell = dataRow.createCell(parentIdColIndex);
+                            cell.setCellValue(parentId);
+                            cell.setCellStyle(dataStyle);
+                        } else {
+                            // 即使没有值,也要创建单元格并应用样式
+                            Cell cell = dataRow.createCell(parentIdColIndex);
+                            cell.setCellValue("");
+                            cell.setCellStyle(dataStyle);
+                        }
+                    }
+
+                    // 为所有剩余列(年限列和备注列)创建空单元格并应用样式
+                    for (int colIndex = 0; colIndex < totalColumns; colIndex++) {
+                        if (dataRow.getCell(colIndex) == null) {
+                            Cell cell = dataRow.createCell(colIndex);
+                            cell.setCellValue("");
+                            cell.setCellStyle(dataStyle);
                         }
                     }
                 }
@@ -2885,7 +3086,7 @@ public class CostProjectTaskSurveyGenericController {
     }
 
     private void fillExcelDataVerify(Sheet sheet, List<CostVerifyTemplateItems> itemsList,
-                                     Map<String, Integer> headerIndexMap, int rowIdColIndex, int parentIdColIndex) {
+                                     Map<String, Integer> headerIndexMap, int rowIdColIndex, int parentIdColIndex, CellStyle dataStyle) {
 
         if (itemsList == null || itemsList.isEmpty()) {
             return;
@@ -2899,7 +3100,11 @@ public class CostProjectTaskSurveyGenericController {
         // 按父子关系排序
         List<String> sortedRowIds = sortRowIdsByParentChildVerify(itemsByRowId);
 
-        int rowNum = 1;
+        // 获取表头行,计算总列数
+        Row headerRow = sheet.getRow(1);
+        int totalColumns = headerRow != null ? headerRow.getLastCellNum() : 0;
+
+        int rowNum = 2;
         int totalCellsWritten = 0;
         int cellsSkippedNoMapping = 0;
 
@@ -2914,7 +3119,9 @@ public class CostProjectTaskSurveyGenericController {
                     if (colIndex != null) {
                         String cellValue = item.getRvalue();
                         if (StringUtil.isNotEmpty(cellValue)) {
-                            dataRow.createCell(colIndex).setCellValue(cellValue);
+                            Cell cell = dataRow.createCell(colIndex);
+                            cell.setCellValue(cellValue);
+                            cell.setCellStyle(dataStyle);
                             totalCellsWritten++;
                         }
                     } else {
@@ -2924,18 +3131,36 @@ public class CostProjectTaskSurveyGenericController {
 
                 // 填充 rowId 和 parentId 列
                 if (rowIdColIndex >= 0) {
-                    dataRow.createCell(rowIdColIndex).setCellValue(rowId);
+                    Cell cell = dataRow.createCell(rowIdColIndex);
+                    cell.setCellValue(rowId);
+                    cell.setCellStyle(dataStyle);
                 }
                 if (parentIdColIndex >= 0) {
                     String parentId = rowItems.get(0).getParentid();
                     if (StringUtil.isNotEmpty(parentId)) {
-                        dataRow.createCell(parentIdColIndex).setCellValue(parentId);
+                        Cell cell = dataRow.createCell(parentIdColIndex);
+                        cell.setCellValue(parentId);
+                        cell.setCellStyle(dataStyle);
+                    } else {
+                        // 即使没有值,也要创建单元格并应用样式
+                        Cell cell = dataRow.createCell(parentIdColIndex);
+                        cell.setCellValue("");
+                        cell.setCellStyle(dataStyle);
+                    }
+                }
+
+                // 为所有剩余列创建空单元格并应用样式
+                for (int colIndex = 0; colIndex < totalColumns; colIndex++) {
+                    if (dataRow.getCell(colIndex) == null) {
+                        Cell cell = dataRow.createCell(colIndex);
+                        cell.setCellValue("");
+                        cell.setCellStyle(dataStyle);
                     }
                 }
             }
         }
 
-        System.out.println("数据填充完成 - 行数: " + (rowNum - 1) + ", 单元格: " + totalCellsWritten + ", 跳过: " + cellsSkippedNoMapping);
+        System.out.println("数据填充完成 - 行数: " + (rowNum - 2) + ", 单元格: " + totalCellsWritten + ", 跳过: " + cellsSkippedNoMapping);
     }
 
 
@@ -3066,4 +3291,311 @@ public class CostProjectTaskSurveyGenericController {
         uploadData.setIsDeleted("0");
         return uploadData;
     }
+
+    /**
+     * 校验Excel表头是否与导出时一致(成本调查表)
+     */
+    private List<String> validateExcelHeaders(Row headerRow, List<CostSurveyTemplateHeaders> headersList,
+                                               String taskId, String templateType, String type,
+                                               Integer rowIdColumnIndex, Integer parentIdColumnIndex,
+                                               Map<String, Integer> auditPeriodColumnMap, Integer remarkColumnIndex) {
+        List<String> errors = new ArrayList<>();
+
+        // 1. 构建期望的表头列表
+        Set<String> expectedHeaders = new HashSet<>();
+        for (CostSurveyTemplateHeaders header : headersList) {
+            if (StringUtil.isEmpty(header.getShowVisible()) || "1".equals(header.getShowVisible())) {
+                expectedHeaders.add(header.getFieldName().trim());
+            }
+        }
+
+        // 2. 如果是固定表,添加年限列和备注列
+        if ("2".equals(templateType)) {
+            CostProjectTask task = costProjectTaskManager.getById(taskId);
+            if (task != null) {
+                CostProjectApproval approval = costProjectApprovalManager.getById(task.getProjectId());
+                if (approval != null && StringUtil.isNotEmpty(approval.getAuditPeriod())) {
+                    String[] periods = approval.getAuditPeriod().split(",");
+                    for (String period : periods) {
+                        expectedHeaders.add(period.trim());
+                    }
+                    expectedHeaders.add("备注");
+                }
+            }
+        }
+
+        // 3. 如果是固定表或动态表,添加行ID和父行ID
+        if ("2".equals(templateType) || "3".equals(templateType)) {
+            expectedHeaders.add("行ID");
+            expectedHeaders.add("父行ID");
+        }
+
+        // 4. 读取Excel中的实际表头
+        Set<String> actualHeaders = new HashSet<>();
+        for (int i = 0; i < headerRow.getLastCellNum(); i++) {
+            Cell cell = headerRow.getCell(i);
+            if (cell != null) {
+                String cellValue = getCellStringValue(cell);
+                if (StringUtil.isNotEmpty(cellValue)) {
+                    actualHeaders.add(cellValue.trim());
+                }
+            }
+        }
+
+        // 5. 检查是否有多余的表头
+        Set<String> extraHeaders = new HashSet<>(actualHeaders);
+        extraHeaders.removeAll(expectedHeaders);
+        if (!extraHeaders.isEmpty()) {
+            errors.add(String.format("Excel文件包含多余的表头列:%s", String.join("、", extraHeaders)));
+        }
+
+        // 6. 检查是否缺少必需的表头
+        Set<String> missingHeaders = new HashSet<>(expectedHeaders);
+        missingHeaders.removeAll(actualHeaders);
+        if (!missingHeaders.isEmpty()) {
+            errors.add(String.format("Excel文件缺少必需的表头列:%s", String.join("、", missingHeaders)));
+        }
+
+        return errors;
+    }
+
+    /**
+     * 校验Excel表头是否与导出时一致(财务数据表)
+     */
+    private List<String> validateExcelHeadersFd(Row headerRow, List<CostSurveyFdTemplateHeaders> headersList,
+                                                 String taskId, String templateType, String type,
+                                                 Integer rowIdColumnIndex, Integer parentIdColumnIndex,
+                                                 Map<String, Integer> auditPeriodColumnMap, Integer remarkColumnIndex) {
+        List<String> errors = new ArrayList<>();
+
+        // 1. 构建期望的表头列表
+        Set<String> expectedHeaders = new HashSet<>();
+        for (CostSurveyFdTemplateHeaders header : headersList) {
+            if (StringUtil.isEmpty(header.getShowVisible()) || "1".equals(header.getShowVisible())) {
+                expectedHeaders.add(header.getFieldName().trim());
+            }
+        }
+
+        // 2. 如果是固定表,添加年限列和备注列
+        if ("2".equals(templateType)) {
+            CostProjectTask task = costProjectTaskManager.getById(taskId);
+            if (task != null) {
+                CostProjectApproval approval = costProjectApprovalManager.getById(task.getProjectId());
+                if (approval != null && StringUtil.isNotEmpty(approval.getAuditPeriod())) {
+                    String[] periods = approval.getAuditPeriod().split(",");
+                    for (String period : periods) {
+                        expectedHeaders.add(period.trim());
+                    }
+                    expectedHeaders.add("备注");
+                }
+            }
+        }
+
+        // 3. 如果是固定表或动态表,添加行ID和父行ID
+        if ("2".equals(templateType) || "3".equals(templateType)) {
+            expectedHeaders.add("行ID");
+            expectedHeaders.add("父行ID");
+        }
+
+        // 4. 读取Excel中的实际表头
+        Set<String> actualHeaders = new HashSet<>();
+        for (int i = 0; i < headerRow.getLastCellNum(); i++) {
+            Cell cell = headerRow.getCell(i);
+            if (cell != null) {
+                String cellValue = getCellStringValue(cell);
+                if (StringUtil.isNotEmpty(cellValue)) {
+                    actualHeaders.add(cellValue.trim());
+                }
+            }
+        }
+
+        // 5. 检查是否有多余的表头
+        Set<String> extraHeaders = new HashSet<>(actualHeaders);
+        extraHeaders.removeAll(expectedHeaders);
+        if (!extraHeaders.isEmpty()) {
+            errors.add(String.format("Excel文件包含多余的表头列:%s", String.join("、", extraHeaders)));
+        }
+
+        // 6. 检查是否缺少必需的表头
+        Set<String> missingHeaders = new HashSet<>(expectedHeaders);
+        missingHeaders.removeAll(actualHeaders);
+        if (!missingHeaders.isEmpty()) {
+            errors.add(String.format("Excel文件缺少必需的表头列:%s", String.join("、", missingHeaders)));
+        }
+
+        return errors;
+    }
+
+    /**
+     * 根据cellCode获取对应的项目名称
+     * @param cellCode 单元格编码,如 "A1"
+     * @param type 类型:1-成本调查表 2-财务数据表 3-核定表
+     * @return 项目名称,如 "基本工资"
+     */
+    private String getCellCodeItemName(String cellCode, String type) {
+        try {
+            List<? extends Object> allItems = null;
+
+            // 根据type获取所有模板项
+            switch (type) {
+                case "1": {
+                    // 成本调查表 - 需要获取所有模板的items
+                    List<CostSurveyTemplate> templates = costSurveyTemplateManager.list();
+                    for (CostSurveyTemplate template : templates) {
+                        CostSurveyTemplateVersion version = costSurveyTemplateVersionManager.selectCurrentVersion(template.getSurveyTemplateId());
+                        if (version != null) {
+                            List<CostSurveyTemplateItems> items = costSurveyTemplateItemsDao.selectBySurveyTemplateIdAndVersion(
+                                    template.getSurveyTemplateId(), version.getId());
+                            for (CostSurveyTemplateItems item : items) {
+                                if (cellCode.equals(item.getCellCode())) {
+                                    return item.getRvalue(); // 返回项目名称
+                                }
+                            }
+                        }
+                    }
+                    break;
+                }
+                case "2": {
+                    // 财务数据表
+                    List<CostSurveyFdTemplate> templates = costSurveyFdTemplateManager.list();
+                    for (CostSurveyFdTemplate template : templates) {
+                        CostSurveyFdTemplateVersion version = costSurveyFdTemplateVersionManager.selectCurrentVersion(template.getSurveyTemplateId());
+                        if (version != null) {
+                            List<CostSurveyFdTemplateItems> items = costSurveyFdTemplateItemsDao.selectBySurveyTemplateIdAndVersion(
+                                    template.getSurveyTemplateId(), version.getId());
+                            for (CostSurveyFdTemplateItems item : items) {
+                                if (cellCode.equals(item.getCellCode())) {
+                                    return item.getRvalue(); // 返回项目名称
+                                }
+                            }
+                        }
+                    }
+                    break;
+                }
+                case "3": {
+                    // 核定表
+                    List<CostVerifyTemplate> templates = costVerifyTemplateManager.list();
+                    for (CostVerifyTemplate template : templates) {
+                        List<CostVerifyTemplateItems> items = costVerifyTemplateItemsDao.selectByVerifyTemplateId(
+                                template.getSurveyTemplateId(), null);
+                        for (CostVerifyTemplateItems item : items) {
+                            if (cellCode.equals(item.getCellCode())) {
+                                return item.getRvalue(); // 返回项目名称
+                            }
+                        }
+                    }
+                    break;
+                }
+            }
+        } catch (Exception e) {
+            System.err.println("获取cellCode[" + cellCode + "]对应的项目名称失败: " + e.getMessage());
+        }
+
+        return cellCode; // 如果找不到,返回cellCode本身
+    }
+
+    /**
+     * 构建带项目名称的计算过程字符串
+     * @param formula 原始公式,如 "(A1+A2+A3)"
+     * @param referencedCellsDebug 引用单元格的值列表,如 ["A1=10", "A2=20", "A3=30"]
+     * @param cellCodeToItemNameMap cellCode到项目名称的映射
+     * @return 计算过程字符串,如 "基本工资(10) + 津贴(20) + 奖金(30)"
+     */
+    private String buildCalculationProcessWithNames(String formula, List<String> referencedCellsDebug,
+                                                     Map<String, String> cellCodeToItemNameMap) {
+        String process = formula;
+
+        // 将引用单元格替换为 "项目名称(值)" 的格式
+        for (String cellDebug : referencedCellsDebug) {
+            String[] parts = cellDebug.split("=");
+            if (parts.length == 2) {
+                String cellCode = parts[0];
+                String value = parts[1];
+                String itemName = cellCodeToItemNameMap.getOrDefault(cellCode, cellCode);
+
+                // 构建替换字符串:基本工资(10)
+                String replacement = itemName + "(" + value + ")";
+
+                // 使用正则表达式替换,确保只替换完整的单元格引用
+                process = process.replaceAll("\\b" + cellCode + "\\b", replacement);
+            }
+        }
+
+        return process;
+    }
+
+    /**
+     * 创建标题样式
+     */
+    private CellStyle createTitleStyle(Workbook workbook) {
+        CellStyle style = workbook.createCellStyle();
+
+        // 字体设置
+        Font font = workbook.createFont();
+        font.setFontName("宋体");
+        font.setFontHeightInPoints((short) 16);
+        font.setBold(true);
+        style.setFont(font);
+
+        // 对齐方式
+        style.setAlignment(org.apache.poi.ss.usermodel.HorizontalAlignment.CENTER);
+        style.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER);
+
+        return style;
+    }
+
+    /**
+     * 创建表头样式
+     */
+    private CellStyle createHeaderStyle(Workbook workbook) {
+        CellStyle style = workbook.createCellStyle();
+
+        // 字体设置
+        Font font = workbook.createFont();
+        font.setFontName("宋体");
+        font.setFontHeightInPoints((short) 11);
+        font.setBold(true);
+        style.setFont(font);
+
+        // 对齐方式
+        style.setAlignment(org.apache.poi.ss.usermodel.HorizontalAlignment.CENTER);
+        style.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER);
+
+        // 边框
+        style.setBorderTop(org.apache.poi.ss.usermodel.BorderStyle.THIN);
+        style.setBorderBottom(org.apache.poi.ss.usermodel.BorderStyle.THIN);
+        style.setBorderLeft(org.apache.poi.ss.usermodel.BorderStyle.THIN);
+        style.setBorderRight(org.apache.poi.ss.usermodel.BorderStyle.THIN);
+
+        // 背景色(浅灰色)
+        style.setFillForegroundColor(org.apache.poi.ss.usermodel.IndexedColors.GREY_25_PERCENT.getIndex());
+        style.setFillPattern(org.apache.poi.ss.usermodel.FillPatternType.SOLID_FOREGROUND);
+
+        return style;
+    }
+
+    /**
+     * 创建数据样式
+     */
+    private CellStyle createDataStyle(Workbook workbook) {
+        CellStyle style = workbook.createCellStyle();
+
+        // 字体设置
+        Font font = workbook.createFont();
+        font.setFontName("宋体");
+        font.setFontHeightInPoints((short) 11);
+        style.setFont(font);
+
+        // 对齐方式
+        style.setAlignment(org.apache.poi.ss.usermodel.HorizontalAlignment.CENTER);
+        style.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER);
+
+        // 边框
+        style.setBorderTop(org.apache.poi.ss.usermodel.BorderStyle.THIN);
+        style.setBorderBottom(org.apache.poi.ss.usermodel.BorderStyle.THIN);
+        style.setBorderLeft(org.apache.poi.ss.usermodel.BorderStyle.THIN);
+        style.setBorderRight(org.apache.poi.ss.usermodel.BorderStyle.THIN);
+
+        return style;
+    }
 }

+ 4 - 0
assistMg/src/main/java/com/hotent/project/controller/CostProjectTaskMaterialController.java

@@ -55,10 +55,14 @@ public class CostProjectTaskMaterialController extends BaseController<CostProjec
 	@ApiOperation(value = "新增,更新任务定制-报送资料要求数据", httpMethod = "POST", notes = "新增,更新任务定制-报送资料要求数据")
 	public CommonResult<String> save(@ApiParam(name="CostProjectTaskMaterial",value="任务定制-报送资料要求对象", required = true)@RequestBody CostProjectTaskMaterial costProjectTaskMaterial) throws Exception{
 		String msg = StringUtil.isEmpty(costProjectTaskMaterial.getId()) ? "添加任务定制-报送资料要求成功" : "更新任务定制-报送资料要求成功";
+
+		// 如果有文件上传,设置上传状态和时间
 		if(StringUtils.isNotBlank(costProjectTaskMaterial.getFileUrl())) {
 			costProjectTaskMaterial.setIsUpload("1");
 			costProjectTaskMaterial.setUploadTime(LocalDateTime.now());
 		}
+
+		// 调用Manager层保存,会自动处理任务节点和资料类别
 		baseService.createOrUpdate(costProjectTaskMaterial);
 		return CommonResult.<String>ok().message(msg);
 	}

+ 17 - 8
assistMg/src/main/java/com/hotent/project/manager/impl/CostProjectTaskManagerImpl.java

@@ -365,14 +365,22 @@ public class CostProjectTaskManagerImpl extends BaseManagerImpl<CostProjectTaskD
         }
         // 2. 子流程状态改为审核中
         CostProjectTask task = this.getById(costTaskPageReq.getTaskId());
-        task.setCurrentNode(NodeConstant.clcs.getNodeKey());
-        task.setStatus(TaskStatusConstant.AUDITING.getStatusCode());
+        String currentNode = task.getCurrentNode();
+
+        // 如果当前节点不是tjcl,则保持当前节点不变,只修改状态
+        if (!"tjcl".equals(currentNode)) {
+            task.setStatus(TaskStatusConstant.AUDITING.getStatusCode());
+        } else {
+            task.setCurrentNode(NodeConstant.clcs.getNodeKey());
+            task.setStatus(TaskStatusConstant.AUDITING.getStatusCode());
+            CostProjectTask parentTask = this.getById(task.getPid());
+            String parentCurrentNode = parentTask.getCurrentNode();
+            parentTask.setCurrentNode(NodeConstant.clcs.getNodeKey());
+            parentTask.setStatus(TaskStatusConstant.AUDITING.getStatusCode());
+            this.updateById(parentTask);
+        }
         this.updateById(task);
-        // 3. 父任务也修改
-        CostProjectTask parentTask = this.getById(task.getPid());
-        parentTask.setCurrentNode(NodeConstant.clcs.getNodeKey());
-        parentTask.setStatus(TaskStatusConstant.AUDITING.getStatusCode());
-        this.updateById(parentTask);
+
         // 发送通知
         String title = NodeConstant.getNodeValueByKey(task.getCurrentNode()) + "材料已提交";
         // 操作人
@@ -383,7 +391,8 @@ public class CostProjectTaskManagerImpl extends BaseManagerImpl<CostProjectTaskD
         String noticeSource = (org.getName()) + " " + AuthenticationUtil.getCurrentUserFullname();
         String sendTarget = task.getCreateBy() == null ? "" : task.getCreateBy();
         costNoticeManager.sendNotice(task.getProjectId(), task.getId(), "1", title, content, enterpriseId, noticeSource, sendTarget);
-        return "任务提交成功,已进入材料初审阶段";
+
+        return "任务提交成功";
     }
 
     @Override

+ 51 - 0
assistMg/src/main/java/com/hotent/project/manager/impl/CostProjectTaskMaterialManagerImpl.java

@@ -55,10 +55,61 @@ public class CostProjectTaskMaterialManagerImpl extends BaseManagerImpl<CostProj
 	@Override
 	@Transactional
 	public void createOrUpdate(CostProjectTaskMaterial costProjectTaskMaterial) {
+		// 根据taskId获取任务节点
+		if (costProjectTaskMaterial.getTaskId() != null) {
+			CostProjectTask task = costProjectTaskManager.getById(costProjectTaskMaterial.getTaskId());
+			if (task != null) {
+				String currentNode = task.getCurrentNode();
+				costProjectTaskMaterial.setTaskNode(currentNode);
+
+				// 如果不是clcs节点,且有文件上传,需要根据文件类型设置informationType
+				if (!"clcs".equals(currentNode) && costProjectTaskMaterial.getFileUrl() != null) {
+					String fileUrl = costProjectTaskMaterial.getFileUrl();
+					String fileExtension = getFileExtension(fileUrl);
+
+					if (isWordFile(fileExtension)) {
+						// Word文件设置为3
+						costProjectTaskMaterial.setInformationType("3");
+					} else if (isExcelFile(fileExtension)) {
+						// Excel文件设置为2
+						costProjectTaskMaterial.setInformationType("2");
+					}
+				}
+			}
+		}
+
 		//新建或更新
 		this.saveOrUpdate(costProjectTaskMaterial);
 	}
 
+	/**
+	 * 获取文件扩展名
+	 */
+	private String getFileExtension(String fileUrl) {
+		if (fileUrl == null || fileUrl.isEmpty()) {
+			return "";
+		}
+		int lastDotIndex = fileUrl.lastIndexOf(".");
+		if (lastDotIndex > 0 && lastDotIndex < fileUrl.length() - 1) {
+			return fileUrl.substring(lastDotIndex + 1).toLowerCase();
+		}
+		return "";
+	}
+
+	/**
+	 * 判断是否为Word文件
+	 */
+	private boolean isWordFile(String extension) {
+		return "doc".equals(extension) || "docx".equals(extension);
+	}
+
+	/**
+	 * 判断是否为Excel文件
+	 */
+	private boolean isExcelFile(String extension) {
+		return "xls".equals(extension) || "xlsx".equals(extension);
+	}
+
 	@Override
 	@Transactional
 	public void deleteById(String id) {

+ 13 - 0
assistMg/src/main/java/com/hotent/project/model/CostProjectTaskMaterial.java

@@ -133,6 +133,11 @@ public class CostProjectTaskMaterial extends BaseModel<CostProjectTaskMaterial>
     @TableField("audited_unit_id")
     private String auditedUnitId;
 
+    @ApiModelProperty(value = "任务节点")
+    @JsonProperty("taskNode")
+    @TableField("task_node")
+    private String taskNode;
+
     public String getAuditedUnitId() {
         return auditedUnitId;
     }
@@ -307,6 +312,14 @@ public class CostProjectTaskMaterial extends BaseModel<CostProjectTaskMaterial>
         this.uploadTime = uploadTime;
     }
 
+    public String getTaskNode() {
+        return taskNode;
+    }
+
+    public void setTaskNode(String taskNode) {
+        this.taskNode = taskNode;
+    }
+
     @Override
     public String toString() {
         return "CostProjectTaskMaterial{" +

+ 0 - 1
assistMg/src/main/java/com/hotent/surveyinfo/controller/CostSurveyTemplateController.java

@@ -293,7 +293,6 @@ public class CostSurveyTemplateController extends BaseController<CostSurveyTempl
             costVerifyTemplate.setSurveyTemplateNameYw(PinyinUtil.getPinyin(sourceTemplate.getSurveyTemplateName()));
             costVerifyTemplate.setCreatetemplateid(sourceTemplate.getSurveyTemplateId());
             costVerifyTemplate.setStatus(taskId==null?"-1":"0");
-            costVerifyTemplate.setSurveyTemplateName(templatename);
             costVerifyTemplate.setCatalogId(catalogId);
             costVerifyTemplate.setCreateBy(user.getAccount());
             costVerifyTemplate.setCreateTime(LocalDateTime.now());