xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/order/XpOrder.java
@@ -198,5 +198,13 @@ @ApiModelProperty(value = "下单时段") @TableField("time_slot") private String timeSlot; @ApiModelProperty(value = "车辆到达时间") private LocalDateTime arrivalTime; @ApiModelProperty(value = "接单时间") private LocalDateTime acceptanceTime; @ApiModelProperty(value = "行程开始时间") private LocalDateTime tripBegin; @ApiModelProperty(value = "行程结束时间") private LocalDateTime tripEnd; } xp-robotaxi-api/src/main/java/com/xiaopeng/api/query/operation/PointPageListQuery.java
@@ -5,13 +5,17 @@ import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.util.List; @Data @ApiModel(value = "点位管理列表查询query") public class PointPageListQuery { @ApiModelProperty(value = "查询参数(名称、poi、唯一ID)") private String queryParams; @ApiModelProperty(value = "运营状态 1=待启用 2=启用中 3=已停用 4=已失效") private Integer operationStatus; private String operationStatus; @ApiModelProperty(value = "运营状态数组 前端忽略") private List<Integer> operationStatusIds; @ApiModelProperty(value = "点位类型1运营点位 2测试点位") private Integer pointType; xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpPointManagementController.java
@@ -16,11 +16,13 @@ import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.util.StringUtils; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; @@ -46,6 +48,10 @@ @ApiOperation(value = "点位管理列表", response = XpPoint.class) @PostMapping("/list") public R<List<XpPoint>> list(@RequestBody PointPageListQuery query) { if (StringUtils.hasLength(query.getOperationStatus())){ List<Integer> operationStatusIds = Arrays.stream(query.getOperationStatus().split(",")).map(Integer::parseInt).collect(Collectors.toList()); query.setOperationStatusIds(operationStatusIds); } return xpPointClient.list( query); } /** xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/OperationApplication.java
@@ -23,7 +23,11 @@ @EnableTransactionManagement//开启事务 public class OperationApplication { public static void main(String[] args) { SpringApplication.run(OperationApplication.class, args); System.out.println("(♥◠‿◠)ノ゙ 运营模块启动成功 ლ(´ڡ`ლ)゙ \n"); try { SpringApplication.run(OperationApplication.class, args); System.out.println("(♥◠‿◠)ノ゙ 运营模块启动成功 ლ(´ڡ`ლ)゙ \n"); }catch (Exception e){ e.printStackTrace(); } } } xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/job/base/TimeJobType.java
@@ -5,7 +5,8 @@ * @date 2025年2月17日 下午7:22:28 */ public enum TimeJobType { ORDER_CANCEL("order_cancel","订单取消"); ELECTRONIC_EFFECT("electronic_effect","电子围栏生效"), ELECTRONIC_FAILURE("electronic_failure","电子围栏失效"); private String type; private String desc; private TimeJobType(String type, String desc) { xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/job/jobs/ElectronicEffectJob.java
New file @@ -0,0 +1,60 @@ package com.xiaopeng.operation.job.jobs; import com.xiaopeng.api.model.operation.XpElectronicFence; import com.xiaopeng.api.model.operation.XpElectronicFenceArea; import com.xiaopeng.operation.job.base.AbstractJob; import lombok.extern.slf4j.Slf4j; import org.quartz.JobDataMap; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import java.util.List; /** * 直播推送定时任务 * @author Administrator * */ @Slf4j public class ElectronicEffectJob extends AbstractJob { public static final String effect = "electronicEffect_"; public static final String failure = "electronicFailure_"; @Override public void execute(JobExecutionContext context) throws JobExecutionException { JobDataMap maps = context.getMergedJobDataMap(); Long electronicId = maps.getLong("id"); Long type = maps.getLong("type"); try { if (type==1L){ // 电子围栏生效 XpElectronicFence electronicFence = xpElectronicFenceService.getById(electronicId); electronicFence.setStatus(2); xpElectronicFenceService.updateById(electronicFence); List<XpElectronicFenceArea> electronicFenceAreaList = xpElectronicFenceAreaService.lambdaQuery().eq(XpElectronicFenceArea::getElectronicId, electronicId).list(); // 设置为生效 for(XpElectronicFenceArea electronicFenceArea : electronicFenceAreaList){ electronicFenceArea.setAreaStatus(1); } xpElectronicFenceAreaService.updateBatchById(electronicFenceAreaList); }else{ // 电子围栏失效 XpElectronicFence electronicFence = xpElectronicFenceService.getById(electronicId); electronicFence.setStatus(3); xpElectronicFenceService.updateById(electronicFence); List<XpElectronicFenceArea> electronicFenceAreaList = xpElectronicFenceAreaService.lambdaQuery().eq(XpElectronicFenceArea::getElectronicId, electronicId).list(); // 设置为禁用 for(XpElectronicFenceArea electronicFenceArea : electronicFenceAreaList){ electronicFenceArea.setAreaStatus(2); } xpElectronicFenceAreaService.updateBatchById(electronicFenceAreaList); } }catch(Exception e){ e.printStackTrace(); } } } xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpElectronicFenceServiceImpl.java
@@ -2,6 +2,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.google.common.collect.ImmutableMap; import com.xiaopeng.api.model.map.XpGeoFencingPolygon; import com.xiaopeng.api.model.map.XpGeoFencingProhibitedPolygon; import com.xiaopeng.api.model.operation.XpElectronicFence; @@ -9,11 +10,15 @@ import com.xiaopeng.api.model.operation.XpPoint; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.core.exception.ServiceException; import com.xiaopeng.common.core.utils.DateUtils; import com.xiaopeng.common.core.utils.bean.BeanUtils; import com.xiaopeng.common.core.web.page.PageInfo; import com.xiaopeng.operation.constant.I18nKeyConstant; import com.xiaopeng.api.dto.operation.ElectronicFenceAddDto; import com.xiaopeng.api.dto.operation.ElectronicFenceUpdateDto; import com.xiaopeng.operation.job.base.QuartzManager; import com.xiaopeng.operation.job.base.TimeJobType; import com.xiaopeng.operation.job.jobs.ElectronicEffectJob; import com.xiaopeng.operation.mapper.XpElectronicFenceAreaMapper; import com.xiaopeng.operation.mapper.XpElectronicFenceMapper; import com.xiaopeng.operation.mapper.XpPointMapper; @@ -28,13 +33,11 @@ import org.springframework.data.mongodb.core.geo.GeoJsonPolygon; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -63,7 +66,7 @@ public PageInfo<XpElectronicFence> pageList(ElectronicPageListQuery query) { PageInfo<XpElectronicFence> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); List<XpElectronicFence> list = this.baseMapper.pageList(pageInfo, query); if (list.isEmpty()){ if (list.isEmpty()) { return new PageInfo<>(); } List<Long> electronicIds = list.stream().map(XpElectronicFence::getId).collect(Collectors.toList()); @@ -72,7 +75,7 @@ .collect(Collectors.groupingBy(XpElectronicFenceArea::getElectronicId)); for (XpElectronicFence xpElectronicFence : list) { List<XpElectronicFenceArea> xpElectronicFenceAreas = electronicFenceAreaMap.get(xpElectronicFence.getId()); if (xpElectronicFenceAreas != null){ if (xpElectronicFenceAreas != null) { xpElectronicFence.setOperatingAreaCount(xpElectronicFenceAreas.stream().filter(xpElectronicFenceArea -> xpElectronicFenceArea.getAreaType() == 1).count()); xpElectronicFence.setProhibitedAreaCount(xpElectronicFenceAreas.stream().filter(xpElectronicFenceArea -> xpElectronicFenceArea.getAreaType() == 2).count()); @@ -114,6 +117,7 @@ // 保存主表数据 XpElectronicFence xpElectronicFence = new XpElectronicFence(); BeanUtils.copyProperties(dto, xpElectronicFence); xpElectronicFence.setStatus(0); if (dto.getStatus() == 0) { xpElectronicFence.setStatus(0); @@ -126,7 +130,6 @@ if (dto.getEffectTime().isBefore(LocalDateTime.now())) { // 设置为启用中 xpElectronicFence.setStatus(2); } else { xpElectronicFence.setStatus(1); } @@ -134,6 +137,58 @@ } xpElectronicFence.setCityCode(dto.getCityCode()); this.save(xpElectronicFence); if (dto.getStatus() == 0) { xpElectronicFence.setStatus(0); } else if (dto.getStatus() == 1) { if (dto.getEffectType() == 1) { // 设置为启用中 xpElectronicFence.setStatus(2); xpElectronicFence.setEffectTime(LocalDateTime.now()); } else { if (dto.getEffectTime().isBefore(LocalDateTime.now())) { // 设置为启用中 xpElectronicFence.setStatus(2); } else { // 添加定时任务job type=1电子围栏生效 type=2电子围栏失效 Map<String, ? extends Object> maps = new ImmutableMap.Builder<String, Long>(). put("type", 1L) .put("id", xpElectronicFence.getId()) .build(); QuartzManager.addJob( ElectronicEffectJob.class, (ElectronicEffectJob.effect + xpElectronicFence.getId()).toUpperCase(), TimeJobType.ELECTRONIC_EFFECT, DateUtils.localDateTimeToDate(dto.getEffectTime()), maps ); xpElectronicFence.setStatus(1); } } if (dto.getFailureType() != null && dto.getFailureType() == 2) { if (dto.getFailureTime().isBefore(LocalDateTime.now())) { // 设置待启用 xpElectronicFence.setStatus(1); } else { // 添加定时任务job type=1电子围栏生效 type=2电子围栏失效 Map<String, ? extends Object> maps = new ImmutableMap.Builder<String, Long>(). put("type", 2L) .put("id", xpElectronicFence.getId()) .build(); QuartzManager.addJob( ElectronicEffectJob.class, (ElectronicEffectJob.failure + xpElectronicFence.getId()).toUpperCase(), TimeJobType.ELECTRONIC_FAILURE, DateUtils.localDateTimeToDate(dto.getEffectTime()), maps ); xpElectronicFence.setStatus(1); } } } this.updateById(xpElectronicFence); if (xpElectronicFence.getStatus() == 2) { // 设置电子围栏ID并保存区域数据 for (XpElectronicFenceArea area : newElectronicFenceAreas) { @@ -225,6 +280,46 @@ // 设置为启用中 xpElectronicFence.setStatus(2); } else { // 先删除以前的定时任务 QuartzManager.removeJob((ElectronicEffectJob.effect + xpElectronicFence.getId()).toUpperCase(), TimeJobType.ELECTRONIC_EFFECT); // 添加定时任务job type=1电子围栏生效 type=2电子围栏失效 Map<String, ? extends Object> maps = new ImmutableMap.Builder<String, Long>(). put("type", 1L) .put("id", xpElectronicFence.getId()) .build(); QuartzManager.addJob( ElectronicEffectJob.class, (ElectronicEffectJob.effect + xpElectronicFence.getId()).toUpperCase(), TimeJobType.ELECTRONIC_EFFECT, DateUtils.localDateTimeToDate(dto.getEffectTime()), maps ); xpElectronicFence.setStatus(1); } } if (dto.getFailureType() != null && dto.getFailureType() == 2) { if (dto.getFailureTime().isBefore(LocalDateTime.now())) { // 设置待启用 xpElectronicFence.setStatus(1); } else { // 先删除以前的定时任务 QuartzManager.removeJob((ElectronicEffectJob.failure + xpElectronicFence.getId()).toUpperCase(), TimeJobType.ELECTRONIC_FAILURE); // 添加定时任务job type=1电子围栏生效 type=2电子围栏失效 Map<String, ? extends Object> maps = new ImmutableMap.Builder<String, Long>(). put("type", 2L) .put("id", xpElectronicFence.getId()) .build(); QuartzManager.addJob( ElectronicEffectJob.class, (ElectronicEffectJob.failure + xpElectronicFence.getId()).toUpperCase(), TimeJobType.ELECTRONIC_FAILURE, DateUtils.localDateTimeToDate(dto.getEffectTime()), maps ); xpElectronicFence.setStatus(1); } } @@ -249,7 +344,7 @@ query.addCriteria(Criteria.where("fenceId").is(String.valueOf(xpElectronicFence.getId()))); query.addCriteria(Criteria.where("areaId").is(String.valueOf(newElectronicFenceArea.getId()))); XpGeoFencingPolygon old = mongoTemplate.findOne(query, XpGeoFencingPolygon.class); if (old==null){ if (old == null) { XpGeoFencingPolygon xpGeoFencingPolygon = new XpGeoFencingPolygon(); xpGeoFencingPolygon.setFenceId(String.valueOf(xpElectronicFence.getId())); xpGeoFencingPolygon.setName(xpElectronicFence.getElectronicName()); @@ -259,7 +354,7 @@ GeoJsonPolygon geoJsonPolygon = convertToGeoJsonPolygon(newElectronicFenceArea.getFencePoints()); xpGeoFencingPolygon.setPoints(geoJsonPolygon); mongoTemplate.insert(xpGeoFencingPolygon); }else{ } else { // 如果存在,则更新已有文档 old.setFenceId(String.valueOf(xpElectronicFence.getId())); old.setName(xpElectronicFence.getElectronicName()); @@ -280,7 +375,7 @@ query.addCriteria(Criteria.where("fenceId").is(String.valueOf(xpElectronicFence.getId()))); query.addCriteria(Criteria.where("areaId").is(String.valueOf(newElectronicFenceArea.getId()))); XpGeoFencingProhibitedPolygon old = mongoTemplate.findOne(query, XpGeoFencingProhibitedPolygon.class); if (old==null) { if (old == null) { XpGeoFencingProhibitedPolygon xpGeoFencingProhibitedPolygon = new XpGeoFencingProhibitedPolygon(); xpGeoFencingProhibitedPolygon.setFenceId(String.valueOf(xpElectronicFence.getId())); xpGeoFencingProhibitedPolygon.setName(xpElectronicFence.getElectronicName()); @@ -289,7 +384,7 @@ GeoJsonPolygon geoJsonPolygon = convertToGeoJsonPolygon(newElectronicFenceArea.getFencePoints()); xpGeoFencingProhibitedPolygon.setPoints(geoJsonPolygon); mongoTemplate.save(xpGeoFencingProhibitedPolygon); }else{ } else { old.setFenceId(String.valueOf(xpElectronicFence.getId())); old.setName(xpElectronicFence.getElectronicName()); old.setAreaId(String.valueOf(newElectronicFenceArea.getId())); @@ -479,7 +574,6 @@ } /** * * @return */ @Override xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPricingServiceImpl.java
@@ -503,4 +503,6 @@ // return null; } } xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpPointMapper.xml
@@ -80,8 +80,11 @@ <if test="query.pointType != null"> and t1.point_type = #{query.pointType} </if> <if test="query.operationStatus != null"> and t1.operation_status = #{query.operationStatus} <if test="query.operationStatusIds != null and query.operationStatusIds.size()>0"> AND t1.operation_status IN <foreach collection="query.operationStatusIds" separator="," item="id" open="(" close=")"> #{id} </foreach> </if> order by t1.create_time desc </select> xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -59,6 +59,7 @@ import com.xiaopeng.order.job.base.QuartzManager; import com.xiaopeng.order.job.base.TimeJobType; import com.xiaopeng.order.job.jobs.OrderCancelJob; import io.swagger.annotations.ApiModelProperty; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; @@ -815,17 +816,40 @@ // 根据订单所属开通城市id 查询定价 R<XpPricing> pricingByCityId = xpPricingClient.getPricingByCityId(order.getCityId()); XpPricing pricing = pricingByCityId.getData(); if (pricing == null) { throw new ServiceException("当前城市未配置定价规则", I18nKeyConstant.ORDER_PRICING_NOT_EXISTS); } Long id = pricing.getId(); Integer pricingType = pricing.getPricingType(); String basicPricingJson = pricing.getBasicPricingJson(); String startingFareJson = pricing.getStartingFareJson(); String dynamicPricingJson = pricing.getDynamicPricingJson(); String priceRule = pricing.getPriceRule(); if (pricing == null) { throw new ServiceException("当前城市未配置定价规则", I18nKeyConstant.ORDER_PRICING_NOT_EXISTS); } // 根据计价规则计算费用 BigDecimal startMoney = BigDecimal.ZERO;// 起步价 BigDecimal mileageMoney = BigDecimal.ZERO;// 里程费 BigDecimal durationMoney = BigDecimal.ZERO;// 时长费 BigDecimal waitMoney = BigDecimal.ZERO;// 等待费 BigDecimal longDistancemoney = BigDecimal.ZERO;// 远途费 BigDecimal redPacketMoney = BigDecimal.ZERO;// 红包抵扣金额 BigDecimal couponMoney = BigDecimal.ZERO;// 优惠券抵扣金额 if (pricingType==1){ }else{ } if (org.springframework.util.StringUtils.hasLength(basicPricingJson)){ } if (org.springframework.util.StringUtils.hasLength(startingFareJson)){ } if (org.springframework.util.StringUtils.hasLength(dynamicPricingJson)){ } if (org.springframework.util.StringUtils.hasLength(priceRule)){ } // 计算完价格后 挑选优惠券 GetUserCouponDto getUserCouponDto = new GetUserCouponDto(); getUserCouponDto.setUserId(Long.valueOf(uid));