Эх сурвалжийг харах

refactor(app): 优化课程核销和订单处理逻辑

wzq 1 долоо хоног өмнө
parent
commit
d0f060a3b4
16 өөрчлөгдсөн 482 нэмэгдсэн , 168 устгасан
  1. 49 40
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/controller/OrderController.java
  2. 17 9
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/controller/commercial/CommercialController.java
  3. 2 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/service/IAppIsinService.java
  4. 1 1
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/service/IOrderService.java
  5. 198 8
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/service/WeChatPayService.java
  6. 5 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/service/impl/AppIsinServiceImpl.java
  7. 28 61
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/service/impl/OrderServiceImpl.java
  8. 9 8
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/config/WechatPayV3Utils.java
  9. 10 4
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/config/WechatUrlConstants.java
  10. 15 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/entity/RefundAmount.java
  11. 20 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/entity/RefundsForm.java
  12. 44 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/entity/WeChatRefundParam.java
  13. 55 36
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/paytest/payController.java
  14. 2 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/mapper/AppIsinMapper.java
  15. 26 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/mapper/xml/AppIsinMapper.xml
  16. 1 1
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/service/impl/AppCoureseServiceImpl.java

+ 49 - 40
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/controller/OrderController.java

@@ -13,6 +13,7 @@ import org.jeecg.modules.app.form.CreateOrderForm;
 import org.jeecg.modules.app.form.PageOrdersForm;
 import org.jeecg.modules.app.form.UserPayForm;
 import org.jeecg.modules.app.service.IOrderService;
+import org.jeecg.modules.app.service.WeChatPayService;
 import org.jeecg.modules.app.vo.OrderVO;
 import org.jeecg.modules.app.vo.PageOrdersVO;
 import org.jeecg.modules.app.vo.QueryOrderVerifyRecordsVO;
@@ -24,12 +25,11 @@ import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
+import java.security.GeneralSecurityException;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
-import static java.lang.Thread.sleep;
-
 @Slf4j
 @Tag(name = "APP订单相关接口")
 @RestController
@@ -37,91 +37,95 @@ import static java.lang.Thread.sleep;
 public class OrderController {
     @Resource
     private IOrderService appOrderService;
+    @Resource
+    private WeChatPayService weChatPayService;
+
     /**
+     * @return Result<OrderVO.PreviewOrderPlaceSchool>
      * @Author SheepHy
      * @Description 学校场地预约-预览页
      * @Date 10:10 2025/7/14
      * @Param placeId startTime
-     * @return Result<OrderVO.PreviewOrderPlaceSchool>
      **/
-    @Operation(summary="学校场地预约-预览页")
+    @Operation(summary = "学校场地预约-预览页")
     @GetMapping("/previewOrderPlaceSchool")
-    public Result<OrderVO.PreviewOrderPlaceSchool> previewOrderPlaceSchool(@RequestParam("placeId") @Schema(description = "场地ID")String placeId,
+    public Result<OrderVO.PreviewOrderPlaceSchool> previewOrderPlaceSchool(@RequestParam("placeId") @Schema(description = "场地ID") String placeId,
                                                                            @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
                                                                            @DateTimeFormat(pattern = "yyyy-MM-dd")
-                                                                           @RequestParam("startTime") @Schema(description = "当前选择日期(年月日)")Date startTime){
-        return Result.ok(appOrderService.previewOrderPlaceSchool(placeId,startTime));
+                                                                           @RequestParam("startTime") @Schema(description = "当前选择日期(年月日)") Date startTime) {
+        return Result.ok(appOrderService.previewOrderPlaceSchool(placeId, startTime));
     }
 
     /**
+     * @return boolean
      * @Author SheepHy
      * @Description 课程限购校验
      * @Date 16:22 2025/7/14
      * @Param courseId 课程ID
-     * @return boolean
      **/
-    @Operation(summary="课程限购校验")
+    @Operation(summary = "课程限购校验")
     @GetMapping("/checkCourseLimitNum")
-    public Result<Boolean> checkCourseLimitNum(@RequestParam("courseId") @Schema(description = "课程ID")String courseId,
-                                               @RequestParam("limitNum") @Schema(description = "购买数")int limitNum){
+    public Result<Boolean> checkCourseLimitNum(@RequestParam("courseId") @Schema(description = "课程ID") String courseId,
+                                               @RequestParam("limitNum") @Schema(description = "购买数") int limitNum) {
         return Result.OK(appOrderService.checkCourseLimitNum(courseId, limitNum));
     }
 
     /**
+     * @return OrderVO.PreviewOrderCourseSchool {@link OrderVO.PreviewOrderCourse}
      * @Author SheepHy
      * @Description 课程购买-预览页(学校课程、体育馆课程、教练课程)
      * @Date 15:43 2025/7/14
      * @Param courseId
-     * @return OrderVO.PreviewOrderCourseSchool {@link OrderVO.PreviewOrderCourse}
      **/
-    @Operation(summary="课程购买-预览页(学校课程、体育馆课程、教练课程)")
+    @Operation(summary = "课程购买-预览页(学校课程、体育馆课程、教练课程)")
     @GetMapping("/previewOrderCourse")
-    public Result<OrderVO.PreviewOrderCourse> previewOrderCourse(@RequestParam("courseId") @Schema(description = "课程ID")String courseId){
+    public Result<OrderVO.PreviewOrderCourse> previewOrderCourse(@RequestParam("courseId") @Schema(description = "课程ID") String courseId) {
         return Result.ok(appOrderService.previewOrderCourse(courseId));
     }
 
     /**
+     * @return OrderVO.PreviewOrderPlaceGymnasiumChartered {@link OrderVO.PreviewOrderPlaceGymnasiumChartered}
      * @Author SheepHy
      * @Description 体育馆包场-预览页
      * @Date 16:13 2025/7/14
      * @Param placeId
-     * @return OrderVO.PreviewOrderPlaceGymnasiumChartered {@link OrderVO.PreviewOrderPlaceGymnasiumChartered}
      **/
-    @Operation(summary="体育馆包场-预览页")
+    @Operation(summary = "体育馆包场-预览页")
     @GetMapping("/previewOrderPlaceGymnasiumChartered")
-    public Result<OrderVO.PreviewOrderPlaceGymnasiumChartered> previewOrderPlaceGymnasiumChartered(@RequestParam("rulesId") @Schema(description = "场次IDS多个逗号拼接")String rulesId){
+    public Result<OrderVO.PreviewOrderPlaceGymnasiumChartered> previewOrderPlaceGymnasiumChartered(@RequestParam("rulesId") @Schema(description = "场次IDS多个逗号拼接") String rulesId) {
         return Result.ok(appOrderService.previewOrderPlaceGymnasiumChartered(rulesId));
     }
 
     /**
+     * @return OrderVO.createOrderPlaceSchool
      * @Author SheepHy
      * @Description 学校场地预约-创建
      * @Date 10:10 2025/7/14
      * @Param rulesId 时间段ID
-     * @return OrderVO.createOrderPlaceSchool
      **/
-    @Operation(summary="学校场地预约-创建")
+    @Operation(summary = "学校场地预约-创建")
     @GetMapping("/createOrderPlaceSchool")
-    public Result<OrderVO.createOrderPlaceSchool> createOrderPlaceSchool(@RequestParam("rulesId") @Schema(description = "场次IDS多个逗号拼接")String rulesId,
-                                                                         @RequestParam("userIds") @Schema(description = "使用用户IDS多个逗号拼接")String userIds){
+    public Result<OrderVO.createOrderPlaceSchool> createOrderPlaceSchool(@RequestParam("rulesId") @Schema(description = "场次IDS多个逗号拼接") String rulesId,
+                                                                         @RequestParam("userIds") @Schema(description = "使用用户IDS多个逗号拼接") String userIds) {
         return Result.ok(appOrderService.createOrderPlaceSchool(rulesId, userIds));
     }
 
     /**
+     * @return OrderVO.PreviewOrderPlaceSchoolTime {@link OrderVO.PreviewOrderPlaceSchoolTime}
      * @Author SheepHy
      * @Description 学校包场-预览时间选择
      * @Date 14:45 2025/7/17
      * @Param placeId
-     * @return OrderVO.PreviewOrderPlaceSchoolTime {@link OrderVO.PreviewOrderPlaceSchoolTime}
      **/
-    @Operation(summary="学校包场-预览时间选择")
+    @Operation(summary = "学校包场-预览时间选择")
     @GetMapping("/previewOrderPlaceSchoolTime")
-    public Result<List<OrderVO.PreviewOrderPlaceSchoolTime>> previewOrderPlaceSchoolTime(@RequestParam("placeId") @Schema(description = "当前选择场次ID")String placeId){
+    public Result<List<OrderVO.PreviewOrderPlaceSchoolTime>> previewOrderPlaceSchoolTime(@RequestParam("placeId") @Schema(description = "当前选择场次ID") String placeId) {
         return Result.ok(appOrderService.previewOrderPlaceSchoolTime(placeId));
     }
 
     /**
      * 订单-创建
+     *
      * @param createOrderForm
      * @return
      */
@@ -134,70 +138,75 @@ public class OrderController {
 
     /**
      * 支付回调
+     *
      * @param request
      * @return
      */
     @Operation(summary = "支付回调")
     @RepeatSubmit(serviceId = "createOrder", limitType = RepeatSubmit.Type.PARAM, lockTime = 10)
     @RequestMapping("/wechatPayNotify")
-    public Map<String, String> wechatPayNotify(HttpServletRequest request, HttpServletResponse  response) throws InterruptedException {
-        sleep(10000);
+    public Map<String, String> wechatPayNotify(HttpServletRequest request, HttpServletResponse response) throws InterruptedException {
         return appOrderService.wechatPayNotify(request, response);
     }
 
     /**
      * 订单支付是否成功查询
+     *
      * @param orderCode
      * @return
      */
     @Operation(summary = "订单支付是否成功查询")
     @GetMapping("/orderQuery")
-    public Result<String> orderQuery(@RequestParam(name = "orderCode")String orderCode) throws IOException {
+    public Result<String> orderQuery(@RequestParam(name = "orderCode") String orderCode) throws IOException {
         return Result.OK(appOrderService.orderQuery(orderCode));
     }
 
     /**
      * 分页查询我的订单列表
+     *
      * @param pageOrdersForm
      * @return
      */
     @Operation(summary = "分页查询我的订单列表")
     @PostMapping("/pageOrders")
-    public Result<IPage<PageOrdersVO>> pageOrders(@RequestBody PageOrdersForm pageOrdersForm){
+    public Result<IPage<PageOrdersVO>> pageOrders(@RequestBody PageOrdersForm pageOrdersForm) {
         return Result.OK(appOrderService.pageOrders(pageOrdersForm));
     }
 
     /**
      * 订单主动取消
+     *
      * @param orderId
      * @return
      */
     @Operation(summary = "订单主动取消")
     @PutMapping("/cancelOrder")
-    public Result<String> cancelOrder(@RequestParam(name = "orderId")String orderId){
+    public Result<String> cancelOrder(@RequestParam(name = "orderId") String orderId) {
         return Result.OK(appOrderService.cancelOrder(orderId));
     }
 
     /**
      * 订单退款
+     *
      * @param orderCode
      * @return
      */
     @Operation(summary = "订单退款")
     @PutMapping("/refundOrder")
-    public Result<String> refundOrder(@RequestParam(name = "orderCode")String orderCode){
-        return Result.OK(appOrderService.refundOrder(orderCode));
+    public Result<String> refundOrder(@RequestParam(name = "orderCode") String orderCode,@RequestParam(name = "reason") String reason) {
+        return Result.OK(appOrderService.refundOrder(orderCode,reason));
     }
 
     /**
-     * 订单退款
-     * @param request
+     * 订单退款回调
+     *
+     * @param jsonData
      * @return
      */
     @Operation(summary = "订单退款回调")
     @RequestMapping("/refundOrderNotify")
-    public Result<String> refundOrderNotify(HttpServletRequest request){
-        return Result.OK();
+    public Map<String, Object> refundOrderNotify(@RequestBody String jsonData) throws GeneralSecurityException, IOException {
+        return weChatPayService.refundOrderNotify(jsonData);
     }
 
     /**
@@ -222,20 +231,20 @@ public class OrderController {
     @Operation(summary = "订单-查询课程课时核销记录")
     @GetMapping("/queryOrderVerifyRecords")
     public Result<List<QueryOrderVerifyRecordsVO>> queryOrderVerifyRecords(@Schema(description = "订单ID") @RequestParam(name = "orderId") String orderId,
-                                                                     @Schema(description = "券号") @RequestParam(name = "ticketNo") String ticketNo) {
-        return Result.ok(appOrderService.queryOrderVerifyRecords(orderId,ticketNo));
+                                                                           @Schema(description = "券号") @RequestParam(name = "ticketNo") String ticketNo) {
+        return Result.ok(appOrderService.queryOrderVerifyRecords(orderId, ticketNo));
     }
 
     /**
+     * @return
      * @Author SheepHy
      * @Description 体育馆无固定场-预览页
      * @Date 17:22 2025/8/4
      * @Param
-     * @return
      **/
-    @Operation(summary="体育馆无固定场-预览页")
+    @Operation(summary = "体育馆无固定场-预览页")
     @GetMapping("/PreviewOrderPlaceGymnasiumNoFixation")
-    public Result<OrderVO.PreviewOrderPlaceGymnasiumNoFixation> previewOrderPlaceGymnasiumNoFixation(@RequestParam("placeId") @Schema(description = "场地ID")String placeId){
+    public Result<OrderVO.PreviewOrderPlaceGymnasiumNoFixation> previewOrderPlaceGymnasiumNoFixation(@RequestParam("placeId") @Schema(description = "场地ID") String placeId) {
         return Result.ok(appOrderService.previewOrderPlaceGymnasiumNoFixation(placeId));
     }
 }

+ 17 - 9
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/controller/commercial/CommercialController.java

@@ -1,5 +1,6 @@
 package org.jeecg.modules.app.controller.commercial;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -17,19 +18,13 @@ import org.jeecg.modules.app.form.CourseQueryUsersForm;
 import org.jeecg.modules.app.form.TemporaryCourseForm;
 import org.jeecg.modules.app.service.IAppIsinService;
 import org.jeecg.modules.app.vo.*;
-import org.jeecg.modules.system.app.entity.AppCoursesPriceRules;
-import org.jeecg.modules.system.app.entity.AppCoursesVerificationRecord;
-import org.jeecg.modules.system.app.entity.AppOrderProInfo;
-import org.jeecg.modules.system.app.entity.FamilyMembers;
+import org.jeecg.modules.system.app.entity.*;
 import org.jeecg.modules.system.app.form.VerifyForm;
 import org.jeecg.modules.system.app.service.*;
 import org.springframework.web.bind.annotation.*;
 
 import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
-import java.util.TreeSet;
+import java.util.*;
 import java.util.stream.Collectors;
 
 @Slf4j
@@ -53,6 +48,8 @@ public class CommercialController {
 
     private final IAppIsinService appIsinService;
 
+    private final IAppInstructorService appInstructorService;
+
     /**
      * 查询部门下的课程
      *
@@ -141,7 +138,11 @@ public class CommercialController {
         List<FamilyMembers> differenceList = list.stream()
                 .filter(e -> !familUserIds.contains(e.getId()))
                 .collect(Collectors.toList());
-        return Result.OK(differenceList);
+        List<FamilyMembers> unique = differenceList.stream().collect(
+                Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(FamilyMembers::getPhone))),
+                        ArrayList::new)
+        );
+        return Result.OK(unique);
     }
 
     /**
@@ -230,8 +231,15 @@ public class CommercialController {
     public Result<IPage<AppIsinVerifyVO>> pageAppIsinVerifyRecords(@Schema(description = "页数") @RequestParam(name = "pageNo") Integer pageNo,
                                                                    @Schema(description = "条数") @RequestParam(name = "pageSize") Integer pageSize) {
         LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+        List<AppInstructor> list = appInstructorService.list();
+        List<AppInstructor> collect = list.stream().filter(e -> Objects.equals(loginUser.getId(), e.getUserId())).collect(Collectors.toList());
         String orgCode = loginUser.getOrgCode();
         Page<AppIsinVerifyVO> page = new Page<>(pageNo, pageSize);
+        //是否为教练
+        if (CollUtil.isNotEmpty(collect)){
+            Page<AppIsinVerifyVO> pageList = appIsinService.pageAppIsinVerifies(page, orgCode);
+            return Result.OK(pageList);
+        }
         Page<AppIsinVerifyVO> pageList = appIsinService.pageAppIsinVerifyRecords(page, orgCode);
         return Result.OK(pageList);
     }

+ 2 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/service/IAppIsinService.java

@@ -11,6 +11,8 @@ public interface IAppIsinService extends IService<AppIsin> {
 
     Page<AppIsinVerifyVO> pageAppIsinVerifyRecords(Page<AppIsinVerifyVO> page, String orgCode);
 
+    Page<AppIsinVerifyVO> pageAppIsinVerifies(Page<AppIsinVerifyVO> page, String userId);
+
     String repealVerifyRecord(String appIsinId) throws ParseException;
 
 }

+ 1 - 1
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/service/IOrderService.java

@@ -93,7 +93,7 @@ public interface IOrderService {
 
     IPage<PageOrdersVO> pageOrders(PageOrdersForm pageOrdersForm);
 
-    String refundOrder(String orderCode);
+    String refundOrder(String orderCode, String reason);
 
     Map<String, String> wechatPayNotify(HttpServletRequest request, HttpServletResponse response);
 }

+ 198 - 8
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/service/WeChatPayService.java

@@ -1,5 +1,6 @@
 package org.jeecg.modules.app.service;
 
+import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson2.JSONArray;
@@ -8,22 +9,36 @@ import com.aliyun.oss.ServiceException;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.jeecg.common.constant.CommonConstant;
 import org.jeecg.modules.pay.config.WechatConstants;
 import org.jeecg.modules.pay.config.WechatPayV3Utils;
 import org.jeecg.modules.pay.config.WechatUrlConstants;
+import org.jeecg.modules.pay.serverPay.WXPayUtility;
 import org.jeecg.modules.system.app.entity.AppOrder;
+import org.jeecg.modules.system.app.entity.AppOrderProInfo;
 import org.jeecg.modules.system.app.mapper.AppOrderMapper;
+import org.jeecg.modules.system.app.mapper.AppOrderProInfoMapper;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
+import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
 import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
 import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
+import java.security.GeneralSecurityException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
 import java.text.DateFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
+import java.util.concurrent.ThreadLocalRandom;
 
 /**
  * @author wangzhiqiang
@@ -40,6 +55,9 @@ public class WeChatPayService {
     @Resource
     private AppOrderMapper appOrderMapper;
 
+    @Resource
+    private AppOrderProInfoMapper appOrderProInfoMapper;
+
 
     /**
      * 小程序支付拉起
@@ -60,7 +78,7 @@ public class WeChatPayService {
         StringBuilder sb = new StringBuilder();
         //返回给小程序拉起微信支付的参数
         Map<String, String> result = new HashMap<>();
-        result.put("appId", WechatConstants.WECHAT_SP_APPID); //小程序appid
+        result.put("appId", WechatConstants.WECHAT_SUB_APPID); //小程序appid
         sb.append(result.get("appId")).append("\n");
         result.put("timeStamp", (new Date().getTime() / 1000) + ""); //时间戳
         sb.append(result.get("timeStamp")).append("\n");
@@ -178,9 +196,25 @@ public class WeChatPayService {
         // 处理支付成功后的业务 例如 将订单状态修改为已支付 具体参数键值可参考文档 注意!!! 微信可能会多次发送重复的通知 因此要判断业务是否已经处理过了 避免重复处理
         try {
             String orderCode = res.getString("out_trade_no");
-            //查询订单,判断是否已修改已支付状态
+            //查询订单,判断是否已修改已支付状态
             AppOrder appOrder = appOrderMapper.selectOne(Wrappers.<AppOrder>lambdaQuery().eq(AppOrder::getOrderCode, orderCode).last("limit 1"));
-
+            if (ObjectUtil.isNotEmpty(appOrder)) {
+                if (Objects.equals(appOrder.getOrderStatus(), CommonConstant.ORDER_STATUS_0)){
+                    appOrder.setOrderStatus(CommonConstant.ORDER_STATUS_1);
+                    appOrder.setPayStatus(CommonConstant.ORDER_STATUS_1);
+                    appOrder.setPayTime(new Date());
+                    appOrder.setPayType(CommonConstant.STATUS_0_INT);
+                    appOrder.setCallbackStatus(CommonConstant.STATUS_1_INT);
+                    appOrderMapper.updateById(appOrder);
+                    List<AppOrderProInfo> proInfoList = appOrderProInfoMapper.selectList(Wrappers.<AppOrderProInfo>lambdaQuery().eq(AppOrderProInfo::getOrderId, appOrder.getId()));
+                    if (ObjectUtil.isNotEmpty(proInfoList)){
+                        for (AppOrderProInfo appOrderProInfo : proInfoList) {
+                            appOrderProInfo.setOrderStatus(CommonConstant.ORDER_STATUS_1);
+                            appOrderProInfoMapper.updateById(appOrderProInfo);
+                        }
+                    }
+                }
+            }
             result.put("code", "SUCCESS");
             result.put("message", "OK");
             result.put("orderCode",orderCode);
@@ -190,7 +224,6 @@ public class WeChatPayService {
             result.put("message", "失败");
             return result;
         }
-
     }
 
     /**
@@ -200,8 +233,165 @@ public class WeChatPayService {
      * @return null代表查询失败 SUCCESS-成功 USERPAYING和ACCEPT为中间态 其他为支付失败
      */
     public String orderQueryByOutTradeNo(String out_trade_no) {
-        JSONObject res = wechatPayV3Utils.sendGet(String.format(WechatUrlConstants.PAY_V3_QUERY_OUT, out_trade_no, WechatConstants.WECHAT_SP_APPID));
+        String url = WechatUrlConstants.PAY_V3_QUERY_OUT;
+        url = url.replace("{out_trade_no}", WXPayUtility.urlEncode(out_trade_no));
+        Map<String, Object> args = new HashMap<>();
+        args.put("sp_mchid", WechatConstants.WECHAT_SP_MCH_ID);
+        args.put("sub_mchid", WechatConstants.WECHAT_SUB_MCH_ID);
+        url = url + "?" + WXPayUtility.urlEncode(args);
+        JSONObject res = wechatPayV3Utils.sendGet(url);
         return res == null ? null : res.getString("trade_state");
     }
 
+    /**
+     * 申请退款
+     * @param orderCode 原订单号
+     */
+    public void refundOrder(String orderCode,String reason){
+
+        log.info("进入退款接口------>");
+        log.info("执行操作的 原支付交易对应的商户订单号:{}", orderCode);
+
+        Integer totalFee = 1;
+        Integer total = 1;
+        AppOrder appOrder = appOrderMapper.selectOne(Wrappers.<AppOrder>lambdaQuery().eq(AppOrder::getOrderCode, orderCode).last("limit 1"));
+        if (ObjectUtil.isNotEmpty(appOrder)) {
+            total = appOrder.getPrice().intValue();
+            totalFee = appOrder.getPrice().intValue();
+        }
+        //退款单号
+        String out_refund_no = generateOrderNumber(1);
+
+        //todo 创建退款订单
+
+
+        //todo 发起分账回退
+
+        try {
+            JSONObject params = new JSONObject();
+            params.put("out_trade_no", orderCode);//商户订单号
+            params.put("out_refund_no", out_refund_no);//商户退款单号
+            params.put("reason", reason);//退款原因
+            params.put("notify_url", WechatUrlConstants.PAY_V3_REFUND_NOTIFY);//退款通知
+
+            JSONObject amount = new JSONObject();
+            amount.put("refund", (long) (totalFee * 100));//退款金额
+            amount.put("currency", "CNY");
+            amount.put("total", (long) (total * 100));//原订单金额
+            params.put("amount", amount);
+            // 执行请求POST 请求发送到微信退款接口
+            JSONObject res = wechatPayV3Utils.sendPost(WechatUrlConstants.PAY_V3_REFUND, params);
+
+            log.info("最终拿到的微信支付通知数据:" + res);
+
+            final String status = res.getString("status");
+            switch (status) {
+                case "SUCCESS":
+                    log.info("退款成功");
+                    break;
+                case "CLOSED":
+                    log.info("退款关闭");
+                    break;
+                case "PROCESSING":
+                    log.info("退款处理中");
+
+                    break;
+                case "ABNORMAL":
+                    log.info("退款异常");
+                    break;
+            }
+        } catch (Exception e) {
+            // TODO Auto-generated catch block
+            log.info(e.toString());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * @return String 订单号
+     * @Author SheepHy
+     * @Description 订单编号生成逻辑
+     * @Date 17:18 2025/7/15
+     * @params 类型:0-(D:订单) 1-(T:退单) 2-(B:保单)
+     **/
+    private String generateOrderNumber(int type) {
+        String format = DateUtil.format(new Date(), "yyyyMMddHHmmss");
+        int nextInt = ThreadLocalRandom.current().nextInt(1000, 10000);
+
+        if (type == 0) {
+            return "D" + format + nextInt;
+        } else {
+            return "T" + format + nextInt;
+        }
+    }
+
+    public Map<String, Object> refundOrderNotify(String jsonData) throws IOException, GeneralSecurityException {
+
+        //转为map格式
+        Map<String, String> jsonMap = JSONObject.parseObject(jsonData, Map.class);
+
+        //退款成功后返回一个加密字段resource,以下为解密
+        /**
+         * 解密需要从resource参数中,获取到ciphertext,nonce,associated_data这三个参数进行解密
+         */
+        String resource = JSONObject.toJSONString(jsonMap.get("resource"));
+        JSONObject object = JSONObject.parseObject(resource);
+
+        String ciphertext = String.valueOf(object.get("ciphertext"));
+        String nonce = String.valueOf(object.get("nonce"));
+        String associated_data = String.valueOf(object.get("associated_data"));
+
+        String resultStr = decryptToString(associated_data.getBytes(StandardCharsets.UTF_8), nonce.getBytes(StandardCharsets.UTF_8), ciphertext);
+        Map<String, String> reqInfo = JSONObject.parseObject(resultStr, Map.class);
+
+        String refund_status = reqInfo.get("refund_status");//退款状态
+        String out_trade_no = reqInfo.get("out_trade_no"); //订单号
+
+        Map<String, Object> parm = new HashMap<>();
+        if (!StringUtils.isEmpty(refund_status) && "SUCCESS".equals(refund_status))  {
+
+            //查询订单
+            AppOrder order = appOrderMapper.selectOne(Wrappers.<AppOrder>lambdaQuery().eq(AppOrder::getOrderCode, out_trade_no).last("limit 1"));
+            if (ObjectUtil.isNotEmpty(order)) {
+                if (order.getOrderStatus() == 0) {
+                    order.setOrderStatus(CommonConstant.ORDER_STATUS_1);
+                    order.setPayStatus(CommonConstant.ORDER_STATUS_1);
+                    order.setPayTime(new Date());
+                    order.setPayType(CommonConstant.STATUS_0_INT);
+                    order.setCallbackStatus(CommonConstant.STATUS_1_INT);
+                    appOrderMapper.updateById(order);
+                    List<AppOrderProInfo> proInfoList = appOrderProInfoMapper.selectList(Wrappers.<AppOrderProInfo>lambdaQuery().eq(AppOrderProInfo::getOrderId, order.getId()));
+                    if (ObjectUtil.isNotEmpty(proInfoList)) {
+                        for (AppOrderProInfo appOrderProInfo : proInfoList) {
+                            appOrderProInfo.setOrderStatus(CommonConstant.ORDER_STATUS_1);
+                            appOrderProInfoMapper.updateById(appOrderProInfo);
+                        }
+                    }
+                }
+            }
+            parm.put("code", "SUCCESS");
+            parm.put("message", "成功");
+        } else {
+            parm.put("code", "FAIL");
+            parm.put("message", "失败");
+            throw new RuntimeException("退款失败");
+        }
+        return parm;  //返回给前端的参数
+    }
+
+    //退款回调  解密数据
+    public String decryptToString(byte[] associatedData, byte[] nonce, String ciphertext) throws GeneralSecurityException, IOException {
+        try {
+            Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
+            SecretKeySpec key = new SecretKeySpec(WechatConstants.WECHAT_MCH_SECRET_V3.getBytes(), "AES");// 这里的apiV3key是你的商户APIV3密钥
+            GCMParameterSpec spec = new GCMParameterSpec(128, nonce);//规定为128
+            cipher.init(Cipher.DECRYPT_MODE, key, spec);
+            cipher.updateAAD(associatedData);
+            return new String(cipher.doFinal(Base64.getDecoder().decode(ciphertext)), StandardCharsets.UTF_8);
+        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
+            throw new IllegalStateException(e);
+        } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
 }

+ 5 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/service/impl/AppIsinServiceImpl.java

@@ -39,6 +39,11 @@ public class AppIsinServiceImpl extends ServiceImpl<AppIsinMapper, AppIsin> impl
         return baseMapper.pageAppIsinVerifyRecords(page,orgCode);
     }
 
+    @Override
+    public Page<AppIsinVerifyVO> pageAppIsinVerifies(Page<AppIsinVerifyVO> page, String userId) {
+        return baseMapper.pageAppIsinVerifies(page,userId);
+    }
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public String repealVerifyRecord(String appIsinId) throws ParseException {

+ 28 - 61
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/service/impl/OrderServiceImpl.java

@@ -17,7 +17,6 @@ import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.gson.JsonObject;
 import com.google.gson.JsonParser;
-import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
 import lombok.extern.log4j.Log4j2;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -38,8 +37,8 @@ import org.jeecg.modules.app.vo.OrderVO;
 import org.jeecg.modules.app.vo.PageOrdersVO;
 import org.jeecg.modules.app.vo.QueryOrderVerifyRecordsVO;
 import org.jeecg.modules.pay.config.WechatConstants;
+import org.jeecg.modules.pay.config.WechatPayV3Utils;
 import org.jeecg.modules.pay.config.WechatUrlConstants;
-import org.jeecg.modules.pay.serverPay.WxV3PayConfig;
 import org.jeecg.modules.redission.RedissonDelayQueue;
 import org.jeecg.modules.system.app.dto.receiptPaymentDetails.ReceiptPaymentDetailsInfoVo;
 import org.jeecg.modules.system.app.entity.*;
@@ -57,12 +56,9 @@ import org.springframework.transaction.annotation.Transactional;
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import java.io.BufferedReader;
 import java.io.IOException;
-import java.io.PrintWriter;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
-import java.nio.charset.StandardCharsets;
 import java.text.SimpleDateFormat;
 import java.time.LocalDate;
 import java.time.LocalTime;
@@ -129,6 +125,8 @@ public class OrderServiceImpl implements IOrderService {
     private WeChatPayService weChatPayService;
     @Resource
     private RedisTemplate<String, Object> redisTemplate;
+    @Resource
+    private WechatPayV3Utils wechatPayV3Utils;
 
     @Autowired
     IReceiptPaymentDetailsInfoService iReceiptPaymentDetailsInfoService;
@@ -1134,9 +1132,7 @@ public class OrderServiceImpl implements IOrderService {
         payForm.setOrderId(appOrder.getId()).setOrderCode(orderCode);
 
         //判断是否试听课(试听课不走订单)
-        if (ObjectUtil.isNotEmpty(appOrder.getOrderOrFree()) && appOrder.getOrderOrFree() == 1) {
-            payForm.setOrPayOrder(0);
-        } else if (appOrder.getOrderType() == 0) {
+        if (ObjectUtil.isNotEmpty(appOrder.getOrderOrFree()) && appOrder.getOrderOrFree() == 1 && appOrder.getPrice().compareTo(BigDecimal.ZERO)== 0) {
             payForm.setOrPayOrder(0);
         } else {
             Calendar calendar = Calendar.getInstance();
@@ -1156,13 +1152,14 @@ public class OrderServiceImpl implements IOrderService {
             params.put("attach", appOrder.getOrderCode()); //附加数据 选填
             // 在查询API和支付通知中原样返回 可作为自定义参数使用
             params.put("notify_url", WechatUrlConstants.PAY_V3_NOTIFY); //支付结果异步通知接口
-//            params.put("trade_type", WechatConstants.WECHAT_TRADE_TYPE);//JSAPI
             //分账必传参数
-            JSONObject settleInfo = new JSONObject();
-            settleInfo.put("profit_sharing", Boolean.TRUE);
-            params.put("settle_info", settleInfo);
+            if (appOrder.getOrderType() != 0){
+                JSONObject settleInfo = new JSONObject();
+                settleInfo.put("profit_sharing", Boolean.TRUE);
+                params.put("settle_info", settleInfo);
+            }
             //电子发票入口
-//            params.put("support_fapiao ", Boolean.TRUE);
+            params.put("support_fapiao", Boolean.TRUE);
 
             //订单金额信息
             JSONObject amount_json = new JSONObject();
@@ -1614,13 +1611,14 @@ public class OrderServiceImpl implements IOrderService {
     @Override
     public String orderQuery(String orderCode) throws IOException {
 
+        //查询订单
+        AppOrder appOrder = appOrderMapper.selectOne(Wrappers.<AppOrder>lambdaQuery().eq(AppOrder::getOrderCode, orderCode).last("limit 1"));
+
         //null代表查询失败 SUCCESS-成功 USERPAYING和ACCEPT为中间态 其他为支付失败
-//        String s = weChatPayService.orderQueryByOutTradeNo(orderCode);
-        String s = "SUCCESS";
-        if ("SUCCESS".equals(s)) {
-            //查询订单
-            AppOrder appOrder = appOrderMapper.selectOne(Wrappers.<AppOrder>lambdaQuery().eq(AppOrder::getOrderCode, orderCode).last("limit 1"));
-            if (ObjectUtil.isNotEmpty(appOrder)) {
+        String s = weChatPayService.orderQueryByOutTradeNo(orderCode);
+        if ("SUCCESS".equals(s) || appOrder.getOriginalPrice().compareTo(BigDecimal.ZERO)==0) {
+
+            if (ObjectUtil.isNotEmpty(appOrder) && Objects.equals(appOrder.getOrderStatus(), CommonConstant.ORDER_STATUS_0)) {
                 appOrder.setOrderStatus(1);
                 appOrderMapper.updateById(appOrder);
                 List<AppOrderProInfo> proInfoList = appOrderProInfoMapper.selectList(Wrappers.<AppOrderProInfo>lambdaQuery().eq(AppOrderProInfo::getOrderId, appOrder.getId()));
@@ -1696,12 +1694,9 @@ public class OrderServiceImpl implements IOrderService {
         });
         return pageOrders;
     }
-
     @Override
-    public String refundOrder(String orderCode) {
-
-        //todo 分账退款
-
+    @Transactional(rollbackFor = Exception.class)
+    public String refundOrder(String orderCode, String reason){
         AppOrder appOrder = appOrderMapper.selectOne(Wrappers.<AppOrder>lambdaQuery().eq(AppOrder::getOrderCode, orderCode).last("limit 1"));
         if (ObjectUtil.isNotEmpty(appOrder)) {
             if (appOrder.getOrderStatus() == 0) {
@@ -1715,48 +1710,20 @@ public class OrderServiceImpl implements IOrderService {
                     appOrderProInfoMapper.updateById(appOrderProInfo);
                 }
             }
-            return "退款成功!";
         }
+        //调用退款逻辑
+        weChatPayService.refundOrder(orderCode, reason);
 
-        return "退款失败!";
+        return "申请成功,预计在3个工作日内处理!";
     }
 
+    /**
+     * 支付回调
+     * @param request
+     * @param response
+     * @return
+     */
     public Map<String, String> wechatPayNotify(HttpServletRequest request, HttpServletResponse response) {
-
-        try {
-            System.err.println("微信回调");
-            BufferedReader reader = request.getReader();
-            String string1 = reader.toString();
-            StringBuilder requestBody = new StringBuilder();
-            String line;
-            while ((line = reader.readLine()) != null) {
-                requestBody.append(line);
-            }
-            System.err.println("全部请求体" + requestBody);
-            JSONObject jsonObject = JSONObject.parseObject(requestBody.toString());
-            JSONObject resource = jsonObject.getJSONObject("resource");
-            AesUtil aesUtil = new AesUtil(WxV3PayConfig.apiV3Key.getBytes(StandardCharsets.UTF_8));
-            String decryptedData = aesUtil.decryptToString(resource.getString("associated_data").getBytes(StandardCharsets.UTF_8), resource.getString("nonce").getBytes(StandardCharsets.UTF_8),
-                    resource.getString("ciphertext"));
-            System.err.println("微信解密的字符串信息" + decryptedData);
-            JSONObject jsonInfo = (JSONObject) JSONObject.parse(decryptedData);
-            String out_trade_no = jsonInfo.getString("out_trade_no");// 下单时传给微信的订单号
-            String transaction_id = jsonInfo.getString("transaction_id");// 返回的微信订单号
-            String trade_state = jsonInfo.getString("trade_state");// 交易状态     /*SUCCESS:支付成功 REFUND:转入退款 NOTPAY:未支付 CLOSED:已关闭 REVOKED:已撤销(仅付款码支付会返回)USERPAYING:用户支付中(仅付款码支付会返回)PAYERROR:支付失败(仅付款码支付会返回*/
-
-
-            if (trade_state.equals("SUCCESS")) {
-                // 支付成功,执行相应的代码逻辑即可
-                PrintWriter out = response.getWriter();
-                out.write("SUCCESS");
-                out.flush();
-                out.close();
-            }
-
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-
         Map<String, String> stringStringMap = weChatPayService.wechatPayNotify(request);
         //对订单进行封账金额统计
         if (stringStringMap != null

+ 9 - 8
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/config/WechatPayV3Utils.java

@@ -3,7 +3,6 @@ package org.jeecg.modules.pay.config;
 import com.alibaba.fastjson2.JSONObject;
 import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
 import com.wechat.pay.contrib.apache.httpclient.auth.*;
-import com.wechat.pay.contrib.apache.httpclient.auth.Signer;
 import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
 import com.wechat.pay.contrib.apache.httpclient.constant.WechatPayHttpHeaders;
 import com.wechat.pay.contrib.apache.httpclient.notification.Notification;
@@ -19,13 +18,15 @@ import org.apache.http.client.utils.URIBuilder;
 import org.apache.http.entity.StringEntity;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.util.EntityUtils;
+import org.springframework.core.io.ClassPathResource;
 import org.springframework.stereotype.Component;
 
 import javax.servlet.http.HttpServletRequest;
 import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
+import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
-import java.security.*;
+import java.security.PrivateKey;
+import java.security.Signature;
 import java.util.Base64;
 
 /**
@@ -50,12 +51,12 @@ public class WechatPayV3Utils {
      * 获取商户证书私钥
      */
     private void setMerchantPrivateKey() throws Exception {
-//        ClassPathResource classPathResource = new ClassPathResource("cert/apiclient_key.pem");
-//        InputStream certStream = classPathResource.getInputStream();
-//        //读取文件形式加载商户私钥
-//        merchantPrivateKey = PemUtil.loadPrivateKey(certStream);
+        ClassPathResource classPathResource = new ClassPathResource("cert/apiclient_key.pem");
+        InputStream certStream = classPathResource.getInputStream();
+        //读取文件形式加载商户私钥
+        merchantPrivateKey = PemUtil.loadPrivateKey(certStream);
         //直接把商户私钥以字符串形式配置
-        merchantPrivateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(WechatConstants.WECHAT_MCH_PRIVATE_KEY.getBytes(StandardCharsets.UTF_8)));
+//        merchantPrivateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(WechatConstants.WECHAT_MCH_PRIVATE_KEY.getBytes(StandardCharsets.UTF_8)));
     }
 
     /**

+ 10 - 4
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/config/WechatUrlConstants.java

@@ -11,10 +11,10 @@ public class WechatUrlConstants {
     public final static String PAY_V3_JSAPI = "https://api.mch.weixin.qq.com/v3/pay/partner/transactions/jsapi";
 
     //微信支付v3 申请退款
-    public final static String PAY_V3_REFUND = "https://api.mch.weixin.qq.com/v3/pay/partner/transactions/out-trade-no/{out_trade_no}";
+    public final static String PAY_V3_REFUND = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds";
 
     //微信支付v3 通过商户订单号查询订单
-    public final static String PAY_V3_QUERY_OUT = "https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/%s?mchid=%s";
+    public final static String PAY_V3_QUERY_OUT = "https://api.mch.weixin.qq.com/v3/pay/partner/transactions/out-trade-no/{out_trade_no}";
 
     //微信支付v3 支付通知接口地址
     public final static String PAY_V3_NOTIFY = "https://1caa0b6f.r28.cpolar.top/jeecg-boot/app/order/wechatPayNotify";
@@ -22,10 +22,16 @@ public class WechatUrlConstants {
     //微信支付v3 退款通知接口地址
     public final static String PAY_V3_REFUND_NOTIFY = "https://1caa0b6f.r28.cpolar.top/jeecg-boot/app/order/refundOrderNotify";
 
-    //微信支付v3 请求分账
+    //服务商 添加分账接收方
+    public final static String PAY_V3_RECEIVERS_ADD = "https://api.mch.weixin.qq.com/v3/profitsharing/receivers/add";
+
+    //服务商 删除分账接收方
+    public final static String PAY_V3_RECEIVERS_DELETE = "https://api.mch.weixin.qq.com/v3/profitsharing/receivers/delete";
+
+    //服务商 请求分账
     public final static String PAY_V3_PROFIT_SHARING = "https://api.mch.weixin.qq.com/v3/profitsharing/orders";
 
-    //微信支付v3 查询分账结果
+    //服务商 查询分账结果
     public final static String PAY_V3_QUERY_PROFIT_SHARING = "https://api.mch.weixin.qq.com/v3/profitsharing/orders/";
 
 }

+ 15 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/entity/RefundAmount.java

@@ -0,0 +1,15 @@
+package org.jeecg.modules.pay.entity;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class RefundAmount implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Integer refund;
+    private Integer total;
+    private String currency = "CNY";
+}

+ 20 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/entity/RefundsForm.java

@@ -0,0 +1,20 @@
+package org.jeecg.modules.pay.entity;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@Accessors(chain = true)
+public class RefundsForm implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private String sub_mchid;
+    private String out_trade_no;
+    private String out_refund_no;
+    private String reason;
+    private String notify_url;
+    private RefundAmount amount;
+}

+ 44 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/entity/WeChatRefundParam.java

@@ -0,0 +1,44 @@
+package org.jeecg.modules.pay.entity;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class WeChatRefundParam {
+
+    /**
+     * 微信支付订单号,微信支付订单号和商家订单号二选一
+     */
+    private String transactionId;
+
+    /**
+     * 商家订单号,对应 out_trade_no,
+     */
+    private String orderId;
+
+    /**
+     * 商户退款单号,对应out_refund_no
+     */
+    private String refundOrderId;
+
+    /**
+     * 退款原因,选填
+     */
+    private String reason;
+
+    /**
+     * 回调地址
+     */
+    private String notify;
+
+    /**
+     * 退款金额
+     */
+    private BigDecimal refundMoney;
+
+    /**
+     * 原订单金额,必填
+     */
+    private BigDecimal totalMoney;
+}

+ 55 - 36
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/paytest/payController.java

@@ -1,15 +1,25 @@
 package org.jeecg.modules.pay.paytest;
 
 
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.RandomUtil;
 import com.alibaba.fastjson2.JSONObject;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.jeecg.modules.pay.config.WechatPayV3Utils;
 import org.jeecg.modules.pay.config.WechatUrlConstants;
+import org.jeecg.modules.pay.entity.ProfitSharingRequest;
+import org.jeecg.modules.pay.entity.Receiver;
+import org.jeecg.modules.system.app.entity.AppOrder;
+import org.jeecg.modules.system.app.service.IAppOrderService;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.util.ArrayList;
+import java.util.List;
+
 @Slf4j
 @RestController
 @AllArgsConstructor
@@ -18,6 +28,8 @@ public class payController {
 
     private final WechatPayV3Utils wechatPayV3Utils;
 
+    private final IAppOrderService appOrderService;
+
     @GetMapping(value = "/getPay")
     public String getPay(String orderSn,int total , String description) {
         PayMerchantUtil payMerchantUtil = new PayMerchantUtil();
@@ -56,41 +68,48 @@ public class payController {
 //        return null;
 //    }
 
-//    @GetMapping(value = "/test")
-//    public JSONObject test(String out_order_no) {
-//        //1.参数封装
-//        /**
-//         * 分账接收方列表,不超过50个json对象,不能设置出资子商户作为分账接受方
-//         点击行前的+展开字段详情
-//         */
-//        List<Receiver> receivers = new ArrayList<>();
-//        //查询当前订单的分账接收方列表
-//        for (int i = 0; i < 1; i++) {
-//            Receiver receiver = new Receiver();
-//            receiver.setType("MERCHANT_ID")
-//                    .setAccount(ServiceProvider.sp_mchid)
-//                    .setAmount(1)
-//                    .setDescription("微信文档值得吐槽");
-//            receivers.add(receiver);
-//        }
-//        ProfitSharingRequest profitSharingRequest = new ProfitSharingRequest();
-//        profitSharingRequest
-//                .setNonce_str(RandomUtil.randomString(32))
-//                .setSign_type("HMAC-SHA256")
-//                .setAppid(ServiceProvider.sp_appid)
-//                .setSub_mchid(ServiceProvider.sub_mchid)
-//                .setTransaction_id("4200001042202104228993583353")
-//                .setOut_order_no("P001001001")
-//                .setReceivers(receivers)
-//                .setUnfreeze_unsplit(Boolean.TRUE);
-//        try {
-//            JSONObject res = wechatPayV3Utils.sendPost(WechatUrlConstants.PAY_V3_PROFIT_SHARING, JSONObject.from(profitSharingRequest));
-//            log.info("wechatPay res:{}", res.toString());
-//            return res;
-//        } catch (Exception e) {
-//            e.printStackTrace();
-//        }
-//        return null;
-//    }
+    @GetMapping(value = "/test1")
+    public JSONObject test(String out_order_no) {
+
+        AppOrder appOrder = appOrderService.getOne(Wrappers.lambdaQuery(AppOrder.class).eq(AppOrder::getOrderCode, out_order_no).last("limit 1"));
+
+        //1.参数封装
+        /**
+         * 分账接收方列表,不超过50个json对象,不能设置出资子商户作为分账接受方
+         点击行前的+展开字段详情
+         */
+        List<Receiver> receivers = new ArrayList<>();
+        if (ObjectUtil.isNotEmpty(appOrder)) {
+            String orgCode = appOrder.getOrgCode();
+            //通过orgCode查询订单的分账发起方及接收方
+        }
+        //查询当前订单的分账接收方列表
+        for (int i = 0; i < 1; i++) {
+            Receiver receiver = new Receiver();
+            receiver.setType("MERCHANT_ID")
+                    .setAccount(ServiceProvider.sp_mchid)
+                    .setAmount(1)
+                    .setDescription("微信文档值得吐槽");
+            receivers.add(receiver);
+        }
+        ProfitSharingRequest profitSharingRequest = new ProfitSharingRequest();
+        profitSharingRequest
+                .setNonce_str(RandomUtil.randomString(32))
+                .setSign_type("HMAC-SHA256")
+                .setAppid(ServiceProvider.sp_appid)
+                .setSub_mchid(ServiceProvider.sub_mchid)
+                .setTransaction_id("4200001042202104228993583353")
+                .setOut_order_no("P001001001")
+                .setReceivers(receivers)
+                .setUnfreeze_unsplit(Boolean.TRUE);
+        try {
+            JSONObject res = wechatPayV3Utils.sendPost(WechatUrlConstants.PAY_V3_PROFIT_SHARING, JSONObject.from(profitSharingRequest));
+            log.info("wechatPay res:{}", res.toString());
+            return res;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
 }
  

+ 2 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/mapper/AppIsinMapper.java

@@ -15,4 +15,6 @@ import org.jeecg.modules.system.app.entity.AppIsin;
 public interface AppIsinMapper extends BaseMapper<AppIsin> {
 
     Page<AppIsinVerifyVO> pageAppIsinVerifyRecords(Page page,@Param("orgCode") String orgCode);
+
+    Page<AppIsinVerifyVO> pageAppIsinVerifies(Page<AppIsinVerifyVO> page,@Param("userId") String userId);
 }

+ 26 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/mapper/xml/AppIsinMapper.xml

@@ -28,4 +28,30 @@
         ORDER BY
             i.use_time DESC
     </select>
+    <select id="pageAppIsinVerifies" resultType="org.jeecg.modules.app.vo.AppIsinVerifyVO">
+        SELECT
+            i.id,
+            i.use_time,
+            i.ticket_no,
+            i.isin_status,
+            i.remark,
+            opi.type,
+            opi.product_image,
+            opi.product_name,
+            opi.original_price,
+            opi.use_date_str,
+            opi.frame_time_str
+        FROM
+            nm_isin i
+                LEFT JOIN nm_order_pro_info opi ON i.order_pro_info_id = opi.id
+                LEFT JOIN nm_courses c on c.id = opi.product_id
+        <where>
+            i.isin_status = 1 and o.order_type != 0
+            <if test="userId != null and userId != ''">
+                and c.user_id = #{userId}
+            </if>
+        </where>
+        ORDER BY
+            i.use_time DESC
+    </select>
 </mapper>

+ 1 - 1
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/service/impl/AppCoureseServiceImpl.java

@@ -93,7 +93,7 @@ public class AppCoureseServiceImpl extends ServiceImpl<AppCoursesMapper, AppCour
             appCourses.setPriceType(0);
         }
 
-        if (ObjUtil.isNotEmpty(appCourses.getOriginalPrice())){
+        if (ObjUtil.isEmpty(appCourses.getOriginalPrice())){
             appCourses.setOriginalPrice(appCourses.getSellingPrice());
         }