xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/maintenance/XpTask.java
@@ -12,9 +12,6 @@ import java.math.BigDecimal; import java.time.LocalDateTime; import java.math.BigDecimal; import java.time.LocalDateTime; /** * <p> * 任务管理 @@ -91,6 +88,9 @@ @ApiModelProperty(value = "是否已发送过期通知 0=未发送 1=已发送") private Integer expiredNoticeSent; @ApiModelProperty(value = "事故即将超时通知是否已发送 0=未发送 1=已发送") private Integer willTimeoutNoticeSent; @ApiModelProperty(value = "状态 0=待到达 1=待处理 2=已完成 3=已取消") private Integer status; xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/schedule/AccidentTaskNotificationSupport.java
New file @@ -0,0 +1,199 @@ package com.xiaopeng.maintenance.schedule; import com.alibaba.fastjson2.JSONObject; import com.xiaopeng.api.dto.pushMessage.AliPushMessageDTO; import com.xiaopeng.api.feignClient.account.XpOperationUserClient; import com.xiaopeng.api.feignClient.pushMessage.XpAliPushMessageClient; import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient; import com.xiaopeng.api.model.account.XpOperationsUser; import com.xiaopeng.api.model.account.XpOperationsUserNotification; import com.xiaopeng.api.model.vehicleConvoy.XpVehicle; import com.xiaopeng.common.core.constant.AliPushTypeConstant; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.core.enums.TaskTypeNotificationEnum; import com.xiaopeng.common.core.utils.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; /** * 事故任务通知支撑类 * * <p>用于事故任务相关定时通知的通用方法抽取。</p> * * @author mitao * @since 2026-03-14 */ @Component public class AccidentTaskNotificationSupport { private static final Logger log = LoggerFactory.getLogger(AccidentTaskNotificationSupport.class); @Autowired private XpOperationUserClient xpOperationUserClient; @Autowired private XpVehicleClient xpVehicleClient; @Autowired private XpAliPushMessageClient xpAliPushMessageClient; /** * 解析 handleUserId(逗号分隔) */ public Set<Long> parseUserIds(String handleUserId) { if (StringUtils.isBlank(handleUserId)) { return Collections.emptySet(); } String[] parts = handleUserId.split(","); Set<Long> userIds = new HashSet<>(); for (String part : parts) { if (StringUtils.isBlank(part)) { continue; } try { userIds.add(Long.valueOf(part.trim())); } catch (NumberFormatException e) { log.warn("任务接收人ID非法,handleUserId={}", handleUserId); } } return userIds; } /** * 获取运维人员信息 */ public Map<Long, XpOperationsUser> fetchOperationUsers(Set<Long> userIds) { if (CollectionUtils.isEmpty(userIds)) { return Collections.emptyMap(); } try { R<List<XpOperationsUser>> result = xpOperationUserClient.listByIds(new ArrayList<>(userIds)); if (result == null || CollectionUtils.isEmpty(result.getData())) { return Collections.emptyMap(); } return result.getData().stream() .filter(Objects::nonNull) .filter(u -> u.getId() != null) .collect(Collectors.toMap(XpOperationsUser::getId, u -> u, (a, b) -> a)); } catch (Exception e) { log.error("获取运维人员信息失败", e); return Collections.emptyMap(); } } /** * 批量获取车辆信息 */ public Map<Long, XpVehicle> fetchVehicles(Set<Long> vehicleIds) { if (CollectionUtils.isEmpty(vehicleIds)) { return Collections.emptyMap(); } try { R<List<XpVehicle>> result = xpVehicleClient.listByIds(new ArrayList<>(vehicleIds)); if (result == null || CollectionUtils.isEmpty(result.getData())) { return Collections.emptyMap(); } return result.getData().stream() .filter(Objects::nonNull) .filter(v -> v.getId() != null) .collect(Collectors.toMap(XpVehicle::getId, v -> v, (a, b) -> a)); } catch (Exception e) { log.error("获取车辆信息失败", e); return Collections.emptyMap(); } } /** * 构建推送 body JSON */ public String buildPushBodyJson(String content, Integer strategyCode, Long taskId) { Map<String, Object> param = new HashMap<>(); param.put("content", content); param.put("strategy", strategyCode); param.put("type", TaskTypeNotificationEnum.ACCIDENT_TASK.getCode()); param.put("id", taskId == null ? "0" : taskId.toString()); return JSONObject.toJSONString(param); } /** * 批量构建通知记录(包含 notificationExt) */ public List<XpOperationsUserNotification> buildNotifications(List<XpOperationsUser> users, Integer notificationType, String content, Long taskId, String bodyJson) { if (CollectionUtils.isEmpty(users)) { return Collections.emptyList(); } List<XpOperationsUserNotification> notifications = new ArrayList<>(); for (XpOperationsUser user : users) { if (user == null || user.getId() == null) { continue; } XpOperationsUserNotification notification = new XpOperationsUserNotification(); notification.setNotificationType(notificationType); notification.setNotificationContent(content); notification.setOperationsUserId(user.getId()); notification.setDataId(taskId == null ? 0L : taskId); notification.setReadStatus(0); notification.setNotificationExt(bodyJson); notifications.add(notification); } return notifications; } /** * 推送通知(按 deviceType 分组) */ public int pushToUsersByDeviceType(List<XpOperationsUser> users, String title, String bodyJson) { if (CollectionUtils.isEmpty(users)) { return 0; } Map<Integer, List<XpOperationsUser>> operationUserMap = users.stream() .filter(u -> u != null && u.getDeviceType() != null && StringUtils.isNotBlank(u.getPhoneNumber())) .collect(Collectors.groupingBy(XpOperationsUser::getDeviceType)); int pushCount = 0; for (Map.Entry<Integer, List<XpOperationsUser>> entry : operationUserMap.entrySet()) { List<XpOperationsUser> groupUsers = entry.getValue(); if (CollectionUtils.isEmpty(groupUsers)) { continue; } String account = groupUsers.stream() .map(XpOperationsUser::getPhoneNumber) .filter(StringUtils::isNotBlank) .collect(Collectors.joining(",")); if (StringUtils.isBlank(account)) { continue; } try { xpAliPushMessageClient.pushMessage(AliPushMessageDTO.builder() .body(bodyJson) .account(account) .title(title) .pushType(AliPushTypeConstant.MESSAGE) .deviceType(entry.getKey()) .build()); pushCount++; } catch (Exception e) { log.error("事故任务推送失败,deviceType={}", entry.getKey(), e); } } return pushCount; } } xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/schedule/AccidentTaskTimeoutCheckScheduleTask.java
New file @@ -0,0 +1,187 @@ package com.xiaopeng.maintenance.schedule; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.xiaopeng.api.feignClient.account.XpOperationUserNotificationClient; import com.xiaopeng.api.model.account.XpOperationsUser; import com.xiaopeng.api.model.account.XpOperationsUserNotification; import com.xiaopeng.api.model.maintenance.XpTask; import com.xiaopeng.api.model.vehicleConvoy.XpVehicle; import com.xiaopeng.api.vo.maintenance.TaskScheduleConstants; import com.xiaopeng.common.core.enums.NotificationTypeEnum; import com.xiaopeng.common.core.utils.StringUtils; import com.xiaopeng.maintenance.mapper.XpTaskMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; /** * 事故任务超时检查定时任务 * * <p>每分钟执行一次,判断事故任务是否超时并发送通知。</p> * * @author mitao * @since 2026-03-14 */ @Component public class AccidentTaskTimeoutCheckScheduleTask { private static final Logger log = LoggerFactory.getLogger(AccidentTaskTimeoutCheckScheduleTask.class); private static final String TASK_NAME = "事故任务超时检查定时任务"; private static final String PUSH_TITLE = "事故超时警示"; private static final String CONTENT_TEMPLATE = "车辆%s在%s发生的紧急事故已超时!"; @Autowired private XpTaskMapper taskMapper; @Autowired private XpOperationUserNotificationClient xpOperationUserNotificationClient; @Autowired private AccidentTaskNotificationSupport notificationSupport; /** * 每分钟执行一次 */ @Scheduled(cron = "0 * * * * ?") public void executeAccidentTaskTimeoutCheck() { log.info("========== 开始执行{} ==========", TASK_NAME); try { LocalDateTime now = LocalDateTime.now(); List<XpTask> tasks = queryTimeoutAccidentTasks(now); if (CollectionUtils.isEmpty(tasks)) { log.info("未找到超时事故任务,跳过执行"); return; } Set<Long> vehicleIds = tasks.stream() .map(XpTask::getVehicleId) .filter(Objects::nonNull) .collect(Collectors.toSet()); Map<Long, XpVehicle> vehicleMap = notificationSupport.fetchVehicles(vehicleIds); Set<Long> allUserIds = new HashSet<>(); for (XpTask task : tasks) { allUserIds.addAll(notificationSupport.parseUserIds(task.getHandleUserId())); } Map<Long, XpOperationsUser> userMap = notificationSupport.fetchOperationUsers(allUserIds); int notifiedTaskCount = 0; int notificationCount = 0; int pushCount = 0; List<XpOperationsUserNotification> allNotifications = new ArrayList<>(); for (XpTask task : tasks) { try { if (task == null || task.getId() == null) { continue; } Set<Long> userIds = notificationSupport.parseUserIds(task.getHandleUserId()); if (CollectionUtils.isEmpty(userIds)) { log.warn("事故任务ID={} 未配置有效处理人,跳过通知", task.getId()); continue; } int affectedRows = markTimeoutNoticeSent(task.getId(), now); if (affectedRows <= 0) { continue; } List<XpOperationsUser> users = userIds.stream() .map(userMap::get) .filter(Objects::nonNull) .collect(Collectors.toList()); if (CollectionUtils.isEmpty(users)) { log.warn("事故任务ID={} 未匹配到有效运维人员,跳过通知", task.getId()); continue; } String plateNumber = resolvePlateNumber(vehicleMap.get(task.getVehicleId())); String vehicleLocation = StringUtils.defaultString(task.getVehicleLocation()); String content = String.format(CONTENT_TEMPLATE, plateNumber, vehicleLocation); String bodyJson = notificationSupport.buildPushBodyJson( content, NotificationTypeEnum.ACCIDENT_TIMEOUT.getCode(), task.getId() ); allNotifications.addAll(notificationSupport.buildNotifications( users, NotificationTypeEnum.ACCIDENT_TIMEOUT.getCode(), content, task.getId(), bodyJson )); pushCount += notificationSupport.pushToUsersByDeviceType(users, PUSH_TITLE, bodyJson); notifiedTaskCount++; } catch (Exception e) { log.error("处理超时事故任务通知失败,任务ID={}", task == null ? null : task.getId(), e); } } if (!CollectionUtils.isEmpty(allNotifications)) { xpOperationUserNotificationClient.addNotificationBatch(allNotifications); notificationCount = allNotifications.size(); } log.info("========== {} 执行完成,任务数: {},通知记录数: {},推送次数: {} ==========", TASK_NAME, notifiedTaskCount, notificationCount, pushCount); } catch (Exception e) { log.error("{}执行失败", TASK_NAME, e); } } /** * 查询超时事故任务:endTime < now 且未发送超时通知 */ private List<XpTask> queryTimeoutAccidentTasks(LocalDateTime now) { return taskMapper.selectList(new LambdaQueryWrapper<XpTask>() .eq(XpTask::getTaskCategory, TaskScheduleConstants.TASK_CATEGORY_ACCIDENT) .in(XpTask::getStatus, TaskScheduleConstants.TASK_STATUS_PENDING_ARRIVE, TaskScheduleConstants.TASK_STATUS_PENDING) .isNotNull(XpTask::getEndTime) .lt(XpTask::getEndTime, now) .eq(XpTask::getExpiredNoticeSent, 0)); } /** * 原子更新(抢占式)标记超时通知已发送 */ private int markTimeoutNoticeSent(Long taskId, LocalDateTime now) { return taskMapper.update(null, new LambdaUpdateWrapper<XpTask>() .set(XpTask::getExpiredNoticeSent, 1) .eq(XpTask::getId, taskId) .eq(XpTask::getTaskCategory, TaskScheduleConstants.TASK_CATEGORY_ACCIDENT) .in(XpTask::getStatus, TaskScheduleConstants.TASK_STATUS_PENDING_ARRIVE, TaskScheduleConstants.TASK_STATUS_PENDING) .isNotNull(XpTask::getEndTime) .lt(XpTask::getEndTime, now) .eq(XpTask::getExpiredNoticeSent, 0)); } private String resolvePlateNumber(XpVehicle vehicle) { return vehicle == null ? "" : StringUtils.defaultString(vehicle.getPlateNumber()); } } xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/schedule/AccidentTaskWillTimeoutScheduleTask.java
New file @@ -0,0 +1,237 @@ package com.xiaopeng.maintenance.schedule; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.xiaopeng.api.feignClient.account.XpOperationUserNotificationClient; import com.xiaopeng.api.model.account.XpOperationsUser; import com.xiaopeng.api.model.account.XpOperationsUserNotification; import com.xiaopeng.api.model.maintenance.XpTask; import com.xiaopeng.api.model.maintenance.XpTaskRule; import com.xiaopeng.api.model.vehicleConvoy.XpVehicle; import com.xiaopeng.api.vo.maintenance.TaskScheduleConstants; import com.xiaopeng.common.core.enums.NotificationTypeEnum; import com.xiaopeng.common.core.utils.StringUtils; import com.xiaopeng.maintenance.mapper.XpTaskMapper; import com.xiaopeng.maintenance.mapper.XpTaskRuleMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import java.time.Duration; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; /** * 事故任务即将超时检查定时任务 * * <p>每分钟执行一次,判断事故任务在即将超时窗口内并发送通知。</p> * * @author mitao * @since 2026-03-14 */ @Component public class AccidentTaskWillTimeoutScheduleTask { private static final Logger log = LoggerFactory.getLogger(AccidentTaskWillTimeoutScheduleTask.class); private static final String TASK_NAME = "事故任务即将超时检查定时任务"; private static final String PUSH_TITLE = "事故即将超时提示"; private static final String CONTENT_TEMPLATE = "车辆%s在%s发生的紧急事故即将超时,剩余时间%s分钟,请及时到达现场!"; @Autowired private XpTaskMapper taskMapper; @Autowired private XpTaskRuleMapper taskRuleMapper; @Autowired private XpOperationUserNotificationClient xpOperationUserNotificationClient; @Autowired private AccidentTaskNotificationSupport notificationSupport; /** * 每分钟执行一次 */ @Scheduled(cron = "0 * * * * ?") public void executeAccidentTaskWillTimeoutCheck() { log.info("========== 开始执行{} ==========", TASK_NAME); try { XpTaskRule taskRule = getTaskRule(); Integer processingTimeLimit = taskRule == null ? null : taskRule.getProcessingTimeLimit(); Integer factorMinutes = calcWillTimeoutFactorMinutes(processingTimeLimit); if (factorMinutes == null || factorMinutes <= 0) { log.info("未配置有效处理时限或即将超时因子<=0,跳过执行,processingTimeLimit={}", processingTimeLimit); return; } LocalDateTime now = LocalDateTime.now(); LocalDateTime windowEnd = now.plusMinutes(factorMinutes); List<XpTask> tasks = queryWillTimeoutAccidentTasks(now, windowEnd); if (CollectionUtils.isEmpty(tasks)) { log.info("未找到即将超时事故任务,跳过执行"); return; } Set<Long> vehicleIds = tasks.stream() .map(XpTask::getVehicleId) .filter(Objects::nonNull) .collect(Collectors.toSet()); Map<Long, XpVehicle> vehicleMap = notificationSupport.fetchVehicles(vehicleIds); Set<Long> allUserIds = new HashSet<>(); for (XpTask task : tasks) { allUserIds.addAll(notificationSupport.parseUserIds(task.getHandleUserId())); } Map<Long, XpOperationsUser> userMap = notificationSupport.fetchOperationUsers(allUserIds); int notifiedTaskCount = 0; int notificationCount = 0; int pushCount = 0; List<XpOperationsUserNotification> allNotifications = new ArrayList<>(); for (XpTask task : tasks) { try { if (task == null || task.getId() == null) { continue; } Set<Long> userIds = notificationSupport.parseUserIds(task.getHandleUserId()); if (CollectionUtils.isEmpty(userIds)) { log.warn("事故任务ID={} 未配置有效处理人,跳过通知", task.getId()); continue; } int affectedRows = markWillTimeoutNoticeSent(task.getId(), now, windowEnd); if (affectedRows <= 0) { continue; } List<XpOperationsUser> users = userIds.stream() .map(userMap::get) .filter(Objects::nonNull) .collect(Collectors.toList()); if (CollectionUtils.isEmpty(users)) { log.warn("事故任务ID={} 未匹配到有效运维人员,跳过通知", task.getId()); continue; } String plateNumber = resolvePlateNumber(vehicleMap.get(task.getVehicleId())); String vehicleLocation = StringUtils.defaultString(task.getVehicleLocation()); String remainMinutes = String.valueOf(calcRemainMinutes(now, task.getEndTime())); String content = String.format(CONTENT_TEMPLATE, plateNumber, vehicleLocation, remainMinutes); String bodyJson = notificationSupport.buildPushBodyJson( content, NotificationTypeEnum.ACCIDENT_WILL_TIMEOUT.getCode(), task.getId() ); allNotifications.addAll(notificationSupport.buildNotifications( users, NotificationTypeEnum.ACCIDENT_WILL_TIMEOUT.getCode(), content, task.getId(), bodyJson )); pushCount += notificationSupport.pushToUsersByDeviceType(users, PUSH_TITLE, bodyJson); notifiedTaskCount++; } catch (Exception e) { log.error("处理即将超时事故任务通知失败,任务ID={}", task == null ? null : task.getId(), e); } } if (!CollectionUtils.isEmpty(allNotifications)) { xpOperationUserNotificationClient.addNotificationBatch(allNotifications); notificationCount = allNotifications.size(); } log.info("========== {} 执行完成,任务数: {},通知记录数: {},推送次数: {} ==========", TASK_NAME, notifiedTaskCount, notificationCount, pushCount); } catch (Exception e) { log.error("{}执行失败", TASK_NAME, e); } } /** * 获取任务规则配置 */ private XpTaskRule getTaskRule() { return taskRuleMapper.selectOne(new LambdaQueryWrapper<XpTaskRule>().last("limit 1")); } /** * 计算即将超时窗口(分钟):floor(processingTimeLimit * 0.2) */ private Integer calcWillTimeoutFactorMinutes(Integer processingTimeLimit) { if (processingTimeLimit == null || processingTimeLimit <= 0) { return 0; } return (int) Math.floor(processingTimeLimit * 0.2d); } /** * 查询即将超时事故任务:now < endTime <= windowEnd 且未发送即将超时通知 */ private List<XpTask> queryWillTimeoutAccidentTasks(LocalDateTime now, LocalDateTime windowEnd) { return taskMapper.selectList(new LambdaQueryWrapper<XpTask>() .eq(XpTask::getTaskCategory, TaskScheduleConstants.TASK_CATEGORY_ACCIDENT) .in(XpTask::getStatus, TaskScheduleConstants.TASK_STATUS_PENDING_ARRIVE, TaskScheduleConstants.TASK_STATUS_PENDING) .isNotNull(XpTask::getEndTime) .gt(XpTask::getEndTime, now) .le(XpTask::getEndTime, windowEnd) .eq(XpTask::getWillTimeoutNoticeSent, 0)); } /** * 原子更新(抢占式)标记即将超时通知已发送 */ private int markWillTimeoutNoticeSent(Long taskId, LocalDateTime now, LocalDateTime windowEnd) { return taskMapper.update(null, new LambdaUpdateWrapper<XpTask>() .set(XpTask::getWillTimeoutNoticeSent, 1) .eq(XpTask::getId, taskId) .eq(XpTask::getTaskCategory, TaskScheduleConstants.TASK_CATEGORY_ACCIDENT) .in(XpTask::getStatus, TaskScheduleConstants.TASK_STATUS_PENDING_ARRIVE, TaskScheduleConstants.TASK_STATUS_PENDING) .isNotNull(XpTask::getEndTime) .gt(XpTask::getEndTime, now) .le(XpTask::getEndTime, windowEnd) .eq(XpTask::getWillTimeoutNoticeSent, 0)); } /** * 计算剩余分钟数(向上取整,避免出现 0 分钟) */ private long calcRemainMinutes(LocalDateTime now, LocalDateTime endTime) { if (endTime == null) { return 0; } long seconds = Duration.between(now, endTime).getSeconds(); if (seconds <= 0) { return 0; } return (seconds + 59) / 60; } private String resolvePlateNumber(XpVehicle vehicle) { return vehicle == null ? "" : StringUtils.defaultString(vehicle.getPlateNumber()); } } xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpTaskServiceImpl.java
@@ -251,6 +251,8 @@ // 根据事故处理限时配置设置任务截止时间 LocalDateTime endTime = LocalDateTime.now().plusMinutes(taskRule.getProcessingTimeLimit()); xpTask.setEndTime(endTime); xpTask.setExpiredNoticeSent(0); xpTask.setWillTimeoutNoticeSent(0); this.save(xpTask); // 异步发送消息通知 @@ -1168,6 +1170,7 @@ task.setReportTime(LocalDateTime.now()); task.setEndTime(LocalDateTime.now().plusMinutes(taskRule.getProcessingTimeLimit())); task.setExpiredNoticeSent(0); task.setWillTimeoutNoticeSent(0); task.setStatus(TaskScheduleConstants.TASK_STATUS_PENDING_ARRIVE); task.setCreateBy("系统自动生成"); task.setCreateTime(LocalDateTime.now()); @@ -1217,6 +1220,8 @@ task.setVehicleLat(dto.getVehicleLat()); task.setReportUserId(reportUserId); task.setReportTime(LocalDateTime.now()); task.setExpiredNoticeSent(0); task.setWillTimeoutNoticeSent(0); saveTask.add(task); } this.saveBatch(saveTask); xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -216,13 +216,14 @@ if (userByMobile == null || userByMobile.getId() == null) { return buildEmptyOrderPage(query); } query.setUid(userByMobile.getId()); query.setUid(userByMobile.getUid()); } // 1. 构建查询条件 LambdaQueryWrapper<XpOrder> wrapper = buildQueryWrapper(query); if (CollUtil.isNotEmpty(vehicleIdsFilter)) { wrapper.in(XpOrder::getVehicleId, vehicleIdsFilter); } wrapper.eq(Objects.nonNull(query.getUid()), XpOrder::getAppUserId, query.getUid()); wrapper.orderByDesc(XpOrder::getCreateTime); // 2. 分页查询 @@ -366,8 +367,10 @@ if (userByMobile == null || userByMobile.getId() == null) { return new ArrayList<>(); } query.setUid(userByMobile.getId()); query.setUid(userByMobile.getUid()); } wrapper.eq(Objects.nonNull(query.getUid()), XpOrder::getAppUserId, query.getUid()); wrapper.orderByDesc(XpOrder::getCreateTime); // 2. 查询订单列表 List<XpOrder> orderList = this.list(wrapper);