Explorar el Código

Merge remote-tracking branch 'origin/企微聊天' into 企微聊天

# Conflicts:
#	fs-service/src/main/java/com/fs/his/config/IntegralConfig.java
ct hace 6 días
padre
commit
17203010d2
Se han modificado 68 ficheros con 3183 adiciones y 388 borrados
  1. 110 0
      fs-admin/src/main/java/com/fs/his/controller/AdProfitDetailController.java
  2. 2 2
      fs-admin/src/main/java/com/fs/his/controller/FsStorePaymentController.java
  3. 58 12
      fs-admin/src/main/java/com/fs/hisStore/controller/FsStorePaymentScrmController.java
  4. 2 0
      fs-ipad-task/src/main/java/com/fs/app/service/IpadSendServer.java
  5. 7 2
      fs-service/pom.xml
  6. 23 0
      fs-service/src/main/java/com/fs/app/service/AppPayService.java
  7. 148 0
      fs-service/src/main/java/com/fs/app/service/impl/AppPayServiceImpl.java
  8. 43 17
      fs-service/src/main/java/com/fs/course/service/impl/FsCourseProductOrderServiceImpl.java
  9. 44 18
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseOrderServiceImpl.java
  10. 48 26
      fs-service/src/main/java/com/fs/course/service/impl/FsUserVipOrderServiceImpl.java
  11. 6 0
      fs-service/src/main/java/com/fs/his/config/IntegralConfig.java
  12. 96 0
      fs-service/src/main/java/com/fs/his/domain/AdProfitDetail.java
  13. 42 0
      fs-service/src/main/java/com/fs/his/domain/FsIntegralExchange.java
  14. 15 0
      fs-service/src/main/java/com/fs/his/domain/FsPayConfig.java
  15. 9 0
      fs-service/src/main/java/com/fs/his/domain/FsStorePayment.java
  16. 99 0
      fs-service/src/main/java/com/fs/his/dto/AdProfitDetailDto.java
  17. 3 1
      fs-service/src/main/java/com/fs/his/enums/FsUserIntegralLogTypeEnum.java
  18. 68 0
      fs-service/src/main/java/com/fs/his/mapper/AdProfitDetailMapper.java
  19. 62 0
      fs-service/src/main/java/com/fs/his/mapper/FsIntegralExchangeMapper.java
  20. 6 0
      fs-service/src/main/java/com/fs/his/mapper/FsUserIntegralLogsMapper.java
  21. 3 0
      fs-service/src/main/java/com/fs/his/mapper/FsUserMapper.java
  22. 1 0
      fs-service/src/main/java/com/fs/his/param/FsCourseProductOrderRefundParam.java
  23. 1 0
      fs-service/src/main/java/com/fs/his/param/FsInquiryOrderCancelParam.java
  24. 1 0
      fs-service/src/main/java/com/fs/his/param/FsInquiryOrderDoPayParam.java
  25. 1 0
      fs-service/src/main/java/com/fs/his/param/FsInquiryOrderRefundParam.java
  26. 1 0
      fs-service/src/main/java/com/fs/his/param/FsPackageOrderDoPayParam.java
  27. 1 0
      fs-service/src/main/java/com/fs/his/param/FsStoreOrderDoPayParam.java
  28. 4 1
      fs-service/src/main/java/com/fs/his/param/FsUserAddIntegralParam.java
  29. 5 0
      fs-service/src/main/java/com/fs/his/param/PayOrderParam.java
  30. 66 0
      fs-service/src/main/java/com/fs/his/service/IAdProfitDetailService.java
  31. 62 0
      fs-service/src/main/java/com/fs/his/service/IFsIntegralExchangeService.java
  32. 3 1
      fs-service/src/main/java/com/fs/his/service/IFsPackageOrderService.java
  33. 1 2
      fs-service/src/main/java/com/fs/his/service/IFsStorePaymentService.java
  34. 10 0
      fs-service/src/main/java/com/fs/his/service/IFsUserService.java
  35. 120 0
      fs-service/src/main/java/com/fs/his/service/impl/AdProfitDetailServiceImpl.java
  36. 34 6
      fs-service/src/main/java/com/fs/his/service/impl/FsInquiryOrderServiceImpl.java
  37. 93 0
      fs-service/src/main/java/com/fs/his/service/impl/FsIntegralExchangeServiceImpl.java
  38. 175 48
      fs-service/src/main/java/com/fs/his/service/impl/FsPackageOrderServiceImpl.java
  39. 94 4
      fs-service/src/main/java/com/fs/his/service/impl/FsStoreAfterSalesServiceImpl.java
  40. 115 21
      fs-service/src/main/java/com/fs/his/service/impl/FsStoreOrderServiceImpl.java
  41. 206 48
      fs-service/src/main/java/com/fs/his/service/impl/FsStorePaymentServiceImpl.java
  42. 20 7
      fs-service/src/main/java/com/fs/his/service/impl/FsUserInformationCollectionServiceImpl.java
  43. 69 0
      fs-service/src/main/java/com/fs/his/service/impl/FsUserIntegralLogsServiceImpl.java
  44. 200 8
      fs-service/src/main/java/com/fs/his/service/impl/FsUserServiceImpl.java
  45. 6 0
      fs-service/src/main/java/com/fs/his/service/impl/MerchantAppConfigServiceImpl.java
  46. 76 0
      fs-service/src/main/java/com/fs/his/utils/ProfitShareUtils.java
  47. 30 0
      fs-service/src/main/java/com/fs/his/utils/UniAdSignUtils.java
  48. 23 0
      fs-service/src/main/java/com/fs/his/vo/ExchangeDetailVo.java
  49. 22 0
      fs-service/src/main/java/com/fs/his/vo/IntegralExchangeVo.java
  50. 4 0
      fs-service/src/main/java/com/fs/hisStore/param/FsStoreOrderOtherPayParam.java
  51. 38 6
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreAfterSalesScrmServiceImpl.java
  52. 96 33
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java
  53. 92 36
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStorePaymentScrmServiceImpl.java
  54. 36 2
      fs-service/src/main/java/com/fs/huifuPay/service/impl/HuiFuServiceImpl.java
  55. 4 0
      fs-service/src/main/java/com/fs/system/mapper/SysConfigMapper.java
  56. 22 3
      fs-service/src/main/java/com/fs/ybPay/service/impl/PayServiceImpl.java
  57. 135 0
      fs-service/src/main/resources/mapper/his/AdProfitDetailMapper.xml
  58. 70 0
      fs-service/src/main/resources/mapper/his/FsIntegralExchangeMapper.xml
  59. 2 0
      fs-service/src/main/resources/mapper/his/FsStorePaymentMapper.xml
  60. 17 0
      fs-service/src/main/resources/mapper/his/FsUserIntegralLogsMapper.xml
  61. 4 0
      fs-service/src/main/resources/mapper/his/FsUserMapper.xml
  62. 11 1
      fs-service/src/main/resources/mapper/system/SysConfigMapper.xml
  63. 86 0
      fs-user-app/src/main/java/com/fs/app/controller/AppPayController.java
  64. 40 0
      fs-user-app/src/main/java/com/fs/app/controller/CommonController.java
  65. 138 37
      fs-user-app/src/main/java/com/fs/app/controller/InquiryOrderController.java
  66. 1 1
      fs-user-app/src/main/java/com/fs/app/controller/PackageOrderController.java
  67. 51 35
      fs-user-app/src/main/java/com/fs/app/controller/live/LiveOrderController.java
  68. 2 10
      fs-user-app/src/main/java/com/fs/app/controller/store/CompanyUserScrmController.java

+ 110 - 0
fs-admin/src/main/java/com/fs/his/controller/AdProfitDetailController.java

@@ -0,0 +1,110 @@
+package com.fs.his.controller;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+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.poi.ExcelUtil;
+import com.fs.his.domain.AdProfitDetail;
+import com.fs.his.dto.AdProfitDetailDto;
+import com.fs.his.service.IAdProfitDetailService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 广告分佣Controller
+ * 
+ * @author fs
+ * @date 2025-11-27
+ */
+@RestController
+@RequestMapping("/adv/profit")
+public class AdProfitDetailController extends BaseController
+{
+    @Autowired
+    private IAdProfitDetailService adProfitDetailService;
+
+    /**
+     * 查询广告分佣列表
+     */
+    @PreAuthorize("@ss.hasPermi('adv:profit:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(AdProfitDetailDto adProfitDetailDto)
+    {
+        startPage();
+        List<AdProfitDetailDto> list = adProfitDetailService.selectAdProfitDetailList(adProfitDetailDto);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出广告分佣列表
+     */
+    @PreAuthorize("@ss.hasPermi('adv:profit:export')")
+    @Log(title = "广告分佣", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(AdProfitDetailDto adProfitDetailDto)
+    {
+        List<AdProfitDetailDto> list = adProfitDetailService.selectAdProfitDetailList(adProfitDetailDto);
+        ExcelUtil<AdProfitDetailDto> util = new ExcelUtil<AdProfitDetailDto>(AdProfitDetailDto.class);
+        return util.exportExcel(list, "广告分佣数据");
+    }
+
+    /**
+     * 获取广告分佣详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('adv:profit:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(adProfitDetailService.selectAdProfitDetailById(id));
+    }
+
+    /**
+     * 新增广告分佣
+     */
+    @PreAuthorize("@ss.hasPermi('adv:profit:add')")
+    @Log(title = "广告分佣", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody AdProfitDetail adProfitDetail)
+    {
+        return toAjax(adProfitDetailService.insertAdProfitDetail(adProfitDetail));
+    }
+
+    /**
+     * 修改广告分佣
+     */
+    @PreAuthorize("@ss.hasPermi('adv:profit:edit')")
+    @Log(title = "广告分佣", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody AdProfitDetail adProfitDetail)
+    {
+        return toAjax(adProfitDetailService.updateAdProfitDetail(adProfitDetail));
+    }
+
+    /**
+     * 删除广告分佣
+     */
+    @PreAuthorize("@ss.hasPermi('adv:profit:remove')")
+    @Log(title = "广告分佣", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(adProfitDetailService.deleteAdProfitDetailByIds(ids));
+    }
+
+    /**
+     * 查询用户可提现 和 已提现总金额
+     */
+//    @PreAuthorize("@ss.hasPermi('adv:profit:remove')")
+//    @Log(title = "广告分佣", businessType = BusinessType.DELETE)
+    @GetMapping("/getWithFinishAndMayWithdraw")
+    public R getWithFinishAndMayWithdraw()
+    {
+        return adProfitDetailService.getWithFinishAndMayWithdraw();
+    }
+}

+ 2 - 2
fs-admin/src/main/java/com/fs/his/controller/FsStorePaymentController.java

@@ -130,10 +130,10 @@ public class FsStorePaymentController extends BaseController
     }
     @PreAuthorize("@ss.hasPermi('his:storePayment:refund')")
     @GetMapping(value = "refund/{paymentId}")
-    public R refund(@PathVariable("paymentId") Long paymentId)
+    public R refund(@PathVariable("paymentId") Long paymentId,String appId)
     {
         log.info("sysUserId: {} 提交退款", getUserId());
-        return fsStorePaymentService.refundFsStorePayment(paymentId);
+        return fsStorePaymentService.refundFsStorePayment(paymentId,appId);
     }
 
     /**

+ 58 - 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(fsStorePayment.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);
@@ -248,7 +265,36 @@ 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("store-"+payment.getPayCode());
+                refundRequest.setOutRefundNo("store-"+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);
+                    }
+                    else {
+                        return R.error("退款请求失败"+refundQueryResult.getErrCodeDes());
+                    }
+                } catch (WxPayException e) {
+                    return R.error("退款请求失败"+e.getErrCodeDes());
+                }
             }
 
             //小雨点退款

+ 2 - 0
fs-ipad-task/src/main/java/com/fs/app/service/IpadSendServer.java

@@ -19,6 +19,8 @@ import com.fs.course.config.CourseConfig;
 import com.fs.course.domain.*;
 import com.fs.course.mapper.FsCoursePlaySourceConfigMapper;
 import com.fs.course.mapper.FsUserCourseVideoMapper;
+import com.fs.course.domain.FsCoursePlaySourceConfig;
+import com.fs.course.domain.FsCourseWatchLog;
 import com.fs.course.service.IFsCoursePlaySourceConfigService;
 import com.fs.course.service.IFsCourseWatchLogService;
 import com.fs.fastGpt.service.AiHookService;

+ 7 - 2
fs-service/pom.xml

@@ -123,7 +123,7 @@
         <dependency>
             <groupId>com.github.binarywang</groupId>
             <artifactId>weixin-java-pay</artifactId>
-            <version>4.7.2.B</version>
+            <version>4.8.0</version>
         </dependency>
         <dependency>
             <groupId>com.github.binarywang</groupId>
@@ -302,7 +302,12 @@
             <version>1.0.250</version>
         </dependency>
 
-
+        <!-- 支付宝-->
+        <dependency>
+            <groupId>com.alipay.sdk</groupId>
+            <artifactId>alipay-sdk-java</artifactId>
+            <version>4.38.0.ALL</version>
+        </dependency>
     </dependencies>
 
 </project>

+ 23 - 0
fs-service/src/main/java/com/fs/app/service/AppPayService.java

@@ -0,0 +1,23 @@
+package com.fs.app.service;
+
+import com.fs.common.core.domain.R;
+import com.fs.his.param.FsPackageOrderDoPayParam;
+import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
+
+
+import java.util.Map;
+
+public interface AppPayService {
+
+    /**
+     * 支付宝回调
+     */
+    String aliNotify(Map<String, String> params);
+
+    /**
+     * 微信支付回调
+     */
+    String wxNotify(WxPayOrderNotifyResult result);
+
+    R getPayConfig(String appId);
+}

+ 148 - 0
fs-service/src/main/java/com/fs/app/service/impl/AppPayServiceImpl.java

@@ -0,0 +1,148 @@
+package com.fs.app.service.impl;
+
+import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson.JSON;
+import com.alipay.api.AlipayApiException;
+import com.alipay.api.AlipayClient;
+import com.alipay.api.DefaultAlipayClient;
+import com.alipay.api.diagnosis.DiagnosisUtils;
+import com.alipay.api.domain.AlipayTradeAppPayModel;
+import com.alipay.api.internal.util.AlipaySignature;
+import com.alipay.api.request.AlipayTradeAppPayRequest;
+import com.alipay.api.response.AlipayTradeAppPayResponse;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.fs.app.service.AppPayService;
+import com.fs.common.core.domain.R;
+import com.fs.common.exception.CustomException;
+import com.fs.common.utils.ServletUtils;
+import com.fs.common.utils.ip.IpUtils;
+import com.fs.core.config.WxPayProperties;
+import com.fs.core.utils.OrderCodeUtils;
+import com.fs.his.domain.*;
+import com.fs.his.dto.PayConfigDTO;
+import com.fs.his.enums.FsPackageOrderStatusEnum;
+import com.fs.his.mapper.FsPackageOrderMapper;
+import com.fs.his.mapper.FsStorePaymentMapper;
+import com.fs.his.mapper.FsUserWxMapper;
+import com.fs.his.param.FsPackageOrderDoPayParam;
+import com.fs.his.service.*;
+import com.fs.huifuPay.service.HuiFuService;
+import com.fs.system.domain.SysConfig;
+import com.fs.system.mapper.SysConfigMapper;
+import com.fs.system.service.ISysConfigService;
+import com.fs.tzBankPay.TzBankService.TzBankService;
+import com.fs.tzBankPay.doman.PayType;
+import com.fs.ybPay.domain.OrderResult;
+import com.fs.ybPay.dto.OrderQueryDTO;
+import com.fs.ybPay.service.IPayService;
+import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
+import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
+import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
+import com.github.binarywang.wxpay.config.WxPayConfig;
+import com.github.binarywang.wxpay.exception.WxPayException;
+import com.github.binarywang.wxpay.service.WxPayService;
+import com.google.gson.Gson;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.Map;
+
+@Slf4j
+@Service
+public class AppPayServiceImpl implements AppPayService {
+
+    @Autowired
+    private SysConfigMapper sysConfigMapper;
+    @Autowired
+    private IFsInquiryOrderService inquiryOrderService;
+    @Lazy
+    @Autowired
+    private IFsStoreOrderService storeOrderService;
+    @Autowired
+    private IFsPackageOrderService packageOrderService;
+
+    /**
+     * 支付宝回调
+     */
+    @Override
+    public String aliNotify(Map<String, String> params) {
+        log.info("支付宝回调参数: {}", params);
+        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
+        FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
+        try {
+            boolean flag = AlipaySignature.rsaCheckV1(params, fsPayConfig.getAliPublicKey(), "UTF-8","RSA2");
+            if (!flag) {
+                log.info("支付宝回调验签失败:{}", params);
+            }
+
+            String tradeStatus = params.get("trade_status");
+            if (!"TRADE_SUCCESS".equals(tradeStatus)) {
+                return "success";
+            }
+
+            String[] arr = params.get("out_trade_no").split("-");
+            String tradeNo = params.get("trade_no");
+            switch (arr[0]) {
+                case "inquiry":
+                    inquiryOrderService.payConfirm("", arr[1],"","",1,tradeNo,"");
+                    break;
+                case "store":
+                    storeOrderService.payConfirm("", arr[1],"","",1,tradeNo,"");
+                    break;
+                case "package":
+                    packageOrderService.payConfirm("", arr[1],"","",1,tradeNo,"");
+                    break;
+            }
+
+
+        } catch (Exception e) {
+            log.info("支付宝回调异常:{}", e);
+            throw new RuntimeException(e);
+        }
+
+        return "success";
+    }
+
+    @Override
+    public String wxNotify(WxPayOrderNotifyResult result) {
+        log.info("微信回调参数: {}", result);
+        if (!"SUCCESS".equals(result.getReturnCode())){
+            return WxPayNotifyResponse.success("微信回调失败");
+        }
+
+        if (!"SUCCESS".equals(result.getResultCode())){
+            return WxPayNotifyResponse.success("交易失败");
+        }
+
+        String[] tradeNoArr = result.getOutTradeNo().split("-");
+        switch (tradeNoArr[0]) {
+            case "inquiry":
+                inquiryOrderService.payConfirm("", tradeNoArr[1],"","",1,result.getTransactionId(),"");
+                break;
+            case "store":
+                storeOrderService.payConfirm("", tradeNoArr[1],"","",1,result.getTransactionId(),"");
+                break;
+            case "package":
+                packageOrderService.payConfirm("", tradeNoArr[1],"","",1,result.getTransactionId(),"");
+                break;
+        }
+        return WxPayNotifyResponse.success("OK");
+    }
+
+    @Override
+    public R getPayConfig(String appId) {
+        MerchantAppConfig merchantAppConfig = sysConfigMapper.getPayConfig(appId);
+        if (merchantAppConfig == null || StringUtils.isEmpty(merchantAppConfig.getMerchantType())) {
+            return R.error("商户信息不存在");
+        }
+        return R.ok(merchantAppConfig.getMerchantType());
+    }
+
+}

+ 43 - 17
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,19 @@ 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 +398,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 +417,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 +436,11 @@ public class FsCourseProductOrderServiceImpl extends ServiceImpl<FsCourseProduct
                 storePayment.setOpenId(openId);
                 storePayment.setUserId(user.getUserId());
                 storePayment.setBusinessId(courseProductOrder.getCourseOrderId().toString());
+                storePayment.setMerchantId(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 +465,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 +486,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 +511,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");
@@ -606,7 +632,7 @@ public class FsCourseProductOrderServiceImpl extends ServiceImpl<FsCourseProduct
                     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(param.getAppId());
                     payConfig.setMchId(fsPayConfig.getWxMchId());
                     payConfig.setMchKey(fsPayConfig.getWxMchKey());
 

+ 44 - 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,12 @@ public class FsUserCourseOrderServiceImpl implements IFsUserCourseOrderService
                 storePayment.setOpenId(openId);
                 storePayment.setUserId(user.getUserId());
                 storePayment.setBusinessId(order.getOrderId().toString());
+                storePayment.setMerchantId(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 +480,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 +500,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 +520,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 +565,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 +589,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 +612,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 +623,12 @@ public class FsUserCourseOrderServiceImpl implements IFsUserCourseOrderService
 //                storePayment.setOpenId(user.getMpOpenId());
                 storePayment.setUserId(user.getUserId());
                 storePayment.setBusinessId(order.getOrderId().toString());
+                storePayment.setMerchantId(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 +649,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());

+ 48 - 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,12 @@ public class FsUserVipOrderServiceImpl implements IFsUserVipOrderService
                 storePayment.setOpenId(openId);
                 storePayment.setUserId(user.getUserId());
                 storePayment.setBusinessId(order.getOrderId().toString());
+                storePayment.setMerchantId(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 +333,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 +353,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 +373,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 +409,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 +435,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 +458,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 +469,12 @@ public class FsUserVipOrderServiceImpl implements IFsUserVipOrderService
 //                storePayment.setOpenId(user.getMpOpenId());
                 storePayment.setUserId(user.getUserId());
                 storePayment.setBusinessId(order.getOrderId().toString());
+                storePayment.setMerchantId(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 +495,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());

+ 6 - 0
fs-service/src/main/java/com/fs/his/config/IntegralConfig.java

@@ -3,6 +3,7 @@ package com.fs.his.config;
 import lombok.Data;
 
 import java.io.Serializable;
+import java.math.BigDecimal;
 
 @Data
 public class IntegralConfig implements Serializable {
@@ -32,4 +33,9 @@ public class IntegralConfig implements Serializable {
     private Integer integralArticleTime; // 观看文章(图文)一篇  多少秒算已看完
 
     private Long defaultGrandGift; // 签到大礼品配置
+    private BigDecimal integralUserRatio;// 广告联盟 用户分润比例
+    private BigDecimal integralCompanyRatio;// 广告联盟 公司分润比例
+    private BigDecimal integralHuYiRatio;// 广告联盟 互医分润比例
+    private BigDecimal integralYunLianRatio;// 广告联盟 云联分润比例
+    private Integer minimumIntegral; // 广告联盟 用户保底收益
 }

+ 96 - 0
fs-service/src/main/java/com/fs/his/domain/AdProfitDetail.java

@@ -0,0 +1,96 @@
+package com.fs.his.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fs.common.annotation.Excel;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+* <p>
+* ad_profit_detail 实体类
+* </p>
+*/
+@Getter
+@Setter
+@TableName("ad_profit_detail")
+public class AdProfitDetail implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+    * 主键
+    */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    /**
+    * 广告回调唯一交易ID
+    */
+    @Excel(name = "广告回调唯一交易ID")
+    private String adTransId;
+
+    /**
+    * 广告任务id
+    */
+    @Excel(name = "广告任务id")
+    private String adTaskId;
+
+    /**
+    * 广告平台结算总金额
+    */
+    @Excel(name = "广告平台结算总金额")
+    private BigDecimal sumMoney;
+
+    /**
+    * 用户id
+    */
+    @Excel(name = "用户id")
+    private Long userId;
+
+    /**
+    * 用户分润
+    */
+    @Excel(name = "用户分润")
+    private BigDecimal userMoney;
+
+    /**
+    * 公司id
+    */
+    @Excel(name = "公司id")
+    private Long companyId;
+
+    /**
+    * 公司分润
+    */
+    @Excel(name = "公司分润")
+    private BigDecimal companyMoney;
+
+    /**
+    * 互医分润
+    */
+    @Excel(name = "互医分润")
+    private BigDecimal huyiMoney;
+
+    /**
+    * 云联分润
+    */
+    @Excel(name = "云联分润")
+    private BigDecimal yunlianMoney;
+
+    /**
+     * 广告原始回调参数
+     */
+    private String originParam;
+
+    /**
+    * 创建时间
+    */
+    private LocalDateTime createTime;
+
+
+}

+ 42 - 0
fs-service/src/main/java/com/fs/his/domain/FsIntegralExchange.java

@@ -0,0 +1,42 @@
+package com.fs.his.domain;
+
+import com.fs.common.annotation.Excel;
+import com.fs.common.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 用户积分提现佣金记录对象 fs_integral_exchange
+ *
+ * @author fs
+ * @date 2026-01-09
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class FsIntegralExchange extends BaseEntity{
+
+    /** $column.columnComment */
+    private Long id;
+
+    /** $column.columnComment */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private Long userId;
+
+    /** 积分 正数表示增加积分,负数表示减少积分 */
+    @Excel(name = "积分 正数表示增加积分,负数表示减少积分")
+    private Long integral;
+
+    /** $column.columnComment */
+    @Excel(name = "积分 正数表示增加积分,负数表示减少积分")
+    private Integer status;
+
+    /** $column.columnComment */
+    @Excel(name = "积分 正数表示增加积分,负数表示减少积分")
+    private String phone;
+
+    /** $column.columnComment */
+    @Excel(name = "积分 正数表示增加积分,负数表示减少积分")
+    private String nickName;
+
+
+}

+ 15 - 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;
@@ -33,4 +37,15 @@ public class FsPayConfig {
     private String hfPayOnlineNotifyUrl;
     private String hfRefundNotifyUrl;
     private String hfOnlineRefundNotifyUrl;
+
+    private String aliAppId;
+    private String aliPrivateKey;
+    private String aliPublicKey;
+    private String aliNotifyUrl;
+
+    private String wxAppMchId;
+    private String wxAppMchKey;
+    private String wxAppNotifyUrl;
+    private String wxAppAppId;
+    private String wxAppKeyPath;
 }

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

@@ -96,6 +96,15 @@ public class FsStorePayment extends BaseEntity
     private BigDecimal shareMoney;
     private Integer isShare;
 
+    private Long merchantId;
+
+    public Long getMerchantId() {
+        return merchantId;
+    }
+
+    public void setMerchantId(Long merchantId) {
+        this.merchantId = merchantId;
+    }
 
     //小程序appId
     private String appId;

+ 99 - 0
fs-service/src/main/java/com/fs/his/dto/AdProfitDetailDto.java

@@ -0,0 +1,99 @@
+package com.fs.his.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fs.common.annotation.Excel;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+@Getter
+@Setter
+public class AdProfitDetailDto implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 广告回调唯一交易ID
+     */
+    @Excel(name = "回调ID")
+    private String adTransId;
+
+    /**
+     * 广告任务id
+     */
+    private String adTaskId;
+
+    /**
+     * 广告平台结算总金额
+     */
+    @Excel(name = "结算总金额")
+    private BigDecimal sumMoney;
+
+    /**
+     * 用户id
+     */
+    @Excel(name = "用户id")
+    private Long userId;
+
+    /**
+     * 用户分润
+     */
+    @Excel(name = "用户分润")
+    private BigDecimal userMoney;
+
+    /**
+     * 公司id
+     */
+    @Excel(name = "公司id")
+    private Long companyId;
+
+    /**
+     * 公司分润
+     */
+    @Excel(name = "公司分润")
+    private BigDecimal companyMoney;
+
+    /**
+     * 互医分润
+     */
+    @Excel(name = "互医分润")
+    private BigDecimal huyiMoney;
+
+    /**
+     * 云联分润
+     */
+    @Excel(name = "云联分润")
+    private BigDecimal yunlianMoney;
+
+    /**
+     * 创建时间
+     */
+    @Excel(name = "创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+
+    /**
+     * 公司名称
+     */
+    @Excel(name = "公司名称")
+    private String companyName;
+
+    /**
+     * 用户昵称
+     */
+    @Excel(name = "用户昵称")
+    private String nickName;
+
+    @JsonFormat(pattern = "yyyy-MM-dd ")
+    private Date sTime;
+    @JsonFormat(pattern = "yyyy-MM-dd ")
+    private Date eTime;
+}

+ 3 - 1
fs-service/src/main/java/com/fs/his/enums/FsUserIntegralLogTypeEnum.java

@@ -39,7 +39,9 @@ public enum FsUserIntegralLogTypeEnum {
 //    TYPE_27(27, "积分订单取消退回积分"),
     TYPE_28(28, "首次下载APP获取积分"),
     TYPE_29(29,"玩游戏获取积分"),
-    TYPE_30(30,"阅读文章获取积分")
+    TYPE_30(30,"阅读文章获取积分"),
+    TYPE_31(31,"广告积分"),
+    TYPE_32(32,"积分兑换佣金"),
     ;
 
 

+ 68 - 0
fs-service/src/main/java/com/fs/his/mapper/AdProfitDetailMapper.java

@@ -0,0 +1,68 @@
+package com.fs.his.mapper;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.his.domain.AdProfitDetail;
+import com.fs.his.dto.AdProfitDetailDto;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+* <p>
+* ad_profit_detail Mapper 接口
+* </p>
+*/
+public interface AdProfitDetailMapper extends BaseMapper<AdProfitDetail>  {
+    /**
+     * 查询广告分佣
+     *
+     * @param id 广告分佣主键
+     * @return 广告分佣
+     */
+    AdProfitDetail selectAdProfitDetailById(Long id);
+
+    /**
+     * 查询广告分佣列表
+     *
+     * @param adProfitDetailDto 广告分佣
+     * @return 广告分佣集合
+     */
+    List<AdProfitDetailDto> selectAdProfitDetailList(AdProfitDetailDto adProfitDetailDto);
+
+    /**
+     * 新增广告分佣
+     *
+     * @param adProfitDetail 广告分佣
+     * @return 结果
+     */
+    int insertAdProfitDetail(AdProfitDetail adProfitDetail);
+
+    /**
+     * 修改广告分佣
+     *
+     * @param adProfitDetail 广告分佣
+     * @return 结果
+     */
+    int updateAdProfitDetail(AdProfitDetail adProfitDetail);
+
+    /**
+     * 删除广告分佣
+     *
+     * @param id 广告分佣主键
+     * @return 结果
+     */
+    int deleteAdProfitDetailById(Long id);
+
+    /**
+     * 批量删除广告分佣
+     *
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    int deleteAdProfitDetailByIds(Long[] ids);
+
+    String getCompanyByUserId(String userId);
+
+    Map<String, Object> getWithFinishAndMayWithdraw();
+}

+ 62 - 0
fs-service/src/main/java/com/fs/his/mapper/FsIntegralExchangeMapper.java

@@ -0,0 +1,62 @@
+package com.fs.his.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.his.domain.FsIntegralExchange;
+
+import java.util.List;
+
+/**
+ * 用户积分提现佣金记录Mapper接口
+ * 
+ * @author fs
+ * @date 2026-01-09
+ */
+public interface FsIntegralExchangeMapper extends BaseMapper<FsIntegralExchange>{
+    /**
+     * 查询用户积分提现佣金记录
+     * 
+     * @param id 用户积分提现佣金记录主键
+     * @return 用户积分提现佣金记录
+     */
+    FsIntegralExchange selectFsIntegralExchangeById(Long id);
+
+    /**
+     * 查询用户积分提现佣金记录列表
+     * 
+     * @param fsIntegralExchange 用户积分提现佣金记录
+     * @return 用户积分提现佣金记录集合
+     */
+    List<FsIntegralExchange> selectFsIntegralExchangeList(FsIntegralExchange fsIntegralExchange);
+
+    /**
+     * 新增用户积分提现佣金记录
+     * 
+     * @param fsIntegralExchange 用户积分提现佣金记录
+     * @return 结果
+     */
+    int insertFsIntegralExchange(FsIntegralExchange fsIntegralExchange);
+
+    /**
+     * 修改用户积分提现佣金记录
+     * 
+     * @param fsIntegralExchange 用户积分提现佣金记录
+     * @return 结果
+     */
+    int updateFsIntegralExchange(FsIntegralExchange fsIntegralExchange);
+
+    /**
+     * 删除用户积分提现佣金记录
+     * 
+     * @param id 用户积分提现佣金记录主键
+     * @return 结果
+     */
+    int deleteFsIntegralExchangeById(Long id);
+
+    /**
+     * 批量删除用户积分提现佣金记录
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    int deleteFsIntegralExchangeByIds(Long[] ids);
+}

+ 6 - 0
fs-service/src/main/java/com/fs/his/mapper/FsUserIntegralLogsMapper.java

@@ -1,8 +1,11 @@
 package com.fs.his.mapper;
 
+import com.fs.common.annotation.DataSource;
+import com.fs.common.enums.DataSourceType;
 import com.fs.his.domain.FsUserIntegralLogs;
 import com.fs.his.param.FsUserIntegralLogsListUParam;
 import com.fs.his.param.FsUserIntegralLogsParam;
+import com.fs.his.vo.ExchangeDetailVo;
 import com.fs.his.vo.FsUserIntegralLogsListUVO;
 import com.fs.his.vo.FsUserIntegralLogsListVO;
 import com.fs.his.vo.SubIntegralVO;
@@ -143,4 +146,7 @@ public interface FsUserIntegralLogsMapper
 
     List<FsUserIntegralLogs> selectFsUserIntegralLogsByUserIdAndLogType(@Param("userId") Long userId, @Param("logType") Integer logType, @Param("date") LocalDate date);
 
+    @DataSource(DataSourceType.SHARDING)
+    List<ExchangeDetailVo> getExchangDetailList(ExchangeDetailVo detailVo);
+
 }

+ 3 - 0
fs-service/src/main/java/com/fs/his/mapper/FsUserMapper.java

@@ -14,6 +14,7 @@ import com.fs.his.param.FindUserByParam;
 import com.fs.his.param.FsUserParam;
 import com.fs.his.vo.FsUserVO;
 import com.fs.his.vo.FsUserExportListVO;
+import com.fs.his.vo.IntegralExchangeVo;
 import com.fs.his.vo.OptionsVO;
 import com.fs.hisStore.vo.FsCompanyUserListQueryVO;
 import com.fs.qw.dto.FsUserTransferParamDTO;
@@ -480,4 +481,6 @@ public interface FsUserMapper
 
     @Select("select * from fs_user where apple_key = #{appleKey}")
     FsUser findUserByAppleKey(String appleKey);
+
+    IntegralExchangeVo getWallet(Long userId);
 }

+ 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/FsInquiryOrderDoPayParam.java

@@ -10,5 +10,6 @@ public class FsInquiryOrderDoPayParam implements Serializable {
     Long userId;
 
     private String appId;
+    private String payType;
 
 }

+ 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;
 
 
 }

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

@@ -13,4 +13,5 @@ public class FsPackageOrderDoPayParam implements Serializable {
 
     private String appId;//小程序id
     private String createPackageOrderKey;
+    private String payType;
 }

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

@@ -12,4 +12,5 @@ public class FsStoreOrderDoPayParam implements Serializable {
     Long userId;
 
     private String appId;
+    private String payType;
 }

+ 4 - 1
fs-service/src/main/java/com/fs/his/param/FsUserAddIntegralParam.java

@@ -13,8 +13,11 @@ public class FsUserAddIntegralParam implements Serializable {
 
     private Long userId;
 
-    private Integer type; //类型1浏览商品 2刷视频 3邀请奖励 4被邀请奖励
+    private Integer type; //类型1浏览商品 2刷视频 3邀请奖励 4被邀请奖励 5广告积分
 
     private Long integral;
 
+    // 广告积分使用
+    private String extra;
+
 }

+ 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;
     /**
      * 支付方式
      */

+ 66 - 0
fs-service/src/main/java/com/fs/his/service/IAdProfitDetailService.java

@@ -0,0 +1,66 @@
+package com.fs.his.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.common.core.domain.R;
+import com.fs.his.domain.AdProfitDetail;
+import com.fs.his.dto.AdProfitDetailDto;
+
+import java.util.List;
+
+/**
+ * 广告分佣Service接口
+ * 
+ * @author fs
+ * @date 2025-11-27
+ */
+public interface IAdProfitDetailService extends IService<AdProfitDetail>{
+    /**
+     * 查询广告分佣
+     * 
+     * @param id 广告分佣主键
+     * @return 广告分佣
+     */
+    AdProfitDetail selectAdProfitDetailById(Long id);
+
+    /**
+     * 查询广告分佣列表
+     * 
+     * @param adProfitDetailDto 广告分佣
+     * @return 广告分佣集合
+     */
+    List<AdProfitDetailDto> selectAdProfitDetailList(AdProfitDetailDto adProfitDetailDto);
+
+    /**
+     * 新增广告分佣
+     * 
+     * @param adProfitDetail 广告分佣
+     * @return 结果
+     */
+    int insertAdProfitDetail(AdProfitDetail adProfitDetail);
+
+    /**
+     * 修改广告分佣
+     * 
+     * @param adProfitDetail 广告分佣
+     * @return 结果
+     */
+    int updateAdProfitDetail(AdProfitDetail adProfitDetail);
+
+    /**
+     * 批量删除广告分佣
+     * 
+     * @param ids 需要删除的广告分佣主键集合
+     * @return 结果
+     */
+    int deleteAdProfitDetailByIds(Long[] ids);
+
+    /**
+     * 删除广告分佣信息
+     * 
+     * @param id 广告分佣主键
+     * @return 结果
+     */
+    int deleteAdProfitDetailById(Long id);
+
+    R getWithFinishAndMayWithdraw();
+}

+ 62 - 0
fs-service/src/main/java/com/fs/his/service/IFsIntegralExchangeService.java

@@ -0,0 +1,62 @@
+package com.fs.his.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.his.domain.FsIntegralExchange;
+
+import java.util.List;
+
+/**
+ * 用户积分提现佣金记录Service接口
+ * 
+ * @author fs
+ * @date 2026-01-09
+ */
+public interface IFsIntegralExchangeService extends IService<FsIntegralExchange>{
+    /**
+     * 查询用户积分提现佣金记录
+     * 
+     * @param id 用户积分提现佣金记录主键
+     * @return 用户积分提现佣金记录
+     */
+    FsIntegralExchange selectFsIntegralExchangeById(Long id);
+
+    /**
+     * 查询用户积分提现佣金记录列表
+     * 
+     * @param fsIntegralExchange 用户积分提现佣金记录
+     * @return 用户积分提现佣金记录集合
+     */
+    List<FsIntegralExchange> selectFsIntegralExchangeList(FsIntegralExchange fsIntegralExchange);
+
+    /**
+     * 新增用户积分提现佣金记录
+     * 
+     * @param fsIntegralExchange 用户积分提现佣金记录
+     * @return 结果
+     */
+    int insertFsIntegralExchange(FsIntegralExchange fsIntegralExchange);
+
+    /**
+     * 修改用户积分提现佣金记录
+     * 
+     * @param fsIntegralExchange 用户积分提现佣金记录
+     * @return 结果
+     */
+    int updateFsIntegralExchange(FsIntegralExchange fsIntegralExchange);
+
+    /**
+     * 批量删除用户积分提现佣金记录
+     * 
+     * @param ids 需要删除的用户积分提现佣金记录主键集合
+     * @return 结果
+     */
+    int deleteFsIntegralExchangeByIds(Long[] ids);
+
+    /**
+     * 删除用户积分提现佣金记录信息
+     * 
+     * @param id 用户积分提现佣金记录主键
+     * @return 结果
+     */
+    int deleteFsIntegralExchangeById(Long id);
+}

+ 3 - 1
fs-service/src/main/java/com/fs/his/service/IFsPackageOrderService.java

@@ -13,6 +13,8 @@ import com.fs.his.param.*;
 import com.fs.his.vo.*;
 import io.swagger.models.auth.In;
 
+import javax.servlet.http.HttpServletRequest;
+
 /**
  * 套餐订单Service接口
  *
@@ -95,7 +97,7 @@ public interface IFsPackageOrderService
 
     Integer PackageStoreOrderRefund(Long orderId,String opeName);
 
-    R payment(FsPackageOrderDoPayParam param);
+    R payment(FsPackageOrderDoPayParam param, HttpServletRequest request);
 
     R cancel(FsPackageOrderCancelParam param);
 

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

@@ -16,7 +16,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;
 
@@ -92,7 +91,7 @@ public interface IFsStorePaymentService
 
     String updateFsStorePaymentByDecryptForm(Long paymentId, Date refundDate,String orgHfSeqId);
 
-    R refundFsStorePayment(Long paymentId);
+    R refundFsStorePayment(Long paymentId, String appId);
 
     R sendRedPacket(WxSendRedPacketParam param);
 

+ 10 - 0
fs-service/src/main/java/com/fs/his/service/IFsUserService.java

@@ -239,4 +239,14 @@ public interface IFsUserService
     int realDeleteFsUserByUserId(Long userId);
 
     R checkIsSales(FsUser fsUser);
+
+    R uniCallBack(Map<String, Object> params);
+
+    R createLogs(Long userId);
+
+    R getWallet(Long userId);
+
+    R integralExchange(Long userId);
+
+    R exchangDetail(Map<String, Object> params);
 }

+ 120 - 0
fs-service/src/main/java/com/fs/his/service/impl/AdProfitDetailServiceImpl.java

@@ -0,0 +1,120 @@
+package com.fs.his.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fs.common.core.domain.R;
+import com.fs.his.domain.AdProfitDetail;
+import com.fs.his.dto.AdProfitDetailDto;
+import com.fs.his.mapper.AdProfitDetailMapper;
+import com.fs.his.service.IAdProfitDetailService;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.time.LocalDateTime;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 广告分佣Service业务层处理
+ * 
+ * @author fs
+ * @date 2025-11-27
+ */
+@Service
+public class AdProfitDetailServiceImpl extends ServiceImpl<AdProfitDetailMapper, AdProfitDetail> implements IAdProfitDetailService {
+
+    /**
+     * 查询广告分佣
+     * 
+     * @param id 广告分佣主键
+     * @return 广告分佣
+     */
+    @Override
+    public AdProfitDetail selectAdProfitDetailById(Long id)
+    {
+        return baseMapper.selectAdProfitDetailById(id);
+    }
+
+    /**
+     * 查询广告分佣列表
+     * 
+     * @param adProfitDetailDto 广告分佣
+     * @return 广告分佣
+     */
+    @Override
+    public List<AdProfitDetailDto> selectAdProfitDetailList(AdProfitDetailDto adProfitDetailDto)
+    {
+        List<AdProfitDetailDto> list = baseMapper.selectAdProfitDetailList(adProfitDetailDto);
+        list.stream().forEach(item -> {
+            item.setSumMoney(item.getSumMoney().divide(BigDecimal.valueOf(100)));
+            item.setUserMoney(item.getUserMoney().divide(BigDecimal.valueOf(100)));
+            item.setCompanyMoney(item.getCompanyMoney() != null ? item.getCompanyMoney().divide(BigDecimal.valueOf(100)) : null);
+            item.setYunlianMoney(item.getYunlianMoney() != null ? item.getYunlianMoney().divide(BigDecimal.valueOf(100)) : null);
+            item.setHuyiMoney(item.getHuyiMoney() != null ? item.getHuyiMoney().divide(BigDecimal.valueOf(100)) : null);
+        });
+        return list;
+    }
+
+    /**
+     * 新增广告分佣
+     * 
+     * @param adProfitDetail 广告分佣
+     * @return 结果
+     */
+    @Override
+    public int insertAdProfitDetail(AdProfitDetail adProfitDetail)
+    {
+        adProfitDetail.setCreateTime(LocalDateTime.now());
+        return baseMapper.insertAdProfitDetail(adProfitDetail);
+    }
+
+    /**
+     * 修改广告分佣
+     * 
+     * @param adProfitDetail 广告分佣
+     * @return 结果
+     */
+    @Override
+    public int updateAdProfitDetail(AdProfitDetail adProfitDetail)
+    {
+        return baseMapper.updateAdProfitDetail(adProfitDetail);
+    }
+
+    /**
+     * 批量删除广告分佣
+     * 
+     * @param ids 需要删除的广告分佣主键
+     * @return 结果
+     */
+    @Override
+    public int deleteAdProfitDetailByIds(Long[] ids)
+    {
+        return baseMapper.deleteAdProfitDetailByIds(ids);
+    }
+
+    /**
+     * 删除广告分佣信息
+     * 
+     * @param id 广告分佣主键
+     * @return 结果
+     */
+    @Override
+    public int deleteAdProfitDetailById(Long id)
+    {
+        return baseMapper.deleteAdProfitDetailById(id);
+    }
+
+    @Override
+    public R getWithFinishAndMayWithdraw() {
+        Map<String,Object> map = baseMapper.getWithFinishAndMayWithdraw();
+        // 可提现总金额
+        BigDecimal totalMayWithdraw = new BigDecimal(map.get("totalMayWithdraw").toString()).divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN);
+        // 已提现总金额
+        BigDecimal totalWithdrawFinish = new BigDecimal(map.get("totalWithdrawFinish").toString()).divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN);
+        Map<String,Object> widthdrawMap = new HashMap<>();
+        widthdrawMap.put("totalMayWithdraw",totalMayWithdraw);
+        widthdrawMap.put("totalWithdrawFinish",totalWithdrawFinish);
+        return R.ok(widthdrawMap);
+    }
+}

+ 34 - 6
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,9 +332,20 @@ 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);
-                        payConfig.setAppId(fsPayConfig.getAppId());
+                        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);
+                        payConfig.setAppId(fsCoursePlaySourceConfig.getAppid());
                         payConfig.setMchId(fsPayConfig.getWxMchId());
                         payConfig.setMchKey(fsPayConfig.getWxMchKey());
 
@@ -1485,9 +1502,20 @@ 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);
-                    payConfig.setAppId(fsPayConfig.getAppId());
+                    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);
+                    payConfig.setAppId(fsCoursePlaySourceConfig.getAppid());
                     payConfig.setMchId(fsPayConfig.getWxMchId());
                     payConfig.setMchKey(fsPayConfig.getWxMchKey());
 

+ 93 - 0
fs-service/src/main/java/com/fs/his/service/impl/FsIntegralExchangeServiceImpl.java

@@ -0,0 +1,93 @@
+package com.fs.his.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fs.common.utils.DateUtils;
+import com.fs.his.domain.FsIntegralExchange;
+import com.fs.his.mapper.FsIntegralExchangeMapper;
+import com.fs.his.service.IFsIntegralExchangeService;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 用户积分提现佣金记录Service业务层处理
+ * 
+ * @author fs
+ * @date 2026-01-09
+ */
+@Service
+public class FsIntegralExchangeServiceImpl extends ServiceImpl<FsIntegralExchangeMapper, FsIntegralExchange> implements IFsIntegralExchangeService {
+
+    /**
+     * 查询用户积分提现佣金记录
+     * 
+     * @param id 用户积分提现佣金记录主键
+     * @return 用户积分提现佣金记录
+     */
+    @Override
+    public FsIntegralExchange selectFsIntegralExchangeById(Long id)
+    {
+        return baseMapper.selectFsIntegralExchangeById(id);
+    }
+
+    /**
+     * 查询用户积分提现佣金记录列表
+     * 
+     * @param fsIntegralExchange 用户积分提现佣金记录
+     * @return 用户积分提现佣金记录
+     */
+    @Override
+    public List<FsIntegralExchange> selectFsIntegralExchangeList(FsIntegralExchange fsIntegralExchange)
+    {
+        return baseMapper.selectFsIntegralExchangeList(fsIntegralExchange);
+    }
+
+    /**
+     * 新增用户积分提现佣金记录
+     * 
+     * @param fsIntegralExchange 用户积分提现佣金记录
+     * @return 结果
+     */
+    @Override
+    public int insertFsIntegralExchange(FsIntegralExchange fsIntegralExchange)
+    {
+        fsIntegralExchange.setCreateTime(DateUtils.getNowDate());
+        return baseMapper.insertFsIntegralExchange(fsIntegralExchange);
+    }
+
+    /**
+     * 修改用户积分提现佣金记录
+     * 
+     * @param fsIntegralExchange 用户积分提现佣金记录
+     * @return 结果
+     */
+    @Override
+    public int updateFsIntegralExchange(FsIntegralExchange fsIntegralExchange)
+    {
+        return baseMapper.updateFsIntegralExchange(fsIntegralExchange);
+    }
+
+    /**
+     * 批量删除用户积分提现佣金记录
+     * 
+     * @param ids 需要删除的用户积分提现佣金记录主键
+     * @return 结果
+     */
+    @Override
+    public int deleteFsIntegralExchangeByIds(Long[] ids)
+    {
+        return baseMapper.deleteFsIntegralExchangeByIds(ids);
+    }
+
+    /**
+     * 删除用户积分提现佣金记录信息
+     * 
+     * @param id 用户积分提现佣金记录主键
+     * @return 结果
+     */
+    @Override
+    public int deleteFsIntegralExchangeById(Long id)
+    {
+        return baseMapper.deleteFsIntegralExchangeById(id);
+    }
+}

+ 175 - 48
fs-service/src/main/java/com/fs/his/service/impl/FsPackageOrderServiceImpl.java

@@ -17,6 +17,12 @@ import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
+import com.alipay.api.AlipayClient;
+import com.alipay.api.DefaultAlipayClient;
+import com.alipay.api.diagnosis.DiagnosisUtils;
+import com.alipay.api.domain.AlipayTradeAppPayModel;
+import com.alipay.api.request.AlipayTradeAppPayRequest;
+import com.alipay.api.response.AlipayTradeAppPayResponse;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.common.constant.FsConstants;
@@ -33,6 +39,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 +55,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;
@@ -74,6 +83,7 @@ import com.github.binarywang.wxpay.exception.WxPayException;
 import com.github.binarywang.wxpay.service.WxPayService;
 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;
 import org.slf4j.LoggerFactory;
@@ -84,12 +94,15 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.interceptor.TransactionAspectSupport;
 
+import javax.servlet.http.HttpServletRequest;
+
 /**
  * 套餐订单Service业务层处理
  *
  * @author fs
  * @date 2023-08-25
  */
+@Slf4j
 @Service
 public class FsPackageOrderServiceImpl implements IFsPackageOrderService
 {
@@ -98,6 +111,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
@@ -866,7 +884,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());
@@ -964,7 +981,7 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
 
     @Override
     @Transactional
-    public R payment(FsPackageOrderDoPayParam param) {
+    public R payment(FsPackageOrderDoPayParam param, HttpServletRequest request) {
         //更新订单状态
         FsPackageOrder fsPackageOrder=fsPackageOrderMapper.selectFsPackageOrderByOrderId(param.getOrderId());
         if(!fsPackageOrder.getStatus().equals(FsPackageOrderStatusEnum.STATUS_1.getValue())){
@@ -979,36 +996,57 @@ 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);
 
         //金牛多小程序支付
         String openId = null;
         String appId = param.getAppId();
-        if (StringUtils.isNotBlank(appId)) {
-            //查询fs_user_wx的openId
-            Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
-                    .eq(FsUserWx::getFsUserId, param.getUserId())
-                    .eq(FsUserWx::getAppId, appId);
-            FsUserWx fsUserWx = fsUserWxMapper.selectOne(queryWrapper);
-            if (fsUserWx != null) {
-                openId = fsUserWx.getOpenId();
-            }
+        if (request.getHeader("sourcetype") != null && "APP".equals(request.getHeader("sourcetype"))) {
+            FsUser fsUser = fsUserService.selectFsUserByUserId(param.getUserId().longValue());
+            openId = fsUser.getAppOpenId();
         } else {
-            appId = payConfigDTO.getAppId();
-            openId = Objects.isNull(user) ? "" : user.getMaOpenId();
-            if (StringUtils.isBlank(openId)){
+            if (StringUtils.isNotBlank(appId)) {
+                //查询fs_user_wx的openId
                 Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
                         .eq(FsUserWx::getFsUserId, param.getUserId())
                         .eq(FsUserWx::getAppId, appId);
                 FsUserWx fsUserWx = fsUserWxMapper.selectOne(queryWrapper);
-                if (Objects.nonNull(fsUserWx)){
+                if (fsUserWx != null) {
                     openId = fsUserWx.getOpenId();
                 }
+            } else {
+                appId = fsCoursePlaySourceConfig.getAppid();
+                openId = Objects.isNull(user) ? "" : user.getMaOpenId();
+                if (StringUtils.isBlank(openId)){
+                    Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
+                            .eq(FsUserWx::getFsUserId, param.getUserId())
+                            .eq(FsUserWx::getAppId, appId);
+                    FsUserWx fsUserWx = fsUserWxMapper.selectOne(queryWrapper);
+                    if (Objects.nonNull(fsUserWx)){
+                        openId = fsUserWx.getOpenId();
+                    }
+                }
             }
         }
 
-        if(user!=null&& StringUtils.isNotEmpty(openId)){
+        if (user != null
+                && (
+                StringUtils.isNotEmpty(openId)
+                        || "appPay".equals(merchantAppConfig.getMerchantType())
+                        || ("hf".equals(merchantAppConfig.getMerchantType()) && "ali".equals(param.getPayType()))
+        )) {
             if(fsPackageOrder.getPayMoney().compareTo(new BigDecimal(0))==1){
                 String payCode =  OrderCodeUtils.getOrderSn();
                 if(StringUtils.isEmpty(payCode)){
@@ -1016,12 +1054,12 @@ 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());
                 storePayment.setCreateTime(new Date());
-                storePayment.setPayTypeCode("weixin");
+                storePayment.setPayTypeCode(!"appPay".equals(merchantAppConfig.getMerchantType()) ? "weixin" : param.getPayType());
                 storePayment.setBusinessType(3);
                 storePayment.setCompanyId(fsPackageOrder.getCompanyId());
                 storePayment.setCompanyUserId(fsPackageOrder.getCompanyUserId());
@@ -1030,12 +1068,11 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
                 storePayment.setUserId(user.getUserId());
                 storePayment.setStoreId(fsPackageOrder.getStoreId());
                 storePayment.setBusinessId(fsPackageOrder.getOrderId().toString());
+                storePayment.setMerchantId(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 +1097,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 +1118,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,10 +1143,10 @@ 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");
+                        o.setTradeType(StringUtils.isEmpty(param.getPayType()) || param.getPayType().equals("wx") ? "T_MINIAPP" : "A_NATIVE");
                         o.setOpenid(openId);
                         o.setReqSeqId("package-"+storePayment.getPayCode());
                         o.setTransAmt(storePayment.getPayMoney().toString());
@@ -1132,6 +1169,61 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
                         mt.setAppId(appId);
                         storePaymentService.updateFsStorePayment(mt);
                         return R.ok().put("isPay", 0).put("data", result).put("type", "hf");
+                    } else if (merchantAppConfig.getMerchantType().equals("appPay") && "wx".equals(param.getPayType())) {
+                        //创建微信订单
+                        WxPayConfig payConfig = new WxPayConfig();
+                        payConfig.setAppId(appId);
+                        payConfig.setMchId(fsPayConfig.getWxAppMchId());
+                        payConfig.setMchKey(fsPayConfig.getWxAppMchKey());
+                        payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
+                        payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));
+                        payConfig.setKeyPath(null);
+                        payConfig.setNotifyUrl(fsPayConfig.getWxAppNotifyUrl());
+                        wxPayService.setConfig(payConfig);
+                        WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
+                        orderRequest.setBody("套餐包订单支付");
+                        orderRequest.setOutTradeNo("package-"+storePayment.getPayCode());
+                        orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(storePayment.getPayMoney().toString()));
+                        orderRequest.setTradeType("APP");
+                        orderRequest.setSpbillCreateIp(IpUtils.getIpAddr(request));
+                        orderRequest.setNotifyUrl(fsPayConfig.getNotifyUrlScrm());
+                        //调用统一下单接口,获取"预支付交易会话标识"
+                        try {
+                            Object result = wxPayService.createOrder(orderRequest);
+                            return R.ok().put("data",result).put("type","wxApp").put("isPay",0);
+                        } catch (WxPayException e) {
+                            e.printStackTrace();
+                            throw new CustomException("支付失败"+e.getMessage());
+                        }
+                    } else if (merchantAppConfig.getMerchantType().equals("appPay") && "ali".equals(param.getPayType())) {
+                        // 实例化客户端
+                        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", fsPayConfig.getAliAppId(), fsPayConfig.getAliPrivateKey(), "json", "utf-8", fsPayConfig.getAliPublicKey(), "RSA2");
+
+                        // 构造请求参数以调用接口
+                        AlipayTradeAppPayRequest aliRequest = new AlipayTradeAppPayRequest();
+                        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
+                        // 商户订单号
+                        model.setOutTradeNo("package-" + storePayment.getPayCode());
+                        // 订单总金额
+                        model.setTotalAmount(storePayment.getPayMoney().toString());
+                        // 订单标题r
+                        model.setSubject("套餐包订单支付");
+
+                        aliRequest.setBizModel(model);
+                        aliRequest.setNotifyUrl(fsPayConfig.getAliNotifyUrl());
+
+                        try {
+                            AlipayTradeAppPayResponse result = alipayClient.sdkExecute(aliRequest);
+                            if (!result.isSuccess()) {
+                                String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(result);
+                                log.error("支付宝支付调用失败 诊断链接:{}", diagnosisUrl);
+                                throw new CustomException(result.getSubMsg());
+                            }
+
+                            return R.ok().put("isPay", 0).put("data", result).put("type", "aliPay");
+                        } catch (Exception e){
+                            log.info("支付宝支付异常: {}", e);
+                        }
                     }
                 }
             }
@@ -1211,8 +1303,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 +1327,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 +1342,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 +1356,12 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
                 storePayment.setUserId(user.getUserId());
                 storePayment.setStoreId(fsPackageOrder.getStoreId());
                 storePayment.setBusinessId(fsPackageOrder.getOrderId().toString());
+                storePayment.setMerchantId(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 +1382,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 +1423,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 +1449,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 +1472,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 +1486,11 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
                 storePayment.setUserId(user.getUserId());
                 storePayment.setStoreId(fsPackageOrder.getStoreId());
                 storePayment.setBusinessId(fsPackageOrder.getOrderId().toString());
+                storePayment.setMerchantId(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 +1511,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 +1554,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 +1581,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 +1604,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 +1618,12 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
                 storePayment.setUserId(user.getUserId());
                 storePayment.setStoreId(fsPackageOrder.getStoreId());
                 storePayment.setBusinessId(fsPackageOrder.getOrderId().toString());
+                storePayment.setMerchantId(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 +1644,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");

+ 94 - 4
fs-service/src/main/java/com/fs/his/service/impl/FsStoreAfterSalesServiceImpl.java

@@ -14,6 +14,12 @@ import cn.hutool.core.util.IdUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
+import com.alipay.api.AlipayApiException;
+import com.alipay.api.AlipayClient;
+import com.alipay.api.DefaultAlipayClient;
+import com.alipay.api.domain.AlipayTradeRefundModel;
+import com.alipay.api.request.AlipayTradeRefundRequest;
+import com.alipay.api.response.AlipayTradeRefundResponse;
 import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
 import com.fs.common.exception.CustomException;
@@ -31,6 +37,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 +56,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;
@@ -71,6 +80,7 @@ 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.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
 import com.google.gson.Gson;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -96,6 +106,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;
@@ -477,12 +491,22 @@ 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("小程序没有配置商户信息");
+            }
+            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(fsCoursePlaySourceConfig.getAppid());
                 payConfig.setMchId(fsPayConfig.getWxMchId());
                 payConfig.setMchKey(fsPayConfig.getWxMchKey());
                 payConfig.setKeyPath(wxPayProperties.getKeyPath());
@@ -593,6 +617,60 @@ public class FsStoreAfterSalesServiceImpl implements IFsStoreAfterSalesService {
                 } else {
                     throw new CustomException("退款请求失败" + refund.getResp_desc());
                 }
+            } else if ("appPay".equals(payment.getPayMode()) && "wx".equals(payment.getPayTypeCode())) {
+                // 处理微信退款
+                WxPayService wxPayService = getWxPayService(fsPayConfig);
+                WxPayRefundRequest refundRequest = new WxPayRefundRequest();
+                refundRequest.setOutTradeNo(orderType+"-"+payment.getPayCode());
+                refundRequest.setOutRefundNo(orderType+"-"+payment.getPayCode());
+                refundRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(payment.getPayMoney().toString()));
+                refundRequest.setRefundFee(WxPayUnifiedOrderRequest.yuanToFen(payment.getPayMoney().toString()));
+                try {
+                    WxPayRefundResult refundResult = wxPayService.refund(refundRequest);
+                    WxPayRefundQueryResult refundQueryResult = wxPayService.refundQuery("", refundResult.getOutTradeNo(), refundResult.getOutRefundNo(), refundResult.getRefundId());
+                    if (refundQueryResult != null && refundQueryResult.getResultCode().equals("SUCCESS")) {
+                        FsStorePayment paymentMap = new FsStorePayment();
+                        paymentMap.setPaymentId(payment.getPaymentId());
+                        paymentMap.setStatus(-1);
+                        paymentMap.setRefundTime(DateUtils.getNowDate());
+                        paymentMap.setRefundMoney(payment.getPayMoney());
+                        fsStorePaymentMapper.updateFsStorePayment(paymentMap);
+                    } else {
+                        throw new CustomException("退款请求失败" + refundQueryResult.getReturnMsg());
+                    }
+
+                } catch (WxPayException e) {
+                    throw new CustomException("退款请求失败" + e);
+                }
+
+            } else if ("appPay".equals(payment.getPayMode()) && "ali".equals(payment.getPayTypeCode())) {
+                // 实例化客户端
+                SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
+                AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", fsPayConfig.getAliAppId(), fsPayConfig.getAliPrivateKey(), "json", "utf-8", fsPayConfig.getAliPublicKey(), "RSA2");
+                // 构造请求参数以调用接口
+                AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
+                AlipayTradeRefundModel model = new AlipayTradeRefundModel();
+                model.setOutTradeNo(orderType+"-"+payment.getPayCode());
+                model.setRefundAmount(payment.getPayMoney().toString());
+                request.setBizModel(model);
+                try {
+                    AlipayTradeRefundResponse response = alipayClient.execute(request);
+                    if (response.isSuccess()) {
+                        FsStorePayment paymentMap = new FsStorePayment();
+                        paymentMap.setPaymentId(payment.getPaymentId());
+                        paymentMap.setStatus(-1);
+                        paymentMap.setRefundTime(DateUtils.getNowDate());
+                        paymentMap.setRefundMoney(payment.getPayMoney());
+                        fsStorePaymentMapper.updateFsStorePayment(paymentMap);
+                    } else {
+//                        String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
+                        throw new CustomException("支付宝退款请求失败" + response.getSubMsg());
+                    }
+
+                } catch (AlipayApiException e) {
+                    throw new CustomException("支付宝退款请求失败" + e);
+                }
+
             }
             //管易作废
             if (StringUtils.isNotEmpty(fsStoreOrder.getExtendOrderId())) {
@@ -633,6 +711,18 @@ public class FsStoreAfterSalesServiceImpl implements IFsStoreAfterSalesService {
         return i;
     }
 
+    private WxPayService getWxPayService(FsPayConfig fsPayConfig){
+        WxPayConfig payConfig = new WxPayConfig();
+        payConfig.setAppId(fsPayConfig.getWxAppAppId());
+        payConfig.setMchId(fsPayConfig.getWxAppMchId());
+        payConfig.setMchKey(fsPayConfig.getWxAppMchKey());
+        payConfig.setKeyPath(fsPayConfig.getWxAppKeyPath());
+        payConfig.setNotifyUrl(fsPayConfig.getWxAppNotifyUrl());
+        WxPayServiceImpl payService = new WxPayServiceImpl();
+        payService.setConfig(payConfig);
+        return payService;
+    }
+
 
 
     @Override

+ 115 - 21
fs-service/src/main/java/com/fs/his/service/impl/FsStoreOrderServiceImpl.java

@@ -6,6 +6,12 @@ import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONArray;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
+import com.alipay.api.AlipayClient;
+import com.alipay.api.DefaultAlipayClient;
+import com.alipay.api.diagnosis.DiagnosisUtils;
+import com.alipay.api.domain.AlipayTradeAppPayModel;
+import com.alipay.api.request.AlipayTradeAppPayRequest;
+import com.alipay.api.response.AlipayTradeAppPayResponse;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.common.core.domain.R;
@@ -28,6 +34,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 +53,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 +162,9 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
     private FsStoreOrderMapper fsStoreOrderMapper;
 
     @Autowired
-    private FsStoreOrderScrmMapper fsStoreOrderScrmMapper;
+    private FsCoursePlaySourceConfigMapper fsCoursePlaySourceConfigMapper;
+    @Autowired
+    private MerchantAppConfigMapper merchantAppConfigMapper;
 
     @Autowired
     private FsStoreOrderItemMapper fsStoreOrderItemMapper;
@@ -2972,8 +2983,19 @@ 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());
+        FsPayConfig fsPayConfig = JSON.parseObject(merchantAppConfig.getDataJson(), FsPayConfig.class);
         String openId = null;
         String appId = param.getAppId();
         if (StringUtils.isNotBlank(appId)) {
@@ -2986,7 +3008,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()
@@ -2999,7 +3021,12 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
             }
         }
 
-        if (user != null && StringUtils.isNotEmpty(openId)) {
+        if (user != null
+                && (
+                StringUtils.isNotEmpty(openId)
+                        || "appPay".equals(merchantAppConfig.getMerchantType())
+                        || ("hf".equals(merchantAppConfig.getMerchantType()) && "ali".equals(param.getPayType()))
+        )) {
 
             if (order.getPayMoney().compareTo(new BigDecimal(0)) == 0) {
                 this.payConfirm(order.getOrderCode(), "", "", "", 2,null,null);
@@ -3012,11 +3039,11 @@ 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());
-                storePayment.setPayTypeCode("weixin");
+                storePayment.setPayTypeCode(!"appPay".equals(merchantAppConfig.getMerchantType()) ? "weixin" : param.getPayType());
                 storePayment.setBusinessType(2);
                 storePayment.setRemark("药品订单支付");
                 storePayment.setOpenId(openId);
@@ -3025,14 +3052,14 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                 storePayment.setCompanyUserId(order.getCompanyUserId());
                 storePayment.setStoreId(order.getStoreId());
                 storePayment.setBusinessId(order.getOrderId().toString());
+                storePayment.setMerchantId(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));
@@ -3056,7 +3083,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());
@@ -3076,7 +3103,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()); // 交易金额
@@ -3101,9 +3128,9 @@ 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.setTradeType(StringUtils.isEmpty(param.getPayType()) || param.getPayType().equals("wx") ? "T_MINIAPP" : "A_NATIVE");
                         o.setOpenid(openId);
                         o.setReqSeqId("store-" + storePayment.getPayCode());
                         o.setTransAmt(storePayment.getPayMoney().toString());
@@ -3115,6 +3142,62 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                         mt.setAppId(appId);
                         storePaymentService.updateFsStorePayment(mt);
                         return R.ok().put("isPay", 0).put("data", result).put("type", "hf");
+                    } else if (merchantAppConfig.getMerchantType().equals("appPay") && "wx".equals(param.getPayType())) {
+                        //创建微信订单
+                        WxPayConfig payConfig = new WxPayConfig();
+                        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
+                        payConfig.setAppId(appId);
+                        payConfig.setMchId(fsPayConfig.getWxAppMchId());
+                        payConfig.setMchKey(fsPayConfig.getWxAppMchKey());
+                        payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
+                        payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));
+                        payConfig.setKeyPath(null);
+                        payConfig.setNotifyUrl(fsPayConfig.getWxAppNotifyUrl());
+                        wxPayService.setConfig(payConfig);
+                        WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
+                        orderRequest.setBody("药品订单支付");
+                        orderRequest.setOutTradeNo("store-"+storePayment.getPayCode());
+                        orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(storePayment.getPayMoney().toString()));
+                        orderRequest.setTradeType("APP");
+                        orderRequest.setNotifyUrl(fsPayConfig.getNotifyUrlScrm());
+                        //调用统一下单接口,获取"预支付交易会话标识"
+                        try {
+                            Object result = wxPayService.createOrder(orderRequest);
+                            return R.ok().put("data",result).put("type","wxApp").put("isPay",0);
+                        } catch (WxPayException e) {
+                            e.printStackTrace();
+                            throw new CustomException("支付失败"+e.getMessage());
+                        }
+                    } else if (merchantAppConfig.getMerchantType().equals("appPay") && "ali".equals(param.getPayType())) {
+                        // 实例化客户端
+                        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
+                        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", fsPayConfig.getAliAppId(), fsPayConfig.getAliPrivateKey(), "json", "utf-8", fsPayConfig.getAliPublicKey(), "RSA2");
+
+                        // 构造请求参数以调用接口
+                        AlipayTradeAppPayRequest aliRequest = new AlipayTradeAppPayRequest();
+                        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
+                        // 商户订单号
+                        model.setOutTradeNo("store-" + storePayment.getPayCode());
+                        // 订单总金额
+                        model.setTotalAmount(storePayment.getPayMoney().toString());
+                        // 订单标题r
+                        model.setSubject("药品订单支付");
+
+                        aliRequest.setBizModel(model);
+                        aliRequest.setNotifyUrl(fsPayConfig.getAliNotifyUrl());
+
+                        try {
+                            AlipayTradeAppPayResponse result = alipayClient.sdkExecute(aliRequest);
+                            if (!result.isSuccess()) {
+                                String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(result);
+                                log.error("支付宝支付调用失败 诊断链接:{}", diagnosisUrl);
+                                throw new CustomException(result.getSubMsg());
+                            }
+
+                            return R.ok().put("isPay", 0).put("data", result).put("type", "aliPay");
+                        } catch (Exception e){
+                            log.info("支付宝支付异常: {}", e);
+                        }
                     }
 
                 } else {
@@ -3138,8 +3221,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();
@@ -3153,7 +3246,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()
@@ -3183,7 +3276,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());
@@ -3196,10 +3289,11 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                 storePayment.setCompanyUserId(order.getCompanyUserId());
                 storePayment.setStoreId(order.getStoreId());
                 storePayment.setBusinessId(order.getOrderId().toString());
+                storePayment.setMerchantId(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("store" + storePayment.getPayCode()); // 业务系统订单号
                         o.setTrxAmt(storePayment.getPayMoney().doubleValue()); // 交易金额
@@ -3219,7 +3313,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);

+ 206 - 48
fs-service/src/main/java/com/fs/his/service/impl/FsStorePaymentServiceImpl.java

@@ -16,6 +16,13 @@ import cn.hutool.core.util.IdUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.TypeReference;
+import com.alipay.api.AlipayApiException;
+import com.alipay.api.AlipayClient;
+import com.alipay.api.DefaultAlipayClient;
+import com.alipay.api.diagnosis.DiagnosisUtils;
+import com.alipay.api.domain.AlipayTradeRefundModel;
+import com.alipay.api.request.AlipayTradeRefundRequest;
+import com.alipay.api.response.AlipayTradeRefundResponse;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -39,9 +46,10 @@ 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;
@@ -57,6 +65,9 @@ import com.fs.his.service.*;
 
 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;
 import com.fs.his.utils.PhoneUtil;
 import com.fs.his.vo.FsStorePaymentExcelVO;
 import com.fs.his.vo.FsStorePaymentVO;
@@ -136,6 +147,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
@@ -154,8 +170,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
@@ -537,7 +553,7 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
     @Autowired
     IPayService payService;
     @Override
-    public R refundFsStorePayment(Long paymentId) {
+    public R refundFsStorePayment(Long paymentId, String appId) {
         FsStorePayment fsStorePayment = fsStorePaymentMapper.selectFsStorePaymentByPaymentId(paymentId);
         if(fsStorePayment!=null){
             String orderType="";
@@ -557,12 +573,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(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.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);
@@ -670,11 +697,81 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
                 }else {
                     throw new CustomException("退款请求失败"+refund.getResp_desc());
                 }
+            } else if ("appPay".equals(fsStorePayment.getPayMode()) && "wx".equals(fsStorePayment.getPayTypeCode())) {
+                // 处理微信退款
+                WxPayService wxPayService = getWxPayService();
+                WxPayRefundRequest refundRequest = new WxPayRefundRequest();
+                refundRequest.setOutTradeNo(orderType+"-"+fsStorePayment.getPayCode());
+                refundRequest.setOutRefundNo(orderType+"-"+fsStorePayment.getPayCode());
+                refundRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(fsStorePayment.getPayMoney().toString()));
+                refundRequest.setRefundFee(WxPayUnifiedOrderRequest.yuanToFen(fsStorePayment.getPayMoney().toString()));
+                try {
+                    WxPayRefundResult refundResult = wxPayService.refund(refundRequest);
+                    WxPayRefundQueryResult refundQueryResult = wxPayService.refundQuery("", refundResult.getOutTradeNo(), refundResult.getOutRefundNo(), refundResult.getRefundId());
+                    if (refundQueryResult != null && refundQueryResult.getResultCode().equals("SUCCESS")) {
+                        FsStorePayment paymentMap = new FsStorePayment();
+                        paymentMap.setPaymentId(fsStorePayment.getPaymentId());
+                        paymentMap.setStatus(-1);
+                        paymentMap.setRefundTime(DateUtils.getNowDate());
+                        paymentMap.setRefundMoney(fsStorePayment.getPayMoney());
+                        fsStorePaymentMapper.updateFsStorePayment(paymentMap);
+                    } else {
+                        throw new CustomException("退款请求失败" + refundQueryResult.getReturnMsg());
+                    }
+
+                } catch (WxPayException e) {
+                    throw new CustomException("退款请求失败" + e);
+                }
+
+            } else if ("appPay".equals(fsStorePayment.getPayMode()) && "ali".equals(fsStorePayment.getPayTypeCode())) {
+                // 实例化客户端
+                SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
+                FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
+                AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", fsPayConfig.getAliAppId(), fsPayConfig.getAliPrivateKey(), "json", "utf-8", fsPayConfig.getAliPublicKey(), "RSA2");
+                // 构造请求参数以调用接口
+                AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
+                AlipayTradeRefundModel model = new AlipayTradeRefundModel();
+                model.setOutTradeNo(orderType+"-"+fsStorePayment.getPayCode());
+                model.setRefundAmount(fsStorePayment.getPayMoney().toString());
+                request.setBizModel(model);
+                try {
+                    AlipayTradeRefundResponse response = alipayClient.execute(request);
+                    if (response.isSuccess()) {
+                        FsStorePayment paymentMap = new FsStorePayment();
+                        paymentMap.setPaymentId(fsStorePayment.getPaymentId());
+                        paymentMap.setStatus(-1);
+                        paymentMap.setRefundTime(DateUtils.getNowDate());
+                        paymentMap.setRefundMoney(fsStorePayment.getPayMoney());
+                        fsStorePaymentMapper.updateFsStorePayment(paymentMap);
+                    } else {
+//                        String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
+                        throw new CustomException("支付宝退款请求失败" + response.getSubMsg());
+                    }
+
+                } catch (AlipayApiException e) {
+                    throw new CustomException("支付宝退款请求失败" + e);
+                }
+
             }
         }
         return R.ok();
     }
 
+
+    private WxPayService getWxPayService(){
+        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
+        FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
+        WxPayConfig payConfig = new WxPayConfig();
+        payConfig.setAppId(fsPayConfig.getWxAppAppId());
+        payConfig.setMchId(fsPayConfig.getWxAppMchId());
+        payConfig.setMchKey(fsPayConfig.getWxAppMchKey());
+        payConfig.setKeyPath(fsPayConfig.getWxAppKeyPath());
+        payConfig.setNotifyUrl(fsPayConfig.getWxAppNotifyUrl());
+        WxPayServiceImpl payService = new WxPayServiceImpl();
+        payService.setConfig(payConfig);
+        return payService;
+    }
+
     @Override
     public FsStorePayment selectFsStorePaymentByPaymentCode(String payCode) {
         return fsStorePaymentMapper.selectFsStorePaymentByPaymentCode(payCode);
@@ -1369,9 +1466,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);
@@ -1610,7 +1721,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;
     }
 
@@ -1842,8 +1953,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)) {
@@ -1856,7 +1978,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()
@@ -1901,40 +2023,76 @@ 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.setMerchantId(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("product-" + 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());
+                    //存储分账明细
+                    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;
@@ -792,12 +795,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());

+ 69 - 0
fs-service/src/main/java/com/fs/his/service/impl/FsUserIntegralLogsServiceImpl.java

@@ -1,13 +1,18 @@
 package com.fs.his.service.impl;
 
+import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.fs.common.core.domain.R;
 import com.fs.common.utils.DateUtils;
 import com.fs.his.config.IntegralConfig;
+import com.fs.his.domain.AdProfitDetail;
 import com.fs.his.domain.FsUser;
 import com.fs.his.domain.FsUserIntegralLogs;
 import com.fs.his.domain.FsUserNewTask;
 import com.fs.his.enums.FsUserIntegralLogTypeEnum;
+import com.fs.his.mapper.AdProfitDetailMapper;
 import com.fs.his.mapper.FsUserIntegralLogsMapper;
 import com.fs.his.mapper.FsUserMapper;
 import com.fs.his.mapper.FsUserNewTaskMapper;
@@ -25,7 +30,9 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
 
+import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.util.*;
 
@@ -47,6 +54,9 @@ public class FsUserIntegralLogsServiceImpl implements IFsUserIntegralLogsService
     private ISysConfigService configService;
     @Autowired
     private FsUserNewTaskMapper fsUserNewTaskMapper;
+    @Autowired
+    private AdProfitDetailMapper adProfitDetailMapper;
+
     /**
      * 查询积分记录
      *
@@ -211,11 +221,70 @@ public class FsUserIntegralLogsServiceImpl implements IFsUserIntegralLogsService
                     return addVideoIntegral(config.getIntegralFirstVideo(),config.getIntegralFinishVideo(),user.getUserId(),user.getIntegral());
                 case 3:
                     return addGameIntegral(param.getIntegral(),user.getUserId(),user.getIntegral());
+                case 5:
+                    return addAdvIntegral(param,user);
             }
         }
         return R.error("用户信息不存在");
     }
 
+    /**
+     * 添加广告积分
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public R addAdvIntegral(FsUserAddIntegralParam param, FsUser user) {
+        try {
+            // 查询用户详细分润
+            AdProfitDetail adProfitDetail = adProfitDetailMapper.selectOne(new LambdaQueryWrapper<AdProfitDetail>()
+                    .eq(AdProfitDetail::getUserId, param.getUserId())
+                    .eq(AdProfitDetail::getAdTaskId, param.getExtra()));
+            if (BeanUtil.isEmpty(adProfitDetail)) {
+                return R.error("用户没有分润信息");
+            }
+
+            // 客户分润转积分  1元=1000积分   库里存储的是单位是分: * 10
+            BigDecimal customerPoints = adProfitDetail.getUserMoney()
+                    .multiply(new BigDecimal("10"))
+                    .setScale(0, BigDecimal.ROUND_DOWN);
+
+            if (customerPoints.compareTo(BigDecimal.ZERO) <= 0) {
+                return R.error("芳华币为0,无法添加");
+            }
+
+            // 更新用户积分
+            FsUser fsUser = new FsUser();
+            fsUser.setUserId(param.getUserId());
+            long newIntegral = Objects.nonNull(user.getIntegral())
+                    ? user.getIntegral() + customerPoints.longValue()
+                    : customerPoints.longValue();
+            long newWithdrawIntegral = Objects.nonNull(user.getWithdrawIntegral())
+                    ? user.getWithdrawIntegral() + customerPoints.longValue()
+                    : customerPoints.longValue();
+            fsUser.setIntegral(newIntegral);
+            fsUser.setWithdrawIntegral(newWithdrawIntegral);
+            fsUser.setUpdateTime(new Date());
+            fsUserMapper.updateFsUser(fsUser);
+
+            // 添加积分记录
+            FsUserIntegralLogs integralLogs = new FsUserIntegralLogs();
+            integralLogs.setLogType(FsUserIntegralLogTypeEnum.TYPE_31.getValue());
+            integralLogs.setUserId(param.getUserId());
+            integralLogs.setIntegral(customerPoints.longValue());
+            integralLogs.setBalance(newIntegral); // 用计算后的新积分作为余额,避免重复计算
+            integralLogs.setCreateTime(new Date());
+            integralLogs.setNickName(user.getNickName());
+            integralLogs.setPhone(user.getPhone());
+//            fsUserIntegralLogsMapper.insertFsUserIntegralLogs(integralLogs);
+            insertFsUserIntegralLogs(integralLogs);
+            return R.ok("广告任务完成,获得" + customerPoints + "芳华币").put("integral", customerPoints);
+
+        } catch (Exception e) {
+            log.error("用户[{}]芳华币添加失败,参数:{}", param.getUserId(), JSON.toJSONString(param), e);
+            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+            return R.error("获取芳华币失败,请稍后重试");
+        }
+    }
+
     public R addGameIntegral(Long integral,Long userId,Long userIntegral) {
         FsUser userMap=new FsUser();
         userMap.setUserId(userId);

+ 200 - 8
fs-service/src/main/java/com/fs/his/service/impl/FsUserServiceImpl.java

@@ -13,9 +13,13 @@ import java.util.function.Function;
 import java.util.stream.Collectors;
 
 import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.IdUtil;
 import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.common.constant.HttpStatus;
@@ -51,14 +55,11 @@ import com.fs.his.mapper.*;
 import com.fs.his.param.FindUserByParam;
 import com.fs.his.param.FsUserAddIntegralTemplateParam;
 import com.fs.his.param.FsUserParam;
-import com.fs.his.service.IFsUserIntegralLogsService;
-import com.fs.his.service.IFsUserProjectTagService;
-import com.fs.his.service.IFsUserWxService;
+import com.fs.his.service.*;
 import com.fs.his.utils.PhoneUtil;
-import com.fs.his.vo.FsUserVO;
-import com.fs.his.vo.FsUserExportListVO;
-import com.fs.his.vo.FsUserFollowDoctorVO;
-import com.fs.his.vo.UserVo;
+import com.fs.his.utils.ProfitShareUtils;
+import com.fs.his.utils.UniAdSignUtils;
+import com.fs.his.vo.*;
 import com.fs.im.config.ImTypeConfig;
 import com.fs.im.service.OpenIMService;
 import com.fs.hisStore.domain.FsStoreOrderScrm;
@@ -87,6 +88,7 @@ import com.fs.watch.domain.vo.FsUserAndCompanyAndDoctorVo;
 import com.fs.watch.service.WatchUserService;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.client.methods.CloseableHttpResponse;
@@ -101,7 +103,6 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
-import com.fs.his.service.IFsUserService;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -115,6 +116,7 @@ import static com.fs.hisStore.enums.BillDetailEnum.CATEGORY_3;
  * @author fs
  * @date 2023-06-07
  */
+@Slf4j
 @Service
 public class FsUserServiceImpl implements IFsUserService {
     Logger logger = LoggerFactory.getLogger(getClass());
@@ -186,6 +188,15 @@ public class FsUserServiceImpl implements IFsUserService {
 
     @Autowired
     private IFsUserWxService fsUserWxService;
+    @Autowired
+    private AdProfitDetailMapper adProfitDetailMapper;
+    @Autowired
+    private IFsIntegralExchangeService fsIntegralExchangeService;
+    @Autowired
+    private IFsUserIntegralLogsService fsUserIntegralLogsService;
+    @Autowired
+    private FsUserIntegralLogsMapper fsUserIntegralLogsMapper;
+
 
 
     /**
@@ -1656,4 +1667,185 @@ public class FsUserServiceImpl implements IFsUserService {
         }
     }
 
+    /**
+     * 接收 UniApp 激励广告回调
+     */
+    @Override
+    public R uniCallBack(Map<String, Object> params) {
+        log.info("接收到uniapp激励广告回调参数:{}", params);
+
+        // 交易id
+        String transId = params.get("trans_id").toString();
+        String sign = params.get("sign").toString();
+
+        // 签名验证
+        if (!UniAdSignUtils.verifySign(transId, sign)) {
+            log.error("签名验证失败:trans_id={}, sign={}", transId, sign);
+            return R.ok().put("isValid", false);
+        }
+
+        // 防止重复回调
+        int count = adProfitDetailMapper.selectCount(new LambdaQueryWrapper<AdProfitDetail>().eq(AdProfitDetail::getAdTransId, transId));
+        if (count > 0) {
+            return R.ok().put("isValid", false);
+        }
+
+        if (!params.containsKey("cpm")){
+            log.error("uniapp广告回调cpm为空,回调参数={}", params);
+            return R.ok().put("isValid", false);
+        }
+
+        // 广告收益(元)
+        BigDecimal singleProfit = new BigDecimal(params.get("cpm").toString())
+                .divide(new BigDecimal("1000"), 6, RoundingMode.HALF_UP);
+
+        // 获取分润比例
+        String json = configService.selectConfigByKey("his.integral");
+        IntegralConfig config = JSONUtil.toBean(json, IntegralConfig.class);
+
+        List<BigDecimal> ratios = Arrays.asList(
+                config.getIntegralUserRatio(),
+                config.getIntegralCompanyRatio(),
+                config.getIntegralHuYiRatio(),
+                config.getIntegralYunLianRatio()
+        );
+
+        // 使用银行级分配算法
+        Map<Integer, BigDecimal> profitMap = ProfitShareUtils.allocate(singleProfit, ratios);
+
+        BigDecimal customerProfit = profitMap.get(0);
+        BigDecimal salesProfit    = profitMap.get(1);
+        BigDecimal huyiProfit     = profitMap.get(2);
+        BigDecimal yunlianProfit  = profitMap.get(3);
+
+        // 计算用户本次广告积分
+        BigDecimal userIntegra = customerProfit.multiply(new BigDecimal("10")).setScale(0, RoundingMode.DOWN);
+        // 配置的保底收益
+        Integer minimumIntegral = config.getMinimumIntegral();
+        boolean resultCom = userIntegra.compareTo(BigDecimal.valueOf(minimumIntegral)) < 0;
+
+        // 查询用户的销售公司
+        String companyId = adProfitDetailMapper.getCompanyByUserId(params.get("user_id").toString());
+
+        // 入库
+        AdProfitDetail adProfitDetail = new AdProfitDetail();
+        adProfitDetail.setAdTransId(transId);
+        adProfitDetail.setAdTaskId(params.get("extra").toString());
+        adProfitDetail.setSumMoney(singleProfit);
+        adProfitDetail.setUserId(Long.valueOf(params.get("user_id").toString()));
+        // 如果用户收益小于保底收益,直接给用户保底 并且不进行分润
+        if (resultCom) {
+            adProfitDetail.setUserMoney(BigDecimal.valueOf(minimumIntegral).divide(new BigDecimal("10"),2,RoundingMode.DOWN));
+        } else {
+            adProfitDetail.setUserMoney(customerProfit);
+            adProfitDetail.setCompanyMoney(salesProfit);
+            adProfitDetail.setHuyiMoney(huyiProfit);
+            adProfitDetail.setYunlianMoney(yunlianProfit);
+        }
+
+
+        adProfitDetail.setCompanyId(
+                StringUtils.isNotEmpty(companyId) ? Long.valueOf(companyId) : null
+        );
+
+        adProfitDetail.setCreateTime(LocalDateTime.now());
+        adProfitDetail.setOriginParam(JSON.toJSONString(params));
+
+        int result = adProfitDetailMapper.insert(adProfitDetail);
+
+        return R.ok().put("isValid", result > 0);
+    }
+
+
+    /**
+     * uniapp广告 返回一个广告id
+     */
+    @Override
+    public R createLogs(Long userId) {
+        String adTaskId = IdUtil.fastSimpleUUID() + userId;
+        return R.ok().put("extra", adTaskId);
+    }
+
+    /**
+     * 获取用户钱包明细
+     */
+    @Override
+    public R getWallet(Long userId) {
+        IntegralExchangeVo vo = fsUserMapper.getWallet(userId);
+        vo.setMayWithdraw(vo.getMayWithdraw().divide(BigDecimal.valueOf(100)));
+        vo.setTotalCommission(vo.getTotalCommission().divide(BigDecimal.valueOf(100)));
+        vo.setWithdrawFinish(vo.getWithdrawFinish().divide(BigDecimal.valueOf(100)));
+        vo.setWithdrawCash(new BigDecimal(vo.getWithdrawIntegral()).divide(BigDecimal.valueOf(1000),2,RoundingMode.DOWN));
+        return R.ok().put("data", vo);
+    }
+
+    /**
+     * 用户钱包 积分兑换佣金
+     */
+    @Override
+    //@Transactional(rollbackFor = Exception.class)
+    public R integralExchange(Long userId) {
+        // 查询用户钱包明细
+        FsUser fsUser = fsUserMapper.selectFsUserByUserId(userId);
+        if (BeanUtil.isEmpty(fsUser)) {
+            return R.error("用户不存在");
+        }
+
+        Long withdrawIntegral = fsUser.getWithdrawIntegral();
+        if (withdrawIntegral < 0){
+            return R.error("积分不足");
+        }
+
+        // 积分转金额  1元=1000积分   库里存储的是单位是分:÷10
+        BigDecimal commission = new BigDecimal(withdrawIntegral ).divide(BigDecimal.valueOf(10),2,RoundingMode.DOWN);
+        // 更新用户积分 佣金
+        FsUser user = new FsUser();
+        user.setUserId(userId);
+        user.setIntegral(fsUser.getIntegral() - withdrawIntegral);
+        user.setWithdrawIntegral(0L);
+        user.setTotalCommission(fsUser.getTotalCommission().add(commission));
+        user.setUpdateTime(new Date());
+        user.setMayWithdraw(fsUser.getMayWithdraw().add(commission));
+        fsUserMapper.updateFsUser(user);
+        FsIntegralExchange fsIntegralExchange = new FsIntegralExchange();
+        fsIntegralExchange.setUserId(userId);
+        fsIntegralExchange.setNickName(fsUser.getNickName());
+        fsIntegralExchange.setPhone(fsUser.getPhone());
+        fsIntegralExchange.setCreateTime(new Date());
+        fsIntegralExchange.setIntegral(-withdrawIntegral);
+        fsIntegralExchangeService.insertFsIntegralExchange(fsIntegralExchange);
+        //添加积分记录
+        FsUserIntegralLogs logs = new FsUserIntegralLogs();
+        logs.setUserId(userId);
+        if(fsIntegralExchange.getId() != null){
+            logs.setBusinessId(fsIntegralExchange.getId().toString());
+        }
+        logs.setLogType(FsUserIntegralLogTypeEnum.TYPE_32.getValue());
+        logs.setIntegral(-withdrawIntegral);
+        logs.setBalance(fsUser.getIntegral() - withdrawIntegral);
+        logs.setCreateTime(new Date());
+        logs.setNickName(StringUtils.isNotEmpty(fsUser.getNickName()) ? fsUser.getNickName() : null);
+        logs.setPhone(fsUser.getPhone());
+        fsUserIntegralLogsService.insertFsUserIntegralLogs(logs);
+        return R.ok("兑换成功");
+    }
+
+    /**
+     * 用户钱包 获取兑换明细
+     */
+    @Override
+    public R exchangDetail(Map<String, Object> params) {
+        PageHelper.startPage(Integer.parseInt(params.get("page").toString()), Integer.parseInt(params.get("limit").toString()));
+        ExchangeDetailVo detailVo = new ExchangeDetailVo();
+        detailVo.setUserId(Long.valueOf(params.get("userId").toString()));
+        detailVo.setLogType(FsUserIntegralLogTypeEnum.TYPE_32.getValue());
+        // 查询积分记录
+        List<ExchangeDetailVo> logsList =fsUserIntegralLogsMapper.getExchangDetailList(detailVo);
+        PageInfo<ExchangeDetailVo> logsPageInfo = new PageInfo<>(logsList);
+        Map<String,Object> rMap = new HashMap<>();
+        rMap.put("rows", logsPageInfo.getList());
+        rMap.put("total", logsPageInfo.getTotal());
+        return R.ok().put("data", rMap);
+    }
+
 }

+ 6 - 0
fs-service/src/main/java/com/fs/his/service/impl/MerchantAppConfigServiceImpl.java

@@ -131,6 +131,9 @@ public class MerchantAppConfigServiceImpl extends ServiceImpl<MerchantAppConfigM
                 merchantAppConfig.setMerchantId(fsPayConfig.getHuifuId());
                 merchantAppConfig.setCallbackUrl(fsPayConfig.getHfPayNotifyUrl());
                 break;
+            case "appPay": // app官方支付
+                merchantAppConfig.setMerchantId(fsPayConfig.getAliAppId() + "&" + fsPayConfig.getWxAppMchId());
+                break;
             default:
                 throw new RuntimeException("商户类型错误");
         }
@@ -166,6 +169,9 @@ public class MerchantAppConfigServiceImpl extends ServiceImpl<MerchantAppConfigM
                 merchantAppConfig.setMerchantId(fsPayConfig.getHuifuId());
                 merchantAppConfig.setCallbackUrl(fsPayConfig.getHfPayNotifyUrl());
                 break;
+            case "appPay": // app官方支付
+                merchantAppConfig.setMerchantId(fsPayConfig.getAliAppId() + "&" + fsPayConfig.getWxAppMchId());
+                break;
             default:
                 throw new RuntimeException("商户类型错误");
         }

+ 76 - 0
fs-service/src/main/java/com/fs/his/utils/ProfitShareUtils.java

@@ -0,0 +1,76 @@
+package com.fs.his.utils;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ProfitShareUtils {
+
+    /**
+     * 分润项内部结构(用于排序与临时计算)
+     */
+    private static class CalcItem {
+        int index;              // 下标(保持原顺序)
+        int integerPart;        // 截断后的整数部分(分)
+        BigDecimal decimalPart; // 小数部分
+        CalcItem(int index, int integerPart, BigDecimal decimalPart) {
+            this.index = index;
+            this.integerPart = integerPart;
+            this.decimalPart = decimalPart;
+        }
+    }
+
+    /**
+     * 分润核心算法:银行级最小单位分配法
+     *
+     * @param total 总金额(元)
+     * @param ratios 比例列表(合计建议为 1)
+     * @return Map<Integer, BigDecimal>   key = 下标,value = 金额(元)
+     */
+    public static Map<Integer, BigDecimal> allocate(BigDecimal total, List<BigDecimal> ratios) {
+
+        if (total == null || ratios == null || ratios.isEmpty()) {
+            throw new IllegalArgumentException("金额或比例不能为空");
+        }
+
+        // 金额换算成分(总金额必须是合法金额,能够 *100 得到整数)
+        BigDecimal totalCentBD = total.multiply(new BigDecimal("100"));
+        int totalCent = totalCentBD.intValue();
+
+        List<CalcItem> calcs = new ArrayList<>();
+        int sumInteger = 0;
+
+        // 1) 计算每项理论金额(单位:分)
+        for (int i = 0; i < ratios.size(); i++) {
+
+            BigDecimal raw = totalCentBD.multiply(ratios.get(i)); // 理论分
+            int integerPart = raw.setScale(0, BigDecimal.ROUND_DOWN).intValue();
+            BigDecimal decimalPart = raw.subtract(new BigDecimal(integerPart)); // 小数部分
+
+            sumInteger += integerPart;
+            calcs.add(new CalcItem(i, integerPart, decimalPart));
+        }
+
+        // 2) 计算剩余分
+        int remain = totalCent - sumInteger;
+
+        // 3) 按小数从大到小分配剩余分
+        calcs.sort((a, b) -> b.decimalPart.compareTo(a.decimalPart));
+
+        for (int i = 0; i < remain; i++) {
+            calcs.get(i).integerPart += 1;
+        }
+
+        // 4) 输出结果(元)
+        Map<Integer, BigDecimal> result = new HashMap<>();
+        for (CalcItem c : calcs) {
+            BigDecimal yuan = new BigDecimal(c.integerPart)
+                    .divide(new BigDecimal("100"), 2, BigDecimal.ROUND_DOWN);
+            result.put(c.index, yuan);
+        }
+
+        return result;
+    }
+}

+ 30 - 0
fs-service/src/main/java/com/fs/his/utils/UniAdSignUtils.java

@@ -0,0 +1,30 @@
+package com.fs.his.utils;
+
+import cn.hutool.crypto.digest.DigestAlgorithm;
+import cn.hutool.crypto.digest.Digester;
+
+/**
+ * UniApp激励广告回调签名验证工具类
+ */
+public class UniAdSignUtils {
+    // 广告位secret
+    private static final String UNI_AD_SECRET = "1e2aa28a5e7d50f5013f2ffd8b4fd8fbd5ec85e1d83b0e5aedb6bd666b4b0b7e";
+
+    /**
+     * 验证UniApp广告回调签名
+     * 签名规则:sign = sha256(secret + trans_id)
+     * @param transId      回调参数中的trans_id(唯一交易ID)
+     * @param receivedSign 回调参数中收到的sign
+     * @return 签名是否有效
+     */
+    public static boolean verifySign(String transId, String receivedSign) {
+        // 校验参数合法性
+        if (transId == null || receivedSign == null) {
+            return false;
+        }
+
+        Digester sha256 = new Digester(DigestAlgorithm.SHA256);
+        String sign = sha256.digestHex(UNI_AD_SECRET + ":" + transId);
+        return sign.equals(receivedSign);
+    }
+}

+ 23 - 0
fs-service/src/main/java/com/fs/his/vo/ExchangeDetailVo.java

@@ -0,0 +1,23 @@
+package com.fs.his.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 积分兑换佣金明细
+ */
+
+@Data
+public class ExchangeDetailVo {
+    private  Long id;
+    private  Long  userId;
+    private Integer logType;
+    private Long integral;
+    private Long balance;
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createTime;
+    private BigDecimal commission;
+}

+ 22 - 0
fs-service/src/main/java/com/fs/his/vo/IntegralExchangeVo.java

@@ -0,0 +1,22 @@
+package com.fs.his.vo;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class IntegralExchangeVo {
+    private Long userId;
+    // 总积分
+    private Long integral;
+    // 可提现佣金
+    private BigDecimal mayWithdraw;
+    // 可兑换积分
+    private Long withdrawIntegral;
+    // 累计佣金
+    private BigDecimal totalCommission;
+    // 已提现佣金
+    private BigDecimal withdrawFinish;
+    // 可兑换现金
+    private BigDecimal withdrawCash;
+}

+ 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;
 
 }

+ 38 - 6
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,13 +1530,24 @@ 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(fsCoursePlaySourceConfig.getAppid());
                 payConfig.setMchId(fsPayConfig.getWxMchId());
                 payConfig.setMchKey(fsPayConfig.getWxMchKey());
                 payConfig.setKeyPath(wxPayProperties.getKeyPath());

+ 96 - 33
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java

@@ -48,8 +48,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.*;
@@ -179,7 +181,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 +189,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;
@@ -2484,13 +2489,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(fsCoursePlaySourceConfig.getAppid());
                         payConfig.setMchId(fsPayConfig.getWxMchId());
                         payConfig.setMchKey(fsPayConfig.getWxMchKey());
                         payConfig.setKeyPath(fsPayConfig.getKeyPath());
@@ -4268,12 +4284,23 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
             }
             String payCode =  OrderCodeUtils.getOrderSn();
             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 +4312,10 @@ 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());
                 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());
@@ -4320,9 +4347,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 +4432,28 @@ 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 =  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());
@@ -4426,7 +4467,7 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
             storePayment.setIsPayRemain(1);
             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 +4490,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 +4563,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");
@@ -4543,7 +4595,7 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
             storePayment.setOrderId(order.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());
@@ -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());
@@ -4644,7 +4707,7 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
             storePayment.setIsPayRemain(1);
             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 +4731,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));

+ 92 - 36
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStorePaymentScrmServiceImpl.java

@@ -24,9 +24,12 @@ 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,13 +38,15 @@ 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;
@@ -70,6 +75,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;
@@ -105,11 +111,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 +893,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();
 
@@ -927,37 +946,74 @@ public class FsStorePaymentScrmServiceImpl implements IFsStorePaymentScrmService
         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);
-        }
-        else{
-            return R.error(result.getResp_desc());
+        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("product-" + 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());
+                    //存储分账明细
+                    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

+ 36 - 2
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);
@@ -50,7 +58,7 @@ public class HuiFuServiceImpl implements HuiFuService {
                     doInit(getMerConfig(fsHfpayConfig));
                 } else {
                     //多小程序
-                    doInit(getMerConfig());
+                    doInit(getMerConfig(order.getAppId()));
                 }
             } else {
                 doInit(getMerConfig());
@@ -402,4 +410,30 @@ public class HuiFuServiceImpl implements HuiFuService {
         config = fsPayConfig;
         return merConfig;
     }
+
+    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(fsPayConfig.getHfProductId());
+        merConfig.setSysId(fsPayConfig.getHfSysId());
+        merConfig.setRsaPrivateKey(fsPayConfig.getHfRsaPrivateKey());
+        merConfig.setRsaPublicKey(fsPayConfig.getHfRsaPublicKey());
+        merConfig.setHuifuId(fsPayConfig.getHuifuId());
+
+        config = fsPayConfig;
+        return merConfig;
+    }
 }

+ 4 - 0
fs-service/src/main/java/com/fs/system/mapper/SysConfigMapper.java

@@ -1,6 +1,8 @@
 package com.fs.system.mapper;
 
 import java.util.List;
+
+import com.fs.his.domain.MerchantAppConfig;
 import com.fs.system.domain.SysConfig;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Select;
@@ -71,4 +73,6 @@ public interface SysConfigMapper
 
     @Select("select * from sys_config where config_key=#{configKey}")
     SysConfig selectConfigByConfigKey(String configKey);
+
+    MerchantAppConfig getPayConfig(String appId);
 }

+ 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");

+ 135 - 0
fs-service/src/main/resources/mapper/his/AdProfitDetailMapper.xml

@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fs.his.mapper.AdProfitDetailMapper">
+    <resultMap type="AdProfitDetail" id="AdProfitDetailResult">
+        <result property="id"    column="id"    />
+        <result property="adTransId"    column="ad_trans_id"    />
+        <result property="adTaskId"    column="ad_task_id"    />
+        <result property="sumMoney"    column="sum_money"    />
+        <result property="userId"    column="user_id"    />
+        <result property="userMoney"    column="user_money"    />
+        <result property="companyId"    column="company_id"    />
+        <result property="companyMoney"    column="company_money"    />
+        <result property="huyiMoney"    column="huyi_money"    />
+        <result property="yunlianMoney"    column="yunlian_money"    />
+        <result property="createTime"    column="create_time"    />
+    </resultMap>
+
+    <sql id="selectAdProfitDetailVo">
+        select id, ad_trans_id, ad_task_id, sum_money, user_id, user_money, company_id, company_money, huyi_money, yunlian_money, create_time from ad_profit_detail
+    </sql>
+
+
+
+    <select id="selectAdProfitDetailById" parameterType="Long" resultMap="AdProfitDetailResult">
+        <include refid="selectAdProfitDetailVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertAdProfitDetail" parameterType="AdProfitDetail" useGeneratedKeys="true" keyProperty="id">
+        insert into ad_profit_detail
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="adTransId != null and adTransId != ''">ad_trans_id,</if>
+            <if test="adTaskId != null">ad_task_id,</if>
+            <if test="sumMoney != null">sum_money,</if>
+            <if test="userId != null">user_id,</if>
+            <if test="userMoney != null">user_money,</if>
+            <if test="companyId != null">company_id,</if>
+            <if test="companyMoney != null">company_money,</if>
+            <if test="huyiMoney != null">huyi_money,</if>
+            <if test="yunlianMoney != null">yunlian_money,</if>
+            <if test="createTime != null">create_time,</if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="adTransId != null and adTransId != ''">#{adTransId},</if>
+            <if test="adTaskId != null">#{adTaskId},</if>
+            <if test="sumMoney != null">#{sumMoney},</if>
+            <if test="userId != null">#{userId},</if>
+            <if test="userMoney != null">#{userMoney},</if>
+            <if test="companyId != null">#{companyId},</if>
+            <if test="companyMoney != null">#{companyMoney},</if>
+            <if test="huyiMoney != null">#{huyiMoney},</if>
+            <if test="yunlianMoney != null">#{yunlianMoney},</if>
+            <if test="createTime != null">#{createTime},</if>
+        </trim>
+    </insert>
+
+    <update id="updateAdProfitDetail" parameterType="AdProfitDetail">
+        update ad_profit_detail
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="adTransId != null and adTransId != ''">ad_trans_id = #{adTransId},</if>
+            <if test="adTaskId != null">ad_task_id = #{adTaskId},</if>
+            <if test="sumMoney != null">sum_money = #{sumMoney},</if>
+            <if test="userId != null">user_id = #{userId},</if>
+            <if test="userMoney != null">user_money = #{userMoney},</if>
+            <if test="companyId != null">company_id = #{companyId},</if>
+            <if test="companyMoney != null">company_money = #{companyMoney},</if>
+            <if test="huyiMoney != null">huyi_money = #{huyiMoney},</if>
+            <if test="yunlianMoney != null">yunlian_money = #{yunlianMoney},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteAdProfitDetailById" parameterType="Long">
+        delete from ad_profit_detail where id = #{id}
+    </delete>
+
+    <delete id="deleteAdProfitDetailByIds" parameterType="String">
+        delete from ad_profit_detail where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+
+    <select id="getCompanyByUserId" resultType="java.lang.String">
+        SELECT
+            company_id
+        FROM
+            `qw_external_contact`
+        WHERE
+            fs_user_id = #{userId}
+        ORDER BY
+            create_time ASC LIMIT 1
+    </select>
+
+    <select id="selectAdProfitDetailList" resultType="com.fs.his.dto.AdProfitDetailDto">
+        SELECT
+        a.*,
+        b.company_name,
+        c.nick_name
+        FROM
+        `ad_profit_detail` a
+        LEFT JOIN company b ON a.company_id = b.company_id
+        LEFT JOIN fs_user c ON a.user_id = c.user_id
+        <where>
+            <if test="adTransId != null  and adTransId != ''"> and a.ad_trans_id = #{adTransId}</if>
+            <if test="adTaskId != null  and adTaskId != ''"> and a.ad_task_id = #{adTaskId}</if>
+            <if test="sumMoney != null "> and a.sum_money = #{sumMoney}</if>
+            <if test="userId != null "> and a.user_id = #{userId}</if>
+            <if test="userMoney != null "> and a.user_money = #{userMoney}</if>
+            <if test="companyId != null "> and a.company_id = #{companyId}</if>
+            <if test="companyMoney != null "> and a.company_money = #{companyMoney}</if>
+            <if test="huyiMoney != null "> and a.huyi_money = #{huyiMoney}</if>
+            <if test="yunlianMoney != null "> and a.yunlian_money = #{yunlianMoney}</if>
+            <if test="companyName != null"> and b.company_name = #{companyName}</if>
+            <if test="sTime != null"> and Date(a.create_time) &gt;= Date(#{sTime})</if>
+            <if test="eTime != null"> and Date(a.create_time) &lt;= Date(#{eTime})</if>
+            <if test="nickName != null"> and c.nick_name like concat('%',#{nickName},'%')</if>
+        </where>
+        order by a.create_time desc
+    </select>
+
+    <select id="getWithFinishAndMayWithdraw" resultType="java.util.Map">
+        SELECT
+            SUM(may_withdraw) AS totalMayWithdraw,
+            SUM(withdraw_finish) AS totalWithdrawFinish
+        FROM
+            fs_user
+        WHERE
+            may_withdraw > 0.00
+           OR withdraw_finish > 0.00
+    </select>
+
+
+</mapper>

+ 70 - 0
fs-service/src/main/resources/mapper/his/FsIntegralExchangeMapper.xml

@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fs.his.mapper.FsIntegralExchangeMapper">
+
+    <resultMap type="FsIntegralExchange" id="FsIntegralExchangeResult">
+        <result property="id"    column="id"    />
+        <result property="userId"    column="user_id"    />
+        <result property="integral"    column="integral"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="status"    column="status"    />
+        <result property="phone"    column="phone"    />
+        <result property="nickName"    column="nick_name"    />
+    </resultMap>
+
+    <sql id="selectFsIntegralExchangeVo">
+        select id, user_id, integral, create_time, status, phone, nick_name from fs_integral_exchange
+    </sql>
+
+    <select id="selectFsIntegralExchangeList" parameterType="FsIntegralExchange" resultMap="FsIntegralExchangeResult">
+        <include refid="selectFsIntegralExchangeVo"/>
+        <where>
+            <if test="userId != null "> and user_id = #{userId}</if>
+            <if test="integral != null "> and integral = #{integral}</if>
+            <if test="status != null "> and status = #{status}</if>
+            <if test="phone != null  and phone != ''"> and phone = #{phone}</if>
+            <if test="nickName != null  and nickName != ''"> and nick_name like concat('%', #{nickName}, '%')</if>
+        </where>
+    </select>
+
+    <select id="selectFsIntegralExchangeById" parameterType="Long" resultMap="FsIntegralExchangeResult">
+        <include refid="selectFsIntegralExchangeVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertFsIntegralExchange"
+            parameterType="com.fs.his.domain.FsIntegralExchange"
+            useGeneratedKeys="true"
+            keyProperty="id">
+        insert into fs_integral_exchange
+            (user_id, integral, create_time, status, phone, nick_name)
+        values
+            (#{userId}, #{integral}, #{createTime}, #{status}, #{phone}, #{nickName})
+    </insert>
+
+    <update id="updateFsIntegralExchange" parameterType="FsIntegralExchange">
+        update fs_integral_exchange
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="userId != null">user_id = #{userId},</if>
+            <if test="integral != null">integral = #{integral},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="phone != null">phone = #{phone},</if>
+            <if test="nickName != null">nick_name = #{nickName},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteFsIntegralExchangeById" parameterType="Long">
+        delete from fs_integral_exchange where id = #{id}
+    </delete>
+
+    <delete id="deleteFsIntegralExchangeByIds" parameterType="String">
+        delete from fs_integral_exchange where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</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="merchantId != null">merchant_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="merchantId != null">#{merchantId},</if>
          </trim>
     </insert>
 

+ 17 - 0
fs-service/src/main/resources/mapper/his/FsUserIntegralLogsMapper.xml

@@ -61,6 +61,23 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </select>
 
 
+    <select id="getExchangDetailList" resultType="com.fs.his.vo.ExchangeDetailVo">
+        SELECT
+            id,
+            user_id,
+            log_type,
+            integral,
+            balance,
+            create_time,
+            ROUND(ABS(integral / 1000), 3) AS commission
+        FROM
+            fs_user_integral_logs
+        WHERE
+            user_id = #{userId}
+          AND log_type = #{logType}
+        order by create_time desc
+    </select>
+
     <insert id="insertFsUserIntegralLogs" parameterType="FsUserIntegralLogs" useGeneratedKeys="true" keyProperty="id">
         insert into fs_user_integral_logs
         <trim prefix="(" suffix=")" suffixOverrides=",">

+ 4 - 0
fs-service/src/main/resources/mapper/his/FsUserMapper.xml

@@ -2472,5 +2472,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         order by user_id desc
     </select>
 
+    <select id="getWallet" resultType="com.fs.his.vo.IntegralExchangeVo">
+        SELECT user_id,integral, withdraw_integral, total_commission, withdraw_finish,may_withdraw FROM fs_user WHERE user_id = #{userId}
+    </select>
+
 
 </mapper>

+ 11 - 1
fs-service/src/main/resources/mapper/system/SysConfigMapper.xml

@@ -63,7 +63,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <include refid="selectConfigVo"/>
         where config_key = #{configKey} limit 1
     </select>
-    
+
+    <select id="getPayConfig" resultType="com.fs.his.domain.MerchantAppConfig">
+        SELECT
+            b.*
+        FROM
+            `fs_course_play_source_config` a
+                LEFT JOIN merchant_app_config b ON a.merchant_config_id = b.id
+        WHERE
+            a.appid = #{appId}
+    </select>
+
     <insert id="insertConfig" parameterType="SysConfig">
         insert into sys_config (
 			<if test="configName != null and configName != '' ">config_name,</if>

+ 86 - 0
fs-user-app/src/main/java/com/fs/app/controller/AppPayController.java

@@ -0,0 +1,86 @@
+package com.fs.app.controller;
+
+
+import com.fs.app.service.AppPayService;
+import com.fs.common.core.domain.R;
+import com.fs.his.domain.FsPayConfig;
+import com.fs.system.domain.SysConfig;
+import com.fs.system.mapper.SysConfigMapper;
+import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
+import com.github.binarywang.wxpay.config.WxPayConfig;
+import com.github.binarywang.wxpay.exception.WxPayException;
+import com.github.binarywang.wxpay.service.WxPayService;
+import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
+import com.google.gson.Gson;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+@Slf4j
+@Api("app支付接口")
+@RestController
+@RequestMapping("/appPay")
+public class AppPayController extends AppBaseController {
+
+    @Autowired
+    private AppPayService appPayService;
+    @Autowired
+    private SysConfigMapper sysConfigMapper;
+
+    @ApiOperation("支付宝回调")
+    @PostMapping("/aliNotify")
+    public String aliNotify(HttpServletRequest request) {
+        Map<String, String> params = new HashMap<String, String>();
+        Map requestParams = request.getParameterMap();
+        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
+            String name = (String) iter.next();
+            String[] values = (String[]) requestParams.get(name);
+            String valueStr = "";
+            for (int i = 0; i < values.length; i++) {
+                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
+            }
+            //乱码解决,这段代码在出现乱码时使用。
+            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
+            params.put(name, valueStr);
+        }
+        return appPayService.aliNotify(params);
+    }
+
+
+
+    @ApiOperation("微信支付回调")
+    @PostMapping("/wxNotify")
+    public String wxNotify(@RequestBody String xmlData) throws WxPayException {
+        WxPayService payService = getWxPayService();
+        WxPayOrderNotifyResult result = payService.parseOrderNotifyResult(xmlData);
+        return appPayService.wxNotify(result);
+    }
+
+    @ApiOperation("获取支付配置")
+    @GetMapping("/getPayConfig")
+    public R getPayConfig(@RequestParam String appId){
+        return appPayService.getPayConfig(appId);
+    }
+
+
+    private WxPayService getWxPayService(){
+        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.pay");
+        FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
+        WxPayConfig payConfig = new WxPayConfig();
+        payConfig.setAppId(fsPayConfig.getWxAppAppId());
+        payConfig.setMchId(fsPayConfig.getWxAppMchId());
+        payConfig.setMchKey(fsPayConfig.getWxAppMchKey());
+        payConfig.setKeyPath(fsPayConfig.getWxAppKeyPath());
+        payConfig.setNotifyUrl(fsPayConfig.getWxAppNotifyUrl());
+        WxPayServiceImpl payService = new WxPayServiceImpl();
+        payService.setConfig(payConfig);
+        return payService;
+    }
+}

+ 40 - 0
fs-user-app/src/main/java/com/fs/app/controller/CommonController.java

@@ -688,4 +688,44 @@ public class CommonController {
 		StoreConfig config=JSONUtil.toBean(json,StoreConfig.class);
 		return R.ok(config.getJumpStoreAppId());
 	}
+
+	/**
+	 * 接收 UniApp 激励广告回调
+	 */
+	@GetMapping("/uniCallBack")
+	public R uniCallBack(@RequestParam Map<String,Object> params){
+		return userService.uniCallBack(params);
+	}
+
+	/**
+	 * uniapp广告 返回一个广告id
+	 */
+	@PostMapping("/createLogs")
+	public R createLogs(@RequestBody Map<String,Object> params){
+		return userService.createLogs(Long.valueOf(params.get("userId").toString()));
+	}
+
+	/**
+	 * 获取用户钱包明细
+	 */
+	@GetMapping("/getWallet/{userId}")
+	public R getWallet(@PathVariable("userId") Long userId){
+		return userService.getWallet(userId);
+	}
+
+	/**
+	 * 用户钱包 积分兑换佣金
+	 */
+	@GetMapping("/integralExchange/{userId}")
+	public R integralExchange(@PathVariable("userId") Long userId){
+		return userService.integralExchange(userId);
+	}
+
+	/**
+	 * 用户钱包 获取兑换明细
+	 */
+	@PostMapping("/exchangDetail")
+	public R exchangDetail(@RequestBody Map<String,Object> params){
+		return userService.exchangDetail(params);
+	}
 }

+ 138 - 37
fs-user-app/src/main/java/com/fs/app/controller/InquiryOrderController.java

@@ -2,6 +2,14 @@ package com.fs.app.controller;
 
 
 import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson.JSON;
+import com.alipay.api.AlipayApiException;
+import com.alipay.api.AlipayClient;
+import com.alipay.api.DefaultAlipayClient;
+import com.alipay.api.diagnosis.DiagnosisUtils;
+import com.alipay.api.domain.AlipayTradeAppPayModel;
+import com.alipay.api.request.AlipayTradeAppPayRequest;
+import com.alipay.api.response.AlipayTradeAppPayResponse;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.app.annotation.Login;
@@ -15,6 +23,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 +36,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;
@@ -50,6 +61,7 @@ import com.github.pagehelper.PageInfo;
 import com.google.gson.Gson;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.logging.log4j.core.LogEvent;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -63,6 +75,7 @@ import java.math.BigDecimal;
 import java.util.*;
 
 
+@Slf4j
 @Api("订单接口")
 @RestController
 @RequestMapping(value="/app/inquiryOrder")
@@ -93,8 +106,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
@@ -113,6 +129,8 @@ public class InquiryOrderController extends  AppBaseController {
     private ISysConfigService configService;
     @Autowired
     private IFsUserWxService userWxService;
+    @Autowired
+    private IFsUserService fsUserService;
     @Login
     @ApiOperation("确认订单")
     @PostMapping("/confirm")
@@ -173,9 +191,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 +271,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);
@@ -279,28 +306,34 @@ public class InquiryOrderController extends  AppBaseController {
 
         String openId = null;
         String appId = param.getAppId();
-        if (StringUtils.isNotBlank(appId)) {
-            //查询fs_user_wx的openId
-            Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
-                    .eq(FsUserWx::getFsUserId, param.getUserId())
-                    .eq(FsUserWx::getAppId, appId);
-            FsUserWx fsUserWx = fsUserWxMapper.selectOne(queryWrapper);
-            if (fsUserWx != null) {
-                openId = fsUserWx.getOpenId();
-            }
+        if (request.getHeader("sourcetype") != null && "APP".equals(request.getHeader("sourcetype"))) {
+            FsUser fsUser = fsUserService.selectFsUserByUserId(param.getUserId().longValue());
+            openId = fsUser.getAppOpenId();
         } else {
-            appId = payConfigDTO.getAppId();
-            openId = Objects.isNull(user) ? "" : user.getMaOpenId();
-            if (StringUtils.isBlank(openId)){
+            if (StringUtils.isNotBlank(appId)) {
+                //查询fs_user_wx的openId
                 Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
                         .eq(FsUserWx::getFsUserId, param.getUserId())
                         .eq(FsUserWx::getAppId, appId);
                 FsUserWx fsUserWx = fsUserWxMapper.selectOne(queryWrapper);
-                if (Objects.nonNull(fsUserWx)){
+                if (fsUserWx != null) {
                     openId = fsUserWx.getOpenId();
                 }
+            } else {
+                appId = merchantAppConfig.getAppId();
+                openId = Objects.isNull(user) ? "" : user.getMaOpenId();
+                if (StringUtils.isBlank(openId)){
+                    Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
+                            .eq(FsUserWx::getFsUserId, param.getUserId())
+                            .eq(FsUserWx::getAppId, appId);
+                    FsUserWx fsUserWx = fsUserWxMapper.selectOne(queryWrapper);
+                    if (Objects.nonNull(fsUserWx)){
+                        openId = fsUserWx.getOpenId();
+                    }
+                }
             }
         }
+
         //String json=configService.selectConfigByKey("his.pay");
         //PayConfigDTO payConfigDTO= JSONUtil.toBean(json, PayConfigDTO.class);
 
@@ -319,7 +352,7 @@ public class InquiryOrderController extends  AppBaseController {
 //            }
 //        }
 
-        if (StringUtils.isBlank(openId)){
+        if ((!"appPay".equals(merchantAppConfig.getMerchantType()) && (StringUtils.isBlank(openId) || ("hf".equals(merchantAppConfig.getMerchantType()) && "wx".equals(param.getPayType())) ))) {
             return R.error("用户OPENID不存在");
         }
 
@@ -334,25 +367,24 @@ public class InquiryOrderController extends  AppBaseController {
             }
             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());
             storePayment.setBusinessCode(order.getOrderSn());
             storePayment.setPayMoney(order.getPayMoney());
             storePayment.setCreateTime(new Date());
-            storePayment.setPayTypeCode("weixin");
+            storePayment.setPayTypeCode(!"appPay".equals(merchantAppConfig.getMerchantType()) ? "weixin" : param.getPayType());
             storePayment.setBusinessType(1);
             storePayment.setRemark("问诊订单支付");
             storePayment.setOpenId(openId);
             storePayment.setUserId(user.getUserId());
             storePayment.setBusinessId(order.getOrderId().toString());
+            storePayment.setMerchantId(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());
@@ -378,7 +410,7 @@ public class InquiryOrderController extends  AppBaseController {
                         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());
@@ -400,7 +432,7 @@ public class InquiryOrderController extends  AppBaseController {
                         throw new CustomException("支付失败");
                     }
                 }
-                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()); // 交易金额
@@ -425,9 +457,9 @@ 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("T_MINIAPP");
+                    o.setTradeType(StringUtils.isEmpty(param.getPayType()) || param.getPayType().equals("wx") ? "T_MINIAPP" : "A_NATIVE");
                     o.setOpenid(openId);
                     o.setAppId(appId);
                     o.setReqSeqId("inquiry-"+storePayment.getPayCode());
@@ -441,6 +473,62 @@ public class InquiryOrderController extends  AppBaseController {
                     mt.setAppId(appId);
                     storePaymentService.updateFsStorePayment(mt);
                     return R.ok().put("isPay",0).put("data",result).put("type","hf");
+                } else if (merchantAppConfig.getMerchantType().equals("appPay") && "wx".equals(param.getPayType())) {
+                    //创建微信订单
+                    WxPayConfig payConfig = new WxPayConfig();
+                    payConfig.setAppId(appId);
+                    payConfig.setMchId(fsPayConfig.getWxAppMchId());
+                    payConfig.setMchKey(fsPayConfig.getWxAppMchKey());
+                    payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
+                    payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));
+                    payConfig.setKeyPath(null);
+                    payConfig.setNotifyUrl(fsPayConfig.getWxAppNotifyUrl());
+                    wxPayService.setConfig(payConfig);
+                    WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
+                    orderRequest.setBody("问诊订单支付");
+                    orderRequest.setOutTradeNo("inquiry-"+storePayment.getPayCode());
+                    orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(storePayment.getPayMoney().toString()));
+                    orderRequest.setTradeType("APP");
+                    orderRequest.setSpbillCreateIp(IpUtils.getIpAddr(request));
+                    orderRequest.setNotifyUrl(fsPayConfig.getNotifyUrlScrm());
+                    //调用统一下单接口,获取"预支付交易会话标识"
+                    try {
+                        Object result = wxPayService.createOrder(orderRequest);
+                        return R.ok().put("data",result).put("type","wxApp").put("isPay",0);
+                    } catch (WxPayException e) {
+                        e.printStackTrace();
+                        throw new CustomException("支付失败"+e.getMessage());
+                    }
+                } else if (merchantAppConfig.getMerchantType().equals("appPay") && "ali".equals(param.getPayType())) {
+                    // 实例化客户端
+                    AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", fsPayConfig.getAliAppId(), fsPayConfig.getAliPrivateKey(), "json", "utf-8", fsPayConfig.getAliPublicKey(), "RSA2");
+
+                    // 构造请求参数以调用接口
+                    AlipayTradeAppPayRequest aliRequest = new AlipayTradeAppPayRequest();
+                    AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
+                    // 商户订单号
+                    model.setOutTradeNo("inquiry-" + storePayment.getPayCode());
+                    // 订单总金额
+                    model.setTotalAmount(storePayment.getPayMoney().toString());
+                    // 订单标题r
+                    model.setSubject("问诊订单支付");
+
+                    aliRequest.setBizModel(model);
+                    aliRequest.setNotifyUrl(fsPayConfig.getAliNotifyUrl());
+
+                    try {
+                        AlipayTradeAppPayResponse result = alipayClient.sdkExecute(aliRequest);
+                        if (!result.isSuccess()) {
+                            String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(result);
+                            log.error("支付宝支付调用失败 诊断链接:{}", diagnosisUrl);
+                            throw new CustomException(result.getSubMsg());
+                        }
+
+                        return R.ok().put("isPay", 0).put("data", result).put("type", "aliPay");
+                    } catch (Exception e){
+                        log.info("支付宝支付异常: {}", e);
+                        throw new CustomException("支付系统异常,请稍后重试");
+                    }
                 }
             }
             else{
@@ -460,8 +548,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 +575,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 +601,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());
@@ -514,10 +614,11 @@ public class InquiryOrderController extends  AppBaseController {
             storePayment.setOpenId(openId);
             storePayment.setUserId(user.getUserId());
             storePayment.setBusinessId(order.getOrderId().toString());
+            storePayment.setMerchantId(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("inquiry" + storePayment.getPayCode()); // 业务系统订单号
                     o.setTrxAmt(storePayment.getPayMoney().doubleValue()); // 交易金额
@@ -537,7 +638,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 +649,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/PackageOrderController.java

@@ -78,7 +78,7 @@ public class PackageOrderController extends  AppBaseController {
     public R payment(HttpServletRequest request, @Validated @RequestBody FsPackageOrderDoPayParam param)
     {
         param.setUserId(Long.parseLong(getUserId()));
-        return packageOrderService.payment(param);
+        return packageOrderService.payment(param,request);
     }
 
     @Login

+ 51 - 35
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,33 +20,27 @@ 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;
-import com.fs.his.dto.ExpressInfoDTO;
-import com.fs.his.enums.ShipperCodeEnum;
-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;
-import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayQueryRequest;
 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 +68,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.*;
@@ -130,7 +121,10 @@ public class LiveOrderController extends AppBaseController
     IPayService ybPayService;
     @Autowired
     private HuiFuService huiFuService;
-
+    @Autowired
+    private FsCoursePlaySourceConfigMapper fsCoursePlaySourceConfigMapper;
+    @Autowired
+    private MerchantAppConfigMapper merchantAppConfigMapper;
 
 
 
@@ -581,7 +575,7 @@ public class LiveOrderController extends AppBaseController
 //                }
 //            }else if(fsPayConfig.getType().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));
@@ -653,16 +647,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 +678,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 +701,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 +774,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 +804,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 +827,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;