From 5171fcf8ccf77a670632e54d2c88642377bfc2ae Mon Sep 17 00:00:00 2001
From: liujie <1793218484@qq.com>
Date: 星期二, 10 三月 2026 16:55:21 +0800
Subject: [PATCH] 门票对接
---
ruoyi-system/src/main/java/com/ruoyi/system/service/TTicketOrderService.java | 2
ruoyi-system/src/main/java/com/ruoyi/system/model/TTicketOrder.java | 8 +
ruoyi-system/src/main/java/com/ruoyi/system/utils/ticketUtil/TicketUtil.java | 246 ++++++++++++++++++++++++++++++++++++++++-
ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/OrderController.java | 34 +++++
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTicketOrderServiceImpl.java | 50 ++++++++
5 files changed, 330 insertions(+), 10 deletions(-)
diff --git a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/OrderController.java b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/OrderController.java
index dc38c2c..b349467 100644
--- a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/OrderController.java
+++ b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/OrderController.java
@@ -5,6 +5,7 @@
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.dto.CreateOrderDto;
import com.ruoyi.system.dto.CreateOrderRequest;
+import com.ruoyi.system.model.TTicketOrder;
import com.ruoyi.system.query.AppletOrderListQuery;
import com.ruoyi.system.service.TAppUserService;
import com.ruoyi.system.service.TTicketOrderService;
@@ -16,10 +17,9 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
/**
* 下单接口
@@ -70,6 +70,32 @@
}
+ /**
+ * 退单
+ */
+ @ApiOperation(value = "退单")
+ @PostMapping("/refundOrder")
+ public R<Void> refundOrder(@RequestParam Integer orderId) throws Exception {
+ Integer userId = tokenService.getLoginUserApplet().getUserId();
+ TTicketOrder order = tTicketOrderService.getById(orderId);
+ if(order.getAppUserId().equals(userId)){
+ boolean refund = tTicketOrderService.refundOrder(order);
+ if(refund){
+ return R.ok();
+ }
+ }
+ return R.fail("退单失败");
+ }
+ /**
+ * 验票通知
+ */
+ @ApiOperation(value = "验票通知")
+ @PostMapping("/verifyTicket")
+ public R<Void> verifyTicket(HttpServletRequest request) throws Exception {
+
+ return R.ok();
+ }
+
}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/model/TTicketOrder.java b/ruoyi-system/src/main/java/com/ruoyi/system/model/TTicketOrder.java
index 728d88a..36c9b27 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/model/TTicketOrder.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/model/TTicketOrder.java
@@ -44,6 +44,10 @@
@TableField("order_price")
private BigDecimal orderPrice;
+ @ApiModelProperty(value = "票价")
+ @TableField("ticket_price")
+ private BigDecimal ticketPrice;
+
@ApiModelProperty(value = "支付时间")
@TableField("pay_time")
private LocalDateTime payTime;
@@ -80,6 +84,10 @@
@TableField("partner_order_id")
private String partnerOrderId;
+ @ApiModelProperty(value = "门票信息")
+ @TableField("visit_persons")
+ private String visitPersons;
+
@ApiModelProperty(value = "审核意见")
@TableField("audit_content")
private String auditContent;
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/TTicketOrderService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/TTicketOrderService.java
index d1512d3..7837c5d 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/TTicketOrderService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/TTicketOrderService.java
@@ -28,4 +28,6 @@
boolean addOrder(CreateOrderDto request, Integer userId) throws Exception;
+ boolean refundOrder(TTicketOrder order) throws Exception;
+
}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTicketOrderServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTicketOrderServiceImpl.java
index 5f9092a..6c3c92b 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTicketOrderServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTicketOrderServiceImpl.java
@@ -1,5 +1,7 @@
package com.ruoyi.system.service.impl;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.utils.OrderNos;
import com.ruoyi.system.dto.CreateOrderDto;
@@ -20,6 +22,8 @@
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@@ -102,6 +106,10 @@
order.setPartnerOrderId(createOrderVo.getPartnerOrderId());
order.setOrderPrice(new BigDecimal(createOrderVo.getOrderAmount()).setScale(2, BigDecimal.ROUND_HALF_UP));
+ // 获取票价
+ BigDecimal ticketPrice = order.getOrderPrice().divide(new BigDecimal(dto.getQuantity()), 2, BigDecimal.ROUND_HALF_UP);
+ order.setTicketPrice(ticketPrice);
+
String result = dto.getVisitPersons().stream()
.map(String::valueOf) // Integer 转 String
@@ -112,6 +120,48 @@
order.setTicketInfo(dto.getProductName());
boolean save = this.save(order);
+
+
return save;
}
+
+ @Override
+ public boolean refundOrder(TTicketOrder order) throws Exception {
+ String nowTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+ // 查询未使用的票
+ String visitPersons = order.getVisitPersons();
+ JSONArray jsonArray = JSONArray.parseArray(visitPersons);
+ List<String> ticketIds = new ArrayList<>();
+ for (int i = 0; i < jsonArray.size(); i++) {
+ JSONObject jsonObject = jsonArray.getJSONObject(i);
+ Integer status = jsonObject.getInteger("status");
+ if(status==null || status==0){
+ String ticketId = jsonObject.getString("ticketId");
+ ticketIds.add(ticketId);
+ }
+ }
+ if(ticketIds.isEmpty()){
+ throw new RuntimeException("无未使用的票");
+ }
+ boolean refund = ticketUtil.cannelTicket(order.getOrderNo(), order.getPartnerOrderId(), ticketIds);
+ if(refund){
+ for (int i = 0; i < jsonArray.size(); i++) {
+ JSONObject jsonObject = jsonArray.getJSONObject(i);
+ Integer status = jsonObject.getInteger("status");
+ if(status==null || status==0){
+ jsonObject.put("status",2);
+ jsonObject.put("refundTime",System.currentTimeMillis());
+ }
+ }
+
+ // jsonArray 转换为字符串
+ String result = jsonArray.toJSONString();
+ order.setVisitPersons(result);
+ order.setStatus(4);
+ order.setRefundMoney(order.getTicketPrice().multiply(new BigDecimal(ticketIds.size())));
+ boolean update = this.updateById(order);
+ return update;
+ }
+ return false;
+ }
}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/utils/ticketUtil/TicketUtil.java b/ruoyi-system/src/main/java/com/ruoyi/system/utils/ticketUtil/TicketUtil.java
index 53bbf7c..9285498 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/utils/ticketUtil/TicketUtil.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/utils/ticketUtil/TicketUtil.java
@@ -8,19 +8,24 @@
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.system.dto.CreateOrderRequest;
+import com.ruoyi.system.dto.VisitPerson;
import com.ruoyi.system.vo.CreateOrderVo;
import com.ruoyi.system.vo.TicketListVo;
-import java.util.ArrayList;
-import java.util.Base64;
-import java.util.HashMap;
-import java.util.List;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
/**
* 门票接口
*/
public class TicketUtil {
+ /**
+ * 获取门票列表
+ * @return
+ * @throws Exception
+ */
public List<TicketListVo> getTicketList() throws Exception {
ArrayList<TicketListVo> ticketListVos = new ArrayList<>();
String userId = "1d9a42e0-9de3-451b-9964-4e9f8e62b101";
@@ -123,6 +128,12 @@
}
+ /**
+ * 创建订单
+ * @param request
+ * @return
+ * @throws Exception
+ */
public CreateOrderVo saveOrder(CreateOrderRequest request) throws Exception {
String userId = "1d9a42e0-9de3-451b-9964-4e9f8e62b101";
String method = "createOrder";
@@ -193,7 +204,7 @@
byte[] decodedBytes = Base64.getDecoder().decode(responseBody);
String decodedResponse = new String(decodedBytes, "UTF-8");
System.out.println("Base64解码后的响应: " + decodedResponse);
- String res_code = JSONObject.parseObject(decodedResponse).get("res_code").toString();
+ String res_code = JSONObject.parseObject(decodedResponse).getJSONObject("responseHead").getString("res_code");
if("1000".equals(res_code)){
String responseBody1 = JSONObject.parseObject(decodedResponse).get("responseBody").toString();
String decryptedResponseBody = DesUtil.decrypt(responseBody1, desKey);
@@ -207,7 +218,7 @@
return createOrderVo;
}else {
- String res_msg = JSONObject.parseObject(decodedResponse).get("res_msg").toString();
+ String res_msg = JSONObject.parseObject(decodedResponse).getJSONObject("responseHead").getString("res_msg");
System.out.println("错误信息: " + res_msg);
throw new RuntimeException(res_msg);
}
@@ -219,8 +230,231 @@
return null;
}
+
+
+
+ /**
+ * 支付订单
+ * @param
+ * @return
+ * @throws Exception
+ */
+ public String payOrder(String orderId,String partnerOrderId) throws Exception {
+ String userId = "1d9a42e0-9de3-451b-9964-4e9f8e62b101";
+ String method = "payOrder";
+ String timestamp = System.currentTimeMillis() + "";
+ String desKey = "TFD9BEOK"; // DES密钥必须是8字节
+ String userKey = "TFD9BEOK"; // 用于签名的用户密钥
+
+ // 1. 构建请求体数据
+ HashMap<String, Object> bodyData = new HashMap<>();
+ bodyData.put("orderId", orderId);
+ bodyData.put("partnerOrderId", partnerOrderId);
+
+ String requestBody = JSON.toJSONString(bodyData);
+ System.out.println("原始请求体: " + requestBody);
+
+ // 2. 使用DES加密请求体
+ String encryptedBody = DesUtil.encrypt(requestBody, desKey);
+ System.out.println("DES加密后的请求体: " + encryptedBody);
+
+ // 3. 生成签名
+ String params = userId + method + timestamp + encryptedBody + userKey;
+ String md5 = SecureUtil.md5(params);
+ System.out.println("MD5签名: " + md5);
+
+ // 4. 构建请求头
+ HashMap<String, Object> headMap = new HashMap<>();
+ headMap.put("user_id", userId);
+ headMap.put("method", method);
+ headMap.put("timestamp", timestamp);
+ headMap.put("sign", md5);
+
+ // 5. 构建完整的请求消息
+ HashMap<String, Object> fullRequestMap = new HashMap<>();
+ fullRequestMap.put("requestHead", headMap);
+ fullRequestMap.put("requestBody", encryptedBody);
+
+ // 6. 将完整消息转换为JSON字符串
+ String fullRequestJson = JSON.toJSONString(fullRequestMap);
+ System.out.println("完整请求JSON: " + fullRequestJson);
+
+ // 7. 对整个JSON字符串进行Base64编码
+ String base64EncodedRequest = Base64.getEncoder().encodeToString(fullRequestJson.getBytes("UTF-8"));
+ System.out.println("Base64编码后的请求: " + base64EncodedRequest);
+
+ // 8. 发送HTTP请求
+ HttpRequest post = HttpUtil.createPost("http://ota.huilvyun.com.cn:8086/scenic-ota/ota/v2/zshl/rent034/payOrder");
+
+ // 设置请求头
+ post.header("Content-Type", "text/plain;charset=UTF-8"); // 根据要求,可能是纯文本
+ // 或者如果是application/json,则使用:
+ // post.header("Content-Type", "application/json;charset=UTF-8");
+
+ // 直接将Base64编码后的字符串作为body发送
+ post.body(base64EncodedRequest);
+
+ System.out.println("发送请求...");
+ HttpResponse execute = post.execute();
+
+ // 9. 处理响应
+ System.out.println("响应状态码: " + execute.getStatus());
+ String responseBody = execute.body();
+ System.out.println("原始响应Body: " + responseBody);
+ // 10. 解析响应(假设响应也是Base64编码的)
+ if (responseBody != null && !responseBody.isEmpty()) {
+ try {
+ // 先Base64解码
+ byte[] decodedBytes = Base64.getDecoder().decode(responseBody);
+ String decodedResponse = new String(decodedBytes, "UTF-8");
+ System.out.println("Base64解码后的响应: " + decodedResponse);
+ String res_code = JSONObject.parseObject(decodedResponse).getJSONObject("responseHead").getString("res_code");
+ if("1000".equals(res_code)){
+ String responseBody1 = JSONObject.parseObject(decodedResponse).get("responseBody").toString();
+ String decryptedResponseBody = DesUtil.decrypt(responseBody1, desKey);
+ System.out.println("解密后的响应: " + decryptedResponseBody);
+ JSONObject jsonObject = JSONObject.parseObject(decryptedResponseBody);
+ String visitPersons = jsonObject.getJSONArray("visitPersons").toString();
+ return visitPersons;
+ }else {
+ String res_msg = JSONObject.parseObject(decodedResponse).getJSONObject("responseHead").getString("res_msg");
+ System.out.println("错误信息: " + res_msg);
+ throw new RuntimeException(res_msg);
+ }
+ } catch (IllegalArgumentException e) {
+ System.out.println("响应不是有效的Base64格式: " + e.getMessage());
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * 取消订单
+ * @param
+ * @return
+ * @throws Exception
+ */
+ public Boolean cannelTicket(String orderId,String partnerOrderId,List<String> refundDetailIds) throws Exception {
+ String userId = "1d9a42e0-9de3-451b-9964-4e9f8e62b101";
+ String method = "cannelTicket";
+ String timestamp = System.currentTimeMillis() + "";
+ String desKey = "TFD9BEOK"; // DES密钥必须是8字节
+ String userKey = "TFD9BEOK"; // 用于签名的用户密钥
+
+ // 1. 构建请求体数据
+ HashMap<String, Object> bodyData = new HashMap<>();
+ bodyData.put("orderId", orderId);
+ bodyData.put("partnerOrderId", partnerOrderId);
+ bodyData.put("refundDetailIds", refundDetailIds);
+
+ String requestBody = JSON.toJSONString(bodyData);
+ System.out.println("原始请求体: " + requestBody);
+
+ // 2. 使用DES加密请求体
+ String encryptedBody = DesUtil.encrypt(requestBody, desKey);
+ System.out.println("DES加密后的请求体: " + encryptedBody);
+
+ // 3. 生成签名
+ String params = userId + method + timestamp + encryptedBody + userKey;
+ String md5 = SecureUtil.md5(params);
+ System.out.println("MD5签名: " + md5);
+
+ // 4. 构建请求头
+ HashMap<String, Object> headMap = new HashMap<>();
+ headMap.put("user_id", userId);
+ headMap.put("method", method);
+ headMap.put("timestamp", timestamp);
+ headMap.put("sign", md5);
+
+ // 5. 构建完整的请求消息
+ HashMap<String, Object> fullRequestMap = new HashMap<>();
+ fullRequestMap.put("requestHead", headMap);
+ fullRequestMap.put("requestBody", encryptedBody);
+
+ // 6. 将完整消息转换为JSON字符串
+ String fullRequestJson = JSON.toJSONString(fullRequestMap);
+ System.out.println("完整请求JSON: " + fullRequestJson);
+
+ // 7. 对整个JSON字符串进行Base64编码
+ String base64EncodedRequest = Base64.getEncoder().encodeToString(fullRequestJson.getBytes("UTF-8"));
+ System.out.println("Base64编码后的请求: " + base64EncodedRequest);
+
+ // 8. 发送HTTP请求
+ HttpRequest post = HttpUtil.createPost("http://ota.huilvyun.com.cn:8086/scenic-ota/ota/v2/zshl/rent034/cannelTicket");
+
+ // 设置请求头
+ post.header("Content-Type", "text/plain;charset=UTF-8"); // 根据要求,可能是纯文本
+ // 或者如果是application/json,则使用:
+ // post.header("Content-Type", "application/json;charset=UTF-8");
+
+ // 直接将Base64编码后的字符串作为body发送
+ post.body(base64EncodedRequest);
+
+ System.out.println("发送请求...");
+ HttpResponse execute = post.execute();
+
+ // 9. 处理响应
+ System.out.println("响应状态码: " + execute.getStatus());
+ String responseBody = execute.body();
+ System.out.println("原始响应Body: " + responseBody);
+ // 10. 解析响应(假设响应也是Base64编码的)
+ if (responseBody != null && !responseBody.isEmpty()) {
+ try {
+ // 先Base64解码
+ byte[] decodedBytes = Base64.getDecoder().decode(responseBody);
+ String decodedResponse = new String(decodedBytes, "UTF-8");
+ System.out.println("Base64解码后的响应: " + decodedResponse);
+ String res_code = JSONObject.parseObject(decodedResponse).getJSONObject("responseHead").getString("res_code");
+ if("1000".equals(res_code)){
+ return true;
+ }else {
+ String res_msg = JSONObject.parseObject(decodedResponse).getJSONObject("responseHead").getString("res_msg");
+ System.out.println("错误信息: " + res_msg);
+ throw new RuntimeException(res_msg);
+ }
+ } catch (IllegalArgumentException e) {
+ System.out.println("响应不是有效的Base64格式: " + e.getMessage());
+ }
+ }
+
+ return null;
+ }
+
+
+
+
public static void main(String[] args) {
try {
+ System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+// CreateOrderRequest createOrderRequest = new CreateOrderRequest();
+// createOrderRequest.setOrderId("20231025110000000000000000000001");
+// createOrderRequest.setTravelDate("2026-03-11");
+// createOrderRequest.setQuantity(1);
+// createOrderRequest.setProductId("HXY19051010090001");
+// List<VisitPerson> visitPersons = new ArrayList<>();
+// VisitPerson visitPerson = new VisitPerson();
+// visitPerson.setIdCard("511028200002150815");
+// visitPersons.add(visitPerson);
+// createOrderRequest.setVisitPersons(visitPersons);
+// TicketUtil ticketUtil = new TicketUtil();
+// CreateOrderVo createOrderVo = ticketUtil.saveOrder(createOrderRequest);
+// System.out.println(createOrderVo);
+//
+//
+// String payOrder = ticketUtil.payOrder(createOrderVo.getOrderId(), createOrderVo.getPartnerOrderId());
+// System.out.println(payOrder);
+// List<String> list =new ArrayList<>();
+// JSONArray jsonArray = JSONArray.parseArray(payOrder);
+// for (int i = 0; i < jsonArray.size(); i++) {
+// JSONObject jsonObject = jsonArray.getJSONObject(i);
+// String ticketId = jsonObject.getString("ticketId");
+// list.add(ticketId);
+// }
+//
+// Boolean b = ticketUtil.cannelTicket(createOrderVo.getOrderId(), createOrderVo.getPartnerOrderId(), list);
+// System.out.println(b);
+
} catch (Exception e) {
throw new RuntimeException(e);
}
--
Gitblit v1.7.1