Commit aff7611343f7c00107aadb602af8fafdf54ede8a

Authored by wangqian
2 parents 4f0ee40a 1b6d9c9e

Merge remote-tracking branch 'origin/dev' into dev

urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/api/road/RoadApiImpl.java
... ... @@ -5,6 +5,7 @@ import cn.hutool.json.JSONUtil;
5 5 import com.alibaba.fastjson.JSON;
6 6 import com.zteits.urbanops.framework.common.util.http.HttpUtils;
7 7 import com.zteits.urbanops.framework.common.util.object.BeanUtils;
  8 +import com.zteits.urbanops.framework.datapermission.core.annotation.DataPermission;
8 9 import com.zteits.urbanops.module.garden.controller.admin.road.vo.RoadRespVO;
9 10 import com.zteits.urbanops.module.garden.dto.road.RoadReqDTO;
10 11 import com.zteits.urbanops.module.garden.dto.road.RoadRespDTO;
... ... @@ -69,6 +70,7 @@ public class RoadApiImpl implements RoadApi {
69 70 }
70 71  
71 72 @Override
  73 + @DataPermission(enable = false)
72 74 public RoadStreetRespDTO getRoadInfoById(String id) {
73 75 RoadRespVO roadRespVO = roadService.getUniqueRoad(Long.parseLong(id));
74 76 if(null == roadRespVO){
... ...
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/app/homepage/vo/TaskDistanceSortRespVO.java
... ... @@ -55,4 +55,7 @@ public class TaskDistanceSortRespVO extends TaskDetailsRspVo {
55 55  
56 56 /** 班组平均完成时长(分钟) */
57 57 private BigDecimal teamAvgMinutes;
  58 +
  59 + /** 个人历史完成率 = 6个月内已完成 / 6个月内总任务数 */
  60 + private BigDecimal historyCompletionRate;
58 61 }
... ...
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/dal/dataobject/UserTaskEfficiencyDO.java
... ... @@ -53,6 +53,9 @@ public class UserTaskEfficiencyDO extends BaseDO {
53 53 /** 效率比 = teamAvg / userAvg */
54 54 private BigDecimal efficiencyRatio;
55 55  
  56 + /** 个人历史完成率 = 6个月内已完成 / 6个月内总任务数 */
  57 + private BigDecimal historyCompletionRate;
  58 +
56 59 /** 统计周期 yyyy-MM */
57 60 private String statPeriod;
58 61 }
... ...
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/dal/mysql/UserTaskEfficiencyMapper.java
... ... @@ -40,4 +40,7 @@ public interface UserTaskEfficiencyMapper extends BaseMapperX<UserTaskEfficiency
40 40  
41 41 /** 工单效率统计 */
42 42 List<Map<String, Object>> statWorkOrderEfficiency(@Param("beginTime") String beginTime);
  43 +
  44 + /** 从 task_statistics 汇总用户 6 个月历史任务总量 */
  45 + List<Map<String, Object>> statHistoryTotalCount(@Param("beginDate") String beginDate);
43 46 }
... ...
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/dal/mysql/maintainplan/MaintainPlanDetailMapper.java
... ... @@ -3,6 +3,7 @@ package com.zteits.urbanops.module.garden.dal.mysql.maintainplan;
3 3  
4 4 import com.baomidou.mybatisplus.core.metadata.IPage;
5 5 import com.zteits.urbanops.framework.common.pojo.PageResult;
  6 +import com.zteits.urbanops.framework.common.util.collection.ArrayUtils;
6 7 import com.zteits.urbanops.framework.mybatis.core.mapper.BaseMapperX;
7 8 import com.zteits.urbanops.framework.mybatis.core.query.LambdaQueryWrapperX;
8 9 import com.zteits.urbanops.module.garden.controller.admin.maintainplan.vo.MaintainPlanDetailPageReqVO;
... ... @@ -33,8 +34,8 @@ public interface MaintainPlanDetailMapper extends BaseMapperX&lt;MaintainPlanDetail
33 34 .eqIfPresent(MaintainPlanDetailDO::getDeptId, reqVO.getDeptId())
34 35 .eqIfPresent(MaintainPlanDetailDO::getRoadId, reqVO.getRoadId())
35 36 .eqIfPresent(MaintainPlanDetailDO::getSortNum, reqVO.getSortNum())
36   - .betweenIfPresent(MaintainPlanDetailDO::getBeginTime, reqVO.getBeginTime())
37   - .betweenIfPresent(MaintainPlanDetailDO::getEndTime, reqVO.getEndTime())
  37 + .geIfPresent(MaintainPlanDetailDO::getBeginTime, ArrayUtils.get(reqVO.getBeginTime(), 0))
  38 + .leIfPresent(MaintainPlanDetailDO::getEndTime, ArrayUtils.get(reqVO.getEndTime(), 0))
38 39 .eqIfPresent(MaintainPlanDetailDO::getPlanFinishNum, reqVO.getPlanFinishNum())
39 40 .eqIfPresent(MaintainPlanDetailDO::getFinishState, reqVO.getFinishState())
40 41 .likeIfPresent(MaintainPlanDetailDO::getCreatorName, reqVO.getCreatorName())
... ... @@ -60,4 +61,4 @@ public interface MaintainPlanDetailMapper extends BaseMapperX&lt;MaintainPlanDetail
60 61 */
61 62 List<AppMaintainNotFinishPlanDetailRespVO> getMaintainNotFinishPlanCommitDetail(@Param("req") AppMaintainNotFinishPlanDetailReqVO reqVO);
62 63  
63   -}
64 64 \ No newline at end of file
  65 +}
... ...
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/job/TaskEfficiencyCalculateJob.java
... ... @@ -39,6 +39,7 @@ public class TaskEfficiencyCalculateJob implements JobHandler {
39 39  
40 40 // 2. 6个月窗口
41 41 String beginTime = LocalDate.now().minusMonths(6).withDayOfMonth(1) + " 00:00:00";
  42 + String beginDate = LocalDate.now().minusMonths(6).withDayOfMonth(1).toString();
42 43  
43 44 // 3. 三类任务分别统计
44 45 List<UserTaskEfficiencyDO> all = new ArrayList<>();
... ... @@ -59,6 +60,19 @@ public class TaskEfficiencyCalculateJob implements JobHandler {
59 60 e.setEfficiencyRatio(calcRatio(e.getAvgMinutes(), e.getTeamAvgMinutes()));
60 61 }
61 62  
  63 + // 5.5 计算个人历史完成率
  64 + Map<Long, Map<String, Object>> historyMap = loadHistoryTotalMap(beginDate);
  65 + for (UserTaskEfficiencyDO e : all) {
  66 + Map<String, Object> h = historyMap.get(e.getUserId());
  67 + if (h != null) {
  68 + long total = toLong(h.get("history_total"));
  69 + long completed = toLong(h.get("history_completed"));
  70 + e.setHistoryCompletionRate(total > 0
  71 + ? BigDecimal.valueOf(completed).divide(BigDecimal.valueOf(total), 4, RoundingMode.HALF_UP)
  72 + : BigDecimal.ZERO);
  73 + }
  74 + }
  75 +
62 76 // 6. 生成大类汇总(ALL)
63 77 all.addAll(buildCategorySummary(all, statPeriod));
64 78  
... ... @@ -132,6 +146,17 @@ public class TaskEfficiencyCalculateJob implements JobHandler {
132 146 return ratio;
133 147 }
134 148  
  149 + private Map<Long, Map<String, Object>> loadHistoryTotalMap(String beginDate) {
  150 + List<Map<String, Object>> rows = userTaskEfficiencyMapper.statHistoryTotalCount(beginDate);
  151 + Map<Long, Map<String, Object>> map = new LinkedHashMap<>();
  152 + if (rows != null) {
  153 + for (Map<String, Object> row : rows) {
  154 + map.put(toLong(row.get("user_id")), row);
  155 + }
  156 + }
  157 + return map;
  158 + }
  159 +
135 160 private List<UserTaskEfficiencyDO> buildCategorySummary(List<UserTaskEfficiencyDO> all, String statPeriod) {
136 161 Map<String, List<UserTaskEfficiencyDO>> catMap = new LinkedHashMap<>();
137 162 for (UserTaskEfficiencyDO e : all) {
... ... @@ -178,6 +203,19 @@ public class TaskEfficiencyCalculateJob implements JobHandler {
178 203 s.setEfficiencyRatio(ratioWeight > 0
179 204 ? weightedRatio.divide(BigDecimal.valueOf(ratioWeight), 4, RoundingMode.HALF_UP)
180 205 : BigDecimal.ONE);
  206 + // 加权计算 historyCompletionRate
  207 + BigDecimal weightedRate = BigDecimal.ZERO;
  208 + int rateWeightCnt = 0;
  209 + for (UserTaskEfficiencyDO e : group) {
  210 + if (e.getCompletedCount() > 0 && e.getHistoryCompletionRate() != null) {
  211 + weightedRate = weightedRate.add(
  212 + e.getHistoryCompletionRate().multiply(BigDecimal.valueOf(e.getCompletedCount())));
  213 + rateWeightCnt += e.getCompletedCount();
  214 + }
  215 + }
  216 + s.setHistoryCompletionRate(rateWeightCnt > 0
  217 + ? weightedRate.divide(BigDecimal.valueOf(rateWeightCnt), 4, RoundingMode.HALF_UP)
  218 + : BigDecimal.ZERO);
181 219 summaries.add(s);
182 220 }
183 221 return summaries;
... ...
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/homepage/HomepageSummaryServiceImpl.java
... ... @@ -429,6 +429,8 @@ public class HomepageSummaryServiceImpl implements HomepageSummaryService{
429 429  
430 430 @Override
431 431 public TaskDistanceSortResultVO queryTaskDetailsWithDistance(AppTaskDistanceSortReqVO req) {
  432 + Log.info("queryTaskDetailsWithDistance: " + JSON.toJSONString(req));
  433 +
432 434 // 1. 获取当前登录用户信息
433 435 Long userId = SecurityFrameworkUtils.getLoginUserId();
434 436 Long deptId = SecurityFrameworkUtils.getDeptId();
... ... @@ -456,9 +458,20 @@ public class HomepageSummaryServiceImpl implements HomepageSummaryService{
456 458 if (db == null) return -1;
457 459 return da.compareTo(db);
458 460 });
459   - result.setSortedTasks(sortedTasks);
460 461 result.setTeamProgress(teamProgress);
461 462 result.setTotalPendingTasks(sortedTasks.size());
  463 +
  464 + // 4.5 加载效率数据,设置个人历史完成率
  465 + Map<String, UserTaskEfficiencyDO> effMap = loadEfficiencyMap(userId);
  466 + for (TaskDistanceSortRespVO task : sortedTasks) {
  467 + UserTaskEfficiencyDO effDO = lookupEfficiency(effMap, task.getTaskType(), task.getTaskSubType());
  468 + if (effDO != null && effDO.getHistoryCompletionRate() != null) {
  469 + task.setHistoryCompletionRate(effDO.getHistoryCompletionRate());
  470 + }
  471 + }
  472 +
  473 + result.setSortedTasks(sortedTasks);
  474 +
462 475 int totalDist = 0;
463 476 int totalWalkMin = 0;
464 477 int totalTriMin = 0;
... ... @@ -506,6 +519,15 @@ public class HomepageSummaryServiceImpl implements HomepageSummaryService{
506 519 result.add(sortVo);
507 520 }
508 521 }
  522 + // 加载效率数据,设置个人历史完成率
  523 + Map<String, UserTaskEfficiencyDO> effMap = loadEfficiencyMap(userId);
  524 + for (TaskDistanceSortRespVO task : result) {
  525 + UserTaskEfficiencyDO effDO = lookupEfficiency(effMap, task.getTaskType(), task.getTaskSubType());
  526 + if (effDO != null && effDO.getHistoryCompletionRate() != null) {
  527 + task.setHistoryCompletionRate(effDO.getHistoryCompletionRate());
  528 + }
  529 + }
  530 + logTaskList("已办SQL原始记录", result);
509 531 Log.info("返回App参数: " + JSON.toJSONString(result));
510 532 return result;
511 533 }
... ... @@ -540,6 +562,7 @@ public class HomepageSummaryServiceImpl implements HomepageSummaryService{
540 562 LocalDateTime now = LocalDateTime.now();
541 563 List<TaskDistanceSortRespVO> allTasks = homepageSummaryMapper
542 564 .queryPendingTaskDetailsWithGps(roleIds, userId, deptId, now);
  565 + logTaskList("待办SQL原始记录(距离排序)", allTasks);
543 566  
544 567 // 分离有 GPS 和无 GPS 任务
545 568 List<TaskDistanceSortRespVO> tasksWithGps = new ArrayList<>();
... ... @@ -660,6 +683,7 @@ public class HomepageSummaryServiceImpl implements HomepageSummaryService{
660 683  
661 684 @Override
662 685 public TaskDistanceSortResultVO queryTaskDetailsWithSmartSort(AppTaskSmartSortReqVO req) {
  686 + Log.info("queryTaskDetailsWithSmartSort: " + JSON.toJSONString(req));
663 687 Long userId = SecurityFrameworkUtils.getLoginUserId();
664 688 Long deptId = SecurityFrameworkUtils.getDeptId();
665 689  
... ... @@ -669,17 +693,17 @@ public class HomepageSummaryServiceImpl implements HomepageSummaryService{
669 693 TeamProgressVO teamProgress = buildTeamProgress(userId, deptId);
670 694 TaskDistanceSortResultVO result = new TaskDistanceSortResultVO();
671 695 sortedTasks.sort((a, b) -> {
672   - Integer da = a.getDistance(), db = b.getDistance();
673   - if (da == null && db == null) return 0;
674   - if (da == null) return 1;
675   - if (db == null) return -1;
676   - return da.compareTo(db);
677   - });
678   - result.setSortedTasks(sortedTasks);
  696 + Integer da = a.getDistance(), db = b.getDistance();
  697 + if (da == null && db == null) return 0;
  698 + if (da == null) return 1;
  699 + if (db == null) return -1;
  700 + return da.compareTo(db);
  701 + });
679 702 result.setTeamProgress(teamProgress);
680 703 result.setTotalPendingTasks(sortedTasks.size());
  704 + result.setSortedTasks(sortedTasks);
681 705 Log.info("返回App参数: " + JSON.toJSONString(result));
682   - return result;
  706 + return result;
683 707 }
684 708  
685 709 List<Long> roleIds = roleApi.getRoleIdsByUserId(userId);
... ... @@ -706,13 +730,23 @@ public class HomepageSummaryServiceImpl implements HomepageSummaryService{
706 730 } catch (Exception e) {
707 731 Log.warn("读取智能排序配置失败", e);
708 732 }
  733 + Log.info("智能排序配置: distWeight=" + distWeight + ", effWeight=" + effWeight
  734 + + ", threshold=" + threshold + ", clamp=[" + clampMin + "," + clampMax + "]");
709 735  
710 736 // 2. 查询今日待办任务
711 737 List<TaskDistanceSortRespVO> allTasks = homepageSummaryMapper
712 738 .queryPendingTaskDetailsWithGps(roleIds, userId, deptId, LocalDateTime.now());
  739 + Log.info("待办任务总数: " + (allTasks != null ? allTasks.size() : 0) + ", userId=" + userId + ", deptId=" + deptId);
  740 + logTaskList("待办SQL原始记录(智能排序)", allTasks);
713 741  
714 742 // 3. 查询效率矩阵
715 743 Map<String, UserTaskEfficiencyDO> effMap = loadEfficiencyMap(userId);
  744 + Log.info("效率矩阵条目数: " + effMap.size());
  745 + if (!effMap.isEmpty()) {
  746 + effMap.forEach((k, v) -> Log.info(" eff: key=" + k + ", ratio=" + v.getEfficiencyRatio()
  747 + + ", userAvg=" + v.getAvgMinutes() + ", teamAvg=" + v.getTeamAvgMinutes()
  748 + + ", cnt=" + v.getCompletedCount()));
  749 + }
716 750  
717 751 // 4. 为每个任务打分
718 752 List<TaskDistanceSortRespVO> tasksWithGps = new ArrayList<>();
... ... @@ -728,6 +762,7 @@ public class HomepageSummaryServiceImpl implements HomepageSummaryService{
728 762 if (effDO != null) {
729 763 task.setUserAvgMinutes(effDO.getAvgMinutes());
730 764 task.setTeamAvgMinutes(effDO.getTeamAvgMinutes());
  765 + task.setHistoryCompletionRate(effDO.getHistoryCompletionRate());
731 766 }
732 767  
733 768 if (task.getTaskLat() != null && task.getTaskLon() != null) {
... ... @@ -737,10 +772,20 @@ public class HomepageSummaryServiceImpl implements HomepageSummaryService{
737 772 double distScore = Math.max(0, 1 - dist / threshold);
738 773 task.setDistanceScore(Math.round(distScore * 100.0) / 100.0);
739 774 task.setCompositeScore(Math.round((distWeight * distScore + effWeight * effScore) * 100.0) / 100.0);
  775 + Log.info(" score: " + task.getTaskName() + " | dist=" + (int)dist + "m"
  776 + + " | distScore=" + task.getDistanceScore()
  777 + + " | effScore=" + task.getEfficiencyScore()
  778 + + " | eff%=" + task.getEfficiencyPercent()
  779 + + " | composite=" + task.getCompositeScore()
  780 + + " | type=" + task.getTaskType() + "/" + task.getTaskSubType());
740 781 tasksWithGps.add(task);
741 782 } else {
742 783 task.setDistanceScore(0.0);
743 784 task.setCompositeScore(Math.round((effWeight * effScore) * 100.0) / 100.0);
  785 + Log.info(" score(无GPS): " + task.getTaskName()
  786 + + " | effScore=" + task.getEfficiencyScore()
  787 + + " | eff%=" + task.getEfficiencyPercent()
  788 + + " | type=" + task.getTaskType() + "/" + task.getTaskSubType());
744 789 tasksWithoutGps.add(task);
745 790 }
746 791 }
... ... @@ -782,9 +827,10 @@ public class HomepageSummaryServiceImpl implements HomepageSummaryService{
782 827 if (db == null) return -1;
783 828 return da.compareTo(db);
784 829 });
785   - result.setSortedTasks(sortedTasks);
786 830 result.setTeamProgress(teamProgress);
787 831 result.setTotalPendingTasks(sortedTasks.size());
  832 + result.setSortedTasks(sortedTasks);
  833 +
788 834 int totalDist = 0;
789 835 for (TaskDistanceSortRespVO t : sortedTasks) {
790 836 if (t.getDistance() != null) totalDist += t.getDistance();
... ... @@ -833,4 +879,21 @@ public class HomepageSummaryServiceImpl implements HomepageSummaryService{
833 879 if (val < min) return min;
834 880 return val;
835 881 }
  882 +
  883 + private void logTaskList(String tag, List<TaskDistanceSortRespVO> list) {
  884 + if (list == null) {
  885 + Log.info(tag + ": null");
  886 + return;
  887 + }
  888 + Log.info(tag + ": 共" + list.size() + "条");
  889 + for (int i = 0; i < list.size(); i++) {
  890 + TaskDistanceSortRespVO t = list.get(i);
  891 + Log.info(tag + "[" + i + "] taskName=" + t.getTaskName()
  892 + + ", taskType=" + t.getTaskType()
  893 + + ", planNo=" + t.getPlanNo()
  894 + + ", batchNo=" + t.getBatchNo()
  895 + + ", distance=" + t.getDistance()
  896 + + ", lat=" + t.getTaskLat() + ", lon=" + t.getTaskLon());
  897 + }
  898 + }
836 899 }
... ...
urbanops-module-garden/src/main/resources/mapper/UserTaskEfficiencyMapper.xml
... ... @@ -71,4 +71,15 @@
71 71 GROUP BY t.ASSIGNEE_, u.dept_id, m.order_type
72 72 </select>
73 73  
  74 + <!-- 汇总用户 6 个月历史任务总量 -->
  75 + <select id="statHistoryTotalCount" resultType="java.util.Map">
  76 + SELECT user_id,
  77 + SUM(insp_total + mt_total + wo_total) AS history_total,
  78 + SUM(insp_completed + mt_completed + wo_completed) AS history_completed
  79 + FROM garden_task_statistics
  80 + WHERE busi_date >= #{beginDate}
  81 + AND deleted = 0
  82 + GROUP BY user_id
  83 + </select>
  84 +
74 85 </mapper>
... ...
urbanops-module-garden/src/main/resources/mapper/homepage/HomepageSummaryMapper.xml
... ... @@ -647,7 +647,7 @@
647 647 <foreach collection='roleIds' item='roleId' open='(' close=')' separator=','>
648 648 #{roleId}
649 649 </foreach>
650   - AND NOT EXISTS (SELECT 1 FROM garden_inspection_plan_commit ic WHERE ic.batch_no = a.batch_no AND ic.user_id = #{userId})
  650 +<!-- AND NOT EXISTS (SELECT 1 FROM garden_inspection_plan_commit ic WHERE ic.batch_no = a.batch_no AND ic.user_id = #{userId})-->
651 651 AND r.starting_latitude IS NOT NULL AND r.starting_latitude != ''
652 652  
653 653 UNION ALL
... ... @@ -677,7 +677,7 @@
677 677 <foreach collection='roleIds' item='roleId' open='(' close=')' separator=','>
678 678 #{roleId}
679 679 </foreach>
680   - AND NOT EXISTS (SELECT 1 FROM garden_maintain_plan_commit mc WHERE mc.batch_no = a.batch_no AND mc.user_id = #{userId})
  680 +<!-- AND NOT EXISTS (SELECT 1 FROM garden_maintain_plan_commit mc WHERE mc.batch_no = a.batch_no AND mc.user_id = #{userId})-->
681 681 AND r.starting_latitude IS NOT NULL AND r.starting_latitude != ''
682 682 ) t
683 683 </select>
... ...
urbanops-module-system/src/main/java/com/zteits/urbanops/module/system/enums/DictTypeConstants.java
... ... @@ -36,4 +36,6 @@ public interface DictTypeConstants {
36 36  
37 37 String TASK_SORT_WEIGHT_CONFIG = "task_sort_weight_config"; // 智能排序权重配置
38 38  
  39 + String COMPLETION_RATE_CONFIG = "completion_rate_config"; // 个人历史完成率配置
  40 +
39 41 }
... ...
urbanops-server/src/main/resources/application.yaml
... ... @@ -3,7 +3,7 @@ spring:
3 3 name: urbanops-server
4 4  
5 5 profiles:
6   - active: dev
  6 + active: prod
7 7  
8 8  
9 9 main:
... ...