| | |
| | | package com.stylefeng.guns.modular.system.service.impl; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.mybatisplus.mapper.EntityWrapper; |
| | | import com.baomidou.mybatisplus.service.impl.ServiceImpl; |
| | | import com.stylefeng.guns.core.shiro.ShiroKit; |
| | | import com.stylefeng.guns.core.util.ToolUtil; |
| | | import com.stylefeng.guns.modular.system.controller.resp.DataStatisticsOrderYearResp; |
| | | import com.stylefeng.guns.modular.system.controller.resp.PerformanceTableResp; |
| | | import com.stylefeng.guns.modular.system.controller.resp.TOrderResp; |
| | | import com.stylefeng.guns.modular.system.controller.resp.TOrderServerResp; |
| | | import com.stylefeng.guns.modular.system.controller.util.UUIDUtil; |
| | | import com.stylefeng.guns.modular.system.dao.TAppUserMapper; |
| | | import com.stylefeng.guns.modular.system.dao.TBranchOfficeMapper; |
| | | import com.stylefeng.guns.modular.system.dao.TDriverMapper; |
| | | import com.stylefeng.guns.modular.system.dao.TOrderMapper; |
| | | import com.stylefeng.guns.modular.system.enums.OrderStateEnum; |
| | | import com.stylefeng.guns.modular.system.model.TAppUser; |
| | | import com.stylefeng.guns.modular.system.model.TBranchOffice; |
| | | import com.stylefeng.guns.modular.system.model.TDriver; |
| | | import com.stylefeng.guns.modular.system.model.TOrder; |
| | | import com.stylefeng.guns.modular.system.service.ITOrderService; |
| | | import com.stylefeng.guns.modular.system.util.DateUtil; |
| | | import com.stylefeng.guns.modular.system.model.*; |
| | | import com.stylefeng.guns.modular.system.service.*; |
| | | import com.stylefeng.guns.modular.system.util.*; |
| | | import com.stylefeng.guns.modular.system.util.GaoDe.MapUtil; |
| | | import com.stylefeng.guns.modular.system.util.GaoDe.model.District; |
| | | import com.stylefeng.guns.modular.system.util.juhe.WeatherUtil; |
| | | import com.stylefeng.guns.modular.system.util.mongodb.model.Location; |
| | | 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 org.springframework.ui.Model; |
| | | import org.springframework.util.CollectionUtils; |
| | | import org.springframework.util.StringUtils; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.math.BigDecimal; |
| | | import java.math.MathContext; |
| | | import java.math.RoundingMode; |
| | | import java.text.SimpleDateFormat; |
| | | import java.time.LocalDate; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | @Service |
| | | public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> implements ITOrderService { |
| | | |
| | | @Autowired |
| | | @Resource |
| | | private TOrderMapper tOrderMapper; |
| | | @Autowired |
| | | |
| | | @Resource |
| | | private TAppUserMapper tAppUserMapper; |
| | | @Autowired |
| | | |
| | | @Resource |
| | | private TDriverMapper tDriverMapper; |
| | | @Autowired |
| | | |
| | | @Resource |
| | | private TBranchOfficeMapper tBranchOfficeMapper; |
| | | |
| | | @Autowired |
| | | private ITAppUserService appUserService; |
| | | |
| | | @Autowired |
| | | private RedisUtil redisUtil; |
| | | |
| | | @Autowired |
| | | private ITSystemConfigService systemConfigService; |
| | | |
| | | @Autowired |
| | | private ITYouTuiDriverService youTuiDriverService; |
| | | |
| | | @Resource |
| | | private MongoTemplate mongoTemplate; |
| | | |
| | | @Autowired |
| | | private IWeatherCityService weatherCityService; |
| | | |
| | | @Autowired |
| | | private PushUtil pushUtil; |
| | | |
| | | @Autowired |
| | | private ITDriverWorkService driverWorkService; |
| | | |
| | | @Autowired |
| | | private ITDriverService driverService; |
| | | |
| | | |
| | | |
| | | |
| | | @Override |
| | | public List<TOrderResp> getOrderList(String createTime, String code, Integer source, String userName, String userPhone, Integer state, String driverName,Integer isException) { |
| | |
| | | public void orderDetail(Integer orderId, Model model) { |
| | | // 订单信息 |
| | | TOrder tOrder = tOrderMapper.selectById(orderId); |
| | | model.addAttribute("id",orderId); |
| | | model.addAttribute("createTime",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(tOrder.getCreateTime()));//下单时间 |
| | | model.addAttribute("code",tOrder.getCode());//订单编号 |
| | | model.addAttribute("source",tOrder.getSource());//订单来源 |
| | |
| | | |
| | | // 查询用户 |
| | | TAppUser tAppUser = tAppUserMapper.selectById(tOrder.getUserId()); |
| | | model.addAttribute("userName",tAppUser.getNickname()); |
| | | model.addAttribute("userPhone",tAppUser.getPhone()); |
| | | model.addAttribute("havDiscount",tAppUser.getHavDiscount()); |
| | | if(1 == tAppUser.getHavDiscount()){ |
| | | // 计算9折优惠金额 |
| | | BigDecimal multiply = tOrder.getOrderMoney().multiply(new BigDecimal("0.1")).setScale(2); |
| | | model.addAttribute("multiply",multiply); |
| | | if(null != tAppUser){ |
| | | model.addAttribute("userName",tAppUser.getNickname()); |
| | | model.addAttribute("userPhone",tAppUser.getPhone()); |
| | | model.addAttribute("havDiscount",tAppUser.getHavDiscount()); |
| | | if(1 == tAppUser.getHavDiscount()){ |
| | | // 计算9折优惠金额 |
| | | BigDecimal multiply = tOrder.getOrderMoney().multiply(new BigDecimal("0.1")).setScale(2); |
| | | model.addAttribute("multiply",multiply); |
| | | } |
| | | }else{ |
| | | model.addAttribute("userName",tOrder.getUserName()); |
| | | model.addAttribute("userPhone",tOrder.getUserPhone()); |
| | | model.addAttribute("havDiscount", 0); |
| | | model.addAttribute("multiply",0D); |
| | | } |
| | | |
| | | // 查询司机 |
| | |
| | | // 查询司机当月有效订单数量 |
| | | return tOrderMapper.getValidOrderCount(driverId,orderMoney,month); |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public ResultUtil add(TOrder tOrder) { |
| | | String startAddress = tOrder.getStartAddress(); |
| | | String endAddress = tOrder.getEndAddress(); |
| | | String userPhone = tOrder.getUserPhone(); |
| | | int count = this.selectCount(new EntityWrapper<TOrder>().eq("userPhone", userPhone).eq("status", 1).in("state", Arrays.asList(101, 102, 103, 104, 105, 106, 201))); |
| | | if(count > 0){ |
| | | return ResultUtil.error("该用户还有未完成的订单", ""); |
| | | } |
| | | TAppUser tAppUser = appUserService.selectOne(new EntityWrapper<TAppUser>().eq("phone", userPhone).eq("status", 1)); |
| | | if(null != tAppUser){ |
| | | tOrder.setUserId(tAppUser.getId()); |
| | | } |
| | | JSONObject jsonObject = JSON.parseObject(startAddress); |
| | | String address = jsonObject.getString("address"); |
| | | address = address.replaceAll("& #40;", "("); |
| | | address = address.replaceAll("& #41;", ")"); |
| | | tOrder.setStartAddress(address); |
| | | tOrder.setStartLat(jsonObject.getString("lat")); |
| | | tOrder.setStartLng(jsonObject.getString("lon")); |
| | | tOrder.setSource(3); |
| | | if(ToolUtil.isNotEmpty(endAddress)){ |
| | | jsonObject = JSON.parseObject(endAddress); |
| | | String address1 = jsonObject.getString("address"); |
| | | address1 = address1.replaceAll("& #40;", "("); |
| | | address1 = address1.replaceAll("& #41;", ")"); |
| | | tOrder.setEndAddress(address1); |
| | | tOrder.setEndLat(jsonObject.getString("lat")); |
| | | tOrder.setEndLng(jsonObject.getString("lon")); |
| | | } |
| | | if(ToolUtil.isEmpty(tOrder.getStartLng()) || ToolUtil.isEmpty(tOrder.getStartLat())){ |
| | | return ResultUtil.error("请输入有效的起点"); |
| | | } |
| | | |
| | | tOrder.setCode(UUIDUtil.getTimeStr() + UUIDUtil.getNumberRandom(3)); |
| | | Double d = 0D; |
| | | if(ToolUtil.isNotEmpty(endAddress)){ |
| | | if(ToolUtil.isEmpty(tOrder.getEndLng()) || ToolUtil.isEmpty(tOrder.getEndLat())){ |
| | | return ResultUtil.error("请输入有效的终点"); |
| | | } |
| | | Map<String, String> distance = MapUtil.getDistance(tOrder.getStartLng() + "," + tOrder.getStartLat(), tOrder.getEndLng() + "," + tOrder.getEndLat(), 1); |
| | | if(null == distance){ |
| | | return ResultUtil.error("获取预估距离出错", ""); |
| | | } |
| | | d = Double.valueOf(distance.get("distance")) / 1000; |
| | | tOrder.setEstimatedMileage(d); |
| | | tOrder.setEstimatedTime(Integer.valueOf(distance.get("duration")) / 60); |
| | | } |
| | | String city = ""; |
| | | District geocode = MapUtil.geocode(tOrder.getStartLng(), tOrder.getStartLat()); |
| | | if(null != geocode){ |
| | | WeatherCity weatherCity = weatherCityService.selectOne(new EntityWrapper<WeatherCity>() |
| | | .where("'" + geocode.getCity() + "' like CONCAT('%', city, '%') and '" + geocode.getDistrict() + "' like CONCAT('%', district, '%') ")); |
| | | city = null != weatherCity ? weatherCity.getId().toString() : ""; |
| | | } |
| | | tOrder.setCreateTime(new Date()); |
| | | tOrder = getOrderPrice(1, d, 0, tOrder, city); |
| | | tOrder.setState(101); |
| | | tOrder.setStatus(1); |
| | | this.insert(tOrder); |
| | | //推送状态 |
| | | pushOrder(tOrder); |
| | | return ResultUtil.success(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 获取订单价格 |
| | | * @param type 计算类型(1=预估价,2=订单费) |
| | | * @param distance 行驶公里 |
| | | * @param waitTime 等待时长 |
| | | * @param order 订单数据 |
| | | * @param city 查询天气的城市 |
| | | * @return |
| | | */ |
| | | public TOrder getOrderPrice(Integer type, Double distance, Integer waitTime, TOrder order, String city){ |
| | | order = getOrderInitialPrice(order); |
| | | TSystemConfig systemConfig = systemConfigService.selectOne(new EntityWrapper<TSystemConfig>().eq("type", 5)); |
| | | if(null == systemConfig){ |
| | | if(type == 1){//预估金额 |
| | | order.setEstimatedPrice(new BigDecimal(0)); |
| | | } |
| | | if(type == 2){//订单金额 |
| | | order.setOrderMoney(new BigDecimal(0)); |
| | | } |
| | | return order; |
| | | } |
| | | JSONObject jsonObject = JSON.parseObject(systemConfig.getContent()); |
| | | JSONArray chargeStandard = jsonObject.getJSONArray("ChargeStandard"); |
| | | JSONObject extraCost = jsonObject.getJSONObject("ExtraCost"); |
| | | Date date = order.getCreateTime(); |
| | | |
| | | boolean b = true; |
| | | for (int i = 1; i < chargeStandard.size(); i++) {//各种时间段 |
| | | JSONObject jsonObject1 = chargeStandard.getJSONObject(i); |
| | | String num1 = jsonObject1.getString("num1"); |
| | | String num2 = jsonObject1.getString("num2"); |
| | | JSONArray num3 = jsonObject1.getJSONArray("num3");//起步里程 |
| | | Double num4 = jsonObject1.getDouble("num4");//长途里程 |
| | | Double num5 = jsonObject1.getDouble("num5");//长途里程 |
| | | Double num6 = jsonObject1.getDouble("num6");//长途费 |
| | | Double num7 = jsonObject1.getDouble("num7");//超出长途里程每num10公里 |
| | | Double num8 = jsonObject1.getDouble("num8");//超过num8每num10公里收取num11 |
| | | |
| | | String[] split = num1.split(":"); |
| | | Integer hour1 = Integer.valueOf(split[0]); |
| | | Calendar s = Calendar.getInstance(); |
| | | s.setTime(date); |
| | | s.set(Calendar.HOUR_OF_DAY, hour1); |
| | | s.set(Calendar.MINUTE, Integer.valueOf(split[1])); |
| | | s.set(Calendar.SECOND, 0); |
| | | |
| | | split = num2.split(":"); |
| | | Integer hour2 = Integer.valueOf(split[0]); |
| | | Calendar e = Calendar.getInstance(); |
| | | e.setTime(date); |
| | | e.set(Calendar.HOUR_OF_DAY, hour2); |
| | | e.set(Calendar.MINUTE, Integer.valueOf(split[1])); |
| | | e.set(Calendar.SECOND, 0); |
| | | |
| | | if(hour1 > hour2){ |
| | | if(s.getTimeInMillis() > date.getTime()){ |
| | | s.set(Calendar.DAY_OF_YEAR, s.get(Calendar.DAY_OF_YEAR) - 1); |
| | | }else{ |
| | | e.set(Calendar.DAY_OF_YEAR, e.get(Calendar.DAY_OF_YEAR) + 1); |
| | | } |
| | | } |
| | | |
| | | if(date.getTime() >= s.getTimeInMillis() && date.getTime() < e.getTimeInMillis()){ |
| | | b = false; |
| | | Double dd = 0d; |
| | | for (int j = 0; j < num3.size(); j++) { |
| | | JSONObject jsonObject2 = num3.getJSONObject(j); |
| | | Double num1_1 = jsonObject2.getDouble("num1"); |
| | | Double num2_1 = jsonObject2.getDouble("num2"); |
| | | Double num3_1 = jsonObject2.getDouble("num3"); |
| | | if(num1_1.compareTo(distance) <= 0 && num2_1.compareTo(distance) > 0){ |
| | | order.setStartDistance(distance);//起步里程 |
| | | order.setStartPrice(new BigDecimal(num3_1));//起步价 |
| | | } |
| | | if(j == num3.size() - 1 && order.getStartPrice().doubleValue() == 0){ |
| | | order.setStartDistance(num2_1);//起步里程 |
| | | order.setStartPrice(new BigDecimal(num3_1));//起步价 |
| | | dd = distance - num2_1; |
| | | } |
| | | } |
| | | if(dd != 0){ |
| | | //计算长途费 |
| | | if(distance.compareTo(num4) > 0){ |
| | | order.setLongDistance(num4 + "-" + num5);//长途里程 |
| | | order.setLongDistancePrice(new BigDecimal(num6));//长途费 |
| | | } |
| | | //计算长途里程超出的部分 |
| | | if(distance.compareTo(num5) > 0){ |
| | | BigDecimal subtract1 = new BigDecimal(distance).subtract(new BigDecimal(num5)); |
| | | BigDecimal divide1 = subtract1.divide(new BigDecimal(num7), new MathContext(2, RoundingMode.HALF_EVEN)); |
| | | BigDecimal multiply1 = divide1.multiply(new BigDecimal(num8)); |
| | | order.setOverLongDistance(subtract1.doubleValue());//超出长途里程 |
| | | order.setOverLongDistancePrice(multiply1);//超出长途里程费 |
| | | } |
| | | } |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if(b){//默认配置 |
| | | JSONObject jsonObject1 = chargeStandard.getJSONObject(0); |
| | | JSONArray num3 = jsonObject1.getJSONArray("num3");//起步里程 |
| | | Double num4 = jsonObject1.getDouble("num4");//长途里程 |
| | | Double num5 = jsonObject1.getDouble("num5");//长途里程 |
| | | Double num6 = jsonObject1.getDouble("num6");//长途费 |
| | | Double num7 = jsonObject1.getDouble("num7");//超出长途里程每num10公里 |
| | | Double num8 = jsonObject1.getDouble("num8");//超过num8每num10公里收取num11 |
| | | |
| | | Double dd = 0d; |
| | | for (int j = 0; j < num3.size(); j++) { |
| | | JSONObject jsonObject2 = num3.getJSONObject(j); |
| | | Double num1_1 = jsonObject2.getDouble("num1"); |
| | | Double num2_1 = jsonObject2.getDouble("num2"); |
| | | Double num3_1 = jsonObject2.getDouble("num3"); |
| | | if(num1_1.compareTo(distance) <= 0 && num2_1.compareTo(distance) > 0){ |
| | | order.setStartDistance(distance);//起步里程 |
| | | order.setStartPrice(new BigDecimal(num3_1));//起步价 |
| | | } |
| | | if(j == num3.size() - 1 && order.getStartPrice().doubleValue() == 0){ |
| | | order.setStartDistance(num2_1);//起步里程 |
| | | order.setStartPrice(new BigDecimal(num3_1));//起步价 |
| | | dd = distance - num2_1; |
| | | } |
| | | } |
| | | if(dd != 0){ |
| | | //计算长途费 |
| | | if(distance.compareTo(num4) > 0){ |
| | | order.setLongDistance(num4 + "-" + num5);//长途里程 |
| | | order.setLongDistancePrice(new BigDecimal(num6));//长途费 |
| | | } |
| | | //计算长途里程超出的部分 |
| | | if(distance.compareTo(num5) > 0){ |
| | | BigDecimal subtract1 = new BigDecimal(distance).subtract(new BigDecimal(num5)); |
| | | BigDecimal divide1 = subtract1.divide(new BigDecimal(num7), new MathContext(2, RoundingMode.HALF_EVEN)); |
| | | BigDecimal multiply1 = divide1.multiply(new BigDecimal(num8)); |
| | | order.setOverLongDistance(subtract1.doubleValue());//超出长途里程 |
| | | order.setOverLongDistancePrice(multiply1);//超出长途里程费 |
| | | } |
| | | } |
| | | } |
| | | |
| | | //计算额外费用 |
| | | Integer num1 = extraCost.getInteger("num1");//等待时长 |
| | | Double num2 = extraCost.getDouble("num2");//等待费 |
| | | Integer num3 = extraCost.getInteger("num3");//等待超出时长 |
| | | Double num4 = extraCost.getDouble("num4");//等到超出时长费用单价 X/分钟 |
| | | Double num5 = extraCost.getDouble("num5");//恶劣天气公里 |
| | | Double num6 = extraCost.getDouble("num6");//恶劣天气费 |
| | | Double num7 = extraCost.getDouble("num7");//恶劣天气超出公里 |
| | | Double num8 = extraCost.getDouble("num8");//恶劣天气超出公里单价 X/公里 |
| | | Double num9 = extraCost.getDouble("num9");//恶劣天气最高收取金额 |
| | | |
| | | //等待费用 |
| | | if(waitTime.compareTo(num1) >= 0){ |
| | | order.setWaitTime(num1);//等待时长 |
| | | order.setWaitTimePrice(new BigDecimal(num2));//等待费用 |
| | | |
| | | Integer w = waitTime - num3; |
| | | BigDecimal multiply = new BigDecimal(w).multiply(new BigDecimal(num4)); |
| | | order.setOutWaitTime(w);//等待时长超出分钟 |
| | | order.setOutWaitTimePrice(multiply);//等待时长超出费用 |
| | | } |
| | | |
| | | //恶劣天气 |
| | | systemConfig = systemConfigService.selectOne(new EntityWrapper<TSystemConfig>().eq("type", 8)); |
| | | if(null != systemConfig){ |
| | | JSONObject jsonObject1 = JSON.parseObject(systemConfig.getContent()); |
| | | Integer num11 = jsonObject1.getInteger("num1");//开启恶劣天气计价 |
| | | if(1 == num11){ |
| | | boolean badWeather = WeatherUtil.isBadWeather(city); |
| | | if(badWeather){ |
| | | order.setBadWeatherDistance(new BigDecimal(num5));//恶劣天气公里 |
| | | order.setBadWeatherPrice(new BigDecimal(num6));//恶劣天气费 |
| | | if(distance.compareTo(num7) > 0){ |
| | | BigDecimal subtract = new BigDecimal(distance).subtract(new BigDecimal(num7)); |
| | | BigDecimal multiply = subtract.multiply(new BigDecimal(num8)); |
| | | order.setOverBadWeatherDistance(subtract.doubleValue());//恶劣天气超出公里 |
| | | order.setOverBadWeatherPrice(multiply);//恶劣天气超出公里费 |
| | | } |
| | | |
| | | double add = order.getOverBadWeatherPrice().add(order.getBadWeatherPrice()).setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue(); |
| | | if(num9.compareTo(add) < 0){//超出最高金额(重新调整金额) |
| | | if(num9.compareTo(num6) < 0){//如果恶劣天气费大于最高金额 |
| | | order.setBadWeatherPrice(new BigDecimal(num9));//恶劣天气费 |
| | | order.setOverBadWeatherPrice(new BigDecimal(0));//恶劣天气超出公里费 |
| | | }else{ |
| | | BigDecimal subtract = new BigDecimal(num9).subtract(new BigDecimal(add)); |
| | | order.setOverBadWeatherPrice(subtract);//恶劣天气超出公里费 |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | //计算总金额 |
| | | BigDecimal bigDecimal = order.getStartPrice().add(order.getOverDrivePrice()).add(order.getLongDistancePrice()).add(order.getOverLongDistancePrice()) |
| | | .add(order.getWaitTimePrice()).add(order.getOutWaitTimePrice()).add(order.getBadWeatherPrice()).add(order.getOverBadWeatherPrice()).subtract(order.getDiscountAmount()).setScale(2, BigDecimal.ROUND_HALF_EVEN); |
| | | |
| | | if(type == 1){//预估价 |
| | | order.setEstimatedPrice(bigDecimal); |
| | | } |
| | | if(type == 2){//订单金额 |
| | | order.setOrderMoney(bigDecimal); |
| | | } |
| | | return order; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 初始订单费用 |
| | | * @param order |
| | | * @return |
| | | */ |
| | | public TOrder getOrderInitialPrice(TOrder order){ |
| | | order.setStartDistance(0D);//起步里程 |
| | | order.setStartPrice(new BigDecimal(0));//起步价 |
| | | order.setOverDriveDistance(0D);//超出起步里程 |
| | | order.setOverDrivePrice(new BigDecimal(0));//超出起步里程费 |
| | | order.setLongDistance("");//长途里程 |
| | | order.setLongDistancePrice(new BigDecimal(0));//长途里程费 |
| | | order.setOverLongDistance(0D);//超出长途里程 |
| | | order.setOverLongDistancePrice(new BigDecimal(0));//超出长途里程费 |
| | | order.setWaitTime(0);//等待时长 |
| | | order.setWaitTimePrice(new BigDecimal(0));//等待费 |
| | | order.setOutWaitTime(0);//超出等待时长 |
| | | order.setOutWaitTimePrice(new BigDecimal(0));//超出等待时长费 |
| | | order.setBadWeatherDistance(new BigDecimal(0));//恶劣天气里程 |
| | | order.setBadWeatherPrice(new BigDecimal(0));//恶劣天气里程费 |
| | | order.setOverBadWeatherDistance(0D);//恶劣天气超出里程 |
| | | order.setOverBadWeatherPrice(new BigDecimal(0));//恶劣天气超出里程费 |
| | | order.setDiscountedPrice(new BigDecimal(0));//优惠金额 |
| | | order.setCouponId(null);//优惠券 |
| | | order.setDiscountAmount(new BigDecimal(0));//折扣优惠金额 |
| | | order.setDiscount(0D);//折扣 |
| | | return order; |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * 订单推送逻辑 |
| | | * @param order |
| | | */ |
| | | public void pushOrder(TOrder order){ |
| | | /** |
| | | * 1.先找最大推单范围内的优推司机 -》 距离最近 |
| | | * 没有1 - 》 |
| | | * 2.按照后台推送配置在范围内查找合适司机 |
| | | * 合适司:积分 > 评分 > 距离 |
| | | * 3.司机没有接单直接将订单置入大厅 |
| | | */ |
| | | try { |
| | | 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){ |
| | | redisUtil.unlock(); |
| | | order.setHallOrder(1); |
| | | this.updateById(order); |
| | | ExtraPushOrder(order); |
| | | return; |
| | | } |
| | | TSystemConfig systemConfig = systemConfigService.selectOne(new EntityWrapper<TSystemConfig>().eq("type", 1)); |
| | | if(null == systemConfig){ |
| | | redisUtil.unlock(); |
| | | 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; |
| | | TYouTuiDriver youTuiDriver1 = null; |
| | | if(driverIds.size() > 0){ |
| | | List<TYouTuiDriver> youTuiDrivers = youTuiDriverService.selectList(new EntityWrapper<TYouTuiDriver>().in("driverId", driverIds) |
| | | .eq("state", 2).last(" and (surplusQuantity > 0 or now() < endTime) and now() < failureTime")); |
| | | Double d = null; |
| | | for (TYouTuiDriver youTuiDriver : youTuiDrivers) { |
| | | String value = redisUtil.getValue("DRIVER" + youTuiDriver.getDriverId()); |
| | | if(ToolUtil.isEmpty(value)){ |
| | | continue; |
| | | } |
| | | TDriver driver1 = driverService.selectById(youTuiDriver.getDriverId()); |
| | | if(driver1.getServerStatus() == 2 || driver1.getOpenOrderQRCode() == 1){ |
| | | continue; |
| | | } |
| | | TDriverWork driverWork = driverWorkService.selectOne(new EntityWrapper<TDriverWork>().eq("driverId", driver1.getId()).eq("status", 1)); |
| | | if(null == driverWork){ |
| | | 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++) { |
| | | if(null != driver){ |
| | | break; |
| | | } |
| | | 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<TDriver> drivers = driverService.selectList(new EntityWrapper<TDriver>().eq("approvalStatus", 2) |
| | | .eq("serverStatus", 1).eq("openOrderQRCode", 0).eq("status", 1).in("id", driverIds)); |
| | | if(drivers.size() == 0){ |
| | | continue; |
| | | } |
| | | |
| | | Integer integral = null; |
| | | Double score = null; |
| | | Double d = null; |
| | | for (TDriver driver1 : drivers) { |
| | | String value = redisUtil.getValue("DRIVER" + driver1.getId()); |
| | | if(ToolUtil.isEmpty(value)){ |
| | | continue; |
| | | } |
| | | TDriverWork driverWork = driverWorkService.selectOne(new EntityWrapper<TDriverWork>().eq("driverId", driver1.getId()).eq("status", 1)); |
| | | if(null == driverWork){ |
| | | continue; |
| | | } |
| | | |
| | | if(integral == null || integral.compareTo(driver1.getIntegral()) < 0){//积分大 |
| | | integral = driver1.getIntegral(); |
| | | score = driver1.getScore(); |
| | | driver = driver1.getId(); |
| | | Map<String, Double> distance = GeodesyUtil.getDistance(value, order.getStartLng() + "," + order.getStartLat()); |
| | | Double wgs84 = distance.get("WGS84"); |
| | | d = wgs84; |
| | | continue; |
| | | } |
| | | if(integral.compareTo(driver1.getIntegral()) == 0 && score.compareTo(driver1.getScore()) < 0){//积分相同对比评分 |
| | | integral = driver1.getIntegral(); |
| | | score = driver1.getScore(); |
| | | driver = driver1.getId(); |
| | | Map<String, Double> distance = GeodesyUtil.getDistance(value, order.getStartLng() + "," + order.getStartLat()); |
| | | Double wgs84 = distance.get("WGS84"); |
| | | d = wgs84; |
| | | continue; |
| | | } |
| | | if(integral.compareTo(driver1.getIntegral()) == 0 && score.compareTo(driver1.getScore()) == 0){//积分相同/评分相同对比距离 |
| | | Map<String, Double> distance = GeodesyUtil.getDistance(value, order.getStartLng() + "," + order.getStartLat()); |
| | | Double wgs84 = distance.get("WGS84"); |
| | | if(d.compareTo(wgs84) > 0){ |
| | | d = wgs84; |
| | | integral = driver1.getIntegral(); |
| | | score = driver1.getScore(); |
| | | driver = driver1.getId(); |
| | | continue; |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | } |
| | | } |
| | | |
| | | if(null != driver){ |
| | | TDriver tDriver = driverService.selectById(driver); |
| | | tDriver.setServerStatus(2); |
| | | driverService.updateById(tDriver); |
| | | |
| | | pushUtil.pushGrabOrder(driver, 2, order.getId(), num4); |
| | | //创建定时任务处理订单到大厅 |
| | | new Timer().schedule(new TimerTask() { |
| | | @Override |
| | | public void run() { |
| | | TOrder order1 = TOrderServiceImpl.this.selectById(order.getId()); |
| | | if(order1.getState() == 101 || order1.getState() == 201){ |
| | | tDriver.setServerStatus(1); |
| | | driverService.updateById(tDriver); |
| | | |
| | | order1.setHallOrder(1); |
| | | TOrderServiceImpl.this.updateById(order1); |
| | | |
| | | ExtraPushOrder(order1); |
| | | } |
| | | } |
| | | }, num4 * 1000); |
| | | }else{ |
| | | order.setHallOrder(1); |
| | | this.updateById(order); |
| | | ExtraPushOrder(order); |
| | | } |
| | | redisUtil.unlock(); |
| | | }catch (Exception e){ |
| | | redisUtil.unlock(); |
| | | e.printStackTrace(); |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | public void ExtraPushOrder(TOrder order){ |
| | | String startLat = order.getStartLat(); |
| | | String startLng = order.getStartLng(); |
| | | |
| | | //找到中心点 |
| | | GeoJsonPoint geoJsonPoint = new GeoJsonPoint(Double.valueOf(startLng), Double.valueOf(startLat)); |
| | | Double num = 5D;//范围公里 |
| | | //构造半径 |
| | | 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()); |
| | | if(driverIds.size() == 0){ |
| | | return; |
| | | } |
| | | List<TDriverWork> tDriverWorks = driverWorkService.selectList(new EntityWrapper<TDriverWork>().in("driverId", driverIds).eq("status", 1)); |
| | | driverIds = tDriverWorks.stream().map(TDriverWork::getDriverId).collect(Collectors.toList()); |
| | | List<TDriver> drivers = tDriverMapper.selectList(new EntityWrapper<TDriver>().eq("approvalStatus", 2) |
| | | .eq("serverStatus", 1).eq("openOrderQRCode", 0).eq("status", 1).in("id", driverIds)); |
| | | if(drivers.size() == 0){ |
| | | return; |
| | | } |
| | | for (TDriver driver1 : drivers) { |
| | | String value = redisUtil.getValue("DRIVER" + driver1.getId()); |
| | | if (ToolUtil.isEmpty(value)) { |
| | | return; |
| | | } |
| | | pushUtil.pushGrabOrderExtras(driver1.getId(), 2); |
| | | } |
| | | } |
| | | |
| | | } |