Просмотр исходного кода

一键群发对于app看课/直播跳转短链兼容

hulin 15 часов назад
Родитель
Сommit
0ae7dbdae9

+ 0 - 27
fs-company/src/main/java/com/fs/company/controller/common/Test.java

@@ -1,18 +1,10 @@
 package com.fs.company.controller.common;
 
-import com.alibaba.fastjson.JSON;
-import com.fs.ad.enums.AdUploadType;
-import com.fs.common.annotation.DataSource;
-import com.fs.common.core.domain.R;
 import com.fs.common.core.redis.RedisCache;
-import com.fs.common.enums.DataSourceType;
 import com.fs.common.service.impl.SmsServiceImpl;
 import com.fs.company.mapper.*;
 import com.fs.company.service.ICompanyService;
-import com.fs.company.service.ICompanyUserService;
-import com.fs.company.vo.RedPacketMoneyVO;
 import com.fs.course.mapper.FsCourseRedPacketLogMapper;
-import com.fs.course.service.IFsCourseWatchLogService;
 import com.fs.course.service.ITencentCloudCosService;
 import com.fs.erp.domain.ErpDeliverys;
 import com.fs.erp.domain.ErpOrderQuery;
@@ -20,31 +12,18 @@ import com.fs.erp.dto.ErpOrderQueryRequert;
 import com.fs.erp.dto.ErpOrderQueryResponse;
 import com.fs.erp.service.IErpOrderService;
 import com.fs.fastGpt.mapper.FastGptChatSessionMapper;
-import com.fs.fastGpt.service.IFastgptEventLogTotalService;
 import com.fs.his.config.FsSysConfig;
 import com.fs.his.mapper.*;
 import com.fs.his.service.*;
 import com.fs.his.service.impl.FsPackageOrderServiceImpl;
 import com.fs.his.utils.ConfigUtil;
-import com.fs.his.utils.qrcode.QRCodeUtils;
 import com.fs.hisStore.domain.FsStoreOrderScrm;
 import com.fs.im.service.IImService;
-import com.fs.im.service.OpenIMService;
 import com.fs.qw.service.IQwAppContactWayService;
-import com.fs.qw.service.IQwCompanyService;
 import com.fs.qw.service.IQwExternalContactTransferLogService;
-import com.fs.qw.service.IQwUserService;
-import com.fs.qw.vo.AdUploadVo;
 import com.fs.qwApi.service.QwApiService;
-import com.fs.sop.service.IQwSopTempContentService;
-import com.fs.sop.service.IQwSopTempDayService;
-import com.fs.sop.service.IQwSopTempRulesService;
-import com.fs.sop.service.IQwSopTempService;
 import com.fs.system.mapper.SysConfigMapper;
-import com.google.zxing.WriterException;
-import lombok.AllArgsConstructor;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.rocketmq.spring.core.RocketMQTemplate;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
@@ -54,12 +33,6 @@ import org.springframework.web.bind.annotation.RestController;
 
 import java.util.List;
 
-import javax.imageio.ImageIO;
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
 @RestController
 public class Test {
     @Autowired

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

@@ -2,6 +2,7 @@ package com.fs.app.service;
 
 import cn.hutool.core.util.ObjectUtil;
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.fs.common.core.redis.RedisCache;
@@ -22,6 +23,8 @@ import com.fs.course.service.IFsCoursePlaySourceConfigService;
 import com.fs.course.service.IFsCourseWatchLogService;
 import com.fs.his.domain.FsUser;
 import com.fs.his.mapper.FsUserMapper;
+import com.fs.his.utils.LinkUtil;
+import com.fs.his.utils.PhoneUtil;
 import com.fs.ipad.IpadSendUtils;
 import com.fs.ipad.vo.*;
 import com.fs.live.domain.LiveWatchLog;
@@ -278,7 +281,7 @@ public class IpadSendServer {
         }
     }
 
-        public void sendTxtAtMsg(BaseVo vo) {
+    public void sendTxtAtMsg(BaseVo vo) {
         WxSendTextAtMsgTwoDTO dto = new WxSendTextAtMsgTwoDTO();
         List<WxSendTextAtMsgTwoDTO.Contentva> contentvaList = new ArrayList<>();
         WxSendTextAtMsgTwoDTO.Contentva contentva = new WxSendTextAtMsgTwoDTO.Contentva();
@@ -287,10 +290,10 @@ public class IpadSendServer {
         contentvaList.add(contentva);
         dto.setContentva(contentvaList);
         dto.setBase(vo);
-         dto.setUuid(vo.getUuid());
+        dto.setUuid(vo.getUuid());
         dto.setSend_userid(ipadSendUtils.userIds(vo));
         dto.setIsRoom(true);
-       ipadSendUtils.sendTxtAtMsgVo(dto, vo.getServerId());
+        ipadSendUtils.sendTxtAtMsgVo(dto, vo.getServerId());
     }
 
     public void sendVoice(BaseVo vo, QwSopCourseFinishTempSetting.Setting content) {
@@ -543,12 +546,12 @@ public class IpadSendServer {
         Integer courseType = setting.getCourseType();
         String logId = qwSopLogs.getId();
         if(null != liveWatchLog){
-                    if (!QwSopLogsServiceImpl.isCourseTypeValid(courseType, liveWatchLog.getLogType())) {
-                        // 作废消息
-                        log.warn("SOP_LOG_ID:{}, 看课状态未满足,不发送", qwSopLogs.getId());
-                        qwSopLogsService.updateQwSopLogsByWatchLogType(logId, "看课状态未满足,不发送");
-                        return false;
-                    }
+            if (!QwSopLogsServiceImpl.isCourseTypeValid(courseType, liveWatchLog.getLogType())) {
+                // 作废消息
+                log.warn("SOP_LOG_ID:{}, 看课状态未满足,不发送", qwSopLogs.getId());
+                qwSopLogsService.updateQwSopLogsByWatchLogType(logId, "看课状态未满足,不发送");
+                return false;
+            }
         }
         else{
             log.warn("SOP_LOG_ID:{}, 无观看记录,不发送", qwSopLogs.getId());
@@ -723,6 +726,12 @@ public class IpadSendServer {
                     content.setSendStatus(0);
                     content.setSendRemarks("短信待发送");
                     break;
+                    //跳转APP看课链接
+                case "23":
+                    //跳转APP直播链接
+                case "24":
+                    sendAppShortLink(vo, content, miniMap);
+                    break;
                 case "99":
                     // 群发
                     sendTxtAtMsg(vo);
@@ -739,6 +748,42 @@ public class IpadSendServer {
         }
     }
 
+    private void sendAppShortLink(BaseVo vo, QwSopCourseFinishTempSetting.Setting content, Map<String, FsCoursePlaySourceConfig> miniMap) {
+//        //发送短链前,先发送一个介绍语
+//        TxtVo introduction = TxtVo.builder().content("请复制以下短链内容").build();
+//        introduction.setBase(vo);
+//        ipadSendUtils.sendTxt(introduction);
+        //发送短链内容
+        String miniProgramPage = content.getMiniprogramPage();
+        String sendShortLink = null;
+        //解析直播短链信息
+        String livePrefix = "/pages_live/livingList?link=";
+        if (miniProgramPage.startsWith(livePrefix)) {
+            JSONObject obj = JSONObject.parseObject(miniProgramPage.substring(livePrefix.length()));
+            sendShortLink = livePrefix + obj.getString("link");
+        }
+        //解析课程短链信息
+        String coursePrefix = "/pages/courseAnswer/index?link=";
+        if (miniProgramPage.startsWith(coursePrefix)) {
+            JSONObject obj = JSONObject.parseObject(miniProgramPage.substring(coursePrefix.length()));
+            sendShortLink = coursePrefix + obj.getString("link");
+        }
+        if (null == sendShortLink) {
+            log.warn("发送链接为空");
+            return;
+        }
+        sendShortLink = sendShortLink.replace(".html","");
+        String InvitationCode = LinkUtil.encryptLink(sendShortLink);
+        TxtVo txtVo = TxtVo.builder().content(InvitationCode).build();
+        txtVo.setBase(vo);
+        WxWorkResponseDTO<WxWorkSendTextMsgRespDTO> resp = ipadSendUtils.sendTxt(txtVo);
+        if (resp.getErrcode() != 0) {
+            log.debug("ID:{}-ipad接口请求返回异常:{}", vo.getId(), resp.getErrmsg());
+            content.setSendStatus(2);
+            content.setSendRemarks("发送失败:" + resp.getErrmsg());
+        }
+    }
+
     /**
      * 发送直播短链
      * @param vo

+ 54 - 5
fs-qw-task/src/main/java/com/fs/app/taskService/impl/SopLogsTaskServiceImpl.java

@@ -436,7 +436,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 
 
     private void processSopGroup(String sopId, List<SopUserLogsVo> userLogsVos, LocalDateTime currentTime, Map<String,
-            QwGroupChat> groupChatMap, CourseConfig config, Map<Long, Map<Integer, List<CompanyMiniapp>>> miniMap,
+                                         QwGroupChat> groupChatMap, CourseConfig config, Map<Long, Map<Integer, List<CompanyMiniapp>>> miniMap,
                                  List<Company> companies) throws Exception {
         QwSopRuleTimeVO ruleTimeVO = sopMapper.selectQwSopByClickHouseId(sopId);
 
@@ -522,7 +522,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 
 
             if (logVo.getFilterMode()==2 && config != null && config.getRoomLinkAllow() != null && config.getRoomLinkAllow()) {
-                 return;
+                return;
             }
 
             LocalDate startDate = LocalDate.parse(logVo.getStartTime(), DATE_FORMATTER);
@@ -1360,6 +1360,17 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                         log.error("赋值-小程序封面地址失败-" + e);
                     }
                     break;
+                //录播
+                case "24":
+                    corpId = logVo.getCorpId();
+                    shortH5Link = createH5LiveShortLink(setting, corpId,
+                            qwUserId, companyUserId, companyId);
+
+                    sopLogs.setSendType(Integer.valueOf(setting.getContentType()));
+                    clonedContent.setLiveId(setting.getLiveId());
+
+                    setting.setMiniprogramPage(shortH5Link);
+                    break;
                 default:
                     break;
             }
@@ -1370,7 +1381,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
     }
 
     private String createRegisteredLinkByMiniApp(QwSopTempSetting.Content.Setting setting, SopUserLogsVo logVo, Date sendTime,
-                                                  String qwUserId,
+                                                 String qwUserId,
                                                  String companyUserId, String companyId, String externalId, Long fsUserId) {
         // 获取缓存的配置
         CourseConfig config;
@@ -1432,7 +1443,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 
 
     public String createRegisteredGroupLinkByMiniApp(QwSopTempSetting.Content.Setting setting, SopUserLogsVo logVo, Date sendTime,
-                                                      String qwUserId,
+                                                     String qwUserId,
                                                      Long companyUserId, String companyId, String chatId) {
         // 获取缓存的配置
         CourseConfig config;
@@ -1606,6 +1617,17 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                         log.error("赋值-小程序封面地址失败-" + e);
                     }
                     break;
+                //跳转app直播
+                case "24":
+                    corpId = logVo.getCorpId();
+                    shortH5Link = createH5LiveShortLink(setting, corpId,
+                            qwUserId, companyUserId, companyId);
+
+                    sopLogs.setSendType(Integer.valueOf(setting.getContentType()));
+                    clonedContent.setLiveId(setting.getLiveId());
+
+                    setting.setMiniprogramPage(shortH5Link);
+                    break;
                 default:
                     break;
             }
@@ -1625,7 +1647,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                                      SopUserLogsVo logVo, Date sendTime, Long courseId, Long videoId, String qwUserId, String companyUserId,
                                      String companyId, String externalId, String welcomeText, String qwUserName,
                                      Long fsUserId, boolean isGroupChat, String miniAppId, QwGroupChat groupChat, CourseConfig config, Map<Long,
-            Map<Integer, List<CompanyMiniapp>>> miniMap, Integer grade, Integer sendMsgType,
+                    Map<Integer, List<CompanyMiniapp>>> miniMap, Integer grade, Integer sendMsgType,
                                      List<Company> companies,Long serverId) {
         QwExternalContact contact = null;
         if (logVo.getExternalId() != null) {
@@ -1954,6 +1976,33 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 
                         enqueueQwSopSmsLogs(sopSmsLogs);
                     }
+                    break;
+                //跳转app看课
+                case "23":
+                    try {
+                        addWatchLogIfNeeded(sopLogs, videoId, courseId, sendTime, qwUserId, companyUserId, companyId, externalId, logVo,2);
+
+                        String shortH5link = createH5LinkByMiniApp(setting, logVo, sendTime, courseId, videoId,
+                                qwUserId, companyUserId, companyId, externalId, isOfficial, sopLogs.getFsUserId());
+
+                        setting.setMiniprogramTitle("邀请链接");
+                        setting.setMiniprogramPage(shortH5link);
+
+                    } catch (Exception e) {
+                        log.error("app看课模板解析失败:" + e);
+                    }
+                    break;
+                //app直播跳转
+                case "24":
+                    String corpId = logVo.getCorpId();
+                    String shortH5Link = createH5LiveShortLink(setting, corpId,
+                            qwUserId, companyUserId, companyId);
+
+                    sopLogs.setSendType(Integer.valueOf(setting.getContentType()));
+                    clonedContent.setLiveId(setting.getLiveId());
+
+                    setting.setMiniprogramPage(shortH5Link);
+
                     break;
                 default:
                     break;

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

@@ -168,6 +168,8 @@ public interface IFsCourseWatchLogService extends IService<FsCourseWatchLog> {
 
     R decryptLink(String url);
 
+    R decryptLinkV2(String url);
+
     List<FsCourseWatchLog> selectFsUserWatchLogByExtId(QwExternalContact qwExternalContact);
 
     FsCourseWatchLog selectFsCourseWatchLogWithUCCV(Long userId, Long companyUserId, Integer courseId, Integer videoId);

+ 9 - 0
fs-service/src/main/java/com/fs/course/service/impl/FsCourseWatchLogServiceImpl.java

@@ -40,6 +40,7 @@ import com.fs.his.config.FsSysConfig;
 import com.fs.his.domain.FsUser;
 import com.fs.his.service.IFsUserService;
 import com.fs.his.utils.ConfigUtil;
+import com.fs.his.utils.LinkUtil;
 import com.fs.his.utils.PhoneUtil;
 import com.fs.qw.Bean.MsgBean;
 import com.fs.qw.cache.IQwExternalContactCacheService;
@@ -1743,6 +1744,14 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
         return R.ok().put("data", data);
     }
 
+    @Override
+    public R decryptLinkV2(String url) {
+        String decryptLink = LinkUtil.decryptLink(url);
+        Map<String, Object> data = new HashMap<>();
+        data.put("decryptLink", decryptLink);
+        return R.ok().put("data", data);
+    }
+
     @Override
     public List<FsCourseWatchLog> selectFsUserWatchLogByExtId(QwExternalContact qwExternalContact) {
         return fsCourseWatchLogMapper.selectFsUserWatchLogByExtId(qwExternalContact);

+ 109 - 0
fs-service/src/main/java/com/fs/his/utils/Base62Utils.java

@@ -0,0 +1,109 @@
+package com.fs.his.utils;
+
+public class Base62Utils {
+    private static final String BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+    private static final int BASE62 = 62;
+    
+    /**
+     * 将字节数组转换为 Base62 字符串
+     */
+    public static String bytesToBase62(byte[] data) {
+        if (data == null || data.length == 0) {
+            return "";
+        }
+        
+        StringBuilder sb = new StringBuilder();
+        int idx = 0;
+        
+        while (idx < data.length) {
+            long value = 0;
+            int count = 0;
+            
+            for (int i = 0; i < 7 && idx < data.length; i++, idx++, count++) {
+                value = (value << 8) | (data[idx] & 0xFF);
+            }
+            
+            long[] encoded = encodeBase62(value, count);
+            for (int i = encoded.length - 1; i >= 0; i--) {
+                sb.append(BASE62_CHARS.charAt((int)encoded[i]));
+            }
+        }
+        
+        return sb.toString();
+    }
+    
+    /**
+     * 将 Base62 字符串转换为字节数组
+     */
+    public static byte[] base62ToBytes(String base62String) {
+        if (base62String == null || base62String.isEmpty()) {
+            return new byte[0];
+        }
+        
+        byte[] result = new byte[(base62String.length() * 7 + 7) / 8];
+        int resultIdx = 0;
+        int strIdx = 0;
+        
+        while (strIdx < base62String.length()) {
+            long value = 0;
+            int count = 0;
+            
+            for (int i = 0; i < 11 && strIdx < base62String.length(); i++, strIdx++) {
+                char c = base62String.charAt(strIdx);
+                int digit = decodeBase62Char(c);
+                if (digit == -1) {
+                    throw new IllegalArgumentException("Invalid Base62 character: " + c);
+                }
+                value = value * BASE62 + digit;
+                count++;
+            }
+            
+            int bytesToWrite = (count * 6 + 7) / 8;
+            for (int i = bytesToWrite - 1; i >= 0 && resultIdx < result.length; i--, resultIdx++) {
+                result[resultIdx] = (byte)((value >> (i * 8)) & 0xFF);
+            }
+        }
+        
+        return trimZeroBytes(result);
+    }
+    
+    private static long[] encodeBase62(long value, int byteCount) {
+        int outputSize = (byteCount * 8 + 5) / 6;
+        long[] result = new long[outputSize];
+        int idx = 0;
+        
+        while (value > 0) {
+            result[idx++] = value % BASE62;
+            value /= BASE62;
+        }
+        
+        return java.util.Arrays.copyOf(result, idx);
+    }
+    
+    private static int decodeBase62Char(char c) {
+        if (c >= '0' && c <= '9') return c - '0';
+        if (c >= 'A' && c <= 'Z') return c - 'A' + 10;
+        if (c >= 'a' && c <= 'z') return c - 'a' + 36;
+        return -1;
+    }
+    
+    private static byte[] trimZeroBytes(byte[] data) {
+        int nonZeroCount = 0;
+        for (byte b : data) {
+            if (b != 0) nonZeroCount++;
+        }
+        
+        if (nonZeroCount == data.length) {
+            return data;
+        }
+        
+        byte[] trimmed = new byte[nonZeroCount];
+        int idx = 0;
+        for (byte b : data) {
+            if (b != 0) {
+                trimmed[idx++] = b;
+            }
+        }
+        return trimmed;
+    }
+}

+ 83 - 0
fs-service/src/main/java/com/fs/his/utils/LinkUtil.java

@@ -0,0 +1,83 @@
+package com.fs.his.utils;
+
+import com.fs.common.utils.ParseUtils;
+import org.springframework.util.Base64Utils;
+
+import javax.crypto.Cipher;
+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";
+
+
+    public static String encryptLink(String text) {
+        String encryptedText=null;
+        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;
+    }
+
+    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);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return text;
+    }
+
+    public static String decryptPhoneMk(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);
+            text =text.replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        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);
+            }
+        }
+
+        return text;
+    }
+
+    public static void main(String[] args) {
+        System.out.println(decryptLink("43fP1nkB0dzuoa8nyqZ45nbgqeXHtgOeOYbfSS53fsCDaR0Y1F4ySPuMzi8UNrY0VBL21XdcWAY232W9UOkjTTL3O"));
+    }
+}

+ 2 - 0
fs-service/src/main/java/com/fs/live/service/ILiveService.java

@@ -222,6 +222,8 @@ public interface ILiveService
 
     R liveDecryptLink(String url);
 
+    R liveDecryptLinkV2(String url);
+
     R getLiveQwUserInfo(Long qwUserId);
 
     List<Live> selectLiveListNew(Live live);

+ 14 - 0
fs-service/src/main/java/com/fs/live/service/impl/LiveServiceImpl.java

@@ -23,6 +23,7 @@ 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.utils.LinkUtil;
 import com.fs.his.utils.PhoneUtil;
 import com.fs.hisStore.domain.FsStoreProductScrm;
 import com.fs.hisStore.mapper.FsStoreProductScrmMapper;
@@ -222,6 +223,19 @@ public class LiveServiceImpl implements ILiveService
         return R.ok().put("data", data);
     }
 
+    /**
+     * 解密链接
+     * @param url
+     * @return
+     */
+    @Override
+    public R liveDecryptLinkV2(String url) {
+        String decryptLink = LinkUtil.decryptLink(url);
+        Map<String, Object> data = new HashMap<>();
+        data.put("decryptLink", decryptLink);
+        return R.ok().put("data", data);
+    }
+
     @Override
     public R getLiveQwUserInfo(Long qwUserId) {
         QwUser qwUser = qwUserMapper.selectQwUserById(qwUserId);

+ 1 - 1
fs-service/src/main/java/com/fs/sop/service/impl/QwSopServiceImpl.java

@@ -564,7 +564,7 @@ public class QwSopServiceImpl implements IQwSopService {
                 if (ruleTimeVO.getTempStatus().equals("0")){
                     QwSop qwSop=new QwSop();
                     qwSop.setId(ruleTimeVO.getId());
-                    qwSop.setStatus(0L);
+                    qwSop.setStatus(0L);//模板不运行了,则当前任务也停用
 
                     qwSopMapper.updateQwSop(qwSop);
                     return;

+ 281 - 81
fs-service/src/main/java/com/fs/sop/service/impl/SopUserLogsInfoServiceImpl.java

@@ -99,6 +99,7 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
     private static final String appLink = "https://jump.ylrztop.com/jumpapp/pages/index/index?link=";
     private static final String registeredRealLink = "/pages_course/register.html?link=";
     private static final String h5LiveShortLink = "/pages_course/livingInvite.html?s=";
+    private static final String appLiveShortLink = "/pages_live/livingList?link=";
     private static final String h5miniappLink = "/pages_course/shortLink.html?s=";
 //    private static final String miniappRealLink = "/pages/index/index?course=";
 
@@ -381,64 +382,64 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
 
         try {
 
-                //用于查询
-                SopUserLogs userLogs=new SopUserLogs();
-                userLogs.setSopId(param.getSopId());
-                userLogs.setQwUserId(param.getQwUserId());
-                userLogs.setCorpId(param.getCorpId());
-                userLogs.setStatus(1);
-                userLogs.setStartTime(param.getParamTime());
-
-                String  unionSopStartId = sopUserLogsService.selectSopUserLogsByUpdate(userLogs);
-
-                 BatchSopUserLogsInfoParamU infoParamU=new BatchSopUserLogsInfoParamU();
-                    infoParamU.setIds(param.getIds());
-                //查询sop任务开始时间营期表 是否有这个营期
-                if (!StringUtil.strIsNullOrEmpty(unionSopStartId)){
-                    infoParamU.setUserLogsId(unionSopStartId);
+            //用于查询
+            SopUserLogs userLogs=new SopUserLogs();
+            userLogs.setSopId(param.getSopId());
+            userLogs.setQwUserId(param.getQwUserId());
+            userLogs.setCorpId(param.getCorpId());
+            userLogs.setStatus(1);
+            userLogs.setStartTime(param.getParamTime());
+
+            String  unionSopStartId = sopUserLogsService.selectSopUserLogsByUpdate(userLogs);
+
+            BatchSopUserLogsInfoParamU infoParamU=new BatchSopUserLogsInfoParamU();
+            infoParamU.setIds(param.getIds());
+            //查询sop任务开始时间营期表 是否有这个营期
+            if (!StringUtil.strIsNullOrEmpty(unionSopStartId)){
+                infoParamU.setUserLogsId(unionSopStartId);
+                if (param.getIds().length>0){
+                    batchUpdateSopUserLogsInfoToTime(infoParamU);
+                }
+
+            }
+            else {
+                //如果查不出来营期 ,则新建营期
+                //查询sop的模板id
+                QwSop qwSop = qwSopService.selectQwSopById(param.getSopId());
+
+                //查询这个sop任务的员工的信息
+                QwUser qwUser = qwUserMapper.selectQwUserByQwUseridAndCorpId(param.getQwUserId(), param.getCorpId());
+
+                SopUserLogsParamByDate userLogsParamByDate = new SopUserLogsParamByDate();
+                userLogsParamByDate.setSopId(param.getSopId());
+                userLogsParamByDate.setSopTempId(qwSop.getTempId());
+                userLogsParamByDate.setQwUserId(param.getQwUserId());
+                userLogsParamByDate.setCorpId(param.getCorpId());
+                userLogsParamByDate.setStartTime(param.getParamTime());
+                userLogsParamByDate.setStatus(1);
+                userLogsParamByDate.setUserId(qwUser.getId()+"|"+qwUser.getCompanyUserId()+"|"+qwUser.getCompanyId());
+
+                //如果没有这个营期没有就先插入
+                int i1 = sopUserLogsService.insertSopUserLogsByDate(userLogsParamByDate);
+                if (i1>0){
+                    userLogs.setSopTempId(qwSop.getTempId());
+                    //获取新的
+                    String  unionSopStartIdNew = sopUserLogsService.selectSopUserLogsByUnionSopId(userLogs);
+                    infoParamU.setUserLogsId(unionSopStartIdNew);
+
                     if (param.getIds().length>0){
                         batchUpdateSopUserLogsInfoToTime(infoParamU);
                     }
 
                 }
-                else {
-                    //如果查不出来营期 ,则新建营期
-                    //查询sop的模板id
-                    QwSop qwSop = qwSopService.selectQwSopById(param.getSopId());
-
-                    //查询这个sop任务的员工的信息
-                    QwUser qwUser = qwUserMapper.selectQwUserByQwUseridAndCorpId(param.getQwUserId(), param.getCorpId());
-
-                    SopUserLogsParamByDate userLogsParamByDate = new SopUserLogsParamByDate();
-                    userLogsParamByDate.setSopId(param.getSopId());
-                    userLogsParamByDate.setSopTempId(qwSop.getTempId());
-                    userLogsParamByDate.setQwUserId(param.getQwUserId());
-                    userLogsParamByDate.setCorpId(param.getCorpId());
-                    userLogsParamByDate.setStartTime(param.getParamTime());
-                    userLogsParamByDate.setStatus(1);
-                    userLogsParamByDate.setUserId(qwUser.getId()+"|"+qwUser.getCompanyUserId()+"|"+qwUser.getCompanyId());
-
-                    //如果没有这个营期没有就先插入
-                    int i1 = sopUserLogsService.insertSopUserLogsByDate(userLogsParamByDate);
-                    if (i1>0){
-                        userLogs.setSopTempId(qwSop.getTempId());
-                        //获取新的
-                        String  unionSopStartIdNew = sopUserLogsService.selectSopUserLogsByUnionSopId(userLogs);
-                        infoParamU.setUserLogsId(unionSopStartIdNew);
-
-                        if (param.getIds().length>0){
-                            batchUpdateSopUserLogsInfoToTime(infoParamU);
-                        }
 
-                    }
 
 
-
-                }
-            } catch (ConstraintViolationException e) {
-                return R.error().put("msg", "修改营期失败:目标营期已经有此客户,请检查客户信息 是否重复,重复请联系超管 删除此营期数据");
-            } catch (Exception e) {
-                return R.error().put("msg", "修改营期失败:" + e.getMessage());
+            }
+        } catch (ConstraintViolationException e) {
+            return R.error().put("msg", "修改营期失败:目标营期已经有此客户,请检查客户信息 是否重复,重复请联系超管 删除此营期数据");
+        } catch (Exception e) {
+            return R.error().put("msg", "修改营期失败:" + e.getMessage());
         }
 
         return R.ok();
@@ -746,7 +747,7 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
 //                                    miniAppId = String.valueOf(luckyBagConfig.get("appId"));
 
 
-                                   if (!miniMap.isEmpty() && qwUser.getSendMsgType() == 1) {
+                                    if (!miniMap.isEmpty() && qwUser.getSendMsgType() == 1) {
                                         Map<Integer, List<CompanyMiniapp>> integerListMap = miniMap.get(Long.valueOf(companyId));
                                         if (integerListMap != null) {
                                             int listIndexNum = 1;
@@ -856,6 +857,51 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                                     log.error("浏览器看课模板解析失败:" + e);
                                 }
                                 break;
+                            //跳转app看课
+                            case "23":
+                                try {
+                                    //生成看课记录
+                                    addWatchLogIfNeeded(
+                                            param.getSopId(),
+                                            param.getVideoId(), param.getCourseId(),
+                                            Long.valueOf(groupUser.getFsUserId()), qwUserId,
+                                            companyUserId, companyId,
+                                            groupUser.getId(), param.getStartTime(),
+                                            createTime, 2
+                                    );
+                                    //生成看课短链
+                                    String shortH5link = createH5LinkByMiniAppV2(st, param.getCorpId(), createTime, param.getCourseId(), param.getVideoId(),
+                                            String.valueOf(qwUser.getId()), companyUserId, companyId, groupUser.getId(), config);
+                                    st.setMiniprogramPage(shortH5link);
+                                } catch (Exception e) {
+                                    log.error("跳转app看课模板解析失败:" + e);
+                                }
+                                break;
+                            //跳转app直播
+                            case "24":
+                                try{
+                                    sopLogs.setSendType(20);//直播
+                                    qwUserId = String.valueOf(qwUser.getId());
+                                    //生成直播短链
+                                    String shortH5Link = createH5LiveShortLinkV2(st, param.getCorpId(),
+                                            qwUser.getId(), companyUserId, companyId);
+                                    st.setMiniprogramPage(shortH5Link);
+                                    String json0 = configService.selectConfigByKey("his.config");
+                                    FSSysConfig sysConfig0 = JSON.parseObject(json0, FSSysConfig.class);
+                                    //直播观看记录
+                                    createLiveWatchLogAndInsert(
+                                            qwUser.getCompanyId().toString(),
+                                            qwUser.getCompanyUserId().toString(),
+                                            groupUser.getId().toString(),
+                                            Long.valueOf(st.getLiveId()),
+                                            sysConfig0.getAppId(),
+                                            2,
+                                            String.valueOf(qwUser.getId()),
+                                            param.getCorpId());
+                                } catch (Exception e) {
+                                    log.error("跳转app直播模板解析失败:" + e);
+                                }
+                                break;
                             //群公告
                             case "11":
                                 sopLogs.setSendType(21); // 设置为群公告类型
@@ -1043,7 +1089,7 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
 //                                String luckyjson = configService.selectConfigByKey("luckyBag.config");
 //                                Map<String, Object> luckyBagConfig = JSON.parseObject(luckyjson, Map.class);
 //                                miniAppId = String.valueOf(luckyBagConfig.get("appId"));
-                               if (!miniMap.isEmpty() && qwUser.getSendMsgType() == 1) {
+                                if (!miniMap.isEmpty() && qwUser.getSendMsgType() == 1) {
                                     Map<Integer, List<CompanyMiniapp>> integerListMap = miniMap.get(Long.valueOf(companyId));
                                     if (integerListMap != null) {
                                         int listIndexNum = 1;
@@ -1193,9 +1239,9 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                 sopLogs.setSort(30000000);
                 sopLogs.setSendType(5);
                 sopLogs.setExternalUserName(item.getExternalUserName());
-                   if(sendLiveMsgFinal){
-                       sopLogs.setSendType(20);
-                   }
+                if(sendLiveMsgFinal){
+                    sopLogs.setSendType(20);
+                }
 
                 Long msgNum = Long.valueOf(generateRandomNumberWithLock());
                 sopLogs.setSmsLogsId(msgNum);
@@ -1252,15 +1298,15 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
 //                                    log.warn("生成短链失败,跳过设置 URL。");
 //                                }
 //                            }else {
-                                if ("1".equals(st.getContentType())) {
-                                    String defaultName = "同学";
-                                    if(contact != null && StringUtils.isNotEmpty(contact.getName()) && !"待同步客户".equals(contact.getName())){
-                                        defaultName = contact.getName();
-                                    }
-                                    st.setValue(st.getValue()
-                                            .replaceAll("#销售称呼#",StringUtil.strIsNullOrEmpty(qwUser.getWelcomeText())?"":qwUser.getWelcomeText())
-                                            .replaceAll("#客户称呼#",contact == null || StringUtil.strIsNullOrEmpty(contact.getStageStatus()) || "0".equals(contact.getStageStatus())?defaultName:contact.getStageStatus()));
+                            if ("1".equals(st.getContentType())) {
+                                String defaultName = "同学";
+                                if(contact != null && StringUtils.isNotEmpty(contact.getName()) && !"待同步客户".equals(contact.getName())){
+                                    defaultName = contact.getName();
                                 }
+                                st.setValue(st.getValue()
+                                        .replaceAll("#销售称呼#",StringUtil.strIsNullOrEmpty(qwUser.getWelcomeText())?"":qwUser.getWelcomeText())
+                                        .replaceAll("#客户称呼#",contact == null || StringUtil.strIsNullOrEmpty(contact.getStageStatus()) || "0".equals(contact.getStageStatus())?defaultName:contact.getStageStatus()));
+                            }
 //                            }
 
                             break;
@@ -1344,7 +1390,7 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                             FSSysConfig sysConfig= JSON.parseObject(js,FSSysConfig.class);
                             //发个人看课记录处理
                             try {
-                                    createLiveWatchLogAndInsert(qwUser.getCompanyId().toString(), qwUser.getCompanyUserId().toString(),item.getExternalId().toString(),Long.valueOf(st.getLiveId()),sysConfig.getAppId(),2, qwUserId,param.getCorpId());
+                                createLiveWatchLogAndInsert(qwUser.getCompanyId().toString(), qwUser.getCompanyUserId().toString(),item.getExternalId().toString(),Long.valueOf(st.getLiveId()),sysConfig.getAppId(),2, qwUserId,param.getCorpId());
 
                             } catch (Exception e) {
                                 log.error("群聊创建直播看课记录失败!", e);
@@ -1600,6 +1646,49 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                                 sopSmsLogsList.add(sopSmsLogs);
                             }
                             break;
+                        //跳转app看课
+                        case "23":
+                            try {
+                                //生成看课记录
+                                addWatchLogIfNeeded(
+                                        item.getSopId(),
+                                        param.getVideoId(), param.getCourseId(),
+                                        item.getFsUserId(), String.valueOf(qwUser.getId()),
+                                        companyUserId, companyId,
+                                        item.getExternalId(), item.getStartTime(),
+                                        createTime, 2);
+                                //生成看课短链
+                                String shortH5link = createH5LinkByMiniAppV2(st, param.getCorpId(), createTime, param.getCourseId(), param.getVideoId(),
+                                        String.valueOf(qwUser.getId()), companyUserId, companyId, item.getExternalId(), config);
+                                st.setMiniprogramPage(shortH5link);
+                            } catch (Exception e) {
+                                log.error("跳转app看课模板解析失败:" + e);
+                            }
+                            break;
+                        //跳转app直播
+                        case "24":
+                            try{
+                                sopLogs.setSendType(20);//直播
+                                //生成直播短链
+                                String shortH5Link = createH5LiveShortLinkV2(st, param.getCorpId(),
+                                        qwUser.getId(), companyUserId, companyId);
+                                st.setMiniprogramPage(shortH5Link);
+                                String json1 = configService.selectConfigByKey("his.config");
+                                FSSysConfig sysConfig0 = JSON.parseObject(json1, FSSysConfig.class);
+                                //直播观看记录
+                                createLiveWatchLogAndInsert(
+                                        qwUser.getCompanyId().toString(),
+                                        qwUser.getCompanyUserId().toString(),
+                                        item.getExternalId().toString(),
+                                        Long.valueOf(st.getLiveId()),
+                                        sysConfig0.getAppId(),
+                                        2,
+                                        String.valueOf(qwUser.getId()),
+                                        param.getCorpId());
+                            } catch (Exception e) {
+                                log.error("跳转app直播模板解析失败:" + e);
+                            }
+                            break;
                         //群公告(仅用于一键群发,个人不应该有群公告)
                         case "11":
                             log.warn("群公告不能发给个人,跳过处理,sopId:{}, externalId:{}", param.getSopId(), item.getExternalId());
@@ -1695,7 +1784,7 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
         param.setIds(ids);
         log.info("一键群发操作日志1:{}", JSON.toJSONString(param));
         processQwSopLogsBySendMsg(param,param.getDraftStrategy());
-        return null;
+        return R.ok();
     }
 
     @Override
@@ -2003,15 +2092,15 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
 //                            log.warn("生成短链失败,跳过设置 URL。");
 //                        }
 //                    }else {
-                        if ("1".equals(st.getContentType())) {
-                            String defaultName = "同学";
-                            if(contact != null && StringUtils.isNotEmpty(contact.getName()) && !"待同步客户".equals(contact.getName())){
-                                defaultName = contact.getName();
-                            }
-                            st.setValue(st.getValue()
-                                    .replaceAll("#销售称呼#",StringUtil.strIsNullOrEmpty(qwUser.getWelcomeText())?"":qwUser.getWelcomeText())
-                                    .replaceAll("#客户称呼#",contact == null || StringUtil.strIsNullOrEmpty(contact.getStageStatus()) || "0".equals(contact.getStageStatus())?defaultName:contact.getStageStatus()));
+                    if ("1".equals(st.getContentType())) {
+                        String defaultName = "同学";
+                        if(contact != null && StringUtils.isNotEmpty(contact.getName()) && !"待同步客户".equals(contact.getName())){
+                            defaultName = contact.getName();
                         }
+                        st.setValue(st.getValue()
+                                .replaceAll("#销售称呼#",StringUtil.strIsNullOrEmpty(qwUser.getWelcomeText())?"":qwUser.getWelcomeText())
+                                .replaceAll("#客户称呼#",contact == null || StringUtil.strIsNullOrEmpty(contact.getStageStatus()) || "0".equals(contact.getStageStatus())?defaultName:contact.getStageStatus()));
+                    }
 //                    }
 
                     break;
@@ -2359,12 +2448,55 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                         sopSmsLogsList.add(sopSmsLogs);
                     }
                     break;
+                //跳转app看课
+                case "23":
+                    try {
+                        //生成看课记录
+                        addWatchLogIfNeeded(
+                                item.getSopId(),
+                                param.getVideoId(), param.getCourseId(),
+                                item.getFsUserId(), String.valueOf(qwUser.getId()),
+                                companyUserId, companyId,
+                                item.getExternalId(), item.getStartTime(),
+                                dataTime, 2);
+                        //生成看课短链
+                        String shortH5link = createH5LinkByMiniAppV2(st, param.getCorpId(), dataTime, param.getCourseId(), param.getVideoId(),
+                                String.valueOf(qwUser.getId()), companyUserId, companyId, item.getExternalId(), config);
+                        st.setMiniprogramPage(shortH5link);
+                    } catch (Exception e) {
+                        log.error("跳转app看课模板解析失败:" + e);
+                    }
+                    break;
+                //跳转app直播
+                case "24":
+                    try{
+                        sopLogs.setSendType(20);//直播
+                        qwUserId = qwUser.getId();
+                        corpId = param.getCorpId();
+                        //生成直播短链
+                        shortH5Link = createH5LiveShortLinkV2(st, corpId,
+                                qwUserId, companyUserId, companyId);
+                        st.setMiniprogramPage(shortH5Link);
+                        String json0 = configService.selectConfigByKey("his.config");
+                        FSSysConfig sysConfig0 = JSON.parseObject(json0, FSSysConfig.class);
+                        //直播观看记录
+                        createLiveWatchLogAndInsert(
+                                qwUser.getCompanyId().toString(),
+                                qwUser.getCompanyUserId().toString(),
+                                item.getExternalId().toString(),
+                                Long.valueOf(st.getLiveId()),
+                                sysConfig0.getAppId(),
+                                2,
+                                String.valueOf(qwUser.getId()),
+                                param.getCorpId());
+                    } catch (Exception e) {
+                        log.error("跳转app直播模板解析失败:" + e);
+                    }
+                    break;
                 default:
                     break;
-
             }
         }
-
         return  list;
     }
 
@@ -2404,6 +2536,38 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
         return link.getRealLink();
     }
 
+    /**
+     * 创建看课短链
+     * @param setting
+     * @param corpId
+     * @param sendTime
+     * @param courseId
+     * @param videoId
+     * @param qwUserId
+     * @param companyUserId
+     * @param companyId
+     * @param externalId
+     * @param config
+     * @return
+     */
+    String createH5LinkByMiniAppV2(QwSopCourseFinishTempSetting.Setting setting, String corpId, Date sendTime,
+                                 Integer courseId, Integer videoId, String qwUserId,
+                                 String companyUserId, String companyId, Long externalId, CourseConfig config) {
+        FsCourseLink link = createFsCourseLink(corpId, sendTime, courseId, videoId, Long.valueOf(qwUserId),
+                companyUserId, companyId, externalId, 3, null);
+        FsCourseRealLink courseMap = new FsCourseRealLink();
+        BeanUtils.copyProperties(link, courseMap);
+        String courseJson = JSON.toJSONString(courseMap);
+        String realLinkFull = appRealLink + courseJson;
+        link.setRealLink(realLinkFull);
+        Date updateTime = createUpdateTime(setting, sendTime, config);
+        link.setUpdateTime(updateTime);
+        link.setCreateTime(new Date());
+        //存短链-
+        fsCourseLinkMapper.insertFsCourseLink(link);
+        return link.getRealLink();
+    }
+
     /**
      * 创建直播短链
      * @param setting
@@ -2447,6 +2611,42 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
     }
 
 
+    /**
+     * 创建直播短链
+     * @param setting
+     * @param corpId
+     * @param qwUserId
+     * @param companyUserId
+     * @param companyId
+     * @return
+     */
+    private String createH5LiveShortLinkV2(QwSopCourseFinishTempSetting.Setting setting, String corpId, Long qwUserId, String companyUserId, String companyId) {
+        // 手动创建 FsCourseLink 对象,避免使用 BeanUtils.copyProperties
+        FsCourseLink link = new FsCourseLink();
+        link.setCompanyId(Long.parseLong(companyId));
+        link.setQwUserId(Long.valueOf(qwUserId));
+        link.setCompanyUserId(Long.parseLong(companyUserId));
+        link.setLiveId(Long.valueOf(setting.getLiveId()));
+        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();
+        BeanUtils.copyProperties(link, courseMap);
+        String courseJson = JSON.toJSONString(link);
+        String realLinkFull = appLiveShortLink + courseJson;
+        link.setRealLink(realLinkFull);
+        //存短链-
+        fsCourseLinkMapper.insertFsCourseLink(link);
+        return link.getRealLink();
+    }
+
+
     public String createActivityLinkByMiniApp(QwSopCourseFinishTempSetting.Setting st, QwSopLogs sopLogs, String corpId, Date sendTime, Integer courseId, Integer videoId, String qwUserId, String companyUserId, String companyId, Long externalId, CourseConfig config, String chatId) {
         FsCourseLink link = createFsCourseLink(corpId, sendTime, courseId, videoId, Long.valueOf(qwUserId),
                 companyUserId, companyId, null, 3, chatId);
@@ -2643,8 +2843,8 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
 
     //插入观看记录
     public void addWatchLogIfNeeded(String sopId, Integer videoId, Integer courseId,
-                                     Long fsUserId, String qwUserId, String companyUserId,
-                                     String companyId, Long externalId, String startTime,Date createTime, Integer watchType) {
+                                    Long fsUserId, String qwUserId, String companyUserId,
+                                    String companyId, Long externalId, String startTime,Date createTime, Integer watchType) {
 
         try {
             FsCourseWatchLog watchLog = new FsCourseWatchLog();
@@ -2702,11 +2902,11 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
     }
 
     public String createLinkByMiniApp(QwSopCourseFinishTempSetting.Setting setting, String corpId, Date sendTime,
-                                     Integer courseId, Integer videoId, Long qwUserId,
-                                     String companyUserId, String companyId, Long externalId,CourseConfig config, String chatId) {
+                                      Integer courseId, Integer videoId, Long qwUserId,
+                                      String companyUserId, String companyId, Long externalId,CourseConfig config, String chatId) {
 
         FsCourseLink link = createFsCourseLink(corpId, sendTime, courseId, videoId, qwUserId,
-                                                companyUserId, companyId, externalId,3,chatId);
+                companyUserId, companyId, externalId,3,chatId);
 
         FsCourseRealLink courseMap = new FsCourseRealLink();
         BeanUtils.copyProperties(link,courseMap);
@@ -2791,7 +2991,7 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
         byAppVO.setSortLink(sortLink);
         byAppVO.setAppMsgLink(appMsgLink);
 
-            //异步生成app链接记录
+        //异步生成app链接记录
         asyncSopTestService.createFsCourseSopAppLink(link.getLink(),sendTime,updateTime,companyId,companyUserId,String.valueOf(qwUserId),
                 qwUserName,corpId,courseId,setting.getLinkTitle(),setting.getLinkImageUrl(),videoId,
                 setting.getLinkDescribe(),appMsgLink,externalId);

+ 0 - 2
fs-service/src/main/java/com/fs/sop/service/impl/SopUserLogsServiceImpl.java

@@ -107,8 +107,6 @@ public class SopUserLogsServiceImpl implements ISopUserLogsService {
     private QwGroupChatUserMapper qwGroupChatUserMapper;
     @Autowired
     private QwGroupChatMapper qwGroupChatMapper;
-
-
     @Autowired
     private ISysConfigService configService;
 

+ 6 - 0
fs-user-app/src/main/java/com/fs/app/controller/CourseController.java

@@ -376,6 +376,12 @@ public class CourseController extends  AppBaseController{
         return courseWatchLogService.decryptLink(param.getUrl());
     }
 
+    @ApiOperation("解密链接参数2.0")
+    @PostMapping("/decryptLink/v2")
+    public R decryptLinkV2(@RequestBody FsCourseEncryptLinkParam param) {
+        return courseWatchLogService.decryptLinkV2(param.getUrl());
+    }
+
 
     @ApiOperation("获取我的sop课程")
     @PostMapping("/getSopCourseH5StudyList")

+ 6 - 0
fs-user-app/src/main/java/com/fs/app/controller/live/LiveController.java

@@ -426,6 +426,12 @@ public class LiveController extends AppBaseController {
 		return liveService.liveDecryptLink(param.getUrl());
 	}
 
+	@ApiOperation("解密链接参数")
+	@PostMapping("/decryptLink/v2")
+	public R decryptLinkV2(@RequestBody FsLiveEncryptLinkParam param) {
+		return liveService.liveDecryptLink(param.getUrl());
+	}
+
 	@ApiOperation("获取微信小程序企微信息")
 	@PostMapping("/getLiveQwUserInfo/{qwUserId}")
 	public R getLiveQwUserInfo(@PathVariable Long qwUserId) {

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

@@ -34,6 +34,7 @@ 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.utils.PhoneUtil;
 import com.fs.sop.domain.QwSopTempVoice;
 import com.fs.sop.service.IQwSopTempVoiceService;
 import com.fs.system.oss.CloudStorageService;
@@ -57,7 +58,9 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
@@ -272,6 +275,27 @@ 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("上传声纹")
     @PostMapping("/addVoicePrintUrl")