xuhy
2026-02-26 834c554dbb81d0ddcf2b9f32be01bd7d0c1745c0
Merge remote-tracking branch 'origin/master'
2个文件已添加
23个文件已修改
483 ■■■■■ 已修改文件
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/config/ThreadPoolConfig.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/TokenController.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpAppUserCouponController.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/mapper/XpAppUserCouponMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/IXpAppUserCouponService.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysLoginService.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpAppUserCouponServiceImpl.java 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/resources/mapper/account/XpAppUserCouponMapper.xml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/resources/mapper/account/XpQualificationAuditMapper.xml 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/operation/AppLoginCodeDTO.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/operation/AppLoginPasswordDTO.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/account/XpAppUserCoupon.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/account/XpOperationsUser.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpCruisePlan.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpCruisePlanPoint.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpCruisePlanVehicle.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpVehicleOperationsController.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpCouponController.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpCruisePlanController.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/query/CruisePlanQuery.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/query/UserFeedBackQuery.java 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpCruisePlanService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpCruisePlanServiceImpl.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/config/ThreadPoolConfig.java
New file
@@ -0,0 +1,39 @@
package com.xiaopeng.account.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration
@EnableAsync
public class ThreadPoolConfig {
    @Bean(name = "couponSendExecutor")
    public ThreadPoolTaskExecutor couponSendExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 核心参数
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(20);  // 增大队列容量
        executor.setKeepAliveSeconds(60);
        // 线程名称前缀
        executor.setThreadNamePrefix("sendCoupon-");
        // 拒绝策略:调用者线程执行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 等待所有任务结束后再关闭线程池
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setAwaitTerminationSeconds(60);
        // 初始化
        executor.initialize();
        return executor;
    }
}
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/TokenController.java
@@ -78,7 +78,7 @@
    @PostMapping("base/v1/operationPasswordLogin")
    public R<?> operationPasswordLogin(@RequestBody AppLoginPasswordDTO appLoginPasswordDTO, HttpServletRequest request) {
        // 用户登录
        LoginOperationUser userInfo = sysLoginService.operationPasswordLogin(appLoginPasswordDTO.getPhoneNumber(), appLoginPasswordDTO.getPassword(), request);
        LoginOperationUser userInfo = sysLoginService.operationPasswordLogin(appLoginPasswordDTO.getPhoneNumber(), appLoginPasswordDTO.getPassword(), appLoginPasswordDTO.getDeviceType(), request);
        HashMap<String, Object> map = new HashMap<>();
        map.put("token", tokenService.createOperationUserToken(userInfo));
//        List<SysRole> roles = userInfo.getXpOperationsUser().getRoles();
@@ -94,7 +94,7 @@
    @PostMapping("base/v1/verificationCodeLogin")
    public R<?> verificationCodeLogin(@RequestBody AppLoginCodeDTO appLoginCodeDTO, HttpServletRequest request) {
        // 用户登录
        LoginOperationUser userInfo = sysLoginService.verificationCodeLogin(appLoginCodeDTO.getPhoneNumber(), appLoginCodeDTO.getVerificationCode(), request);
        LoginOperationUser userInfo = sysLoginService.verificationCodeLogin(appLoginCodeDTO.getPhoneNumber(), appLoginCodeDTO.getVerificationCode(),appLoginCodeDTO.getDeviceType(), request);
        HashMap<String, Object> map = new HashMap<>();
        map.put("token", tokenService.createOperationUserToken(userInfo));
//        List<SysRole> roles = userInfo.getXpOperationsUser().getRoles();
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpAppUserCouponController.java
@@ -59,19 +59,19 @@
    @PostMapping("/inner/appUserCoupon/getUserCoupon")
    public R<UserCouponVo> getUserCoupon(@RequestBody GetUserCouponDto dto) {
        String phone ="18888888888";
        if(dto.getUserId()>1){
            UserResourcesDto baseUserByUid = userResourcesClient.getBaseUserByUid(dto.getUserId().toString());
            if(baseUserByUid!=null){
                Object data = baseUserByUid.getData();
                phone = JSONObject.parseObject(data.toString()).getString("mobile");
            }
        }
//        String phone ="18888888888";
//        if(dto.getUserId()>1){
//            UserResourcesDto baseUserByUid = userResourcesClient.getBaseUserByUid(dto.getUserId().toString());
//            if(baseUserByUid!=null){
//                Object data = baseUserByUid.getData();
//                phone = JSONObject.parseObject(data.toString()).getString("mobile");
//            }
//        }
        UserCouponVo userCouponVo = new UserCouponVo();
        // 获取用户所有优惠券
        List<XpAppUserCoupon> couponList = xpAppUserCouponService.list(new LambdaQueryWrapper<XpAppUserCoupon>().eq(XpAppUserCoupon::getStatus, 1).eq(XpAppUserCoupon::getPhone,phone).apply("FIND_IN_SET({0}, open_city_id)", dto.getOpenCityId()) );
        List<XpAppUserCoupon> couponList = xpAppUserCouponService.list(new LambdaQueryWrapper<XpAppUserCoupon>().eq(XpAppUserCoupon::getStatus, 1).eq(XpAppUserCoupon::getAppUserId,dto.getUserId()).apply("FIND_IN_SET({0}, open_city_id)", dto.getOpenCityId()) );
        if(couponList.isEmpty()){
            return R.ok(userCouponVo);
        }
@@ -116,14 +116,14 @@
    public R<XpAppUserCouponVo> list(@RequestBody XpUserCouponListQuery query, HttpServletRequest request) {
        // uid已通过拦截器otp校验,可以直接使用
        String uid = request.getHeader("XP-Uid");
        String phone ="18888888888";
        UserResourcesDto baseUserByUid = userResourcesClient.getBaseUserByUid(uid);
        if(baseUserByUid!=null){
            Object data = baseUserByUid.getData();
            phone = JSONObject.parseObject(data.toString()).getString("mobile");
        }
//        String phone ="18888888888";
//        UserResourcesDto baseUserByUid = userResourcesClient.getBaseUserByUid(uid);
//        if(baseUserByUid!=null){
//            Object data = baseUserByUid.getData();
//            phone = JSONObject.parseObject(data.toString()).getString("mobile");
//        }
        XpAppUserCouponVo vo = xpAppUserCouponService.userCouponList(query, phone);
        XpAppUserCouponVo vo = xpAppUserCouponService.userCouponList(query, uid);
        return R.ok(vo);
    }
@@ -154,14 +154,14 @@
    public R<XpAppUserCouponListVo> detail(@PathVariable("couponId") Long couponId, HttpServletRequest request) {
        // uid已通过拦截器otp校验,可以直接使用
        String uid = request.getHeader("XP-Uid");
        String phone ="18888888888";
        UserResourcesDto baseUserByUid = userResourcesClient.getBaseUserByUid(uid);
        if(baseUserByUid!=null){
            Object data = baseUserByUid.getData();
            phone = JSONObject.parseObject(data.toString()).getString("mobile");
        }
//        String phone ="18888888888";
//        UserResourcesDto baseUserByUid = userResourcesClient.getBaseUserByUid(uid);
//        if(baseUserByUid!=null){
//            Object data = baseUserByUid.getData();
//            phone = JSONObject.parseObject(data.toString()).getString("mobile");
//        }
        XpAppUserCoupon coupon = xpAppUserCouponService.getById(couponId);
        if(phone.equals(coupon.getPhone())){
        if(uid.equals(coupon.getAppUserId().toString())){
            XpAppUserCouponListVo vo = new XpAppUserCouponListVo();
            vo.setCouponId(coupon.getId().toString());
            vo.setTitle(coupon.getCouponName());
@@ -189,13 +189,13 @@
    public R<XpAppUserCouponTotalVo> total(HttpServletRequest request) {
        // uid已通过拦截器otp校验,可以直接使用
        String uid = request.getHeader("XP-Uid");
        String phone ="18888888888";
        UserResourcesDto baseUserByUid = userResourcesClient.getBaseUserByUid(uid);
        if(baseUserByUid!=null){
            Object data = baseUserByUid.getData();
            phone = JSONObject.parseObject(data.toString()).getString("mobile");
        }
        XpAppUserCouponTotalVo vo = xpAppUserCouponService.userCouponTotal(phone);
//        String phone ="18888888888";
//        UserResourcesDto baseUserByUid = userResourcesClient.getBaseUserByUid(uid);
//        if(baseUserByUid!=null){
//            Object data = baseUserByUid.getData();
//            phone = JSONObject.parseObject(data.toString()).getString("mobile");
//        }
        XpAppUserCouponTotalVo vo = xpAppUserCouponService.userCouponTotal(uid);
        return R.ok(vo);
    }
@@ -206,7 +206,8 @@
    @PostMapping("/api/v1/appUserCoupon/send")
    @ApiOperation(value = "发放优惠券", tags = {"管理后台-发放优惠券"})
    public R<String> send(@RequestBody SendCouponDto dto) {
        return xpAppUserCouponService.send(dto);
        xpAppUserCouponService.send(dto);
        return R.ok();
    }
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/mapper/XpAppUserCouponMapper.java
@@ -17,6 +17,6 @@
 */
public interface XpAppUserCouponMapper extends BaseMapper<XpAppUserCoupon> {
    Page<XpAppUserCouponListVo> userCouponList(@Param("page") Page<XpAppUserCouponListVo> page, @Param("query") XpUserCouponListQuery query, @Param("phone") String phone);
    Page<XpAppUserCouponListVo> userCouponList(@Param("page") Page<XpAppUserCouponListVo> page, @Param("query") XpUserCouponListQuery query, @Param("uid") String uid);
}
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/IXpAppUserCouponService.java
@@ -1,17 +1,16 @@
package com.xiaopeng.account.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.account.model.dto.ReceiveCouponDto;
import com.xiaopeng.account.model.dto.SendCouponDto;
import com.xiaopeng.account.model.query.XpUserCouponListQuery;
import com.xiaopeng.account.model.vo.XpAppUserCouponListVo;
import com.xiaopeng.account.model.vo.XpAppUserCouponTotalVo;
import com.xiaopeng.account.model.vo.XpAppUserCouponVo;
import com.xiaopeng.api.model.account.XpAppUserCoupon;
import com.xiaopeng.common.core.domain.R;
import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
 * <p>
@@ -26,17 +25,17 @@
    /**
     * 获取用户优惠券列表
     * @param query
     * @param phone
     * @param uid
     * @return
     */
    XpAppUserCouponVo userCouponList(XpUserCouponListQuery query, String phone);
    XpAppUserCouponVo userCouponList(XpUserCouponListQuery query, String uid);
    /**+
     * 获取用户优惠券数量total
     * @param phone
     * @param uid
     * @return
     */
    XpAppUserCouponTotalVo userCouponTotal(String phone);
    XpAppUserCouponTotalVo userCouponTotal(String uid);
    /**
     * 领取优惠券
@@ -56,9 +55,10 @@
    /**
     * 发送优惠券
     *
     * @param dto
     * @return
     */
    R<String> send(SendCouponDto dto);
   R<String> send(SendCouponDto dto);
}
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysLoginService.java
@@ -7,7 +7,6 @@
import com.xiaopeng.api.dto.operation.UpdatePasswordDTO;
import com.xiaopeng.api.model.account.SysUser;
import com.xiaopeng.api.model.account.XpOperationsUser;
import com.xiaopeng.api.model.operation.SysMenu;
import com.xiaopeng.api.vo.account.LoginOperationUser;
import com.xiaopeng.api.vo.account.LoginUser;
import com.xiaopeng.common.core.constant.CacheConstants;
@@ -26,9 +25,7 @@
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
 * 登录校验方法
@@ -150,7 +147,7 @@
        recordLogService.recordLogininfor(request, sysUser.getId().intValue(), username, Constants.LOGIN_SUCCESS_STATUS, "注册成功");
    }
    public LoginOperationUser operationPasswordLogin(String phoneNumber, String password, HttpServletRequest request) {
    public LoginOperationUser operationPasswordLogin(String phoneNumber, String password, Integer deviceType, HttpServletRequest request) {
        LoginOperationUser loginOperationUser = new LoginOperationUser();
        phoneNumber = phoneNumber.trim();
        // 查询运维用户信息
@@ -171,9 +168,12 @@
        }
        passwordService.validateOperationsUser(operationsUser, password, request);
        loginOperationUser.setXpOperationsUser(operationsUser);
        //更新用户登录设备类型
        operationsUser.setDeviceType(deviceType);
        operationsUserService.updateById(operationsUser);
        return loginOperationUser;
    }
    public LoginOperationUser verificationCodeLogin(String phoneNumber, String code, HttpServletRequest request) {
    public LoginOperationUser verificationCodeLogin(String phoneNumber, String code, Integer deviceType, HttpServletRequest request) {
        LoginOperationUser loginOperationUser = new LoginOperationUser();
        phoneNumber = phoneNumber.trim();
        // 查询运维用户信息
@@ -201,6 +201,9 @@
        }
        loginOperationUser.setXpOperationsUser(operationsUser);
        //更新用户登录设备类型
        operationsUser.setDeviceType(deviceType);
        operationsUserService.updateById(operationsUser);
        return loginOperationUser;
    }
    public Boolean verificationCodeUpdate(UpdatePasswordDTO updatePasswordDTO, HttpServletRequest request) {
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpAppUserCouponServiceImpl.java
@@ -14,20 +14,22 @@
import com.xiaopeng.account.model.vo.XpAppUserCouponVo;
import com.xiaopeng.account.service.IXpAppUserCouponService;
import com.xiaopeng.account.util.holiday.HolidayUtil;
import com.xiaopeng.api.dto.account.UserResourcesDto;
import com.xiaopeng.api.feignClient.account.UserResourcesClient;
import com.xiaopeng.api.feignClient.operation.XpCouponClient;
import com.xiaopeng.api.feignClient.operation.XpWhiteListClient;
import com.xiaopeng.api.model.account.XpAppUserCoupon;
import com.xiaopeng.api.model.operation.XpCoupon;
import com.xiaopeng.api.model.operation.XpWhitelist;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
 * <p>
@@ -49,16 +51,20 @@
    @Autowired
    private XpWhiteListClient xpWhiteListClient;
    @Autowired
    private UserResourcesClient userResourcesClient;
    /**
     * 获取用户优惠券列表
     * @param query
     * @param phone
     * @param uid
     * @return
     */
    @Override
    public XpAppUserCouponVo userCouponList(XpUserCouponListQuery query, String phone) {
    public XpAppUserCouponVo userCouponList(XpUserCouponListQuery query, String uid) {
        Page<XpAppUserCouponListVo> page = new Page<>(query.getPageNum(), query.getPageSize());
        Page<XpAppUserCouponListVo> list = baseMapper.userCouponList(page, query, phone);
        Page<XpAppUserCouponListVo> list = baseMapper.userCouponList(page, query, uid);
        XpAppUserCouponVo vo = new XpAppUserCouponVo();
        vo.setTotal((int) page.getTotal());
        vo.setList(list.getRecords());
@@ -67,12 +73,12 @@
    /**
     * 获取用户优惠券数量total
     * @param phone
     * @param uid
     * @return
     */
    @Override
    public XpAppUserCouponTotalVo userCouponTotal(String phone) {
        List<XpAppUserCoupon> couponList = baseMapper.selectList(new LambdaQueryWrapper<XpAppUserCoupon>().eq(XpAppUserCoupon::getPhone, phone));
    public XpAppUserCouponTotalVo userCouponTotal(String uid) {
        List<XpAppUserCoupon> couponList = baseMapper.selectList(new LambdaQueryWrapper<XpAppUserCoupon>().eq(XpAppUserCoupon::getAppUserId, uid));
        XpAppUserCouponTotalVo vo = new XpAppUserCouponTotalVo();
        vo.setAvailableNum((int) couponList.stream().filter(e -> e.getStatus() == 1).count());
        vo.setUsedNum((int) couponList.stream().filter(e -> e.getStatus() == 2).count());
@@ -89,7 +95,7 @@
    @Override
    public boolean receive(ReceiveCouponDto dto, String uid) {
        XpAppUserCoupon coupon = baseMapper.selectById(dto.getCouponId());
        if(coupon.getAppUserId().toString().equals(uid)){
        if (coupon.getAppUserId().toString().equals(uid)) {
            coupon.setStatus(1);
            return updateById(coupon);
@@ -104,12 +110,12 @@
     */
    @Override
    public List<XpAppUserCoupon> timeRule(List<XpAppUserCoupon> couponList) {
       List<XpAppUserCoupon> xpAppUserCoupons = new ArrayList<>();
        List<XpAppUserCoupon> xpAppUserCoupons = new ArrayList<>();
        for (XpAppUserCoupon coupon : couponList) {
            String timeJson = coupon.getTimeJson();
            Boolean inOperationTime = isInOperationTime(timeJson);
            if(inOperationTime){
            if (inOperationTime) {
                xpAppUserCoupons.add(coupon);
            }
        }
@@ -119,38 +125,61 @@
    /**
     * 发送优惠券
     *
     * @param dto
     * @return
     */
    @Override
    @Async("couponSendExecutor")
    public R<String> send(SendCouponDto dto) {
        R<XpCoupon> coupon = xpCouponClient.getCouponById(dto.getCouponId());
        if(coupon!=null){
        if (coupon != null) {
            XpCoupon xpCoupon = coupon.getData();
            if(dto.getPhone()==null){
            if (dto.getPhone() == null) {
                // 全部发放
                R<List<String>> allWhiteList = xpWhiteListClient.getAllWhiteList();
                if(allWhiteList!=null){
                if (allWhiteList != null) {
                    List<String> phoneList = allWhiteList.getData();
                    dto.setPhone(phoneList);
                }
            }
            for (String phone : dto.getPhone()) {
                XpAppUserCoupon xpAppUserCoupon = new XpAppUserCoupon();
                xpAppUserCoupon.setFullMoney(xpCoupon.getConditionalAmount());
                xpAppUserCoupon.setMoney(xpCoupon.getAmount());
                xpAppUserCoupon.setCouponId(dto.getCouponId());
                UserResourcesDto userByMobile = userResourcesClient.getUserByMobile(phone);
                if (userByMobile != null) {
                    Long uid = JSONObject.parseObject(userByMobile.getData().toString()).getLong("uid");
                    XpAppUserCoupon xpAppUserCoupon = new XpAppUserCoupon();
                    xpAppUserCoupon.setFullMoney(xpCoupon.getConditionalAmount());
                    xpAppUserCoupon.setMoney(xpCoupon.getAmount());
                    xpAppUserCoupon.setCouponId(dto.getCouponId());
                    xpAppUserCoupon.setAppUserId(uid);
                    xpAppUserCoupon.setExpirationTime(LocalDateTime.now().plusDays(100));
                    xpAppUserCoupon.setStatus(0);
                    xpAppUserCoupon.setCouponType(xpCoupon.getCouponType());
                    xpAppUserCoupon.setPhone(phone);
                xpAppUserCoupon.setExpirationTime(LocalDateTime.now().plusDays(100));
                xpAppUserCoupon.setStatus(0);
                xpAppUserCoupon.setCouponType(xpCoupon.getCouponType());
                xpAppUserCoupon.setPhone( phone);
                    xpAppUserCoupon.setCouponName(xpCoupon.getCouponName());
                    xpAppUserCoupon.setOpenCityId("0");
                    xpAppUserCoupon.setTimeJson("[{\"time\": [\"00:00-23:59\"], \"type\": 3, \"typeStr\": 0}]");
                    baseMapper.insert(xpAppUserCoupon);
                }else {
                    Long uid = 1l;
                    XpAppUserCoupon xpAppUserCoupon = new XpAppUserCoupon();
                    xpAppUserCoupon.setFullMoney(xpCoupon.getConditionalAmount());
                    xpAppUserCoupon.setMoney(xpCoupon.getAmount());
                    xpAppUserCoupon.setCouponId(dto.getCouponId());
                    xpAppUserCoupon.setAppUserId(uid);
                    xpAppUserCoupon.setExpirationTime(LocalDateTime.now().plusDays(100));
                    xpAppUserCoupon.setStatus(0);
                    xpAppUserCoupon.setCouponType(xpCoupon.getCouponType());
                    xpAppUserCoupon.setPhone(phone);
                xpAppUserCoupon.setCouponName(xpCoupon.getCouponName());
                xpAppUserCoupon.setOpenCityId("0");
                xpAppUserCoupon.setTimeJson("[{\"time\": [\"00:00-23:59\"], \"type\": 3, \"typeStr\": 0}]");
                baseMapper.insert(xpAppUserCoupon);
                    xpAppUserCoupon.setCouponName(xpCoupon.getCouponName());
                    xpAppUserCoupon.setOpenCityId("0");
                    xpAppUserCoupon.setTimeJson("[{\"time\": [\"00:00-23:59\"], \"type\": 3, \"typeStr\": 0}]");
                    baseMapper.insert(xpAppUserCoupon);
                }
            }
        }
@@ -167,9 +196,9 @@
        JSONArray jsonArray = JSONArray.parseArray(timeJson);
        Integer holidayToday = holidayUtil.isHolidayToday();
        for (Object o : jsonArray) {
            JSONObject jsonObject =JSONObject.parseObject(o.toString());
            JSONObject jsonObject = JSONObject.parseObject(o.toString());
            String type = jsonObject.getString("type");
            if(type.equals(holidayToday.toString())){
            if (type.equals(holidayToday.toString())) {
                JSONArray time = jsonObject.getJSONArray("time");
                // 判断当前时间 是否在time时间段中
                for (Object object : time) {
@@ -177,17 +206,17 @@
                    String startTime = timeArray[0];
                    String endTime = timeArray[1];
                    boolean currentTimeInRange = DateUtils.isCurrentTimeInRange(startTime, endTime);
                    if(currentTimeInRange){
                    if (currentTimeInRange) {
                        return true;
                    }
                }
            }else if(type.equals("3")){
            } else if (type.equals("3")) {
                // 判断是什么类型 0每天  1-7 想起
                String typeStr = jsonObject.getString("typeStr");
                // 查看今天周几
                Integer week = DateUtils.getWeek();
                // 包含每天 或者  包含当天
                if(typeStr.contains("0") || typeStr.contains(week.toString())){
                if (typeStr.contains("0") || typeStr.contains(week.toString())) {
                    JSONArray time = jsonObject.getJSONArray("time");
                    // 判断当前时间 是否在time时间段中
                    for (Object object : time) {
@@ -195,7 +224,7 @@
                        String startTime = timeArray[0];
                        String endTime = timeArray[1];
                        boolean currentTimeInRange = DateUtils.isCurrentTimeInRange(startTime, endTime);
                        if(currentTimeInRange){
                        if (currentTimeInRange) {
                            return true;
                        }
                    }
xp-robotaxi-account-boot/src/main/resources/mapper/account/XpAppUserCouponMapper.xml
@@ -23,7 +23,7 @@
        else status
        end as `status`
        FROM xp_app_user_coupon
        WHERE phone = #{phone}
        WHERE app_user_id = #{uid}
        ) as t
        where 1=1
        <if test="query.status != null">
xp-robotaxi-account-boot/src/main/resources/mapper/account/XpQualificationAuditMapper.xml
@@ -13,7 +13,7 @@
        xou.nick_name, xou.phone_number, xou.avatar,xou.unique_number
        from xp_qualification_audit xqa
        left join xp_operations_user xou on xqa.operations_user_id = xou.id
        left join xp_operations_role xor on xou.id = xor.operations_user_id
        left join xp_operations_role xore on xou.id = xore.operations_user_id
        where xqa.is_deleted = 0
            <if test="query.nickName != null and query.nickName != ''">
                and xou.nick_name like concat('%',#{query.nickName},'%')
@@ -22,7 +22,7 @@
                and xou.phone_number like concat('%',#{query.phoneNumber},'%')
            </if>
            <if test="query.roleId != null">
                and xor.role_id = #{query.roleId}
                and xore.role_id = #{query.roleId}
            </if>
            <if test="query.auditStatus != null">
                and xqa.audit_status = #{query.auditStatus}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/operation/AppLoginCodeDTO.java
@@ -13,4 +13,7 @@
    private String phoneNumber;
    @ApiModelProperty(value = "验证码")
    private String verificationCode;
    @ApiModelProperty(value = "设备类型 1-Android 2-iOS")
    private Integer deviceType;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/operation/AppLoginPasswordDTO.java
@@ -13,4 +13,7 @@
    private String phoneNumber;
    @ApiModelProperty(value = "密码")
    private String password;
    @ApiModelProperty(value = "设备类型 1-Android 2-iOS")
    private Integer deviceType;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/account/XpAppUserCoupon.java
@@ -31,7 +31,7 @@
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.NONE)
    @TableId(value = "id", type = IdType.ASSIGN_ID)
    private Long id;
    @ApiModelProperty(value = "满减金额")
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/account/XpOperationsUser.java
@@ -69,4 +69,6 @@
    @ApiModelProperty(value = "培训结业证")
    private String trainingGraduationCertificate;
    @ApiModelProperty(value = "设备类型 1-Android 2-iOS")
    private Integer deviceType;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpCruisePlan.java
@@ -1,10 +1,13 @@
package com.xiaopeng.api.model.operation;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDateTime;
import java.io.Serializable;
import com.xiaopeng.common.core.web.domain.BaseModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -24,7 +27,7 @@
@Accessors(chain = true)
@TableName("xp_cruise_plan")
@ApiModel(value="XpCruisePlan对象", description="巡游计划")
public class XpCruisePlan implements Serializable {
public class XpCruisePlan extends BaseModel {
    private static final long serialVersionUID = 1L;
@@ -35,20 +38,13 @@
    @ApiModelProperty(value = "计划名称")
    private String planName;
    @ApiModelProperty(value = "是否删除 0=未删除 1=已删除")
    private Boolean isDeleted;
    @ApiModelProperty(value = "关联点位数")
    @TableField(exist = false)
    private Integer pointNum;
    @ApiModelProperty(value = "创建时间")
    private LocalDateTime createTime;
    @ApiModelProperty(value = "修改时间")
    private LocalDateTime updateTime;
    @ApiModelProperty(value = "创建人")
    private String createBy;
    @ApiModelProperty(value = "修改人")
    private String updateBy;
    @ApiModelProperty(value = "关联车辆数")
    @TableField(exist = false)
    private Integer vehicleNum;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpCruisePlanPoint.java
@@ -5,6 +5,8 @@
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDateTime;
import java.io.Serializable;
import com.xiaopeng.common.core.web.domain.BaseModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -38,23 +40,10 @@
    @ApiModelProperty(value = "点位ID")
    private Integer pointId;
    @ApiModelProperty(value = " 排序")
    @ApiModelProperty(value = "排序")
    private Integer sortOrder;
    @ApiModelProperty(value = "是否删除 0=未删除 1=已删除")
    private Boolean isDeleted;
    @ApiModelProperty(value = "创建时间")
    private LocalDateTime createTime;
    @ApiModelProperty(value = "修改时间")
    private LocalDateTime updateTime;
    @ApiModelProperty(value = "创建人")
    private String createBy;
    @ApiModelProperty(value = "修改人")
    private String updateBy;
    @ApiModelProperty(value = "是否停车 0-否 1-是")
    private Integer stopFlag;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpCruisePlanVehicle.java
@@ -5,6 +5,8 @@
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import com.xiaopeng.common.core.web.domain.BaseModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -28,30 +30,10 @@
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "主键")
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    @ApiModelProperty(value = "巡游计划ID")
    private Long cruisePlanId;
    @ApiModelProperty(value = "车辆ID")
    private Long vehicleId;
    @ApiModelProperty(value = "是否删除 0=未删除 1=已删除")
    private Boolean isDeleted;
    @ApiModelProperty(value = "创建时间")
    private LocalDateTime createTime;
    @ApiModelProperty(value = "修改时间")
    private LocalDateTime updateTime;
    @ApiModelProperty(value = "创建人")
    private String createBy;
    @ApiModelProperty(value = "修改人")
    private String updateBy;
}
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
@@ -426,7 +426,7 @@
            LonLatDto origin = new LonLatDto();
            if (orderId.contains("XU")) {
                orderType = OrderType.CRUISE_ORDER;
                // todo 下发巡游单的导航数据
                R<XpCruiseOrder> cruiseOrder = xpCruiseOrderClient.getCruiseOrder(orderId);
                XpCruiseOrder xpCruiseOrder = cruiseOrder.getData();
@@ -534,7 +534,7 @@
        Long vehicleId = null;
        String orderType = "";
        if (orderId.contains("XU")) {
            // todo 下发巡游单的导航数据
            orderType = OrderType.CRUISE_ORDER;
            //巡游单
            if (orderPhase.equals(OrderPhase.ROUTE_TO_CRUISE)) {
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpVehicleOperationsController.java
@@ -75,7 +75,13 @@
        // 发车
        if(dto.getDepartureStatus()==1){
            // 找车辆的任务  生成巡游单子 下发命令 TODO
            // 找车辆的任务  生成巡游单子 下发命令 TODO v
        }else if(dto.getDepartureStatus()==3){
            // 收车 关闭当前巡游单子 生成新的返程单子  找到收车站点
            xpCruiseOrderClient.updateCruiseOrder(xpVehicle.getVehicleVin());
@@ -90,10 +96,13 @@
            xpCruiseOrder.setOrderType(2);
            xpCruiseOrder.setStartLon(x);
            xpCruiseOrder.setStartLat(y);
            // TODO 找到收车站点
            // TODO v 找到收车站点
            xpCruiseOrder.setStatus(1);
            xpCruiseOrderClient.addCruiseOrder(xpCruiseOrder);
            // 下发命令
            orderMissionClient.pushOrder(new PushOrderDto( xpCruiseOrder.getVehicleVin(),xpCruiseOrder.getId(),null));
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpCouponController.java
@@ -8,12 +8,9 @@
import com.xiaopeng.operation.service.IXpCouponService;
import com.xiaopeng.operation.vo.XpBannerListVo;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@@ -25,7 +22,7 @@
 * @author mitao
 * @since 2026-02-03
 */
@Controller
@RestController
@RequestMapping("")
public class XpCouponController {
@@ -47,7 +44,7 @@
     * 优惠券列表
     */
    @PostMapping("/v1/api/xp-coupon/list")
    @ApiOperation(value = "优惠券列表",tags = {"管理后台-优惠券列表"},response = XpCoupon.class)
    @ApiOperation(value = "优惠券列表",tags = {"管理后台-优惠券"},response = XpCoupon.class)
    public R<Page<XpCoupon>> list(@RequestBody XpCouponListQuery query ){
        return R.ok(xpCouponService.getList(query));
    }
@@ -61,7 +58,7 @@
     * @return
     */
    @PostMapping("/v1/api/xp-coupon/add")
    @ApiOperation(value = "添加优惠券",tags = {"管理后台-添加优惠券"},response = XpCoupon.class)
    @ApiOperation(value = "添加优惠券",tags = {"管理后台-优惠券"},response = XpCoupon.class)
    public R<?> add(@RequestBody XpCoupon xpCoupon){
        xpCouponService.save(xpCoupon);
        return R.ok();
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpCruisePlanController.java
@@ -1,6 +1,16 @@
package com.xiaopeng.operation.controller;
import com.xiaopeng.api.model.operation.XpCruisePlan;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.operation.query.CruisePlanQuery;
import com.xiaopeng.operation.service.IXpCruisePlanService;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -14,6 +24,15 @@
 * @since 2026-02-26
 */
@RestController
@RequiredArgsConstructor(onConstructor_ = @Lazy)
public class XpCruisePlanController {
    private final IXpCruisePlanService xpCruisePlanService;
    @ApiOperation(value = "获取巡游计划分页列表", tags = {"管理后台-巡游计划"})
    @PostMapping(value = {"/api/v1/xp-cruise-plan/pageList"})
    public R<PageInfo<XpCruisePlan>> getPageList(@RequestBody CruisePlanQuery query){
        return R.ok(xpCruisePlanService.getPageList(query));
    }
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/query/CruisePlanQuery.java
New file
@@ -0,0 +1,22 @@
package com.xiaopeng.operation.query;
import com.xiaopeng.common.core.web.page.BasePage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * @author MiTao
 * @date 2026-02-26 14:32
 *
 */
@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "巡游计划分页查询对象")
public class CruisePlanQuery extends BasePage {
    @ApiModelProperty(value = "反馈内容")
    private String planName;
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/query/UserFeedBackQuery.java
@@ -15,6 +15,7 @@
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "用户反馈分页查询对象")
public class UserFeedBackQuery extends BasePage {
    @ApiModelProperty(value = "反馈内容")
    private String feedbackContent;
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpCruisePlanService.java
@@ -2,6 +2,8 @@
import com.xiaopeng.api.model.operation.XpCruisePlan;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.operation.query.CruisePlanQuery;
/**
 * <p>
@@ -13,4 +15,10 @@
 */
public interface IXpCruisePlanService extends IService<XpCruisePlan> {
    /**
     * 获取巡游计划分页列表
     * @param query
     * @return
     */
    PageInfo<XpCruisePlan> getPageList(CruisePlanQuery query);
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpCruisePlanServiceImpl.java
@@ -1,10 +1,26 @@
package com.xiaopeng.operation.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaopeng.api.model.operation.XpCruisePlan;
import com.xiaopeng.api.model.operation.XpCruisePlanPoint;
import com.xiaopeng.api.model.operation.XpCruisePlanVehicle;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.operation.mapper.XpCruisePlanMapper;
import com.xiaopeng.operation.query.CruisePlanQuery;
import com.xiaopeng.operation.service.IXpCruisePlanPointService;
import com.xiaopeng.operation.service.IXpCruisePlanService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaopeng.operation.service.IXpCruisePlanVehicleService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
 * <p>
@@ -15,6 +31,32 @@
 * @since 2026-02-26
 */
@Service
@RequiredArgsConstructor(onConstructor_ = @Lazy)
public class XpCruisePlanServiceImpl extends ServiceImpl<XpCruisePlanMapper, XpCruisePlan> implements IXpCruisePlanService {
    private final IXpCruisePlanPointService xpCruisePlanPointService;
    private final IXpCruisePlanVehicleService xpCruisePlanVehicleService;
    @Override
    public PageInfo<XpCruisePlan> getPageList(CruisePlanQuery query) {
        PageInfo<XpCruisePlan> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
        Page<XpCruisePlan> page = lambdaQuery()
                .like(StringUtils.isNotBlank(query.getPlanName()), XpCruisePlan::getPlanName, query.getPlanName())
                .orderByDesc(XpCruisePlan::getCreateTime)
                .page(pageInfo);
        //收集巡游计划ID
        List<Long> planIds = page.getRecords().stream().map(XpCruisePlan::getId).collect(Collectors.toList());
        // 批量查询巡游计划点位和车辆信息,并组装到巡游计划对象中
        Map<Long, List<XpCruisePlanPoint>> pointMap = CollUtil.isNotEmpty(planIds) ? xpCruisePlanPointService.lambdaQuery().in(XpCruisePlanPoint::getCruisePlanId, planIds)
                .list().stream().collect(Collectors.groupingBy(XpCruisePlanPoint::getCruisePlanId)) : Collections.emptyMap();
        Map<Long, List<XpCruisePlanVehicle>> vehicleMap = CollUtil.isNotEmpty(planIds) ? xpCruisePlanVehicleService.lambdaQuery().in(XpCruisePlanVehicle::getCruisePlanId, planIds)
                .list().stream().collect(Collectors.groupingBy(XpCruisePlanVehicle::getCruisePlanId)) : Collections.emptyMap();
        page.getRecords().forEach(plan -> {
            plan.setPointNum(pointMap.get(plan.getId()).size());
            plan.setVehicleNum(vehicleMap.get(plan.getId()).size());
        });
        pageInfo.setRecords(page.getRecords());
        return pageInfo;
    }
}
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -4,7 +4,7 @@
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -12,6 +12,7 @@
import com.google.common.collect.ImmutableMap;
import com.xiaopeng.api.dto.account.GetUserCouponDto;
import com.xiaopeng.api.dto.account.UseUserCouponDto;
import com.xiaopeng.api.dto.account.UserResourcesDto;
import com.xiaopeng.api.dto.automaticPilot.PushOrderDto;
import com.xiaopeng.api.dto.operation.LonLatDto;
import com.xiaopeng.api.dto.order.GetOrderNumDto;
@@ -23,6 +24,7 @@
import com.xiaopeng.api.dto.statistics.OrderStatisticsDTO;
import com.xiaopeng.api.dto.statistics.StatisticsQueryDTO;
import com.xiaopeng.api.dto.vehicleConvoy.BaseVehicleUserDto;
import com.xiaopeng.api.feignClient.account.UserResourcesClient;
import com.xiaopeng.api.feignClient.account.XpAppUserClient;
import com.xiaopeng.api.feignClient.account.XpAppUserCouponClient;
import com.xiaopeng.api.feignClient.automaticPilot.OrderMissionClient;
@@ -43,6 +45,7 @@
import com.xiaopeng.api.model.vehicleConvoy.XpFleet;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.api.vo.OrderType;
import com.xiaopeng.api.vo.account.GetUserListByUidsVo;
import com.xiaopeng.api.vo.account.UserCouponVo;
import com.xiaopeng.api.vo.automaticPilot.proto.down.cloudOrderOperation.OrderOperationType;
import com.xiaopeng.api.vo.operation.RouteVo;
@@ -50,6 +53,7 @@
import com.xiaopeng.api.vo.vehicleConvoy.AddTaxiPassengerVo;
import com.xiaopeng.api.vo.vehicleConvoy.CancelTaxiPassengerVo;
import com.xiaopeng.common.core.constant.CacheConstants;
import com.xiaopeng.common.core.constant.HttpStatus;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.enums.OrderStatusEnum;
import com.xiaopeng.common.core.enums.PushMessageTypeEnum;
@@ -122,7 +126,7 @@
@RequiredArgsConstructor(onConstructor_ = @Lazy)
public class XpOrderServiceImpl extends ServiceImpl<XpOrderMapper, XpOrder> implements IXpOrderService {
    private final XpAppUserClient xpAppUserClient;
    private final UserResourcesClient userResourcesClient;
    private final XpPointClient xpPointClient;
    private final XpVehicleClient xpVehicleClient;
    private final XpAppUserCouponClient xpAppUserCouponClient;
@@ -212,13 +216,13 @@
        }
        // 4. 批量查询关联数据
        Map<Long, XpAppUser> userMap = batchGetUsers(userIds);
        JSONObject jsonObject = batchGetUsers(userIds);
        Map<Long, XpVehicle> vehicleMap = batchGetVehicles(vehicleIds);
        Map<Long, XpFleet> fleetMap = batchGetFleets(fleetIds);
        // 5. 组装 VO
        List<XpOrderPageVO> voList = pageResult.getRecords().stream()
                .map(order -> convertToPageVO(order, userMap, vehicleMap, fleetMap))
                .map(order -> convertToPageVO(order, jsonObject, vehicleMap, fleetMap))
                .collect(Collectors.toList());
        // 6. 返回分页结果
@@ -241,11 +245,11 @@
        // 3. 获取用户信息
        if (Objects.nonNull(order.getAppUserId())) {
            Map<Long, XpAppUser> userMap = batchGetUsers(Collections.singleton(order.getAppUserId()));
            XpAppUser user = userMap.get(order.getAppUserId());
            if (Objects.nonNull(user)) {
                vo.setNickName(user.getNickName());
                vo.setPhoneNumber(user.getPhoneNumber());
            JSONObject jsonObject = batchGetUsers(Collections.singleton(order.getAppUserId()));
            JSONObject userInfo = jsonObject.getJSONObject(order.getAppUserId().toString());
            if (Objects.nonNull(userInfo)) {
                vo.setNickName(userInfo.getString("nickName"));
                vo.setPhoneNumber(userInfo.getString("mobile"));
            }
        }
@@ -320,13 +324,13 @@
        }
        // 4. 批量查询关联数据
        Map<Long, XpAppUser> userMap = batchGetUsers(userIds);
        JSONObject jsonObject = batchGetUsers(userIds);
        Map<Long, XpVehicle> vehicleMap = batchGetVehicles(vehicleIds);
        Map<Long, XpFleet> fleetMap = batchGetFleets(fleetIds);
        // 5. 组装 VO
        return orderList.stream()
                .map(order -> convertToPageVO(order, userMap, vehicleMap, fleetMap))
                .map(order -> convertToPageVO(order, jsonObject, vehicleMap, fleetMap))
                .collect(Collectors.toList());
    }
@@ -355,20 +359,22 @@
    /**
     * 批量获取用户信息
     */
    private Map<Long, XpAppUser> batchGetUsers(Set<Long> userIds) {
    private JSONObject batchGetUsers(Set<Long> userIds) {
        if (CollectionUtils.isEmpty(userIds)) {
            return new HashMap<>();
            return new JSONObject();
        }
        try {
            R<List<XpAppUser>> result = xpAppUserClient.listByIds(new ArrayList<>(userIds));
            if (Objects.nonNull(result) && Objects.nonNull(result.getData())) {
                return result.getData().stream()
                        .collect(Collectors.toMap(XpAppUser::getId, Function.identity(), (a, b) -> a));
            GetUserListByUidsVo getUserListByUidsVo = new GetUserListByUidsVo();
            getUserListByUidsVo.setUids(new ArrayList<>(userIds));
            getUserListByUidsVo.setGetPreCarOwner(Boolean.TRUE);
            UserResourcesDto userListByUids = userResourcesClient.getUserListByUids(getUserListByUidsVo);
            if (userListByUids.getCode().equals(HttpStatus.SUCCESS)) {
                return JSONObject.parseObject(userListByUids.getData().toString());
            }
        } catch (Exception e) {
            log.error("批量获取用户信息失败: {}", e.getMessage());
        }
        return new HashMap<>();
        return new JSONObject();
    }
    /**
@@ -452,7 +458,7 @@
     * 转换为分页列表 VO
     */
    private XpOrderPageVO convertToPageVO(XpOrder order,
                                          Map<Long, XpAppUser> userMap,
                                          JSONObject jsonObject,
                                          Map<Long, XpVehicle> vehicleMap,
                                          Map<Long, XpFleet> fleetMap) {
        XpOrderPageVO vo = new XpOrderPageVO();
@@ -467,10 +473,10 @@
        vo.setStatus(order.getStatus());
        // 用户信息
        if (Objects.nonNull(order.getAppUserId()) && userMap.containsKey(order.getAppUserId())) {
            XpAppUser user = userMap.get(order.getAppUserId());
            vo.setNickName(user.getNickName());
            vo.setPhoneNumber(user.getPhoneNumber());
        if (Objects.nonNull(order.getAppUserId()) && jsonObject.containsKey(order.getAppUserId().toString())) {
            JSONObject userInfo = jsonObject.getJSONObject(order.getAppUserId().toString());
            vo.setNickName(userInfo.getString("nickName"));
            vo.setPhoneNumber(userInfo.getString("mobile"));
        }
        // 车辆信息