From de5f07fe1acd8d462f9c54d7a04c5c47a87264d1 Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期六, 07 三月 2026 21:01:24 +0800
Subject: [PATCH] 修改bug
---
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/ISysPermissionService.java | 13
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/navigationDeviationEvent/NavigationDeviationEvent.java | 23
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpFleetController.java | 1
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/ReassignOrderClientFallbackFactory.java | 26 +
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/AbnormalReason.java | 27 +
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/VehicleStatus.java | 18
xp-robotaxi-vehicle-convoy-boot/src/main/resources/i18n/messages.properties | 11
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudCreateOrder/TaskResultStatus.java | 28 +
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/importExcel/XpVehicleImportExcel.java | 2
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleAnnualRecordServiceImpl.java | 2
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/jobs/OrderCancelJob.java | 2
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpOpenCityServiceImpl.java | 2
xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/utils/XpPricingUtil.java | 68 ++
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/SystemPhase.java | 27 +
xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsRoleMapper.xml | 8
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpPoint.java | 2
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/MessageType.java | 25 +
xp-robotaxi-gateway-boot/src/main/java/com/xiaopeng/gateway/filter/RequestParamGlobalFilter.java | 31
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/RtMsgHeader.java | 34 +
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/VehicleDynamicStatus.java | 42 +
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/exportExcel/XpVehicleExportExcel.java | 14
xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java | 6
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/RTCmdType.java | 60 ++
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/SystemRuntimeStatus.java | 47 +
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpMapController.java | 34
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpAppVersionServiceImpl.java | 1
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpFleetServiceImpl.java | 24
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/RtMsgHeader.java | 30 +
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysLoginService.java | 7
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/account/XpOperationsUserWithRoleVO.java | 3
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/SystemStatus.java | 28 +
xp-robotaxi-vehicle-convoy-boot/src/main/resources/i18n/messages_zh_CN.properties | 11
xp-robotaxi-operation-boot/src/main/resources/i18n/messages.properties | 1
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/MessageType.java | 25 +
xp-robotaxi-vehicle-convoy-boot/src/main/resources/i18n/messages_en_US.properties | 11
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudOrderOperation/OrderOperationStatus.java | 26 +
xp-robotaxi-automatic-pilot-boot/src/test/java/com/ruoyi/account/RuoYiAccountApplicationTests.java | 30 +
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java | 74 ++
xp-robotaxi-gateway-boot/src/main/java/com/xiaopeng/gateway/filter/CacheRequestFilter.java | 8
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysGroupServiceImpl.java | 2
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpRoutePlanServiceImpl.java | 3
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudOrderOperation/OrderOperationState.java | 22
xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsUserMapper.xml | 6
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/FareVo.java | 5
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java | 76 ++
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysPermissionServiceImpl.java | 61 ++
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysRoleServiceImpl.java | 32 +
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/TaskOrderUtil.java | 7
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/RTCmdType.java | 54 ++
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpOpenCityServiceImpl.java | 2
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/constant/I18nKeyConstant.java | 4
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudCreateOrder/RtTaskResult.java | 22
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/ISysRoleService.java | 8
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/xpuNavigationRequest/NavigationRequest.java | 42 +
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/MsgContent.java | 19
xp-robotaxi-api/src/main/java/com/xiaopeng/api/query/operation/PointPageListQuery.java | 22
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/MsgContent.java | 19
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudCreateOrder/RtTaskListResponse.java | 15
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/DrivingMode.java | 26 +
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/mapper/XpOperationsUserMapper.java | 4
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java | 13
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpOperationsUserServiceImpl.java | 5
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/vo/FleetVehicleVO.java | 12
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpCruisePlanServiceImpl.java | 2
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java | 22
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/ServiceAvailability.java | 25 +
xp-robotaxi-operation-boot/src/main/resources/i18n/messages_zh_CN.properties | 1
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/mapper/XpOperationsRoleMapper.java | 8
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/operation/XpPointEnableDisableDto.java | 3
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpPointManagementController.java | 1
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/VehicleStaticInfo.java | 22
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/xpuNavigationRequest/NavigationType.java | 27 +
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/GearLevel.java | 27 +
xp-robotaxi-operation-boot/src/main/resources/i18n/messages_en_US.properties | 1
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpSchedulingDetailController.java | 2
75 files changed, 1,351 insertions(+), 103 deletions(-)
diff --git a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/mapper/XpOperationsRoleMapper.java b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/mapper/XpOperationsRoleMapper.java
index 3415bc2..c787f4f 100644
--- a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/mapper/XpOperationsRoleMapper.java
+++ b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/mapper/XpOperationsRoleMapper.java
@@ -38,4 +38,12 @@
@Param("phoneNumber") String phoneNumber,
@Param("roleId") Long roleId
);
+
+ /**
+ * 根据用户ID查询用户及角色信息
+ *
+ * @param userId 用户ID
+ * @return 用户及角色信息列表
+ */
+ List<XpOperationsRole> selectSysUserRoleByOperationUserId(@Param("userId")Long userId);
}
diff --git a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/mapper/XpOperationsUserMapper.java b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/mapper/XpOperationsUserMapper.java
index b1c444e..35d625c 100644
--- a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/mapper/XpOperationsUserMapper.java
+++ b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/mapper/XpOperationsUserMapper.java
@@ -24,11 +24,11 @@
public interface XpOperationsUserMapper extends BaseMapper<XpOperationsUser> {
/**
* 查询带角色信息的运维用户分页列表
- * @param xpOperationsUserWithRoleVOPage
+ * @param pageInfo
* @param query
* @return
*/
- Page<XpOperationsUserWithRoleVO> selectUserPageByConditions(Page<XpOperationsUserWithRoleVO> xpOperationsUserWithRoleVOPage, @Param("query") XpOperationsUserPageQuery query);
+ Page<XpOperationsUserWithRoleVO> selectUserPageByConditions(PageInfo<XpOperationsUserWithRoleVO> pageInfo, @Param("query") XpOperationsUserPageQuery query);
/**
* 分页查询
diff --git a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/ISysPermissionService.java b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/ISysPermissionService.java
index c2f8409..d85aeb4 100644
--- a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/ISysPermissionService.java
+++ b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/ISysPermissionService.java
@@ -1,6 +1,7 @@
package com.xiaopeng.account.service;
import com.xiaopeng.api.model.account.SysUser;
+import com.xiaopeng.api.model.account.XpOperationsUser;
import com.xiaopeng.api.model.operation.SysMenu;
import java.util.List;
@@ -20,6 +21,12 @@
* @return 角色权限信息
*/
Set<String> getRolePermission(SysUser user);
+ /**
+ * 获取运维角色数据权限
+ *
+ * @return 角色权限信息
+ */
+ Set<String> getRolePermission(XpOperationsUser user);
/**
* 获取菜单数据权限
@@ -27,4 +34,10 @@
* @return 菜单权限信息
*/
Set<String> getMenuPermission(SysUser user);
+ /**
+ * 获取运维菜单数据权限
+ *
+ * @return 菜单权限信息
+ */
+ Set<String> getMenuPermission(XpOperationsUser user);
}
diff --git a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/ISysRoleService.java b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/ISysRoleService.java
index 63e0745..2a6bbb1 100644
--- a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/ISysRoleService.java
+++ b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/ISysRoleService.java
@@ -9,6 +9,7 @@
import com.xiaopeng.api.model.account.SysRole;
import com.xiaopeng.common.core.web.page.PageInfo;
+import java.util.Collection;
import java.util.Set;
/**
@@ -90,4 +91,11 @@
* @return
*/
Boolean checkMenuExistRole(Long menuId);
+
+ /**
+ * 根据操作用户ID查询权限
+ * @param id
+ * @return
+ */
+ Set<String> selectRolePermissionByOperationUserId(Long id);
}
diff --git a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysGroupServiceImpl.java b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysGroupServiceImpl.java
index c6cabda..99cdb83 100644
--- a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysGroupServiceImpl.java
+++ b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysGroupServiceImpl.java
@@ -69,7 +69,6 @@
// 创建权限组实体
SysGroup group = BeanUtil.copyProperties(dto, SysGroup.class);
- group.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
// 保存权限组
this.save(group);
@@ -100,7 +99,6 @@
existGroup.setGroupName(dto.getGroupName());
existGroup.setRemarks(dto.getRemarks());
existGroup.setGroupType(dto.getGroupType());
- existGroup.setUpdateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
this.updateById(existGroup);
// 删除旧的菜单关联
diff --git a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysLoginService.java b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysLoginService.java
index 425a74e..397a090 100644
--- a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysLoginService.java
+++ b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysLoginService.java
@@ -166,6 +166,13 @@
}
passwordService.validateOperationsUser(operationsUser, password, request);
loginOperationUser.setXpOperationsUser(operationsUser);
+ // 查询用户角色
+ // 角色集合
+ Set<String> roles = permissionService.getRolePermission(operationsUser);
+ // 权限集合
+ Set<String> menuPermission = permissionService.getMenuPermission(operationsUser);
+ loginOperationUser.setRoles(roles);
+ loginOperationUser.setPermissions(menuPermission);
//更新用户登录设备类型
operationsUser.setDeviceType(deviceType);
operationsUserService.updateById(operationsUser);
diff --git a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysPermissionServiceImpl.java b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysPermissionServiceImpl.java
index 1c8651d..63d6c26 100644
--- a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysPermissionServiceImpl.java
+++ b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysPermissionServiceImpl.java
@@ -6,19 +6,21 @@
import java.util.Set;
import java.util.stream.Collectors;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.xiaopeng.account.mapper.XpOperationsRoleMapper;
import com.xiaopeng.account.service.ISysGroupMenuService;
import com.xiaopeng.account.service.ISysPermissionService;
import com.xiaopeng.account.service.ISysRoleService;
import com.xiaopeng.account.service.ISysUserRoleService;
import com.xiaopeng.api.feignClient.operation.SysMenuClient;
-import com.xiaopeng.api.model.account.SysUser;
-import com.xiaopeng.api.model.account.SysUserRole;
+import com.xiaopeng.api.model.account.*;
import com.xiaopeng.api.model.operation.SysMenu;
import com.xiaopeng.common.core.domain.R;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
/**
* 用户权限处理
@@ -41,7 +43,8 @@
@Autowired
private SysMenuClient sysMenuClient;
-
+ @Autowired
+ private XpOperationsRoleMapper xpOperationsRoleMapper;
/**
* 获取角色数据权限
*
@@ -61,6 +64,14 @@
{
roles.addAll(roleService.selectRolePermissionByUserId(user.getId()));
}
+ return roles;
+ }
+
+ @Override
+ public Set<String> getRolePermission(XpOperationsUser user) {
+ Set<String> roles = new HashSet<String>();
+ // 管理员拥有所有权限
+ roles.addAll(roleService.selectRolePermissionByOperationUserId(user.getId()));
return roles;
}
@@ -121,4 +132,48 @@
return perms;
}
+
+ @Override
+ public Set<String> getMenuPermission(XpOperationsUser user) {
+ Set<String> perms = new HashSet<>();
+ try {
+ // 1. 根据 userId 查询 sys_user_role 获取 roleId
+ List<XpOperationsRole> xpOperationsRoles = xpOperationsRoleMapper.selectSysUserRoleByOperationUserId(user.getId());
+ if (CollectionUtils.isEmpty(xpOperationsRoles)) {
+ log.warn("用户[{}]未分配角色", user.getId());
+ return perms;
+ }
+ List<Long> roleIds = xpOperationsRoles.stream().map(XpOperationsRole::getRoleId).collect(Collectors.toList());
+
+ // 2. 根据 roleId 查询 sys_role 获取 groupId
+ List<SysRole> sysRoles = roleService.list(Wrappers.lambdaQuery(SysRole.class)
+ .in(SysRole::getId, roleIds));
+ List<Long> groupIds = sysRoles.stream().map(SysRole::getGroupId).collect(Collectors.toList());
+ if (CollectionUtils.isEmpty(groupIds)) {
+ log.warn("角色[{}]未关联权限组", groupIds);
+ return perms;
+ }
+
+ // 3. 根据 groupId 查询 sys_group_menu 获取 menuId 列表
+ List<SysGroupMenu> sysGroupMenus = groupMenuService.list(Wrappers.lambdaQuery(SysGroupMenu.class)
+ .in(SysGroupMenu::getGroupId, groupIds));
+ List<Long> menuIds = sysGroupMenus.stream().map(SysGroupMenu::getMenuId).collect(Collectors.toList());
+ if (CollectionUtils.isEmpty(menuIds)) {
+ log.warn("权限组[{}]未配置菜单权限", menuIds);
+ return perms;
+ }
+
+ // 4. 通过 Feign 调用 operation 服务,根据 menuId 列表获取菜单列表
+ R<List<SysMenu>> result = sysMenuClient.getMenusByMenuIds(menuIds);
+ if (R.isSuccess(result) && result.getData() != null) {
+ perms = result.getData().stream().map(item -> item.getId().toString()).collect(Collectors.toSet());
+ } else {
+ log.error("调用菜单服务获取菜单列表失败: {}", result != null ? result.getMsg() : "返回结果为空");
+ }
+
+ } catch (Exception e) {
+ log.error("获取用户[{}]菜单权限异常", user.getId(), e);
+ }
+ return perms;
+ }
}
diff --git a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysRoleServiceImpl.java b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysRoleServiceImpl.java
index f4c6304..e9e9ce0 100644
--- a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysRoleServiceImpl.java
+++ b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysRoleServiceImpl.java
@@ -2,10 +2,12 @@
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaopeng.account.constant.I18nKeyConstant;
import com.xiaopeng.account.mapper.SysRoleMapper;
import com.xiaopeng.account.mapper.SysRoleMenuMapper;
+import com.xiaopeng.account.mapper.XpOperationsRoleMapper;
import com.xiaopeng.account.model.dto.SysRoleAddDTO;
import com.xiaopeng.account.model.dto.SysRoleEditDTO;
import com.xiaopeng.account.model.query.SysRolePageQuery;
@@ -18,6 +20,7 @@
import com.xiaopeng.api.feignClient.operation.SysMenuClient;
import com.xiaopeng.api.model.account.SysRole;
import com.xiaopeng.api.model.account.SysUserRole;
+import com.xiaopeng.api.model.account.XpOperationsRole;
import com.xiaopeng.api.model.operation.SysMenu;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.exception.ServiceException;
@@ -53,6 +56,7 @@
private final SysMenuClient sysMenuClient;
private final SysRoleMenuMapper sysRoleMenuMapper;
+ private final XpOperationsRoleMapper xpOperationsRoleMapper;
/**
* 根据角色ID查询权限组ID
@@ -342,4 +346,32 @@
public Boolean checkMenuExistRole(Long menuId) {
return sysRoleMenuMapper.checkMenuExistRole(menuId) > 0;
}
+
+ @Override
+ public Set<String> selectRolePermissionByOperationUserId(Long userId) {
+ Set<String> roles = new HashSet<>();
+ if (userId == null) {
+ return roles;
+ }
+
+ // 查询用户关联的角色
+ List<XpOperationsRole> xpOperationsRoles = xpOperationsRoleMapper.selectSysUserRoleByOperationUserId(userId);
+ if (CollectionUtils.isEmpty(xpOperationsRoles)) {
+ return roles;
+ }
+
+ // 查询角色信息
+ List<Long> roleIds = xpOperationsRoles.stream().map(XpOperationsRole::getRoleId).collect(Collectors.toList());
+ List<SysRole> roleList= this.list(Wrappers.lambdaQuery(SysRole.class)
+ .in(SysRole::getId, roleIds));
+ if (!CollectionUtils.isEmpty(roleList)) {
+ roleList.forEach(role -> {
+ if (role != null) {
+ roles.add(role.getRoleName());
+ }
+ });
+ }
+
+ return roles;
+ }
}
diff --git a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpOperationsUserServiceImpl.java b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpOperationsUserServiceImpl.java
index b7e010c..0d323c2 100644
--- a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpOperationsUserServiceImpl.java
+++ b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpOperationsUserServiceImpl.java
@@ -91,10 +91,9 @@
@Override
public PageInfo<XpOperationsUserWithRoleVO> selectUserPageByConditions(XpOperationsUserPageQuery query) {
- Page<XpOperationsUserWithRoleVO> page = baseMapper.selectUserPageByConditions(new Page<>(query.getPageNum(), query.getPageSize()), query);
- PageInfo<XpOperationsUserWithRoleVO> pageInfo = new PageInfo<>();
+ PageInfo<XpOperationsUserWithRoleVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
+ Page<XpOperationsUserWithRoleVO> page = baseMapper.selectUserPageByConditions(pageInfo, query);
pageInfo.setRecords(page.getRecords());
- pageInfo.setTotal(page.getTotal());
return pageInfo;
}
diff --git a/xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsRoleMapper.xml b/xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsRoleMapper.xml
index bc76133..819b31a 100644
--- a/xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsRoleMapper.xml
+++ b/xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsRoleMapper.xml
@@ -42,5 +42,13 @@
AND r.id = #{roleId}
</if>
</select>
+ <select id="selectSysUserRoleByOperationUserId"
+ resultType="com.xiaopeng.api.model.account.XpOperationsRole">
+ SELECT
+ ur.operations_user_id AS operationsUserId,
+ ur.role_id AS roleId
+ FROM xp_operations_role ur
+ WHERE ur.operations_user_id = #{operationsUserId}
+ </select>
</mapper>
diff --git a/xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsUserMapper.xml b/xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsUserMapper.xml
index 2e65da1..cd06d8d 100644
--- a/xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsUserMapper.xml
+++ b/xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsUserMapper.xml
@@ -11,7 +11,7 @@
SELECT
u.*,
r.id AS roleId,
- r.role_name AS roleName
+ GROUP_CONCAT(r.role_name) AS roleName
FROM xp_operations_user u
LEFT JOIN xp_operations_role ur ON u.id = ur.operations_user_id
LEFT JOIN sys_role r ON ur.role_id = r.id AND r.is_deleted = 0
@@ -26,9 +26,11 @@
AND r.id = #{query.roleId}
</if>
</where>
+ GROUP BY u.id
+ ORDER BY u.create_time DESC
</select>
<select id="pageList" resultType="com.xiaopeng.api.vo.account.XpOperationsUserVO">
- SELECT xou.id, xou.nick_name, xou.unique_number, xou.avatar, xou.password, xou.phone_number, xou.remarks, xou.status,
+ SELECT xou.id, xou.nick_name, xou.unique_number, xou.avatar,xou.sex, 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
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/operation/XpPointEnableDisableDto.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/operation/XpPointEnableDisableDto.java
index b0a80b7..6de4a9c 100644
--- a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/operation/XpPointEnableDisableDto.java
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/operation/XpPointEnableDisableDto.java
@@ -12,4 +12,7 @@
@ApiModelProperty(value = "运营状态 1=待启用 2=启用中 3=已停用 4=已失效")
private Integer operationStatus;
+ @ApiModelProperty(value = "验证状态 1=待验证、2=验证中、3=已验证 4验证失败 5待生效")
+ private Integer verificationStatus;
+
}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/ReassignOrderClientFallbackFactory.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/ReassignOrderClientFallbackFactory.java
new file mode 100644
index 0000000..eaf9a31
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/ReassignOrderClientFallbackFactory.java
@@ -0,0 +1,26 @@
+package com.xiaopeng.api.factory.operation;
+
+import com.xiaopeng.api.dto.operation.ReassignOrderDTO;
+import com.xiaopeng.api.feignClient.operation.ReassignOrderClient;
+import com.xiaopeng.common.core.domain.R;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.cloud.openfeign.FallbackFactory;
+
+public class ReassignOrderClientFallbackFactory implements FallbackFactory<ReassignOrderClient> {
+
+ private static final Logger log = LoggerFactory.getLogger(ReassignOrderClientFallbackFactory.class);
+
+ @Override
+ public ReassignOrderClient create(Throwable cause) {
+ log.error("改派服务调用失败: {}", cause.getMessage());
+ return new ReassignOrderClient(){
+
+ @Override
+ public R<String> reassignOrder(ReassignOrderDTO dto) {
+ return R.fail("改派派单失败,"+cause.getMessage());
+ }
+ };
+ }
+
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpPoint.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpPoint.java
index 4a59b5f..e6e5a8f 100644
--- a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpPoint.java
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpPoint.java
@@ -55,7 +55,7 @@
@ApiModelProperty(value = "点位类型 1=运营点位 2=测试点位")
private Integer pointType;
- @ApiModelProperty(value = "验证状态 1=待验证、2=验证中、3=已验证 4验证失败")
+ @ApiModelProperty(value = "验证状态 1=待验证、2=验证中、3=已验证 4验证失败 5待生效")
private Integer verificationStatus;
@ApiModelProperty(value = "限停时长")
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/query/operation/PointPageListQuery.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/query/operation/PointPageListQuery.java
new file mode 100644
index 0000000..a1e8392
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/query/operation/PointPageListQuery.java
@@ -0,0 +1,22 @@
+package com.xiaopeng.api.query.operation;
+
+import com.xiaopeng.common.core.web.page.BasePage;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+@ApiModel(value = "点位管理列表查询query")
+public class PointPageListQuery {
+ @ApiModelProperty(value = "查询参数(名称、poi、唯一ID)")
+ private String queryParams;
+ @ApiModelProperty(value = "运营状态 1=待启用 2=启用中 3=已停用 4=已失效")
+ private String operationStatus;
+ @ApiModelProperty(value = "运营状态数组 前端忽略")
+ private List<Integer> operationStatusIds;
+ @ApiModelProperty(value = "点位类型1运营点位 2测试点位")
+ private Integer pointType;
+
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/account/XpOperationsUserWithRoleVO.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/account/XpOperationsUserWithRoleVO.java
index edfce97..a48ec3d 100644
--- a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/account/XpOperationsUserWithRoleVO.java
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/account/XpOperationsUserWithRoleVO.java
@@ -21,4 +21,7 @@
@ApiModelProperty(value = "关联角色")
private List<SysRole> roles;
+
+ @ApiModelProperty(value = "关联角色名称, 逗号拼接")
+ private String roleName;
}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/MessageType.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/MessageType.java
new file mode 100644
index 0000000..81d0826
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/MessageType.java
@@ -0,0 +1,25 @@
+package com.xiaopeng.api.vo.automaticPilot.proto.down;
+
+/**
+ * 消息类型枚举
+ */
+public enum MessageType {
+
+ MESSAGE_TYPE_UNKNOWN(0),
+ MESSAGE_TYPE_RESPONSE(1), // 应答
+ MESSAGE_TYPE_REQUEST(2); // 请求
+
+ private int value;
+
+ MessageType(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ public void setValue(int value) {
+ this.value = value;
+ }
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/MsgContent.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/MsgContent.java
new file mode 100644
index 0000000..af0f27f
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/MsgContent.java
@@ -0,0 +1,19 @@
+package com.xiaopeng.api.vo.automaticPilot.proto.down;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.Data;
+
+/**
+ * 消息内容
+ */
+@Data
+public class MsgContent {
+ /**
+ * 消息头
+ */
+ private RtMsgHeader header;
+ /**
+ * 消息体
+ */
+ private JSONObject content_detail;
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/RTCmdType.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/RTCmdType.java
new file mode 100644
index 0000000..88780a0
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/RTCmdType.java
@@ -0,0 +1,54 @@
+package com.xiaopeng.api.vo.automaticPilot.proto.down;
+
+public enum RTCmdType {
+
+ // RT CMD 云端发起CMD范围:10001~12000
+ CLOUD_ORDER_OPERATION(10001), // 云端操作订单 (云端→XPU)
+ CLOUD_TASK_CONTROL(10003), // 云端任务操作 (云端→XPU)
+ CLOUD_CREATE_ORDER(10004), // 云端新增订单 (云端→XPU)
+
+ // RT CMD 座舱发起CMD范围:12001~14000
+ VEHICLE_ORDER_OPERATION(12001), // 车端操作订单 (座舱→XPU)
+ VEHICLE_TASK_CONTROL(12002), // 车端任务操作 (座舱→XPU)
+ SYSTEM_STATUS_CDU(12003), // CDU发布系统运行状态 (座舱→XPU)
+ CDU_PULL_OVER_REQUEST(12004), // 座舱发起靠边停车 (座舱→XPU)
+ EMERGENCY_STOP(12005), // 座舱触发急停 (座舱→XPU)
+ CDU_PICKUP_CONFIRMATION(12006), // 用户上车确认 (座舱→XPU)
+ CDU_DROPOFF_INFO(12007), // 用户下车信息 (座舱→XPU)
+ CDU_NAVIGATION_DEVIATION(12008), // 导航偏航 (座舱→XPU)
+ CDU_UPDATE_REALTIME_NAVI_POSE(12009), // 实时更新位置 (座舱→XPU)
+
+ // RT CMD XPU发起CMD范围:14001~18000
+ SYSTEM_STATUS_XPU(14001), // XPU发布系统运行状态 (XPU→云端)
+ XPU_NAVIGATION_REQUEST(14002), // XPU向云端请求导航 (XPU→云端)
+ XPU_REQ_CDU_START_NAVIGATION(14003), // XPU向座舱请求还原云端导航 (XPU→座舱)
+ PULLOVER_STATUS(14004), // XPU向CDU周期发送靠边停车状态 (XPU→座舱)
+ XPU_TO_CDU_NEW_ORDER(14005), // XPU通知座舱收到新订单 (XPU→座舱)
+
+ // RT EVENT CMD从16001开始
+ TRIP_STATUS_UPDATE_EVENT(16001), // 行程状态更新 (XPU→云端)(XPU→座舱)
+ PULLOVER_STATUS_EVENT(16002), // 靠边停车状态 (XPU→云端)(XPU→座舱)
+ DRIVING_MODE_UPDATE_EVENT(16003), // 驾驶模式变化 (XPU→云端)(XPU→座舱)
+ SYSTEM_STATUS_UPDATE_EVENT(16004), // 系统状态变化 (XPU→云端)(XPU→座舱)
+ TASK_STATE_UPDATE_EVENT(16005), // 任务状态变化 (XPU→云端)(XPU→座舱)
+ ORDER_STATE_UPDATE_EVENT(16006), // 订单状态变化 (XPU→云端)(XPU→座舱)
+ POINT_ARRIVAL_STATUS_EVENT(16007), // 到达目标点状态 (XPU→云端)(XPU→座舱)
+ PICKUP_CONFIRMATION_EVENT(16008), // 用户上车确认 (XPU→云端)(XPU→座舱)
+ DROPOFF_INFO_EVENT(16009), // 用户下车信息 (XPU→云端)
+ NAVIGATION_DEVIATION_EVENT(16010), // 导航偏航 (XPU→云端)
+ EMERGENCY_STOP_EVENT(16011), // 急停 (XPU→云端)(XPU→座舱)
+ NAVIGATION_UPDATE_EVENT(16012), // 导航信息变化 (XPU→云端)
+ TASK_QUEUE_UPDATE_EVENT(16013), // XPU待执行任务队列 (XPU→云端)
+ SYSTEM_STATE_ANAPSHOT_SYNC_EVENT(16014),// 每次MQTT连接之后触发 (XPU→云端)
+ ORDER_STATE_UPDATE_TO_CDU_EVENT(16015); // 更新订单状态到CDU (XPU→云端)
+
+ private int value;
+
+ RTCmdType(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/RtMsgHeader.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/RtMsgHeader.java
new file mode 100644
index 0000000..d36185e
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/RtMsgHeader.java
@@ -0,0 +1,30 @@
+package com.xiaopeng.api.vo.automaticPilot.proto.down;
+
+import lombok.Data;
+
+/**
+ * 消息头
+ */
+@Data
+public class RtMsgHeader {
+ /**
+ * 消息唯一ID(UUID)
+ */
+ private String msg_id;
+ /**
+ * 发送时间戳,单位ms
+ */
+ private Long timestamp;
+ /**
+ * 消息命令类型
+ */
+ private RTCmdType cmd;
+ /**
+ * 序列号
+ */
+ private Long sequence;
+ /**
+ * 请求或应答
+ */
+ private MessageType type;
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudCreateOrder/RtTaskListResponse.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudCreateOrder/RtTaskListResponse.java
new file mode 100644
index 0000000..1e47f70
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudCreateOrder/RtTaskListResponse.java
@@ -0,0 +1,15 @@
+package com.xiaopeng.api.vo.automaticPilot.proto.down.cloudCreateOrder;
+
+import lombok.Data;
+import java.util.List;
+
+/**
+ * RT任务列表应答
+ */
+@Data
+public class RtTaskListResponse {
+ /**
+ * 每个任务的详细结果
+ */
+ private List<RtTaskResult> results;
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudCreateOrder/RtTaskResult.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudCreateOrder/RtTaskResult.java
new file mode 100644
index 0000000..664a300
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudCreateOrder/RtTaskResult.java
@@ -0,0 +1,22 @@
+package com.xiaopeng.api.vo.automaticPilot.proto.down.cloudCreateOrder;
+
+import lombok.Data;
+
+/**
+ * 任务结果
+ */
+@Data
+public class RtTaskResult {
+ /**
+ * 订单ID
+ */
+ private String order_id;
+ /**
+ * 任务ID
+ */
+ private String task_id;
+ /**
+ * 任务状态
+ */
+ private TaskResultStatus status;
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudCreateOrder/TaskResultStatus.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudCreateOrder/TaskResultStatus.java
new file mode 100644
index 0000000..002092d
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudCreateOrder/TaskResultStatus.java
@@ -0,0 +1,28 @@
+package com.xiaopeng.api.vo.automaticPilot.proto.down.cloudCreateOrder;
+
+/**
+ * 任务处理结果状态
+ */
+public enum TaskResultStatus {
+
+ TASK_RESULT_STATUS_UNSPECIFIED(0), // 未指定
+ ACCEPTED(1), // 已接受
+ NO_CAPABILITY(2), // 无执行任务能力
+ PRECONDITION_NOT_MET(3), // 执行条件不满足
+ DUPLICATE(4), // 重复任务
+ INVALID(5); // 无效任务
+
+ private int value;
+
+ TaskResultStatus(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ public void setValue(int value) {
+ this.value = value;
+ }
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudOrderOperation/OrderOperationState.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudOrderOperation/OrderOperationState.java
new file mode 100644
index 0000000..75b51e5
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudOrderOperation/OrderOperationState.java
@@ -0,0 +1,22 @@
+package com.xiaopeng.api.vo.automaticPilot.proto.down.cloudOrderOperation;
+
+import lombok.Data;
+
+/**
+ * 订单操作状态消息
+ */
+@Data
+public class OrderOperationState {
+ /**
+ * 订单ID
+ */
+ private String order_id;
+ /**
+ * 订单操作类型
+ */
+ private OrderOperationType operation_type;
+ /**
+ * 操作状态
+ */
+ private OrderOperationStatus status;
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudOrderOperation/OrderOperationStatus.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudOrderOperation/OrderOperationStatus.java
new file mode 100644
index 0000000..de8a31b
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudOrderOperation/OrderOperationStatus.java
@@ -0,0 +1,26 @@
+package com.xiaopeng.api.vo.automaticPilot.proto.down.cloudOrderOperation;
+
+/**
+ * 操作状态
+ */
+public enum OrderOperationStatus {
+
+ OPERATION_STATUS_UNSPECIFIED(0),
+ PROCESSING(1), // 处理中
+ SUCCESS(2), // 成功
+ FAILED(3); // 失败
+
+ private int value;
+
+ OrderOperationStatus(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ public void setValue(int value) {
+ this.value = value;
+ }
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/MessageType.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/MessageType.java
new file mode 100644
index 0000000..1e372be
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/MessageType.java
@@ -0,0 +1,25 @@
+package com.xiaopeng.api.vo.automaticPilot.proto.up;
+
+/**
+ * 消息类型枚举
+ */
+public enum MessageType {
+
+ MESSAGE_TYPE_UNKNOWN(0),
+ MESSAGE_TYPE_RESPONSE(1), // 应答
+ MESSAGE_TYPE_REQUEST(2); // 请求
+
+ private int value;
+
+ MessageType(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ public void setValue(int value) {
+ this.value = value;
+ }
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/MsgContent.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/MsgContent.java
new file mode 100644
index 0000000..ad95467
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/MsgContent.java
@@ -0,0 +1,19 @@
+package com.xiaopeng.api.vo.automaticPilot.proto.up;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.Data;
+
+/**
+ * 消息内容
+ */
+@Data
+public class MsgContent {
+ /**
+ * 消息头
+ */
+ private RtMsgHeader header;
+ /**
+ * 应答消息
+ */
+ private JSONObject content_detail;
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/RTCmdType.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/RTCmdType.java
new file mode 100644
index 0000000..8909145
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/RTCmdType.java
@@ -0,0 +1,60 @@
+package com.xiaopeng.api.vo.automaticPilot.proto.up;
+
+/**
+ * RT命令类型枚举
+ */
+public enum RTCmdType {
+ // RT CMD 云端发起CMD范围:10001~12000
+ CLOUD_ORDER_OPERATION(10001), // 云端操作订单 (云端→XPU)
+ CLOUD_TASK_CONTROL(10003), // 云端任务操作 (云端→XPU)
+ CLOUD_CREATE_ORDER(10004), // 云端新增订单 (云端→XPU)
+
+ // RT CMD 座舱发起CMD范围:12001~14000
+ VEHICLE_ORDER_OPERATION(12001), // 车端操作订单 (座舱→XPU)
+ VEHICLE_TASK_CONTROL(12002), // 车端任务操作 (座舱→XPU)
+ SYSTEM_STATUS_CDU(12003), // CDU发布系统运行状态 (座舱→XPU)
+ CDU_PULL_OVER_REQUEST(12004), // 座舱发起靠边停车 (座舱→XPU)
+ EMERGENCY_STOP(12005), // 座舱触发急停 (座舱→XPU)
+ CDU_PICKUP_CONFIRMATION(12006), // 用户上车确认 (座舱→XPU)
+ CDU_DROPOFF_INFO(12007), // 用户下车信息 (座舱→XPU)
+ CDU_NAVIGATION_DEVIATION(12008), // 导航偏航 (座舱→XPU)
+ CDU_UPDATE_REALTIME_NAVI_POSE(12009), // 实时更新位置 (座舱→XPU)
+
+ // RT CMD XPU发起CMD范围:14001~18000
+ SYSTEM_STATUS_XPU(14001), // XPU发布系统运行状态 (XPU→云端)
+ XPU_NAVIGATION_REQUEST(14002), // XPU向云端请求导航 (XPU→云端)
+ XPU_REQ_CDU_START_NAVIGATION(14003), // XPU向座舱请求还原云端导航 (XPU→座舱)
+ PULLOVER_STATUS(14004), // XPU向CDU周期发送靠边停车状态 (XPU→座舱)
+ XPU_TO_CDU_NEW_ORDER(14005), // XPU通知座舱收到新订单 (XPU→座舱)
+
+ // RT EVENT CMD从16001开始
+ TRIP_STATUS_UPDATE_EVENT(16001), // 行程状态更新 (XPU→云端)(XPU→座舱)
+ PULLOVER_STATUS_EVENT(16002), // 靠边停车状态 (XPU→云端)(XPU→座舱)
+ DRIVING_MODE_UPDATE_EVENT(16003), // 驾驶模式变化 (XPU→云端)(XPU→座舱)
+ SYSTEM_STATUS_UPDATE_EVENT(16004), // 系统状态变化 (XPU→云端)(XPU→座舱)
+ TASK_STATE_UPDATE_EVENT(16005), // 任务状态变化 (XPU→云端)(XPU→座舱)
+ ORDER_STATE_UPDATE_EVENT(16006), // 订单状态变化 (XPU→云端)(XPU→座舱)
+ POINT_ARRIVAL_STATUS_EVENT(16007), // 到达目标点状态 (XPU→云端)(XPU→座舱)
+ PICKUP_CONFIRMATION_EVENT(16008), // 用户上车确认 (XPU→云端)(XPU→座舱)
+ DROPOFF_INFO_EVENT(16009), // 用户下车信息 (XPU→云端)
+ NAVIGATION_DEVIATION_EVENT(16010), // 导航偏航 (XPU→云端)
+ EMERGENCY_STOP_EVENT(16011), // 急停 (XPU→云端)(XPU→座舱)
+ NAVIGATION_UPDATE_EVENT(16012), // 导航信息变化 (XPU→云端)
+ TASK_QUEUE_UPDATE_EVENT(16013), // XPU待执行任务队列 (XPU→云端)
+ SYSTEM_STATE_ANAPSHOT_SYNC_EVENT(16014),// 每次MQTT连接之后触发 (XPU→云端)
+ ORDER_STATE_UPDATE_TO_CDU_EVENT(16015); // 更新订单状态到CDU (XPU→云端)
+
+ private int value;
+
+ RTCmdType(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ public void setValue(int value) {
+ this.value = value;
+ }
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/RtMsgHeader.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/RtMsgHeader.java
new file mode 100644
index 0000000..2e1c014
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/RtMsgHeader.java
@@ -0,0 +1,34 @@
+package com.xiaopeng.api.vo.automaticPilot.proto.up;
+
+import lombok.Data;
+
+/**
+ * 消息头
+ */
+@Data
+public class RtMsgHeader {
+ /**
+ * 消息唯一ID(UUID)
+ */
+ private String msg_id;
+ /**
+ * 发送时间戳,单位ms
+ */
+ private Long timestamp;
+ /**
+ * 消息命令类型
+ */
+ private RTCmdType cmd;
+ /**
+ * 序列号
+ */
+ private Long sequence;
+ /**
+ * 请求或应答
+ */
+ private MessageType type;
+ /**
+ * 消息来源 {cloud,cdu,xpu}
+ */
+ private String source;
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/navigationDeviationEvent/NavigationDeviationEvent.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/navigationDeviationEvent/NavigationDeviationEvent.java
new file mode 100644
index 0000000..c0d8ddf
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/navigationDeviationEvent/NavigationDeviationEvent.java
@@ -0,0 +1,23 @@
+package com.xiaopeng.api.vo.automaticPilot.proto.up.navigationDeviationEvent;
+
+
+import lombok.Data;
+
+/**
+ * 导航偏航信息
+ */
+@Data
+public class NavigationDeviationEvent {
+ /**
+ * 事件类型
+ */
+ private RtEventType event_type;
+ /**
+ * 导航偏航消息
+ */
+ private NavigationDeviationMessage navigation_deviation_message;
+ /**
+ * 时间戳(毫秒)
+ */
+ private Long timestamp;
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/AbnormalReason.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/AbnormalReason.java
new file mode 100644
index 0000000..c373479
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/AbnormalReason.java
@@ -0,0 +1,27 @@
+package com.xiaopeng.api.vo.automaticPilot.proto.up.systemStatusXpu;
+
+/**
+ * 异常原因(Abnormal状态使用)
+ */
+public enum AbnormalReason {
+
+ ABNORMAL_REASON_UNSPECIFIED(0),
+ REMOTE_CONTROL_MODE(1), // 远程控车模式
+ MRM(2), // MRM(Minimal Risk Maneuver,最小风险机动)
+ E_STOP(3), // E-Stop(Emergency Stop,紧急停止)
+ FAULT(4); // 故障
+
+ private int value;
+
+ AbnormalReason(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ public void setValue(int value) {
+ this.value = value;
+ }
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/DrivingMode.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/DrivingMode.java
new file mode 100644
index 0000000..cba4711
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/DrivingMode.java
@@ -0,0 +1,26 @@
+package com.xiaopeng.api.vo.automaticPilot.proto.up.systemStatusXpu;
+
+/**
+ * 车辆驾驶模式枚举
+ */
+public enum DrivingMode {
+
+ DRIVING_MODE_UNSPECIFIED(0), // 未指定
+ AUTONOMOUS(1), // L4自动驾驶模式
+ REMOTE_DRIVING(2), // 云代驾远程控车模式
+ MANUAL_DRIVING(3); // 手动驾驶模式
+
+ private int value;
+
+ DrivingMode(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ public void setValue(int value) {
+ this.value = value;
+ }
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/GearLevel.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/GearLevel.java
new file mode 100644
index 0000000..42ed7e5
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/GearLevel.java
@@ -0,0 +1,27 @@
+package com.xiaopeng.api.vo.automaticPilot.proto.up.systemStatusXpu;
+
+/**
+ * 档位枚举
+ */
+public enum GearLevel {
+
+ GEAR_Invalid(0),
+ GEAR_D(1),
+ GEAR_N(2),
+ GEAR_R(3),
+ GEAR_P(4);
+
+ private int value;
+
+ GearLevel(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ public void setValue(int value) {
+ this.value = value;
+ }
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/ServiceAvailability.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/ServiceAvailability.java
new file mode 100644
index 0000000..260c4e0
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/ServiceAvailability.java
@@ -0,0 +1,25 @@
+package com.xiaopeng.api.vo.automaticPilot.proto.up.systemStatusXpu;
+
+/**
+ * 服务可用性(Normal状态使用)
+ */
+public enum ServiceAvailability {
+
+ SERVICE_AVAILABILITY_UNSPECIFIED(0),
+ ROBOTAXI_AVAILABLE(1), // Robotaxi可用
+ VPD_AVAILABLE(2); // VPD可用
+
+ private int value;
+
+ ServiceAvailability(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ public void setValue(int value) {
+ this.value = value;
+ }
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/SystemPhase.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/SystemPhase.java
new file mode 100644
index 0000000..5f8657f
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/SystemPhase.java
@@ -0,0 +1,27 @@
+package com.xiaopeng.api.vo.automaticPilot.proto.up.systemStatusXpu;
+
+/**
+ * 系统初始化阶段枚举
+ */
+public enum SystemPhase {
+
+ SYSTEM_STATUS_UNSPECIFIED(0), // 未指定状态
+ SYSTEM_INITIALIZING(1), // 系统初始化中
+ SYSTEM_SELF_CHECKING(2), // 系统自检中
+ SYSTEM_NORMAL(3), // 系统处于normal态
+ SYSTEM_ABNORMAL(4); // 系统处于abnormal态
+
+ private int value;
+
+ SystemPhase(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ public void setValue(int value) {
+ this.value = value;
+ }
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/SystemRuntimeStatus.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/SystemRuntimeStatus.java
new file mode 100644
index 0000000..c1a444a
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/SystemRuntimeStatus.java
@@ -0,0 +1,47 @@
+package com.xiaopeng.api.vo.automaticPilot.proto.up.systemStatusXpu;
+
+import lombok.Data;
+
+/**
+ * 系统运行状态消息
+ */
+@Data
+public class SystemRuntimeStatus {
+ /**
+ * 时间戳(毫秒)
+ */
+ private Long timestamp;
+ /**
+ * 当前登录用户ID
+ */
+ private Long uid;
+ /**
+ * 车辆状态
+ */
+ private VehicleStatus vehicle_status;
+ /**
+ * 系统状态
+ */
+ private SystemStatus system_status;
+ /**
+ * 驾驶模式
+ */
+ private DrivingMode driving_mode;
+ /**
+ * 正在运行订单信息
+ */
+ private OrderStatusInfo running_order_status_info;
+ /**
+ * RT行程信息
+ */
+ private RtTripInfo rt_trip_info;
+ /**
+ * 实时位姿
+ */
+ private RealtimePose pose;
+ /**
+ * 实时导航信息
+ */
+ private NavigationInfo navigation_info;
+}
+
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/SystemStatus.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/SystemStatus.java
new file mode 100644
index 0000000..1beb286
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/SystemStatus.java
@@ -0,0 +1,28 @@
+package com.xiaopeng.api.vo.automaticPilot.proto.up.systemStatusXpu;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 系统状态
+ */
+@Data
+public class SystemStatus {
+ /**
+ * 系统阶段
+ */
+ private SystemPhase system_phase;
+ /**
+ * Abnormal状态时的原因
+ */
+ private AbnormalReason abnormal_reason;
+ /**
+ * 可用服务列表
+ */
+ private List<ServiceAvailability> available_services;
+ /**
+ * 是否紧急状态
+ */
+ private Boolean is_emergency;
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/VehicleDynamicStatus.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/VehicleDynamicStatus.java
new file mode 100644
index 0000000..36402e0
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/VehicleDynamicStatus.java
@@ -0,0 +1,42 @@
+package com.xiaopeng.api.vo.automaticPilot.proto.up.systemStatusXpu;
+
+import lombok.Data;
+
+/**
+ * 车辆动态状态(实时变化)
+ */
+@Data
+public class VehicleDynamicStatus {
+ /**
+ * 档位
+ */
+ private GearLevel gear_level;
+ /**
+ * 方向盘转向角(度)
+ */
+ private Float steering_angle;
+ /**
+ * 仪表显示车速(m/s)
+ */
+ private Float speed;
+ /**
+ * 时间戳(毫秒)
+ */
+ private Long timestamp;
+ /**
+ * 油门开度(0-100%)
+ */
+ private Float throttle;
+ /**
+ * 刹车压力(0-100%)
+ */
+ private Float brake;
+ /**
+ * 手刹状态
+ */
+ private Boolean parking_brake;
+ /**
+ * 电池电量(0-100%)
+ */
+ private Float battery_level;
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/VehicleStaticInfo.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/VehicleStaticInfo.java
new file mode 100644
index 0000000..04d920b
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/VehicleStaticInfo.java
@@ -0,0 +1,22 @@
+package com.xiaopeng.api.vo.automaticPilot.proto.up.systemStatusXpu;
+
+import lombok.Data;
+
+/**
+ * 车辆静态信息(固定或很少变化)
+ */
+@Data
+public class VehicleStaticInfo {
+ /**
+ * XPU设备ID
+ */
+ private String xpu_id;
+ /**
+ * 需要信息安全确认
+ */
+ private String vin;
+ /**
+ * 时间戳(毫秒)
+ */
+ private Long timestamp;
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/VehicleStatus.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/VehicleStatus.java
new file mode 100644
index 0000000..9facb65
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/systemStatusXpu/VehicleStatus.java
@@ -0,0 +1,18 @@
+package com.xiaopeng.api.vo.automaticPilot.proto.up.systemStatusXpu;
+
+import lombok.Data;
+
+/**
+ * 车辆状态
+ */
+@Data
+public class VehicleStatus {
+ /**
+ * 静态信息
+ */
+ private VehicleStaticInfo static_info;
+ /**
+ * 动态状态
+ */
+ private VehicleDynamicStatus dynamic_status;
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/xpuNavigationRequest/NavigationRequest.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/xpuNavigationRequest/NavigationRequest.java
new file mode 100644
index 0000000..5b33c27
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/xpuNavigationRequest/NavigationRequest.java
@@ -0,0 +1,42 @@
+package com.xiaopeng.api.vo.automaticPilot.proto.up.xpuNavigationRequest;
+
+import lombok.Data;
+
+/**
+ * 请求导航消息
+ */
+@Data
+public class NavigationRequest {
+ /**
+ * 请求唯一ID
+ */
+ private String request_id;
+ /**
+ * 订单ID
+ */
+ private String order_id;
+ /**
+ * 任务ID
+ */
+ private String task_id;
+ /**
+ * 当前订单阶段
+ */
+ private OrderPhase order_phase;
+ /**
+ * 请求原因
+ */
+ private NavigationType navigation_type;
+ /**
+ * 当前位姿
+ */
+ private RealtimePose current_pose;
+ /**
+ * 目标点(经纬度)
+ */
+ private GeoPoint target_point;
+ /**
+ * 请求时间戳(毫秒)
+ */
+ private Long timestamp;
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/xpuNavigationRequest/NavigationType.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/xpuNavigationRequest/NavigationType.java
new file mode 100644
index 0000000..f2434db
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/xpuNavigationRequest/NavigationType.java
@@ -0,0 +1,27 @@
+package com.xiaopeng.api.vo.automaticPilot.proto.up.xpuNavigationRequest;
+
+/**
+ * 导航类型枚举
+ */
+public enum NavigationType {
+
+ NAVIGATION_TYPE_UNSPECIFIED(0), // 未指定
+ NAVIGATION_TYPE_DEVIATION(1), // 偏航(车辆偏离原路线)
+ NAVIGATION_TYPE_TO_PICKUP(2), // 接驾行程(前往上车点)
+ NAVIGATION_TYPE_TO_DESTINATION(3), // 送驾行程(前往目的地)
+ NAVIGATION_TYPE_CRUISE(4); // 巡游
+
+ private int value;
+
+ NavigationType(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ public void setValue(int value) {
+ this.value = value;
+ }
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/FareVo.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/FareVo.java
index a3d9d1d..ad2d6e1 100644
--- a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/FareVo.java
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/FareVo.java
@@ -32,4 +32,9 @@
@ApiModelProperty(value = "优惠券id")
private Long couponId;
+
+
+
+ @ApiModelProperty("系统优惠金额")
+ private Double systemDiscount;
}
diff --git a/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java b/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
index 3af09ed..1455bf1 100644
--- a/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
+++ b/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
@@ -46,6 +46,8 @@
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.data.mongodb.core.query.Update;
+import org.springframework.data.mongodb.core.query.UpdateDefinition;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
@@ -275,32 +277,56 @@
VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(vin)), VehiclePosition.class);
if (null == vehiclePosition) {
vehiclePosition = new VehiclePosition();
- }
- vehiclePosition.setVin(vin);
- vehiclePosition.setPoint(new GeoJsonPoint(longitude, latitude));
- vehiclePosition.setCourse(course);
- vehiclePosition.setAlt(alt);
- VehicleStatus vehicleStatus = systemRuntimeStatus.getVehicleStatus();
- //车辆动态信息
- VehicleDynamicStatus dynamicStatus = vehicleStatus.getDynamicStatus();
- vehiclePosition.setSpeed(dynamicStatus.getSpeed());
- vehiclePosition.setCurrentElectricity(dynamicStatus.getBmsSocDisp());
- vehiclePosition.setMileageRange(dynamicStatus.getDstBatDisp());
- //订单信息
- OrderStatusInfo runningOrderStatusInfo = systemRuntimeStatus.getRunningOrderStatusInfo();
- Long orderId = null;
- String order_id = runningOrderStatusInfo.getOrderId();
- vehiclePosition.setHasOrder(0);
- if (StringUtils.isNotEmpty(order_id)) {
- if (order_id.contains("XU")) {
- vehiclePosition.setHasOrder(1);
- orderId = Long.parseLong(order_id.substring(2));
- } else {
- orderId = Long.parseLong(order_id);
+ vehiclePosition.setVin(vin);
+ vehiclePosition.setPoint(new GeoJsonPoint(longitude, latitude));
+ vehiclePosition.setCourse(course);
+ vehiclePosition.setAlt(alt);
+ VehicleStatus vehicleStatus = systemRuntimeStatus.getVehicleStatus();
+ //车辆动态信息
+ VehicleDynamicStatus dynamicStatus = vehicleStatus.getDynamicStatus();
+ vehiclePosition.setSpeed(dynamicStatus.getSpeed());
+ vehiclePosition.setCurrentElectricity(dynamicStatus.getBmsSocDisp());
+ vehiclePosition.setMileageRange(dynamicStatus.getDstBatDisp());
+ //订单信息
+ OrderStatusInfo runningOrderStatusInfo = systemRuntimeStatus.getRunningOrderStatusInfo();
+ Long orderId = null;
+ String order_id = runningOrderStatusInfo.getOrderId();
+ vehiclePosition.setHasOrder(0);
+ if (StringUtils.isNotEmpty(order_id)) {
+ if (order_id.contains("XU")) {
+ vehiclePosition.setHasOrder(1);
+ orderId = Long.parseLong(order_id.substring(2));
+ } else {
+ orderId = Long.parseLong(order_id);
+ }
}
+ vehiclePosition.setOrderId(orderId);
+ mongoTemplate.save(vehiclePosition);
+ }else{
+ VehicleDynamicStatus dynamicStatus = vehicleStatus.getDynamicStatus();
+ String order_id = runningOrderStatusInfo.getOrderId();
+ Long orderId = null;
+ Integer hasOrder = 0;
+ if (StringUtils.isNotEmpty(order_id)) {
+ if (order_id.contains("XU")) {
+ hasOrder = 1;
+ orderId = Long.parseLong(order_id.substring(2));
+ } else {
+ orderId = Long.parseLong(order_id);
+ }
+ }
+ vehiclePosition.setOrderId(orderId);
+ Update update = new Update()
+ .set("point", new GeoJsonPoint(longitude, latitude))
+ .set("course", course)
+ .set("alt", alt)
+ .set("speed", dynamicStatus.getSpeed())
+ .set("currentElectricity", dynamicStatus.getBmsSocDisp())
+ .set("mileageRange", dynamicStatus.getDstBatDisp())
+ .set("hasOrder", hasOrder)
+ .set("orderId", orderId);
+ mongoTemplate.updateFirst(new Query(Criteria.where("vin").is(vin)), update, VehiclePosition.class);
}
- vehiclePosition.setOrderId(orderId);
- mongoTemplate.save(vehiclePosition);
//调用推送服务接口
if (null != orderId) {
RtTripInfo rtTripInfo = systemRuntimeStatus.getRtTripInfo();
diff --git a/xp-robotaxi-automatic-pilot-boot/src/test/java/com/ruoyi/account/RuoYiAccountApplicationTests.java b/xp-robotaxi-automatic-pilot-boot/src/test/java/com/ruoyi/account/RuoYiAccountApplicationTests.java
new file mode 100644
index 0000000..9302669
--- /dev/null
+++ b/xp-robotaxi-automatic-pilot-boot/src/test/java/com/ruoyi/account/RuoYiAccountApplicationTests.java
@@ -0,0 +1,30 @@
+//package com.ruoyi.account;
+//
+//import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+//import com.ruoyi.common.security.service.TokenService;
+//import com.ruoyi.system.api.model.LoginUserApplet;
+//import org.junit.jupiter.api.Test;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.boot.test.context.SpringBootTest;
+//
+//import java.util.HashMap;
+//import java.util.Map;
+//
+//@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = RuoYiAccountApplication.class)
+//public class RuoYiAccountApplicationTests {
+// @Autowired
+// private TokenService tokenService;
+//
+// @Test
+// public void test(){
+// LoginUserApplet loginUserApplet = new LoginUserApplet();
+// loginUserApplet.setUserId(1839480334642704385L);
+// loginUserApplet.setUserIdStr("1839480334642704385");
+// loginUserApplet.setName("158****3127");
+// loginUserApplet.setPhone("15828353127");
+// loginUserApplet.setAvatar("");
+// loginUserApplet.setAddress("");
+// Map<String, Object> tokenInfos = new HashMap<>();
+// System.err.println(tokenService.createTokenApplet(loginUserApplet));
+// }
+//}
diff --git a/xp-robotaxi-gateway-boot/src/main/java/com/xiaopeng/gateway/filter/CacheRequestFilter.java b/xp-robotaxi-gateway-boot/src/main/java/com/xiaopeng/gateway/filter/CacheRequestFilter.java
index 1f37289..8ed4bd5 100644
--- a/xp-robotaxi-gateway-boot/src/main/java/com/xiaopeng/gateway/filter/CacheRequestFilter.java
+++ b/xp-robotaxi-gateway-boot/src/main/java/com/xiaopeng/gateway/filter/CacheRequestFilter.java
@@ -8,6 +8,7 @@
import org.springframework.cloud.gateway.filter.OrderedGatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
+import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
@@ -52,6 +53,11 @@
if (method == null || method == HttpMethod.GET || method == HttpMethod.DELETE) {
return chain.filter(exchange);
}
+ String contentType = exchange.getRequest().getHeaders().getFirst(HttpHeaders.CONTENT_TYPE);
+ // multipart(二进制)请求不缓存body,避免大文件带来内存/性能风险
+ if (contentType != null && contentType.toLowerCase().startsWith("multipart/")) {
+ return chain.filter(exchange);
+ }
return ServerWebExchangeUtils.cacheRequestBodyAndRequest(exchange, (serverHttpRequest) -> {
if (serverHttpRequest == exchange.getRequest()) {
return chain.filter(exchange);
@@ -72,4 +78,4 @@
this.order = order;
}
}
-}
\ No newline at end of file
+}
diff --git a/xp-robotaxi-gateway-boot/src/main/java/com/xiaopeng/gateway/filter/RequestParamGlobalFilter.java b/xp-robotaxi-gateway-boot/src/main/java/com/xiaopeng/gateway/filter/RequestParamGlobalFilter.java
index b7d3dce..e21c05c 100644
--- a/xp-robotaxi-gateway-boot/src/main/java/com/xiaopeng/gateway/filter/RequestParamGlobalFilter.java
+++ b/xp-robotaxi-gateway-boot/src/main/java/com/xiaopeng/gateway/filter/RequestParamGlobalFilter.java
@@ -10,14 +10,13 @@
import org.springframework.core.io.buffer.*;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
+import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
-
-import java.nio.charset.StandardCharsets;
/**
* 跨站脚本过滤器
@@ -44,10 +43,30 @@
if(method != HttpMethod.POST){
return chain.filter(exchange);
}
+ String contentType = request.getHeaders().getFirst(HttpHeaders.CONTENT_TYPE);
+ // multipart(二进制)请求禁止读取/重写body,否则会导致文件内容损坏
+ if (StringUtils.isNotEmpty(contentType) && StringUtils.startsWithIgnoreCase(contentType, "multipart/")) {
+ return chain.filter(exchange);
+ }
+ // 非JSON请求不处理,避免误伤其他content-type
+ if (!isJsonContentType(contentType)) {
+ return chain.filter(exchange);
+ }
ServerHttpRequestDecorator httpRequestDecorator = requestDecorator(exchange);
return chain.filter(exchange.mutate().request(httpRequestDecorator).build());
}
-
+
+ private boolean isJsonContentType(String contentType) {
+ if (StringUtils.isEmpty(contentType)) {
+ return false;
+ }
+ if (StringUtils.startsWithIgnoreCase(contentType, MediaType.APPLICATION_JSON_VALUE)) {
+ return true;
+ }
+ // 兼容 application/*+json
+ return StringUtils.containsIgnoreCase(contentType, "+json");
+ }
+
private ServerHttpRequestDecorator requestDecorator(ServerWebExchange exchange) {
ServerHttpRequestDecorator serverHttpRequestDecorator = new ServerHttpRequestDecorator(exchange.getRequest()) {
@@ -60,12 +79,10 @@
byte[] content = new byte[join.readableByteCount()];
join.read(content);
DataBufferUtils.release(join);
- String bodyStr = new String(content, StandardCharsets.UTF_8);
// 转成字节
- byte[] bytes = bodyStr.getBytes();
NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);
- DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length);
- buffer.write(bytes);
+ DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(content.length);
+ buffer.write(content);
return buffer;
});
}
diff --git a/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java b/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java
index 50ed32a..13caed5 100644
--- a/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java
+++ b/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java
@@ -349,10 +349,16 @@
if (userCouponVo != null) {
fareVo.setDiscountAmount(userCouponVo.getMoney());
fareVo.setFinalFare(fareVo.getOriginalFare() - fareVo.getDiscountAmount());
+ if(fareVo.getFinalFare()>0){
+ fareVo.setSystemDiscount(fareVo.getFinalFare());
+ fareVo.setFinalFare(0.0);
+ }
fareVo.setCouponId(userCouponVo.getId());
} else {
fareVo.setDiscountAmount(0.0);
fareVo.setFinalFare(fareVo.getOriginalFare());
+ fareVo.setSystemDiscount(fareVo.getFinalFare());
+ fareVo.setFinalFare(0.0);
}
// 10. 检查等待时间
diff --git a/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/utils/XpPricingUtil.java b/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/utils/XpPricingUtil.java
index c980f83..790a763 100644
--- a/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/utils/XpPricingUtil.java
+++ b/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/utils/XpPricingUtil.java
@@ -262,15 +262,26 @@
// 先判断今日是否节假日
boolean holiday = holidayUtil.isHoliday();
if (holiday) {
- if (realDistance > rule.getDouble("num6")) {
+ if (realDistance > rule.getDouble("num6") && realDistance < rule.getDouble("num7")) {
longDistanceOne = rule.getDouble("num32") * (realDistance - rule.getDouble("num6"));
longDistanceOne = new BigDecimal(longDistanceOne).setScale(2,RoundingMode.HALF_UP).doubleValue();
-
}
- if (realDistance > rule.getDouble("num9")) {
+ if (realDistance > rule.getDouble("num7")) {
+ longDistanceOne = rule.getDouble("num32") * (rule.getDouble("num7") - rule.getDouble("num6"));
+ longDistanceOne = new BigDecimal(longDistanceOne).setScale(2,RoundingMode.HALF_UP).doubleValue();
+ }
+
+
+ if (realDistance > rule.getDouble("num9") && realDistance < rule.getDouble("num10")) {
longDistanceTwo = rule.getDouble("num33") * (realDistance - rule.getDouble("num9"));
longDistanceTwo = new BigDecimal(longDistanceTwo).setScale(2,RoundingMode.HALF_UP).doubleValue();
}
+ if (realDistance > rule.getDouble("num10")) {
+ longDistanceTwo = rule.getDouble("num33") * (rule.getDouble("num10") - rule.getDouble("num9"));
+ longDistanceTwo = new BigDecimal(longDistanceTwo).setScale(2,RoundingMode.HALF_UP).doubleValue();
+ }
+
+
if (realDistance > rule.getDouble("num12")) {
longDistanceThree = rule.getDouble("num34") * (realDistance - rule.getDouble("num12"));
longDistanceThree = new BigDecimal(longDistanceThree).setScale(2,RoundingMode.HALF_UP).doubleValue();
@@ -301,14 +312,26 @@
} else {
if (date.getTime() > calendarNight.getTimeInMillis() && date.getTime() < calendar.getTimeInMillis()) {
- if (realDistance > rule.getDouble("num6")) {
+ if (realDistance > rule.getDouble("num6") && realDistance < rule.getDouble("num7")) {
longDistanceOne = rule.getDouble("num18") * (realDistance - rule.getDouble("num6"));
longDistanceOne = new BigDecimal(longDistanceOne).setScale(2,RoundingMode.HALF_UP).doubleValue();
}
- if (realDistance > rule.getDouble("num9")) {
+ if (realDistance > rule.getDouble("num7")) {
+ longDistanceOne = rule.getDouble("num18") * (rule.getDouble("num7") - rule.getDouble("num6"));
+ longDistanceOne = new BigDecimal(longDistanceOne).setScale(2,RoundingMode.HALF_UP).doubleValue();
+ }
+
+
+ if (realDistance > rule.getDouble("num9") && realDistance < rule.getDouble("num10")) {
longDistanceTwo = rule.getDouble("num19") * (realDistance - rule.getDouble("num9"));
longDistanceTwo = new BigDecimal(longDistanceTwo).setScale(2,RoundingMode.HALF_UP).doubleValue();
}
+ if (realDistance > rule.getDouble("num10")) {
+ longDistanceTwo = rule.getDouble("num19") * (rule.getDouble("num10") - rule.getDouble("num9"));
+ longDistanceTwo = new BigDecimal(longDistanceTwo).setScale(2,RoundingMode.HALF_UP).doubleValue();
+ }
+
+
if (realDistance > rule.getDouble("num12")) {
longDistanceThree = rule.getDouble("num20") * (realDistance - rule.getDouble("num12"));
longDistanceThree = new BigDecimal(longDistanceThree).setScale(2,RoundingMode.HALF_UP).doubleValue();
@@ -360,14 +383,27 @@
e2.set(Calendar.MINUTE, Integer.valueOf(rule.getString("num22").split(" - ")[1].split(":")[1]));
//高峰时段处理逻辑
if ((date.getTime() > calendarStart.getTimeInMillis() && date.getTime() < calendarEnd.getTimeInMillis()) || (date.getTime() > s2.getTimeInMillis() && date.getTime() < e2.getTimeInMillis())) {
- if (realDistance > rule.getDouble("num6")) {
+ if (realDistance > rule.getDouble("num6") && realDistance < rule.getDouble("num7")) {
longDistanceOne = rule.getDouble("num26") * (realDistance - rule.getDouble("num6"));
longDistanceOne = new BigDecimal(longDistanceOne).setScale(2,RoundingMode.HALF_UP).doubleValue();
}
- if (realDistance > rule.getDouble("num9")) {
+ if (realDistance > rule.getDouble("num7")) {
+ longDistanceOne = rule.getDouble("num26") * (rule.getDouble("num7") - rule.getDouble("num6"));
+ longDistanceOne = new BigDecimal(longDistanceOne).setScale(2,RoundingMode.HALF_UP).doubleValue();
+ }
+
+
+
+ if (realDistance > rule.getDouble("num9") && realDistance < rule.getDouble("num10")) {
longDistanceTwo = rule.getDouble("num27") * (realDistance - rule.getDouble("num9"));
longDistanceTwo = new BigDecimal(longDistanceTwo).setScale(2,RoundingMode.HALF_UP).doubleValue();
}
+ if (realDistance > rule.getDouble("num10")) {
+ longDistanceTwo = rule.getDouble("num27") * (rule.getDouble("num10") - rule.getDouble("num9"));
+ longDistanceTwo = new BigDecimal(longDistanceTwo).setScale(2,RoundingMode.HALF_UP).doubleValue();
+ }
+
+
if (realDistance > rule.getDouble("num12")) {
longDistanceThree = rule.getDouble("num28") * (realDistance - rule.getDouble("num12"));
longDistanceThree = new BigDecimal(longDistanceThree).setScale(2,RoundingMode.HALF_UP).doubleValue();
@@ -401,14 +437,28 @@
} else {
//其他时间段的计算
- if (realDistance > rule.getDouble("num6")) {
+ if (realDistance > rule.getDouble("num6") && realDistance < rule.getDouble("num7")) {
longDistanceOne = rule.getDouble("num8") * (realDistance - rule.getDouble("num6"));
longDistanceOne = new BigDecimal(longDistanceOne).setScale(2,RoundingMode.HALF_UP).doubleValue();
}
- if (realDistance > rule.getDouble("num9")) {
+ if (realDistance > rule.getDouble("num7")) {
+ longDistanceOne = rule.getDouble("num8") * (rule.getDouble("num7") - rule.getDouble("num6"));
+ longDistanceOne = new BigDecimal(longDistanceOne).setScale(2,RoundingMode.HALF_UP).doubleValue();
+ }
+
+
+
+
+ if (realDistance > rule.getDouble("num9") && realDistance < rule.getDouble("num10")) {
longDistanceTwo = rule.getDouble("num11") * (realDistance - rule.getDouble("num9"));
longDistanceTwo = new BigDecimal(longDistanceTwo).setScale(2,RoundingMode.HALF_UP).doubleValue();
}
+ if (realDistance > rule.getDouble("num10")) {
+ longDistanceTwo = rule.getDouble("num11") * (rule.getDouble("num10") - rule.getDouble("num9"));
+ longDistanceTwo = new BigDecimal(longDistanceTwo).setScale(2,RoundingMode.HALF_UP).doubleValue();
+ }
+
+
if (realDistance > rule.getDouble("num12")) {
longDistanceThree = rule.getDouble("num13") * (realDistance - rule.getDouble("num12"));
longDistanceThree = new BigDecimal(longDistanceThree).setScale(2,RoundingMode.HALF_UP).doubleValue();
diff --git a/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpSchedulingDetailController.java b/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpSchedulingDetailController.java
index a1e7348..11274b6 100644
--- a/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpSchedulingDetailController.java
+++ b/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpSchedulingDetailController.java
@@ -61,7 +61,7 @@
@ApiOperation(value = "排班考勤-排班计划管理-保存排班数据", response = XpErrorType.class, tags = "管理后台-运维执行")
@PostMapping("/api/v1/scheduling/saveSchedulingDetail")
public R<?> saveSchedulingDetail(@RequestBody SaveSchedulingVo vo){
- SysUser sysUser = SecurityUtils.getLoginUser().getSysUser();
+ SysUser sysUser = tokenService.getLoginUser().getSysUser();
return xpSchedulingDetailService.saveSchedulingDetail(vo, sysUser.getId());
}
diff --git a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpMapController.java b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpMapController.java
index 1365c3b..baa9153 100644
--- a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpMapController.java
+++ b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpMapController.java
@@ -60,22 +60,36 @@
List<String> operatingArea = xpGeoFencingPolygonService.findFencesContainingPoint(startPoint, "operating_area", "points");
String fenceId = operatingArea.get(0);
- List<Document> pointsInFence = xpGeoFencingPolygonService.findPointsByParentId(fenceId, "parentId", "prohibited_area");
+ List<Document> pointsInFence = xpGeoFencingPolygonService.findPointsByParentId(fenceId, "fenceId", "prohibited_area");
// 避让区域
ArrayList<String> pointStrParam = new ArrayList<>();
try {
for (Document document : pointsInFence) {
- List<GeoPoint> points = document.getList("points", GeoPoint.class);
- // 一个区域的点位
- ArrayList<String> pointStr = new ArrayList<>();
- for (GeoPoint point : points) {
- pointStr.add( point.getLongitude()+","+point.getLatitude());
- }
- if(!pointStr.isEmpty()){
- pointStrParam.add(String.join(";", pointStr));
- }
+ // 获取points字段(它是GeoJSON对象)
+ Document geoJsonDoc = document.get("points", Document.class);
+ if (geoJsonDoc != null && "Polygon".equals(geoJsonDoc.getString("type"))) {
+ // 获取coordinates数组
+ List<List<List<Double>>> coordinates = (List<List<List<Double>>>) geoJsonDoc.get("coordinates");
+
+ if (coordinates != null && !coordinates.isEmpty()) {
+ // 获取第一个多边形环(通常只有一个)
+ List<List<Double>> polygonPoints = coordinates.get(0);
+
+ // 转换为经纬度字符串
+ ArrayList<String> pointStr = new ArrayList<>();
+ for (List<Double> point : polygonPoints) {
+ if (point.size() >= 2) {
+ pointStr.add(point.get(0) + "," + point.get(1));
+ }
+ }
+
+ if (!pointStr.isEmpty()) {
+ pointStrParam.add(String.join(";", pointStr));
+ }
+ }
+ }
}
RouteVo routeVo = gdMapGeocodingUtil.getDistanceAndTime(dto.getOrigin(), dto.getDestination(), String.join("|", pointStrParam), fenceId,dto.getRoutePlanRule());
if(routeVo==null){
diff --git a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpPointManagementController.java b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpPointManagementController.java
index 17a3d9e..44bb695 100644
--- a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpPointManagementController.java
+++ b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpPointManagementController.java
@@ -144,6 +144,7 @@
public R enableDisable(@RequestBody XpPointEnableDisableDto dto) {
XpPoint xpPoint = xpPointService.getById(dto.getId());
xpPoint.setOperationStatus(dto.getOperationStatus());
+ xpPoint.setVerificationStatus(dto.getVerificationStatus());
xpPoint.setElectronicAreaId(null);
xpPointService.updateById(xpPoint);
return R.ok();
diff --git a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpOpenCityServiceImpl.java b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpOpenCityServiceImpl.java
index 009257b..9e9035a 100644
--- a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpOpenCityServiceImpl.java
+++ b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpOpenCityServiceImpl.java
@@ -105,7 +105,6 @@
public void add(OpenCityAddDTO dto) {
checkIfExist(dto, null);
XpOpenCity xpOpenCity = BeanUtil.copyProperties(dto, XpOpenCity.class);
- xpOpenCity.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
save(xpOpenCity);
}
@@ -129,7 +128,6 @@
public void edit(OpenCityEditDTO dto) {
checkIfExist(dto, dto.getId());
XpOpenCity xpOpenCity = BeanUtil.copyProperties(dto, XpOpenCity.class);
- xpOpenCity.setUpdateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
updateById(xpOpenCity);
}
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpAppVersionServiceImpl.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpAppVersionServiceImpl.java
index 50321c5..7cadc1c 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpAppVersionServiceImpl.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpAppVersionServiceImpl.java
@@ -91,7 +91,6 @@
if (Objects.nonNull(latestVersion)) {
latestVersionCode = latestVersion.getVersionCode();
}
- appVersion.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
appVersion.setVersionCode(latestVersionCode + 1); // 版本号自增
save(appVersion);
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpCruisePlanServiceImpl.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpCruisePlanServiceImpl.java
index 720bac7..cf628db 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpCruisePlanServiceImpl.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpCruisePlanServiceImpl.java
@@ -88,7 +88,6 @@
validateVehicleBind(vehicleIdSet, null);
XpCruisePlan plan = new XpCruisePlan();
plan.setPlanName(dto.getPlanName());
- plan.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
boolean planSaved = save(plan);
if (!planSaved || plan.getId() == null) {
throw new ServiceException("新增巡游计划失败", I18nKeyConstant.CRUISE_PLAN_ADD_FAIL);
@@ -120,7 +119,6 @@
Set<Long> vehicleIdSet = validateVehicleList(dto.getVehicleIdList());
validateVehicleBind(vehicleIdSet, dto.getId());
plan.setPlanName(dto.getPlanName());
- plan.setUpdateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
boolean planUpdated = updateById(plan);
if (!planUpdated) {
throw new ServiceException("编辑巡游计划失败", I18nKeyConstant.CRUISE_PLAN_EDIT_FAIL);
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpOpenCityServiceImpl.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpOpenCityServiceImpl.java
index 42b2d66..d76abcc 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpOpenCityServiceImpl.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpOpenCityServiceImpl.java
@@ -105,7 +105,6 @@
public void add(OpenCityAddDTO dto) {
checkIfExist(dto, null);
XpOpenCity xpOpenCity = BeanUtil.copyProperties(dto, XpOpenCity.class);
- xpOpenCity.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
save(xpOpenCity);
}
@@ -129,7 +128,6 @@
public void edit(OpenCityEditDTO dto) {
checkIfExist(dto, dto.getId());
XpOpenCity xpOpenCity = BeanUtil.copyProperties(dto, XpOpenCity.class);
- xpOpenCity.setUpdateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
updateById(xpOpenCity);
}
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpRoutePlanServiceImpl.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpRoutePlanServiceImpl.java
index 0812e3c..ef6c539 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpRoutePlanServiceImpl.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpRoutePlanServiceImpl.java
@@ -64,7 +64,6 @@
routePlan.setCityCode(openCity.getCityCode());
routePlan.setDistrictName(openCity.getDistrictName());
routePlan.setDistrictCode(openCity.getDistrictCode());
- routePlan.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
// 5. 保存到数据库
this.save(routePlan);
}
@@ -96,7 +95,7 @@
routePlan.setCityCode(openCity.getCityCode());
routePlan.setDistrictName(openCity.getDistrictName());
routePlan.setDistrictCode(openCity.getDistrictCode());
- routePlan.setUpdateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
+// routePlan.setUpdateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
// 5. 保存更新
this.updateById(routePlan);
}
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/TaskOrderUtil.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/TaskOrderUtil.java
index b8ab400..e56e360 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/TaskOrderUtil.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/TaskOrderUtil.java
@@ -213,7 +213,12 @@
// 最终没找到车
// redisService.popFirstElement(quoteName);
// 取消订单
- xpOrderClient.cancelOrder(orderId);
+ R<XpOrder> xpOrderR = xpOrderClient.queryOrderById(Long.valueOf(orderId));
+ if(xpOrderR.getCode()==200){
+ if (xpOrderR.getData().getStatus()==1) {
+ xpOrderClient.cancelOrder(orderId);
+ }
+ }
}
diff --git a/xp-robotaxi-operation-boot/src/main/resources/i18n/messages.properties b/xp-robotaxi-operation-boot/src/main/resources/i18n/messages.properties
index 15509d6..bd3033f 100644
--- a/xp-robotaxi-operation-boot/src/main/resources/i18n/messages.properties
+++ b/xp-robotaxi-operation-boot/src/main/resources/i18n/messages.properties
@@ -34,3 +34,4 @@
cruise.plan.vehicle.already.bound=车辆已关联其他巡游计划
cruise.plan.add.fail=新增巡游计划失败
cruise.plan.edit.fail=编辑巡游计划失败
+account.format.error=以下帐号格式不正确:{0}
diff --git a/xp-robotaxi-operation-boot/src/main/resources/i18n/messages_en_US.properties b/xp-robotaxi-operation-boot/src/main/resources/i18n/messages_en_US.properties
index 7dce07a..115e31d 100644
--- a/xp-robotaxi-operation-boot/src/main/resources/i18n/messages_en_US.properties
+++ b/xp-robotaxi-operation-boot/src/main/resources/i18n/messages_en_US.properties
@@ -27,3 +27,4 @@
cruise.plan.vehicle.duplicate=Duplicate vehicle ID
cruise.plan.vehicle.already.bound=Vehicle [{0}] has been associated with other cruising plans
cruise.plan.add.fail=The new cruise plan failed
+account.format.error=The following account format is incorrect: {0}
diff --git a/xp-robotaxi-operation-boot/src/main/resources/i18n/messages_zh_CN.properties b/xp-robotaxi-operation-boot/src/main/resources/i18n/messages_zh_CN.properties
index 46a4ca9..d9e6cdf 100644
--- a/xp-robotaxi-operation-boot/src/main/resources/i18n/messages_zh_CN.properties
+++ b/xp-robotaxi-operation-boot/src/main/resources/i18n/messages_zh_CN.properties
@@ -27,3 +27,4 @@
cruise.plan.vehicle.duplicate=车辆ID重复
cruise.plan.vehicle.already.bound=车辆[{0}]已关联其他巡游计划
cruise.plan.add.fail=新增巡游计划失败
+account.format.error=以下帐号格式不正确:{0}
diff --git a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/jobs/OrderCancelJob.java b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/jobs/OrderCancelJob.java
index db4eea8..ae8f352 100644
--- a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/jobs/OrderCancelJob.java
+++ b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/jobs/OrderCancelJob.java
@@ -35,7 +35,7 @@
try {
log.info("开始执行订单取消任务");
XpOrder xpOrder = xpOrderService.getById(orderId);
- if(Objects.nonNull(xpOrder)){
+ if(Objects.nonNull(xpOrder) && xpOrder.getStatus()==4){
log.info("订单取消开始");
xpOrderService.cancelOrder(String.valueOf(xpOrder.getId()));
log.info("订单取消状态修改完成");
diff --git a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
index 829c92a..2b0f4eb 100644
--- a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
+++ b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -444,9 +444,9 @@
throw new ServiceException("当前订单状态不允许取消,只有待接单、待出发、接驾中状态的订单可以取消", I18nKeyConstant.ORDER_CANCEL_FAILED);
}
} else {
- // 关闭订单:只有待付款(8)、待评价(9)状态可以关闭
- if (currentStatus != 7 && currentStatus != 8 && currentStatus != 9) {
- throw new ServiceException("当前订单状态不允许关闭,只有待付款、待评价状态的订单可以关闭", I18nKeyConstant.ORDER_CLOSE_FAILED);
+ // 关闭订单:0=已取消,1=待接单,2=待出发,3=接驾中,4=待客上车,5=乘客已上车,6=服务中 状态可以关闭
+ if (currentStatus == 7 || currentStatus == 8 || currentStatus == 9 || currentStatus == 10) {
+ throw new ServiceException("当前订单状态不允许关闭", I18nKeyConstant.ORDER_CLOSE_FAILED);
}
}
@@ -859,6 +859,9 @@
List<XpHistoryStartPointsVo> data = r.getData();
for (XpHistoryStartPointsVo datum : data) {
+ // 保留2位数小数
+ Double distance = datum.getDistance();
+ datum.setDistance(BigDecimal.valueOf(distance).setScale(2, RoundingMode.HALF_UP).doubleValue());
xpOrders.stream().filter(e->e.getEndPointId().equals(datum.getId())).findFirst().ifPresent(
order->{
datum.setNum(order.getNum());
@@ -887,6 +890,9 @@
List<XpHistoryEndPointsVo> data = r.getData();
for (XpHistoryEndPointsVo datum : data) {
+ // 保留2位数小数
+ Double distance = datum.getDistance();
+ datum.setDistance(BigDecimal.valueOf(distance).setScale(2, RoundingMode.HALF_UP).doubleValue());
xpOrders.stream().filter(e->e.getEndPointId().equals(datum.getId())).findFirst().ifPresent(
order->{
datum.setNum(order.getNum());
@@ -1155,6 +1161,7 @@
xpOrder.setArrivalTime(LocalDateTime.now());
break;
case 5:
+ xpOrder.setBoardingTime(LocalDateTime.now());
// 删除定时任务job
QuartzManager.removeJob((OrderCancelJob.name + xpOrder.getId()).toUpperCase(), TimeJobType.ORDER_CANCEL);
break;
diff --git a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/constant/I18nKeyConstant.java b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/constant/I18nKeyConstant.java
index b754313..a954298 100644
--- a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/constant/I18nKeyConstant.java
+++ b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/constant/I18nKeyConstant.java
@@ -14,6 +14,10 @@
// ========== 车辆导入相关 ==========
String VEHICLE_IMPORT_FAILED = "vehicle.import.failed";
String VEHICLE_IMPORT_DATA_EMPTY = "vehicle.import.data.empty";
+ String VEHICLE_IMPORT_FIELDS_REQUIRED = "vehicle.import.fields.required";
+
+ // ========== 车队删除相关 ==========
+ String FLEET_DELETE_HAS_BOUND_VEHICLE_OR_USER = "fleet.delete.has.bound.vehicle.or.user";
// ========== 车辆运营相关 ==========
String VEHICLE_OPERATION_INFO_INCOMPLETE = "vehicle.operation.info.incomplete";
diff --git a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpFleetController.java b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpFleetController.java
index bf12bf4..944ec9f 100644
--- a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpFleetController.java
+++ b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpFleetController.java
@@ -198,7 +198,6 @@
/**
* 根据ID列表批量查询车队信息(内部接口)
*
- * @param ids 车队ID列表
* @return 车队列表
*/
@ApiOperation(value = "获取车队不分页列表", tags = {"管理后台-车队管理"})
diff --git a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java
index 363a498..6f65c23 100644
--- a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java
+++ b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java
@@ -16,7 +16,6 @@
import com.xiaopeng.api.feignClient.maintenance.XpTaskClient;
import com.xiaopeng.api.feignClient.maintenance.XpTaskRuleClient;
import com.xiaopeng.api.feignClient.maintenance.XpVehiclePreparationClient;
-import com.xiaopeng.api.feignClient.order.XpOrderClient;
import com.xiaopeng.api.model.maintenance.XpTask;
import com.xiaopeng.api.model.maintenance.XpTaskRule;
import com.xiaopeng.api.model.vehicleConvoy.XpFleetVehicle;
@@ -41,9 +40,12 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.openxml4j.exceptions.NotOfficeXmlFileException;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
+import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Lazy;
+import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
@@ -51,15 +53,15 @@
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
-import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
+import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
-import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@@ -87,6 +89,7 @@
private final XpTaskClient xpTaskClient;
private final XpTaskRuleClient xpTaskRuleClient;
private final MongoTemplate mongoTemplate;
+ private final MessageSource messageSource;
/**
* 根据ID列表批量查询车辆信息(内部接口)
*
@@ -120,10 +123,12 @@
@GetMapping("/inner/vehicle/queryById")
public R<XpVehicle> queryById(@RequestParam Long id) {
XpVehicle xpVehicle = xpVehicleService.getById(id);
- // 获取车队
- XpFleetVehicle xpFleetVehicle = vehicleService.getOne(new LambdaQueryWrapper<XpFleetVehicle>().eq(XpFleetVehicle::getVehicleId, xpVehicle.getId()));
- if (Objects.nonNull(xpFleetVehicle)) {
- xpVehicle.setFleetId(xpFleetVehicle.getFleetId());
+ if (Objects.nonNull(xpVehicle)) {
+ // 获取车队
+ XpFleetVehicle xpFleetVehicle = vehicleService.getOne(new LambdaQueryWrapper<XpFleetVehicle>().eq(XpFleetVehicle::getVehicleId, xpVehicle.getId()));
+ if (Objects.nonNull(xpFleetVehicle)) {
+ xpVehicle.setFleetId(xpFleetVehicle.getFleetId());
+ }
}
return R.ok(xpVehicle);
}
@@ -224,7 +229,7 @@
@PostMapping("/api/v1/vehicle/importTemplate")
public void importTemplate() {
// 1. 查询导出数据
- Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), XpVehicleExportExcel.class, new ArrayList<>());
+ Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), XpVehicleImportExcel.class, new ArrayList<>());
// 4. 输出到响应流
HttpServletResponse response = WebUtils.response();
@@ -232,7 +237,7 @@
response.setCharacterEncoding("utf-8");
ServletOutputStream outputStream = null;
try {
- String fileName = URLEncoder.encode("在库车辆导入模板.xls", "utf-8");
+ String fileName = URLEncoder.encode("在库车辆导入模板.xlsx", "utf-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName);
outputStream = response.getOutputStream();
workbook.write(outputStream);
@@ -266,6 +271,9 @@
importList = ExcelImportUtil.importExcel(inputStream, XpVehicleImportExcel.class, params);
} catch (Exception e) {
log.error("车辆导入失败:{}", e.getMessage(), e);
+ if (e instanceof NotOfficeXmlFileException || e.getCause() instanceof NotOfficeXmlFileException) {
+ throw new ServiceException("上传文件不是有效的Excel(.xlsx)文件!", I18nKeyConstant.VEHICLE_IMPORT_FAILED);
+ }
throw new ServiceException("车辆导入失败!", I18nKeyConstant.VEHICLE_IMPORT_FAILED);
} finally {
if (inputStream != null) {
@@ -279,10 +287,60 @@
if (CollectionUtils.isEmpty(importList)) {
throw new ServiceException("导入数据为空!", I18nKeyConstant.VEHICLE_IMPORT_DATA_EMPTY);
}
+ validateImportRequiredFields(importList, params.getHeadRows());
+ uploadVehiclePicture(importList);
xpVehicleService.importVehicles(importList);
return R.ok();
}
+ private void validateImportRequiredFields(List<XpVehicleImportExcel> importList, int headRows) {
+ for (int index = 0; index < importList.size(); index++) {
+ XpVehicleImportExcel row = importList.get(index);
+ List<String> missingFields = new ArrayList<>();
+ addIfBlank(missingFields, row.getVehicleCode(), "vehicle.import.field.vehicleCode");
+ addIfBlank(missingFields, row.getVehicleVin(), "vehicle.import.field.vehicleVin");
+ addIfBlank(missingFields, row.getPlateNumber(), "vehicle.import.field.plateNumber");
+ addIfBlank(missingFields, row.getVehicleModel(), "vehicle.import.field.vehicleModel");
+ addIfBlank(missingFields, row.getVehicleColor(), "vehicle.import.field.vehicleColor");
+ addIfBlank(missingFields, row.getVehiclePictures(), "vehicle.import.field.vehiclePictures");
+ addIfBlank(missingFields, row.getProcurementSource(), "vehicle.import.field.procurementSource");
+ if (!missingFields.isEmpty()) {
+ int excelRowNumber = index + headRows + 1;
+ String missing = String.join(", ", missingFields);
+ throw new ServiceException("导入数据必填字段为空!", I18nKeyConstant.VEHICLE_IMPORT_FIELDS_REQUIRED,
+ new Object[]{excelRowNumber, missing});
+ }
+ }
+ }
+
+ private void addIfBlank(List<String> missingFields, String value, String fieldNameKey) {
+ if (StringUtils.isBlank(value)) {
+ String fieldName = messageSource.getMessage(fieldNameKey, null, fieldNameKey, LocaleContextHolder.getLocale());
+ missingFields.add(fieldName);
+ }
+ }
+
+ private void uploadVehiclePicture(List<XpVehicleImportExcel> importList) {
+ for (XpVehicleImportExcel xpVehicleImportExcel : importList) {
+ xpVehicleImportExcel.setVehiclePictures(getOssUrl(xpVehicleImportExcel.getVehiclePictures()));
+ }
+ }
+ private String getOssUrl(String filePath) {
+ try {
+ // 获取到暂存的文件
+ File tmpFile = new File(filePath);
+ FileInputStream fileInputStream = new FileInputStream(tmpFile);
+ // TODO 上传oss
+ JSONObject res = new JSONObject();
+ res.put("url", "https://we-park-life.oss-cn-beijing.aliyuncs.com/img/K4vqtLmVc6.png");
+ res.put("id", "1");
+ res.put("name", "测试.png");
+ return res.toJSONString();
+ } catch (Exception e) {
+ log.error("广告物料整体项目结算表导入图片上传oss异常", e);
+ }
+ return null;
+ }
/**
* 导出在库车辆列表
*
diff --git a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/exportExcel/XpVehicleExportExcel.java b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/exportExcel/XpVehicleExportExcel.java
index 34f73b0..47ab7e0 100644
--- a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/exportExcel/XpVehicleExportExcel.java
+++ b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/exportExcel/XpVehicleExportExcel.java
@@ -59,12 +59,12 @@
@Excel(name = "保险到期时间", width = 20, exportFormat = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime insuranceEndTime;
- @ApiModelProperty(value = "运营资质到期时间")
- @Excel(name = "运营资质到期时间", width = 20, exportFormat = "yyyy-MM-dd HH:mm:ss")
- private LocalDateTime qualificationExpireTime;
-
- @ApiModelProperty(value = "备注")
- @Excel(name = "备注", width = 25)
- private String remarks;
+ // @ApiModelProperty(value = "运营资质到期时间")
+ // @Excel(name = "运营资质到期时间", width = 20, exportFormat = "yyyy-MM-dd HH:mm:ss")
+ // private LocalDateTime qualificationExpireTime;
+ //
+ // @ApiModelProperty(value = "备注")
+ // @Excel(name = "备注", width = 25)
+ // private String remarks;
}
diff --git a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/importExcel/XpVehicleImportExcel.java b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/importExcel/XpVehicleImportExcel.java
index 0f3c94b..eeb60a6 100644
--- a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/importExcel/XpVehicleImportExcel.java
+++ b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/importExcel/XpVehicleImportExcel.java
@@ -30,7 +30,7 @@
@Excel(name = "车辆颜色", width = 12)
private String vehicleColor;
- @Excel(name = "车辆图片", width = 12, type = 2)
+ @Excel(name = "车辆图片", width = 12, type = 2, savePath = "/Users/mitao/Documents/excel/upload/img/")
private String vehiclePictures;
@Excel(name = "采购来源", width = 15)
diff --git a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/vo/FleetVehicleVO.java b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/vo/FleetVehicleVO.java
index 67ac867..81114b8 100644
--- a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/vo/FleetVehicleVO.java
+++ b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/vo/FleetVehicleVO.java
@@ -1,5 +1,6 @@
package com.xiaopeng.vehicleConvoy.model.vo;
+import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -33,4 +34,15 @@
@ApiModelProperty(value = "运营状态描述")
private String operatingStatusDesc;
+
+ @ApiModelProperty(value = "采购来源")
+ private String procurementSource;
+
+ @ApiModelProperty(value = "围栏id")
+ private Long electronicId;
+
+ @ApiModelProperty(value = "运营区域")
+ private String electronicName;
+
+
}
diff --git a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpFleetServiceImpl.java b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpFleetServiceImpl.java
index b0ec75c..ac41988 100644
--- a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpFleetServiceImpl.java
+++ b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpFleetServiceImpl.java
@@ -1,5 +1,6 @@
package com.xiaopeng.vehicleConvoy.service.impl;
+import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -17,6 +18,7 @@
import com.xiaopeng.api.model.vehicleConvoy.XpFleetVehicle;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.api.vo.account.XpOperationsUserWithRoleVO;
+import com.xiaopeng.api.vo.operation.ElectronicFenceDetailVo;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.exception.ServiceException;
import com.xiaopeng.common.core.web.page.PageInfo;
@@ -368,6 +370,18 @@
if (!CollectionUtils.isEmpty(vehicleIds)) {
R<List<XpVehicle>> vehiclesResult = xpVehicleClient.listByIds(vehicleIds);
if (vehiclesResult.getData() != null) {
+ List<Long> electronicIds = vehiclesResult.getData().stream()
+ .map(XpVehicle::getElectronicId)
+ .filter(Objects::nonNull)
+ .distinct()
+ .collect(Collectors.toList());
+ Map<Long, String> electronicNameMap = new HashMap<>();
+ if (CollUtil.isNotEmpty(electronicIds)) {
+ List<XpElectronicFence> data = xpElectronicClient.listByIds(electronicIds).getData();
+ electronicNameMap = CollUtil.isNotEmpty(data) ?
+ data.stream().collect(Collectors.toMap(XpElectronicFence::getId, XpElectronicFence::getElectronicName))
+ : Collections.emptyMap();
+ }
for (XpVehicle vehicle : vehiclesResult.getData()) {
// 如果有车牌号筛选条件,进行过滤
if (StringUtils.isNotBlank(query.getPlateNumber()) &&
@@ -382,6 +396,9 @@
vo.setVehicleColor(vehicle.getVehicleColor());
vo.setVehicleModel(vehicle.getVehicleModel());
vo.setOperatingStatus(vehicle.getOperatingStatus());
+ vo.setProcurementSource(vehicle.getProcurementSource());
+ vo.setElectronicId(vehicle.getElectronicId());
+ vo.setElectronicName(electronicNameMap.get(vehicle.getElectronicId()));
records.add(vo);
}
}
@@ -469,6 +486,13 @@
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteById(Long id) {
+ long vehicleCount = xpFleetVehicleService.count(new LambdaQueryWrapper<XpFleetVehicle>()
+ .eq(XpFleetVehicle::getFleetId, id));
+ long userCount = xpFleetOperationsService.count(new LambdaQueryWrapper<XpFleetOperations>()
+ .eq(XpFleetOperations::getFleetId, id));
+ if (vehicleCount > 0 || userCount > 0) {
+ throw new ServiceException("该车队下仍有绑定车辆/人员,无法删除", I18nKeyConstant.FLEET_DELETE_HAS_BOUND_VEHICLE_OR_USER);
+ }
// 删除用户关联
xpFleetOperationsService.lambdaUpdate().eq(XpFleetOperations::getFleetId, id).remove();
// 删除车辆关联
diff --git a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleAnnualRecordServiceImpl.java b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleAnnualRecordServiceImpl.java
index 5701f07..58e7471 100644
--- a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleAnnualRecordServiceImpl.java
+++ b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleAnnualRecordServiceImpl.java
@@ -36,7 +36,7 @@
wrapper.ge(XpVehicleAnnualRecord::getCreateTime, LocalDateTime.of(query.getStartTime(), LocalTime.MIN));
}
if (Objects.nonNull(query.getEndTime())) {
- wrapper.ge(XpVehicleAnnualRecord::getCreateTime, LocalDateTime.of(query.getEndTime(), LocalTime.MAX));
+ wrapper.le(XpVehicleAnnualRecord::getCreateTime, LocalDateTime.of(query.getEndTime(), LocalTime.MAX));
}
wrapper.like(StringUtils.isNotBlank(query.getOperationsUserName()), XpVehicleAnnualRecord::getCreateBy, query.getOperationsUserName());
wrapper.orderByDesc(XpVehicleAnnualRecord::getCreateTime);
diff --git a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java
index 3bd5b58..83b3f4f 100644
--- a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java
+++ b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java
@@ -547,7 +547,7 @@
// 校验通过,批量转为运营状态(vehicleType: 1→2)
LambdaUpdateWrapper<XpVehicle> wrapper = new LambdaUpdateWrapper<>();
- wrapper.in(XpVehicle::getId, idStr)
+ wrapper.in(XpVehicle::getId, ids)
.set(XpVehicle::getVehicleType, 2)
.set(XpVehicle::getOperatingStatus, 1);
this.update(wrapper);
@@ -585,7 +585,25 @@
public PageInfo<XpVehicle> vehiclePageList(VehiclePageQuery query) {
PageInfo<XpVehicle> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
List<XpVehicle> list = this.baseMapper.vehiclePageList(pageInfo, query);
-
+ //查询运营区域名称
+ List<Long> electronicIds = list.stream()
+ .map(XpVehicle::getElectronicId)
+ .filter(Objects::nonNull)
+ .distinct()
+ .collect(Collectors.toList());
+ Map<Long, String> electronicNameMap = new HashMap<>();
+ if (CollUtil.isNotEmpty(electronicIds)) {
+ List<XpElectronicFence> data = xpElectronicClient.listByIds(electronicIds).getData();
+ electronicNameMap = CollUtil.isNotEmpty(data) ?
+ data.stream().collect(Collectors.toMap(XpElectronicFence::getId, XpElectronicFence::getElectronicName))
+ : Collections.emptyMap();
+ }
+ Map<Long, String> finalElectronicNameMap = electronicNameMap;
+ list.forEach(item -> {
+ if (item.getElectronicId() != null) {
+ item.setElectronicName(finalElectronicNameMap.get(item.getElectronicId()));
+ }
+ });
if (CollUtil.isNotEmpty(list)) {
LocalDate today = LocalDate.now();
List<Long> expiredVehicleIds = new ArrayList<>();
diff --git a/xp-robotaxi-vehicle-convoy-boot/src/main/resources/i18n/messages.properties b/xp-robotaxi-vehicle-convoy-boot/src/main/resources/i18n/messages.properties
index bfb6d2f..d92e3d3 100644
--- a/xp-robotaxi-vehicle-convoy-boot/src/main/resources/i18n/messages.properties
+++ b/xp-robotaxi-vehicle-convoy-boot/src/main/resources/i18n/messages.properties
@@ -4,11 +4,20 @@
fleet.operation.user.bound.v1=
fleet.vehicle.bound.v2=当前车队已和该车辆关联
fleet.vehicle.bound.v1=车辆[{0}]已绑定车队[{1}]
+fleet.delete.has.bound.vehicle.or.user=该车队下仍有绑定车辆/人员,无法删除
policy.application.audit.status.notNull=保单审核状态不能为空
welcome.message=欢迎来到我们的应用程序!
# 车辆管理
vehicle.import.failed=车辆导入失败!
vehicle.import.data.empty=导入数据为空!
+vehicle.import.fields.required=第{0}行以下字段不能为空:{1}
+vehicle.import.field.vehicleCode=车辆编码
+vehicle.import.field.vehicleVin=车辆VIN码
+vehicle.import.field.plateNumber=车牌号
+vehicle.import.field.vehicleModel=型号
+vehicle.import.field.vehicleColor=车辆颜色
+vehicle.import.field.vehiclePictures=车辆图片
+vehicle.import.field.procurementSource=采购来源
vehicle.operation.info.incomplete=以下信息未完善,无法开始运营:{0}
vehicle.batch.operation.condition.not.met=以下车辆不满足运营条件:{0}
-vehicle.time.expired=以下时间已过期,请填写有效日期:{0}
\ No newline at end of file
+vehicle.time.expired=以下时间已过期,请填写有效日期:{0}
diff --git a/xp-robotaxi-vehicle-convoy-boot/src/main/resources/i18n/messages_en_US.properties b/xp-robotaxi-vehicle-convoy-boot/src/main/resources/i18n/messages_en_US.properties
index 97bc40a..aaa7326 100644
--- a/xp-robotaxi-vehicle-convoy-boot/src/main/resources/i18n/messages_en_US.properties
+++ b/xp-robotaxi-vehicle-convoy-boot/src/main/resources/i18n/messages_en_US.properties
@@ -3,6 +3,7 @@
policy.application.audit.ids.notEmpty=The list of policy application ids cannot be empty
fleet.operation.user.bound.v1=Operation user [{0}] already bound fleet:[{1}]
fleet.vehicle.bound.v2=The current team has been associated with this vehicle.
+fleet.delete.has.bound.vehicle.or.user=The fleet still has bound vehicles/personnel and cannot be deleted
policy.application.audit.status.notNull=The review status of the insurance policy cannot be empty
welcome.message=Welcome to our application!
order.not.exists=No valid order information found
@@ -10,9 +11,17 @@
# Vehicle Management
vehicle.import.failed=Vehicle import failed!
vehicle.import.data.empty=Import data is empty!
+vehicle.import.fields.required=Row {0}: the following fields are required: {1}
+vehicle.import.field.vehicleCode=Vehicle Code
+vehicle.import.field.vehicleVin=VIN
+vehicle.import.field.plateNumber=Plate Number
+vehicle.import.field.vehicleModel=Model
+vehicle.import.field.vehicleColor=Color
+vehicle.import.field.vehiclePictures=Vehicle Picture
+vehicle.import.field.procurementSource=Procurement Source
vehicle.operation.info.incomplete=The following information is incomplete and cannot start operation: {0}
vehicle.batch.operation.condition.not.met=The following vehicles do not meet operating conditions: {0}
vehicle.time.expired=The following dates have expired, please enter valid dates: {0}
vehicle.not.p.gear=The trunk cannot be opened when the vehicle is not in P gear
vehicle.temperature.up=The highest temperature is 28°C
-vehicle.temperature.down=The lowest temperature is 22°C
\ No newline at end of file
+vehicle.temperature.down=The lowest temperature is 22°C
diff --git a/xp-robotaxi-vehicle-convoy-boot/src/main/resources/i18n/messages_zh_CN.properties b/xp-robotaxi-vehicle-convoy-boot/src/main/resources/i18n/messages_zh_CN.properties
index 6ae8a61..125ad0b 100644
--- a/xp-robotaxi-vehicle-convoy-boot/src/main/resources/i18n/messages_zh_CN.properties
+++ b/xp-robotaxi-vehicle-convoy-boot/src/main/resources/i18n/messages_zh_CN.properties
@@ -4,6 +4,7 @@
fleet.user.bound=运维人员[{0}]已绑定车队[{1}]
fleet.operation.user.bound.v1=运维人员[{0}]已绑定车队[{1}]
fleet.vehicle.bound.v2=当前车队已和该车辆关联
+fleet.delete.has.bound.vehicle.or.user=该车队下仍有绑定车辆/人员,无法删除
policy.application.audit.status.notNull=保单审核状态不能为空
welcome.message=欢迎来到我们的应用程序!
order.not.exists=未查询到有效订单信息
@@ -11,9 +12,17 @@
# 车辆管理
vehicle.import.failed=车辆导入失败!
vehicle.import.data.empty=导入数据为空!
+vehicle.import.fields.required=第{0}行以下字段不能为空:{1}
+vehicle.import.field.vehicleCode=车辆编码
+vehicle.import.field.vehicleVin=车辆VIN码
+vehicle.import.field.plateNumber=车牌号
+vehicle.import.field.vehicleModel=型号
+vehicle.import.field.vehicleColor=车辆颜色
+vehicle.import.field.vehiclePictures=车辆图片
+vehicle.import.field.procurementSource=采购来源
vehicle.operation.info.incomplete=以下信息未完善,无法开始运营:{0}
vehicle.batch.operation.condition.not.met=以下车辆不满足运营条件:{0}
vehicle.time.expired=以下时间已过期,请填写有效日期:{0}
vehicle.not.p.gear=车辆非P档,无法开启后备箱
vehicle.temperature.up=温度最高28℃
-vehicle.temperature.down=温度最低22℃
\ No newline at end of file
+vehicle.temperature.down=温度最低22℃
--
Gitblit v1.7.1