puzhibing
2026-02-12 1e139141c1ca4124f40383f9c426da9c2c23342b
Merge remote-tracking branch 'origin/master'
4个文件已添加
36个文件已修改
898 ■■■■■ 已修改文件
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpAppUserCouponController.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/IXpAppUserCouponService.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpAppUserCouponServiceImpl.java 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/util/holiday/HolidayUtil.java 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/account/GetUserCouponDto.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/order/GetOrderNumDto.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/XpSystemSettingClientFallbackFactory.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/order/XpOrderClientFallbackFactory.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/XpSystemSettingClient.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/order/XpOrderClient.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/account/XpAppUserCoupon.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpPricing.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/order/XpOrder.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/query/operation/PointPageListQuery.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/order/FareBreakdownVo.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/IndexController.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpPointManagementController.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceAreaServiceImpl.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/GDMapGeocodingUtil.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/OperationApplication.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpSystemSettingController.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/job/base/TimeJobType.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/job/jobs/ElectronicEffectJob.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/XpSystemSettingService.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpElectronicFenceServiceImpl.java 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPricingServiceImpl.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpSystemSettingServiceImpl.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/TaskOrderUtil.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/XpPricingUtil.java 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpPointMapper.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/base/TimeJobType.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/jobs/EndTripJob.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/IXpOrderService.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/dto/SetTemperatureDTO.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/dto/UnlockAppletDTO.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/IXpVehicleService.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpAppUserCouponController.java
@@ -52,10 +52,16 @@
    public R<UserCouponVo> getUserCoupon(@RequestBody GetUserCouponDto dto) {
        UserCouponVo userCouponVo = new UserCouponVo();
        // 获取用户所有优惠券
        List<XpAppUserCoupon> couponList = xpAppUserCouponService.list(new LambdaQueryWrapper<XpAppUserCoupon>().eq(XpAppUserCoupon::getStatus, 1).eq(XpAppUserCoupon::getAppUserId, dto.getUserId()));
        List<XpAppUserCoupon> couponList = xpAppUserCouponService.list(new LambdaQueryWrapper<XpAppUserCoupon>().eq(XpAppUserCoupon::getStatus, 1).eq(XpAppUserCoupon::getAppUserId, dto.getUserId()).apply("FIND_IN_SET({0}, open_city_id)", dto.getOpenCityId()) );
        if(couponList.isEmpty()){
            return R.ok(userCouponVo);
        }
        // 计算使用时间规则
        couponList = xpAppUserCouponService.timeRule(couponList);
        if(couponList.isEmpty()){
            return R.ok(userCouponVo);
        }
        // 优先用满足条件且抵扣金额最大的
        List<XpAppUserCoupon> discountUserCoupons = couponList.stream().filter(e -> e.getCouponType() == 1).sorted(Comparator.comparing(XpAppUserCoupon::getMoney).reversed()).collect(Collectors.toList());
        if(!discountUserCoupons.isEmpty()){
@@ -73,6 +79,8 @@
    }
    /**
     * 获取优惠券列表
     */
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/IXpAppUserCouponService.java
@@ -9,6 +9,8 @@
import com.xiaopeng.account.model.vo.XpAppUserCouponVo;
import com.xiaopeng.api.model.account.XpAppUserCoupon;
import java.util.List;
/**
 * <p>
 * 用户优惠券 服务类
@@ -42,4 +44,12 @@
     */
    boolean receive(ReceiveCouponDto dto, String uid);
    /**
     *  根据时间规则筛选出优惠券
     * @param couponList
     * @return
     */
    List<XpAppUserCoupon> timeRule(List<XpAppUserCoupon> couponList);
}
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpAppUserCouponServiceImpl.java
@@ -1,5 +1,7 @@
package com.xiaopeng.account.service.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -10,9 +12,14 @@
import com.xiaopeng.account.model.vo.XpAppUserCouponTotalVo;
import com.xiaopeng.account.model.vo.XpAppUserCouponVo;
import com.xiaopeng.account.service.IXpAppUserCouponService;
import com.xiaopeng.account.util.holiday.HolidayUtil;
import com.xiaopeng.api.model.account.XpAppUserCoupon;
import com.xiaopeng.common.core.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
@@ -25,6 +32,9 @@
 */
@Service
public class XpAppUserCouponServiceImpl extends ServiceImpl<XpAppUserCouponMapper, XpAppUserCoupon> implements IXpAppUserCouponService {
    @Autowired
    private HolidayUtil holidayUtil;
    /**
     * 获取用户优惠券列表
@@ -57,6 +67,12 @@
        return vo;
    }
    /**
     * 领取优惠券
     * @param dto
     * @param uid
     * @return
     */
    @Override
    public boolean receive(ReceiveCouponDto dto, String uid) {
        XpAppUserCoupon coupon = baseMapper.selectById(dto.getCouponId());
@@ -67,4 +83,74 @@
        }
        return false;
    }
    /**
     * 时间规则
     * @param couponList
     * @return
     */
    @Override
    public List<XpAppUserCoupon> timeRule(List<XpAppUserCoupon> couponList) {
       List<XpAppUserCoupon> xpAppUserCoupons = new ArrayList<>();
        for (XpAppUserCoupon coupon : couponList) {
            String timeJson = coupon.getTimeJson();
            Boolean inOperationTime = isInOperationTime(timeJson);
            if(inOperationTime){
                xpAppUserCoupons.add(coupon);
            }
        }
        return xpAppUserCoupons;
    }
    /**
     * 是否在运营内
     * @param timeJson 规则json字符串
     * @return
     */
    private Boolean isInOperationTime(String timeJson) {
        JSONArray jsonArray = JSONArray.parseArray(timeJson);
        Integer holidayToday = holidayUtil.isHolidayToday();
        for (Object o : jsonArray) {
            JSONObject jsonObject =JSONObject.parseObject(o.toString());
            String type = jsonObject.getString("type");
            if(type.equals(holidayToday.toString())){
                JSONArray time = jsonObject.getJSONArray("time");
                // 判断当前时间 是否在time时间段中
                for (Object object : time) {
                    String[] timeArray = object.toString().split("-");
                    String startTime = timeArray[0];
                    String endTime = timeArray[1];
                    boolean currentTimeInRange = DateUtils.isCurrentTimeInRange(startTime, endTime);
                    if(currentTimeInRange){
                        return true;
                    }
                }
            }else if(type.equals("3")){
                // 判断是什么类型 0每天  1-7 想起
                String typeStr = jsonObject.getString("typeStr");
                // 查看今天周几
                Integer week = DateUtils.getWeek();
                // 包含每天 或者  包含当天
                if(typeStr.contains("0") || typeStr.contains(week.toString())){
                    JSONArray time = jsonObject.getJSONArray("time");
                    // 判断当前时间 是否在time时间段中
                    for (Object object : time) {
                        String[] timeArray = object.toString().split("-");
                        String startTime = timeArray[0];
                        String endTime = timeArray[1];
                        boolean currentTimeInRange = DateUtils.isCurrentTimeInRange(startTime, endTime);
                        if(currentTimeInRange){
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }
}
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/util/holiday/HolidayUtil.java
New file
@@ -0,0 +1,80 @@
package com.xiaopeng.account.util.holiday;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.xiaopeng.common.core.constant.CacheConstants;
import com.xiaopeng.common.core.utils.HttpUtils;
import com.xiaopeng.common.redis.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.LocalDate;
import java.util.concurrent.TimeUnit;
@Component
public class HolidayUtil {
    @Autowired
    private RedisService redisService;
    public  boolean isHoliday() {
        LocalDate now = LocalDate.now();
        // 判断缓存里面是否有节假日算法
        if (redisService.getCacheObject(CacheConstants.IS_HOLIDAY+now) != null && ("1").equals(redisService.getCacheObject(CacheConstants.IS_HOLIDAY+now).toString())) {
            return true;
        }
        String result = HttpUtil.get("https://publicapi.xiaoai.me/holiday/day?date=" +now);
        JSONObject jsonObject = JSONObject.parseObject(result);
        Object data = jsonObject.get("data");
        JSONArray parse = JSONArray.parse(data.toString());
        for (int i = 0; i < parse.size(); i++) {
            JSONObject jsonObject1 = parse.getJSONObject(i);
            if (jsonObject1.get("daytype").toString().equals("1")) {
                redisService.setCacheObject(CacheConstants.IS_HOLIDAY+now, "1", 1l, TimeUnit.DAYS);
                return true;
            }
        }
        redisService.setCacheObject(CacheConstants.IS_HOLIDAY+now, "0", 1l, TimeUnit.DAYS);
        return false;
    }
    /**
     * 2非工作日  0工作日  1节假日 3调休日
     * @return
     */
    public  Integer isHolidayToday() {
        LocalDate now = LocalDate.now();
        Object cacheObject = redisService.getCacheObject(CacheConstants.IS_DAY + now);
        // 判断缓存里面是否有节假日算法
        if (cacheObject!=null) {
            return Integer.valueOf(cacheObject.toString());
        }
        String result = HttpUtils.sendGet("https://publicapi.xiaoai.me/holiday/day?date=" +now);
//        String result = HttpUtils.sendGet("https://publicapi.xiaoai.me/holiday/day?date=2026-01-04");
        JSONObject jsonObject = JSONObject.parseObject(result);
        Object data = jsonObject.get("data");
        JSONArray parse = JSONArray.parse(data.toString());
        for (int i = 0; i < parse.size(); i++) {
            JSONObject jsonObject1 = parse.getJSONObject(i);
            String daytype = jsonObject1.get("daytype").toString();
            if (daytype.equals("0")) {
                redisService.setCacheObject(CacheConstants.IS_DAY + now, "0", 1l, TimeUnit.DAYS);
                return 0;
            } else if (daytype.equals("1")) {
                redisService.setCacheObject(CacheConstants.IS_DAY + now, "1", 1l, TimeUnit.DAYS);
                return 1;
            } else if (daytype.equals("2")) {
                redisService.setCacheObject(CacheConstants.IS_DAY + now, "0", 1l, TimeUnit.DAYS);
                return 0;
            }
        }
        return 0;
    }
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/account/GetUserCouponDto.java
@@ -16,4 +16,7 @@
    @ApiModelProperty(value = "订单总金额")
    private Double totalAmount;
    @ApiModelProperty(value = "开通城市id")
    private Long openCityId;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/order/GetOrderNumDto.java
New file
@@ -0,0 +1,18 @@
package com.xiaopeng.api.dto.order;
import io.swagger.annotations.ApiModel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@ApiModel(value = "获取订单数量")
@AllArgsConstructor
@NoArgsConstructor
public class GetOrderNumDto {
    // 时间参数
    private String timeStr;
    // 开通城市ID
    private Long openCityId;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/XpSystemSettingClientFallbackFactory.java
@@ -19,6 +19,12 @@
                log.error("获取下单距离失败:{}", cause.getMessage());
                return R.fail("获取下单距离失败");
            }
            @Override
            public R<Integer> getOrderFinishTime() {
                log.error("获取自动结束行程时间失败:{}", cause.getMessage());
                return R.fail("获取自动结束行程时间失败,"+cause.getMessage());
            }
        };
    }
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/order/XpOrderClientFallbackFactory.java
@@ -67,6 +67,12 @@
                log.error("根据订单编号查询订单信息查询失败,原因: {}", cause.getMessage());
                return R.fail();
            }
            @Override
            public R<Integer> getOrderNum(String timeStr) {
                log.error("获取订单数量失败,原因: {}", cause.getMessage());
                return R.fail();
            }
        };
    }
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/XpSystemSettingClient.java
@@ -15,6 +15,11 @@
    @GetMapping("/base/v1/mini-program/support/getOrderDistance")
    R getOrderDistance();
    /**
     * 获取自动结束行程时间
     * @return
     */
    @GetMapping("/api/v1/mini-program/support/getOrderFinishTime")
    R<Integer> getOrderFinishTime();
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/order/XpOrderClient.java
@@ -1,5 +1,6 @@
package com.xiaopeng.api.feignClient.order;
import com.xiaopeng.api.dto.order.GetOrderNumDto;
import com.xiaopeng.api.dto.statistics.OrderStatisticsDTO;
import com.xiaopeng.api.dto.statistics.StatisticsQueryDTO;
import com.xiaopeng.api.factory.order.XpOrderClientFallbackFactory;
@@ -72,4 +73,15 @@
    @PostMapping("/inner/order/queryOrderByOrderNo")
    R<XpOrder> queryOrderByOrderNo(@RequestParam String orderNo);
    /**
     * 获取订单数量
     *
     * @param
     * @return 订单数量
     */
    @PostMapping("/inner/order/getOrderNum")
    R<Integer> getOrderNum(@RequestBody GetOrderNumDto dto);
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/account/XpAppUserCoupon.java
@@ -68,4 +68,7 @@
    @ApiModelProperty(value = "城市id集合")
    private String openCityId;
    @ApiModelProperty(value = "使用时间规则")
    private String timeJson;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpPricing.java
@@ -68,4 +68,9 @@
    @TableField("price_rule")
    private String priceRule;
    @ApiModelProperty(value = "是否动态价格 0否 1是")
    @TableField("is_dynamic_price")
    private Integer isDynamicPrice;
}
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-api/src/main/java/com/xiaopeng/api/vo/order/FareBreakdownVo.java
@@ -35,4 +35,8 @@
    private BigDecimal couponMoney;
    @ApiModelProperty(value = "订单金额")
    private BigDecimal orderMoney;
    @ApiModelProperty(value = "订单全程公里数")
    private BigDecimal totalKilometers;
    @ApiModelProperty(value = "订单全程时间(单位分钟)")
    private BigDecimal totalTime;
}
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/IndexController.java
@@ -3,6 +3,7 @@
import com.xiaopeng.api.dto.operation.PointMapQuery;
import com.xiaopeng.api.feignClient.operation.XpPointClient;
import com.xiaopeng.api.model.operation.XpPoint;
import com.xiaopeng.api.query.operation.PointPageListQuery;
import com.xiaopeng.api.vo.account.LoginOperationUser;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.redis.service.RedisService;
@@ -38,6 +39,12 @@
        R<List<XpPoint>> pageInfo= pointClient.pointMap(query);
        return pageInfo;
    }
    @ApiOperation(value = "点位管理列表", tags = {"运维APP-站点导航"})
    @PostMapping("/list")
    public R<List<XpPoint>> list(@RequestBody PointPageListQuery query) {
        return pointClient.list( query);
    }
    @ApiOperation(value = "点位详情")
    @GetMapping("/api/v1/pointDetail")
    public R<XpPoint> pointDetail(@RequestParam(value = "点位id", required = true)Long id) {
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-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceAreaServiceImpl.java
@@ -279,7 +279,7 @@
    @Override
    public WalkTimeVo getWalkTime(WalkTimeDto dto) {
        WalkTimeVo walkTimeVo = new WalkTimeVo();
        String apiKey = "009f3714aca6a61e05d3e63ea03226c9";
        String apiKey = "66ae577f63898dae3016d599fda57221";
        // 创建服务实例
        GaodeMapService gaodeService = new GaodeMapService(apiKey);
        AmapWalkingRouteUtil.WalkingRouteResult result = gaodeService.getWalkingRoute(dto.getStartLongitude()+","+dto.getStartLatitude(),dto.getEndLongitude()+","+dto.getEndLatitude());
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/GDMapGeocodingUtil.java
@@ -24,7 +24,7 @@
@Lazy
public class GDMapGeocodingUtil {
    private String key = "f11b217cdbb08cd780919ed7398c5504";
    private String key = "66ae577f63898dae3016d599fda57221";
    @Autowired
    private RestTemplate restTemplate;
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/controller/XpSystemSettingController.java
@@ -19,7 +19,7 @@
@Slf4j
@RestController
@RequestMapping("/base/v1/mini-program")
@RequestMapping("")
@Api(tags = "系统设置模块")
public class XpSystemSettingController extends BaseController {
@@ -33,7 +33,7 @@
    }
    @GetMapping("/support/phone")
    @GetMapping("/base/v1/mini-program/support/phone")
    @ApiOperation(value = "获取客服电话",tags = {"小程序首页"},response = String.class)
    public AjaxResult<CustomerServicePhoneVo> getBannerList() {
        Object customerServicePhone = redisService.getCacheObject(CacheConstants.CUSTOMER_SERVICE_PHONE);
@@ -52,11 +52,16 @@
//    }
    @GetMapping("/support/getOrderDistance")
    @GetMapping("/base/v1/mini-program/support/getOrderDistance")
    @ApiOperation(value = "获取下单距离",tags = {"小程序首页-服务调用获取下单距离"},response = Integer.class)
    public R getOrderDistance() {
        return R.ok(xpSystemSettingService.getOrderDistance());
    }
    @ApiOperation(value = "获取自动结束行程时间",tags = {"小程序-业务流程"},response = Integer.class)
    @GetMapping("/api/v1/mini-program/support/getOrderFinishTime")
    public R<Integer> getOrderFinishTime() {
        return R.ok(xpSystemSettingService.getOrderFinishTime());
    }
}
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/XpSystemSettingService.java
@@ -27,5 +27,11 @@
    Integer getOrderDistance();
    /**
     * 获取自动结束行程时间
     * @return
     */
    Integer getOrderFinishTime();
}
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
@@ -187,7 +187,7 @@
            routeAndFareDto.setRoutePlanRule(xpRoutePlan.getRoutePlanRule());
        }
//        XpPricing xpPricing = this.baseMapper.selectOne(new LambdaQueryWrapper<XpPricing>().eq(XpPricing::getCityId, routeAndFareDto.getOpenCityId()));
        XpPricing xpPricing = this.baseMapper.selectOne(new LambdaQueryWrapper<XpPricing>().eq(XpPricing::getCityId, routeAndFareDto.getOpenCityId()));
//        if (xpPricing == null) {
//            throw new ServiceException("当前区域未开通服务", I18nKeyConstant.NO_CURRENT_REGION);
//        }
@@ -217,8 +217,8 @@
                () -> {
                        // 优惠券
                        return xpAppUserCouponClient.getUserCoupon(
//                                new GetUserCouponDto(Long.valueOf(userId), xpPricingCardVo.getTotalPrice())
                                new GetUserCouponDto(Long.valueOf(userId), 1d)
//                                new GetUserCouponDto(Long.valueOf(userId), xpPricingCardVo.getTotalPrice(),routeAndFareDto.getOpenCityId())
                                new GetUserCouponDto(Long.valueOf(userId), 1d,routeAndFareDto.getOpenCityId())
                        );
                },
                executorService
@@ -503,4 +503,6 @@
//        return null;
    }
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpSystemSettingServiceImpl.java
@@ -35,4 +35,13 @@
        }
        return 0;
    }
    @Override
    public Integer getOrderFinishTime() {
        XpSystemSetting xpSystemSetting = this.getOne(null);
        if (xpSystemSetting != null) {
            return xpSystemSetting.getArriveTime();
        }
        return 15;
    }
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/TaskOrderUtil.java
@@ -130,7 +130,7 @@
        Integer onePushTime = xpTradingStrategy.getOnePushTime();
        int count = onePushTime / 3;
        // 第一轮推单
        processOrder(quoteName, count, uid, split, orderNo, xpTradingStrategy, distance, duration, planRule);
        processPushOrder(quoteName, count, uid, split, orderNo, xpTradingStrategy, distance, duration, planRule);
//
//        for (int i = 0; i < count; i++) {
@@ -172,22 +172,22 @@
        // 第二轮推单
        Integer twoPushTime = xpTradingStrategy.getTwoPushTime();
        count = twoPushTime / 3;
        processOrder(quoteName, count, uid, split, orderNo, xpTradingStrategy, distance, duration, planRule);
        processPushOrder(quoteName, count, uid, split, orderNo, xpTradingStrategy, distance, duration, planRule);
        // 第三轮推单
        Integer threePushTime = xpTradingStrategy.getThreePushTime();
        count = threePushTime / 3;
        processOrder(quoteName, count, uid, split, orderNo, xpTradingStrategy, distance, duration, planRule);
        processPushOrder(quoteName, count, uid, split, orderNo, xpTradingStrategy, distance, duration, planRule);
        // 第四轮推单
        Integer fourPushTime = xpTradingStrategy.getFourPushTime();
        count = fourPushTime / 3;
        processOrder(quoteName, count, uid, split, orderNo, xpTradingStrategy, distance, duration, planRule);
        processPushOrder(quoteName, count, uid, split, orderNo, xpTradingStrategy, distance, duration, planRule);
        // 第五轮推单
        Integer fivePushTime = xpTradingStrategy.getFivePushTime();
        count = fivePushTime / 3;
        processOrder(quoteName, count, uid, split, orderNo, xpTradingStrategy, distance, duration, planRule);
        processPushOrder(quoteName, count, uid, split, orderNo, xpTradingStrategy, distance, duration, planRule);
        // 最终没找到车
        redisService.popFirstElement(quoteName);
@@ -206,7 +206,7 @@
     * @param orderNo 订单号
     * @param xpTradingStrategy  规则
     */
    private void processOrder(String quoteName, int count, String uid, String[] split, String orderNo, XpTradingStrategy xpTradingStrategy, String distance, String duration, String planRule) {
    private void processPushOrder(String quoteName, int count, String uid, String[] split, String orderNo, XpTradingStrategy xpTradingStrategy, String distance, String duration, String planRule) {
        // 订单状态
        R<XpOrder> xpOrderR = xpOrderClient.queryOrderByOrderNo(orderNo);
        if (xpOrderR.getCode() != 200) {
@@ -586,6 +586,8 @@
                        addTaxiPassengerVo.setAppId("");
                        BaseVehicleUserDto baseVehicleUserDto = userVehicleClient.addTaxiPassenger(addTaxiPassengerVo);
                        if (baseVehicleUserDto.getCode() == 200) {
                            // TODO 下单
                            // 绑定成功  弹出这个队列第一个订单
                            redisService.popFirstElement(quoteName);
                            return;
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/XpPricingUtil.java
@@ -2,13 +2,20 @@
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xiaopeng.api.dto.order.GetOrderNumDto;
import com.xiaopeng.api.feignClient.order.XpOrderClient;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.redis.service.RedisService;
import com.xiaopeng.operation.utils.holiday.HolidayUtil;
import com.xiaopeng.operation.vo.XpPricingCardVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
 * 计算价格的工具类
@@ -20,19 +27,76 @@
    @Autowired
    private HolidayUtil holidayUtil;
    @Autowired
    private RedisService redisService;
    @Autowired
    private XpOrderClient xpOrderClient;
    /**
     *  计算基础价格
     * @param rule
     * @param distance
     * @param duration
     * @param wait
     * @param waitMoney
     * @param rule 基础规则
     * @param distance 里程
     * @param duration  时间
     * @param wait  时间
     * @param waitMoney 等待费
     * @param openCityId 开通城市id
     * @param isDynamicPriceStatus 是否开启动态调价
     * @return
     * @throws Exception
     */
    public XpPricingCardVo calculationPrice(JSONObject rule, JSONArray startingFareJson, double distance, long duration, long wait, Double waitMoney) {
    public XpPricingCardVo calculationPrice(String uid,JSONObject rule, JSONArray startingFareJson, double distance, long duration, long wait, Double waitMoney,Integer isDynamicPriceStatus,Long openCityId,String dynamicPricingJson) {
        // 默认费率1
        double priceRate=1;
        if(isDynamicPriceStatus==1){
            // 先判断是否已经调价过了
            Object userDynamicPriceObj = redisService.getCacheObject("USER_DYNAMIC_PRICE_" + openCityId + "_" + uid);
            if(userDynamicPriceObj!=null){
                // 是否调价过了
                priceRate = Double.parseDouble(userDynamicPriceObj.toString());
            }else {
                // 没有调过
                //是否触发动态调价 redis获取
                Object dynamicPriceObj = redisService.getCacheObject("DYNAMIC_PRICE_" + openCityId);
                if(dynamicPriceObj!=null){
                    JSONObject jsonObject = JSONObject.parseObject(dynamicPricingJson);
                    // 触发动态调价
                    // value=时间
                    String timeStr = dynamicPriceObj.toString();
                    // 判断当前距离这个时间范围的新增订单数(排除取消) / 上浮数量 算出应该增加的价格率
                    R<Integer> r = xpOrderClient.getOrderNum(new GetOrderNumDto(timeStr,openCityId));
                    if(r.getData()==200){
                        int num = r.getData();
                        // X单上升一次调价
                        Integer orderNum = getOrderNum(jsonObject, 4);
                        // 需要调价的次数
                        int count = num / orderNum;
                        if(count>0){
                            // 计算每次上升的费率
                            Integer upRate = getOrderNum(jsonObject, 5);
                            BigDecimal divide = new BigDecimal(upRate).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
                            for (int i = count; i > 0; i--) {
                                // 当前费率+(费率*上升百分比)
                                priceRate =  new BigDecimal(priceRate).multiply(divide).add(new BigDecimal(priceRate)).setScale(2, RoundingMode.HALF_UP).doubleValue();
                            }
                            // 冷却时间
                            Integer time = getOrderNum(jsonObject, 6);
                            // 触发调价了
                            redisService.setCacheObject("USER_DYNAMIC_PRICE_" + openCityId + "_" + uid, priceRate,time.longValue(), TimeUnit.MINUTES);
                        }
                    }
                }
            }
        }
        XpPricingCardVo xpPricingCardVo = new XpPricingCardVo();
        double amount = 0;
        //等待费
@@ -253,9 +317,28 @@
        }
        // 订单总额
        Double startPrice = xpPricingCardVo.getStartPrice();
        // 先减去起步价重新计算
        amount = amount - startPrice;
        // 动态计算费用
        startPrice= new BigDecimal(startPrice).multiply(new BigDecimal(priceRate)).setScale(2, RoundingMode.HALF_UP).doubleValue();
        amount = amount+startPrice;
        xpPricingCardVo.setTotalPrice(amount);
        return xpPricingCardVo;
    }
    /**
     * 获取配置  4每X单  5上升X%  6冷却
     *
     * @param rule
     * @param num
     * @return
     */
    private Integer getOrderNum(JSONObject rule, int num) {
        Integer param = rule.getInteger("num" + num);
        return param;
    }
}
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/controller/XpOrderController.java
@@ -4,9 +4,11 @@
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xiaopeng.api.dto.order.GetOrderNumDto;
import com.xiaopeng.api.dto.statistics.OrderStatisticsDTO;
import com.xiaopeng.api.dto.statistics.StatisticsQueryDTO;
import com.xiaopeng.api.model.order.XpOrder;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.api.vo.order.FareBreakdownVo;
import com.xiaopeng.api.vo.order.XpHistoryEndPointsVo;
import com.xiaopeng.api.vo.order.XpHistoryStartPointsVo;
@@ -100,6 +102,16 @@
    @PostMapping("/inner/order/queryOrderByOrderNo")
    public R<XpOrder> queryOrderByOrderNo(@RequestParam String orderNo){
        return R.ok(xpOrderService.getOne(new LambdaQueryWrapper<XpOrder>().eq(XpOrder::getOrderNumber, orderNo)));
    }
    /**
     * 获取订单数量
     *
     * @return 订单数量
     */
    @PostMapping("/inner/order/getOrderNum")
    public  R<Integer> getOrderNum(@RequestBody GetOrderNumDto dto){
        return R.ok(xpOrderService.getOrderNum(dto));
    }
    /**
@@ -377,5 +389,14 @@
        return xpOrderService.updateOrderStatus(orderId,status);
    }
    /**
     * 业务流程-通过订单id查询车辆信息
     */
    @ApiOperation(value = "通过订单id查询车辆信息", tags = {"小程序-业务流程"})
    @GetMapping("/api/v1/order/queryVehicleByOrderId")
    public R<XpVehicle> queryVehicleByOrderId(@RequestParam Long orderId, HttpServletRequest request) {
        String uid = request.getHeader("XP-Uid");
        return R.ok(xpOrderService.queryVehicleByOrderId(orderId,uid));
    }
}
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/base/TimeJobType.java
@@ -5,7 +5,8 @@
 * @date 2025年2月17日 下午7:22:28
 */
public enum TimeJobType {
    ORDER_CANCEL("order_cancel","订单取消");
    ORDER_CANCEL("order_cancel","订单取消"),
    END_TRIP("end_trip","自动结束行程");
    private String type;
    private String desc;
    private TimeJobType(String type, String desc) {
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/jobs/EndTripJob.java
New file
@@ -0,0 +1,42 @@
package com.xiaopeng.order.job.jobs;
import com.alibaba.fastjson2.JSONObject;
import com.xiaopeng.api.dto.pushMessage.SendMessageDTO;
import com.xiaopeng.api.model.order.XpOrder;
import com.xiaopeng.common.core.enums.OrderStatusEnum;
import com.xiaopeng.common.core.enums.PushMessageTypeEnum;
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.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
 * 直播推送定时任务
 * @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("开始执行自动结束行程任务");
            // TODO 自动结束行程任务
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/IXpOrderService.java
@@ -2,9 +2,11 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.api.dto.order.GetOrderNumDto;
import com.xiaopeng.api.dto.statistics.OrderStatisticsDTO;
import com.xiaopeng.api.dto.statistics.StatisticsQueryDTO;
import com.xiaopeng.api.model.order.XpOrder;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.api.vo.order.FareBreakdownVo;
import com.xiaopeng.api.vo.order.XpHistoryEndPointsVo;
import com.xiaopeng.api.vo.order.XpHistoryStartPointsVo;
@@ -158,6 +160,24 @@
    R payment(XpOrderPayDto dto, String uid);
    /**
     * 添加订单
     * @param xpOrder
     * @return
     */
    boolean addOrder(XpOrder xpOrder);
    /**
     * 根据订单ID查询车辆信息
     * @param orderId 订单ID
     * @param uid
     * @return
     */
    XpVehicle queryVehicleByOrderId(Long orderId, String uid);
    /**
     * 获取订单数量
     * @return
     */
    Integer getOrderNum(GetOrderNumDto dto);
}
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -9,6 +9,7 @@
import com.google.common.collect.ImmutableMap;
import com.xiaopeng.api.dto.account.GetUserCouponDto;
import com.xiaopeng.api.dto.operation.LonLatDto;
import com.xiaopeng.api.dto.order.GetOrderNumDto;
import com.xiaopeng.api.dto.order.HistoryEndPointsDto;
import com.xiaopeng.api.dto.order.HistoryStartPointsDto;
import com.xiaopeng.api.dto.statistics.DailyCountDTO;
@@ -17,6 +18,7 @@
import com.xiaopeng.api.dto.vehicleConvoy.BaseVehicleUserDto;
import com.xiaopeng.api.feignClient.account.XpAppUserClient;
import com.xiaopeng.api.feignClient.account.XpAppUserCouponClient;
import com.xiaopeng.api.feignClient.operation.XpSystemSettingClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.UserVehicleClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetVehicleClient;
@@ -46,6 +48,7 @@
import com.xiaopeng.common.redis.service.RedisService;
import com.xiaopeng.common.security.utils.SecurityUtils;
import com.xiaopeng.order.constant.I18nKeyConstant;
import com.xiaopeng.order.job.jobs.EndTripJob;
import com.xiaopeng.order.mapper.XpOrderMapper;
import com.xiaopeng.order.model.dto.XpOrderCommentDto;
import com.xiaopeng.order.model.dto.XpOrderPayDto;
@@ -59,6 +62,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;
@@ -68,6 +72,8 @@
import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
@@ -100,6 +106,7 @@
    private final IXpOrderReassignService xpOrderReassignService;
    private final RedisService redisService;
    private final XpPricingClient xpPricingClient;
    private final XpSystemSettingClient xpSystemSettingClient;
    @Override
    public OrderStatisticsDTO getOrderStatistics(StatisticsQueryDTO query) {
@@ -778,8 +785,8 @@
        xpOrder.setStatus(status);
        switch (status) {
            case 4:
                // 添加定时任务job
                Map<String, ? extends Object> maps =
                // 添加取消订单定时任务job
                Map<String, ? extends Object> cancelJobMaps =
                        new ImmutableMap.Builder<String, Long>().
                                put("id", xpOrder.getId())
                                .build();
@@ -788,12 +795,28 @@
                        (OrderCancelJob.name + xpOrder.getId()).toUpperCase(),
                        TimeJobType.ORDER_CANCEL,
                        DateUtils.localDateTimeToDate(LocalDateTime.now().plusMinutes(5)),
                        maps
                        cancelJobMaps
                );
                break;
            case 5:
                // 删除定时任务job
                QuartzManager.removeJob((OrderCancelJob.name + xpOrder.getId()).toUpperCase(), TimeJobType.ORDER_CANCEL);
                break;
            case 7:
                // 查询自动结束行程时间
                Integer arriveTime = xpSystemSettingClient.getOrderFinishTime().getData();
                // 添加自动结束行程定时任务job
                Map<String, ? extends Object> endTripJobMaps =
                        new ImmutableMap.Builder<String, Long>().
                                put("id", xpOrder.getId())
                                .build();
                QuartzManager.addJob(
                        EndTripJob.class,
                        (EndTripJob.name + xpOrder.getId()).toUpperCase(),
                        TimeJobType.END_TRIP,
                        DateUtils.localDateTimeToDate(LocalDateTime.now().plusMinutes(arriveTime)),
                        endTripJobMaps
                );
                break;
        }
        baseMapper.updateById(xpOrder);
@@ -815,17 +838,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));
@@ -836,6 +882,7 @@
            order.setCouponId(userCouponVo.getId());
            order.setCouponMoney(BigDecimal.valueOf(userCouponVo.getMoney()));
        }
        order.setTripEnd(LocalDateTime.now());
        baseMapper.updateById(order);
        // 解绑用户与车辆关系
        CancelTaxiPassengerVo cancelTaxiPassengerVo = new CancelTaxiPassengerVo();
@@ -856,6 +903,21 @@
        XpOrder order = this.getById(orderId);
        FareBreakdownVo fareBreakdownVo = new FareBreakdownVo();
        BeanUtils.copyProperties(order, fareBreakdownVo);
        fareBreakdownVo.setTotalKilometers(
                BigDecimal.valueOf(order.getStartMileage() + order.getMileageKilometers() + order.getLongDistance())
        );
        LocalDateTime createTime = order.getCreateTime();
        LocalDateTime tripEnd = order.getTripEnd();
        // 计算行程时间 单位分钟
        // 计算时间差
        Duration duration = Duration.between(createTime, tripEnd);
        // 转换为分钟并保留一位小数
        BigDecimal minutes = BigDecimal.valueOf(duration.getSeconds())
                .divide(BigDecimal.valueOf(60), 1, RoundingMode.HALF_UP);
        fareBreakdownVo.setTotalTime(minutes);
        return R.ok(fareBreakdownVo);
    }
@@ -868,13 +930,40 @@
        return R.ok();
    }
    /**
     * 添加订单
     * @param xpOrder
     * @return
     */
    @Override
    public boolean addOrder(XpOrder xpOrder) {
        int insert = this.baseMapper.insert(xpOrder);
        if (insert <= 0) {
            return false;
        }
        return true;
    }
    @Override
    public XpVehicle queryVehicleByOrderId(Long orderId, String uid) {
        XpOrder xpOrder = this.getById(orderId);
        XpVehicle xpVehicle = xpVehicleClient.queryById(xpOrder.getVehicleId()).getData();
        return xpVehicle;
    }
    /**
     * 获取订单数量
     * @param dto
     * @return
     */
    @Override
    public Integer getOrderNum(GetOrderNumDto dto) {
        Long num = this.baseMapper.selectCount(new LambdaQueryWrapper<XpOrder>().eq(XpOrder::getCityId, dto.getOpenCityId()).between(BaseModel::getCreateTime, dto.getTimeStr(), new Date()));
        return num.intValue();
    }
    /**
     * 获取当前用户正在执行的订单
     *
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java
@@ -7,9 +7,12 @@
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.xiaopeng.api.feignClient.order.XpOrderClient;
import com.xiaopeng.api.model.order.XpOrder;
import com.xiaopeng.api.feignClient.maintenance.XpVehiclePreparationClient;
import com.xiaopeng.api.model.query.XpVehiclePreparationPageQuery;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.api.vo.vehicleConvoy.VehicleTemperatureVo;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicleAnnualRecord;
import com.xiaopeng.api.vo.maintenance.XpVehiclePreparationDetailVO;
import com.xiaopeng.api.vo.vehicleConvoy.VehiclesCommandCallbackVo;
@@ -38,6 +41,7 @@
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
@@ -45,6 +49,7 @@
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
 * <p>
@@ -61,6 +66,7 @@
public class XpVehicleController {
    private final IXpVehicleService xpVehicleService;
    private final XpOrderClient xpOrderClient;
    private final IXpVehicleAnnualRecordService xpVehicleAnnualRecordService;
    private final XpVehiclePreparationClient xpVehiclePreparationClient;
@@ -453,7 +459,7 @@
     */
    @ApiOperation(value = "打开车门操作", tags = {"小程序-业务流程"})
    @PostMapping("/api/v1/order/vehicle/unlock")
    public R<String> unlock(@RequestBody UnlockAppletDTO dto) {
    public R<Integer> unlock(@RequestBody UnlockAppletDTO dto) {
        return R.ok(xpVehicleService.unlock(dto));
    }
@@ -462,8 +468,19 @@
     */
    @ApiOperation(value = "打开设置温度", tags = {"小程序-业务流程"})
    @PostMapping("/api/v1/order/ac/set-temperature")
    public R<String> setTemperature(@RequestBody SetTemperatureDTO dto) {
    public R<Integer> setTemperature(@RequestBody SetTemperatureDTO dto) {
        return R.ok(xpVehicleService.setTemperature(dto));
    }
    /**
     * 业务流程-通过订单id查询当前车辆温度
     */
    @ApiOperation(value = "通过订单id查询当前车辆温度", tags = {"小程序-业务流程"})
    @GetMapping("/api/v1/order/queryTemperatureByOrderId")
    public R<VehicleTemperatureVo> queryTemperatureByOrderId(@RequestParam Long orderId, HttpServletRequest request) {
        String uid = request.getHeader("XP-Uid");
        VehicleTemperatureVo vehicleTemperatureVo = xpVehicleService.queryTemperatureByOrderId(orderId,uid);
        return R.ok(vehicleTemperatureVo);
    }
}
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/dto/SetTemperatureDTO.java
@@ -11,9 +11,9 @@
public class SetTemperatureDTO implements Serializable {
    @ApiModelProperty(value = "订单id")
    private Long order_id;
    private Long orderId;
    @ApiModelProperty(value = "设置温度值")
    private Integer target_temperature;
    private Integer targetTemperature;
}
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/dto/UnlockAppletDTO.java
@@ -11,9 +11,9 @@
public class UnlockAppletDTO implements Serializable {
    @ApiModelProperty(value = "订单id")
    private Long order_id;
    private Long orderId;
    @ApiModelProperty(value = "要开启的车门类型,取值: \"door\" — 主副驾车门 \"trunk\" — 后备箱")
    private String door_type;
    private String doorType;
}
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/IXpVehicleService.java
@@ -2,6 +2,7 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.api.vo.vehicleConvoy.VehicleTemperatureVo;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.vehicleConvoy.model.dto.*;
import com.xiaopeng.vehicleConvoy.model.importExcel.XpVehicleImportExcel;
@@ -60,14 +61,14 @@
     * @param dto 车门解锁/后备箱解锁参数
     * @return
     */
    String unlock(UnlockAppletDTO dto);
    Integer unlock(UnlockAppletDTO dto);
    /**
     * 车辆详情-设定温度
     * @param dto 设定温度参数
     * @return
     */
    String setTemperature(SetTemperatureDTO dto);
    Integer setTemperature(SetTemperatureDTO dto);
    /**
     * 新增车辆
@@ -156,4 +157,12 @@
     * @param query 查询参数
     */
    List<XpVehicle> operationVehicleExportList(OperationVehicleExportQuery query);
    /**
     * 查询车辆温度
     *
     * @param orderId 订单ID
     * @return 车辆温度
     */
    VehicleTemperatureVo queryTemperatureByOrderId(Long orderId,String uid);
}
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java
@@ -12,6 +12,7 @@
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicleAnnualRecord;
import com.xiaopeng.api.vo.operation.ElectronicFenceDetailVo;
import com.xiaopeng.api.vo.vehicleConvoy.VehicleTemperatureVo;
import com.xiaopeng.api.vo.vehicleConvoy.VehiclesCommandEnum;
import com.xiaopeng.api.vo.vehicleConvoy.VehiclesCommandParamVo;
import com.xiaopeng.api.vo.vehicleConvoy.VehiclesCommandVo;
@@ -119,9 +120,9 @@
    }
    @Override
    public String unlock(UnlockAppletDTO dto) {
    public Integer unlock(UnlockAppletDTO dto) {
        // 查询订单
        XpOrder xpOrder = xpOrderClient.queryOrderById(dto.getOrder_id()).getData();
        XpOrder xpOrder = xpOrderClient.queryOrderById(dto.getOrderId()).getData();
        if(Objects.isNull(xpOrder)){
            throw new ServiceException("未查询到有效订单信息", I18nKeyConstant.ORDER_NOT_EXISTS);
        }
@@ -133,18 +134,25 @@
        VehiclesCommandVo vehiclesCommandVo = new VehiclesCommandVo();
        vehiclesCommandVo.setUid(xpOrder.getAppUserId());
        vehiclesCommandVo.setVin(xpVehicle.getVehicleVin());
        if("door".equals(dto.getDoor_type())){
        if("door".equals(dto.getDoorType())){
            vehiclesCommandVo.setCommandCode(VehiclesCommandEnum.DOOR_UNLOCK);
        }else {
            vehiclesCommandVo.setCommandCode(VehiclesCommandEnum.DOOR_TRUNK_OPEN);
        }
        return vehicleControlUtil.vehiclesCommand(vehiclesCommandVo);
        try{
            String result = vehicleControlUtil.vehiclesCommand(vehiclesCommandVo);
            log.info("车辆控制结果:{}", result);
            return 1;
        }catch (Exception e){
            log.error("车辆控制异常:{}", e.getMessage());
            return 0;
        }
    }
    @Override
    public String setTemperature(SetTemperatureDTO dto) {
    public Integer setTemperature(SetTemperatureDTO dto) {
        // 查询订单
        XpOrder xpOrder = xpOrderClient.queryOrderById(dto.getOrder_id()).getData();
        XpOrder xpOrder = xpOrderClient.queryOrderById(dto.getOrderId()).getData();
        if(Objects.isNull(xpOrder)){
            throw new ServiceException("未查询到有效订单信息", I18nKeyConstant.ORDER_NOT_EXISTS);
        }
@@ -158,9 +166,16 @@
        vehiclesCommandVo.setVin(xpVehicle.getVehicleVin());
        vehiclesCommandVo.setCommandCode(VehiclesCommandEnum.HVAC_TEMP_SET);
        VehiclesCommandParamVo vehiclesCommandParamVo = new VehiclesCommandParamVo();
        vehiclesCommandParamVo.setDegree(dto.getTarget_temperature());
        vehiclesCommandParamVo.setDegree(dto.getTargetTemperature());
        vehiclesCommandVo.setExtParam(vehiclesCommandParamVo);
        return vehicleControlUtil.vehiclesCommand(vehiclesCommandVo);
        try{
            String result = vehicleControlUtil.vehiclesCommand(vehiclesCommandVo);
            log.info("车辆控制结果:{}", result);
            return 1;
        }catch (Exception e){
            log.error("车辆控制异常:{}", e.getMessage());
            return 0;
        }
    }
    @Override
@@ -573,4 +588,24 @@
        }
        return list;
    }
    @Override
    public VehicleTemperatureVo queryTemperatureByOrderId(Long orderId,String uid) {
        XpOrder xpOrder = xpOrderClient.queryOrderById(orderId).getData();
        if(Objects.isNull(xpOrder)){
            throw new ServiceException("未查询到有效订单信息", I18nKeyConstant.ORDER_NOT_EXISTS);
        }
        XpVehicle xpVehicle = this.getById(xpOrder.getVehicleId());
        if(Objects.isNull(xpVehicle)){
            throw new ServiceException("未查询到有效车辆信息", I18nKeyConstant.VEHICLE_NOT_EXISTS);
        }
        try{
            VehicleTemperatureVo vehicleTemperatureVo = vehicleControlUtil.queryVehicleTemperature(uid, xpVehicle.getVehicleVin());
            log.info("查询车辆温度成功:{}",vehicleTemperatureVo);
            return vehicleTemperatureVo;
        }catch (Exception e){
            log.error("查询车辆温度失败",e);
            return new VehicleTemperatureVo();
        }
    }
}