From 12b75ea8869fa6e65b1bd53d4460328e73a66125 Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期三, 22 三月 2023 22:35:20 +0800
Subject: [PATCH] 新增加司机端接口

---
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/OrderServiceImpl.java | 1032 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 1,003 insertions(+), 29 deletions(-)

diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/OrderServiceImpl.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/OrderServiceImpl.java
index 04e0e9d..21016f6 100644
--- a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/OrderServiceImpl.java
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/OrderServiceImpl.java
@@ -6,30 +6,39 @@
 import com.baomidou.mybatisplus.mapper.EntityWrapper;
 import com.baomidou.mybatisplus.service.impl.ServiceImpl;
 import com.supersavedriving.driver.modular.system.dao.OrderMapper;
-import com.supersavedriving.driver.modular.system.model.Driver;
-import com.supersavedriving.driver.modular.system.model.DriverWork;
-import com.supersavedriving.driver.modular.system.model.Order;
-import com.supersavedriving.driver.modular.system.model.SystemConfig;
-import com.supersavedriving.driver.modular.system.service.IDriverService;
-import com.supersavedriving.driver.modular.system.service.IDriverWorkService;
-import com.supersavedriving.driver.modular.system.service.IOrderService;
-import com.supersavedriving.driver.modular.system.service.ISystemConfigService;
+import com.supersavedriving.driver.modular.system.model.*;
+import com.supersavedriving.driver.modular.system.service.*;
+import com.supersavedriving.driver.modular.system.util.*;
 import com.supersavedriving.driver.modular.system.util.GaoDe.MapUtil;
-import com.supersavedriving.driver.modular.system.util.ResultUtil;
-import com.supersavedriving.driver.modular.system.util.UUIDUtil;
+import com.supersavedriving.driver.modular.system.util.mongodb.model.Location;
+import com.supersavedriving.driver.modular.system.warpper.*;
+import com.supersavedriving.driver.core.util.ToolUtil;
+import com.supersavedriving.driver.modular.system.util.*;
+import com.supersavedriving.driver.modular.system.util.GaoDe.model.District;
+import com.supersavedriving.driver.modular.system.util.juhe.WeatherUtil;
+import com.supersavedriving.driver.modular.system.warpper.*;
+import com.supersavedriving.driver.modular.system.model.*;
+import com.supersavedriving.driver.modular.system.service.*;
+import com.supersavedriving.driver.modular.system.util.PushUtil;
 import com.supersavedriving.driver.modular.system.warpper.AddOrderWarpper;
-import com.supersavedriving.driver.modular.system.warpper.BaseWarpper;
+import com.supersavedriving.driver.modular.system.warpper.HallOrderList;
+import com.supersavedriving.driver.modular.system.warpper.OrderInfoWarpper;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.geo.Circle;
+import org.springframework.data.geo.Distance;
+import org.springframework.data.geo.Metrics;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
 import org.springframework.stereotype.Service;
 
-import javax.xml.crypto.Data;
 import java.math.BigDecimal;
 import java.math.MathContext;
 import java.math.RoundingMode;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Map;
+import java.util.*;
+import java.util.stream.Collectors;
 
 
 /**
@@ -49,6 +58,47 @@
     @Autowired
     private ISystemConfigService systemConfigService;
 
+    @Autowired
+    private PushUtil pushUtil;
+
+    @Autowired
+    private MongoTemplate mongoTemplate;
+
+    @Autowired
+    private IAppUserService appUserService;
+
+    @Autowired
+    private RedisUtil redisUtil;
+
+    @Autowired
+    private ISystemMessageService systemMessageService;
+
+    @Autowired
+    private IOrderRefusalService orderRefusalService;
+
+    @Autowired
+    private IYouTuiDriverService youTuiDriverService;
+
+    @Autowired
+    private IWeatherCityService weatherCityService;
+
+    @Autowired
+    private IOrderTransferService orderTransferService;
+
+    @Autowired
+    private ICancelOrderService cancelOrderService;
+
+    @Autowired
+    private IAccountChangeDetailService accountChangeDetailService;
+
+    @Autowired
+    private IRevenueService revenueService;
+
+    private Map<String, Timer> timerMap = new HashMap<>();
+
+
+
+
 
     /**
      * 获取服务中的订单id
@@ -66,21 +116,42 @@
     }
 
 
+    /**
+     * 司机代客下单
+     * @param uid
+     * @param addOrderWarpper
+     * @return
+     * @throws Exception
+     */
     @Override
     public ResultUtil driverAddOrder(Integer uid, AddOrderWarpper addOrderWarpper) throws Exception {
         /**
          * 司机上线且空闲,下单直接给当前司机,其余进大厅
          * 司机下的订单不需要创建新用户,且只能走线下支付
          */
+
+        int count = this.selectCount(new EntityWrapper<Order>().eq("userPhone", addOrderWarpper.getPhone()).eq("status", 1).in("state", Arrays.asList(101, 102, 103, 104, 105, 106, 201)));
+        if(count > 0){
+            return ResultUtil.error("该用户还有未完成的订单");
+        }
         Driver driver = driverService.selectById(uid);
         DriverWork driverWork = driverWorkService.selectOne(new EntityWrapper<DriverWork>().eq("driverId", uid).eq("status", 1));
         Order order1 = this.selectOne(new EntityWrapper<Order>().eq("driverId", uid).eq("status", 1).in("state", Arrays.asList(102, 103, 104, 105, 201)));
         Order order = new Order();
         if(driverWork != null && null == order1){
             order.setDriverId(uid);
+            driver.setServerStatus(2);
+            order.setOrderTakingTime(new Date());
         }
         order.setCode(UUIDUtil.getTimeStr() + UUIDUtil.getNumberRandom(3));
         order.setSource(2);
+
+        AppUser appUser = appUserService.selectOne(new EntityWrapper<AppUser>().eq("phone", addOrderWarpper.getPhone()).eq("status", 1));
+        if(null != appUser){
+            order.setUserId(appUser.getId());
+        }
+        order.setUserName(addOrderWarpper.getUserName());
+        order.setUserPhone(addOrderWarpper.getPhone());
         order.setAgentId(driver.getAgentId());
         order.setBranchOfficeId(driver.getBranchOfficeId());
         order.setStartAddress(addOrderWarpper.getStartAddress());
@@ -89,29 +160,48 @@
         order.setEndAddress(addOrderWarpper.getEndAddress());
         order.setEndLat(addOrderWarpper.getEndLat());
         order.setEndLng(addOrderWarpper.getEndLng());
-        Map<String, String> distance = MapUtil.getDistance(order.getStartLng() + "," + order.getStartLat(), order.getEndLng() + "," + order.getEndLat(), 1);
-        if(null == distance){
-            return ResultUtil.error("获取预估距离出错");
+        Double d = 0D;
+        if(ToolUtil.isNotEmpty(addOrderWarpper.getEndAddress())){
+            Map<String, String> distance = MapUtil.getDistance(order.getStartLng() + "," + order.getStartLat(), order.getEndLng() + "," + order.getEndLat(), 1);
+            if(null == distance){
+                return ResultUtil.error("获取预估距离出错");
+            }
+            d = Double.valueOf(distance.get("distance")) / 1000;
+            order.setEstimatedMileage(d);
         }
-        Double d = Double.valueOf(distance.get("distance")) / 1000;
-        order = getOrderPrice(1, d, 0, order);
+        String city = "";
+        District geocode = MapUtil.geocode(order.getStartLng(), order.getStartLat());
+        if(null != geocode){
+            WeatherCity weatherCity = weatherCityService.selectOne(new EntityWrapper<WeatherCity>().where(" '" + geocode.getDistrict() + "' like district"));
+            city = null != weatherCity ? weatherCity.getId().toString() : "";
+        }
+        order = getOrderPrice(1, d, 0, order, city);
         order.setState(null == order.getDriverId() ? 101 : 102);
         order.setStatus(1);
         order.setCreateTime(new Date());
         this.insert(order);
-        return null;
+        driverService.updateById(driver);
+        //推送状态
+        if(null != order.getDriverId()){
+            pushUtil.pushOrderStatus(uid, 2, order.getId(), order.getStatus());
+        }else{
+            //开始推单
+            pushOrder(order);
+        }
+        return ResultUtil.success();
     }
 
 
     /**
      * 获取订单价格
-     * @param type
-     * @param distance
-     * @param waitTime
-     * @param order
+     * @param type          计算类型(1=预估价,2=订单费)
+     * @param distance      行驶公里
+     * @param waitTime      等待时长
+     * @param order         订单数据
+     * @param city          查询天气的城市
      * @return
      */
-    public Order getOrderPrice(Integer type, Double distance, Integer waitTime, Order order){
+    public Order getOrderPrice(Integer type, Double distance, Integer waitTime, Order order, String city){
         order = getOrderInitialPrice(order);
         SystemConfig systemConfig = systemConfigService.selectOne(new EntityWrapper<SystemConfig>().eq("type", 5));
         if(null == systemConfig){
@@ -209,7 +299,8 @@
         }
 
         //恶劣天气
-        if(true){
+        boolean badWeather = WeatherUtil.isBadWeather(city);
+        if(badWeather){
             order.setBadWeatherDistance(num5);//恶劣天气公里
             order.setBadWeatherPrice(num6);//恶劣天气费
             if(distance.compareTo(num7) > 0){
@@ -231,9 +322,15 @@
             }
         }
 
+        //计算折扣
+        if(null != order.getUserId()){
+
+        }
+
         //计算总金额
         BigDecimal bigDecimal = new BigDecimal(order.getStartPrice() + order.getOverDrivePrice() + order.getLongDistancePrice() + order.getOverLongDistancePrice() +
-                order.getWaitTimePrice() + order.getOutWaitTimePrice() + order.getBadWeatherPrice() + order.getOverBadWeatherPrice()).setScale(2, BigDecimal.ROUND_HALF_EVEN);
+                order.getWaitTimePrice() + order.getOutWaitTimePrice() + order.getBadWeatherPrice() + order.getOverBadWeatherPrice() - order.getDiscountAmount()).setScale(2, BigDecimal.ROUND_HALF_EVEN);
+
         if(type == 1){//预估价
             order.setEstimatedPrice(bigDecimal.doubleValue());
         }
@@ -268,7 +365,884 @@
         order.setOverBadWeatherPrice(0D);//恶劣天气超出里程费
         order.setDiscountedPrice(0D);//优惠金额
         order.setCouponId(null);//优惠券
+        order.setDiscountAmount(0D);//折扣优惠金额
+        order.setDiscount(0D);//折扣
         return order;
     }
 
+
+    /**
+     * 订单推送逻辑
+     * @param order
+     */
+    public void pushOrder(Order order){
+        /**
+         * 1.先找最大推单范围内的优推司机 -》 距离最近
+         * 没有1 - 》
+         *      2.按照后台推送配置在范围内查找合适司机
+         *        合适司:积分 > 评分 > 距离
+         *      3.司机没有接单直接将订单置入大厅
+         */
+        SystemConfig systemConfig = systemConfigService.selectOne(new EntityWrapper<SystemConfig>().eq("type", 1));
+        if(null == systemConfig){
+            return;
+        }
+        JSONObject jsonObject = JSON.parseObject(systemConfig.getContent());
+        Double num3 = jsonObject.getDouble("num3");//推单最大范围
+        Integer num4 = jsonObject.getInteger("num4");//接单时间
+        String startLat = order.getStartLat();
+        String startLng = order.getStartLng();
+
+        //1
+        //找到中心点
+        GeoJsonPoint geoJsonPoint = new GeoJsonPoint(Double.valueOf(startLng), Double.valueOf(startLat));
+        Double num = num3 / 1000;//范围公里
+        //构造半径
+        Distance distanceR = new Distance(num, Metrics.KILOMETERS);
+        //画圆
+        Circle circle = new Circle(geoJsonPoint, distanceR);
+        // 构造query对象
+        Query query = Query.query(Criteria.where("location").withinSphere(circle));
+        List<Location> locations = mongoTemplate.find(query, Location.class);
+        List<Integer> driverIds = locations.stream().map(Location::getDriverId).collect(Collectors.toList());
+        Integer driver = null;
+        YouTuiDriver youTuiDriver1 = null;
+        if(driverIds.size() > 0){
+            List<YouTuiDriver> youTuiDrivers = youTuiDriverService.selectList(new EntityWrapper<YouTuiDriver>().in("driverId", driverIds)
+                    .eq("state", 2).last(" and (surplusQuantity > 0 or now() < endTime) and now() < failureTime"));
+            Double d = null;
+            for (YouTuiDriver youTuiDriver : youTuiDrivers) {
+                String value = redisUtil.getValue("DRIVER" + youTuiDriver.getDriverId());
+                if(ToolUtil.isEmpty(value)){
+                    continue;
+                }
+                Map<String, Double> distance = GeodesyUtil.getDistance(value, order.getStartLng() + "," + order.getStartLat());
+                Double wgs84 = distance.get("WGS84");
+                if(d == null || d.compareTo(wgs84) > 0){
+                    d = wgs84;
+                    driver = youTuiDriver.getDriverId();
+                    youTuiDriver1 = youTuiDriver;
+                }
+            }
+        }
+
+        if(null != youTuiDriver1 && youTuiDriver1.getType() == 1){
+            youTuiDriver1.setSurplusQuantity(youTuiDriver1.getSurplusQuantity() - 1);
+            youTuiDriverService.updateById(youTuiDriver1);
+        }
+
+        //开始范围查找
+        if(null == driver){
+            for (int i = 1; i < 4; i++) {
+                num = jsonObject.getDouble("num" + i) / 1000;//范围公里
+                //构造半径
+                distanceR = new Distance(num, Metrics.KILOMETERS);
+                //画圆
+                circle = new Circle(geoJsonPoint, distanceR);
+                // 构造query对象
+                query = Query.query(Criteria.where("location").withinSphere(circle));
+                locations = mongoTemplate.find(query, Location.class);
+
+                driverIds = locations.stream().map(Location::getDriverId).collect(Collectors.toList());
+                if(driverIds.size() > 0){
+                    List<Driver> drivers = driverService.selectList(new EntityWrapper<Driver>().eq("approvalStatus", 2).eq("serverStatus", 1).eq("status", 1).in("id", driverIds));
+                    if(drivers.size() == 0){
+                        continue;
+                    }
+
+                    Integer integral = null;
+                    Double score = null;
+                    Double d = null;
+                    for (Driver driver1 : drivers) {
+                        if(integral == null || integral.compareTo(driver1.getIntegral()) < 0){//积分大
+                            integral = driver1.getIntegral();
+                            score = driver1.getScore();
+                            driver = driver1.getId();
+                            continue;
+                        }
+                        if(integral.compareTo(driver1.getIntegral()) == 0 && score.compareTo(driver1.getScore()) < 0){//积分相同对比评分
+                            integral = driver1.getIntegral();
+                            score = driver1.getScore();
+                            driver = driver1.getId();
+                            continue;
+                        }
+                        if(integral.compareTo(driver1.getIntegral()) == 0 && score.compareTo(driver1.getScore()) == 0){//积分相同/评分相同对比距离
+                            String value = redisUtil.getValue("DRIVER" + driver1.getId());
+                            if(ToolUtil.isEmpty(value)){
+                                continue;
+                            }
+                            Map<String, Double> distance = GeodesyUtil.getDistance(value, order.getStartLng() + "," + order.getStartLat());
+                            Double wgs84 = distance.get("WGS84");
+                            if(d == null || d.compareTo(wgs84) > 0){
+                                d = wgs84;
+                                driver = driver1.getId();
+                                continue;
+                            }
+                        }
+                    }
+
+                }
+            }
+        }
+
+        if(null != driver){
+            pushUtil.pushGrabOrder(driver, 2, order.getId(), num4);
+            //创建定时任务处理订单到大厅
+            new Timer().schedule(new TimerTask() {
+                @Override
+                public void run() {
+                    Order order1 = OrderServiceImpl.this.selectById(order.getId());
+                    if(order1.getState() == 101 || order1.getState() == 201){
+                        order1.setHallOrder(1);
+                        OrderServiceImpl.this.updateById(order1);
+                    }
+                }
+            }, num4 * 1000);
+        }else{
+            order.setHallOrder(1);
+            this.updateById(order);
+        }
+    }
+
+
+
+    /**
+     * 获取大厅订单列表
+     * @param uid
+     * @param pageNum
+     * @param pageSize
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public List<HallOrderList> queryOrderHall(Integer uid, Integer pageNum, Integer pageSize) throws Exception {
+        pageNum = (pageNum - 1) * pageSize;
+        List<HallOrderList> hallOrderLists = this.baseMapper.queryOrderHall(pageNum, pageSize);
+        hallOrderLists.forEach(hallOrderList -> {
+            hallOrderList.setCurrentDistance(0D);
+            if(ToolUtil.isNotEmpty(hallOrderList.getEndLng())){
+                Map<String, Double> distance = GeodesyUtil.getDistance(hallOrderList.getStartLng() + "," + hallOrderList.getStartLat(), hallOrderList.getEndLng() + "," + hallOrderList.getEndLat());
+                Double wgs84 = distance.get("WGS84");
+                hallOrderList.setCurrentDistance(wgs84);
+            }
+        });
+        return hallOrderLists;
+    }
+
+
+    /**
+     * 司机拒单
+     * @param uid
+     * @param orderId
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public ResultUtil rejectionOrder(Integer uid, Long orderId) throws Exception {
+        Order order = this.selectById(orderId);
+        DriverWork driverWork = driverWorkService.selectOne(new EntityWrapper<DriverWork>().eq("driverId", uid).eq("status", 1));
+        if(null == driverWork){
+            return ResultUtil.error("请先上班");
+        }
+        OrderRefusal orderRefusal = new OrderRefusal();
+        orderRefusal.setCode(order.getCode());
+        orderRefusal.setCreateTime(new Date());
+        orderRefusal.setDriverId(uid);
+        orderRefusal.setEndAddress(order.getEndAddress());
+        orderRefusal.setStartAddress(order.getStartAddress());
+        orderRefusal.setOrderId(orderId);
+        orderRefusalService.insert(orderRefusal);
+
+        Driver driver = driverService.selectById(order.getDriverId());
+        //扣除积分
+        SystemConfig systemConfig = systemConfigService.selectOne(new EntityWrapper<SystemConfig>().eq("type", 4));
+        if(null != systemConfig) {
+            //{"num1":"10:00","num2":"14:00","num3":10,"num4":10,"num5":10,"num6":10,"num7":10,"num8":10,"num9":5,"num10":5}
+            //拒绝订单扣除积分
+            Integer num10 = JSON.parseObject(systemConfig.getContent()).getInteger("num10");
+            if (num10 > 0) {
+                AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
+                accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
+                accountChangeDetail.setUserType(2);
+                accountChangeDetail.setUserId(order.getDriverId());
+                accountChangeDetail.setType(2);
+                accountChangeDetail.setOldData(driver.getIntegral().doubleValue());
+                driver.setIntegral(driver.getIntegral() - num10);
+                accountChangeDetail.setNewData(driver.getIntegral().doubleValue());
+                accountChangeDetail.setExplain("拒绝订单扣除积分");
+                accountChangeDetailService.saveData(accountChangeDetail);
+                driverService.updateById(driver);
+            }
+        }
+        return ResultUtil.success();
+    }
+
+    /**
+     * 司机接单操作
+     * @param uid
+     * @param orderId
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public ResultUtil receiveOrder(Integer uid, Long orderId) throws Exception {
+        try {
+            Driver driver = driverService.selectById(uid);
+            DriverWork driverWork = driverWorkService.selectOne(new EntityWrapper<DriverWork>().eq("driverId", uid).eq("status", 1));
+            if(null == driverWork){
+                return ResultUtil.error("请先上班");
+            }
+            boolean lock = redisUtil.lock();
+            if(!lock){
+                return ResultUtil.error("请重试");
+            }
+            Order order = this.selectById(orderId);
+            Integer state = order.getState();
+            Integer oldDriverId = order.getDriverId();
+            if(state == 301){
+                redisUtil.unlock();
+                return ResultUtil.error("订单已被取消");
+            }
+            if(state != 101){
+                redisUtil.unlock();
+                return ResultUtil.error("手速慢了哦");
+            }
+            order.setDriverId(uid);
+            order.setAgentId(driver.getAgentId());
+            order.setBranchOfficeId(driver.getBranchOfficeId());
+            order.setState(102);
+            order.setOrderTakingTime(new Date());
+            this.updateById(order);
+            redisUtil.unlock();
+
+            if(null != order.getUserId()){
+                AppUser appUser = appUserService.selectById(order.getUserId());
+                appUser.setCancelCount(0);
+                appUserService.updateById(appUser);
+            }
+
+            driver.setServerStatus(2);
+            driverService.updateById(driver);
+            if(state == 201){//转单的订单
+                //停止定时任务
+                Timer timer = timerMap.get(order.getId().toString());
+                if(null != timer){
+                    timer.cancel();
+                    timerMap.remove(order.getId().toString());
+                }
+                //原司机下班
+                Driver oldDriver = driverService.selectById(oldDriverId);
+                oldDriver.setServerStatus(1);
+                driverService.updateById(oldDriver);
+
+                DriverWork driverWork1 = driverWorkService.selectOne(new EntityWrapper<DriverWork>().eq("driverId", oldDriverId).eq("status", 1));
+                driverWork1.setStatus(2);
+                driverWork1.setOffWorkTime(new Date());
+                driverWorkService.updateById(driverWork1);
+
+                //添加关系数据
+                OrderTransfer orderTransfer = orderTransferService.selectOne(new EntityWrapper<OrderTransfer>().eq("orderId", order.getId()).eq("status", 1).isNull("successTime"));
+                if(null != orderTransfer){
+                    orderTransfer.setNewDriverId(uid);
+                    orderTransfer.setSuccessTime(new Date());
+                    orderTransferService.updateById(orderTransfer);
+                }else{
+                    orderTransfer = new OrderTransfer();
+                    orderTransfer.setOrderId(order.getId());
+                    orderTransfer.setOldDriverId(oldDriverId);
+                    orderTransfer.setCreateTime(new Date());
+                    orderTransfer.setStatus(1);
+                    orderTransfer.setNewDriverId(uid);
+                    orderTransfer.setSuccessTime(new Date());
+                    orderTransferService.insert(orderTransfer);
+                }
+
+                pushUtil.pushTransferSuccessful(order.getUserId(), 1, order.getId());
+                pushUtil.pushTransferSuccessful(oldDriverId, 2, order.getId());
+            }
+
+            //推动订单数据
+            //发送系统消息
+            systemMessageService.addSystemMessage(uid, 2, "接单成功", "您已成功接到用户订单,请尽快联系客户!");
+            pushUtil.pushOrderStatus(order.getDriverId(), 2, order.getId(), order.getState());
+            if(null != order.getUserId()){
+                systemMessageService.addSystemMessage(order.getUserId(), 1, "接单成功", driver.getName() + "师傅已成功接到您的订单,请保持电话畅通!");
+                pushUtil.pushOrderStatus(order.getUserId(), 1, order.getId(), order.getState());
+            }
+        }catch (Exception e){
+            redisUtil.unlock();
+            e.printStackTrace();
+            throw e;
+        }
+        return ResultUtil.success();
+    }
+
+
+    /**
+     * 获取订单详情
+     * @param orderId
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public OrderInfoWarpper queryOrderInfo(Integer uid, Long orderId) throws Exception {
+        OrderInfoWarpper orderInfoWarpper = this.baseMapper.queryOrderInfo(orderId);
+        AppUser appUser = appUserService.selectById(uid);
+        orderInfoWarpper.setBalance(appUser.getAccountBalance());
+        orderInfoWarpper.setCurrentDistance(0D);
+        String value = redisUtil.getValue("DRIVER" + uid);
+        orderInfoWarpper.setPickUpTime(0);
+        if(ToolUtil.isNotEmpty(value)){
+            Map<String, Double> distance = GeodesyUtil.getDistance(orderInfoWarpper.getStartLng() + "," + orderInfoWarpper.getStartLat(), value);
+            Double wgs84 = distance.get("WGS84");
+            orderInfoWarpper.setCurrentDistance(null == wgs84 ? 0d : wgs84);
+            Map<String, String> distance1 = MapUtil.getDistance(orderInfoWarpper.getStartLng() + "," + orderInfoWarpper.getStartLat(), value, 0);
+            orderInfoWarpper.setPickUpTime(Integer.valueOf(distance1.get("duration")) / 60);
+        }
+        return orderInfoWarpper;
+    }
+
+
+    /**
+     * 司机走订单流程
+     * @param uid
+     * @param processOperationsWarpper
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public ResultUtil driverProcessOperations(Integer uid, ProcessOperationsWarpper processOperationsWarpper) throws Exception {
+        //101=待接单,102=已接单,103=前往预约点,104=到达预约点,105=开始服务,106=到达目的地,107=待支付,108=待评价,109=已完成,201=转单中,301=已取消,401=等待中
+        Order order = this.selectById(processOperationsWarpper.getOrderId());
+        if(order.getState() == processOperationsWarpper.getState()){
+            return ResultUtil.error("不能重复操作");
+        }
+        if(order.getState() == 201){
+            return ResultUtil.error("订单正在转单中");
+        }
+        order.setState(processOperationsWarpper.getState());
+        switch (processOperationsWarpper.getState()){
+            case 103:
+                order.setGoToAppointmentPointTime(new Date());
+                pushOrderInfo(order.getId(), uid);//开始推送订单数据
+                break;
+            case 104:
+                order.setStartWaitTime(new Date());
+                order.setArrivalTimeAtTheAppointmentPoint(new Date());
+                break;
+            case 105:
+                if(null == order.getStartTime()){
+                    redisUtil.addSetValue("serverOrder", order.getId().toString());//存入缓存用于计算实时距离
+                    order.setBoardingTime(new Date());
+                    order.setStartTime(new Date());
+                }
+                order.setStartWaitTime(null);
+                //计算等待用户时长
+                Integer w = Double.valueOf((System.currentTimeMillis() - order.getStartWaitTime().getTime()) / 60000).intValue();
+                order.setWaitTime(order.getWaitTime() + w);
+                break;
+            case 106:
+                order.setGetoffTime(new Date());
+                if(ToolUtil.isEmpty(order.getEndAddress())){
+                    order.setEndAddress(processOperationsWarpper.getEndAddress());
+                    order.setEndLng(processOperationsWarpper.getEndLng());
+                    order.setEndLat(processOperationsWarpper.getEndLat());
+                }
+                //停止定时任务
+                Timer timer = timerMap.get(order.getId().toString());
+                if(null != timer){
+                    timer.cancel();
+                    timerMap.remove(order.getId().toString());
+                }
+                //开始计算费用
+                String city = "";
+                District geocode = MapUtil.geocode(order.getEndLng(), order.getEndLat());
+                if(null != geocode){
+                    WeatherCity weatherCity = weatherCityService.selectOne(new EntityWrapper<WeatherCity>().where(" '" + geocode.getDistrict() + "' like district"));
+                    city = null != weatherCity ? weatherCity.getId().toString() : "";
+                }
+                order = getOrderPrice(2, Double.valueOf(order.getActualMileage() / 1000), order.getWaitTime(), order, city);
+
+                //修改司机状态和积分
+                Driver driver = driverService.selectById(order.getDriverId());
+                driver.setServerStatus(1);
+                driverService.updateById(driver);
+                saveIntegral(order);
+                break;
+            case 401:
+                order.setStartWaitTime(new Date());
+                break;
+        }
+        this.updateAllColumnById(order);
+
+        //推送订单状态
+        pushUtil.pushOrderStatus(order.getDriverId(), 2, order.getId(), order.getState());
+        if(null != order.getUserId()){
+            pushUtil.pushOrderStatus(order.getUserId(), 1, order.getId(), order.getState());
+        }
+        return ResultUtil.success();
+    }
+
+
+    /**
+     * 添加订单积分奖励
+     * @param order
+     * @throws Exception
+     */
+    public void saveIntegral(Order order) throws Exception{
+        Driver driver = driverService.selectById(order.getDriverId());
+        SystemConfig systemConfig = systemConfigService.selectOne(new EntityWrapper<SystemConfig>().eq("type", 4));
+        if(null != systemConfig){
+            //{"num1":"10:00","num2":"14:00","num3":10,"num4":10,"num5":10,"num6":10,"num7":10,"num8":10,"num9":5,"num10":5}
+            //完成订单奖励
+            Integer num5 = JSON.parseObject(systemConfig.getContent()).getInteger("num5");
+            if(num5 > 0){
+                AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
+                accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
+                accountChangeDetail.setUserType(2);
+                accountChangeDetail.setUserId(order.getDriverId());
+                accountChangeDetail.setType(2);
+                accountChangeDetail.setOldData(driver.getIntegral().doubleValue());
+                driver.setIntegral(driver.getIntegral() + num5);
+                accountChangeDetail.setNewData(driver.getIntegral().doubleValue());
+                accountChangeDetail.setExplain("完成订单奖励");
+                accountChangeDetailService.saveData(accountChangeDetail);
+            }
+            //恶劣天气完成订单奖励
+            Integer num8 = JSON.parseObject(systemConfig.getContent()).getInteger("num8");
+            if(num8 > 0){
+                AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
+                accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
+                accountChangeDetail.setUserType(2);
+                accountChangeDetail.setUserId(order.getDriverId());
+                accountChangeDetail.setType(2);
+                accountChangeDetail.setOldData(driver.getIntegral().doubleValue());
+                driver.setIntegral(driver.getIntegral() + num8);
+                accountChangeDetail.setNewData(driver.getIntegral().doubleValue());
+                accountChangeDetail.setExplain("恶劣天气完成订单奖励");
+                accountChangeDetailService.saveData(accountChangeDetail);
+            }
+            driverService.updateById(driver);
+
+            if(null == order.getUserId()){
+                return;
+            }
+            //推荐用户首单完成奖励
+            Integer num4 = JSON.parseObject(systemConfig.getContent()).getInteger("num4");
+            if(num4 > 0){
+                List<Integer> state = Arrays.asList(105);
+                int count = this.selectCount(new EntityWrapper<Order>().eq("userId", order.getUserId()).eq("status", 1).in("state", state));
+                if(count > 1){
+                    return;
+                }
+                AppUser appUser = appUserService.selectById(order.getUserId());
+                if(appUser.getInviterType() == 1){
+                    return;
+                }
+                Driver driver1 = driverService.selectById(appUser.getInviterId());
+                AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
+                accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
+                accountChangeDetail.setUserType(2);
+                accountChangeDetail.setUserId(driver1.getId());
+                accountChangeDetail.setType(2);
+                accountChangeDetail.setOldData(driver1.getIntegral().doubleValue());
+                driver1.setIntegral(driver1.getIntegral() + num4);
+                accountChangeDetail.setNewData(driver1.getIntegral().doubleValue());
+                accountChangeDetail.setExplain("推荐用户完成首单奖励");
+                accountChangeDetailService.saveData(accountChangeDetail);
+                driverService.updateById(driver1);
+            }
+
+        }
+    }
+
+
+
+    /**
+     * 定时任务推送订单数据
+     * @param orderId
+     * @param uid
+     */
+    public void pushOrderInfo(Long orderId, Integer uid){
+        Timer timer = new Timer();
+        timer.schedule(new TimerTask() {
+            @Override
+            public void run() {
+                String value = redisUtil.getValue("DRIVER" + uid);
+                Order order = OrderServiceImpl.this.selectById(orderId);
+                if(order.getState() == 106){
+                    Timer timer = timerMap.get(order.getId().toString());
+                    if(null != timer){
+                        timer.cancel();
+                        timerMap.remove(order.getId().toString());
+                    }
+                }
+
+                PushOrderInfoWarpper pushOrderInfoWarpper = new PushOrderInfoWarpper();
+                pushOrderInfoWarpper.setId(orderId);
+                if(ToolUtil.isNotEmpty(value)){
+                    String[] split = value.split(",");
+                    pushOrderInfoWarpper.setDriverLat(split[1]);
+                    pushOrderInfoWarpper.setDriverLng(split[0]);
+                }
+                pushOrderInfoWarpper.setWaitTime(order.getWaitTime());
+                pushOrderInfoWarpper.setState(order.getState());
+                pushOrderInfoWarpper.setActualMileage(Double.valueOf(order.getActualMileage() / 1000));
+                int travelTime = Double.valueOf((System.currentTimeMillis() - order.getStartTime().getTime()) / 60000).intValue();
+                pushOrderInfoWarpper.setTravelTime(travelTime);
+                pushUtil.pushOrderInfo(uid, 2, pushOrderInfoWarpper);
+            }
+        },0, 5000);
+        timerMap.put(orderId.toString(), timer);
+    }
+
+
+    /**
+     * 司机转单操作
+     * @param uid
+     * @param orderId
+     * @param cause
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public ResultUtil transferOrder(Integer uid, Long orderId, String cause) throws Exception {
+        Order order = this.selectById(orderId);
+        if(order.getDriverId().compareTo(uid) != 0){
+            return ResultUtil.error("无权操作");
+        }
+        if(order.getState() > 104){
+            return ResultUtil.error("订单不支持转单");
+        }
+        order.setOldState(order.getState());
+        order.setState(201);
+        this.updateById(order);
+
+        OrderTransfer orderTransfer = new OrderTransfer();
+        orderTransfer.setOrderId(orderId);
+        orderTransfer.setOldDriverId(order.getDriverId());
+        orderTransfer.setCause(cause);
+        orderTransfer.setStatus(1);
+        orderTransfer.setCreateTime(new Date());
+        orderTransferService.insert(orderTransfer);
+
+        //开始派单
+        pushOrder(order);
+        return ResultUtil.success();
+    }
+
+
+    /**
+     * 司机修改订单终点
+     * @param uid
+     * @param orderEndAddressWarpper
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public ResultUtil setOrderEndAddress(Integer uid, OrderEndAddressWarpper orderEndAddressWarpper) throws Exception {
+        Order order = this.selectById(orderEndAddressWarpper.getOrderId());
+        order.setEndLat(orderEndAddressWarpper.getEndLat());
+        order.setEndLng(orderEndAddressWarpper.getEndLng());
+        order.setEndAddress(orderEndAddressWarpper.getEndAddress());
+        Map<String, String> distance = MapUtil.getDistance(order.getStartLng() + "," + order.getStartLat(), order.getEndLng() + "," + order.getEndLat(), 1);
+        if(null == distance){
+            return ResultUtil.error("获取预估距离出错");
+        }
+        Double d = Double.valueOf(distance.get("distance")) / 1000;
+        order.setEstimatedMileage(d);
+        String city = "";
+        District geocode = MapUtil.geocode(order.getStartLng(), order.getStartLat());
+        if(null != geocode){
+            WeatherCity weatherCity = weatherCityService.selectOne(new EntityWrapper<WeatherCity>().where(" '" + geocode.getDistrict() + "' like district"));
+            city = null != weatherCity ? weatherCity.getId().toString() : "";
+        }
+        order = getOrderPrice(1, d, 0, order, city);
+        this.updateById(order);
+        return ResultUtil.success();
+    }
+
+
+    /**
+     * 司机取消转到操作
+     * @param uid
+     * @param orderId
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public ResultUtil cancelTransferOrder(Integer uid, Long orderId) throws Exception {
+        Order order = this.selectById(orderId);
+        if(order.getState() != 201){
+            return ResultUtil.error("不能取消转单");
+        }
+        order.setState(order.getOldState());
+        order.setOldState(null);
+        this.updateAllColumnById(order);
+
+        OrderTransfer orderTransfer = orderTransferService.selectOne(new EntityWrapper<OrderTransfer>().eq("orderId", orderId)
+                .eq("status", 1).isNull("successTime").orderBy("createTime desc limit 0, 1"));
+        if(null != orderTransfer){
+            orderTransfer.setStatus(3);
+            orderTransferService.updateById(orderTransfer);
+        }
+        return ResultUtil.success();
+    }
+
+
+    /**
+     * 司机取消订单
+     * @param uid
+     * @param orderId
+     * @param cause
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public ResultUtil driverCancelOrder(Integer uid, Long orderId, String cause) throws Exception {
+        Order order = this.selectById(orderId);
+        if(uid.compareTo(order.getDriverId()) != 0){
+            return ResultUtil.error("无法取消订单");
+        }
+        if(order.getState() > 105){
+            return ResultUtil.error("无法取消订单");
+        }
+
+        order.setState(301);
+        this.updateById(order);
+
+        CancelOrder cancelOrder = new CancelOrder();
+        cancelOrder.setOrderId(orderId);
+        cancelOrder.setUserType(2);
+        cancelOrder.setUserId(uid);
+        cancelOrder.setCause(cause);
+        cancelOrder.setStatus(1);
+        cancelOrder.setCreateTime(new Date());
+        cancelOrderService.insert(cancelOrder);
+        return ResultUtil.success();
+    }
+
+
+    /**
+     * 获取订单费用明细
+     * @param uid
+     * @param orderId
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public OrderPriceWarpper queryOrderPrice(Integer uid, Long orderId) throws Exception {
+        Driver driver = driverService.selectById(uid);
+        Order order = this.selectById(orderId);
+        OrderPriceWarpper orderPriceWarpper = new OrderPriceWarpper();
+        BeanUtils.copyProperties(order, orderPriceWarpper);
+        orderPriceWarpper.setActualMileage(new BigDecimal(order.getActualMileage() / 1000).setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue());
+        orderPriceWarpper.setTravelTime(Double.valueOf((order.getGetoffTime().getTime() - order.getStartTime().getTime()) / 60000).intValue());
+        orderPriceWarpper.setWxCollectionCode(driver.getWxCollectionCode());
+        orderPriceWarpper.setZfbCollectionCode(driver.getZfbCollectionCode());
+        return orderPriceWarpper;
+    }
+
+
+    /**
+     * 修改订单状态
+     * @param uid
+     * @param orderId
+     * @param state
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public ResultUtil setOrderStatus(Integer uid, Long orderId, Integer state) throws Exception {
+        List<Integer> s = Arrays.asList(107, 108);
+        if(s.contains(state)){
+            return ResultUtil.error("操作失败");
+        }
+        Order order = this.selectById(orderId);
+        order.setState(state);
+        if(state == 108){
+            order.setPayType(3);
+            order.setPayTime(new Date());
+            order.setPayMoney(order.getOrderMoney() - order.getDiscountAmount());
+        }
+        this.updateById(order);
+
+        if(state == 108){//计算抽成
+            saveRevenue(order);
+        }
+
+        pushUtil.pushOrderStatus(order.getDriverId(), 2, orderId, order.getState());
+        if(null != order.getUserId()){
+            pushUtil.pushOrderStatus(order.getUserId(), 1, orderId, order.getState());
+        }
+        return ResultUtil.success();
+    }
+
+
+    /**
+     * 计算抽成和分佣
+     * @param order
+     */
+    public void saveRevenue(Order order){
+
+    }
+
+    /**
+     * 获取司机的订单列表
+     * @param driverId
+     * @param state
+     * @param pageNum
+     * @param pageSize
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public List<DriverOrderListWarpper> queryDriverOrderList(Integer driverId, Integer state, Integer pageNum, Integer pageSize) throws Exception {
+        pageNum = (pageNum - 1) * pageSize;
+        return this.baseMapper.queryDriverOrderList(driverId, state, pageNum, pageSize);
+    }
+
+    /**
+     * 司机邀请列表
+     * @param driverId
+     * @param time
+     * @param pageNum
+     * @param pageSize
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public List<InviteListWarpper> queryInviteList(Integer driverId, String time, Integer pageNum, Integer pageSize) throws Exception {
+        pageNum = (pageNum - 1) * pageSize;
+        return this.baseMapper.queryInviteList(driverId, time, pageNum, pageSize);
+    }
+
+
+    /**
+     * 获取业绩汇总数据
+     * @param driverId
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public PerformanceSummaryWarpper queryPerformanceSummary(Integer driverId, Integer type, String time, Integer dayType) throws Exception {
+        Driver driver = driverService.selectById(driverId);
+        PerformanceSummaryWarpper performanceSummaryWarpper = new PerformanceSummaryWarpper();
+        BeanUtils.copyProperties(driver, performanceSummaryWarpper);
+        Double amount = revenueService.queryTotalAmount(driverId);
+        performanceSummaryWarpper.setGrossIncome(amount);
+        List<Integer> state = Arrays.asList(107, 108, 109);
+        int count = this.selectCount(new EntityWrapper<Order>().eq("driverId", driverId).in("state", state).eq("status", 1));
+        performanceSummaryWarpper.setTotalOrder(count);
+        List<PerformanceRankingWarpper> list = new ArrayList<>();
+        int position = 0;
+        Double d = 0D;
+        List<PerformanceRankingWarpper> performanceRankingWarppers = null;
+        if(type == 1){//订单量
+            performanceRankingWarppers = this.baseMapper.queryDriverRank(time, dayType);
+        }
+        if(type == 2){//佣金
+            performanceRankingWarppers = revenueService.queryDriverRank(2, time, dayType);
+        }
+        if(type == 3){//收入
+            performanceRankingWarppers = revenueService.queryDriverRank(null, time, dayType);
+        }
+        for (int i = 0; i < performanceRankingWarppers.size(); i++) {
+            PerformanceRankingWarpper performanceRankingWarpper = performanceRankingWarppers.get(i);
+            Double amountOfData = performanceRankingWarpper.getAmountOfData();
+            if(amountOfData.compareTo(d) != 0){
+                position++;
+                d = amountOfData;
+            }
+            if(position <= 10){
+                list.add(performanceRankingWarpper);
+            }
+            if(performanceRankingWarpper.getDriverId().compareTo(driverId) == 0){
+                break;
+            }
+        }
+        performanceSummaryWarpper.setPosition(position);
+        performanceSummaryWarpper.setList(list);
+        return performanceSummaryWarpper;
+    }
+
+
+    /**
+     * 获取我的业绩
+     * @param driverId
+     * @param time
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public List<MyAchievementWarpper> queryMyAchievement(Integer driverId, String time) throws Exception {
+        List<MyAchievementWarpper> list = new ArrayList<>();
+        time = time.replaceAll("-", "年") + "月";
+        //订单量
+        List<PerformanceRankingWarpper> performanceRankingWarppers = performanceRankingWarppers = this.baseMapper.queryDriverRank(time, 2);
+        int position = 0;
+        Double d = 0D;
+        for (int i = 0; i < performanceRankingWarppers.size(); i++) {
+            PerformanceRankingWarpper performanceRankingWarpper = performanceRankingWarppers.get(i);
+            Double amountOfData = performanceRankingWarpper.getAmountOfData();
+            if(amountOfData.compareTo(d) != 0){
+                position++;
+                d = amountOfData;
+            }
+            if(performanceRankingWarpper.getDriverId().compareTo(driverId) == 0){
+                break;
+            }
+        }
+        MyAchievementWarpper myAchievementWarpper = new MyAchievementWarpper();
+        myAchievementWarpper.setType("订单");
+        myAchievementWarpper.setTime(time);
+        myAchievementWarpper.setRank(position);
+        myAchievementWarpper.setAmountOfData(d);
+        list.add(myAchievementWarpper);
+
+        //收入
+        performanceRankingWarppers = revenueService.queryDriverRank(null, time, 2);
+        position = 0;
+        d = 0D;
+        for (int i = 0; i < performanceRankingWarppers.size(); i++) {
+            PerformanceRankingWarpper performanceRankingWarpper = performanceRankingWarppers.get(i);
+            Double amountOfData = performanceRankingWarpper.getAmountOfData();
+            if(amountOfData.compareTo(d) != 0){
+                position++;
+                d = amountOfData;
+            }
+            if(performanceRankingWarpper.getDriverId().compareTo(driverId) == 0){
+                break;
+            }
+        }
+        myAchievementWarpper = new MyAchievementWarpper();
+        myAchievementWarpper.setType("收入");
+        myAchievementWarpper.setTime(time);
+        myAchievementWarpper.setRank(position);
+        myAchievementWarpper.setAmountOfData(d);
+        list.add(myAchievementWarpper);
+
+        //佣金
+        performanceRankingWarppers = revenueService.queryDriverRank(2, time, 2);
+        position = 0;
+        d = 0D;
+        for (int i = 0; i < performanceRankingWarppers.size(); i++) {
+            PerformanceRankingWarpper performanceRankingWarpper = performanceRankingWarppers.get(i);
+            Double amountOfData = performanceRankingWarpper.getAmountOfData();
+            if(amountOfData.compareTo(d) != 0){
+                position++;
+                d = amountOfData;
+            }
+            if(performanceRankingWarpper.getDriverId().compareTo(driverId) == 0){
+                break;
+            }
+        }
+        myAchievementWarpper = new MyAchievementWarpper();
+        myAchievementWarpper.setType("佣金");
+        myAchievementWarpper.setTime(time);
+        myAchievementWarpper.setRank(position);
+        myAchievementWarpper.setAmountOfData(d);
+        list.add(myAchievementWarpper);
+        return list;
+    }
 }

--
Gitblit v1.7.1