From 329c96f7338097bdaf2ba304e3b51628f5edabb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E9=B9=8F?= <812968653@qq.com> Date: Sun, 13 Sep 2026 08:55:09 +0800 Subject: [PATCH] =?UTF-8?q?=E9=AA=91=E8=A1=8C=E6=A8=A1=E5=9D=97=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/rideplan/AppRideRecordController.java | 9 +++++ .../rideplan/vo/AppRideRecordStatsRespVO.java | 28 +++++++++++++++ .../rideplan/MemberRideRecordMapper.java | 10 ++++++ .../rideplan/MemberRideRecordService.java | 7 ++++ .../rideplan/MemberRideRecordServiceImpl.java | 35 +++++++++++++++++++ 5 files changed, 89 insertions(+) create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/rideplan/vo/AppRideRecordStatsRespVO.java diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/rideplan/AppRideRecordController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/rideplan/AppRideRecordController.java index eb63ca2..d0ffca4 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/rideplan/AppRideRecordController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/rideplan/AppRideRecordController.java @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.member.controller.app.rideplan.vo.AppRideRecordCreateReqVO; import cn.iocoder.yudao.module.member.controller.app.rideplan.vo.AppRideRecordPageReqVO; import cn.iocoder.yudao.module.member.controller.app.rideplan.vo.AppRideRecordRespVO; +import cn.iocoder.yudao.module.member.controller.app.rideplan.vo.AppRideRecordStatsRespVO; import cn.iocoder.yudao.module.member.service.rideplan.MemberRideRecordService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -78,6 +79,14 @@ public class AppRideRecordController { return success(rideRecordService.getCornerRank(roadName, cornerName)); } + @GetMapping("/stats") + @Operation(summary = "批量骑手战报统计(免登录)", description = "返回每个骑手的战报数/最佳压弯/总里程;最多 100 人") + @PermitAll + public CommonResult> stats( + @RequestParam("userIds") @Size(max = 100, message = "一次最多查询 100 个骑手") List userIds) { + return success(rideRecordService.getRideRecordStats(userIds)); + } + @PostMapping("/like") @Operation(summary = "点赞/取消点赞(需登录)", description = "幂等切换,返回操作后是否处于点赞状态") @Parameter(name = "recordId", description = "战报编号", required = true, example = "1") diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/rideplan/vo/AppRideRecordStatsRespVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/rideplan/vo/AppRideRecordStatsRespVO.java new file mode 100644 index 0000000..adfe44b --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/rideplan/vo/AppRideRecordStatsRespVO.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.member.controller.app.rideplan.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 用户 APP - 骑手战报统计 Response VO + * + * 供首页骑友列表 / 骑友主页展示「战报数 / 最佳压弯 / 总里程」骑行数据行, + * 批量接口避免列表逐人查询。 + */ +@Schema(description = "用户 APP - 骑手战报统计 Response VO") +@Data +public class AppRideRecordStatsRespVO { + + @Schema(description = "骑手用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + private Long userId; + + @Schema(description = "战报数量(正常状态)", requiredMode = Schema.RequiredMode.REQUIRED, example = "3") + private Long reportCount; + + @Schema(description = "最佳压弯角度(度)", requiredMode = Schema.RequiredMode.REQUIRED, example = "38.5") + private Double bestLean; + + @Schema(description = "总里程(公里)", requiredMode = Schema.RequiredMode.REQUIRED, example = "260.8") + private Double totalKm; + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/rideplan/MemberRideRecordMapper.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/rideplan/MemberRideRecordMapper.java index e55b224..6c29ff0 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/rideplan/MemberRideRecordMapper.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/rideplan/MemberRideRecordMapper.java @@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.member.controller.app.rideplan.vo.AppRideRecordPa import cn.iocoder.yudao.module.member.dal.dataobject.rideplan.MemberRideRecordDO; import org.apache.ibatis.annotations.Mapper; +import java.util.Collection; import java.util.List; @Mapper @@ -56,4 +57,13 @@ public interface MemberRideRecordMapper extends BaseMapperX .eq(MemberRideRecordDO::getStatus, status)); } + /** + * 批量查一批骑手的正常状态战报(用于列表/主页骑行数据统计) + */ + default List selectNormalByUserIds(Collection userIds) { + return selectList(new LambdaQueryWrapperX() + .in(MemberRideRecordDO::getUserId, userIds) + .eq(MemberRideRecordDO::getStatus, 0)); + } + } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/rideplan/MemberRideRecordService.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/rideplan/MemberRideRecordService.java index 6ee9a10..16bd844 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/rideplan/MemberRideRecordService.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/rideplan/MemberRideRecordService.java @@ -4,7 +4,9 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.member.controller.app.rideplan.vo.AppRideRecordCreateReqVO; import cn.iocoder.yudao.module.member.controller.app.rideplan.vo.AppRideRecordPageReqVO; import cn.iocoder.yudao.module.member.controller.app.rideplan.vo.AppRideRecordRespVO; +import cn.iocoder.yudao.module.member.controller.app.rideplan.vo.AppRideRecordStatsRespVO; +import java.util.Collection; import java.util.List; /** @@ -42,6 +44,11 @@ public interface MemberRideRecordService { */ boolean toggleLike(Long userId, Long recordId); + /** + * 批量骑手战报统计(免登录):战报数 / 最佳压弯 / 总里程,供列表与主页骑行数据行 + */ + List getRideRecordStats(Collection userIds); + /** * 举报战报(需登录),达到阈值自动下架 */ diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/rideplan/MemberRideRecordServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/rideplan/MemberRideRecordServiceImpl.java index 83f36a0..bfcf127 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/rideplan/MemberRideRecordServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/rideplan/MemberRideRecordServiceImpl.java @@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.member.controller.app.rideplan.vo.AppRideRecordCreateReqVO; import cn.iocoder.yudao.module.member.controller.app.rideplan.vo.AppRideRecordPageReqVO; import cn.iocoder.yudao.module.member.controller.app.rideplan.vo.AppRideRecordRespVO; +import cn.iocoder.yudao.module.member.controller.app.rideplan.vo.AppRideRecordStatsRespVO; import cn.iocoder.yudao.module.member.dal.dataobject.rideplan.MemberRideRecordDO; import cn.iocoder.yudao.module.member.dal.dataobject.rideplan.MemberRideRecordLikeDO; import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; @@ -18,6 +19,7 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.LinkedHashSet; @@ -143,6 +145,39 @@ public class MemberRideRecordServiceImpl implements MemberRideRecordService { return boards; } + @Override + public List getRideRecordStats(Collection userIds) { + if (userIds == null || userIds.isEmpty()) { + return Collections.emptyList(); + } + List records = rideRecordMapper.selectNormalByUserIds(userIds); + if (records.isEmpty()) { + return Collections.emptyList(); + } + Map> grouped = records.stream() + .collect(Collectors.groupingBy(MemberRideRecordDO::getUserId)); + List statsList = new ArrayList<>(grouped.size()); + for (Map.Entry> entry : grouped.entrySet()) { + java.math.BigDecimal best = java.math.BigDecimal.ZERO; + java.math.BigDecimal totalKm = java.math.BigDecimal.ZERO; + for (MemberRideRecordDO r : entry.getValue()) { + if (r.getMaxLean() != null && r.getMaxLean().compareTo(best) > 0) { + best = r.getMaxLean(); + } + if (r.getDistanceKm() != null) { + totalKm = totalKm.add(r.getDistanceKm()); + } + } + AppRideRecordStatsRespVO vo = new AppRideRecordStatsRespVO(); + vo.setUserId(entry.getKey()); + vo.setReportCount((long) entry.getValue().size()); + vo.setBestLean(best.doubleValue()); + vo.setTotalKm(totalKm.doubleValue()); + statsList.add(vo); + } + return statsList; + } + @Override @Transactional(rollbackFor = Exception.class) public boolean toggleLike(Long userId, Long recordId) {