Pārlūkot izejas kodu

feat(消费服务、海康消费机服务): 海康消费机请求消费处理

1.消费服务增加了海康消费机请求消费的dubbo远程接口
2.海康消费服务增加了测试controller
luo.yibo@datuai.com 11 mēneši atpakaļ
vecāks
revīzija
07be2b3346

+ 25 - 0
ruoyi-api/ruoyi-api-consume/src/main/java/org/dromara/consume/api/RemoteConsumeService.java

@@ -3,6 +3,7 @@ package org.dromara.consume.api;
 import org.dromara.common.core.domain.R;
 import org.dromara.common.core.domain.model.ErrorInfo;
 import org.dromara.consume.api.domain.bo.RemoteConsumeBo;
+import org.dromara.consume.api.domain.bo.RemoteResultDto;
 
 /**
  * @ClassName RemoteConsumeService
@@ -29,4 +30,28 @@ public interface RemoteConsumeService {
      * @return 返回一个包含错误信息的响应对象,如果操作成功则data为null,如果失败则data包含具体的错误信息
      */
     R<ErrorInfo> createFeatureDataOne(Long userId, String photoUrl);
+
+    /**
+     * 处理海康请求的消费数据。
+     *
+     * @param remoteBo 包含消费相关业务数据的对象,用于传递消费的基础信息和扩展信息
+     * @return 返回一个包含错误信息的响应对象,如果操作成功则data为null,如果失败则data包含具体的错误信息
+     */
+    RemoteResultDto dealHikRequestConsume(RemoteConsumeBo remoteBo);
+
+    /**
+     * 处理海康上传的消费记录。
+     *
+     * @param remoteBo 包含消费相关业务数据的对象,用于传递消费的基础信息和扩展信息
+     * @return 返回一个包含错误信息的响应对象,如果操作成功则data为null,如果失败则data包含具体的错误信息
+     */
+    R<ErrorInfo>  dealHikUploadRecord(RemoteConsumeBo remoteBo);
+
+    /**
+     * 处理海康上传的离线消费记录。
+     *
+     * @param remoteBo 包含消费相关业务数据的对象,用于传递消费的基础信息和扩展信息
+     * @return 返回一个包含错误信息的响应对象,如果操作成功则data为null,如果失败则data包含具体的错误信息
+     */
+    R<ErrorInfo>  dealHikUploadOffLineRecord(RemoteConsumeBo remoteBo);
 }

+ 6 - 0
ruoyi-api/ruoyi-api-consume/src/main/java/org/dromara/consume/api/domain/bo/RemoteConsumeBo.java

@@ -76,6 +76,11 @@ public class RemoteConsumeBo implements Serializable {
      */
     private Long termNo;
 
+    /**
+     * 设备MAC地址
+     */
+    private String termMac;
+
     /**
      * 机器流水号
      */
@@ -94,6 +99,7 @@ public class RemoteConsumeBo implements Serializable {
      * 记录Id
      */
     private Long recordId;
+
     /**
      * 消费记录标志位?
      */

+ 31 - 0
ruoyi-api/ruoyi-api-consume/src/main/java/org/dromara/consume/api/domain/bo/RemoteResultDto.java

@@ -0,0 +1,31 @@
+package org.dromara.consume.api.domain.bo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.domain.model.ErrorInfo;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 消费远程调用结果传输对象
+ * <p>
+ *
+ * @author luoyibo
+ * @version 2.2.0
+ * @date 2025-06-06
+ * @since JDK17
+ */
+@Data
+@AllArgsConstructor
+public class RemoteResultDto implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = -5105235135533930807L;
+
+    private R<ErrorInfo> errorInfo;
+    private RemoteConsumeBo updatedRemoteBo;
+
+    // public RemoteResultDto(R<ErrorInfo> result, RemoteConsumeBo updatedRemote) {}
+}

+ 5 - 0
ruoyi-server/ruoyi-server-common/src/main/java/org/dromara/server/common/domain/consume/bo/ConsumptionBo.java

@@ -71,6 +71,11 @@ public class ConsumptionBo {
      */
     private Long termNo;
 
+    /**
+     * 设备MAC地址
+     */
+    private String termMac;
+
     /**
      * 机器流水号
      */

+ 1 - 1
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/business/BaseBusiness.java

@@ -93,7 +93,7 @@ public class BaseBusiness {
 
         XfConsumeDetailOriginalBo originalBo = new XfConsumeDetailOriginalBo();
         BeanUtil.copyProperties(consumeBo, originalBo);
-        if (originalBo.getRecordId() == 0) {
+        if (ObjectUtil.isNotEmpty(originalBo.getRecordId()) && originalBo.getRecordId() == 0) {
             originalBo.setRecordId(null);
         }
         originalBo.setOriginalId(originalId);

+ 19 - 12
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/business/CheckBusiness.java

@@ -28,11 +28,9 @@ import org.dromara.server.consume.domain.vo.XfCardLimitedVo;
 import org.dromara.server.consume.domain.vo.XfConsumeDetailOriginalVo;
 import org.dromara.server.consume.domain.vo.XfTermVo;
 import org.dromara.server.consume.domain.vo.yc.TermToken;
-import org.dromara.server.consume.domain.vo.yc.UserInfoVo;
 import org.dromara.server.consume.service.IConsumeDetailOriginalService;
 import org.dromara.server.consume.service.IPtBagService;
 import org.dromara.server.consume.service.IXfCardLimitedService;
-import org.dromara.server.consume.service.IXfConsumeDetailService;
 import org.jetbrains.annotations.NotNull;
 import org.springframework.stereotype.Service;
 
@@ -77,7 +75,6 @@ public class CheckBusiness {
     private final RemotePtXfTermService remoteXfTermService;
 
     private final IConsumeDetailOriginalService consumeDetailOriginalService;
-    private final IXfConsumeDetailService consumeDetailService;
     private final IPtBagService bagService;
     private final TokenManager tokenManager;
     private final IXfCardLimitedService cardLimitedService;
@@ -132,7 +129,7 @@ public class CheckBusiness {
     public R<ErrorInfo> checkParam(ConsumptionBo bo) {
         ErrorInfo errorInfo;
         // 检查设备机号
-        if (ObjectUtil.isEmpty(bo.getTermNo()) || bo.getTermNo() == 0) {
+        if ((ObjectUtil.isEmpty(bo.getTermNo()) || bo.getTermNo() == 0) && ObjectUtil.isEmpty(bo.getTermMac())) {
             errorInfo = new ErrorInfo(1, ApiErrorTypeConstants.PARAM_ERROR, "设备机号不正确", "设备机号必须大于零!");
             return R.fail(errorInfo);
         }
@@ -208,12 +205,18 @@ public class CheckBusiness {
      * @return 检查结果
      */
     public R<ErrorInfo> checkTerm(ConsumptionBo bo, XfTermVo useTermVo) {
-        long termNo = bo.getTermNo();
+        String msg = ObjectUtil.isEmpty(bo.getTermMac()) ? bo.getTermNo().toString() : bo.getTermMac();
         String tenantId = ObjectUtil.isNotEmpty(bo.getTenantId()) ? bo.getTenantId() : defaultConfig.getTenantId();
-        RemoteXfTermVo remoteXfTermVo = remoteXfTermService.queryByNo(termNo, tenantId);
+        RemoteXfTermVo remoteXfTermVo;
+        if ((ObjectUtil.isNotEmpty(bo.getTermNo()) && bo.getTermNo() > 0)) {
+            remoteXfTermVo = remoteXfTermService.queryByNo(bo.getTermNo(), tenantId);
+        } else {
+            remoteXfTermVo = remoteXfTermService.queryByMac(bo.getTermMac());
+            bo.setTermNo(remoteXfTermVo.getTermNo());
+        }
         if (ObjectUtil.isEmpty(remoteXfTermVo)) {
             ErrorInfo errorInfo = new ErrorInfo(400, "", "设备不存在",
-                                                MessageFormat.format("机号为[{0}]的设备不存在,不允许交易", termNo));
+                                                MessageFormat.format("机号或MAC为[{0}]的设备不存在,不允许交易", msg));
 
             return R.fail(errorInfo);
         }
@@ -548,8 +551,8 @@ public class CheckBusiness {
             }
         }
         // XfConsumeDetailVo consumeDetailVo = consumeDetailService.queryVoByOriginalId(originalId);
-        //XfConsumeDetailVo consumeDetailVo = consumeDetailService.queryVoByOriginalId(bo.getOriginalId());
-        //if (ObjectUtil.isNotEmpty(consumeDetailVo)) {
+        // XfConsumeDetailVo consumeDetailVo = consumeDetailService.queryVoByOriginalId(bo.getOriginalId());
+        // if (ObjectUtil.isNotEmpty(consumeDetailVo)) {
         //    // 认为是重复上传,不再入账
         //    return R.fail(new ErrorInfo(400, ApiErrorTypeConstants.RECORD_IS_EXISTS, "原始消费记录已处理",
         //                                MessageFormat.format("标识为[{0}]的原始消费记录已处理", bo.getRecordId())));
@@ -597,7 +600,8 @@ public class CheckBusiness {
                 bagVo.setBalance(balance);
                 sb.append(BagNameEnum.getMessage(Integer.parseInt(bagCode)));
                 doBagVos.add(bagVo);
-                log.warn("[上传交易]-[扣费钱包]-[钱包代码:{},钱包余额:{},消费金额:{},扣款金额:{},姓名:{}]", bagCode, balance, consumeMoney,doMoney,userAccountVo.getRealName());
+                log.warn("[上传交易]-[扣费钱包]-[钱包代码:{},钱包余额:{},消费金额:{},扣款金额:{},姓名:{}]", bagCode, balance, consumeMoney, doMoney,
+                         userAccountVo.getRealName());
                 break;
             } else {
                 // 如果消费金额>0,则可能会需要多钱包扣费
@@ -609,7 +613,8 @@ public class CheckBusiness {
                         bagVo.setBalance(balance.subtract(doMoney));
                         sb.append(BagNameEnum.getMessage(Integer.parseInt(bagCode)));
                         doBagVos.add(bagVo);
-                        log.warn("[上传交易]-[扣费钱包]-[钱包代码:{},钱包余额:{},消费金额:{},扣款金额:{},姓名:{}]", bagCode, balance, consumeMoney,doMoney,userAccountVo.getRealName());
+                        log.warn("[上传交易]-[扣费钱包]-[钱包代码:{},钱包余额:{},消费金额:{},扣款金额:{},姓名:{}]", bagCode, balance, consumeMoney,
+                                 doMoney, userAccountVo.getRealName());
                         break;
                     } else {
                         // 将钱包扣费为0,剩余待扣金额=消费金额-原钱包余额
@@ -631,6 +636,7 @@ public class CheckBusiness {
 
         return R.ok();
     }
+
     public R<ErrorInfo> checkOrigDeductionBag(ConsumptionBo bo, RemoteUserAccountVo userAccountVo, XfTermVo termVo) {
         // 设备的扣费钱包字符串
         String consumeType = termVo.getConsumeType();
@@ -649,11 +655,12 @@ public class CheckBusiness {
         // 如果扣费钱包总余额<消费金额,则不允许消费
         if (consumeMoney.compareTo(totalBalance) > 0) {
             return R.fail(new ErrorInfo(400, ApiErrorTypeConstants.CONSUME_CHECK_FAIL, "钱包余额不足",
-                MessageFormat.format("余额不足,总余额[{0}],消费金额[{1}]", totalBalance, consumeMoney)));
+                                        MessageFormat.format("余额不足,总余额[{0}],消费金额[{1}]", totalBalance, consumeMoney)));
         }
         bo.setBalance(totalBalance.subtract(consumeMoney));
         return R.ok();
     }
+
     /**
      * 设备限额、限次与折扣验证
      *

+ 27 - 0
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/domain/convert/RemoteConsumeBoConvert.java

@@ -0,0 +1,27 @@
+package org.dromara.server.consume.domain.convert;
+
+import org.dromara.consume.api.domain.bo.RemoteConsumeBo;
+import org.dromara.server.common.domain.consume.bo.ConsumptionBo;
+import org.mapstruct.*;
+import org.mapstruct.factory.Mappers;
+
+/**
+ * 消费业务对象转换类
+ * <p>
+ *
+ * @author luoyibo
+ * @version 2.2.0
+ * @date 2025-06-06
+ * @since JDK17
+ */
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING, unmappedTargetPolicy = ReportingPolicy.IGNORE)
+public interface RemoteConsumeBoConvert {
+    RemoteConsumeBoConvert INSTANCE = Mappers.getMapper(RemoteConsumeBoConvert.class);
+
+    ConsumptionBo fromRemote(RemoteConsumeBo remoteConsumeBo);
+
+    RemoteConsumeBo toRemote(ConsumptionBo bo);
+
+    @InheritInverseConfiguration
+    void updateRemote(@MappingTarget RemoteConsumeBo target, ConsumptionBo source);
+}

+ 30 - 0
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/dubbo/RemoteConsumeServiceImpl.java

@@ -2,14 +2,17 @@ package org.dromara.server.consume.dubbo;
 
 import cn.hutool.core.bean.BeanUtil;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.dubbo.config.annotation.DubboService;
 import org.dromara.common.core.domain.R;
 import org.dromara.common.core.domain.model.ErrorInfo;
 import org.dromara.consume.api.RemoteConsumeService;
 import org.dromara.consume.api.domain.bo.RemoteConsumeBo;
+import org.dromara.consume.api.domain.bo.RemoteResultDto;
 import org.dromara.server.common.domain.consume.bo.ConsumptionBo;
 import org.dromara.server.consume.business.ArcFaceBusiness;
 import org.dromara.server.consume.business.ConsumeBusiness;
+import org.dromara.server.consume.domain.convert.RemoteConsumeBoConvert;
 import org.springframework.stereotype.Service;
 
 /**
@@ -20,6 +23,7 @@ import org.springframework.stereotype.Service;
  * @Version 1.0
  * @since jdk17
  */
+@Slf4j
 @RequiredArgsConstructor
 @Service
 @DubboService
@@ -49,4 +53,30 @@ public class RemoteConsumeServiceImpl implements RemoteConsumeService {
     public R<ErrorInfo> createFeatureDataOne(Long userId, String photoUrl) {
         return faceBusiness.createFeatureDataOne(userId, photoUrl);
     }
+
+    @Override
+    public RemoteResultDto dealHikRequestConsume(RemoteConsumeBo remoteBo) {
+        // log.info("before:{}", remoteBo);
+        System.out.println("调用前引用: " + System.identityHashCode(remoteBo));
+        ConsumptionBo bo = RemoteConsumeBoConvert.INSTANCE.fromRemote(remoteBo);
+        R<ErrorInfo> result =  consumeBusiness.createOrder(bo, "", "");
+        // RemoteConsumeBoConvert.INSTANCE.updateRemote(remoteBo, bo);
+        // log.info("after:{}", remoteBo);
+        // System.out.println("调用后引用: " + System.identityHashCode(remoteBo));
+        //
+        RemoteConsumeBo updatedRemote = RemoteConsumeBoConvert.INSTANCE.toRemote(bo);
+        return new RemoteResultDto(result, updatedRemote);
+    }
+
+    @Override
+    public R<ErrorInfo> dealHikUploadRecord(RemoteConsumeBo remoteBo) {
+        ConsumptionBo bo = RemoteConsumeBoConvert.INSTANCE.fromRemote(remoteBo);
+        return consumeBusiness.postOrder(bo, "", "");
+    }
+
+    @Override
+    public R<ErrorInfo> dealHikUploadOffLineRecord(RemoteConsumeBo remoteBo) {
+        ConsumptionBo bo = RemoteConsumeBoConvert.INSTANCE.fromRemote(remoteBo);
+        return consumeBusiness.fullOrder(bo, "", "");
+    }
 }

+ 116 - 22
ruoyi-server/ruoyi-server-hik/src/main/java/org/dromara/server/hik/controller/TestController.java

@@ -1,44 +1,42 @@
 package org.dromara.server.hik.controller;
 
 import cn.dev33.satoken.annotation.SaIgnore;
-import cn.hutool.core.collection.CollectionUtil;
-import cn.hutool.json.JSONObject;
-import cn.hutool.json.JSONUtil;
-import io.undertow.servlet.spec.PartImpl;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ObjectUtil;
 import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
 import jakarta.servlet.http.Part;
-import jodd.util.StringUtil;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.fileupload.FileItemFactory;
-import org.apache.commons.fileupload.disk.DiskFileItemFactory;
-import org.apache.commons.fileupload.servlet.ServletFileUpload;
-import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
+import org.apache.dubbo.config.annotation.DubboReference;
 import org.dromara.common.core.domain.R;
-import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.core.domain.model.ErrorInfo;
+import org.dromara.common.core.domain.model.ErrorResult;
+import org.dromara.common.core.enums.CreditTypeEnum;
+import org.dromara.consume.api.RemoteConsumeService;
+import org.dromara.consume.api.domain.bo.RemoteConsumeBo;
+import org.dromara.consume.api.domain.bo.RemoteResultDto;
 import org.dromara.server.hik.domain.dto.DeviceDto;
 import org.dromara.server.hik.domain.dto.QueryDto;
 import org.dromara.server.hik.domain.dto.UploadEmpDto;
 import org.dromara.server.hik.event.EventHandleRouter;
 import org.dromara.server.hik.event.domain.FileContent;
 import org.dromara.server.hik.service.ISendDeviceService;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
 import org.springframework.util.StreamUtils;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
-import org.springframework.web.multipart.MultipartHttpServletRequest;
-import org.springframework.web.multipart.MultipartResolver;
-import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;
 
 import java.io.BufferedReader;
-import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.math.BigDecimal;
 import java.nio.charset.Charset;
-import java.nio.file.Path;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
 
 /**
  * 海康消费机
@@ -61,6 +59,9 @@ public class TestController {
 
     private final EventHandleRouter eventHandleRouter;
 
+    @DubboReference
+    private final RemoteConsumeService remoteConsumeService;
+
     //region 设备监听相关
     /**
      * 设置指定设备监听服务地址
@@ -232,6 +233,7 @@ public class TestController {
         return sendDeviceService.upLoadEmpToDevice();
     }
     //endregion
+
     /**
      * 删除指定设备上某个用户的所有卡片信息。
      * <p>
@@ -246,6 +248,18 @@ public class TestController {
         return sendDeviceService.deleteAllCardByUserNo(device,userNo);
     }
 
+    /**
+     * 接收并处理发送到服务器的设备推送数据。
+     * 该方法处理不同类型的 content,包括 multipart/form-data 和 application/json。
+     * 对于 multipart/form-data,它分别处理 JSON 和 image/jpeg 部分。
+     * 对于 application/json,它直接处理 JSON 负载。
+     * 如果内容类型不受支持,则记录警告并返回 null。
+     *
+     * @param request 包含传入数据和元数据的 HttpServletRequest 对象。
+     *                它必须包含适合处理的内容类型和有效负载。
+     * @return 一个包含由 eventHandleRouter 路由的处理数据的 Map<String, Object>。
+     *         如果在处理过程中发生错误或内容类型不受支持,则返回 null。
+     */
     @PostMapping(("/info"))
     public Map<String, Object> receiveDevicePushData(HttpServletRequest request) throws IOException {
         try {
@@ -317,8 +331,88 @@ public class TestController {
         return null;
     }
 
-      // 处理 JSON 请求
+    /**
+     * 根据提供的消费信息处理海康消费机的消费请求。
+     * 该方法处理传入的请求,验证消费详情,
+     * 并执行必要的操作以完成消费请求。
+     *
+     * @param mapConsumeInfo 包含消费详细信息的键值对的 Map
+     * @return 表示消费请求处理结果的 Object
+     */
+    @PostMapping("/requestConsume")
+    public Object requestConsume(@RequestBody Map<String, Object> mapConsumeInfo) {
+        RemoteConsumeBo remoteBo = new RemoteConsumeBo();
+        if(ObjectUtil.isNotEmpty(mapConsumeInfo.get("userNo"))){
+            remoteBo.setUserNo(Long.valueOf(mapConsumeInfo.get("userNo").toString()));
+        }
+        if(ObjectUtil.isNotEmpty(mapConsumeInfo.get("factoryId"))){
+            remoteBo.setFactoryId(Long.valueOf(mapConsumeInfo.get("factoryId").toString()));
+        } else {
+            remoteBo.setFactoryId(0L);
+        }
+        if(ObjectUtil.isNotEmpty(mapConsumeInfo.get("consumeDate"))){
+            remoteBo.setConsumeDate(DateUtil.parseDateTime(mapConsumeInfo.get("consumeDate").toString()));
+        }
+        if(ObjectUtil.isNotEmpty(mapConsumeInfo.get("termRecordId"))){
+            remoteBo.setTermRecordId(Long.valueOf(mapConsumeInfo.get("termRecordId").toString()));
+        }
+        if(ObjectUtil.isNotEmpty(mapConsumeInfo.get("consumeMoney"))){
+            remoteBo.setConsumeMoney(new BigDecimal(mapConsumeInfo.get("consumeMoney").toString()));
+        }
+        if(ObjectUtil.isNotEmpty(mapConsumeInfo.get("termMac"))){
+            remoteBo.setTermMac(mapConsumeInfo.get("termMac").toString());
+        }
+        remoteBo.setCardNo(0L);
+        remoteBo.setStatusFlag(4);
+        remoteBo.setCreditType(CreditTypeEnum.TERM_CONSUME.code());
+
+        RemoteResultDto result = remoteConsumeService.dealHikRequestConsume(remoteBo);
+        R<ErrorInfo> errorInfo = result.getErrorInfo();
+        if (R.isError(errorInfo)) {
+            ErrorResult errResult = new ErrorResult();
+            errResult.setStatusCode(HttpStatus.NOT_FOUND.value());
+            errResult.setMessage(errorInfo.getMsg());
+            errResult.getErrors().add(errorInfo.getData());
+            return new ResponseEntity<Object>(errResult, null, HttpStatus.NOT_FOUND);
+        }
+        // if(ObjectUtil.isNotEmpty(mapConsumeInfo.get("qrCode"))){
+        //     remoteBo.setUserNo(Long.valueOf(mapConsumeInfo.get("qrCode").toString()));
+        // }
+        return result.getUpdatedRemoteBo();
+    }
+
+    /**
+     * 将消费记录上传到服务器。
+     *
+     * @param mapConsumeInfo 包含要上传的消费信息的 Map。
+     *                       键表示字段名称,值表示相应的数据。
+     * @return 表示上传操作结果的 Object。
+     *         这可能是成功消息、错误详情或其他相关信息。
+     */
+    @PostMapping("/uploadRecord")
+    public Object uploadConsumeRecord(@RequestBody Map<String, Object> mapConsumeInfo) {
+
+
+        return null;
+    }
+
+    /**
+     * 将离线记录上传到服务器。
+     * 该方法处理提供的消费信息并负责上传过程。
+     *
+     * @param mapConsumeInfo 包含要上传的消费信息的 Map
+     * @return 表示上传操作结果的 Object
+     */
+    @PostMapping("/offlineRecord")
+    public Object uploadOfflineRecord(@RequestBody Map<String, Object> mapConsumeInfo) {
+
+
+        return null;
+    }
+
+    // 处理 JSON 请求
     private String handleJsonRequest(HttpServletRequest request) throws IOException {
+
         if (request.getContentType() != null
                 && request.getContentType().contains("application/json")) {
 
@@ -331,9 +425,9 @@ public class TestController {
 
                 return requestData.toString();
                 // 使用任意 JSON 库解析
-//                JSONObject jsonObject = JSONUtil.parseObj(requestData.toString());
-//                System.out.println("收到 JSON 数据:");
-//                System.out.println(jsonObject.toString());
+                //                JSONObject jsonObject = JSONUtil.parseObj(requestData.toString());
+                //                System.out.println("收到 JSON 数据:");
+                //                System.out.println(jsonObject.toString());
             }
         }
         return null;