无关风月
2026-02-28 cf7424ad3ffcb4720f93175ccbaa60c7c0b24c6c
Merge remote-tracking branch 'origin/master'
21个文件已修改
376 ■■■■■ 已修改文件
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpOperationsUserController.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/IXpOperationsUserService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpOperationsUserServiceImpl.java 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsUserMapper.xml 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpElectronicFence.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpRegion.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/order/XpOrder.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/account/XpOperationsUserWithRoleVO.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/order/XpHistoryEndPointsVo.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/order/XpHistoryStartPointsVo.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpClockInServiceImpl.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpRegionController.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/dto/XpTradingStrategyEditDTO.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderController.java 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/mapper/XpOrderMapper.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/resources/mapper/order/XpOrderMapper.xml 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpFleetServiceImpl.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleAnnualRecordServiceImpl.java 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpOperationsUserController.java
@@ -8,6 +8,7 @@
import com.xiaopeng.account.model.dto.XpOperationsUserDTO;
import com.xiaopeng.account.model.query.XpOperationsUserPageQuery;
import com.xiaopeng.account.model.query.XpOperationsUserQuery;
import com.xiaopeng.account.service.IXpOperationsRoleService;
import com.xiaopeng.account.service.IXpOperationsUserService;
import com.xiaopeng.api.dto.account.XpOperationsUserQueryDTO;
import com.xiaopeng.api.model.account.XpOperationsUser;
@@ -97,7 +98,7 @@
        if (CollectionUtils.isEmpty(ids)) {
            return R.ok(new ArrayList<>());
        }
        List<XpOperationsUserWithRoleVO> result = xpOperationsRoleMapper.selectUsersWithRoleByIds(ids);
        List<XpOperationsUserWithRoleVO> result = xpOperationsUserService.selectUsersWithRoleByIds(ids);
        return R.ok(result);
    }
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/IXpOperationsUserService.java
@@ -114,4 +114,11 @@
     * @param file
     */
    void importOperationsUser(MultipartFile file);
    /**
     * 根据ID列表批量查询用户及角色信息
     * @param ids
     * @return
     */
    List<XpOperationsUserWithRoleVO> selectUsersWithRoleByIds(List<Long> ids);
}
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpOperationsUserServiceImpl.java
@@ -1,6 +1,7 @@
package com.xiaopeng.account.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -14,6 +15,7 @@
import com.xiaopeng.account.model.dto.XpOperationsUserDTO;
import com.xiaopeng.account.model.query.XpOperationsUserPageQuery;
import com.xiaopeng.account.model.query.XpOperationsUserQuery;
import com.xiaopeng.account.service.ISysRoleService;
import com.xiaopeng.account.service.IXpOperationsRoleService;
import com.xiaopeng.account.service.IXpOperationsUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -43,6 +45,7 @@
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
@@ -75,6 +78,8 @@
    private IXpQualificationAuditService xpQualificationAuditService;
    @Autowired
    private SysRoleMapper sysRoleMapper;
    @Autowired
    private ISysRoleService iSysRoleService;
    @Override
    public List<XpOperationsUser> listByName(String nickName) {
@@ -159,19 +164,13 @@
        // 8. 查询角色信息
        List<XpOperationsUserWithRoleVO> userWithRoles = xpOperationsRoleMapper.selectUsersWithRoleByIds(Collections.singletonList(userId));
        if (!CollectionUtils.isEmpty(userWithRoles)) {
            List<XpOperationsUserProfileVO.RoleInfoVO> roleVOs = userWithRoles.stream()
                    .filter(r -> r.getRoleId() != null)
                    .map(r -> {
                        XpOperationsUserProfileVO.RoleInfoVO roleVO = new XpOperationsUserProfileVO.RoleInfoVO();
                        roleVO.setRoleId(r.getRoleId());
                        roleVO.setRoleName(r.getRoleName());
                        return roleVO;
                    })
        XpOperationsUserWithRoleVO operationsUserWithRoleVO = userWithRoles.get(0);
        if (CollUtil.isNotEmpty(operationsUserWithRoleVO.getRoles())) {
            List<XpOperationsUserProfileVO.RoleInfoVO> roleVOs = operationsUserWithRoleVO.getRoles().stream()
                    .map(item -> BeanUtil.copyProperties(item, XpOperationsUserProfileVO.RoleInfoVO.class))
                    .collect(Collectors.toList());
            vo.setRoles(roleVOs);
        }
        return vo;
    }
@@ -331,33 +330,6 @@
    @Override
    public void exportOperationsUser(XpOperationsUserQuery query, HttpServletResponse response) {
        List<ExportOperationsUserVo> list = this.baseMapper.exportOperationsUser(query);
        // 查询角色名称
        List<Long> operationsUserIds = list.stream().map(ExportOperationsUserVo::getId).collect(Collectors.toList());
        // 查询用户信息
        List<XpOperationsRole> xpOperationsRoles = xpOperationsRoleMapper.selectList(Wrappers.lambdaQuery(XpOperationsRole.class)
                .in(XpOperationsRole::getOperationsUserId, operationsUserIds));
        if(!CollectionUtils.isEmpty(xpOperationsRoles)){
            List<Long> roleIds = xpOperationsRoles.stream().map(XpOperationsRole::getRoleId).collect(Collectors.toList());
            // 查询列表关联的所有角色
            List<SysRole> sysRoles = sysRoleMapper.selectList(Wrappers.lambdaQuery(SysRole.class)
                    .in(SysRole::getId, roleIds));
            if(!CollectionUtils.isEmpty(sysRoles)){
                // 角色匹配账号id
                Map<Long, List<SysRole>> map = new HashMap<>();
                for (XpOperationsRole xpOperationsRole : xpOperationsRoles) {
                    List<SysRole> sysRoleList = sysRoles.stream().filter(sysRole -> sysRole.getId().equals(xpOperationsRole.getRoleId())).collect(Collectors.toList());
                    map.put(xpOperationsRole.getOperationsUserId(), sysRoleList);
                }
                // 角色名称匹配
                for (ExportOperationsUserVo xpOperationsUserVO : list) {
                    xpOperationsUserVO.setRoleName(map.get(xpOperationsUserVO.getId()).stream().map(SysRole::getRoleName).collect(Collectors.joining(";")));
                }
            }
        }
        ExcelUtil<ExportOperationsUserVo> util = new ExcelUtil<ExportOperationsUserVo>(ExportOperationsUserVo.class);
        util.exportExcel(response, list, "运维人员管理列表");
    }
@@ -403,6 +375,75 @@
    @Override
    public void exportTemplate(HttpServletResponse response) {
        ExcelUtil<ExportOperationsUserVo> util = new ExcelUtil<ExportOperationsUserVo>(ExportOperationsUserVo.class);
        util.exportExcel(response);
        util.importTemplateExcel(response, "运维人员管理列表");
    }
    @Override
    public List<XpOperationsUserWithRoleVO> selectUsersWithRoleByIds(List<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return Collections.emptyList();
        }
        List<XpOperationsUser> operationsUsers = listByIds(ids);
        if (CollUtil.isEmpty(operationsUsers)) {
            return Collections.emptyList();
        }
        // 查询用户角色信息
        List<Long> userIds = operationsUsers.stream()
                .map(XpOperationsUser::getId)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
        if (CollUtil.isEmpty(userIds)) {
            return Collections.emptyList();
        }
        // 获取关联角色ids
        List<XpOperationsRole> operationsRoles = xpOperationsRoleMapper.selectList(
                Wrappers.lambdaQuery(XpOperationsRole.class)
                        .in(XpOperationsRole::getOperationsUserId, userIds)
        );
        // userId -> 该用户关联的 roleId 列表
        Map<Long, List<Long>> userRoleIdsMap = CollUtil.isNotEmpty(operationsRoles)
                ? operationsRoles.stream()
                .filter(r -> r.getOperationsUserId() != null && r.getRoleId() != null)
                .collect(Collectors.groupingBy(
                        XpOperationsRole::getOperationsUserId,
                        Collectors.mapping(XpOperationsRole::getRoleId,
                                Collectors.collectingAndThen(Collectors.toList(),
                                        list -> list.stream().distinct().collect(Collectors.toList())))
                ))
                : Collections.emptyMap();
        // 一次性查出所有角色
        List<Long> roleIds = userRoleIdsMap.values().stream()
                .flatMap(Collection::stream)
                .distinct()
                .collect(Collectors.toList());
        Map<Long, SysRole> roleMap = CollUtil.isNotEmpty(roleIds)
                ? iSysRoleService.listByIds(roleIds).stream()
                .collect(Collectors.toMap(SysRole::getId, Function.identity(), (a, b) -> a))
                : Collections.emptyMap();
        // 组装 VO:每个用户对应角色列表
        return operationsUsers.stream().map(u -> {
            Long uid = u.getId();
            List<Long> roleIdList = userRoleIdsMap.getOrDefault(uid, Collections.emptyList());
            List<SysRole> roles = roleIdList.stream()
                    .map(roleMap::get)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());
            // 根据你的 VO 字段调整
            XpOperationsUserWithRoleVO vo = BeanUtil.copyProperties(u, XpOperationsUserWithRoleVO.class);
            vo.setRoles(roles);
            return vo;
        }).collect(Collectors.toList());
    }
}
xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsUserMapper.xml
@@ -52,26 +52,47 @@
    <select id="exportOperationsUser" resultType="com.xiaopeng.api.vo.account.ExportOperationsUserVo">
        SELECT xou.id, xou.nick_name, xou.unique_number, xou.avatar, xou.password, xou.phone_number, xou.remarks, xou.status,
        xou.id_card_front, xou.id_card_back, xou.driver_license, xou.certificate_of_no_criminal_record,
        xou.training_graduation_certificate, xou.is_deleted, xou.create_time, xou.update_time, xou.create_by
        from xp_operations_user xou
        left join xp_operations_role xor on xou.id = xor.operations_user_id
        <where>
            <if test="query.nickName != null and query.nickName != ''">
                and xou.nick_name like concat('%',#{query.nickName},'%')
            </if>
            <if test="query.phoneNumber != null and query.phoneNumber != ''">
                and xou.phone_number like concat('%',#{query.phoneNumber},'%')
            </if>
            <if test="query.roleId != null">
                and xor.role_id = #{query.roleId}
            </if>
            <if test="query.status != null">
                and xou.status = #{query.status}
            </if>
            AND xou.is_deleted = 0
        </where>
        SELECT
        xou.id,
        xou.nick_name,
        xou.unique_number,
        xou.avatar,
        xou.PASSWORD,
        xou.phone_number,
        xou.remarks,
        xou.STATUS,
        xou.id_card_front,
        xou.id_card_back,
        xou.driver_license,
        xou.certificate_of_no_criminal_record,
        xou.training_graduation_certificate,
        xou.is_deleted,
        xou.create_time,
        xou.update_time,
        xou.create_by,
        bb.roleName
        FROM
        xp_operations_user xou
        left join (
        select a.operations_user_id, GROUP_CONCAT(b.role_name SEPARATOR ';') as roleName from xp_operations_role a
        left join sys_role b on (a.role_id = b.id)
        group by a.operations_user_id
        ) bb on (xou.id = bb.operations_user_id)
        WHERE xou.is_deleted = 0
        <if test="query.nickName != null and query.nickName != ''">
            and xou.nick_name like concat('%',#{query.nickName},'%')
        </if>
        <if test="query.phoneNumber != null and query.phoneNumber != ''">
            and xou.phone_number like concat('%',#{query.phoneNumber},'%')
        </if>
        <if test="query.roleId != null">
            AND EXISTS (SELECT 1 FROM xp_operations_role xore
            WHERE xore.operations_user_id = xou.id
            AND xore.role_id = #{query.roleId})
        </if>
        <if test="query.status != null">
            and xou.status = #{query.status}
        </if>
        order by xou.create_time desc
    </select>
</mapper>
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpElectronicFence.java
@@ -4,13 +4,13 @@
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xiaopeng.common.core.web.domain.BaseModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.time.LocalDateTime;
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpRegion.java
@@ -64,5 +64,7 @@
    private Integer isOpen=0;
    private String china;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/order/XpOrder.java
@@ -223,4 +223,8 @@
    @ApiModelProperty(value = "队列名称")
    @TableField("queue_name")
    private String queueName;
    // 用于计数
    @TableField(exist = false)
    private Integer num;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/account/XpOperationsUserWithRoleVO.java
@@ -1,10 +1,13 @@
package com.xiaopeng.api.vo.account;
import com.xiaopeng.api.model.account.SysRole;
import com.xiaopeng.api.model.account.XpOperationsUser;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
/**
 * 运维人员及角色信息视图对象
@@ -16,9 +19,6 @@
@ApiModel("运维人员及角色信息视图对象")
public class XpOperationsUserWithRoleVO extends XpOperationsUser {
    @ApiModelProperty(value = "角色id")
    private Long roleId;
    @ApiModelProperty(value = "角色名称")
    private String roleName;
    @ApiModelProperty(value = "关联角色")
    private List<SysRole> roles;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/order/XpHistoryEndPointsVo.java
@@ -31,4 +31,7 @@
    private Long electronicAreaId;
    private Integer num;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/order/XpHistoryStartPointsVo.java
@@ -31,4 +31,6 @@
    private Long electronicAreaId;
    private Integer num;
}
xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java
@@ -203,10 +203,9 @@
        }
//        // 算距离
        R<RouteVo> distanceAndDuration = xpMapClient.getDistanceAndDuration(routeAndFareDto);
        if(distanceAndDuration.getCode()!=200){
        if (distanceAndDuration.getCode() != 200) {
            throw new ServiceException("未找到路径", I18nKeyConstant.PATH_NOT_FOUND);
        }
@@ -226,7 +225,7 @@
            xpPricingCardVo = xpPricingUtil.calculationFixedPrice(userId,
                    JSON.parseObject(xpPricing.getBasicPricingJson()),
                    JSON.parseArray(xpPricing.getStartingFareJson()),
                    routeVo.getDistance(), routeVo.getDuration(),0, 0.0, xpPricing.getIsDynamicPrice(), routeAndFareDto.getOpenCityId(), xpPricing.getDynamicPricingJson()
                    routeVo.getDistance(), routeVo.getDuration(), 0, 0.0, xpPricing.getIsDynamicPrice(), routeAndFareDto.getOpenCityId(), xpPricing.getDynamicPricingJson()
            );
        }
@@ -244,7 +243,7 @@
                () -> {
                    // 优惠券
                    return xpAppUserCouponClient.getUserCoupon(
                                new GetUserCouponDto(Long.valueOf(userId), finalXpPricingCardVo.getTotalPrice(),routeAndFareDto.getOpenCityId())
                            new GetUserCouponDto(Long.valueOf(userId), finalXpPricingCardVo.getTotalPrice(), routeAndFareDto.getOpenCityId())
//                            new GetUserCouponDto(Long.valueOf(userId), 1d, routeAndFareDto.getOpenCityId())
                    );
                },
@@ -289,7 +288,7 @@
        if (userCouponVo != null) {
            Double money = userCouponVo.getMoney();
            xpPricingCardVo.setCoupon(String.valueOf(userCouponVo.getMoney()));
            if(xpPricingCardVo.getTotalPrice()> money){
            if (xpPricingCardVo.getTotalPrice() > money) {
                xpPricingCardVo.setSystemDiscount(xpPricingCardVo.getTotalPrice() - money);
            }
@@ -557,7 +556,7 @@
            throw new ServiceException("订单生成失败", I18nKeyConstant.ORDER_CREATE_FAIL);
        }
        Long orderId = addOrderR.getData();
        xpOrder.setId(orderId);
        // 静默处理 不推单
        if (isSilent) {
            // todo 用于测试流程,正式联调需要删除此代码
@@ -684,11 +683,11 @@
     * 测试阶段用于自动完成小程序的整个流程数据状态流转
     * @param orderId
     */
    public void testOrder(Long orderId, Integer status){
    public void testOrder(Long orderId, Integer status) {
        XpOrder xpOrder = xpOrderClient.queryOrderById(orderId).getData();
        Long appUserId = xpOrder.getAppUserId();
        if(2 == status){
            if(xpOrder.getStatus() == 0){
        if (2 == status) {
            if (xpOrder.getStatus() == 0) {
                return;
            }
            xpOrder.setAppUserId(null);
@@ -697,10 +696,10 @@
            xpOrder.setFleetId(2L);
            xpOrderClient.updateOrder(xpOrder);
        }
        if(3 == status){
        if (3 == status) {
            //修改状态为接驾中
            xpOrder = xpOrderClient.queryOrderById(orderId).getData();
            if(xpOrder.getStatus() == 0){
            if (xpOrder.getStatus() == 0) {
                return;
            }
            xpOrder.setAppUserId(null);
@@ -739,7 +738,7 @@
            route.put("duration", routeVo.getDuration());
            route.put("routeID", routeVo.getRouteID());
            List<com.alibaba.fastjson2.JSONObject> collect = routeVo.getPolyline().stream().map(item->{
            List<com.alibaba.fastjson2.JSONObject> collect = routeVo.getPolyline().stream().map(item -> {
                com.alibaba.fastjson2.JSONObject point = new com.alibaba.fastjson2.JSONObject();
                point.put("latitude", item.getLatitude());
                point.put("longitude", item.getLongitude());
@@ -754,10 +753,10 @@
            messageDTO.setMessage(jsonObject.toJSONString());
            xpPushMessageClient.sendRoute(messageDTO);
        }
        if(4 == status){
        if (4 == status) {
            //司机到达起点
            xpOrder = xpOrderClient.queryOrderById(orderId).getData();
            if(xpOrder.getStatus() == 0){
            if (xpOrder.getStatus() == 0) {
                return;
            }
            xpOrder.setAppUserId(null);
@@ -772,10 +771,10 @@
            dto.setMessage("{\"type\":\"VEHICLE_LOCATION\",\"content\":\"{\\\"orderId\\\":\\\"" + orderId + "\\\",\\\"lon\\\":" + xpOrder.getStartLon() + ",\\\"lat\\\":" + xpOrder.getStartLat() + "}\",\"timestamp\":\"176569945845456\"}");
            xpPushMessageClient.sendVehicleLocation(dto);
        }
        if(5 == status){
        if (5 == status) {
            //乘客上车
            xpOrder = xpOrderClient.queryOrderById(orderId).getData();
            if(xpOrder.getStatus() == 0){
            if (xpOrder.getStatus() == 0) {
                return;
            }
            xpOrder.setAppUserId(null);
@@ -806,7 +805,7 @@
            route.put("distance", routeVo.getDistance());
            route.put("duration", routeVo.getDuration());
            route.put("routeID", routeVo.getRouteID());
            List<com.alibaba.fastjson2.JSONObject> collect = routeVo.getPolyline().stream().map(item->{
            List<com.alibaba.fastjson2.JSONObject> collect = routeVo.getPolyline().stream().map(item -> {
                com.alibaba.fastjson2.JSONObject point = new com.alibaba.fastjson2.JSONObject();
                point.put("latitude", item.getLatitude());
                point.put("longitude", item.getLongitude());
@@ -820,7 +819,7 @@
            messageDTO.setMessage(jsonObject.toJSONString());
            xpPushMessageClient.sendRoute(messageDTO);
        }
        if(6 == status){
        if (6 == status) {
            //开始服务中
            xpOrder.setAppUserId(null);
            xpOrder.setStatus(6);
@@ -832,7 +831,7 @@
            xpPushMessageClient.sendStatus(dto);
        }
        if(7 == status){
        if (7 == status) {
            //乘客待下车
            xpOrder.setAppUserId(null);
            xpOrder.setStatus(7);
@@ -878,7 +877,7 @@
//            xpOrder
        if(8 == status){
        if (8 == status) {
            //乘客待支付
            xpOrder.setAppUserId(null);
            xpOrder.setStatus(8);
@@ -889,7 +888,7 @@
            xpPushMessageClient.sendStatus(dto);
        }
        if(9 == status){
        if (9 == status) {
            //乘客支付成功
            xpOrder.setAppUserId(null);
            xpOrder.setStatus(9);
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpClockInServiceImpl.java
@@ -1,8 +1,10 @@
package com.xiaopeng.maintenance.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaopeng.api.feignClient.account.XpOperationUserClient;
import com.xiaopeng.api.model.account.SysRole;
import com.xiaopeng.api.model.account.XpOperationsRole;import com.xiaopeng.api.model.account.XpOperationsUser;import com.xiaopeng.api.model.maintenance.XpCheckLocation;
import com.xiaopeng.api.model.maintenance.XpClockIn;
import com.xiaopeng.api.model.maintenance.XpShift;
@@ -41,6 +43,7 @@
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
@@ -253,17 +256,19 @@
        List<String> appUserIdList = clockInStatistics.stream().map(ClockInStatisticsDto::getAppUserId).collect(Collectors.toList());
        List<Long> ids = appUserIdList.stream().map(Long::parseLong).collect(Collectors.toList());
        List<XpOperationsUserWithRoleVO> data = xpOperationUserClient.listByIdsWithRole(ids).getData();
        Map<Long, XpOperationsUserWithRoleVO> userMap = data.stream().collect(Collectors.toMap(XpOperationsUserWithRoleVO::getId, Function.identity()));
        //将查询结果组装成map对象,用于循环中提取数据
        for (ClockInStatisticsDto clockInStatistic : clockInStatistics) {
            String appUserId = clockInStatistic.getAppUserId();
            //运维账号可以拥有多个角色
            List<XpOperationsUserWithRoleVO> collect = data.stream().filter(x->x.getId().equals(Long.parseLong(appUserId))).collect(Collectors.toList());
            if(!collect.isEmpty()){
                XpOperationsUserWithRoleVO xpOperationsUserWithRoleVO = collect.get(0);
                clockInStatistic.setName(xpOperationsUserWithRoleVO.getNickName());
            if(CollUtil.isNotEmpty(userMap)){
                XpOperationsUserWithRoleVO vo = userMap.get(Long.parseLong(appUserId));
                if (Objects.nonNull(vo)) {
                    clockInStatistic.setName(vo.getNickName());
                    String roleName = vo.getRoles().stream().map(SysRole::getRoleName).collect(Collectors.joining(";"));
                    clockInStatistic.setRoleName(roleName);
                }
            }
            String roleName = collect.stream().map(XpOperationsUserWithRoleVO::getRoleName).collect(Collectors.joining(";"));
            clockInStatistic.setRoleName(roleName);
            Integer shouldClockInDays = clockInStatistic.getShouldClockInDays();
            Integer clockInDays = clockInStatistic.getClockInDays();
            clockInStatistic.setNotClockInDays(shouldClockInDays - clockInDays);
@@ -311,16 +316,18 @@
        List<String> appUserIdList = clockInStatistics.stream().map(ClockInStatisticsDto::getAppUserId).collect(Collectors.toList());
        List<Long> ids = appUserIdList.stream().map(Long::parseLong).collect(Collectors.toList());
        List<XpOperationsUserWithRoleVO> data = xpOperationUserClient.listByIdsWithRole(ids).getData();
        Map<Long, XpOperationsUserWithRoleVO> userMap = data.stream().collect(Collectors.toMap(XpOperationsUserWithRoleVO::getId, Function.identity()));
        for (ClockInStatisticsDto clockInStatistic : clockInStatistics) {
            String appUserId = clockInStatistic.getAppUserId();
            //运维账号可以拥有多个角色
            List<XpOperationsUserWithRoleVO> collect = data.stream().filter(x->x.getId().equals(Long.parseLong(appUserId))).collect(Collectors.toList());
            if(!collect.isEmpty()){
                XpOperationsUserWithRoleVO xpOperationsUserWithRoleVO = collect.get(0);
                clockInStatistic.setName(xpOperationsUserWithRoleVO.getNickName());
            if(CollUtil.isNotEmpty(userMap)){
                XpOperationsUserWithRoleVO vo = userMap.get(Long.parseLong(appUserId));
                if (Objects.nonNull(vo)) {
                    clockInStatistic.setName(vo.getNickName());
                    String roleName = vo.getRoles().stream().map(SysRole::getRoleName).collect(Collectors.joining(";"));
                    clockInStatistic.setRoleName(roleName);
                }
            }
            String roleName = collect.stream().map(XpOperationsUserWithRoleVO::getRoleName).collect(Collectors.joining(";"));
            clockInStatistic.setRoleName(roleName);
            Integer shouldClockInDays = clockInStatistic.getShouldClockInDays();
            Integer clockInDays = clockInStatistic.getClockInDays();
            clockInStatistic.setNotClockInDays(shouldClockInDays - clockInDays);
@@ -356,7 +363,7 @@
        //将查询结果组装成map对象,用于循环中提取数据
        for (ClockInStatisticsDetailsDto clockInStatistic : clockInStatisticsDetails) {
            clockInStatistic.setName(xpOperationsUserWithRoleVO.getNickName());
            clockInStatistic.setRoleName(xpOperationsUserWithRoleVO.getRoleName());
            clockInStatistic.setRoleName(xpOperationsUserWithRoleVO.getRoles().stream().map(SysRole::getRoleName).collect(Collectors.joining(";")));
        }
        pageInfo.setRecords(clockInStatisticsDetails);
        return pageInfo;
@@ -385,7 +392,7 @@
        //将查询结果组装成map对象,用于循环中提取数据
        for (ClockInStatisticsDetailsDto clockInStatistic : clockInStatisticsDetails) {
            clockInStatistic.setName(xpOperationsUserWithRoleVO.getNickName());
            clockInStatistic.setRoleName(xpOperationsUserWithRoleVO.getRoleName());
            clockInStatistic.setRoleName(xpOperationsUserWithRoleVO.getRoles().stream().map(SysRole::getRoleName).collect(Collectors.joining(";")));
        }
        ExcelUtil<ClockInStatisticsDetailsDto> excel = new ExcelUtil<ClockInStatisticsDetailsDto>(ClockInStatisticsDetailsDto.class);
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpRegionController.java
@@ -74,15 +74,12 @@
                        .map(item -> (XpRegion) item)
                        .collect(Collectors.toList());
                if(query.getCityName()!=null){
                    list = list.stream().filter(item -> item.getName().contains(query.getCityName()) || item.getInitial().contains(query.getCityName())).collect(Collectors.toList());
                }
            } catch (ClassCastException e) {
                // 缓存数据结构异常,重新加载
                redisService.deleteObject(CacheConstants.XP_REGION);
            }
        }else {
            list = regionService.list(Wrappers.lambdaQuery(XpRegion.class).ne(XpRegion::getParentId, 0).and(w->w.like(query.getCityName()!=null , XpRegion::getInitial, query.getCityName()).or().like(query.getCityName()!=null , XpRegion::getInitial, query.getCityName())).like(query.getCityName()!=null , XpRegion::getName, query.getCityName()).isNotNull(XpRegion::getInitial).orderByAsc(XpRegion::getInitial));
            list = regionService.list(Wrappers.lambdaQuery(XpRegion.class).ne(XpRegion::getParentId, 0).isNotNull(XpRegion::getInitial).orderByAsc(XpRegion::getInitial));
            redisService.setCacheList(CacheConstants.XP_REGION_CITY, list);
        }
        List<XpOpenCity> openCities = openCityService.list(new LambdaQueryWrapper<XpOpenCity>().eq(XpOpenCity::getStatus,1));
@@ -96,7 +93,7 @@
        }
        if (query.getCityName() != null) {
            list = list.stream().filter(item -> item.getName().contains(query.getCityName())).collect(Collectors.toList());
            list = list.stream().filter(item -> item.getName().contains(query.getCityName()) || item.getInitial().equals(query.getCityName()) || item.getChina().contains(query.getCityName().toLowerCase())).collect(Collectors.toList());
        }
        if (query.getIsOpen() != null) {
            list = list.stream().filter(item -> item.getIsOpen().equals(query.getIsOpen())).collect(Collectors.toList());
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/dto/XpTradingStrategyEditDTO.java
@@ -1,5 +1,6 @@
package com.xiaopeng.operation.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xiaopeng.api.model.operation.XpTradingStrategyCity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@@ -37,9 +38,11 @@
    private Boolean isLongValid;
    @ApiModelProperty(value = "豁免开始时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime exemptionStartTime;
    @ApiModelProperty(value = "豁免结束时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime exemptionEndTime;
    @ApiModelProperty(value = "豁免角色 逗号分割 0=全部 1=新客 2=老客 3=流失召回 4=媒体")
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderController.java
@@ -140,6 +140,7 @@
     */
    @PostMapping("/inner/order/updateOrder")
    public R<?> updateOrder(@RequestBody XpOrder xpOrder){
        xpOrder.setAppUserId(null);
        return xpOrderService.updateById(xpOrder)?R.ok():R.fail();
    }
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/mapper/XpOrderMapper.java
@@ -63,4 +63,11 @@
     * @return
     */
    List<XpOrderHistoryListVO> getHistoryOrderList(@Param("page") Page<XpOrderHistoryListVO> page, @Param("query") XpHistoryOrderListQuery query, @Param("uid") Long uid);
    List<XpOrder> getHistoryStartPoints(@Param("uid") Long uid);
    List<XpOrder> getHistoryEndPoints(@Param("uid") Long uid);
}
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -358,7 +358,7 @@
            wrapper.ge(XpOrder::getCreateTime, LocalDateTime.of(query.getStartTime(), LocalTime.MIN));
        }
        if (Objects.nonNull(query.getEndTime())) {
            wrapper.ge(XpOrder::getCreateTime, LocalDateTime.of(query.getEndTime(), LocalTime.MAX));
            wrapper.le(XpOrder::getCreateTime, LocalDateTime.of(query.getEndTime(), LocalTime.MAX));
        }
        wrapper.orderByDesc(XpOrder::getCreateTime);
        return wrapper;
@@ -508,8 +508,8 @@
     */
    private void cancelOrder(XpOrder order) {
        // 1. 更新订单状态为已取消(0)
        order.setStatus(0);
        this.updateById(order);
        lambdaUpdate().set(XpOrder::getStatus, 0)
                .eq(XpOrder::getId, order.getId()).update();
        // 2. 保存取消记录
        XpOrderCancel orderCancel = new XpOrderCancel();
@@ -831,7 +831,8 @@
    @Override
    public List<XpHistoryStartPointsVo> getHistoryStartPoints(String uid, double lon, double lat) {
        //
        List<XpOrder> xpOrders = this.baseMapper.selectList(new LambdaQueryWrapper<XpOrder>().eq(XpOrder::getAppUserId, Long.parseLong(uid)).orderByDesc(BaseModel::getCreateTime).last("LIMIT 10"));
        List<XpOrder> xpOrders = this.baseMapper.getHistoryStartPoints(Long.valueOf(uid));
//        selectList(new LambdaQueryWrapper<XpOrder>().eq(XpOrder::getAppUserId, Long.parseLong(uid)).orderByDesc(BaseModel::getCreateTime).last("LIMIT 10"));
        if (xpOrders.isEmpty()) {
            return Collections.emptyList();
        }
@@ -839,14 +840,28 @@
        List<Long> startPointsIds = xpOrders.stream().map(XpOrder::getStartPointId).collect(Collectors.toList());
        R<List<XpHistoryStartPointsVo>> r = xpPointClient.getHistoryStartPoints(new HistoryStartPointsDto(startPointsIds, lon, lat));
        return r.getData();
        List<XpHistoryStartPointsVo> data = r.getData();
        for (XpHistoryStartPointsVo datum : data) {
            xpOrders.stream().filter(e->e.getEndPointId().equals(datum.getId())).findFirst().ifPresent(
                    order->{
                        datum.setNum(order.getNum());
                    }
            );
        }
        data =  data.stream().sorted(Comparator.comparingInt(XpHistoryStartPointsVo::getNum).reversed()).collect(Collectors.toList());
        return data;
    }
    @Override
    public List<XpHistoryEndPointsVo> getHistoryEndPoints(String uid, double lon, double lat) {
        //
        List<XpOrder> xpOrders = this.baseMapper.selectList(new LambdaQueryWrapper<XpOrder>().eq(XpOrder::getAppUserId, Long.parseLong(uid)).orderByDesc(BaseModel::getCreateTime).last("LIMIT 10"));
        List<XpOrder> xpOrders = this.baseMapper.getHistoryEndPoints(Long.valueOf(uid));
//        selectList(new LambdaQueryWrapper<XpOrder>().eq(XpOrder::getAppUserId, Long.parseLong(uid)).orderByDesc(BaseModel::getCreateTime).last("LIMIT 10"));
        if (xpOrders.isEmpty()) {
            return Collections.emptyList();
        }
@@ -854,7 +869,19 @@
        List<Long> endPointsIds = xpOrders.stream().map(XpOrder::getEndPointId).collect(Collectors.toList());
        R<List<XpHistoryEndPointsVo>> r = xpPointClient.getHistoryEndPoints(new HistoryEndPointsDto(endPointsIds, lon, lat));
        return r.getData();
        List<XpHistoryEndPointsVo> data = r.getData();
        for (XpHistoryEndPointsVo datum : data) {
            xpOrders.stream().filter(e->e.getEndPointId().equals(datum.getId())).findFirst().ifPresent(
                    order->{
                        datum.setNum(order.getNum());
                    }
            );
        }
        data =  data.stream().sorted(Comparator.comparingInt(XpHistoryEndPointsVo::getNum).reversed()).collect(Collectors.toList());
        return data;
    }
@@ -943,6 +970,7 @@
        }
        if(order.getStatus()==1){
            order.setStatus(0);
            order.setAppUserId(null);
            baseMapper.updateById(order);
            return;
        }
@@ -1136,6 +1164,7 @@
                );
                break;
        }
        xpOrder.setAppUserId(null);
        this.updateById(xpOrder);
        return R.ok();
    }
@@ -1979,6 +2008,7 @@
                xpGeoQueryEntity.setOrderId(split[0]);
                // 存mongo数据
                xpPricingClient.updateXpGeoQueryEntity(split[0]);
                order.setAppUserId(null);
                this.updateById(order);
                // 修改车辆信息
xp-robotaxi-order-boot/src/main/resources/mapper/order/XpOrderMapper.xml
@@ -53,5 +53,25 @@
        </if>
        order by create_time desc
    </select>
    <select id="getHistoryStartPoints" resultType="com.xiaopeng.api.model.order.XpOrder"
            parameterType="java.lang.Long">
        SELECT
            start_point_id,
            COUNT(*) AS num
        FROM xp_order where app_user_id = #{uid}
        GROUP BY start_point_id
        ORDER BY num DESC,create_time desc
            LIMIT 10;
    </select>
    <select id="getHistoryEndPoints" resultType="com.xiaopeng.api.model.order.XpOrder"
            parameterType="java.lang.Long">
        SELECT
            end_point_id,
            COUNT(*) AS num
        FROM xp_order where app_user_id = #{uid}
        GROUP BY end_point_id
        ORDER BY num DESC,create_time desc
            LIMIT 10;
    </select>
</mapper>
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpFleetServiceImpl.java
@@ -8,6 +8,7 @@
import com.xiaopeng.api.feignClient.maintenance.XpCheckLocationClient;
import com.xiaopeng.api.feignClient.operation.XpElectronicClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
import com.xiaopeng.api.model.account.SysRole;
import com.xiaopeng.api.model.account.XpOperationsUser;
import com.xiaopeng.api.model.maintenance.XpCheckLocation;
import com.xiaopeng.api.model.operation.XpElectronicFence;
@@ -452,7 +453,7 @@
                    vo.setNickName(user.getNickName());
                    vo.setPhoneNumber(user.getPhoneNumber());
                    vo.setJobNumber(user.getUniqueNumber());
                    vo.setRoleName(user.getRoleName());
                    vo.setRoleName(user.getRoles().stream().map(SysRole::getRoleName).collect(Collectors.joining(",")));
                    records.add(vo);
                }
            }
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleAnnualRecordServiceImpl.java
@@ -39,6 +39,7 @@
            wrapper.ge(XpVehicleAnnualRecord::getCreateTime, LocalDateTime.of(query.getEndTime(), LocalTime.MAX));
        }
        wrapper.like(StringUtils.isNotBlank(query.getOperationsUserName()), XpVehicleAnnualRecord::getCreateBy, query.getOperationsUserName());
        wrapper.orderByDesc(XpVehicleAnnualRecord::getCreateTime);
        return this.page(page, wrapper);
    }
}
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java
@@ -502,8 +502,7 @@
        // 批量将运营车辆转为在库状态(vehicleType: 2→1)
        LambdaUpdateWrapper<XpVehicle> wrapper = new LambdaUpdateWrapper<>();
        wrapper.in(XpVehicle::getId, ids)
                .set(XpVehicle::getVehicleType, 1)
                .set(XpVehicle::getOperatingStatus, null);
                .set(XpVehicle::getVehicleType, 1);
        this.update(wrapper);
    }