Bladeren bron

1.政府定价成本监审结论报告 单独处理

赵越越 2 weken geleden
bovenliggende
commit
60e0ce2dd3

+ 7 - 155
assistMg/src/main/java/com/hotent/project/manager/impl/CostProjectDocumentManagerImpl.java

@@ -33,6 +33,7 @@ import com.hotent.uc.manager.UserManager;
 import com.hotent.uc.model.Org;
 import com.hotent.uc.model.User;
 import com.hotent.uc.util.ContextUtil;
+import com.hotent.util.CostDataUtil;
 import com.hotent.util.FileUtils;
 import com.hotent.util.HtmlUtils;
 import com.hotent.util.wordexcelutils.*;
@@ -364,7 +365,7 @@ public class CostProjectDocumentManagerImpl extends BaseManagerImpl<CostProjectD
                         }
                         break;
                     case "SongDaWenShuWenHao":
-                        costProjectDocumentFile.setDataValue(projectDocument.getDocumentNumber());
+                        costProjectDocumentFile.setDataValue(costProjectDocument.getDocumentNumber());
                         break;
                     case "ShouSongDaRen":
                         costProjectDocumentFile.setDataValue(auditedUnit.getContactName());
@@ -569,20 +570,19 @@ public class CostProjectDocumentManagerImpl extends BaseManagerImpl<CostProjectD
 
                     CompleteTemplateProcessor.processTemplateComplete(document,auditedUnit.getUnitName(),mapList,DateUtils.format(new Date(),ISO8601_DATE_PATTERN));
                 }
-            } else if (costProjectDocument.getDocumentAlias().equals("zfdjcbjsjlbg4")) {
+            } else if (costProjectDocument.getDocumentAlias().equals("zfdjcbjsjlbg")) {
                 CostProjectApproval costProjectApproval = costProjectApprovalManager.get(costProjectDocument.getProjectId());
 
                 List<CostProjectTask> taskByProjectId = costProjectTaskManager.findTaskByProjectId(costProjectApproval.getProjectId(), costProjectDocument.getEnterpriseId());
 
                 List<Map<String,Object>> maps= costTemplateFileManager.getSurveyTemplate(taskByProjectId.get(0).getId());
 
-                //Map<String, Object> map1 = processCostData(maps);
+                CostDataUtil costDataUtil = new CostDataUtil();
+                Map<String, Object> map1 = costDataUtil.convertToCostFormat(maps);
                 @SuppressWarnings("unchecked")
-                List<String> years = (List<String>) processCostData(maps).get("years");
+                List<String> years = (List<String>)map1.get("years");
                 @SuppressWarnings("unchecked")
-                List<Map<String, Object>> costItems = (List<Map<String, Object>>) processCostData(maps).get("costItems");
-                System.err.println("years-----"+ JSON.toJSONString(years));
-                System.err.println("costItems-----"+ JSON.toJSONString(costItems));
+                List<Map<String, Object>> costItems = (List<Map<String, Object>>) map1.get("costItems");
 
                 // 处理文档
                 RobustComplexDocumentProcessor.processDocumentWithMaps(
@@ -592,8 +592,6 @@ public class CostProjectDocumentManagerImpl extends BaseManagerImpl<CostProjectD
                         costItems
                 );
 
-                // 保存结果
-                //document.write(new FileOutputStream("Map版处理完成的文档.docx"));
             } else {
                 SmartTemplateWriter.writeToTemplate(document,map);
             }
@@ -602,156 +600,10 @@ public class CostProjectDocumentManagerImpl extends BaseManagerImpl<CostProjectD
             throw new RuntimeException("处理Word文档时出错", e);
         }
 
-       // DocumentProcessor.processWordDocument(templatePath,outputPath,map,new LinkedHashMap<>());
         return EipConfig.getImgUrl()+FileUploadUtil.getPathFileName(outputPath,fileName);
     }
 
 
-    // 或者直接在Service中处理
-    public Map<String, Object> processCostData(List<Map<String, Object>> rawData) {
-        // 如果数据为空,返回空结构
-        if (rawData == null || rawData.isEmpty()) {
-            Map<String, Object> emptyResult = new HashMap<>();
-            emptyResult.put("years", new ArrayList<String>());
-            emptyResult.put("costItems", new ArrayList<Map<String, Object>>());
-            return emptyResult;
-        }
-
-        // 1. 提取所有年份
-        Set<String> years = new TreeSet<>();
-        // 按项目名称分组:项目名 -> (年份 -> 值)
-        Map<String, Map<String, String>> projectData = new HashMap<>();
-
-        for (Map<String, Object> row : rawData) {
-            try {
-                // 安全获取字段
-                String rkey = getStringValue(row, "rkey");
-                String projectName = getStringValue(row, "xm");
-                Object rvalueObj = row.get("rvalue");
-
-                if (rkey == null || projectName == null) {
-                    continue;
-                }
-
-                // 提取年份(从"2024年核定值"中提取"2024")
-                String year = extractYear(rkey);
-                if (year == null) {
-                    continue;
-                }
-
-                // 添加到年份集合
-                years.add(year);
-
-                // 转换值为字符串
-                String value = "";
-                if (rvalueObj != null) {
-                    String strValue = rvalueObj.toString().trim();
-                    if (!strValue.isEmpty()) {
-                        value = strValue;
-                    }
-                }
-
-                // 存储到项目数据中
-                projectData.putIfAbsent(projectName, new HashMap<>());
-                projectData.get(projectName).put(year, value);
-
-            } catch (Exception e) {
-                // 跳过错误数据
-                continue;
-            }
-        }
-
-        // 2. 构建costItems列表
-        List<Map<String, Object>> costItems = new ArrayList<>();
-
-        // 按项目名称排序
-        List<String> sortedProjectNames = new ArrayList<>(projectData.keySet());
-        Collections.sort(sortedProjectNames);
-
-        for (String projectName : sortedProjectNames) {
-            Map<String, Object> item = new HashMap<>();
-
-            // 添加costItemName字段
-            item.put("costItemName", projectName);
-
-            // 添加yearValues字段
-            Map<String, String> yearValues = new HashMap<>();
-            Map<String, String> projectYearData = projectData.get(projectName);
-
-            for (String year : years) {
-                String value = projectYearData.getOrDefault(year, "");
-                yearValues.put(year, value);
-            }
-            item.put("yearValues", yearValues);
-
-            costItems.add(item);
-        }
-
-        // 3. 添加合计行(可选)
-        if (!costItems.isEmpty()) {
-            Map<String, Object> totalItem = new HashMap<>();
-            totalItem.put("costItemName", "合计");
-
-            Map<String, String> totalValues = new HashMap<>();
-            for (String year : years) {
-                int sum = 0;
-                for (Map<String, String> projectYearData : projectData.values()) {
-                    String value = projectYearData.get(year);
-                    if (value != null && !value.trim().isEmpty()) {
-                        try {
-                            sum += Integer.parseInt(value.replace(",", ""));
-                        } catch (NumberFormatException e) {
-                            // 忽略非数字值
-                        }
-                    }
-                }
-                totalValues.put(year, sum > 0 ? String.valueOf(sum) : "");
-            }
-            totalItem.put("yearValues", totalValues);
-            costItems.add(totalItem);
-        }
-
-        // 4. 构建返回结果
-        Map<String, Object> result = new HashMap<>();
-        result.put("years", new ArrayList<>(years));
-        result.put("costItems", costItems);
-
-        return result;
-    }
-
-    /**
-     * 安全获取字符串值
-     */
-    private String getStringValue(Map<String, Object> map, String key) {
-        Object value = map.get(key);
-        if (value == null) {
-            return null;
-        }
-        if (value instanceof String) {
-            String str = (String) value;
-            return str.trim();
-        }
-        return value.toString().trim();
-    }
-
-    /**
-     * 从字符串中提取年份
-     */
-    private String extractYear(String text) {
-        if (text == null) {
-            return null;
-        }
-
-        // 匹配4位数字年份
-        Pattern pattern = Pattern.compile("\\d{4}");
-        Matcher matcher = pattern.matcher(text);
-        if (matcher.find()) {
-            return matcher.group();
-        }
-
-        return null;
-    }
-
     @Override
     public void feedbackDocumentUrl(CostProjectDocumentReq req) {
         if (ObjectUtil.isEmpty(req.getId())) {

+ 351 - 0
assistMg/src/main/java/com/hotent/util/CostDataUtil.java

@@ -0,0 +1,351 @@
+package com.hotent.util;
+
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+import java.util.*;
+import java.util.stream.Collectors;
+/**
+ *@author: zhao yue yue
+ *@create: 2025-12-08 10:05
+ */
+public class CostDataUtil {
+
+
+
+    /**
+     * 将查询结果转换为目标格式
+     * @param maps 查询结果:包含序号(xuhao)、项目名称(xiangmu)、年份(nianfen)、数值(shuzhi)和rowid
+     * @return 转换后的数据结构
+     */
+    public Map<String, Object> convertToCostFormat(List<Map<String, Object>> maps) {
+        if (maps == null || maps.isEmpty()) {
+            return createEmptyResult();
+        }
+
+        // 1. 提取所有年份(从nianfen字段中提取年份数字)
+        Set<String> years = extractYearsFromData(maps);
+
+        // 2. 按序号和项目名称分组
+        Map<String, Map<String, String>> groupedData = groupBySerialAndProject(maps, years);
+
+        // 3. 构建costItems列表(按序号排序)
+        List<Map<String, Object>> costItems = buildCostItems(groupedData, years);
+
+        // 4. 添加合计行(可选)
+        addTotalItem(costItems, groupedData, years);
+
+        // 5. 返回最终结果
+        return buildResult(years, costItems);
+    }
+
+    /**
+     * 从数据中提取所有年份
+     */
+    private Set<String> extractYearsFromData(List<Map<String, Object>> maps) {
+        return maps.stream()
+                .map(row -> {
+                    String nianfen = (String) row.get("nianfen");
+                    if (nianfen != null) {
+                        // 提取年份数字,如从"2024年核定值"中提取"2024"
+                        return extractYearNumber(nianfen);
+                    }
+                    return null;
+                })
+                .filter(Objects::nonNull)
+                .filter(year -> !year.isEmpty())
+                .collect(Collectors.toCollection(TreeSet::new)); // 自动排序
+    }
+
+    /**
+     * 按序号和项目名称分组
+     */
+    private Map<String, Map<String, String>> groupBySerialAndProject(
+            List<Map<String, Object>> maps,
+            Set<String> years) {
+
+        // 使用LinkedHashMap保持插入顺序
+        Map<String, Map<String, String>> result = new LinkedHashMap<>();
+
+        for (Map<String, Object> row : maps) {
+            try {
+                String xuhao = (String) row.get("xuhao");
+                String xiangmu = (String) row.get("xiangmu");
+                String nianfen = (String) row.get("nianfen");
+                Object shuzhiObj = row.get("shuzhi");
+
+                if (xuhao == null || xiangmu == null || nianfen == null) {
+                    continue;
+                }
+
+                // 生成唯一键:序号 + "|" + 项目名称
+                String key = xuhao + "|" + xiangmu;
+
+                // 初始化项目数据
+                if (!result.containsKey(key)) {
+                    result.put(key, new HashMap<>());
+                }
+
+                // 提取年份
+                String year = extractYearNumber(nianfen);
+                if (year != null && years.contains(year)) {
+                    // 转换值为字符串
+                    String value = "";
+                    if (shuzhiObj != null) {
+                        String strValue = shuzhiObj.toString().trim();
+                        if (!strValue.isEmpty()) {
+                            value = strValue;
+                        }
+                    }
+                    result.get(key).put(year, value);
+                }
+
+            } catch (Exception e) {
+                // 跳过错误数据
+                continue;
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * 构建costItems列表,按序号排序
+     */
+    private List<Map<String, Object>> buildCostItems(
+            Map<String, Map<String, String>> groupedData,
+            Set<String> years) {
+
+        List<Map<String, Object>> costItems = new ArrayList<>();
+
+        // 按序号排序(先按中文序号,再按数字序号)
+        List<String> sortedKeys = groupedData.keySet().stream()
+                .sorted((key1, key2) -> {
+                    // 分割键:序号|项目名称
+                    String[] parts1 = key1.split("\\|");
+                    String[] parts2 = key2.split("\\|");
+                    String xuhao1 = parts1[0];
+                    String xuhao2 = parts2[0];
+
+                    // 自定义排序:先中文序号,后数字序号
+                    return compareChineseAndNumber(xuhao1, xuhao2);
+                })
+                .collect(Collectors.toList());
+
+        for (String key : sortedKeys) {
+            String[] parts = key.split("\\|");
+            String xuhao = parts[0];
+            String xiangmu = parts[1];
+
+            Map<String, Object> item = new HashMap<>();
+
+            // 使用项目名称作为costItemName
+            item.put("costItemName", xiangmu);
+            // 如果需要,也可以添加序号字段
+            item.put("serialNumber", xuhao);
+
+            // 添加年份数据
+            Map<String, String> yearValues = new HashMap<>();
+            Map<String, String> projectYearData = groupedData.get(key);
+
+            for (String year : years) {
+                String value = projectYearData != null ?
+                        projectYearData.getOrDefault(year, "") : "";
+                yearValues.put(year, value);
+            }
+            item.put("yearValues", yearValues);
+
+            costItems.add(item);
+        }
+
+        return costItems;
+    }
+
+    /**
+     * 添加合计行
+     */
+    private void addTotalItem(
+            List<Map<String, Object>> costItems,
+            Map<String, Map<String, String>> groupedData,
+            Set<String> years) {
+
+        Map<String, Object> totalItem = new HashMap<>();
+        totalItem.put("costItemName", "合计");
+
+        Map<String, String> totalValues = new HashMap<>();
+
+        for (String year : years) {
+            BigDecimal total = BigDecimal.ZERO;
+
+            for (Map<String, String> projectYearData : groupedData.values()) {
+                String valueStr = projectYearData.get(year);
+                if (valueStr != null && !valueStr.trim().isEmpty()) {
+                    try {
+                        // 移除逗号等分隔符
+                        String cleanValue = valueStr.replaceAll("[^\\d.-]", "");
+                        if (!cleanValue.isEmpty()) {
+                            BigDecimal value = new BigDecimal(cleanValue);
+                            total = total.add(value);
+                        }
+                    } catch (NumberFormatException e) {
+                        // 忽略转换错误
+                    }
+                }
+            }
+
+            // 格式化合计值(添加千分位)
+            String totalStr = total.compareTo(BigDecimal.ZERO) > 0 ?
+                    formatNumberWithCommas(total) : "";
+            totalValues.put(year, totalStr);
+        }
+
+        totalItem.put("yearValues", totalValues);
+        costItems.add(totalItem);
+    }
+
+    /**
+     * 构建最终结果
+     */
+    private Map<String, Object> buildResult(Set<String> years, List<Map<String, Object>> costItems) {
+        Map<String, Object> result = new HashMap<>();
+        result.put("years", new ArrayList<>(years));
+        result.put("costItems", costItems);
+        return result;
+    }
+
+    /**
+     * 提取年份数字
+     */
+    private String extractYearNumber(String nianfen) {
+        if (nianfen == null) return null;
+
+        // 匹配4位数字年份
+        java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("\\d{4}");
+        java.util.regex.Matcher matcher = pattern.matcher(nianfen);
+        if (matcher.find()) {
+            return matcher.group();
+        }
+        return null;
+    }
+
+    /**
+     * 比较中文序号和数字序号
+     */
+    private int compareChineseAndNumber(String xuhao1, String xuhao2) {
+        // 中文序号映射
+        Map<String, Integer> chineseMap = new HashMap<>();
+        chineseMap.put("一", 1);
+        chineseMap.put("二", 2);
+        chineseMap.put("三", 3);
+        chineseMap.put("四", 4);
+        chineseMap.put("五", 5);
+        chineseMap.put("六", 6);
+        chineseMap.put("七", 7);
+        chineseMap.put("八", 8);
+        chineseMap.put("九", 9);
+        chineseMap.put("十", 10);
+
+        // 尝试将字符串转换为数字
+        Integer num1 = chineseMap.get(xuhao1);
+        Integer num2 = chineseMap.get(xuhao2);
+
+        if (num1 == null) {
+            try {
+                num1 = Integer.parseInt(xuhao1);
+            } catch (NumberFormatException e) {
+                num1 = Integer.MAX_VALUE; // 无法转换的排到最后
+            }
+        }
+
+        if (num2 == null) {
+            try {
+                num2 = Integer.parseInt(xuhao2);
+            } catch (NumberFormatException e) {
+                num2 = Integer.MAX_VALUE; // 无法转换的排到最后
+            }
+        }
+
+        return Integer.compare(num1, num2);
+    }
+
+    /**
+     * 格式化数字(添加千分位)
+     */
+    private String formatNumberWithCommas(BigDecimal number) {
+        DecimalFormat formatter = new DecimalFormat("#,##0");
+        return formatter.format(number);
+    }
+
+    /**
+     * 创建空结果
+     */
+    private Map<String, Object> createEmptyResult() {
+        Map<String, Object> result = new HashMap<>();
+        result.put("years", new ArrayList<String>());
+        result.put("costItems", new ArrayList<Map<String, Object>>());
+        return result;
+    }
+
+    /**
+     * 使用示例
+     */
+    public static void main(String[] args) {
+        // 模拟你的查询数据
+        List<Map<String, Object>> maps = new ArrayList<>();
+
+        // 添加测试数据(根据你提供的数据)
+        addRow(maps, "一", "人数", "2024年核定值", "");
+        addRow(maps, "一", "人数", "2025年核定值", "");
+        addRow(maps, "1", "1班", "2024年核定值", "");
+        addRow(maps, "1", "1班", "2025年核定值", "");
+        addRow(maps, "2", "2班", "2024年核定值", "");
+        addRow(maps, "2", "2班", "2025年核定值", "");
+        addRow(maps, "二", "1班费用", "2024年核定值", "");
+        addRow(maps, "二", "1班费用", "2025年核定值", "");
+        addRow(maps, "1", "押金", "2024年核定值", "");
+        addRow(maps, "1", "押金", "2025年核定值", "");
+        addRow(maps, "2", "缴纳", "2024年核定值", "");
+        addRow(maps, "2", "缴纳", "2025年核定值", "");
+        addRow(maps, "三", "班级乘法", "2024年核定值", "556");
+        addRow(maps, "三", "班级乘法", "2025年核定值", "85");
+        addRow(maps, "四", "人均费用", "2024年核定值", "223");
+        addRow(maps, "四", "人均费用", "2025年核定值", "225");
+
+        CostDataUtil converter = new CostDataUtil();
+        Map<String, Object> result = converter.convertToCostFormat(maps);
+
+        // 输出结果
+        System.out.println("Years: " + result.get("years"));
+
+        @SuppressWarnings("unchecked")
+        List<Map<String, Object>> costItems = (List<Map<String, Object>>) result.get("costItems");
+
+        System.out.println("\nCost Items:");
+        for (Map<String, Object> item : costItems) {
+            String costItemName = (String) item.get("costItemName");
+            System.out.println("\n项目: " + costItemName);
+
+            @SuppressWarnings("unchecked")
+            Map<String, String> yearValues = (Map<String, String>) item.get("yearValues");
+
+            @SuppressWarnings("unchecked")
+            List<String> years = (List<String>) result.get("years");
+
+            for (String year : years) {
+                String value = yearValues.get(year);
+                System.out.println("  " + year + "年: " + (value != null && !value.isEmpty() ? value : ""));
+            }
+        }
+    }
+
+    private static void addRow(List<Map<String, Object>> list,
+                               String xuhao, String xiangmu,
+                               String nianfen, String shuzhi) {
+        Map<String, Object> row = new HashMap<>();
+        row.put("xuhao", xuhao);
+        row.put("xiangmu", xiangmu);
+        row.put("nianfen", nianfen);
+        row.put("shuzhi", shuzhi);
+        list.add(row);
+    }
+
+}

+ 2 - 2
assistMg/src/main/java/com/hotent/util/wordexcelutils/RobustComplexDocumentProcessor.java

@@ -332,9 +332,9 @@ public class RobustComplexDocumentProcessor {
             // 设置成本项目
             String costItemName = (String) item.get("costItemName");
             setCellText(cells.get(0), costItemName != null ? costItemName : "");
-
+            String serialNumber = (String)item.get("serialNumber");
             // 设置行次
-            setCellText(cells.get(1), String.valueOf(i + 1));
+            setCellText(cells.get(1), serialNumber != null ? serialNumber : "");
 
             // 设置各年份数据
             for (int j = 0; j < years.size(); j++) {

+ 13 - 13
assistMg/src/main/resources/mapper/CostDocumentTemplateFileMapper.xml

@@ -74,25 +74,25 @@
 	</select>
 
 	<select id="getSurveyTemplate" resultType="java.util.HashMap">
-
 		WITH ranked_data AS (
 			SELECT
 				*,
 				ROW_NUMBER() OVER (PARTITION BY rowid ORDER BY id ASC) as position
 		FROM cost_survey_template_upload_data
 		WHERE task_id = #{id}
-		  AND parent_id = -1
 			)
-		SELECT
-			a.rkey, b.rvalue xm, a.rvalue
-		FROM ranked_data a
-				 INNER JOIN ranked_data b ON a.rowid = b.rowid
-		WHERE a.rkey LIKE '%核定值%'
-		  AND b.position = 2
-
-		ORDER BY
-			b.rvalue,  -- 按项目名称排序
-			a.rkey;
-
+		SELECT DISTINCT
+				(SELECT rvalue FROM ranked_data WHERE rowid = r.rowid AND position = 1) as xuhao,
+				(SELECT rvalue FROM ranked_data WHERE rowid = r.rowid AND position = 3) as xiangmu,
+				r.rkey as nianfen,
+				r.rvalue as shuzhi,
+				r.rowid,
+				r.order_num
+		FROM ranked_data r
+		WHERE r.rkey LIKE CONCAT('%', '核定值', '%')
+		ORDER BY r.order_num,
+				 (SELECT rvalue FROM ranked_data WHERE rowid = r.rowid AND position = 1),
+				 (SELECT rvalue FROM ranked_data WHERE rowid = r.rowid AND position = 3),
+				 r.rkey
 	</select>
 </mapper>