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

益寿缘-销售端-新增h5页面获取获客链接的url接口

cgp 3 дней назад
Родитель
Сommit
53cc5d76f1

+ 3 - 0
fs-service/src/main/java/com/fs/qw/domain/QwAcquisitionAssistant.java

@@ -89,6 +89,9 @@ public class QwAcquisitionAssistant extends BaseEntity
     /** 主体corpId */
     private String corpId;
 
+    /** 页面参数 */
+    private String pageParam;
+
     /**
      * 将参数列表转换为JSON字符串
      */

+ 8 - 0
fs-service/src/main/java/com/fs/qw/mapper/QwAcquisitionAssistantMapper.java

@@ -74,4 +74,12 @@ public interface QwAcquisitionAssistantMapper
      * @return 结果
      */
     public int updateStatus(QwAcquisitionAssistant qwAcquisitionAssistant);
+
+    /**
+     * 根据pageParam查询
+     *
+     * @param pageParam
+     * @return
+     */
+    String selectQwAcquisitionUrlByPageParam(String pageParam);
 }

+ 6 - 0
fs-service/src/main/java/com/fs/qw/service/IQwAcquisitionAssistantService.java

@@ -91,4 +91,10 @@ public interface IQwAcquisitionAssistantService
      * @return 企微-获客链接管理
      */
     public QwAcquisitionAssistant selectQwAcquisitionAssistantById(Long id);
+
+    /**
+     * 根据页面参数查询获客链接url
+     * */
+    public String selectQwAcquisitionUrlByPageParam(String pageParam);
+
 }

+ 30 - 1
fs-service/src/main/java/com/fs/qw/service/impl/QwAcquisitionAssistantServiceImpl.java

@@ -13,6 +13,7 @@ import com.fs.qw.dto.acquisition.*;
 import com.fs.qw.mapper.QwAcquisitionAssistantMapper;
 import com.fs.qw.service.IQwAcquisitionAssistantService;
 import com.fs.qw.service.IQwCompanyService;
+import com.fs.qw.utils.UniqueStringUtil;
 import com.fs.qw.vo.AcquisitionAssistantDetailVO;
 import com.fs.qwApi.config.QwApiConfig;
 import com.fs.wx.kf.service.IWeixinKfService;
@@ -49,6 +50,10 @@ public class QwAcquisitionAssistantServiceImpl implements IQwAcquisitionAssistan
     // 获客链接管理-企微的ACCESS_TOKEN的key
     private static final String QW_ACQUISITION_KEY_PREFIX = "qw:acquisition:key:";
 
+
+    // 获客链接-页面参数-url的key
+    private static final String QW_ACQUISITION_URL_KEY_PREFIX = "qw:acquisition:url:key:";
+
     /**
      * 获取access_token并返回完整URL
      */
@@ -202,6 +207,7 @@ public class QwAcquisitionAssistantServiceImpl implements IQwAcquisitionAssistan
         }
     }
 
+
     // ==================== 列表相关方法 ====================
 
     @Override
@@ -526,7 +532,9 @@ public class QwAcquisitionAssistantServiceImpl implements IQwAcquisitionAssistan
 
             request.put("priority_option", priorityOption);
         }
-
+        //生成随机网页参数编码(字母+数字)
+        String randomParam = UniqueStringUtil.generateShortUnique();
+        assistant.setPageParam(randomParam);
         // 调用企微API
         String url = buildApiUrl(corpid, corpsecret, QwApiConfig.createAcquisition);
 
@@ -636,4 +644,25 @@ public class QwAcquisitionAssistantServiceImpl implements IQwAcquisitionAssistan
         }
         return assistant;
     }
+
+    @Override
+    public String selectQwAcquisitionUrlByPageParam(String pageParam) {
+        String key=QW_ACQUISITION_URL_KEY_PREFIX+pageParam;
+        String url=null;
+        try {
+            Object cacheObj = redisCache.getCacheObject(key);
+            if (cacheObj instanceof String) {
+                url = (String) cacheObj;
+                log.debug("从缓存获取获客链接url成功,pageParam:{}", pageParam);
+            }
+        } catch (Exception e) {
+            log.warn("从缓存获取获客链接url异常, 将重新获取, pageParam:{}", pageParam);
+        }
+        if (url == null){
+            url = qwAcquisitionAssistantMapper.selectQwAcquisitionUrlByPageParam(pageParam);
+            Integer cacheExpire = 15;//默认缓存15天
+            redisCache.setCacheObject(key, url, cacheExpire, TimeUnit.DAYS);
+        }
+        return url;
+    }
 }

+ 146 - 0
fs-service/src/main/java/com/fs/qw/utils/UniqueStringUtil.java

@@ -0,0 +1,146 @@
+package com.fs.qw.utils;
+
+import java.security.SecureRandom;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * 生成不重复的随机字符串工具类
+ * 用于生成网页参数编码、短链接等场景
+ */
+public class UniqueStringUtil {
+    
+    // 字符集:数字+大小写字母
+    private static final String CHAR_SET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+    private static final int BASE = CHAR_SET.length();
+    
+    // 安全随机数生成器
+    private static final SecureRandom SECURE_RANDOM = new SecureRandom();
+    
+    // 自增序列(保证同一毫秒内的唯一性)
+    private static final AtomicLong SEQUENCE = new AtomicLong(1);
+    
+    // 用于检查重复的缓存(可选,用于调试)
+    private static final ConcurrentHashMap<String, Boolean> GENERATED_CACHE = new ConcurrentHashMap<>();
+    
+    /**
+     * 生成指定长度的不重复随机字符串
+     * @param length 字符串长度
+     * @return 不重复的随机字符串
+     */
+    public static String generateUnique(int length) {
+        if (length <= 0 || length > 64) {
+            throw new IllegalArgumentException("Length must be between 1 and 64");
+        }
+        
+        String result;
+        do {
+            result = generateRandomString(length);
+        } while (GENERATED_CACHE.putIfAbsent(result, Boolean.TRUE) != null);
+        
+        return result;
+    }
+    
+    /**
+     * 生成带时间戳的随机字符串(确保唯一性)
+     * @param length 字符串长度
+     * @return 唯一字符串
+     */
+    public static String generateTimeBasedUnique(int length) {
+        // 时间戳部分(毫秒级,转换为36进制)
+        String timePart = Long.toString(System.currentTimeMillis(), 36);
+        
+        // 序列号部分(转换为62进制)
+        long seq = SEQUENCE.getAndIncrement();
+        if (seq >= Long.MAX_VALUE / 2) {
+            SEQUENCE.set(1);
+        }
+        String seqPart = toBase62(seq);
+        
+        // 随机部分
+        String randomPart = generateRandomString(length - Math.min(timePart.length() + seqPart.length(), length));
+        
+        // 组合
+        String result = (timePart + seqPart + randomPart).substring(0, length);
+        
+        return result;
+    }
+    
+    /**
+     * 生成短字符串(8-16位,适合做网页参数)
+     * @return 唯一短字符串
+     */
+    public static String generateShortUnique() {
+        return generateTimeBasedUnique(12);
+    }
+    
+    /**
+     * 生成长字符串(32位,类似UUID)
+     * @return 唯一长字符串
+     */
+    public static String generateLongUnique() {
+        return generateTimeBasedUnique(32);
+    }
+    
+    /**
+     * 生成随机字符串
+     */
+    private static String generateRandomString(int length) {
+        StringBuilder sb = new StringBuilder(length);
+        for (int i = 0; i < length; i++) {
+            int index = SECURE_RANDOM.nextInt(BASE);
+            sb.append(CHAR_SET.charAt(index));
+        }
+        return sb.toString();
+    }
+    
+    /**
+     * 将数字转换为62进制字符串
+     */
+    private static String toBase62(long number) {
+        if (number == 0) return "0";
+        
+        StringBuilder sb = new StringBuilder();
+        long num = number;
+        
+        while (num > 0) {
+            int remainder = (int) (num % 62);
+            sb.append(CHAR_SET.charAt(remainder));
+            num = num / 62;
+        }
+        
+        return sb.reverse().toString();
+    }
+    
+    /**
+     * 生成批量唯一字符串
+     */
+    public static String[] generateBatch(int count, int length) {
+        String[] results = new String[count];
+        for (int i = 0; i < count; i++) {
+            results[i] = generateTimeBasedUnique(length);
+        }
+        return results;
+    }
+    
+    public static void main(String[] args) {
+        System.out.println("=== 测试生成唯一字符串 ===");
+        
+        // 测试生成10个短字符串
+        System.out.println("\n生成10个短字符串(12位):");
+        for (int i = 0; i < 10; i++) {
+            System.out.println(generateShortUnique());
+        }
+        
+        // 测试生成长字符串
+        System.out.println("\n生成长字符串(32位):");
+        System.out.println(generateLongUnique());
+        
+        // 测试批量生成
+        System.out.println("\n批量生成5个16位字符串:");
+        String[] batch = generateBatch(5, 16);
+        for (String s : batch) {
+            System.out.println(s);
+        }
+    }
+}

+ 17 - 1
fs-service/src/main/resources/mapper/qw/QwAcquisitionAssistantMapper.xml

@@ -26,13 +26,14 @@
         <result property="delFlag"            column="del_flag"          />
         <result property="corpId"            column="corp_id"          />
         <result property="syncTime"            column="sync_time"          />
+        <result property="pageParam"            column="page_param"          />
     </resultMap>
 
     <sql id="selectQwAcquisitionAssistantVo">
         select id, link_id, link_name, url, scheme, qw_create_time, skip_verify,
                mark_source, priority_type, user_list, department_list, priority_user_list,
                qw_user_table_id_list,range_desc, status, remark,
-               create_by, create_time, update_by, update_time, del_flag,corp_id,sync_time
+               create_by, create_time, update_by, update_time, del_flag,corp_id,sync_time,page_param
         from qw_acquisition_assistant
     </sql>
 
@@ -74,6 +75,9 @@
             <if test="corpId != null">
                 and corp_id = #{corpId}
             </if>
+            <if test="pageParam != null">
+                and page_param = #{pageParam}
+            </if>
             <if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
                 and date_format(qw_create_time, '%y%m%d') &gt;= date_format(#{params.beginTime}, '%y%m%d')
             </if>
@@ -84,6 +88,15 @@
         order by create_time desc
     </select>
 
+    <select id="selectQwAcquisitionUrlByPageParam" resultType="java.lang.String" parameterType="java.lang.String">
+        SELECT url
+        FROM qw_acquisition_assistant
+        WHERE page_param = #{pageParam}
+          AND status = 1
+          AND del_flag = '0'
+        ORDER BY create_time DESC
+    </select>
+
     <!-- 新增 -->
     <insert id="insertQwAcquisitionAssistant" parameterType="QwAcquisitionAssistant" useGeneratedKeys="true" keyProperty="id">
         insert into qw_acquisition_assistant
@@ -109,6 +122,7 @@
             <if test="delFlag != null">del_flag,</if>
             <if test="corpId != null">corp_id,</if>
             <if test="syncTime != null">sync_time,</if>
+            <if test="pageParam != null">page_param,</if>
         </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="linkId != null">#{linkId},</if>
@@ -132,6 +146,7 @@
             <if test="delFlag != null">#{delFlag},</if>
             <if test="corpId != null">#{corpId},</if>
             <if test="syncTime != null">#{syncTime},</if>
+            <if test="pageParam != null">#{pageParam},</if>
         </trim>
     </insert>
 
@@ -156,6 +171,7 @@
             <if test="updateTime != null">update_time = #{updateTime},</if>
             <if test="corpId != null">corp_id = #{corpId},</if>
             <if test="syncTime != null">sync_time = #{syncTime},</if>
+            <if test="pageParam != null">page_param = #{pageParam},</if>
         </trim>
         where id = #{id}
     </update>

+ 31 - 0
fs-user-app/src/main/java/com/fs/app/controller/CustomerLinkWeChatController.java

@@ -0,0 +1,31 @@
+package com.fs.app.controller;
+
+import com.fs.qw.service.IQwAcquisitionAssistantService;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 获客链接+微信
+ * */
+@Slf4j
+@RestController
+@RequestMapping(value="/app/customerLinkWeChat")
+public class CustomerLinkWeChatController  extends AppBaseController{
+    @Autowired
+    private IQwAcquisitionAssistantService qwAcquisitionAssistantService;
+
+    /**
+     * 获取跳转链接
+     * */
+    @GetMapping("/goToLink/{pageParam}")
+    @CrossOrigin
+    public String goToLink(@PathVariable String pageParam) {
+        if (StringUtils.isBlank(pageParam)){
+            return "参数错误";
+        }
+        String url = qwAcquisitionAssistantService.selectQwAcquisitionUrlByPageParam(pageParam);
+        return url;
+    }
+}