From b4d8cb69ff3a3d35a10a7e5c487ff683b31cc9f1 Mon Sep 17 00:00:00 2001 From: puzhibing <393733352@qq.com> Date: 星期五, 24 二月 2023 10:06:03 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/master' --- driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/OrderServiceImpl.java | 375 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 347 insertions(+), 28 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..d26afc6 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 @@ -5,31 +5,32 @@ import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.baomidou.mybatisplus.service.impl.ServiceImpl; +import com.supersavedriving.driver.core.util.ToolUtil; 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.juhe.WeatherUtil; +import com.supersavedriving.driver.modular.system.util.mongodb.model.Location; 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.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 +50,30 @@ @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; + + + + /** * 获取服务中的订单id @@ -66,21 +91,41 @@ } + /** + * 司机代客下单 + * @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.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 +134,43 @@ 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); + order = getOrderPrice(1, d, 0, order, ""); + order.setHallOrder(0); 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 +268,8 @@ } //恶劣天气 - if(true){ + boolean badWeather = WeatherUtil.isBadWeather(city); + if(badWeather){ order.setBadWeatherDistance(num5);//恶劣天气公里 order.setBadWeatherPrice(num6);//恶劣天气费 if(distance.compareTo(num7) > 0){ @@ -271,4 +331,263 @@ 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(startLat), Double.valueOf(startLng)); + 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; + if(driverIds.size() > 0){ + List<YouTuiDriver> youTuiDrivers = youTuiDriverService.selectList(new EntityWrapper<YouTuiDriver>().in("driverId", driverIds).last(" 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(); + } + } + } + + + //开始范围查找 + 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.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 -> { + 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); + 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(5); + if(!lock){ + int num1 = 1; + while (num1 <= 10){ + Thread.sleep(3000);//等待3秒 + lock = redisUtil.lock(5); + if(lock){ + break; + }else{ + num1++; + } + } + } + Order order = this.selectById(orderId); + if(order.getState() != 301){ + redisUtil.unlock(); + return ResultUtil.error("订单已被取消"); + } + if(order.getState() != 101){ + redisUtil.unlock(); + return ResultUtil.error("手速慢了哦"); + } + order.setDriverId(uid); + order.setAgentId(driver.getAgentId()); + order.setBranchOfficeId(driver.getBranchOfficeId()); + order.setState(102); + this.updateById(order); + redisUtil.unlock(); + + driver.setServerStatus(2); + driverService.updateById(driver); + + //推动订单数据 + new Thread(new Runnable() { + @Override + public void run() { + //发送系统消息 + 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()); + } + } + }).start(); + }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); + String value = redisUtil.getValue("DRIVER" + uid); + Map<String, Double> distance = GeodesyUtil.getDistance(orderInfoWarpper.getStartLng() + "," + orderInfoWarpper.getStartLat(), value); + Double wgs84 = distance.get("WGS84"); + orderInfoWarpper.setCurrentDistance(wgs84); + return orderInfoWarpper; + } } -- Gitblit v1.7.1