From 1e16fb98c0dd2db59429e7b40f42841ea01bdb2e Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期六, 07 三月 2026 21:00:54 +0800
Subject: [PATCH] 修改车辆管理功能和区域管理bug
---
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpElectronicFenceServiceImpl.java | 22 +++++
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceServiceImpl.java | 22 +++++
xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsUserNotificationMapper.xml | 2
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpMapController.java | 29 ++++--
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpTaskServiceImpl.java | 9 +-
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/vehicleConvoy/BaseVehicleUserDto.java | 2
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/GDMapGeocodingUtil.java | 34 ++++++++
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java | 89 +++++++++++++++++----
8 files changed, 172 insertions(+), 37 deletions(-)
diff --git a/xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsUserNotificationMapper.xml b/xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsUserNotificationMapper.xml
index 0987c57..382f3ee 100644
--- a/xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsUserNotificationMapper.xml
+++ b/xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsUserNotificationMapper.xml
@@ -4,7 +4,7 @@
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
- id, notification_type, notification_content, operations_user_id, data_id, is_deleted, create_time, update_time, create_by, update_by
+ id, notification_type, notification_content, operations_user_id, data_id, read_status, is_deleted, create_time, update_time, create_by, update_by
</sql>
<!-- 分页查询用户通知列表 -->
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/vehicleConvoy/BaseVehicleUserDto.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/vehicleConvoy/BaseVehicleUserDto.java
index cd4ac5d..eda1a83 100644
--- a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/vehicleConvoy/BaseVehicleUserDto.java
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/vehicleConvoy/BaseVehicleUserDto.java
@@ -6,7 +6,7 @@
@Data
public class BaseVehicleUserDto {
/**
- * 状态码
+ * 状态码 0成功
*/
private Integer code;
/**
diff --git a/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpTaskServiceImpl.java b/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpTaskServiceImpl.java
index 36d0b6e..d56a30f 100644
--- a/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpTaskServiceImpl.java
+++ b/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpTaskServiceImpl.java
@@ -727,9 +727,9 @@
xpTaskHandleDetailRoutine.setTaskImage(dto.getTaskImage());
xpTaskHandleDetailRoutine.setOperationsUserId(id);
xpTaskHandleDetailRoutineMapper.insert(xpTaskHandleDetailRoutine);
- task.setStatus(2);
- this.updateById(task);
- return null;
+ //更新任务状态为已完成
+ lambdaUpdate().set(XpTask::getStatus, 2).eq(XpTask::getId, dto.getId()).update();
+ return R.ok();
}
@Override
@@ -923,8 +923,7 @@
if (Objects.nonNull(taskId)) {
XpTask task = this.getById(taskId);
if (Objects.nonNull(task)) {
- task.setStatus(status);
- this.updateById(task);
+ this.lambdaUpdate().set(XpTask::getStatus, status).eq(XpTask::getId, taskId).update();
}
}
}
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 af9283e..07485dd 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
@@ -99,21 +99,28 @@
// 获取电子围栏的禁行区域点位
GeoPoint startPoint = new GeoPoint(dto.getOrigin().getLongitude(),dto.getOrigin().getLatitude());
List<String> operatingArea = xpGeoFencingPolygonService.findFencesContainingPoint(startPoint, "operating_area", "points");
- String fenceId = operatingArea.get(0);
- List<Document> pointsInFence = xpGeoFencingPolygonService.findPointsByParentId(fenceId, "parentId", "prohibited_area");
// 避让区域
- ArrayList<String> pointStrParam = new ArrayList<>();
- 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());
+ ArrayList<String> pointStrParam = null;
+ String fenceId = null;
+ if(!operatingArea.isEmpty()){
+ fenceId = operatingArea.get(0);
+ List<Document> pointsInFence = xpGeoFencingPolygonService.findPointsByParentId(fenceId, "parentId", "prohibited_area");
+ if(!pointsInFence.isEmpty()){
+ pointStrParam = new ArrayList<>();
}
- if(!pointStr.isEmpty()){
- pointStrParam.add(String.join(";", pointStr));
+ 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));
+ }
}
}
+
RouteVo routeVo = gdMapGeocodingUtil.getDistanceAndTime(dto.getOrigin(), dto.getDestination(), String.join("|", pointStrParam), fenceId,dto.getRoutePlanRule());
if(routeVo==null){
return R.fail("没有找到路线");
diff --git a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceServiceImpl.java b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceServiceImpl.java
index 5cafe56..a6fa724 100644
--- a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceServiceImpl.java
+++ b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceServiceImpl.java
@@ -26,6 +26,7 @@
import com.xiaopeng.map.mapper.XpPointMapper;
import com.xiaopeng.map.mapper.XpRegionMapper;
import com.xiaopeng.map.service.XpElectronicFenceService;
+import com.xiaopeng.map.utils.GDMapGeocodingUtil;
import com.xiaopeng.map.utils.PolygonOverlapService;
import lombok.extern.slf4j.Slf4j;
import net.sourceforge.pinyin4j.PinyinHelper;
@@ -66,6 +67,8 @@
private XpPointMapper xpPointMapper;
@Autowired
private XpRegionMapper xpRegionMapper;
+ @Autowired
+ private GDMapGeocodingUtil gdMapGeocodingUtil;
@Override
public PageInfo<XpElectronicFence> pageList(ElectronicPageListQuery query) {
@@ -155,6 +158,16 @@
}
}
}
+
+ //根据经纬度获取当前城市code
+ XpElectronicFenceArea xpElectronicFenceArea = dto.getElectronicFenceAreas().get(0);
+ String[] split = xpElectronicFenceArea.getFencePoints().split(",")[0].split("_");
+ Map<String, String> geocode = gdMapGeocodingUtil.geocode(split[0], split[1]);
+ if(null == geocode){
+ return R.fail("经纬度转换城市code失败");
+ }
+ String cityCode = geocode.get("cityCode");
+ dto.setCityCode(cityCode);
xpElectronicFence.setCityCode(dto.getCityCode());
// 生成围栏id 规则:城市首字母-类型简写-4位自增流水号(如 SZ-OP-001),支持复制;数据停用或删除后,流水号不回收
XpRegion xpRegion = xpRegionMapper.selectOne(new LambdaQueryWrapper<XpRegion>()
@@ -363,6 +376,15 @@
}
}
}
+ //根据经纬度获取当前城市code
+ XpElectronicFenceArea electronicFenceArea = dto.getElectronicFenceAreas().get(0);
+ String[] split = electronicFenceArea.getFencePoints().split(",")[0].split("_");
+ Map<String, String> geocode = gdMapGeocodingUtil.geocode(split[0], split[1]);
+ if(null == geocode){
+ return R.fail("经纬度转换城市code失败");
+ }
+ String cityCode = geocode.get("cityCode");
+ dto.setCityCode(cityCode);
xpElectronicFence.setCityCode(dto.getCityCode());
this.updateById(xpElectronicFence);
diff --git a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/GDMapGeocodingUtil.java b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/GDMapGeocodingUtil.java
index d944f64..c5a3b70 100644
--- a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/GDMapGeocodingUtil.java
+++ b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/GDMapGeocodingUtil.java
@@ -13,6 +13,7 @@
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Map;
/**
* 高德地图的地理编码工具类
@@ -121,4 +122,37 @@
return jsonObject.getString("data");
}
+
+
+ /**
+ * 根据经纬度获取行政区域信息
+ * @param lon
+ * @param lan
+ * @return
+ * @throws Exception
+ */
+ public Map<String, String> geocode(String lon, String lan) {
+ String url = "https://restapi.amap.com/v3/geocode/regeo?key=" + key + "&location=" + lon + "," + lan;
+ String forObject = HttpUtils.sendGet(url);
+ JSONObject jsonObject = JSON.parseObject(forObject);
+ Map<String, String> map = new HashMap<>();
+ if(jsonObject.getString("status").equals("1")){
+ JSONObject regeocode = jsonObject.getJSONObject("regeocode");
+ JSONObject addressComponent = regeocode.getJSONObject("addressComponent");
+ String address = regeocode.getString("formatted_address");
+ map.put("address", address);
+ String code = addressComponent.getString("adcode");
+ String province = addressComponent.getString("province");
+ String city = addressComponent.getString("city");
+ String district = addressComponent.getString("district");
+ map.put("province", province);
+ map.put("provinceCode", code.substring(0, 2) + "0000");
+ map.put("city", city);
+ map.put("cityCode", code.substring(0, 4) + "00");
+ map.put("district", district);
+ map.put("districtCode", code);
+ }
+ return map;
+ }
+
}
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpElectronicFenceServiceImpl.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpElectronicFenceServiceImpl.java
index 764b934..e271bee 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpElectronicFenceServiceImpl.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpElectronicFenceServiceImpl.java
@@ -28,6 +28,7 @@
import com.xiaopeng.operation.mapper.XpPointMapper;
import com.xiaopeng.operation.mapper.XpRegionMapper;
import com.xiaopeng.operation.service.IXpElectronicFenceService;
+import com.xiaopeng.operation.utils.GDMapGeocodingUtil;
import com.xiaopeng.operation.utils.PolygonOverlapService;
import lombok.extern.slf4j.Slf4j;
import net.sourceforge.pinyin4j.PinyinHelper;
@@ -67,6 +68,8 @@
private XpPointMapper xpPointMapper;
@Autowired
private XpRegionMapper xpRegionMapper;
+ @Autowired
+ private GDMapGeocodingUtil gdMapGeocodingUtil;
@Override
public PageInfo<XpElectronicFence> pageList(ElectronicPageListQuery query) {
@@ -157,6 +160,15 @@
}
}
}
+ //根据经纬度获取当前城市code
+ XpElectronicFenceArea xpElectronicFenceArea = dto.getElectronicFenceAreas().get(0);
+ String[] split = xpElectronicFenceArea.getFencePoints().split(",")[0].split("_");
+ Map<String, String> geocode = gdMapGeocodingUtil.geocode(split[0], split[1]);
+ if(null == geocode){
+ return R.fail("经纬度转换城市code失败");
+ }
+ String cityCode = geocode.get("cityCode");
+ dto.setCityCode(cityCode);
xpElectronicFence.setCityCode(dto.getCityCode());
// 生成围栏id 规则:城市首字母-类型简写-4位自增流水号(如 SZ-OP-001),支持复制;数据停用或删除后,流水号不回收
XpRegion xpRegion = xpRegionMapper.selectOne(new LambdaQueryWrapper<XpRegion>()
@@ -366,8 +378,16 @@
}
}
}
+ //根据经纬度获取当前城市code
+ XpElectronicFenceArea electronicFenceArea = dto.getElectronicFenceAreas().get(0);
+ String[] split = electronicFenceArea.getFencePoints().split(",")[0].split("_");
+ Map<String, String> geocode = gdMapGeocodingUtil.geocode(split[0], split[1]);
+ if(null == geocode){
+ return R.fail("经纬度转换城市code失败");
+ }
+ String cityCode = geocode.get("cityCode");
+ dto.setCityCode(cityCode);
xpElectronicFence.setCityCode(dto.getCityCode());
-
this.updateById(xpElectronicFence);
// 删除旧的区域数据,然后保存新的区域数据
xpElectronicFenceAreaMapper.delete(new LambdaQueryWrapper<XpElectronicFenceArea>()
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 2bd648a..3bd5b58 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
@@ -49,6 +49,7 @@
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
+import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
@@ -348,21 +349,21 @@
Locale locale = LocaleContextHolder.getLocale();
if (dto.getAnnualInspectionDate() != null && dto.getAnnualInspectionDate().isBefore(now)) {
- if (locale.equals(Locale.CHINESE)) {
+ if ("zh".equals(locale.getLanguage())) {
expiredItems.add("年检到期时间");
} else {
expiredItems.add("Annual inspection expiration date");
}
}
if (dto.getInsuranceEndTime() != null && dto.getInsuranceEndTime().isBefore(now)) {
- if (locale.equals(Locale.CHINESE)) {
+ if ("zh".equals(locale.getLanguage())) {
expiredItems.add("保险到期时间");
} else {
expiredItems.add("Insurance expiration date");
}
}
if (dto.getQualificationExpireTime() != null && dto.getQualificationExpireTime().isBefore(now)) {
- if (locale.equals(Locale.CHINESE)) {
+ if ("zh".equals(locale.getLanguage())) {
expiredItems.add("运营资质到期时间");
} else {
expiredItems.add("Operation qualification expiration date");
@@ -371,7 +372,7 @@
if (!expiredItems.isEmpty()) {
String detail;
- if (locale.equals(Locale.CHINESE)) {
+ if ("zh".equals(locale.getLanguage())) {
detail = String.join("、", expiredItems);
} else {
detail = String.join("; ", expiredItems);
@@ -393,7 +394,7 @@
|| StringUtils.isBlank(vehicle.getInsurancePhone())
|| vehicle.getInsuranceEndTime() == null
|| StringUtils.isBlank(vehicle.getPolicyInformation())) {
- if (locale.equals(Locale.CHINESE)) {
+ if ("zh".equals(locale.getLanguage())) {
missingItems.add("保险信息");
} else {
missingItems.add("Insurance information");
@@ -403,7 +404,7 @@
// 校验年检信息
if (vehicle.getAnnualInspectionDate() == null
|| StringUtils.isBlank(vehicle.getInspectionAttachments())) {
- if (locale.equals(Locale.CHINESE)) {
+ if ("zh".equals(locale.getLanguage())) {
missingItems.add("年检信息");
} else {
missingItems.add("Annual inspection information");
@@ -412,7 +413,7 @@
// 校验运营区域
if (vehicle.getElectronicId() == null) {
- if (locale.equals(Locale.CHINESE)) {
+ if ("zh".equals(locale.getLanguage())) {
missingItems.add("运营区域");
} else {
missingItems.add("Operation area");
@@ -422,7 +423,7 @@
// 校验运营资质
if (StringUtils.isBlank(vehicle.getOperationQualification())
|| vehicle.getQualificationExpireTime() == null) {
- if (locale.equals(Locale.CHINESE)) {
+ if ("zh".equals(locale.getLanguage())) {
missingItems.add("运营资质");
} else {
missingItems.add("Operation qualification");
@@ -431,7 +432,7 @@
if (!missingItems.isEmpty()) {
String detail;
- if (locale.equals(Locale.CHINESE)) {
+ if ("zh".equals(locale.getLanguage())) {
detail = String.join("、", missingItems);
} else {
detail = String.join("; ", missingItems);
@@ -455,6 +456,32 @@
&& vehicle.getQualificationExpireTime() != null;
}
+ /**
+ * 检查车辆是否有任意一项证件过期(精确到日期)
+ * - 精确度:yyyy-MM-dd(只比较日期部分)
+ * - 到期日期等于今天不算过期(使用 isBefore)
+ * @param vehicle 车辆信息
+ * @param today 今天日期
+ */
+ private boolean isAnyDateExpired(XpVehicle vehicle, LocalDate today) {
+ // 年检到期时间检查:已过期
+ if (vehicle.getAnnualInspectionDate() != null
+ && vehicle.getAnnualInspectionDate().toLocalDate().isBefore(today)) {
+ return true;
+ }
+ // 保险到期时间检查:已过期
+ if (vehicle.getInsuranceEndTime() != null
+ && vehicle.getInsuranceEndTime().toLocalDate().isBefore(today)) {
+ return true;
+ }
+ // 运营资质到期时间检查:已过期
+ if (vehicle.getQualificationExpireTime() != null
+ && vehicle.getQualificationExpireTime().toLocalDate().isBefore(today)) {
+ return true;
+ }
+ return false;
+ }
+
@Override
@Transactional(rollbackFor = Exception.class)
public void batchOperation(String idStr) {
@@ -464,7 +491,7 @@
List<String> ids = Arrays.asList(idStr.split(","));
// 查询车辆完整信息
List<XpVehicle> vehicles = this.listByIds(ids);
- LocalDateTime now = LocalDateTime.now();
+ LocalDate now = LocalDate.now();
List<String> errorMessages = new ArrayList<>();
for (XpVehicle vehicle : vehicles) {
@@ -473,38 +500,38 @@
// 校验状态为待运营
if (!Integer.valueOf(2).equals(vehicle.getStatus())) {
- if (locale.equals(Locale.CHINESE)) {
+ if ("zh".equals(locale.getLanguage())) {
reasons.add("状态非待运营");
} else {
reasons.add("Status is not 'Pending Operation'");
}
}
// 校验年检到期时间
- if (vehicle.getAnnualInspectionDate() == null || vehicle.getAnnualInspectionDate().isBefore(now)) {
- if (locale.equals(Locale.CHINESE)) {
+ if (vehicle.getAnnualInspectionDate() == null || vehicle.getAnnualInspectionDate().toLocalDate().isBefore(now)) {
+ if ("zh".equals(locale.getLanguage())) {
reasons.add("年检已过期");
} else {
reasons.add("Annual inspection has expired");
}
}
// 校验保险到期时间
- if (vehicle.getInsuranceEndTime() == null || vehicle.getInsuranceEndTime().isBefore(now)) {
- if (locale.equals(Locale.CHINESE)) {
+ if (vehicle.getInsuranceEndTime() == null || vehicle.getInsuranceEndTime().toLocalDate().isBefore(now)) {
+ if ("zh".equals(locale.getLanguage())) {
reasons.add("保险已过期");
} else {
reasons.add("Insurance has expired");
}
}
// 校验运营资质到期时间
- if (vehicle.getQualificationExpireTime() == null || vehicle.getQualificationExpireTime().isBefore(now)) {
- if (locale.equals(Locale.CHINESE)) {
+ if (vehicle.getQualificationExpireTime() == null || vehicle.getQualificationExpireTime().toLocalDate().isBefore(now)) {
+ if ("zh".equals(locale.getLanguage())) {
reasons.add("运营资质已过期");
} else {
reasons.add("Operation qualification has expired");
}
}
if (!reasons.isEmpty()) {
- if (locale.equals(Locale.CHINESE)) {
+ if ("zh".equals(locale.getLanguage())) {
errorMessages.add("车辆[" + vehicle.getPlateNumber() + "]:" + String.join("、", reasons));
} else {
errorMessages.add("Vehicles [" + vehicle.getPlateNumber() + "]: " + String.join("; ", reasons));
@@ -558,6 +585,32 @@
public PageInfo<XpVehicle> vehiclePageList(VehiclePageQuery query) {
PageInfo<XpVehicle> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
List<XpVehicle> list = this.baseMapper.vehiclePageList(pageInfo, query);
+
+ if (CollUtil.isNotEmpty(list)) {
+ LocalDate today = LocalDate.now();
+ List<Long> expiredVehicleIds = new ArrayList<>();
+
+ for (XpVehicle vehicle : list) {
+ // 检查是否有任意一项过期(精确到 yyyy-MM-dd)
+ boolean isExpired = isAnyDateExpired(vehicle, today);
+
+ if (isExpired && !Integer.valueOf(3).equals(vehicle.getStatus())) {
+ // 记录需要更新状态的车辆ID
+ expiredVehicleIds.add(vehicle.getId());
+ // 同时更新返回结果中的状态
+ vehicle.setStatus(3);
+ }
+ }
+
+ // 批量更新过期车辆状态到数据库
+ if (CollUtil.isNotEmpty(expiredVehicleIds)) {
+ LambdaUpdateWrapper<XpVehicle> updateWrapper = new LambdaUpdateWrapper<>();
+ updateWrapper.in(XpVehicle::getId, expiredVehicleIds)
+ .set(XpVehicle::getStatus, 3);
+ this.update(updateWrapper);
+ }
+ }
+
pageInfo.setRecords(list);
return pageInfo;
}
--
Gitblit v1.7.1