xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpOperationsUserController.java
@@ -2,6 +2,7 @@ import com.xiaopeng.account.mapper.XpOperationsRoleMapper; import com.xiaopeng.account.model.dto.XpOperationsUserDTO; import com.xiaopeng.account.model.query.XpOperationsUserPageQuery; import com.xiaopeng.account.service.IXpOperationsUserService; import com.xiaopeng.api.dto.account.XpOperationsUserQueryDTO; @@ -16,6 +17,7 @@ import org.springframework.util.CollectionUtils; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; import java.util.ArrayList; import java.util.List; @@ -130,4 +132,16 @@ return R.ok(profile); } /** * 运维APP-个人中心-证件上传 * @param dto * @return */ @ApiOperation(value = "个人中心-证件上传", tags = {"运维APP-个人中心"}) @PostMapping("/api/v1/saveCertificate") public R<?> saveCertificate(@Valid @RequestBody XpOperationsUserDTO dto){ xpOperationsUserService.saveCertificate(dto); return R.ok(); } } xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpOperationsUserNotificationController.java
@@ -1,9 +1,17 @@ package com.xiaopeng.account.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.stereotype.Controller; import com.xiaopeng.account.model.query.XpOperationsUserNotificationPageQuery; import com.xiaopeng.account.service.IXpOperationsUserNotificationService; import com.xiaopeng.api.model.account.XpOperationsUserNotification; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.core.web.page.PageInfo; import com.xiaopeng.common.security.service.TokenService; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; /** * <p> @@ -13,8 +21,38 @@ * @author mitao * @since 2026-02-03 */ @Controller @RequestMapping("/xp-operations-user-notification") @Slf4j @RestController public class XpOperationsUserNotificationController { @Autowired private IXpOperationsUserNotificationService notificationService; @Autowired private TokenService tokenService; /** * 根据当前登录用户获取通知分页列表(运维APP接口) */ @PostMapping("/api/v1/notification/list") @ApiOperation(value = "获取通知分页列表", tags = {"运维APP-消息通知"}) public R<PageInfo<XpOperationsUserNotification>> getNotificationList( @RequestBody XpOperationsUserNotificationPageQuery query) { log.info("查询通知分页列表, pageNum={}, pageSize={}", query.getPageNum(), query.getPageSize()); // 从Token中获取当前登录用户ID Long currentUserId = tokenService.getLoginOperationUser().getId(); query.setOperationsUserId(currentUserId); // 查询分页列表 PageInfo<XpOperationsUserNotification> pageInfo = notificationService.selectNotificationPageByUserId(query); log.info("查询通知分页列表成功, userId={}, total={}", currentUserId, pageInfo.getTotal()); return R.ok(pageInfo); } } xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/mapper/XpOperationsUserNotificationMapper.java
@@ -1,7 +1,10 @@ package com.xiaopeng.account.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.xiaopeng.account.model.query.XpOperationsUserNotificationPageQuery; import com.xiaopeng.api.model.account.XpOperationsUserNotification; import org.apache.ibatis.annotations.Param; /** * <p> @@ -13,4 +16,14 @@ */ public interface XpOperationsUserNotificationMapper extends BaseMapper<XpOperationsUserNotification> { /** * 分页查询用户通知列表 * @param page 分页对象 * @param query 查询条件 * @return 通知分页列表 */ Page<XpOperationsUserNotification> selectNotificationPageByUserId( Page<XpOperationsUserNotification> page, @Param("query") XpOperationsUserNotificationPageQuery query ); } xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/vo/SysGroupDetailVO.java
@@ -29,4 +29,7 @@ @ApiModelProperty(value = "菜单列表") private List<SysMenuVO> menus; @ApiModelProperty(value = "菜单列表") private List<Long> menuIds; } xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/IXpOperationsUserNotificationService.java
@@ -1,7 +1,9 @@ package com.xiaopeng.account.service; import com.baomidou.mybatisplus.extension.service.IService; import com.xiaopeng.account.model.query.XpOperationsUserNotificationPageQuery; import com.xiaopeng.api.model.account.XpOperationsUserNotification; import com.xiaopeng.common.core.web.page.PageInfo; /** * <p> @@ -13,4 +15,12 @@ */ public interface IXpOperationsUserNotificationService extends IService<XpOperationsUserNotification> { /** * 分页查询用户通知列表 * @param query 查询条件 * @return 通知分页列表 */ PageInfo<XpOperationsUserNotification> selectNotificationPageByUserId( XpOperationsUserNotificationPageQuery query ); } xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/IXpOperationsUserService.java
@@ -1,12 +1,14 @@ package com.xiaopeng.account.service; import com.baomidou.mybatisplus.extension.service.IService; import com.xiaopeng.account.model.dto.XpOperationsUserDTO; import com.xiaopeng.account.model.query.XpOperationsUserPageQuery; import com.xiaopeng.api.model.account.XpOperationsUser; import com.xiaopeng.api.vo.account.XpOperationsUserProfileVO; import com.xiaopeng.api.vo.account.XpOperationsUserWithRoleVO; import com.xiaopeng.common.core.web.page.PageInfo; import javax.validation.Valid; import java.util.List; /** @@ -39,4 +41,10 @@ * @return 个人中心首页信息 */ XpOperationsUserProfileVO getUserProfile(Long userId); /** * * @param dto */ void saveCertificate(@Valid XpOperationsUserDTO dto); } xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysGroupServiceImpl.java
@@ -137,8 +137,10 @@ List<SysMenu> menus = result.getData(); // 构建菜单树 vo.setMenus(buildMenuTree(menus)); vo.setMenuIds(menus.stream().map(SysMenu::getId).collect(Collectors.toList())); } else { vo.setMenus(new ArrayList<>()); vo.setMenuIds(new ArrayList<>()); } } catch (Exception e) { log.error("获取菜单列表失败: {}", e.getMessage()); xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpOperationsUserNotificationServiceImpl.java
@@ -1,9 +1,12 @@ package com.xiaopeng.account.service.impl; import com.xiaopeng.account.mapper.XpOperationsUserNotificationMapper; import com.xiaopeng.account.service.IXpOperationsUserNotificationService; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.xiaopeng.account.mapper.XpOperationsUserNotificationMapper; import com.xiaopeng.account.model.query.XpOperationsUserNotificationPageQuery; import com.xiaopeng.account.service.IXpOperationsUserNotificationService; import com.xiaopeng.api.model.account.XpOperationsUserNotification; import com.xiaopeng.common.core.web.page.PageInfo; import org.springframework.stereotype.Service; /** @@ -17,4 +20,27 @@ @Service public class XpOperationsUserNotificationServiceImpl extends ServiceImpl<XpOperationsUserNotificationMapper, XpOperationsUserNotification> implements IXpOperationsUserNotificationService { @Override public PageInfo<XpOperationsUserNotification> selectNotificationPageByUserId( XpOperationsUserNotificationPageQuery query) { // 创建分页对象 Page<XpOperationsUserNotification> page = new Page<>( query.getPageNum(), query.getPageSize() ); // 执行分页查询 Page<XpOperationsUserNotification> resultPage = baseMapper.selectNotificationPageByUserId( page, query ); // 封装分页结果 PageInfo<XpOperationsUserNotification> pageInfo = new PageInfo<>(); pageInfo.setRecords(resultPage.getRecords()); pageInfo.setTotal(resultPage.getTotal()); return pageInfo; } } xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpOperationsUserServiceImpl.java
@@ -1,8 +1,10 @@ package com.xiaopeng.account.service.impl; import cn.hutool.core.bean.BeanUtil; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.xiaopeng.account.mapper.XpOperationsRoleMapper; import com.xiaopeng.account.mapper.XpOperationsUserMapper; import com.xiaopeng.account.model.dto.XpOperationsUserDTO; import com.xiaopeng.account.model.query.XpOperationsUserPageQuery; import com.xiaopeng.account.service.IXpOperationsUserService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -149,4 +151,10 @@ return vo; } @Override public void saveCertificate(XpOperationsUserDTO dto) { XpOperationsUser xpOperationsUser = BeanUtil.copyProperties(dto, XpOperationsUser.class); updateById(xpOperationsUser); } } xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsUserNotificationMapper.xml
@@ -7,4 +7,15 @@ id, notification_type, notification_content, operations_user_id, data_id, is_deleted, create_time, update_time, create_by, update_by </sql> <!-- 分页查询用户通知列表 --> <select id="selectNotificationPageByUserId" resultType="com.xiaopeng.api.model.account.XpOperationsUserNotification"> SELECT <include refid="Base_Column_List"/> FROM xp_operations_user_notification WHERE operations_user_id = #{query.operationsUserId} AND is_deleted = 0 ORDER BY create_time DESC </select> </mapper> xp-robotaxi-account-boot/xp-robotaxi-account-boot.iml
File was deleted xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/maintenance/XpTaskRule.java
@@ -113,5 +113,6 @@ @ApiModelProperty(value = "任务处理时限(分钟)") private Integer processingTimeLimit; @ApiModelProperty(value = "可以操作到达的配置范围,单位米") private Double canArriveRange; } xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpAppVersion.java
@@ -38,10 +38,4 @@ @ApiModelProperty(value = "更新说明") private String updateDescription; @ApiModelProperty(value = "是否强制更新 0-否 1-是") private Integer forceUpdateFlag; @ApiModelProperty(value = "版本号 判断是否需要升级") private Integer versionCode; } xp-robotaxi-api/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -28,4 +28,5 @@ com.xiaopeng.api.factory.automaticPilot.OrderMissionClientFallbackFactory com.xiaopeng.api.factory.maintenance.XpCheckLocationClientFallbackFactory com.xiaopeng.api.factory.automaticPilot.OrderMissionClientFallbackFactory com.xiaopeng.api.factory.maintenance.XpClockInClientFallbackFactory com.xiaopeng.api.factory.maintenance.XpClockInClientFallbackFactory com.xiaopeng.api.factory.account.SysGroupMenuClientFallbackFactory xp-robotaxi-api/xp-robotaxi-api.iml
File was deleted xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpChargingRecordController.java
@@ -11,6 +11,7 @@ import com.xiaopeng.maintenance.dto.XpChargingRecordStopDTO; import com.xiaopeng.maintenance.model.vo.XpChargingRecordVO; import com.xiaopeng.maintenance.service.IXpChargingRecordService; import com.xiaopeng.maintenance.vo.ChargingStatusVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; @@ -65,6 +66,18 @@ } /** * 车辆运维-车辆运维-车辆充电查询当前状态 */ @ApiOperation(value = "车辆运维-车辆运维-车辆充电查询当前状态", tags = {"运维APP-车辆管理"}) @GetMapping("/api/v1/chargingRecord/queryChargingStatus") public R<ChargingStatusVO> queryChargingStatus(@RequestParam Long vehicleId) { Long id = tokenService.getLoginOperationUser().getId(); ChargingStatusVO chargingStatusVO = xpChargingRecordService.queryChargingStatus(vehicleId); return R.ok(chargingStatusVO); } /** * 车辆运维-车辆运维-充电记录详情 */ @ApiOperation(value = "车辆运维-运维记录-充电记录详情", tags = {"运维APP-车辆管理"}) xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpVehicleRepairController.java
@@ -10,6 +10,7 @@ import com.xiaopeng.maintenance.model.query.XpVehicleRepairPageQuery; import com.xiaopeng.maintenance.model.vo.XpVehicleRepairVO; import com.xiaopeng.maintenance.service.IXpVehicleRepairService; import com.xiaopeng.maintenance.vo.RepairStatusVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; @@ -76,6 +77,17 @@ } /** * 车辆详情-车辆运维-查询车辆维修状态 */ @ApiOperation(value = "车辆运维-车辆运维-查询车辆维修状态", tags = {"运维APP-车辆管理"}) @GetMapping("/api/v1/vehicleRepair/queryRepairStatus") public R<RepairStatusVO> queryRepairStatus(@RequestParam Long vehicleId) { Long id = tokenService.getLoginOperationUser().getId(); RepairStatusVO repairStatusVO = xpVehicleRepairService.queryRepairStatus(vehicleId); return R.ok(repairStatusVO); } /** * 车辆运维-车辆运维-维修记录详情 */ @ApiOperation(value = "车辆运维-运维记录-维修记录详情", tags = {"运维APP-车辆管理"}) xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/model/query/TaskPageListQuery.java
@@ -26,4 +26,10 @@ private Integer status; @ApiModelProperty(value = "车牌号") private String plateNumber; @ApiModelProperty(value = "当前位置经度") private Double longitude; @ApiModelProperty(value = "当前位置纬度") private Double latitude; } xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/model/vo/TaskAccidentDetailVO.java
@@ -7,6 +7,7 @@ import lombok.Data; import java.io.Serializable; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.List; @@ -29,6 +30,7 @@ @ApiModelProperty(value = "任务紧急程度 0=P0 1=P1 2=P2 3=P3") private Integer taskUrgencyLevel; @ApiModelProperty(value = "任务处理时限") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private LocalDateTime endTime; @ApiModelProperty(value = "车牌号") private String plateNumber; @@ -41,7 +43,7 @@ @ApiModelProperty(value = "任务创建人") private String createBy; @ApiModelProperty(value = "任务创建时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private LocalDateTime createTime; @ApiModelProperty(value = "任务编号") @@ -60,4 +62,13 @@ private String taskDescription; @ApiModelProperty(value = "任务描述图片") private String taskImage; @ApiModelProperty(value = "车辆经度") private BigDecimal vehicleLon; @ApiModelProperty(value = "车辆纬度") private BigDecimal vehicleLat; @ApiModelProperty(value = "可以操作到达的配置范围,单位米") private Double canArriveRange = 200D; } xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/model/vo/TaskPageListVO.java
@@ -2,6 +2,7 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -38,6 +39,7 @@ @ApiModelProperty(value = "任务紧急程度 0=P0 1=P1 2=P2 3=P3") private Integer taskUrgencyLevel; @ApiModelProperty(value = "任务处理时限") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private LocalDateTime endTime; @ApiModelProperty(value = "车辆位置") private String vehicleLocation; @@ -55,4 +57,7 @@ @ApiModelProperty(value = "状态 0=待到达 1=待处理 2=已完成 3=已取消") private Integer status; @ApiModelProperty(value = "可以操作到达的配置范围,单位米") private Double canArriveRange = 200D; } xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/IXpChargingRecordService.java
@@ -7,6 +7,7 @@ import com.xiaopeng.maintenance.dto.XpChargingRecordStartDTO; import com.xiaopeng.maintenance.dto.XpChargingRecordStopDTO; import com.xiaopeng.maintenance.model.vo.XpChargingRecordVO; import com.xiaopeng.maintenance.vo.ChargingStatusVO; /** * <p> @@ -55,4 +56,11 @@ * @param id */ void deleteRecordById(Long id); /** * 查询充电状态 * @param vehicleId * @return */ ChargingStatusVO queryChargingStatus(Long vehicleId); } xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/IXpVehicleRepairService.java
@@ -5,6 +5,7 @@ import com.xiaopeng.common.core.web.page.PageInfo; import com.xiaopeng.maintenance.model.query.XpVehicleRepairPageQuery; import com.xiaopeng.maintenance.model.vo.XpVehicleRepairVO; import com.xiaopeng.maintenance.vo.RepairStatusVO; import javax.validation.Valid; @@ -32,4 +33,12 @@ * @return */ PageInfo<XpVehicleRepairVO> queryDetectionByVehicleId(@Valid XpVehicleRepairPageQuery query); /** * 获取车辆维修状态 * * @param vehicleId * @return */ RepairStatusVO queryRepairStatus(Long vehicleId); } xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpChargingRecordServiceImpl.java
@@ -16,6 +16,7 @@ import com.xiaopeng.maintenance.mapper.XpChargingRecordMapper; import com.xiaopeng.maintenance.model.vo.XpChargingRecordVO; import com.xiaopeng.maintenance.service.IXpChargingRecordService; import com.xiaopeng.maintenance.vo.ChargingStatusVO; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -191,4 +192,34 @@ public void deleteRecordById(Long id) { removeById(id); } @Override public ChargingStatusVO queryChargingStatus(Long vehicleId) { ChargingStatusVO chargingStatusVO = new ChargingStatusVO(); // 查询车辆当前充电信息 XpChargingRecord xpChargingRecord = this.getOne(new LambdaQueryWrapper<XpChargingRecord>() .eq(XpChargingRecord::getVehicleId, vehicleId) .isNull(XpChargingRecord::getEndRemainingBattery) .isNull(XpChargingRecord::getTaskId) .orderByDesc(XpChargingRecord::getCreateTime) .last("LIMIT 1")); if(Objects.nonNull(xpChargingRecord)){ chargingStatusVO.setStatus(2); // 查询开始充电操作人名称 XpOperationsUser operationsUser = xpOperationUserClient.queryById(xpChargingRecord.getStartOperationsUserId()).getData(); if(Objects.nonNull(operationsUser)){ chargingStatusVO.setOperatorStartName(operationsUser.getNickName()); } }else{ chargingStatusVO.setStatus(1); } // 设置充电信息 chargingStatusVO.setXpChargingRecord(xpChargingRecord); return chargingStatusVO; } } xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpTaskServiceImpl.java
@@ -82,6 +82,8 @@ @Autowired private XpVehicleClient xpVehicleClient; @Autowired private XpTaskRuleMapper xpTaskRuleMapper; @Override public PageInfo<WorkBenchVO> workbench(WorkBenchQuery query) { PageInfo<WorkBenchVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); @@ -123,6 +125,12 @@ } PageInfo<TaskPageListVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); List<TaskPageListVO> list = this.baseMapper.pageList(pageInfo, query); XpTaskRule xpTaskRule = xpTaskRuleMapper.selectOne(new LambdaQueryWrapper<XpTaskRule>().last("limit 1")); if (Objects.nonNull(xpTaskRule)) { list.stream().filter(item -> item.getTaskCategory().equals(2)).forEach(item->{ item.setCanArriveRange(xpTaskRule.getCanArriveRange()); }); } pageInfo.setRecords(list); return pageInfo; } @@ -177,6 +185,8 @@ res.setTaskCode(task.getTaskCode()); res.setTaskCategory(task.getTaskCategory()); res.setTaskTypeId(task.getTaskTypeId()); res.setVehicleLon(task.getVehicleLon()); res.setVehicleLat(task.getVehicleLat()); Map<Long, List<XpErrorType>> errorType = errorTypeMapper.selectList(new LambdaQueryWrapper<XpErrorType>() .in(XpErrorType::getId, Arrays.asList(task.getTaskTypeId().split(",")))) .stream().collect(Collectors.groupingBy(XpErrorType::getParentId)); @@ -188,6 +198,10 @@ res.setStatus(task.getStatus()); res.setTaskDescription(task.getTaskDescription()); res.setTaskImage(task.getTaskImage()); XpTaskRule xpTaskRule = xpTaskRuleMapper.selectOne(new LambdaQueryWrapper<XpTaskRule>().last("limit 1")); if (Objects.nonNull(xpTaskRule)) { res.setCanArriveRange(xpTaskRule.getCanArriveRange()); } return R.ok(res); } xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpVehicleRepairServiceImpl.java
@@ -6,6 +6,7 @@ import com.xiaopeng.api.feignClient.account.XpOperationUserClient; import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient; import com.xiaopeng.api.model.account.XpOperationsUser; import com.xiaopeng.api.model.maintenance.XpChargingRecord; import com.xiaopeng.api.model.maintenance.XpVehicleRepair; import com.xiaopeng.api.model.vehicleConvoy.XpVehicle; import com.xiaopeng.common.core.domain.R; @@ -14,6 +15,8 @@ import com.xiaopeng.maintenance.model.query.XpVehicleRepairPageQuery; import com.xiaopeng.maintenance.model.vo.XpVehicleRepairVO; import com.xiaopeng.maintenance.service.IXpVehicleRepairService; import com.xiaopeng.maintenance.vo.ChargingStatusVO; import com.xiaopeng.maintenance.vo.RepairStatusVO; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -165,4 +168,34 @@ return pageInfo; } @Override public RepairStatusVO queryRepairStatus(Long vehicleId) { RepairStatusVO repairStatusVO = new RepairStatusVO(); // 查询车辆当前维修信息 XpVehicleRepair xpVehicleRepair = this.getOne(new LambdaQueryWrapper<XpVehicleRepair>() .eq(XpVehicleRepair::getVehicleId, vehicleId) .isNull(XpVehicleRepair::getReturnTime) .isNull(XpVehicleRepair::getTaskId) .orderByDesc(XpVehicleRepair::getCreateTime) .last("LIMIT 1")); if(Objects.nonNull(xpVehicleRepair)){ repairStatusVO.setStatus(2); // 查询开始充电操作人名称 XpOperationsUser operationsUser = xpOperationUserClient.queryById(xpVehicleRepair.getSendUserId()).getData(); if(Objects.nonNull(operationsUser)){ repairStatusVO.setSendUserName(operationsUser.getNickName()); } }else{ repairStatusVO.setStatus(1); } // 设置维修信息 repairStatusVO.setXpVehicleRepair(xpVehicleRepair); return repairStatusVO; } } xp-robotaxi-maintenance-boot/src/main/resources/mapper/maintenance/XpTaskMapper.xml
@@ -44,7 +44,7 @@ </select> <select id="pageList" resultType="com.xiaopeng.maintenance.model.vo.TaskPageListVO"> select t1.id,t1.task_code as taskCode,t1.end_time as endTime,t1.task_category as taskCategory,t1.task_type_id as taskTypeId,t1.task_urgency_level as taskUrgencyLevel,t1.task_description as taskDescription,t1.vehicle_location as vehicleLocation,t1.vehicle_id as vehicleId,t1.vehicle_lon as vehicleLon,t1.vehicle_lat as vehicleLat,t1.handle_user_id as handleUserId,t1.handle_time as handleTime,t1.assignee_user_id as assigneeUserId ,t1.assignee_time as assigneeTime,t1.task_image,taskImage,t1.report_user_id as reportUserId,t1.report_time as reportTime,t1.status as status,t1.is_deleted as isDeleted,t1.create_time as createTime,t1.update_time as updateTime,t1.create_by as createBy,t1.update_by as updateBy,t2.plate_number as plateNumber ,t1.assignee_time as assigneeTime,t1.task_image as taskImage,t1.report_user_id as reportUserId,t1.report_time as reportTime,t1.status as status,t1.is_deleted as isDeleted,t1.create_time as createTime,t1.update_time as updateTime,t1.create_by as createBy,t1.update_by as updateBy,t2.plate_number as plateNumber from xp_task t1 left join xp_vehicle t2 on t1.vehicle_id = t2.id where t1.is_deleted = 0 xp-robotaxi-maintenance-boot/src/main/resources/mapper/maintenance/XpVehiclePreparationMapper.xml
@@ -10,7 +10,7 @@ </sql> <select id="operationRecords" resultType="com.xiaopeng.maintenance.model.vo.OperationRecordsVO"> SELECT xvp.id, xvp.vehicle_id, xvp.start_remaining_battery,xvp.end_remaining_battery, SELECT xvp.id, xvp.vehicle_id, xvp.operations_user_id,xvp.create_time AS operationTime FROM xp_vehicle_preparation xvp WHERE xvp.is_deleted = 0 xp-robotaxi-operation-boot/pom.xml
@@ -40,7 +40,6 @@ </dependency> <!-- hutool--> <!-- <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> @@ -48,17 +47,6 @@ <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> --> <dependency> <groupId>com.xiaopeng.logan</groupId> <artifactId>logan2-namor-client</artifactId> <version>1.16.0</version> </dependency> <dependency> <groupId>com.xiaopeng.logan</groupId> <artifactId>logan-starter-core</artifactId> <version>2.3.5</version> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> @@ -180,16 +168,22 @@ <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> </dependency> <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId> <version>5.0.0</version> </dependency> <dependency> <groupId>org.yaml</groupId> <artifactId>snakeyaml</artifactId> <version>1.33</version> </dependency> <!-- <dependency>--> <!-- <groupId>org.apache.shardingsphere</groupId>--> <!-- <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>--> <!-- <version>5.0.0</version>--> <!-- </dependency>--> <!-- <!– 使用 BASE 事务时,需要引入此模块 –>--> <!-- <dependency>--> <!-- <groupId>org.apache.shardingsphere</groupId>--> <!-- <artifactId>shardingsphere-transaction-base-seata-at</artifactId>--> <!-- <version>5.0.0</version>--> <!-- </dependency>--> <!-- <dependency>--> <!-- <groupId>org.yaml</groupId>--> <!-- <artifactId>snakeyaml</artifactId>--> <!-- <version>1.33</version>--> <!-- </dependency>--> </dependencies> @@ -204,15 +198,11 @@ </dependencyManagement> <build> <!--<finalName>${project.artifactId}</finalName>--> <finalName>${project.artifactId}</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <classifier>exec</classifier> <executable>true</executable> </configuration> <executions> <execution> <goals> xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/OssController.java
@@ -1,7 +1,9 @@ package com.xiaopeng.operation.controller; import cn.hutool.core.lang.UUID; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.operation.vo.FileUploadVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; @@ -28,14 +30,18 @@ @PostMapping("/upload") @ApiOperation(value = "文件上传",tags = "文件上传") public R<String> uploadOSS(@RequestPart("file") MultipartFile file) { public R<FileUploadVO> uploadOSS(@RequestPart("file") MultipartFile file) { try { // // 上传并返回访问地址 // String fileName = file.getOriginalFilename(); // String prefix = fileName.substring(fileName.lastIndexOf(".")); // long fileSize = file.getSize(); // String url = OssUploadUtil.ossUpload(file); return R.ok("https://we-park-life.oss-cn-beijing.aliyuncs.com/img/K4vqtLmVc6.png"); FileUploadVO fileUploadVO = new FileUploadVO(); fileUploadVO.setId(UUID.randomUUID().toString()); fileUploadVO.setName("测试.jpg"); fileUploadVO.setUrl("https://we-park-life.oss-cn-beijing.aliyuncs.com/img/K4vqtLmVc6.png"); return R.ok(fileUploadVO); } catch (Exception e) { System.err.println("上传文件失败"+e); return R.fail(e.getMessage()); xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpAgreementController.java
@@ -2,24 +2,19 @@ import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.core.web.controller.BaseController; import com.xiaopeng.common.core.web.domain.AjaxResult; import com.xiaopeng.operation.service.XpAgreementService; import com.xiaopeng.operation.vo.XpAgreementVo; import com.xiaopeng.operation.vo.XpBannerListVo; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @Slf4j @RestController @RequestMapping("/base/v1/mini-program") @Api(tags = "协议模块") public class XpAgreementController extends BaseController { private final XpAgreementService xpAgreementService; @@ -29,21 +24,23 @@ } @ApiOperation(value = "获取协议",tags = {"小程序-首页"},response = XpAgreementVo.class) @GetMapping("/privacy/content/{type}") @GetMapping("/base/v1/mini-program/privacy/content/{type}") public R<XpAgreementVo> getContent(@PathVariable Integer type) { return R.ok(xpAgreementService.getContentByType(type)); } @ApiOperation(value = "获取协议所有",tags = {"小程序-首页所有"},response = XpAgreementVo.class) @GetMapping("/privacy/contentAll") @GetMapping("/base/v1/mini-program/privacy/contentAll") public R<List<XpAgreementVo>> contentAll() { return R.ok(xpAgreementService.getContentByTypeAll()); } @ApiOperation(value = "获取协议/隐私政策",tags = {"运维APP-个人中心"},response = XpAgreementVo.class) @GetMapping("/base/v1/privacy/content/{type}") public R<XpAgreementVo> getAppContent(@ApiParam(name = "type", value = "类型 1=用户服务协议 2=平台隐私政策 ") @PathVariable Integer type) { return R.ok(xpAgreementService.getContentByType(type)); } } xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpAppVersionController.java
@@ -1,16 +1,14 @@ package com.xiaopeng.operation.controller; import com.xiaopeng.api.model.operation.XpAppVersion; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.core.web.page.BasePage; import com.xiaopeng.common.core.web.page.PageInfo; import com.xiaopeng.operation.service.IXpAppVersionService; import com.xiaopeng.operation.vo.XpAppVersionVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Lazy; import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * App版本管理 Controller @@ -20,10 +18,15 @@ */ @Slf4j @RestController @RequiredArgsConstructor(onConstructor_ = @Lazy) @RequestMapping("") @Api(tags = "App版本管理") public class XpAppVersionController { private final IXpAppVersionService appVersionService; public XpAppVersionController(IXpAppVersionService appVersionService) { this.appVersionService = appVersionService; } /** * 获取App最新版本(运维APP接口) @@ -34,18 +37,5 @@ log.info("查询App最新版本"); XpAppVersionVO vo = appVersionService.getLatestVersion(); return R.ok(vo); } @ApiOperation(value = "获取版本管理分页列表", tags = "管理后台-APP版本") @PostMapping("/api/v1/appVersion/page") public R<PageInfo<XpAppVersion>> getPageList(@RequestBody BasePage basePage) { return R.ok(appVersionService.getPageList(basePage)); } @ApiOperation(value = "发布APP版本", tags = "管理后台-APP版本") @PostMapping("/api/v1/appVersion/release") public R<?> release(@RequestBody XpAppVersion appVersion) { appVersionService.release(appVersion); return R.ok(); } } xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpSystemSettingController.java
@@ -1,6 +1,5 @@ package com.xiaopeng.operation.controller; import com.xiaopeng.api.model.operation.SysOperLog; import com.xiaopeng.common.core.constant.CacheConstants; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.core.web.controller.BaseController; @@ -8,14 +7,12 @@ import com.xiaopeng.common.redis.service.RedisService; import com.xiaopeng.operation.service.XpSystemSettingService; import com.xiaopeng.operation.vo.CustomerServicePhoneVo; import com.xiaopeng.operation.vo.XpBannerListVo; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.bind.annotation.*; import java.util.List; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @Slf4j @RestController @@ -64,4 +61,14 @@ return R.ok(xpSystemSettingService.getOrderFinishTime()); } @GetMapping("/base/v1/support/phone") @ApiOperation(value = "获取客服电话", tags = {"运维APP-个人中心"}, response = String.class) public R<CustomerServicePhoneVo> getCustomerPhone() { Object customerServicePhone = redisService.getCacheObject(CacheConstants.CUSTOMER_SERVICE_PHONE); if (customerServicePhone != null) { return R.ok(new CustomerServicePhoneVo(customerServicePhone.toString())); } else { return R.ok(new CustomerServicePhoneVo(xpSystemSettingService.getCustomerServicePhone())); } } } xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpAppVersionService.java
@@ -2,8 +2,6 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.xiaopeng.api.model.operation.XpAppVersion; import com.xiaopeng.common.core.web.page.BasePage; import com.xiaopeng.common.core.web.page.PageInfo; import com.xiaopeng.operation.vo.XpAppVersionVO; /** @@ -19,17 +17,4 @@ * @return 最新版本信息 */ XpAppVersionVO getLatestVersion(); /** * 获取版本管理分页列表 * @param basePage * @return */ PageInfo<XpAppVersion> getPageList(BasePage basePage); /** * 新增APP版本 * @param appVersion */ void release(XpAppVersion appVersion); } xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/SysMenuServiceImpl.java
@@ -1,9 +1,18 @@ package com.xiaopeng.operation.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.xiaopeng.api.feignClient.account.SysGroupMenuClient; import com.xiaopeng.api.feignClient.account.SysRoleClient; import com.xiaopeng.api.feignClient.account.SysUserRoleClient; import com.xiaopeng.api.model.account.SysRole; import com.xiaopeng.api.model.account.SysUserRole; import com.xiaopeng.api.model.operation.SysMenu; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.security.service.TokenService; import com.xiaopeng.operation.mapper.SysMenuMapper; import com.xiaopeng.operation.service.ISysMenuService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.*; @@ -17,8 +26,21 @@ * @author mitao * @since 2026-02-03 */ @Slf4j @Service public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements ISysMenuService { @Autowired private TokenService tokenService; @Autowired private SysUserRoleClient sysUserRoleClient; @Autowired private SysRoleClient sysRoleClient; @Autowired private SysGroupMenuClient sysGroupMenuClient; /** * 根据菜单ID列表查询菜单列表 @@ -105,7 +127,61 @@ @Override public List<SysMenu> getPermission() { try { // 1. 获取当前登录用户ID Long userId = tokenService.getLoginUser().getUserid(); if (userId == null) { log.warn("获取当前登录用户ID失败"); return Collections.emptyList(); } return Collections.emptyList(); // 2. 查询用户角色关联 R<SysUserRole> userRoleResult = sysUserRoleClient.selectSysUserRoleByUserId(userId); if (userRoleResult == null || userRoleResult.getCode() != 200 || userRoleResult.getData() == null) { log.warn("查询用户角色关联失败, userId={}", userId); return Collections.emptyList(); } Long roleId = userRoleResult.getData().getRoleId(); if (roleId == null) { log.warn("用户未关联角色, userId={}", userId); return Collections.emptyList(); } // 3. 查询角色信息 R<SysRole> roleResult = sysRoleClient.getRoleById(roleId); if (roleResult == null || roleResult.getCode() != 200 || roleResult.getData() == null) { log.warn("查询角色信息失败, roleId={}", roleId); return Collections.emptyList(); } Long groupId = roleResult.getData().getGroupId(); if (groupId == null) { log.warn("角色未关联权限组, roleId={}", roleId); return Collections.emptyList(); } // 4. 查询权限组关联的菜单ID列表 R<List<Long>> menuIdsResult = sysGroupMenuClient.selectMenuIdsByGroupId(groupId); if (menuIdsResult == null || menuIdsResult.getCode() != 200 || menuIdsResult.getData() == null) { log.warn("查询权限组菜单ID列表失败, groupId={}", groupId); return Collections.emptyList(); } List<Long> menuIds = menuIdsResult.getData(); if (menuIds.isEmpty()) { log.info("权限组未关联菜单, groupId={}", groupId); return Collections.emptyList(); } // 5. 查询菜单详情 List<SysMenu> menus = this.listByIds(menuIds); log.info("查询用户权限菜单成功, userId={}, menuCount={}", userId, menus.size()); return menus; } catch (Exception e) { log.error("查询用户权限菜单异常", e); return Collections.emptyList(); } } } xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpAgreementAppUserServiceImpl.java
@@ -8,7 +8,6 @@ import com.xiaopeng.operation.service.XpAgreementAppUserService; import org.springframework.stereotype.Service; import java.time.LocalDateTime; import java.util.List; import java.util.stream.Collectors; @@ -29,11 +28,6 @@ xpAgreementAppUser.setAppUserId(appUserId); List<Long> type = xpAgreementAppUserDto.getType(); xpAgreementAppUser.setAgreementIds(type.stream().map(String::valueOf).collect(Collectors.joining(","))); xpAgreementAppUser.setCreateBy(appUserId.toString()); xpAgreementAppUser.setUpdateBy(appUserId.toString()); xpAgreementAppUser.setCreateTime(LocalDateTime.now()); xpAgreementAppUser.setUpdateTime(LocalDateTime.now()); xpAgreementAppUser.setDeleted(false); return save(xpAgreementAppUser); } } xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpAppVersionServiceImpl.java
@@ -1,39 +1,16 @@ package com.xiaopeng.operation.service.impl; import cn.hutool.core.bean.BeanUtil; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.xiaopeng.api.dto.pushMessage.AliPushMessageDTO; import com.xiaopeng.api.feignClient.account.XpOperationUserClient; import com.xiaopeng.api.feignClient.account.XpOperationUserNotificationClient; import com.xiaopeng.api.feignClient.pushMessage.XpAliPushMessageClient; import com.xiaopeng.api.model.account.XpOperationsUser; import com.xiaopeng.api.model.account.XpOperationsUserNotification; import com.xiaopeng.api.model.operation.XpAppVersion; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.core.enums.NotificationTypeEnum; import com.xiaopeng.common.core.exception.ServiceException; import com.xiaopeng.common.core.web.page.BasePage; import com.xiaopeng.common.core.web.page.PageInfo; import com.xiaopeng.common.security.utils.SecurityUtils; import com.xiaopeng.operation.mapper.XpAppVersionMapper; import com.xiaopeng.operation.service.IXpAppVersionService; import com.xiaopeng.operation.vo.XpAppVersionVO; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; /** * App版本管理 服务实现类 @@ -43,20 +20,13 @@ */ @Slf4j @Service @RequiredArgsConstructor(onConstructor_ = @Lazy) public class XpAppVersionServiceImpl extends ServiceImpl<XpAppVersionMapper, XpAppVersion> implements IXpAppVersionService { private final XpOperationUserClient xpOperationUserClient; private final XpOperationUserNotificationClient xpOperationUserNotificationClient; private final XpAliPushMessageClient xpAliPushMessageClient; @Override public XpAppVersionVO getLatestVersion() { // 查询最新版本(按ID倒序,取第一条) XpAppVersion latestVersion = this.lambdaQuery() .orderByDesc(XpAppVersion::getVersionCode) .orderByDesc(XpAppVersion::getId) .last("LIMIT 1") .one(); @@ -69,179 +39,5 @@ XpAppVersionVO vo = BeanUtil.copyProperties(latestVersion, XpAppVersionVO.class); log.info("获取最新App版本成功, version={}", vo.getVersion()); return vo; } @Override public PageInfo<XpAppVersion> getPageList(BasePage basePage) { Page<XpAppVersion> page = lambdaQuery().orderByDesc(XpAppVersion::getVersionCode).page(new Page<>(basePage.getPageNum(), basePage.getPageSize())); PageInfo<XpAppVersion> pageInfo = new PageInfo<>(); BeanUtil.copyProperties(page, pageInfo); return pageInfo; } @Override public void release(XpAppVersion appVersion) { Integer latestVersionCode = 0; //获取最新版本信息 XpAppVersion latestVersion = this.lambdaQuery() .orderByDesc(XpAppVersion::getVersionCode) .last("LIMIT 1") .one(); if (Objects.nonNull(latestVersion)) { latestVersionCode = latestVersion.getVersionCode(); } appVersion.setVersionCode(latestVersionCode + 1); // 版本号自增 save(appVersion); // 异步发送版本更新通知 sendVersionUpdateNotification(appVersion); } /** * 发送版本更新通知 * @param appVersion 版本信息 */ private void sendVersionUpdateNotification(XpAppVersion appVersion) { // 异步处理,避免阻塞主流程 ThreadPoolExecutor executor = new ThreadPoolExecutor( 1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>() ); executor.execute(() -> { try { // 1. 获取所有启用状态的运维用户 R<List<XpOperationsUser>> result = xpOperationUserClient.listAllEnabled(); if (result == null || result.getCode() != 200 || result.getData() == null || result.getData().isEmpty()) { log.warn("没有需要通知的启用状态用户"); return; } List<XpOperationsUser> enabledUsers = result.getData(); log.info("版本更新通知,共需通知 {} 位用户", enabledUsers.size()); // 2. 构建通知内容 String message = "新版本上线啦!请前往更新。"; String bodyJson = buildPushBodyJson(message); // 3. 构建并保存通知记录 List<XpOperationsUserNotification> notifications = enabledUsers.stream() .map(user -> buildNotification(message, bodyJson, user)) .collect(Collectors.toList()); // 批量保存通知记录 xpOperationUserNotificationClient.addNotificationBatch(notifications); log.info("版本更新通知记录保存成功,共 {} 条", notifications.size()); // 4. 按设备类型分组并批量推送 pushMessageByDeviceType(enabledUsers, message); } catch (Exception e) { log.error("发送版本更新通知失败", e); } }); executor.shutdown(); } /** * 构建推送 body JSON * @param message 消息内容 * @return JSON 字符串 */ private String buildPushBodyJson(String message) { JSONObject body = new JSONObject(); body.put("content", message); body.put("strategy", NotificationTypeEnum.VERSION_UPDATE_TIP.getCode()); // 8 body.put("type", 0); body.put("id", 0); return body.toJSONString(); } /** * 构建通知实体 * @param message 消息内容 * @param bodyJson 推送body内容 * @param user 运维用户 * @return 通知实体 */ private XpOperationsUserNotification buildNotification(String message, String bodyJson, XpOperationsUser user) { XpOperationsUserNotification notification = new XpOperationsUserNotification(); notification.setNotificationType(NotificationTypeEnum.VERSION_UPDATE_TIP.getCode()); // 8 notification.setNotificationContent(message); notification.setOperationsUserId(user.getId()); notification.setDataId(0L); // 版本更新通知 dataId 设置为 0 notification.setReadStatus(0); // 未读 notification.setNotificationExt(bodyJson); return notification; } /** * 按设备类型分组推送消息 * @param users 用户列表 * @param message 消息内容 */ private void pushMessageByDeviceType(List<XpOperationsUser> users, String message) { // 按设备类型分组 (1=Android, 2=iOS) Map<Integer, List<XpOperationsUser>> usersByDeviceType = users.stream() .filter(u -> u.getDeviceType() != null && u.getPhoneNumber() != null) .collect(Collectors.groupingBy(XpOperationsUser::getDeviceType)); // 分别推送 Android 和 iOS for (Map.Entry<Integer, List<XpOperationsUser>> entry : usersByDeviceType.entrySet()) { Integer deviceType = entry.getKey(); List<XpOperationsUser> deviceUsers = entry.getValue(); // 按 1000 个手机号一批进行推送 List<List<XpOperationsUser>> batches = partition(deviceUsers, 1000); for (List<XpOperationsUser> batch : batches) { String accounts = batch.stream() .map(XpOperationsUser::getPhoneNumber) .collect(Collectors.joining(",")); AliPushMessageDTO pushDTO = buildPushMessageDTO(deviceType, accounts, message); try { xpAliPushMessageClient.pushMessage(pushDTO); log.info("版本更新推送成功,设备类型={},用户数={}", deviceType == 1 ? "Android" : "iOS", batch.size()); } catch (Exception e) { log.error("版本更新推送失败,设备类型={}", deviceType, e); } } } } /** * 构建推送消息 DTO * @param deviceType 设备类型 * @param accounts 手机号(逗号分隔) * @param message 消息内容 * @return 推送 DTO */ private AliPushMessageDTO buildPushMessageDTO(Integer deviceType, String accounts, String message) { AliPushMessageDTO dto = new AliPushMessageDTO(); dto.setDeviceType(deviceType); dto.setAccount(accounts); dto.setTitle("APP版本更新提示"); dto.setBody(buildPushBodyJson(message)); dto.setPushType("NOTICE"); return dto; } /** * 将列表按指定大小分批 * @param list 原始列表 * @param batchSize 批次大小 * @return 分批后的列表 */ private <T> List<List<T>> partition(List<T> list, int batchSize) { List<List<T>> batches = new ArrayList<>(); for (int i = 0; i < list.size(); i += batchSize) { batches.add(list.subList(i, Math.min(i + batchSize, list.size()))); } return batches; } } xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/vo/XpAgreementVo.java
@@ -10,7 +10,7 @@ @ApiModelProperty(value = "id") private Long id; @ApiModelProperty(value = "类型") @ApiModelProperty(value = "类型 1=用户服务协议 2=平台隐私政策 3=敏感个人信息处理情况说明 4=向第三方提供个人信息情况的说明 5=乘车须知 6=计费规则说明") private Integer type; @ApiModelProperty(value = "内容") xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/vo/XpAppVersionVO.java
@@ -25,10 +25,4 @@ @ApiModelProperty(value = "更新说明") private String updateDescription; @ApiModelProperty(value = "是否强制更新 0-否 1-是") private Integer forceUpdateFlag; @ApiModelProperty(value = "版本号 判断是否需要升级") private Integer versionCode; } xp-robotaxi-operation-boot/src/main/resources/bootstrap.yml
@@ -2,7 +2,6 @@ port: 6060 tomcat: basedir: /data/tomcat # Spring spring: application: # 应用名称 @@ -12,4 +11,244 @@ allow-circular-references: true profiles: # 环境配置 active: local active: dev # active: prod --- spring: config: activate: on-profile: dev cloud: nacos: discovery: # 服务注册地址 server-addr: 192.168.110.80:8848 service: ${spring.application.name} group: DEFAULT_GROUP namespace: 5185ac4b-6369-48eb-a21b-a7cbc441c5f1 username: nacos password: nacos config: # 配置中心地址 server-addr: 192.168.110.80:8848 namespace: 5185ac4b-6369-48eb-a21b-a7cbc441c5f1 group: DEFAULT_GROUP name: ${spring.application.name} username: nacos password: nacos # 配置文件格式 file-extension: yml # 共享配置 shared-configs: - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} --- seata: enabled: true application-id: ${spring.application.name} tx-service-group: seata_tx_group #此处配置自定义的seata事务分组名称 enable-auto-data-source-proxy: false #关闭数据库代理 service: vgroup-mapping: seata_tx_group: default data-source-proxy-mode: AT config: type: nacos nacos: # 开发环境 server-addr: 192.168.110.80:8848 namespace: 5185ac4b-6369-48eb-a21b-a7cbc441c5f1 group: DEFAULT_GROUP data-id: seata-server.properties username: nacos password: nacos # 生产环境 # server-addr: 192.168.0.137:8848,192.168.0.123:8848 # namespace: c6cf40b5-44e8-43f9-be61-8d10fa830e2a # group: DEFAULT_GROUP # data-id: seata-server.properties # username: nacos # password: nacos registry: type: nacos nacos: application: seata-server # 开发环境 server-addr: 192.168.110.80:8848 namespace: 5185ac4b-6369-48eb-a21b-a7cbc441c5f1 group: DEFAULT_GROUP username: nacos password: nacos # 生产环境 # server-addr: 192.168.0.137:8848,192.168.0.123:8848 # namespace: c6cf40b5-44e8-43f9-be61-8d10fa830e2a # group: DEFAULT_GROUP # username: nacos # password: nacos cloud: nacos: discovery: # 开发环境 server-addr: 192.168.110.80:8848 namespace: 5185ac4b-6369-48eb-a21b-a7cbc441c5f1 group: DEFAULT_GROUP application: seata-server #Nacos 中 Seata 名称 username: nacos password: nacos # 生产环境 # server-addr: 192.168.0.137:8848,192.168.0.123:8848 # namespace: c6cf40b5-44e8-43f9-be61-8d10fa830e2a # group: DEFAULT_GROUP # application: seata-server #Nacos 中 Seata 名称 # username: nacos # password: nacos sentinel: transport: dashboard: 192.168.0.137:8080 # Sentinel控制台地址 eager: true --- spring: config: activate: on-profile: prod cloud: nacos: discovery: # 服务注册地址 server-addr: 192.168.0.137:8848,192.168.0.123:8848 service: ${spring.application.name} group: DEFAULT_GROUP namespace: c6cf40b5-44e8-43f9-be61-8d10fa830e2a username: nacos password: nacos config: # 配置中心地址 server-addr: 192.168.0.137:8848,192.168.0.123:8848 namespace: c6cf40b5-44e8-43f9-be61-8d10fa830e2a username: nacos password: nacos group: DEFAULT_GROUP name: ${spring.application.name} # 配置文件格式 file-extension: yml # 共享配置 shared-configs: - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} --- spring: config: activate: on-profile: test cloud: nacos: discovery: # 服务注册地址 server-addr: 127.0.0.1:8848 service: ${spring.application.name} group: DEFAULT_GROUP namespace: 96712c7a-480b-4f40-b783-39f00f3b33ce config: # 配置中心地址 server-addr: 127.0.0.1:8848 namespace: 96712c7a-480b-4f40-b783-39f00f3b33ce group: DEFAULT_GROUP name: ${spring.application.name} # 配置文件格式 file-extension: yml # 共享配置 shared-configs: - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} --- #--- #spring: # shardingsphere: # props: # sql-show: true # sql-simple: true # datasource: # names: xp0 # xp0: # type: com.alibaba.druid.pool.DruidDataSource # driver-class-name: com.mysql.cj.jdbc.Driver # url: jdbc:mysql://192.168.110.34:3306/xprt_operation?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 # username: root # password: 123456 # rules: # sharding: # tables: # sys_oper_log: # actual-data-nodes: xp0.sys_oper_log # database-strategy: # standard: # sharding-column: userId # sharding-algorithm-name: sys-oper-log-inline # key-generate-strategy: # column: oper_id # key-generator-name: snowflake # xp_agreement_app_user: # actual-data-nodes: xp0.xp_agreement_app_user # database-strategy: # standard: # sharding-column: app_user_id # sharding-algorithm-name: xp-agreement-app-user-inline # key-generate-strategy: # column: id # key-generator-name: snowflake # xp_point: # actual-data-nodes: xp0.xp_point # database-strategy: # standard: # sharding-column: id # sharding-algorithm-name: xp-point-inline # key-generate-strategy: # column: id # key-generator-name: snowflake # sharding-algorithms: # sys-oper-log-inline: # type: INLINE # props: # algorithm-expression: sys_oper_log # xp-agreement-app-user-inline: # type: INLINE # props: # algorithm-expression: xp_agreement_app_user # xp-point-inline: # type: INLINE # props: # algorithm-expression: xp_point # key-generators: # snowflake: # type: SNOWFLAKE # single-table: # tables: # - xp0.sys_config # - xp0.sys_dict_data # - xp0.sys_dict_type # - xp0.sys_logininfor # - xp0.sys_menu # - xp0.xp_acticity # - xp0.xp_acticity_coupon # - xp0.xp_agreement # - xp0.xp_banner # - xp0.xp_coupon # - xp0.xp_electronic_fence # - xp0.xp_electronic_fence_area # - xp0.xp_feedback_type # - xp0.xp_frequently_asked_questions # - xp0.xp_invitation_code # - xp0.xp_notification # - xp0.xp_open_city # - xp0.xp_pricing # - xp0.xp_pricing_item # - xp0.xp_region # - xp0.xp_ride_guide # - xp0.xp_route_plan # - xp0.xp_system_setting # - xp0.xp_trading_strategy # - xp0.xp_trading_strategy_city # - xp0.xp_user_feedback # - xp0.xp_whitelist # - xp0.xp_whitelist_operlog xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpPolicyApplicationController.java
@@ -5,6 +5,7 @@ import com.xiaopeng.common.security.service.TokenService; import com.xiaopeng.vehicleConvoy.model.dto.XpPolicyApplicationAuditDTO; import com.xiaopeng.vehicleConvoy.model.query.XpPolicyApplicationQuery; import com.xiaopeng.vehicleConvoy.model.vo.QueryPolicyInfoVO; import com.xiaopeng.vehicleConvoy.model.vo.XpPolicyApplicationVO; import com.xiaopeng.vehicleConvoy.service.IXpPolicyApplicationService; import io.swagger.annotations.ApiOperation; @@ -59,4 +60,14 @@ return R.ok(); } @ApiOperation(value = "通过车辆id查询保单审核明细", tags = {"运维APP-车辆管理"}) @GetMapping("/api/v1/policyApplication/queryPolicyInfoByVid") public R<QueryPolicyInfoVO> queryPolicyInfoByVid(@RequestParam Long vehicleId) { Long id = tokenService.getLoginOperationUser().getId(); QueryPolicyInfoVO queryPolicyInfoVO = xpPolicyApplicationService.queryPolicyInfoByVid(vehicleId,id); return R.ok(queryPolicyInfoVO); } } xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/query/VehicleMapQuery.java
@@ -9,7 +9,7 @@ @ApiModel(value = "运维APP-车辆地图查询参数") public class VehicleMapQuery extends BasePage { @ApiModelProperty(value = "车牌号") private String platNumber; private String plateNumber; @ApiModelProperty(value = "运营状态 1运营中 2维修中 3已收车 4车辆异常") private String status; @ApiModelProperty(value = "围栏id") xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/vo/XpPolicyApplicationVO.java
@@ -64,4 +64,7 @@ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private LocalDateTime createTime; @ApiModelProperty(value = "保单信息") private String policyInformation; } xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/IXpPolicyApplicationService.java
@@ -5,6 +5,7 @@ import com.xiaopeng.common.core.web.page.PageInfo; import com.xiaopeng.vehicleConvoy.model.dto.XpPolicyApplicationAuditDTO; import com.xiaopeng.vehicleConvoy.model.query.XpPolicyApplicationQuery; import com.xiaopeng.vehicleConvoy.model.vo.QueryPolicyInfoVO; import com.xiaopeng.vehicleConvoy.model.vo.XpPolicyApplicationVO; import javax.validation.Valid; @@ -37,4 +38,12 @@ * @param userId 用户id */ void applyPolicyInformation(Long vehicleId,Long userId); /** * 查询保单信息 * @param vehicleId * @param id * @return */ QueryPolicyInfoVO queryPolicyInfoByVid(Long vehicleId, Long id); } xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpPolicyApplicationServiceImpl.java
@@ -3,6 +3,7 @@ import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.xiaopeng.api.feignClient.account.SysUserClient; @@ -18,12 +19,15 @@ import com.xiaopeng.common.core.web.page.PageInfo; import com.xiaopeng.common.security.utils.SecurityUtils; import com.xiaopeng.vehicleConvoy.mapper.XpPolicyApplicationMapper; import com.xiaopeng.vehicleConvoy.mapper.XpVehicleMapper; import com.xiaopeng.vehicleConvoy.model.dto.XpPolicyApplicationAuditDTO; import com.xiaopeng.vehicleConvoy.model.query.XpPolicyApplicationQuery; import com.xiaopeng.vehicleConvoy.model.vo.QueryPolicyInfoVO; import com.xiaopeng.vehicleConvoy.model.vo.XpPolicyApplicationVO; import com.xiaopeng.vehicleConvoy.service.IXpPolicyApplicationService; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -50,6 +54,7 @@ private final XpOperationUserClient xpOperationUserClient; private final XpVehicleClient xpVehicleClient; private final SysUserClient sysUserClient; private final XpVehicleMapper xpVehicleMapper; @Override public PageInfo<XpPolicyApplicationVO> pageList(XpPolicyApplicationQuery query) { @@ -229,4 +234,32 @@ this.save(xpPolicyApplication); } @Override public QueryPolicyInfoVO queryPolicyInfoByVid(Long vehicleId, Long id) { XpPolicyApplication xpPolicyApplication = this.getOne(Wrappers.lambdaQuery(XpPolicyApplication.class) .eq(XpPolicyApplication::getVehicleId, vehicleId) .eq(XpPolicyApplication::getApplicantId, id) .orderByDesc(XpPolicyApplication::getCreateTime) .last("limit 1")); QueryPolicyInfoVO queryPolicyInfoVO = new QueryPolicyInfoVO(); if (Objects.nonNull(xpPolicyApplication)) { XpPolicyApplicationVO xpPolicyApplicationVO = new XpPolicyApplicationVO(); BeanUtils.copyProperties(xpPolicyApplication, xpPolicyApplicationVO); // 查询车辆 if (Objects.nonNull(xpPolicyApplication.getVehicleId())) { XpVehicle xpVehicle = xpVehicleMapper.selectById(xpPolicyApplication.getVehicleId()); xpPolicyApplicationVO.setPlateNumber(xpVehicle.getPlateNumber()); xpPolicyApplicationVO.setVehicleCode(xpVehicle.getVehicleCode()); if(xpPolicyApplicationVO.getAuditStatus() == 2){ xpPolicyApplicationVO.setPolicyInformation(xpVehicle.getPolicyInformation()); } } queryPolicyInfoVO.setStatus(xpPolicyApplication.getAuditStatus()); }else { queryPolicyInfoVO.setStatus(0); } return queryPolicyInfoVO; } }