From e1bbc0cf1d8bb72fbd41976712bb847d242f3671 Mon Sep 17 00:00:00 2001
From: liujie <1793218484@qq.com>
Date: 星期一, 09 三月 2026 20:59:36 +0800
Subject: [PATCH] 门票对接

---
 ruoyi-system/src/main/java/com/ruoyi/system/service/TTicketOrderService.java          |    4 
 ruoyi-system/src/main/java/com/ruoyi/system/utils/ticketUtil/DesUtil.java             |  109 +++++++++
 ruoyi-system/pom.xml                                                                  |    6 
 ruoyi-system/src/main/java/com/ruoyi/system/dto/CreateOrderDto.java                   |   33 +++
 ruoyi-system/src/main/java/com/ruoyi/system/model/TTicketOrder.java                   |    4 
 ruoyi-system/src/main/java/com/ruoyi/system/utils/ticketUtil/TicketUtil.java          |  228 ++++++++++++++++++++
 ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/OrderController.java          |   18 +
 ruoyi-system/src/main/java/com/ruoyi/system/dto/CreateOrderRequest.java               |   38 +++
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTicketOrderServiceImpl.java |   70 ++++++
 ruoyi-system/src/main/java/com/ruoyi/system/vo/CreateOrderVo.java                     |   10 
 ruoyi-system/src/main/java/com/ruoyi/system/vo/TicketListVo.java                      |   60 +++++
 ruoyi-system/src/main/java/com/ruoyi/system/dto/VisitPerson.java                      |   23 ++
 ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TicketController.java         |   20 +
 13 files changed, 614 insertions(+), 9 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 2ecca3d..dc38c2c 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
@@ -3,6 +3,8 @@
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.framework.web.service.TokenService;
+import com.ruoyi.system.dto.CreateOrderDto;
+import com.ruoyi.system.dto.CreateOrderRequest;
 import com.ruoyi.system.query.AppletOrderListQuery;
 import com.ruoyi.system.service.TAppUserService;
 import com.ruoyi.system.service.TTicketOrderService;
@@ -52,6 +54,22 @@
     }
 
 
+    /**
+     * 下单
+     *
+     */
+    @ApiOperation(value = "下单")
+    @PostMapping("/addOrder")
+    public R<Void> addOrder(@RequestBody CreateOrderDto request) throws Exception {
+        Integer userId = tokenService.getLoginUserApplet().getUserId();
+        boolean save = tTicketOrderService.addOrder(request, userId);
+        if (!save) {
+            return R.fail("下单失败");
+        }
+        return R.ok();
+    }
+
+
 
 
 }
diff --git a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TicketController.java b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TicketController.java
index f4d50b1..5dddd17 100644
--- a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TicketController.java
+++ b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TicketController.java
@@ -2,16 +2,12 @@
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.framework.web.service.TokenService;
 import com.ruoyi.system.model.TTourist;
-import com.ruoyi.system.query.AppletOrderListQuery;
-import com.ruoyi.system.service.TAppUserService;
-import com.ruoyi.system.service.TTicketOrderService;
 import com.ruoyi.system.service.TTouristService;
-import com.ruoyi.system.vo.AppletOrderListVO;
-import com.ruoyi.system.vo.TTicketOrderVo;
+import com.ruoyi.system.vo.TicketListVo;
+import com.ruoyi.system.utils.ticketUtil.TicketUtil;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.RequiredArgsConstructor;
@@ -37,8 +33,8 @@
 public class TicketController {
 
     private final TokenService tokenService;
-    private final TAppUserService appUserService;
     private final TTouristService tTouristService;
+    private final TicketUtil ticketUtil;
 
 
     @ApiOperation(value = "获取游客信息", response = TTourist.class)
@@ -48,8 +44,6 @@
         List<TTourist> list = tTouristService.list(new LambdaQueryWrapper<TTourist>().eq(TTourist::getAppUserId, userId));
         return R.ok(list);
     }
-
-
 
 
     @ApiOperation(value = "获取游客详情信息", response = TTourist.class)
@@ -109,4 +103,12 @@
         return R.ok();
     }
 
+
+
+    @ApiOperation(value = "获取门票信息", response = TicketListVo.class)
+    @GetMapping("/ticketList")
+    public R<List<TicketListVo>> ticketList() throws Exception {
+        List<TicketListVo> list = ticketUtil.getTicketList();
+        return R.ok(list);
+    }
 }
diff --git a/ruoyi-system/pom.xml b/ruoyi-system/pom.xml
index 1fe46cf..e031604 100644
--- a/ruoyi-system/pom.xml
+++ b/ruoyi-system/pom.xml
@@ -127,6 +127,12 @@
             <scope>system</scope>
             <systemPath>${project.basedir}/lib/icbc-ca.jar</systemPath>
         </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>2.0.24</version>
+            <scope>compile</scope>
+        </dependency>
     </dependencies>
 
 
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/dto/CreateOrderDto.java b/ruoyi-system/src/main/java/com/ruoyi/system/dto/CreateOrderDto.java
new file mode 100644
index 0000000..696fa47
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/dto/CreateOrderDto.java
@@ -0,0 +1,33 @@
+package com.ruoyi.system.dto;// 请求DTO
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.*;
+import java.util.List;
+
+@Data
+public class CreateOrderDto {
+    @NotBlank(message = "游玩日期不能为空")
+    @Pattern(regexp = "^\\d{4}-\\d{2}-\\d{2}$", message = "游玩日期格式错误,应为yyyy-MM-dd")
+    @ApiModelProperty(value = "游玩日期")
+    private String travelDate;
+
+    @NotNull(message = "预订数量不能为空")
+    @Min(value = 1, message = "预订数量必须大于0")
+    @ApiModelProperty(value = "预订数量")
+    private Integer quantity;
+    
+    @NotBlank(message = "产品编号不能为空")
+    @ApiModelProperty(value = "产品编号")
+    private String productId;
+
+    @NotBlank(message = "产品名称")
+    @ApiModelProperty(value = "产品名称")
+    private String productName;
+
+    @NotEmpty(message = "游玩人Ids不能为空")
+    @ApiModelProperty(value = "游玩人Ids")
+    private List<Integer> visitPersons;
+
+}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/dto/CreateOrderRequest.java b/ruoyi-system/src/main/java/com/ruoyi/system/dto/CreateOrderRequest.java
new file mode 100644
index 0000000..93eca83
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/dto/CreateOrderRequest.java
@@ -0,0 +1,38 @@
+package com.ruoyi.system.dto;// 请求DTO
+import lombok.Data;
+import javax.validation.constraints.*;
+import java.util.List;
+
+@Data
+public class CreateOrderRequest {
+
+    @NotBlank(message = "不传")
+    private String orderId;
+
+    @NotBlank(message = "游玩日期不能为空")
+    @Pattern(regexp = "^\\d{4}-\\d{2}-\\d{2}$", message = "游玩日期格式错误,应为yyyy-MM-dd")
+    private String travelDate;
+    
+    @Pattern(regexp = "^\\d{2}:\\d{2}~\\d{2}:\\d{2}$", message = "分时预约时段格式错误,应为HH:mm~HH:mm")
+    private String travelTime;
+    
+    @NotNull(message = "预订数量不能为空")
+    @Min(value = 1, message = "预订数量必须大于0")
+    private Integer quantity;
+    
+    @NotBlank(message = "产品编号不能为空")
+    private String productId;
+
+    @NotBlank(message = "预订人姓名")
+    private String bookName;
+
+    @NotBlank(message = "预订人手机号")
+    private String bookMobile;
+
+    @NotBlank(message = "预订人身份证号")
+    private String idCard;
+    
+    @NotEmpty(message = "游玩人信息不能为空")
+    private List<VisitPerson> visitPersons;
+
+}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/dto/VisitPerson.java b/ruoyi-system/src/main/java/com/ruoyi/system/dto/VisitPerson.java
new file mode 100644
index 0000000..c5ed675
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/dto/VisitPerson.java
@@ -0,0 +1,23 @@
+package com.ruoyi.system.dto;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Pattern;
+
+@Data
+public class VisitPerson {
+    @NotBlank(message = "游玩人姓名")
+    private String name;
+
+    @NotBlank(message = "游玩人手机号")
+    private String mobile;
+
+    @NotBlank(message = "身份证号不能为空")
+    @Pattern(regexp = "^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[\\dXx]$",
+            message = "身份证号格式不正确")
+    private String idCard;
+
+    @NotBlank(message = "人像图片")
+    private String face; // 人像图片base64
+}
\ No newline at end of file
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 075c611..728d88a 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
@@ -76,6 +76,10 @@
     @TableField("refund_reason")
     private String refundReason;
 
+    @ApiModelProperty(value = "开放平台订单号")
+    @TableField("partner_order_id")
+    private String partnerOrderId;
+
     @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 a068058..d1512d3 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
@@ -1,6 +1,8 @@
 package com.ruoyi.system.service;
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.system.dto.CreateOrderDto;
+import com.ruoyi.system.dto.CreateOrderRequest;
 import com.ruoyi.system.model.TTicketOrder;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.ruoyi.system.query.AppletOrderListQuery;
@@ -24,4 +26,6 @@
 
     Page<TTicketOrderVo> refundPageList(Page<TTicketOrderVo> page, TTicketOrderQuery query);
 
+    boolean addOrder(CreateOrderDto request, Integer userId) 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 e1ed51b..5f9092a 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,16 +1,28 @@
 package com.ruoyi.system.service.impl;
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.common.utils.OrderNos;
+import com.ruoyi.system.dto.CreateOrderDto;
+import com.ruoyi.system.dto.CreateOrderRequest;
+import com.ruoyi.system.dto.VisitPerson;
 import com.ruoyi.system.model.TTicketOrder;
 import com.ruoyi.system.mapper.TTicketOrderMapper;
+import com.ruoyi.system.model.TTourist;
 import com.ruoyi.system.query.AppletOrderListQuery;
 import com.ruoyi.system.query.TTicketOrderQuery;
+import com.ruoyi.system.service.TAppUserService;
 import com.ruoyi.system.service.TTicketOrderService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.system.service.TTouristService;
+import com.ruoyi.system.utils.ticketUtil.TicketUtil;
+import com.ruoyi.system.vo.CreateOrderVo;
 import com.ruoyi.system.vo.TTicketOrderVo;
 import org.springframework.stereotype.Service;
 
+import java.math.BigDecimal;
+import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -22,6 +34,19 @@
  */
 @Service
 public class TTicketOrderServiceImpl extends ServiceImpl<TTicketOrderMapper, TTicketOrder> implements TTicketOrderService {
+
+
+    private final TicketUtil ticketUtil;
+    private final TTouristService tTouristService;
+
+
+
+
+    public TTicketOrderServiceImpl(TicketUtil ticketUtil, TTouristService tTouristService) {
+        this.ticketUtil = ticketUtil;
+        this.tTouristService = tTouristService;
+    }
+
 
     @Override
     public Page<TTicketOrderVo> pageList(Page<TTicketOrderVo> page, TTicketOrderQuery query) {
@@ -44,4 +69,49 @@
         page.setRecords( list);
         return page;
     }
+
+    @Override
+    public boolean addOrder(CreateOrderDto dto, Integer userId) throws Exception {
+
+        CreateOrderRequest request = new CreateOrderRequest();
+        String did = OrderNos.getDid();
+        request.setOrderId(did);
+        request.setTravelDate(dto.getTravelDate());
+        request.setQuantity(dto.getQuantity());
+        request.setProductId(dto.getProductId());
+
+        if (dto.getQuantity()!=dto.getVisitPersons().size()) {
+            throw new RuntimeException("人数不匹配");
+        }
+
+        List<TTourist> tTourists = tTouristService.listByIds(dto.getVisitPersons());
+        ArrayList<VisitPerson> visitPeople = new ArrayList<>();
+        for (TTourist tTourist : tTourists) {
+            VisitPerson visitPerson = new VisitPerson();
+            visitPerson.setName(tTourist.getName());
+            visitPerson.setMobile(tTourist.getPhone());
+            visitPerson.setIdCard(tTourist.getIdCard());
+            visitPeople.add(visitPerson);
+        }
+        request.setVisitPersons(visitPeople);
+        CreateOrderVo createOrderVo = ticketUtil.saveOrder(request);
+
+        TTicketOrder order = new TTicketOrder();
+        order.setAppUserId(userId);
+        order.setOrderNo(did);
+        order.setPartnerOrderId(createOrderVo.getPartnerOrderId());
+        order.setOrderPrice(new BigDecimal(createOrderVo.getOrderAmount()).setScale(2, BigDecimal.ROUND_HALF_UP));
+
+
+        String result = dto.getVisitPersons().stream()
+                .map(String::valueOf)  // Integer 转 String
+                .collect(Collectors.joining(","));
+        order.setTourist(result);
+        order.setTicketNum(dto.getQuantity());
+        order.setStatus(0);
+
+        order.setTicketInfo(dto.getProductName());
+        boolean save = this.save(order);
+        return save;
+    }
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/utils/ticketUtil/DesUtil.java b/ruoyi-system/src/main/java/com/ruoyi/system/utils/ticketUtil/DesUtil.java
new file mode 100644
index 0000000..a5c1502
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/utils/ticketUtil/DesUtil.java
@@ -0,0 +1,109 @@
+package com.ruoyi.system.utils.ticketUtil;
+import java.io.IOException;
+import java.security.SecureRandom;
+import java.util.Base64;
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.DESKeySpec;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import sun.misc.BASE64Decoder;
+import sun.misc.BASE64Encoder;
+public class DesUtil {
+    private static final String DES = "DES";
+
+    /**
+     * Description 根据键值进行加密
+     * @param data 
+     * @param key  加密键byte数组
+     * @return
+     * @throws Exception
+     */
+    public static String encrypt(String data, String key) throws Exception {
+        byte[] bt = encrypt(data.getBytes("UTF-8"), key.getBytes("UTF-8"));
+        String strs = new BASE64Encoder().encode(bt);
+        return strs;
+    }
+    /**
+     * Description 根据键值进行解密
+     * @param data
+     * @param key  加密键byte数组
+     * @return
+     * @throws IOException
+     * @throws Exception
+     */
+    public static String decrypt(String data, String key) throws Exception,
+            Exception {
+        if (data == null)
+            return null;
+        BASE64Decoder decoder = new BASE64Decoder();
+        byte[] buf = decoder.decodeBuffer(data);
+        byte[] bt = decrypt(buf,key.getBytes("UTF-8"));
+        return new String(bt, "UTF-8");
+    }
+    /**
+     * Description 根据键值进行加密
+     * @param data
+     * @param key  加密键byte数组
+     * @return
+     * @throws Exception
+     */
+    private static byte[] encrypt(byte[] data, byte[] key) throws Exception {
+        // 生成一个可信任的随机数源
+        SecureRandom sr = new SecureRandom();
+        // 从原始密钥数据创建DESKeySpec对象
+        DESKeySpec dks = new DESKeySpec(key);
+        // 创建一个密钥工厂,然后用它把DESKeySpec转换成SecretKey对象
+        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
+        SecretKey securekey = keyFactory.generateSecret(dks);
+        // Cipher对象实际完成加密操作
+        Cipher cipher = Cipher.getInstance(DES);
+        // 用密钥初始化Cipher对象
+        cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);
+        return cipher.doFinal(data);
+    }
+    /**
+     * Description 根据键值进行解密
+     * @param data
+     * @param key  加密键byte数组
+     * @return
+     * @throws Exception
+     */
+    private static byte[] decrypt(byte[] data, byte[] key) throws Exception {
+        // 生成一个可信任的随机数源
+        SecureRandom sr = new SecureRandom();
+        // 从原始密钥数据创建DESKeySpec对象
+        DESKeySpec dks = new DESKeySpec(key);
+        // 创建一个密钥工厂,然后用它把DESKeySpec转换成SecretKey对象
+        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
+        SecretKey securekey = keyFactory.generateSecret(dks);
+        // Cipher对象实际完成解密操作
+        Cipher cipher = Cipher.getInstance(DES);
+        // 用密钥初始化Cipher对象
+        cipher.init(Cipher.DECRYPT_MODE, securekey, sr);
+        return cipher.doFinal(data);
+    }
+
+
+
+    public static void main(String[] args) throws Exception {
+
+    }
+
+    /**
+     * 辅助方法:将字符串进行Base64编码
+     */
+    public static String toBase64(String data) throws Exception {
+        return Base64.getEncoder().encodeToString(data.getBytes("UTF-8"));
+    }
+
+    /**
+     * 辅助方法:将Base64字符串解码
+     */
+    public static String fromBase64(String base64Data) throws Exception {
+        byte[] decodedBytes = Base64.getDecoder().decode(base64Data);
+        return new String(decodedBytes, "UTF-8");
+    }
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..53bbf7c
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/utils/ticketUtil/TicketUtil.java
@@ -0,0 +1,228 @@
+package com.ruoyi.system.utils.ticketUtil;
+
+import cn.hutool.crypto.SecureUtil;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.ruoyi.system.dto.CreateOrderRequest;
+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;
+
+/**
+ * 门票接口
+ */
+public class TicketUtil {
+
+    public List<TicketListVo> getTicketList() throws Exception {
+        ArrayList<TicketListVo> ticketListVos = new ArrayList<>();
+        String userId = "1d9a42e0-9de3-451b-9964-4e9f8e62b101";
+        String method = "getProductInfo";
+        String timestamp = System.currentTimeMillis() + "";
+        String desKey = "TFD9BEOK";  // DES密钥必须是8字节
+        String userKey = "TFD9BEOK";  // 用于签名的用户密钥
+
+        // 1. 构建请求体数据
+        HashMap<String, Object> bodyData = new HashMap<>();
+        bodyData.put("pageIndex", 1);
+        bodyData.put("pageSize", 100);
+        bodyData.put("sceneryNo", "");
+
+        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/getProductInfo");
+
+        // 设置请求头
+        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 responseBody1 = JSONObject.parseObject(decodedResponse).get("responseBody").toString();
+                String decryptedResponseBody = DesUtil.decrypt(responseBody1, desKey);
+                System.out.println("解密后的响应: " + decryptedResponseBody);
+                JSONArray productList = JSONObject.parseObject(decryptedResponseBody).getJSONArray("productList");
+
+
+                for (int i = 0; i < productList.size(); i++) {
+                    JSONObject product = productList.getJSONObject(i);
+                    TicketListVo ticketListVo = new TicketListVo();
+                    ticketListVo.setProductId(product.getString("productId"));
+                    ticketListVo.setProductName(product.getString("productName"));
+                    ticketListVo.setPrice(product.getLong("price"));
+                    ticketListVo.setSceneryNo(product.getString("sceneryNo"));
+                    ticketListVo.setSceneryName(product.getString("sceneryName"));
+                    ticketListVo.setBeginSaleDate(product.getString("beginSaleDate"));
+                    ticketListVo.setEndSaleDate(product.getString("endSaleDate"));
+                    ticketListVo.setIsCanRefund(product.getInteger("isCanRefund"));
+                    ticketListVos.add(ticketListVo);
+                }
+                return ticketListVos;
+
+            } catch (IllegalArgumentException e) {
+                System.out.println("响应不是有效的Base64格式: " + e.getMessage());
+            }
+        }
+        return ticketListVos;
+    }
+
+
+    public  CreateOrderVo saveOrder(CreateOrderRequest request) throws Exception {
+        String userId = "1d9a42e0-9de3-451b-9964-4e9f8e62b101";
+        String method = "createOrder";
+        String timestamp = System.currentTimeMillis() + "";
+        String desKey = "TFD9BEOK";  // DES密钥必须是8字节
+        String userKey = "TFD9BEOK";  // 用于签名的用户密钥
+
+        // 1. 构建请求体数据
+//        HashMap<String, Object> bodyData = new HashMap<>();
+//        bodyData.put("pageIndex", 1);
+//        bodyData.put("pageSize", 100);
+//        bodyData.put("sceneryNo", "");
+
+        String requestBody = JSON.toJSONString(request);
+        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/createOrder");
+
+        // 设置请求头
+        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).get("res_code").toString();
+                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);
+
+                    CreateOrderVo createOrderVo = new CreateOrderVo();
+                    createOrderVo.setOrderId(jsonObject.getString("orderId"));
+                    createOrderVo.setOrderAmount(jsonObject.getString("orderAmount"));
+                    createOrderVo.setPartnerOrderId(jsonObject.getString("partnerOrderId"));
+                    return createOrderVo;
+                }else {
+
+                    String res_msg = JSONObject.parseObject(decodedResponse).get("res_msg").toString();
+                    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 {
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/vo/CreateOrderVo.java b/ruoyi-system/src/main/java/com/ruoyi/system/vo/CreateOrderVo.java
new file mode 100644
index 0000000..eb128ed
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/vo/CreateOrderVo.java
@@ -0,0 +1,10 @@
+package com.ruoyi.system.vo;
+
+import lombok.Data;
+
+@Data
+public class CreateOrderVo {
+    private String orderId;        // 分销商订单号
+    private String partnerOrderId;  // 开放平台订单号
+    private String orderAmount;     // 订单金额
+}
\ No newline at end of file
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/vo/TicketListVo.java b/ruoyi-system/src/main/java/com/ruoyi/system/vo/TicketListVo.java
new file mode 100644
index 0000000..87d6c3a
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/vo/TicketListVo.java
@@ -0,0 +1,60 @@
+package com.ruoyi.system.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 门票信息Vo
+ */
+@ApiModel("门票信息Vo")
+@Data
+public class TicketListVo {
+    /**
+     * 门票ID
+     */
+    @ApiModelProperty("门票ID")
+    private String productId;
+
+    /**
+     * 门票名称
+     */
+    @ApiModelProperty("门票名称")
+    private String productName;
+
+    /**
+     * 门票价格
+     */
+    @ApiModelProperty("门票价格")
+    private Long price;
+
+    /**
+     * 景点编号
+     */
+    @ApiModelProperty("景点编号")
+    private String sceneryNo;
+
+    /**
+     * 景点名称
+     */
+    @ApiModelProperty("景点名称")
+    private String sceneryName;
+
+    /**
+     * 开售时间
+     */
+    @ApiModelProperty("开售时间")
+    private String beginSaleDate;
+
+    /**
+     * 截止时间
+     */
+    @ApiModelProperty("截止时间")
+    private String endSaleDate;
+
+    /**
+     * 是否可退(0不支持 1支持)
+     */
+    @ApiModelProperty("是否可退(0不支持 1支持)")
+    private Integer isCanRefund;
+}

--
Gitblit v1.7.1