package com.yaoyicloud.render.cso; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import com.yaoyicloud.easier.common.file.core.FileProperties; import com.yaoyicloud.easier.common.file.core.FileTemplate; import com.yaoyicloud.factory.CSOAbstractRender; import org.apache.commons.collections4.MapUtils; import com.deepoove.poi.config.Configure; import com.deepoove.poi.config.ConfigureBuilder; import com.deepoove.poi.policy.DynamicTableRenderPolicy; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.primitives.Longs; import com.google.protobuf.ByteString; import com.google.protobuf.ListValue; import com.google.protobuf.util.JsonFormat; import com.yaoyicloud.config.CommonDataCache; import com.yaoyicloud.config.FilerepoProperties; import com.yaoyicloud.message.CSOProtos; import lombok.extern.slf4j.Slf4j; @Slf4j public final class EntPromotionSummaryRender extends CSOAbstractRender { private final FilerepoProperties filerepoProperties; private final CommonDataCache commonDataCache; public EntPromotionSummaryRender(String cwd, FileTemplate ossTemplate, FileProperties properties, FilerepoProperties filerepoProperties, CommonDataCache commonDataCache) { super(cwd, ossTemplate, properties); this.filerepoProperties = filerepoProperties; this.commonDataCache = commonDataCache; } @Override protected Map renderDocx(String info, String relationId, Integer counter) throws IOException { log.info("开始渲染CSO企业报告推广总结模块,relationId: {}", relationId); CSOProtos.PromotionSummary.Builder promotionSummary = CSOProtos.PromotionSummary.newBuilder(); JsonFormat.parser().merge(info, promotionSummary); // 获取用户提交的积分数据 Map userSubmittedScoreMapMap = promotionSummary.getUserSubmittedScoreMapMap(); // 关键步骤:将Protobuf的bytes数据转换为Map> Map> userScoreMap = new HashMap<>(); for (Map.Entry entry : userSubmittedScoreMapMap.entrySet()) { String userId = entry.getKey(); ByteString byteString = entry.getValue(); // 解析bytes为ListValue ListValue listValue = ListValue.parseFrom(byteString); // 转换为List List scoreList = listValue.getValuesList().stream() .map(value -> (int) value.getNumberValue()) .collect(Collectors.toList()); userScoreMap.put(userId, scoreList); } CSOProtos.PromotionSummary defaultInstance = CSOProtos.PromotionSummary.getDefaultInstance(); CSOProtos.PromotionSummary mergedProto = defaultInstance.toBuilder() .mergeFrom(promotionSummary.build()) .build(); String completeJson = JsonFormat.printer() .includingDefaultValueFields() .print(mergedProto); ObjectMapper objectMapper = new ObjectMapper(); Map data = objectMapper.readValue(completeJson, new TypeReference>() {}); // 将用户积分数据添加到渲染数据中 data.put("userScoreMap", userScoreMap); // 这将使数据在模板中可用 Map commonDataCacheData = commonDataCache.getData(relationId); if (MapUtils.isNotEmpty(commonDataCacheData)) { data.putAll(commonDataCacheData); } commonDataCacheData.put("sensitiveFlag", data.get("sensitiveFlag")); data.put("levelInteger", counter); fillDefaultValues(data); return data; } @Override protected ConfigureBuilder builder(String relationId) { ConfigureBuilder builder = Configure.builder(); DynamicTableRenderPolicy twoLevelTableDynamicPolicy = getTwoLevelTableDynamicPolicy(); DynamicTableRenderPolicy lastRowDaynamicPolicy = getTableLastRowDynamicPolicy(); Map commonDataCacheData = commonDataCache.getData(relationId); DynamicTableRenderPolicy tableDynamicPolicy = super.getDynamicTableRenderPolicy(commonDataCacheData); builder.bind("task_analysis_5_1", twoLevelTableDynamicPolicy); builder.bind("task_promotion_count_5_1_1", twoLevelTableDynamicPolicy); builder.bind("task_promotion_count_5_1_1_last", lastRowDaynamicPolicy); builder.bind("task_promotioner_5_4", tableDynamicPolicy); builder.bind("task_promotioner_quality_5_4_1", this.indicatorsRenderPolicyToProtobuf()); builder.bind("task_promotioner_quality_5_4_1_last", lastRowDaynamicPolicy); return builder; } @Override protected String getBasicPath() throws IOException { return filerepoProperties.getBasePath(); } @Override protected String getReportImagePath() { return filerepoProperties.getReportImagePath(); } /** * 填充默认值,确保所有必要字段都存在 */ @SuppressWarnings("checkstyle:MethodLength") private void fillDefaultValues(Map data) { Integer submitedTaskScore = (Integer) data.get("submitedTaskScore"); Integer totalApprovedScore = (Integer) data.get("totalApprovedScore"); data.put("rejectedTaskScore", submitedTaskScore - totalApprovedScore); // 提取任务类型元数据(taskTypeMetas) List> taskTypeMetas = (List>) data.get("taskTypeMetas"); // 提取按类型统计的任务数据(taskStatsByType) List> taskStatsByTypeList = (List>) data.get("taskStatsByType"); // 提取按用户统计的任务数据(taskStatsByPerson) List> taskStatsByPersonList = (List>) data.get("taskStatsByPerson"); // 提取全局统计字段 int approvedCnt = (Integer) data.getOrDefault("taskPromotionerQuality541ApprovedCnt", 0); int submittedCnt = (Integer) data.getOrDefault("taskPromotionerQuality541SubmittedCnt", 0); int rejectedCnt = (Integer) data.getOrDefault("taskPromotionerQuality541RejectedCnt", 0); Map> userScoreMap = (Map>) data.get("userScoreMap"); Long scoreSum = 0L; for (Map.Entry> stringListEntry : userScoreMap.entrySet()) { scoreSum += stringListEntry.getValue().stream().mapToLong(Long::valueOf).sum(); } Map userNameMap = taskTypeMetas.stream() .collect(Collectors.toMap( m -> m.get("userId").toString(), m -> m.get("userName").toString(), (oldValue, newValue) -> oldValue)); data.put("userNameMap", userNameMap); // 2. 复现 task_analysis_5_1(按任务类型的统计分析) Map>> taskAnalysis51 = new HashMap<>(); Map mpParentTypeCount = new HashMap<>(); Map mpParentTypeScore = new HashMap<>(); // 解析taskStatsByType(protobuf中是列表,实际应为单个对象,取第一个) if (!taskStatsByTypeList.isEmpty()) { Map taskStatsByType = taskStatsByTypeList.get(0); Map> taskStatsMap = (Map>) taskStatsByType.get("taskStats"); for (Map.Entry> entry : taskStatsMap.entrySet()) { String taskTypeId = entry.getKey(); Map taskStat = entry.getValue(); int count = (Integer) taskStat.get("count"); Object o = taskStat.get("score"); Long score = Longs.tryParse(o.toString()); // 从taskTypeMetas中获取父/子分类名称(根据taskTypeId匹配) String parentName = ""; String childName = ""; for (Map meta : taskTypeMetas) { if (meta.get("taskTypeId").equals(taskTypeId)) { parentName = (String) meta.get("parentName"); childName = (String) meta.get("childName"); break; } } // 构建行数据 List row = new ArrayList<>(); row.add(childName); row.add(count); row.add(count * 1.0 / approvedCnt); // 占比=当前类型数量/总通过数量 row.add(score); row.add(score * 1d / scoreSum); // 积分占比 // 按父分类分组 List> rowList = taskAnalysis51.getOrDefault(parentName, new ArrayList<>()); rowList.add(row); taskAnalysis51.put(parentName, rowList); // 更新父分类的总数量和积分 mpParentTypeCount.put(parentName, mpParentTypeCount.getOrDefault(parentName, 0) + count); mpParentTypeScore.put(parentName, mpParentTypeScore.getOrDefault(parentName, 0L) + score); } } data.put("task_analysis_5_1", taskAnalysis51); // 复现 task_analysis_5_1 的最大值(最多任务的父分类) if (!mpParentTypeCount.isEmpty()) { Map starTaskMap = (Map) data.get("starTaskMap"); Map.Entry maxEntry = starTaskMap.entrySet().iterator().next(); data.put("task_analysis_5_1_maxName", maxEntry.getKey()); data.put("task_analysis_5_1_maxCount", maxEntry.getValue().toString()); // 计算最大父分类的积分占比 long maxParentScore = mpParentTypeScore.getOrDefault(maxEntry.getKey(), 0L); data.put("task_analysis_5_1_maxPercent", String.format("%.2f", maxParentScore * 1.0 / scoreSum * 100)); } // 3. 复现 task_promotion_count_5_1_1(按任务类型的推广人统计) Map>> taskPromotionCount511 = new HashMap<>(); Set allPromotioners = new HashSet<>(); // 所有推广人ID if (!taskStatsByTypeList.isEmpty()) { Map taskStatsByType = taskStatsByTypeList.get(0); Map> taskStatsMap = (Map>) taskStatsByType.get("taskStats"); for (Map.Entry> entry : taskStatsMap.entrySet()) { String taskTypeId = entry.getKey(); Map taskStat = entry.getValue(); int count = (Integer) taskStat.get("count"); List promotioners = (List) taskStat.get("promotioners"); // 该任务类型的推广人列表 if (promotioners != null) { allPromotioners.addAll(promotioners); } // 从taskTypeMetas中获取父/子分类名称 String parentName = ""; String childName = ""; for (Map meta : taskTypeMetas) { if (meta.get("taskTypeId").equals(taskTypeId)) { parentName = (String) meta.get("parentName"); childName = (String) meta.get("childName"); break; } } // 构建行数据 List row = new ArrayList<>(); row.add(childName); row.add(promotioners != null ? promotioners.size() : 0); // 推广人数 row.add(count); // 任务数量 row.add(promotioners != null && !promotioners.isEmpty() ? count * 1.0 / promotioners.size() : 0); // 人均任务数 // 按父分类分组 List> rowList = taskPromotionCount511.getOrDefault(parentName, new ArrayList<>()); rowList.add(row); taskPromotionCount511.put(parentName, rowList); } } data.put("task_promotion_count_5_1_1", taskPromotionCount511); // 复现推广人平均任务数 int promotionerCount = allPromotioners.size(); String avgByPerson = promotionerCount > 0 ? String.format("%.2f", approvedCnt * 1.0 / promotionerCount) : "0.00"; data.put("task_promotion_count_5_1_1_avg", avgByPerson); // 复现task_promotion_count_5_1_1_last(合计行) List lastRow511 = new ArrayList<>(); lastRow511.add(null); // label lastRow511.add(promotionerCount); // 总推广人数 lastRow511.add(approvedCnt); // 总任务数 lastRow511.add(avgByPerson); // 平均任务数 data.put("task_promotion_count_5_1_1_last", lastRow511); // 4. 复现 task_promotioner_5_4(按推广人的任务类型统计) Map>> taskPromotioner54 = new HashMap<>(); if (!taskStatsByPersonList.isEmpty()) { Map taskStatsByPerson = taskStatsByPersonList.get(0); Map> userStatsMap = (Map>) taskStatsByPerson.get("userStats"); for (Map.Entry> userEntry : userStatsMap.entrySet()) { String userId = userEntry.getKey(); Map userTaskStats = userEntry.getValue(); Map> taskStatsByUser = (Map>) userTaskStats.get("taskStats"); // 获取用户名(从taskTypeMetas中匹配) // String userName = "无姓名"; // for (Map meta : taskTypeMetas) { // if (meta.get("userId").equals(userId)) { // userName = (String) meta.get("userName"); // break; // } // } // 构建该用户的任务统计行 List> rowList = new ArrayList<>(); for (Map.Entry> taskEntry : taskStatsByUser.entrySet()) { String taskTypeId = taskEntry.getKey(); Map taskStat = taskEntry.getValue(); int count = (Integer) taskStat.get("count"); Object o = taskStat.get("score"); Long score = Longs.tryParse(o.toString()); // 获取任务类型名称 String taskTypeName = ""; for (Map meta : taskTypeMetas) { if (meta.get("taskTypeId").equals(taskTypeId)) { taskTypeName = (String) meta.get("childName"); break; } } List row = new ArrayList<>(); row.add(taskTypeName); row.add(count); row.add(count * 1.0 / approvedCnt); // 任务占比 row.add(score); row.add(score * 1d / scoreSum); rowList.add(row); } taskPromotioner54.put(userId, rowList); } } data.put("task_promotioner_5_4", taskPromotioner54); // 5. 复现 task_promotioner_quality_5_4_1(推广人质量统计) List> taskPromotionerQuality541 = new ArrayList<>(); int idx = 1; if (!taskStatsByPersonList.isEmpty()) { Map taskStatsByPerson = taskStatsByPersonList.get(0); Map> userStatsMap = (Map>) taskStatsByPerson.get("userStats"); for (Map.Entry> userEntry : userStatsMap.entrySet()) { String userId = userEntry.getKey(); Map userTaskStats = userEntry.getValue(); Map> taskStatsByUser = (Map>) userTaskStats.get("taskStats"); // 计算该用户的总通过任务数和积分 int userApprovedCnt = 0; long userApprovedScore = 0L; for (Map taskStat : taskStatsByUser.values()) { userApprovedCnt += (Integer) taskStat.get("count"); userApprovedScore += Longs.tryParse(taskStat.get("score").toString()); } int userSubmittedCnt = 0; int userSubmittedScore = 0; // 获取用户名 String userName = "无姓名"; for (Map meta : taskTypeMetas) { if (meta.get("userId").equals(userId)) { userSubmittedCnt = userScoreMap.get(meta.get("userId").toString()).size(); userSubmittedScore = userScoreMap.get(meta.get("userId")).stream().mapToInt(Integer::intValue).sum(); userName = (String) meta.get("userName"); break; } } // 构建行数据 Map row = new HashMap<>(); row.put("seq", idx++); row.put("promotioner", userName); row.put("submittedCnt", userSubmittedCnt); row.put("approvedCnt", userApprovedCnt); row.put("taskRate", userSubmittedCnt > 0 ? String.format("%.2f%%", userApprovedCnt * 1.0 / userSubmittedCnt * 100) : "0.00%"); row.put("submittedScore", userSubmittedScore); row.put("approvedScore", userApprovedScore); row.put("scoreRate", userSubmittedScore > 0 ? String.format("%.2f%%", userApprovedScore * 1.0 / userSubmittedScore * 100) : "0.00%"); taskPromotionerQuality541.add(row); } } data.put("task_promotioner_quality_5_4_1", taskPromotionerQuality541); // 6. 复现 task_promotioner_quality_5_4_1_last(合计行) List lastRow541 = new ArrayList<>(); lastRow541.add(null); // label lastRow541.add(submittedCnt); // 总提交数 lastRow541.add(approvedCnt); // 总通过数 String taskRate = submittedCnt > 0 ? String.format("%.2f%%", approvedCnt * 1.0 / submittedCnt * 100) : "0.00%"; lastRow541.add(taskRate); Long totalSubmittedScore = Longs.tryParse(scoreSum.toString()); lastRow541.add(totalSubmittedScore); lastRow541.add(scoreSum); // 总通过积分 String scoreRate = totalSubmittedScore > 0 ? String.format("%.2f%%", scoreSum * 1.0 / totalSubmittedScore * 100) : "0.00%"; lastRow541.add(scoreRate); data.put("task_promotioner_quality_5_4_1_last", lastRow541); // 7. 填充其他字段 data.put("task_promotioner_quality_5_4_1_taskRate", taskRate.replace("%", "")); data.put("task_promotioner_quality_5_4_1_scoreRate", scoreRate.replace("%", "")); data.put("task_promotioner_quality_5_4_1_approvedCnt", approvedCnt); data.put("task_promotioner_quality_5_4_1_submittedCnt", submittedCnt); data.put("task_promotioner_quality_5_4_1_rejectedCnt", rejectedCnt); } }