Merge remote-tracking branch 'origin/master'
| | |
| | | |
| | | import org.springframework.stereotype.Controller; |
| | | import org.springframework.web.bind.annotation.RequestParam; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.util.List; |
| | |
| | | * @author mitao |
| | | * @since 2026-02-03 |
| | | */ |
| | | @Controller |
| | | @RequestMapping("") |
| | | @RestController |
| | | public class XpOperationsRoleController { |
| | | |
| | | |
| | |
| | | .in(XpOperationsRole::getOperationsUserId, operationsUserIds)); |
| | | |
| | | if(!CollectionUtils.isEmpty(xpOperationsRoles)){ |
| | | List<Long> roleIds = xpOperationsRoles.stream().map(XpOperationsRole::getRoleId).collect(Collectors.toList()); |
| | | List<Long> roleIds = xpOperationsRoles.stream().map(XpOperationsRole::getRoleId).distinct().collect(Collectors.toList()); |
| | | // 查询列表关联的所有角色 |
| | | List<SysRole> sysRoles = sysRoleMapper.selectList(Wrappers.lambdaQuery(SysRole.class) |
| | | .in(SysRole::getId, roleIds)); |
| | |
| | | xou.id_card_front, xou.id_card_back, xou.driver_license, xou.certificate_of_no_criminal_record, |
| | | xou.training_graduation_certificate, xou.is_deleted, xou.create_time, xou.update_time, xou.create_by |
| | | from xp_operations_user xou |
| | | left join xp_operations_role xore on xou.id = xore.operations_user_id |
| | | where xou.is_deleted = 0 |
| | | <if test="query.nickName != null and query.nickName != ''"> |
| | | and xou.nick_name like concat('%',#{query.nickName},'%') |
| | |
| | | and xou.phone_number like concat('%',#{query.phoneNumber},'%') |
| | | </if> |
| | | <if test="query.roleId != null"> |
| | | and xore.role_id = #{query.roleId} |
| | | AND EXISTS (SELECT 1 FROM xp_operations_role xore |
| | | WHERE xore.operations_user_id = xou.id |
| | | AND xore.role_id = #{query.roleId}) |
| | | </if> |
| | | <if test="query.status != null"> |
| | | and xou.status = #{query.status} |
| | | </if> |
| | | |
| | | |
| | | order by xou.create_time desc |
| | | </select> |
| | | |
| | |
| | | package com.xiaopeng.api.vo.account; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | |
| | | * @author mitao |
| | | * @date 2026-02-14 |
| | | */ |
| | | @ApiModel(value = "运维人员个人中心首页VO") |
| | | @Data |
| | | public class XpOperationsUserProfileVO implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| New file |
| | |
| | | package com.xiaopeng.automaticPilot.job.base; |
| | | |
| | | import com.xiaopeng.api.feignClient.automaticPilot.OrderMissionClient; |
| | | import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient; |
| | | import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient; |
| | | import com.xiaopeng.order.job.utils.SpringContextsUtil; |
| | | import com.xiaopeng.order.service.IXpCruiseOrderService; |
| | | import com.xiaopeng.order.service.IXpOrderService; |
| | | import com.xiaopeng.order.service.XpOrderTimeoutLogService; |
| | | import org.quartz.Job; |
| | | import org.quartz.JobExecutionContext; |
| | | import org.quartz.JobExecutionException; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | |
| | | public abstract class AbstractJob implements Job { |
| | | protected Logger logger = LoggerFactory.getLogger(getClass()); |
| | | |
| | | @Override |
| | | public abstract void execute(JobExecutionContext context) throws JobExecutionException; |
| | | |
| | | protected IXpOrderService xpOrderService; |
| | | protected XpPushMessageClient xpPushMessageClient; |
| | | protected XpOrderTimeoutLogService xpOrderTimeoutLogService; |
| | | protected IXpCruiseOrderService xpCruiseOrderService; |
| | | protected OrderMissionClient orderMissionClient; |
| | | protected XpVehicleClient xpVehicleClient; |
| | | public AbstractJob(){ |
| | | this.xpOrderService = SpringContextsUtil.getBean(IXpOrderService.class); |
| | | this.xpPushMessageClient = SpringContextsUtil.getBean(XpPushMessageClient.class); |
| | | this.xpOrderTimeoutLogService = SpringContextsUtil.getBean(XpOrderTimeoutLogService.class); |
| | | } |
| | | |
| | | |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.automaticPilot.job.base; |
| | | |
| | | import com.xiaopeng.order.job.base.TimeJobType; |
| | | import org.quartz.*; |
| | | import org.quartz.impl.StdSchedulerFactory; |
| | | |
| | | import java.util.Date; |
| | | import java.util.Map; |
| | | |
| | | public class QuartzManager { |
| | | private static SchedulerFactory factory = new StdSchedulerFactory(); |
| | | private static final String TRIGGER_NAME_PREFIX = "TRIGGER_PREFIX_"; |
| | | private static final String JOB_NAME_PREFIX = "JOB_PREFIX_"; |
| | | |
| | | /** |
| | | * 添加定时任务:具体某个时间点执行一次的任务,如:在某个2015-06-01 12:00发送一条消息 |
| | | * |
| | | * @param jobName |
| | | * 具体的任务名+ID标识唯一 |
| | | * @param jobType |
| | | * @param date |
| | | * @param jp |
| | | */ |
| | | public synchronized static void addJob(Class<? extends Job> jobClass, String jobName, TimeJobType jobType, Date date, |
| | | Map<String, ? extends Object> jp) { |
| | | //logger.debug("ADD JOB {},jobName={},jobTyep={},jobDate={},",jobClass.getName(),jobName,jobType,date); |
| | | try { |
| | | Scheduler sched = factory.getScheduler(); |
| | | JobDetail job = JobBuilder.newJob(jobClass).withIdentity(JOB_NAME_PREFIX + jobName, jobType.getType()) |
| | | .setJobData(new JobDataMap(jp)).build(); |
| | | |
| | | SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger() |
| | | .withIdentity(TRIGGER_NAME_PREFIX + jobName, jobType.getType()).startAt(date).build(); |
| | | removeJob(jobName, jobType); |
| | | |
| | | sched.scheduleJob(job, trigger); |
| | | |
| | | if (!sched.isShutdown()) { |
| | | sched.start(); |
| | | } |
| | | } catch (Exception e) { |
| | | //logger.error("ADD JOB exception {},jobName={},jobTyep={},jobDate={},",jobClass.getName(),jobName,jobType,date); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 修改一个任务的触发时间(使用默认的任务组名,触发器名,触发器组名) |
| | | * @param jobName |
| | | * @param time |
| | | */ |
| | | public synchronized static void modifyJobTime(String jobName,TimeJobType jobType, Date time) { |
| | | //logger.error("Update JOB exception,jobName={},jobTyep={},jobDate={}," ,jobName,jobType,time); |
| | | try { |
| | | JobKey jobKey = new JobKey(JOB_NAME_PREFIX + jobName, jobType.getType()); |
| | | TriggerKey key = new TriggerKey(TRIGGER_NAME_PREFIX + jobName, jobType.getType()); |
| | | |
| | | |
| | | Scheduler sched = factory.getScheduler(); |
| | | SimpleTrigger trigger = (SimpleTrigger) sched.getTrigger(key); |
| | | if(trigger == null) { |
| | | return; |
| | | } |
| | | Date oldTime = trigger.getStartTime(); |
| | | |
| | | if (oldTime.getTime() != time.getTime()) { |
| | | JobDetail jobDetail = sched.getJobDetail(jobKey); |
| | | Class<? extends Job> objJobClass = jobDetail.getJobClass(); |
| | | removeJob(jobName,jobType); |
| | | Map<String, Object> jp = jobDetail.getJobDataMap(); |
| | | addJob(objJobClass, jobName, jobType, time, jp); |
| | | } |
| | | } catch (Exception e) { |
| | | // logger.error("Update JOB exception,jobName={},jobTyep={},jobDate={}," ,jobName,jobType,time); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 移除一个任务 |
| | | * |
| | | * @param jobName |
| | | */ |
| | | public synchronized static void removeJob(String jobName, TimeJobType jobType) { |
| | | try { |
| | | JobKey jobKey = new JobKey(JOB_NAME_PREFIX + jobName, jobType.getType()); |
| | | TriggerKey key = new TriggerKey(TRIGGER_NAME_PREFIX + jobName, jobType.getType()); |
| | | Scheduler sched = factory.getScheduler(); |
| | | |
| | | JobDetail detail = sched.getJobDetail(jobKey); |
| | | if (detail != null) { |
| | | sched.pauseJob(jobKey); |
| | | sched.pauseTrigger(key);// 停止触发器 |
| | | sched.unscheduleJob(key);// 移除触发器 |
| | | sched.deleteJob(jobKey);// 删除任务 |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 启动所有定时任务 |
| | | */ |
| | | public synchronized static void startJobs() { |
| | | try { |
| | | Scheduler sched = factory.getScheduler(); |
| | | sched.start(); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 关闭所有定时任务 |
| | | */ |
| | | public synchronized static void shutdownJobs() { |
| | | try { |
| | | Scheduler sched = factory.getScheduler(); |
| | | if (!sched.isShutdown()) { |
| | | sched.shutdown(); |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.automaticPilot.job.base; |
| | | |
| | | /** |
| | | * @Description 按时间点发布的任务类型 |
| | | * @date 2025年2月17日 下午7:22:28 |
| | | */ |
| | | public enum TimeJobType { |
| | | ORDER_CANCEL("order_cancel","订单取消"), |
| | | ADD_CRUISE_MISSION("add_cruise_mission","添加巡游任务"), |
| | | END_TRIP("end_trip","自动结束行程"); |
| | | private String type; |
| | | private String desc; |
| | | private TimeJobType(String type, String desc) { |
| | | this.type = type; |
| | | this.desc = desc; |
| | | } |
| | | public String getType() { |
| | | return type; |
| | | } |
| | | public void setType(String type) { |
| | | this.type = type; |
| | | } |
| | | public String getDesc() { |
| | | return desc; |
| | | } |
| | | public void setDesc(String desc) { |
| | | this.desc = desc; |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.automaticPilot.job.exceptions; |
| | | |
| | | /** |
| | | * @文件说明:定时器任务执行异常 |
| | | * @版权所有:成都喜来达 |
| | | * @项目名称: fengsheng |
| | | * @创建者: Leeyns |
| | | * @创建日期: 2016年5月18日 |
| | | * @最近修改者:Leeyns |
| | | * @最近修改日期:2016年5月18日 |
| | | */ |
| | | public class TimeException extends Exception { |
| | | |
| | | /** |
| | | * TODO |
| | | */ |
| | | private static final long serialVersionUID = 5703430073981692250L; |
| | | |
| | | private String message; |
| | | |
| | | public TimeException() { |
| | | super(); |
| | | } |
| | | |
| | | public TimeException(String message) { |
| | | super(message); |
| | | this.message = message; |
| | | } |
| | | |
| | | public String getMessage() { |
| | | return message; |
| | | } |
| | | |
| | | public void setMessage(String message) { |
| | | this.message = message; |
| | | } |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.automaticPilot.job.jobs; |
| | | |
| | | import com.xiaopeng.api.dto.automaticPilot.PushOrderDto; |
| | | import com.xiaopeng.api.model.order.XpCruiseOrder; |
| | | import com.xiaopeng.api.model.vehicleConvoy.XpVehicle; |
| | | import com.xiaopeng.common.core.domain.R; |
| | | import com.xiaopeng.order.job.base.AbstractJob; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.quartz.JobDataMap; |
| | | import org.quartz.JobExecutionContext; |
| | | import org.quartz.JobExecutionException; |
| | | |
| | | /** |
| | | * 推送定时任务 |
| | | * @author Administrator |
| | | * |
| | | */ |
| | | @Slf4j |
| | | public class AddCruiseMissionJob extends AbstractJob { |
| | | |
| | | public static final String name = "addCruiseMission_"; |
| | | |
| | | @Override |
| | | public void execute(JobExecutionContext context) |
| | | throws JobExecutionException { |
| | | JobDataMap maps = context.getMergedJobDataMap(); |
| | | Long orderId = maps.getLong("id"); |
| | | try { |
| | | log.info("开始执行添加任务"); |
| | | XpCruiseOrder xpCruiseOrder = xpCruiseOrderService.getById(orderId); |
| | | R<XpVehicle> xpVehicleR = xpVehicleClient.queryById(xpCruiseOrder.getVehicleId()); |
| | | if(xpVehicleR.getData().getState()==0){ |
| | | orderMissionClient.pushOrder(new PushOrderDto(xpCruiseOrder.getVehicleVin(),xpCruiseOrder.getId(),null)); |
| | | } |
| | | }catch(Exception e){ |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.automaticPilot.job.jobs; |
| | | |
| | | import com.xiaopeng.api.model.order.XpOrder; |
| | | import com.xiaopeng.api.model.order.XpOrderTimeoutLog; |
| | | import com.xiaopeng.order.job.base.AbstractJob; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.quartz.JobDataMap; |
| | | import org.quartz.JobExecutionContext; |
| | | import org.quartz.JobExecutionException; |
| | | |
| | | /** |
| | | * 推送定时任务 |
| | | * @author Administrator |
| | | * |
| | | */ |
| | | @Slf4j |
| | | public class EndTripJob extends AbstractJob { |
| | | |
| | | public static final String name = "endTrip_"; |
| | | |
| | | @Override |
| | | public void execute(JobExecutionContext context) |
| | | throws JobExecutionException { |
| | | JobDataMap maps = context.getMergedJobDataMap(); |
| | | Long orderId = maps.getLong("id"); |
| | | try { |
| | | log.info("开始执行自动结束行程任务"); |
| | | XpOrder xpOrder = xpOrderService.getById(orderId); |
| | | xpOrderService.endTrip(xpOrder.getId(), String.valueOf(xpOrder.getAppUserId())); |
| | | log.info("结束执行自动结束行程任务"); |
| | | // 添加超时记录 |
| | | XpOrderTimeoutLog xpOrderTimeoutLog = new XpOrderTimeoutLog(); |
| | | xpOrderTimeoutLog.setOrderId(xpOrder.getId()); |
| | | xpOrderTimeoutLog.setUserId(xpOrder.getAppUserId()); |
| | | xpOrderTimeoutLogService.save(xpOrderTimeoutLog); |
| | | }catch(Exception e){ |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.automaticPilot.job.jobs; |
| | | |
| | | import com.xiaopeng.api.model.order.XpOrder; |
| | | import com.xiaopeng.order.job.base.AbstractJob; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.quartz.JobDataMap; |
| | | import org.quartz.JobExecutionContext; |
| | | import org.quartz.JobExecutionException; |
| | | |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 直播推送定时任务 |
| | | * @author Administrator |
| | | * |
| | | */ |
| | | @Slf4j |
| | | public class OrderCancelJob extends AbstractJob { |
| | | |
| | | public static final String name = "orderCancel_"; |
| | | |
| | | @Override |
| | | public void execute(JobExecutionContext context) |
| | | throws JobExecutionException { |
| | | JobDataMap maps = context.getMergedJobDataMap(); |
| | | Long orderId = maps.getLong("id"); |
| | | try { |
| | | log.info("开始执行订单取消任务"); |
| | | XpOrder xpOrder = xpOrderService.getById(orderId); |
| | | if(Objects.nonNull(xpOrder)){ |
| | | log.info("订单取消开始"); |
| | | xpOrderService.cancelOrder(String.valueOf(xpOrder.getId())); |
| | | log.info("订单取消状态修改完成"); |
| | | } |
| | | }catch(Exception e){ |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.automaticPilot.job.utils; |
| | | |
| | | import org.springframework.beans.BeansException; |
| | | import org.springframework.context.ApplicationContext; |
| | | import org.springframework.context.ApplicationContextAware; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | @Component |
| | | public class SpringContextsUtil implements ApplicationContextAware{ |
| | | |
| | | private static ApplicationContext applicationContext; |
| | | |
| | | @Override |
| | | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { |
| | | if (SpringContextsUtil.applicationContext == null) { |
| | | SpringContextsUtil.applicationContext = applicationContext; |
| | | } |
| | | } |
| | | // 获取applicationContext |
| | | public static ApplicationContext getApplicationContext() { |
| | | return applicationContext; |
| | | } |
| | | // 通过name获取 Bean. |
| | | public static Object getBean(String name) { |
| | | return getApplicationContext().getBean(name); |
| | | } |
| | | // 通过class获取Bean. |
| | | public static <T> T getBean(Class<T> clazz) { |
| | | return getApplicationContext().getBean(clazz); |
| | | } |
| | | // 通过name,以及Clazz返回指定的Bean |
| | | public static <T> T getBean(String name, Class<T> clazz) { |
| | | System.out.println(getApplicationContext().getBean(name, clazz)); |
| | | return getApplicationContext().getBean(name, clazz); |
| | | } |
| | | |
| | | } |
| | |
| | | import com.xiaopeng.api.vo.OrderType; |
| | | import com.xiaopeng.api.vo.SystemEventType; |
| | | import com.xiaopeng.api.vo.automaticPilot.VehiclePosition; |
| | | import com.xiaopeng.api.vo.automaticPilot.proto.down.cloudOrderOperation.ActionType; |
| | | import com.xiaopeng.api.vo.automaticPilot.proto.down.cloudOrderOperation.OrderOperationType; |
| | | import com.xiaopeng.api.vo.automaticPilot.proto.down.cloudOrderOperation.PointType; |
| | | import com.xiaopeng.api.vo.automaticPilot.proto.up.navigationDeviationEvent.NavigationDeviationEvent; |
| | | import com.xiaopeng.api.vo.automaticPilot.proto.up.navigationDeviationEvent.NavigationDeviationMessage; |
| | | import com.xiaopeng.api.vo.automaticPilot.proto.up.orderStateUpdateEvent.OrderStatusInfoEvent; |
| | | import com.xiaopeng.api.vo.automaticPilot.proto.up.systemStatusXpu.*; |
| | | import com.xiaopeng.api.vo.automaticPilot.proto.up.xpuNavigationRequest.NavigationRequest; |
| | | import com.xiaopeng.api.vo.automaticPilot.protobuf.*; |
| | | import com.xiaopeng.api.vo.operation.RouteVo; |
| | | import com.xiaopeng.api.vo.vehicleConvoy.CancelTaxiPassengerVo; |
| | |
| | | lastXpCruiseOrder.setStatus(1); |
| | | xpCruiseOrderClient.addCruiseOrder(lastXpCruiseOrder); |
| | | |
| | | |
| | | |
| | | // 获取点位id |
| | | Long endPointId = xpCruiseOrder.getEndPointId(); |
| | | // 获取点位信息 获取点位是否需要停车 |
| | | // xpCruisePlanClient.getPlanPointInfo(endPointId); |
| | | |
| | | |
| | | |
| | | com.xiaopeng.api.vo.automaticPilot.protobuf.RtTask.Builder taskBuilder = com.xiaopeng.api.vo.automaticPilot.protobuf.RtTask.newBuilder(); |
| | | taskBuilder.setOrderId(lastXpCruiseOrder.getId()); |
| | | taskBuilder.setTaskId("MISSION_"+ IdUtil.fastUUID()); |
| | |
| | | |
| | | String TASK_NOT_EXIST = "task.not.exist"; |
| | | String VEHICLE_NOT_EXIST = "vehicle.not.exist"; |
| | | |
| | | |
| | | String TASK_RULE_NOT_CONFIG = "task.rule.not.config"; |
| | | } |
| | |
| | | List<Long> ids = appUserIdList.stream().map(Long::parseLong).collect(Collectors.toList()); |
| | | List<XpOperationsUserWithRoleVO> data = xpOperationUserClient.listByIdsWithRole(ids).getData(); |
| | | //将查询结果组装成map对象,用于循环中提取数据 |
| | | Map<Long,XpOperationsUserWithRoleVO> map = data.stream().collect(Collectors.toMap(XpOperationsUserWithRoleVO::getId, item->item)); |
| | | for (ClockInStatisticsDto clockInStatistic : clockInStatistics) { |
| | | String appUserId = clockInStatistic.getAppUserId(); |
| | | XpOperationsUserWithRoleVO xpOperationsUserWithRoleVO = map.get(Long.parseLong(appUserId)); |
| | | clockInStatistic.setName(xpOperationsUserWithRoleVO.getNickName()); |
| | | clockInStatistic.setRoleName(xpOperationsUserWithRoleVO.getRoleName()); |
| | | //运维账号可以拥有多个角色 |
| | | List<XpOperationsUserWithRoleVO> collect = data.stream().filter(x->x.getId().equals(Long.parseLong(appUserId))).collect(Collectors.toList()); |
| | | if(!collect.isEmpty()){ |
| | | XpOperationsUserWithRoleVO xpOperationsUserWithRoleVO = collect.get(0); |
| | | clockInStatistic.setName(xpOperationsUserWithRoleVO.getNickName()); |
| | | } |
| | | String roleName = collect.stream().map(XpOperationsUserWithRoleVO::getRoleName).collect(Collectors.joining(";")); |
| | | clockInStatistic.setRoleName(roleName); |
| | | Integer shouldClockInDays = clockInStatistic.getShouldClockInDays(); |
| | | Integer clockInDays = clockInStatistic.getClockInDays(); |
| | | clockInStatistic.setNotClockInDays(shouldClockInDays - clockInDays); |
| | |
| | | List<String> appUserIdList = clockInStatistics.stream().map(ClockInStatisticsDto::getAppUserId).collect(Collectors.toList()); |
| | | List<Long> ids = appUserIdList.stream().map(Long::parseLong).collect(Collectors.toList()); |
| | | List<XpOperationsUserWithRoleVO> data = xpOperationUserClient.listByIdsWithRole(ids).getData(); |
| | | //将查询结果组装成map对象,用于循环中提取数据 |
| | | Map<Long,XpOperationsUserWithRoleVO> map = data.stream().collect(Collectors.toMap(XpOperationsUserWithRoleVO::getId, item->item)); |
| | | for (ClockInStatisticsDto clockInStatistic : clockInStatistics) { |
| | | String appUserId = clockInStatistic.getAppUserId(); |
| | | XpOperationsUserWithRoleVO xpOperationsUserWithRoleVO = map.get(Long.parseLong(appUserId)); |
| | | clockInStatistic.setName(xpOperationsUserWithRoleVO.getNickName()); |
| | | clockInStatistic.setRoleName(xpOperationsUserWithRoleVO.getRoleName()); |
| | | //运维账号可以拥有多个角色 |
| | | List<XpOperationsUserWithRoleVO> collect = data.stream().filter(x->x.getId().equals(Long.parseLong(appUserId))).collect(Collectors.toList()); |
| | | if(!collect.isEmpty()){ |
| | | XpOperationsUserWithRoleVO xpOperationsUserWithRoleVO = collect.get(0); |
| | | clockInStatistic.setName(xpOperationsUserWithRoleVO.getNickName()); |
| | | } |
| | | String roleName = collect.stream().map(XpOperationsUserWithRoleVO::getRoleName).collect(Collectors.joining(";")); |
| | | clockInStatistic.setRoleName(roleName); |
| | | Integer shouldClockInDays = clockInStatistic.getShouldClockInDays(); |
| | | Integer clockInDays = clockInStatistic.getClockInDays(); |
| | | clockInStatistic.setNotClockInDays(shouldClockInDays - clockInDays); |
| | |
| | | package com.xiaopeng.maintenance.service.impl; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.date.DateUtil; |
| | | import com.alibaba.fastjson2.JSONObject; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | |
| | | XpTaskRule taskRule = xpTaskRuleService.lambdaQuery().last("limit 1").one(); |
| | | XpTaskRuleRole taskRuleRole = xpTaskRuleRoleService.lambdaQuery().eq(XpTaskRuleRole::getRuleType, 9).last("limit 1").one(); |
| | | if (Objects.isNull(taskRuleRole) || Objects.isNull(taskRule)) { |
| | | throw new ServiceException("未配置车辆事故任务分配规则", I18nKeyConstant.TASK_RULE_NOT_CONFIG); |
| | | throw new ServiceException("未配置车辆事故任务分配规则"); |
| | | } |
| | | R<List<XpOperationsRole>> xpOperationsRoleResult = xpOperationUserClient.getXpOperationsRoleByRoleId(taskRuleRole.getRoleId()); |
| | | if (CollUtil.isNotEmpty(xpOperationsRoleResult.getData())) { |
| | | List<Long> userIds = xpOperationsRoleResult.getData().stream().map(XpOperationsRole::getOperationsUserId).collect(Collectors.toList()); |
| | | xpTask.setHandleUserId(StringUtils.join(userIds, ",")); |
| | | } |
| | | //查询事故处理限时配置 |
| | | LocalDateTime endTime = LocalDateTime.now().plusMinutes(taskRule.getProcessingTimeLimit()); |
| | | xpTask.setEndTime(endTime); |
| | | this.save(xpTask); |
| | | |
| | | //发送消息通知 |
| | |
| | | .body(JSONObject.toJSONString(param)) |
| | | .account(account).title("车辆事故警示") |
| | | .pushType(AliPushTypeConstant.NOTICE) |
| | | .deviceType(data.get(0).getDeviceType()) |
| | | .deviceType(data.get(0).getDeviceType()) |
| | | .build()); |
| | | } |
| | | |
| | |
| | | |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import com.xiaopeng.api.model.maintenance.XpTaskRuleRole; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | |
| | | import java.io.Serializable; |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | import java.time.LocalTime; |
| | | import java.util.List; |
| | | |
| | | @Data |
| | |
| | | @ApiModelProperty(value = "车辆日常监测 频次") |
| | | private Integer vehicleInspectionFrequency; |
| | | @ApiModelProperty(value = "车辆日常检测 任务下放时间") |
| | | private LocalDateTime vehicleInspectionTime; |
| | | @JsonFormat(pattern = "HH:mm:ss", timezone = "GMT+8") |
| | | private LocalTime vehicleInspectionTime; |
| | | |
| | | @ApiModelProperty(value = "车辆日常监测 紧急程度 0=P0 1=P1 2=P2 3=P3") |
| | | private Integer vehicleInspectionLevel; |
| | |
| | | private Boolean vehicleCollection; |
| | | |
| | | @ApiModelProperty(value = "车辆收车每日时间") |
| | | private LocalDateTime vehicleCollectionTime; |
| | | @JsonFormat(pattern = "HH:mm:ss", timezone = "GMT+8") |
| | | private LocalTime vehicleCollectionTime; |
| | | |
| | | @ApiModelProperty(value = "车辆保养周期是否启用") |
| | | private Boolean maintenanceCycle; |
| | |
| | | private Integer maintenanceCycleTimeType; |
| | | |
| | | @ApiModelProperty(value = "车辆保养周期 任务下放时间") |
| | | private LocalDateTime maintenanceCycleTaskTime; |
| | | @JsonFormat(pattern = "HH:mm:ss", timezone = "GMT+8") |
| | | private LocalTime maintenanceCycleTaskTime; |
| | | |
| | | @ApiModelProperty(value = "车辆保养周期 紧急程度 0=P0 1=P1 2=P2 3=P3") |
| | | private Integer maintenanceCycleLevel; |
| | |
| | | private Integer chargingStrategyLevel; |
| | | |
| | | @ApiModelProperty(value = "车身清洁保养周期X") |
| | | private Integer vehicleCleanTime; |
| | | private Integer vehicleCleanCycle; |
| | | |
| | | @ApiModelProperty(value = "车身清洁保养任务下放时间") |
| | | @JsonFormat(pattern = "HH:mm:ss", timezone = "GMT+8") |
| | | private LocalTime vehicleCleanTime; |
| | | |
| | | @ApiModelProperty(value = "车身清洁保养周期X 1=天 2=月") |
| | | private Integer vehicleCleanTimeType; |
| | |
| | | private Integer vehicleCleanLevel; |
| | | |
| | | @ApiModelProperty(value = "日常整备保养周期X") |
| | | private Integer routineMaintenanceTime; |
| | | private Integer routineMaintenanceCycle; |
| | | |
| | | @ApiModelProperty(value = "日常整备保养任务下放时间") |
| | | @JsonFormat(pattern = "HH:mm:ss", timezone = "GMT+8") |
| | | private LocalTime routineMaintenanceTime; |
| | | |
| | | @ApiModelProperty(value = "日常整备保养周期X 1=天 2=月") |
| | | private Integer routineMaintenanceTimeType; |
| | |
| | | # 中文 |
| | | welcome.message=欢迎来到我们的应用程序! |
| | | task.not.exist=任务不存在 |
| | | vehicle.not.exist=车辆不存在 |
| | | task.rule.not.config=未配置车辆事故任务分配规则 |
| | | vehicle.not.exist=车辆不存在 |
| | |
| | | package com.xiaopeng.order.job.base; |
| | | |
| | | import com.xiaopeng.api.feignClient.automaticPilot.OrderMissionClient; |
| | | import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient; |
| | | import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient; |
| | | import com.xiaopeng.api.model.order.XpCruiseOrder; |
| | | import com.xiaopeng.order.service.IXpCruiseOrderService; |
| | | import com.xiaopeng.order.service.IXpOrderService; |
| | | import com.xiaopeng.order.job.utils.SpringContextsUtil; |
| | | import com.xiaopeng.order.service.XpOrderTimeoutLogService; |
| | |
| | | protected IXpOrderService xpOrderService; |
| | | protected XpPushMessageClient xpPushMessageClient; |
| | | protected XpOrderTimeoutLogService xpOrderTimeoutLogService; |
| | | |
| | | protected IXpCruiseOrderService xpCruiseOrderService; |
| | | protected OrderMissionClient orderMissionClient; |
| | | protected XpVehicleClient xpVehicleClient; |
| | | public AbstractJob(){ |
| | | this.xpOrderService = SpringContextsUtil.getBean(IXpOrderService.class); |
| | | this.xpPushMessageClient = SpringContextsUtil.getBean(XpPushMessageClient.class); |
| | |
| | | */ |
| | | public enum TimeJobType { |
| | | ORDER_CANCEL("order_cancel","订单取消"), |
| | | ADD_CRUISE_MISSION("add_cruise_mission","添加巡游任务"), |
| | | END_TRIP("end_trip","自动结束行程"); |
| | | private String type; |
| | | private String desc; |
| New file |
| | |
| | | package com.xiaopeng.order.job.jobs; |
| | | |
| | | import com.xiaopeng.api.dto.automaticPilot.PushOrderDto; |
| | | import com.xiaopeng.api.model.order.XpCruiseOrder; |
| | | import com.xiaopeng.api.model.order.XpOrder; |
| | | import com.xiaopeng.api.model.vehicleConvoy.XpVehicle; |
| | | import com.xiaopeng.common.core.domain.R; |
| | | import com.xiaopeng.order.job.base.AbstractJob; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.quartz.JobDataMap; |
| | | import org.quartz.JobExecutionContext; |
| | | import org.quartz.JobExecutionException; |
| | | |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * 推送定时任务 |
| | | * @author Administrator |
| | | * |
| | | */ |
| | | @Slf4j |
| | | public class AddCruiseMissionJob extends AbstractJob { |
| | | |
| | | public static final String name = "addCruiseMission_"; |
| | | |
| | | @Override |
| | | public void execute(JobExecutionContext context) |
| | | throws JobExecutionException { |
| | | JobDataMap maps = context.getMergedJobDataMap(); |
| | | Long orderId = maps.getLong("id"); |
| | | try { |
| | | log.info("开始执行添加任务"); |
| | | XpCruiseOrder xpCruiseOrder = xpCruiseOrderService.getById(orderId); |
| | | R<XpVehicle> xpVehicleR = xpVehicleClient.queryById(xpCruiseOrder.getVehicleId()); |
| | | if(xpVehicleR.getData().getState()==0){ |
| | | orderMissionClient.pushOrder(new PushOrderDto(xpCruiseOrder.getVehicleVin(),xpCruiseOrder.getId(),null)); |
| | | } |
| | | }catch(Exception e){ |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | import com.xiaopeng.api.model.order.XpOrder; |
| | | import com.xiaopeng.api.model.order.XpOrderEvaluate; |
| | | import com.xiaopeng.api.vo.account.GetUserListByUidsVo; |
| | | import com.xiaopeng.common.core.constant.HttpStatus; |
| | | import com.xiaopeng.common.core.domain.R; |
| | | import com.xiaopeng.common.core.utils.StringUtils; |
| | | import com.xiaopeng.common.core.web.page.PageInfo; |
| | |
| | | } |
| | | |
| | | // 4. 批量查询关联数据 |
| | | Map<Long, XpAppUser> userMap = batchGetUsers(userIds); |
| | | JSONObject jsonObject = batchGetUsers(userIds); |
| | | Map<Long, XpVehicle> vehicleMap = batchGetVehicles(vehicleIds); |
| | | Map<Long, XpOrder> orderMap = batchGetOrders(orderIds); |
| | | |
| | | // 5. 根据查询条件过滤(手机号、车牌号) |
| | | List<OrderEvaluatePageVO> voList = evaluatePage.getRecords().stream() |
| | | .map(evaluate -> convertToPageVO(evaluate, userMap, vehicleMap, orderMap)) |
| | | .map(evaluate -> convertToPageVO(evaluate, jsonObject, vehicleMap, orderMap)) |
| | | .filter(vo -> filterByQuery(vo, query)) |
| | | .collect(Collectors.toList()); |
| | | |
| | |
| | | /** |
| | | * 批量获取用户信息 |
| | | */ |
| | | private Map<Long, XpAppUser> batchGetUsers(Set<Long> userIds) { |
| | | private JSONObject batchGetUsers(Set<Long> userIds) { |
| | | if (CollectionUtils.isEmpty(userIds)) { |
| | | return new HashMap<>(); |
| | | return new JSONObject(); |
| | | } |
| | | try { |
| | | R<List<XpAppUser>> result = xpAppUserClient.listByIds(new ArrayList<>(userIds)); |
| | | if (Objects.nonNull(result) && Objects.nonNull(result.getData())) { |
| | | return result.getData().stream() |
| | | .collect(Collectors.toMap(XpAppUser::getId, Function.identity(), (a, b) -> a)); |
| | | GetUserListByUidsVo getUserListByUidsVo = new GetUserListByUidsVo(); |
| | | getUserListByUidsVo.setUids(new ArrayList<>(userIds)); |
| | | getUserListByUidsVo.setGetPreCarOwner(Boolean.TRUE); |
| | | UserResourcesDto userListByUids = userResourcesClient.getUserListByUids(getUserListByUidsVo); |
| | | if (userListByUids.getCode().equals(HttpStatus.SUCCESS)) { |
| | | return JSONObject.parseObject(userListByUids.getData().toString()); |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("批量获取用户信息失败: {}", e.getMessage()); |
| | | } |
| | | return new HashMap<>(); |
| | | return new JSONObject(); |
| | | } |
| | | |
| | | /** |
| | |
| | | * VO转换 |
| | | */ |
| | | private OrderEvaluatePageVO convertToPageVO(XpOrderEvaluate evaluate, |
| | | Map<Long, XpAppUser> userMap, |
| | | JSONObject jsonObject, |
| | | Map<Long, XpVehicle> vehicleMap, |
| | | Map<Long, XpOrder> orderMap) { |
| | | OrderEvaluatePageVO vo = new OrderEvaluatePageVO(); |
| | |
| | | vo.setEvaluateTime(evaluate.getEvaluateTime()); |
| | | |
| | | // 用户信息 |
| | | if (Objects.nonNull(evaluate.getAppUserId()) && userMap.containsKey(evaluate.getAppUserId())) { |
| | | XpAppUser user = userMap.get(evaluate.getAppUserId()); |
| | | vo.setNickName(user.getNickName()); |
| | | vo.setPhoneNumber(user.getPhoneNumber()); |
| | | if (Objects.nonNull(evaluate.getAppUserId()) && jsonObject.containsKey(evaluate.getAppUserId().toString())) { |
| | | JSONObject userInfo = jsonObject.getJSONObject(evaluate.getAppUserId().toString()); |
| | | vo.setNickName(userInfo.getString("nickName")); |
| | | vo.setPhoneNumber(userInfo.getString("mobile")); |
| | | } |
| | | |
| | | // 车辆信息 |
| | |
| | | import com.xiaopeng.api.feignClient.account.XpAppUserClient; |
| | | import com.xiaopeng.api.feignClient.account.XpAppUserCouponClient; |
| | | import com.xiaopeng.api.feignClient.automaticPilot.OrderMissionClient; |
| | | import com.xiaopeng.api.feignClient.maintenance.XpTaskRuleClient; |
| | | import com.xiaopeng.api.feignClient.operation.XpCruisePlanClient; |
| | | import com.xiaopeng.api.feignClient.operation.XpPointClient; |
| | | import com.xiaopeng.api.feignClient.operation.XpPricingClient; |
| | | import com.xiaopeng.api.feignClient.operation.XpSystemSettingClient; |
| | | import com.xiaopeng.api.feignClient.order.XpCruiseOrderClient; |
| | | import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient; |
| | | import com.xiaopeng.api.feignClient.vehicleConvoy.UserVehicleClient; |
| | | import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetClient; |
| | | import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetVehicleClient; |
| | | import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient; |
| | | import com.xiaopeng.api.model.account.XpAppUser; |
| | | import com.xiaopeng.api.model.maintenance.XpTaskRule; |
| | | import com.xiaopeng.api.model.operation.XpFeedbackType; |
| | | import com.xiaopeng.api.model.operation.XpGeoQueryEntity; |
| | | import com.xiaopeng.api.model.operation.XpPoint; |
| | |
| | | import com.xiaopeng.order.dto.MileageDto; |
| | | import com.xiaopeng.order.job.base.QuartzManager; |
| | | import com.xiaopeng.order.job.base.TimeJobType; |
| | | import com.xiaopeng.order.job.jobs.AddCruiseMissionJob; |
| | | import com.xiaopeng.order.job.jobs.EndTripJob; |
| | | import com.xiaopeng.order.job.jobs.OrderCancelJob; |
| | | import com.xiaopeng.order.mangodb.model.OrderTrajectory; |
| | |
| | | import org.springframework.data.mongodb.core.MongoTemplate; |
| | | import org.springframework.data.mongodb.core.query.Criteria; |
| | | import org.springframework.data.mongodb.core.query.Query; |
| | | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.util.CollectionUtils; |
| | |
| | | private final OrderMissionClient orderMissionClient; |
| | | private final XpOrderDetailMapper xpOrderDetailMapper; |
| | | private final XpCruiseOrderMapper xpCruiseOrderMapper; |
| | | private final XpTaskRuleClient xpTaskRuleClient; |
| | | private final XpCruisePlanClient xpCruisePlanClient; |
| | | |
| | | |
| | | @Autowired |
| | |
| | | if(vehicle!=null){ |
| | | // 修改车辆状态 |
| | | vehicle.setState(0); |
| | | xpVehicleClient.updateVehicleById(vehicle); |
| | | |
| | | |
| | | // 修改mongodb车辆状态 |
| | | |
| | | |
| | | |
| | | // 获取配置 根据配置判断是否该收车 如果是则找到收车点位进行收车操作 |
| | | R<XpTaskRule> xpTaskRuleR = xpTaskRuleClient.queryDetail(); |
| | | XpTaskRule xpTaskRule = xpTaskRuleR.getData(); |
| | | |
| | | // 生成新的巡游单子 回到最新巡游的初始起点位置 |
| | | XpCruiseOrder xpCruiseOrders = xpCruiseOrderMapper.selectOne(new LambdaQueryWrapper<XpCruiseOrder>().eq(XpCruiseOrder::getVehicleId, vehicle.getId()).eq(XpCruiseOrder::getStatus, 2).orderByDesc(BaseModel::getCreateTime).last("limit 1")); |
| | |
| | | xpCruiseOrder.setLastOrderId(xpCruiseOrders.getId()); |
| | | xpCruiseOrder.setCreateTime(LocalDateTime.now()); |
| | | xpCruiseOrder.setId("XU"+ IdUtil.fastUUID()); |
| | | |
| | | // 判断当前时分秒是否大于收车时间 |
| | | LocalTime vehicleCollectionTime = xpTaskRule.getVehicleCollectionTime(); |
| | | if (vehicleCollectionTime.isBefore(LocalTime.now())) { |
| | | vehicle.setOperatingStatus(3); |
| | | //找到车辆的收车点位 更新终点点位 |
| | | R<XpCruiseOrder> returnCruisePoint = xpCruisePlanClient.findReturnCruisePoint(xpCruiseOrder); |
| | | xpCruiseOrder = returnCruisePoint.getData(); |
| | | } |
| | | xpVehicleClient.updateVehicleById(vehicle); |
| | | |
| | | xpCruiseOrderMapper.insert(xpCruiseOrder); |
| | | |
| | | |
| | | R<XpPoint> xpPointR = xpPointClient.queryById(order.getEndPointId()); |
| | | XpPoint data = xpPointR.getData(); |
| | | //下发命令 |
| | | orderMissionClient.pushOrder(new PushOrderDto(vehicle.getVehicleVin(),xpCruiseOrder.getId(),null)); |
| | | // 添加自动结束行程定时任务job |
| | | Map<String, ? extends Object> jobMaps = |
| | | new ImmutableMap.Builder<String, String>(). |
| | | put("id", xpCruiseOrder.getId()) |
| | | .build(); |
| | | QuartzManager.addJob( |
| | | AddCruiseMissionJob.class, |
| | | (AddCruiseMissionJob.name + xpCruiseOrder.getId()).toUpperCase(), |
| | | TimeJobType.ADD_CRUISE_MISSION, |
| | | DateUtils.localDateTimeToDate(LocalDateTime.now().plusMinutes(data.getParkingTimeLimit())), |
| | | jobMaps |
| | | ); |
| | | |
| | | |
| | | } |
| | | |
| | |
| | | */ |
| | | @GetMapping("/base/v1/aliPush/test") |
| | | public R<String> test(){ |
| | | String s = aliPushUtil.pushMessage(1, "13540694412", "事故即将超时提示", "{\"content\":\"车辆川A12345在天府新谷发生的紧急事故即将超时,剩余时间5分钟,请及时到达现场!\",\"strategy\":2\"type\":7,\"id\":1}","NOTICE"); |
| | | String s = aliPushUtil.pushMessage(1, "13540694412", "事故即将超时提示", "{\"content\":\"你目前剩余1条待办任务,请及时处理!\",\"strategy\":6,\"type\":2,\"id\":3}","NOTICE"); |
| | | return R.ok(s); |
| | | } |
| | | /** |
| | |
| | | */ |
| | | @GetMapping("/base/v1/aliPush/test1") |
| | | public R<String> test1(){ |
| | | String s = aliPushUtil.pushMessage(1, "13540694412", "APP版本更新提示", "{\"content\":\"新版本上线啦!请前往更新。\",\"strategy\":8\"type\":0,\"id\":0}","MESSAGE"); |
| | | String s = aliPushUtil.pushMessage(1, "13540694412", "APP版本更新提示", "{\"content\":\"新版本上线啦!请前往更新。\",\"strategy\":8,\"type\":0,\"id\":0}","MESSAGE"); |
| | | return R.ok(s); |
| | | } |
| | | |
| | |
| | | # 中文 |
| | | fleet.operation.user.bound.v2=当前车队已和该人员关联 |
| | | policy.application.audit.ids.notEmpty=保单申请ID列表不能为空 |
| | | fleet.operation.user.bound.v1=运维人员[{0}]已绑定车队[{1}] |
| | | fleet.operation.user.bound.v1= |
| | | fleet.vehicle.bound.v2=当前车队已和该车辆关联 |
| | | fleet.vehicle.bound.v1=车辆[{0}]已绑定车队[{1}] |
| | | policy.application.audit.status.notNull=保单审核状态不能为空 |