123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405 |
- 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<String, Object> 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<String, ByteString> userSubmittedScoreMapMap = promotionSummary.getUserSubmittedScoreMapMap();
- // 关键步骤:将Protobuf的bytes数据转换为Map<String, List<Integer>>
- Map<String, List<Integer>> userScoreMap = new HashMap<>();
- for (Map.Entry<String, ByteString> entry : userSubmittedScoreMapMap.entrySet()) {
- String userId = entry.getKey();
- ByteString byteString = entry.getValue();
- // 解析bytes为ListValue
- ListValue listValue = ListValue.parseFrom(byteString);
- // 转换为List<Integer>
- List<Integer> 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<String, Object> data = objectMapper.readValue(completeJson, new TypeReference<Map<String, Object>>() {});
- // 将用户积分数据添加到渲染数据中
- data.put("userScoreMap", userScoreMap); // 这将使数据在模板中可用
- Map<String, Object> 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<String, Object> 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<String, Object> data) {
- Integer submitedTaskScore = (Integer) data.get("submitedTaskScore");
- Integer totalApprovedScore = (Integer) data.get("totalApprovedScore");
- data.put("rejectedTaskScore", submitedTaskScore - totalApprovedScore);
- // 提取任务类型元数据(taskTypeMetas)
- List<Map<String, Object>> taskTypeMetas = (List<Map<String, Object>>) data.get("taskTypeMetas");
- // 提取按类型统计的任务数据(taskStatsByType)
- List<Map<String, Object>> taskStatsByTypeList = (List<Map<String, Object>>) data.get("taskStatsByType");
- // 提取按用户统计的任务数据(taskStatsByPerson)
- List<Map<String, Object>> taskStatsByPersonList = (List<Map<String, Object>>) 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<String, List<Integer>> userScoreMap = (Map<String, List<Integer>>) data.get("userScoreMap");
- Long scoreSum = 0L;
- for (Map.Entry<String, List<Integer>> stringListEntry : userScoreMap.entrySet()) {
- scoreSum += stringListEntry.getValue().stream().mapToLong(Long::valueOf).sum();
- }
- Map<String, String> 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<String, List<List<Object>>> taskAnalysis51 = new HashMap<>();
- Map<String, Integer> mpParentTypeCount = new HashMap<>();
- Map<String, Long> mpParentTypeScore = new HashMap<>();
- // 解析taskStatsByType(protobuf中是列表,实际应为单个对象,取第一个)
- if (!taskStatsByTypeList.isEmpty()) {
- Map<String, Object> taskStatsByType = taskStatsByTypeList.get(0);
- Map<String, Map<String, Object>> taskStatsMap =
- (Map<String, Map<String, Object>>) taskStatsByType.get("taskStats");
- for (Map.Entry<String, Map<String, Object>> entry : taskStatsMap.entrySet()) {
- String taskTypeId = entry.getKey();
- Map<String, Object> 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<String, Object> meta : taskTypeMetas) {
- if (meta.get("taskTypeId").equals(taskTypeId)) {
- parentName = (String) meta.get("parentName");
- childName = (String) meta.get("childName");
- break;
- }
- }
- // 构建行数据
- List<Object> row = new ArrayList<>();
- row.add(childName);
- row.add(count);
- row.add(count * 1.0 / approvedCnt); // 占比=当前类型数量/总通过数量
- row.add(score);
- row.add(score * 1d / scoreSum); // 积分占比
- // 按父分类分组
- List<List<Object>> 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<String, Integer> starTaskMap = (Map<String, Integer>) data.get("starTaskMap");
- Map.Entry<String, Integer> 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<String, List<List<Object>>> taskPromotionCount511 = new HashMap<>();
- Set<String> allPromotioners = new HashSet<>(); // 所有推广人ID
- if (!taskStatsByTypeList.isEmpty()) {
- Map<String, Object> taskStatsByType = taskStatsByTypeList.get(0);
- Map<String, Map<String, Object>> taskStatsMap =
- (Map<String, Map<String, Object>>) taskStatsByType.get("taskStats");
- for (Map.Entry<String, Map<String, Object>> entry : taskStatsMap.entrySet()) {
- String taskTypeId = entry.getKey();
- Map<String, Object> taskStat = entry.getValue();
- int count = (Integer) taskStat.get("count");
- List<String> promotioners = (List<String>) taskStat.get("promotioners"); // 该任务类型的推广人列表
- if (promotioners != null) {
- allPromotioners.addAll(promotioners);
- }
- // 从taskTypeMetas中获取父/子分类名称
- String parentName = "";
- String childName = "";
- for (Map<String, Object> meta : taskTypeMetas) {
- if (meta.get("taskTypeId").equals(taskTypeId)) {
- parentName = (String) meta.get("parentName");
- childName = (String) meta.get("childName");
- break;
- }
- }
- // 构建行数据
- List<Object> 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<List<Object>> 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<Object> 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<String, List<List<Object>>> taskPromotioner54 = new HashMap<>();
- if (!taskStatsByPersonList.isEmpty()) {
- Map<String, Object> taskStatsByPerson = taskStatsByPersonList.get(0);
- Map<String, Map<String, Object>> userStatsMap =
- (Map<String, Map<String, Object>>) taskStatsByPerson.get("userStats");
- for (Map.Entry<String, Map<String, Object>> userEntry : userStatsMap.entrySet()) {
- String userId = userEntry.getKey();
- Map<String, Object> userTaskStats = userEntry.getValue();
- Map<String, Map<String, Object>> taskStatsByUser =
- (Map<String, Map<String, Object>>) userTaskStats.get("taskStats");
- // 获取用户名(从taskTypeMetas中匹配)
- // String userName = "无姓名";
- // for (Map<String, Object> meta : taskTypeMetas) {
- // if (meta.get("userId").equals(userId)) {
- // userName = (String) meta.get("userName");
- // break;
- // }
- // }
- // 构建该用户的任务统计行
- List<List<Object>> rowList = new ArrayList<>();
- for (Map.Entry<String, Map<String, Object>> taskEntry : taskStatsByUser.entrySet()) {
- String taskTypeId = taskEntry.getKey();
- Map<String, Object> taskStat = taskEntry.getValue();
- int count = (Integer) taskStat.get("count");
- Object o = taskStat.get("score");
- Long score = Longs.tryParse(o.toString());
- // 获取任务类型名称
- String taskTypeName = "";
- for (Map<String, Object> meta : taskTypeMetas) {
- if (meta.get("taskTypeId").equals(taskTypeId)) {
- taskTypeName = (String) meta.get("childName");
- break;
- }
- }
- List<Object> 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<Map<String, Object>> taskPromotionerQuality541 = new ArrayList<>();
- int idx = 1;
- if (!taskStatsByPersonList.isEmpty()) {
- Map<String, Object> taskStatsByPerson = taskStatsByPersonList.get(0);
- Map<String, Map<String, Object>> userStatsMap =
- (Map<String, Map<String, Object>>) taskStatsByPerson.get("userStats");
- for (Map.Entry<String, Map<String, Object>> userEntry : userStatsMap.entrySet()) {
- String userId = userEntry.getKey();
- Map<String, Object> userTaskStats = userEntry.getValue();
- Map<String, Map<String, Object>> taskStatsByUser =
- (Map<String, Map<String, Object>>) userTaskStats.get("taskStats");
- // 计算该用户的总通过任务数和积分
- int userApprovedCnt = 0;
- long userApprovedScore = 0L;
- for (Map<String, Object> 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<String, Object> 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<String, Object> 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<Object> 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);
- }
- }
|