当前位置: 首页 > news >正文

乐尚代驾-----Day10(订单三)

hi UU 们!!!我又来跟辛辣!感谢你们的观看,话不多说!~

 

  • 司机到达代驾终点,代驾结束了。
  • 结束代驾之后,


– 获取额外费用(高速费、停车费等)

– 计算订单实际里程(实际与预估有偏差)

– 计算代驾实际费用

– 系统奖励

– 分账信息

– 生成最终账单

计算订单实际里程
在MongoDB保存代驾过程中司机位置信息,把MongoDB存储司机位置信息获取出来,以时间排序,连接成一条线,这条线是实际距离

地图微服务接口

@Operation(summary = "代驾服务:计算订单实际里程")
@GetMapping("/calculateOrderRealDistance/{orderId}")
public Result<BigDecimal> calculateOrderRealDistance(@PathVariable Long orderId) {return Result.ok(locationService.calculateOrderRealDistance(orderId));
}@Overridepublic BigDecimal calculateOrderRealDistance(Long orderId) {//1 根据订单id获取代驾订单位置信息,根据创建时间排序(升序)//查询MongoDB//第一种方式
//        OrderServiceLocation orderServiceLocation = new OrderServiceLocation();
//        orderServiceLocation.setOrderId(orderId);
//        Example<OrderServiceLocation> example = Example.of(orderServiceLocation);
//        Sort sort = Sort.by(Sort.Direction.ASC, "createTime");
//        List<OrderServiceLocation> list = orderServiceLocationRepository.findAll(example, sort);//第二种方式//MongoRepository只需要 按照规则 在MongoRepository把查询方法创建出来就可以了// 总体规则://1 查询方法名称 以 get  |  find  | read开头//2 后面查询字段名称,满足驼峰式命名,比如OrderId//3 字段查询条件添加关键字,比如Like  OrderBy   Asc// 具体编写 : 根据订单id获取代驾订单位置信息,根据创建时间排序(升序)List<OrderServiceLocation> list =orderServiceLocationRepository.findByOrderIdOrderByCreateTimeAsc(orderId);//2 第一步查询返回订单位置信息list集合//把list集合遍历,得到每个位置信息,计算两个位置距离//把计算所有距离相加操作double realDistance = 0;if(!CollectionUtils.isEmpty(list)) {for (int i = 0,size = list.size()-1; i < size; i++) {OrderServiceLocation location1 = list.get(i);OrderServiceLocation location2 = list.get(i + 1);//计算位置距离double distance = LocationUtil.getDistance(location1.getLatitude().doubleValue(),location1.getLongitude().doubleValue(),location2.getLatitude().doubleValue(),location2.getLongitude().doubleValue());realDistance += distance;}}//3 返回最终计算实际距离return new BigDecimal(realDistance);}/*** 代驾服务:计算订单实际里程* @param orderId* @return*/
@GetMapping("/map/location/calculateOrderRealDistance/{orderId}")
Result<BigDecimal> calculateOrderRealDistance(@PathVariable Long orderId);

计算系统奖励

系统奖励
每天完成5单后 每单奖励2元
每天完成10单后 每单奖励5元
每天完成20单后 每单奖励10元

//package对应的不一定是真正的目录,可以任意写com.abc,同一个包下的drl文件可以相互访问
package  com.atguigu.daijiaimport com.atguigu.daijia.model.form.rules.RewardRuleRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;global com.atguigu.daijia.model.vo.rules.RewardRuleResponse rewardRuleResponse;/**
系统奖励00:00:00-06:59:59  完成5单后 每单奖励5元07:00:00-23:59:59  完成10单后 每单奖励2元
*/
rule "00:00:00-06:59:59  完成5单后 每单奖励5元"salience 10          //指定优先级,数值越大优先级越高,不指定的情况下由上到下执行no-loop true         //防止陷入死循环when/*规则条件,到工作内存中查找FeeRuleRequest对象里面出来的结果只能是ture或者false$rule是绑定变量名,可以任意命名,官方推荐$符号,定义了绑定变量名,可以在then部分操作fact对象*/$rule:RewardRuleRequest(startTime >= "00:00:00" && startTime <= "06:59:59" && orderNum > 5)thenrewardRuleResponse.setRewardAmount(new BigDecimal("5.0"));System.out.println("00:00:00-06:59:59 奖励:" + rewardRuleResponse.getRewardAmount() + "元");
end
rule "07:00:00-23:59:59  完成10单后 每单奖励2元"salience 10          //指定优先级,数值越大优先级越高,不指定的情况下由上到下执行no-loop true         //防止陷入死循环when/*规则条件,到工作内存中查找FeeRuleRequest对象里面出来的结果只能是ture或者false$rule是绑定变量名,可以任意命名,官方推荐$符号,定义了绑定变量名,可以在then部分操作fact对象*/$rule:RewardRuleRequest(startTime >= "07:00:00" && startTime <= "23:59:59" && orderNum > 10)thenrewardRuleResponse.setRewardAmount(new BigDecimal("2.0"));System.out.println("00:00:00-06:59:59 奖励:" + rewardRuleResponse.getRewardAmount() + "元");
endpublic class DroolsHelper {private static final String RULES_CUSTOMER_RULES_DRL = "rules/FeeRule.drl";public static KieSession loadForRule(String drlStr) {KieServices kieServices = KieServices.Factory.get();KieFileSystem kieFileSystem = kieServices.newKieFileSystem();kieFileSystem.write(ResourceFactory.newClassPathResource(drlStr));KieBuilder kb = kieServices.newKieBuilder(kieFileSystem);kb.buildAll();KieModule kieModule = kb.getKieModule();KieContainer kieContainer = kieServices.newKieContainer(kieModule.getReleaseId());return kieContainer.newKieSession();}
}@Operation(summary = "计算订单奖励费用")
@PostMapping("/calculateOrderRewardFee")
public Result<RewardRuleResponseVo>calculateOrderRewardFee(@RequestBody RewardRuleRequestForm rewardRuleRequestForm) {return Result.ok(rewardRuleService.calculateOrderRewardFee(rewardRuleRequestForm));
}@Override
public RewardRuleResponseVo calculateOrderRewardFee(RewardRuleRequestForm rewardRuleRequestForm) {//封装传入参数对象RewardRuleRequest rewardRuleRequest = new RewardRuleRequest();rewardRuleRequest.setOrderNum(rewardRuleRequestForm.getOrderNum());//创建规则引擎对象KieSession kieSession = DroolsHelper.loadForRule(RULES_CUSTOMER_RULES_DRL);//封装返回对象RewardRuleResponse rewardRuleResponse = new RewardRuleResponse();kieSession.setGlobal("rewardRuleResponse",rewardRuleResponse);//设置对象,触发规则kieSession.insert(rewardRuleRequest);kieSession.fireAllRules();//终止会话kieSession.dispose();//封装RewardRuleResponseVoRewardRuleResponseVo rewardRuleResponseVo = new RewardRuleResponseVo();rewardRuleResponseVo.setRewardAmount(rewardRuleResponse.getRewardAmount());return rewardRuleResponseVo;
}/*** 计算订单奖励费用* @param rewardRuleRequestForm* @return*/
@PostMapping("/rules/reward/calculateOrderRewardFee")
Result<RewardRuleResponseVo> calculateOrderRewardFee(@RequestBody RewardRuleRequestForm rewardRuleRequestForm);

 

根据时间段获取订单数

  • 因为系统奖励的计算,白天和晚上是不一样的,所以会根据时间段来获取
@Operation(summary = "根据时间段获取订单数")
@GetMapping("/getOrderNumByTime/{startTime}/{endTime}")
public Result<Long> getOrderNumByTime(@PathVariable String startTime, @PathVariable String endTime) {return Result.ok(orderInfoService.getOrderNumByTime(startTime, endTime));
}@Override
public Long getOrderNumByTime(String startTime, String endTime) {// 09 <= time < 10   <= time1  <    11// 这么写所有的订单都可以被查询到,且不会重复LambdaQueryWrapper<OrderInfo> wrapper = new LambdaQueryWrapper<>();wrapper.ge(OrderInfo::getStartServiceTime,startTime);wrapper.lt(OrderInfo::getStartServiceTime,endTime);Long count = orderInfoMapper.selectCount(wrapper);return count;
}/***  根据时间段获取订单数* @param startTime* @param endTime* @return*/
@GetMapping("/order/info/getOrderNumByTime/{startTime}/{endTime}")
Result<Long> getOrderNumByTime(@PathVariable("startTime") String startTime, @PathVariable("endTime") String endTime);

计算分账信息

  • 结束代驾之后,计算分账信息,平台按照一定规则抽成处理,将分账信息记录数据库表


支付微信平台费用
平台费率:0.6%
订单金额小于等于100
当天完成订单小于等于10单 平台抽成 20%
当天完成订单大于10单 平台抽成 18%
订单金额大于100
当天完成订单小于等于10单 平台抽成 18%
当天完成订单大于10单 平台抽成 16%

//package对应的不一定是真正的目录,可以任意写com.abc,同一个包下的drl文件可以相互访问
package  com.atguigu.daijiaimport com.atguigu.daijia.model.form.rules.ProfitsharingRuleRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;global com.atguigu.daijia.model.vo.rules.ProfitsharingRuleResponse profitsharingRuleResponse;
//支付微信平台费率:0.6%
//global BigDecimal paymentRate = new BigDecimal(0.006);
/**
支付微信平台费用平台费率:0.6%
*/
rule "支付微信平台费用 平台费率:0.6%"salience 10          //指定优先级,数值越大优先级越高,不指定的情况下由上到下执行no-loop true         //防止陷入死循环when/*规则条件,到工作内存中查找FeeRuleRequest对象里面出来的结果只能是ture或者false$rule是绑定变量名,可以任意命名,官方推荐$符号,定义了绑定变量名,可以在then部分操作fact对象*/$rule:ProfitsharingRuleRequest()thenprofitsharingRuleResponse.setOrderAmount($rule.getOrderAmount());profitsharingRuleResponse.setPaymentRate(new BigDecimal("0.006"));BigDecimal paymentFee = profitsharingRuleResponse.getOrderAmount().multiply(profitsharingRuleResponse.getPaymentRate()).setScale(2, RoundingMode.HALF_UP);profitsharingRuleResponse.setPaymentFee(paymentFee);System.out.println("支付微信平台费用:" + profitsharingRuleResponse.getPaymentFee() + "元");
end/**
订单金额小于等于100当天完成订单小于等于10单 平台抽成 20%当天完成订单大于10单 平台抽成 18%
*/
rule "订单金额小于等于100 当天完成订单小于等于10单"salience 10          //指定优先级,数值越大优先级越高,不指定的情况下由上到下执行no-loop true         //防止陷入死循环when/*规则条件,到工作内存中查找FeeRuleRequest对象里面出来的结果只能是ture或者false$rule是绑定变量名,可以任意命名,官方推荐$符号,定义了绑定变量名,可以在then部分操作fact对象*/$rule:ProfitsharingRuleRequest(orderAmount <= 100.0 && orderNum <= 10)thenBigDecimal totalAmount = profitsharingRuleResponse.getOrderAmount().subtract(profitsharingRuleResponse.getPaymentFee());BigDecimal platformIncome = totalAmount.multiply(new BigDecimal("0.2")).setScale(2, RoundingMode.HALF_UP);BigDecimal driverTotalIncome = totalAmount.subtract(platformIncome);//代驾司机个税,税率:10%BigDecimal driverTaxFee = driverTotalIncome.multiply(new BigDecimal("0.1")).setScale(2, RoundingMode.HALF_UP);BigDecimal driverIncome = driverTotalIncome.subtract(driverTaxFee);profitsharingRuleResponse.setPlatformIncome(platformIncome);profitsharingRuleResponse.setDriverIncome(driverIncome);profitsharingRuleResponse.setDriverTaxRate(new BigDecimal("0.1"));profitsharingRuleResponse.setDriverTaxFee(driverTaxFee);System.out.println("平台分账收入:" + platformIncome + "元" + ",司机分账收入:" + driverIncome + "元" + ",司机个税:" + driverTaxFee + "元");
end
rule "订单金额小于等于100 天完成订单大于10单"salience 10          //指定优先级,数值越大优先级越高,不指定的情况下由上到下执行no-loop true         //防止陷入死循环when/*规则条件,到工作内存中查找FeeRuleRequest对象里面出来的结果只能是ture或者false$rule是绑定变量名,可以任意命名,官方推荐$符号,定义了绑定变量名,可以在then部分操作fact对象*/$rule:ProfitsharingRuleRequest(orderAmount <= 100.0 && orderNum > 10)thenBigDecimal totalAmount = profitsharingRuleResponse.getOrderAmount().subtract(profitsharingRuleResponse.getPaymentFee());BigDecimal platformIncome = totalAmount.multiply(new BigDecimal("0.18")).setScale(2, RoundingMode.HALF_UP);BigDecimal driverTotalIncome = totalAmount.subtract(platformIncome);//代驾司机个税,税率:10%BigDecimal driverTaxFee = driverTotalIncome.multiply(new BigDecimal("0.1")).setScale(2, RoundingMode.HALF_UP);BigDecimal driverIncome = driverTotalIncome.subtract(driverTaxFee);profitsharingRuleResponse.setPlatformIncome(platformIncome);profitsharingRuleResponse.setDriverIncome(driverIncome);profitsharingRuleResponse.setDriverTaxRate(new BigDecimal("0.1"));profitsharingRuleResponse.setDriverTaxFee(driverTaxFee);System.out.println("平台分账收入:" + platformIncome + "元" + ",司机分账收入:" + driverIncome + "元" + ",司机个税:" + driverTaxFee + "元");
end/**
订单金额大于100当天完成订单小于等于10单 平台抽成 18%当天完成订单大于10单 平台抽成 16%
*/
rule "订单金额大于100 当天完成订单小于等于10单"salience 10          //指定优先级,数值越大优先级越高,不指定的情况下由上到下执行no-loop true         //防止陷入死循环when/*规则条件,到工作内存中查找FeeRuleRequest对象里面出来的结果只能是ture或者false$rule是绑定变量名,可以任意命名,官方推荐$符号,定义了绑定变量名,可以在then部分操作fact对象*/$rule:ProfitsharingRuleRequest(orderAmount > 100.0 && orderNum <= 10)thenBigDecimal totalAmount = profitsharingRuleResponse.getOrderAmount().subtract(profitsharingRuleResponse.getPaymentFee());BigDecimal platformIncome = totalAmount.multiply(new BigDecimal("0.18")).setScale(2, RoundingMode.HALF_UP);BigDecimal driverTotalIncome = totalAmount.subtract(platformIncome);//代驾司机个税,税率:10%BigDecimal driverTaxFee = driverTotalIncome.multiply(new BigDecimal("0.1")).setScale(2, RoundingMode.HALF_UP);BigDecimal driverIncome = driverTotalIncome.subtract(driverTaxFee);profitsharingRuleResponse.setPlatformIncome(platformIncome);profitsharingRuleResponse.setDriverIncome(driverIncome);profitsharingRuleResponse.setDriverTaxRate(new BigDecimal("0.1"));profitsharingRuleResponse.setDriverTaxFee(driverTaxFee);System.out.println("平台分账收入:" + platformIncome + "元" + ",司机分账收入:" + driverIncome + "元" + ",司机个税:" + driverTaxFee + "元");
end
rule "订单金额大于100 天完成订单大于10单"salience 10          //指定优先级,数值越大优先级越高,不指定的情况下由上到下执行no-loop true         //防止陷入死循环when/*规则条件,到工作内存中查找FeeRuleRequest对象里面出来的结果只能是ture或者false$rule是绑定变量名,可以任意命名,官方推荐$符号,定义了绑定变量名,可以在then部分操作fact对象*/$rule:ProfitsharingRuleRequest(orderAmount > 100.0 && orderNum > 10)thenBigDecimal totalAmount = profitsharingRuleResponse.getOrderAmount().subtract(profitsharingRuleResponse.getPaymentFee());BigDecimal platformIncome = totalAmount.multiply(new BigDecimal("0.18")).setScale(2, RoundingMode.HALF_UP);BigDecimal driverTotalIncome = totalAmount.subtract(platformIncome);//代驾司机个税,税率:10%BigDecimal driverTaxFee = driverTotalIncome.multiply(new BigDecimal("0.1")).setScale(2, RoundingMode.HALF_UP);BigDecimal driverIncome = driverTotalIncome.subtract(driverTaxFee);profitsharingRuleResponse.setPlatformIncome(platformIncome);profitsharingRuleResponse.setDriverIncome(driverIncome);profitsharingRuleResponse.setDriverTaxRate(new BigDecimal("0.1"));profitsharingRuleResponse.setDriverTaxFee(driverTaxFee);System.out.println("平台分账收入:" + platformIncome + "元" + ",司机分账收入:" + driverIncome + "元" + ",司机个税:" + driverTaxFee + "元");
end@RestController
@RequestMapping("/rules/profitsharing")
@SuppressWarnings({"unchecked", "rawtypes"})
public class ProfitsharingRuleController {@Autowiredprivate ProfitsharingRuleService profitsharingRuleService;@Operation(summary = "计算系统分账费用")@PostMapping("/calculateOrderProfitsharingFee")public Result<ProfitsharingRuleResponseVo> calculateOrderProfitsharingFee(@RequestBody ProfitsharingRuleRequestForm profitsharingRuleRequestForm) {return Result.ok(profitsharingRuleService.calculateOrderProfitsharingFee(profitsharingRuleRequestForm));}
}private static final String RULES_CUSTOMER_RULES_DRL = "rules/ProfitsharingRule.drl";@Override
public ProfitsharingRuleResponseVo calculateOrderProfitsharingFee(ProfitsharingRuleRequestForm profitsharingRuleRequestForm) {//传入参数对象封装ProfitsharingRuleRequest profitsharingRuleRequest = new ProfitsharingRuleRequest();profitsharingRuleRequest.setOrderAmount(profitsharingRuleRequestForm.getOrderAmount());profitsharingRuleRequest.setOrderNum(profitsharingRuleRequestForm.getOrderNum());//创建kieSessionKieSession kieSession = DroolsHelper.loadForRule(RULES_CUSTOMER_RULES_DRL);//封装返回对象ProfitsharingRuleResponse profitsharingRuleResponse = new ProfitsharingRuleResponse();kieSession.setGlobal("profitsharingRuleResponse",profitsharingRuleResponse);//触发规则,返回vo对象kieSession.insert(profitsharingRuleRequest);kieSession.fireAllRules();kieSession.dispose();ProfitsharingRuleResponseVo profitsharingRuleResponseVo = new ProfitsharingRuleResponseVo();BeanUtils.copyProperties(profitsharingRuleResponse,profitsharingRuleResponseVo);return profitsharingRuleResponseVo;
}/*** 计算订单分账数据* @param profitsharingRuleRequestForm* @return*/
@PostMapping("/rules/profitsharing/calculateOrderProfitsharingFee")
Result<ProfitsharingRuleResponseVo> calculateOrderProfitsharingFee(@RequestBody ProfitsharingRuleRequestForm profitsharingRuleRequestForm);

 

结束代驾更新账单

  • 更新订单数据:订单状态、订单实际距离、订单实际金额等
  • 添加实际账单信息
  • 添加分账信息
@Operation(summary = "结束代驾服务更新订单账单")
@PostMapping("/endDrive")
public Result<Boolean> endDrive(@RequestBody UpdateOrderBillForm updateOrderBillForm) {return Result.ok(orderInfoService.endDrive(updateOrderBillForm));
}@Override
public Boolean endDrive(UpdateOrderBillForm updateOrderBillForm) {//1 更新订单信息// update order_info set ..... where id=? and driver_id=?LambdaQueryWrapper<OrderInfo> wrapper = new LambdaQueryWrapper<>();wrapper.eq(OrderInfo::getId,updateOrderBillForm.getOrderId());wrapper.eq(OrderInfo::getDriverId,updateOrderBillForm.getDriverId());OrderInfo orderInfo = new OrderInfo();orderInfo.setStatus(OrderStatus.END_SERVICE.getStatus());orderInfo.setRealAmount(updateOrderBillForm.getTotalAmount());orderInfo.setFavourFee(updateOrderBillForm.getFavourFee());orderInfo.setRealDistance(updateOrderBillForm.getRealDistance());orderInfo.setEndServiceTime(new Date());int rows = orderInfoMapper.update(orderInfo, wrapper);if(rows == 1) {//添加账单数据OrderBill orderBill = new OrderBill();BeanUtils.copyProperties(updateOrderBillForm,orderBill);orderBill.setOrderId(updateOrderBillForm.getOrderId());orderBill.setPayAmount(updateOrderBillForm.getTotalAmount());orderBillMapper.insert(orderBill);//添加分账信息OrderProfitsharing orderProfitsharing = new OrderProfitsharing();BeanUtils.copyProperties(updateOrderBillForm, orderProfitsharing);orderProfitsharing.setOrderId(updateOrderBillForm.getOrderId());orderProfitsharing.setRuleId(updateOrderBillForm.getProfitsharingRuleId());orderProfitsharing.setStatus(1);orderProfitsharingMapper.insert(orderProfitsharing);} else {throw new GuiguException(ResultCodeEnum.UPDATE_ERROR);}return true;
}/*** 结束代驾服务更新订单账单* @param updateOrderBillForm* @return*/
@PostMapping("/order/info/endDrive")
Result<Boolean> endDrive(@RequestBody UpdateOrderBillForm updateOrderBillForm);

结束代驾

  • 调用以上的所有接口最终实现
@Operation(summary = "结束代驾服务更新订单账单")
@GuiguLogin
@PostMapping("/endDrive")
public Result<Boolean> endDrive(@RequestBody OrderFeeForm orderFeeForm) {Long driverId = AuthContextHolder.getUserId();orderFeeForm.setDriverId(driverId);return Result.ok(orderService.endDrive(orderFeeForm));
}@Override
public Boolean endDrive(OrderFeeForm orderFeeForm) {//1 根据orderId获取订单信息,判断当前订单是否司机接单OrderInfo orderInfo = orderInfoFeignClient.getOrderInfo(orderFeeForm.getOrderId()).getData();if(orderInfo.getDriverId() != orderFeeForm.getDriverId()) {throw new GuiguException(ResultCodeEnum.ILLEGAL_REQUEST);}//2 计算订单实际里程BigDecimal realDistance =locationFeignClient.calculateOrderRealDistance(orderFeeForm.getOrderId()).getData();//3 计算代驾实际费用//远程调用,计算代驾费用//封装FeeRuleRequestFormFeeRuleRequestForm feeRuleRequestForm = new FeeRuleRequestForm();feeRuleRequestForm.setDistance(realDistance);feeRuleRequestForm.setStartTime(orderInfo.getStartServiceTime());//计算司机到达代驾开始位置时间//orderInfo.getArriveTime() - orderInfo.getAcceptTime()// 分钟 = 毫秒 / 1000 * 60Integer waitMinute =Math.abs((int)((orderInfo.getArriveTime().getTime()-orderInfo.getAcceptTime().getTime())/(1000 * 60)));feeRuleRequestForm.setWaitMinute(waitMinute);//远程调用 代驾费用FeeRuleResponseVo feeRuleResponseVo = feeRuleFeignClient.calculateOrderFee(feeRuleRequestForm).getData();//实际费用 = 代驾费用 + 其他费用(停车费)BigDecimal totalAmount =feeRuleResponseVo.getTotalAmount().add(orderFeeForm.getTollFee()).add(orderFeeForm.getParkingFee()).add(orderFeeForm.getOtherFee()).add(orderInfo.getFavourFee());feeRuleResponseVo.setTotalAmount(totalAmount);//4 计算系统奖励String startTime = new DateTime(orderInfo.getStartServiceTime()).toString("yyyy-MM-dd") + " 00:00:00";String endTime = new DateTime(orderInfo.getStartServiceTime()).toString("yyyy-MM-dd") + " 24:00:00";Long orderNum = orderInfoFeignClient.getOrderNumByTime(startTime, endTime).getData();//4.2.封装参数RewardRuleRequestForm rewardRuleRequestForm = new RewardRuleRequestForm();rewardRuleRequestForm.setStartTime(orderInfo.getStartServiceTime());rewardRuleRequestForm.setOrderNum(orderNum);RewardRuleResponseVo rewardRuleResponseVo = rewardRuleFeignClient.calculateOrderRewardFee(rewardRuleRequestForm).getData();//5 计算分账信息ProfitsharingRuleRequestForm profitsharingRuleRequestForm = new ProfitsharingRuleRequestForm();profitsharingRuleRequestForm.setOrderAmount(feeRuleResponseVo.getTotalAmount());profitsharingRuleRequestForm.setOrderNum(orderNum);ProfitsharingRuleResponseVo profitsharingRuleResponseVo = profitsharingRuleFeignClient.calculateOrderProfitsharingFee(profitsharingRuleRequestForm).getData();//6 封装实体类,结束代驾更新订单,添加账单和分账信息UpdateOrderBillForm updateOrderBillForm = new UpdateOrderBillForm();updateOrderBillForm.setOrderId(orderFeeForm.getOrderId());updateOrderBillForm.setDriverId(orderFeeForm.getDriverId());//路桥费、停车费、其他费用updateOrderBillForm.setTollFee(orderFeeForm.getTollFee());updateOrderBillForm.setParkingFee(orderFeeForm.getParkingFee());updateOrderBillForm.setOtherFee(orderFeeForm.getOtherFee());//乘客好处费updateOrderBillForm.setFavourFee(orderInfo.getFavourFee());//实际里程updateOrderBillForm.setRealDistance(realDistance);//订单奖励信息BeanUtils.copyProperties(rewardRuleResponseVo, updateOrderBillForm);//代驾费用信息BeanUtils.copyProperties(feeRuleResponseVo, updateOrderBillForm);//分账相关信息BeanUtils.copyProperties(profitsharingRuleResponseVo, updateOrderBillForm);updateOrderBillForm.setProfitsharingRuleId(profitsharingRuleResponseVo.getProfitsharingRuleId());orderInfoFeignClient.endDrive(updateOrderBillForm);return true;
}

智能判断司机刷单行为

  • 什么是刷单行为?
  • 司机还没有到达代驾地点就点击到达,司机还没有到达终点就点击结束代驾,这样做是为了争取更多的订单,争取更多的平台奖励。

司机到达代驾开始位置判断

– 通过腾讯地图,获取司机当前位置,当前位置到代驾开始位置距离

– 如果距离超过1公里,没有到达开始位置

司机到达代驾结束位置判断
– 通过腾讯地图,获取司机当前位置,当前位置到代驾结束位置距离

– 如果距离超过2公里,没有到达开始位置

判断预估里程和实际里程差别

//司机到达代驾起始地点
@Override
public Boolean driverArriveStartLocation(Long orderId, Long driverId) {//判断// orderInfo有代驾开始位置OrderInfo orderInfo = orderInfoFeignClient.getOrderInfo(orderId).getData();//司机当前位置OrderLocationVo orderLocationVo = locationFeignClient.getCacheOrderLocation(orderId).getData();//司机当前位置 和 代驾开始位置距离double distance = LocationUtil.getDistance(orderInfo.getStartPointLatitude().doubleValue(),orderInfo.getStartPointLongitude().doubleValue(),orderLocationVo.getLatitude().doubleValue(),orderLocationVo.getLongitude().doubleValue());if(distance > SystemConstant.DRIVER_START_LOCATION_DISTION) {throw new GuiguException(ResultCodeEnum.DRIVER_START_LOCATION_DISTION_ERROR);}return orderInfoFeignClient.driverArriveStartLocation(orderId,driverId).getData();
}//防止刷
OrderServiceLastLocationVo orderServiceLastLocationVo = locationFeignClient.getOrderServiceLastLocation(orderFeeForm.getOrderId()).getData();//司机当前位置 距离 结束代驾位置 
double distance = LocationUtil.getDistance(orderInfo.getEndPointLatitude().doubleValue(),orderInfo.getEndPointLongitude().doubleValue(),orderServiceLastLocationVo.getLatitude().doubleValue(),orderServiceLastLocationVo.getLongitude().doubleValue());
if(distance > SystemConstant.DRIVER_END_LOCATION_DISTION) {throw new GuiguException(ResultCodeEnum.DRIVER_END_LOCATION_DISTION_ERROR);
}

谢谢uu们的观看,你们的努力真的很棒,加油!!!!

相关文章:

乐尚代驾-----Day10(订单三)

hi UU 们&#xff01;&#xff01;&#xff01;我又来跟辛辣&#xff01;感谢你们的观看&#xff0c;话不多说&#xff01;~ 司机到达代驾终点&#xff0c;代驾结束了。结束代驾之后&#xff0c; – 获取额外费用&#xff08;高速费、停车费等&#xff09; – 计算订单实际里程…...

105. 聚光源SpotLight

入门部分给大家介绍过平行光DirectionalLight、点光源PointLight、环境光AmbientLight,下面给大家介绍一个新的光源对象&#xff0c;也就是聚光源SpotLight。 创建聚光源SpotLight 聚光源可以认为是一个沿着特定方会逐渐发散的光源&#xff0c;照射范围在三维空间中构成一个圆…...

系统接口权限拦截器,获取用户信息存储

UserInfo 类 这是一个表示用户信息的 Java 类&#xff0c;使用了 Lombok 注解来简化代码编写。 import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString;import java.io.Serializable; import java.util.List;Data ToString EqualsAndHashCode public…...

Chromium HTML5 新的 Input 类型color 对应c++

一、Input 类型: color color 类型用在input字段主要用于选取颜色&#xff0c;如下所示&#xff1a; <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>菜鸟教程(runoob.com)</title> </head> <body&…...

问:SQL中的通用函数及用法?

SQL函数是在SQL语句中使用的预定义的计算工具&#xff0c;可以对一列数据进行操作并返回一个单一的结果。这些函数大致可以分为两类&#xff1a;Aggregate函数和Scalar函数。Aggregate函数对一组值执行计算&#xff0c;并返回单个值&#xff0c;如求和、平均值、最大值和最小值…...

.NET Core WebApi第6讲:WebApi的前端怎么派人去拿数据?(区别MVC)

一、前端界面小基础 head&#xff1a;引入CSS, 引入JS是写在head里面。 body&#xff1a;眼睛肉眼能看到的用户展示的界面是写在body里面。 二、前端怎么派人去拿数据&#xff1f; 1、MVC&#xff1a;前后端不分离&#xff0c;MVC相比WebApi只是多了一个views的文件夹 &am…...

Chromium HTML5 新的 Input 类型date 对应c++

一、Input 类型: date date 类型允许你从一个日期选择器选择一个日期。 <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>test</title> </head> <body><form action"demo-form.php"…...

ZooKeeper的应用场景:深入探讨分布式系统中的多样化应用

Apache ZooKeeper 是一个开源的分布式协调服务&#xff0c;专为确保分布式系统中的高可用性和一致性而设计。在现代分布式应用程序中&#xff0c;协调、同步和管理是实现高效和可靠服务的关键部分&#xff0c;而 ZooKeeper 通过提供这些基础功能而成为许多分布式系统不可或缺的…...

【Vue3】第四篇

Vue3学习第四篇 01. 插槽Slots02. 插槽Slots&#xff08;续集&#xff09;03. 插槽Slots&#xff08;再续集&#xff09;04. 组件生命周期05. 生命周期应用06. 动态组件07. 组件保持存活08. 异步组件09. 依赖注入10. Vue应用 01. 插槽Slots 模板内容&#xff1a;html结构&#…...

Chromium HTML5 新的 Input 类型tel对应c++

一、Input 类型: tel <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>test</title> </head> <body><form action"demo-form.php">电话号码: <input type"tel" name…...

JVM—类加载器、双亲委派机制

目录 什么是类加载器 类加载器的分类 Bootstrap启动类加载器 通过启动类加载器加载用户jar包 Extension扩展类加载器和Application应用程序类加载器 通过扩展类加载器加载用户jar包 双亲委派机制 打破双亲委派机制 自定义类加载器 线程上下文类加载器 Osgi框架的类加…...

笔试题 求空格分割的英文句子中,最大单词长度。

求空格分割的英文句子中&#xff0c;最大单词长度。例如:“this is a word”&#xff0c;最大单词长度为4。要求:不能用 split 函数对字符串进行切分&#xff0c;算法复杂度为o(n) public class MaxWordLength { public static int maxWordLength(String sentence) { if (se…...

【笔记】大模型长度外推技术 NTK-Aware Scaled RoPE

NTK-Aware Scaled RoPE 正弦编码(Sinusoidal)旋转位置编码RoPE编码步骤&#xff1a;旋转位置编码的优势 NTK-Aware Scaled RoPE直接外推线性内插进制转换高频外推、低频内插的理解位置编码 总结参考&#xff1a; 长度外推技术是自然语言处理&#xff08;NLP&#xff09;领域中&…...

前端 eslint 配置,以及在git提交之前自动format

目录 1、配置eslint步骤 1、eslint安装配置步骤 2、配置scripts步骤 3、测试eslint 2、配置git-hook1、安装环境2、最终效果 众所周知&#xff0c;前端项目可以在报很多error的情况下运行。但是良好的代码规范仍然有利于项目的开发维护&#xff0c;这里提供我的规范&#xff0c…...

2024.10.9华为留学生笔试题解

第一题无线基站名字相似度 动态规划 考虑用动态规划解决 char1=input().strip() char2=input().strip() n,m=len(char1),len(char2) dp=[[0]*(m+1) for _ in range(n+1)] #dp[i][j]定义为以i-1为结尾的char1 和以 j-1为结尾的char2 的最短编辑距离 setA = set(wirel@com) set…...

利用ADPF性能提示优化Android应用体验

Android Dynamic Performance Framework(ADPF)是google推广的一套用于优化散热以及CPU性能的动态性能框架。本文主要介绍其中的performance hint的部分。 1、为何引入ADPF 我们都知道&#xff0c;在大多数设备上&#xff0c;Android 会动态调整CPU的频率和核心类型。如果work l…...

论文阅读 - Pre-trained Online Contrastive Learning for Insurance Fraud Detection

Pre-trained Online Contrastive Learning for Insurance Fraud Detection| Proceedings of the AAAI Conference on Artificial Intelligence 目录 摘要 Introduction Methodology Problem Formulation Pre-trained Model for Enhanced Robustness Detecting Network a…...

【最全基础知识2】机器视觉系统硬件组成之工业相机镜头篇--51camera

机器视觉系统中,工业镜头作为必备的器件之一,须和工业相机搭配。工业镜头是机器视觉系统中不可或缺的重要组成部分,其质量和性能直接影响到整个系统的成像质量和检测精度。 目录 一、基本功能和作用 二、分类 1、按成像方式分 2、按焦距分 3、按接口类型分 4、按应用…...

虚拟机WIN7安装PADS VX24 出现脚本故障 IPW213

用虚拟机安装WIN7&#xff0c;再开始安装PADS V24出现脚本故障IPW213 有去.NetFramework3.5 仍然没有效果 Download Microsoft .NET Framework 3.5 from Official Microsoft Download Center 最终用360驱动大师检测了下 发现有些必备组件没有安装&#xff0c;安装之后重启。 …...

Java正则表达式详解万字笔记内容丰富

正则表达式 1.1 正则表达式的概念及演示 在Java中&#xff0c;我们经常需要验证一些字符串&#xff0c;例如&#xff1a;年龄必须是2位的数字、用户名必须是8位长度而且只能包含大小写字母、数字等。正则表达式就是用来验证各种字符串的规则。它内部描述了一些规则&#xff0c…...

文件属性与目录

⚫ Linux 系统的文件类型&#xff1b; 普通文件&#xff1a;存储数据&#xff0c;如文本文件、可执行文件等。 目录&#xff1a;用于组织文件和其他目录的特殊文件。 符号链接&#xff1a;指向另一个文件或目录的引用&#xff0c;类似于 Windows 中的快捷方式。 硬链接&#x…...

5G 基站SCTP

如何实现SCTP多归属链路对接 文章目录 ​​前言​​​​一、SCTP是什么&#xff1f;​​​​二、lksctp​​​​三.sctp初始化​​​​四.绑定本端两个IP​​​​ 五.与对端建链​​​​六.设置主要路径​​​​七.设置是否启用心跳​​​​八.关于防火墙的配置​ ​总结​​ …...

MFC的SendMessage与PostMessage的区别

一、SendMessage 同步操作&#xff1a; SendMessage 是一个同步函数&#xff0c;它会将消息发送到指定的窗口&#xff0c;并等待该窗口的消息处理过程完成&#xff0c;然后返回。这意味着它会阻塞当前线程&#xff0c;直到消息处理完成。 直接调用&#xff1a; SendMessage 会…...

学习虚幻C++开发日志——基础案例(持续更新中)

官方文档&#xff1a;虚幻引擎C编程教程 | 虚幻引擎 5.5 文档 | Epic Developer Community | Epic Developer Community 1.物体上下起伏并旋转 1.1第一种写法 创建一个继承于Actor的类&#xff0c;并为新的Actor命名为FloatingActor&#xff0c;然后点击Create Class 重新…...

【CUDA代码实践03】m维网格n维线程块对二维矩阵的索引

文章目录 一、数据存储方式二、二维网格二维线程块三、二维网格一维线程块四、一维网格一维线程块 为了方便下次找到文章&#xff0c;也方便联系我给大家提供帮助&#xff0c;欢迎大家点赞&#x1f44d;、收藏&#x1f4c2;和关注&#x1f514;&#xff01;一起讨论技术问题&am…...

VSCode Qt6安装OpenSSL

报错 Could NOT find OpenSSL, try to set the path to OpenSSL root folder in thesystem variable OPENSSL_ROOT_DIR (missing: OPENSSL_CRYPTO_LIBRARYOPENSSL_INCLUDE_DIR SSL Crypto) (Required is at least version "3.0")问题确认 这个错误显示在Windows环境…...

JAVA学习-练习试用Java实现“定义一个用户类,包含用户名和密码”

问题&#xff1a; 定义一个用户类&#xff08;User&#xff09;&#xff0c;包含用户名&#xff08;username&#xff09;和密码&#xff08;password&#xff09;属性&#xff0c;提供静态方法验证密码是否有效&#xff08;长度至少为6&#xff09;&#xff0c;并提供getter和…...

大数据之VIP(Virtual IP,虚拟IP)负载均衡

VIP&#xff08;Virtual IP&#xff0c;虚拟IP&#xff09;负载均衡是一种在计算机网络中常用的技术&#xff0c;用于将网络请求流量均匀地分散到多个服务器上&#xff0c;以提高系统的可扩展性、可靠性和性能。以下是对VIP负载均衡的详细解释&#xff1a; 一、VIP负载均衡的基…...

鸿蒙网络编程系列38-Web组件文件下载示例

1. web组件文件下载能力简介 在本系列的第22篇文章&#xff0c;介绍了web组件的文件上传能力&#xff0c;同样的&#xff0c;web组件也具备文件下载能力&#xff0c;鸿蒙API提供了处理web组件下载事件的委托类型WebDownloadDelegate&#xff0c;该类型包括四个下载事件的回调接…...

Cisco Packet Tracer 8.0 路由器的基本配置和Telnet设置

文章目录 构建拓扑图配置IP地址配置路由器命令说明测试效果 构建拓扑图 1&#xff0c;添加2811路由器。 2&#xff0c;添加pc0。 3&#xff0c;使用交叉线连接路由器和pc&#xff08;注意线路端口&#xff09;。 4&#xff0c;使用配置线连接路由器和pc&#xff08;注意线路…...

企业网站手机端开发/seo搜索引擎工具

多态应用 ​ 应用实例 多态数组 数组的定义类型为父类类型&#xff0c;里面保存的实际元素类型为子类类型 现有一个继承结构如下&#xff1a;要求创建一个Person对象、2个student对象 和两个Teacher有一个teach&#xff0c;同一放在数组中&#xff0c;并调用say方法 publ…...

增城住房和建设局网站/上海抖音seo

为什么贴漆面透明保护膜(隐形车衣)&#xff1f;1&#xff0c;有效防护高速行驶中小石头弹伤车漆。2&#xff0c;防止钥匙等恶意划伤。3&#xff0c;有效防护意外轻微碰擦&#xff0c;不伤原漆。4&#xff0c;抗氧化阻隔紫外线、酸雨、动物粪便等侵蚀。5&#xff0c;增加车漆30%…...

wordpress中文注释/小红书关键词优化

最近开发的APP在使用时需要绑定host&#xff0c;以前只知道在PC端绑定&#xff0c;现在将手机端绑定host的方法记录一下。我今天使用的方法基本思路是PC端绑定host之后&#xff0c;将PC作为热点&#xff0c;手机连接这个热点。 一、PC绑定host&#xff1a;以windows电脑端为例…...

wordpress主题inn/百度网页高级搜索

Spring的定义对DI的初步理解对AOP的初步理解对DI的深入探究对AOP的深入探究Spring的事务管理Spring MVC 首先&#xff0c;我们来看这样一个场景&#xff1a;有一个骑士&#xff0c;他要去完成寻找圣杯的任务。情景很简单&#xff0c;我们以往的做法是这样的&#xff1a;声明一个…...

手机网站建设哪家便宜/百度小说搜索风云榜排行榜

概述 byval是将实参所占的内存空间复制一份出来&#xff1b;byref是给实参另起一个别名&#xff0c;就好像是一个人两个名字。这两个的区别针对于一般的数据类型&#xff0c;大家都非常的清楚&#xff0c;但是&#xff0c;当用遇到对象类型的变量的时候&#xff0c;要小心了&am…...

汕头 网站/品牌宣传

在我们平时工作中经常会遇到要操作Excel的功能&#xff0c;比如导出个用户信息或者订单信息的Excel报表。你肯定听说过POI这个东西&#xff0c;可以实现。但是POI实现的API确实很麻烦&#xff0c;它需要写那种逐行解析的代码&#xff08;类似Xml解析&#xff09;。今天给大家推…...