| | |
| | | import com.stylefeng.guns.modular.smallLogistics.server.IOrderLogisticsService; |
| | | import com.stylefeng.guns.modular.specialTrain.model.OrderPrivateCar; |
| | | import com.stylefeng.guns.modular.specialTrain.server.IOrderPrivateCarService; |
| | | import com.stylefeng.guns.modular.system.dao.CarMapper; |
| | | import com.stylefeng.guns.modular.system.dao.SystemPriceMapper; |
| | | import com.stylefeng.guns.modular.system.model.*; |
| | | import com.stylefeng.guns.modular.system.model.vo.TripOrderVo; |
| | | import com.stylefeng.guns.modular.system.model.vo.TripSheetVo; |
| | | import com.stylefeng.guns.modular.system.model.vo.UnPayOrderVO; |
| | | import com.stylefeng.guns.modular.system.pdf.TripSheetGenerator; |
| | | import com.stylefeng.guns.modular.system.service.*; |
| | | import com.stylefeng.guns.modular.system.util.*; |
| | | import com.stylefeng.guns.modular.system.util.qianyuntong.model.QYTPaymentCallback; |
| | |
| | | import io.swagger.annotations.ApiImplicitParams; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | |
| | | import javax.annotation.Resource; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.File; |
| | | import java.io.PrintWriter; |
| | | import java.io.Serializable; |
| | | import java.lang.reflect.InvocationTargetException; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.*; |
| | | |
| | |
| | | |
| | | @Autowired |
| | | private IOrderService orderService; |
| | | |
| | | |
| | | @Autowired |
| | | private IDriverService driverService; |
| | | |
| | | |
| | | @Autowired |
| | | private WeChatUtil weChatUtil; |
| | | |
| | | |
| | | @Autowired |
| | | private IOrderPrivateCarService orderPrivateCarService; |
| | | |
| | | |
| | | @Autowired |
| | | private GDMapGeocodingUtil gdMapGeocodingUtil; |
| | | |
| | | @Autowired |
| | | private IComplaintService complaintService; |
| | | |
| | | |
| | | @Autowired |
| | | private IOrderEvaluateService orderEvaluateService; |
| | | |
| | | |
| | | @Autowired |
| | | private IOrderCrossCityService orderCrossCityService; |
| | | |
| | | |
| | | @Autowired |
| | | private IOrderLogisticsService orderLogisticsService; |
| | | |
| | |
| | | private IUserCouponRecordService userCouponRecordService; |
| | | @Value("${pushMinistryOfTransport}") |
| | | private boolean pushMinistryOfTransport; |
| | | |
| | | |
| | | @Value("${trip.sheet.filePath}") |
| | | private String filePath; |
| | | @Autowired |
| | | private EmailUtil emailUtil; |
| | | @Autowired |
| | | private TripSheetGenerator tripSheetGenerator; |
| | | @Autowired |
| | | private IServerCarModelService serverCarModelService; |
| | | |
| | | |
| | | |
| | | @Resource |
| | | private SystemPriceMapper systemPriceMapper; |
| | |
| | | @Resource |
| | | private RedisTemplate<String, Object> redisTemplate; |
| | | |
| | | @Resource |
| | | private ISystemPriceCityService systemPriceCityService; |
| | | |
| | | |
| | | |
| | | /** |
| | | * 获取正在进行中的订单 |
| | |
| | | map = orderCrossCityService.queryOrderInfo(orderId); |
| | | break; |
| | | } |
| | | |
| | | if(map.get("companyId") != null){ |
| | | Company companyId = companyService.selectById(map.get("companyId").toString()); |
| | | map.put("companyName", companyId.getName()); |
| | | }else { |
| | | String string = map.get("driverId").toString(); |
| | | Driver driver = driverService.selectById(string); |
| | | Company company = companyService.selectById(driver.getCompanyId()); |
| | | map.put("companyName", company.getName()); |
| | | } |
| | | if(map.get("telX") != null){ |
| | | map.put("driverPhone", map.get("telX")); |
| | | } |
| | |
| | | } |
| | | |
| | | OrderPrivateCar orderPrivateCar = orderPrivateCarService.selectById(orderId); |
| | | if(orderPrivateCar.getState()>1){ |
| | | Map<String, Object> query1 = systemPriceMapper.query(orderPrivateCar.getCompanyId(), 1, orderPrivateCar.getServerCarModelId()); |
| | | System.out.println("参数:"+orderPrivateCar.getCompanyId()+"|"+orderPrivateCar.getServerCarModelId()); |
| | | System.out.println("query1:"+query1); |
| | | if(orderPrivateCar.getState()>1) { |
| | | Map<String, String> geocode = gdMapGeocodingUtil.geocode(orderPrivateCar.getStartLon().toString(), orderPrivateCar.getStartLat().toString()); |
| | | String provinceCode = geocode.get("provinceCode"); |
| | | String cityCode = geocode.get("cityCode"); |
| | | String districtCode = geocode.get("districtCode"); |
| | | //获取匹配的城市价格配置 |
| | | SystemPriceCity systemPriceCity = systemPriceCityService.queryOne(provinceCode, cityCode, districtCode); |
| | | if (null == systemPriceCity) { |
| | | return ResultUtil.error("请先配置价格规则"); |
| | | } |
| | | Map<String, Object> query1 = systemPriceMapper.query(orderPrivateCar.getCompanyId(), 1, orderPrivateCar.getServerCarModelId(), systemPriceCity.getId()); |
| | | System.out.println("参数:" + orderPrivateCar.getCompanyId() + "|" + orderPrivateCar.getServerCarModelId()); |
| | | System.out.println("query1:" + query1); |
| | | //开始根据不同的方式计算金额 |
| | | if(query1!=null){ |
| | | JSONObject jsonObject = JSON.parseObject(query1.get("content").toString());//等待费 |
| | | JSONObject contentPutOne = JSON.parseObject(query1.get("contentPutOne").toString());//一人拼成 |
| | | JSONObject contentNotOne = JSON.parseObject(query1.get("contentNotOne").toString());//一人未拼成 |
| | | JSONObject contentPutTwo = JSON.parseObject(query1.get("contentPutTwo").toString());//2人拼成 |
| | | JSONObject contentNotTwo = JSON.parseObject(query1.get("contentNotTwo").toString());//2人未拼成 |
| | | JSONObject contentPutThree = JSON.parseObject(query1.get("contentPutThree").toString());//3人拼成 |
| | | if (query1 != null) { |
| | | JSONObject jsonObject = JSON.parseObject(query1.get("content").toString());//等待费 |
| | | JSONObject contentPutOne = JSON.parseObject(query1.get("contentPutOne").toString());//一人拼成 |
| | | JSONObject contentNotOne = JSON.parseObject(query1.get("contentNotOne").toString());//一人未拼成 |
| | | JSONObject contentPutTwo = JSON.parseObject(query1.get("contentPutTwo").toString());//2人拼成 |
| | | JSONObject contentNotTwo = JSON.parseObject(query1.get("contentNotTwo").toString());//2人未拼成 |
| | | JSONObject contentPutThree = JSON.parseObject(query1.get("contentPutThree").toString());//3人拼成 |
| | | JSONObject contentNotThree = JSON.parseObject(query1.get("contentNotThree").toString());//3人未拼成 |
| | | JSONObject contentExclusive = JSON.parseObject(query1.get("contentExclusive").toString());//独享 |
| | | JSONObject contentPrice = JSON.parseObject(query1.get("contentPrice").toString());//一口价 |
| | |
| | | orderInfoWarpper.setTime(arriveTime.substring(11,arriveTime.length()-3)); |
| | | } |
| | | return ResultUtil.success(orderInfoWarpper); |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | return ResultUtil.runErr(); |
| | | } |
| | | } |
| | | |
| | | |
| | | @ResponseBody |
| | | @PostMapping("/api/order/addAppeal") |
| | | @ApiOperation(value = "发起申诉", tags = {"用户端-服务中"}, notes = "",response = OrderInfoWarpper.class) |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(value = "订单id", name = "orderId", required = true, dataType = "int"), |
| | | @ApiImplicitParam(value = "订单类型(1=专车,2=出租车,3=城际)", name = "orderType", required = true, dataType = "int"), |
| | | @ApiImplicitParam(value = "申诉描述", name = "abnormalIntro", required = true, dataType = "String"), |
| | | @ApiImplicitParam(value = "申诉图片", name = "abnormalImg", required = true, dataType = "String"), |
| | | @ApiImplicitParam(name = "Authorization", value = "Bearer +token", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....") |
| | | }) |
| | | public ResultUtil<OrderInfoWarpper> addAppeal(Integer orderId, Integer orderType,String abnormalIntro, String abnormalImg, HttpServletRequest request){ |
| | | try { |
| | | Integer uid = userInfoService.getUserIdFormRedis(request); |
| | | if(null == uid){ |
| | | return ResultUtil.tokenErr(); |
| | | } |
| | | switch (orderType){ |
| | | case 1://专车 |
| | | orderPrivateCarService.addAppeal(uid, orderId,abnormalIntro,abnormalImg); |
| | | break; |
| | | case 2://出租车 |
| | | orderTaxiService.addAppeal(uid,orderId,abnormalIntro,abnormalImg); |
| | | break; |
| | | case 3://跨城 |
| | | orderCrossCityService.addAppeal(uid,orderId,abnormalIntro,abnormalImg); |
| | | break; |
| | | } |
| | | return ResultUtil.success(); |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | return ResultUtil.runErr(); |
| | |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 推广订单支付成功回调 |
| | | * |
| | | * @param orderId |
| | | * @return |
| | | */ |
| | | private void promotion(Integer orderType,Integer orderId){ |
| | | switch (orderType){ |
| | | case 1: |
| | | orderPrivateCarService.promotion(orderId); |
| | | break; |
| | | case 2: |
| | | orderTaxiService.promotion(orderId); |
| | | break; |
| | | case 3: |
| | | orderCrossCityService.promotion(orderId); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | |
| | | |
| | | @ResponseBody |
| | | @PostMapping("/api/get/unPayOrder") |
| | | @ApiOperation(value = "获取未支付订单", tags = {"用户端-首页"}, notes = "") |
| | |
| | | } |
| | | } |
| | | |
| | | @PostMapping("/api/order/queryMyTripList") |
| | | @ApiOperation(value = "获取我的行程列表", tags = {"用户端-个人中心"}, notes = "") |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(value = "订单类型(1=专车,2=出租车,3=跨城出行)", name = "type", required = true, dataType = "int"), |
| | | @ApiImplicitParam(value = "页码(首页1)", name = "pageNum", required = true, dataType = "int"), |
| | | @ApiImplicitParam(value = "页条数", name = "size", required = true, dataType = "int"), |
| | | @ApiImplicitParam(name = "Authorization", value = "Bearer +token", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....") |
| | | }) |
| | | public ResultUtil<List<TripOrderVo>> queryMyTripList(Integer type, Integer pageNum, Integer size, HttpServletRequest request){ |
| | | try { |
| | | Integer uid = userInfoService.getUserIdFormRedis(request); |
| | | if(null == uid){ |
| | | return ResultUtil.tokenErr(); |
| | | } |
| | | |
| | | List<Map<String,Object>> raw = fetchTrips(uid, type, pageNum, size); |
| | | return ResultUtil.success(TripOrderVo.getTripOrderVo(raw)); |
| | | |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | return ResultUtil.runErr(); |
| | | } |
| | | } |
| | | /** |
| | | * 私有:拉取指定 type 的行程列表。 |
| | | * type=0 → 全部类型;1/2/3 → 对应三种服务;pageNum/size 负责分页。 |
| | | * 对于 type==1 或 3,内部额外加载 serverCarModel 信息。 |
| | | */ |
| | | private List<Map<String,Object>> fetchTrips( |
| | | Integer uid, Integer type, Integer pageNum, Integer size) throws Exception { |
| | | |
| | | List<Map<String, Object>> list = new ArrayList<>(); |
| | | if (type == null || type == 0) { |
| | | list.addAll(orderPrivateCarService.queryMyTripListAll(uid)); |
| | | list.addAll(orderTaxiService.queryMyTripListAll(uid)); |
| | | list.addAll(orderCrossCityService.queryMyTripListAll(uid)); |
| | | } else { |
| | | switch (type) { |
| | | case 1: |
| | | list = orderPrivateCarService.queryMyTripList(uid, pageNum, size); |
| | | break; |
| | | case 2: |
| | | list = orderTaxiService.queryMyTripList(uid, pageNum, size); |
| | | break; |
| | | case 3: |
| | | list = orderCrossCityService.queryMyTripList(uid, pageNum, size); |
| | | break; |
| | | default: |
| | | throw new IllegalArgumentException("无效的订单类型:" + type); |
| | | } |
| | | } |
| | | // 排序 |
| | | list.sort((a, b) -> { |
| | | Date da = (Date) a.get("boardingTime"); |
| | | Date db = (Date) b.get("boardingTime"); |
| | | if (da == null && db == null) return 0; |
| | | if (da == null) return 1; // a 在后面 |
| | | if (db == null) return -1; // b 在后面 |
| | | return db.compareTo(da); // 都不为空,再按时间倒序 |
| | | }); |
| | | // 将经纬度转换为城市并设置到数据中 |
| | | if (list != null && !list.isEmpty()) { |
| | | for (Map<String, Object> orderMap : list) { |
| | | // 获取经纬度(根据实际字段名调整) |
| | | Object lonObj = orderMap.get("boardingLon"); |
| | | Object latObj = orderMap.get("boardingLat"); |
| | | //获取公司id |
| | | Object companyId = orderMap.get("companyId"); |
| | | |
| | | Object serverCarModelId =null; |
| | | ServerCarModel serverCarModel = null; |
| | | if (orderMap.get("serverCarModelId") != null ){ |
| | | //获取车型id |
| | | serverCarModelId = orderMap.get("serverCarModelId"); |
| | | serverCarModel = serverCarModelService.selectById((Serializable) serverCarModelId); |
| | | } |
| | | |
| | | if (lonObj != null && latObj != null) { |
| | | String lon = lonObj.toString(); |
| | | String lat = latObj.toString(); |
| | | Company company = companyService.selectById((Serializable) companyId); |
| | | |
| | | try { |
| | | // 调用逆地理编码接口获取城市信息 |
| | | Map<String, String> geoInfo = gdMapGeocodingUtil.geocode(lon, lat); |
| | | // 将城市信息存入map,供后续转换VO使用 |
| | | orderMap.put("city", geoInfo.getOrDefault("city", "")); |
| | | orderMap.put("companyName", company.getName()); |
| | | if (serverCarModel != null) { |
| | | orderMap.put("serverCarModel", serverCarModel.getName()); |
| | | } |
| | | } catch (Exception e) { |
| | | // 记录转换失败日志,不中断流程 |
| | | System.err.println("经纬度转城市失败: " + lon + "," + lat + ",错误: " + e.getMessage()); |
| | | orderMap.put("city", ""); // 转换失败时设为空 |
| | | } |
| | | } else { |
| | | orderMap.put("city", ""); // 经纬度为空时设为空 |
| | | } |
| | | } |
| | | } |
| | | return list; |
| | | } |
| | | @PostMapping("/api/user/sendTripSheetEmail") |
| | | @ApiOperation(value = "发送行程单邮件", tags = {"用户端-个人中心"}, notes = "") |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(value = "行程单信息", name = "tripSheet", required = false, dataType = "com.stylefeng.guns.modular.system.model.vo.TripSheetVo"), |
| | | @ApiImplicitParam(name = "Authorization", value = "Bearer +token", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....") |
| | | }) |
| | | public ResultUtil sendTripSheetEmail(@RequestBody TripSheetVo tripSheet, |
| | | HttpServletRequest request) { |
| | | try { |
| | | // 从Redis中获取当前用户ID |
| | | Integer uid = userInfoService.getUserIdFormRedis(request); |
| | | if (null == uid) { |
| | | return ResultUtil.tokenErr(); |
| | | } |
| | | List<TripOrderVo> orderList = new ArrayList<>(); |
| | | if (tripSheet.isAllOrders()) { |
| | | // 这里复用 queryMyTripList 逻辑,不分页,type=0 表示全部 |
| | | List<Map<String, Object>> rawList = fetchTrips(uid, 0, null, null); |
| | | orderList = TripOrderVo.getTripOrderVo(rawList); |
| | | } else { |
| | | // 指定订单ID集合:验证并查询订单 |
| | | if (tripSheet.getOrderIdList() == null || tripSheet.getOrderIdList().isEmpty()) { |
| | | return ResultUtil.error("请传入订单ID集合或者选择全部订单"); |
| | | } |
| | | // 根据订单类型和ID查询订单 |
| | | orderList = queryOrdersByTypeAndIds(uid, tripSheet.getOrderType(), tripSheet.getOrderIdList()); |
| | | } |
| | | List<TripOrderVo> tripOrderVos = processTripOrderVos(orderList); |
| | | String filePath = tripSheetGenerator.generatePdf(tripOrderVos); |
| | | File attachment = new File(filePath); |
| | | emailUtil.sendEmailWithAttachment(tripSheet.getRecipientEmail(), "行程单", "请查收您的行程单", attachment); |
| | | attachment.delete(); // 发送成功后删除临时文件 |
| | | return ResultUtil.success("邮件发送成功"); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return ResultUtil.error("邮件发送失败"); |
| | | } |
| | | } |
| | | /** |
| | | * 根据订单类型和ID集合查询订单 |
| | | */ |
| | | private List<TripOrderVo> queryOrdersByTypeAndIds(Integer userId, Integer orderType, List<Integer> orderIds) throws InvocationTargetException, IllegalAccessException { |
| | | List<TripOrderVo> orderList = new ArrayList<>(); |
| | | |
| | | // 根据订单类型查询对应表的订单 |
| | | switch (orderType) { |
| | | case 1: |
| | | EntityWrapper<OrderPrivateCar> wrapper = new EntityWrapper<>(); |
| | | wrapper.in("id", orderIds); |
| | | List<OrderPrivateCar> orderPrivateCars = orderPrivateCarService.selectList(wrapper); |
| | | for (OrderPrivateCar orderPrivateCar : orderPrivateCars) { |
| | | TripOrderVo vo = new TripOrderVo(); |
| | | BeanUtils.copyProperties(orderPrivateCar, vo); |
| | | orderList.add(vo); |
| | | } |
| | | break; |
| | | case 2: |
| | | EntityWrapper<OrderTaxi> wrapper2 = new EntityWrapper<>(); |
| | | wrapper2.in("id", orderIds); |
| | | List<OrderTaxi> orderTaxis = orderTaxiService.selectList(wrapper2); |
| | | for (OrderTaxi orderTaxi : orderTaxis) { |
| | | TripOrderVo vo = new TripOrderVo(); |
| | | BeanUtils.copyProperties(orderTaxi, vo); |
| | | orderList.add(vo); |
| | | } |
| | | break; |
| | | case 3: |
| | | EntityWrapper<OrderCrossCity> wrapper3 = new EntityWrapper<>(); |
| | | wrapper3.in("id", orderIds); |
| | | List<OrderCrossCity> orderCrossCities = orderCrossCityService.selectList(wrapper3); |
| | | for (OrderCrossCity orderCrossCity : orderCrossCities) { |
| | | TripOrderVo vo = new TripOrderVo(); |
| | | BeanUtils.copyProperties(orderCrossCity, vo); |
| | | orderList.add(vo); |
| | | } |
| | | break; |
| | | default: |
| | | throw new IllegalArgumentException("无效的订单类型:" + orderType); |
| | | } |
| | | orderList.sort((a, b) -> { |
| | | Date da = a.getBoardingTime(); |
| | | Date db = b.getBoardingTime(); |
| | | if (da == null && db == null) return 0; |
| | | if (da == null) return 1; // a 在后面 |
| | | if (db == null) return -1; // b 在后面 |
| | | return db.compareTo(da); // 都不为空,再按时间倒序 |
| | | }); |
| | | |
| | | |
| | | return orderList; |
| | | } |
| | | |
| | | /** |
| | | * 处理行程订单VO列表,补充经纬度、公司和车型信息 |
| | | */ |
| | | private List<TripOrderVo> processTripOrderVos(List<TripOrderVo> orderVoList) { |
| | | if (orderVoList == null || orderVoList.isEmpty()) { |
| | | return new ArrayList<>(); |
| | | } |
| | | |
| | | for (TripOrderVo orderVo : orderVoList) { |
| | | // 处理经纬度转城市信息 |
| | | handleGeoInfoForVo(orderVo); |
| | | |
| | | // 处理公司信息 |
| | | handleCompanyInfoForVo(orderVo); |
| | | |
| | | // 处理车型信息 |
| | | handleCarModelInfoForVo(orderVo); |
| | | } |
| | | |
| | | return orderVoList; |
| | | } |
| | | |
| | | /** |
| | | * 处理经纬度转城市信息 |
| | | */ |
| | | private void handleGeoInfoForVo(TripOrderVo orderVo) { |
| | | // 直接从VO获取经纬度(假设VO中有对应的getter方法) |
| | | String lon = String.valueOf(orderVo.getBoardingLon()); |
| | | String lat = String.valueOf(orderVo.getBoardingLat()); |
| | | |
| | | if (StringUtils.isEmpty(lon) || StringUtils.isEmpty(lat)) { |
| | | orderVo.setCity(""); |
| | | return; |
| | | } |
| | | |
| | | try { |
| | | // 调用逆地理编码接口获取城市信息 |
| | | Map<String, String> geoInfo = gdMapGeocodingUtil.geocode(lon, lat); |
| | | orderVo.setCity(geoInfo.getOrDefault("city", "")); |
| | | } catch (Exception e) { |
| | | // 记录转换失败日志,不中断流程 |
| | | System.err.println("经纬度转城市失败: " + lon + "," + lat + ",错误: " + e.getMessage()); |
| | | orderVo.setCity(""); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 处理公司信息 |
| | | */ |
| | | private void handleCompanyInfoForVo(TripOrderVo orderVo) { |
| | | // 从VO获取公司ID |
| | | Integer companyId = orderVo.getCompanyId(); |
| | | if (companyId == null) { |
| | | orderVo.setCompanyName(""); |
| | | return; |
| | | } |
| | | |
| | | Company company = companyService.selectById(companyId); |
| | | if (company != null) { |
| | | orderVo.setCompanyName(company.getName()); |
| | | } else { |
| | | orderVo.setCompanyName(""); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 处理车型信息 |
| | | */ |
| | | private void handleCarModelInfoForVo(TripOrderVo orderVo) { |
| | | // 从VO获取车型ID |
| | | Integer serverCarModelId = orderVo.getServerCarModelId(); |
| | | if (serverCarModelId == null) { |
| | | orderVo.setServerCarModel(""); |
| | | return; |
| | | } |
| | | |
| | | ServerCarModel serverCarModel = serverCarModelService.selectById(serverCarModelId); |
| | | if (serverCarModel != null) { |
| | | orderVo.setServerCarModel(serverCarModel.getName()); |
| | | } else { |
| | | orderVo.setServerCarModel(""); |
| | | } |
| | | } |
| | | |
| | | } |