- 司机到达代驾终点,代驾结束了。
- 结束代驾之后,
– 获取额外费用(高速费、停车费等)
– 计算订单实际里程(实际与预估有偏差)
– 计算代驾实际费用
– 系统奖励
– 分账信息
– 生成最终账单
计算订单实际里程
- 在MongoDB保存代驾过程中司机位置信息,把MongoDB存储司机位置信息获取出来,以时间排序,连接成一条线,这条线是实际距离
准备计算距离工具类
地图微服务接口
@Operation(summary = "代驾服务:计算订单实际里程")
@GetMapping("/calculateOrderRealDistance/{orderId}")
public Result<BigDecimal> calculateOrderRealDistance(@PathVariable Long orderId) {
return Result.ok(locationService.calculateOrderRealDistance(orderId));
}
@Override
public 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.daijia
import 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)
then
rewardRuleResponse.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)
then
rewardRuleResponse.setRewardAmount(new BigDecimal("2.0"));
System.out.println("00:00:00-06:59:59 奖励:" + rewardRuleResponse.getRewardAmount() + "元");
end
public 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();
//封装RewardRuleResponseVo
RewardRuleResponseVo 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.daijia
import 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()
then
profitsharingRuleResponse.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)
then
BigDecimal 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)
then
BigDecimal 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)
then
BigDecimal 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)
then
BigDecimal 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 {
@Autowired
private 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());
//创建kieSession
KieSession 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 计算代驾实际费用
//远程调用,计算代驾费用
//封装FeeRuleRequestForm
FeeRuleRequestForm feeRuleRequestForm = new FeeRuleRequestForm();
feeRuleRequestForm.setDistance(realDistance);
feeRuleRequestForm.setStartTime(orderInfo.getStartServiceTime());
//计算司机到达代驾开始位置时间
//orderInfo.getArriveTime() - orderInfo.getAcceptTime()
// 分钟 = 毫秒 / 1000 * 60
Integer 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);
}
在她们脸上看见楼上两位女主人面貌的痕迹,知道了答案。
房思琪的初恋乐园
林奕含