浏览代码

知识库数据导出调整

徐滕 1 周之前
父节点
当前提交
c1fd2c4f56

+ 14 - 0
src/main/java/com/jeeplus/modules/WorkKnowledgeBase/dao/WorkKnowledgeBasePointDetailDao.java

@@ -273,4 +273,18 @@ public interface WorkKnowledgeBasePointDetailDao extends CrudDao<WorkKnowledgeBa
      * @return 月份列表,如 ["2026-10", "2026-09", ...]
      */
     List<String> findExchangeMonths();
+
+    /**
+     * 按point_mode分组统计已审核通过文件的创建积分和审核积分(用于汇总统计页签)
+     * @param shareIds 已审核通过的文件ID列表
+     * @return Map列表,每个Map包含pointMode/fileCount/totalCreatePoint/totalAuditPoint
+     */
+    List<java.util.Map<String, Object>> sumPointsByPointModeForPassedFiles(@Param("shareIds") List<String> shareIds);
+
+    /**
+     * 查询每个已审核通过文件的详细积分数据(用于汇总统计时排除管理员上传文件的审核积分)
+     * @param shareIds 已审核通过的文件ID列表
+     * @return Map列表,每个Map包含shareId/pointMode/createPoint/auditPoint
+     */
+    List<java.util.Map<String, Object>> findFilePointDetailsForPassedFiles(@Param("shareIds") List<String> shareIds);
 }

+ 24 - 0
src/main/java/com/jeeplus/modules/WorkKnowledgeBase/service/WorkKnowledgeBasePointDetailService.java

@@ -275,4 +275,28 @@ public class WorkKnowledgeBasePointDetailService extends CrudService<WorkKnowled
     public List<String> findExchangeMonths() {
         return pointDetailDao.findExchangeMonths();
     }
+
+    /**
+     * 按point_mode分组统计已审核通过文件的创建积分和审核积分(用于汇总统计页签)
+     * @param shareIds 已审核通过的文件ID列表
+     * @return Map列表,每个Map包含pointMode/fileCount/totalCreatePoint/totalAuditPoint
+     */
+    public List<Map<String, Object>> sumPointsByPointModeForPassedFiles(List<String> shareIds) {
+        if (shareIds == null || shareIds.isEmpty()) {
+            return new ArrayList<>();
+        }
+        return pointDetailDao.sumPointsByPointModeForPassedFiles(shareIds);
+    }
+
+    /**
+     * 查询每个已审核通过文件的详细积分数据(用于汇总统计时排除管理员上传文件的审核积分)
+     * @param shareIds 已审核通过的文件ID列表
+     * @return Map列表,每个Map包含shareId/pointMode/createPoint/auditPoint
+     */
+    public List<Map<String, Object>> findFilePointDetailsForPassedFiles(List<String> shareIds) {
+        if (shareIds == null || shareIds.isEmpty()) {
+            return new ArrayList<>();
+        }
+        return pointDetailDao.findFilePointDetailsForPassedFiles(shareIds);
+    }
 }

+ 122 - 12
src/main/java/com/jeeplus/modules/WorkKnowledgeBase/web/WorkKnowledgeBaseShareController.java

@@ -70,6 +70,9 @@ public class WorkKnowledgeBaseShareController extends BaseController {
     @Autowired
     private WorkKnowledgeBaseAuditRecordService auditRecordService;
 
+    @Autowired
+    private com.jeeplus.modules.WorkKnowledgeBase.service.WorkKnowledgeBasePointDetailService pointDetailService;
+
     @ModelAttribute
     public WorkKnowledgeBaseShareInfo get(@RequestParam(required = false) String id) {
         WorkKnowledgeBaseShareInfo entity = null;
@@ -1397,31 +1400,124 @@ public class WorkKnowledgeBaseShareController extends BaseController {
                 allExportData.addAll(exportData);
             }
 
-            // ======================== 最后一个页签:汇总统计 ========================
+            // ======================== 最后一个页签:汇总统计(含积分维度) ========================
             int totalCount = allExportData.size();
-            int passedCount = 0, auditingCount = 0, pendingCount = 0, draftCount = 0, rejectedCount = 0;
+            int auditingCount = 0, pendingCount = 0, draftCount = 0, rejectedCount = 0;
+
+            // 收集已审核通过的文件ID,并区分管理员上传和普通审核通过
+            List<String> passedFileIds = new ArrayList<>();
+            Set<String> adminUploadedFileIds = new HashSet<>(); // 管理员上传的文件ID集合
             for (Map<String, Object> row : allExportData) {
                 String status = row.get("auditStatus") != null ? row.get("auditStatus").toString() : "";
                 switch (status) {
-                    case "5": passedCount++; break;
                     case "2": auditingCount++; break;
                     case "1": pendingCount++; break;
                     case "0": draftCount++; break;
                     case "4": rejectedCount++; break;
+                    case "5": // 审核通过
+                        String fileId = row.get("id") != null ? row.get("id").toString() : "";
+                        if (StringUtils.isNotBlank(fileId)) {
+                            passedFileIds.add(fileId);
+                            // 判断是否为管理员上传:create_by = submit_audit_user_id
+                            String createBy = row.get("createBy") != null ? row.get("createBy").toString() : "";
+                            String submitAuditUserId = row.get("submitAuditUserId") != null ? row.get("submitAuditUserId").toString() : "";
+                            if (StringUtils.isNotBlank(createBy) && createBy.equals(submitAuditUserId)) {
+                                adminUploadedFileIds.add(fileId);
+                            }
+                        }
+                        break;
+                }
+            }
+
+            // 查询每个文件的详细积分数据(未聚合)
+            List<Map<String, Object>> filePointDetails = new ArrayList<>();
+            if (!passedFileIds.isEmpty()) {
+                filePointDetails = pointDetailService.findFilePointDetailsForPassedFiles(passedFileIds);
+            }
+
+            // 遍历每个文件的积分数据,排除管理员上传的文件的审核积分
+            long fixedCreatePoint = 0, fixedAuditPoint = 0;
+            int fixedFileCount = 0;
+            long intervalCreatePoint = 0, intervalAuditPoint = 0;
+            int intervalFileCount = 0;
+            
+            for (Map<String, Object> detail : filePointDetails) {
+                String shareId = detail.get("shareId") != null ? detail.get("shareId").toString() : "";
+                String pointMode = detail.get("pointMode") != null ? detail.get("pointMode").toString() : "1";
+                long createPoint = detail.get("createPoint") != null ? ((Number) detail.get("createPoint")).longValue() : 0;
+                long auditPoint = detail.get("auditPoint") != null ? ((Number) detail.get("auditPoint")).longValue() : 0;
+                
+                // 如果是管理员上传的文件,只统计创建积分,不计入审核积分
+                if (adminUploadedFileIds.contains(shareId)) {
+                    auditPoint = 0L; // 管理员上传的文件没有审核积分
+                }
+                
+                if ("1".equals(pointMode)) {
+                    // 固定分值
+                    fixedFileCount++;
+                    fixedCreatePoint += createPoint;
+                    fixedAuditPoint += auditPoint;
+                } else {
+                    // 区间分值
+                    intervalFileCount++;
+                    intervalCreatePoint += createPoint;
+                    intervalAuditPoint += auditPoint;
                 }
             }
+
+            // 未审核/草稿/审核未通过 预期积分(默认:创建人20分 + 审核人5分×3人 = 35分/文件)
+            int expectedPointsPerFile = 20 + 5 * 3;
+            long pendingExpectedPoints = (long) pendingCount * expectedPointsPerFile;
+            long draftExpectedPoints = (long) draftCount * expectedPointsPerFile;
+            long rejectedExpectedPoints = (long) rejectedCount * expectedPointsPerFile;
+
+            // 组装汇总统计页签(5列:统计项 | 文件数 | 创建积分 | 审核积分 | 总积分)
             List<String> summaryHeaders = new ArrayList<>();
             summaryHeaders.add("统计项|label");
-            summaryHeaders.add("数量|count");
+            summaryHeaders.add("文件数|count");
+            summaryHeaders.add("创建积分|createPoint");
+            summaryHeaders.add("审核积分|auditPoint");
+            summaryHeaders.add("总积分|totalPoint");
             List<Map<String, Object>> summaryData = new ArrayList<>();
-            String[] labels = {"总数据量", "审核通过", "审核中", "未审核", "草稿", "审核未通过"};
-            int[] counts = {totalCount, passedCount, auditingCount, pendingCount, draftCount, rejectedCount};
-            for (int i = 0; i < labels.length; i++) {
-                Map<String, Object> row = new HashMap<>();
-                row.put("label", labels[i]);
-                row.put("count", counts[i]);
-                summaryData.add(row);
-            }
+
+            // 第1行:总数据量
+            addSummaryRow(summaryData, "总数据量", totalCount, 0L, 0L, 0L);
+
+            // 第2行:审核通过(固定分值)
+            long fixedTotalPoint = fixedCreatePoint + fixedAuditPoint * 3;
+            addSummaryRow(summaryData, "审核通过(固定分值)", fixedFileCount, fixedCreatePoint, fixedAuditPoint, fixedTotalPoint);
+
+            // 第3行:审核通过(区间分值)
+            long intervalTotalPoint = intervalCreatePoint + intervalAuditPoint * 3;
+            addSummaryRow(summaryData, "审核通过(区间分值)", intervalFileCount, intervalCreatePoint, intervalAuditPoint, intervalTotalPoint);
+
+            // 第4行:审核中
+            addSummaryRow(summaryData, "审核中", auditingCount, 0L, 0L, 0L);
+
+            // 第5行:未审核(预期积分)
+            long pendingCreatePoint = (long) pendingCount * 20;
+            long pendingAuditPoint = (long) pendingCount * 5;
+            addSummaryRow(summaryData, "未审核", pendingCount, pendingCreatePoint, pendingAuditPoint, pendingExpectedPoints);
+
+            // 第6行:草稿(预期积分)
+            long draftCreatePoint = (long) draftCount * 20;
+            long draftAuditPoint = (long) draftCount * 5;
+            addSummaryRow(summaryData, "草稿", draftCount, draftCreatePoint, draftAuditPoint, draftExpectedPoints);
+
+            // 第7行:审核未通过(预期积分)
+            long rejectedCreatePoint = (long) rejectedCount * 20;
+            long rejectedAuditPoint = (long) rejectedCount * 5;
+            addSummaryRow(summaryData, "审核未通过", rejectedCount, rejectedCreatePoint, rejectedAuditPoint, rejectedExpectedPoints);
+
+            // 第8行:典型案例(预测)- 用户自行填写数量,其他列按公式计算
+            // 平均创建积分 = 审核通过(区间分值)的创建积分 / 文件数
+            long avgCreatePointPerFile = intervalFileCount > 0 ? intervalCreatePoint / intervalFileCount : 0;
+            int predictedCount = 0; // 用户自行填写
+            long predictedCreatePoint = avgCreatePointPerFile * predictedCount;
+            long predictedAuditPoint = 20L * predictedCount; // 每条审核积分20分
+            long predictedTotalPoint = (avgCreatePointPerFile + 3 * 20) * predictedCount; // (平均创建积分 + 3×审核积分) × 数量
+            addSummaryRow(summaryData, "典型案例(预测)", predictedCount, predictedCreatePoint, predictedAuditPoint, predictedTotalPoint);
+
             excel.addSheet("汇总统计", "汇总统计", summaryHeaders, summaryData);
 
             String fileName = "知识库数据导出(含审核)_" + DateUtils.getDate("yyyyMMddHHmmss") + ".xlsx";
@@ -2178,4 +2274,18 @@ public class WorkKnowledgeBaseShareController extends BaseController {
         }
         return resultList;
     }
+
+    /**
+     * 辅助方法:添加汇总统计行
+     */
+    private void addSummaryRow(List<Map<String, Object>> summaryData, String label,
+                                int count, long createPoint, long auditPoint, long totalPoint) {
+        Map<String, Object> row = new HashMap<>();
+        row.put("label", label);
+        row.put("count", count);
+        row.put("createPoint", createPoint);
+        row.put("auditPoint", auditPoint);
+        row.put("totalPoint", totalPoint);
+        summaryData.add(row);
+    }
 }

+ 60 - 0
src/main/resources/mappings/modules/WorkKnowledgeBase/WorkKnowledgeBasePointDetailDao.xml

@@ -1139,4 +1139,64 @@
         ) tmp
     </select>
 
+    <!-- 按point_mode分组统计已审核通过文件的创建积分和审核积分(用于汇总统计页签) -->
+    <select id="sumPointsByPointModeForPassedFiles" resultType="java.util.HashMap">
+        SELECT
+            IFNULL(mode_grp.point_mode, '1') AS pointMode,
+            COUNT(DISTINCT mode_grp.share_id) AS fileCount,
+            COALESCE(SUM(mode_grp.create_point), 0) AS totalCreatePoint,
+            COALESCE(SUM(mode_grp.audit_point), 0) AS totalAuditPoint
+        FROM (
+            SELECT
+                fp.share_id,
+                IFNULL(r.point_mode, '1') AS point_mode,
+                fp.create_point,
+                fp.audit_point
+            FROM (
+                -- 子查询:按share_id聚合每个文件的创建积分和审核积分
+                SELECT 
+                    pd.share_id,
+                    COALESCE(SUM(CASE WHEN pd.change_type = 1 THEN pd.point ELSE 0 END), 0) AS create_point,
+                    COALESCE(SUM(CASE WHEN pd.change_type = 2 THEN pd.point ELSE 0 END), 0) AS audit_point,
+                    MAX(pd.category_id) AS category_id  -- 取该文件任意一个category_id用于关联规则
+                FROM work_knowledge_base_point_detail pd
+                WHERE pd.del_flag = '0'
+                  AND pd.point &gt; 0
+                  AND pd.share_id IN
+                <foreach collection="shareIds" item="sid" open="(" separator="," close=")">
+                    #{sid}
+                </foreach>
+                GROUP BY pd.share_id
+            ) fp
+            LEFT JOIN work_knowledge_base_point_rule r ON r.category_id = fp.category_id AND r.rule_type = '1' AND r.del_flag = '0'
+        ) mode_grp
+        GROUP BY mode_grp.point_mode
+    </select>
+
+    <!-- 查询每个已审核通过文件的详细积分数据(用于汇总统计时排除管理员上传文件的审核积分) -->
+    <select id="findFilePointDetailsForPassedFiles" resultType="java.util.HashMap">
+        SELECT 
+            fp.share_id AS shareId,
+            IFNULL(r.point_mode, '1') AS pointMode,
+            fp.create_point AS createPoint,
+            fp.audit_point AS auditPoint
+        FROM (
+            -- 子查询:按share_id聚合每个文件的创建积分和审核积分
+            SELECT 
+                pd.share_id,
+                COALESCE(SUM(CASE WHEN pd.change_type = 1 THEN pd.point ELSE 0 END), 0) AS create_point,
+                COALESCE(SUM(CASE WHEN pd.change_type = 2 THEN pd.point ELSE 0 END), 0) AS audit_point,
+                MAX(pd.category_id) AS category_id  -- 取该文件任意一个category_id用于关联规则
+            FROM work_knowledge_base_point_detail pd
+            WHERE pd.del_flag = '0'
+              AND pd.point &gt; 0
+              AND pd.share_id IN
+            <foreach collection="shareIds" item="sid" open="(" separator="," close=")">
+                #{sid}
+            </foreach>
+            GROUP BY pd.share_id
+        ) fp
+        LEFT JOIN work_knowledge_base_point_rule r ON r.category_id = fp.category_id AND r.rule_type = '1' AND r.del_flag = '0'
+    </select>
+
 </mapper>