package com.stylefeng.guns.modular.system.controller.taxi; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.baomidou.mybatisplus.plugins.Page; import com.stylefeng.guns.core.base.controller.BaseController; import com.stylefeng.guns.core.common.constant.factory.PageFactory; import com.stylefeng.guns.core.log.LogObjectHolder; import com.stylefeng.guns.core.shiro.ShiroKit; import com.stylefeng.guns.core.util.DateUtil; import com.stylefeng.guns.core.util.ExcelExportUtil; import com.stylefeng.guns.core.util.SinataUtil; import com.stylefeng.guns.core.util.ToolUtil; 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.redisqueue.RedisFifoQueue; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.InputStreamReader; import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.time.LocalDateTime; import java.util.*; /** * 出租车订单控制器 * * @author fengshuonan * @Date 2020-06-08 10:25:55 */ @Controller @RequestMapping("/tOrderTaxi") public class TOrderTaxiController extends BaseController { public static List orderIds = new ArrayList<>(); private String PREFIX = "/system/tOrderTaxi/"; @Autowired private ITOrderTaxiService tOrderTaxiService; @Autowired private ITOrderPositionService tOrderPositionService; @Autowired private ITDriverService tDriverService; @Autowired private GDMapElectricFenceUtil gdMapElectricFenceUtil; @Autowired private GDMapGeocodingUtil gdMapGeocodingUtil; @Autowired private ITUserService itUserService; @Autowired private PushUtil pushUtil; @Autowired private ITCompanyCityService companyCityService; @Autowired private ITSysPushOrderService pushOrderService; @Autowired private RedisUtil redisUtil; @Autowired private ITDriverService driverService; @Autowired private ITSystemNoticeService systemNoticeService; @Value("${filePath}") private String filePath; private ResultUtil resultUtil; @Autowired private RedisFifoQueue redisFifoQueue; /** * 跳转到出租车订单首页 */ @RequestMapping("") public String index() { return PREFIX + "tOrderTaxi.html"; } /** * 跳转到添加出租车订单 */ @RequestMapping("/tOrderTaxi_add") public String tOrderTaxiAdd() { return PREFIX + "tOrderTaxi_add.html"; } /** * 跳转到修改出租车订单 */ @RequestMapping("/tOrderTaxi_update/{tOrderTaxiId}") public String tOrderTaxiUpdate(@PathVariable Integer tOrderTaxiId, Model model) { Map tOrderTaxi = tOrderTaxiService.getTaxiOrderDetailById(tOrderTaxiId); model.addAttribute("item",tOrderTaxi); LogObjectHolder.me().set(tOrderTaxi); return PREFIX + "tOrderTaxi_edit.html"; } /** * 跳转到改派出租车订单 */ @RequestMapping("/tOrderTaxi_changeOrder/{tOrderTaxiId}") public String tOrderTaxi_changeOrder(@PathVariable Integer tOrderTaxiId, Model model) { TOrderTaxi tOrderTaxi = tOrderTaxiService.selectById(tOrderTaxiId); model.addAttribute("item",tOrderTaxi); LogObjectHolder.me().set(tOrderTaxi); return PREFIX + "tOrderTaxi_changeOrder.html"; } /** * 跳转到出租车订单轨迹页面 */ @RequestMapping("/tOrderTaxi_trajectory/{tOrderTaxiId}") public String tOrderTaxi_trajectory(@PathVariable Integer tOrderTaxiId, Model model) { model.addAttribute("tOrderTaxiId",tOrderTaxiId); return PREFIX + "tOrderTaxi_trajectory.html"; } /** * 获取出租车订单列表 */ @RequestMapping(value = "/list") @ResponseBody public Object list(String insertTime, String orderNum, Integer orderSource, String userName, String userPhone, String passengers, String passengersPhone, String driver, Integer state, Integer status ) { String beginTime = null; String endTime = null; if (SinataUtil.isNotEmpty(insertTime)){ String[] timeArray = insertTime.split(" - "); beginTime = timeArray[0]; endTime = timeArray[1]; } Page> page = new PageFactory>().defaultPage(); page.setRecords(tOrderTaxiService.getTaxiOrderList(page,beginTime,endTime,ShiroKit.getUser().getRoleType(),ShiroKit.getUser().getObjectId(),orderNum,orderSource,userName,userPhone,passengers,passengersPhone,driver,state,status)); return super.packForBT(page); } @GetMapping("/export") public void export(String insertTime, String orderNum, Integer orderSource, String userName, String userPhone, String passengers, String passengersPhone, String driver, Integer state, Integer status, HttpServletRequest request, HttpServletResponse response){ String beginTime = null; String endTime = null; if (SinataUtil.isNotEmpty(insertTime)){ String[] timeArray = insertTime.split(" - "); beginTime = timeArray[0]; endTime = timeArray[1]; } Page> page = new Page(1, 99999); List> taxiOrderList = tOrderTaxiService.getTaxiOrderList(page, beginTime, endTime, ShiroKit.getUser().getRoleType(), ShiroKit.getUser().getObjectId(), orderNum, orderSource, userName, userPhone, passengers, passengersPhone, driver, state,status); // 表格数据【封装】 List> dataList = new ArrayList<>(); // 列【封装】 List shellList = new ArrayList(); shellList.add("下单时间"); shellList.add("订单编号"); shellList.add("订单来源"); shellList.add("乘车时间"); shellList.add("下单用户昵称"); shellList.add("下单用户手机"); shellList.add("乘车用户姓名"); shellList.add("乘车用户手机"); shellList.add("起点"); shellList.add("终点"); shellList.add("接单司机"); shellList.add("司机手机号"); shellList.add("车辆所属机构"); shellList.add("接单车辆"); shellList.add("订单金额"); shellList.add("司机抽成"); shellList.add("已核退单"); shellList.add("状态"); dataList.add(shellList); for (Map object : taxiOrderList){ // 详细数据列【封装】 shellList = new ArrayList(); if(SinataUtil.isNotEmpty(object.get("insertTime"))){ shellList.add(com.stylefeng.guns.core.util.DateUtil.formatDate(com.stylefeng.guns.core.util.DateUtil.parse(object.get("insertTime").toString(),"YYYY-MM-dd HH:mm:ss.S"), "YYYY-MM-dd HH:mm")); }else{ shellList.add("-"); } if(SinataUtil.isNotEmpty(object.get("orderNum"))){ shellList.add(object.get("orderNum").toString()); }else{ shellList.add("-"); } if(SinataUtil.isNotEmpty(object.get("orderSource"))){ switch (object.get("orderSource").toString()){ case "1": shellList.add("APP下单"); break; case "2": shellList.add("扫码下单"); break; case "3": shellList.add("小程序下单"); break; case "4": shellList.add("司机下单"); break; case "5": shellList.add("调度下单"); break; case "6": shellList.add("电话下单"); break; case "7": shellList.add("95128电召"); break; } }else{ shellList.add("-"); } if(SinataUtil.isNotEmpty(object.get("travelTime"))){ shellList.add(com.stylefeng.guns.core.util.DateUtil.formatDate(com.stylefeng.guns.core.util.DateUtil.parse(object.get("travelTime").toString(),"YYYY-MM-dd HH:mm:ss.S"), "YYYY-MM-dd HH:mm")); }else{ shellList.add("-"); } if(SinataUtil.isNotEmpty(object.get("userName"))){ shellList.add(object.get("userName").toString()); }else{ shellList.add("-"); } if(SinataUtil.isNotEmpty(object.get("userPhone"))){ shellList.add(object.get("userPhone").toString()); }else{ shellList.add("-"); } if(SinataUtil.isNotEmpty(object.get("passengers"))){ shellList.add(object.get("passengers").toString()); }else{ shellList.add("-"); } if(SinataUtil.isNotEmpty(object.get("passengersPhone"))){ shellList.add(object.get("passengersPhone").toString()); }else{ shellList.add("-"); } if(SinataUtil.isNotEmpty(object.get("startAddress"))){ shellList.add(object.get("startAddress").toString()); }else{ shellList.add("-"); } if(SinataUtil.isNotEmpty(object.get("endAddress"))){ shellList.add(object.get("endAddress").toString()); }else{ shellList.add("-"); } if(SinataUtil.isNotEmpty(object.get("driver"))){ shellList.add(object.get("driver").toString().split("-")[0]); }else{ shellList.add("-"); } if(SinataUtil.isNotEmpty(object.get("driver"))){ shellList.add(object.get("driver").toString().split("-")[1]); }else{ shellList.add("-"); } if(SinataUtil.isNotEmpty(object.get("company"))){ shellList.add(object.get("company").toString()); }else{ shellList.add("-"); } if(SinataUtil.isNotEmpty(object.get("car"))){ shellList.add(object.get("car").toString()); }else{ shellList.add("-"); } if(SinataUtil.isNotEmpty(object.get("payMoney"))){ shellList.add(object.get("payMoney").toString()); }else{ shellList.add("-"); } if(SinataUtil.isNotEmpty(object.get("commission"))){ shellList.add(object.get("commission").toString()); }else{ shellList.add("-"); } if(SinataUtil.isNotEmpty(object.get("status"))){ switch (object.get("status").toString()){ case "1": shellList.add("否"); break; case "2": shellList.add("是"); break; case "3": shellList.add("否"); break; } }else{ shellList.add("否"); } if(SinataUtil.isNotEmpty(object.get("state"))){ switch (object.get("state").toString()){ case "1": shellList.add("待接单"); break; case "2": shellList.add("待出发"); break; case "3": shellList.add("待到达预约地点"); break; case "4": shellList.add("待乘客上车"); break; case "5": shellList.add("服务中"); break; case "6": shellList.add("完成服务"); break; case "7": shellList.add("待支付"); break; case "8": shellList.add("待评价"); break; case "9": shellList.add("已完成"); break; case "10": shellList.add("已取消"); break; case "11": shellList.add("改派中"); break; case "12": shellList.add("取消待支付"); break; } }else{ shellList.add("-"); } dataList.add(shellList); } try { // 调用工具类进行导出 ExcelExportUtil.easySheet("出租车订单"+ DateUtil.formatDate(new Date(), "YYYYMMddHHmmss"), "出租车订单", dataList,request, response); } catch (Exception e) { e.printStackTrace(); } } /** * 选择司机列表 */ @RequestMapping(value = "/selectDriver/{orderId}") @ResponseBody public Object selectDriver(@PathVariable Integer orderId, String name, String phone) { TOrderTaxi tOrderTaxi = tOrderTaxiService.selectById(orderId); Page> page = new PageFactory>().defaultPage(); page.setRecords(tOrderTaxiService.getCanSelectTaxiDriverList(page,tOrderTaxi.getCompanyId(),name,phone)); return super.packForBT(page); } /** * 获取订单轨迹 * @param orderDetailId * @return */ @ResponseBody @RequestMapping(value = "/getOrderTrack", method = RequestMethod.POST) public ResultUtil getOrderTrack(String orderDetailId){ if(ToolUtil.isNotEmpty(orderDetailId)){ try { // List list = tOrderPositionService.selectList(new EntityWrapper().eq("orderType", 2).eq("orderId", orderDetailId).orderBy("insertTime")); /*if(list.size() == 0){ return ResultUtil.error("该订单没有运行轨迹"); }*/ //将数据存储到文件中 File file = new File(filePath + orderDetailId + "_2.txt"); if(!file.exists()){ return ResultUtil.success(new ArrayList<>()); } //读取文件(字符流) BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file),"UTF-8")); //循环取出数据 String str = null; StringBuffer sb = new StringBuffer(); while ((str = in.readLine()) != null) { sb.append(str); } List list = JSONArray.parseArray(sb.toString(), TOrderPosition.class); resultUtil = ResultUtil.success(list); }catch (Exception e){ e.printStackTrace(); resultUtil = ResultUtil.runErr(); } }else { resultUtil = ResultUtil.paranErr(); } return resultUtil; } /** * 删除出租车订单 */ @RequestMapping(value = "/delete") @ResponseBody public Object delete(@RequestParam Integer tOrderTaxiId) { TOrderTaxi tOrderTaxi = tOrderTaxiService.selectById(tOrderTaxiId); tOrderTaxi.setIsDelete(2); tOrderTaxiService.updateById(tOrderTaxi); return SUCCESS_TIP; } /** * 出租车订单改派司机 */ @RequestMapping(value = "/selectDriver") @ResponseBody public Object selectDriver(@RequestParam Integer orderId,@RequestParam Integer driverId) { //修改订单 TOrderTaxi tOrderTaxi = tOrderTaxiService.selectById(orderId); //修改之前司机状态 -- 空闲 TDriver oldDriver = tDriverService.selectById(tOrderTaxi.getDriverId()); oldDriver.setState(2); tDriverService.updateById(oldDriver); //查找司机对象 TDriver nowDriver = tDriverService.selectById(driverId); nowDriver.setState(3); tDriverService.updateById(nowDriver); //修改出租车订单 tOrderTaxi.setState(tOrderTaxi.getOldState()); tOrderTaxi.setDriverId(driverId); tOrderTaxi.setCarId(nowDriver.getCarId()); tOrderTaxiService.updateById(tOrderTaxi); //增加推送 Map map = new HashMap<>(); map.put("orderId", tOrderTaxi.getId().toString()); map.put("orderType", "2"); String result = HttpRequestUtil.postRequest(PushURL.order_push_url, map); System.out.println("出租车改派:【orderId="+tOrderTaxi.getId().toString()+"】,调用接口:"+result); return SUCCESS_TIP; } /** * 取消出租车订单 */ @RequestMapping(value = "/cancel") @ResponseBody public Object cancel(@RequestParam Integer tOrderTaxiId) { TOrderTaxi tOrderTaxi = tOrderTaxiService.selectById(tOrderTaxiId); redisUtil.remove("orderMark"); //修改之前司机状态 -- 空闲 if(null != tOrderTaxi.getDriverId()){ TDriver driver = tDriverService.selectById(tOrderTaxi.getDriverId()); driver.setState(2); tDriverService.updateById(driver); } List allItems = redisFifoQueue.getAllItems(); if (!allItems.isEmpty()){ if (allItems.get(0).equals(tOrderTaxi.getId().toString())){ redisUtil.remove("orderMark"); } } tOrderTaxi.setState(10); tOrderTaxiService.updateById(tOrderTaxi); redisFifoQueue.removeOrderById(tOrderTaxi.getId().toString()); //增加推送 Map map = new HashMap<>(); map.put("id", tOrderTaxi.getId().toString()); map.put("orderType", "2"); String result = HttpRequestUtil.postRequest(PushURL.cancel_order_url, map); System.out.println("出租车取消:【orderId="+tOrderTaxi.getId().toString()+"】,调用接口:"+result); return SUCCESS_TIP; } /** * 修改出租车订单 */ @RequestMapping(value = "/update") @ResponseBody public Object update(TOrderTaxi tOrderTaxi) { tOrderTaxiService.updateById(tOrderTaxi); return SUCCESS_TIP; } /** * 出租车订单详情 */ @RequestMapping(value = "/detail/{tOrderTaxiId}") @ResponseBody public Object detail(@PathVariable("tOrderTaxiId") Integer tOrderTaxiId) { return tOrderTaxiService.selectById(tOrderTaxiId); } @ResponseBody @PostMapping("/add") public ResultUtil add(String passengers, String passengersPhone, String startAddress, String endAddress, Integer orderType, String travelTime, String remark){ try { startAddress = startAddress.replaceAll("& #40;", "\\(");//特殊字符转义 startAddress = startAddress.replaceAll("& #41;", "\\)"); TOrderTaxi tOrderTaxi = new TOrderTaxi(); tOrderTaxi.setStartAddress(startAddress); endAddress = endAddress.replaceAll("& #40;", "\\(");//特殊字符转义 endAddress = endAddress.replaceAll("& #41;", "\\)"); tOrderTaxi.setEndAddress(endAddress); tOrderTaxi.setPassengers(passengers); tOrderTaxi.setPassengersPhone(passengersPhone); tOrderTaxi.setOrderType(orderType); if(orderType == 1){ tOrderTaxi.setTravelTime(new Date()); }else if(ToolUtil.isNotEmpty(travelTime)){ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); tOrderTaxi.setTravelTime(sdf.parse(travelTime)); } Map geocoding_s = gdMapGeocodingUtil.geocoding(null, null, null, tOrderTaxi.getStartAddress()); if(Integer.valueOf(geocoding_s.get("status").toString()) != 0){ return ResultUtil.error("无效的起点"); } Map geocoding_e = gdMapGeocodingUtil.geocoding(null, null, null, tOrderTaxi.getEndAddress()); if(Integer.valueOf(geocoding_e.get("status").toString()) != 0){ return ResultUtil.error("无效的终点"); } List s = (List)geocoding_s.get("data"); List e = (List)geocoding_e.get("data"); if(s.size() == 0){ return ResultUtil.error("未查询到有效的起点"); } if(e.size() == 0){ return ResultUtil.error("未查询到有效的终点"); } tOrderTaxi.setType(1); TUser tUser = itUserService.selectOne(new EntityWrapper().eq("phone", tOrderTaxi.getPassengersPhone()).eq("state", 1).ne("flag", 3)); if(null == tUser){ tUser = new TUser(); tUser.setState(1); tUser.setFlag("1"); tUser.setInsertTime(new Date()); tUser.setPhone(tOrderTaxi.getPassengersPhone()); tUser.setName(tOrderTaxi.getPassengers()); tUser.setIsAuth(1); itUserService.insert(tUser); } tOrderTaxi.setUserId(tUser.getId()); tOrderTaxi.setOrderNum(this.getOrderNum()); tOrderTaxi.setPlacementAddress(tOrderTaxi.getStartAddress()); tOrderTaxi.setPlacementLon(Double.valueOf(s.get(0).split(",")[0])); tOrderTaxi.setPlacementLat(Double.valueOf(s.get(0).split(",")[1])); tOrderTaxi.setStartLon(Double.valueOf(s.get(0).split(",")[0])); tOrderTaxi.setStartLat(Double.valueOf(s.get(0).split(",")[1])); tOrderTaxi.setEndLon(Double.valueOf(e.get(0).split(",")[0])); tOrderTaxi.setEndLat(Double.valueOf(e.get(0).split(",")[1])); tOrderTaxi.setMileage(0D); tOrderTaxi.setOrderMoney(new BigDecimal(0)); tOrderTaxi.setTravelMoney(new BigDecimal(0)); tOrderTaxi.setParkMoney(new BigDecimal(0)); tOrderTaxi.setRoadTollMoney(new BigDecimal(0)); tOrderTaxi.setRedPacketMoney(new BigDecimal(0)); tOrderTaxi.setCouponMoney(new BigDecimal(0)); tOrderTaxi.setInsertTime(new Date()); tOrderTaxi.setIsReassign(1); tOrderTaxi.setState(1);//待接单 tOrderTaxi.setSubstitute(0); tOrderTaxi.setOrderSource(5); tOrderTaxi.setIsDelete(1); tOrderTaxiService.insert(tOrderTaxi); if(tOrderTaxi.getState() == 1){ //推送司机抢单 this.pushOrder(tOrderTaxi); } //添加消息 systemNoticeService.addSystemNotice(1, "您的出租车订单已下单成功,我们正在为您指派司机,请稍后!", tOrderTaxi.getUserId(), 1); }catch (Exception e){ e.printStackTrace(); return ResultUtil.runErr(); } return ResultUtil.success(); } public synchronized String getOrderNum() throws Exception{ int size = tOrderTaxiService.selectCount(null); return "TAXI" + String.valueOf(1000000 + size + 1).substring(1); } /** * 推送订单给司机抢单 * @param orderTaxi * @throws Exception */ public void pushOrder(TOrderTaxi orderTaxi) throws Exception{ new Thread(new Runnable() { @Override public void run() { try { orderIds.add(orderTaxi.getId());//添加记录,防止调用接口重复提醒无人接单 String vehicle = redisUtil.getValue("VEHICLE"); List integers = new ArrayList<>(); if(ToolUtil.isNotEmpty(vehicle)){ integers = JSON.parseArray(vehicle).toJavaList(Integer.class); } TCompany query = companyCityService.query(String.valueOf(orderTaxi.getStartLon()), String.valueOf(orderTaxi.getStartLat()));//获取起点所属分公司 List querys = pushOrderService.querys(null, 2, query.getId());//获取需要推送的次数 for(int i = 1; i <= querys.size(); i++){ TSysPushOrder pushOrder = pushOrderService.querys(i, 2, query.getId()).get(0); //获取空闲司机 List list = driverService.queryIdleDriver(2, orderTaxi.getStartLon(), orderTaxi.getStartLat(), pushOrder.getPushDistance(), null);//所有附近空闲司机 if(list.size() > 0){ double driverProportion = pushOrder.getDriverProportion() / 100;//推送占比计算成小数 int lastIndex = Double.valueOf(list.size() * driverProportion).intValue();//计算占比转成整数(下标截取) lastIndex = lastIndex == 0 ? list.size() : lastIndex; list = list.subList(0, lastIndex);//获取空闲司机中占比数据 for(TDriver driver : list){//开始进行推送 //查询是否在限制推单范围内 boolean bo = false; for(Integer integer : integers){ if(integer.compareTo(driver.getId()) == 0){ bo = true; break; } } if(bo){ continue; } pushUtil.pushOrderState(2, driver.getId(), orderTaxi.getId(), 2, orderTaxi.getState(), pushOrder.getPushTime()); } } Thread.sleep(pushOrder.getPushTime() * 1000);//设置等待时间 Integer state = tOrderTaxiService.selectById(orderTaxi.getId()).getState(); if(state > 1){ break; } if(i == querys.size() && state == 1){ pushUtil.pushEndPush(1, orderTaxi.getUserId(), orderTaxi.getId(), 2); orderIds.remove(orderTaxi.getId()); // 新增接单大厅 Date date = new Date(); LocalDateTime localDateTime = date.toInstant() .atZone(java.time.ZoneId.systemDefault()) .toLocalDateTime(); LocalDateTime newDateTime = localDateTime.plusMinutes(3); Date newDate = java.util.Date.from(newDateTime.atZone(java.time.ZoneId.systemDefault()).toInstant()); orderTaxi.setEndTime(newDate); tOrderTaxiService.updateById(orderTaxi); } } } catch (Exception e) { e.printStackTrace(); } } }).start(); } }