乐尚代驾-----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 们!!!我又来跟辛辣!感谢你们的观看,话不多说!~ 司机到达代驾终点,代驾结束了。结束代驾之后, – 获取额外费用(高速费、停车费等) – 计算订单实际里程…...
105. 聚光源SpotLight
入门部分给大家介绍过平行光DirectionalLight、点光源PointLight、环境光AmbientLight,下面给大家介绍一个新的光源对象,也就是聚光源SpotLight。 创建聚光源SpotLight 聚光源可以认为是一个沿着特定方会逐渐发散的光源,照射范围在三维空间中构成一个圆…...
系统接口权限拦截器,获取用户信息存储
UserInfo 类 这是一个表示用户信息的 Java 类,使用了 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字段主要用于选取颜色,如下所示: <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>菜鸟教程(runoob.com)</title> </head> <body&…...
问:SQL中的通用函数及用法?
SQL函数是在SQL语句中使用的预定义的计算工具,可以对一列数据进行操作并返回一个单一的结果。这些函数大致可以分为两类:Aggregate函数和Scalar函数。Aggregate函数对一组值执行计算,并返回单个值,如求和、平均值、最大值和最小值…...
.NET Core WebApi第6讲:WebApi的前端怎么派人去拿数据?(区别MVC)
一、前端界面小基础 head:引入CSS, 引入JS是写在head里面。 body:眼睛肉眼能看到的用户展示的界面是写在body里面。 二、前端怎么派人去拿数据? 1、MVC:前后端不分离,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 是一个开源的分布式协调服务,专为确保分布式系统中的高可用性和一致性而设计。在现代分布式应用程序中,协调、同步和管理是实现高效和可靠服务的关键部分,而 ZooKeeper 通过提供这些基础功能而成为许多分布式系统不可或缺的…...
【Vue3】第四篇
Vue3学习第四篇 01. 插槽Slots02. 插槽Slots(续集)03. 插槽Slots(再续集)04. 组件生命周期05. 生命周期应用06. 动态组件07. 组件保持存活08. 异步组件09. 依赖注入10. Vue应用 01. 插槽Slots 模板内容: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框架的类加…...
笔试题 求空格分割的英文句子中,最大单词长度。
求空格分割的英文句子中,最大单词长度。例如:“this is a word”,最大单词长度为4。要求:不能用 split 函数对字符串进行切分,算法复杂度为o(n) public class MaxWordLength { public static int maxWordLength(String sentence) { if (se…...
【笔记】大模型长度外推技术 NTK-Aware Scaled RoPE
NTK-Aware Scaled RoPE 正弦编码(Sinusoidal)旋转位置编码RoPE编码步骤:旋转位置编码的优势 NTK-Aware Scaled RoPE直接外推线性内插进制转换高频外推、低频内插的理解位置编码 总结参考: 长度外推技术是自然语言处理(NLP)领域中&…...
前端 eslint 配置,以及在git提交之前自动format
目录 1、配置eslint步骤 1、eslint安装配置步骤 2、配置scripts步骤 3、测试eslint 2、配置git-hook1、安装环境2、最终效果 众所周知,前端项目可以在报很多error的情况下运行。但是良好的代码规范仍然有利于项目的开发维护,这里提供我的规范,…...
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 我们都知道,在大多数设备上,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,再开始安装PADS V24出现脚本故障IPW213 有去.NetFramework3.5 仍然没有效果 Download Microsoft .NET Framework 3.5 from Official Microsoft Download Center 最终用360驱动大师检测了下 发现有些必备组件没有安装,安装之后重启。 …...
Java正则表达式详解万字笔记内容丰富
正则表达式 1.1 正则表达式的概念及演示 在Java中,我们经常需要验证一些字符串,例如:年龄必须是2位的数字、用户名必须是8位长度而且只能包含大小写字母、数字等。正则表达式就是用来验证各种字符串的规则。它内部描述了一些规则,…...
文件属性与目录
⚫ Linux 系统的文件类型; 普通文件:存储数据,如文本文件、可执行文件等。 目录:用于组织文件和其他目录的特殊文件。 符号链接:指向另一个文件或目录的引用,类似于 Windows 中的快捷方式。 硬链接&#x…...
5G 基站SCTP
如何实现SCTP多归属链路对接 文章目录 前言一、SCTP是什么?二、lksctp三.sctp初始化四.绑定本端两个IP 五.与对端建链六.设置主要路径七.设置是否启用心跳八.关于防火墙的配置 总结 …...
MFC的SendMessage与PostMessage的区别
一、SendMessage 同步操作: SendMessage 是一个同步函数,它会将消息发送到指定的窗口,并等待该窗口的消息处理过程完成,然后返回。这意味着它会阻塞当前线程,直到消息处理完成。 直接调用: SendMessage 会…...
学习虚幻C++开发日志——基础案例(持续更新中)
官方文档:虚幻引擎C编程教程 | 虚幻引擎 5.5 文档 | Epic Developer Community | Epic Developer Community 1.物体上下起伏并旋转 1.1第一种写法 创建一个继承于Actor的类,并为新的Actor命名为FloatingActor,然后点击Create Class 重新…...
【CUDA代码实践03】m维网格n维线程块对二维矩阵的索引
文章目录 一、数据存储方式二、二维网格二维线程块三、二维网格一维线程块四、一维网格一维线程块 为了方便下次找到文章,也方便联系我给大家提供帮助,欢迎大家点赞👍、收藏📂和关注🔔!一起讨论技术问题&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实现“定义一个用户类,包含用户名和密码”
问题: 定义一个用户类(User),包含用户名(username)和密码(password)属性,提供静态方法验证密码是否有效(长度至少为6),并提供getter和…...
大数据之VIP(Virtual IP,虚拟IP)负载均衡
VIP(Virtual IP,虚拟IP)负载均衡是一种在计算机网络中常用的技术,用于将网络请求流量均匀地分散到多个服务器上,以提高系统的可扩展性、可靠性和性能。以下是对VIP负载均衡的详细解释: 一、VIP负载均衡的基…...
鸿蒙网络编程系列38-Web组件文件下载示例
1. web组件文件下载能力简介 在本系列的第22篇文章,介绍了web组件的文件上传能力,同样的,web组件也具备文件下载能力,鸿蒙API提供了处理web组件下载事件的委托类型WebDownloadDelegate,该类型包括四个下载事件的回调接…...
Cisco Packet Tracer 8.0 路由器的基本配置和Telnet设置
文章目录 构建拓扑图配置IP地址配置路由器命令说明测试效果 构建拓扑图 1,添加2811路由器。 2,添加pc0。 3,使用交叉线连接路由器和pc(注意线路端口)。 4,使用配置线连接路由器和pc(注意线路…...
企业网站手机端开发/seo搜索引擎工具
多态应用 应用实例 多态数组 数组的定义类型为父类类型,里面保存的实际元素类型为子类类型 现有一个继承结构如下:要求创建一个Person对象、2个student对象 和两个Teacher有一个teach,同一放在数组中,并调用say方法 publ…...
增城住房和建设局网站/上海抖音seo
为什么贴漆面透明保护膜(隐形车衣)?1,有效防护高速行驶中小石头弹伤车漆。2,防止钥匙等恶意划伤。3,有效防护意外轻微碰擦,不伤原漆。4,抗氧化阻隔紫外线、酸雨、动物粪便等侵蚀。5,增加车漆30%…...
wordpress中文注释/小红书关键词优化
最近开发的APP在使用时需要绑定host,以前只知道在PC端绑定,现在将手机端绑定host的方法记录一下。我今天使用的方法基本思路是PC端绑定host之后,将PC作为热点,手机连接这个热点。 一、PC绑定host:以windows电脑端为例…...
wordpress主题inn/百度网页高级搜索
Spring的定义对DI的初步理解对AOP的初步理解对DI的深入探究对AOP的深入探究Spring的事务管理Spring MVC 首先,我们来看这样一个场景:有一个骑士,他要去完成寻找圣杯的任务。情景很简单,我们以往的做法是这样的:声明一个…...
手机网站建设哪家便宜/百度小说搜索风云榜排行榜
概述 byval是将实参所占的内存空间复制一份出来;byref是给实参另起一个别名,就好像是一个人两个名字。这两个的区别针对于一般的数据类型,大家都非常的清楚,但是,当用遇到对象类型的变量的时候,要小心了&am…...
汕头 网站/品牌宣传
在我们平时工作中经常会遇到要操作Excel的功能,比如导出个用户信息或者订单信息的Excel报表。你肯定听说过POI这个东西,可以实现。但是POI实现的API确实很麻烦,它需要写那种逐行解析的代码(类似Xml解析)。今天给大家推…...