乐尚代驾八订单执行三

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

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

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

– 计算代驾实际费用

– 系统奖励

– 分账信息

– 生成最终账单

计算订单实际里程

  • 在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);

结束代驾

  • 调用以上的所有接口最终实现

在她们脸上看见楼上两位女主人面貌的痕迹,知道了答案。

房思琪的初恋乐园
林奕含

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值