Commit f7fcb204d96745b842137441373d15cabeafc87a

Authored by 王彪总
1 parent 1606feb1

feat(garden): 新增任务距离排序和智能排序功能

- 实现任务按距离排序和班组进度统计功能
- 添加任务智能排序(距离+个人效率加权)功能
- 新增GPS距离计算工具类和相关数据传输对象
- 添加出行速度配置和智能排序权重配置字典类型
- 实现用户任务效率预计算定时任务
- 优化API签名切面注解使用方式
- 添加微信公众号开放平台回调接口免登录配置
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/job/TaskEfficiencyCalculateJob.java
@@ -6,6 +6,7 @@ import com.zteits.urbanops.module.garden.dal.mysql.UserTaskEfficiencyMapper; @@ -6,6 +6,7 @@ import com.zteits.urbanops.module.garden.dal.mysql.UserTaskEfficiencyMapper;
6 import jakarta.annotation.Resource; 6 import jakarta.annotation.Resource;
7 import lombok.extern.slf4j.Slf4j; 7 import lombok.extern.slf4j.Slf4j;
8 import org.springframework.stereotype.Component; 8 import org.springframework.stereotype.Component;
  9 +import org.springframework.transaction.annotation.Transactional;
9 10
10 import java.math.BigDecimal; 11 import java.math.BigDecimal;
11 import java.math.RoundingMode; 12 import java.math.RoundingMode;
@@ -28,6 +29,7 @@ public class TaskEfficiencyCalculateJob implements JobHandler { @@ -28,6 +29,7 @@ public class TaskEfficiencyCalculateJob implements JobHandler {
28 private UserTaskEfficiencyMapper userTaskEfficiencyMapper; 29 private UserTaskEfficiencyMapper userTaskEfficiencyMapper;
29 30
30 @Override 31 @Override
  32 + @Transactional(rollbackFor = Exception.class)
31 public String execute(String param) { 33 public String execute(String param) {
32 String statPeriod = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM")); 34 String statPeriod = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM"));
33 log.info("TaskEfficiencyCalculateJob start, statPeriod={}", statPeriod); 35 log.info("TaskEfficiencyCalculateJob start, statPeriod={}", statPeriod);
@@ -67,8 +69,8 @@ public class TaskEfficiencyCalculateJob implements JobHandler { @@ -67,8 +69,8 @@ public class TaskEfficiencyCalculateJob implements JobHandler {
67 e.setUpdater("job"); 69 e.setUpdater("job");
68 e.setCreateTime(now); 70 e.setCreateTime(now);
69 e.setUpdateTime(now); 71 e.setUpdateTime(now);
70 - userTaskEfficiencyMapper.insert(e);  
71 } 72 }
  73 + userTaskEfficiencyMapper.insertBatch(all);
72 74
73 log.info("TaskEfficiencyCalculateJob done, total={}", all.size()); 75 log.info("TaskEfficiencyCalculateJob done, total={}", all.size());
74 return "success, total=" + all.size(); 76 return "success, total=" + all.size();
@@ -155,8 +157,27 @@ public class TaskEfficiencyCalculateJob implements JobHandler { @@ -155,8 +157,27 @@ public class TaskEfficiencyCalculateJob implements JobHandler {
155 s.setAvgMinutes(totalCnt > 0 157 s.setAvgMinutes(totalCnt > 0
156 ? BigDecimal.valueOf(totalMin).divide(BigDecimal.valueOf(totalCnt), 2, RoundingMode.HALF_UP) 158 ? BigDecimal.valueOf(totalMin).divide(BigDecimal.valueOf(totalCnt), 2, RoundingMode.HALF_UP)
157 : BigDecimal.ZERO); 159 : BigDecimal.ZERO);
158 - s.setTeamAvgMinutes(group.get(0).getTeamAvgMinutes());  
159 - s.setEfficiencyRatio(calcRatio(s.getAvgMinutes(), s.getTeamAvgMinutes())); 160 + // 大类汇总:按 completed_count 加权计算 teamAvg 和 efficiencyRatio
  161 + long teamTotalMin = 0;
  162 + int teamTotalCnt = 0;
  163 + BigDecimal weightedRatio = BigDecimal.ZERO;
  164 + int ratioWeight = 0;
  165 + for (UserTaskEfficiencyDO e : group) {
  166 + if (e.getCompletedCount() > 0 && e.getEfficiencyRatio() != null) {
  167 + weightedRatio = weightedRatio.add(
  168 + e.getEfficiencyRatio().multiply(BigDecimal.valueOf(e.getCompletedCount())));
  169 + ratioWeight += e.getCompletedCount();
  170 + }
  171 + teamTotalMin += e.getTeamAvgMinutes() != null
  172 + ? e.getTeamAvgMinutes().multiply(BigDecimal.valueOf(e.getCompletedCount())).longValue() : 0;
  173 + teamTotalCnt += e.getCompletedCount() != null ? e.getCompletedCount() : 0;
  174 + }
  175 + s.setTeamAvgMinutes(teamTotalCnt > 0
  176 + ? BigDecimal.valueOf(teamTotalMin).divide(BigDecimal.valueOf(teamTotalCnt), 2, RoundingMode.HALF_UP)
  177 + : BigDecimal.ZERO);
  178 + s.setEfficiencyRatio(ratioWeight > 0
  179 + ? weightedRatio.divide(BigDecimal.valueOf(ratioWeight), 4, RoundingMode.HALF_UP)
  180 + : BigDecimal.ONE);
160 summaries.add(s); 181 summaries.add(s);
161 } 182 }
162 return summaries; 183 return summaries;
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/homepage/HomepageSummaryServiceImpl.java
@@ -599,6 +599,7 @@ public class HomepageSummaryServiceImpl implements HomepageSummaryService{ @@ -599,6 +599,7 @@ public class HomepageSummaryServiceImpl implements HomepageSummaryService{
599 int d = (int) Math.round(GpsDistanceUtil.haversineDistance(userLat, userLon, 599 int d = (int) Math.round(GpsDistanceUtil.haversineDistance(userLat, userLon,
600 t.getTaskLat().doubleValue(), t.getTaskLon().doubleValue())); 600 t.getTaskLat().doubleValue(), t.getTaskLon().doubleValue()));
601 t.setDistance(d); 601 t.setDistance(d);
  602 + t.setCumulativeDistance(null);
602 t.setEstimatedWalkingMinutes((int) Math.ceil(d / walkingSpeedMperMin)); 603 t.setEstimatedWalkingMinutes((int) Math.ceil(d / walkingSpeedMperMin));
603 t.setEstimatedTricycleMinutes((int) Math.ceil(d / tricycleSpeedMperMin)); 604 t.setEstimatedTricycleMinutes((int) Math.ceil(d / tricycleSpeedMperMin));
604 } 605 }
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/util/GpsDistanceUtil.java
@@ -26,6 +26,7 @@ public class GpsDistanceUtil { @@ -26,6 +26,7 @@ public class GpsDistanceUtil {
26 double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) 26 double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
27 + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) 27 + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2))
28 * Math.sin(dLon / 2) * Math.sin(dLon / 2); 28 * Math.sin(dLon / 2) * Math.sin(dLon / 2);
  29 + a = Math.min(1.0, a); // 防止浮点精度导致 a > 1 产生 NaN
29 double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); 30 double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
30 return EARTH_RADIUS_M * c; 31 return EARTH_RADIUS_M * c;
31 } 32 }