|  |  |  | 
|---|
|  |  |  | import com.supersavedriving.user.modular.system.util.MallBook.model.*; | 
|---|
|  |  |  | import com.supersavedriving.user.modular.system.util.MallBook.util.Transfer; | 
|---|
|  |  |  | import com.supersavedriving.user.modular.system.util.MallBook.util.TrhRequest; | 
|---|
|  |  |  | import com.supersavedriving.user.modular.system.util.juhe.WeatherUtil; | 
|---|
|  |  |  | import com.supersavedriving.user.modular.system.util.mongodb.model.Location; | 
|---|
|  |  |  | import com.supersavedriving.user.modular.system.warpper.*; | 
|---|
|  |  |  | import io.swagger.models.auth.In; | 
|---|
|  |  |  | import org.redisson.api.RLock; | 
|---|
|  |  |  | import org.redisson.api.RedissonClient; | 
|---|
|  |  |  | import org.slf4j.Logger; | 
|---|
|  |  |  | import org.slf4j.LoggerFactory; | 
|---|
|  |  |  | import org.springframework.beans.BeanUtils; | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import javax.annotation.Resource; | 
|---|
|  |  |  | import java.math.BigDecimal; | 
|---|
|  |  |  | import java.math.MathContext; | 
|---|
|  |  |  | import java.math.RoundingMode; | 
|---|
|  |  |  | import java.net.InetAddress; | 
|---|
|  |  |  | import java.text.SimpleDateFormat; | 
|---|
|  |  |  | import java.time.LocalDateTime; | 
|---|
|  |  |  | import java.util.*; | 
|---|
|  |  |  | import java.util.concurrent.TimeUnit; | 
|---|
|  |  |  | import java.util.stream.Collectors; | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | private RedisUtil redisUtil; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | private RedissonClient redissonClient; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | private MongoTemplate mongoTemplate; | 
|---|
|  |  |  | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public ResultUtil travelOrder(Integer uid, TravelOrder travelOrder) throws Exception { | 
|---|
|  |  |  | List<Integer> state = Arrays.asList(101, 102, 103, 104, 105, 106, 107, 201, 401); | 
|---|
|  |  |  | Order order = this.selectOne(new EntityWrapper<Order>().eq("userId", uid).eq("status", 1).in("state", state)); | 
|---|
|  |  |  | if(null != order){ | 
|---|
|  |  |  | return ResultUtil.error("您还有正在进行的订单"); | 
|---|
|  |  |  | RLock lock1 = redissonClient.getLock("travelOrder:" + uid); | 
|---|
|  |  |  | boolean lock2 = lock1.tryLock(5, 10, TimeUnit.SECONDS); | 
|---|
|  |  |  | if(!lock2){ | 
|---|
|  |  |  | return ResultUtil.error("系统繁忙,请稍后重试"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | AppUser appUser = appUserService.selectById(uid); | 
|---|
|  |  |  | order = this.selectOne(new EntityWrapper<Order>().eq("userPhone", appUser.getPhone()).eq("status", 1).in("state", state)); | 
|---|
|  |  |  | if(null != order){ | 
|---|
|  |  |  | return ResultUtil.error("您还有正在进行的订单"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | String startAddress = travelOrder.getStartAddress(); | 
|---|
|  |  |  | startAddress = startAddress.replaceAll("& #40;", "("); | 
|---|
|  |  |  | startAddress = startAddress.replaceAll("& #41;", ")"); | 
|---|
|  |  |  | travelOrder.setStartAddress(startAddress); | 
|---|
|  |  |  | if(ToolUtil.isNotEmpty(travelOrder.getEndAddress())){ | 
|---|
|  |  |  | String endAddress = travelOrder.getEndAddress(); | 
|---|
|  |  |  | endAddress = endAddress.replaceAll("& #40;", "("); | 
|---|
|  |  |  | endAddress = endAddress.replaceAll("& #41;", ")"); | 
|---|
|  |  |  | travelOrder.setEndAddress(endAddress); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | order = new Order(); | 
|---|
|  |  |  | BeanUtils.copyProperties(travelOrder, order); | 
|---|
|  |  |  | if(ToolUtil.isEmpty(travelOrder.getUserPhone())){ | 
|---|
|  |  |  | order.setUserPhone(appUser.getPhone()); | 
|---|
|  |  |  | order.setUserName(appUser.getNickname()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | order.setUserId(uid); | 
|---|
|  |  |  | order.setSource(1); | 
|---|
|  |  |  | order.setHallOrder(0); | 
|---|
|  |  |  | order.setStatus(1); | 
|---|
|  |  |  | order.setCreateTime(new Date()); | 
|---|
|  |  |  | order.setState(null != travelOrder.getDriverId() ? 102 : 101); | 
|---|
|  |  |  | Double d = 0D; | 
|---|
|  |  |  | if(ToolUtil.isNotEmpty(travelOrder.getEndAddress())){ | 
|---|
|  |  |  | Map<String, String> distance = MapUtil.getDistance(order.getStartLng() + "," + order.getStartLat(), order.getEndLng() + "," + order.getEndLat(), 1); | 
|---|
|  |  |  | if(null == distance){ | 
|---|
|  |  |  | return ResultUtil.error("获取预估距离出错"); | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | List<Integer> state = Arrays.asList(101, 102, 103, 104, 105, 106, 107, 201, 401); | 
|---|
|  |  |  | Order order = this.selectOne(new EntityWrapper<Order>().eq("userId", uid).eq("status", 1).in("state", state)); | 
|---|
|  |  |  | if(null != order){ | 
|---|
|  |  |  | return ResultUtil.error("您还有正在进行的订单"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | d = Double.valueOf(distance.get("distance")) / 1000; | 
|---|
|  |  |  | order.setEstimatedMileage(d); | 
|---|
|  |  |  | order.setEstimatedTime(Integer.valueOf(distance.get("duration")) / 60); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | String city = ""; | 
|---|
|  |  |  | Integer branchOfficeId = null; | 
|---|
|  |  |  | District geocode = MapUtil.geocode(order.getStartLng().toString(), order.getStartLat().toString()); | 
|---|
|  |  |  | if(null != geocode){ | 
|---|
|  |  |  | String districtCode = geocode.getDistrictCode(); | 
|---|
|  |  |  | BranchOffice branchOffice = branchOfficeService.selectOne(new EntityWrapper<BranchOffice>().eq("status", 1).eq("districtCode", districtCode)); | 
|---|
|  |  |  | if(null == branchOffice){ | 
|---|
|  |  |  | String cityCode = geocode.getCityCode(); | 
|---|
|  |  |  | branchOffice = branchOfficeService.selectOne(new EntityWrapper<BranchOffice>().eq("status", 1).eq("cityCode", cityCode)); | 
|---|
|  |  |  | AppUser appUser = appUserService.selectById(uid); | 
|---|
|  |  |  | order = this.selectOne(new EntityWrapper<Order>().eq("userPhone", appUser.getPhone()).eq("status", 1).in("state", state)); | 
|---|
|  |  |  | if(null != order){ | 
|---|
|  |  |  | return ResultUtil.error("您还有正在进行的订单"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | String startAddress = travelOrder.getStartAddress(); | 
|---|
|  |  |  | startAddress = startAddress.replaceAll("& #40;", "("); | 
|---|
|  |  |  | startAddress = startAddress.replaceAll("& #41;", ")"); | 
|---|
|  |  |  | travelOrder.setStartAddress(startAddress); | 
|---|
|  |  |  | if(ToolUtil.isNotEmpty(travelOrder.getEndAddress())){ | 
|---|
|  |  |  | String endAddress = travelOrder.getEndAddress(); | 
|---|
|  |  |  | endAddress = endAddress.replaceAll("& #40;", "("); | 
|---|
|  |  |  | endAddress = endAddress.replaceAll("& #41;", ")"); | 
|---|
|  |  |  | travelOrder.setEndAddress(endAddress); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | order = new Order(); | 
|---|
|  |  |  | BeanUtils.copyProperties(travelOrder, order); | 
|---|
|  |  |  | if(ToolUtil.isEmpty(travelOrder.getUserPhone())){ | 
|---|
|  |  |  | order.setUserPhone(appUser.getPhone()); | 
|---|
|  |  |  | order.setUserName(appUser.getNickname()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | order.setUserId(uid); | 
|---|
|  |  |  | order.setSource(1); | 
|---|
|  |  |  | order.setHallOrder(0); | 
|---|
|  |  |  | order.setStatus(1); | 
|---|
|  |  |  | order.setCreateTime(new Date()); | 
|---|
|  |  |  | order.setState(null != travelOrder.getDriverId() ? 102 : 101); | 
|---|
|  |  |  | Double d = 0D; | 
|---|
|  |  |  | if(ToolUtil.isNotEmpty(travelOrder.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); | 
|---|
|  |  |  | order.setEstimatedTime(Integer.valueOf(distance.get("duration")) / 60); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | String city = ""; | 
|---|
|  |  |  | Integer branchOfficeId = null; | 
|---|
|  |  |  | District geocode = MapUtil.geocode(order.getStartLng().toString(), order.getStartLat().toString()); | 
|---|
|  |  |  | if(null != geocode){ | 
|---|
|  |  |  | String districtCode = geocode.getDistrictCode(); | 
|---|
|  |  |  | BranchOffice branchOffice = branchOfficeService.selectOne(new EntityWrapper<BranchOffice>().eq("status", 1).eq("districtCode", districtCode)); | 
|---|
|  |  |  | if(null == branchOffice){ | 
|---|
|  |  |  | String provinceCode = geocode.getProvinceCode(); | 
|---|
|  |  |  | branchOffice = branchOfficeService.selectOne(new EntityWrapper<BranchOffice>().eq("status", 1).eq("provinceCode", provinceCode)); | 
|---|
|  |  |  | String cityCode = geocode.getCityCode(); | 
|---|
|  |  |  | branchOffice = branchOfficeService.selectOne(new EntityWrapper<BranchOffice>().eq("status", 1).eq("cityCode", cityCode)); | 
|---|
|  |  |  | if(null == branchOffice){ | 
|---|
|  |  |  | String provinceCode = geocode.getProvinceCode(); | 
|---|
|  |  |  | branchOffice = branchOfficeService.selectOne(new EntityWrapper<BranchOffice>().eq("status", 1).eq("provinceCode", provinceCode)); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if(null == branchOffice){ | 
|---|
|  |  |  | return ResultUtil.error("起点暂无企业服务"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | branchOfficeId = branchOffice.getId(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | order.setCreateTime(new Date()); | 
|---|
|  |  |  | order = getOrderPrice(1, d, 0, order, city, branchOfficeId); | 
|---|
|  |  |  | if(null != travelOrder.getDriverId()){ | 
|---|
|  |  |  | DriverWork driverWork = driverWorkService.selectOne(new EntityWrapper<DriverWork>().eq("driverId", travelOrder.getDriverId()).eq("status", 1)); | 
|---|
|  |  |  | if(null == driverWork){ | 
|---|
|  |  |  | return ResultUtil.error("司机还未上班"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | Driver driver = driverService.selectById(travelOrder.getDriverId()); | 
|---|
|  |  |  | if(driver.getServerStatus() == 2){ | 
|---|
|  |  |  | return ResultUtil.error("司机正在服务中"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | order.setAgentId(driver.getAgentId()); | 
|---|
|  |  |  | order.setBranchOfficeId(driver.getBranchOfficeId()); | 
|---|
|  |  |  | order.setOrderTakingTime(new Date()); | 
|---|
|  |  |  | driver.setServerStatus(2); | 
|---|
|  |  |  | driverService.updateById(driver); | 
|---|
|  |  |  | appUser.setCancelCount(0); | 
|---|
|  |  |  | appUser.setIsException(1); | 
|---|
|  |  |  | appUserService.updateById(appUser); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | List<Order> orderList = new ArrayList<>(); | 
|---|
|  |  |  | for (Integer i = 0; i < travelOrder.getDriverNum(); i++) { | 
|---|
|  |  |  | order.setId(null); | 
|---|
|  |  |  | order.setCode(UUIDUtil.getTimeStr() + UUIDUtil.getNumberRandom(5)); | 
|---|
|  |  |  | boolean insert = this.insert(order); | 
|---|
|  |  |  | if(insert){ | 
|---|
|  |  |  | orderList.add(order); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if(null == branchOffice){ | 
|---|
|  |  |  | return ResultUtil.error("起点暂无企业服务"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | branchOfficeId = branchOffice.getId(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | order.setCreateTime(new Date()); | 
|---|
|  |  |  | order = getOrderPrice(1, d, 0, order, city, branchOfficeId); | 
|---|
|  |  |  | if(null != travelOrder.getDriverId()){ | 
|---|
|  |  |  | DriverWork driverWork = driverWorkService.selectOne(new EntityWrapper<DriverWork>().eq("driverId", travelOrder.getDriverId()).eq("status", 1)); | 
|---|
|  |  |  | if(null == driverWork){ | 
|---|
|  |  |  | return ResultUtil.error("司机还未上班"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | Driver driver = driverService.selectById(travelOrder.getDriverId()); | 
|---|
|  |  |  | if(driver.getServerStatus() == 2){ | 
|---|
|  |  |  | return ResultUtil.error("司机正在服务中"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | order.setAgentId(driver.getAgentId()); | 
|---|
|  |  |  | order.setBranchOfficeId(driver.getBranchOfficeId()); | 
|---|
|  |  |  | order.setOrderTakingTime(new Date()); | 
|---|
|  |  |  | driver.setServerStatus(2); | 
|---|
|  |  |  | driverService.updateById(driver); | 
|---|
|  |  |  | appUser.setCancelCount(0); | 
|---|
|  |  |  | appUser.setIsException(1); | 
|---|
|  |  |  | appUserService.updateById(appUser); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | for (Integer i = 0; i < travelOrder.getDriverNum(); i++) { | 
|---|
|  |  |  | order.setId(null); | 
|---|
|  |  |  | order.setCode(UUIDUtil.getTimeStr() + UUIDUtil.getNumberRandom(5)); | 
|---|
|  |  |  | boolean insert = this.insert(order); | 
|---|
|  |  |  | if(insert){ | 
|---|
|  |  |  | //推送状态 | 
|---|
|  |  |  | pushUtil.pushOrderStatus(uid, 1, order.getId(), order.getState()); | 
|---|
|  |  |  | if(null != order.getDriverId()){ | 
|---|
|  |  |  | PushOrderInfoWarpper pushOrderInfoWarpper = new PushOrderInfoWarpper(); | 
|---|
|  |  |  | pushOrderInfoWarpper.setId(order.getId()); | 
|---|
|  |  |  | pushOrderInfoWarpper.setState(order.getState()); | 
|---|
|  |  |  | pushUtil.pushOrderInfo(order.getDriverId(), 2, pushOrderInfoWarpper); | 
|---|
|  |  |  | }else{ | 
|---|
|  |  |  | //推单 | 
|---|
|  |  |  | Order finalOrder = order; | 
|---|
|  |  |  | new Thread(()->{ | 
|---|
|  |  |  | pushOrder(finalOrder.getId()); | 
|---|
|  |  |  | }).start(); | 
|---|
|  |  |  | new Thread(new Runnable() { | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public void run() { | 
|---|
|  |  |  | orderList.forEach(order -> { | 
|---|
|  |  |  | //推送状态 | 
|---|
|  |  |  | pushUtil.pushOrderStatus(uid, 1, order.getId(), order.getState()); | 
|---|
|  |  |  | if(null != order.getDriverId()){ | 
|---|
|  |  |  | PushOrderInfoWarpper pushOrderInfoWarpper = new PushOrderInfoWarpper(); | 
|---|
|  |  |  | pushOrderInfoWarpper.setId(order.getId()); | 
|---|
|  |  |  | pushOrderInfoWarpper.setState(order.getState()); | 
|---|
|  |  |  | pushUtil.pushOrderInfo(order.getDriverId(), 2, pushOrderInfoWarpper); | 
|---|
|  |  |  | }else{ | 
|---|
|  |  |  | //推单 | 
|---|
|  |  |  | pushOrder(order.getId(), uid); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }).start(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | redisUtil.setStrValue("newOrder", "true"); | 
|---|
|  |  |  | return ResultUtil.success(order.getId()); | 
|---|
|  |  |  | }catch (Exception e){ | 
|---|
|  |  |  | e.printStackTrace(); | 
|---|
|  |  |  | }finally { | 
|---|
|  |  |  | lock1.unlock(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | redisUtil.setStrValue("newOrder", "true"); | 
|---|
|  |  |  | return ResultUtil.success(order.getId()); | 
|---|
|  |  |  | return ResultUtil.error("系统异常"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 订单推送逻辑 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public void pushOrder(Long orderId){ | 
|---|
|  |  |  | public void pushOrder(Long orderId, Integer uid){ | 
|---|
|  |  |  | System.err.println("开始推单:" + orderId); | 
|---|
|  |  |  | //        RLock lock1 = redissonClient.getLock("pushOrder:" + uid); | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | Order order = this.selectById(orderId); | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | 
|---|
|  |  |  | *        合适司:积分 > 评分 > 距离 | 
|---|
|  |  |  | *      3.司机没有接单直接将订单置入大厅 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | 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++; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if(!lock){ | 
|---|
|  |  |  | order.setHallOrder(1); | 
|---|
|  |  |  | this.updateById(order); | 
|---|
|  |  |  | ExtraPushOrder(order); | 
|---|
|  |  |  | redisUtil.unlock(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | //            boolean lock2 = lock1.tryLock(5, 10, TimeUnit.SECONDS); | 
|---|
|  |  |  | //            if(!lock2){ | 
|---|
|  |  |  | //                order.setHallOrder(1); | 
|---|
|  |  |  | //                this.updateById(order); | 
|---|
|  |  |  | //                ExtraPushOrder(order); | 
|---|
|  |  |  | //            } | 
|---|
|  |  |  | SystemConfig systemConfig = systemConfigService.selectOne(new EntityWrapper<SystemConfig>().eq("type", 1)); | 
|---|
|  |  |  | if(null == systemConfig){ | 
|---|
|  |  |  | redisUtil.unlock(); | 
|---|
|  |  |  | return; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | JSONObject jsonObject = JSON.parseObject(systemConfig.getContent()); | 
|---|
|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if(null != driver){ | 
|---|
|  |  |  | System.err.println("完成司机查找:" + driver); | 
|---|
|  |  |  | //防止多笔订单推给一个司机 | 
|---|
|  |  |  | Driver driver1 = driverService.selectById(driver); | 
|---|
|  |  |  | driver1.setServerStatus(2); | 
|---|
|  |  |  | 
|---|
|  |  |  | ExtraPushOrder(order); | 
|---|
|  |  |  | redisUtil.setStrValue("lobbyOrder", "true"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | redisUtil.unlock(); | 
|---|
|  |  |  | }catch (Exception e){ | 
|---|
|  |  |  | e.printStackTrace(); | 
|---|
|  |  |  | redisUtil.unlock(); | 
|---|
|  |  |  | }finally { | 
|---|
|  |  |  | //            lock1.unlock(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } | 
|---|