Преглед на файлове

Merge remote-tracking branch 'origin/Payment'

yfh преди 1 месец
родител
ревизия
ca5568df20
променени са 57 файла, в които са добавени 1747 реда и са изтрити 573 реда
  1. 51 8
      fs-admin/src/main/java/com/fs/his/task/CompanyBalanceTask.java
  2. 3 0
      fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreOrderScrmController.java
  3. 60 12
      fs-admin/src/main/java/com/fs/hisStore/controller/FsStorePaymentScrmController.java
  4. 1 1
      fs-admin/src/main/resources/application.yml
  5. 4 4
      fs-company-app/src/main/java/com/fs/app/controller/FsUserController.java
  6. 0 1
      fs-company-app/src/main/java/com/fs/app/controller/FsUserCourseVideoController.java
  7. 1 1
      fs-company-app/src/main/java/com/fs/app/controller/WxCompanyUserController.java
  8. 38 0
      fs-company/src/main/java/com/fs/company/controller/common/CommonController.java
  9. 18 17
      fs-live-app/src/main/java/com/fs/live/task/Task.java
  10. 1 1
      fs-live-app/src/main/resources/application.yml
  11. 1 1
      fs-quartz/src/main/java/com/fs/quartz/config/ScheduleConfig.java
  12. 3 1
      fs-service/src/main/java/com/fs/company/domain/CompanyRedPacketBalanceLogs.java
  13. 13 7
      fs-service/src/main/java/com/fs/company/mapper/CompanyRedPacketBalanceLogsMapper.java
  14. 7 2
      fs-service/src/main/java/com/fs/company/service/ICompanyService.java
  15. 287 25
      fs-service/src/main/java/com/fs/company/service/impl/CompanyServiceImpl.java
  16. 1 1
      fs-service/src/main/java/com/fs/course/mapper/FsCourseAnswerLogsMapper.java
  17. 54 20
      fs-service/src/main/java/com/fs/course/service/impl/FsCourseProductOrderServiceImpl.java
  18. 11 0
      fs-service/src/main/java/com/fs/course/service/impl/FsCourseRedPacketLogServiceImpl.java
  19. 46 18
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseOrderServiceImpl.java
  20. 9 3
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseServiceImpl.java
  21. 2 8
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java
  22. 50 26
      fs-service/src/main/java/com/fs/course/service/impl/FsUserVipOrderServiceImpl.java
  23. 4 0
      fs-service/src/main/java/com/fs/his/domain/FsPayConfig.java
  24. 9 0
      fs-service/src/main/java/com/fs/his/domain/FsStorePayment.java
  25. 1 0
      fs-service/src/main/java/com/fs/his/param/FsCourseProductOrderRefundParam.java
  26. 1 0
      fs-service/src/main/java/com/fs/his/param/FsInquiryOrderCancelParam.java
  27. 1 0
      fs-service/src/main/java/com/fs/his/param/FsInquiryOrderRefundParam.java
  28. 5 0
      fs-service/src/main/java/com/fs/his/param/PayOrderParam.java
  29. 0 1
      fs-service/src/main/java/com/fs/his/service/IFsStorePaymentService.java
  30. 40 4
      fs-service/src/main/java/com/fs/his/service/impl/FsInquiryOrderServiceImpl.java
  31. 95 34
      fs-service/src/main/java/com/fs/his/service/impl/FsPackageOrderServiceImpl.java
  32. 25 3
      fs-service/src/main/java/com/fs/his/service/impl/FsStoreAfterSalesServiceImpl.java
  33. 46 20
      fs-service/src/main/java/com/fs/his/service/impl/FsStoreOrderServiceImpl.java
  34. 127 51
      fs-service/src/main/java/com/fs/his/service/impl/FsStorePaymentServiceImpl.java
  35. 20 7
      fs-service/src/main/java/com/fs/his/service/impl/FsUserInformationCollectionServiceImpl.java
  36. 3 0
      fs-service/src/main/java/com/fs/hisStore/domain/FsStorePaymentScrm.java
  37. 4 0
      fs-service/src/main/java/com/fs/hisStore/param/FsStoreOrderOtherPayParam.java
  38. 39 9
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreAfterSalesScrmServiceImpl.java
  39. 116 47
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java
  40. 98 45
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStorePaymentScrmServiceImpl.java
  41. 24 17
      fs-service/src/main/java/com/fs/huifuPay/sdk/opps/core/utils/HuiFuUtils.java
  42. 36 50
      fs-service/src/main/java/com/fs/huifuPay/service/impl/HuiFuServiceImpl.java
  43. 5 1
      fs-service/src/main/java/com/fs/live/service/impl/LiveOrderServiceImpl.java
  44. 22 3
      fs-service/src/main/java/com/fs/ybPay/service/impl/PayServiceImpl.java
  45. 2 2
      fs-service/src/main/resources/application-config-druid-sft.yml
  46. 187 0
      fs-service/src/main/resources/application-dev-test.yml
  47. 17 2
      fs-service/src/main/resources/mapper/company/CompanyRedPacketBalanceLogsMapper.xml
  48. 9 1
      fs-service/src/main/resources/mapper/course/FsCourseAnswerLogsMapper.xml
  49. 2 0
      fs-service/src/main/resources/mapper/his/FsStorePaymentMapper.xml
  50. 1 1
      fs-service/src/main/resources/mapper/hisStore/FsStorePaymentScrmMapper.xml
  51. 48 22
      fs-user-app/src/main/java/com/fs/app/controller/InquiryOrderController.java
  52. 1 1
      fs-user-app/src/main/java/com/fs/app/controller/WxH5MpController.java
  53. 8 29
      fs-user-app/src/main/java/com/fs/app/controller/WxPayController.java
  54. 1 1
      fs-user-app/src/main/java/com/fs/app/controller/course/CourseFsUserLoginController.java
  55. 32 32
      fs-user-app/src/main/java/com/fs/app/controller/live/LiveCompletionPointsController.java
  56. 55 23
      fs-user-app/src/main/java/com/fs/app/controller/live/LiveOrderController.java
  57. 2 10
      fs-user-app/src/main/java/com/fs/app/controller/store/CompanyUserScrmController.java

+ 51 - 8
fs-admin/src/main/java/com/fs/his/task/CompanyBalanceTask.java

@@ -1,13 +1,15 @@
 package com.fs.his.task;
 
+import com.fs.common.core.domain.R;
+import com.fs.common.utils.DateUtils;
+import com.fs.common.utils.StringUtils;
 import com.fs.company.service.ICompanyService;
-import com.fs.company.vo.RedPacketMoneyVO;
 import com.fs.course.service.BalanceRollbackErrorService;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 
-import java.util.List;
+import java.util.Date;
 
 /**
  * @description: 公司余额同步定时任务 (红包余额)
@@ -16,6 +18,7 @@ import java.util.List;
  * @version: 1.0
  */
 @Component("companyBalanceTask")
+@Slf4j
 public class CompanyBalanceTask {
 
 
@@ -58,19 +61,30 @@ public class CompanyBalanceTask {
      */
     public void initCompanyBalance() {
         balanceRollbackErrorService.initCompanyBalance();
-
     }
 
     /**
-     * @Description: 红包余额回滚(回滚的是客户没领取的红包),红包记录表中,两天没领取的记录不会再发送
+     * @Description: 优化成回滚前查询记录,一笔一笔回滚
      * @Param: 每天0点执行一次
      * @Return:
      * @Author xgb
      * @Date 2025/11/7 9:48
      */
-    public void rollbackRedPacketMoney() throws Exception {
-        // 这个地方真加的是company money字段 xgb 红包余额独立后这个方法弃用
-        companyService.rollbackRedPacketMoney();
+    public void rollbackRedPacketMoney(String time) throws Exception {
+        // 默认是前两天时间
+        String createSTime;
+        String createETime;
+        if (StringUtils.isNotBlank(time)) {
+            Date date = DateUtils.parseDate(time);
+            createSTime = time+" 00:00:00";
+            createETime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD,DateUtils.addDays(date, 1))+" 00:00:00";
+        } else {
+            createSTime = DateUtils.parseDateToStr( DateUtils.YYYY_MM_DD,DateUtils.addDays(new Date(), -2))+" 00:00:00";
+            createETime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD,DateUtils.addDays(new Date(), -1))+" 00:00:00";
+        }
+
+        // 这个地方真加的是company money字段 xgb
+        companyService.rollbackRedPacketMoney(createSTime, createETime);
     }
 
     /**
@@ -86,6 +100,35 @@ public class CompanyBalanceTask {
 
 
 
+    /**
+     * @Description: 更具批次号查询转账结果
+     * @Param:
+     * @Return:
+     * @Author xgb
+     * @Date 2025/12/25 10:31
+     */
+    public void checkMchTransferStatus(String outBatchNo,String companyIdStr) {
+        Long companyId=Long.parseLong(companyIdStr);
+        String result=companyService.checkMchTransferStatus(outBatchNo,companyId);
+        log.info("查询商户转账结果:{}",result);
+    }
+
+
+
+    /**
+     * @Description: 更具批次号查询转账结果
+     * @Param:
+     * @Return:
+     * @Author xgb
+     * @Date 2025/12/25 10:31
+     */
+    public void checkMchTransferStatusByBatchID(String batchId,String companyIdStr) {
+        Long companyId=Long.parseLong(companyIdStr);
+        R result=companyService.checkMchTransferStatusByBatchID(batchId,companyId);
+        log.info("查询商户转账结果:{}",result);
+    }
+
+
 
 
 }

+ 3 - 0
fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreOrderScrmController.java

@@ -1,6 +1,7 @@
 package com.fs.hisStore.controller;
 
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
@@ -206,6 +207,8 @@ public class FsStoreOrderScrmController extends BaseController {
             for (FsStoreOrderVO vo : list) {
                 if(vo.getPhone()!=null){
                     vo.setPhone(vo.getPhone().replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2"));
+                }
+                if(ObjectUtil.isNotEmpty(vo.getUserPhone())){
                     vo.setUserPhone(vo.getUserPhone().replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2"));
                 }
                 if (CloudHostUtils.hasCloudHostName("康年堂")){

+ 60 - 12
fs-admin/src/main/java/com/fs/hisStore/controller/FsStorePaymentScrmController.java

@@ -1,5 +1,6 @@
 package com.fs.hisStore.controller;
 
+import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
 import com.alipay.api.AlipayApiException;
@@ -12,15 +13,20 @@ import com.fs.common.core.domain.R;
 import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
 import com.fs.common.utils.CloudHostUtils;
+import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.ParseUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.common.utils.spring.SpringUtils;
 import com.fs.company.service.ICompanyService;
 import com.fs.config.cloud.CloudHostProper;
+import com.fs.course.domain.FsCoursePlaySourceConfig;
+import com.fs.course.service.IFsCoursePlaySourceConfigService;
 import com.fs.his.domain.FsHfpayConfig;
+import com.fs.his.domain.FsPayConfig;
+import com.fs.his.domain.MerchantAppConfig;
 import com.fs.his.mapper.FsHfpayConfigMapper;
-import com.fs.hisStore.domain.FsPayConfigScrm;
+import com.fs.his.service.IMerchantAppConfigService;
 import com.fs.huifuPay.domain.HuiFuQueryOrderResult;
 import com.fs.huifuPay.domain.HuiFuRefundResult;
 import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayQueryRequest;
@@ -32,6 +38,13 @@ import com.fs.hisStore.service.IFsStoreOrderScrmService;
 import com.fs.hisStore.service.IFsStorePaymentScrmService;
 import com.fs.hisStore.vo.FsStorePaymentVO;
 import com.fs.system.service.ISysConfigService;
+import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
+import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
+import com.github.binarywang.wxpay.bean.result.WxPayRefundQueryResult;
+import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
+import com.github.binarywang.wxpay.config.WxPayConfig;
+import com.github.binarywang.wxpay.exception.WxPayException;
+import com.github.binarywang.wxpay.service.WxPayService;
 import com.ijpay.alipay.AliPayApi;
 import com.ijpay.alipay.AliPayApiConfig;
 import com.ijpay.alipay.AliPayApiConfigKit;
@@ -63,10 +76,16 @@ public class FsStorePaymentScrmController extends BaseController
     private IFsStorePaymentScrmService fsStorePaymentService;
     @Autowired
     private AliPayBean aliPayBean;
-
+    @Autowired
+    private WxPayService wxPayService;
     @Autowired
     private ICompanyService companyService;
-
+    @Autowired
+    private IFsCoursePlaySourceConfigService fsCoursePlaySourceConfigService;
+    @Autowired
+    private IMerchantAppConfigService merchantAppConfigService;
+    @Autowired
+    IFsStorePaymentScrmService paymentService;
     @Autowired
     private IFsStoreOrderScrmService orderService;
     @Autowired
@@ -194,16 +213,14 @@ public class FsStorePaymentScrmController extends BaseController
         }
 
         if(payment.getPayTypeCode().equals("weixin")){
-            String json;
-//            if (CloudHostUtils.hasCloudHostName("康年堂")){
-                json = configService.selectConfigByKey("his.pay");
-//            } else {
-//                json = configService.selectConfigByKey("store.pay");
-//            }
-            if (StringUtils.isBlank(json)) {
+            FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigService.selectCoursePlaySourceConfigByAppId(payment.getAppId());
+            MerchantAppConfig merchantAppConfig = merchantAppConfigService.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
+
+            if (ObjectUtil.isEmpty(merchantAppConfig)) {
                 return R.error("缺少支付相关配置");
             }
-            FsPayConfigScrm fsPayConfig = JSON.parseObject(json, FsPayConfigScrm.class);
+            FsPayConfig fsPayConfig = JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
+
             if (payment.getPayMode()!=null&&payment.getPayMode().equals("hf")){
                 String huifuId="";
                 FsHfpayConfigMapper fsHfpayConfigMapper = SpringUtils.getBean(FsHfpayConfigMapper.class);
@@ -229,6 +246,7 @@ public class FsStorePaymentScrmController extends BaseController
                 extendInfoMap.put("org_party_order_id", payment.getBankSerialNo());
                 request.setExtendInfo(extendInfoMap);
                 logger.info("请求参数:"+request);
+                request.setAppId(payment.getAppId());
                 HuiFuRefundResult refund = huiFuService.refund(request);
                 logger.info("退款:"+refund);
                 if((refund.getResp_code().equals("00000000")||refund.getResp_code().equals("00000100"))&&(refund.getTrans_stat().equals("S")||refund.getTrans_stat().equals("P"))){
@@ -248,7 +266,37 @@ public class FsStorePaymentScrmController extends BaseController
 
             }
             else if (payment.getPayMode()!=null&&payment.getPayMode().equals("wx")){
-
+                WxPayConfig payConfig = new WxPayConfig();
+                payConfig.setAppId(fsCoursePlaySourceConfig.getAppid());
+                payConfig.setMchId(fsPayConfig.getWxMchId());
+                payConfig.setMchKey(fsPayConfig.getWxMchKey());
+                payConfig.setKeyPath(fsPayConfig.getKeyPath());
+                payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
+                payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));
+                wxPayService.setConfig(payConfig);
+                WxPayRefundRequest refundRequest = new WxPayRefundRequest();
+                refundRequest.setOutTradeNo("payment-"+payment.getPayCode());
+                refundRequest.setOutRefundNo("payment-"+payment.getPayCode());
+                refundRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(payment.getPayMoney().toString()));
+                refundRequest.setRefundFee(WxPayUnifiedOrderRequest.yuanToFen(fsStorePayment.getRefundMoney().toString()));
+                try {
+                    WxPayRefundResult refundResult = wxPayService.refund(refundRequest);
+                    WxPayRefundQueryResult refundQueryResult = wxPayService.refundQuery("", refundResult.getOutTradeNo(), refundResult.getOutRefundNo(), refundResult.getRefundId());
+                    if(refundQueryResult!=null&&refundQueryResult.getResultCode().equals("SUCCESS")){
+                        FsStorePaymentScrm paymentMap=new FsStorePaymentScrm();
+                        paymentMap.setPaymentId(payment.getPaymentId());
+                        paymentMap.setStatus(-1);
+                        paymentMap.setRefundTime(DateUtils.getNowDate());
+                        paymentMap.setRefundMoney(fsStorePayment.getRefundMoney());
+                        paymentService.updateFsStorePayment(paymentMap);
+                        return R.ok("退款成功");
+                    }
+                    else {
+                        return R.error("退款请求失败"+refundQueryResult.getErrCodeDes());
+                    }
+                } catch (WxPayException e) {
+                    return R.error("退款请求失败"+e.getErrCodeDes());
+                }
             }
 
             //小雨点退款

+ 1 - 1
fs-admin/src/main/resources/application.yml

@@ -4,7 +4,7 @@ server:
 # Spring配置
 spring:
   profiles:
-#    active: druid-ylrz
+#    active: dev-test
 #    active: druid-hdt
 #    active: druid-yzt
 #    active: druid-sxjz-test

+ 4 - 4
fs-company-app/src/main/java/com/fs/app/controller/FsUserController.java

@@ -214,8 +214,8 @@ public class FsUserController extends AppBaseController {
     ) {
         long userId = Long.parseLong(getUserId());
         // 中康的数据太多太卡不要这个
-//        return ResponseResult.ok(Collections.emptyList());
-        return ResponseResult.ok(fsUserService.userRanking(userId, startTime, endTime, periodId, videoId, order, type));
+        return ResponseResult.ok(Collections.emptyList());
+//        return ResponseResult.ok(fsUserService.userRanking(userId, startTime, endTime, periodId, videoId, order, type));
     }
 
     @Login
@@ -231,8 +231,8 @@ public class FsUserController extends AppBaseController {
     ) {
         long userId = Long.parseLong(getUserId());
         // 中康的数据太多太卡不要这个
-//        return ResponseResult.ok(Collections.emptyList());
-        return ResponseResult.ok(fsUserService.courseRanking(userId, startTime, endTime, courseId, videoId, order, type));
+        return ResponseResult.ok(Collections.emptyList());
+//        return ResponseResult.ok(fsUserService.courseRanking(userId, startTime, endTime, courseId, videoId, order, type));
     }
 
     @Login

+ 0 - 1
fs-company-app/src/main/java/com/fs/app/controller/FsUserCourseVideoController.java

@@ -170,7 +170,6 @@ public class FsUserCourseVideoController extends AppBaseController {
         } else {
             params.put("companyUserId", companyUser.getUserId());
         }
-
         PageHelper.startPage(pageNum, pageSize);
         List<FsUserCourseParticipationRecordVO> record = fsUserCourseService.getParticipationRecordByMap(params);
         return ResponseResult.ok(new PageInfo<>(record));

+ 1 - 1
fs-company-app/src/main/java/com/fs/app/controller/WxCompanyUserController.java

@@ -171,7 +171,7 @@ public class WxCompanyUserController extends AppBaseController {
      */
     private FsUser createUser(LoginMaWxParam param, WxMaJscode2SessionResult session, WxMaPhoneNumberInfo phoneNoInfo, Company company, CompanyUser companyUser) {
         FsUser user = new FsUser();
-        user.setStatus((company != null ? company.getFsUserIsDefaultBlack() : 0) == 1 ? 0 : 1);
+        user.setStatus(1);
         user.setUnionId(session.getUnionid() == null ? "" : session.getUnionid());
         user.setCreateTime(new Date());
         if (param.getAuthType() == 1 && phoneNoInfo != null) {

+ 38 - 0
fs-company/src/main/java/com/fs/company/controller/common/CommonController.java

@@ -6,10 +6,12 @@ import com.fs.common.constant.Constants;
 import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
 import com.fs.common.exception.file.OssException;
+import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.ServletUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.file.FileUploadUtils;
 import com.fs.common.utils.file.FileUtils;
+import com.fs.company.service.ICompanyService;
 import com.fs.company.utils.AudioUtils;
 import com.fs.company.vo.WangUploadVO;
 import com.fs.course.service.ITencentCloudCosService;
@@ -40,6 +42,7 @@ import java.awt.image.BufferedImage;
 import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
@@ -71,6 +74,9 @@ public class CommonController
     @Autowired
     private OpenIMService openIMService;
 
+    @Autowired
+    private ICompanyService companyService;
+
     @Autowired
     private TokenService tokenService;
 //    @Autowired
@@ -93,6 +99,38 @@ public class CommonController
 //        qwWorkTaskService.addQwWorkByConversionDay();
       return R.ok();
     }
+
+    @GetMapping("common/test2")
+    public R test2(String time) throws Exception
+    {
+        // 默认是前两天时间
+        String createSTime;
+        String createETime;
+        if (StringUtils.isNotBlank(time)) {
+            Date date = DateUtils.parseDate(time);
+            createSTime = time+" 00:00:00";
+            createETime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD,DateUtils.addDays(date, 1))+" 00:00:00";
+        } else {
+            createSTime = DateUtils.parseDateToStr( DateUtils.YYYY_MM_DD,DateUtils.addDays(new Date(), -2))+" 00:00:00";
+            createETime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD,DateUtils.addDays(new Date(), -1))+" 00:00:00";
+        }
+
+        // 这个地方真加的是company money字段 xgb
+        companyService.rollbackRedPacketMoney(createSTime, createETime);
+        return R.ok();
+    }
+
+    @GetMapping("common/test3")
+    public R test2(String companyIdStr,String outBatchNo) throws Exception
+    {
+        // 默认是前两天时间
+        Long companyId=Long.parseLong(companyIdStr);
+        R result=companyService.checkMchTransferStatusByBatchID(outBatchNo,companyId);
+        log.info("查询商户转账结果:{}",result);
+        return R.ok();
+    }
+
+
     /**
      * 通用下载请求
      *

+ 18 - 17
fs-live-app/src/main/java/com/fs/live/task/Task.java

@@ -186,17 +186,17 @@ public class Task {
                                 .mapToLong(LiveVideo::getDuration)
                                 .sum();
                     }
-                    
+
                     // 如果视频时长大于0,将直播间信息存入Redis
                     if (videoDuration > 0 && live.getStartTime() != null) {
                         Map<String, Object> tagMarkInfo = new HashMap<>();
                         tagMarkInfo.put("liveId", live.getLiveId());
                         tagMarkInfo.put("startTime", live.getStartTime().atZone(java.time.ZoneId.systemDefault()).toInstant().toEpochMilli());
                         tagMarkInfo.put("videoDuration", videoDuration);
-                        
+
                         String tagMarkKey = String.format(LiveKeysConstant.LIVE_TAG_MARK_CACHE, live.getLiveId());
                         redisCache.setCacheObject(tagMarkKey, JSON.toJSONString(tagMarkInfo), 24, TimeUnit.HOURS);
-                        log.info("直播间开启,已加入打标签缓存: liveId={}, startTime={}, videoDuration={}", 
+                        log.info("直播间开启,已加入打标签缓存: liveId={}, startTime={}, videoDuration={}",
                                 live.getLiveId(), live.getStartTime(), videoDuration);
                     }
                 } catch (Exception e) {
@@ -537,19 +537,19 @@ public class Task {
                 // 回放:使用 Redis 中的数据减去直播的数据,得到回放的数据
                 String likeKey = "live:like:" + liveData.getLiveId();
                 String totalViewsKey = TOTAL_VIEWS_KEY + liveData.getLiveId();
-                
+
                 // 从 Redis 获取总数据(直播+回放)
                 Long totalLikeCount = getAsLong(redisCache, likeKey);
                 Long totalViewCount = getAsLong(redisCache, totalViewsKey);
-                
+
                 // 获取数据库中直播的数据
                 Long liveLikeCount = liveData.getLikes() != null ? liveData.getLikes() : 0L;
                 Long liveViewCount = liveData.getTotalViews() != null ? liveData.getTotalViews() : 0L;
-                
+
                 // 回放数据 = Redis总数据 - 直播数据
                 Long replayLikeNum = totalLikeCount - liveLikeCount;
                 Long replayViewNum = totalViewCount - liveViewCount;
-                
+
                 // 确保回放数据不为负数
                 if (replayLikeNum < 0L) {
                     replayLikeNum = 0L;
@@ -557,7 +557,7 @@ public class Task {
                 if (replayViewNum < 0L) {
                     replayViewNum = 0L;
                 }
-                
+
                 // 更新回放数据
                 liveData.setReplayLikeNum(replayLikeNum);
                 liveData.setReplayViewNum(replayViewNum);
@@ -646,11 +646,11 @@ public class Task {
             // 获取所有打标签缓存的key
             String pattern = String.format(LiveKeysConstant.LIVE_TAG_MARK_CACHE, "*");
             Set<String> keys = redisCache.redisTemplate.keys(pattern);
-            
+
             if (keys == null || keys.isEmpty()) {
                 return;
             }
-            
+
             long currentTimeMillis = System.currentTimeMillis();
             LocalDateTime now = LocalDateTime.now();
             List<Long> processedLiveIds = new ArrayList<>();
@@ -662,19 +662,19 @@ public class Task {
                     if (cacheValue == null) {
                         continue;
                     }
-                    
+
                     String jsonStr = cacheValue.toString();
                     JSONObject tagMarkInfo = JSON.parseObject(jsonStr);
                     Long liveId = tagMarkInfo.getLong("liveId");
                     Long startTimeMillis = tagMarkInfo.getLong("startTime");
                     Long videoDuration = tagMarkInfo.getLong("videoDuration");
-                    
+
                     if (liveId == null || startTimeMillis == null || videoDuration == null || videoDuration <= 0) {
-                        log.warn("直播间打标签缓存信息不完整: key={}, liveId={}, startTime={}, videoDuration={}", 
+                        log.warn("直播间打标签缓存信息不完整: key={}, liveId={}, startTime={}, videoDuration={}",
                                 key, liveId, startTimeMillis, videoDuration);
                         continue;
                     }
-                    
+
                     // 查询直播间信息
                     Live live = liveService.selectLiveDbByLiveId(liveId);
                     if (live == null || live.getStartTime() == null) {
@@ -791,7 +791,7 @@ public class Task {
                     log.error("处理直播间打标签缓存异常: key={}, error={}", key, e.getMessage(), e);
                 }
             }
-            
+
             // 删除已处理的直播间缓存
             for (Long liveId : processedLiveIds) {
                 try {
@@ -871,6 +871,7 @@ public class Task {
                             if (onlineSeconds == null || onlineSeconds <= 0) {
                                 continue;
                             }
+
                             // 获取用户的 companyId 和 companyUserId
                             LiveUserFirstEntry liveUserFirstEntry =
                                     liveUserFirstEntryService.selectEntityByLiveIdUserIdWithCache(liveId, userId);
@@ -891,7 +892,7 @@ public class Task {
                             // 使用 updateLiveWatchLogTypeByDuration 的逻辑更新观看记录状态
                             updateLiveWatchLogTypeByDuration(liveId, userId, qwUserId, externalContactId,
                                     onlineSeconds, totalVideoDuration, updateLog);
-                            
+
                         } catch (Exception e) {
                             log.error("处理用户观看记录状态异常: liveId={}, userId={}, error={}",
                                     liveId, user.getUserId(), e.getMessage(), e);
@@ -909,7 +910,7 @@ public class Task {
                             redisCache.setCacheObject("live:watch:log:cache:" + liveWatchLog.getLogId(), liveWatchLog, 1, TimeUnit.HOURS);
                         }
                     }
-                    
+
                 } catch (Exception e) {
                     log.error("处理直播间观看记录状态异常: liveId={}, error={}",
                             live.getLiveId(), e.getMessage(), e);

+ 1 - 1
fs-live-app/src/main/resources/application.yml

@@ -6,4 +6,4 @@ server:
 # Spring配置
 spring:
   profiles:
-    active: druid-bjzm-test
+    active: dev-test

+ 1 - 1
fs-quartz/src/main/java/com/fs/quartz/config/ScheduleConfig.java

@@ -49,7 +49,7 @@ public class ScheduleConfig
         // 可选,QuartzScheduler
         // 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
         factory.setOverwriteExistingJobs(true);
-        // 设置自动启动,默认为true
+        // 设置自动启动,默认为true 切记调整为true
         factory.setAutoStartup(true);
 //        factory.setAutoStartup(false);
 

+ 3 - 1
fs-service/src/main/java/com/fs/company/domain/CompanyRedPacketBalanceLogs.java

@@ -39,8 +39,10 @@ public class CompanyRedPacketBalanceLogs extends BaseEntity{
     @Excel(name = "类型")
     private Integer logsType;
 
-    /** 是否处理状态(0-初始化,1-已同步) */
+    /** 是否处理状态(0-初始化,1-已同步(收到红包回调)) */
     private Long status;
 
+    // 红包日志id
+    private Long redPacketId;
 
 }

+ 13 - 7
fs-service/src/main/java/com/fs/company/mapper/CompanyRedPacketBalanceLogsMapper.java

@@ -1,20 +1,22 @@
 package com.fs.company.mapper;
 
+import java.util.Date;
 import java.util.List;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.fs.company.domain.Company;
 import com.fs.company.domain.CompanyRedPacketBalanceLogs;
+import org.apache.ibatis.annotations.Param;
 
 /**
  * 企业红包余额记录Mapper接口
- * 
+ *
  * @author fs
  * @date 2025-11-19
  */
 public interface CompanyRedPacketBalanceLogsMapper extends BaseMapper<CompanyRedPacketBalanceLogs>{
     /**
      * 查询企业红包余额记录
-     * 
+     *
      * @param logsId 企业红包余额记录主键
      * @return 企业红包余额记录
      */
@@ -22,7 +24,7 @@ public interface CompanyRedPacketBalanceLogsMapper extends BaseMapper<CompanyRed
 
     /**
      * 查询企业红包余额记录列表
-     * 
+     *
      * @param companyRedPacketBalanceLogs 企业红包余额记录
      * @return 企业红包余额记录集合
      */
@@ -30,7 +32,7 @@ public interface CompanyRedPacketBalanceLogsMapper extends BaseMapper<CompanyRed
 
     /**
      * 新增企业红包余额记录
-     * 
+     *
      * @param companyRedPacketBalanceLogs 企业红包余额记录
      * @return 结果
      */
@@ -38,7 +40,7 @@ public interface CompanyRedPacketBalanceLogsMapper extends BaseMapper<CompanyRed
 
     /**
      * 修改企业红包余额记录
-     * 
+     *
      * @param companyRedPacketBalanceLogs 企业红包余额记录
      * @return 结果
      */
@@ -46,7 +48,7 @@ public interface CompanyRedPacketBalanceLogsMapper extends BaseMapper<CompanyRed
 
     /**
      * 删除企业红包余额记录
-     * 
+     *
      * @param logsId 企业红包余额记录主键
      * @return 结果
      */
@@ -54,11 +56,15 @@ public interface CompanyRedPacketBalanceLogsMapper extends BaseMapper<CompanyRed
 
     /**
      * 批量删除企业红包余额记录
-     * 
+     *
      * @param logsIds 需要删除的数据主键集合
      * @return 结果
      */
     int deleteCompanyRedPacketBalanceLogsByLogsIds(Long[] logsIds);
 
     Company getCompanyRedPacketBalance(Long companyId);
+
+    void updateCompanyRedPacketBalanceLogsByRedPacketId(CompanyRedPacketBalanceLogs redLogs);
+
+    List<CompanyRedPacketBalanceLogs> selectCompanyRedPacketBalanceLogsListByStatus(@Param("createSTime") String createSTime,@Param("createETime") String createETime);
 }

+ 7 - 2
fs-service/src/main/java/com/fs/company/service/ICompanyService.java

@@ -2,6 +2,7 @@ package com.fs.company.service;
 
 import java.math.BigDecimal;
 import java.time.LocalTime;
+import java.util.Date;
 import java.util.List;
 
 import com.fs.common.core.domain.R;
@@ -177,7 +178,7 @@ public interface ICompanyService
 
     void redPacketTopUpCompany(Long companyId, BigDecimal money,String type);
 
-    void asyncRecordBalanceLog(Long companyId, BigDecimal money,Integer logType, BigDecimal balance, String remark);
+    void asyncRecordBalanceLog(Long companyId, BigDecimal money, Integer logType, BigDecimal balance, String remark, Long logId);
 
     void recordRedPacketBalance();
 
@@ -187,7 +188,7 @@ public interface ICompanyService
      */
     void batchUpdateCompany(List<Company> list);
 
-    void rollbackRedPacketMoney();
+    void rollbackRedPacketMoney(String createSTime, String createETime);
 
 
     List<CompanyVO> liveShowList(CompanyParam param);
@@ -197,4 +198,8 @@ public interface ICompanyService
     void addCompanyTuiLiveMoney(LiveOrder order);
 
     void subLiveCompanyMoney(LiveOrder order);
+
+    String checkMchTransferStatus(String outBatchNo,Long companyId);
+
+    R checkMchTransferStatusByBatchID(String batchId, Long companyId);
 }

+ 287 - 25
fs-service/src/main/java/com/fs/company/service/impl/CompanyServiceImpl.java

@@ -6,12 +6,12 @@ import java.util.*;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
-import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
 import com.fs.common.constant.FsConstants;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.redis.RedisCache;
+import com.fs.common.exception.CustomException;
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.SecurityUtils;
 import com.fs.common.utils.StringUtils;
@@ -19,11 +19,13 @@ import com.fs.company.domain.*;
 import com.fs.company.mapper.*;
 import com.fs.company.param.CompanyLiveShowParam;
 import com.fs.company.param.CompanyParam;
-import com.fs.company.service.ICompanyMiniappService;
-import com.fs.company.service.ICompanyProfitService;
-import com.fs.company.service.ICompanyRoleService;
+import com.fs.company.service.*;
 import com.fs.company.vo.*;
+import com.fs.course.config.CourseConfig;
+import com.fs.course.config.RedPacketConfig;
+import com.fs.course.domain.FsCourseRedPacketLog;
 import com.fs.course.mapper.FsCourseRedPacketLogMapper;
+import com.fs.course.service.IFsCourseRedPacketLogService;
 import com.fs.his.config.StoreConfig;
 import com.fs.his.domain.FsInquiryOrder;
 import com.fs.his.domain.FsStoreOrder;
@@ -41,19 +43,26 @@ import com.fs.store.config.CompanyMenuConfig;
 import com.fs.system.domain.SysConfig;
 import com.fs.system.mapper.SysConfigMapper;
 import com.fs.system.service.ISysConfigService;
+import com.github.binarywang.wxpay.bean.transfer.QueryTransferBatchesRequest;
+import com.github.binarywang.wxpay.bean.transfer.QueryTransferBatchesResult;
+import com.github.binarywang.wxpay.bean.transfer.TransferBillsGetResult;
+import com.github.binarywang.wxpay.config.WxPayConfig;
+import com.github.binarywang.wxpay.exception.WxPayException;
+import com.github.binarywang.wxpay.service.TransferService;
+import com.github.binarywang.wxpay.service.WxPayService;
+import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
 import com.github.pagehelper.PageHelper;
 import com.google.gson.Gson;
 import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.lang3.ObjectUtils;
 import org.redisson.api.RLock;
 import org.redisson.api.RedissonClient;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
-import com.fs.company.service.ICompanyService;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.support.TransactionTemplate;
@@ -129,6 +138,9 @@ public class CompanyServiceImpl implements ICompanyService
     @Autowired
     private CompanyRedPacketBalanceLogsMapper companyRedPacketBalanceLogsMapper;
 
+    @Autowired
+    private ICompanyConfigService companyConfigService;
+
 
     @Override
     public List<CompanyVO> liveShowList(CompanyParam param) {
@@ -186,6 +198,150 @@ public class CompanyServiceImpl implements ICompanyService
         }
     }
 
+    @Override
+    public String checkMchTransferStatus(String outBatchNo,Long companyId) {
+
+        // 查看红包发送配置
+        String json = configService.selectConfigByKey("course.config");
+        CourseConfig courseConfig = JSONUtil.toBean(json, CourseConfig.class);
+        RedPacketConfig config;
+        switch (courseConfig.getRedPacketMode()){// 1-总配置 2- 分公司配置
+            case 1:
+                json = configService.selectConfigByKey("redPacket.config");
+                config = JSONUtil.toBean(json, RedPacketConfig.class);
+                break;
+            case 2:
+                json = companyConfigService.selectRedPacketConfigByKey(companyId);
+                //如果分公司配置为空就走总后台的配置
+                if (StringUtils.isEmpty(json)){
+                    json = configService.selectConfigByKey("redPacket.config");
+                }
+                config = JSONUtil.toBean(json, RedPacketConfig.class);
+                break;
+            default:
+                throw new UnsupportedOperationException("当前红包模式不支持!");
+        }
+
+        WxPayConfig payConfig = new WxPayConfig();
+        BeanUtils.copyProperties(config, payConfig);
+
+        WxPayService wxPayService = new WxPayServiceImpl();
+        wxPayService.setConfig(payConfig);
+
+        TransferService transferService = wxPayService.getTransferService();
+
+        if (Objects.isNull(config.getIsNew()) || !Arrays.asList(0,1).contains(config.getIsNew())) {
+            logger.error("红包配置错误 isNew is err");
+            throw new CustomException("红包配置错误 isNew is err ");
+        }
+
+        try {
+            if (config.getIsNew() == 0) {
+                QueryTransferBatchesRequest request = new QueryTransferBatchesRequest();
+                request.setOutBatchNo(outBatchNo);
+                request.setNeedQueryDetail(true);
+                request.setOffset(0);
+                request.setLimit(20);
+                request.setDetailStatus("ALL");
+                QueryTransferBatchesResult result = transferService.transferBatchesOutBatchNo(request);
+                List<QueryTransferBatchesResult.TransferDetail> detailList = result.getTransferDetailList();
+                boolean isSuccess = detailList.stream().anyMatch(d -> "SUCCESS".equals(d.getDetailStatus()));
+                if (isSuccess) {
+                    return result.getTransferBatch().getBatchId();
+                }
+
+                boolean isFail = detailList.stream().anyMatch(d -> "FAIL".equals(d.getDetailStatus()));
+                if (isFail) {
+                    return "";
+                }
+            } else {
+                TransferBillsGetResult result = transferService.getBillsByOutBillNo(outBatchNo);
+                if ("SUCCESS".equals(result.getState())) {
+                    return result.getTransferBillNo();
+                } else if ("FAIL".equals(result.getState())) {
+                    return "";
+                } else if ("CANCELLED".equals(result.getState())) {
+                    return "";
+                }
+            }
+        } catch (WxPayException e) {
+            logger.error("查询转账单失败 err: {}", e.getMessage(), e);
+            throw new CustomException("查询转账单失败:" + e.getMessage());
+        }
+
+        throw new CustomException("转账处理中");
+    }
+
+    @Override
+    public R checkMchTransferStatusByBatchID(String batchId, Long companyId) {
+        // 获取配置信息
+        CourseConfig courseConfig = JSONUtil.toBean(configService.selectConfigByKey("course.config"), CourseConfig.class);
+
+        String json;
+        RedPacketConfig config = new RedPacketConfig();
+        // 根据红包模式获取配置
+        switch (courseConfig.getRedPacketMode()){
+            case 1:
+                json = configService.selectConfigByKey("redPacket.config");
+                config = JSONUtil.toBean(json, RedPacketConfig.class);
+                break;
+            case 2:
+                json = companyConfigService.selectRedPacketConfigByKey(companyId);
+                //如果分公司配置为空就走总后台的配置
+                if (StringUtils.isEmpty(json)){
+                    json = configService.selectConfigByKey("redPacket.config");
+                }
+                config = JSONUtil.toBean(json, RedPacketConfig.class);
+                break;
+            default:
+                throw new UnsupportedOperationException("当前红包模式不支持!");
+        }
+
+        //创建微信订单
+        WxPayConfig payConfig = new WxPayConfig();
+        BeanUtils.copyProperties(config,payConfig);
+        WxPayService wxPayService = new WxPayServiceImpl();
+        wxPayService.setConfig(payConfig);
+        TransferService transferService=wxPayService.getTransferService();
+
+        Map<String,Object> map = new HashMap<>();
+        map.put("status","待确认"); //
+        if (config.getIsNew() != null && config.getIsNew() == 1) {
+            try {
+                TransferBillsGetResult queryRedPacketResult = transferService.getBillsByTransferBillNo(batchId);
+                logger.info("FsCourseRedPacketLog-batchId:{},【红包处理】查询批次结果:{}",batchId,queryRedPacketResult.toString());
+                if(("SUCCESS").equals(queryRedPacketResult.getState())){
+                    map.put("status","success");
+                }else if(("FAIL").equals(queryRedPacketResult.getState())){
+                    map.put("status","fail");
+                }
+                return R.ok(map);
+            } catch (WxPayException e) {
+                logger.error(e.getMessage());
+                return R.error(e.getMessage());
+            }
+        } else {
+            QueryTransferBatchesRequest request = new QueryTransferBatchesRequest();
+            request.setBatchId(batchId);
+            request.setNeedQueryDetail(false);
+
+            try {
+                QueryTransferBatchesResult queryTransferBatchesResult = transferService.transferBatchesBatchId(request);
+                logger.info("FsCourseRedPacketLog-batchId,【红包处理】查询批次结果:{}",batchId,queryTransferBatchesResult.toString());
+                if(("FINISHED").equals(queryTransferBatchesResult.getTransferBatch().getBatchStatus())){
+                    map.put("status","success");
+                }else if(("CLOSED").equals(queryTransferBatchesResult.getTransferBatch().getBatchStatus())){
+                    map.put("status","fail");
+                }
+                return R.ok(map);
+            } catch (WxPayException e) {
+                logger.error(e.getMessage());
+                return R.error(e.getMessage());
+            }
+        }
+
+    }
+
     @Override
     public List<OptionsVO> selectAllCompanyList(Long deptId) {
         return companyMapper.selectAllCompanyList(deptId);
@@ -1449,7 +1605,7 @@ public class CompanyServiceImpl implements ICompanyService
                                     // 记录余额变更日志
                                     String remark = "同步公司余额,差额: " + amount+"(正数为增加,负数为扣减)";
                                     // 实际不发生交易只是从缓存同步金额到数据库中 交易金额登记为0,备注清楚同步的金额
-                                    asyncRecordBalanceLog(company.getCompanyId(),new BigDecimal(0),17,redisMoney,remark);
+                                    asyncRecordBalanceLog(company.getCompanyId(),new BigDecimal(0),17,redisMoney,remark, null);
                                 }
                             }
                             return null;
@@ -1502,7 +1658,7 @@ public class CompanyServiceImpl implements ICompanyService
                 redisCache.setCacheObject(companyMoneyKey, newMoney.toString());
 
                 // 异步登记余额添加日志
-                asyncRecordBalanceLog(companyId,money,16,newMoney,"红包充值(负数为扣款)");
+                asyncRecordBalanceLog(companyId,money,16,newMoney,"红包充值(负数为扣款)", null);
 
             } else {
                 logger.error("获取redis锁失败,异常请求参数companyId:{},money:{},type:{}",companyId,money, type);
@@ -1528,15 +1684,17 @@ public class CompanyServiceImpl implements ICompanyService
 
     /**
      * 异步登记余额添加日志  xgb
+     *
      * @param companyId 公司ID
-     * @param money 变更金额
-     * @param balance 当前余额
-     * @param remark 备注信息
-     * @param logType 16-红包余额充值 15-红包余额扣除 17-同步公司余额
+     * @param money     变更金额
+     * @param logType   16-红包余额充值 15-红包余额扣除 17-同步公司余额
+     * @param balance   当前余额
+     * @param remark    备注信息
+     * @param logId
      */
     @Async
     @Override
-    public void asyncRecordBalanceLog(Long companyId, BigDecimal money,Integer logType, BigDecimal balance, String remark) {
+    public void asyncRecordBalanceLog(Long companyId, BigDecimal money, Integer logType, BigDecimal balance, String remark, Long logId) {
         try {
             CompanyRedPacketBalanceLogs log = new CompanyRedPacketBalanceLogs();
             log.setCompanyId(companyId);
@@ -1545,6 +1703,7 @@ public class CompanyServiceImpl implements ICompanyService
             log.setLogsType(logType); // 同步余额
             log.setBalance(balance);
             log.setCreateTime(new Date());
+            log.setRedPacketId(logId);
             companyRedPacketBalanceLogsMapper.insertCompanyRedPacketBalanceLogs(log);
         } catch (Exception e) {
             logger.error("异步登记红包余额日志失败 - 公司ID: {}, 金额: {}, 余额: {}, 备注: {}",
@@ -1575,7 +1734,7 @@ public class CompanyServiceImpl implements ICompanyService
                     // 实际不发生交易只是从缓存获取当天余额报错25小时 交易金额登记为0,备注清楚同步的金额
                     String remark = "时间:" + time +",当前公司余额,金额: " + moneyStr;
                     BigDecimal money = new BigDecimal(moneyStr);
-                    asyncRecordBalanceLog(company.getCompanyId(),new BigDecimal(0),18,money,remark);
+                    asyncRecordBalanceLog(company.getCompanyId(),new BigDecimal(0),18,money,remark, null);
                 }
                 return null;
             });
@@ -1599,18 +1758,121 @@ public class CompanyServiceImpl implements ICompanyService
      * @Author xgb
      * @Date 2025/11/7 9:53
      */
+//    @Override
+//    public void rollbackRedPacketMoney() {
+//        List<RedPacketMoneyVO> redPacketMoneyVOS = fsCourseRedPacketLogMapper.selectFsCourseAddRedPacketLogByCompany();
+//        for(RedPacketMoneyVO company:redPacketMoneyVOS){
+//            logger.info("红包余额回滚开始:{}",company);
+//        }
+//        Optional.ofNullable(redPacketMoneyVOS).ifPresent(list -> list.forEach(company -> {
+//
+//            if(company.getCompanyId()==null){
+//                logger.error("红包记录表中存在公司id为null的异常数据");
+//                return;
+//            }
+//            String companyMoneyKey = FsConstants.COMPANY_MONEY_KEY + company.getCompanyId();
+//            // 加锁,与看课发放红包的加锁保持一致
+//            RLock lock = redissonClient.getLock(FsConstants.COMPANY_MONEY_LOCK + company.getCompanyId());
+//            boolean lockAcquired = false;
+//            try {
+//                lockAcquired = lock.tryLock(3, 10, TimeUnit.SECONDS);
+//                if (lockAcquired) {
+//                    BigDecimal redisMoney;
+//                    // 获取当前余额
+//                    String moneyStr = redisCache.getCacheObject(companyMoneyKey);
+//                    if (StringUtils.isNotEmpty(moneyStr)) {
+//                        redisMoney = new BigDecimal(moneyStr);
+//                    }else {
+//                        logger.error("缓存公司id:{}的余额不存在,回滚金额{}",company.getCompanyId(),company.getMoney());
+//                        return;
+//                    }
+//                    BigDecimal newMoney = redisMoney.add(company.getMoney());
+//                    redisCache.setCacheObject(companyMoneyKey, newMoney.toString());
+//
+//                    String remark = "执行时间:"+DateUtils.getTime()+",T2天客户未领取红包退回,金额: " + company.getMoney();
+//                    asyncRecordBalanceLog(company.getCompanyId(),company.getMoney(),16,newMoney,remark, null);
+//                }
+//            } catch (Exception e) {
+//                logger.error("退回的红包同步增加到缓存和数据表,参数错误,请求异常,异常信息:{}", e.getMessage(), e);
+//            } finally {
+//                if (lockAcquired && lock.isHeldByCurrentThread()) {
+//                    try {
+//                        lock.unlock();
+//                    } catch (IllegalMonitorStateException e) {
+//                        logger.warn("尝试释放非当前线程持有的锁: companyId:{}", company.getCompanyId());
+//                    }
+//                }
+//            }
+//        }));
+//    }
+
+
+    /**
+     * @Description: 红包余额回滚(回滚的是客户没领取的红包),红包记录表中,两天没领取的记录不会再发送
+     * @Param:
+     * @Return:
+     * @Author xgb
+     * @Date 2025/12/25 9:32
+     */
     @Override
-    public void rollbackRedPacketMoney() {
-        List<RedPacketMoneyVO> redPacketMoneyVOS = fsCourseRedPacketLogMapper.selectFsCourseAddRedPacketLogByCompany();
-        for(RedPacketMoneyVO company:redPacketMoneyVOS){
-            logger.info("红包余额回滚开始:{}",company);
-        }
-        Optional.ofNullable(redPacketMoneyVOS).ifPresent(list -> list.forEach(company -> {
+    public void rollbackRedPacketMoney(String createSTime, String createETime) {
+        // 回滚前查询一下红包记录
+        List<CompanyRedPacketBalanceLogs> companyRedPacketBalanceLogsList = companyRedPacketBalanceLogsMapper.selectCompanyRedPacketBalanceLogsListByStatus(createSTime, createETime);
+
+        Optional.ofNullable(companyRedPacketBalanceLogsList).ifPresent(list -> list.forEach(company -> {
+
+            if(company.getRedPacketId()==null){// 无数据跳过
+                logger.info("红包记录未登记,流水{}",company.getLogsId());
+                return;
+            }
+
+            // 查询红包记录
+            FsCourseRedPacketLog redLogs = fsCourseRedPacketLogMapper.selectFsCourseRedPacketLogByLogId(company.getRedPacketId());
+            if(redLogs==null){
+                logger.error("未查询到红包记录,流水{}",company.getLogsId());
+                return;
+            }
 
             if(company.getCompanyId()==null){
-                logger.error("红包记录表中存在公司id为null的异常数据");
+                logger.error("红包记录表中存在公司id为null的异常数据,流水{}",company.getLogsId());
+                return;
+            }
+
+            if(!StringUtils.isEmpty(redLogs.getBatchId())){
+                R result=checkMchTransferStatusByBatchID(redLogs.getBatchId(),redLogs.getCompanyId());
+                if("200".equals(result.get("code"))){
+                    FsCourseRedPacketLog update = new FsCourseRedPacketLog();
+                    update.setUpdateTime(new Date());
+                    update.setLogId(redLogs.getLogId());
+
+                    // 更新扣减状态
+                    CompanyRedPacketBalanceLogs redBalanceLogs = new CompanyRedPacketBalanceLogs();
+                    redBalanceLogs.setRedPacketId(company.getRedPacketId());
+
+                    if("success".equals(result.get("status"))){
+                        update.setStatus(1);
+                        fsCourseRedPacketLogMapper.updateFsCourseRedPacketLog(update);
+
+                        redBalanceLogs.setStatus(1L);
+                        companyRedPacketBalanceLogsMapper.updateCompanyRedPacketBalanceLogsByRedPacketId(redBalanceLogs);
+                        return;
+                    }else if("fail".equals(result.get("status"))){// 只对失败的部分进行回滚
+                        // 更新支付状态
+                        update.setStatus(2); // 已退回
+                        fsCourseRedPacketLogMapper.updateFsCourseRedPacketLog(update);
+
+                        redBalanceLogs.setStatus(2L);
+                        companyRedPacketBalanceLogsMapper.updateCompanyRedPacketBalanceLogsByRedPacketId(redBalanceLogs);
+                    }
+                }else {
+                    logger.info("商户转账状态查询失败,流水{}",company.getLogsId());
+                    return;
+                }
+            }else {
+                logger.error("红包记录表中存在商户批次号为null的异常数据,流水{}",company.getLogsId());
                 return;
             }
+
             String companyMoneyKey = FsConstants.COMPANY_MONEY_KEY + company.getCompanyId();
             // 加锁,与看课发放红包的加锁保持一致
             RLock lock = redissonClient.getLock(FsConstants.COMPANY_MONEY_LOCK + company.getCompanyId());
@@ -1624,14 +1886,14 @@ public class CompanyServiceImpl implements ICompanyService
                     if (StringUtils.isNotEmpty(moneyStr)) {
                         redisMoney = new BigDecimal(moneyStr);
                     }else {
-                        logger.error("缓存公司id:{}的余额不存在,回滚金额{}",company.getCompanyId(),company.getMoney());
+                        logger.error("缓存公司id:{}的余额不存在,回滚金额{}",company.getCompanyId(),redLogs.getAmount());
                         return;
                     }
-                    BigDecimal newMoney = redisMoney.add(company.getMoney());
+                    BigDecimal newMoney = redisMoney.add(redLogs.getAmount());
                     redisCache.setCacheObject(companyMoneyKey, newMoney.toString());
 
-                    String remark = "执行时间:"+DateUtils.getTime()+",T2天客户未领取红包退回,金额: " + company.getMoney();
-                    asyncRecordBalanceLog(company.getCompanyId(),company.getMoney(),16,newMoney,remark);
+                    String remark = "执行时间:"+DateUtils.getTime()+",T2天客户未领取红包退回,金额: " + redLogs.getAmount();
+                    asyncRecordBalanceLog(company.getCompanyId(),redLogs.getAmount(),19,newMoney,remark, redLogs.getLogId());
                 }
             } catch (Exception e) {
                 logger.error("退回的红包同步增加到缓存和数据表,参数错误,请求异常,异常信息:{}", e.getMessage(), e);

+ 1 - 1
fs-service/src/main/java/com/fs/course/mapper/FsCourseAnswerLogsMapper.java

@@ -131,7 +131,7 @@ public interface FsCourseAnswerLogsMapper
     int selectErrorCountByCourseVideo(@Param("videoId") Long videoId, @Param("userId") Long userId, @Param("qwUserId") String qwUserId,@Param("project") Long project);
 
     Long selectRedStatus(@Param("userId") Long userId, @Param("videoId") Long videoId, @Param("periodId") Long periodId);
-
+    Integer selectRedStatus2(@Param("userId") Long userId, @Param("videoId") Long videoId, @Param("periodId") Long periodId);
     List<FsCourseAnswerLogsListVO> selectFsCourseAnswerLogsListVONew(FsCourseAnswerLogsParam param);
 
     Long selectFsCourseAnswerLogsListVONewCount(FsCourseAnswerLogsParam param);

+ 54 - 20
fs-service/src/main/java/com/fs/course/service/impl/FsCourseProductOrderServiceImpl.java

@@ -18,7 +18,9 @@ import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.ip.IpUtils;
 import com.fs.core.config.WxPayProperties;
 import com.fs.core.utils.OrderCodeUtils;
+import com.fs.course.domain.FsCoursePlaySourceConfig;
 import com.fs.course.domain.FsCourseProduct;
+import com.fs.course.mapper.FsCoursePlaySourceConfigMapper;
 import com.fs.course.mapper.FsCourseProductMapper;
 import com.fs.course.param.FsCourseProductOrderCreateParam;
 import com.fs.course.param.FsCourseProductOrderListParam;
@@ -30,6 +32,7 @@ import com.fs.his.dto.PayConfigDTO;
 import com.fs.his.enums.FsCourseProductOrderStatusEnum;
 import com.fs.his.mapper.FsStorePaymentMapper;
 import com.fs.his.mapper.FsUserWxMapper;
+import com.fs.his.mapper.MerchantAppConfigMapper;
 import com.fs.his.param.ApplyCourseProductOrderRefundParam;
 import com.fs.his.param.FsCourseProductOrderComputeParam;
 import com.fs.his.param.FsCourseProductOrderDoPayParam;
@@ -38,6 +41,7 @@ import com.fs.his.service.IFsStorePaymentService;
 import com.fs.his.service.IFsUserService;
 import com.fs.his.service.IFsUserWxService;
 import com.fs.his.utils.PhoneUtil;
+import com.fs.hisStore.domain.FsPayConfigScrm;
 import com.fs.huifuPay.domain.HuiFuCreateOrder;
 import com.fs.huifuPay.domain.HuiFuRefundResult;
 import com.fs.huifuPay.domain.HuifuCreateOrderResult;
@@ -94,6 +98,11 @@ public class FsCourseProductOrderServiceImpl extends ServiceImpl<FsCourseProduct
 
     @Autowired FsCourseProductOrderMapper courseProductOrderMapper;
 
+    @Autowired
+    private FsCoursePlaySourceConfigMapper fsCoursePlaySourceConfigMapper;
+    @Autowired
+    private MerchantAppConfigMapper merchantAppConfigMapper;
+
     @Autowired
     private IFsUserService userService;
 
@@ -277,9 +286,18 @@ public class FsCourseProductOrderServiceImpl extends ServiceImpl<FsCourseProduct
             return R.error("订单状态不正确");
         }
         FsUser user = userService.selectFsUserByUserId(courseProductOrder.getUserId());
-
-        String json = configService.selectConfigByKey("his.pay");
-        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
+        if (StringUtils.isBlank(param.getAppId())) {
+            throw new IllegalArgumentException("appId不能为空");
+        }
+        FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(param.getAppId());
+        if (fsCoursePlaySourceConfig == null) {
+            throw new CustomException("未找到appId对应的小程序配置: " + param.getAppId());
+        }
+        Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+        if (merchantConfigId == null || merchantConfigId <= 0) {
+            throw new CustomException("小程序没有配置商户信息");
+        }
+        MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
         String openId = null;
         String appId = param.getAppId();
         if (StringUtils.isNotBlank(appId)) {
@@ -293,7 +311,7 @@ public class FsCourseProductOrderServiceImpl extends ServiceImpl<FsCourseProduct
                 openId = fsUserWx.getOpenId();
             }
         } else {
-            appId = payConfigDTO.getAppId();
+            appId = merchantAppConfig.getAppId();
             openId = Objects.isNull(user) ? "" : user.getMaOpenId();
             if (StringUtils.isBlank(openId)){
                 Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
@@ -354,8 +372,20 @@ public class FsCourseProductOrderServiceImpl extends ServiceImpl<FsCourseProduct
         FsUser user = userService.selectFsUserByUserId(param.getUserId());
         logger.info("用户信息==============={}",user);
 
-        String json = configService.selectConfigByKey("his.pay");
-        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
+        if (StringUtils.isBlank(param.getAppId())) {
+            throw new IllegalArgumentException("appId不能为空");
+        }
+        FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(param.getAppId());
+        if (fsCoursePlaySourceConfig == null) {
+            throw new CustomException("未找到appId对应的小程序配置: " + param.getAppId());
+        }
+        Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+        if (merchantConfigId == null || merchantConfigId <= 0) {
+            throw new CustomException("小程序没有配置商户信息");
+        }
+
+        MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
+        FsPayConfig fsPayConfig = JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
         String openId = null;
         String appId = param.getAppId();
         if (StringUtils.isNotBlank(appId)) {
@@ -369,7 +399,7 @@ public class FsCourseProductOrderServiceImpl extends ServiceImpl<FsCourseProduct
                 openId = fsUserWx.getOpenId();
             }
         } else {
-            appId = payConfigDTO.getAppId();
+            appId = merchantAppConfig.getAppId();
             openId = Objects.isNull(user) ? "" : user.getMaOpenId();
             if (StringUtils.isBlank(openId)){
                 Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
@@ -388,15 +418,13 @@ public class FsCourseProductOrderServiceImpl extends ServiceImpl<FsCourseProduct
 //        if (user != null && fsUserWx != null && StringUtils.isNotEmpty(fsUserWx.getOpenId())) {
         if (user != null && StringUtils.isNotEmpty(openId)) {
             if (courseProduct.getProductPrice().compareTo(new BigDecimal(0))==1) {
-//                String json = configService.selectConfigByKey("his.pay");
-//                PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
                 String payCode =  OrderCodeUtils.getOrderSn();
                 if(StringUtils.isEmpty(payCode)){
                     return R.error("订单生成失败,请重试");
                 }
                 FsStorePayment storePayment=new FsStorePayment();
                 storePayment.setStatus(0);
-                storePayment.setPayMode(payConfigDTO.getType());
+                storePayment.setPayMode(merchantAppConfig.getMerchantType());
                 storePayment.setBusinessCode(courseProductOrder.getOrderCode());
                 storePayment.setPayCode(payCode);
                 storePayment.setPayMoney(courseProduct.getProductPrice());
@@ -409,12 +437,12 @@ public class FsCourseProductOrderServiceImpl extends ServiceImpl<FsCourseProduct
                 storePayment.setOpenId(openId);
                 storePayment.setUserId(user.getUserId());
                 storePayment.setBusinessId(courseProductOrder.getCourseOrderId().toString());
+                storePayment.setAppId(appId);
+                storePayment.setMerConfigId(merchantAppConfig.getId());
                 if (storePaymentService.insertFsStorePayment(storePayment) > 0) {
-                    if (payConfigDTO.getType().equals("wx")) {
+                    if (merchantAppConfig.getMerchantType().equals("wx")) {
                         //创建微信订单
                         WxPayConfig payConfig = new WxPayConfig();
-                        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
-                        FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
                         payConfig.setAppId(appId);
                         payConfig.setMchId(fsPayConfig.getWxMchId());
                         payConfig.setMchKey(fsPayConfig.getWxMchKey());
@@ -439,7 +467,7 @@ public class FsCourseProductOrderServiceImpl extends ServiceImpl<FsCourseProduct
                             e.printStackTrace();
                             throw new CustomException("支付失败" + e.getMessage());
                         }
-                    } else if (payConfigDTO.getType().equals("yb")) {
+                    } else if (merchantAppConfig.getMerchantType().equals("yb")) {
                         WxJspayDTO p = new WxJspayDTO();
                         // 使用setter方法为对象赋值
                         p.setPayMoney(storePayment.getPayMoney().toString());
@@ -460,7 +488,7 @@ public class FsCourseProductOrderServiceImpl extends ServiceImpl<FsCourseProduct
                         } else {
                             throw new CustomException("支付失败");
                         }
-                    } else if (payConfigDTO.getType().equals("tz")) {
+                    } else if (merchantAppConfig.getMerchantType().equals("tz")) {
                         PayCreateOrder o = new PayCreateOrder();
                         o.setOrderNo("product" + storePayment.getPayCode()); // 业务系统订单号
                         o.setTrxAmt(storePayment.getPayMoney().doubleValue()); // 交易金额
@@ -485,7 +513,7 @@ public class FsCourseProductOrderServiceImpl extends ServiceImpl<FsCourseProduct
                         mt.setTradeNo(result.getBody().getOrderFlowNo());
                         fsStorePaymentMapper.updateFsStorePayment(mt);
                         return R.ok().put("isPay", 0).put("data", result).put("type", "tz");
-                    }else if (payConfigDTO.getType().equals("hf")) {
+                    }else if (merchantAppConfig.getMerchantType().equals("hf")) {
                         logger.info("创建汇付订单");
                         HuiFuCreateOrder o = new HuiFuCreateOrder();
                         o.setTradeType("T_MINIAPP");
@@ -598,19 +626,25 @@ public class FsCourseProductOrderServiceImpl extends ServiceImpl<FsCourseProduct
         mapOrder.setRefundTime(new Date());
         courseProductOrderMapper.updateFsCourseProductOrder(mapOrder);
 
+
         if(courseProduct.getProductPrice().compareTo(new BigDecimal(0))==1){
             List<FsStorePayment> fsStorePayments = fsStorePaymentMapper.selectFsStorePaymentByPay(6, param.getCourseOrderId());
             if (fsStorePayments != null && fsStorePayments.size() == 1) {
                 FsStorePayment payment=fsStorePayments.get(0);
+                FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(param.getAppId());
+                Long merConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+                if(payment.getMerConfigId()!=null){
+                    merConfigId=payment.getMerConfigId();
+                }
+                MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(merConfigId);
                 if(payment.getPayMode().equals("wx")){
                     WxPayConfig payConfig = new WxPayConfig();
-                    SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
-                    FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
-                    payConfig.setAppId(fsPayConfig.getAppId());
+                    FsPayConfig fsPayConfig = JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
+                    payConfig.setAppId(param.getAppId());
                     payConfig.setMchId(fsPayConfig.getWxMchId());
                     payConfig.setMchKey(fsPayConfig.getWxMchKey());
 
-                    payConfig.setKeyPath(wxPayProperties.getKeyPath());
+                    payConfig.setKeyPath(fsPayConfig.getKeyPath());
 
                     payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                     payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));

+ 11 - 0
fs-service/src/main/java/com/fs/course/service/impl/FsCourseRedPacketLogServiceImpl.java

@@ -15,8 +15,10 @@ import com.fs.common.utils.StringUtils;
 import com.fs.company.cache.ICompanyDeptCacheService;
 import com.fs.company.domain.Company;
 import com.fs.company.domain.CompanyMoneyLogs;
+import com.fs.company.domain.CompanyRedPacketBalanceLogs;
 import com.fs.company.mapper.CompanyMapper;
 import com.fs.company.mapper.CompanyMoneyLogsMapper;
+import com.fs.company.mapper.CompanyRedPacketBalanceLogsMapper;
 import com.fs.company.service.ICompanyConfigService;
 import com.fs.course.config.CourseConfig;
 import com.fs.course.config.RedPacketConfig;
@@ -67,6 +69,8 @@ public class FsCourseRedPacketLogServiceImpl implements IFsCourseRedPacketLogSer
     private ISysConfigService configService;
     @Autowired
     private ICompanyDeptCacheService companyDeptCacheService;
+    @Autowired
+    private CompanyRedPacketBalanceLogsMapper companyRedPacketBalanceLogsMapper;
     /**
      * 查询短链课程看课记录
      *
@@ -160,6 +164,13 @@ public class FsCourseRedPacketLogServiceImpl implements IFsCourseRedPacketLogSer
             log.setUpdateTime(new Date());
             log.setBatchId(batchId);
             fsCourseRedPacketLogMapper.updateFsCourseRedPacketLog(log);
+
+            // 更新扣减状态
+            CompanyRedPacketBalanceLogs redLogs = new CompanyRedPacketBalanceLogs();
+            redLogs.setRedPacketId(log.getLogId());
+            redLogs.setStatus(1L);
+            companyRedPacketBalanceLogsMapper.updateCompanyRedPacketBalanceLogsByRedPacketId(redLogs);
+
             return R.ok();
         }
         return R.error("批次不存在");

+ 46 - 18
fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseOrderServiceImpl.java

@@ -80,6 +80,10 @@ public class FsUserCourseOrderServiceImpl implements IFsUserCourseOrderService
     @Autowired
     private FsUserCourseOrderMapper fsUserCourseOrderMapper;
     @Autowired
+    private FsCoursePlaySourceConfigMapper fsCoursePlaySourceConfigMapper;
+    @Autowired
+    private MerchantAppConfigMapper merchantAppConfigMapper;
+    @Autowired
     private FsUserMapper fsUserMapper;
     @Autowired
     private FsUserCourseMapper fsUserCourseMapper;
@@ -374,8 +378,20 @@ public class FsUserCourseOrderServiceImpl implements IFsUserCourseOrderService
         }
         FsUser user=fsUserMapper.selectFsUserByUserId(param.getUserId());
 
-        String json = configService.selectConfigByKey("his.pay");
-        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
+        if (StringUtils.isBlank(param.getAppId())) {
+            throw new IllegalArgumentException("appId不能为空");
+        }
+        FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(param.getAppId());
+        if (fsCoursePlaySourceConfig == null) {
+            throw new CustomException("未找到appId对应的小程序配置: " + param.getAppId());
+        }
+        Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+        if (merchantConfigId == null || merchantConfigId <= 0) {
+            throw new CustomException("小程序没有配置商户信息");
+        }
+        MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
+        FsPayConfig fsPayConfig = JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
+//        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
 
 //        String openId = Objects.isNull(user) ? "" : user.getMaOpenId();
 //        if (StringUtils.isBlank(openId)){
@@ -400,7 +416,7 @@ public class FsUserCourseOrderServiceImpl implements IFsUserCourseOrderService
                 openId = fsUserWx.getOpenId();
             }
         } else {
-            appId = payConfigDTO.getAppId();
+            appId = merchantAppConfig.getAppId();
             openId = Objects.isNull(user) ? "" : user.getMaOpenId();
             if (StringUtils.isBlank(openId)){
                 Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
@@ -424,7 +440,7 @@ public class FsUserCourseOrderServiceImpl implements IFsUserCourseOrderService
                 }
                 FsStorePayment storePayment = new FsStorePayment();
                 storePayment.setStatus(0);
-                storePayment.setPayMode(payConfigDTO.getType());
+                storePayment.setPayMode(merchantAppConfig.getMerchantType());
                 storePayment.setBusinessCode(order.getOrderCode());
                 storePayment.setPayCode(payCode);
                 storePayment.setPayMoney(order.getPayMoney());
@@ -435,13 +451,13 @@ public class FsUserCourseOrderServiceImpl implements IFsUserCourseOrderService
                 storePayment.setOpenId(openId);
                 storePayment.setUserId(user.getUserId());
                 storePayment.setBusinessId(order.getOrderId().toString());
+                storePayment.setAppId(appId);
+                storePayment.setMerConfigId(merchantAppConfig.getId());
                 if (storePaymentService.insertFsStorePayment(storePayment) > 0) {
-                    if (payConfigDTO.getType().equals("wx")) {
+                    if (merchantAppConfig.getMerchantType().equals("wx")) {
                         //创建微信订单
                         WxPayConfig payConfig = new WxPayConfig();
-                        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
-                        FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
-                        payConfig.setAppId(fsPayConfig.getAppId());
+                        payConfig.setAppId(fsCoursePlaySourceConfig.getAppid());
                         payConfig.setMchId(fsPayConfig.getWxMchId());
                         payConfig.setMchKey(fsPayConfig.getWxMchKey());
                         payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
@@ -465,7 +481,7 @@ public class FsUserCourseOrderServiceImpl implements IFsUserCourseOrderService
                             e.printStackTrace();
                             throw new CustomException("支付失败" + e.getMessage());
                         }
-                    } else if (payConfigDTO.getType().equals("yb")) {
+                    } else if (merchantAppConfig.getMerchantType().equals("yb")) {
                         WxJspayDTO p = new WxJspayDTO();
                         // 使用setter方法为对象赋值
                         p.setPayMoney(storePayment.getPayMoney().toString());
@@ -485,7 +501,7 @@ public class FsUserCourseOrderServiceImpl implements IFsUserCourseOrderService
                         } else {
                             throw new CustomException("支付失败");
                         }
-                    } else if (payConfigDTO.getType().equals("tz")) {
+                    } else if (merchantAppConfig.getMerchantType().equals("tz")) {
                         PayCreateOrder o = new PayCreateOrder();
                         o.setOrderNo("course" + storePayment.getPayCode()); // 业务系统订单号
                         o.setTrxAmt(storePayment.getPayMoney().doubleValue()); // 交易金额
@@ -505,7 +521,7 @@ public class FsUserCourseOrderServiceImpl implements IFsUserCourseOrderService
                         mt.setTradeNo(result.getBody().getOrderFlowNo());
                         fsStorePaymentMapper.updateFsStorePayment(mt);
                         return R.ok().put("isPay", 0).put("data", result).put("type", "tz");
-                    } else if (payConfigDTO.getType().equals("hf")) {
+                    } else if (merchantAppConfig.getMerchantType().equals("hf")) {
                         HuiFuCreateOrder o = new HuiFuCreateOrder();
                         o.setTradeType("T_MINIAPP");
                         o.setOpenid(openId);
@@ -550,8 +566,18 @@ public class FsUserCourseOrderServiceImpl implements IFsUserCourseOrderService
 //        }
         FsUser user=fsUserMapper.selectFsUserByUserId(param.getUserId());
 
-        String json = configService.selectConfigByKey("his.pay");
-        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
+        if (StringUtils.isBlank(param.getAppId())) {
+            throw new IllegalArgumentException("appId不能为空");
+        }
+        FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(param.getAppId());
+        if (fsCoursePlaySourceConfig == null) {
+            throw new CustomException("未找到appId对应的小程序配置: " + param.getAppId());
+        }
+        Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+        if (merchantConfigId == null || merchantConfigId <= 0) {
+            throw new CustomException("小程序没有配置商户信息");
+        }
+        MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
         String openId = null;
         String appId = param.getAppId();
         if (StringUtils.isNotBlank(appId)) {
@@ -564,7 +590,7 @@ public class FsUserCourseOrderServiceImpl implements IFsUserCourseOrderService
                 openId = fsUserWx.getOpenId();
             }
         } else {
-            appId = payConfigDTO.getAppId();
+            appId = merchantAppConfig.getAppId();
             openId = Objects.isNull(user) ? "" : user.getMaOpenId();
             if (StringUtils.isBlank(openId)){
                 Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
@@ -587,7 +613,7 @@ public class FsUserCourseOrderServiceImpl implements IFsUserCourseOrderService
 //                PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
                 FsStorePayment storePayment=new FsStorePayment();
                 storePayment.setStatus(0);
-                storePayment.setPayMode(payConfigDTO.getType());
+                storePayment.setPayMode(merchantAppConfig.getMerchantType());
                 storePayment.setBusinessCode(order.getOrderCode());
                 storePayment.setPayCode(payCode);
                 storePayment.setPayMoney(order.getPayMoney());
@@ -598,11 +624,13 @@ public class FsUserCourseOrderServiceImpl implements IFsUserCourseOrderService
 //                storePayment.setOpenId(user.getMpOpenId());
                 storePayment.setUserId(user.getUserId());
                 storePayment.setBusinessId(order.getOrderId().toString());
+                storePayment.setAppId(appId);
+                storePayment.setMerConfigId(merchantAppConfig.getId());
                 if(storePaymentService.insertFsStorePayment(storePayment)>0){
 
-                    if (payConfigDTO.getType().equals("yb")) {
+                    if (merchantAppConfig.getMerchantType().equals("yb")) {
                         return R.error("支付暂不可用!");
-                    } else if (payConfigDTO.getType().equals("tz")) {
+                    } else if (merchantAppConfig.getMerchantType().equals("tz")) {
                         PayCreateOrder o = new PayCreateOrder();
                         o.setOrderNo("course" + storePayment.getPayCode()); // 业务系统订单号
                         o.setTrxAmt(storePayment.getPayMoney().doubleValue()); // 交易金额
@@ -623,7 +651,7 @@ public class FsUserCourseOrderServiceImpl implements IFsUserCourseOrderService
                         mt.setTradeNo(result.getBody().getOrderFlowNo());
                         fsStorePaymentMapper.updateFsStorePayment(mt);
                         return R.ok().put("isPay", 0).put("data", result).put("type", "tz");
-                    }else if (payConfigDTO.getType().equals("hf")) {
+                    }else if (merchantAppConfig.getMerchantType().equals("hf")) {
                         HuiFuCreateOrder o = new HuiFuCreateOrder();
                         o.setTradeType("A_NATIVE");
 //                        o.setOpenid(user.getMaOpenId());

+ 9 - 3
fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseServiceImpl.java

@@ -556,14 +556,20 @@ public class FsUserCourseServiceImpl implements IFsUserCourseService
             Long lxDay = fsCourseWatchLogMapper.selectByWatchlxDay(recordVO.getUserId(),recordVO.getProjectId());
             System.out.println("进入了连续观看天数:"+lxDay+"天");
             recordVO.setWatchLxCount(lxDay);
-
+            //中康小程序统计发送红包状态问题(未答题、未领取、发送成功->0 未领取  1  发送成功  2.没有就是未答题
             // 领取状态
-            Long count = fsCourseAnswerLogsMapper.selectRedStatus(recordVO.getUserId(), recordVO.getVideoId(), (Long) params.get("periodId"));
+            Integer status = fsCourseAnswerLogsMapper.selectRedStatus2(recordVO.getUserId(), recordVO.getVideoId(), (Long) params.get("periodId"));
+            if (status==null){
+                recordVO.setRedStatus(2);
+            }else{
+                recordVO.setRedStatus(status);
+            }
+/*
             if (Objects.nonNull(count) && count > 0) {
                 recordVO.setRedStatus(1);
             } else {
                 recordVO.setRedStatus(0);
-            }
+            }*/
         });
         return list;
     }

+ 2 - 8
fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java

@@ -27,7 +27,6 @@ import com.fs.company.domain.CompanyCompanyFsuser;
 import com.fs.company.domain.CompanyUser;
 import com.fs.company.mapper.CompanyCompanyFsuserMapper;
 import com.fs.company.mapper.CompanyMapper;
-import com.fs.company.mapper.CompanyMoneyLogsMapper;
 import com.fs.company.mapper.CompanyUserMapper;
 import com.fs.company.service.ICompanyService;
 import com.fs.config.cloud.CloudHostProper;
@@ -84,8 +83,6 @@ import com.fs.system.mapper.SysDictDataMapper;
 import com.fs.system.service.ISysConfigService;
 import com.fs.voice.utils.StringUtil;
 import com.github.binarywang.wxpay.bean.transfer.TransferBillsResult;
-import com.volcengine.helper.VodUploadProgressListener;
-import com.volcengine.model.beans.Functions;
 import com.volcengine.service.vod.IVodService;
 import com.volcengine.service.vod.model.business.VodUrlUploadURLSet;
 import com.volcengine.service.vod.model.request.*;
@@ -103,12 +100,9 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.multipart.MultipartFile;
 
-import java.io.File;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
-import java.text.SimpleDateFormat;
 import java.time.*;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
@@ -1883,7 +1877,7 @@ public class FsUserCourseVideoServiceImpl extends ServiceImpl<FsUserCourseVideoM
 
                 // 异步登记余额扣减日志
                 BigDecimal money=amount.multiply(BigDecimal.valueOf(-1));
-                companyService.asyncRecordBalanceLog(param.getCompanyId(), money, 15, newMoney, "发放红包");
+                companyService.asyncRecordBalanceLog(param.getCompanyId(), money, 15, newMoney, "发放红包",redPacketLog.getLogId());
 //            redisCache.setCacheObject("h5user:redPacket:"+param.getUserId(),LocalDateTime.now().toString());
 
                 return sendRedPacket;
@@ -2146,7 +2140,7 @@ public class FsUserCourseVideoServiceImpl extends ServiceImpl<FsUserCourseVideoM
 
                     // 异步登记余额扣减日志
                     BigDecimal money = amount.multiply(BigDecimal.valueOf(-1));
-                    companyService.asyncRecordBalanceLog(param.getCompanyId(), money, 15, newMoney, "发放红包");
+                    companyService.asyncRecordBalanceLog(param.getCompanyId(), money, 15, newMoney, "发放红包", redPacketLog.getLogId());
 
                     return sendRedPacket;
 

+ 50 - 26
fs-service/src/main/java/com/fs/course/service/impl/FsUserVipOrderServiceImpl.java

@@ -10,6 +10,7 @@ import java.util.Objects;
 
 import cn.hutool.core.util.IdUtil;
 import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.common.core.domain.R;
@@ -20,8 +21,10 @@ import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.ip.IpUtils;
 import com.fs.core.config.WxPayProperties;
 import com.fs.core.utils.OrderCodeUtils;
+import com.fs.course.domain.FsCoursePlaySourceConfig;
 import com.fs.course.domain.FsUserCourseOrder;
 import com.fs.course.domain.FsUserVipPackage;
+import com.fs.course.mapper.FsCoursePlaySourceConfigMapper;
 import com.fs.course.mapper.FsUserVipPackageMapper;
 import com.fs.course.param.FsUserVipOrderCreateUParam;
 import com.fs.course.param.FsUserVipOrderParam;
@@ -29,11 +32,9 @@ import com.fs.course.param.FsUserVipOrderPayUParam;
 import com.fs.course.vo.FsUserVipOrderListPVO;
 import com.fs.his.domain.*;
 import com.fs.his.dto.PayConfigDTO;
-import com.fs.his.mapper.FsStorePaymentErrorMapper;
-import com.fs.his.mapper.FsStorePaymentMapper;
-import com.fs.his.mapper.FsUserMapper;
-import com.fs.his.mapper.FsUserWxMapper;
+import com.fs.his.mapper.*;
 import com.fs.his.service.IFsStorePaymentService;
+import com.fs.hisStore.domain.FsPayConfigScrm;
 import com.fs.huifuPay.domain.HuiFuCreateOrder;
 import com.fs.huifuPay.domain.HuifuCreateOrderResult;
 import com.fs.huifuPay.service.HuiFuService;
@@ -81,12 +82,10 @@ public class FsUserVipOrderServiceImpl implements IFsUserVipOrderService
     private FsUserVipPackageMapper fsUserVipPackageMapper;
     @Autowired
     private FsUserMapper userMapper;
-
     @Autowired
-    private ISysConfigService configService;
-
+    private FsCoursePlaySourceConfigMapper fsCoursePlaySourceConfigMapper;
     @Autowired
-    private SysConfigMapper sysConfigMapper;
+    private MerchantAppConfigMapper merchantAppConfigMapper;
 
     @Autowired
     private IFsStorePaymentService storePaymentService;
@@ -233,8 +232,20 @@ public class FsUserVipOrderServiceImpl implements IFsUserVipOrderService
         }
         FsUser user = userMapper.selectFsUserByUserId(param.getUserId());
 
-        String json = configService.selectConfigByKey("his.pay");
-        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
+        if (StringUtils.isBlank(param.getAppId())) {
+            throw new IllegalArgumentException("appId不能为空");
+        }
+        FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(param.getAppId());
+        if (fsCoursePlaySourceConfig == null) {
+            throw new CustomException("未找到appId对应的小程序配置: " + param.getAppId());
+        }
+        Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+        if (merchantConfigId == null || merchantConfigId <= 0) {
+            throw new CustomException("小程序没有配置商户信息");
+        }
+        MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
+        FsPayConfig fsPayConfig = JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
+//        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
 
 //        String openId = Objects.isNull(user) ? "" : user.getMaOpenId();
 //        if (StringUtils.isBlank(openId)){
@@ -258,7 +269,7 @@ public class FsUserVipOrderServiceImpl implements IFsUserVipOrderService
                 openId = fsUserWx.getOpenId();
             }
         } else {
-            appId = payConfigDTO.getAppId();
+            appId = merchantAppConfig.getAppId();
             openId = Objects.isNull(user) ? "" : user.getMaOpenId();
             if (StringUtils.isBlank(openId)){
                 Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
@@ -282,7 +293,7 @@ public class FsUserVipOrderServiceImpl implements IFsUserVipOrderService
                 }
                 FsStorePayment storePayment = new FsStorePayment();
                 storePayment.setStatus(0);
-                storePayment.setPayMode(payConfigDTO.getType());
+                storePayment.setPayMode(merchantAppConfig.getMerchantType());
                 storePayment.setBusinessCode(order.getOrderCode());
                 storePayment.setPayCode(payCode);
                 storePayment.setPayMoney(order.getPayMoney());
@@ -293,13 +304,13 @@ public class FsUserVipOrderServiceImpl implements IFsUserVipOrderService
                 storePayment.setOpenId(openId);
                 storePayment.setUserId(user.getUserId());
                 storePayment.setBusinessId(order.getOrderId().toString());
+                storePayment.setAppId(appId);
+                storePayment.setMerConfigId(merchantAppConfig.getId());
                 if (storePaymentService.insertFsStorePayment(storePayment) > 0) {
-                    if (payConfigDTO.getType().equals("wx")) {
+                    if (merchantAppConfig.getMerchantType().equals("wx")) {
                         //创建微信订单
                         WxPayConfig payConfig = new WxPayConfig();
-                        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
-                        FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
-                        payConfig.setAppId(fsPayConfig.getAppId());
+                        payConfig.setAppId(fsCoursePlaySourceConfig.getAppid());
                         payConfig.setMchId(fsPayConfig.getWxMchId());
                         payConfig.setMchKey(fsPayConfig.getWxMchKey());
                         payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
@@ -323,7 +334,7 @@ public class FsUserVipOrderServiceImpl implements IFsUserVipOrderService
                             e.printStackTrace();
                             throw new CustomException("支付失败" + e.getMessage());
                         }
-                    } else if (payConfigDTO.getType().equals("yb")) {
+                    } else if (merchantAppConfig.getMerchantType().equals("yb")) {
                         WxJspayDTO p = new WxJspayDTO();
                         // 使用setter方法为对象赋值
                         p.setPayMoney(storePayment.getPayMoney().toString());
@@ -343,7 +354,7 @@ public class FsUserVipOrderServiceImpl implements IFsUserVipOrderService
                         } else {
                             throw new CustomException("支付失败");
                         }
-                    } else if (payConfigDTO.getType().equals("tz")) {
+                    } else if (merchantAppConfig.getMerchantType().equals("tz")) {
                         PayCreateOrder o = new PayCreateOrder();
                         o.setOrderNo("appvip" + storePayment.getPayCode()); // 业务系统订单号
                         o.setTrxAmt(storePayment.getPayMoney().doubleValue()); // 交易金额
@@ -363,7 +374,7 @@ public class FsUserVipOrderServiceImpl implements IFsUserVipOrderService
                         mt.setTradeNo(result.getBody().getOrderFlowNo());
                         fsStorePaymentMapper.updateFsStorePayment(mt);
                         return R.ok().put("isPay", 0).put("data", result).put("type", "tz");
-                    } else if (payConfigDTO.getType().equals("hf")) {
+                    } else if (merchantAppConfig.getMerchantType().equals("hf")) {
                         HuiFuCreateOrder o = new HuiFuCreateOrder();
                         o.setTradeType("T_MINIAPP");
                         o.setOpenid(openId);
@@ -399,8 +410,19 @@ public class FsUserVipOrderServiceImpl implements IFsUserVipOrderService
         }
         FsUser user = userMapper.selectFsUserByUserId(param.getUserId());
 
-        String json = configService.selectConfigByKey("his.pay");
-        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
+        if (StringUtils.isBlank(param.getAppId())) {
+            throw new IllegalArgumentException("appId不能为空");
+        }
+        FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(param.getAppId());
+        if (fsCoursePlaySourceConfig == null) {
+            throw new CustomException("未找到appId对应的小程序配置: " + param.getAppId());
+        }
+        Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+        if (merchantConfigId == null || merchantConfigId <= 0) {
+            throw new CustomException("小程序没有配置商户信息");
+        }
+        MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
+//        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
 
         String openId = null;
         String appId = param.getAppId();
@@ -414,7 +436,7 @@ public class FsUserVipOrderServiceImpl implements IFsUserVipOrderService
                 openId = fsUserWx.getOpenId();
             }
         } else {
-            appId = payConfigDTO.getAppId();
+            appId = merchantAppConfig.getAppId();
             openId = Objects.isNull(user) ? "" : user.getMaOpenId();
             if (StringUtils.isBlank(openId)){
                 Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
@@ -437,7 +459,7 @@ public class FsUserVipOrderServiceImpl implements IFsUserVipOrderService
 //                PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
                 FsStorePayment storePayment=new FsStorePayment();
                 storePayment.setStatus(0);
-                storePayment.setPayMode(payConfigDTO.getType());
+                storePayment.setPayMode(merchantAppConfig.getMerchantType());
                 storePayment.setBusinessCode(order.getOrderCode());
                 storePayment.setPayCode(payCode);
                 storePayment.setPayMoney(order.getPayMoney());
@@ -448,11 +470,13 @@ public class FsUserVipOrderServiceImpl implements IFsUserVipOrderService
 //                storePayment.setOpenId(user.getMpOpenId());
                 storePayment.setUserId(user.getUserId());
                 storePayment.setBusinessId(order.getOrderId().toString());
+                storePayment.setAppId(appId);
+                storePayment.setMerConfigId(merchantAppConfig.getId());
                 if(storePaymentService.insertFsStorePayment(storePayment)>0){
 
-                    if (payConfigDTO.getType().equals("yb")) {
+                    if (merchantAppConfig.getMerchantType().equals("yb")) {
                         return R.error("支付暂不可用!");
-                    } else if (payConfigDTO.getType().equals("tz")) {
+                    } else if (merchantAppConfig.getMerchantType().equals("tz")) {
                         PayCreateOrder o = new PayCreateOrder();
                         o.setOrderNo("appvip" + storePayment.getPayCode()); // 业务系统订单号
                         o.setTrxAmt(storePayment.getPayMoney().doubleValue()); // 交易金额
@@ -473,7 +497,7 @@ public class FsUserVipOrderServiceImpl implements IFsUserVipOrderService
                         mt.setTradeNo(result.getBody().getOrderFlowNo());
                         fsStorePaymentMapper.updateFsStorePayment(mt);
                         return R.ok().put("isPay", 0).put("data", result).put("type", "tz");
-                    }else if (payConfigDTO.getType().equals("hf")) {
+                    }else if (merchantAppConfig.getMerchantType().equals("hf")) {
                         HuiFuCreateOrder o = new HuiFuCreateOrder();
                         o.setTradeType("A_NATIVE");
 //                        o.setOpenid(user.getMaOpenId());

+ 4 - 0
fs-service/src/main/java/com/fs/his/domain/FsPayConfig.java

@@ -17,6 +17,10 @@ public class FsPayConfig {
     private String wxMchKey;
     private String keyPath;
     private String wxApiV3Key;
+
+    /**
+     * 微信回调地址
+     */
     private String notifyUrlScrm;
 
     private String ybNotifyUrl;

+ 9 - 0
fs-service/src/main/java/com/fs/his/domain/FsStorePayment.java

@@ -100,6 +100,15 @@ public class FsStorePayment extends BaseEntity
     //小程序appId
     private String appId;
 
+    private Long merConfigId;
+
+    public Long getMerConfigId() {
+        return merConfigId;
+    }
+
+    public void setMerConfigId(Long merConfigId) {
+        this.merConfigId = merConfigId;
+    }
 
     public Integer getIsShare() {
         return isShare;

+ 1 - 0
fs-service/src/main/java/com/fs/his/param/FsCourseProductOrderRefundParam.java

@@ -8,4 +8,5 @@ public class FsCourseProductOrderRefundParam {
     private Long courseOrderId;
 
     private String sysUserName;
+    private String appId;
 }

+ 1 - 0
fs-service/src/main/java/com/fs/his/param/FsInquiryOrderCancelParam.java

@@ -8,5 +8,6 @@ import java.io.Serializable;
 public class FsInquiryOrderCancelParam   implements Serializable {
     Long orderId;
     Integer type;//1用户取消 2未支付自动取消 3未接单自动取消 4 后台取消订单
+    String appId;
 
 }

+ 1 - 0
fs-service/src/main/java/com/fs/his/param/FsInquiryOrderRefundParam.java

@@ -8,6 +8,7 @@ import java.io.Serializable;
 public class FsInquiryOrderRefundParam implements Serializable {
     Long orderId;
     String sysUserName;
+    String appId;
 
 
 }

+ 5 - 0
fs-service/src/main/java/com/fs/his/param/PayOrderParam.java

@@ -36,6 +36,11 @@ public class PayOrderParam {
      * 用户ID
      */
     private Long userId;
+
+    /**
+     * appId
+     */
+    private String appId;
     /**
      * 支付方式
      */

+ 0 - 1
fs-service/src/main/java/com/fs/his/service/IFsStorePaymentService.java

@@ -15,7 +15,6 @@ import com.fs.his.vo.FsStorePaymentExcelVO;
 import com.fs.his.vo.FsStorePaymentVO;
 import com.fs.hisStore.param.FsStorePaymentGetWxaCodeParam;
 import com.fs.hisStore.param.FsStorePaymentPayParam;
-import me.chanjar.weixin.common.error.WxErrorException;
 
 import javax.servlet.http.HttpServletRequest;
 

+ 40 - 4
fs-service/src/main/java/com/fs/his/service/impl/FsInquiryOrderServiceImpl.java

@@ -31,6 +31,8 @@ import com.fs.company.service.ICompanyUserService;
 import com.fs.core.config.WxMaConfiguration;
 import com.fs.core.config.WxPayProperties;
 import com.fs.core.utils.OrderCodeUtils;
+import com.fs.course.domain.FsCoursePlaySourceConfig;
+import com.fs.course.mapper.FsCoursePlaySourceConfigMapper;
 import com.fs.event.TemplateBean;
 import com.fs.event.TemplateEvent;
 import com.fs.event.TemplateListenEnum;
@@ -119,6 +121,10 @@ public class FsInquiryOrderServiceImpl implements IFsInquiryOrderService
     @Autowired
     private RocketMQTemplate rocketMQTemplate;
     @Autowired
+    private FsCoursePlaySourceConfigMapper fsCoursePlaySourceConfigMapper;
+    @Autowired
+    private MerchantAppConfigMapper merchantAppConfigMapper;
+    @Autowired
     private TzBankService tzBankService;
     @Autowired
     private ApplicationEventPublisher publisher;
@@ -326,8 +332,23 @@ public class FsInquiryOrderServiceImpl implements IFsInquiryOrderService
                     FsStorePayment payment=payments.get(0);
                     if(payment.getPayMode().equals("wx")){
                         WxPayConfig payConfig = new WxPayConfig();
-                        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
-                        FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
+                        if (StringUtils.isBlank(param.getAppId())) {
+                            throw new IllegalArgumentException("appId不能为空");
+                        }
+                        FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(param.getAppId());
+                        if (fsCoursePlaySourceConfig == null) {
+                            throw new CustomException("未找到appId对应的小程序配置: " + param.getAppId());
+                        }
+                        Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+                        if (merchantConfigId == null || merchantConfigId <= 0) {
+                            throw new CustomException("小程序没有配置商户信息");
+                        }
+                        Long merConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+                        if(payment.getMerConfigId()!=null){
+                            merConfigId=payment.getMerConfigId();
+                        }
+                        MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(merConfigId);
+                        FsPayConfig fsPayConfig = com.hc.openapi.tool.fastjson.JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
                         payConfig.setAppId(fsPayConfig.getAppId());
                         payConfig.setMchId(fsPayConfig.getWxMchId());
                         payConfig.setMchKey(fsPayConfig.getWxMchKey());
@@ -1485,8 +1506,23 @@ public class FsInquiryOrderServiceImpl implements IFsInquiryOrderService
 
                 if(payment.getPayMode().equals("wx")){
                     WxPayConfig payConfig = new WxPayConfig();
-                    SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
-                    FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
+                    if (StringUtils.isBlank(param.getAppId())) {
+                        throw new IllegalArgumentException("appId不能为空");
+                    }
+                    FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(param.getAppId());
+                    if (fsCoursePlaySourceConfig == null) {
+                        throw new CustomException("未找到appId对应的小程序配置: " + param.getAppId());
+                    }
+                    Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+                    if (merchantConfigId == null || merchantConfigId <= 0) {
+                        throw new CustomException("小程序没有配置商户信息");
+                    }
+                    Long merConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+                    if(payment.getMerConfigId()!=null){
+                        merConfigId=payment.getMerConfigId();
+                    }
+                    MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(merConfigId);
+                    FsPayConfig fsPayConfig = com.hc.openapi.tool.fastjson.JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
                     payConfig.setAppId(fsPayConfig.getAppId());
                     payConfig.setMchId(fsPayConfig.getWxMchId());
                     payConfig.setMchKey(fsPayConfig.getWxMchKey());

+ 95 - 34
fs-service/src/main/java/com/fs/his/service/impl/FsPackageOrderServiceImpl.java

@@ -33,6 +33,8 @@ import com.fs.config.cloud.CloudHostProper;
 import com.fs.core.config.WxMaConfiguration;
 import com.fs.core.config.WxPayProperties;
 import com.fs.core.utils.OrderCodeUtils;
+import com.fs.course.domain.FsCoursePlaySourceConfig;
+import com.fs.course.mapper.FsCoursePlaySourceConfigMapper;
 import com.fs.his.config.FsSysConfig;
 import com.fs.his.domain.*;
 import com.fs.his.dto.PackageConfigDTO;
@@ -47,6 +49,7 @@ import com.fs.his.utils.ConfigUtil;
 import com.fs.his.utils.HttpUtil;
 import com.fs.his.utils.PhoneUtil;
 import com.fs.his.vo.*;
+import com.fs.hisStore.domain.FsPayConfigScrm;
 import com.fs.huifuPay.domain.HuiFuCreateOrder;
 import com.fs.huifuPay.domain.HuifuCreateOrderResult;
 import com.fs.huifuPay.sdk.opps.core.utils.HuiFuUtils;
@@ -98,6 +101,11 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
     private WxPayService wxPayService;
     @Autowired
     private WxPayProperties wxPayProperties;
+
+    @Autowired
+    private FsCoursePlaySourceConfigMapper fsCoursePlaySourceConfigMapper;
+    @Autowired
+    private MerchantAppConfigMapper merchantAppConfigMapper;
     @Autowired
     IPayService payService;
     @Autowired
@@ -445,7 +453,11 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
                     }
                 } else {
                     payMoney = payPrice.multiply(new BigDecimal((100 - configDTO.getPayRate()))).divide(new BigDecimal(100));
-                    payMoney = new BigDecimal(payMoney.setScale(0, BigDecimal.ROUND_HALF_UP).longValue());
+                    payMoney=new BigDecimal(payMoney.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
+                    // 如果小程序需要支付的金额小于0.01元,不能走物流代收,让走货到付款 xgb
+                    if (payMoney.compareTo(new BigDecimal("0.01")) < 0) {
+                        return R.error("物流代收计算支付金额为0,不允许选择物流代收");
+                    }
                 }
 //                if (sysConfig.getRetainer() != null && sysConfig.getRate() != null && sysConfig.getRate().compareTo(new BigDecimal(0)) > 0) {
 //                    if (payPrice.compareTo(new BigDecimal(100)) < 0) {
@@ -866,7 +878,6 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
             List<FsStorePayment> payments = fsStorePaymentMapper.selectFsStorePaymentByPay(3,orderId);
             if(payments!=null&&payments.size()==1){
                 FsStorePayment payment=payments.get(0);
-                String json=configService.selectConfigByKey("his.pay");
                 if(payment.getPayMode().equals("wx")){
                     WxPayConfig payConfig = new WxPayConfig();
                     payConfig.setAppId(wxPayProperties.getAppId());
@@ -979,8 +990,20 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
 
         FsUser user=userService.selectFsUserByUserId(param.getUserId());
 
-        String json = configService.selectConfigByKey("his.pay");
-        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
+        if (StringUtils.isBlank(param.getAppId())) {
+            throw new IllegalArgumentException("appId不能为空");
+        }
+        FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(param.getAppId());
+        if (fsCoursePlaySourceConfig == null) {
+            throw new CustomException("未找到appId对应的小程序配置: " + param.getAppId());
+        }
+        Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+        if (merchantConfigId == null || merchantConfigId <= 0) {
+            throw new CustomException("小程序没有配置商户信息");
+        }
+        MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
+        FsPayConfig fsPayConfig = JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
+//        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
 
         //金牛多小程序支付
         String openId = null;
@@ -995,7 +1018,7 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
                 openId = fsUserWx.getOpenId();
             }
         } else {
-            appId = payConfigDTO.getAppId();
+            appId = fsCoursePlaySourceConfig.getAppid();
             openId = Objects.isNull(user) ? "" : user.getMaOpenId();
             if (StringUtils.isBlank(openId)){
                 Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
@@ -1016,7 +1039,7 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
                 }
                 FsStorePayment storePayment=new FsStorePayment();
                 storePayment.setStatus(0);
-                storePayment.setPayMode(payConfigDTO.getType());
+                storePayment.setPayMode(merchantAppConfig.getMerchantType());
                 storePayment.setBusinessCode(fsPackageOrder.getOrderSn());
                 storePayment.setPayCode(payCode);
                 storePayment.setPayMoney(fsPackageOrder.getPayMoney());
@@ -1030,12 +1053,12 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
                 storePayment.setUserId(user.getUserId());
                 storePayment.setStoreId(fsPackageOrder.getStoreId());
                 storePayment.setBusinessId(fsPackageOrder.getOrderId().toString());
+                storePayment.setAppId(appId);
+                storePayment.setMerConfigId(merchantAppConfig.getId());
                 if(storePaymentService.insertFsStorePayment(storePayment)>0){
-                    if (payConfigDTO.getType().equals("wx")) {
+                    if (merchantAppConfig.getMerchantType().equals("wx")) {
                         //创建微信订单
                         WxPayConfig payConfig = new WxPayConfig();
-                        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
-                        FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
                         payConfig.setAppId(appId);
                         payConfig.setMchId(fsPayConfig.getWxMchId());
                         payConfig.setMchKey(fsPayConfig.getWxMchKey());
@@ -1060,7 +1083,7 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
                             e.printStackTrace();
                             throw new CustomException("支付失败" + e.getMessage());
                         }
-                    } else if (payConfigDTO.getType().equals("yb")) {
+                    } else if (merchantAppConfig.getMerchantType().equals("yb")) {
                         WxJspayDTO p = new WxJspayDTO();
                         // 使用setter方法为对象赋值
                         p.setPayMoney(storePayment.getPayMoney().toString());
@@ -1081,7 +1104,7 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
                         } else {
                             throw new CustomException("支付失败");
                         }
-                    } else if (payConfigDTO.getType().equals("tz")) {
+                    } else if (merchantAppConfig.getMerchantType().equals("tz")) {
                         PayCreateOrder o = new PayCreateOrder();
                         o.setOrderNo("package" + storePayment.getPayCode()); // 业务系统订单号
                         o.setTrxAmt(storePayment.getPayMoney().doubleValue()); // 交易金额
@@ -1106,7 +1129,7 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
                         mt.setTradeNo(result.getBody().getOrderFlowNo());
                         fsStorePaymentMapper.updateFsStorePayment(mt);
                         return R.ok().put("isPay", 0).put("data", result).put("type", "tz");
-                    }else if (payConfigDTO.getType().equals("hf")) {
+                    }else if (merchantAppConfig.getMerchantType().equals("hf")) {
                         logger.info("创建汇付订单");
                         HuiFuCreateOrder o = new HuiFuCreateOrder();
                         o.setTradeType("T_MINIAPP");
@@ -1117,7 +1140,7 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
                         o.setAppId(appId);
                         //公司分账
                         try {
-                            HuiFuUtils.doDiv(o,fsPackageOrder.getCompanyId());
+                            HuiFuUtils.doDiv(o,fsPackageOrder.getCompanyId(),storePayment.getMerConfigId());
                             //存储分账明细
                             HuiFuUtils.saveDivItem(o, fsPackageOrder.getOrderSn(), storePayment.getPayCode());
                         } catch (Exception e) {
@@ -1211,8 +1234,18 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
                 if(StringUtils.isEmpty(payCode)){
                     return R.error("订单生成失败,请重试");
                 }
-                String json = configService.selectConfigByKey("his.pay");
-                PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
+                if (StringUtils.isBlank(param.getAppId())) {
+                    throw new IllegalArgumentException("appId不能为空");
+                }
+                FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(param.getAppId());
+                if (fsCoursePlaySourceConfig == null) {
+                    throw new CustomException("未找到appId对应的小程序配置: " + param.getAppId());
+                }
+                Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+                if (merchantConfigId == null || merchantConfigId <= 0) {
+                    throw new CustomException("小程序没有配置商户信息");
+                }
+                MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
                 String openId = null;
                 String appId = param.getAppId();
                 if (StringUtils.isNotBlank(appId)) {
@@ -1225,7 +1258,7 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
                         openId = fsUserWx.getOpenId();
                     }
                 } else {
-                    appId = payConfigDTO.getAppId();
+                    appId = merchantAppConfig.getAppId();
                     openId = Objects.isNull(user) ? "" : user.getMaOpenId();
                     if (StringUtils.isBlank(openId)){
                         Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
@@ -1240,7 +1273,7 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
 
                 FsStorePayment storePayment=new FsStorePayment();
                 storePayment.setStatus(0);
-                storePayment.setPayMode(payConfigDTO.getType());
+                storePayment.setPayMode(merchantAppConfig.getMerchantType());
                 storePayment.setBusinessCode(fsPackageOrder.getOrderSn());
                 storePayment.setPayCode(payCode);
                 storePayment.setPayMoney(fsPackageOrder.getPayMoney());
@@ -1254,11 +1287,13 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
                 storePayment.setUserId(user.getUserId());
                 storePayment.setStoreId(fsPackageOrder.getStoreId());
                 storePayment.setBusinessId(fsPackageOrder.getOrderId().toString());
+                storePayment.setAppId(appId);
+                storePayment.setMerConfigId(merchantAppConfig.getId());
                 if(storePaymentService.insertFsStorePayment(storePayment)>0){
 
-                    if (payConfigDTO.getType().equals("yb")) {
+                    if (merchantAppConfig.getMerchantType().equals("yb")) {
                         return R.error("支付暂不可用!");
-                    } else if (payConfigDTO.getType().equals("tz")) {
+                    } else if (merchantAppConfig.getMerchantType().equals("tz")) {
                         PayCreateOrder o = new PayCreateOrder();
                         o.setOrderNo("package" + storePayment.getPayCode()); // 业务系统订单号
                         o.setTrxAmt(storePayment.getPayMoney().doubleValue()); // 交易金额
@@ -1279,7 +1314,7 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
                         mt.setTradeNo(result.getBody().getOrderFlowNo());
                         fsStorePaymentMapper.updateFsStorePayment(mt);
                         return R.ok().put("isPay", 0).put("data", result).put("type", "tz");
-                    }else if (payConfigDTO.getType().equals("hf")) {
+                    }else if (merchantAppConfig.getMerchantType().equals("hf")) {
                         logger.info("创建汇付订单");
                         HuiFuCreateOrder o = new HuiFuCreateOrder();
                         o.setTradeType("A_NATIVE");
@@ -1320,8 +1355,19 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
         //如果存在优惠券  判断优惠券是否已使用
         FsUser user=userService.selectFsUserByUserId(param.getUserId());
 
-        String json = configService.selectConfigByKey("his.pay");
-        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
+        if (StringUtils.isBlank(param.getAppId())) {
+            throw new IllegalArgumentException("appId不能为空");
+        }
+        FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(param.getAppId());
+        if (fsCoursePlaySourceConfig == null) {
+            throw new CustomException("未找到appId对应的小程序配置: " + param.getAppId());
+        }
+        Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+        if (merchantConfigId == null || merchantConfigId <= 0) {
+            throw new CustomException("小程序没有配置商户信息");
+        }
+        MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
+//        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
 
         String openId = null;
         String appId = param.getAppId();
@@ -1335,7 +1381,7 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
                 openId = fsUserWx.getOpenId();
             }
         } else {
-            appId = payConfigDTO.getAppId();
+            appId = merchantAppConfig.getAppId();
             openId = Objects.isNull(user) ? "" : user.getMaOpenId();
             if (StringUtils.isBlank(openId)){
                 Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
@@ -1358,7 +1404,7 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
                 }
                 FsStorePayment storePayment=new FsStorePayment();
                 storePayment.setStatus(0);
-                storePayment.setPayMode(payConfigDTO.getType());
+                storePayment.setPayMode(merchantAppConfig.getMerchantType());
                 storePayment.setBusinessCode(fsPackageOrder.getOrderSn());
                 storePayment.setPayCode(payCode);
                 storePayment.setPayMoney(fsPackageOrder.getPayMoney());
@@ -1372,10 +1418,12 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
                 storePayment.setUserId(user.getUserId());
                 storePayment.setStoreId(fsPackageOrder.getStoreId());
                 storePayment.setBusinessId(fsPackageOrder.getOrderId().toString());
+                storePayment.setAppId(appId);
+                storePayment.setMerConfigId(merchantAppConfig.getId());
                 if(storePaymentService.insertFsStorePayment(storePayment)>0){
-                    if (payConfigDTO.getType().equals("yb")) {
+                    if (merchantAppConfig.getMerchantType().equals("yb")) {
                         return R.error("支付暂不可用!");
-                    } else if (payConfigDTO.getType().equals("tz")) {
+                    } else if (merchantAppConfig.getMerchantType().equals("tz")) {
                         PayCreateOrder o = new PayCreateOrder();
                         o.setOrderNo("package" + storePayment.getPayCode()); // 业务系统订单号
                         o.setTrxAmt(storePayment.getPayMoney().doubleValue()); // 交易金额
@@ -1396,7 +1444,7 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
                         mt.setTradeNo(result.getBody().getOrderFlowNo());
                         fsStorePaymentMapper.updateFsStorePayment(mt);
                         return R.ok().put("isPay", 0).put("data", result).put("type", "tz");
-                    }else if (payConfigDTO.getType().equals("hf")) {
+                    }else if (merchantAppConfig.getMerchantType().equals("hf")) {
                         logger.info("创建汇付订单");
                         HuiFuCreateOrder o = new HuiFuCreateOrder();
                         o.setTradeType("T_JSAPI");
@@ -1439,8 +1487,19 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
         //如果存在优惠券  判断优惠券是否已使用
         FsUser user=userService.selectFsUserByUserId(param.getUserId());
 
-        String json = configService.selectConfigByKey("his.pay");
-        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
+        if (StringUtils.isBlank(param.getAppId())) {
+            throw new IllegalArgumentException("appId不能为空");
+        }
+        FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(param.getAppId());
+        if (fsCoursePlaySourceConfig == null) {
+            throw new CustomException("未找到appId对应的小程序配置: " + param.getAppId());
+        }
+        Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+        if (merchantConfigId == null || merchantConfigId <= 0) {
+            throw new CustomException("小程序没有配置商户信息");
+        }
+        MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
+//        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
 
         //金牛多小程序支付
         String openId = null;
@@ -1455,7 +1514,7 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
                 openId = fsUserWx.getOpenId();
             }
         } else {
-            appId = payConfigDTO.getAppId();
+            appId = merchantAppConfig.getAppId();
             openId = Objects.isNull(user) ? "" : user.getMaOpenId();
             if (StringUtils.isBlank(openId)){
                 Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
@@ -1478,7 +1537,7 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
 //                PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
                 FsStorePayment storePayment=new FsStorePayment();
                 storePayment.setStatus(0);
-                storePayment.setPayMode(payConfigDTO.getType());
+                storePayment.setPayMode(merchantAppConfig.getMerchantType());
                 storePayment.setBusinessCode(fsPackageOrder.getOrderSn());
                 storePayment.setPayCode(payCode);
                 storePayment.setPayMoney(fsPackageOrder.getPayMoney());
@@ -1492,11 +1551,13 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
                 storePayment.setUserId(user.getUserId());
                 storePayment.setStoreId(fsPackageOrder.getStoreId());
                 storePayment.setBusinessId(fsPackageOrder.getOrderId().toString());
+                storePayment.setAppId(appId);
+                storePayment.setMerConfigId(merchantAppConfig.getId());
                 if(storePaymentService.insertFsStorePayment(storePayment)>0){
 
-                    if (payConfigDTO.getType().equals("yb")) {
+                    if (merchantAppConfig.getMerchantType().equals("yb")) {
                         return R.error("支付暂不可用!");
-                    } else if (payConfigDTO.getType().equals("tz")) {
+                    } else if (merchantAppConfig.getMerchantType().equals("tz")) {
                         PayCreateOrder o = new PayCreateOrder();
                         o.setOrderNo("package" + storePayment.getPayCode()); // 业务系统订单号
                         o.setTrxAmt(storePayment.getPayMoney().doubleValue()); // 交易金额
@@ -1517,7 +1578,7 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
                         mt.setTradeNo(result.getBody().getOrderFlowNo());
                         fsStorePaymentMapper.updateFsStorePayment(mt);
                         return R.ok().put("isPay", 0).put("data", result).put("type", "tz");
-                    }else if (payConfigDTO.getType().equals("hf")) {
+                    }else if (merchantAppConfig.getMerchantType().equals("hf")) {
                         logger.info("创建汇付订单");
                         HuiFuCreateOrder o = new HuiFuCreateOrder();
                         o.setTradeType("A_NATIVE");

+ 25 - 3
fs-service/src/main/java/com/fs/his/service/impl/FsStoreAfterSalesServiceImpl.java

@@ -31,6 +31,8 @@ import com.fs.company.service.impl.CompanyServiceImpl;
 import com.fs.company.vo.FsStoreOrderStatisticsVO;
 import com.fs.core.config.WxPayProperties;
 import com.fs.core.utils.OrderCodeUtils;
+import com.fs.course.domain.FsCoursePlaySourceConfig;
+import com.fs.course.mapper.FsCoursePlaySourceConfigMapper;
 import com.fs.his.config.FsSysConfig;
 import com.fs.his.config.StoreConfig;
 import com.fs.erp.dto.BaseResponse;
@@ -48,6 +50,7 @@ import com.fs.his.param.*;
 import com.fs.his.service.*;
 import com.fs.his.utils.ConfigUtil;
 import com.fs.his.vo.*;
+import com.fs.hisStore.domain.FsPayConfigScrm;
 import com.fs.huifuPay.domain.HuiFuRefundResult;
 import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayRefundRequest;
 import com.fs.huifuPay.sdk.opps.core.utils.HuiFuUtils;
@@ -96,6 +99,10 @@ public class FsStoreAfterSalesServiceImpl implements IFsStoreAfterSalesService {
     @Autowired
     private FsStoreAfterSalesLogsMapper fsStoreAfterSalesLogsMapper;
     @Autowired
+    private FsCoursePlaySourceConfigMapper fsCoursePlaySourceConfigMapper;
+    @Autowired
+    private MerchantAppConfigMapper merchantAppConfigMapper;
+    @Autowired
     private FsStoreOrderMapper fsStoreOrderMapper;
     @Autowired
     private FsStoreOrderLogsMapper fsStoreOrderLogsMapper;
@@ -475,11 +482,25 @@ public class FsStoreAfterSalesServiceImpl implements IFsStoreAfterSalesService {
             if (reMoney.compareTo(payment.getPayMoney()) > 0) {
                 throw new CustomException("退款金额不能大于实际支付金额"); //退款金额不能大于实际支付金额
             }
-            String json = configService.selectConfigByKey("his.pay");
+            if (StringUtils.isBlank(payment.getAppId())) {
+                throw new IllegalArgumentException("appId不能为空");
+            }
+            FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(payment.getAppId());
+            if (fsCoursePlaySourceConfig == null) {
+                throw new CustomException("未找到appId对应的小程序配置: " + payment.getAppId());
+            }
+            Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+            if (merchantConfigId == null || merchantConfigId <= 0) {
+                throw new CustomException("小程序没有配置商户信息");
+            }
+            Long merConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+            if(payment.getMerConfigId()!=null){
+                merConfigId=payment.getMerConfigId();
+            }
+            MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(merConfigId);
+            FsPayConfig fsPayConfig = JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
             if (payment.getPayMode().equals("wx")) {
                 WxPayConfig payConfig = new WxPayConfig();
-                SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
-                FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
                 payConfig.setAppId(fsPayConfig.getAppId());
                 payConfig.setMchId(fsPayConfig.getWxMchId());
                 payConfig.setMchKey(fsPayConfig.getWxMchKey());
@@ -570,6 +591,7 @@ public class FsStoreAfterSalesServiceImpl implements IFsStoreAfterSalesService {
                 }
 
                 request.setExtendInfo(extendInfoMap);
+                request.setAppId(payment.getAppId());
                 HuiFuRefundResult refund = huiFuService.refund(request);
                 logger.info("订单退款返回结果:退款订单id:" + order.getOrderId() + refund);
                 if ((refund.getResp_code().equals("00000000") || refund.getResp_code().equals("00000100")) && (refund.getTrans_stat().equals("S") || refund.getTrans_stat().equals("P"))) {

+ 46 - 20
fs-service/src/main/java/com/fs/his/service/impl/FsStoreOrderServiceImpl.java

@@ -28,6 +28,8 @@ import com.fs.config.ai.AiHostProper;
 import com.fs.config.cloud.CloudHostProper;
 import com.fs.core.config.WxPayProperties;
 import com.fs.core.utils.OrderCodeUtils;
+import com.fs.course.domain.FsCoursePlaySourceConfig;
+import com.fs.course.mapper.FsCoursePlaySourceConfigMapper;
 import com.fs.erp.domain.*;
 import com.fs.erp.dto.*;
 import com.fs.erp.dto.df.*;
@@ -45,6 +47,7 @@ import com.fs.his.service.*;
 import com.fs.his.utils.ConfigUtil;
 import com.fs.his.utils.PhoneUtil;
 import com.fs.his.vo.*;
+import com.fs.hisStore.domain.FsPayConfigScrm;
 import com.fs.hisStore.domain.FsStoreOrderScrm;
 import com.fs.hisStore.domain.FsStorePaymentScrm;
 import com.fs.hisStore.mapper.FsStoreOrderScrmMapper;
@@ -153,7 +156,9 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
     private FsStoreOrderMapper fsStoreOrderMapper;
 
     @Autowired
-    private FsStoreOrderScrmMapper fsStoreOrderScrmMapper;
+    private FsCoursePlaySourceConfigMapper fsCoursePlaySourceConfigMapper;
+    @Autowired
+    private MerchantAppConfigMapper merchantAppConfigMapper;
 
     @Autowired
     private FsStoreOrderItemMapper fsStoreOrderItemMapper;
@@ -2960,8 +2965,18 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
 //        }
         FsUser user = userService.selectFsUserByUserId(param.getUserId());
         //在线支付
-        String json = configService.selectConfigByKey("his.pay");
-        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
+        if (StringUtils.isBlank(param.getAppId())) {
+            throw new IllegalArgumentException("appId不能为空");
+        }
+        FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(param.getAppId());
+        if (fsCoursePlaySourceConfig == null) {
+            throw new CustomException("未找到appId对应的小程序配置: " + param.getAppId());
+        }
+        Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+        if (merchantConfigId == null || merchantConfigId <= 0) {
+            throw new CustomException("小程序没有配置商户信息");
+        }
+        MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
         String openId = null;
         String appId = param.getAppId();
         if (StringUtils.isNotBlank(appId)) {
@@ -2974,7 +2989,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                 openId = fsUserWx.getOpenId();
             }
         } else {
-            appId = payConfigDTO.getAppId();
+            appId = merchantAppConfig.getAppId();
             openId = Objects.isNull(user) ? "" : user.getMaOpenId();
             if (StringUtils.isBlank(openId)){
                 Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
@@ -3000,7 +3015,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                 FsStorePayment storePayment = new FsStorePayment();
                 storePayment.setStatus(0);
                 storePayment.setPayCode(payCode);
-                storePayment.setPayMode(payConfigDTO.getType());
+                storePayment.setPayMode(merchantAppConfig.getMerchantType());
                 storePayment.setPayMoney(order.getPayMoney());
                 storePayment.setBusinessCode(order.getOrderCode());
                 storePayment.setCreateTime(new Date());
@@ -3013,20 +3028,21 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                 storePayment.setCompanyUserId(order.getCompanyUserId());
                 storePayment.setStoreId(order.getStoreId());
                 storePayment.setBusinessId(order.getOrderId().toString());
+                storePayment.setAppId(appId);
+                storePayment.setMerConfigId(merchantAppConfig.getId());
                 if (storePaymentService.insertFsStorePayment(storePayment) > 0) {
 
-                    if (payConfigDTO.getType().equals("wx")) {
+                    if (merchantAppConfig.getMerchantType().equals("wx")) {
                         //创建微信订单
                         WxPayConfig payConfig = new WxPayConfig();
-                        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
-                        FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
-                        payConfig.setAppId(fsPayConfig.getAppId());
+                        FsPayConfig fsPayConfig = JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
+                        payConfig.setAppId(fsCoursePlaySourceConfig.getAppid());
                         payConfig.setMchId(fsPayConfig.getWxMchId());
                         payConfig.setMchKey(fsPayConfig.getWxMchKey());
                         payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                         payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                         payConfig.setKeyPath(null);
-                        payConfig.setNotifyUrl(wxPayProperties.getNotifyUrl());
+                        payConfig.setNotifyUrl(fsPayConfig.getNotifyUrlScrm());
                         wxPayService.setConfig(payConfig);
                         WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
                         orderRequest.setOpenid(openId);//公众号支付提供用户openid
@@ -3044,7 +3060,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                             e.printStackTrace();
                             throw new CustomException("支付失败" + e.getMessage());
                         }
-                    } else if (payConfigDTO.getType().equals("yb")) {
+                    } else if (merchantAppConfig.getMerchantType().equals("yb")) {
                         WxJspayDTO p = new WxJspayDTO();
                         // 使用setter方法为对象赋值
                         p.setPayMoney(storePayment.getPayMoney().toString());
@@ -3064,7 +3080,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                         } else {
                             throw new CustomException("支付失败");
                         }
-                    } else if (payConfigDTO.getType().equals("tz")) {
+                    } else if (merchantAppConfig.getMerchantType().equals("tz")) {
                         PayCreateOrder o = new PayCreateOrder();
                         o.setOrderNo("store" + storePayment.getPayCode()); // 业务系统订单号
                         o.setTrxAmt(storePayment.getPayMoney().doubleValue()); // 交易金额
@@ -3089,7 +3105,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                         mt.setTradeNo(result.getBody().getOrderFlowNo());
                         fsStorePaymentMapper.updateFsStorePayment(mt);
                         return R.ok().put("isPay", 0).put("data", result).put("type", "tz");
-                    } else if (payConfigDTO.getType().equals("hf")) {
+                    } else if (merchantAppConfig.getMerchantType().equals("hf")) {
                         HuiFuCreateOrder o = new HuiFuCreateOrder();
                         o.setTradeType("T_MINIAPP");
                         o.setOpenid(openId);
@@ -3126,8 +3142,18 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
 
         FsUser user = userService.selectFsUserByUserId(param.getUserId());
 
-        String json = configService.selectConfigByKey("his.pay");
-        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
+        if (StringUtils.isBlank(param.getAppId())) {
+            throw new IllegalArgumentException("appId不能为空");
+        }
+        FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(param.getAppId());
+        if (fsCoursePlaySourceConfig == null) {
+            throw new CustomException("未找到appId对应的小程序配置: " + param.getAppId());
+        }
+        Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+        if (merchantConfigId == null || merchantConfigId <= 0) {
+            throw new CustomException("小程序没有配置商户信息");
+        }
+        MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
 
         String openId = null;
         String appId = param.getAppId();
@@ -3141,7 +3167,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                 openId = fsUserWx.getOpenId();
             }
         } else {
-            appId = payConfigDTO.getAppId();
+            appId = merchantAppConfig.getAppId();
             openId = Objects.isNull(user) ? "" : user.getMaOpenId();
             if (StringUtils.isBlank(openId)){
                 Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
@@ -3171,7 +3197,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                 FsStorePayment storePayment = new FsStorePayment();
                 storePayment.setStatus(0);
                 storePayment.setPayCode(payCode);
-                storePayment.setPayMode(payConfigDTO.getType());
+                storePayment.setPayMode(merchantAppConfig.getMerchantType());
                 storePayment.setPayMoney(order.getPayMoney());
                 storePayment.setBusinessCode(order.getOrderCode());
                 storePayment.setCreateTime(new Date());
@@ -3185,9 +3211,9 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                 storePayment.setStoreId(order.getStoreId());
                 storePayment.setBusinessId(order.getOrderId().toString());
                 if (storePaymentService.insertFsStorePayment(storePayment) > 0) {
-                    if (payConfigDTO.getType().equals("yb")) {
+                    if (merchantAppConfig.getMerchantType().equals("yb")) {
                         return R.error("支付暂不可用!");
-                    } else if (payConfigDTO.getType().equals("tz")) {
+                    } else if (merchantAppConfig.getMerchantType().equals("tz")) {
                         PayCreateOrder o = new PayCreateOrder();
                         o.setOrderNo("store" + storePayment.getPayCode()); // 业务系统订单号
                         o.setTrxAmt(storePayment.getPayMoney().doubleValue()); // 交易金额
@@ -3207,7 +3233,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                         mt.setTradeNo(result.getBody().getOrderFlowNo());
                         fsStorePaymentMapper.updateFsStorePayment(mt);
                         return R.ok().put("isPay", 0).put("data", result).put("type", "tz");
-                    } else if (payConfigDTO.getType().equals("hf")) {
+                    } else if (merchantAppConfig.getMerchantType().equals("hf")) {
                         HuiFuCreateOrder o = new HuiFuCreateOrder();
                         o.setTradeType("A_NATIVE");
                         o.setOpenid(openId);

+ 127 - 51
fs-service/src/main/java/com/fs/his/service/impl/FsStorePaymentServiceImpl.java

@@ -38,21 +38,19 @@ import com.fs.company.service.ICompanyUserService;
 import com.fs.company.vo.FsStorePaymentStatisticsVO;
 import com.fs.config.cloud.CloudHostProper;
 import com.fs.core.config.WxMaConfiguration;
-import com.fs.core.config.WxPayProperties;
 import com.fs.core.utils.OrderCodeUtils;
 import com.fs.course.config.RedPacketConfig;
+import com.fs.course.domain.FsCoursePlaySourceConfig;
+import com.fs.course.mapper.FsCoursePlaySourceConfigMapper;
 import com.fs.course.service.IFsCourseRedPacketLogService;
 import com.fs.course.service.IFsUserCourseOrderService;
 import com.fs.course.service.IFsUserVipOrderService;
 import com.fs.his.domain.*;
-import com.fs.his.dto.PayConfigDTO;
 import com.fs.his.enums.PaymentMethodEnum;
 import com.fs.his.mapper.*;
 import com.fs.his.param.*;
 import com.fs.his.service.IFsInquiryOrderService;
 
-import com.fs.his.param.WxSendRedPacketParam;
-import com.fs.his.service.IFsInquiryOrderService;
 import com.fs.his.service.IFsPackageOrderService;
 import com.fs.his.service.IFsStoreOrderService;
 import com.fs.his.service.IFsStorePaymentService;
@@ -98,7 +96,6 @@ import com.github.binarywang.wxpay.exception.WxPayException;
 import com.github.binarywang.wxpay.service.TransferService;
 import com.github.binarywang.wxpay.service.WxPayService;
 import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
-import com.google.gson.Gson;
 import com.hc.openapi.tool.fastjson.JSON;
 import me.chanjar.weixin.common.error.WxErrorException;
 
@@ -134,6 +131,11 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
     private FsStorePaymentMapper fsStorePaymentMapper;
     @Autowired
     private FsStorePaymentScrmMapper fsStorePaymentScrmMapper;
+
+    @Autowired
+    private FsCoursePlaySourceConfigMapper fsCoursePlaySourceConfigMapper;
+    @Autowired
+    private MerchantAppConfigMapper merchantAppConfigMapper;
     @Autowired
     private TzBankService tzBankService;
     @Autowired
@@ -152,8 +154,8 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
     private IFsUserVipOrderService vipOrderService;
     @Autowired
     SysConfigMapper sysConfigMapper;
-    @Autowired
-    private WxPayProperties wxPayProperties;
+//    @Autowired
+//    private WxPayProperties wxPayProperties;
     @Autowired
     private WxPayService wxPayService;
     @Autowired
@@ -440,12 +442,23 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
 
             if(fsStorePayment.getPayMode().equals("wx")){
                 WxPayConfig payConfig = new WxPayConfig();
-                SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
-                FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
-                payConfig.setAppId(fsPayConfig.getAppId());
+                if (StringUtils.isBlank(fsStorePayment.getAppId())) {
+                    throw new IllegalArgumentException("appId不能为空");
+                }
+                FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(fsStorePayment.getAppId());
+                if (fsCoursePlaySourceConfig == null) {
+                    throw new CustomException("未找到appId对应的小程序配置: " + fsStorePayment.getAppId());
+                }
+                Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+                if (merchantConfigId == null || merchantConfigId <= 0) {
+                    throw new CustomException("小程序没有配置商户信息");
+                }
+                MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
+                FsPayConfig fsPayConfig = com.alibaba.fastjson.JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
+                payConfig.setAppId(fsCoursePlaySourceConfig.getAppid());
                 payConfig.setMchId(fsPayConfig.getWxMchId());
                 payConfig.setMchKey(fsPayConfig.getWxMchKey());
-                payConfig.setKeyPath(wxPayProperties.getKeyPath());
+                payConfig.setKeyPath(fsPayConfig.getKeyPath());
                 payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                 payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                 wxPayService.setConfig(payConfig);
@@ -1254,9 +1267,23 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
             throw new CustomException("用户不存在");
         }
 
-        String json = configService.selectConfigByKey("his.pay");
-        logger.debug("支付配置 his.pay: {}", json);
-        FsPayConfig payConfig = JSONUtil.toBean(json, FsPayConfig.class);
+        if (StringUtils.isBlank(payOrderParam.getAppId())) {
+            throw new IllegalArgumentException("appId不能为空");
+        }
+        FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(payOrderParam.getAppId());
+        if (fsCoursePlaySourceConfig == null) {
+            throw new CustomException("未找到appId对应的小程序配置: " + payOrderParam.getAppId());
+        }
+        Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+        if (merchantConfigId == null || merchantConfigId <= 0) {
+            throw new CustomException("小程序没有配置商户信息");
+        }
+        MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
+        FsPayConfig payConfig =JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
+        payConfig.setType(merchantAppConfig.getMerchantType());
+        payConfig.setAppId(fsCoursePlaySourceConfig.getAppid());
+        logger.debug("支付配置 his.pay: {}", payConfig);
+//        FsPayConfig payConfig = JSONUtil.toBean(json, FsPayConfig.class);
 
         if (isWechatPayment(payOrderParam.getPaymentMethod())) {
             String openId = getOpenIdForPaymentMethod(user, payOrderParam.getPaymentMethod(), payConfig);
@@ -1495,7 +1522,7 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
         payConfig.setSubAppId(StringUtils.trimToNull(null));
         payConfig.setSubMchId(StringUtils.trimToNull(null));
         payConfig.setKeyPath(null);
-        payConfig.setNotifyUrl(wxPayProperties.getNotifyUrl());
+        payConfig.setNotifyUrl(fsPayConfig.getNotifyUrlScrm());
         return payConfig;
     }
 
@@ -1722,8 +1749,19 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
             return R.error("用户不存在!");
         }
 
-        String json = configService.selectConfigByKey("his.pay");
-        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
+        if (StringUtils.isBlank(param.getAppId())) {
+            throw new IllegalArgumentException("appId不能为空");
+        }
+        FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(param.getAppId());
+        if (fsCoursePlaySourceConfig == null) {
+            throw new CustomException("未找到appId对应的小程序配置: " + param.getAppId());
+        }
+        Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+        if (merchantConfigId == null || merchantConfigId <= 0) {
+            throw new CustomException("小程序没有配置商户信息");
+        }
+        MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
+        FsPayConfig fsPayConfig = JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
         String openId = null;
         String appId = param.getAppId();
         if (StringUtils.isNotBlank(appId)) {
@@ -1736,7 +1774,7 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
                 openId = fsUserWx.getOpenId();
             }
         } else {
-            appId = payConfigDTO.getAppId();
+            appId = merchantAppConfig.getAppId();
             openId = Objects.isNull(user) ? "" : user.getMaOpenId();
             if (StringUtils.isBlank(openId)){
                 Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
@@ -1781,40 +1819,78 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
         storePayment.setRemark("商城收款订单支付");
         storePayment.setOpenId(openId);
         storePayment.setUserId(user.getUserId());
-        storePayment.setPayMode("hf");//目前微信收款仅支持汇付
-        fsStorePaymentMapper.insertFsStorePayment(storePayment);
-
-        //汇付支付
-        HuiFuCreateOrder o = new HuiFuCreateOrder();
-        o.setTradeType("T_MINIAPP");
-        o.setOpenid(openId);
-        o.setReqSeqId("payment-"+storePayment.getPayCode());
-        o.setTransAmt(storePayment.getPayMoney().toString());
-        o.setGoodsDesc("商城订单支付");
-        o.setAppId(appId);
-        //公司分账
-        try {
-            HuiFuUtils.doDiv(o,company.getCompanyId());
-            //存储分账明细
-            HuiFuUtils.saveDivItem(o, storePayment.getPayCode(), storePayment.getPayCode());
-        } catch (Exception e) {
-            logger.error("-------------微信收款分账出错:{}", e.getMessage());
-        }
-        HuifuCreateOrderResult result = huiFuService.createOrder(o);
-        if(result.getResp_code()!=null&&(result.getResp_code().equals("00000000")||result.getResp_code().equals("00000100"))){
-            FsStorePayment mt=new FsStorePayment();
-            mt.setPaymentId(storePayment.getPaymentId());
-            mt.setTradeNo(result.getHf_seq_id());
-            mt.setAppId(appId);
-            fsStorePaymentMapper.updateFsStorePayment(mt);
-            Map<String, Object> resultMap = com.alibaba.fastjson.JSON.parseObject(result.getPay_info(), new TypeReference<Map<String, Object>>() {});
-            String s = (String) resultMap.get("package");
-            resultMap.put("packageValue",s);
-            return R.ok().put("result",resultMap);
-        }
-        else{
-            return R.error(result.getResp_desc());
+        storePayment.setPayMode(merchantAppConfig.getMerchantType());
+        storePayment.setAppId(appId);
+        storePayment.setMerConfigId(merchantAppConfig.getId());
+
+        if (fsStorePaymentMapper.insertFsStorePayment(storePayment) > 0) {
+            if (merchantAppConfig.getMerchantType().equals("wx")) {
+                //创建微信订单
+                WxPayConfig payConfig = new WxPayConfig();
+                payConfig.setAppId(appId);
+                payConfig.setMchId(fsPayConfig.getWxMchId());
+                payConfig.setMchKey(fsPayConfig.getWxMchKey());
+                payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
+                payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));
+                payConfig.setKeyPath(null);
+                payConfig.setNotifyUrl(fsPayConfig.getNotifyUrlScrm());
+                wxPayService.setConfig(payConfig);
+                WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
+                orderRequest.setOpenid(openId);//公众号支付提供用户openid
+                orderRequest.setBody("收款支付");
+                orderRequest.setOutTradeNo("payment-" + storePayment.getPayCode());
+                orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(storePayment.getPayMoney().toString()));//测试
+                //orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(money));//测试
+                orderRequest.setTradeType("JSAPI");
+                orderRequest.setSpbillCreateIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
+                //调用统一下单接口,获取"预支付交易会话标识"
+                try {
+                    WxPayMpOrderResult orderResult = wxPayService.createOrder(orderRequest);
+                    return R.ok().put("data", orderResult).put("type", "wx").put("isPay", 0);
+                } catch (WxPayException e) {
+                    e.printStackTrace();
+                    throw new CustomException("支付失败" + e.getMessage());
+                }
+            } else if (merchantAppConfig.getMerchantType().equals("hf")) {
+
+                //汇付支付
+                HuiFuCreateOrder o = new HuiFuCreateOrder();
+                o.setTradeType("T_MINIAPP");
+                o.setOpenid(openId);
+                o.setReqSeqId("payment-"+storePayment.getPayCode());
+                o.setTransAmt(storePayment.getPayMoney().toString());
+                o.setGoodsDesc("商城订单支付");
+                o.setAppId(appId);
+                //公司分账
+                try {
+                    HuiFuUtils.doDiv(o,company.getCompanyId(), storePayment.getMerConfigId());
+                    //存储分账明细
+                    HuiFuUtils.saveDivItem(o, storePayment.getPayCode(), storePayment.getPayCode());
+                } catch (Exception e) {
+                    logger.error("-------------微信收款分账出错:{}", e.getMessage());
+                }
+                HuifuCreateOrderResult result = huiFuService.createOrder(o);
+
+                if(result.getResp_code()!=null&&(result.getResp_code().equals("00000000")||result.getResp_code().equals("00000100"))){
+                    FsStorePayment mt=new FsStorePayment();
+                    mt.setPaymentId(storePayment.getPaymentId());
+                    mt.setTradeNo(result.getHf_seq_id());
+                    mt.setAppId(appId);
+                    fsStorePaymentMapper.updateFsStorePayment(mt);
+                    Map<String, Object> resultMap = com.alibaba.fastjson.JSON.parseObject(result.getPay_info(), new TypeReference<Map<String, Object>>() {});
+                    String s = (String) resultMap.get("package");
+                    resultMap.put("packageValue",s);
+                    return R.ok().put("result",resultMap);
+                }
+                else{
+                    return R.error(result.getResp_desc());
+                }
+            }
+        }else {
+            return R.error("新增订单失败!");
         }
+        return R.error("支付失败!");
+
     }
 
 }

+ 20 - 7
fs-service/src/main/java/com/fs/his/service/impl/FsUserInformationCollectionServiceImpl.java

@@ -22,6 +22,8 @@ import com.fs.company.service.ICompanyUserService;
 import com.fs.core.config.WxMaConfiguration;
 import com.fs.core.config.WxPayProperties;
 import com.fs.core.utils.OrderCodeUtils;
+import com.fs.course.domain.FsCoursePlaySourceConfig;
+import com.fs.course.mapper.FsCoursePlaySourceConfigMapper;
 import com.fs.his.config.FsSysConfig;
 import com.fs.his.domain.*;
 import com.fs.his.dto.FsUserInformationCollectionDTO;
@@ -32,6 +34,7 @@ import com.fs.his.param.*;
 import com.fs.his.service.*;
 import com.fs.his.utils.ConfigUtil;
 import com.fs.his.vo.*;
+import com.fs.hisStore.domain.FsPayConfigScrm;
 import com.fs.huifuPay.domain.HuiFuRefundResult;
 import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentDelaytransConfirmrefundRequest;
 import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayRefundRequest;
@@ -80,11 +83,11 @@ import java.util.stream.Collectors;
 public class FsUserInformationCollectionServiceImpl extends ServiceImpl<FsUserInformationCollectionMapper, FsUserInformationCollection> implements IFsUserInformationCollectionService {
     Logger logger= LoggerFactory.getLogger(getClass());
 
-    @Autowired
-    private ISysConfigService configService;
 
     @Autowired
-    SysConfigMapper sysConfigMapper;
+    private FsCoursePlaySourceConfigMapper fsCoursePlaySourceConfigMapper;
+    @Autowired
+    private MerchantAppConfigMapper merchantAppConfigMapper;
 
     @Autowired
     private WxPayProperties wxPayProperties;
@@ -827,12 +830,22 @@ public class FsUserInformationCollectionServiceImpl extends ServiceImpl<FsUserIn
 
         if (payments != null && !payments.isEmpty()) {
             FsStorePayment payment = payments.get(0);
-            String json = configService.selectConfigByKey("his.pay");
             if (payment.getPayMode().equals("wx")) {
                 WxPayConfig payConfig = new WxPayConfig();
-                SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
-                FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
-                payConfig.setAppId(fsPayConfig.getAppId());
+                if (StringUtils.isBlank(payment.getAppId())) {
+                    throw new IllegalArgumentException("appId不能为空");
+                }
+                FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(payment.getAppId());
+                if (fsCoursePlaySourceConfig == null) {
+                    throw new CustomException("未找到appId对应的小程序配置: " + payment.getAppId());
+                }
+                Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+                if (merchantConfigId == null || merchantConfigId <= 0) {
+                    throw new CustomException("小程序没有配置商户信息");
+                }
+                MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
+                FsPayConfig fsPayConfig = JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
+                payConfig.setAppId(fsCoursePlaySourceConfig.getAppid());
                 payConfig.setMchId(fsPayConfig.getWxMchId());
                 payConfig.setMchKey(fsPayConfig.getWxMchKey());
                 payConfig.setKeyPath(wxPayProperties.getKeyPath());

+ 3 - 0
fs-service/src/main/java/com/fs/hisStore/domain/FsStorePaymentScrm.java

@@ -104,4 +104,7 @@ public class FsStorePaymentScrm extends BaseEntity
     //小程序appId(用于多汇付支付/退款)
     private String appId;
 
+    // 商户配置ID (用于多汇付支付/退款) 切换汇付后需要查询历史汇付配置信息退款
+    private Long merConfigId;
+
 }

+ 4 - 0
fs-service/src/main/java/com/fs/hisStore/param/FsStoreOrderOtherPayParam.java

@@ -17,5 +17,9 @@ public class FsStoreOrderOtherPayParam implements Serializable
     @NotNull(message = "code")
     private String code;
 
+    /**
+     * appId
+     */
+    private String appId;
 
 }

+ 39 - 9
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreAfterSalesScrmServiceImpl.java

@@ -20,6 +20,8 @@ import com.fs.company.service.ICompanyService;
 import com.fs.config.cloud.CloudHostProper;
 import com.fs.core.config.WxPayProperties;
 import com.fs.core.utils.OrderCodeUtils;
+import com.fs.course.domain.FsCoursePlaySourceConfig;
+import com.fs.course.mapper.FsCoursePlaySourceConfigMapper;
 import com.fs.erp.constant.AfterSalesOrderStatusEnum;
 import com.fs.erp.domain.FsJstAftersalePush;
 import com.fs.erp.dto.BaseResponse;
@@ -105,6 +107,12 @@ public class FsStoreAfterSalesScrmServiceImpl implements IFsStoreAfterSalesScrmS
     private ICompanyService companyService;
     @Autowired
     private FsStoreAfterSalesScrmMapper fsStoreAfterSalesMapper;
+
+
+    @Autowired
+    private FsCoursePlaySourceConfigMapper fsCoursePlaySourceConfigMapper;
+    @Autowired
+    private MerchantAppConfigMapper merchantAppConfigMapper;
     @Autowired
     private IFsStoreAfterSalesItemScrmService afterSalesItemService;
     @Autowired
@@ -825,12 +833,25 @@ public class FsStoreAfterSalesScrmServiceImpl implements IFsStoreAfterSalesScrmS
         if(order.getPayMoney().compareTo(BigDecimal.ZERO)==1){
             List<FsStorePaymentScrm> payments=paymentService.selectFsStorePaymentByOrderId(order.getId());
             if(payments!=null){
-                String json = configService.selectConfigByKey("his.pay");
-                FsPayConfigScrm fsPayConfig = JSON.parseObject(json, FsPayConfigScrm.class);
+
                 for(FsStorePaymentScrm payment:payments){
+                    if (StringUtils.isBlank(payment.getAppId())) {
+                        throw new IllegalArgumentException("appId不能为空");
+                    }
+                    FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(payment.getAppId());
+                    if (fsCoursePlaySourceConfig == null) {
+                        throw new CustomException("未找到appId对应的小程序配置: " + payment.getAppId());
+                    }
+                    Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+                    if (merchantConfigId == null || merchantConfigId <= 0) {
+                        throw new CustomException("小程序没有配置商户信息");
+                    }
+                    MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
+                    FsPayConfig fsPayConfig = JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
+
                     if (payment.getPayMode()==null||payment.getPayMode().equals("wx")){
                         WxPayConfig payConfig = new WxPayConfig();
-                        payConfig.setAppId(fsPayConfig.getAppId());
+                        payConfig.setAppId(fsCoursePlaySourceConfig.getAppid());
                         payConfig.setMchId(fsPayConfig.getWxMchId());
                         payConfig.setMchKey(fsPayConfig.getWxMchKey());
                         payConfig.setKeyPath(fsPayConfig.getKeyPath());
@@ -1509,16 +1530,25 @@ public class FsStoreAfterSalesScrmServiceImpl implements IFsStoreAfterSalesScrmS
         if (payments != null && payments.size() > 0) {
             FsStorePaymentScrm payment = payments.get(0);
 //            String json = configService.selectConfigByKey("store.pay");
-            String json = configService.selectConfigByKey("his.pay");
-            FsPayConfigScrm fsPayConfig = JSON.parseObject(json, FsPayConfigScrm.class);
+            if (StringUtils.isBlank(payment.getAppId())) {
+                throw new IllegalArgumentException("appId不能为空");
+            }
+            FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(payment.getAppId());
+            if (fsCoursePlaySourceConfig == null) {
+                throw new CustomException("未找到appId对应的小程序配置: " + payment.getAppId());
+            }
+            Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+            if (merchantConfigId == null || merchantConfigId <= 0) {
+                throw new CustomException("小程序没有配置商户信息");
+            }
+            MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
+            FsPayConfig fsPayConfig = JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
             if (payment.getPayMode().equals("wx")) {
                 WxPayConfig payConfig = new WxPayConfig();
-                //SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
-                //FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
-                payConfig.setAppId(fsPayConfig.getAppId());
+                payConfig.setAppId(payment.getAppId());
                 payConfig.setMchId(fsPayConfig.getWxMchId());
                 payConfig.setMchKey(fsPayConfig.getWxMchKey());
-                payConfig.setKeyPath(wxPayProperties.getKeyPath());
+                payConfig.setKeyPath(fsPayConfig.getKeyPath());
                 payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                 payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                 wxPayService.setConfig(payConfig);

+ 116 - 47
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java

@@ -19,7 +19,6 @@ import com.fs.api.param.OrderListParam;
 import com.fs.api.vo.OrderListVO;
 import com.fs.api.vo.ProductListVO;
 import com.fs.common.config.FSSysConfig;
-import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.entity.SysDictData;
 import com.fs.common.core.redis.RedisCache;
@@ -33,7 +32,6 @@ import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.IpUtil;
 import com.fs.common.utils.ServletUtils;
 import com.fs.common.utils.StringUtils;
-import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.common.utils.ip.IpUtils;
 import com.fs.common.utils.spring.SpringUtils;
 import com.fs.company.domain.*;
@@ -48,8 +46,10 @@ import com.fs.config.cloud.CloudHostProper;
 import com.fs.core.config.WxMaConfiguration;
 import com.fs.core.config.WxPayProperties;
 import com.fs.core.utils.OrderCodeUtils;
+import com.fs.course.domain.FsCoursePlaySourceConfig;
 import com.fs.course.dto.FsOrderDeliveryNoteDTO;
 import com.fs.course.dto.OrderOpenIdTransDTO;
+import com.fs.course.mapper.FsCoursePlaySourceConfigMapper;
 import com.fs.erp.domain.*;
 import com.fs.erp.dto.*;
 import com.fs.erp.dto.df.*;
@@ -74,7 +74,6 @@ import com.fs.his.utils.ConfigUtil;
 import com.fs.his.vo.FsInquiryOrderVO;
 import com.fs.his.vo.FsStoreOrderAmountScrmStatsVo;
 import com.fs.his.vo.FsStoreOrderExcelVO;
-import com.fs.his.vo.*;
 import com.fs.his.vo.FsPrescribeVO;
 import com.fs.hisStore.config.FsErpConfig;
 import com.fs.hisStore.constants.ErpTypeEnum;
@@ -83,7 +82,6 @@ import com.fs.hisStore.mapper.*;
 import com.fs.hisStore.param.*;
 import com.fs.hisStore.vo.*;
 import com.fs.hisStore.vo.FsStoreOrderErpExportVO;
-import com.fs.hisStore.vo.FsStoreOrderExportVO;
 import com.fs.hisStore.vo.FsStoreOrderItemVO;
 import com.fs.hisStore.vo.FsStoreOrderVO;
 import com.fs.hisStore.vo.FsStoreProductAttrValueVO;
@@ -151,7 +149,6 @@ import javax.annotation.PostConstruct;
 import java.lang.reflect.Field;
 import java.math.BigDecimal;
 import java.nio.charset.Charset;
-import java.sql.SQLException;
 import java.sql.Timestamp;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
@@ -166,7 +163,6 @@ import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
 import static com.fs.his.utils.PhoneUtil.decryptPhone;
-import static com.fs.his.utils.PhoneUtil.encryptPhone;
 import static com.fs.hisStore.constants.StoreConstants.DELIVERY;
 
 /**
@@ -179,7 +175,6 @@ import static com.fs.hisStore.constants.StoreConstants.DELIVERY;
 @EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
 @Slf4j
 public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
-    private static final String STORE_PAY_CONF = "his.pay";
 
     Logger logger = LoggerFactory.getLogger(getClass());
     @Autowired
@@ -188,6 +183,10 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
     @Autowired
     private CompanyUserUserMapper companyUserUserMapper;
     @Autowired
+    private FsCoursePlaySourceConfigMapper fsCoursePlaySourceConfigMapper;
+    @Autowired
+    private MerchantAppConfigMapper merchantAppConfigMapper;
+    @Autowired
     private IFsStoreOrderStatusScrmService orderStatusService;
     @Autowired
     private FsStoreCartScrmMapper cartMapper;
@@ -1401,7 +1400,6 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
             order.setStatus(OrderInfoEnum.STATUS_2.getValue());
             order.setDeliveryId(deliveryId);
             order.setDeliverySendTime(new Date());
-            order.setUpdateTime(new Date());
 
             fsStoreOrderMapper.updateFsStoreOrder(order);
             orderStatusService.create(order.getId(), OrderLogEnum.DELIVERY_GOODS.getValue(),
@@ -2460,9 +2458,12 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
                 fsStoreAfterSalesParam.setProductList(productParams);
 
                 return fsStoreAfterSalesScrmService.applyForAfterSales(order.getUserId(),fsStoreAfterSalesParam);
-            } else{
-                jSTOrderService.refundUpdateScrm(request);
-            }
+            }/* else{
+                ErpRefundOrder order1=new ErpRefundOrder();
+                order1.setOrderCode(order.getOrderCode());
+                order1.setDeliverySn(order.getDeliverySn());
+                erpOrderService.refundOrder(order1);
+            }*/
         }
         order.setStatus(-2);
         order.setRefundPrice(order.getPayMoney());
@@ -2484,13 +2485,24 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
             //将钱退还给用户
             List<FsStorePaymentScrm> payments = paymentService.selectFsStorePaymentByOrderId(order.getId());
             if (payments != null) {
-                String json = configService.selectConfigByKey("his.pay");
-
-                FsPayConfigScrm fsPayConfig = JSON.parseObject(json, FsPayConfigScrm.class);
                 for (FsStorePaymentScrm payment : payments) {
+                    if (StringUtils.isBlank(payment.getAppId())) {
+                        throw new IllegalArgumentException("appId不能为空");
+                    }
+                    FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(payment.getAppId());
+                    if (fsCoursePlaySourceConfig == null) {
+                        throw new CustomException("未找到appId对应的小程序配置: " + payment.getAppId());
+                    }
+                    Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+                    if (merchantConfigId == null || merchantConfigId <= 0) {
+                        throw new CustomException("小程序没有配置商户信息");
+                    }
+                    MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
+                    FsPayConfig fsPayConfig = JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
+
                     if (payment.getPayMode() == null || payment.getPayMode().equals("wx")) {
                         WxPayConfig payConfig = new WxPayConfig();
-                        payConfig.setAppId(fsPayConfig.getAppId());
+                        payConfig.setAppId(payment.getAppId());
                         payConfig.setMchId(fsPayConfig.getWxMchId());
                         payConfig.setMchKey(fsPayConfig.getWxMchKey());
                         payConfig.setKeyPath(fsPayConfig.getKeyPath());
@@ -3135,6 +3147,7 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
 
             //获取运费模板区域列表按照城市排序
             List<FsShippingTemplatesRegionScrm> shippingTemplatesRegionList = shippingTemplatesRegionService.selectFsShippingTemplatesRegionListByTempIdsAndCityIds(StringUtils.join(tempIds, ","), StringUtils.join(citys, ","));
+
             boolean isQg = false;
 
             if (CollectionUtils.isEmpty(shippingTemplatesRegionList)&&CollectionUtils.isNotEmpty(shippingTemplatesList)&&shippingTemplatesList.size()<2) {
@@ -4234,7 +4247,7 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
                 else if(param.getPayType().equals(2)){
                     order.setPayType("2");
                     BigDecimal payMoney=order.getPayPrice().multiply(new BigDecimal(storeConfig.getPayRate())).divide(new BigDecimal(100));
-                    payMoney=new BigDecimal(payMoney.setScale(0, BigDecimal.ROUND_HALF_UP).longValue());
+                    payMoney=new BigDecimal(payMoney.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                     // 如果小程序需要支付的金额小于0.01元,不能走物流代收,让走货到付款 xgb
                     if (payMoney.compareTo(new BigDecimal("0.01")) < 0) {
                         return R.error("物流代收计算支付金额为0,不允许选择物流代收");
@@ -4266,14 +4279,25 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
                 }
                 this.updateFsStoreOrder(order);
             }
-            String payCode =  OrderCodeUtils.getOrderSn();
+            String payCode = IdUtil.getSnowflake(0, 0).nextIdStr();
             if((order.getPayType().equals("1")||order.getPayType().equals("2")||order.getPayType().equals("3")) && order.getPayMoney().compareTo(new BigDecimal(0))>0){
-                String json = configService.selectConfigByKey(STORE_PAY_CONF);
-                FsPayConfigScrm fsPayConfig = JSON.parseObject(json, FsPayConfigScrm.class);
+                if (StringUtils.isBlank(param.getAppId())) {
+                    throw new IllegalArgumentException("appId不能为空");
+                }
+                FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(param.getAppId());
+                if (fsCoursePlaySourceConfig == null) {
+                    throw new CustomException("未找到appId对应的小程序配置: " + param.getAppId());
+                }
+                Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+                if (merchantConfigId == null || merchantConfigId <= 0) {
+                    throw new CustomException("小程序没有配置商户信息");
+                }
+                MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
+                FsPayConfig fsPayConfig = JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
                 FsStorePaymentScrm storePayment=new FsStorePaymentScrm();
                 storePayment.setCompanyId(order.getCompanyId());
                 storePayment.setCompanyUserId(order.getCompanyUserId());
-                storePayment.setPayMode(fsPayConfig.getType());
+                storePayment.setPayMode(merchantAppConfig.getMerchantType());
                 storePayment.setStatus(0);
                 storePayment.setPayCode(payCode);
                 storePayment.setPayMoney(order.getPayMoney());
@@ -4285,10 +4309,11 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
                 storePayment.setUserId(user.getUserId());
                 storePayment.setBusinessOrderId(order.getId().toString());
                 storePayment.setOrderId(order.getId());
-                storePayment.setAppId(fsPayConfig.getAppId() == null ? "" : fsPayConfig.getAppId());
+                storePayment.setAppId(fsCoursePlaySourceConfig.getAppid() == null ? "" : fsCoursePlaySourceConfig.getAppid());
+                storePayment.setMerConfigId(merchantAppConfig.getId());
                 fsStorePaymentMapper.insertFsStorePayment(storePayment);
 
-                if (fsPayConfig.getType().equals("hf")){
+                if (merchantAppConfig.getMerchantType().equals("hf")){
                     HuiFuCreateOrder o = new HuiFuCreateOrder();
                     o.setTradeType("T_MINIAPP");
                     o.setOpenid(user.getMaOpenId());
@@ -4297,7 +4322,8 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
                     o.setGoodsDesc("商城订单支付");
                     o.setAppId(param.getAppId());
                     try {
-                        HuiFuUtils.doDiv(o,order.getCompanyId());
+
+                        HuiFuUtils.doDiv(o,order.getCompanyId(), storePayment.getMerConfigId());
                         //存储分账明细
                         HuiFuUtils.saveDivItem(o, order.getOrderCode(), storePayment.getPayCode());
                     } catch (Exception e) {
@@ -4320,9 +4346,9 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
                     else{
                         return R.error(result.getResp_desc());
                     }
-                }else  if (fsPayConfig.getType().equals("wx")){
+                }else  if (merchantAppConfig.getMerchantType().equals("wx")){
                     WxPayConfig payConfig = new WxPayConfig();
-                    payConfig.setAppId(fsPayConfig.getAppId());
+                    payConfig.setAppId(fsCoursePlaySourceConfig.getAppid());
                     payConfig.setMchId(fsPayConfig.getWxMchId());
                     payConfig.setMchKey(fsPayConfig.getWxMchKey());
                     payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
@@ -4405,14 +4431,25 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
             if(!order.getIsPayRemain().equals(0)){
                 return R.error("此订单已支付");
             }
-            String payCode =  OrderCodeUtils.getOrderSn();
-            String json = configService.selectConfigByKey(STORE_PAY_CONF);
-            FsPayConfigScrm fsPayConfig = JSON.parseObject(json, FsPayConfigScrm.class);
+            String payCode = IdUtil.getSnowflake(0, 0).nextIdStr();
+            if (StringUtils.isBlank(param.getAppId())) {
+                throw new IllegalArgumentException("appId不能为空");
+            }
+            FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(param.getAppId());
+            if (fsCoursePlaySourceConfig == null) {
+                throw new CustomException("未找到appId对应的小程序配置: " + param.getAppId());
+            }
+            Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+            if (merchantConfigId == null || merchantConfigId <= 0) {
+                throw new CustomException("小程序没有配置商户信息");
+            }
+            MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
+            FsPayConfig fsPayConfig = JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
             FsStorePaymentScrm storePayment=new FsStorePaymentScrm();
             storePayment.setCompanyId(order.getCompanyId());
             storePayment.setCompanyUserId(order.getCompanyUserId());
             storePayment.setStatus(0);
-            storePayment.setPayMode(fsPayConfig.getType());
+            storePayment.setPayMode(merchantAppConfig.getMerchantType());
             storePayment.setPayCode(payCode);
             storePayment.setPayMoney(order.getPayDelivery());
             storePayment.setCreateTime(new Date());
@@ -4424,9 +4461,11 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
             storePayment.setBusinessOrderId(order.getId().toString());
             storePayment.setOrderId(order.getId());
             storePayment.setIsPayRemain(1);
+            storePayment.setMerConfigId(merchantAppConfig.getId());
+            storePayment.setAppId(param.getAppId());
             fsStorePaymentMapper.insertFsStorePayment(storePayment);
 
-            if (fsPayConfig.getType().equals("hf")){
+            if (merchantAppConfig.getMerchantType().equals("hf")){
                 HuiFuCreateOrder o = new HuiFuCreateOrder();
                 o.setTradeType("T_MINIAPP");
                 o.setOpenid(user.getMaOpenId());
@@ -4449,10 +4488,10 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
                 else{
                     return R.error(result.getResp_desc());
                 }
-            }else  if (fsPayConfig.getType().equals("wx")){
+            }else  if (merchantAppConfig.getMerchantType().equals("wx")){
                 //创建微信订单
                 WxPayConfig payConfig = new WxPayConfig();
-                payConfig.setAppId(fsPayConfig.getAppId());
+                payConfig.setAppId(fsCoursePlaySourceConfig.getAppid());
                 payConfig.setMchId(fsPayConfig.getWxMchId());
                 payConfig.setMchKey(fsPayConfig.getWxMchKey());
                 payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
@@ -4522,16 +4561,27 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
                 return R.error("正在支付中...");
             }
 
-            String json = configService.selectConfigByKey(STORE_PAY_CONF);
-            FsPayConfigScrm fsPayConfig = JSON.parseObject(json, FsPayConfigScrm.class);
-            String payCode =  OrderCodeUtils.getOrderSn();
+            if (StringUtils.isBlank(param.getAppId())) {
+                throw new IllegalArgumentException("appId不能为空");
+            }
+            FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(param.getAppId());
+            if (fsCoursePlaySourceConfig == null) {
+                throw new CustomException("未找到appId对应的小程序配置: " + param.getAppId());
+            }
+            Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+            if (merchantConfigId == null || merchantConfigId <= 0) {
+                throw new CustomException("小程序没有配置商户信息");
+            }
+            MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
+            FsPayConfig fsPayConfig = JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
+            String payCode = IdUtil.getSnowflake(0, 0).nextIdStr();
             //易宝支付
             FsStorePaymentScrm storePayment=new FsStorePaymentScrm();
             storePayment.setCompanyId(order.getCompanyId());
             storePayment.setCompanyUserId(order.getCompanyUserId());
             storePayment.setStatus(0);
             storePayment.setPayCode(payCode);
-            storePayment.setPayMode(fsPayConfig.getType());
+            storePayment.setPayMode(merchantAppConfig.getMerchantType());
             storePayment.setPayMoney(order.getPayMoney());
             storePayment.setCreateTime(new Date());
             storePayment.setPayTypeCode("weixin");
@@ -4541,9 +4591,11 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
             storePayment.setUserId(user.getUserId());
             storePayment.setBusinessOrderId(order.getId().toString());
             storePayment.setOrderId(order.getId());
+            storePayment.setMerConfigId(merchantAppConfig.getId());
+            storePayment.setAppId(param.getAppId());
             fsStorePaymentMapper.insertFsStorePayment(storePayment);
 
-            if (fsPayConfig.getType().equals("hf")){
+            if (merchantAppConfig.getMerchantType().equals("hf")){
                 HuiFuCreateOrder o = new HuiFuCreateOrder();
                 o.setTradeType("T_MINIAPP");
                 o.setOpenid(user.getMaOpenId());
@@ -4566,10 +4618,10 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
                 else{
                     return R.error(result.getResp_desc());
                 }
-            }else  if (fsPayConfig.getType().equals("wx")){
+            }else  if (merchantAppConfig.getMerchantType().equals("wx")){
                 //创建微信订单
                 WxPayConfig payConfig = new WxPayConfig();
-                payConfig.setAppId(fsPayConfig.getAppId());
+                payConfig.setAppId(fsCoursePlaySourceConfig.getAppid());
                 payConfig.setMchId(fsPayConfig.getWxMchId());
                 payConfig.setMchKey(fsPayConfig.getWxMchKey());
                 payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
@@ -4623,14 +4675,25 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
         }
         FsUserScrm user=userService.selectFsUserById(order.getUserId());
         if(user!=null){
-            String payCode =  OrderCodeUtils.getOrderSn();
-            String json = configService.selectConfigByKey(STORE_PAY_CONF);
-            FsPayConfigScrm fsPayConfig = JSON.parseObject(json, FsPayConfigScrm.class);
+            String payCode = IdUtil.getSnowflake(0, 0).nextIdStr();
+            if (StringUtils.isBlank(param.getAppId())) {
+                throw new IllegalArgumentException("appId不能为空");
+            }
+            FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(param.getAppId());
+            if (fsCoursePlaySourceConfig == null) {
+                throw new CustomException("未找到appId对应的小程序配置: " + param.getAppId());
+            }
+            Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+            if (merchantConfigId == null || merchantConfigId <= 0) {
+                throw new CustomException("小程序没有配置商户信息");
+            }
+            MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
+            FsPayConfig fsPayConfig = JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
             FsStorePaymentScrm storePayment=new FsStorePaymentScrm();
             storePayment.setCompanyId(order.getCompanyId());
             storePayment.setCompanyUserId(order.getCompanyUserId());
             storePayment.setStatus(0);
-            storePayment.setPayMode(fsPayConfig.getType());
+            storePayment.setPayMode(merchantAppConfig.getMerchantType());
             storePayment.setPayCode(payCode);
             storePayment.setPayMoney(order.getPayDelivery());
             storePayment.setCreateTime(new Date());
@@ -4642,9 +4705,11 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
             storePayment.setBusinessOrderId(order.getId().toString());
             storePayment.setOrderId(order.getId());
             storePayment.setIsPayRemain(1);
+            storePayment.setMerConfigId(merchantAppConfig.getId());
+            storePayment.setAppId(param.getAppId());
             fsStorePaymentMapper.insertFsStorePayment(storePayment);
 
-            if (fsPayConfig.getType().equals("hf")){
+            if (merchantAppConfig.getMerchantType().equals("hf")){
                 HuiFuCreateOrder o = new HuiFuCreateOrder();
                 o.setTradeType("T_MINIAPP");
                 o.setOpenid(user.getMaOpenId());
@@ -4668,9 +4733,9 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
                 else{
                     return R.error(result.getResp_desc());
                 }
-            }else if(fsPayConfig.getType().equals("wx")) {
+            }else if(merchantAppConfig.getMerchantType().equals("wx")) {
                 WxPayConfig payConfig = new WxPayConfig();
-                payConfig.setAppId(fsPayConfig.getAppId());
+                payConfig.setAppId(fsCoursePlaySourceConfig.getAppid());
                 payConfig.setMchId(fsPayConfig.getWxMchId());
                 payConfig.setMchKey(fsPayConfig.getWxMchKey());
                 payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
@@ -4750,7 +4815,11 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
                     // 物流代收
                     order.setPayType("2");
                     BigDecimal payMoney=order.getPayPrice().multiply(new BigDecimal(storeConfig.getPayRate())).divide(new BigDecimal(100));
-                    payMoney=new BigDecimal(payMoney.setScale(0, BigDecimal.ROUND_HALF_UP).longValue());
+                    payMoney=new BigDecimal(payMoney.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
+                    // 如果小程序需要支付的金额小于0.01元,不能走物流代收,让走货到付款 xgb
+                    if (payMoney.compareTo(new BigDecimal("0.01")) < 0) {
+                        return R.error("物流代收计算支付金额为0,不允许选择物流代收");
+                    }
                     order.setPayDelivery(order.getPayPrice().subtract(payMoney));
                     order.setPayMoney(payMoney);
                 }

+ 98 - 45
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStorePaymentScrmServiceImpl.java

@@ -15,18 +15,19 @@ import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
 import cn.binarywang.wx.miniapp.bean.shop.request.shipping.*;
 import cn.hutool.core.util.IdUtil;
 import cn.hutool.json.JSONUtil;
-import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.TypeReference;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.common.annotation.DataScope;
-import com.fs.common.config.FSSysConfig;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.redis.RedisCache;
+import com.fs.common.exception.CustomException;
 import com.fs.common.utils.CloudHostUtils;
 import com.fs.common.utils.DateUtils;
+import com.fs.common.utils.ServletUtils;
 import com.fs.common.utils.StringUtils;
+import com.fs.common.utils.ip.IpUtils;
 import com.fs.company.domain.Company;
 import com.fs.company.domain.CompanyUser;
 import com.fs.company.mapper.CompanyConfigMapper;
@@ -35,17 +36,17 @@ import com.fs.company.service.ICompanyUserService;
 import com.fs.core.config.WxMaConfiguration;
 import com.fs.core.utils.OrderCodeUtils;
 import com.fs.course.config.RedPacketConfig;
+import com.fs.course.domain.FsCoursePlaySourceConfig;
 import com.fs.course.domain.FsCourseRedPacketLog;
+import com.fs.course.mapper.FsCoursePlaySourceConfigMapper;
 import com.fs.course.mapper.FsCourseRedPacketLogMapper;
 import com.fs.course.service.IFsCourseRedPacketLogService;
-import com.fs.his.config.FsSysConfig;
-import com.fs.his.domain.FsUser;
-import com.fs.his.domain.FsUserWx;
+import com.fs.his.domain.*;
 import com.fs.his.mapper.FsUserWxMapper;
+import com.fs.his.mapper.MerchantAppConfigMapper;
 import com.fs.his.service.IFsUserService;
 import com.fs.his.service.IFsUserWxService;
 import com.fs.his.utils.ConfigUtil;
-import com.fs.his.utils.HttpUtil;
 import com.fs.hisStore.config.StoreConfig;
 import com.fs.hisStore.enums.SysConfigEnum;
 import com.fs.hisStore.param.*;
@@ -54,14 +55,12 @@ import com.fs.huifuPay.domain.HuiFuCreateOrder;
 import com.fs.huifuPay.domain.HuifuCreateOrderResult;
 import com.fs.huifuPay.sdk.opps.core.utils.HuiFuUtils;
 import com.fs.huifuPay.service.HuiFuService;
-import com.fs.pay.pay.config.PayConfig;
 import com.fs.pay.pay.dto.WxJspayDTO;
 import com.fs.hisStore.vo.FsStorePaymentStatisticsVO;
 import com.fs.system.oss.CloudStorageService;
 import com.fs.system.oss.OSSFactory;
 import com.fs.system.service.ISysConfigService;
 import com.fs.utils.TwelveDigitSnowflake;
-import com.fs.wx.miniapp.config.WxMaProperties;
 import com.fs.hisStore.domain.FsUserScrm;
 import com.fs.hisStore.service.IFsUserScrmService;
 import com.fs.hisStore.vo.FsStorePaymentVO;
@@ -70,6 +69,7 @@ import com.fs.ybPay.domain.CreateWxOrderResult;
 import com.github.binarywang.wxpay.bean.notify.SignatureHeader;
 import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
 import com.github.binarywang.wxpay.bean.notify.WxPayTransferBatchesNotifyV3Result;
+import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
 import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
 import com.github.binarywang.wxpay.bean.transfer.*;
 import com.github.binarywang.wxpay.config.WxPayConfig;
@@ -77,8 +77,6 @@ import com.github.binarywang.wxpay.exception.WxPayException;
 import com.github.binarywang.wxpay.service.TransferService;
 import com.github.binarywang.wxpay.service.WxPayService;
 import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
-import com.google.common.reflect.TypeToken;
-import com.google.gson.Gson;
 import lombok.extern.slf4j.Slf4j;
 import me.chanjar.weixin.common.error.WxErrorException;
 import org.slf4j.Logger;
@@ -105,11 +103,12 @@ public class FsStorePaymentScrmServiceImpl implements IFsStorePaymentScrmService
 {
     Logger logger = LoggerFactory.getLogger(getClass());
     @Autowired
-    private WxMaProperties properties;
+    private WxPayService wxPayService;
+
     @Autowired
-    private IPayService payService;
+    private FsCoursePlaySourceConfigMapper fsCoursePlaySourceConfigMapper;
     @Autowired
-    private FSSysConfig sysConfig;
+    private MerchantAppConfigMapper merchantAppConfigMapper;
     @Autowired
     private FsStorePaymentScrmMapper fsStorePaymentMapper;
     @Autowired
@@ -886,7 +885,19 @@ public class FsStorePaymentScrmServiceImpl implements IFsStorePaymentScrmService
                 return R.error("注册失败客服已停用,或不存在!");
             }
         }
-
+        if (StringUtils.isBlank(param.getAppId())) {
+            throw new IllegalArgumentException("appId不能为空");
+        }
+        FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(param.getAppId());
+        if (fsCoursePlaySourceConfig == null) {
+            throw new CustomException("未找到appId对应的小程序配置: " + param.getAppId());
+        }
+        Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+        if (merchantConfigId == null || merchantConfigId <= 0) {
+            throw new CustomException("小程序没有配置商户信息");
+        }
+        MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
+        FsPayConfig fsPayConfig = com.hc.openapi.tool.fastjson.JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
         //生成支付流水
         String orderSn = IdUtil.getSnowflake(0, 0).nextIdStr();
 
@@ -924,40 +935,82 @@ public class FsStorePaymentScrmServiceImpl implements IFsStorePaymentScrmService
         storePayment.setRemark(StringUtils.isNotBlank(param.getRemark()) ? param.getRemark() : "商城收款订单支付");
         storePayment.setOpenId(openId);
         storePayment.setUserId(user.getUserId());
-        storePayment.setPayMode("hf");//目前微信收款仅支持汇付
-        storePayment.setAppId(param.getAppId());
-        fsStorePaymentMapper.insertFsStorePayment(storePayment);
 
-        //汇付支付
-        HuiFuCreateOrder o = new HuiFuCreateOrder();
-        o.setTradeType("T_MINIAPP");
-        o.setOpenid(openId);
-        o.setReqSeqId("payment-"+storePayment.getPayCode());
-        o.setTransAmt(storePayment.getPayMoney().toString());
-        o.setGoodsDesc("商城订单支付");
-        o.setAppId(param.getAppId());
-        //公司分账
-        try {
-            HuiFuUtils.doDiv(o,company.getCompanyId());
-            //存储分账明细
-            HuiFuUtils.saveDivItem(o, storePayment.getPayCode(), storePayment.getPayCode());
-        } catch (Exception e) {
-            logger.error("-------------微信收款分账出错:{}", e.getMessage());
-        }
-        HuifuCreateOrderResult result = huiFuService.createOrder(o);
-        if(result.getResp_code()!=null&&(result.getResp_code().equals("00000000")||result.getResp_code().equals("00000100"))){
-            FsStorePaymentScrm mt=new FsStorePaymentScrm();
-            mt.setPaymentId(storePayment.getPaymentId());
-            mt.setTradeNo(result.getHf_seq_id());
-            fsStorePaymentMapper.updateFsStorePayment(mt);
-            Map<String, Object> resultMap = JSON.parseObject(result.getPay_info(), new TypeReference<Map<String, Object>>() {});
-            String s = (String) resultMap.get("package");
-            resultMap.put("packageValue",s);
-            return R.ok().put("result",resultMap);
+        if (merchantAppConfig.getMerchantType().equals("wx")){
+            storePayment.setPayMode("wx");
+        }else if (merchantAppConfig.getMerchantType().equals("hf")) {
+            storePayment.setPayMode("hf");
         }
-        else{
-            return R.error(result.getResp_desc());
+        storePayment.setAppId(param.getAppId());
+        storePayment.setMerConfigId(merchantAppConfig.getId());
+        if (fsStorePaymentMapper.insertFsStorePayment(storePayment) > 0) {
+            if (merchantAppConfig.getMerchantType().equals("wx")) {
+                //创建微信订单
+                WxPayConfig payConfig = new WxPayConfig();
+                payConfig.setAppId(appId);
+                payConfig.setMchId(fsPayConfig.getWxMchId());
+                payConfig.setMchKey(fsPayConfig.getWxMchKey());
+                payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
+                payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));
+                payConfig.setKeyPath(null);
+                payConfig.setNotifyUrl(fsPayConfig.getNotifyUrlScrm());
+                wxPayService.setConfig(payConfig);
+                WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
+                orderRequest.setOpenid(openId);//公众号支付提供用户openid
+                orderRequest.setBody("收款支付");
+                orderRequest.setOutTradeNo("payment-" + storePayment.getPayCode());
+                orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(storePayment.getPayMoney().toString()));//测试
+                //orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(money));//测试
+                orderRequest.setTradeType("JSAPI");
+                orderRequest.setSpbillCreateIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
+                //调用统一下单接口,获取"预支付交易会话标识"
+                try {
+                    WxPayMpOrderResult orderResult = wxPayService.createOrder(orderRequest);
+                    return R.ok().put("result", orderResult).put("type", "wx").put("isPay", 0);
+                } catch (WxPayException e) {
+                    e.printStackTrace();
+                    throw new CustomException("支付失败" + e.getMessage());
+                }
+            } else if (merchantAppConfig.getMerchantType().equals("hf")) {
+
+                //汇付支付
+                HuiFuCreateOrder o = new HuiFuCreateOrder();
+                o.setTradeType("T_MINIAPP");
+                o.setOpenid(openId);
+                o.setReqSeqId("payment-"+storePayment.getPayCode());
+                o.setTransAmt(storePayment.getPayMoney().toString());
+                o.setGoodsDesc("商城订单支付");
+                o.setAppId(appId);
+                //公司分账
+                try {
+                    HuiFuUtils.doDiv(o,company.getCompanyId(), storePayment.getMerConfigId());
+                    //存储分账明细
+                    HuiFuUtils.saveDivItem(o, storePayment.getPayCode(), storePayment.getPayCode());
+                } catch (Exception e) {
+                    logger.error("-------------微信收款分账出错:{}", e.getMessage());
+                }
+                HuifuCreateOrderResult result = huiFuService.createOrder(o);
+
+                if(result.getResp_code()!=null&&(result.getResp_code().equals("00000000")||result.getResp_code().equals("00000100"))){
+                    FsStorePaymentScrm mt=new FsStorePaymentScrm();
+                    mt.setPaymentId(storePayment.getPaymentId());
+                    mt.setTradeNo(result.getHf_seq_id());
+                    mt.setAppId(appId);
+                    fsStorePaymentMapper.updateFsStorePayment(mt);
+                    Map<String, Object> resultMap = com.alibaba.fastjson.JSON.parseObject(result.getPay_info(), new TypeReference<Map<String, Object>>() {});
+                    String s = (String) resultMap.get("package");
+                    resultMap.put("packageValue",s);
+                    return R.ok().put("result",resultMap);
+                }
+                else{
+                    return R.error(result.getResp_desc());
+                }
+            }
+        }else {
+            return R.error("新增订单失败!");
         }
+        return R.error("支付失败!");
+
     }
 
     @Override

+ 24 - 17
fs-service/src/main/java/com/fs/huifuPay/sdk/opps/core/utils/HuiFuUtils.java

@@ -6,28 +6,22 @@ import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.spring.SpringUtils;
 import com.fs.company.domain.CompanyDivItem;
-import com.fs.company.mapper.CompanyDivConfigMapper;
 import com.fs.company.param.CompanyAcctInfo;
 import com.fs.company.service.ICompanyDivConfigService;
 import com.fs.company.service.ICompanyDivItemService;
-import com.fs.company.service.impl.CompanyDivConfigServiceImpl;
 import com.fs.company.vo.CompanyDivConfigVo;
-import com.fs.his.domain.FsPackageOrder;
-import com.fs.his.domain.FsPayConfig;
-import com.fs.his.domain.FsStoreOrder;
-import com.fs.his.domain.FsStorePayment;
+import com.fs.course.domain.FsCoursePlaySourceConfig;
+import com.fs.course.mapper.FsCoursePlaySourceConfigMapper;
+import com.fs.his.domain.*;
 import com.fs.his.mapper.FsStorePaymentMapper;
+import com.fs.his.mapper.MerchantAppConfigMapper;
 import com.fs.hisStore.domain.FsStorePaymentScrm;
 import com.fs.hisStore.mapper.FsStorePaymentScrmMapper;
 import com.fs.huifuPay.domain.HuiFuConfirmOrder;
 import com.fs.huifuPay.domain.HuiFuCreateOrder;
 import com.fs.huifuPay.domain.HuiFuQueryOrderResult;
 import com.fs.huifuPay.service.HuiFuService;
-import com.fs.system.domain.SysConfig;
-import com.fs.system.mapper.SysConfigMapper;
-import com.google.gson.Gson;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
@@ -46,12 +40,19 @@ public class HuiFuUtils {
      *
      * @param huiFuCreateOrder
      * @param companyId
+     * @param merConfigId
      */
-    public static void doDiv(HuiFuCreateOrder huiFuCreateOrder, Long companyId) throws Exception {
+    public static void doDiv(HuiFuCreateOrder huiFuCreateOrder, Long companyId, Long merConfigId) throws Exception {
         //默认汇付账户
-        SysConfigMapper sysConfigMapper = SpringUtils.getBean(SysConfigMapper.class);
-        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
-        FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
+        FsCoursePlaySourceConfigMapper fsCoursePlaySourceConfigMapper = SpringUtils.getBean(FsCoursePlaySourceConfigMapper.class);
+        MerchantAppConfigMapper merchantAppConfigMapper = SpringUtils.getBean(MerchantAppConfigMapper.class);
+        FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(huiFuCreateOrder.getAppId());
+        Long merConfigIds = fsCoursePlaySourceConfig.getMerchantConfigId();
+        if(merConfigId!=null){
+            merConfigIds=merConfigId;
+        }
+        MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(merConfigIds);
+        FsPayConfig fsPayConfig = JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
         String defaultHuifuId = fsPayConfig.getHuifuId();
         //查询是否开启分账
         if (companyId != null) {
@@ -230,9 +231,15 @@ public class HuiFuUtils {
             if (payPrice.compareTo(reMoney) > 0) {
                 //部分退款
                 if (companyDivItem != null) {
-                    SysConfigMapper sysConfigMapper = SpringUtils.getBean(SysConfigMapper.class);
-                    SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
-                    FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
+                    FsCoursePlaySourceConfigMapper fsCoursePlaySourceConfigMapper = SpringUtils.getBean(FsCoursePlaySourceConfigMapper.class);
+                    MerchantAppConfigMapper merchantAppConfigMapper = SpringUtils.getBean(MerchantAppConfigMapper.class);
+                    FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(payment.getAppId());
+                    Long merConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+                    if(payment.getMerConfigId()!=null){
+                        merConfigId=payment.getMerConfigId();
+                    }
+                    MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(merConfigId);
+                    FsPayConfig fsPayConfig = JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
                     String defaultHuiFuId = fsPayConfig.getHuifuId(); //默认汇付id
 
                     String detail = companyDivItem.getDetail();

+ 36 - 50
fs-service/src/main/java/com/fs/huifuPay/service/impl/HuiFuServiceImpl.java

@@ -5,9 +5,13 @@ import com.alibaba.fastjson.JSONObject;
 import com.fs.common.exception.CustomException;
 import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.spring.SpringUtils;
+import com.fs.course.domain.FsCoursePlaySourceConfig;
+import com.fs.course.mapper.FsCoursePlaySourceConfigMapper;
 import com.fs.his.domain.FsHfpayConfig;
 import com.fs.his.domain.FsPayConfig;
+import com.fs.his.domain.MerchantAppConfig;
 import com.fs.his.mapper.FsHfpayConfigMapper;
+import com.fs.his.mapper.MerchantAppConfigMapper;
 import com.fs.huifuPay.domain.*;
 import com.fs.huifuPay.sdk.opps.core.config.MerConfig;
 import com.fs.huifuPay.sdk.opps.core.request.*;
@@ -20,6 +24,7 @@ import com.google.gson.Gson;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
@@ -35,7 +40,10 @@ import static com.fs.huifuPay.demo.init.BaseCommon.doInit;
 public class HuiFuServiceImpl implements HuiFuService {
     FsPayConfig config;
     Logger logger= LoggerFactory.getLogger(getClass());
-
+    @Autowired
+    private FsCoursePlaySourceConfigMapper fsCoursePlaySourceConfigMapper;
+    @Autowired
+    private MerchantAppConfigMapper merchantAppConfigMapper;
     @Override
     public HuifuCreateOrderResult createOrder(HuiFuCreateOrder order) {
         logger.info("汇付传参HuiFuCreateOrder==============>{}",order);
@@ -43,15 +51,8 @@ public class HuiFuServiceImpl implements HuiFuService {
         try {
 
             if (order.getAppId() != null) {
-                FsHfpayConfigMapper fsHfpayConfigMapper = SpringUtils.getBean(FsHfpayConfigMapper.class);
-                FsHfpayConfig fsHfpayConfig = fsHfpayConfigMapper.selectByAppId(order.getAppId());
-                if (fsHfpayConfig != null) {
-                    //多汇付支付获取配置
-                    doInit(getMerConfig(fsHfpayConfig));
-                } else {
-                    //多小程序
-                    doInit(getMerConfig());
-                }
+                //多小程序
+                doInit(getMerConfig(order.getAppId()));
             } else {
                 doInit(getMerConfig());
             }
@@ -132,15 +133,8 @@ public class HuiFuServiceImpl implements HuiFuService {
     @Override
     public HuiFuQueryOrderResult queryOrder(V2TradePaymentScanpayQueryRequest request) throws Exception{
         if (request.getAppId() != null) {
-            FsHfpayConfigMapper fsHfpayConfigMapper = SpringUtils.getBean(FsHfpayConfigMapper.class);
-            FsHfpayConfig fsHfpayConfig = fsHfpayConfigMapper.selectByAppId(request.getAppId());
-            if (fsHfpayConfig != null) {
-                //多汇付支付获取配置
-                doInit(getMerConfig(fsHfpayConfig));
-            } else {
-                //多小程序
-                doInit(getMerConfig());
-            }
+            //多汇付支付获取配置
+            doInit(getMerConfig(request.getAppId()));
         } else {
             doInit(getMerConfig());
         }
@@ -164,19 +158,7 @@ public class HuiFuServiceImpl implements HuiFuService {
     public HuiFuRefundResult refund(V2TradePaymentScanpayRefundRequest request) {
         HuiFuRefundResult huiFuRefundResult=null;
         try {
-            if (request.getAppId() != null) {
-                FsHfpayConfigMapper fsHfpayConfigMapper = SpringUtils.getBean(FsHfpayConfigMapper.class);
-                FsHfpayConfig fsHfpayConfig = fsHfpayConfigMapper.selectByAppId(request.getAppId());
-                if (fsHfpayConfig != null) {
-                    //多汇付支付获取配置
-                    doInit(getMerConfig(fsHfpayConfig));
-                } else {
-                    //多小程序
-                    doInit(getMerConfig());
-                }
-            } else {
-                doInit(getMerConfig());
-            }
+            doInit(getMerConfig(request.getAppId()));
             request.setReqDate(DateTools.getCurrentDateYYYYMMDD());
             Map<String, Object> response = doExecute(request);
             String jsonString = JSONObject.toJSONString(response);
@@ -305,15 +287,8 @@ public class HuiFuServiceImpl implements HuiFuService {
         HuiFuQueryOrderResult result =null;
         try {
             if (order.getAppId() != null) {
-                FsHfpayConfigMapper fsHfpayConfigMapper = SpringUtils.getBean(FsHfpayConfigMapper.class);
-                FsHfpayConfig fsHfpayConfig = fsHfpayConfigMapper.selectByAppId(order.getAppId());
-                if (fsHfpayConfig != null) {
-                    //多汇付支付获取配置
-                    doInit(getMerConfig(fsHfpayConfig));
-                } else {
-                    //多小程序
-                    doInit(getMerConfig());
-                }
+                //多汇付支付获取配置
+                doInit(getMerConfig(order.getAppId()));
             } else {
                 doInit(getMerConfig());
             }
@@ -376,16 +351,27 @@ public class HuiFuServiceImpl implements HuiFuService {
         return merConfig;
     }
 
-    public MerConfig getMerConfig(FsHfpayConfig fsHfpayConfig) {
+    public MerConfig getMerConfig(String appId) {
+        if (StringUtils.isBlank(appId)) {
+            throw new IllegalArgumentException("appId不能为空");
+        }
+        FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(appId);
+        if (fsCoursePlaySourceConfig == null) {
+            throw new CustomException("未找到appId对应的小程序配置: " + appId);
+        }
+        Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+        if (merchantConfigId == null || merchantConfigId <= 0) {
+            throw new CustomException("小程序没有配置商户信息");
+        }
+        MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
+        FsPayConfig fsPayConfig = com.hc.openapi.tool.fastjson.JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
+
         MerConfig merConfig = new MerConfig();
-        merConfig.setProcutId(fsHfpayConfig.getHfProductId());
-        merConfig.setSysId(fsHfpayConfig.getHfSysId());
-        merConfig.setRsaPrivateKey(fsHfpayConfig.getHfRsaPrivateKey());
-        merConfig.setRsaPublicKey(fsHfpayConfig.getHfRsaPublicKey());
-        merConfig.setHuifuId(fsHfpayConfig.getHuifuId());
-
-        FsPayConfig fsPayConfig = new FsPayConfig();
-        BeanUtils.copyProperties(fsHfpayConfig,fsPayConfig);
+        merConfig.setProcutId(fsPayConfig.getHfProductId());
+        merConfig.setSysId(fsPayConfig.getHfSysId());
+        merConfig.setRsaPrivateKey(fsPayConfig.getHfRsaPrivateKey());
+        merConfig.setRsaPublicKey(fsPayConfig.getHfRsaPublicKey());
+        merConfig.setHuifuId(fsPayConfig.getHuifuId());
 
         config = fsPayConfig;
         return merConfig;

+ 5 - 1
fs-service/src/main/java/com/fs/live/service/impl/LiveOrderServiceImpl.java

@@ -3117,7 +3117,11 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
                 else if(param.getPayType().equals(2)){
                     order.setPayType("2");
                     BigDecimal payMoney=order.getPayPrice().multiply(new BigDecimal(storeConfig.getPayRate())).divide(new BigDecimal(100));
-                    payMoney=new BigDecimal(payMoney.setScale(0, BigDecimal.ROUND_HALF_UP).longValue());
+                    payMoney=new BigDecimal(payMoney.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
+                    // 如果小程序需要支付的金额小于0.01元,不能走物流代收,让走货到付款 xgb
+                    if (payMoney.compareTo(new BigDecimal("0.01")) < 0) {
+                        return R.error("物流代收计算支付金额为0,不允许选择物流代收");
+                    }
                     order.setPayDelivery(order.getPayPrice().subtract(payMoney));
                     order.setPayMoney(payMoney);
                 }

+ 22 - 3
fs-service/src/main/java/com/fs/ybPay/service/impl/PayServiceImpl.java

@@ -1,7 +1,13 @@
 package com.fs.ybPay.service.impl;
 
+import com.fs.common.exception.CustomException;
+import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.spring.SpringUtils;
+import com.fs.course.domain.FsCoursePlaySourceConfig;
+import com.fs.course.mapper.FsCoursePlaySourceConfigMapper;
 import com.fs.his.domain.FsPayConfig;
+import com.fs.his.domain.MerchantAppConfig;
+import com.fs.his.mapper.MerchantAppConfigMapper;
 import com.fs.system.domain.SysConfig;
 import com.fs.system.mapper.SysConfigMapper;
 import com.fs.tzBankPay.form.GetTokenForm;
@@ -27,11 +33,24 @@ public class PayServiceImpl implements IPayService {
     @Override
     public CreateWxOrderResult createWxOrder(WxJspayDTO wxJspayDTO) {
         SysConfigMapper sysConfigMapper= SpringUtils.getBean(SysConfigMapper.class);
-        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
-        FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
+        FsCoursePlaySourceConfigMapper fsCoursePlaySourceConfigMapper= SpringUtils.getBean(FsCoursePlaySourceConfigMapper.class);
+        MerchantAppConfigMapper merchantAppConfigMapper= SpringUtils.getBean(MerchantAppConfigMapper.class);
+        if (StringUtils.isBlank(wxJspayDTO.getAppId())) {
+            throw new IllegalArgumentException("appId不能为空");
+        }
+        FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(wxJspayDTO.getAppId());
+        if (fsCoursePlaySourceConfig == null) {
+            throw new CustomException("未找到appId对应的小程序配置: " + wxJspayDTO.getAppId());
+        }
+        Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+        if (merchantConfigId == null || merchantConfigId <= 0) {
+            throw new CustomException("小程序没有配置商户信息");
+        }
+        MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
+        FsPayConfig fsPayConfig = com.hc.openapi.tool.fastjson.JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
         String account = fsPayConfig.getYbAccount();
         wxJspayDTO.setAccount(account);
-        wxJspayDTO.setAppId(fsPayConfig.getAppId());
+        wxJspayDTO.setAppId(fsCoursePlaySourceConfig.getAppid());
         wxJspayDTO.setNotifyUrl(fsPayConfig.getYbNotifyUrl());
         wxJspayDTO.setIsMinipg("1");
         wxJspayDTO.setStoreid("0");

+ 2 - 2
fs-service/src/main/resources/application-config-druid-sft.yml

@@ -82,8 +82,8 @@ tencent_cloud_config:
 cloud_host:
   company_name: 四福堂
   projectCode: SFT
-  spaceName:
-  volcengineUrl:
+  spaceName: cqsft-2114522511
+  volcengineUrl: https://cqsftvolcengine.ylrztop.com
 
 #看课授权时显示的头像
 headerImg:

+ 187 - 0
fs-service/src/main/resources/application-dev-test.yml

@@ -0,0 +1,187 @@
+# 数据源配置
+spring:
+    profiles:
+        include: common,config-dev
+#    profiles:
+#        include: config-dev,common
+    # redis 配置
+    redis:
+        # 地址
+        host: localhost
+        # 端口,默认为6379
+        port: 6379
+        # 数据库索引
+        database: 0
+        # 密码
+        password:
+        # 连接超时时间
+        timeout: 20s
+        lettuce:
+            pool:
+                # 连接池中的最小空闲连接
+                min-idle: 0
+                # 连接池中的最大空闲连接
+                max-idle: 8
+                # 连接池的最大数据库连接数
+                max-active: 8
+                # #连接池最大阻塞等待时间(使用负值表示没有限制)
+                max-wait: -1ms
+    datasource:
+        clickhouse:
+            type: com.alibaba.druid.pool.DruidDataSource
+            driverClassName: com.clickhouse.jdbc.ClickHouseDriver
+            url: jdbc:clickhouse://1.14.104.71:8123/sop_test?compress=0&use_server_time_zone=true&use_client_time_zone=false&timezone=Asia/Shanghai
+            username: default
+            password: rt2024
+            initialSize: 10
+            maxActive: 100
+            minIdle: 10
+            maxWait: 6000
+        mysql:
+            type: com.alibaba.druid.pool.DruidDataSource
+            driverClassName: com.mysql.cj.jdbc.Driver
+            druid:
+                # 主库数据源
+                master:
+                    url: jdbc:mysql://cq-cdb-8fjmemkb.sql.tencentcdb.com:27220/his?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true
+                    username: root
+                    password: Ylrz_1q2w3e4r5t6y
+                # 初始连接数
+                initialSize: 5
+                # 最小连接池数量
+                minIdle: 10
+                # 最大连接池数量
+                maxActive: 20
+                # 配置获取连接等待超时的时间
+                maxWait: 60000
+                # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+                timeBetweenEvictionRunsMillis: 60000
+                # 配置一个连接在池中最小生存的时间,单位是毫秒
+                minEvictableIdleTimeMillis: 300000
+                # 配置一个连接在池中最大生存的时间,单位是毫秒
+                maxEvictableIdleTimeMillis: 900000
+                # 配置检测连接是否有效
+                validationQuery: SELECT 1 FROM DUAL
+                testWhileIdle: true
+                testOnBorrow: false
+                testOnReturn: false
+                webStatFilter:
+                    enabled: true
+                statViewServlet:
+                    enabled: true
+                    # 设置白名单,不填则允许所有访问
+                    allow:
+                    url-pattern: /druid/*
+                    # 控制台管理用户名和密码
+                    login-username: fs
+                    login-password: 123456
+                filter:
+                    stat:
+                        enabled: true
+                        # 慢SQL记录
+                        log-slow-sql: true
+                        slow-sql-millis: 1000
+                        merge-sql: true
+                    wall:
+                        config:
+                            multi-statement-allow: true
+        sop:
+            type: com.alibaba.druid.pool.DruidDataSource
+            driverClassName: com.mysql.cj.jdbc.Driver
+            druid:
+                # 主库数据源
+                master:
+                    url: jdbc:mysql://cq-cdb-8fjmemkb.sql.tencentcdb.com:27220/his_sop?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    username: root
+                    password: Ylrz_1q2w3e4r5t6y
+                # 初始连接数
+                initialSize: 5
+                # 最小连接池数量
+                minIdle: 10
+                # 最大连接池数量
+                maxActive: 20
+                # 配置获取连接等待超时的时间
+                maxWait: 60000
+                # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+                timeBetweenEvictionRunsMillis: 60000
+                # 配置一个连接在池中最小生存的时间,单位是毫秒
+                minEvictableIdleTimeMillis: 300000
+                # 配置一个连接在池中最大生存的时间,单位是毫秒
+                maxEvictableIdleTimeMillis: 900000
+                # 配置检测连接是否有效
+                validationQuery: SELECT 1 FROM DUAL
+                testWhileIdle: true
+                testOnBorrow: false
+                testOnReturn: false
+                webStatFilter:
+                    enabled: true
+                statViewServlet:
+                    enabled: true
+                    # 设置白名单,不填则允许所有访问
+                    allow:
+                    url-pattern: /druid/*
+                    # 控制台管理用户名和密码
+                    login-username: fs
+                    login-password: 123456
+                filter:
+                    stat:
+                        enabled: true
+                        # 慢SQL记录
+                        log-slow-sql: true
+                        slow-sql-millis: 1000
+                        merge-sql: true
+                    wall:
+                        config:
+                            multi-statement-allow: true
+
+rocketmq:
+    name-server: rmq-1243b25nj.rocketmq.gz.public.tencenttdmq.com:8080 # RocketMQ NameServer 地址
+    producer:
+        group: my-producer-group
+        access-key: ak1243b25nj17d4b2dc1a03 # 替换为实际的 accessKey
+        secret-key: sk08a7ea1f9f4b0237 # 替换为实际的 secretKey
+    consumer:
+        group: test-group
+        access-key: ak1243b25nj17d4b2dc1a03 # 替换为实际的 accessKey
+        secret-key: sk08a7ea1f9f4b0237 # 替换为实际的 secretKey
+custom:
+    token: "1o62d3YxvdHd4LEUiltnu7sK"
+    encoding-aes-key: "UJfTQ5qKTKlegjkXtp1YuzJzxeHlUKvq5GyFbERN1iU"
+    corp-id: "ww51717e2b71d5e2d3"
+    secret: "6ODAmw-8W4t6h9mdzHh2Z4Apwj8mnsyRnjEDZOHdA7k"
+    private-key-path: "privatekey.pem"
+    webhook-url: "https://your-server.com/wecom/archive"
+# token配置
+token:
+    # 令牌自定义标识
+    header: Authorization
+    # 令牌密钥
+    secret: abcdefghijklmnopqrstuvwxyz
+    # 令牌有效期(默认30分钟)
+    expireTime: 180
+openIM:
+    secret: openIM123
+    userID: imAdmin
+    url: https://web.jnmyim.ylrzfs.com/api
+#是否为新商户,新商户不走mpOpenId
+isNewWxMerchant: true
+#是否使用新im
+im:
+    type: OPENIM
+
+cloud_host:
+    company_name: 弘珍医药
+    projectCode: HZYY
+#看课授权时显示的头像
+headerImg:
+    imgUrl: https://hzyy.obs.cn-north-4.myhuaweicloud.com/fs/20250616/1750067609692.png
+ipad:
+    ipadUrl: http://admin.test.ylrztop.com/ipad
+    aiApi: http://1.95.196.10:3000/api
+    voiceApi:
+    commonApi:
+    url:
+wx_miniapp_temp:
+    pay_order_temp_id:
+    inquiry_temp_id:
+

+ 17 - 2
fs-service/src/main/resources/mapper/company/CompanyRedPacketBalanceLogsMapper.xml

@@ -13,14 +13,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="balance"    column="balance"    />
         <result property="logsType"    column="logs_type"    />
         <result property="status"    column="status"    />
+        <result property="redPacketId"    column="red_packet_id"    />
     </resultMap>
 
     <sql id="selectCompanyRedPacketBalanceLogsVo">
-        select logs_id, company_id, money, remark, create_time, balance, logs_type, status from company_red_packet_balance_logs
+        select logs_id, company_id, money, remark, create_time, balance, logs_type, status,red_packet_id from company_red_packet_balance_logs
     </sql>
 
     <select id="selectCompanyRedPacketBalanceLogsList" parameterType="CompanyRedPacketBalanceLogs" resultMap="CompanyRedPacketBalanceLogsResult">
-        select l.logs_id, l.company_id, l.money, l.remark, l.create_time, l.balance, l.logs_type, l.status,c.company_name
+        select l.logs_id, l.company_id, l.money, l.remark, l.create_time, l.balance, l.logs_type, l.status,l.red_packet_id,c.company_name
         from
         company_red_packet_balance_logs l
         left join company c on c.company_id = l.company_id
@@ -40,6 +41,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     <select id="getCompanyRedPacketBalance" resultType="com.fs.company.domain.Company">
         SELECT * FROM company WHERE company_id = #{companyId}
     </select>
+    <select id="selectCompanyRedPacketBalanceLogsListByStatus"
+            resultType="com.fs.company.domain.CompanyRedPacketBalanceLogs">
+        <include refid="selectCompanyRedPacketBalanceLogsVo"/>  where logs_type = 15 and status = 0  and create_time &gt;= #{createSTime}  AND create_time &lt; #{createETime}
+    </select>
 
     <insert id="insertCompanyRedPacketBalanceLogs" parameterType="CompanyRedPacketBalanceLogs" useGeneratedKeys="true" keyProperty="logsId">
         insert into company_red_packet_balance_logs
@@ -51,6 +56,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="balance != null">balance,</if>
             <if test="logsType != null">logs_type,</if>
             <if test="status != null">status,</if>
+            <if test="redPacketId != null">red_packet_id,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="companyId != null">#{companyId},</if>
@@ -60,6 +66,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="balance != null">#{balance},</if>
             <if test="logsType != null">#{logsType},</if>
             <if test="status != null">#{status},</if>
+            <if test="redPacketId != null">#{redPacketId},</if>
          </trim>
     </insert>
 
@@ -73,9 +80,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="balance != null">balance = #{balance},</if>
             <if test="logsType != null">logs_type = #{logsType},</if>
             <if test="status != null">status = #{status},</if>
+            <if test="redPacketId != null">red_packet_id = #{redPacketId},</if>
         </trim>
         where logs_id = #{logsId}
     </update>
+    <update id="updateCompanyRedPacketBalanceLogsByRedPacketId">
+        update company_red_packet_balance_logs
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="status != null">status = #{status},</if>
+        </trim>
+        where red_packet_id = #{redPacketId} and logs_type = 15
+    </update>
 
     <delete id="deleteCompanyRedPacketBalanceLogsByLogsId" parameterType="Long">
         delete from company_red_packet_balance_logs where logs_id = #{logsId}

+ 9 - 1
fs-service/src/main/resources/mapper/course/FsCourseAnswerLogsMapper.xml

@@ -196,7 +196,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         </where>
         ) AS paged_ids ON cal.log_id = paged_ids.log_id
     </select>
-    
+
     <select id="selectRedStatus" resultType="java.lang.Long">
         select count(log_id)
         from fs_course_red_packet_log
@@ -205,5 +205,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             and period_id = #{periodId}
         </if>
     </select>
+    <select id="selectRedStatus2" resultType="java.lang.Integer">
+        select `status`
+        from fs_course_red_packet_log
+        where user_id = #{userId} and video_id = #{videoId}
+        <if test="periodId != null">
+            and period_id = #{periodId}
+        </if>
+    </select>
 
 </mapper>

+ 2 - 0
fs-service/src/main/resources/mapper/his/FsStorePaymentMapper.xml

@@ -97,6 +97,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="shareMoney != null">share_money,</if>
             <if test="isShare != null">is_share,</if>
             <if test="appId != null">app_id,</if>
+            <if test="merConfigId != null">mer_config_id,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="payCode != null">#{payCode},</if>
@@ -125,6 +126,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="shareMoney != null">#{shareMoney},</if>
             <if test="isShare != null">#{isShare},</if>
             <if test="appId != null">#{appId},</if>
+            <if test="merConfigId != null">#{merConfigId},</if>
          </trim>
     </insert>
 

+ 1 - 1
fs-service/src/main/resources/mapper/hisStore/FsStorePaymentScrmMapper.xml

@@ -33,7 +33,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </resultMap>
 
     <sql id="selectFsStorePaymentVo">
-        select payment_id,app_id,pay_mode, pay_code, pay_type_code, pay_money, pay_time, create_time, trade_no, user_id, open_id, business_type, business_order_id, status,remark,company_id,company_user_id,dept_id,bank_transaction_id,bank_serial_no,refund_money,refund_time,order_id,is_pay_remain,business_code from fs_store_payment_scrm
+        select payment_id,pay_mode, pay_code, pay_type_code, pay_money, pay_time, create_time, trade_no, user_id, open_id, business_type, business_order_id, status,remark,company_id,company_user_id,dept_id,bank_transaction_id,bank_serial_no,refund_money,refund_time,order_id,is_pay_remain,business_code,app_id from fs_store_payment_scrm
 
     </sql>
 

+ 48 - 22
fs-user-app/src/main/java/com/fs/app/controller/InquiryOrderController.java

@@ -2,6 +2,7 @@ package com.fs.app.controller;
 
 
 import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.app.annotation.Login;
@@ -15,6 +16,8 @@ import com.fs.common.utils.ip.IpUtils;
 import com.fs.company.service.ICompanyService;
 import com.fs.core.config.WxPayProperties;
 import com.fs.core.utils.OrderCodeUtils;
+import com.fs.course.domain.FsCoursePlaySourceConfig;
+import com.fs.course.service.IFsCoursePlaySourceConfigService;
 import com.fs.his.domain.*;
 import com.fs.his.dto.FsInquiryOrderPatientDTO;
 import com.fs.his.dto.PayConfigDTO;
@@ -26,6 +29,7 @@ import com.fs.his.utils.PhoneUtil;
 import com.fs.his.vo.FsInquiryOrderListUVO;
 import com.fs.his.vo.FsInquiryOrderPingListUVO;
 import com.fs.his.vo.FsInquiryOrderReportUVO;
+import com.fs.hisStore.domain.FsPayConfigScrm;
 import com.fs.huifuPay.domain.HuiFuCreateOrder;
 import com.fs.huifuPay.domain.HuifuCreateOrderResult;
 import com.fs.huifuPay.service.HuiFuService;
@@ -93,8 +97,11 @@ public class InquiryOrderController extends  AppBaseController {
     private IFsInquiryTempService inquiryTempService;
     @Autowired
     private IFsInquiryOrderReportService orderReportService;
+
+    @Autowired
+    private IFsCoursePlaySourceConfigService fsCoursePlaySourceConfigService;
     @Autowired
-    private IFsInquiryOrderLogsService fsInquiryOrderLogsService;
+    private IMerchantAppConfigService merchantAppConfigService;
     @Autowired
     private IFsStorePaymentService storePaymentService;
     @Autowired
@@ -173,9 +180,6 @@ public class InquiryOrderController extends  AppBaseController {
     )
     {
         logger.info("支付"+param.getOrderId()+":"+param.getAppId());
-        String json=configService.selectConfigByKey("his.pay");
-        PayConfigDTO payConfigDTO= JSONUtil.toBean(json, PayConfigDTO.class);
-
         FsInquiryOrder order=inquiryOrderService.selectFsInquiryOrderByOrderId(param.getOrderId());
         if(order==null){
             return R.error("订单不存在");
@@ -256,8 +260,20 @@ public class InquiryOrderController extends  AppBaseController {
         param.setUserId(userId);
         FsUser user = userService.selectFsUserByUserId(userId);
         //在线支付
-        String json = configService.selectConfigByKey("his.pay");
-        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
+        if (StringUtils.isBlank(param.getAppId())) {
+            throw new IllegalArgumentException("appId不能为空");
+        }
+        FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigService.selectCoursePlaySourceConfigByAppId(param.getAppId());
+        if (fsCoursePlaySourceConfig == null) {
+            throw new CustomException("未找到appId对应的小程序配置: " + param.getAppId());
+        }
+        Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+        if (merchantConfigId == null || merchantConfigId <= 0) {
+            throw new CustomException("小程序没有配置商户信息");
+        }
+        MerchantAppConfig merchantAppConfig = merchantAppConfigService.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
+        FsPayConfig fsPayConfig = JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
+//        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
 //        String openId = "";
 //        if (StringUtils.isNotEmpty(param.getAppId())) {
 //            FsUserWx fsUserWx = userWxService.selectByAppIdAndUserId(param.getAppId(), param.getUserId(), 1);
@@ -289,7 +305,7 @@ public class InquiryOrderController extends  AppBaseController {
                 openId = fsUserWx.getOpenId();
             }
         } else {
-            appId = payConfigDTO.getAppId();
+            appId = merchantAppConfig.getAppId();
             openId = Objects.isNull(user) ? "" : user.getMaOpenId();
             if (StringUtils.isBlank(openId)){
                 Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
@@ -334,7 +350,7 @@ public class InquiryOrderController extends  AppBaseController {
             }
             FsStorePayment storePayment=new FsStorePayment();
             storePayment.setStatus(0);
-            storePayment.setPayMode(payConfigDTO.getType());
+            storePayment.setPayMode(merchantAppConfig.getMerchantId());
             storePayment.setPayCode(payCode);
             storePayment.setCompanyId(order.getCompanyId());
             storePayment.setCompanyUserId(order.getCompanyUserId());
@@ -348,11 +364,9 @@ public class InquiryOrderController extends  AppBaseController {
             storePayment.setUserId(user.getUserId());
             storePayment.setBusinessId(order.getOrderId().toString());
             if(storePaymentService.insertFsStorePayment(storePayment)>0){
-                if(payConfigDTO.getType().equals("wx")){
+                if(merchantAppConfig.getMerchantId().equals("wx")){
                     //创建微信订单
                     WxPayConfig payConfig = new WxPayConfig();
-                    SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
-                    FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
                     payConfig.setAppId(appId);
                     payConfig.setMchId(fsPayConfig.getWxMchId());
                     payConfig.setMchKey(fsPayConfig.getWxMchKey());
@@ -378,7 +392,7 @@ public class InquiryOrderController extends  AppBaseController {
                         throw new CustomException("支付失败"+e.getMessage());
                     }
                 }
-                else if(payConfigDTO.getType().equals("yb")){
+                else if(merchantAppConfig.getMerchantId().equals("yb")){
                     WxJspayDTO p = new WxJspayDTO();
                     // 使用setter方法为对象赋值
                     p.setPayMoney(storePayment.getPayMoney().toString());
@@ -400,7 +414,7 @@ public class InquiryOrderController extends  AppBaseController {
                         throw new CustomException("支付失败");
                     }
                 }
-                else if(payConfigDTO.getType().equals("tz")){
+                else if(merchantAppConfig.getMerchantId().equals("tz")){
                     PayCreateOrder o = new PayCreateOrder();
                     o.setOrderNo("inquiry"+storePayment.getPayCode()); // 业务系统订单号
                     o.setTrxAmt(storePayment.getPayMoney().doubleValue()); // 交易金额
@@ -425,7 +439,7 @@ public class InquiryOrderController extends  AppBaseController {
                     mt.setTradeNo(result.getBody().getOrderFlowNo());
                     storePaymentService.updateFsStorePayment(mt);
                     return R.ok().put("isPay",0).put("data",result).put("type","tz");
-                }else if(payConfigDTO.getType().equals("hf")){
+                }else if(merchantAppConfig.getMerchantId().equals("hf")){
                     HuiFuCreateOrder o = new HuiFuCreateOrder();
                     o.setTradeType("T_MINIAPP");
                     o.setOpenid(openId);
@@ -460,8 +474,20 @@ public class InquiryOrderController extends  AppBaseController {
         FsInquiryOrder order=inquiryOrderService.selectFsInquiryOrderByOrderId(param.getOrderId());
         FsUser user=userService.selectFsUserByUserId(Long.parseLong(getUserId()));
 
-        String json = configService.selectConfigByKey("his.pay");
-        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
+        if (StringUtils.isBlank(param.getAppId())) {
+            throw new IllegalArgumentException("appId不能为空");
+        }
+        FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigService.selectCoursePlaySourceConfigByAppId(param.getAppId());
+        if (fsCoursePlaySourceConfig == null) {
+            throw new CustomException("未找到appId对应的小程序配置: " + param.getAppId());
+        }
+        Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+        if (merchantConfigId == null || merchantConfigId <= 0) {
+            throw new CustomException("小程序没有配置商户信息");
+        }
+        MerchantAppConfig merchantAppConfig = merchantAppConfigService.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
+        FsPayConfig fsPayConfig = JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
+//        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
 
         String openId = null;
         String appId = param.getAppId();
@@ -475,7 +501,7 @@ public class InquiryOrderController extends  AppBaseController {
                 openId = fsUserWx.getOpenId();
             }
         } else {
-            appId = payConfigDTO.getAppId();
+            appId = fsCoursePlaySourceConfig.getAppid();
             openId = Objects.isNull(user) ? "" : user.getMaOpenId();
             if (StringUtils.isBlank(openId)){
                 Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
@@ -501,7 +527,7 @@ public class InquiryOrderController extends  AppBaseController {
 //            PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
             FsStorePayment storePayment=new FsStorePayment();
             storePayment.setStatus(0);
-            storePayment.setPayMode(payConfigDTO.getType());
+            storePayment.setPayMode(merchantAppConfig.getMerchantType());
             storePayment.setPayCode(payCode);
             storePayment.setCompanyId(order.getCompanyId());
             storePayment.setCompanyUserId(order.getCompanyUserId());
@@ -515,9 +541,9 @@ public class InquiryOrderController extends  AppBaseController {
             storePayment.setUserId(user.getUserId());
             storePayment.setBusinessId(order.getOrderId().toString());
             if(storePaymentService.insertFsStorePayment(storePayment)>0){
-                if (payConfigDTO.getType().equals("yb")) {
+                if (merchantAppConfig.getMerchantType().equals("yb")) {
                     return R.error("支付暂不可用!");
-                } else if (payConfigDTO.getType().equals("tz")) {
+                } else if (merchantAppConfig.getMerchantType().equals("tz")) {
                     PayCreateOrder o = new PayCreateOrder();
                     o.setOrderNo("inquiry" + storePayment.getPayCode()); // 业务系统订单号
                     o.setTrxAmt(storePayment.getPayMoney().doubleValue()); // 交易金额
@@ -537,7 +563,7 @@ public class InquiryOrderController extends  AppBaseController {
                     mt.setTradeNo(result.getBody().getOrderFlowNo());
                     storePaymentService.updateFsStorePayment(mt);
                     return R.ok().put("isPay", 0).put("data", result).put("type", "tz");
-                }else if (payConfigDTO.getType().equals("hf")) {
+                }else if (merchantAppConfig.getMerchantType().equals("hf")) {
                     HuiFuCreateOrder o = new HuiFuCreateOrder();
                     o.setTradeType("A_NATIVE");
                     o.setOpenid(openId);
@@ -548,7 +574,7 @@ public class InquiryOrderController extends  AppBaseController {
                     if (o.getAppId()!=null&& !o.getAppId().isEmpty()){
                         Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
                                 .eq(FsUserWx::getFsUserId, Long.parseLong(getUserId()))
-                                .eq(FsUserWx::getAppId, payConfigDTO.getAppId());
+                                .eq(FsUserWx::getAppId, fsCoursePlaySourceConfig.getAppid());
                         FsUserWx fsUserWx = fsUserWxMapper.selectOne(queryWrapper);
                         if (fsUserWx!=null){
                             o.setOpenid(fsUserWx.getOpenId());

+ 1 - 1
fs-user-app/src/main/java/com/fs/app/controller/WxH5MpController.java

@@ -207,7 +207,7 @@ public class WxH5MpController {
 //            newUser.setCompanyUserId(companyUser.getUserId());
             newUser.setUnionId(wxMpUser.getUnionId());
             newUser.setCreateTime(new Date());
-            newUser.setStatus(company != null && company.getFsUserIsDefaultBlack() == 1 ? 0 : 1);
+//            newUser.setStatus(company != null && company.getFsUserIsDefaultBlack() == 1 ? 0 : 1);
             // 新用户 - 添加 appId
             newUser.setAppId(param.getAppId());
             userService.insertFsUser(newUser);

+ 8 - 29
fs-user-app/src/main/java/com/fs/app/controller/WxPayController.java

@@ -1,51 +1,30 @@
 package com.fs.app.controller;
 
 
-import cn.hutool.json.JSONUtil;
+import com.fs.common.core.controller.BaseController;
 import com.fs.company.service.ICompanyRechargeService;
 import com.fs.core.config.WxPayProperties;
-import com.fs.course.config.RedPacketConfig;
-import com.fs.course.domain.FsCourseRedPacketLog;
 import com.fs.course.service.IFsCourseProductOrderService;
 import com.fs.course.service.IFsCourseRedPacketLogService;
-import com.fs.his.param.WxSendRedPacketParam;
-import com.fs.common.core.controller.BaseController;
-
-import com.fs.common.core.domain.R;
 import com.fs.course.service.IFsUserCourseOrderService;
 import com.fs.course.service.IFsUserVipOrderService;
-import com.fs.his.domain.FsPayConfig;
 import com.fs.his.service.*;
 import com.fs.sop.service.ISopUserLogsInfoService;
-import com.fs.system.domain.SysConfig;
 import com.fs.system.service.ISysConfigService;
-import com.github.binarywang.wxpay.bean.notify.SignatureHeader;
 import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
 import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
-import com.github.binarywang.wxpay.bean.notify.WxPayTransferBatchesNotifyV3Result;
-import com.github.binarywang.wxpay.config.WxPayConfig;
-import com.github.binarywang.wxpay.constant.WxPayConstants;
-import com.github.binarywang.wxpay.exception.WxPayException;
 import com.github.binarywang.wxpay.service.WxPayService;
-import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
-import com.github.binarywang.wxpay.util.SignUtils;
-import com.google.gson.Gson;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
-import lombok.Synchronized;
-import me.chanjar.weixin.common.bean.WxJsapiSignature;
-import me.chanjar.weixin.common.error.WxErrorException;
 import org.apache.commons.io.IOUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
 
 import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.util.HashMap;
-import java.util.Map;
 
 @Api("微信支付接口")
 @RestController
@@ -89,6 +68,8 @@ public class WxPayController {
     /**
      * 微信回调
      * 回调接口代码内部自动校验结果签名和业务代码
+     * 经测试这个方法不可用 2025/12/10 请用 /store/app/wxpay/wxPayNotify
+     *
      * @param request
      * @return
      * @throws Exception
@@ -99,14 +80,12 @@ public class WxPayController {
 
         try {
             String xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
+            logger.info("微信回调结果{}", xmlResult);
             WxPayOrderNotifyResult result = wxPayService.parseOrderNotifyResult(xmlResult);
-            System.out.println(result.getReturnCode());
             if("SUCCESS".equals(result.getReturnCode())){
                 //订单号
                 String outtradeno = result.getOutTradeNo();
                 String tradeNo = result.getTransactionId();
-                System.out.println(outtradeno);
-                System.out.println(tradeNo);
                 String[] orderId=outtradeno.split("-");
                 switch (orderId[0]){
                     case "inquiry":
@@ -134,7 +113,7 @@ public class WxPayController {
             }
 
         } catch (Exception e) {
-            logger.error("微信回调结果异常,异常原因{}", e.getMessage());
+            logger.error("微信回调结果异常", e);
             return WxPayNotifyResponse.fail(e.getMessage());
         }
     }

+ 1 - 1
fs-user-app/src/main/java/com/fs/app/controller/course/CourseFsUserLoginController.java

@@ -190,7 +190,7 @@ public class CourseFsUserLoginController extends AppBaseController {
      */
     private FsUser createUser(LoginMaWxParam param, WxMaJscode2SessionResult session, WxMaPhoneNumberInfo phoneNoInfo, Company company, CompanyUser companyUser) {
         FsUser user = new FsUser();
-        user.setStatus((company != null ? company.getFsUserIsDefaultBlack() : 0) == 1 ? 0 : 1);
+        user.setStatus(1);
         user.setUnionId(session.getUnionid() == null ? "" : session.getUnionid());
         user.setCreateTime(new Date());
         if (param.getAuthType() == 1 && phoneNoInfo != null) {

+ 32 - 32
fs-user-app/src/main/java/com/fs/app/controller/live/LiveCompletionPointsController.java

@@ -87,20 +87,20 @@ public class LiveCompletionPointsController extends AppBaseController {
     @GetMapping("/info")
     public R getInfo(@RequestParam Long liveId) {
         Long userId = Long.parseLong(getUserId());
-        
+
         // 1. 获取用户积分余额
         FsUser user = fsUserService.selectFsUserByUserId(userId);
         Long integral = user != null && user.getIntegral() != null ? user.getIntegral() : 0L;
-        
+
         // 2. 获取完课记录列表(包含已领取和未领取)
         List<LiveCompletionPointsRecord> records = completionPointsRecordService.getUserRecords(liveId, userId);
-        
+
         // 3. 统计信息
         long totalPoints = records.stream()
                 .filter(r -> r.getReceiveStatus() == 1)
                 .mapToLong(LiveCompletionPointsRecord::getPointsAwarded)
                 .sum();
-        
+
         long unreceivedCount = records.stream()
                 .filter(r -> r.getReceiveStatus() == 0)
                 .count();
@@ -111,7 +111,7 @@ public class LiveCompletionPointsController extends AppBaseController {
         result.put("totalDays", records.size());  // 累计看直播天数
         result.put("unreceivedCount", unreceivedCount);  // 未领取记录数
         result.put("records", records);  // 完课记录列表
-        
+
         return R.ok().put("data", result);
     }
 
@@ -121,7 +121,7 @@ public class LiveCompletionPointsController extends AppBaseController {
     @PostMapping("/test/create")
     public R testCreateRecord(@RequestParam Long liveId, @RequestParam(required = false) Long watchDuration) {
         Long userId = Long.parseLong(getUserId());
-        
+
         try {
             // 调用完课记录创建方法(watchDuration为null时会自动从数据库累计)
             completionPointsRecordService.checkAndCreateCompletionRecord(liveId, userId, watchDuration);
@@ -139,7 +139,7 @@ public class LiveCompletionPointsController extends AppBaseController {
     @GetMapping("/remaining-time")
     public R getRemainingTime(@RequestParam Long liveId) {
         Long userId = Long.parseLong(getUserId());
-        
+
         try {
             // 1. 获取直播间信息
             Live live = liveService.selectLiveByLiveId(liveId);
@@ -149,7 +149,7 @@ public class LiveCompletionPointsController extends AppBaseController {
 
             // 2. 查询当前用户和当前直播间的最近一次完课记录(不限制日期)
             LiveCompletionPointsRecord record = completionPointsRecordMapper.selectLatestByUserAndLiveId(liveId, userId);
-            
+
             // 3. 如果没有记录,查询直播间配置并生成记录
             if (record == null) {
                 record = completionPointsRecordService.createCompletionRecord(liveId, userId);
@@ -158,9 +158,9 @@ public class LiveCompletionPointsController extends AppBaseController {
             // 4. 计算剩余时长
             RemainingTimeVO vo = new RemainingTimeVO();
             Long videoDuration = live.getDuration() != null ? live.getDuration() : 0L;
-            Long watchDuration = record != null && record.getWatchDuration() != null 
+            Long watchDuration = record != null && record.getWatchDuration() != null
                     ? record.getWatchDuration() : 0L;
-            
+
             vo.setVideoDuration(videoDuration);
             if (record != null) {
                 vo.setCompletionRate(record.getCompletionRate());
@@ -168,7 +168,7 @@ public class LiveCompletionPointsController extends AppBaseController {
             vo.setWatchDuration(watchDuration);
             vo.setRemainingTime(Math.max(0, videoDuration - watchDuration));
             vo.setHasReceived(record != null && record.getReceiveStatus() != null && record.getReceiveStatus() == 1);
-            
+
             return R.ok().put("data", vo);
         } catch (Exception e) {
             return R.error("查询失败: " + e.getMessage());
@@ -183,7 +183,7 @@ public class LiveCompletionPointsController extends AppBaseController {
     @PostMapping("/update-watch-duration")
     public R updateWatchDuration(@RequestParam Long liveId, @RequestParam Long watchDuration) {
         Long userId = Long.parseLong(getUserId());
-        
+
         try {
             // 1. 获取直播间信息
             Live live = liveService.selectLiveByLiveId(liveId);
@@ -194,7 +194,7 @@ public class LiveCompletionPointsController extends AppBaseController {
             // 2. 判断当前时间是否在直播期间(状态为2,直播中)
             boolean isLiveInProgress = false;
             LocalDateTime now = LocalDateTime.now();
-            
+
             if (live.getStatus() != null && live.getStatus() == 2) {
                 // status=2 表示直播中
                 isLiveInProgress = true;
@@ -210,20 +210,20 @@ public class LiveCompletionPointsController extends AppBaseController {
 
             // 3. 查询当前直播间的完课记录(不限制日期)
             LiveCompletionPointsRecord record = completionPointsRecordMapper.selectLatestByUserAndLiveId(liveId, userId);
-            
+
             // 4. 计算看课时长
             Date updateTime = null;
             if (record != null && record.getUpdateTime() != null) {
                 updateTime = record.getUpdateTime();
             }
-            
+
             // 判断更新时间与直播间开始时间的关系
-            Date startTime = live.getStartTime() != null 
+            Date startTime = live.getStartTime() != null
                     ? java.sql.Timestamp.valueOf(live.getStartTime()) : null;
-            
+
             Date currentTime = new Date();
             long timeDiff = 0L;
-            
+
             if (updateTime != null && startTime != null) {
                 if (updateTime.before(startTime)) {
                     // 更新时间小于直播间开始时间,使用直播间开始时间进行计算
@@ -236,7 +236,7 @@ public class LiveCompletionPointsController extends AppBaseController {
                 // 没有更新记录,使用直播间开始时间计算
                 timeDiff = (currentTime.getTime() - startTime.getTime()) / 1000; // 转换为秒
             }
-            
+
             // 5. 如果请求传入的时间大于这个时间差,就使用计算出的看课时长,否则使用请求传入的时长
             Long finalWatchDuration;
             if (watchDuration > timeDiff) {
@@ -246,17 +246,17 @@ public class LiveCompletionPointsController extends AppBaseController {
                 // 否则使用请求传入的时长
                 finalWatchDuration = watchDuration;
             }
-            
+
             // 6. 更新完课记录中的看课时长
             if (record == null) {
                 // 如果没有记录,先创建记录
                 record = completionPointsRecordService.createCompletionRecord(liveId, userId);
             } else {
                 // 更新现有记录的看课时长
-                Long currentWatchDuration = record.getWatchDuration() != null 
+                Long currentWatchDuration = record.getWatchDuration() != null
                         ? record.getWatchDuration() : 0L;
                 record.setWatchDuration(currentWatchDuration + finalWatchDuration);
-                
+
                 // 重新计算完课比例
                 Long videoDuration = live.getDuration();
                 if (videoDuration != null && videoDuration > 0) {
@@ -268,15 +268,15 @@ public class LiveCompletionPointsController extends AppBaseController {
                     }
                     record.setCompletionRate(completionRate);
                 }
-                
+
                 completionPointsRecordMapper.updateRecord(record);
             }
 
             UpdateWatchDurationVO vo = new UpdateWatchDurationVO();
             vo.setWatchDuration(finalWatchDuration);
-            vo.setTotalWatchDuration(record != null && record.getWatchDuration() != null 
+            vo.setTotalWatchDuration(record != null && record.getWatchDuration() != null
                     ? record.getWatchDuration() : finalWatchDuration);
-            
+
             return R.ok().put("data", vo);
         } catch (Exception e) {
             return R.error("更新失败: " + e.getMessage());
@@ -294,11 +294,11 @@ public class LiveCompletionPointsController extends AppBaseController {
     @RepeatSubmit
     public R receivePoints(@RequestParam Long liveId) {
         Long userId = Long.parseLong(getUserId());
-        
+
         try {
             // 1. 查询当前用户和当前直播间的最近一次完课记录(不限制日期)
             LiveCompletionPointsRecord record = completionPointsRecordMapper.selectLatestByUserAndLiveId(liveId, userId);
-            
+
             if (record == null) {
                 return R.error("您还没有看课记录,无法领取积分");
             }
@@ -361,7 +361,7 @@ public class LiveCompletionPointsController extends AppBaseController {
             vo.setRecord(receivedRecord);
             vo.setPoints(receivedRecord.getPointsAwarded());
             vo.setContinuousDays(receivedRecord.getContinuousDays());
-            
+
             return R.ok().put("data", vo);
         } catch (BaseException e) {
             return R.error(e.getMessage());
@@ -377,13 +377,13 @@ public class LiveCompletionPointsController extends AppBaseController {
     @GetMapping("/integral-logs")
     public R getIntegralLogs(@RequestParam(required = false) Integer type) {
         Long userId = Long.parseLong(getUserId());
-        
+
         try {
             FsUserIntegralLogs query = new FsUserIntegralLogs();
             query.setUserId(userId);
-            
+
             List<FsUserIntegralLogs> logs = fsUserIntegralLogsService.selectFsUserIntegralLogsList(query);
-            
+
             // 如果指定了类型,进行过滤
             if (type != null) {
                 if (type == 1) {
@@ -394,7 +394,7 @@ public class LiveCompletionPointsController extends AppBaseController {
                     logs.removeIf(log -> log.getIntegral() == null || log.getIntegral() >= 0);
                 }
             }
-            
+
             return R.ok().put("data", logs);
         } catch (Exception e) {
             return R.error("查询失败: " + e.getMessage());

+ 55 - 23
fs-user-app/src/main/java/com/fs/app/controller/live/LiveOrderController.java

@@ -4,13 +4,11 @@ import cn.binarywang.wx.miniapp.api.WxMaService;
 import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
 import cn.hutool.core.util.IdUtil;
 import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.TypeReference;
 import com.fs.app.annotation.Login;
 import com.fs.app.controller.AppBaseController;
-import com.fs.app.utils.JwtUtils;
 import com.fs.common.annotation.Log;
 import com.fs.common.annotation.RepeatSubmit;
 import com.fs.common.core.domain.AjaxResult;
@@ -22,7 +20,6 @@ import com.fs.common.utils.ParseUtils;
 import com.fs.common.utils.ServletUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.ip.IpUtils;
-import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.core.config.WxMaConfiguration;
 import com.fs.core.utils.OrderCodeUtils;
 import com.fs.erp.service.IErpOrderService;
@@ -32,12 +29,16 @@ import com.fs.his.service.IFsExpressService;
 import com.fs.his.utils.ConfigUtil;
 import com.fs.hisStore.domain.*;
 import com.fs.hisStore.dto.FsStoreOrderComputeDTO;
+import com.fs.course.domain.FsCoursePlaySourceConfig;
+import com.fs.course.mapper.FsCoursePlaySourceConfigMapper;
+import com.fs.his.domain.FsPayConfig;
+import com.fs.his.domain.MerchantAppConfig;
+import com.fs.his.mapper.MerchantAppConfigMapper;
+import com.fs.hisStore.domain.FsUserScrm;
 import com.fs.hisStore.enums.OrderInfoEnum;
-import com.fs.hisStore.mapper.FsStorePaymentScrmMapper;
 import com.fs.hisStore.param.*;
 import com.fs.hisStore.service.IFsStoreOrderScrmService;
 import com.fs.hisStore.service.IFsUserScrmService;
-import com.fs.hisStore.vo.FsStoreOrderItemVO;
 import com.fs.huifuPay.domain.HuiFuCreateOrder;
 import com.fs.huifuPay.domain.HuiFuQueryOrderResult;
 import com.fs.huifuPay.domain.HuifuCreateOrderResult;
@@ -46,9 +47,11 @@ import com.fs.huifuPay.service.HuiFuService;
 import com.fs.live.domain.LiveOrder;
 import com.fs.live.domain.LiveOrderPayment;
 import com.fs.live.dto.LiveOrderComputeDTO;
-import com.fs.live.enums.LiveOrderCancleReason;
 import com.fs.live.mapper.LiveOrderPaymentMapper;
-import com.fs.live.param.*;
+import com.fs.live.param.FsMyLiveOrderQueryParam;
+import com.fs.live.param.LiveOrderComputedParam;
+import com.fs.live.param.LiveOrderConfirmParam;
+import com.fs.live.param.LiveOrderPayParam;
 import com.fs.live.service.ILiveAfterSalesService;
 import com.fs.live.service.ILiveOrderItemService;
 import com.fs.live.service.ILiveOrderService;
@@ -76,7 +79,6 @@ import org.redisson.api.RedissonClient;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
@@ -133,6 +135,10 @@ public class LiveOrderController extends AppBaseController
 
 
 
+    @Autowired
+    private FsCoursePlaySourceConfigMapper fsCoursePlaySourceConfigMapper;
+    @Autowired
+    private MerchantAppConfigMapper merchantAppConfigMapper;
 
     /**
      * 查询订单列表
@@ -475,7 +481,11 @@ public class LiveOrderController extends AppBaseController
 
                     order.setPayType("2");
                     BigDecimal payMoney=order.getPayPrice().multiply(new BigDecimal(storeConfig.getPayRate())).divide(new BigDecimal(100));
-                    payMoney=new BigDecimal(payMoney.setScale(0, BigDecimal.ROUND_HALF_UP).longValue());
+                    payMoney=new BigDecimal(payMoney.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
+                    // 如果小程序需要支付的金额小于0.01元,不能走物流代收,让走货到付款 xgb
+                    if (payMoney.compareTo(new BigDecimal("0.01")) < 0) {
+                        return R.error("物流代收计算支付金额为0,不允许选择物流代收");
+                    }
                     order.setPayDelivery(order.getPayPrice().subtract(payMoney));
                     order.setPayMoney(payMoney);
                 }
@@ -653,16 +663,27 @@ public class LiveOrderController extends AppBaseController
                 return R.error("正在支付中...");
             }
 
-            String json = configService.selectConfigByKey("his.pay");
-            FsPayConfigScrm fsPayConfig = JSON.parseObject(json, FsPayConfigScrm.class);
-            String payCode =  OrderCodeUtils.getOrderSn();
+            if (StringUtils.isBlank(param.getAppId())) {
+                throw new IllegalArgumentException("appId不能为空");
+            }
+            FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(param.getAppId());
+            if (fsCoursePlaySourceConfig == null) {
+                throw new CustomException("未找到appId对应的小程序配置: " + param.getAppId());
+            }
+            Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+            if (merchantConfigId == null || merchantConfigId <= 0) {
+                throw new CustomException("小程序没有配置商户信息");
+            }
+            MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
+            FsPayConfig fsPayConfig = JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
+            String payCode = IdUtil.getSnowflake(0, 0).nextIdStr();
             //易宝支付
             LiveOrderPayment storePayment=new LiveOrderPayment();
             storePayment.setCompanyId(order.getCompanyId());
             storePayment.setCompanyUserId(order.getCompanyUserId());
             storePayment.setStatus(0);
             storePayment.setPayCode(payCode);
-            storePayment.setPayMode(fsPayConfig.getType());
+            storePayment.setPayMode(merchantAppConfig.getMerchantType());
             storePayment.setPayMoney(order.getPayMoney());
             storePayment.setCreateTime(new Date());
             storePayment.setPayTypeCode("weixin");
@@ -673,7 +694,7 @@ public class LiveOrderController extends AppBaseController
             storePayment.setBusinessId(order.getOrderId().toString());
             liveOrderPaymentMapper.insertLiveOrderPayment(storePayment);
 
-            if (fsPayConfig.getType().equals("hf")){
+            if (merchantAppConfig.getMerchantType().equals("hf")){
                 HuiFuCreateOrder o = new HuiFuCreateOrder();
                 o.setTradeType("T_MINIAPP");
                 o.setOpenid(user.getMaOpenId());
@@ -696,10 +717,10 @@ public class LiveOrderController extends AppBaseController
                 else{
                     return R.error(result.getResp_desc());
                 }
-            }else  if (fsPayConfig.getType().equals("wx")){
+            }else  if (merchantAppConfig.getMerchantType().equals("wx")){
                 //创建微信订单
                 WxPayConfig payConfig = new WxPayConfig();
-                payConfig.setAppId(fsPayConfig.getAppId());
+                payConfig.setAppId(fsCoursePlaySourceConfig.getAppid());
                 payConfig.setMchId(fsPayConfig.getWxMchId());
                 payConfig.setMchKey(fsPayConfig.getWxMchKey());
                 payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
@@ -769,14 +790,25 @@ public class LiveOrderController extends AppBaseController
                 return R.error("只有顺丰物流支持尾款支付");
             }
 
-            String payCode =  OrderCodeUtils.getOrderSn();
-            String json = configService.selectConfigByKey("his.pay");
-            FsPayConfigScrm fsPayConfig = JSON.parseObject(json, FsPayConfigScrm.class);
+            String payCode = IdUtil.getSnowflake(0, 0).nextIdStr();
+            if (StringUtils.isBlank(param.getAppId())) {
+                throw new IllegalArgumentException("appId不能为空");
+            }
+            FsCoursePlaySourceConfig fsCoursePlaySourceConfig = fsCoursePlaySourceConfigMapper.selectCoursePlaySourceConfigByAppId(param.getAppId());
+            if (fsCoursePlaySourceConfig == null) {
+                throw new CustomException("未找到appId对应的小程序配置: " + param.getAppId());
+            }
+            Long merchantConfigId = fsCoursePlaySourceConfig.getMerchantConfigId();
+            if (merchantConfigId == null || merchantConfigId <= 0) {
+                throw new CustomException("小程序没有配置商户信息");
+            }
+            MerchantAppConfig merchantAppConfig = merchantAppConfigMapper.selectMerchantAppConfigById(fsCoursePlaySourceConfig.getMerchantConfigId());
+            FsPayConfig fsPayConfig = JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
             LiveOrderPayment storePayment=new LiveOrderPayment();
             storePayment.setCompanyId(order.getCompanyId());
             storePayment.setCompanyUserId(order.getCompanyUserId());
             storePayment.setStatus(0);
-            storePayment.setPayMode(fsPayConfig.getType());
+            storePayment.setPayMode(merchantAppConfig.getMerchantType());
             storePayment.setPayCode(payCode);
             storePayment.setPayMoney(order.getPayDelivery());
             storePayment.setCreateTime(new Date());
@@ -788,7 +820,7 @@ public class LiveOrderController extends AppBaseController
             storePayment.setBusinessId(order.getOrderId().toString());
             liveOrderPaymentMapper.insertLiveOrderPayment(storePayment);
 
-            if (fsPayConfig.getType().equals("hf")){
+            if (merchantAppConfig.getMerchantType().equals("hf")){
                 HuiFuCreateOrder o = new HuiFuCreateOrder();
                 o.setTradeType("T_MINIAPP");
                 o.setOpenid(user.getMaOpenId());
@@ -811,10 +843,10 @@ public class LiveOrderController extends AppBaseController
                 else{
                     return R.error(result.getResp_desc());
                 }
-            }else  if (fsPayConfig.getType().equals("wx")){
+            }else  if (merchantAppConfig.getMerchantType().equals("wx")){
                 //创建微信订单
                 WxPayConfig payConfig = new WxPayConfig();
-                payConfig.setAppId(fsPayConfig.getAppId());
+                payConfig.setAppId(fsCoursePlaySourceConfig.getAppid());
                 payConfig.setMchId(fsPayConfig.getWxMchId());
                 payConfig.setMchKey(fsPayConfig.getWxMchKey());
                 payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));

+ 2 - 10
fs-user-app/src/main/java/com/fs/app/controller/store/CompanyUserScrmController.java

@@ -34,8 +34,6 @@ import com.fs.fastGpt.mapper.FastgptChatVoiceHomoMapper;
 import com.fs.fastgptApi.util.AudioUtils;
 import com.fs.fastgptApi.vo.AudioVO;
 import com.fs.framework.security.SecurityUtils;
-import com.fs.his.dto.PayConfigDTO;
-import com.fs.his.service.IFsPrescribeService;
 import com.fs.sop.domain.QwSopTempVoice;
 import com.fs.sop.service.IQwSopTempVoiceService;
 import com.fs.system.oss.CloudStorageService;
@@ -76,7 +74,6 @@ public class CompanyUserScrmController extends AppBaseController {
     private FSConfig fsConfig;
     @Autowired
     RedisCache redisCache;
-
     @Autowired
     private ICompanyUserService companyUserService;
     @Autowired
@@ -89,8 +86,6 @@ public class CompanyUserScrmController extends AppBaseController {
     @Autowired
     private CompanyUserMapper companyUserMapper;
 
-    @Autowired
-    private IFsPrescribeService fsPrescribeService;
     @Autowired
     private IQwSopTempVoiceService voiceService;
     @Autowired
@@ -262,13 +257,10 @@ public class CompanyUserScrmController extends AppBaseController {
     @GetMapping("/getCompanyWxaCodeByPayment")
     public R getCompanyWxaCodeByPayment(@RequestParam("companyId")Long companyId,
                                         @RequestParam(value = "appId", required = false) String appId,
-                                        @RequestParam(required = false) Long companyUserId,
-                                        HttpServletRequest request){
+                                        @RequestParam(required = false) Long companyUserId){
 
-        String json = configService.selectConfigByKey("his.pay");
-        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
         if (appId == null || appId.trim().isEmpty() ) {
-            appId = payConfigDTO.getAppId();
+            return R.error("请联系管理员更新版本!");
         }
         //获取用户码
         String WxaCode;