From 6f77dcd80df0081466d49c933fff74afedf867b8 Mon Sep 17 00:00:00 2001 From: liujie <1793218484@qq.com> Date: 星期四, 31 七月 2025 10:10:21 +0800 Subject: [PATCH] Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/java/QianYunTong --- UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/dao/OrderPrivateCarMapper.java | 5 UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/vo/TripOrderVo.java | 145 ++++++++ UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/taxi/service/impl/OrderTaxiServiceImpl.java | 25 + UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/OrderCrossCityMapper.java | 5 UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/taxi/dao/mapping/OrderTaxiMapper.xml | 46 ++ UserQYTTravel/guns-admin/src/main/resources/application.yml | 50 + UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/server/IOrderPrivateCarService.java | 4 UserQYTTravel/guns-admin/pom.xml | 21 + UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/server/impl/OrderPrivateCarServiceImpl.java | 24 + UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/taxi/service/IOrderTaxiService.java | 12 UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/taxi/dao/OrderTaxiMapper.java | 12 UserQYTTravel/guns-admin/src/main/resources/static/fonts/AlibabaPuHuiTi-3-105-Heavy.ttf | 0 UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/mapping/OrderCrossCityMapper.xml | 47 ++ UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/OrderCrossCityServiceImpl.java | 24 + UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/IOrderCrossCityService.java | 3 UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/pdf/TripSheetGenerator.java | 335 ++++++++++++++++++ UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/EmailUtil.java | 52 ++ UserQYTTravel/guns-admin/src/main/resources/static/img/logo.png | 0 UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/api/OrderController.java | 212 +++++++++++ UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/dao/mapping/OrderPrivateCarMapper.xml | 48 ++ 20 files changed, 1,053 insertions(+), 17 deletions(-) diff --git a/UserQYTTravel/guns-admin/pom.xml b/UserQYTTravel/guns-admin/pom.xml index 14973e1..3db4b12 100644 --- a/UserQYTTravel/guns-admin/pom.xml +++ b/UserQYTTravel/guns-admin/pom.xml @@ -232,6 +232,27 @@ <artifactId>quartz</artifactId> <version>2.2.1</version> </dependency> +<!-- 生成pdf--> + <dependency> + <groupId>com.itextpdf</groupId> + <artifactId>itextpdf</artifactId> + <version>5.5.13.3</version> + </dependency> + <dependency> + <groupId>com.itextpdf</groupId> + <artifactId>itext-asian</artifactId> + <version>5.2.0</version> + </dependency> +<!-- 邮件依赖--> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-mail</artifactId> + </dependency> + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + <version>2.11.0</version> + </dependency> </dependencies> diff --git a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/api/OrderController.java b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/api/OrderController.java index b6fb4c6..a6f588b 100644 --- a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/api/OrderController.java +++ b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/api/OrderController.java @@ -13,9 +13,12 @@ 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.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; @@ -39,7 +42,9 @@ 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.text.SimpleDateFormat; import java.util.*; @@ -129,6 +134,18 @@ 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; @@ -2172,4 +2189,199 @@ } } + @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>> list = null; +// 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; +// +// } +// +// // 将经纬度转换为城市并设置到数据中 +// 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 (type == 1 || type == 3){ +// //获取车型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", ""); // 经纬度为空时设为空 +// } +// } +// } + List<Map<String,Object>> raw = fetchTrips(uid, type, pageNum, size); + return ResultUtil.success(TripOrderVo.getTripOrderVo(raw)); +// return ResultUtil.success(TripOrderVo.getTripOrderVo(list)); + }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 = "orders", required = false, dataType = "List<OrderWarpper>"), + @ApiImplicitParam(value = "收件人邮箱", name = "recipientEmail", required = false, dataType = "String"), + @ApiImplicitParam(name = "Authorization", value = "Bearer +token", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....") + }) + public ResultUtil sendTripSheetEmail( @RequestParam boolean allOrders, + @RequestBody(required = false) List<TripOrderVo> orders, + @RequestParam String recipientEmail, + HttpServletRequest request) { + try { + // 从Redis中获取当前用户ID + Integer uid = userInfoService.getUserIdFormRedis(request); + if (null == uid) { + return ResultUtil.tokenErr(); + } + if (allOrders) { + // 这里复用 queryMyTripList 逻辑,不分页,type=0 表示全部 + List<Map<String, Object>> rawList = fetchTrips(uid, 0, null, null); + orders = TripOrderVo.getTripOrderVo(rawList); + } else { + // allOrders=false,需要前端传 orders + if (orders == null || orders.isEmpty()) { + return ResultUtil.error("请传入 orders 或者选择全部订单"); + } + } + String filePath = tripSheetGenerator.generatePdf(orders); + File attachment = new File(filePath); + emailUtil.sendEmailWithAttachment(recipientEmail, "行程单", "请查收您的行程单", attachment); + attachment.delete(); // 发送成功后删除临时文件 + return ResultUtil.success("邮件发送成功"); + } catch (Exception e) { + e.printStackTrace(); + return ResultUtil.error("邮件发送失败"); + } + } + } diff --git a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/OrderCrossCityMapper.java b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/OrderCrossCityMapper.java index 9dbc933..02d3c8c 100644 --- a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/OrderCrossCityMapper.java +++ b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/OrderCrossCityMapper.java @@ -91,4 +91,9 @@ * @return */ List<Map<String, Object>> queryRedEnvelope(@Param("uid") Integer uid); + + List<Map<String, Object>> queryMyTripList(@Param("uid") Integer uid, @Param("pageNum") Integer pageNum, + @Param("size") Integer size); + + List<Map<String, Object>> queryMyTripListAll(@Param("uid") Integer uid); } diff --git a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/mapping/OrderCrossCityMapper.xml b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/mapping/OrderCrossCityMapper.xml index 85bc470..e3a9e73 100644 --- a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/mapping/OrderCrossCityMapper.xml +++ b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/mapping/OrderCrossCityMapper.xml @@ -612,4 +612,51 @@ and DATE_FORMAT(a.travelTime, '%Y-%m-%d') = #{day} </if> </select> + + + <select id="queryMyTripList" resultType="map"> + select + id as orderId, + DATE_FORMAT(insertTime, '%Y-%m-%d %H:%i') as orderTime, + DATE_FORMAT(travelTime, '%m月?d日?%H:%i') as time, + startAddress as startAddress, + endAddress as endAddress, + driverId as driverId, + (3) as orderType, + state as state, + oldState as oldState, + thankYouFee, + passengersPhone, + payMoney, + endServiceTime, + companyId, + arriveTime, + boardingTime, + boardingLon, + boardingLat + from t_order_cross_city where userId = #{uid} order by insertTime desc limit #{pageNum}, #{size} + </select> + + <select id="queryMyTripListAll" resultType="map"> + select + id as orderId, + DATE_FORMAT(insertTime, '%Y-%m-%d %H:%i') as orderTime, + DATE_FORMAT(travelTime, '%m月?d日?%H:%i') as time, + startAddress as startAddress, + endAddress as endAddress, + driverId as driverId, + (3) as orderType, + state as state, + oldState as oldState, + thankYouFee, + passengersPhone, + payMoney, + endServiceTime, + companyId, + arriveTime, + boardingTime, + boardingLon, + boardingLat + from t_order_cross_city where userId = #{uid} order by insertTime desc + </select> </mapper> \ No newline at end of file diff --git a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/IOrderCrossCityService.java b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/IOrderCrossCityService.java index 2f6c4d5..d1f2130 100644 --- a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/IOrderCrossCityService.java +++ b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/IOrderCrossCityService.java @@ -329,5 +329,6 @@ void promotion(Integer orderId); - + List<Map<String, Object>> queryMyTripList(Integer uid, Integer pageNum, Integer size) throws Exception; + List<Map<String, Object>> queryMyTripListAll(Integer uid) throws Exception; } diff --git a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/OrderCrossCityServiceImpl.java b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/OrderCrossCityServiceImpl.java index 2629341..9605ec5 100644 --- a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/OrderCrossCityServiceImpl.java +++ b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/OrderCrossCityServiceImpl.java @@ -2737,4 +2737,28 @@ } } } + + @Override + public List<Map<String, Object>> queryMyTripList(Integer uid, Integer pageNum, Integer size) throws Exception { + pageNum = (pageNum - 1) * size; + List<Map<String, Object>> maps = orderCrossCityMapper.queryMyTripList(uid, pageNum, size); + for (Map<String, Object> map : maps) { + if (Integer.valueOf(String.valueOf(map.get("state"))) == 11) { + map.put("state", map.get("oldState")); + } + } + return maps; + } + + @Override + public List<Map<String, Object>> queryMyTripListAll(Integer uid) throws Exception { + + List<Map<String, Object>> maps = orderCrossCityMapper.queryMyTripListAll(uid); + for (Map<String, Object> map : maps) { + if (Integer.valueOf(String.valueOf(map.get("state"))) == 11) { + map.put("state", map.get("oldState")); + } + } + return maps; + } } diff --git a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/dao/OrderPrivateCarMapper.java b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/dao/OrderPrivateCarMapper.java index 28e3d56..f2a49a8 100644 --- a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/dao/OrderPrivateCarMapper.java +++ b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/dao/OrderPrivateCarMapper.java @@ -98,4 +98,9 @@ @Param("state") Integer state, @Param("lon") String lon, @Param("lat") String lat); + + List<Map<String, Object>> queryMyTripList(@Param("uid") Integer uid, @Param("pageNum") Integer pageNum, + @Param("size") Integer size); + + List<Map<String, Object>> queryMyTripListAll(@Param("uid") Integer uid); } diff --git a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/dao/mapping/OrderPrivateCarMapper.xml b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/dao/mapping/OrderPrivateCarMapper.xml index 6bd4523..0644455 100644 --- a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/dao/mapping/OrderPrivateCarMapper.xml +++ b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/dao/mapping/OrderPrivateCarMapper.xml @@ -581,4 +581,52 @@ </if> </select> + + + <select id="queryMyTripList" resultType="map"> + select + id as orderId, + rideType as rideType, + DATE_FORMAT(insertTime, '%Y-%m-%d %H:%i') as orderTime, + DATE_FORMAT(travelTime, '%m月?d日?%H:%i') as time, + startAddress as startAddress, + endAddress as endAddress, + driverId as driverId, + (1) as orderType, + state as state, + oldState as oldState, + thankYouFee, + passengersPhone, + payMoney, + endServiceTime, + companyId, + arriveTime, + boardingTime, + boardingLon, + boardingLat + from t_order_private_car where userId = #{uid} order by insertTime desc limit #{pageNum}, #{size} + </select> + <select id="queryMyTripListAll" resultType="map"> + select + id as orderId, + rideType as rideType, + DATE_FORMAT(insertTime, '%Y-%m-%d %H:%i') as orderTime, + DATE_FORMAT(travelTime, '%m月?d日?%H:%i') as time, + startAddress as startAddress, + endAddress as endAddress, + driverId as driverId, + (1) as orderType, + state as state, + oldState as oldState, + thankYouFee, + passengersPhone, + payMoney, + endServiceTime, + companyId, + arriveTime, + boardingTime, + boardingLon, + boardingLat + from t_order_private_car where userId = #{uid} order by insertTime desc + </select> </mapper> \ No newline at end of file diff --git a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/server/IOrderPrivateCarService.java b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/server/IOrderPrivateCarService.java index 3a6bb39..19033bb 100644 --- a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/server/IOrderPrivateCarService.java +++ b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/server/IOrderPrivateCarService.java @@ -332,4 +332,8 @@ void promotion(Integer orderId); + List<Map<String, Object>> queryMyTripList(Integer uid, Integer pageNum, Integer size) throws Exception; + + List<Map<String, Object>> queryMyTripListAll(Integer uid) throws Exception; + } diff --git a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/server/impl/OrderPrivateCarServiceImpl.java b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/server/impl/OrderPrivateCarServiceImpl.java index 4e068a8..6fcdab1 100644 --- a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/server/impl/OrderPrivateCarServiceImpl.java +++ b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/server/impl/OrderPrivateCarServiceImpl.java @@ -2775,4 +2775,28 @@ } } } + + @Override + public List<Map<String, Object>> queryMyTripList(Integer uid, Integer pageNum, Integer size) throws Exception { + pageNum = (pageNum - 1) * size; + List<Map<String, Object>> maps = orderPrivateCarMapper.queryMyTripList(uid, pageNum, size); + for (Map<String, Object> map : maps) { + if (Integer.valueOf(String.valueOf(map.get("state"))) == 11) { + map.put("state", map.get("oldState")); + } + } + return maps; + } + + @Override + public List<Map<String, Object>> queryMyTripListAll(Integer uid) throws Exception { + + List<Map<String, Object>> maps = orderPrivateCarMapper.queryMyTripListAll(uid); + for (Map<String, Object> map : maps) { + if (Integer.valueOf(String.valueOf(map.get("state"))) == 11) { + map.put("state", map.get("oldState")); + } + } + return maps; + } } diff --git a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/vo/TripOrderVo.java b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/vo/TripOrderVo.java new file mode 100644 index 0000000..ace2687 --- /dev/null +++ b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/vo/TripOrderVo.java @@ -0,0 +1,145 @@ +package com.stylefeng.guns.modular.system.model.vo; + +import com.stylefeng.guns.modular.system.warpper.OrderWarpper; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class TripOrderVo implements Comparable{ + + @ApiModelProperty("订单id") + private Integer orderId; + @ApiModelProperty("订单日期") + private String orderTime; + @ApiModelProperty("出行时间/(小件物流的取货时间)") + private String time; + @ApiModelProperty("起点名称") + private String startAddress; + @ApiModelProperty("终点名称") + private String endAddress; + @ApiModelProperty("公司id(服务商)") + private Integer companyId; + @ApiModelProperty("司机id") + private Integer driverId; + @ApiModelProperty("车辆id") + private Integer carId; + @ApiModelProperty("行程人电话") + private String passengersPhone; + @ApiModelProperty("订单状态(1=待接单,2=待出发,3=待到达预约地点,4=待乘客上车,5=服务中,6=完成服务,7=待支付,8=待评价,9=已完成,10=已取消,11=改派中,12=取消待支付)<br/>" + + "小件物流订单状态(1=待接单,2=待出发,3=待到达预约地点,4=待取货,5=送货中,6=已送达,7=待支付,8=需补差价,9=已取货,10=已取消,11=已支付差价") + private Integer state; + @ApiModelProperty("用车时长") + private Integer carTime; + @ApiModelProperty("车型id") + private Integer serverCarModelId; + @ApiModelProperty("车型") + private String serverCarModel; +// @ApiModelProperty("订单金额") +// private Double orderMoney; + @ApiModelProperty("支付金额") + private Double payMoney; +// @ApiModelProperty("差价金额") +// private Double differenceMoney; + @ApiModelProperty("感谢费") + private Double thankYouFee; +// @ApiModelProperty("开票状态(1=未开票,2=已开票)") +// private Integer invoice; + @ApiModelProperty("订单名称") + private String orderName; + @ApiModelProperty("订单类型(1=专车,2=出租车,3=跨城出行,4=小件物流,5=包车)") + private Integer orderType; + @ApiModelProperty("下单时间") + private Long insertTime; + @ApiModelProperty("服务结束事件") + private String endServiceTime; + @ApiModelProperty("乘车类型(1=独享,2=一口价,3=拼车)") + private Integer rideType; + @ApiModelProperty("上车经度") + private Double boardingLon; + @ApiModelProperty("上车纬度") + private Double boardingLat; + @ApiModelProperty("上车时间") + private LocalDateTime boardingTime; + @ApiModelProperty("到达时间") + private LocalDateTime arriveTime; + @ApiModelProperty("城市") + private String city; + @ApiModelProperty("服务商") + private String companyName; + + public static List<TripOrderVo> getTripOrderVo(List<Map<String, Object>> maps) { + List<TripOrderVo> list = new ArrayList<>(); + if (null != maps) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S"); + for (Map<String, Object> map : maps) { + TripOrderVo tripOrderVo = new TripOrderVo(); + + tripOrderVo.setRideType(null != map.get("rideType") ? Integer.valueOf(String.valueOf(map.get("rideType"))) : 1); + tripOrderVo.setOrderId(null != map.get("orderId") ? Integer.valueOf(String.valueOf(map.get("orderId"))) : 0); + tripOrderVo.setOrderTime(null != map.get("orderTime") ? String.valueOf(map.get("orderTime")) : ""); + tripOrderVo.setTime(null != map.get("time") ? String.valueOf(map.get("time")) : ""); + tripOrderVo.setStartAddress(null != map.get("startAddress") ? String.valueOf(map.get("startAddress")) : ""); + tripOrderVo.setEndAddress(null != map.get("endAddress") ? String.valueOf(map.get("endAddress")) : ""); + tripOrderVo.setState(null != map.get("state") ? Integer.valueOf(String.valueOf(map.get("state"))) : 0); +// tripOrderVo.setOrderMoney(null != map.get("orderMoney") ? Double.valueOf(String.valueOf(map.get("orderMoney"))) : 0); + tripOrderVo.setPayMoney(null != map.get("payMoney") ? Double.valueOf(String.valueOf(map.get("payMoney"))) : 0); +// tripOrderVo.setInvoice(null != map.get("invoice") ? Integer.valueOf(String.valueOf(map.get("invoice"))) : 0); + tripOrderVo.setOrderName(null != map.get("orderName") ? String.valueOf(map.get("orderName")) : ""); + tripOrderVo.setInsertTime(null != map.get("insertTime") ? Long.valueOf(String.valueOf(map.get("insertTime"))) : 0); + tripOrderVo.setOrderType(null != map.get("orderType") ? Integer.valueOf(String.valueOf(map.get("orderType"))) : 0); + tripOrderVo.setDriverId(null != map.get("driverId") ? Integer.valueOf(String.valueOf(map.get("driverId"))) : 0); + tripOrderVo.setCarTime(null != map.get("carTime") ? Integer.valueOf(String.valueOf(map.get("carTime"))) : 0); + tripOrderVo.setServerCarModel(null != map.get("serverCarModel") ? String.valueOf(map.get("serverCarModel")) : ""); +// tripOrderVo.setDifferenceMoney(null != map.get("differenceMoney") ? Double.valueOf(map.get("differenceMoney").toString()) : 0D); + tripOrderVo.setThankYouFee(null != map.get("thankYouFee") ? Double.valueOf(map.get("thankYouFee").toString()) : 0D); + tripOrderVo.setEndServiceTime(null != map.get("endServiceTime") ? String.valueOf(map.get("endServiceTime")) : ""); + tripOrderVo.setCompanyId(null != map.get("companyId") ? Integer.valueOf(String.valueOf(map.get("companyId"))) : 0); + tripOrderVo.setPassengersPhone(null != map.get("passengersPhone") ? String.valueOf(map.get("passengersPhone")) : ""); + tripOrderVo.setBoardingLon(null != map.get("boardingLon") ? Double.valueOf(String.valueOf(map.get("boardingLon"))) : 0D); + tripOrderVo.setBoardingLat(null != map.get("boardingLat") ? Double.valueOf(String.valueOf(map.get("boardingLat"))) : 0D); + tripOrderVo.setCity(null != map.get("city") ? String.valueOf(map.get("city")) : ""); + tripOrderVo.setBoardingTime(null != map.get("boardingTime") ? + LocalDateTime.parse(String.valueOf(map.get("boardingTime")), formatter) : null); + tripOrderVo.setArriveTime(null != map.get("arriveTime") ? + LocalDateTime.parse(String.valueOf(map.get("arriveTime")), formatter) : null); + tripOrderVo.setCompanyName(null != map.get("companyName") ? String.valueOf(map.get("companyName")) : ""); + tripOrderVo.setCarId(null != map.get("carId") ? Integer.valueOf(String.valueOf(map.get("carId"))) : 0); + tripOrderVo.setServerCarModelId(null != map.get("serverCarModelId") ? Integer.valueOf(String.valueOf(map.get("serverCarModelId"))) : 0); + list.add(tripOrderVo); + } + + } + Collections.sort(list); + return list; + } + + @Override + public int compareTo(Object o) { + if (o instanceof OrderWarpper) { + OrderWarpper s = (OrderWarpper) o; + if(this.insertTime == null || s.getInsertTime() == null){ + return -1; + } + if (this.insertTime > s.getInsertTime()) { + return -1; + } else if (this.insertTime == s.getInsertTime()) { + return 0; + } else { + return 1; + } + } + return 0; + } +} diff --git a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/pdf/TripSheetGenerator.java b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/pdf/TripSheetGenerator.java new file mode 100644 index 0000000..eb4a023 --- /dev/null +++ b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/pdf/TripSheetGenerator.java @@ -0,0 +1,335 @@ +package com.stylefeng.guns.modular.system.pdf; + +import com.itextpdf.text.*; +import com.itextpdf.text.pdf.BaseFont; +import com.itextpdf.text.pdf.PdfPCell; +import com.itextpdf.text.pdf.PdfPTable; +import com.itextpdf.text.pdf.PdfWriter; +import com.stylefeng.guns.modular.system.model.vo.TripOrderVo; +import com.stylefeng.guns.modular.system.warpper.OrderWarpper; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.stereotype.Component; +import org.springframework.web.context.ServletContextAware; + +import java.io.*; +import java.net.URL; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; +import java.util.UUID; + +@Component +public class TripSheetGenerator { + + @Value("${trip.sheet.filePath}") + private String pdfDir; + + // 内置中文备用字体 + private static final String FALLBACK_FONT = "STSong-Light"; + private static final String FALLBACK_ENCODING = "UniGB-UCS2-H"; + + // 完整日期时间格式 + private static final DateTimeFormatter DATE_TIME_FORMATTER = + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + public String generatePdf(List<TripOrderVo> orders) throws DocumentException, IOException { + if (orders == null || orders.isEmpty()) { + throw new IllegalArgumentException("订单列表不能为空"); + } + + String fileName = "行程单_" + UUID.randomUUID() + ".pdf"; + String filePath = pdfDir + fileName; + File file = new File(filePath); + FileUtils.forceMkdirParent(file); + + Document document = new Document(PageSize.A4); + PdfWriter.getInstance(document, new FileOutputStream(file)); + document.open(); + + // 新布局:Logo+标题 → 主标题 → 信息行 → 表格 + addLogoAndTitle(document); + addMainTitle(document); + addTripInfo(document, orders); + addOrderTable(document, orders); + + document.close(); + return filePath; + } + + private void addLogoAndTitle(Document document) throws DocumentException { + try { + document.setMargins(10, 50, 50, 50); // 左=0,右=50,上=50,下=50(单位:pt) + Resource logoResource = new ClassPathResource("static/img/logo.png"); + if (logoResource.exists()) { + Image logo = Image.getInstance(logoResource.getURL()); + logo.scaleToFit(80, 40); // 保持logo原有尺寸(宽100pt,高40pt) + + // 1. 调整表格列宽:左列刚好容纳logo,右列仅够放下文字(缩小间距) + // 列宽比例:左列100pt(logo宽度),右列80pt(文字宽度,足够放下“贵人家园”) + PdfPTable layoutTable = new PdfPTable(new float[]{81f, 100f}); // 左列(Logo),右列100f(文字) + layoutTable.setWidthPercentage(35); + layoutTable.setSpacingAfter(15f); // 与下方主标题的间距不变 + layoutTable.setHorizontalAlignment(Element.ALIGN_LEFT); // 整体左对齐,避免居中导致的空隙 + + // 2. 左单元格(logo):消除内边距,紧贴右侧 + PdfPCell logoCell = new PdfPCell(logo); + logoCell.setBorder(Rectangle.NO_BORDER); // 无边框 + logoCell.setPadding(0); // 去除内边距(关键:默认padding会导致空隙) + logoCell.setVerticalAlignment(Element.ALIGN_MIDDLE); // 垂直居中对齐 + logoCell.setHorizontalAlignment(Element.ALIGN_RIGHT); //logo居中 + layoutTable.addCell(logoCell); + + // 3. 右单元格(文字):消除内边距,紧贴左侧 + Font titleFont = getChineseFont(18, Font.BOLD); + Paragraph titlePara = new Paragraph("贵人家园", titleFont); + titlePara.setAlignment(Element.ALIGN_LEFT); // 文字左对齐,贴近logo + titlePara.setSpacingBefore(0); + titlePara.setSpacingAfter(0); + + PdfPCell titleCell = new PdfPCell(titlePara); + titleCell.setBorder(Rectangle.NO_BORDER); // 无边框 + titleCell.setPadding(0); // 去除内边距(关键) + titleCell.setVerticalAlignment(Element.ALIGN_MIDDLE); // 垂直居中对齐 + titleCell.setHorizontalAlignment(Element.ALIGN_LEFT); // 文字靠左,贴近logo + layoutTable.addCell(titleCell); + + document.add(layoutTable); + // 关键3:恢复页面默认边距(避免影响后续内容) + document.setMargins(50, 50, 50, 50); + } else { + // 降级处理(无logo时) + Font titleFont = getChineseFont(18, Font.BOLD); + Paragraph fallbackTitle = new Paragraph("贵人家园", titleFont); + fallbackTitle.setAlignment(Element.ALIGN_LEFT); + fallbackTitle.setSpacingAfter(15f); + document.add(fallbackTitle); + } + } catch (Exception e) { + System.err.println("Logo加载失败: " + e.getMessage()); + // 降级处理 + Font titleFont = getChineseFont(18, Font.BOLD); + Paragraph fallbackTitle = new Paragraph("贵人家园", titleFont); + fallbackTitle.setAlignment(Element.ALIGN_LEFT); + fallbackTitle.setSpacingAfter(15f); + document.add(fallbackTitle); + } + } + + // 新增主标题方法(原 addTitle 逻辑调整) + private void addMainTitle(Document document) throws DocumentException { + Font titleFont = getChineseFont(18, Font.BOLD); + Paragraph mainTitle = new Paragraph("贵人家园—打车—行程单", titleFont); + mainTitle.setAlignment(Element.ALIGN_CENTER); + mainTitle.setSpacingBefore(5f); + mainTitle.setSpacingAfter(15f); + document.add(mainTitle); + } + + + + // 修改信息行构建逻辑(以第一行为例) + private void addTripInfo(Document document, List<TripOrderVo> orders) throws DocumentException { + if (orders.isEmpty()) return; + TripOrderVo first = orders.get(0); + TripOrderVo last = orders.size() > 1 ? orders.get(orders.size() - 1) : first; + + Font infoFont = getChineseFont(10, Font.NORMAL); + // 申请时间现在的时间 + String applyTime = DATE_TIME_FORMATTER.format(LocalDateTime.now()); + + // 行程时间格式化 + String tripTimeStart = first.getBoardingTime() != null + ? DATE_TIME_FORMATTER.format(first.getBoardingTime()) : "N/A"; + String tripTimeEnd = last.getBoardingTime() != null + ? DATE_TIME_FORMATTER.format(last.getBoardingTime()) : "N/A"; + String tripTime = tripTimeStart + " 至 " + tripTimeEnd; + + // 总金额计算(修复:先定义 totalText 并拼接内容) + double totalAmount = orders.stream() + .mapToDouble(o -> o.getPayMoney() != null ? o.getPayMoney() : 0) + .sum(); + String totalPrefix = "共计" + orders.size() + "单行程,合计"; + String totalMoney = String.format("%.2f元", totalAmount); + String totalText = totalPrefix + totalMoney; // 正确定义 totalText + + + // ========== 第一行:申请时间 + 行程时间(均带分隔条) ========== + // 关键:通过表格列宽控制分隔条宽度(8pt) + PdfPTable line1Table = new PdfPTable(4); + line1Table.setWidthPercentage(100); + line1Table.setSpacingAfter(5f); + // 列宽比例:分隔条列固定为8pt,内容列按比例分配 + line1Table.setWidths(new float[]{4, 200, 4, 374}); + + // 列1:申请时间前的蓝色分隔条(宽度由表格列宽控制) + line1Table.addCell(createBlueSeparatorCell()); + + // 列2:申请时间内容 + Paragraph applyPara = new Paragraph(); + applyPara.add(new Chunk("申请时间:", infoFont)); + applyPara.add(new Chunk(applyTime, infoFont)); + line1Table.addCell(createContentCell(applyPara)); + + // 列3:行程时间前的蓝色分隔条(与列1宽度一致) + line1Table.addCell(createBlueSeparatorCell()); + + // 列4:行程时间内容 + Paragraph tripPara = new Paragraph(); + tripPara.add(new Chunk("行程时间:", infoFont)); + tripPara.add(new Chunk(tripTime, infoFont)); + line1Table.addCell(createContentCell(tripPara)); + + document.add(line1Table); + + + // ========== 第二行:手机号 + 共计订单(均带分隔条) ========== + PdfPTable line2Table = new PdfPTable(4); + line2Table.setWidthPercentage(100); + line2Table.setSpacingAfter(15f); + // 与第一行保持完全相同的列宽比例(确保分隔条对齐) + line2Table.setWidths(new float[]{4, 200, 4, 374}); + + // 列1:手机号前的蓝色分隔条 + line2Table.addCell(createBlueSeparatorCell()); + + // 列2:手机号内容 + Paragraph phonePara = new Paragraph(); + phonePara.add(new Chunk("行程人手机号:", infoFont)); + phonePara.add(new Chunk(first.getPassengersPhone() != null ? first.getPassengersPhone() : "N/A", infoFont)); + line2Table.addCell(createContentCell(phonePara)); + + // 列3:共计订单前的蓝色分隔条 + line2Table.addCell(createBlueSeparatorCell()); + + // 列4:共计订单内容 + Paragraph totalPara = new Paragraph(); + totalPara.add(new Chunk(totalPrefix, infoFont)); + Font totalFont = getChineseFont(10, Font.BOLD); + totalFont.setColor(BaseColor.RED); + totalPara.add(new Chunk(totalMoney, totalFont)); + line2Table.addCell(createContentCell(totalPara)); + + document.add(line2Table); + } + + /** + * 蓝色分隔条单元格(宽度由所在表格的列宽控制,无需单独设置) + */ + private PdfPCell createBlueSeparatorCell() { + PdfPCell separatorCell = new PdfPCell(); + // 关键:不设置宽度,完全由表格的 setWidths() 控制 + separatorCell.setBackgroundColor(BaseColor.BLUE); // 蓝色背景 + separatorCell.setBorder(Rectangle.NO_BORDER); // 无边框 + separatorCell.setMinimumHeight(8); // 匹配文字行高 + separatorCell.setPadding(0); // 去除内边距,确保分隔条紧凑 + return separatorCell; + } + + /** + * 内容单元格样式 + */ + private PdfPCell createContentCell(Paragraph content) { + PdfPCell cell = new PdfPCell(content); + cell.setBorder(Rectangle.NO_BORDER); + cell.setPaddingLeft(5); // 内容与分隔条的间距 + cell.setHorizontalAlignment(Element.ALIGN_LEFT); + return cell; + } + private void addOrderTable(Document document, List<TripOrderVo> orders) throws DocumentException { + // 调整列宽:第1列(序号)加宽至1.5f + float[] columnWidths = {1.5f, 2f, 2f, 3f, 2f, 3f, 3f, 2f}; + PdfPTable table = new PdfPTable(columnWidths); + table.setWidthPercentage(100); + table.setSpacingBefore(10f); // 与上方信息行的间距 + + // 表头样式(蓝色背景,白色文字,居中) + Font headerFont = getChineseFont(10, Font.BOLD); + headerFont.setColor(BaseColor.WHITE); + BaseColor headerBg = new BaseColor(59, 130, 246); + String[] headers = {"序号","服务商","车型","上车时间","城市","起点","终点","金额"}; + + for (String header : headers) { + PdfPCell cell = new PdfPCell(new Paragraph(header, headerFont)); + cell.setBackgroundColor(headerBg); + cell.setPadding(5); + cell.setHorizontalAlignment(Element.ALIGN_CENTER); + table.addCell(cell); + } + + // 单元格样式(居中对齐,统一处理) + Font cellFont = getChineseFont(9, Font.NORMAL); + for (int i = 0; i < orders.size(); i++) { + TripOrderVo order = orders.get(i); + // 序号列:强制居中,内容为 i+1 + addCenteredCell(table, String.valueOf(i + 1), cellFont); + addCenteredCell(table, order.getCompanyName(), cellFont); + addCenteredCell(table, order.getServerCarModel(), cellFont); + addCenteredCell(table, + order.getBoardingTime() != null + ? DATE_TIME_FORMATTER.format(order.getBoardingTime()) + : "N/A", + cellFont); + addCenteredCell(table, order.getCity(), cellFont); + addCenteredCell(table, order.getStartAddress(), cellFont); + addCenteredCell(table, order.getEndAddress(), cellFont); + + // 金额列:右对齐 + PdfPCell moneyCell = new PdfPCell( + new Paragraph(String.format("%.2f元", + order.getPayMoney() != null ? order.getPayMoney() : 0), + cellFont) + ); + moneyCell.setHorizontalAlignment(Element.ALIGN_RIGHT); + moneyCell.setPadding(5); + table.addCell(moneyCell); + } + + document.add(table); + } + + // 辅助方法:创建居中对齐的单元格 + private void addCenteredCell(PdfPTable table, String text, Font font) { + PdfPCell cell = new PdfPCell(new Paragraph(text != null ? text : "", font)); + cell.setPadding(5); + cell.setHorizontalAlignment(Element.ALIGN_CENTER); + table.addCell(cell); + } + + private void addTableCell(PdfPTable table, String text, Font font) { + PdfPCell cell = new PdfPCell(new Paragraph(text != null ? text : "", font)); + cell.setPadding(5); + table.addCell(cell); + } + + /** + * 获取中文字体,优先自定义字体,fallback到 CJK 内置 + */ + private Font getChineseFont(float size, int style) { + // 自定义字体 + try { + Resource res = new ClassPathResource("static/fonts/AlibabaPuHuiTi-3-105-Heavy.ttf"); + if (res.exists()) { + BaseFont bf = BaseFont.createFont( + res.getURL().toString(), BaseFont.IDENTITY_H, BaseFont.EMBEDDED); + return new Font(bf, size, style); + } + } catch (Exception e) { + System.err.println("加载自定义字体失败: " + e.getMessage()); + } + // 内置 CJK 字体 + try { + BaseFont bf = BaseFont.createFont( + FALLBACK_FONT, FALLBACK_ENCODING, BaseFont.EMBEDDED); + return new Font(bf, size, style); + } catch (Exception e) { + System.err.println("加载备用字体失败: " + e.getMessage()); + return new Font(Font.FontFamily.HELVETICA, size, style); + } + } +} diff --git a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/EmailUtil.java b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/EmailUtil.java new file mode 100644 index 0000000..e09f2dd --- /dev/null +++ b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/EmailUtil.java @@ -0,0 +1,52 @@ +package com.stylefeng.guns.modular.system.util; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.mail.SimpleMailMessage; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.MimeMessageHelper; +import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; +import javax.mail.MessagingException; +import javax.mail.internet.MimeMessage; +import java.io.File; + +@Component +public class EmailUtil { + private final JavaMailSender javaMailSender; + + // 从配置文件读取发件人邮箱(必须与spring.mail.username一致) + @Value("${spring.mail.username}") + private String fromEmail; + + @Autowired + public EmailUtil(JavaMailSender javaMailSender) { + this.javaMailSender = javaMailSender; + } + + public void sendEmailWithAttachment(String to, String subject, String text, File attachment) throws MessagingException { + MimeMessage message = javaMailSender.createMimeMessage(); + MimeMessageHelper helper = new MimeMessageHelper(message, true); + + // 设置发件人(必须与配置的spring.mail.username一致) + helper.setFrom(fromEmail); + // 设置收件人 + helper.setTo(to); + // 设置邮件主题和内容 + helper.setSubject(subject); + helper.setText(text); + // 添加附件 + helper.addAttachment(attachment.getName(), attachment); + + // 发送邮件 + javaMailSender.send(message); + } + + public void sendSimpleEmail(String to, String subject, String text) { + SimpleMailMessage message = new SimpleMailMessage(); + message.setTo(to); + message.setSubject(subject); + message.setText(text); + javaMailSender.send(message); + } +} \ No newline at end of file diff --git a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/taxi/dao/OrderTaxiMapper.java b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/taxi/dao/OrderTaxiMapper.java index 6f8920e..dce3cc5 100644 --- a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/taxi/dao/OrderTaxiMapper.java +++ b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/taxi/dao/OrderTaxiMapper.java @@ -89,4 +89,16 @@ */ List<OrderTaxi> queryByState_(@Param("uid") Integer uid, @Param("orderType") Integer orderType, @Param("type") Integer type, @Param("state") Integer...state); + + /** + * 获取用户的行程列表 + * @param uid + * @param pageNum + * @param size + * @return + */ + List<Map<String, Object>> queryMyTripList(@Param("uid") Integer uid, @Param("pageNum") Integer pageNum, + @Param("size") Integer size); + + List<Map<String, Object>> queryMyTripListAll(@Param("uid") Integer uid); } diff --git a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/taxi/dao/mapping/OrderTaxiMapper.xml b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/taxi/dao/mapping/OrderTaxiMapper.xml index da859a5..60883ea 100644 --- a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/taxi/dao/mapping/OrderTaxiMapper.xml +++ b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/taxi/dao/mapping/OrderTaxiMapper.xml @@ -414,4 +414,50 @@ and `type` = #{type} </if> </select> + + <select id="queryMyTripList" resultType="map"> + select + id as orderId, + DATE_FORMAT(insertTime, '%Y-%m-%d %H:%i') as orderTime, + DATE_FORMAT(travelTime, '%m月%d日 %H:%i') as time, + startAddress as startAddress, + endAddress as endAddress, + driverId as driverId, + (2) as orderType, + state as state, + oldState as oldState, + thankYouFee, + passengersPhone, + payMoney, + endServiceTime, + companyId, + arriveTime, + boardingTime, + boardingLon, + boardingLat + from t_order_taxi where userId = #{uid} order by insertTime desc limit #{pageNum}, #{size} + </select> + + <select id="queryMyTripListAll" resultType="map"> + select + id as orderId, + DATE_FORMAT(insertTime, '%Y-%m-%d %H:%i') as orderTime, + DATE_FORMAT(travelTime, '%m月%d日 %H:%i') as time, + startAddress as startAddress, + endAddress as endAddress, + driverId as driverId, + (2) as orderType, + state as state, + oldState as oldState, + thankYouFee, + passengersPhone, + payMoney, + endServiceTime, + companyId, + arriveTime, + boardingTime, + boardingLon, + boardingLat + from t_order_taxi where userId = #{uid} order by insertTime desc + </select> </mapper> \ No newline at end of file diff --git a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/taxi/service/IOrderTaxiService.java b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/taxi/service/IOrderTaxiService.java index be2011e..caf8829 100644 --- a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/taxi/service/IOrderTaxiService.java +++ b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/taxi/service/IOrderTaxiService.java @@ -313,4 +313,16 @@ void promotion(Integer orderId); + /** + * 获取我的行程列表 + * @param uid + * @param pageNum + * @param size + * @return + * @throws Exception + */ + List<Map<String, Object>> queryMyTripList(Integer uid, Integer pageNum, Integer size) throws Exception; + + List<Map<String, Object>> queryMyTripListAll(Integer uid) throws Exception; + } diff --git a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/taxi/service/impl/OrderTaxiServiceImpl.java b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/taxi/service/impl/OrderTaxiServiceImpl.java index 3b5bc2a..839b316 100644 --- a/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/taxi/service/impl/OrderTaxiServiceImpl.java +++ b/UserQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/taxi/service/impl/OrderTaxiServiceImpl.java @@ -2332,4 +2332,29 @@ } } } + + @Override + public List<Map<String, Object>> queryMyTripList(Integer uid, Integer pageNum, Integer size) throws Exception { + pageNum = (pageNum - 1) * size; + List<Map<String, Object>> maps = orderTaxiMapper.queryMyTripList(uid, pageNum, size); + for (Map<String, Object> map : maps) { + if (Integer.valueOf(String.valueOf(map.get("state"))) == 11) { + map.put("state", map.get("oldState")); + } + } + return maps; + } + + @Override + public List<Map<String, Object>> queryMyTripListAll(Integer uid) throws Exception { + + List<Map<String, Object>> maps = orderTaxiMapper.queryMyTripListAll(uid); + for (Map<String, Object> map : maps) { + if (Integer.valueOf(String.valueOf(map.get("state"))) == 11) { + map.put("state", map.get("oldState")); + } + } + return maps; + } + } diff --git a/UserQYTTravel/guns-admin/src/main/resources/application.yml b/UserQYTTravel/guns-admin/src/main/resources/application.yml index 3d56997..8a3a7ca 100644 --- a/UserQYTTravel/guns-admin/src/main/resources/application.yml +++ b/UserQYTTravel/guns-admin/src/main/resources/application.yml @@ -33,14 +33,14 @@ host: 192.168.110.80 port: 6379 password: 123456 -# redis: -# host: 172.21.35.151 -# port: 6512 -# password: SC_cache@20#25 -# database: 0 -# timeout: 1000 -# cluster: -# nodes: 172.21.35.151:6512,172.21.35.152:6512,172.21.35.153:6512,172.21.35.151:6513,172.21.35.152:6513,172.21.35.153:6513 + # redis: + # host: 172.21.35.151 + # port: 6512 + # password: SC_cache@20#25 + # database: 0 + # timeout: 1000 + # cluster: + # nodes: 172.21.35.151:6512,172.21.35.152:6512,172.21.35.153:6512,172.21.35.151:6513,172.21.35.152:6513,172.21.35.153:6513 mybatis-plus: typeAliasesPackage: com.stylefeng.guns.modular @@ -72,13 +72,13 @@ filters: wall,mergeStat -#spring: -# datasource: -# url: jdbc:mysql://172.21.35.140:8066/traffic_scdb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=Asia/Shanghai -# username: traffic_scusr -# password: QYT_sc@20#25 -# db-name: traffic_scdb #用来搜集数据库的所有表 -# filters: wall,mergeStat + #spring: + # datasource: + # url: jdbc:mysql://172.21.35.140:8066/traffic_scdb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=Asia/Shanghai + # username: traffic_scusr + # password: QYT_sc@20#25 + # db-name: traffic_scdb #用来搜集数据库的所有表 + # filters: wall,mergeStat --- @@ -86,7 +86,7 @@ data: mongodb: uri: mongodb://192.168.110.80:27017/traveling_track -# uri: mongodb://qyt_jtcx:qyt_jtcx2025@172.21.35.195:27017,172.21.35.196:27017/traveling_track + # uri: mongodb://qyt_jtcx:qyt_jtcx2025@172.21.35.195:27017,172.21.35.196:27017/traveling_track --- @@ -127,3 +127,21 @@ #交通部推送数据功能开关 pushMinistryOfTransport: false + +#邮件配置 +spring: + mail: + host: smtp.qq.com + port: 465 + username: 1721849008@qq.com + password: nhnbmjfdywilcbdj # 这里是授权码,不是邮箱登录密码 + properties: + mail: + smtp: + ssl: + enable: true # 启用 SSL 加密(根据端口是否为 465 决定,通常需要开启) + auth: true # 启用身份验证(必须为 true) +# pdf生成位置 +trip: + sheet: + filePath: D:/qytPdf/ \ No newline at end of file diff --git a/UserQYTTravel/guns-admin/src/main/resources/static/fonts/AlibabaPuHuiTi-3-105-Heavy.ttf b/UserQYTTravel/guns-admin/src/main/resources/static/fonts/AlibabaPuHuiTi-3-105-Heavy.ttf new file mode 100644 index 0000000..3d865c2 --- /dev/null +++ b/UserQYTTravel/guns-admin/src/main/resources/static/fonts/AlibabaPuHuiTi-3-105-Heavy.ttf Binary files differ diff --git a/UserQYTTravel/guns-admin/src/main/resources/static/img/logo.png b/UserQYTTravel/guns-admin/src/main/resources/static/img/logo.png new file mode 100644 index 0000000..0576707 --- /dev/null +++ b/UserQYTTravel/guns-admin/src/main/resources/static/img/logo.png Binary files differ -- Gitblit v1.7.1