From f3a8ace95bb141026b694b70df4d41bf284c6a7d Mon Sep 17 00:00:00 2001
From: liujie <1793218484@qq.com>
Date: 星期三, 11 三月 2026 21:50:11 +0800
Subject: [PATCH] Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/java/Robotaxi
---
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java | 195 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 194 insertions(+), 1 deletions(-)
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 dbe612a..5229a8b 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
@@ -5,6 +5,7 @@
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.lang.Validator;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -69,8 +70,13 @@
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
+import java.util.Locale;
import java.util.Objects;
+import java.util.Set;
+import java.util.regex.Pattern;
/**
* <p>
@@ -85,6 +91,9 @@
@Api(tags = "车辆管理")
@RequiredArgsConstructor(onConstructor_ = @Lazy)
public class XpVehicleController {
+
+ private static final Pattern VEHICLE_CODE_PATTERN = Pattern.compile("^[A-Za-z0-9_]{1,5}$");
+ private static final Pattern VEHICLE_VIN_PATTERN = Pattern.compile("^[A-Z0-9]{17}$");
private final IXpVehicleService xpVehicleService;
private final IXpFleetVehicleService vehicleService;
@@ -267,7 +276,7 @@
*/
@ApiOperation(value = "导入", tags = {"管理后台-车辆管理-在库车辆管理"})
@PostMapping("/api/v1/vehicle/importExcel")
- public R<?> importExcel(@RequestPart("file") MultipartFile file) {
+ public R<?> importExcel(@RequestParam("file") MultipartFile file) {
ImportParams params = new ImportParams();
params.setHeadRows(1);
InputStream inputStream = null;
@@ -294,6 +303,7 @@
throw new ServiceException("导入数据为空!", I18nKeyConstant.VEHICLE_IMPORT_DATA_EMPTY);
}
validateImportRequiredFields(importList, params.getHeadRows());
+ validateImportBusinessFields(importList, params.getHeadRows());
uploadVehiclePicture(importList);
xpVehicleService.importVehicles(importList);
return R.ok();
@@ -326,6 +336,189 @@
}
}
+ private void validateImportBusinessFields(List<XpVehicleImportExcel> importList, int headRows) {
+ List<String> errors = new ArrayList<>();
+ Locale locale = LocaleContextHolder.getLocale();
+
+ for (int index = 0; index < importList.size(); index++) {
+ XpVehicleImportExcel row = importList.get(index);
+ int excelRowNumber = index + headRows + 1;
+
+ String vehicleCode = trimToNull(row.getVehicleCode());
+ String vehicleVin = normalizeVin(row.getVehicleVin());
+ String plateNumber = trimToNull(row.getPlateNumber());
+ String vehicleColor = trimToNull(row.getVehicleColor());
+
+ row.setVehicleCode(vehicleCode);
+ row.setVehicleVin(vehicleVin);
+ row.setPlateNumber(plateNumber);
+ row.setVehicleColor(vehicleColor);
+
+ if (org.apache.commons.lang3.StringUtils.isNotBlank(vehicleCode) && !VEHICLE_CODE_PATTERN.matcher(vehicleCode).matches()) {
+ errors.add(messageSource.getMessage(I18nKeyConstant.VEHICLE_IMPORT_CODE_INVALID,
+ new Object[]{excelRowNumber, vehicleCode},
+ I18nKeyConstant.VEHICLE_IMPORT_CODE_INVALID,
+ locale));
+ }
+ if (org.apache.commons.lang3.StringUtils.isNotBlank(vehicleVin) && !VEHICLE_VIN_PATTERN.matcher(vehicleVin).matches()) {
+ errors.add(messageSource.getMessage(I18nKeyConstant.VEHICLE_IMPORT_VIN_INVALID,
+ new Object[]{excelRowNumber, vehicleVin},
+ I18nKeyConstant.VEHICLE_IMPORT_VIN_INVALID,
+ locale));
+ }
+ if (org.apache.commons.lang3.StringUtils.isNotBlank(plateNumber) && !Validator.isPlateNumber(plateNumber)) {
+ errors.add(messageSource.getMessage(I18nKeyConstant.VEHICLE_IMPORT_PLATE_INVALID,
+ new Object[]{excelRowNumber, plateNumber},
+ I18nKeyConstant.VEHICLE_IMPORT_PLATE_INVALID,
+ locale));
+ }
+ if (org.apache.commons.lang3.StringUtils.isNotBlank(vehicleColor) && vehicleColor.length() > 2) {
+ errors.add(messageSource.getMessage(I18nKeyConstant.VEHICLE_IMPORT_COLOR_INVALID,
+ new Object[]{excelRowNumber, vehicleColor},
+ I18nKeyConstant.VEHICLE_IMPORT_COLOR_INVALID,
+ locale));
+ }
+ }
+
+ Set<String> duplicatedCodes = findDuplicated(importList.stream()
+ .map(XpVehicleImportExcel::getVehicleCode)
+ .filter(org.apache.commons.lang3.StringUtils::isNotBlank)
+ .collect(java.util.stream.Collectors.toList()));
+ Set<String> duplicatedVins = findDuplicated(importList.stream()
+ .map(XpVehicleImportExcel::getVehicleVin)
+ .filter(org.apache.commons.lang3.StringUtils::isNotBlank)
+ .collect(java.util.stream.Collectors.toList()));
+ Set<String> duplicatedPlates = findDuplicated(importList.stream()
+ .map(XpVehicleImportExcel::getPlateNumber)
+ .filter(org.apache.commons.lang3.StringUtils::isNotBlank)
+ .collect(java.util.stream.Collectors.toList()));
+
+ for (int index = 0; index < importList.size(); index++) {
+ XpVehicleImportExcel row = importList.get(index);
+ int excelRowNumber = index + headRows + 1;
+ if (duplicatedCodes.contains(row.getVehicleCode())) {
+ errors.add(messageSource.getMessage(I18nKeyConstant.VEHICLE_IMPORT_CODE_DUPLICATE,
+ new Object[]{excelRowNumber, row.getVehicleCode()},
+ I18nKeyConstant.VEHICLE_IMPORT_CODE_DUPLICATE,
+ locale));
+ }
+ if (duplicatedVins.contains(row.getVehicleVin())) {
+ errors.add(messageSource.getMessage(I18nKeyConstant.VEHICLE_IMPORT_VIN_DUPLICATE,
+ new Object[]{excelRowNumber, row.getVehicleVin()},
+ I18nKeyConstant.VEHICLE_IMPORT_VIN_DUPLICATE,
+ locale));
+ }
+ if (duplicatedPlates.contains(row.getPlateNumber())) {
+ errors.add(messageSource.getMessage(I18nKeyConstant.VEHICLE_IMPORT_PLATE_DUPLICATE,
+ new Object[]{excelRowNumber, row.getPlateNumber()},
+ I18nKeyConstant.VEHICLE_IMPORT_PLATE_DUPLICATE,
+ locale));
+ }
+ }
+
+ Set<String> codeSet = importList.stream()
+ .map(XpVehicleImportExcel::getVehicleCode)
+ .filter(org.apache.commons.lang3.StringUtils::isNotBlank)
+ .collect(java.util.stream.Collectors.toSet());
+ Set<String> vinSet = importList.stream()
+ .map(XpVehicleImportExcel::getVehicleVin)
+ .filter(org.apache.commons.lang3.StringUtils::isNotBlank)
+ .collect(java.util.stream.Collectors.toSet());
+ Set<String> plateSet = importList.stream()
+ .map(XpVehicleImportExcel::getPlateNumber)
+ .filter(org.apache.commons.lang3.StringUtils::isNotBlank)
+ .collect(java.util.stream.Collectors.toSet());
+
+ Set<String> existsCodes = Collections.emptySet();
+ if (!codeSet.isEmpty()) {
+ existsCodes = xpVehicleService.lambdaQuery()
+ .select(XpVehicle::getVehicleCode)
+ .in(XpVehicle::getVehicleCode, codeSet)
+ .list()
+ .stream()
+ .map(XpVehicle::getVehicleCode)
+ .filter(org.apache.commons.lang3.StringUtils::isNotBlank)
+ .collect(java.util.stream.Collectors.toSet());
+ }
+ Set<String> existsVins = Collections.emptySet();
+ if (!vinSet.isEmpty()) {
+ existsVins = xpVehicleService.lambdaQuery()
+ .select(XpVehicle::getVehicleVin)
+ .in(XpVehicle::getVehicleVin, vinSet)
+ .list()
+ .stream()
+ .map(XpVehicle::getVehicleVin)
+ .filter(org.apache.commons.lang3.StringUtils::isNotBlank)
+ .collect(java.util.stream.Collectors.toSet());
+ }
+ Set<String> existsPlates = Collections.emptySet();
+ if (!plateSet.isEmpty()) {
+ existsPlates = xpVehicleService.lambdaQuery()
+ .select(XpVehicle::getPlateNumber)
+ .in(XpVehicle::getPlateNumber, plateSet)
+ .list()
+ .stream()
+ .map(XpVehicle::getPlateNumber)
+ .filter(org.apache.commons.lang3.StringUtils::isNotBlank)
+ .collect(java.util.stream.Collectors.toSet());
+ }
+
+ for (int index = 0; index < importList.size(); index++) {
+ XpVehicleImportExcel row = importList.get(index);
+ int excelRowNumber = index + headRows + 1;
+ if (existsCodes.contains(row.getVehicleCode())) {
+ errors.add(messageSource.getMessage(I18nKeyConstant.VEHICLE_IMPORT_CODE_EXISTS,
+ new Object[]{excelRowNumber, row.getVehicleCode()},
+ I18nKeyConstant.VEHICLE_IMPORT_CODE_EXISTS,
+ locale));
+ }
+ if (existsVins.contains(row.getVehicleVin())) {
+ errors.add(messageSource.getMessage(I18nKeyConstant.VEHICLE_IMPORT_VIN_EXISTS,
+ new Object[]{excelRowNumber, row.getVehicleVin()},
+ I18nKeyConstant.VEHICLE_IMPORT_VIN_EXISTS,
+ locale));
+ }
+ if (existsPlates.contains(row.getPlateNumber())) {
+ errors.add(messageSource.getMessage(I18nKeyConstant.VEHICLE_IMPORT_PLATE_EXISTS,
+ new Object[]{excelRowNumber, row.getPlateNumber()},
+ I18nKeyConstant.VEHICLE_IMPORT_PLATE_EXISTS,
+ locale));
+ }
+ }
+
+ if (!errors.isEmpty()) {
+ throw new ServiceException("导入校验失败!", I18nKeyConstant.VEHICLE_IMPORT_VALIDATE_FAIL,
+ new Object[]{String.join("\n", errors)});
+ }
+ }
+
+ private static String normalizeVin(String vin) {
+ String trimmed = trimToNull(vin);
+ return trimmed == null ? null : trimmed.toUpperCase(Locale.ROOT);
+ }
+
+ private static String trimToNull(String value) {
+ if (value == null) {
+ return null;
+ }
+ String trimmed = value.trim();
+ return trimmed.isEmpty() ? null : trimmed;
+ }
+
+ private static Set<String> findDuplicated(List<String> values) {
+ if (values == null || values.isEmpty()) {
+ return Collections.emptySet();
+ }
+ Set<String> seen = new HashSet<>();
+ Set<String> duplicated = new HashSet<>();
+ for (String value : values) {
+ if (!seen.add(value)) {
+ duplicated.add(value);
+ }
+ }
+ return duplicated;
+ }
+
private void uploadVehiclePicture(List<XpVehicleImportExcel> importList) {
for (XpVehicleImportExcel xpVehicleImportExcel : importList) {
xpVehicleImportExcel.setVehiclePictures(getOssUrl(xpVehicleImportExcel.getVehiclePictures()));
--
Gitblit v1.7.1