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); /** * 分页查询 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); // 删除旧的菜单关联 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; } 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,6 +26,8 @@ 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, 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; } 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 = "限停时长") 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; } 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; } } } } 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; }); } 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()); } 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(); 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); } 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); 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); 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); } 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); } 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); } } 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"; 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 = {"管理后台-车队管理"}) 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; } /** * 导出在库车辆列表 * 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; } 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) 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; } 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(); // 删除车辆关联 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); 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<>(); 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} vehicle.time.expired=以下时间已过期,请填写有效日期:{0} 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 vehicle.temperature.down=The lowest temperature is 22°C 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℃ vehicle.temperature.down=温度最低22℃