zzw před 1 týdnem
rodič
revize
0c5dda212c

+ 87 - 10
assistMg/src/main/java/com/hotent/enterpriseDeclare/controller/material/CostProjectTaskSurveyGenericController.java

@@ -14,6 +14,7 @@ import com.hotent.enterpriseDeclare.manager.CostAuditPeriodRecordManager;
 import com.hotent.enterpriseDeclare.manager.CostSurveyTemplateUploadDataManager;
 import com.hotent.enterpriseDeclare.model.CostAuditPeriodRecord;
 import com.hotent.enterpriseDeclare.model.CostSurveyTemplateUploadData;
+import com.hotent.enterpriseDeclare.service.CellDataQueryService;
 import com.hotent.project.manager.CostProjectApprovalManager;
 import com.hotent.project.manager.CostProjectTaskManager;
 import com.hotent.project.manager.CostProjectTaskMaterialManager;
@@ -98,7 +99,6 @@ public class CostProjectTaskSurveyGenericController {
     @Autowired
     private CostVerifyTemplateItemsDao costVerifyTemplateItemsDao;
 
-
     @Autowired
     private CostSurveyTemplateUploadManager costSurveyTemplateUploadManager;
     @Autowired
@@ -127,7 +127,7 @@ public class CostProjectTaskSurveyGenericController {
     private CostCatalogSurveyManager costCatalogSurveyManager;
 
     @Autowired
-    private CostCatalogUnitManager costCatalogUnitManager;
+    private CellDataQueryService cellDataQueryService;
 
 
     /**
@@ -1872,6 +1872,41 @@ public class CostProjectTaskSurveyGenericController {
                     }
                 }
 
+                // 处理跨表引用(检查模板项中的 calculation_template_id)
+                for (Object item : itemsList) {
+                    String calculationTemplateId = getItemCalculationTemplateId(item);
+                    if (StringUtil.isNotEmpty(calculationTemplateId)) {
+                        String crossTableType = type;
+
+                        // 收集所有年限
+                        Set<String> allPeriods = new HashSet<>();
+                        for (Map<String, String> rowData : rowDataMap.values()) {
+                            for (String key : rowData.keySet()) {
+                                if (key.matches("\\d{4}")) {
+                                    allPeriods.add(key);
+                                }
+                            }
+                        }
+
+                        // 使用 Service 获取跨表数据
+                        String taskId = dataList.get(0).getTaskId();
+                        for (String period : allPeriods) {
+                            Map<String, String> crossData = cellDataQueryService.getCrossTableFormulaData(
+                                taskId,
+                                calculationTemplateId,
+                                crossTableType,
+                                period
+                            );
+                            // 为跨表数据加上表ID前缀,避免与当前表数据冲突
+                            for (Map.Entry<String, String> entry : crossData.entrySet()) {
+                                String prefixedKey = calculationTemplateId + "_" + entry.getKey();
+                                globalCellCodeMap.put(prefixedKey, entry.getValue());
+                            }
+                        }
+                        break;
+                    }
+                }
+
                 // 收集所有的年限(年限的key是4位数字,如"2024")
                 Set<String> periods = new HashSet<>();
                 for (Map<String, String> rowData : rowDataMap.values()) {
@@ -2501,11 +2536,13 @@ public class CostProjectTaskSurveyGenericController {
         // 找到该行的计算公式(同一行的所有模板项共享同一个公式)
         String calculationFormula = null;
         String cellCode = null;
+        String calculationTemplateId = null;
         for (Object item : rowItems) {
             String formula = getItemCalculationFormula(item);
             if (StringUtil.isNotEmpty(formula)) {
                 calculationFormula = formula;
                 cellCode = getItemCellCode(item);
+                calculationTemplateId = getItemCalculationTemplateId(item);
                 break;
             }
         }
@@ -2525,9 +2562,23 @@ public class CostProjectTaskSurveyGenericController {
         while (matcher.find()) {
             String referencedCell = matcher.group();
             String mapKey = referencedCell + "_" + period;
-            String value = globalCellCodeMap.get(mapKey);
-            String displayValue = StringUtil.isNotEmpty(value) ? value : "0";
+            String value = null;
 
+            if (StringUtil.isNotEmpty(calculationTemplateId)) {
+                // 有跨表引用
+                if (cellCodeToRowIdMap.containsKey(referencedCell)) {
+                    // 单元格在当前表
+                    value = globalCellCodeMap.get(mapKey);
+                } else {
+                    // 单元格在跨表
+                    value = globalCellCodeMap.get(calculationTemplateId + "_" + mapKey);
+                }
+            } else {
+                // 没有跨表引用,只查当前表
+                value = globalCellCodeMap.get(mapKey);
+            }
+
+            String displayValue = StringUtil.isNotEmpty(value) ? value : "0";
             referencedCellsDebug.add(referencedCell + "=" + displayValue);
             if (StringUtil.isNotEmpty(value)) {
                 hasAnyReferencedValue = true;
@@ -2545,12 +2596,22 @@ public class CostProjectTaskSurveyGenericController {
         try {
             // 将公式中的单元格引用替换为 cellCode_年限 的形式
             // 例如:(A1+A2+A3) -> (A1_2024+A2_2024+A3_2024)
+            // 对于跨表引用,需要加上表ID前缀:(B1) -> (calculationTemplateId_B1_2024)
             String formulaWithPeriod = calculationFormula;
             matcher = pattern.matcher(calculationFormula);
             StringBuffer sb = new StringBuffer();
             while (matcher.find()) {
                 String referencedCell = matcher.group();
-                matcher.appendReplacement(sb, referencedCell + "_" + period);
+                String mapKey = referencedCell + "_" + period;
+
+                // 检查是否是跨表引用
+                String currentTableRowId = cellCodeToRowIdMap.get(referencedCell);
+                if (StringUtil.isEmpty(currentTableRowId) && StringUtil.isNotEmpty(calculationTemplateId)) {
+                    // 是跨表引用,使用表ID前缀
+                    mapKey = calculationTemplateId + "_" + mapKey;
+                }
+
+                matcher.appendReplacement(sb, mapKey);
             }
             matcher.appendTail(sb);
             formulaWithPeriod = sb.toString();
@@ -3604,7 +3665,7 @@ public class CostProjectTaskSurveyGenericController {
      * @param cellCodeToRowIdMap cellCode到rowid的映射
      * @param rowIdToExcelRowMap rowid到Excel行号的映射
      * @param period 当前校验的年限
-     * @return 计算过程字符串,如 "第3行2024年列(值=10)*(第6行2024年列(值=20)-第5行2024年列(值=5))"
+     * @return 计算过程字符串,如 "第3行2024年列(值=10)*(第6行2024年列(值=20)-第5行2024年列(值=5))+财务数据表B1(值=50)"
      */
     private String buildCalculationProcessWithNames(String formula, List<String> referencedCellsDebug,
                                                      Map<String, String> cellCodeToRowIdMap,
@@ -3623,15 +3684,17 @@ public class CostProjectTaskSurveyGenericController {
                 // 获取该cellCode对应的Excel行号
                 String rowId = cellCodeToRowIdMap.get(cellCode);
                 String rowDisplay;
+
                 if (rowId != null && rowIdToExcelRowMap.get(rowId) != null) {
+                    // 当前表的单元格
                     rowDisplay = "第" + rowIdToExcelRowMap.get(rowId) + "行";
+                    rowDisplay = String.format("%s%s年列(值=%s)", rowDisplay, period, value);
                 } else {
-                    rowDisplay = "行[" + cellCode + "]";
+                    // 跨表引用的单元格
+                    rowDisplay = String.format("其他表%s(值=%s)", cellCode, value);
                 }
 
-                // 构建替换字符串:第3行2024年列(值=10)
-                String replacement = String.format("%s%s年列(值=%s)", rowDisplay, period, value);
-                replacementMap.put(cellCode, replacement);
+                replacementMap.put(cellCode, rowDisplay);
             }
         }
 
@@ -3723,4 +3786,18 @@ public class CostProjectTaskSurveyGenericController {
 
         return style;
     }
+
+    /**
+     * 获取 item 的 calculation_template_id(跨表引用的模板ID)
+     */
+    private String getItemCalculationTemplateId(Object item) {
+        if (item instanceof CostSurveyTemplateItems) {
+            return ((CostSurveyTemplateItems) item).getCalculationTemplateId();
+        } else if (item instanceof CostSurveyFdTemplateItems) {
+            return ((CostSurveyFdTemplateItems) item).getCalculationTemplateId();
+        } else if (item instanceof CostVerifyTemplateItems) {
+            return ((CostVerifyTemplateItems) item).getCalculationTemplateId();
+        }
+        return null;
+    }
 }