| | |
| | | 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); |
| | | |
| | | |
| | | // 优先用满足条件且抵扣金额最大的 |
| | | List<XpAppUserCoupon> discountUserCoupons = couponList.stream().filter(e -> e.getCouponType() == 1).sorted(Comparator.comparing(XpAppUserCoupon::getMoney).reversed()).collect(Collectors.toList()); |
| | | if(!discountUserCoupons.isEmpty()){ |
| | |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * 获取优惠券列表 |
| | | */ |
| | |
| | | import com.xiaopeng.account.model.vo.XpAppUserCouponVo; |
| | | import com.xiaopeng.api.model.account.XpAppUserCoupon; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * <p> |
| | | * 用户优惠券 服务类 |
| | |
| | | */ |
| | | boolean receive(ReceiveCouponDto dto, String uid); |
| | | |
| | | /** |
| | | * 根据时间规则筛选出优惠券 |
| | | * @param couponList |
| | | * @return |
| | | */ |
| | | List<XpAppUserCoupon> timeRule(List<XpAppUserCoupon> couponList); |
| | | |
| | | |
| | | } |
| | |
| | | import com.xiaopeng.api.model.account.XpAppUserCoupon; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | |
| | | /** |
| | |
| | | return vo; |
| | | } |
| | | |
| | | /** |
| | | * 领取优惠券 |
| | | * @param dto |
| | | * @param uid |
| | | * @return |
| | | */ |
| | | @Override |
| | | public boolean receive(ReceiveCouponDto dto, String uid) { |
| | | XpAppUserCoupon coupon = baseMapper.selectById(dto.getCouponId()); |
| | |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * 时间规则 |
| | | * @param couponList |
| | | * @return |
| | | */ |
| | | @Override |
| | | public List<XpAppUserCoupon> timeRule(List<XpAppUserCoupon> couponList) { |
| | | return Collections.emptyList(); |
| | | } |
| | | } |
| | |
| | | |
| | | @ApiModelProperty(value = "订单总金额") |
| | | private Double totalAmount; |
| | | |
| | | @ApiModelProperty(value = "开通城市id") |
| | | private Long openCityId; |
| | | } |
| | |
| | | @PostMapping("/inner/order/queryOrderByOrderNo") |
| | | R<XpOrder> queryOrderByOrderNo(@RequestParam String orderNo); |
| | | |
| | | R<Integer> getOrderNum(String timeStr); |
| | | |
| | | |
| | | } |
| | |
| | | @TableField("price_rule") |
| | | private String priceRule; |
| | | |
| | | |
| | | @ApiModelProperty(value = "是否动态价格 0否 1是") |
| | | @TableField("is_dynamic_price") |
| | | private Integer isDynamicPrice; |
| | | |
| | | } |
| | |
| | | @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()); |
| | |
| | | @Lazy |
| | | public class GDMapGeocodingUtil { |
| | | |
| | | private String key = "f11b217cdbb08cd780919ed7398c5504"; |
| | | private String key = "66ae577f63898dae3016d599fda57221"; |
| | | |
| | | @Autowired |
| | | private RestTemplate restTemplate; |
| | |
| | | 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); |
| | | // } |
| | |
| | | () -> { |
| | | // 优惠券 |
| | | 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 |
| | |
| | | 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++) { |
| | |
| | | // 第二轮推单 |
| | | 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); |
| | |
| | | * @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) { |
| | |
| | | addTaxiPassengerVo.setAppId(""); |
| | | BaseVehicleUserDto baseVehicleUserDto = userVehicleClient.addTaxiPassenger(addTaxiPassengerVo); |
| | | if (baseVehicleUserDto.getCode() == 200) { |
| | | |
| | | // TODO 下单 |
| | | // 绑定成功 弹出这个队列第一个订单 |
| | | redisService.popFirstElement(quoteName); |
| | | return; |
| | |
| | | |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | 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; |
| | | |
| | | /** |
| | | * 计算价格的工具类 |
| | |
| | | @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(timeStr); |
| | | 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; |
| | | //等待费 |
| | |
| | | } |
| | | |
| | | // 订单总额 |
| | | 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; |
| | | } |
| | | } |