Ver código fonte

1.提交济世百康短链跳转app功能

jzp 2 dias atrás
pai
commit
37e425b55b
18 arquivos alterados com 405 adições e 132 exclusões
  1. 10 1
      fs-company/src/main/java/com/fs/company/controller/live/LiveController.java
  2. 1 1
      fs-ipad-task/src/main/java/com/fs/app/service/IpadSendServer.java
  3. 1 1
      fs-service/src/main/java/com/fs/core/config/WxMaConfiguration.java
  4. 2 0
      fs-service/src/main/java/com/fs/course/domain/FsCourseLink.java
  5. 59 57
      fs-service/src/main/java/com/fs/his/utils/LinkUtil.java
  6. 10 0
      fs-service/src/main/java/com/fs/hisStore/domain/FsStoreScrm.java
  7. 1 1
      fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreOrderScrmMapper.java
  8. 3 0
      fs-service/src/main/java/com/fs/hisStore/service/IFsStoreOrderScrmService.java
  9. 165 21
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java
  10. 4 1
      fs-service/src/main/java/com/fs/live/service/ILiveService.java
  11. 116 3
      fs-service/src/main/java/com/fs/live/service/impl/LiveServiceImpl.java
  12. 1 1
      fs-service/src/main/resources/application-config-druid-jsbk.yml
  13. 4 1
      fs-service/src/main/resources/mapper/hisStore/FsStoreScrmMapper.xml
  14. 7 2
      fs-service/src/main/resources/mapper/qw/QwExternalContactMapper.xml
  15. 8 21
      fs-user-app/src/main/java/com/fs/app/controller/InquiryOrderController.java
  16. 3 1
      fs-user-app/src/main/java/com/fs/app/controller/live/LiveController.java
  17. 0 20
      fs-user-app/src/main/java/com/fs/app/controller/store/CompanyUserScrmController.java
  18. 10 0
      fs-user-app/src/main/java/com/fs/app/controller/store/StoreOrderScrmController.java

+ 10 - 1
fs-company/src/main/java/com/fs/company/controller/live/LiveController.java

@@ -5,6 +5,7 @@ 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.domain.model.LoginUser;
 import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
 import com.fs.common.utils.DateUtils;
@@ -12,7 +13,6 @@ import com.fs.common.utils.ServletUtils;
 import com.fs.common.utils.http.HttpUtils;
 import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.company.domain.CompanyUser;
-import com.fs.framework.security.LoginUser;
 import com.fs.framework.security.SecurityUtils;
 import com.fs.framework.service.TokenService;
 import com.fs.his.domain.FsPayConfig;
@@ -402,4 +402,13 @@ public class LiveController extends BaseController
 
         return R.ok().put("data", exist);
     }
+
+    @ApiOperation("创建App跳转通用链接")
+    @GetMapping("/createAppLink")
+    @PreAuthorize("@ss.hasPermi('live:live:createAppLink')")
+    public R createAppLink(@RequestParam("liveId") Long liveId,@RequestParam("corpId")String corpId) {
+        CompanyUser user = SecurityUtils.getLoginUser().getUser();
+        return liveService.createAppLink(user,liveId,corpId);
+    }
+
 }

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

@@ -774,7 +774,7 @@ public class IpadSendServer {
         }
         sendShortLink = sendShortLink.replace(".html","");
         String InvitationCode = LinkUtil.encryptLink(sendShortLink);
-        TxtVo txtVo = TxtVo.builder().content(InvitationCode).build();
+        TxtVo txtVo = TxtVo.builder().content("康好健康"+InvitationCode).build();
         txtVo.setBase(vo);
         WxWorkResponseDTO<WxWorkSendTextMsgRespDTO> resp = ipadSendUtils.sendTxt(txtVo);
         if (resp.getErrcode() != 0) {

+ 1 - 1
fs-service/src/main/java/com/fs/core/config/WxMaConfiguration.java

@@ -111,7 +111,7 @@ public class WxMaConfiguration {
             // 查询数据库
             FsCoursePlaySourceConfigMapper configMapper = SpringUtils.getBean(FsCoursePlaySourceConfigMapper.class);
             Wrapper<FsCoursePlaySourceConfig> queryWrapper = Wrappers.<FsCoursePlaySourceConfig>lambdaQuery()
-                    .eq(FsCoursePlaySourceConfig::getAppid, appid)
+                    .eq(FsCoursePlaySourceConfig::getAppid, appid.trim())
                     .eq(FsCoursePlaySourceConfig::getIsDel, 0);
             FsCoursePlaySourceConfig config = configMapper.selectOne(queryWrapper);
             if (config == null) {

+ 2 - 0
fs-service/src/main/java/com/fs/course/domain/FsCourseLink.java

@@ -72,4 +72,6 @@ public class FsCourseLink extends BaseEntity
     //@ApiModelProperty(value = "直播id")
     private Long liveId;
 
+    private Long userId;
+
 }

+ 59 - 57
fs-service/src/main/java/com/fs/his/utils/LinkUtil.java

@@ -8,76 +8,78 @@ import javax.crypto.spec.SecretKeySpec;
 import java.nio.charset.StandardCharsets;
 
 public class LinkUtil {
-    private static final String KEY = "AESAabCdeREssREA";
-    private static final String TRANSFORMATION = "AES/ECB/PKCS5Padding";
 
+    // 保持密钥不变(16位 AES 密钥)
+    private static final String AES_KEY = "abcedfghijklmnop";
+    // 改用 CBC 模式(比 ECB 安全),搭配 PKCS5Padding
+    private static final String AES_ALGORITHM = "AES/CBC/PKCS5Padding";
+    // CBC 模式需要初始化向量(IV),固定 16 位(和 AES 分组长度一致)
+    private static final byte[] IV = AES_KEY.getBytes(StandardCharsets.UTF_8);
 
-    public static String encryptLink(String text) {
-        String encryptedText=null;
+    // 优化后:仅 AES + Base64URL 编码(去掉 GZIP,适配短字符串)
+    public static String encryptLink(String plainText){
         try {
-            SecretKeySpec secretKey = new SecretKeySpec(KEY.getBytes(), "AES");
-            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
-            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
-            byte[] encryptedBytes = cipher.doFinal(text.getBytes());
-            encryptedText = Base62Utils.bytesToBase62(encryptedBytes);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        return encryptedText;
-    }
+            if (plainText == null || plainText.isEmpty()) {
+                return plainText;
+            }
+            // 1. 初始化 AES CBC 模式(比 ECB 安全,长度和 ECB 一致)
+            SecretKeySpec keySpec = new SecretKeySpec(AES_KEY.getBytes(StandardCharsets.UTF_8), "AES");
+            javax.crypto.spec.IvParameterSpec ivSpec = new javax.crypto.spec.IvParameterSpec(IV);
+            Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
+            cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
 
-    public static String decryptLink(String encryptedText) {
-        String text=null;
-        try {
-            SecretKeySpec secretKey = new SecretKeySpec(KEY.getBytes(), "AES");
-            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
-            cipher.init(Cipher.DECRYPT_MODE, secretKey);
-            byte[] decryptedBytes = cipher.doFinal(Base62Utils.base62ToBytes(encryptedText));
-            text = new String(decryptedBytes);
+            // 2. AES 加密
+            byte[] plainBytes = plainText.getBytes(StandardCharsets.UTF_8);
+            byte[] encryptBytes = cipher.doFinal(plainBytes);
+
+            // 3. Base64URL 编码(优化:替换 +/ 为 -_,去掉 =,比标准 Base64 短)
+            String base64Str = Base64Utils.encodeToString(encryptBytes);
+            return base64Str.replace("+", "-").replace("/", "_").replace("=", "");
         } catch (Exception e) {
-            e.printStackTrace();
+            return null;
         }
-        return text;
     }
 
-    public static String decryptPhoneMk(String encryptedText) {
-        String text=null;
+    // 解密方法(可逆)
+    public static String decryptLink(String cipherText){
         try {
-            SecretKeySpec secretKey = new SecretKeySpec(KEY.getBytes(), "AES");
-            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
-            cipher.init(Cipher.DECRYPT_MODE, secretKey);
-            byte[] decryptedBytes = cipher.doFinal(Base62Utils.base62ToBytes(encryptedText));
-            text = new String(decryptedBytes);
-            text =text.replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2");
+            if (cipherText == null || cipherText.isEmpty()) {
+                return cipherText;
+            }
+            // 1. 还原 Base64URL 为标准 Base64
+            String base64Str = cipherText.replace("-", "+").replace("_", "/");
+            int padding = 4 - (base64Str.length() % 4);
+            if (padding != 4) {
+                base64Str += "====".substring(0, padding);
+            }
+            byte[] encryptBytes = Base64Utils.decodeFromString(base64Str);
+
+            // 2. AES CBC 解密
+            SecretKeySpec keySpec = new SecretKeySpec(AES_KEY.getBytes(StandardCharsets.UTF_8), "AES");
+            javax.crypto.spec.IvParameterSpec ivSpec = new javax.crypto.spec.IvParameterSpec(IV);
+            Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
+            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
+            byte[] plainBytes = cipher.doFinal(encryptBytes);
+
+            return new String(plainBytes, StandardCharsets.UTF_8);
         } catch (Exception e) {
-            e.printStackTrace();
+            return null;
         }
-        return text;
     }
 
-    public static String decryptAutoPhoneMk(String encryptedText) {
-        String text=null;
-        if (encryptedText!=null&&encryptedText!="") {
-            if (encryptedText.length()>11){
-                try {
-                    SecretKeySpec secretKey = new SecretKeySpec(KEY.getBytes(), "AES");
-                    Cipher cipher = Cipher.getInstance(TRANSFORMATION);
-                    cipher.init(Cipher.DECRYPT_MODE, secretKey);
-                    byte[] decryptedBytes = cipher.doFinal(Base62Utils.base62ToBytes(encryptedText));
-                    text = new String(decryptedBytes);
-                    text =text.replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2");
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
-            }else {
-                text =  ParseUtils.parsePhone(encryptedText);
-            }
-        }
+    // 测试:你的原字符串加密后长度对比
+    /*public static void main(String[] args) throws Exception {
+        String original = "/pages_live/livingList?link=2034103257541902336";
+        System.out.println("原字符串长度:" + original.length()); // 约 40 字符
 
-        return text;
-    }
+        // 优化后加密
+        String encrypted = encryptShortStr(original);
+        System.out.println("优化后加密长度:" + encrypted.length()); // 约 50 字符(从 150 大幅缩短)
+        System.out.println("加密后内容:" + encrypted);
+
+        // 解密验证可逆性
+        String decrypted = decryptShortStr(encrypted);
+        System.out.println("解密后是否一致:" + original.equals(decrypted)); // true
+    }*/
 
-    public static void main(String[] args) {
-        System.out.println(decryptLink("43fP1nkB0dzuoa8nyqZ45nbgqeXHtgOeOYbfSS53fsCDaR0Y1F4ySPuMzi8UNrY0VBL21XdcWAY232W9UOkjTTL3O"));
-    }
 }

+ 10 - 0
fs-service/src/main/java/com/fs/hisStore/domain/FsStoreScrm.java

@@ -194,4 +194,14 @@ public class FsStoreScrm extends BaseEntity
     /** 医疗机构执业许可证有效期结束 */
     private LocalDate medicalLicenseExpiryEnd;
 
+
+    /** 其他特殊资格 */
+    private String otherSpecialQualification;
+
+    /** 其他特殊资格有效期开始 */
+    private LocalDate otherSpecialQualificationStart;
+
+    /** 其他特殊资格有效期结束 */
+    private LocalDate otherSpecialQualificationEnd;
+
 }

+ 1 - 1
fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreOrderScrmMapper.java

@@ -37,7 +37,7 @@ public interface FsStoreOrderScrmMapper
      * @param id 订单ID
      * @return 订单
      */
-    public FsStoreOrderScrm selectFsStoreOrderById(Long id);
+    public FsStoreOrderScrm selectFsStoreOrderById(@Param("id") Long id);
 
     /**
      * 根据订单ID列表批量查询订单

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

@@ -15,6 +15,7 @@ import com.fs.erp.domain.ErpOrder;
 import com.fs.his.dto.FsStoreOrderAmountScrmStatsQueryDto;
 import com.fs.his.enums.PaymentMethodEnum;
 import com.fs.his.param.FsIntegralOrderDoPayParam;
+import com.fs.his.param.FsStoreOrderDoPayParam;
 import com.fs.his.param.FsStoreOrderSalesParam;
 import com.fs.his.vo.FsStoreOrderAmountScrmStatsVo;
 import com.fs.his.vo.FsStoreOrderExcelVO;
@@ -391,4 +392,6 @@ public interface IFsStoreOrderScrmService
     R editOrderMoneyBySidebar(FsStoreOrderScrmSidebarVO param);
 
     R payment(FsIntegralOrderDoPayParam param, PaymentMethodEnum paymentMethodEnum);
+
+    R zfbPayment(FsStoreOrderDoPayParam param);
 }

+ 165 - 21
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java

@@ -57,30 +57,35 @@ import com.fs.erp.service.IErpOrderService;
 import com.fs.his.config.AppConfig;
 import com.fs.his.config.FsSysConfig;
 import com.fs.his.domain.*;
-import com.fs.his.dto.FsPrescribeUsageDTO;
-import com.fs.his.dto.FsProdItemDTO;
-import com.fs.his.dto.FsStoreOrderAmountScrmStatsQueryDto;
-import com.fs.his.dto.FsStoreOrderItemDTO;
+import com.fs.his.dto.*;
 import com.fs.his.enums.*;
 import com.fs.his.mapper.*;
-import com.fs.his.param.FsIntegralOrderDoPayParam;
-import com.fs.his.param.FsStoreOrderSalesParam;
-import com.fs.his.param.FsUserAddIntegralTemplateParam;
-import com.fs.his.param.PayOrderParam;
+import com.fs.his.param.*;
 import com.fs.his.service.IFsPrescribeService;
+import com.fs.his.service.IFsStoreOrderService;
 import com.fs.his.service.IFsUserIntegralLogsService;
 import com.fs.his.service.IFsUserWatchService;
 import com.fs.his.utils.ConfigUtil;
-import com.fs.his.vo.FsInquiryOrderVO;
-import com.fs.his.vo.FsStoreOrderAmountScrmStatsVo;
-import com.fs.his.vo.FsStoreOrderExcelVO;
+import com.fs.his.vo.*;
 import com.fs.his.vo.FsPrescribeVO;
 import com.fs.hisStore.config.FsErpConfig;
 import com.fs.hisStore.constants.ErpTypeEnum;
 import com.fs.hisStore.dto.*;
+import com.fs.hisStore.dto.ErpRemarkDTO;
+import com.fs.hisStore.dto.ExpressDataDTO;
+import com.fs.hisStore.dto.ExpressInfoDTO;
+import com.fs.hisStore.dto.ExpressNotifyDTO;
+import com.fs.hisStore.dto.ExpressResultDTO;
+import com.fs.hisStore.dto.FsStoreCartDTO;
+import com.fs.hisStore.dto.StoreOrderExpressExportDTO;
+import com.fs.hisStore.dto.StorePackageProductDTO;
+import com.fs.hisStore.dto.StoreProductGroupDTO;
 import com.fs.hisStore.enums.ShipperCodeEnum;
 import com.fs.hisStore.mapper.*;
 import com.fs.hisStore.param.*;
+import com.fs.hisStore.param.FsStoreAfterSalesParam;
+import com.fs.hisStore.param.FsStoreOrderParam;
+import com.fs.hisStore.param.FsStoreOrderPayParam;
 import com.fs.hisStore.vo.*;
 import com.fs.hisStore.vo.FsStoreOrderErpExportVO;
 import com.fs.hisStore.vo.FsStoreOrderItemVO;
@@ -111,6 +116,11 @@ import com.fs.hisStore.service.*;
 import com.fs.system.domain.SysConfig;
 import com.fs.system.service.ISysConfigService;
 import com.fs.system.service.ISysDictTypeService;
+import com.fs.tzBankPay.TzBankService.TzBankService;
+import com.fs.tzBankPay.doman.PayCreateOrder;
+import com.fs.tzBankPay.doman.PayCreateOrderResult;
+import com.fs.tzBankPay.doman.PayType;
+import com.fs.tzBankPay.doman.TzBankResult;
 import com.fs.wx.miniapp.config.WxMaProperties;
 import com.fs.wx.order.domain.FsWxExpressTask;
 import com.fs.wx.order.dto.*;
@@ -153,6 +163,8 @@ import org.springframework.transaction.interceptor.TransactionAspectSupport;
 import org.redisson.api.RLock;
 import org.redisson.api.RedissonClient;
 
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import javax.annotation.PostConstruct;
 import java.lang.reflect.Field;
 import java.math.BigDecimal;
@@ -253,6 +265,12 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
     @Lazy
     private IFsPrescribeService fsPrescribeService;
 
+    @Autowired
+    private TzBankService tzBankService;
+
+    @Autowired
+    private FsUserWxMapper fsUserWxMapper;
+
     @Autowired
     private IPayService payService;
     @Autowired
@@ -5889,19 +5907,26 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
             if (config.getServiceFee() != null) {
                 storeOrder.setServiceFee(config.getServiceFee());
             }
-
-            //后台制单处理
-            if (param.getPayPrice() != null && param.getPayPrice().compareTo(BigDecimal.ZERO) > 0) {
-                if (param.getPayPrice().compareTo(dto.getTotalPrice()) > 0) {
-                    return R.error("改价价格不能大于商品总价");
+            BigDecimal money = redisCache.getCacheObject("createOrderMoney:" + param.getOrderKey());
+            if(money != null && money.compareTo(BigDecimal.ZERO) >= 0 && money.compareTo(param.getPayPrice()) <= 0){
+                storeOrder.setPayPrice(money);
+                storeOrder.setPayMoney(money);
+            }else{
+                //后台制单处理
+                if (param.getPayPrice() != null && param.getPayPrice().compareTo(BigDecimal.ZERO) > 0) {
+                    if (param.getPayPrice().compareTo(dto.getTotalPrice()) > 0) {
+                        return R.error("改价价格不能大于商品总价");
+                    }
+                    storeOrder.setPayPrice(param.getPayPrice());
+                    storeOrder.setPayMoney(param.getPayPrice());
+                } else {
+                    storeOrder.setPayPrice(dto.getPayPrice());
+                    storeOrder.setPayMoney(dto.getPayPrice());
                 }
-                storeOrder.setPayPrice(param.getPayPrice());
-                storeOrder.setPayMoney(param.getPayPrice());
-            } else {
-                storeOrder.setPayPrice(dto.getPayPrice());
-                storeOrder.setPayMoney(dto.getPayPrice());
             }
 
+
+
             storeOrder.setStatus(1);
             storeOrder.setPaid(1);
             storeOrder.setPayTime(new Date());
@@ -6081,6 +6106,125 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
         return storePaymentService.processPaymentScrm(payOrderParam);
     }
 
+    @Override
+    public R zfbPayment(FsStoreOrderDoPayParam param) {
+        FsStoreOrderScrm order = fsStoreOrderMapper.selectFsStoreOrderById(param.getOrderId());
+
+        FSUserVO user=userService.selectFsUserByUserId(param.getUserId());
+
+        String json = configService.selectConfigByKey("his.pay");
+        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.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();
+            }
+        } else {
+            appId = payConfigDTO.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(order.getPayMoney().compareTo(new BigDecimal(0))==0){
+            /*this.payConfirm(order.getOrderCode(),"","","",2,null,null);
+            return R.ok().put("isPay",1);*/
+        }
+        else{
+            String payCode =  OrderCodeUtils.getOrderSn();
+            if(StringUtils.isEmpty(payCode)){
+                return R.error("订单生成失败,请重试");
+            }
+//            String json = configService.selectConfigByKey("his.pay");
+//            PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
+            FsStorePaymentScrm storePayment=new FsStorePaymentScrm();
+            storePayment.setStatus(0);
+            storePayment.setPayMode(payConfigDTO.getType());
+            storePayment.setPayCode(payCode);
+            storePayment.setCompanyId(order.getCompanyId());
+            storePayment.setCompanyUserId(order.getCompanyUserId());
+            storePayment.setBusinessCode(order.getOrderCode());
+            storePayment.setPayMoney(order.getPayMoney());
+            storePayment.setCreateTime(new Date());
+            storePayment.setPayTypeCode("支付宝");
+            storePayment.setBusinessType(1);
+            storePayment.setRemark("商城订单支付");
+            storePayment.setOpenId(openId);
+            storePayment.setOrderId(order.getId());
+            storePayment.setUserId(user.getUserId());
+            storePayment.setBusinessOrderId(order.getId().toString());
+            if(storePaymentService.insertFsStorePayment(storePayment)>0){
+                if (payConfigDTO.getType().equals("yb")) {
+                    return R.error("支付暂不可用!");
+                } else if (payConfigDTO.getType().equals("tz")) {
+                    PayCreateOrder o = new PayCreateOrder();
+                    o.setOrderNo("store" + storePayment.getPayCode()); // 业务系统订单号
+                    o.setTrxAmt(storePayment.getPayMoney().doubleValue()); // 交易金额
+                    o.setBusinessCstNo(order.getUserId().toString()); // 业务平台客户号
+                    String phone="";
+                    if (user.getPhone()!=null&&user.getPhone().length()>4){
+                        phone=user.getPhone().substring(user.getPhone().length()-4);
+                    }
+                    o.setPayerName("微信用户"+phone);
+                    o.setGoodsInfo("商城订单支付"); // 订单信息
+                    o.setOrderType(2);
+                    o.setOrderId(order.getOrderCode());
+                    o.setPayType(Arrays.asList(PayType.ALIPAY_BARCODE_PAYMENT.getCode()));
+                    TzBankResult<PayCreateOrderResult> result = tzBankService.createOrder(o);
+                    FsStorePaymentScrm mt=new FsStorePaymentScrm();
+                    mt.setPaymentId(storePayment.getPaymentId());
+                    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")) {
+                    HuiFuCreateOrder o = new HuiFuCreateOrder();
+                    o.setTradeType("A_NATIVE");
+                    o.setOpenid(openId);
+                    o.setReqSeqId("store-"+storePayment.getPayCode());
+                    o.setTransAmt(storePayment.getPayMoney().toString());
+                    o.setGoodsDesc("商城订单支付");
+                    o.setAppId(appId);
+                    if (o.getAppId()!=null&& !o.getAppId().isEmpty()){
+                        Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
+                                .eq(FsUserWx::getFsUserId, param.getUserId())
+                                .eq(FsUserWx::getAppId, payConfigDTO.getAppId());
+                        FsUserWx fsUserWx = fsUserWxMapper.selectOne(queryWrapper);
+                        if (fsUserWx!=null){
+                            o.setOpenid(fsUserWx.getOpenId());
+                        }
+                    }
+                    HuifuCreateOrderResult result = huiFuService.createOrder(o);
+                    FsStorePaymentScrm mt=new FsStorePaymentScrm();
+                    mt.setPaymentId(storePayment.getPaymentId());
+                    mt.setTradeNo(result.getHf_seq_id());
+                    mt.setAppId(appId);
+                    storePaymentService.updateFsStorePayment(mt);
+                    return R.ok().put("isPay",0).put("data",result).put("type","hf");
+                }
+
+            }
+            else{
+                throw new CustomException("支付失败");
+            }
+
+        }
+        return R.error();
+    }
+
 
     /**
      * 综合参数

+ 4 - 1
fs-service/src/main/java/com/fs/live/service/ILiveService.java

@@ -2,6 +2,7 @@ package com.fs.live.service;
 
 
 import com.fs.common.core.page.PageRequest;
+import com.fs.company.domain.CompanyUser;
 import com.fs.company.vo.CompanyVO;
 import com.fs.live.param.LiveNotifyParam;
 import com.fs.live.vo.LiveVo;
@@ -222,9 +223,11 @@ public interface ILiveService
 
     R liveDecryptLink(String url);
 
-    R liveDecryptLinkV2(String url);
+    R liveDecryptLinkV2(String url,String userId);
 
     R getLiveQwUserInfo(Long qwUserId);
 
     List<Live> selectLiveListNew(Live live);
+
+    R createAppLink(CompanyUser user, Long liveId, String corpId);
 }

+ 116 - 3
fs-service/src/main/java/com/fs/live/service/impl/LiveServiceImpl.java

@@ -14,15 +14,23 @@ import com.fs.common.core.page.PageRequest;
 import com.fs.common.core.redis.service.StockDeductService;
 import com.fs.common.exception.base.BaseException;
 import com.fs.company.domain.Company;
+import com.fs.company.domain.CompanyUser;
+import com.fs.company.domain.CompanyUserUser;
 import com.fs.company.mapper.CompanyMapper;
+import com.fs.company.service.ICompanyUserService;
+import com.fs.company.service.ICompanyUserUserService;
 import com.fs.company.vo.CompanyVO;
 import com.fs.core.config.WxMaConfiguration;
 import com.fs.course.config.CourseConfig;
+import com.fs.course.domain.FsCourseLink;
+import com.fs.course.domain.FsCourseRealLink;
+import com.fs.course.mapper.FsCourseLinkMapper;
 import com.fs.his.domain.FsStoreProduct;
 import com.fs.his.domain.FsUser;
 import com.fs.his.domain.FsUserWx;
 import com.fs.his.mapper.FsUserMapper;
 import com.fs.his.mapper.FsUserWxMapper;
+import com.fs.his.service.IFsUserService;
 import com.fs.his.utils.LinkUtil;
 import com.fs.his.utils.PhoneUtil;
 import com.fs.hisStore.domain.FsStoreProductScrm;
@@ -43,10 +51,13 @@ import com.fs.live.param.LiveReplayParam;
 import com.fs.live.service.*;
 import com.fs.live.utils.ProcessManager;
 import com.fs.live.vo.*;
+import com.fs.qw.domain.QwExternalContact;
 import com.fs.qw.domain.QwUser;
 import com.fs.qw.mapper.QwUserMapper;
+import com.fs.qw.service.IQwExternalContactService;
 import com.fs.system.domain.SysConfig;
 import com.fs.system.service.ISysConfigService;
+import com.fs.voice.utils.StringUtil;
 import com.github.pagehelper.PageInfo;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -80,6 +91,8 @@ import java.util.concurrent.TimeUnit;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
+import static com.fs.course.utils.LinkUtil.generateRandomStringWithLock;
+
 /**
  * 直播Service业务层处理
  *
@@ -155,6 +168,17 @@ public class LiveServiceImpl implements ILiveService
 
     private final String liveUrl = "/living/#/?s=";
 
+    @Autowired
+    private ICompanyUserUserService companyUserUserService;
+    @Autowired
+    private ICompanyUserService companyUserService;
+    @Autowired
+    private IQwExternalContactService qwExternalContactService;
+    @Autowired
+    private IFsUserService userService;
+    @Autowired
+    private FsCourseLinkMapper fsCourseLinkMapper;
+
     @Override
     public Live selectLiveDbByLiveId(Long liveId) {
         // 缓存中没有,从数据库查询
@@ -229,11 +253,59 @@ public class LiveServiceImpl implements ILiveService
      * @return
      */
     @Override
-    public R liveDecryptLinkV2(String url) {
+    public R liveDecryptLinkV2(String url,String userId) {
+        String json = configService.selectConfigByKey("course.config");
+        CourseConfig config = JSON.parseObject(json, CourseConfig.class);
+        Long fsUserId = Long.valueOf(userId);
         String decryptLink = LinkUtil.decryptLink(url);
         Map<String, Object> data = new HashMap<>();
-        data.put("decryptLink", decryptLink);
-        return R.ok().put("data", data);
+        data.put("decryptLink", config.getRealLinkH5LiveName()+decryptLink);
+        String[] split = decryptLink.split("=");
+        if(split[1] != null){
+            FsCourseLink courseLink = fsCourseLinkMapper.selectFsCourseLinkByLink(split[1]);
+            String realLink = courseLink.getRealLink();
+            data.put("realLink", config.getRealLinkH5LiveName() + realLink);
+            String[] split1 = realLink.split("=");
+            if(split1[1] != null){
+                try {
+                    JSONObject jsonObject = JSONObject.parseObject(split1[1]);
+                    Long companyUserId = jsonObject.getLong("companyUserId");
+                    Long qwExternalId = jsonObject.getLong("qwExternalId");
+
+                    if(companyUserId == null){
+                        return R.error("销售不存在,链接无效!");
+                    }
+
+                    CompanyUserUser map = new CompanyUserUser();
+                    map.setCompanyUserId(companyUserId);
+                    map.setUserId(fsUserId);
+                    //将小程序客户和销售做绑定
+                    List<CompanyUserUser> list = companyUserUserService.selectCompanyUserUserList(map);
+                    if (list == null || list.isEmpty()) {
+                        CompanyUser companyUser = companyUserService.selectCompanyUserById(companyUserId);
+                        if (companyUser != null && companyUser.getStatus().equals("0")) {
+                            map.setCompanyId(companyUser.getCompanyId());
+                            companyUserUserService.insertCompanyUserUser(map);
+                        }
+                    }
+
+                    FsUser user=userService.selectFsUserByUserId(fsUserId);
+                    if(user != null && qwExternalId != null){
+                        QwExternalContact qwExternalContact = qwExternalContactService.selectQwExternalContactById(qwExternalId);
+                        if(qwExternalContact != null && qwExternalContact.getFsUserId() == null){
+                            QwExternalContact qwExtContact = new QwExternalContact();
+                            qwExtContact.setId(qwExternalContact.getId());
+                            qwExtContact.setFsUserId(fsUserId);
+                            qwExternalContactService.updateQwExternalContactBindUserId(qwExtContact);
+                        }
+                    }
+                } catch (Exception e) {
+                    return R.error("链接无效,请联系销售重新发送!");
+                }
+            }
+            return R.ok().put("data", data);
+        }
+        return R.error("链接无效,请联系销售重新发送!");
     }
 
     @Override
@@ -263,6 +335,47 @@ public class LiveServiceImpl implements ILiveService
         return baseMapper.selectLiveListNew(live);
     }
 
+    @Override
+    public R createAppLink(CompanyUser user, Long liveId, String corpId) {
+        if(user == null || user.getCompanyId() == null){
+            return R.error("销售账号请绑定销售公司");
+        }
+
+        if(corpId == null){
+            return R.error("请选择企微公司,方便判定客户归属!");
+        }
+
+        // 手动创建 FsCourseLink 对象,避免使用 BeanUtils.copyProperties
+        FsCourseLink link = new FsCourseLink();
+        link.setCompanyId(user.getCompanyId());
+        //link.setQwUserId(Long.valueOf(qwUserId));
+        link.setCompanyUserId(user.getUserId());
+        link.setLiveId(liveId);
+        link.setCorpId(corpId);
+        link.setUNo(UUID.randomUUID().toString());
+        String randomString = generateRandomStringWithLock();
+        if (StringUtil.strIsNullOrEmpty(randomString)) {
+            link.setLink(UUID.randomUUID().toString().replace("-", ""));
+        } else {
+            link.setLink(randomString);
+        }
+        link.setCreateTime(new Date());
+        FsCourseRealLink courseMap = new FsCourseRealLink();
+        org.springframework.beans.BeanUtils.copyProperties(link, courseMap);
+        String courseJson = JSON.toJSONString(link);
+        String realLinkFull = "/pages_live/livingList?link=" + courseJson;
+        link.setRealLink(realLinkFull);
+        //存短链-
+        fsCourseLinkMapper.insertFsCourseLink(link);
+
+        String sendShortLink = "/pages_live/livingList?link=" + link.getLink();
+
+        sendShortLink = sendShortLink.replace(".html","");
+        String InvitationCode = LinkUtil.encryptLink(sendShortLink);
+        log.info("真实链接为:{},发送的短链为:{}",realLinkFull, InvitationCode);
+        return R.ok().put("realLink","康好健康"+InvitationCode);
+    }
+
 
     /**
      * 查询直播

+ 1 - 1
fs-service/src/main/resources/application-config-druid-jsbk.yml

@@ -68,7 +68,7 @@ fs :
   h5CommonApi: http://172.16.16.4:8010
   jwt:
     # 加密秘钥
-    secret: f4y2x52034348j86b67cde581c0f5625
+    secret: f4y2x52034348j86b67cde58fcsf5625
     # token有效时长,7天,单位秒
     expire: 31536000
     header: AppToken

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

@@ -70,7 +70,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                drug_license_expiry_start,drug_license_expiry_end,medical_device1,medical_device1_expiry_start,medical_device1_expiry_end,
                medicalDevice2,medical_device2_expiry_start,medical_device2_expiry_end,medicalDevice3,medical_device3_expiry_start,
                medical_device3_expiry_end,food_license,food_license_expiry_start,food_license_expiry_end,medical_license,
-               medical_license_expiry_start,medical_license_expiry_end
+               medical_license_expiry_start,medical_license_expiry_end,other_special_qualification,other_special_qualification_start,other_special_qualification_end
         from fs_store_scrm
     </sql>
 
@@ -262,6 +262,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="medicalLicense !=null and medicalLicense !=''"> medical_license = #{medicalLicense} ,</if>
             <if test="medicalLicenseExpiryStart !=null "> medical_license_expiry_start = #{medicalLicenseExpiryStart} ,</if>
             <if test="medicalLicenseExpiryEnd !=null "> medical_license_expiry_end = #{medicalLicenseExpiryEnd} ,</if>
+            <if test="otherSpecialQualification !=null and otherSpecialQualification !=''"> other_special_qualification = #{otherSpecialQualification} ,</if>
+            <if test="otherSpecialQualificationStart !=null "> other_special_qualification_start = #{otherSpecialQualificationStart} ,</if>
+            <if test="otherSpecialQualificationEnd !=null "> other_special_qualification_end = #{otherSpecialQualificationEnd} ,</if>
         </trim>
         where store_id = #{storeId}
     </update>

+ 7 - 2
fs-service/src/main/resources/mapper/qw/QwExternalContactMapper.xml

@@ -820,8 +820,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             resultMap="QwExternalContactResult">
         <include refid="selectQwExternalContactVo"/>
         where corp_id = #{param.corpId} and external_user_id = #{param.externalUserId}
-        and company_user_id = #{param.companyUserId}
-        and user_id is not null and company_id is not null
+        <if test="param.companyUserId != null">
+            and company_user_id = #{param.companyUserId}
+        </if>
+        <if test="param.qwUserId != null">
+            and user_id = #{param.qwUserId}
+        </if>
+        and fs_user_id is not null and company_user_id is not null and qw_user_id is not null
         limit 1
     </select>
 </mapper>

+ 8 - 21
fs-user-app/src/main/java/com/fs/app/controller/InquiryOrderController.java

@@ -470,24 +470,11 @@ public class InquiryOrderController extends  AppBaseController {
     @PostMapping("/zfbPayment")
     public R zfbPayment(HttpServletRequest request, @Validated @RequestBody FsInquiryOrderDoPayParam param)
     {
-        param.setUserId(Long.parseLong(getUserId()));
         FsInquiryOrder order=inquiryOrderService.selectFsInquiryOrderByOrderId(param.getOrderId());
         FsUser user=userService.selectFsUserByUserId(Long.parseLong(getUserId()));
 
-        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 json = configService.selectConfigByKey("his.pay");
+        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
 
         String openId = null;
         String appId = param.getAppId();
@@ -501,7 +488,7 @@ public class InquiryOrderController extends  AppBaseController {
                 openId = fsUserWx.getOpenId();
             }
         } else {
-            appId = fsCoursePlaySourceConfig.getAppid();
+            appId = payConfigDTO.getAppId();
             openId = Objects.isNull(user) ? "" : user.getMaOpenId();
             if (StringUtils.isBlank(openId)){
                 Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
@@ -527,7 +514,7 @@ public class InquiryOrderController extends  AppBaseController {
 //            PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
             FsStorePayment storePayment=new FsStorePayment();
             storePayment.setStatus(0);
-            storePayment.setPayMode(merchantAppConfig.getMerchantType());
+            storePayment.setPayMode(payConfigDTO.getType());
             storePayment.setPayCode(payCode);
             storePayment.setCompanyId(order.getCompanyId());
             storePayment.setCompanyUserId(order.getCompanyUserId());
@@ -541,9 +528,9 @@ public class InquiryOrderController extends  AppBaseController {
             storePayment.setUserId(user.getUserId());
             storePayment.setBusinessId(order.getOrderId().toString());
             if(storePaymentService.insertFsStorePayment(storePayment)>0){
-                if (merchantAppConfig.getMerchantType().equals("yb")) {
+                if (payConfigDTO.getType().equals("yb")) {
                     return R.error("支付暂不可用!");
-                } else if (merchantAppConfig.getMerchantType().equals("tz")) {
+                } else if (payConfigDTO.getType().equals("tz")) {
                     PayCreateOrder o = new PayCreateOrder();
                     o.setOrderNo("inquiry" + storePayment.getPayCode()); // 业务系统订单号
                     o.setTrxAmt(storePayment.getPayMoney().doubleValue()); // 交易金额
@@ -563,7 +550,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 (merchantAppConfig.getMerchantType().equals("hf")) {
+                }else if (payConfigDTO.getType().equals("hf")) {
                     HuiFuCreateOrder o = new HuiFuCreateOrder();
                     o.setTradeType("A_NATIVE");
                     o.setOpenid(openId);
@@ -574,7 +561,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, fsCoursePlaySourceConfig.getAppid());
+                                .eq(FsUserWx::getAppId, payConfigDTO.getAppId());
                         FsUserWx fsUserWx = fsUserWxMapper.selectOne(queryWrapper);
                         if (fsUserWx!=null){
                             o.setOpenid(fsUserWx.getOpenId());

+ 3 - 1
fs-user-app/src/main/java/com/fs/app/controller/live/LiveController.java

@@ -426,10 +426,12 @@ public class LiveController extends AppBaseController {
 		return liveService.liveDecryptLink(param.getUrl());
 	}
 
+	@Login
 	@ApiOperation("解密链接参数")
 	@PostMapping("/decryptLink/v2")
 	public R decryptLinkV2(@RequestBody FsLiveEncryptLinkParam param) {
-		return liveService.liveDecryptLink(param.getUrl());
+		String userId = getUserId();
+		return liveService.liveDecryptLinkV2(param.getUrl(),userId);
 	}
 
 	@ApiOperation("获取微信小程序企微信息")

+ 0 - 20
fs-user-app/src/main/java/com/fs/app/controller/store/CompanyUserScrmController.java

@@ -275,26 +275,6 @@ public class CompanyUserScrmController extends AppBaseController {
         return R.ok().put("data",WxaCode);
     }
 
-    /**
-     * 济世百康功能,将companyUserId加密后发送给客户,后续添加绑定使用
-     * @param companyUserId
-     * @return
-     */
-    @ApiOperation("获取销售邀请码")
-    @GetMapping("/getCompanyUserInvitationCode")
-    public R getCompanyUserInvitationCode(@RequestParam("companyUserId")Long companyUserId){
-        if(companyUserId == null){
-            return R.error("请登陆账号后再试!");
-        }
-        CompanyUser companyUser = companyUserMapper.selectCompanyUserByUserId(companyUserId);
-        if (companyUser == null) {
-            return R.error("销售不存在,邀请码不合法");
-        }
-        String InvitationCode = PhoneUtil.encryptPhone(String.valueOf(companyUserId));
-        Map<String, Object> data = new HashMap<>();
-        data.put("InvitationCode", InvitationCode);
-        return R.ok().put("data",data);
-    }
 
 
     @ApiOperation("上传声纹")

+ 10 - 0
fs-user-app/src/main/java/com/fs/app/controller/store/StoreOrderScrmController.java

@@ -19,6 +19,7 @@ import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.ip.IpUtils;
 import com.fs.core.config.WxMaConfiguration;
 import com.fs.erp.service.IErpOrderService;
+import com.fs.his.param.FsStoreOrderDoPayParam;
 import com.fs.his.utils.ConfigUtil;
 import com.fs.hisStore.config.FsErpConfig;
 import com.fs.hisStore.domain.*;
@@ -216,6 +217,15 @@ public class StoreOrderScrmController extends AppBaseController {
         return orderService.createOrder(Long.parseLong(getUserId()),param);
     }
 
+    @Login
+    @ApiOperation("支付宝支付")
+    @PostMapping("/zfbPayment")
+    public R zfbPayment(HttpServletRequest request, @Validated @RequestBody FsStoreOrderDoPayParam param)
+    {
+        param.setUserId(Long.parseLong(getUserId()));
+        return orderService.zfbPayment(param);
+    }
+
     @Login
     @ApiOperation("支付")
     @PostMapping("/pay")