Bläddra i källkod

fix:卷宗封底/表格居右/

zzw 1 vecka sedan
förälder
incheckning
806b9a90bd

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

@@ -252,7 +252,7 @@ public class CostProjectTaskSurveyGenericController {
                 );
                 // 成本调查表逻辑
                 List<CostSurveyTemplateUpload> uploadList = costSurveyTemplateUploadManager.listByTaskId(taskId);
-                //创建记录
+                // 创建记录
                 if (uploadList.isEmpty()) {
                     for (CostCatalogSurvey survey : list) {
                         CostSurveyTemplate template = costSurveyTemplateManager.getById(survey.getSurveyId());

+ 23 - 10
assistMg/src/main/java/com/hotent/enterpriseDeclare/service/CostSurveyExcelAsyncService.java

@@ -229,6 +229,7 @@ public class CostSurveyExcelAsyncService {
         Sheet sheet = workbook.createSheet(templateName);
         CellStyle titleStyle = ExcelStyleUtil.createTitleStyle(workbook);
         CellStyle headerStyle = ExcelStyleUtil.createHeaderStyle(workbook);
+        CellStyle leftHeaderStyle = ExcelStyleUtil.createLeftHeaderStyle(workbook);
         CellStyle dataStyle = ExcelStyleUtil.createDataStyle(workbook);
 
         Map<String, String> headersIdToUnitMap = new HashMap<>();
@@ -275,15 +276,19 @@ public class CostSurveyExcelAsyncService {
             String unit = headersIdToUnitMap.get(header.getId());
             if ("true".equals(header.getIsAuditPeriod()) && auditPeriods != null && auditPeriods.length > 0) {
                 for (String period : auditPeriods) {
-                    Cell headerCell = headerRow.createCell(colIndex++);
+                    Cell headerCell = headerRow.createCell(colIndex);
                     String headerValue = period.trim() + fieldName;
                     headerCell.setCellValue(headerValue);
-                    headerCell.setCellStyle(headerStyle);
+                    // 第一列使用左对齐样式
+                    headerCell.setCellStyle(colIndex == 0 ? leftHeaderStyle : headerStyle);
+                    colIndex++;
                 }
             } else {
-                Cell headerCell = headerRow.createCell(colIndex++);
+                Cell headerCell = headerRow.createCell(colIndex);
                 headerCell.setCellValue(fieldName);
-                headerCell.setCellStyle(headerStyle);
+                // 第一列使用左对齐样式
+                headerCell.setCellStyle(colIndex == 0 ? leftHeaderStyle : headerStyle);
+                colIndex++;
             }
         }
 
@@ -357,6 +362,7 @@ public class CostSurveyExcelAsyncService {
         Sheet sheet = workbook.createSheet(templateName);
         CellStyle titleStyle = ExcelStyleUtil.createTitleStyle(workbook);
         CellStyle headerStyle = ExcelStyleUtil.createHeaderStyle(workbook);
+        CellStyle leftHeaderStyle = ExcelStyleUtil.createLeftHeaderStyle(workbook);
         CellStyle dataStyle = ExcelStyleUtil.createDataStyle(workbook);
 
         Map<String, String> headersIdToUnitMap = new HashMap<>();
@@ -403,15 +409,19 @@ public class CostSurveyExcelAsyncService {
             String unit = headersIdToUnitMap.get(header.getId());
             if ("true".equals(header.getIsAuditPeriod()) && auditPeriods != null && auditPeriods.length > 0) {
                 for (String period : auditPeriods) {
-                    Cell headerCell = headerRow.createCell(colIndex++);
+                    Cell headerCell = headerRow.createCell(colIndex);
                     String headerValue = period.trim() + fieldName;
                     headerCell.setCellValue(headerValue);
-                    headerCell.setCellStyle(headerStyle);
+                    // 第一列使用左对齐样式
+                    headerCell.setCellStyle(colIndex == 0 ? leftHeaderStyle : headerStyle);
+                    colIndex++;
                 }
             } else {
-                Cell headerCell = headerRow.createCell(colIndex++);
+                Cell headerCell = headerRow.createCell(colIndex);
                 headerCell.setCellValue(fieldName);
-                headerCell.setCellStyle(headerStyle);
+                // 第一列使用左对齐样式
+                headerCell.setCellStyle(colIndex == 0 ? leftHeaderStyle : headerStyle);
+                colIndex++;
             }
         }
 
@@ -898,6 +908,7 @@ public class CostSurveyExcelAsyncService {
         Sheet sheet = workbook.createSheet(templateName);
         CellStyle titleStyle = ExcelStyleUtil.createTitleStyle(workbook);
         CellStyle headerStyle = ExcelStyleUtil.createHeaderStyle(workbook);
+        CellStyle leftHeaderStyle = ExcelStyleUtil.createLeftHeaderStyle(workbook);
         CellStyle dataStyle = ExcelStyleUtil.createDataStyle(workbook);
 
         // 从itemsList中获取unit值,按headersId分组取第一个非空的unit
@@ -925,10 +936,12 @@ public class CostSurveyExcelAsyncService {
         Row headerRow = sheet.createRow(1);
         int colIndex = 0;
         for (CostVerifyTemplateHeaders header : headersList) {
-            Cell headerCell = headerRow.createCell(colIndex++);
+            Cell headerCell = headerRow.createCell(colIndex);
             String fieldName = header.getFieldName();
             headerCell.setCellValue(fieldName);
-            headerCell.setCellStyle(headerStyle);
+            // 第一列使用左对齐样式
+            headerCell.setCellStyle(colIndex == 0 ? leftHeaderStyle : headerStyle);
+            colIndex++;
         }
 
         // 填充数据

+ 3 - 1
assistMg/src/main/java/com/hotent/project/req/ArchiveProofreadReq.java

@@ -55,7 +55,9 @@ public class ArchiveProofreadReq implements Serializable {
     @JsonProperty("retentionPeriod")
     private String retentionPeriod;
 
-
+    @ApiModelProperty(value = "检查人")
+    @JsonProperty("checker")
+    private String checker;
 
     @ApiModelProperty(value = "备注")
     @JsonProperty("remark")

+ 58 - 56
assistMg/src/main/java/com/hotent/project/service/AsyncMaterialSummaryService.java

@@ -374,28 +374,28 @@ public class AsyncMaterialSummaryService {
     private void generateType4Details(CostProjectTaskMaterialSummary summary, CostProjectTask mainTask, List<CostProjectTask> childTasks, List<CostProjectDocument> documents) {
         int orderNum = 1;
         // 获取"成本资料清单"
-        List<CostProjectDocument> matchedDocuments = documents.stream()
-                .filter(doc -> "9".equals(doc.getDocumentType()))
-                .sorted(Comparator.comparing(doc -> doc.getOrderNum() != null ? doc.getOrderNum() : 0))
-                .collect(Collectors.toList());
-
-        for (CostProjectDocument document : matchedDocuments) {
-            CostProjectTaskMaterialSummaryDetail detail = new CostProjectTaskMaterialSummaryDetail();
-            detail.setMasterId(summary.getId());
-            detail.setTaskId(mainTask.getId());
-            detail.setDocumentName(document.getDocumentName());
-            detail.setDocumentNumber(document.getDocumentNumber() != null ? document.getDocumentNumber() : "");
-            detail.setAuditedUnitId(document.getEnterpriseId());
-            if (document.getEnterpriseId() != null) {
-                detail.setAuditedUnitName(auditedUnitManager.getById(document.getEnterpriseId()).getUnitName());
-            }
-            detail.setFileSource("系统生成电子文书");
-            detail.setPageCount(0);
-            detail.setAttachmentUrl(document.getActUrl() != null ? document.getActUrl() : "");
-            detail.setOrderNum(orderNum++);
-            detail.setIsDeleted("0");
-            costProjectTaskMaterialSummaryDetailManager.save(detail);
-        }
+//        List<CostProjectDocument> matchedDocuments = documents.stream()
+//                .filter(doc -> "9".equals(doc.getDocumentType()))
+//                .sorted(Comparator.comparing(doc -> doc.getOrderNum() != null ? doc.getOrderNum() : 0))
+//                .collect(Collectors.toList());
+//
+//        for (CostProjectDocument document : matchedDocuments) {
+//            CostProjectTaskMaterialSummaryDetail detail = new CostProjectTaskMaterialSummaryDetail();
+//            detail.setMasterId(summary.getId());
+//            detail.setTaskId(mainTask.getId());
+//            detail.setDocumentName(document.getDocumentName());
+//            detail.setDocumentNumber(document.getDocumentNumber() != null ? document.getDocumentNumber() : "");
+//            detail.setAuditedUnitId(document.getEnterpriseId());
+//            if (document.getEnterpriseId() != null) {
+//                detail.setAuditedUnitName(auditedUnitManager.getById(document.getEnterpriseId()).getUnitName());
+//            }
+//            detail.setFileSource("系统生成电子文书");
+//            detail.setPageCount(0);
+//            detail.setAttachmentUrl(document.getActUrl() != null ? document.getActUrl() : "");
+//            detail.setOrderNum(orderNum++);
+//            detail.setIsDeleted("0");
+//            costProjectTaskMaterialSummaryDetailManager.save(detail);
+//        }
         // 获取子任务的资料登记表
         for (CostProjectTask childTask : childTasks) {
             // 获取任务的报送资料要求(被监审单位提交的补充资料)
@@ -1413,6 +1413,19 @@ public class AsyncMaterialSummaryService {
         map.put("{卷宗号}", req.getArchiveNo() != null ? req.getArchiveNo() : "");
         map.put("{保管期间周期}", req.getRetentionPeriod() != null ? req.getRetentionPeriod() : "");
 
+        // ========== 封底专用字段 ==========
+        // 制卷人:当前登录用户
+        User currentUser = ContextUtil.getCurrentUser();
+        map.put("{制卷人}", currentUser != null ? currentUser.getFullname() : "");
+
+        // 检查人:前端传递
+        map.put("{检查人}", req.getChecker() != null ? req.getChecker() : "");
+
+        // 生成时间:当前时间(格式:xxxx年xx月xx日)
+        LocalDateTime now = LocalDateTime.now();
+        String generateTime = now.getYear() + "年" + now.getMonthValue() + "月" + now.getDayOfMonth() + "日";
+        map.put("{生成时间}", generateTime);
+
         // ========== 卷宗统计信息 ==========
         // 获取14个资料归纳的总页数
         List<CostProjectTaskMaterialSummary> summaryList = costProjectTaskMaterialSummaryManager.listByTaskId(req.getTaskId());
@@ -1431,7 +1444,7 @@ public class AsyncMaterialSummaryService {
         map.put("{卷宗件数}", "1"); // 默认1件
         map.put("{卷宗页数}", String.valueOf(totalPageCount));
         map.put("{第几件}", "1"); // 默认第1件
-        map.put("{备注}", req.getRemark());
+        map.put("{备注}", req.getRemark() != null ? req.getRemark() : "");
 
         return map;
     }
@@ -1462,47 +1475,36 @@ public class AsyncMaterialSummaryService {
         // 页码累加器:用于生成连续的起止页码
         int currentPage = 1;
 
+        // 为每个资料类别(文件夹)创建一行目录
         for (CostProjectTaskMaterialSummary summary : summaryList) {
-            // 获取该资料类别下的所有明细文件
-            List<CostProjectTaskMaterialSummaryDetail> detailList = summary.getDetailList();
+            CompleteTemplateProcessor.TableRowData rowData =
+                    new CompleteTemplateProcessor.TableRowData();
 
-            if (detailList != null && !detailList.isEmpty()) {
-                // 按orderNum排序
-                detailList.sort(Comparator.comparing(d -> d.getOrderNum() != null ? d.getOrderNum() : 0));
+            // 使用资料类别名称(固定的14个名称)
+            rowData.setDocumentName(summary.getMaterialName());
 
-                // 为每个明细文件创建一行目录
+            // 计算该类别下所有明细文件的总页数
+            int totalPageCount = 0;
+            List<CostProjectTaskMaterialSummaryDetail> detailList = summary.getDetailList();
+            if (detailList != null && !detailList.isEmpty()) {
                 for (CostProjectTaskMaterialSummaryDetail detail : detailList) {
-                    CompleteTemplateProcessor.TableRowData rowData =
-                            new CompleteTemplateProcessor.TableRowData();
-
-                    // 文件名称
-                    rowData.setDocumentName(detail.getDocumentName() != null ? detail.getDocumentName() : summary.getMaterialName());
-
-                    // 该文件的页数
-                    int pageCount = detail.getPageCount() != null ? detail.getPageCount() : 0;
-                    rowData.setPageCount(pageCount);
-
-                    // 连续累加页码:计算在整个卷宗中的起止页码
-                    if (pageCount > 0) {
-                        int startPage = currentPage;
-                        int endPage = currentPage + pageCount - 1;
-                        rowData.setRemark(startPage + "-" + endPage);
-                        currentPage += pageCount;  // 更新页码累加器
-                    } else {
-                        rowData.setRemark("—");
-                    }
-
-                    tableDataList.add(rowData);
+                    totalPageCount += (detail.getPageCount() != null ? detail.getPageCount() : 0);
                 }
+            }
+
+            rowData.setPageCount(totalPageCount);
+
+            // 计算该类别的页码范围
+            if (totalPageCount > 0) {
+                int startPage = currentPage;
+                int endPage = currentPage + totalPageCount - 1;
+                rowData.setRemark(startPage + "-" + endPage);
+                currentPage += totalPageCount;  // 更新页码累加器
             } else {
-                // 如果该资料类别没有明细文件,仍然显示资料类别名称
-                CompleteTemplateProcessor.TableRowData rowData =
-                        new CompleteTemplateProcessor.TableRowData();
-                rowData.setDocumentName(summary.getMaterialName());
-                rowData.setPageCount(0);
                 rowData.setRemark("—");
-                tableDataList.add(rowData);
             }
+
+            tableDataList.add(rowData);
         }
 
         // 只填充表格数据,

+ 0 - 1583
assistMg/src/main/java/com/hotent/project/service/AsyncMaterialSummaryService1.java

@@ -1,1583 +0,0 @@
-package com.hotent.project.service;
-
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.hotent.base.util.StringUtil;
-import com.hotent.baseInfo.manager.AuditedUnitManager;
-import com.hotent.config.EipConfig;
-import com.hotent.project.manager.*;
-import com.hotent.project.model.*;
-import com.hotent.surveyinfo.manager.CostSurveyTemplateUploadManager;
-import com.hotent.surveyinfo.model.CostSurveyTemplateUpload;
-import com.hotent.uc.manager.OrgManager;
-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.FileUploadUtil;
-import com.hotent.util.wordexcelutils.CompleteTemplateProcessor;
-import com.hotent.util.wordexcelutils.SmartTemplateWriter;
-import org.apache.poi.xwpf.usermodel.*;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.scheduling.annotation.Async;
-import org.springframework.stereotype.Service;
-
-import java.io.File;
-import java.time.LocalDateTime;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-/**
- * 异步资料归纳服务
- *
- * @company 山西清众科技股份有限公司
- * @author 超级管理员
- * @since 2025-12-02
- */
-@Service
-public class AsyncMaterialSummaryService1 {
-
-    private static final Logger logger = LoggerFactory.getLogger(AsyncMaterialSummaryService1.class);
-
-    @Autowired
-    private CostProjectTaskMaterialSummaryManager costProjectTaskMaterialSummaryManager;
-
-    @Autowired
-    private CostProjectTaskMaterialSummaryDetailManager costProjectTaskMaterialSummaryDetailManager;
-
-    @Autowired
-    private CostProjectDocumentManager costProjectDocumentManager;
-
-    @Autowired
-    private CostProjectTaskManager costProjectTaskManager;
-
-    @Autowired
-    private CostSurveyTemplateUploadManager costSurveyTemplateUploadManager;
-
-    @Autowired
-    private CostProjectTaskMaterialManager costProjectTaskMaterialManager;
-
-    @Autowired
-    private CostProjectDeliberateManager costProjectDeliberateManager;
-
-    @Autowired
-    private CostProjectTaskAdjustmentRecordManager adjustmentRecordManager;
-
-    @Autowired
-    private CostProjectTaskEvidenceManager costProjectTaskEvidenceManager;
-
-    @Autowired
-    private CostProjectTaskPreliminaryOpinionManager preliminaryOpinionManager;
-
-    @Autowired
-    private CostProjectApprovalManager costProjectApprovalManager;
-
-    @Autowired
-    private AuditedUnitManager auditedUnitManager;
-
-    @Autowired
-    private OrgManager orgManager;
-
-    @Autowired
-    private UserManager userManager;
-
-    @Autowired
-    private CostProjectProccessNodeManager costProjectProccessNodeManager;
-
-    @Autowired
-    private CostProjectProccessManager costProjectProccessManager;
-
-    @Autowired
-    private AsposeArchiveService asposeArchiveService;
-
-
-    // 从配置文件读取模板路径
-    @org.springframework.beans.factory.annotation.Value("${archive.template.coverPath:}")
-    private String coverTemplatePath;
-
-    @org.springframework.beans.factory.annotation.Value("${archive.template.catalogPath:}")
-    private String catalogTemplatePath;
-
-    @org.springframework.beans.factory.annotation.Value("${archive.template.backCoverPath:}")
-    private String backCoverTemplatePath;
-
-
-    /**
-     * 生成资料归纳主表(14个基础资料类别)- 核心逻辑
-     *
-     * @param mainTask   主任务
-     * @param childTasks 子任务列表
-     */
-    public void generateMaterialSummary(CostProjectTask mainTask, List<CostProjectTask> childTasks) {
-        try {
-            // 定义14个基础资料类别
-            String[] materialNames = {
-                    "成本监审报告(含成本监审报告签发稿、送达回证)",
-                    "被监审单位申请定(调)价报告(复印件)",
-                    "成本监审通知书(含送达回证)",
-                    "经营者需提供成本资料清单",
-                    "《政府定价成本监审调查表》",
-                    "成本监审补充资料通知书(含送达回证)",
-                    "成本审核初步意见告知书(含送达回证)",
-                    "经营者书面反馈的材料",
-                    "成本审核初步意见表(集体审议用)",
-                    "成本监审集体审议记录",
-                    "成本监审工作底稿",
-                    "成本监审提取资料登记表",
-                    "提取的成本资料和会计凭证等复印件",
-                    "中止定价成本监审料通知书(含送达回证)"
-            };
-
-            // 为主任务生成14个资料归纳主表记录
-            for (int i = 0; i < materialNames.length; i++) {
-                CostProjectTaskMaterialSummary summary = new CostProjectTaskMaterialSummary();
-                summary.setTaskId(mainTask.getId());
-                summary.setMaterialName(materialNames[i]);
-                summary.setMaterialOrderNum(i + 1);
-                summary.setIsDeleted("0");
-                costProjectTaskMaterialSummaryManager.createOrUpdate(summary);
-
-                // 根据不同的资料类别生成对应的明细记录
-                generateDetailsByMaterialType(summary, mainTask, childTasks, i + 1);
-            }
-        } catch (Exception e) {
-            // 记录异常日志,但不影响主流程
-            logger.error("生成资料归纳失败", e);
-        }
-    }
-
-    /**
-     * 根据资料类别生成对应的明细记录
-     *
-     * @param summary      资料归纳主表
-     * @param mainTask     主任务
-     * @param childTasks   子任务列表
-     * @param materialType 资料类别序号(1-13)
-     */
-    private void generateDetailsByMaterialType(CostProjectTaskMaterialSummary summary,
-                                               CostProjectTask mainTask,
-                                               List<CostProjectTask> childTasks,
-                                               int materialType) {
-        try {
-            // 查询项目下的所有文书
-            List<CostProjectDocument> documents = costProjectDocumentManager.getListByProjectId(mainTask.getProjectId());
-            if (documents == null) {
-                documents = new java.util.ArrayList<>();
-            }
-
-            switch (materialType) {
-                case 1:
-                    // 成本监审报告(含成本监审报告签发稿、送达回证)
-                    generateType1Details(summary, mainTask, documents);
-                    break;
-                case 2:
-                    // 被监审单位申请定(调)价报告(复印件)
-                    generateType2Details(summary, mainTask, childTasks, documents);
-                    break;
-                case 3:
-                    // 成本监审通知书(含送达回证)
-                    generateType3Details(summary, mainTask, childTasks, documents);
-                    break;
-                case 4:
-                    // 经营者需提供成本资料清单
-                    generateType4Details(summary, mainTask, childTasks, documents);
-                    break;
-                case 5:
-                    // 《政府定价成本监审调查表》
-                    generateType5Details(summary, mainTask, childTasks, documents);
-                    break;
-                case 6:
-                    // 成本监审补充资料通知书(含送达回证)
-                    generateType6Details(summary, mainTask, childTasks, documents);
-                    break;
-                case 7:
-                    // 成本审核初步意见告知书(含送达回证)
-                    generateType7Details(summary, mainTask, childTasks, documents);
-                    break;
-                case 8:
-                    // 经营者书面反馈的材料
-                    generateType8Details(summary, mainTask, childTasks, documents);
-                    break;
-                case 9:
-                    // 成本审核初步意见表(集体审议用)
-                    generateType9Details(summary, mainTask, childTasks, documents);
-                    break;
-                case 10:
-                    // 成本监审集体审议记录
-                    generateType10Details(summary, mainTask, documents);
-                    break;
-                case 11:
-                    // 成本监审工作底稿
-                    generateType11Details(summary, mainTask, childTasks, documents);
-                    break;
-                case 12:
-                    // 成本监审提取资料登记表
-                    generateType12Details(summary, mainTask, childTasks, documents);
-                    break;
-                case 13:
-                    // 提取的成本资料和会计凭证等复印件
-                    generateType13Details(summary, mainTask, childTasks, documents);
-                    break;
-                case 14:
-                    // 中止定价成本监审料通知书(含送达回证)
-                    generateType14Details(summary, mainTask, childTasks, documents);
-                    break;
-                default:
-                    throw new RuntimeException("未知的资料类型");
-            }
-        } catch (Exception e) {
-            logger.error("生成资料类型 {} 的明细时出错:{}", materialType, e.getMessage(), e);
-            // 继续执行,不中断整个流程
-        }
-    }
-    //1	卷宗封面
-    //2	卷内目录
-    //3	政府定价成本监审结论报告
-    //4	成本监审通知书
-    //5	成本审核初步意见告知书
-    //6	成本审核初步意见表
-    //7	成本监审集体审议记录
-    //8	成本监审工作底稿
-    //9	成本监审提取资料登记表
-    //10	成本监审补充资料通知书
-    //11	中止定价成本监审通知书
-    //12	送达回证
-    //13	成本监审卷宗备考表
-
-    // ==================== 类型1:成本监审报告(含成本监审报告签发稿、送达回证) ====================
-    // A.成本监审报告(含成本监审报告签发稿)
-    //  包括成本监审报告、报告签发稿等文书。
-    private void generateType1Details(CostProjectTaskMaterialSummary summary, CostProjectTask mainTask, List<CostProjectDocument> documents) {
-        int orderNum = 1;
-        // 获取"成本监审报告"、"成本监审报告签发稿"、"送达回证"
-        List<CostProjectDocument> matchedDocuments = documents.stream()
-                .filter(doc -> "3".equals(doc.getDocumentType())
-                        || "3-12".equals(doc.getDocumentType() + "-" + doc.getDocumentTypeName())
-                )
-                .sorted(Comparator.comparing(doc -> doc.getOrderNum() != null ? doc.getOrderNum() : 0))
-                .collect(Collectors.toList());
-
-        for (CostProjectDocument document : matchedDocuments) {
-            CostProjectTaskMaterialSummaryDetail detail = new CostProjectTaskMaterialSummaryDetail();
-            detail.setMasterId(summary.getId());
-            detail.setTaskId(mainTask.getId());
-            detail.setDocumentName(document.getDocumentName());
-            detail.setDocumentNumber(document.getDocumentNumber() != null ? document.getDocumentNumber() : "");
-            detail.setAuditedUnitId(document.getEnterpriseId());
-            if (document.getEnterpriseId() != null) {
-                detail.setAuditedUnitName(auditedUnitManager.getById(document.getEnterpriseId()).getUnitName());
-            }
-            detail.setFileSource("系统生成电子文书");
-            detail.setPageCount(0);
-            detail.setAttachmentUrl(document.getActUrl() != null ? document.getActUrl() : "");
-            detail.setOrderNum(orderNum++);
-            detail.setIsDeleted("0");
-            costProjectTaskMaterialSummaryDetailManager.save(detail);
-        }
-    }
-
-    // ==================== 类型2:被监审单位申请定(调)价报告(复印件) ====================
-    // 被监审单位申请定(调)价报告等。
-    //来源:从“监审立项”附件获取。
-    private void generateType2Details(CostProjectTaskMaterialSummary summary, CostProjectTask mainTask, List<CostProjectTask> childTasks, List<CostProjectDocument> documents) {
-        int orderNum = 1;
-        // 获取"申请定(调)价报告"
-        List<CostProjectDocument> matchedDocuments = documents.stream()
-                .filter(doc -> "申请定(调)价报告".equals(doc.getDocumentName()))
-                .sorted(Comparator.comparing(doc -> doc.getOrderNum() != null ? doc.getOrderNum() : 0))
-                .collect(Collectors.toList());
-
-        for (CostProjectDocument document : matchedDocuments) {
-            CostProjectTaskMaterialSummaryDetail detail = new CostProjectTaskMaterialSummaryDetail();
-            detail.setMasterId(summary.getId());
-            detail.setTaskId(mainTask.getId());
-            detail.setDocumentName(document.getDocumentName());
-            detail.setDocumentNumber(document.getDocumentNumber() != null ? document.getDocumentNumber() : "");
-            detail.setAuditedUnitId(document.getEnterpriseId());
-            if (document.getEnterpriseId() != null) {
-                detail.setAuditedUnitName(auditedUnitManager.getById(document.getEnterpriseId()).getUnitName());
-            }
-            detail.setFileSource("系统生成电子文书");
-            detail.setPageCount(0);
-            detail.setAttachmentUrl(document.getScanDocumentUrl() != null ? document.getScanDocumentUrl() : "");
-            detail.setOrderNum(orderNum++);
-            detail.setIsDeleted("0");
-            costProjectTaskMaterialSummaryDetailManager.save(detail);
-        }
-        CostProjectApproval approval = costProjectApprovalManager.getById(mainTask.getProjectId());
-        if (approval != null && StringUtil.isNotEmpty(approval.getAccordingFileUrl())) {
-            CostProjectTaskMaterialSummaryDetail detail = new CostProjectTaskMaterialSummaryDetail();
-            detail.setMasterId(summary.getId());
-            detail.setTaskId(mainTask.getId());
-            detail.setDocumentName("成本项目定(调)价依据");
-            detail.setDocumentNumber("");
-            detail.setAuditedUnitId(mainTask.getAuditedUnitId());
-            detail.setAuditedUnitName(mainTask.getAuditedUnitName() != null ? mainTask.getAuditedUnitName() : "");
-            detail.setFileSource("系统生成电子文书");
-            detail.setPageCount(0);
-            detail.setAttachmentUrl(approval.getAccordingFileUrl());
-            detail.setOrderNum(orderNum++);
-            detail.setIsDeleted("0");
-            costProjectTaskMaterialSummaryDetailManager.save(detail);
-        }
-    }
-
-    // ==================== 类型3:成本监审通知书(含送达回证) ====================
-    // 包括成本监审通知书、送达回证等文书。
-    //来源:从"监审文书"中获取。
-    private void generateType3Details(CostProjectTaskMaterialSummary summary, CostProjectTask mainTask, List<CostProjectTask> childTasks, List<CostProjectDocument> documents) {
-        int orderNum = 1;
-        // "成本监审通知书"和"送达回证"
-        List<CostProjectDocument> matchedDocuments = documents.stream()
-                .filter(doc -> "4".equals(doc.getDocumentType())
-                        || "4-12".equals(doc.getDocumentType() + "-" + doc.getDocumentTypeName()))
-                .sorted(Comparator.comparing(doc -> doc.getOrderNum() != null ? doc.getOrderNum() : 0))
-                .collect(Collectors.toList());
-
-        for (CostProjectDocument document : matchedDocuments) {
-            // 如果是4-12(送达回证),使用feedback_document_url字段,否则使用actUrl字段
-            String attachmentUrl = "4-12".equals(document.getDocumentType() + "-" + document.getDocumentTypeName())
-                ? (document.getFeedbackDocumentUrl() != null ? document.getFeedbackDocumentUrl() : "")
-                : (document.getActUrl() != null ? document.getActUrl() : "");
-
-            // 只有当附件URL不为空时才记录
-            if (StringUtil.isEmpty(attachmentUrl)) {
-                continue;
-            }
-
-            CostProjectTaskMaterialSummaryDetail detail = new CostProjectTaskMaterialSummaryDetail();
-            detail.setMasterId(summary.getId());
-            detail.setTaskId(mainTask.getId());
-            detail.setDocumentName(document.getDocumentName());
-            detail.setDocumentNumber(document.getDocumentNumber() != null ? document.getDocumentNumber() : "");
-            detail.setAuditedUnitId(document.getEnterpriseId());
-            if (document.getEnterpriseId() != null) {
-                detail.setAuditedUnitName(auditedUnitManager.getById(document.getEnterpriseId()).getUnitName());
-            }
-            detail.setFileSource("系统生成电子文书");
-            detail.setPageCount(0);
-            detail.setAttachmentUrl(attachmentUrl);
-            detail.setOrderNum(orderNum++);
-            detail.setIsDeleted("0");
-            costProjectTaskMaterialSummaryDetailManager.save(detail);
-        }
-    }
-
-    // ==================== 类型4:经营者需提供成本资料清单(提取资料) ====================
-    // 成本监审任务中的资料报送要求。
-    //来源:从“监审任务部署”中获取。  报送资料
-    private void generateType4Details(CostProjectTaskMaterialSummary summary, CostProjectTask mainTask, List<CostProjectTask> childTasks, List<CostProjectDocument> documents) {
-        int orderNum = 1;
-        // 获取"成本资料清单"
-        List<CostProjectDocument> matchedDocuments = documents.stream()
-                .filter(doc -> "9".equals(doc.getDocumentType()))
-                .sorted(Comparator.comparing(doc -> doc.getOrderNum() != null ? doc.getOrderNum() : 0))
-                .collect(Collectors.toList());
-
-        for (CostProjectDocument document : matchedDocuments) {
-            CostProjectTaskMaterialSummaryDetail detail = new CostProjectTaskMaterialSummaryDetail();
-            detail.setMasterId(summary.getId());
-            detail.setTaskId(mainTask.getId());
-            detail.setDocumentName(document.getDocumentName());
-            detail.setDocumentNumber(document.getDocumentNumber() != null ? document.getDocumentNumber() : "");
-            detail.setAuditedUnitId(document.getEnterpriseId());
-            if (document.getEnterpriseId() != null) {
-                detail.setAuditedUnitName(auditedUnitManager.getById(document.getEnterpriseId()).getUnitName());
-            }
-            detail.setFileSource("系统生成电子文书");
-            detail.setPageCount(0);
-            detail.setAttachmentUrl(document.getActUrl() != null ? document.getActUrl() : "");
-            detail.setOrderNum(orderNum++);
-            detail.setIsDeleted("0");
-            costProjectTaskMaterialSummaryDetailManager.save(detail);
-        }
-        // 获取子任务的资料登记表
-        for (CostProjectTask childTask : childTasks) {
-            // 获取任务的报送资料要求(被监审单位提交的补充资料)
-            List<CostProjectTaskMaterial> list = costProjectTaskMaterialManager.list(
-                    new LambdaQueryWrapper<>(CostProjectTaskMaterial.class)
-                            .eq(CostProjectTaskMaterial::getTaskId, childTask.getId())
-            );
-            for (CostProjectTaskMaterial material : list) {
-                // 只处理已上传的资料
-                if ("1".equals(material.getIsUpload()) && StringUtil.isNotEmpty(material.getFileUrl())) {
-                    CostProjectTaskMaterialSummaryDetail detail = new CostProjectTaskMaterialSummaryDetail();
-                    detail.setMasterId(summary.getId());
-                    detail.setTaskId(mainTask.getId());
-                    detail.setDocumentName(material.getInformationName() != null ? material.getInformationName() : "补充资料");
-                    detail.setDocumentNumber("");
-                    detail.setAuditedUnitId(childTask.getAuditedUnitId());
-                    detail.setAuditedUnitName(childTask.getAuditedUnitName() != null ? childTask.getAuditedUnitName() : "");
-                    detail.setFileSource("监审单位反馈文件");
-                    detail.setPageCount(0);
-                    detail.setAttachmentUrl(material.getFileUrl());
-                    detail.setOrderNum(orderNum++);
-                    detail.setIsDeleted("0");
-                    costProjectTaskMaterialSummaryDetailManager.save(detail);
-                }
-            }
-        }
-    }
-
-    // ==================== 类型5:《政府定价成本监审调查表》 ====================
-    // 各被监审单位的“成本监审调查表”文档。
-    //来源:从“监审任务”中获取各被监审单位填报的成本监审调查表。
-    private void generateType5Details(CostProjectTaskMaterialSummary summary, CostProjectTask mainTask, List<CostProjectTask> childTasks, List<CostProjectDocument> documents) {
-        int orderNum = 1;
-        for (CostProjectTask childTask : childTasks) {
-            List<CostSurveyTemplateUpload> costSurveyTemplateUploads = costSurveyTemplateUploadManager.listByTaskId(childTask.getId());
-            for (CostSurveyTemplateUpload upload : costSurveyTemplateUploads) {
-                if ("1".equals(upload.getIsUpload()) && StringUtil.isNotEmpty(upload.getFileUrl())) {
-                    CostProjectTaskMaterialSummaryDetail detail = new CostProjectTaskMaterialSummaryDetail();
-                    detail.setMasterId(summary.getId());
-                    detail.setTaskId(mainTask.getId());
-                    detail.setDocumentName(upload.getSurveyTemplateName() != null ? upload.getSurveyTemplateName() : "政府定价成本监审调查表");
-                    detail.setDocumentNumber("");
-                    detail.setAuditedUnitId(childTask.getAuditedUnitId());
-                    detail.setAuditedUnitName(childTask.getAuditedUnitName() != null ? childTask.getAuditedUnitName() : "");
-                    detail.setFileSource("监审单位反馈文件");
-                    detail.setPageCount(0);
-                    detail.setAttachmentUrl(upload.getFileUrl());
-                    detail.setOrderNum(orderNum++);
-                    detail.setIsDeleted("0");
-                    costProjectTaskMaterialSummaryDetailManager.save(detail);
-                }
-            }
-        }
-        // 成本调查表(kkkk)
-    }
-
-    // ==================== 类型6:成本监审补充资料通知书(含送达回证) ====================
-    // 监审主体发送给各被监审单位的补充资料通知书、送达回证等文书。
-    //来源:从“监审文书”中获取。
-    private void generateType6Details(CostProjectTaskMaterialSummary summary, CostProjectTask mainTask, List<CostProjectTask> childTasks, List<CostProjectDocument> documents) {
-        int orderNum = 1;
-        List<CostProjectDocument> matchedDocuments = documents.stream()
-                .filter(doc -> "10".equals(doc.getDocumentType())
-                        || "10-12".equals(doc.getDocumentType() + "-" + doc.getDocumentTypeName()))
-                .sorted(Comparator.comparing(doc -> doc.getOrderNum() != null ? doc.getOrderNum() : 0))
-                .collect(Collectors.toList());
-
-        for (CostProjectDocument document : matchedDocuments) {
-            CostProjectTaskMaterialSummaryDetail detail = new CostProjectTaskMaterialSummaryDetail();
-            detail.setMasterId(summary.getId());
-            detail.setTaskId(mainTask.getId());
-            detail.setDocumentName(document.getDocumentName());
-            detail.setDocumentNumber(document.getDocumentNumber() != null ? document.getDocumentNumber() : "");
-            detail.setAuditedUnitId(document.getEnterpriseId());
-            if (document.getEnterpriseId() != null) {
-                detail.setAuditedUnitName(auditedUnitManager.getById(document.getEnterpriseId()).getUnitName());
-            }
-            detail.setFileSource("系统生成电子文书");
-            detail.setPageCount(0);
-            detail.setAttachmentUrl(document.getActUrl() != null ? document.getActUrl() : "");
-            detail.setOrderNum(orderNum++);
-            detail.setIsDeleted("0");
-            costProjectTaskMaterialSummaryDetailManager.save(detail);
-        }
-    }
-
-    // ==================== 类型7:成本审核初步意见告知书(含送达回证) ====================
-    // 监审主体发送给各被监审单位的初步意见告知书、送达回证等文书。
-    // 来源:从“监审文书”中获取。
-    private void generateType7Details(CostProjectTaskMaterialSummary summary, CostProjectTask mainTask, List<CostProjectTask> childTasks, List<CostProjectDocument> documents) {
-        int orderNum = 1;
-        // 获取"成本审核初步意见告知书"和"送达回证"
-        List<CostProjectDocument> matchedDocuments = documents.stream()
-                .filter(doc -> "5".equals(doc.getDocumentType())
-                        || "5-12".equals(doc.getDocumentType() + "-" + doc.getDocumentTypeName()))
-                .sorted(Comparator.comparing(doc -> doc.getOrderNum() != null ? doc.getOrderNum() : 0))
-                .collect(Collectors.toList());
-
-        for (CostProjectDocument document : matchedDocuments) {
-            CostProjectTaskMaterialSummaryDetail detail = new CostProjectTaskMaterialSummaryDetail();
-            detail.setMasterId(summary.getId());
-            detail.setTaskId(mainTask.getId());
-            detail.setDocumentName(document.getDocumentName());
-            detail.setDocumentNumber(document.getDocumentNumber() != null ? document.getDocumentNumber() : "");
-            detail.setAuditedUnitId(document.getEnterpriseId());
-            if (document.getEnterpriseId() != null) {
-                detail.setAuditedUnitName(auditedUnitManager.getById(document.getEnterpriseId()).getUnitName());
-            }
-            detail.setFileSource("系统生成电子文书");
-            detail.setPageCount(0);
-            detail.setAttachmentUrl(document.getActUrl() != null ? document.getActUrl() : "");
-            detail.setOrderNum(orderNum++);
-            detail.setIsDeleted("0");
-            costProjectTaskMaterialSummaryDetailManager.save(detail);
-        }
-    }
-
-    // ==================== 类型8:经营者书面反馈的材料 ====================
-    // 各被监审单位对初步意见告知书的意见反馈资料。
-    //来源:从“监审任务”中获取反馈意见。
-    private void generateType8Details(CostProjectTaskMaterialSummary summary, CostProjectTask mainTask, List<CostProjectTask> childTasks, List<CostProjectDocument> documents) {
-        int orderNum = 1;
-        // 获取"书面反馈材料"(来源:监审单位反馈文件)
-        List<CostProjectDocument> matchedDocuments = documents.stream()
-                .filter(doc -> "书面反馈材料".equals(doc.getDocumentType()))
-                .sorted(Comparator.comparing(doc -> doc.getOrderNum() != null ? doc.getOrderNum() : 0))
-                .collect(Collectors.toList());
-
-        for (CostProjectDocument document : matchedDocuments) {
-            CostProjectTaskMaterialSummaryDetail detail = new CostProjectTaskMaterialSummaryDetail();
-            detail.setMasterId(summary.getId());
-            detail.setTaskId(mainTask.getId());
-            detail.setDocumentName(document.getDocumentName());
-            detail.setDocumentNumber(document.getDocumentNumber() != null ? document.getDocumentNumber() : "");
-            detail.setAuditedUnitId(document.getEnterpriseId());
-            if (document.getEnterpriseId() != null) {
-                detail.setAuditedUnitName(auditedUnitManager.getById(document.getEnterpriseId()).getUnitName());
-            }
-            detail.setFileSource("系统生成电子文书");
-            detail.setPageCount(0);
-            detail.setAttachmentUrl(document.getActUrl() != null ? document.getActUrl() : "");
-            detail.setOrderNum(orderNum++);
-            detail.setIsDeleted("0");
-            costProjectTaskMaterialSummaryDetailManager.save(detail);
-        }
-        // 获取被监审单位的反馈意见和反馈资料
-        for (CostProjectTask childTask : childTasks) {
-            List<CostProjectTaskPreliminaryOpinion> list = preliminaryOpinionManager.list(
-                    new LambdaQueryWrapper<>(CostProjectTaskPreliminaryOpinion.class)
-                            .eq(CostProjectTaskPreliminaryOpinion::getTaskId, childTask.getId())
-            );
-            for (CostProjectTaskPreliminaryOpinion opinion : list) {
-                // 只处理有反馈资料的记录
-                if (StringUtil.isNotEmpty(opinion.getFeedbackMaterials())) {
-                    CostProjectTaskMaterialSummaryDetail detail = new CostProjectTaskMaterialSummaryDetail();
-                    detail.setMasterId(summary.getId());
-                    detail.setTaskId(mainTask.getId());
-                    detail.setDocumentName("书面反馈材料");
-                    detail.setDocumentNumber("");
-                    detail.setAuditedUnitId(childTask.getAuditedUnitId());
-                    detail.setAuditedUnitName(childTask.getAuditedUnitName() != null ? childTask.getAuditedUnitName() : "");
-                    detail.setFileSource("监审单位反馈文件");
-                    detail.setPageCount(0);
-                    detail.setAttachmentUrl(opinion.getFeedbackMaterials());
-                    detail.setOrderNum(orderNum++);
-                    detail.setIsDeleted("0");
-                    costProjectTaskMaterialSummaryDetailManager.save(detail);
-                }
-            }
-        }
-    }
-
-    // ==================== 类型9:成本审核初步意见表(集体审议用) ====================
-    // 来源:从“监审文书”中获取
-    private void generateType9Details(CostProjectTaskMaterialSummary summary, CostProjectTask mainTask, List<CostProjectTask> childTasks, List<CostProjectDocument> documents) {
-        int orderNum = 1;
-        // 获取"成本审核初步意见表"
-        List<CostProjectDocument> matchedDocuments = documents.stream()
-                .filter(doc -> "6".equals(doc.getDocumentType()))
-                .sorted(Comparator.comparing(doc -> doc.getOrderNum() != null ? doc.getOrderNum() : 0))
-                .collect(Collectors.toList());
-
-        for (CostProjectDocument document : matchedDocuments) {
-            CostProjectTaskMaterialSummaryDetail detail = new CostProjectTaskMaterialSummaryDetail();
-            detail.setMasterId(summary.getId());
-            detail.setTaskId(mainTask.getId());
-            detail.setDocumentName(document.getDocumentName());
-            detail.setDocumentNumber(document.getDocumentNumber() != null ? document.getDocumentNumber() : "");
-            detail.setAuditedUnitId(document.getEnterpriseId());
-            if (document.getEnterpriseId() != null) {
-                detail.setAuditedUnitName(auditedUnitManager.getById(document.getEnterpriseId()).getUnitName());
-            }
-            detail.setFileSource("系统生成电子文书");
-            detail.setPageCount(0);
-            detail.setAttachmentUrl(document.getActUrl() != null ? document.getActUrl() : "");
-            detail.setOrderNum(orderNum++);
-            detail.setIsDeleted("0");
-            costProjectTaskMaterialSummaryDetailManager.save(detail);
-        }
-    }
-
-    // ==================== 类型10:成本监审集体审议记录 ====================
-    // 来源:从“监审文书”中获取。
-    private void generateType10Details(CostProjectTaskMaterialSummary summary, CostProjectTask mainTask, List<CostProjectDocument> documents) {
-        int orderNum = 1;
-        // 获取"成本监审集体审议记录"
-        List<CostProjectDocument> matchedDocuments = documents.stream()
-                .filter(doc -> "7".equals(doc.getDocumentType()))
-                .sorted(Comparator.comparing(doc -> doc.getOrderNum() != null ? doc.getOrderNum() : 0))
-                .collect(Collectors.toList());
-
-        for (CostProjectDocument document : matchedDocuments) {
-            CostProjectTaskMaterialSummaryDetail detail = new CostProjectTaskMaterialSummaryDetail();
-            detail.setMasterId(summary.getId());
-            detail.setTaskId(mainTask.getId());
-            detail.setDocumentName(document.getDocumentName());
-            detail.setDocumentNumber(document.getDocumentNumber() != null ? document.getDocumentNumber() : "");
-            detail.setAuditedUnitId(document.getEnterpriseId());
-            if (document.getEnterpriseId() != null) {
-                detail.setAuditedUnitName(auditedUnitManager.getById(document.getEnterpriseId()).getUnitName());
-            }
-            detail.setFileSource("系统生成电子文书");
-            detail.setPageCount(0);
-            detail.setAttachmentUrl(document.getActUrl() != null ? document.getActUrl() : "");
-            detail.setOrderNum(orderNum++);
-            detail.setIsDeleted("0");
-            costProjectTaskMaterialSummaryDetailManager.save(detail);
-        }
-        // 获取集体审议记录
-        List<CostProjectDeliberate> list = costProjectDeliberateManager.list(
-                new LambdaQueryWrapper<CostProjectDeliberate>().eq(CostProjectDeliberate::getTaskId, mainTask.getId())
-        );
-        for (CostProjectDeliberate deliberate : list) {
-            // 只处理有附件的审议记录
-            if (StringUtil.isNotEmpty(deliberate.getAttachmentUrl())) {
-                CostProjectTaskMaterialSummaryDetail detail = new CostProjectTaskMaterialSummaryDetail();
-                detail.setMasterId(summary.getId());
-                detail.setTaskId(mainTask.getId());
-                detail.setDocumentName("成本监审集体审议记录");
-                detail.setDocumentNumber("");
-                detail.setAuditedUnitId(mainTask.getAuditedUnitId());
-                detail.setAuditedUnitName(mainTask.getAuditedUnitName() != null ? mainTask.getAuditedUnitName() : "");
-                detail.setFileSource("监审主体上传文件");
-                detail.setPageCount(0);
-                detail.setAttachmentUrl(deliberate.getAttachmentUrl());
-                detail.setOrderNum(orderNum++);
-                detail.setIsDeleted("0");
-                costProjectTaskMaterialSummaryDetailManager.save(detail);
-            }
-        }
-    }
-
-    // ==================== 类型11:成本监审工作底稿 ====================
-    // 来源:从“监审文书”中获取。
-    private void generateType11Details(CostProjectTaskMaterialSummary summary, CostProjectTask mainTask, List<CostProjectTask> childTasks, List<CostProjectDocument> documents) {
-        int orderNum = 1;
-        // 获取"成本监审工作底稿"
-        List<CostProjectDocument> matchedDocuments = documents.stream()
-                .filter(doc -> "8".equals(doc.getDocumentType()))
-                .sorted(Comparator.comparing(doc -> doc.getOrderNum() != null ? doc.getOrderNum() : 0))
-                .collect(Collectors.toList());
-
-        for (CostProjectDocument document : matchedDocuments) {
-            CostProjectTaskMaterialSummaryDetail detail = new CostProjectTaskMaterialSummaryDetail();
-            detail.setMasterId(summary.getId());
-            detail.setTaskId(mainTask.getId());
-            detail.setDocumentName(document.getDocumentName());
-            detail.setDocumentNumber(document.getDocumentNumber() != null ? document.getDocumentNumber() : "");
-            detail.setAuditedUnitId(document.getEnterpriseId());
-            if (document.getEnterpriseId() != null) {
-                detail.setAuditedUnitName(auditedUnitManager.getById(document.getEnterpriseId()).getUnitName());
-            }
-            detail.setFileSource("系统生成电子文书");
-            detail.setPageCount(0);
-            detail.setAttachmentUrl(document.getActUrl() != null ? document.getActUrl() : "");
-            detail.setOrderNum(orderNum++);
-            detail.setIsDeleted("0");
-            costProjectTaskMaterialSummaryDetailManager.save(detail);
-        }
-        // 获取核增核减记录(工作底稿的一部分)
-        for (CostProjectTask childTask : childTasks) {
-            List<CostProjectTaskAdjustmentRecord> costProjectTaskAdjustmentRecords = adjustmentRecordManager.listByTaskId(childTask.getId());
-            for (CostProjectTaskAdjustmentRecord record : costProjectTaskAdjustmentRecords) {
-                // 只处理有附件的记录
-                if (StringUtil.isNotEmpty(record.getAttachmentUrl())) {
-                    CostProjectTaskMaterialSummaryDetail detail = new CostProjectTaskMaterialSummaryDetail();
-                    detail.setMasterId(summary.getId());
-                    detail.setTaskId(mainTask.getId());
-                    detail.setDocumentName(record.getSubject() != null ? record.getSubject() + "-工作底稿" : "成本监审工作底稿");
-                    detail.setDocumentNumber("");
-                    detail.setAuditedUnitId(childTask.getAuditedUnitId());
-                    detail.setAuditedUnitName(childTask.getAuditedUnitName() != null ? childTask.getAuditedUnitName() : "");
-                    detail.setFileSource("监审单位反馈文件");
-                    detail.setPageCount(0);
-                    detail.setAttachmentUrl(record.getAttachmentUrl());
-                    detail.setOrderNum(orderNum++);
-                    detail.setIsDeleted("0");
-                    costProjectTaskMaterialSummaryDetailManager.save(detail);
-                }
-            }
-        }
-    }
-
-    // ==================== 类型12:成本监审提取资料登记表 ====================
-    // 来源:从“监审文书”中获取。
-    private void generateType12Details(CostProjectTaskMaterialSummary summary, CostProjectTask mainTask, List<CostProjectTask> childTasks, List<CostProjectDocument> documents) {
-        int orderNum = 1;
-        // 获取"成本监审提取资料登记表"
-        List<CostProjectDocument> matchedDocuments = documents.stream()
-                .filter(doc -> "9".equals(doc.getDocumentType()))
-                .sorted(Comparator.comparing(doc -> doc.getOrderNum() != null ? doc.getOrderNum() : 0))
-                .collect(Collectors.toList());
-
-        for (CostProjectDocument document : matchedDocuments) {
-            CostProjectTaskMaterialSummaryDetail detail = new CostProjectTaskMaterialSummaryDetail();
-            detail.setMasterId(summary.getId());
-            detail.setTaskId(mainTask.getId());
-            detail.setDocumentName(document.getDocumentName());
-            detail.setDocumentNumber(document.getDocumentNumber() != null ? document.getDocumentNumber() : "");
-            detail.setAuditedUnitId(document.getEnterpriseId());
-            if (document.getEnterpriseId() != null) {
-                detail.setAuditedUnitName(auditedUnitManager.getById(document.getEnterpriseId()).getUnitName());
-            }
-            detail.setFileSource("系统生成电子文书");
-            detail.setPageCount(0);
-            detail.setAttachmentUrl(document.getActUrl() != null ? document.getActUrl() : "");
-            detail.setOrderNum(orderNum++);
-            detail.setIsDeleted("0");
-            costProjectTaskMaterialSummaryDetailManager.save(detail);
-        }
-        // 获取子任务的资料登记表
-//        for (CostProjectTask childTask : childTasks) {
-//            List<CostProjectTaskEvidence> list = costProjectTaskEvidenceManager.list(
-//                    new LambdaQueryWrapper<CostProjectTaskEvidence>().eq(CostProjectTaskEvidence::getTaskId, childTask.getId())
-//            );
-//            for (CostProjectTaskEvidence evidence : list) {
-//                // 只处理有附件的资料登记
-//                if (StringUtil.isNotEmpty(evidence.getAttachmentUrl())) {
-//                    CostProjectTaskMaterialSummaryDetail detail = new CostProjectTaskMaterialSummaryDetail();
-//                    detail.setMasterId(summary.getId());
-//                    detail.setTaskId(mainTask.getId());
-//                    detail.setDocumentName(evidence.getMaterialName() != null ? evidence.getMaterialName() : "提取资料登记");
-//                    detail.setDocumentNumber("");
-//                    detail.setAuditedUnitId(childTask.getAuditedUnitId());
-//                    detail.setAuditedUnitName(childTask.getAuditedUnitName() != null ? childTask.getAuditedUnitName() : "");
-//                    detail.setFileSource("监审单位反馈文件");
-//                    detail.setPageCount(evidence.getPageCount() != null ? evidence.getPageCount() : 0);
-//                    detail.setAttachmentUrl(evidence.getAttachmentUrl());
-//                    detail.setOrderNum(orderNum++);
-//                    detail.setIsDeleted("0");
-//                    costProjectTaskMaterialSummaryDetailManager.save(detail);
-//                }
-//            }
-//        }
-    }
-
-    // ==================== 类型13:提取的成本资料和会计凭证等复印件 ====================
-    // 来源:各被监审单位首次及补充材料时提交的资料,包括综合性材料、财会资料等。 提取资料登记表
-    private void generateType13Details(CostProjectTaskMaterialSummary summary, CostProjectTask mainTask, List<CostProjectTask> childTasks, List<CostProjectDocument> documents) {
-        int orderNum = 1;
-        // 获取"成本资料和会计凭证"(来源:被监审单位提交的资料)
-        List<CostProjectDocument> matchedDocuments = documents.stream()
-                .filter(doc -> "成本资料和会计凭证".equals(doc.getDocumentType()))
-                .sorted(Comparator.comparing(doc -> doc.getOrderNum() != null ? doc.getOrderNum() : 0))
-                .collect(Collectors.toList());
-
-        for (CostProjectDocument document : matchedDocuments) {
-            CostProjectTaskMaterialSummaryDetail detail = new CostProjectTaskMaterialSummaryDetail();
-            detail.setMasterId(summary.getId());
-            detail.setTaskId(mainTask.getId());
-            detail.setDocumentName(document.getDocumentName());
-            detail.setDocumentNumber(document.getDocumentNumber() != null ? document.getDocumentNumber() : "");
-            detail.setAuditedUnitId(document.getEnterpriseId());
-            if (document.getEnterpriseId() != null) {
-                detail.setAuditedUnitName(auditedUnitManager.getById(document.getEnterpriseId()).getUnitName());
-            }
-            detail.setFileSource("监审单位反馈文件");
-            detail.setPageCount(0);
-            detail.setAttachmentUrl(document.getActUrl() != null ? document.getActUrl() : "");
-            detail.setOrderNum(orderNum++);
-            detail.setIsDeleted("0");
-            costProjectTaskMaterialSummaryDetailManager.save(detail);
-        }
-        // 获取子任务的资料登记表
-        for (CostProjectTask childTask : childTasks) {
-            List<CostProjectTaskEvidence> list = costProjectTaskEvidenceManager.list(
-                    new LambdaQueryWrapper<CostProjectTaskEvidence>().eq(CostProjectTaskEvidence::getTaskId, childTask.getId())
-            );
-            for (CostProjectTaskEvidence evidence : list) {
-                // 只处理有附件的资料登记
-                if (StringUtil.isNotEmpty(evidence.getAttachmentUrl())) {
-                    CostProjectTaskMaterialSummaryDetail detail = new CostProjectTaskMaterialSummaryDetail();
-                    detail.setMasterId(summary.getId());
-                    detail.setTaskId(mainTask.getId());
-                    detail.setDocumentName(evidence.getMaterialName() != null ? evidence.getMaterialName() : "提取资料登记");
-                    detail.setDocumentNumber("");
-                    detail.setAuditedUnitId(childTask.getAuditedUnitId());
-                    detail.setAuditedUnitName(childTask.getAuditedUnitName() != null ? childTask.getAuditedUnitName() : "");
-                    detail.setFileSource("监审单位反馈文件");
-                    detail.setPageCount(evidence.getPageCount() != null ? evidence.getPageCount() : 0);
-                    detail.setAttachmentUrl(evidence.getAttachmentUrl());
-                    detail.setOrderNum(orderNum++);
-                    detail.setIsDeleted("0");
-                    costProjectTaskMaterialSummaryDetailManager.save(detail);
-                }
-            }
-
-        }
-    }
-
-    // ==================== 类型14:中止定价成本监审料通知书(含送达回证) ====================
-    // 来源:从“监审文书”中获取。
-    private void generateType14Details(CostProjectTaskMaterialSummary summary, CostProjectTask mainTask, List<CostProjectTask> childTasks, List<CostProjectDocument> documents) {
-        int orderNum = 1;
-        // 获取"中止定价成本监审通知书"(来源:被监审单位提交的资料)
-        List<CostProjectDocument> matchedDocuments = documents.stream()
-                .filter(doc -> "11".equals(doc.getDocumentType())
-                        || "11-12".equals(doc.getDocumentType() + "-" + doc.getDocumentTypeName()))
-                .sorted(Comparator.comparing(doc -> doc.getOrderNum() != null ? doc.getOrderNum() : 0))
-                .collect(Collectors.toList());
-
-        for (CostProjectDocument document : matchedDocuments) {
-            CostProjectTaskMaterialSummaryDetail detail = new CostProjectTaskMaterialSummaryDetail();
-            detail.setMasterId(summary.getId());
-            detail.setTaskId(mainTask.getId());
-            detail.setDocumentName(document.getDocumentName());
-            detail.setDocumentNumber(document.getDocumentNumber() != null ? document.getDocumentNumber() : "");
-            detail.setAuditedUnitId(document.getEnterpriseId());
-            if (document.getEnterpriseId() != null) {
-                detail.setAuditedUnitName(auditedUnitManager.getById(document.getEnterpriseId()).getUnitName());
-            }
-            detail.setFileSource("系统生成电子文书");
-            detail.setPageCount(0);
-            detail.setAttachmentUrl(document.getActUrl() != null ? document.getActUrl() : "");
-            detail.setOrderNum(orderNum++);
-            detail.setIsDeleted("0");
-            costProjectTaskMaterialSummaryDetailManager.save(detail);
-        }
-    }
-
-    /**
-     * 档案校对通过后,异步生成Word卷宗
-     * 使用docx4j实现节分隔符控制页码:
-     * - 封面、目录、封底:无页码
-     * - 正文:有页码(第 X 页 / 共 Y 页)
-     *
-     * @param taskId 任务ID
-     */
-    @Async
-    public void generateWordArchiveAsync(String taskId) {
-        boolean success = false;
-        String archiveUrl = null;
-        try {
-            logger.info("开始生成Word卷宗,任务ID:{}", taskId);
-
-            // 查询任务的所有资料归纳主表(包含封面、目录、封底)
-            List<CostProjectTaskMaterialSummary> allSummaryList =
-                    costProjectTaskMaterialSummaryManager.listAllByTaskId(taskId);
-
-            // 分类:封面、目录、正文、封底
-            List<String> coverFiles = new java.util.ArrayList<>();    // 封面 -1
-            List<String> catalogFiles = new java.util.ArrayList<>();  // 目录 -2
-            List<String> contentFiles = new java.util.ArrayList<>();  // 正文 1-14
-            List<String> backCoverFiles = new java.util.ArrayList<>();// 封底 -3
-
-            for (CostProjectTaskMaterialSummary summary : allSummaryList) {
-                Integer orderNum = summary.getMaterialOrderNum();
-                if (orderNum == null) continue;
-
-                List<CostProjectTaskMaterialSummaryDetail> detailList = summary.getDetailList();
-                if (detailList == null || detailList.isEmpty()) continue;
-
-                // 按顺序排序
-                detailList.sort(Comparator.comparing(d -> d.getOrderNum() != null ? d.getOrderNum() : 0));
-
-                for (CostProjectTaskMaterialSummaryDetail detail : detailList) {
-                    if (StringUtil.isNotEmpty(detail.getAttachmentUrl())) {
-                        String localPath = convertToLocalPath(detail.getAttachmentUrl());
-                        if (localPath != null && new File(localPath).exists()) {
-                            if (orderNum == -1) {
-                                coverFiles.add(localPath);
-                            } else if (orderNum == -2) {
-                                catalogFiles.add(localPath);
-                            } else if (orderNum == -3) {
-                                backCoverFiles.add(localPath);
-                            } else if (orderNum > 0) {
-                                contentFiles.add(localPath);
-                            }
-                        }
-                    }
-                }
-            }
-
-            // 对正文按materialOrderNum排序
-            // 重新收集正文,确保按materialOrderNum排序
-            // 注意:这里改为按 summary 分组,每个 summary(资料类别)作为一个独立的"文件组"
-            contentFiles.clear();
-            List<CostProjectTaskMaterialSummary> contentSummaries = allSummaryList.stream()
-                    .filter(s -> s.getMaterialOrderNum() != null && s.getMaterialOrderNum() > 0)
-                    .sorted(Comparator.comparing(CostProjectTaskMaterialSummary::getMaterialOrderNum))
-                    .collect(Collectors.toList());
-
-            // 使用特殊标记分隔不同的 summary(资料类别)
-            // 格式:每个 summary 的多个 detail 文件连续添加,然后用 null 作为分隔符
-            for (CostProjectTaskMaterialSummary summary : contentSummaries) {
-                List<CostProjectTaskMaterialSummaryDetail> detailList = summary.getDetailList();
-                if (detailList != null && !detailList.isEmpty()) {
-                    detailList.sort(Comparator.comparing(d -> d.getOrderNum() != null ? d.getOrderNum() : 0));
-
-                    boolean hasValidFile = false;
-                    List<String> summaryFiles = new java.util.ArrayList<>();
-
-                    for (CostProjectTaskMaterialSummaryDetail detail : detailList) {
-                        if (StringUtil.isNotEmpty(detail.getAttachmentUrl())) {
-                            String localPath = convertToLocalPath(detail.getAttachmentUrl());
-                            if (localPath != null && new File(localPath).exists()) {
-                                summaryFiles.add(localPath);
-                                hasValidFile = true;
-                            }
-                        }
-                    }
-
-                    // 只有当该 summary 有有效文件时才添加
-                    if (hasValidFile) {
-                        contentFiles.addAll(summaryFiles);
-                        // 添加分隔符标记(用于 AsposeArchiveService 识别不同 summary 的边界)
-                        contentFiles.add("##SUMMARY_BOUNDARY##");
-                    }
-                }
-            }
-
-            // 移除最后一个分隔符(如果存在)
-            if (!contentFiles.isEmpty() && "##SUMMARY_BOUNDARY##".equals(contentFiles.get(contentFiles.size() - 1))) {
-                contentFiles.remove(contentFiles.size() - 1);
-            }
-
-            // 生成输出文件路径
-            String fileName = FileUploadUtil.generateFileName("卷宗_" + taskId + ".docx");
-            String outputPath = FileUploadUtil.generateSavePath(
-                    EipConfig.getUploadPath(), fileName, "docx");
-
-            // 使用Aspose合并文档
-            asposeArchiveService.mergeDocuments(coverFiles, catalogFiles, contentFiles, backCoverFiles, outputPath);
-
-            // 生成访问URL
-            archiveUrl = FileUploadUtil.getPathFileName(outputPath, fileName);
-            success = true;
-            logger.info("Word卷宗生成完成,任务ID:{},URL:{}", taskId, archiveUrl);
-
-        } catch (Exception e) {
-            logger.error("生成Word卷宗失败,任务ID:{},错误:{}", taskId, e.getMessage(), e);
-        } finally {
-            // 无论成功失败,都更新状态
-            try {
-                CostProjectTask task = costProjectTaskManager.getById(taskId);
-                if (task != null) {
-                    if (success) {
-                        task.setArchiveUrl(archiveUrl);
-                        task.setArchiveStatus("2");
-                        task.setArchiveTime(LocalDateTime.now());
-                    } else {
-                        task.setArchiveStatus("3");
-                    }
-                    costProjectTaskManager.updateById(task);
-                    logger.info("卷宗状态已更新,任务ID:{},状态:{}", taskId, success ? "2-成功" : "3-失败");
-                }
-            } catch (Exception e) {
-                logger.error("更新卷宗状态失败,任务ID:{},错误:{}", taskId, e.getMessage(), e);
-            }
-        }
-    }
-
-
-    /**
-     * 更新单个资料归纳主表的总页数
-     *
-     * @param masterId 主表ID
-     */
-    public void updateMasterTotalPageCount(String masterId) {
-        try {
-            CostProjectTaskMaterialSummary summary = costProjectTaskMaterialSummaryManager.getById(masterId);
-            if (summary == null) {
-                logger.warn("资料归纳主表不存在,ID:{}", masterId);
-                return;
-            }
-
-            // 封面(-1)、目录(-2)、封底(-3)不计算页数,页数设为0
-            Integer orderNum = summary.getMaterialOrderNum();
-            if (orderNum != null && orderNum < 0) {
-                summary.setTotalPageCount("0");
-                costProjectTaskMaterialSummaryManager.updateById(summary);
-                logger.info("资料归纳【{}】为封面/目录/封底,不计算页数", summary.getMaterialName());
-                return;
-            }
-
-            int totalPageCount = 0;
-
-            // 查询该主表的所有明细
-            List<CostProjectTaskMaterialSummaryDetail> detailList = costProjectTaskMaterialSummaryDetailManager.list(
-                    new LambdaQueryWrapper<CostProjectTaskMaterialSummaryDetail>()
-                            .eq(CostProjectTaskMaterialSummaryDetail::getMasterId, masterId)
-                            .eq(CostProjectTaskMaterialSummaryDetail::getIsDeleted, "0")
-            );
-
-            // 累加所有明细的页数
-            for (CostProjectTaskMaterialSummaryDetail detail : detailList) {
-                if (detail.getPageCount() != null) {
-                    totalPageCount += detail.getPageCount();
-                }
-            }
-
-            // 更新主表的总页数
-            summary.setTotalPageCount(String.valueOf(totalPageCount));
-            costProjectTaskMaterialSummaryManager.updateById(summary);
-
-            logger.info("资料归纳【{}】总页数已更新:{}", summary.getMaterialName(), totalPageCount);
-
-        } catch (Exception e) {
-            logger.error("更新主表总页数失败,主表ID:{},错误:{}", masterId, e.getMessage(), e);
-        }
-    }
-
-    /**
-     * 统计每个资料归纳主表的总页数
-     *
-     * @param taskId 任务ID
-     */
-    public void calculatePageCountAsync(String taskId) {
-        try {
-            logger.info("开始异步统计页数,任务ID:{}", taskId);
-
-            // 查询任务的所有资料归纳主表
-            List<CostProjectTaskMaterialSummary> summaryList = costProjectTaskMaterialSummaryManager.listByTaskId(taskId);
-
-            for (CostProjectTaskMaterialSummary summary : summaryList) {
-                Integer orderNum = summary.getMaterialOrderNum();
-
-                // 封面(-1)、目录(-2)、封底(-3)不计算页数,页数设为0
-                if (orderNum != null && orderNum < 0) {
-                    summary.setTotalPageCount("0");
-                    costProjectTaskMaterialSummaryManager.updateById(summary);
-                    logger.info("资料归纳【{}】为封面/目录/封底,不计算页数", summary.getMaterialName());
-                    continue;
-                }
-
-                int totalPageCount = 0;
-
-                // 获取该主表的所有明细
-                if (summary.getDetailList() != null && !summary.getDetailList().isEmpty()) {
-                    for (CostProjectTaskMaterialSummaryDetail detail : summary.getDetailList()) {
-                        if (StringUtil.isNotEmpty(detail.getAttachmentUrl())) {
-                            // 统计该明细的页数
-                            int pageCount = calculateFilePageCount(detail.getAttachmentUrl());
-                            detail.setPageCount(pageCount);
-                            costProjectTaskMaterialSummaryDetailManager.updateById(detail);
-                            // 累加到总页数
-                            totalPageCount += pageCount;
-                        }
-                    }
-                }
-
-                // 更新主表的总页数
-                summary.setTotalPageCount(String.valueOf(totalPageCount));
-                costProjectTaskMaterialSummaryManager.updateById(summary);
-
-                logger.info("资料归纳【{}】统计完成,总页数:{}", summary.getMaterialName(), totalPageCount);
-            }
-
-            logger.info("页数统计完成,任务ID:{}", taskId);
-
-        } catch (Exception e) {
-            logger.error("统计页数失败,任务ID:{},错误:{}", taskId, e.getMessage(), e);
-        }
-    }
-
-    /**
-     * 计算文件页数
-     * 使用Aspose计算,支持Word、Excel、PDF
-     *
-     * @param fileUrl 文件URL或路径
-     * @return 页数
-     */
-    public int calculateFilePageCount(String fileUrl) {
-        try {
-            if (StringUtil.isEmpty(fileUrl)) {
-                return 0;
-            }
-
-            // 转换为本地路径
-            String filePath = fileUrl;
-            if (filePath.startsWith("/profile")) {
-                filePath = EipConfig.getProfile() + filePath.substring(8);
-            }
-
-            // 使用Aspose服务计算页数
-            return asposeArchiveService.calculateFilePageCount(filePath);
-
-        } catch (Exception e) {
-            logger.error("计算文件页数失败,文件:{},错误:{}", fileUrl, e.getMessage(), e);
-            return 1;
-        }
-    }
-
-
-    /**
-     * 生成卷宗文书(封面/目录/封底)
-     * id为空是新增,id不为空是编辑
-     *
-     * @param req 生成请求
-     * @return 生成的文书URL
-     */
-    public String generateArchiveDocument(com.hotent.project.req.ArchiveProofreadReq req) throws Exception {
-        Integer documentType = req.getDocumentType();
-        String existingId = req.getRelatedId();
-
-        // 如果id不为空,从数据库获取已有记录的documentType(id是主表ID)
-        if (StringUtil.isNotEmpty(existingId)) {
-            CostProjectTaskMaterialSummary existing = costProjectTaskMaterialSummaryManager.getById(existingId);
-            if (existing == null) {
-                throw new RuntimeException("主表记录不存在:" + existingId);
-            }
-            Integer orderNum = existing.getMaterialOrderNum();
-            if (orderNum != null && orderNum == -1) {
-                documentType = 1;
-            } else if (orderNum != null && orderNum == -2) {
-                documentType = 2;
-            } else if (orderNum != null && orderNum == -3) {
-                documentType = 3;
-            } else {
-                throw new RuntimeException("无效的文书记录");
-            }
-        }
-
-        String templatePath;
-        String documentName;
-
-        switch (documentType) {
-            case 1:
-                templatePath = coverTemplatePath;
-                documentName = "案卷封面";
-                if (StringUtil.isEmpty(templatePath)) {
-                    throw new RuntimeException("案卷封面模板路径未配置");
-                }
-                break;
-            case 2:
-                templatePath = catalogTemplatePath;
-                documentName = "卷内目录";
-                if (StringUtil.isEmpty(templatePath)) {
-                    throw new RuntimeException("卷内目录模板路径未配置");
-                }
-                break;
-            case 3:
-                templatePath = backCoverTemplatePath;
-                documentName = "案卷封底";
-                if (StringUtil.isEmpty(templatePath)) {
-                    throw new RuntimeException("案卷封底模板路径未配置");
-                }
-                break;
-            default:
-                throw new RuntimeException("不支持的文书类型:" + documentType);
-        }
-
-        // 检查模板文件是否存在
-        File templateFile = new File(templatePath);
-        if (!templateFile.exists()) {
-            throw new RuntimeException("模板文件不存在:" + templatePath);
-        }
-
-        // 生成文书
-        String outputUrl = generateDocumentFromTemplate(templatePath, documentName, req);
-
-        // 保存到数据库(主表+明细表)
-        int orderNum = -documentType; // -1封面、-2目录、-3封底
-        String masterId;
-
-        if (StringUtil.isNotEmpty(existingId)) {
-            // 编辑:existingId是主表ID,查找对应的明细记录
-            masterId = existingId;
-            CostProjectTaskMaterialSummary existingSummary = costProjectTaskMaterialSummaryManager.getById(masterId);
-            if (existingSummary != null) {
-                // 更新task的卷宗号和归档人
-                CostProjectTask task = costProjectTaskManager.getById(existingSummary.getTaskId());
-                if (task != null) {
-                    task.setArchiveNo(req.getArchiveNo());
-                    task.setArchiveUser(ContextUtil.getCurrentUser().getFullname());
-                    costProjectTaskManager.updateById(task);
-                }
-            }
-            CostProjectTaskMaterialSummaryDetail existingDetail = costProjectTaskMaterialSummaryDetailManager.getOne(
-                    new LambdaQueryWrapper<CostProjectTaskMaterialSummaryDetail>()
-                            .eq(CostProjectTaskMaterialSummaryDetail::getMasterId, masterId)
-                            .eq(CostProjectTaskMaterialSummaryDetail::getIsDeleted, "0")
-            );
-            if (existingDetail != null) {
-                // 更新已有明细
-                existingDetail.setAttachmentUrl(outputUrl);
-                existingDetail.setGenerateTime(LocalDateTime.now());
-                costProjectTaskMaterialSummaryDetailManager.updateById(existingDetail);
-            } else {
-                // 创建新明细
-                CostProjectTaskMaterialSummaryDetail detail = new CostProjectTaskMaterialSummaryDetail();
-                detail.setMasterId(masterId);
-                detail.setTaskId(req.getTaskId());
-                detail.setDocumentName(documentName);
-                detail.setFileSource("系统生成电子文书");
-                detail.setAttachmentUrl(outputUrl);
-                detail.setOrderNum(1);
-                detail.setGenerateTime(LocalDateTime.now());
-                detail.setIsDeleted("0");
-                costProjectTaskMaterialSummaryDetailManager.save(detail);
-            }
-        } else {
-            // 新增:创建主表记录
-            CostProjectTaskMaterialSummary summary = new CostProjectTaskMaterialSummary();
-            summary.setTaskId(req.getTaskId());
-            summary.setMaterialOrderNum(orderNum);
-            summary.setMaterialName(documentName);
-            summary.setIsDeleted("0");
-            costProjectTaskMaterialSummaryManager.save(summary);
-            masterId = summary.getId();
-            // 更新task的卷宗号和归档人
-            CostProjectTask task = costProjectTaskManager.getById(req.getTaskId());
-            if (task != null) {
-                task.setArchiveNo(req.getArchiveNo());
-                task.setArchiveUser(ContextUtil.getCurrentUser().getFullname());
-                costProjectTaskManager.updateById(task);
-            }
-
-            // 创建明细记录
-            CostProjectTaskMaterialSummaryDetail detail = new CostProjectTaskMaterialSummaryDetail();
-            detail.setMasterId(masterId);
-            detail.setTaskId(req.getTaskId());
-            detail.setDocumentName(documentName);
-            detail.setFileSource("系统生成电子文书");
-            detail.setAttachmentUrl(outputUrl);
-            detail.setOrderNum(1);
-            detail.setGenerateTime(LocalDateTime.now());
-            detail.setIsDeleted("0");
-            costProjectTaskMaterialSummaryDetailManager.save(detail);
-        }
-
-        return outputUrl;
-    }
-
-
-    /**
-     * 根据模板生成文书
-     *
-     * @param templatePath 模板路径
-     * @param documentName 文书名称
-     * @param req          请求参数
-     * @return 生成的文书URL
-     */
-    private String generateDocumentFromTemplate(String templatePath, String documentName,
-                                                com.hotent.project.req.ArchiveProofreadReq req) throws Exception {
-        java.io.FileInputStream fis = null;
-        XWPFDocument document = null;
-        java.io.FileOutputStream fos = null;
-
-        try {
-            // 读取模板
-            fis = new java.io.FileInputStream(templatePath);
-            document = new XWPFDocument(fis);
-
-            // 构建替换映射
-            Map<String, String> replacements = buildReplacementMap(req);
-
-            // 根据文书类型进行不同处理
-            switch (req.getDocumentType()) {
-                case 1:
-                    // 案卷封面
-                    generateCoverDocument(document, replacements);
-                    break;
-                case 2:
-                    // 卷内目录
-                    generateCatalogDocument(document, replacements, req.getTaskId());
-                    break;
-                case 3:
-                    // 案卷封底
-                    generateBackCoverDocument(document, replacements);
-                    break;
-            }
-
-            // 生成输出文件路径
-            String fileName = FileUploadUtil.generateFileName(documentName + ".docx");
-            String outputPath = FileUploadUtil.generateSavePath(
-                    EipConfig.getUploadPath(), fileName, "docx");
-
-            // 确保目录存在
-            File outputFile = new File(outputPath);
-            if (!outputFile.getParentFile().exists()) {
-                outputFile.getParentFile().mkdirs();
-            }
-
-            // 写入文件
-            fos = new java.io.FileOutputStream(outputPath);
-            document.write(fos);
-
-            // 返回访问URL
-            return FileUploadUtil.getPathFileName(outputPath, fileName);
-
-        } finally {
-            // 关闭资源
-            try {
-                if (fos != null) fos.close();
-                if (document != null) document.close();
-                if (fis != null) fis.close();
-            } catch (Exception e) {
-                logger.warn("关闭文件流失败:{}", e.getMessage());
-            }
-        }
-    }
-
-    /**
-     * 构建替换映射
-     * 自动从数据库获取:年份、监审项目名称、被监审单位、监审期间(开始-结束年度)、监审人员、办结时间
-     * 需要用户传递:价格主管部门、卷宗号、保管期间周期、立卷人、立卷日期、检查人、检查日期、备注
-     */
-    private Map<String, String> buildReplacementMap(com.hotent.project.req.ArchiveProofreadReq req) {
-        Map<String, String> map = new java.util.HashMap<>();
-
-        // 从数据库获取任务信息
-        CostProjectTask task = costProjectTaskManager.getById(req.getTaskId());
-
-        // 从数据库获取立项审批信息(包含监审组人员)
-        CostProjectApproval approval = costProjectApprovalManager.getOne(
-                new LambdaQueryWrapper<CostProjectApproval>()
-                        .eq(CostProjectApproval::getProjectId, task.getProjectId())
-        );
-
-        // ========== 自动获取的字段 ==========
-        Org org = orgManager.getById(approval.getOrgId());
-        map.put("{价格主管部门或成本监审机构}", org.getName());
-        map.put("{年份}", task.getYear());
-        map.put("{监审项目名称}", task.getProjectName());
-        map.put("{被监审单位}", task.getAuditedUnitName());
-
-        // 监审期间(解析开始-结束年度,格式如:2024,2025,2023 逗号分隔)
-        String startYear = "";
-        String endYear = "";
-        String auditPeriod = task.getAuditPeriod();
-        if (StringUtil.isNotEmpty(auditPeriod)) {
-            String[] years = auditPeriod.split(",");
-            int minYear = Integer.MAX_VALUE;
-            int maxYear = Integer.MIN_VALUE;
-            for (String year : years) {
-                try {
-                    int y = Integer.parseInt(year.trim());
-                    if (y < minYear) minYear = y;
-                    if (y > maxYear) maxYear = y;
-                } catch (NumberFormatException e) {
-                }
-            }
-            if (minYear != Integer.MAX_VALUE) {
-                startYear = String.valueOf(minYear);
-                endYear = String.valueOf(maxYear);
-            }
-        }
-        map.put("{监审开始年度}", startYear);
-        map.put("{监审结束年度}", endYear);
-
-        // 监审组负责人及人员(将ID转换为姓名)
-        String auditGroupNames = "";
-        if (approval != null && StringUtil.isNotEmpty(approval.getAuditGroup())) {
-            String[] userIds = approval.getAuditGroup().split(",");
-            StringBuilder names = new StringBuilder();
-            for (String userId : userIds) {
-                try {
-                    User user = userManager.get(userId.trim());
-                    if (user != null) {
-                        if (names.length() > 0) {
-                            names.append(",");
-                        }
-                        names.append(user.getFullname());
-                    }
-                } catch (Exception e) {
-                }
-            }
-            auditGroupNames = names.toString();
-        }
-        map.put("{监审组负责人及人员}", auditGroupNames);
-
-        // 监审办结时间(任务状态为办结时,取更新时间,格式:xxxx年xx月)
-        String auditEndTime = "";
-        CostProjectProccess proccess = costProjectProccessManager.getOne(
-                new LambdaQueryWrapper<CostProjectProccess>().eq(CostProjectProccess::getProjectId, task.getProjectId())
-        );
-        CostProjectProccessNode currentNode = costProjectProccessNodeManager.getOne(
-                new LambdaQueryWrapper<CostProjectProccessNode>()
-                        .eq(CostProjectProccessNode::getProcessId, proccess.getProcessId())
-                        .eq(CostProjectProccessNode::getProcessNodeKey, task.getCurrentNode())
-        );
-        if (currentNode != null) {
-            auditEndTime =
-                    currentNode.getActStartTime().getYear() + "年"
-                            + currentNode.getActStartTime().getMonthValue() + "月"
-                            + currentNode.getActStartTime().getDayOfMonth() + "日";
-        }
-        map.put("{监审办结时间}", auditEndTime);
-
-        // ========== 需要用户传递的字段 ==========
-        map.put("{卷宗号}", req.getArchiveNo() != null ? req.getArchiveNo() : "");
-        map.put("{保管期间周期}", req.getRetentionPeriod() != null ? req.getRetentionPeriod() : "");
-
-        // ========== 卷宗统计信息 ==========
-        // 获取14个资料归纳的总页数
-        List<CostProjectTaskMaterialSummary> summaryList = costProjectTaskMaterialSummaryManager.listByTaskId(req.getTaskId());
-        summaryList = summaryList.stream()
-                .filter(s -> s.getMaterialOrderNum() != null && s.getMaterialOrderNum() > 0)
-                .collect(Collectors.toList());
-        int totalPageCount = 0;
-        for (CostProjectTaskMaterialSummary summary : summaryList) {
-            if (summary.getTotalPageCount() != null) {
-                try {
-                    totalPageCount += Integer.parseInt(summary.getTotalPageCount());
-                } catch (NumberFormatException e) {
-                }
-            }
-        }
-        map.put("{卷宗件数}", "1"); // 默认1件
-        map.put("{卷宗页数}", String.valueOf(totalPageCount));
-        map.put("{第几件}", "1"); // 默认第1件
-        map.put("{备注}", req.getRemark());
-
-        return map;
-    }
-
-    /**
-     * 生成案卷封面
-     */
-    private void generateCoverDocument(XWPFDocument document, Map<String, String> replacements) {
-        SmartTemplateWriter.writeToTemplate(document, replacements);
-    }
-
-    /**
-     * 生成卷内目录
-     */
-    private void generateCatalogDocument(XWPFDocument document, Map<String, String> replacements, String taskId) {
-        // 获取资料归纳列表,生成目录表格
-        List<CostProjectTaskMaterialSummary> summaryList = costProjectTaskMaterialSummaryManager.listByTaskId(taskId);
-
-        // 过滤掉封面、目录、封底(负数序号)
-        summaryList = summaryList.stream()
-                .filter(s -> s.getMaterialOrderNum() != null && s.getMaterialOrderNum() > 0)
-                .sorted(Comparator.comparing(CostProjectTaskMaterialSummary::getMaterialOrderNum))
-                .collect(Collectors.toList());
-
-        // 构建目录数据
-        List<CompleteTemplateProcessor.TableRowData> tableDataList = new java.util.ArrayList<>();
-        int currentPage = 1;
-
-        for (CostProjectTaskMaterialSummary summary : summaryList) {
-            CompleteTemplateProcessor.TableRowData rowData =
-                    new CompleteTemplateProcessor.TableRowData();
-            rowData.setDocumentName(summary.getMaterialName());
-
-            int pageCount = 0;
-            if (summary.getTotalPageCount() != null) {
-                try {
-                    pageCount = Integer.parseInt(summary.getTotalPageCount());
-                } catch (NumberFormatException e) {
-                    pageCount = 0;
-                }
-            }
-            rowData.setPageCount(pageCount);
-
-            // 计算页码范围作为备注
-            if (pageCount > 0) {
-                rowData.setRemark(currentPage + "-" + (currentPage + pageCount - 1));
-                currentPage += pageCount;
-            } else {
-                rowData.setRemark("—");
-            }
-
-            tableDataList.add(rowData);
-        }
-
-        // 只填充表格数据,
-        if (!tableDataList.isEmpty()) {
-            processTableData(document, tableDataList);
-        }
-    }
-
-    /**
-     * 生成案卷封底
-     */
-    private void generateBackCoverDocument(XWPFDocument document, Map<String, String> replacements) {
-        SmartTemplateWriter.writeToTemplate(document, replacements);
-    }
-
-    /**
-     * 处理目录表格数据
-     */
-    private void processTableData(XWPFDocument document, List<CompleteTemplateProcessor.TableRowData> dataList) {
-        List<XWPFTable> tables = document.getTables();
-        if (tables.isEmpty()) {
-            logger.warn("未找到表格");
-            return;
-        }
-
-        XWPFTable table = tables.get(0);
-
-        // 找到模板行(第二行,第一行是表头)
-        int templateRowIndex = 0;
-        if (table.getRows().size() <= templateRowIndex) {
-            logger.warn("表格行数不足");
-            return;
-        }
-
-        // 获取模板行的单元格数量
-        int cellCount = table.getRow(templateRowIndex).getTableCells().size();
-
-        // 删除模板行
-        table.removeRow(templateRowIndex);
-
-        // 从模板行位置开始插入数据行
-        for (int i = 0; i < dataList.size(); i++) {
-            CompleteTemplateProcessor.TableRowData data = dataList.get(i);
-            XWPFTableRow newRow = table.insertNewTableRow(templateRowIndex + i);
-            // 创建单元格
-            for (int j = 0; j < cellCount; j++) {
-                newRow.addNewTableCell();
-            }
-            fillTableRow(newRow, i + 1, data);
-        }
-    }
-
-    /**
-     * 填充表格行数据
-     */
-    private void fillTableRow(XWPFTableRow row, int sequence,
-                              CompleteTemplateProcessor.TableRowData data) {
-        List<XWPFTableCell> cells = row.getTableCells();
-        if (cells.size() >= 4) {
-            setCellText(cells.get(0), String.valueOf(sequence));
-            setCellText(cells.get(1), data.getDocumentName());
-            setCellText(cells.get(2), data.getPageCount() > 0 ? String.valueOf(data.getPageCount()) : "");
-            setCellText(cells.get(3), data.getRemark() != null ? data.getRemark() : "");
-        }
-    }
-
-    /**
-     * 设置单元格文本
-    */
-    private void setCellText(XWPFTableCell cell, String text) {
-        // 清除现有内容
-        for (int i = cell.getParagraphs().size() - 1; i >= 0; i--) {
-            cell.removeParagraph(i);
-        }
-        // 添加新内容
-        XWPFParagraph paragraph = cell.addParagraph();
-        XWPFRun run = paragraph.createRun();
-        run.setText(text);
-        paragraph.setAlignment(ParagraphAlignment.CENTER);
-    }
-
-    /**
-     * 将URL转换为本地文件路径
-     * 支持格式:
-     * 1. /profile/upload/xxx.docx
-     * 2. http://xxx/profile/upload/xxx.docx
-     * 3. 本地绝对路径
-     */
-    private String convertToLocalPath(String fileUrl) {
-        if (StringUtil.isEmpty(fileUrl)) {
-            return null;
-        }
-
-        // http或https开头,提取/profile部分
-        if (fileUrl.startsWith("http://") || fileUrl.startsWith("https://")) {
-            int profileIndex = fileUrl.indexOf("/profile/");
-            if (profileIndex > 0) {
-                String relativePath = fileUrl.substring(profileIndex);
-                return EipConfig.getProfile() + relativePath.substring(8);
-            }
-            return null;
-        }
-
-        // /profile开头
-        if (fileUrl.startsWith("/profile")) {
-            return EipConfig.getProfile() + fileUrl.substring(8);
-        }
-
-        // 本地绝对路径
-        return fileUrl;
-    }
-}

+ 23 - 0
assistMg/src/main/java/com/hotent/util/ExcelStyleUtil.java

@@ -100,6 +100,29 @@ public class ExcelStyleUtil {
     }
 
     /**
+     * 创建表头样式(左对齐,加粗,带边框,白色背景)
+     */
+    public static CellStyle createLeftHeaderStyle(Workbook workbook) {
+        CellStyle style = workbook.createCellStyle();
+        Font font = workbook.createFont();
+        font.setBold(true);
+        font.setFontName("宋体");
+        font.setFontHeightInPoints((short) 11);
+        style.setFont(font);
+        style.setAlignment(HorizontalAlignment.LEFT);
+        style.setVerticalAlignment(VerticalAlignment.CENTER);
+        style.setBorderTop(BorderStyle.THIN);
+        style.setBorderBottom(BorderStyle.THIN);
+        style.setBorderLeft(BorderStyle.THIN);
+        style.setBorderRight(BorderStyle.THIN);
+
+        // 自动换行
+        style.setWrapText(true);
+
+        return style;
+    }
+
+    /**
      * 创建数字数据样式(右对齐,带边框)
      */
     public static CellStyle createNumberDataStyle(Workbook workbook) {