sql/增量sql/xprt_account.sql
@@ -1,5 +1,5 @@ SET FOREIGN_KEY_CHECKS=0; ALTER TABLE `xpeng_account`.`xp_operations_user` MODIFY COLUMN `remarks` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '''' COMMENT ''备注'' AFTER `phone_number`; ALTER TABLE `xpeng_account`.`xp_operations_user` MODIFY COLUMN `remarks` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '备注' AFTER `phone_number`; SET FOREIGN_KEY_CHECKS=1; xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/SysUserController.java
@@ -32,6 +32,10 @@ import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.security.KeyPair; import java.time.Duration; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.List; import java.util.Objects; import java.util.concurrent.TimeUnit; @@ -44,6 +48,9 @@ */ @RestController public class SysUserController extends BaseController { private static final DateTimeFormatter UNIQUE_NUMBER_DATE_FORMATTER = DateTimeFormatter.BASIC_ISO_DATE; private static final String UNIQUE_NUMBER_REDIS_KEY_PREFIX = "sys:user:unique-number:"; @Resource private ISysUserService userService; @@ -99,11 +106,7 @@ if (StringUtils.isNotEmpty(user.getUserAccount()) && !userService.checkUserNameUnique(user)) { throw new ServiceException("登录账号重复", I18nKeyConstant.ACCOUNT_DUPLICATE); } //校验编号是否唯一 Long count = userService.lambdaQuery().eq(SysUser::getUniqueNumber, user.getUniqueNumber()).count(); if (count > 0) { throw new ServiceException("用户编号已存在", I18nKeyConstant.ACCOUNT_UNIQUE_NUMBER_DUPLICATE); } user.setUniqueNumber(generateUniqueNumber()); user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); //TODO 手机号脱敏存储 userService.insertUser(user); @@ -113,6 +116,36 @@ sysUserRoleService.insertSysUserRole(sysUserRole); return AjaxResult.success(); } private String generateUniqueNumber() { LocalDate today = LocalDate.now(); String dateStr = UNIQUE_NUMBER_DATE_FORMATTER.format(today); String redisKey = UNIQUE_NUMBER_REDIS_KEY_PREFIX + dateStr; LocalDateTime now = LocalDateTime.now(); LocalDateTime tomorrowStart = today.plusDays(1).atStartOfDay(); long expireSeconds = Duration.between(now, tomorrowStart).getSeconds() + 60; for (int i = 0; i < 10; i++) { Long seq = redisService.redisTemplate.opsForValue().increment(redisKey); if (seq == null) { throw new ServiceException("用户编号生成失败"); } if (expireSeconds > 0) { redisService.expire(redisKey, expireSeconds, TimeUnit.SECONDS); } if (seq > 999999L) { throw new ServiceException("当天生成用户编号已达上限"); } String uniqueNumber = dateStr + String.format("%06d", seq); Long count = userService.lambdaQuery().eq(SysUser::getUniqueNumber, uniqueNumber).count(); if (count == null || count == 0L) { return uniqueNumber; } } throw new ServiceException("用户编号生成失败,请稍后重试"); } @GetMapping("/verifyUserNameRepeat/{username}") xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/dto/SysGroupAddDTO.java
@@ -23,7 +23,6 @@ private String groupName; @ApiModelProperty(value = "备注", required = true) @NotBlank(message = "{validation.group.remarks.notBlank}") private String remarks; @ApiModelProperty(value = "分组类型 1=管理端 2=运维app") xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsRoleMapper.xml
@@ -31,16 +31,18 @@ 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 WHERE 1=1 <if test="nickName != null and nickName != ''"> AND u.nick_name LIKE CONCAT('%', #{nickName}, '%') </if> <if test="phoneNumber != null and phoneNumber != ''"> AND u.phone_number LIKE CONCAT('%', #{phoneNumber}, '%') </if> <if test="roleId != null"> AND r.id = #{roleId} </if> <where> u.is_deleted = 0 <if test="nickName != null and nickName != ''"> AND u.nick_name LIKE CONCAT('%', #{nickName}, '%') </if> <if test="phoneNumber != null and phoneNumber != ''"> AND u.phone_number LIKE CONCAT('%', #{phoneNumber}, '%') </if> <if test="roleId != null"> AND r.id = #{roleId} </if> </where> </select> <select id="selectSysUserRoleByOperationUserId" resultType="com.xiaopeng.api.model.account.XpOperationsRole"> xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsUserMapper.xml
@@ -16,6 +16,7 @@ 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 <where> u.is_deleted = 0 <if test="query.nickName != null and query.nickName != ''"> AND u.nick_name LIKE CONCAT('%', #{query.nickName}, '%') </if> xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpPoint.java
@@ -1,9 +1,6 @@ package com.xiaopeng.api.model.operation; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.*; import java.math.BigDecimal; import java.time.LocalDateTime; @@ -37,7 +34,7 @@ private Long id; @ApiModelProperty(value = "电子围栏区域id") @TableField("electronic_area_id") @TableField(value = "electronic_area_id", updateStrategy = FieldStrategy.NEVER) private Long electronicAreaId; @ApiModelProperty(value = "点位名称") xp-robotaxi-api/src/main/java/com/xiaopeng/api/query/operation/PointListQuery.java
@@ -19,4 +19,7 @@ @ApiModelProperty(value = "点位类型1运营点位 2测试点位") private Integer pointType; @ApiModelProperty(value = "点位状态(多选) 1待测试 2测试中 3测试不通过 4可运营 5待生效 6启用中 7已停用 8已失效") private List<Integer> operationStatusList; } xp-robotaxi-api/src/main/java/com/xiaopeng/api/query/operation/PointPageListListQuery.java
@@ -14,8 +14,8 @@ private String pointNumber; @ApiModelProperty(value = "点位名称") private String pointName; @ApiModelProperty(value = "点位状态 1待测试 2测试中 3测试不通过 4可运营 5待生效 6启用中 7已停用 8失效") private Integer operationStatus; @ApiModelProperty(value = "点位状态(多选) 1待测试 2测试中 3测试不通过 4可运营 5待生效 6启用中 7已停用 8失效") private List<Integer> operationStatusList; @ApiModelProperty(value = "限停时长") private Integer parkingTimeLimit; @ApiModelProperty(value = "点位经纬度") xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/OrderMissionController.java
@@ -38,6 +38,7 @@ 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.redis.core.RedisTemplate; import org.springframework.web.bind.annotation.*; @@ -294,6 +295,7 @@ ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1000)); Long finalOrderId = orderId; Long finalOrderId1 = orderId; threadPoolExecutor.execute(() -> { //等待10秒后开始执行车子位移 try { @@ -313,17 +315,29 @@ 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(60D); vehiclePosition.setAlt(100F); vehiclePosition.setSpeed(50F); vehiclePosition.setCurrentElectricity(80); vehiclePosition.setMileageRange(300f); vehiclePosition.setHasOrder(0); vehiclePosition.setOrderId(finalOrderId1); mongoTemplate.save(vehiclePosition); }else{ vehiclePosition.setOrderId(finalOrderId1); Update update = new Update() .set("point", new GeoJsonPoint(longitude, latitude)) .set("course", 60D) .set("alt", 100F) .set("speed", 50F) .set("currentElectricity", 80) .set("mileageRange", 300f) .set("hasOrder", 0) .set("orderId", finalOrderId1); mongoTemplate.updateFirst(new Query(Criteria.where("vin").is(vin)), update, VehiclePosition.class); } vehiclePosition.setVin(vin); vehiclePosition.setPoint(new GeoJsonPoint(longitude, latitude)); vehiclePosition.setCourse(60D); vehiclePosition.setAlt(100F); //车辆动态信息 vehiclePosition.setSpeed(50F); vehiclePosition.setCurrentElectricity(80); vehiclePosition.setMileageRange(300f); vehiclePosition.setOrderId(finalOrderId); mongoTemplate.save(vehiclePosition); //调用推送服务接口 if (null != finalOrderId) { PushOrderRouteDTO dto = new PushOrderRouteDTO(); @@ -460,6 +474,7 @@ ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1000)); Long finalOrderId = orderId; Long finalOrderId1 = orderId; threadPoolExecutor.execute(() -> { //等待10秒后开始执行车子位移 try { @@ -480,17 +495,29 @@ 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(60D); vehiclePosition.setAlt(100F); vehiclePosition.setSpeed(50F); vehiclePosition.setCurrentElectricity(80); vehiclePosition.setMileageRange(300f); vehiclePosition.setHasOrder(0); vehiclePosition.setOrderId(finalOrderId1); mongoTemplate.save(vehiclePosition); }else{ vehiclePosition.setOrderId(finalOrderId1); Update update = new Update() .set("point", new GeoJsonPoint(longitude, latitude)) .set("course", 60D) .set("alt", 100F) .set("speed", 50F) .set("currentElectricity", 80) .set("mileageRange", 300f) .set("hasOrder", 0) .set("orderId", finalOrderId1); mongoTemplate.updateFirst(new Query(Criteria.where("vin").is(vin)), update, VehiclePosition.class); } vehiclePosition.setVin(vin); vehiclePosition.setPoint(new GeoJsonPoint(longitude, latitude)); vehiclePosition.setCourse(60D); vehiclePosition.setAlt(100F); //车辆动态信息 vehiclePosition.setSpeed(50F); vehiclePosition.setCurrentElectricity(80); vehiclePosition.setMileageRange(300f); vehiclePosition.setOrderId(finalOrderId); mongoTemplate.save(vehiclePosition); //调用推送服务接口 if (null != finalOrderId) { PushOrderRouteDTO dto = new PushOrderRouteDTO(); xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpPointManagementController.java
@@ -10,23 +10,40 @@ import com.xiaopeng.api.query.operation.PointListQuery; import com.xiaopeng.api.query.operation.PointPageListListQuery; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.core.exception.ServiceException; import com.xiaopeng.common.core.utils.WebUtils; import com.xiaopeng.common.core.web.controller.BaseController; import com.xiaopeng.common.core.web.page.PageInfo; import com.xiaopeng.api.dto.map.XpPointExportExcelQuery; import com.xiaopeng.map.exportExcel.XpPointExportExcel; import com.xiaopeng.map.service.XpElectronicFenceAreaService; import com.xiaopeng.map.service.XpElectronicFenceService; import com.xiaopeng.map.service.XpPointService; import cn.afterturn.easypoi.excel.ExcelExportUtil; import cn.afterturn.easypoi.excel.entity.ExportParams; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.apache.poi.ss.usermodel.Workbook; import org.springframework.beans.BeanUtils; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.function.Function; import java.util.stream.Collectors; @@ -35,6 +52,8 @@ @RequestMapping("/api/v1/point") @Api(tags = "点位管理") public class XpPointManagementController extends BaseController { private static final DateTimeFormatter EXPORT_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); @Resource private XpPointService xpPointService; @@ -79,6 +98,49 @@ List<XpPoint> list = xpPointService.lambdaQuery().in(XpPoint::getId, query.getPointIds()).list(); return R.ok(list); } // "2029885249115987970" "2029883649798512642" @ApiOperation(value = "点位导出") @PostMapping("/exportExcel") public void exportExcel(@RequestBody XpPointExportExcelQuery query) { List<Long> pointIds = query == null ? Collections.emptyList() : query.getPointIds(); List<Long> distinctIds = pointIds == null ? Collections.emptyList() : pointIds.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList()); List<XpPoint> points = distinctIds.isEmpty() ? Collections.emptyList() : xpPointService.lambdaQuery().in(XpPoint::getId, distinctIds).list(); Map<Long, XpPoint> pointById = points.stream() .filter(p -> p.getId() != null) .collect(Collectors.toMap(XpPoint::getId, Function.identity(), (a, b) -> a)); List<XpPointExportExcel> exportList = new ArrayList<>(points.size()); for (Long id : distinctIds) { XpPoint xpPoint = pointById.get(id); if (xpPoint == null) { continue; } exportList.add(toExportRow(xpPoint)); } HttpServletResponse response = WebUtils.response(); if (response == null) { throw new ServiceException("导出失败:未获取到响应对象"); } response.setContentType("application/vnd.ms-excel"); response.setCharacterEncoding(StandardCharsets.UTF_8.name()); try { String fileName = URLEncoder.encode("点位列表.xls", StandardCharsets.UTF_8.name()); response.setHeader("Content-disposition", "attachment;filename=" + fileName); try (Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), XpPointExportExcel.class, exportList); ServletOutputStream outputStream = response.getOutputStream()) { workbook.write(outputStream); } } catch (IOException e) { log.error("点位导出失败 pointIds={}", distinctIds, e); throw new ServiceException("点位导出失败"); } } /** * 新增点位 @@ -114,11 +176,16 @@ // @ShardingSphereTransactionType(TransactionType.BASE) public R edit(@Validated @RequestBody PointUpdateDto pointAddDto) { XpPoint xpPoint = xpPointService.getById(pointAddDto.getId()); //先删除原有的数据,因为会存在点位的从属区域变化的情况,所以先删除原有的数据后添加新的数据重新分片到新的库中 xpPointService.removeById(pointAddDto.getId()); BeanUtils.copyProperties(pointAddDto, xpPoint); xpPoint.setId(null); xpPointService.save(xpPoint); if (!xpPoint.getElectronicAreaId().equals(pointAddDto.getElectronicAreaId())) { BeanUtils.copyProperties(pointAddDto, xpPoint); xpPointService.updateById(xpPoint); } else { //先删除原有的数据,因为会存在点位的从属区域变化的情况,所以先删除原有的数据后添加新的数据重新分片到新的库中 BeanUtils.copyProperties(pointAddDto, xpPoint); xpPointService.removeById(pointAddDto.getId()); xpPoint.setId(null); xpPointService.save(xpPoint); } return R.ok(); } @@ -147,5 +214,56 @@ return R.ok(); } private static XpPointExportExcel toExportRow(XpPoint xpPoint) { XpPointExportExcel exportExcel = new XpPointExportExcel(); exportExcel.setPointNumber(xpPoint.getPointNumber()); exportExcel.setPointName(xpPoint.getPointName()); exportExcel.setStatus(calcExportStatus(xpPoint.getOperationStatus(), xpPoint.getVerificationStatus())); exportExcel.setParkingTimeLimit(xpPoint.getParkingTimeLimit() == null ? null : String.valueOf(xpPoint.getParkingTimeLimit())); exportExcel.setPointLon(xpPoint.getPointLon()); exportExcel.setPointLat(xpPoint.getPointLat()); exportExcel.setCreateBy(xpPoint.getCreateBy()); exportExcel.setCreateTime(formatExportTime(xpPoint.getCreateTime())); return exportExcel; } private static String formatExportTime(LocalDateTime time) { return time == null ? null : EXPORT_TIME_FORMATTER.format(time); } private static Integer calcExportStatus(Integer operationStatus, Integer verificationStatus) { if (operationStatus == null) { return null; } if (verificationStatus == 1) { return 1; } if (verificationStatus == 2) { return 2; } if (verificationStatus == 4) { return 3; } if (verificationStatus == 3 && operationStatus == 1) { return 4; } if (verificationStatus == 5 && operationStatus == 1) { return 5; } if (operationStatus == 2) { return 6; } if (operationStatus == 3) { return 7; } if (operationStatus == 4) { return 8; } if (operationStatus != 1 || verificationStatus == null) { return null; } return null; } } xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/exportExcel/XpPointExportExcel.java
@@ -22,7 +22,7 @@ @cn.afterturn.easypoi.excel.annotation.Excel(name = "点位名称",width = 20) private String pointName; @ApiModelProperty(value = "状态") @cn.afterturn.easypoi.excel.annotation.Excel(name = "状态",width = 20,replace = {"待测试_1","测试中_2","测试不通过_3","可运营_4","待生效_5","启用中_6","已停用_7","失效_8",}) @cn.afterturn.easypoi.excel.annotation.Excel(name = "状态",width = 20,replace = {"待测试_1","测试中_2","测试不通过_3","可运营_4","待生效_5","启用中_6","已停用_7","已失效_8",}) private Integer status; @ApiModelProperty(value = "限停时长") @cn.afterturn.easypoi.excel.annotation.Excel(name = "限停时长",width = 20) xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceServiceImpl.java
@@ -44,6 +44,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; /** @@ -391,6 +392,30 @@ xpElectronicFence.setCityCode(dto.getCityCode()); this.updateById(xpElectronicFence); // 禁行区(areaType=2)差异删除:对比原有禁行区与本次编辑入参禁行区(按id) List<XpElectronicFenceArea> existingProhibitedAreas = xpElectronicFenceAreaService.lambdaQuery() .eq(XpElectronicFenceArea::getElectronicId, dto.getId()) .eq(XpElectronicFenceArea::getAreaType, 2) .list(); Set<Long> incomingProhibitedIds = updatedElectronicFenceAreas.stream() .filter(a -> a != null && a.getAreaType() != null && a.getAreaType() == 2 && a.getId() != null) .map(XpElectronicFenceArea::getId) .collect(Collectors.toSet()); List<Long> toDeleteProhibitedIds = existingProhibitedAreas.stream() .map(XpElectronicFenceArea::getId) .filter(id -> id != null && !incomingProhibitedIds.contains(id)) .collect(Collectors.toList()); if (!toDeleteProhibitedIds.isEmpty()) { // 逻辑删除MySQL禁行区 xpElectronicFenceAreaService.removeByIds(toDeleteProhibitedIds); // 同步删除Mongo禁行区多边形 List<String> toDeleteAreaIdStrings = toDeleteProhibitedIds.stream().map(String::valueOf).collect(Collectors.toList()); Query delMongoQuery = new Query(); delMongoQuery.addCriteria(Criteria.where("fenceId").is(String.valueOf(dto.getId()))); delMongoQuery.addCriteria(Criteria.where("areaId").in(toDeleteAreaIdStrings)); mongoTemplate.remove(delMongoQuery, XpGeoFencingProhibitedPolygon.class); } // 删除旧的区域数据,然后保存新的区域数据 mongoTemplate.remove(new Query(Criteria.where("fenceId").is(String.valueOf(dto.getId()))), XpGeoFencingPolygon.class); if (xpElectronicFence.getStatus() == 2) { xp-robotaxi-map-boot/src/main/resources/mapper/XpPointMapper.xml
@@ -80,11 +80,22 @@ <if test="query.pointType != null"> and t1.point_type = #{query.pointType} </if> <if test="query.operationStatusIds != null and query.operationStatusIds.size()>0"> AND t1.operation_status IN <foreach collection="query.operationStatusIds" separator="," item="id" open="(" close=")"> #{id} </foreach> <if test="query.operationStatusList != null and query.operationStatusList.size() > 0"> <trim prefix="and (" suffix=")" prefixOverrides="OR"> <foreach collection="query.operationStatusList" item="st"> <choose> <when test="st == 1">OR t1.verification_status = 1</when> <when test="st == 2">OR t1.verification_status = 2</when> <when test="st == 3">OR t1.verification_status = 4</when> <when test="st == 4">OR (t1.verification_status = 3 and t1.operation_status = 1)</when> <when test="st == 5">OR (t1.verification_status = 5 and t1.operation_status = 1)</when> <when test="st == 6">OR t1.operation_status = 2</when> <when test="st == 7">OR t1.operation_status = 3</when> <when test="st == 8">OR t1.operation_status = 4</when> <otherwise>OR 1 = 0</otherwise> </choose> </foreach> </trim> </if> order by t1.create_time desc </select> @@ -132,31 +143,22 @@ <if test="query.startTime != null and query.startTime != '' and query.endTime != null and query.endTime != ''"> and xp.create_time between #{query.startTime} and #{query.endTime} </if> <if test="query.operationStatus != null"> <if test="query.operationStatus ==1"> and xp.verification_status = 1 </if> <if test="query.operationStatus ==2"> and xp.verification_status = 2 </if> <if test="query.operationStatus ==3"> and xp.verification_status = 4 </if> <if test="query.operationStatus ==4"> and xp.verification_status = 3 and xp.operation_status =1 </if> <if test="query.operationStatus ==5"> and xp.verification_status = 3 and xp.operation_status =1 </if> <if test="query.operationStatus ==6"> and xp.operation_status =2 </if> <if test="query.operationStatus ==7"> and xp.operation_status =3 </if> <if test="query.operationStatus ==8"> and xp.operation_status =4 </if> <if test="query.operationStatusList != null and query.operationStatusList.size() > 0"> <trim prefix="and (" suffix=")" prefixOverrides="OR"> <foreach collection="query.operationStatusList" item="st"> <choose> <when test="st == 1">OR xp.verification_status = 1</when> <when test="st == 2">OR xp.verification_status = 2</when> <when test="st == 3">OR xp.verification_status = 4</when> <when test="st == 4">OR (xp.verification_status = 3 and xp.operation_status = 1)</when> <when test="st == 5">OR (xp.verification_status = 5 and xp.operation_status = 1)</when> <when test="st == 6">OR xp.operation_status = 2</when> <when test="st == 7">OR xp.operation_status = 3</when> <when test="st == 8">OR xp.operation_status = 4</when> <otherwise>OR 1 = 0</otherwise> </choose> </foreach> </trim> </if> order by xp.create_time desc </select> xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpAgreementController.java
@@ -50,7 +50,7 @@ @ApiOperation(value = "获取协议",tags = {"管理后台-内容中心"}) @GetMapping("/api/v1/agreement/content/{type}") public R<XpAgreement> getAgreementContent(@ApiParam(name = "type", value = "类型 1=用户服务协议 2=平台隐私政策 3=敏感个人信息处理情况说明 4=向第三方提供个人信息情况的说明 5=乘车须知 6=计费规则说明 ") @PathVariable Integer type) { public R<XpAgreement> getAgreementContent(@ApiParam(name = "type", value = "类型 1=用户服务协议 2=平台隐私政策 3=敏感个人信息处理情况说明 4=向第三方提供个人信息情况的说明 5=乘车须知 6=计费规则说明 7= 法律法规") @PathVariable Integer type) { return R.ok(xpAgreementService.getAgreementContent(type)); } @ApiOperation(value = "保存协议",tags = {"管理后台-内容中心"}) xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpSystemSettingServiceImpl.java
@@ -1,12 +1,15 @@ package com.xiaopeng.operation.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.xiaopeng.operation.mapper.XpSystemSettingMapper; import com.xiaopeng.api.model.operation.XpSystemSetting; import com.xiaopeng.operation.service.XpSystemSettingService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.Objects; /** * <p> @@ -49,6 +52,10 @@ @Transactional(rollbackFor = Exception.class) @Override public void saveSystemSetting(XpSystemSetting xpSystemSetting) { saveOrUpdate(xpSystemSetting); if (Objects.nonNull(xpSystemSetting.getId())) { update(xpSystemSetting, new LambdaQueryWrapper<XpSystemSetting>().eq(XpSystemSetting::getId, xpSystemSetting.getId())); } else { save(xpSystemSetting); } } } xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/task/BannerTaskUtil.java
@@ -2,6 +2,7 @@ import com.xiaopeng.api.model.operation.XpBanner; import com.xiaopeng.operation.service.XpBannerService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @@ -13,6 +14,7 @@ * @author 无关风月 * @date 2026/2/26 9:49 */ @Slf4j @Component public class BannerTaskUtil { @@ -26,6 +28,7 @@ @Scheduled(fixedRate = 60000) public void taskMinute() { try { log.info("处理的banner状态定时任务开始执行,当前时间:{}", LocalDateTime.now()); // 根据banner开始、结束时间修改banner状态 List<XpBanner> banners = bannerService.list(); for (XpBanner banner : banners) { xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpPointMapper.xml
@@ -132,31 +132,22 @@ <if test="query.startTime != null and query.startTime != '' and query.endTime != null and query.endTime != ''"> and xp.create_time between #{query.startTime} and #{query.endTime} </if> <if test="query.operationStatus != null"> <if test="query.operationStatus ==1"> and xp.verification_status = 1 </if> <if test="query.operationStatus ==2"> and xp.verification_status = 2 </if> <if test="query.operationStatus ==3"> and xp.verification_status = 4 </if> <if test="query.operationStatus ==4"> and xp.verification_status = 3 and xp.operation_status =1 </if> <if test="query.operationStatus ==5"> and xp.verification_status = 3 and xp.operation_status =1 </if> <if test="query.operationStatus ==6"> and xp.operation_status =2 </if> <if test="query.operationStatus ==7"> and xp.operation_status =3 </if> <if test="query.operationStatus ==8"> and xp.operation_status =4 </if> <if test="query.operationStatusList != null and query.operationStatusList.size() > 0"> <trim prefix="and (" suffix=")" prefixOverrides="OR"> <foreach collection="query.operationStatusList" item="st"> <choose> <when test="st == 1">OR xp.verification_status = 1</when> <when test="st == 2">OR xp.verification_status = 2</when> <when test="st == 3">OR xp.verification_status = 4</when> <when test="st == 4">OR (xp.verification_status = 3 and xp.operation_status = 1)</when> <when test="st == 5">OR (xp.verification_status = 5 and xp.operation_status = 1)</when> <when test="st == 6">OR xp.operation_status = 2</when> <when test="st == 7">OR xp.operation_status = 3</when> <when test="st == 8">OR xp.operation_status = 4</when> <otherwise>OR 1 = 0</otherwise> </choose> </foreach> </trim> </if> order by xp.create_time desc </select> xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpFleetServiceImpl.java
@@ -185,6 +185,7 @@ if (excludeFleetId != null) { wrapper.ne(XpFleetOperations::getFleetId, excludeFleetId); } wrapper.last("limit 1"); XpFleetOperations operations = xpFleetOperationsService.getOne(wrapper); if (operations != null) { // 查询人员姓名和车队名称 @@ -218,6 +219,7 @@ if (excludeFleetId != null) { wrapper.ne(XpFleetVehicle::getFleetId, excludeFleetId); } wrapper.last("limit 1"); XpFleetVehicle fleetVehicle = xpFleetVehicleService.getOne(wrapper); if (fleetVehicle != null) { // 车辆已绑定其他车队,自动解绑 @@ -238,15 +240,53 @@ FleetDetailVO vo = new FleetDetailVO(); BeanUtils.copyProperties(fleet, vo); // 3. 统计人员数量 long userCount = xpFleetOperationsService.count(new LambdaQueryWrapper<XpFleetOperations>() .eq(XpFleetOperations::getFleetId, id)); vo.setUserCount((int) userCount); // 3. 统计人员数量(过滤已删除人员) List<Long> bindUserIds = xpFleetOperationsService.lambdaQuery() .eq(XpFleetOperations::getFleetId, id) .list() .stream() .map(XpFleetOperations::getOperationsUserId) .filter(Objects::nonNull) .distinct() .collect(Collectors.toList()); int userCount = 0; if (!CollectionUtils.isEmpty(bindUserIds)) { try { R<List<XpOperationsUser>> usersResult = xpOperationUserClient.listByIds(bindUserIds); if (usersResult != null && usersResult.getData() != null) { userCount = usersResult.getData().size(); } else { userCount = bindUserIds.size(); } } catch (Exception e) { userCount = bindUserIds.size(); } } vo.setUserCount(userCount); // 4. 统计车辆数量 long vehicleCount = xpFleetVehicleService.count(new LambdaQueryWrapper<XpFleetVehicle>() .eq(XpFleetVehicle::getFleetId, id)); vo.setVehicleCount((int) vehicleCount); // 4. 统计车辆数量(过滤已删除车辆) List<Long> bindVehicleIds = xpFleetVehicleService.lambdaQuery() .eq(XpFleetVehicle::getFleetId, id) .list() .stream() .map(XpFleetVehicle::getVehicleId) .filter(Objects::nonNull) .distinct() .collect(Collectors.toList()); int vehicleCount = 0; if (!CollectionUtils.isEmpty(bindVehicleIds)) { try { R<List<XpVehicle>> vehiclesResult = xpVehicleClient.listByIds(bindVehicleIds); if (vehiclesResult != null && vehiclesResult.getData() != null) { vehicleCount = vehiclesResult.getData().size(); } else { vehicleCount = bindVehicleIds.size(); } } catch (Exception e) { vehicleCount = bindVehicleIds.size(); } } vo.setVehicleCount(vehicleCount); // 5. 查询负责人信息 if (fleet.getOperationsUserId() != null) { xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleAnnualRecordServiceImpl.java
@@ -39,6 +39,7 @@ wrapper.le(XpVehicleAnnualRecord::getCreateTime, LocalDateTime.of(query.getEndTime(), LocalTime.MAX)); } wrapper.like(StringUtils.isNotBlank(query.getOperationsUserName()), XpVehicleAnnualRecord::getCreateBy, query.getOperationsUserName()); wrapper.eq(XpVehicleAnnualRecord::getVehicleId, query.getVehicleId()); wrapper.orderByDesc(XpVehicleAnnualRecord::getCreateTime); return this.page(page, wrapper); }