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

coding:投流代码提交

zhangqin преди 2 дни
родител
ревизия
a77cf3a645
променени са 18 файла, в които са добавени 442 реда и са изтрити 75 реда
  1. 2 4
      fs-ad-new-api/src/main/java/com/fs/app/controller/LandingPageController.java
  2. 1 7
      fs-ad-new-api/src/main/java/com/fs/app/facade/CallbackProcessingFacadeService.java
  3. 126 37
      fs-ad-new-api/src/main/java/com/fs/app/facade/CallbackProcessingFacadeServiceImpl.java
  4. 46 7
      fs-company/src/main/java/com/fs/company/controller/qw/QwAssignRuleController.java
  5. 18 2
      fs-company/src/main/java/com/fs/company/controller/qw/QwCustomerLinkController.java
  6. 6 0
      fs-company/src/main/java/com/fs/company/controller/qw/QwGroupLiveCodeController.java
  7. 19 2
      fs-service/src/main/java/com/fs/newAdv/domain/Lead.java
  8. 1 1
      fs-service/src/main/java/com/fs/newAdv/domain/Site.java
  9. 18 0
      fs-service/src/main/java/com/fs/qw/controller/QwAssignRuleUserController.java
  10. 4 9
      fs-service/src/main/java/com/fs/qw/domain/QwAssignRule.java
  11. 85 0
      fs-service/src/main/java/com/fs/qw/domain/QwAssignRuleUser.java
  12. 5 4
      fs-service/src/main/java/com/fs/qw/domain/QwCustomerLink.java
  13. 5 0
      fs-service/src/main/java/com/fs/qw/domain/QwCustomerLinkUser.java
  14. 18 0
      fs-service/src/main/java/com/fs/qw/mapper/QwAssignRuleUserMapper.java
  15. 23 0
      fs-service/src/main/java/com/fs/qw/service/IQwAssignRuleUserService.java
  16. 1 0
      fs-service/src/main/java/com/fs/qw/service/IQwGroupActualService.java
  17. 45 0
      fs-service/src/main/java/com/fs/qw/service/impl/QwAssignRuleUserServiceImpl.java
  18. 19 2
      fs-service/src/main/java/com/fs/qw/service/impl/QwGroupActualServiceImpl.java

+ 2 - 4
fs-ad-new-api/src/main/java/com/fs/app/controller/LandingPageController.java

@@ -2,6 +2,7 @@ package com.fs.app.controller;
 
 import cn.hutool.core.util.StrUtil;
 import com.fs.app.facade.CallbackProcessingFacadeService;
+import com.fs.common.annotation.DistributeLock;
 import com.fs.common.result.Result;
 import com.fs.newAdv.dto.req.LandingIndexReq;
 import com.fs.newAdv.dto.res.LandingIndexRes;
@@ -34,11 +35,8 @@ public class LandingPageController {
     public Result<LandingIndexRes> track(
             @RequestBody LandingIndexReq req) {
         log.info("落地页访问追踪:req={}", req);
-        Long siteId = Long.valueOf(req.getAllParams().get("siteId"));
-        // 保存落地页访问记录
-        facadeService.saveLandingIndexTrace(siteId, req.getAllParams());
         // 查询落地页模板
-        return Result.success(facadeService.getLandingIndexBySiteId(siteId));
+        return Result.success(facadeService.getLandingIndexBySiteId(req.getAllParams()));
     }
 
 }

+ 1 - 7
fs-ad-new-api/src/main/java/com/fs/app/facade/CallbackProcessingFacadeService.java

@@ -12,19 +12,13 @@ public interface CallbackProcessingFacadeService {
      * @param allParams
      */
     void saveClickTrace(Long advertiserCode,Map<String,String> allParams);
-
-    /**
-     * 落地页追踪点击
-     * @param allParams
-     */
-    void saveLandingIndexTrace(Long siteId, Map<String, String> allParams);
     /**
      * 根据站点ID获取落地页信息
      *
      * @param siteId
      * @return
      */
-    LandingIndexRes getLandingIndexBySiteId(Long siteId);
+    LandingIndexRes getLandingIndexBySiteId(Map<String, String> allParams);
 
     //----------------------code回调---------------------------------
     void gdtGetAuthCode(Integer code, Long state);

+ 126 - 37
fs-ad-new-api/src/main/java/com/fs/app/facade/CallbackProcessingFacadeServiceImpl.java

@@ -2,27 +2,39 @@ package com.fs.app.facade;
 
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
 import com.fs.app.integration.adapter.IAdvertiserAdapter;
-import com.fs.app.integration.client.IAccessTokenClient;
-import com.fs.app.integration.client.IApiClient;
 import com.fs.app.integration.factory.AdvertiserHandlerFactory;
 import com.fs.common.exception.base.BusinessException;
+import com.fs.common.utils.RedisUtil;
 import com.fs.newAdv.domain.LandingPageTemplate;
 import com.fs.newAdv.domain.Lead;
-import com.fs.newAdv.domain.PromotionAccount;
 import com.fs.newAdv.domain.Site;
 import com.fs.newAdv.dto.res.LandingIndexRes;
 import com.fs.newAdv.enums.AdvertiserTypeEnum;
 import com.fs.newAdv.service.ILandingPageTemplateService;
 import com.fs.newAdv.service.ILeadService;
-import com.fs.newAdv.service.IPromotionAccountService;
 import com.fs.newAdv.service.ISiteService;
+import com.fs.qw.domain.QwAssignRule;
+import com.fs.qw.domain.QwAssignRuleUser;
+import com.fs.qw.domain.QwContactWay;
+import com.fs.qw.domain.QwGroupActual;
+import com.fs.qw.service.IQwAssignRuleService;
+import com.fs.qw.service.IQwAssignRuleUserService;
+import com.fs.qw.service.IQwContactWayService;
+import com.fs.qw.service.IQwGroupActualService;
+import com.fs.qwApi.Result.QwAddContactWayResult;
+import com.fs.qwApi.param.QwAddContactWayParam;
+import com.fs.qwApi.service.QwApiService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.time.LocalDateTime;
+import java.util.Collections;
+import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 
@@ -36,9 +48,22 @@ public class CallbackProcessingFacadeServiceImpl implements CallbackProcessingFa
     @Autowired
     private ISiteService siteService;
     @Autowired
+    private IQwAssignRuleUserService assignRuleUserService;
+    @Autowired
+    private IQwAssignRuleService assignRuleService;
+    @Autowired
     private ILandingPageTemplateService landingPageTemplateService;
     @Autowired
-    private IPromotionAccountService promotionAccountService;
+    private IQwGroupActualService actualService;
+    @Autowired
+    private QwApiService qwApiService;
+    @Autowired
+    private IQwContactWayService contactWayService;
+
+    @Autowired
+    private RedisUtil redisUtil;
+
+    private static final String QR_CODE_KEY = "new-adv:qr-code:";
 
     @Override
     public void saveClickTrace(Long advertiserCode, Map<String, String> allParams) {
@@ -58,11 +83,43 @@ public class CallbackProcessingFacadeServiceImpl implements CallbackProcessingFa
         }
     }
 
+    private String getTraceIdByAdvertiser(AdvertiserTypeEnum byCode, Map<String, String> allParams) {
+        switch (byCode) {
+            case OCEANENGINE:
+                return allParams.get("click_id");
+            case TENCENT:
+                return allParams.get("click_id");
+            case OPPO:
+                return allParams.get("traceId");
+            case BAIDU:
+                return allParams.get("bd_vid");
+            case VIVO:
+                return allParams.get("requestId");
+            case IQIYI:
+                return allParams.get("traceId");
+            default:
+                return "ylrz_test";
+        }
+    }
+
     @Override
-    public void saveLandingIndexTrace(Long siteId, Map<String, String> allParams) {
+    @Transactional(rollbackFor = Exception.class)
+    public LandingIndexRes getLandingIndexBySiteId(Map<String, String> allParams) {
+        String paramsSiteId = allParams.get("siteId");
+        if (ObjectUtil.isEmpty(paramsSiteId)) {
+            log.error("站点id不存在:{}", paramsSiteId);
+            return null;
+        }
+        Long siteId = Long.valueOf(paramsSiteId);
         Site byId = siteService.getById(siteId);
+        if (ObjectUtil.isEmpty(byId)) {
+            log.error("站点信息不存在:{}", siteId);
+            return null;
+        }
         Long advertiserId = byId.getAdvertiserId();
+        // 访问链路id
         String traceId = getTraceIdByAdvertiser(Objects.requireNonNull(AdvertiserTypeEnum.getByCode(advertiserId)), allParams);
+        // 保存落地页访问记录
         Lead byTraceId = leadService.getByTraceId(traceId);
         if (ObjectUtil.isEmpty(byTraceId)) {
             byTraceId = new Lead();
@@ -74,48 +131,80 @@ public class CallbackProcessingFacadeServiceImpl implements CallbackProcessingFa
             log.info("落地页站点信息异常:{}---{}", byTraceId.getSiteId(), siteId);
         }
         if (!Objects.equals(byTraceId.getAdvertiserId(), advertiserId)) {
-            log.info("落地页站点信息异常:{}---{}", byTraceId.getAdvertiserId(), advertiserId);
+            log.info("落地页广告商信息异常:{}---{}", byTraceId.getAdvertiserId(), advertiserId);
         }
         byTraceId.setLandingPageRawParams(JSONUtil.toJsonStr(allParams));
         byTraceId.setLandingPageTrigger(1);
         byTraceId.setLandingPageTs(LocalDateTime.now());
         byTraceId.setUpdateTime(LocalDateTime.now());
-        leadService.updateById(byTraceId);
-    }
-
-    private String getTraceIdByAdvertiser(AdvertiserTypeEnum byCode, Map<String, String> allParams) {
-        switch (byCode) {
-            case OCEANENGINE:
-                return allParams.get("click_id");
-            case TENCENT:
-                return allParams.get("click_id");
-            case OPPO:
-                return allParams.get("traceId");
-            case BAIDU:
-                return allParams.get("bdVid");
-            case VIVO:
-                return allParams.get("requestId");
-            case IQIYI:
-                return allParams.get("traceId");
-            default:
-                return null;
+        if (ObjectUtil.isEmpty(byTraceId)) {
+            leadService.save(byTraceId);
+        } else {
+            leadService.updateById(byTraceId);
         }
-    }
 
-    @Override
-    public LandingIndexRes getLandingIndexBySiteId(Long siteId) {
-        Site byId = siteService.getById(siteId);
-        LandingPageTemplate byId1 = landingPageTemplateService.getById(byId.getLaunchPageId());
-        String templateData = byId1.getTemplateData();
-        // JSONArray objects = JSONUtil.parseArray(templateData);
-/*        objects.jsonIter().forEach(o -> {
-            o.getStr("h5-qrcode")
-        });*/
+
+        // 查询模板数据
+        LandingPageTemplate landingPageTemplate = landingPageTemplateService.getById(byId.getLaunchPageId());
+        // 更新动态页面二维码数据
+        JSONObject jsonObject = JSONUtil.parseObj(landingPageTemplate.getTemplateData());
+        JSONArray jsonArray = jsonObject.getJSONArray("configList");
+        jsonArray.stream().iterator().forEachRemaining(item -> {
+            JSONObject itemObj = (JSONObject) item;
+            JSONArray moduleList = itemObj.getJSONArray("moduleList");
+            moduleList.stream().iterator().forEachRemaining(module -> {
+                JSONObject moduleObj = (JSONObject) module;
+                String type = moduleObj.getStr("type");
+                // 判断是否有二维码控件
+                if ("h5-qrcode".equals(type)) {
+                    // 按照配置规则获取二维码链接
+                    String qrCode = redisUtil.get(QR_CODE_KEY + traceId).toString();
+                    if (qrCode == null) {
+                        qrCode = getQrCodeByAllocationRuleId(byId.getLaunchType(), byId.getAllocationRuleId());
+                    }
+                    // 设置二维码
+                    moduleObj.set("workUrl", qrCode);
+                }
+            });
+        });
+        // 封装返回结果
         LandingIndexRes res = new LandingIndexRes();
-        res.setTemplateData(byId1.getTemplateData());
+        res.setTemplateData(JSONUtil.toJsonStr(jsonObject));
         return res;
     }
 
+    private String getQrCodeByAllocationRuleId(Integer launchType, Long allocationRuleId) {
+        // 二维码
+        String qrCode = "";
+        if (allocationRuleId == 1) {
+            // 个人分配规则
+            QwAssignRule byId1 = assignRuleService.getById(allocationRuleId);
+            QwAssignRuleUser qwAssignRuleUser = assignRuleUserService.getUserByAllocationRuleId(allocationRuleId, byId1.getAssignType());
+            if (byId1.getAssignType().equals(3)) {
+                List<String> users = Collections.singletonList(qwAssignRuleUser.getQwUserId());
+                QwAddContactWayParam qwAddContactWayParam = new QwAddContactWayParam();
+                qwAddContactWayParam.setType(1);
+                qwAddContactWayParam.setScene(2);
+                qwAddContactWayParam.setUser(users);
+                qwAddContactWayParam.setSkip_verify(true);
+                QwAddContactWayResult qwAddContactWayResult = qwApiService.addContactWay(qwAddContactWayParam, qwAssignRuleUser.getCorpId());
+                qrCode = qwAddContactWayResult.getQr_code();
+            }
+        } else if (allocationRuleId == 2) {
+            // 活码分配规则
+            if (launchType.equals(1)) {
+                // 线上规则--群活码
+                QwGroupActual qwGroupActual = actualService.getGroupActualByAllocationRuleId(allocationRuleId);
+                qrCode = qwGroupActual.getGroupUrl();
+            } else if (launchType.equals(2)) {
+                // 线下规则--个人活码
+                QwContactWay qwContactWay = contactWayService.selectQwContactWayById(allocationRuleId);
+                qrCode = qwContactWay.getQrCode();
+            }
+        }
+        return qrCode;
+    }
+
     @Override
     public void gdtGetAuthCode(Integer code, Long state) {
    /*     if (code == null || state == null) {

+ 46 - 7
fs-company/src/main/java/com/fs/company/controller/qw/QwAssignRuleController.java

@@ -1,21 +1,22 @@
 package com.fs.company.controller.qw;
 
-import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.fs.common.result.Result;
 import com.fs.qw.domain.QwAssignRule;
-import com.fs.qw.domain.QwGroupActual;
+import com.fs.qw.domain.QwAssignRuleUser;
 import com.fs.qw.service.IQwAssignRuleService;
+import com.fs.qw.service.IQwAssignRuleUserService;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.validation.annotation.Validated;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.*;
 
 /**
  * <p>
- *  前端控制器
+ * 前端控制器
  * </p>
  *
  * @author zhangqin
@@ -26,8 +27,12 @@ import org.springframework.web.bind.annotation.*;
 public class QwAssignRuleController {
     @Autowired
     private IQwAssignRuleService qwAssignRuleService;
+    @Autowired
+
+    private IQwAssignRuleUserService qwAssignRuleUserService;
+
     /**
-     * 分页查询渠道
+     * 分页查询微信分配规则
      */
     @GetMapping("/page")
     public Result<IPage<QwAssignRule>> page(
@@ -40,20 +45,54 @@ public class QwAssignRuleController {
         wrapper.like(StrUtil.isNotBlank(ruleName), QwAssignRule::getRuleName, ruleName);
         wrapper.orderByDesc(QwAssignRule::getCreateTime);
         IPage<QwAssignRule> result = qwAssignRuleService.page(page, wrapper);
+        result.getRecords().forEach(item -> {
+            item.setQwAssignRuleUsers(qwAssignRuleUserService.list(new LambdaQueryWrapper<QwAssignRuleUser>()
+                    .eq(QwAssignRuleUser::getAssignId, item.getId())));
+        });
         return Result.success(result);
     }
 
     /**
-     * 创建企业微信
+     * 创建修改分配规则
      */
     @PostMapping("/addOrUpdate")
-    public Result<Void> create(@RequestBody QwAssignRule qwGroupLiveCode) {
+    @Transactional(rollbackFor = Exception.class)
+    public Result<QwAssignRule> create(@RequestBody QwAssignRule qwGroupLiveCode) {
         boolean success = false;
         if (qwGroupLiveCode.getId() != null) {
             success = qwAssignRuleService.updateById(qwGroupLiveCode);
         } else {
             success = qwAssignRuleService.save(qwGroupLiveCode);
         }
+        if (success) {
+            qwAssignRuleUserService.remove(new LambdaQueryWrapper<QwAssignRuleUser>()
+                    .eq(QwAssignRuleUser::getAssignId, qwGroupLiveCode.getId()));
+            for (QwAssignRuleUser qwAssignRuleUser : qwGroupLiveCode.getQwAssignRuleUsers()) {
+                qwAssignRuleUser.setAssignId(qwGroupLiveCode.getId());
+            }
+            qwAssignRuleUserService.saveBatch(qwGroupLiveCode.getQwAssignRuleUsers());
+        }
+
         return success ? Result.success() : Result.error("创建失败");
     }
+
+    /**
+     * 启用状态
+     */
+    @PostMapping("/enable/{id}/{status}")
+    @Transactional(rollbackFor = Exception.class)
+    public Result<QwAssignRule> create(@PathVariable Long id, @PathVariable Integer status) {
+        boolean update = qwAssignRuleService.update(new LambdaUpdateWrapper<QwAssignRule>()
+                .eq(QwAssignRule::getId, id)
+                .set(QwAssignRule::getStatus, status));
+        return update ? Result.success() : Result.error("修改失败");
+    }
+
+    @GetMapping("/{id}")
+    public Result<QwAssignRule> create(@PathVariable Long id) {
+        QwAssignRule byId = qwAssignRuleService.getById(id);
+        byId.setQwAssignRuleUsers(qwAssignRuleUserService.list(new LambdaQueryWrapper<QwAssignRuleUser>()
+                .eq(QwAssignRuleUser::getAssignId, id)));
+        return Result.success(byId);
+    }
 }

+ 18 - 2
fs-company/src/main/java/com/fs/company/controller/qw/QwCustomerLinkController.java

@@ -17,7 +17,6 @@ import com.fs.qw.dto.QwCustomerLinkUserDto;
 import com.fs.qw.service.IQwCustomerLinkChannelService;
 import com.fs.qw.service.IQwCustomerLinkService;
 import com.fs.qw.service.IQwCustomerLinkUserService;
-import com.fs.qwApi.domain.QwLinkCreateResult;
 import com.fs.qwApi.param.QwLinkCreateParam;
 import com.fs.qwApi.service.QwApiService;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -75,12 +74,14 @@ public class QwCustomerLinkController {
     public Result<IPage<QwCustomerLinkChannel>> pageChannel(
             @RequestParam(defaultValue = "1") Long pageNum,
             @RequestParam(defaultValue = "10") Long pageSize,
-            @RequestParam(required = false) String linkName
+            @RequestParam(required = false) String linkName,
+            @RequestParam(required = false) String sysLinkId
     ) {
         Page<QwCustomerLinkChannel> page = new Page<>(pageNum, pageSize);
         LambdaQueryWrapper<QwCustomerLinkChannel> wrapper = new LambdaQueryWrapper<>();
         wrapper.like(StrUtil.isNotBlank(linkName), QwCustomerLinkChannel::getLinkName, linkName);
         wrapper.eq(QwCustomerLinkChannel::getStatus, 0);
+        wrapper.eq(QwCustomerLinkChannel::getSysLinkId, sysLinkId);
         wrapper.orderByDesc(QwCustomerLinkChannel::getCreateTime);
         IPage<QwCustomerLinkChannel> result = qwCustomerLinkChannelService.page(page, wrapper);
         return Result.success(result);
@@ -125,6 +126,7 @@ public class QwCustomerLinkController {
                         user.setSysLinkId(bean.getId());
                         user.setQwUserId(e.getQwUserId());
                         user.setSysQwUserId(e.getSysQwUserId());
+                        user.setQwUserName(e.getQwUserName());
                         return user;
                     })
                     .collect(Collectors.toList()));
@@ -193,4 +195,18 @@ public class QwCustomerLinkController {
     public Result<Void> createChannel(@PathVariable Long id) {
         return qwCustomerLinkChannelService.removeById(id) ? Result.success() : Result.error("删除失败");
     }
+
+    /**
+     * 查询主链信息
+     *
+     * @param id
+     * @return
+     */
+    @GetMapping("/{id}")
+    public Result<QwCustomerLink> getById(@PathVariable Long id) {
+        QwCustomerLink byId = qwCustomerLinkService.getById(id);
+        byId.setQwCustomerLinkUsers(qwCustomerLinkUserService.list(new LambdaQueryWrapper<QwCustomerLinkUser>()
+                .eq(QwCustomerLinkUser::getSysLinkId, id)));
+        return Result.success(byId);
+    }
 }

+ 6 - 0
fs-company/src/main/java/com/fs/company/controller/qw/QwGroupLiveCodeController.java

@@ -57,4 +57,10 @@ public class QwGroupLiveCodeController {
         }
         return success ? Result.success() : Result.error("创建失败");
     }
+
+
+    @GetMapping("/{id}")
+    public Result<QwGroupLiveCode> getById(@PathVariable Long id) {
+        return Result.success(qwGroupLiveCodeService.getById(id));
+    }
 }

+ 19 - 2
fs-service/src/main/java/com/fs/newAdv/domain/Lead.java

@@ -56,9 +56,26 @@ public class Lead implements Serializable {
      * 是否落地页触发 1是0否
      */
     private Integer landingPageTrigger;
+    /**
+     * qw_group_actual表id
+     */
+    private Long qwGroupActualId;
+    /**
+     * qw_contact_way表id
+     */
+    private Long qwContactWayId;
+
+    /**
+     * qw_assign_rule_user表Id
+     */
+    private Long qwAssignRuleUserId;
+    /**
+     * 是否添加 1是 0否
+     */
+    private Integer addContact;
 
     /**
-     /**
+     * /**
      * 创建时间
      */
     @TableField(value = "create_time", strategy = FieldStrategy.NOT_NULL)
@@ -108,7 +125,7 @@ public class Lead implements Serializable {
     /**
      * 落地页原始参数JSON
      */
-    private String  landingPageRawParams;
+    private String landingPageRawParams;
 
     /**
      * 落地页访问时间

+ 1 - 1
fs-service/src/main/java/com/fs/newAdv/domain/Site.java

@@ -112,7 +112,7 @@ public class Site implements Serializable {
      */
     private Integer status;
     /**
-     * 企微分配规则 1个人分配 2活码分配
+     * 企微分配规则 1个人分配规则 2活码分配
      */
     private Integer allocationRule;
     /**

+ 18 - 0
fs-service/src/main/java/com/fs/qw/controller/QwAssignRuleUserController.java

@@ -0,0 +1,18 @@
+package com.fs.qw.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 微信分配规则用户关联表 前端控制器
+ * </p>
+ *
+ * @author zhangqin
+ * @since 2025-12-05
+ */
+@RestController
+@RequestMapping("/qwAssignRuleUser")
+public class QwAssignRuleUserController {
+
+}

+ 4 - 9
fs-service/src/main/java/com/fs/qw/domain/QwAssignRule.java

@@ -14,6 +14,7 @@ import lombok.Setter;
 
 import java.io.Serializable;
 import java.time.LocalDateTime;
+import java.util.List;
 
 /**
  * <p>
@@ -32,7 +33,7 @@ public class QwAssignRule extends Model<QwAssignRule> {
     private static final long serialVersionUID = 1L;
 
     @TableId(value = "id", type = IdType.AUTO)
-    private Integer id;
+    private Long id;
 
     @ApiModelProperty("规则名称")
     @TableField("rule_name")
@@ -42,10 +43,6 @@ public class QwAssignRule extends Model<QwAssignRule> {
     @TableField("assign_type")
     private Integer assignType;
 
-    @ApiModelProperty("客服人员信息")
-    @TableField("assign_personnel_json")
-    private String assignPersonnelJson;
-
     @ApiModelProperty("是否启用 1是 0否")
     private Integer status;
 
@@ -59,8 +56,6 @@ public class QwAssignRule extends Model<QwAssignRule> {
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private LocalDateTime updateTime;
 
-    @Override
-    public Serializable pkVal() {
-        return this.id;
-    }
+    @TableField(exist = false)
+    private List<QwAssignRuleUser> qwAssignRuleUsers;
 }

+ 85 - 0
fs-service/src/main/java/com/fs/qw/domain/QwAssignRuleUser.java

@@ -0,0 +1,85 @@
+package com.fs.qw.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 微信分配规则用户关联表
+ * </p>
+ *
+ * @author zhangqin
+ * @since 2025-12-05
+ */
+@Getter
+@Setter
+@TableName("qw_assign_rule_user")
+@ApiModel(value = "QwAssignRuleUser对象", description = "微信分配规则用户关联表")
+public class QwAssignRuleUser extends Model<QwAssignRuleUser> {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty("id")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty("分配规则id")
+    @TableField("assign_id")
+    private Long assignId;
+
+    @ApiModelProperty("企微表ID")
+    @TableField("sys_qw_user_id")
+    private Long sysQwUserId;
+
+    @ApiModelProperty("企微微信昵称")
+    @TableField("qw_user_name")
+    private String qwUserName;
+
+    @ApiModelProperty("企微微信用户ID")
+    @TableField("qw_user_id")
+    private String qwUserId;
+
+
+    @ApiModelProperty("企微微信用户ID")
+    @TableField("corp_id")
+    private String corpId;
+
+
+    @ApiModelProperty("今日分配数")
+    @TableField("assign_num_to_day")
+    private Integer assignNumToDay;
+
+    @ApiModelProperty("累积分配数")
+    @TableField("assign_num_count")
+    private Integer assignNumCount;
+
+    @ApiModelProperty("今日添加数")
+    @TableField("add_num_to_day")
+    private Integer addNumToDay;
+
+    @ApiModelProperty("累积添加数")
+    @TableField("add_num_count")
+    private Integer addNumCount;
+    @ApiModelProperty("权重")
+    @TableField("weight")
+    private Integer weight;
+
+    @ApiModelProperty("创建时间")
+    @TableField("create_time")
+    private LocalDateTime createTime;
+
+    @Override
+    public Serializable pkVal() {
+        return this.id;
+    }
+}

+ 5 - 4
fs-service/src/main/java/com/fs/qw/domain/QwCustomerLink.java

@@ -12,6 +12,7 @@ import lombok.Setter;
 
 import java.io.Serializable;
 import java.time.LocalDateTime;
+import java.util.List;
 
 /**
  * <p>
@@ -77,8 +78,8 @@ public class QwCustomerLink extends Model<QwCustomerLink> {
     @TableField("status")
     private Integer status;
 
-    @Override
-    public Serializable pkVal() {
-        return this.id;
-    }
+    @TableField(exist = false)
+    private List<QwCustomerLinkUser> qwCustomerLinkUsers;
+
+
 }

+ 5 - 0
fs-service/src/main/java/com/fs/qw/domain/QwCustomerLinkUser.java

@@ -36,6 +36,7 @@ public class QwCustomerLinkUser extends Model<QwCustomerLinkUser> {
     @ApiModelProperty("链接ID")
     @TableField("sys_link_id")
     private Long sysLinkId;
+
     @ApiModelProperty("企微表ID")
     @TableField("sys_qw_user_id")
     private Long sysQwUserId;
@@ -44,6 +45,10 @@ public class QwCustomerLinkUser extends Model<QwCustomerLinkUser> {
     @TableField("qw_user_id")
     private String qwUserId;
 
+    @ApiModelProperty("企微微信用户Name")
+    @TableField("qw_user_name")
+    private String qwUserName;
+
     @ApiModelProperty("创建时间")
     @TableField("create_time")
     private LocalDateTime createTime;

+ 18 - 0
fs-service/src/main/java/com/fs/qw/mapper/QwAssignRuleUserMapper.java

@@ -0,0 +1,18 @@
+package com.fs.qw.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.qw.domain.QwAssignRuleUser;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ * 微信分配规则用户关联表 Mapper 接口
+ * </p>
+ *
+ * @author zhangqin
+ * @since 2025-12-05
+ */
+@Mapper
+public interface QwAssignRuleUserMapper extends BaseMapper<QwAssignRuleUser> {
+
+}

+ 23 - 0
fs-service/src/main/java/com/fs/qw/service/IQwAssignRuleUserService.java

@@ -0,0 +1,23 @@
+package com.fs.qw.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.qw.domain.QwAssignRuleUser;
+
+/**
+ * <p>
+ * 微信分配规则用户关联表 服务类
+ * </p>
+ *
+ * @author zhangqin
+ * @since 2025-12-05
+ */
+public interface IQwAssignRuleUserService extends IService<QwAssignRuleUser> {
+
+    /**
+     * 按照规则返回数据
+     * @param id
+     * @param assignType
+     * @return
+     */
+    QwAssignRuleUser getUserByAllocationRuleId(Long id, Integer assignType);
+}

+ 1 - 0
fs-service/src/main/java/com/fs/qw/service/IQwGroupActualService.java

@@ -14,4 +14,5 @@ import com.fs.qw.domain.QwGroupActual;
  */
 public interface IQwGroupActualService extends IService<QwGroupActual> {
 
+    QwGroupActual getGroupActualByAllocationRuleId(Long allocationRuleId);
 }

+ 45 - 0
fs-service/src/main/java/com/fs/qw/service/impl/QwAssignRuleUserServiceImpl.java

@@ -0,0 +1,45 @@
+package com.fs.qw.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fs.qw.domain.QwAssignRuleUser;
+import com.fs.qw.mapper.QwAssignRuleUserMapper;
+import com.fs.qw.service.IQwAssignRuleUserService;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * <p>
+ * 微信分配规则用户关联表 服务实现类
+ * </p>
+ *
+ * @author zhangqin
+ * @since 2025-12-05
+ */
+@Service
+public class QwAssignRuleUserServiceImpl extends ServiceImpl<QwAssignRuleUserMapper, QwAssignRuleUser> implements IQwAssignRuleUserService {
+
+    @Override
+    public QwAssignRuleUser getUserByAllocationRuleId(Long id, Integer assignType) {
+        List<QwAssignRuleUser> list = list(new LambdaQueryWrapper<QwAssignRuleUser>()
+                .eq(QwAssignRuleUser::getAssignId, id));
+        int totalWeight = list.stream()
+                .mapToInt(QwAssignRuleUser::getWeight)
+                .sum();
+
+        int random = ThreadLocalRandom.current().nextInt(totalWeight);
+
+        AtomicInteger acc = new AtomicInteger();
+
+        return list.stream()
+                .filter(item -> {
+                    acc.addAndGet(item.getWeight());
+                    return acc.get() > random;
+                })
+                .findFirst()
+                .orElse(null);
+    }
+}

+ 19 - 2
fs-service/src/main/java/com/fs/qw/service/impl/QwGroupActualServiceImpl.java

@@ -1,13 +1,16 @@
 package com.fs.qw.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-
+import com.fs.common.utils.RedisUtil;
 import com.fs.qw.domain.QwGroupActual;
 import com.fs.qw.mapper.QwGroupActualMapper;
-
 import com.fs.qw.service.IQwGroupActualService;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
+
 /**
  * <p>
  * 群活码实际二维码表 服务实现类
@@ -19,4 +22,18 @@ import org.springframework.stereotype.Service;
 @Service
 public class QwGroupActualServiceImpl extends ServiceImpl<QwGroupActualMapper, QwGroupActual> implements IQwGroupActualService {
 
+    @Autowired
+    private RedisUtil redisUtil;
+    // 轮询机计数
+    private final static String MY_ITEM_CURSOR = "new-adv:cursor:";
+
+    @Override
+    public QwGroupActual getGroupActualByAllocationRuleId(Long allocationRuleId) {
+        List<QwGroupActual> list = list(new LambdaQueryWrapper<QwGroupActual>()
+                .eq(QwGroupActual::getLiveCodeId, allocationRuleId));
+        int total = list.size();
+        long cursor = redisUtil.increment(MY_ITEM_CURSOR);
+        int index = (int) ((cursor - 1) % total);
+        return list.get(index);
+    }
 }