Sfoglia il codice sorgente

三方平台自动建群

wangyunpeng 2 giorni fa
parent
commit
8702439a0f
19 ha cambiato i file con 491 aggiunte e 109 eliminazioni
  1. 4 0
      api-module/src/main/java/com/tzld/piaoquan/api/common/enums/ExceptionEnum.java
  2. 65 35
      api-module/src/main/java/com/tzld/piaoquan/api/component/WeComThirdPartyApiClient.java
  3. 6 0
      api-module/src/main/java/com/tzld/piaoquan/api/controller/WeComThirdPartyController.java
  4. 2 2
      api-module/src/main/java/com/tzld/piaoquan/api/dao/generator/MybatisGeneratorMain.java
  5. 123 37
      api-module/src/main/java/com/tzld/piaoquan/api/job/wecom/thirdpart/WeComCreateRoomJob.java
  6. 2 10
      api-module/src/main/java/com/tzld/piaoquan/api/job/wecom/thirdpart/WeComSendMsgJob.java
  7. 34 0
      api-module/src/main/java/com/tzld/piaoquan/api/job/wecom/thirdpart/WeComUserDetailJob.java
  8. 23 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/AntiSpamRuleResponse.java
  9. 10 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/DisableRenameChatroomRequest.java
  10. 9 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/QueryCRMAntiSpamRuleRequest.java
  11. 11 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/SetRoomAntiRequest.java
  12. 14 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/UpdateRoomSendStatusRequest.java
  13. 11 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/po/wecom/thirdpart/ThirdPartWeComRoom.java
  14. 60 0
      api-module/src/main/java/com/tzld/piaoquan/api/model/po/wecom/thirdpart/ThirdPartWeComRoomExample.java
  15. 4 0
      api-module/src/main/java/com/tzld/piaoquan/api/service/WeComThirdPartyService.java
  16. 58 1
      api-module/src/main/java/com/tzld/piaoquan/api/service/impl/WeComThirdPartyServiceImpl.java
  17. 20 5
      api-module/src/main/resources/mapper/wecom/thirdpart/ThirdPartWeComRoomMapper.xml
  18. 22 18
      api-module/src/main/resources/mapper/wecom/thirdpart/ext/ThirdPartWeComMapperExt.xml
  19. 13 1
      api-module/src/test/java/com/tzld/piaoquan/api/WeComThirdPartTest.java

+ 4 - 0
api-module/src/main/java/com/tzld/piaoquan/api/common/enums/ExceptionEnum.java

@@ -48,6 +48,10 @@ public enum ExceptionEnum {
     API_PAGE_SIZE_TOO_LARGE(4002, "每页获取数量不能超过500条"),
     API_PAGE_URL_SIZE_TOO_LARGE(4002, "获取视频嵌入路径 每次最多3条"),
 
+    // 三方平台 自动拉群群发
+    THIRD_PART_STAFF_NOT_FOUND(5001, "账号不存在"),
+    THIRD_PART_ROOM_NOT_FOUND(5002, "群不存在"),
+
     // 自动回复
     CGI_REPLY_BUCKET_DATA_NOT_FOUND(10000, "自动回复数据不存在"),
     CGI_REPLY_BUCKET_DATA_NOT_AUTO_REPLY(10001, "非自动回复数据"),

+ 65 - 35
api-module/src/main/java/com/tzld/piaoquan/api/component/WeComThirdPartyApiClient.java

@@ -149,6 +149,36 @@ public class WeComThirdPartyApiClient {
         return postRequest("/wxwork/setRoomManagement", request);
     }
 
+    /**
+     * 禁止修改群名
+     *
+     * @param request 请求体
+     * @return 响应结果
+     */
+    public String disableRenameChatroom(DisableRenameChatroomRequest request) {
+        return postRequest("/wxwork/DisableRenameChatroom", request);
+    }
+
+    /**
+     * 获取群防骚扰规则列表
+     *
+     * @param request 请求体
+     * @return 响应结果
+     */
+    public String queryCRMAntiSpamRule(QueryCRMAntiSpamRuleRequest request) {
+        return postRequest("/wxwork/queryCRMAntiSpamRule", request);
+    }
+
+    /**
+     * 设置或者移除群防骚扰规则
+     *
+     * @param request 请求体
+     * @return 响应结果
+     */
+    public String setRoomAnti(SetRoomAntiRequest request) {
+        return postRequest("/wxwork/setRoomAnti", request);
+    }
+
     /**
      * 直接邀请进群
      *
@@ -160,7 +190,35 @@ public class WeComThirdPartyApiClient {
     }
 
     /**
-     * 发送消息
+     * 获取客户群列表
+     * @param request
+     * @return
+     */
+    public String getChatroomMembers(GetChatroomMembersRequest request) {
+        return postRequest("/wxwork/GetChatroomMembers", request);
+    }
+
+    /**
+     * 获取群成员列表
+     * @param request
+     * @return
+     */
+    public String getRoomUserList(GetRoomUserListRequest request) {
+        return postRequest("/wxwork/GetRoomUserList", request);
+    }
+
+    /**
+     * 转让群主
+     *
+     * @param request 请求体
+     * @return 响应结果
+     */
+    public String transferChatroomOwner(TransferChatroomOwnerRequest request) {
+        return postRequest("/wxwork/TransferChatroomOwner", request);
+    }
+
+    /**
+     * 发送文本消息
      *
      * @param request 请求体
      * {
@@ -177,7 +235,7 @@ public class WeComThirdPartyApiClient {
     }
 
     /**
-     * 发送消息
+     * 发送小程序消息
      *
      * @param request 请求体
      * {
@@ -203,13 +261,12 @@ public class WeComThirdPartyApiClient {
     }
 
     /**
-     * 转让群主
-     *
-     * @param request 请求体
-     * @return 响应结果
+     * CDN上传网络图片
+     * @param request
+     * @return
      */
-    public String transferChatroomOwner(TransferChatroomOwnerRequest request) {
-        return postRequest("/wxwork/TransferChatroomOwner", request);
+    public String cdnUploadImgLink(CdnUploadImgLinkRequest request) {
+        return postRequest("/wxwork/CdnUploadImgLink", request);
     }
 
     /**
@@ -222,33 +279,6 @@ public class WeComThirdPartyApiClient {
         return postRequest("/wxwork/LoginOut", request);
     }
 
-    /**
-     * 获取客户群列表
-     * @param request
-     * @return
-     */
-    public String getChatroomMembers(GetChatroomMembersRequest request) {
-        return postRequest("/wxwork/GetChatroomMembers", request);
-    }
-
-    /**
-     * 获取群成员列表
-     * @param request
-     * @return
-     */
-    public String getRoomUserList(GetRoomUserListRequest request) {
-        return postRequest("/wxwork/GetRoomUserList", request);
-    }
-
-    /**
-     * CDN上传网络图片
-     * @param request
-     * @return
-     */
-    public String cdnUploadImgLink(CdnUploadImgLinkRequest request) {
-        return postRequest("/wxwork/CdnUploadImgLink", request);
-    }
-
     private String postRequest(String path, Object requestBody) {
         String url = baseUrl + path;
         String json = JSONObject.toJSONString(requestBody);

+ 6 - 0
api-module/src/main/java/com/tzld/piaoquan/api/controller/WeComThirdPartyController.java

@@ -72,4 +72,10 @@ public class WeComThirdPartyController {
         return CommonResponse.success(service.getRoomUserList(request));
     }
 
+    @PostMapping("/updateRoomSendStatus")
+    public CommonResponse<Void> updateRoomSendStatus(@RequestBody UpdateRoomSendStatusRequest request) {
+        service.updateRoomSendStatus(request);
+        return CommonResponse.success();
+    }
+
 }

+ 2 - 2
api-module/src/main/java/com/tzld/piaoquan/api/dao/generator/MybatisGeneratorMain.java

@@ -20,10 +20,10 @@ public class MybatisGeneratorMain {
             throws SQLException, IOException, InterruptedException, InvalidConfigurationException, XMLParserException {
         List<String> warnings = new ArrayList<>();
 
-        File configFile = new File(MybatisGeneratorMain.class.getResource("/mybatis-generator-config.xml").getFile());
+        //File configFile = new File(MybatisGeneratorMain.class.getResource("/mybatis-generator-config.xml").getFile());
 //        File configFile = new File(MybatisGeneratorMain.class.getResource("/mybatis-api-generator-config.xml").getFile());
 //        File configFile = new File(MybatisGeneratorMain.class.getResource("/mybatis-api-contentPlatform-generator-config.xml").getFile());
-//        File configFile = new File(MybatisGeneratorMain.class.getResource("/mybatis-api-wecomThirdpart-generator-config.xml").getFile());
+        File configFile = new File(MybatisGeneratorMain.class.getResource("/mybatis-api-wecomThirdpart-generator-config.xml").getFile());
         ConfigurationParser cp = new ConfigurationParser(warnings);
         Configuration config = cp.parseConfiguration(configFile);
         DefaultShellCallback callback = new DefaultShellCallback(true);

+ 123 - 37
api-module/src/main/java/com/tzld/piaoquan/api/job/wecom/thirdpart/WeComCreateRoomJob.java

@@ -1,14 +1,13 @@
 package com.tzld.piaoquan.api.job.wecom.thirdpart;
 
-import com.google.common.collect.Lists;
 import com.google.common.util.concurrent.ThreadFactoryBuilder;
 import com.tzld.piaoquan.api.component.WeComThirdPartyApiClient;
+import com.tzld.piaoquan.api.controller.GetRoomUserListResponse;
 import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ThirdPartWeComRoomMapper;
 import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ext.ThirdPartWeComMapperExt;
-import com.tzld.piaoquan.api.model.param.wecom.thirdpart.CreateRoomWxRequest;
-import com.tzld.piaoquan.api.model.param.wecom.thirdpart.CreateRoomWxResponse;
-import com.tzld.piaoquan.api.model.param.wecom.thirdpart.InvitationToRoomRequest;
+import com.tzld.piaoquan.api.model.param.wecom.thirdpart.*;
 import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComRoom;
+import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComRoomUser;
 import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComStaff;
 import com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComStaffUser;
 import com.tzld.piaoquan.api.service.WeComThirdPartyService;
@@ -20,10 +19,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
+import java.util.*;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ThreadPoolExecutor;
@@ -75,72 +71,162 @@ public class WeComCreateRoomJob {
             return;
         }
         // 已创建群添加群成员
-        List<ThirdPartWeComRoom> roomList = weComThirdPartyService.getStaffRoomList(staff.getThirdStaffId());
+        List<ThirdPartWeComRoom> roomList = weComThirdPartyService.getStaffRoomList(staff.getId());
+        List<Integer> roomNums = roomList.stream()
+                .map(o -> {
+                    try {
+                        String roomName = o.getName();
+                        if (!roomName.contains("票圈快讯")) {
+                            return null;
+                        }
+                        return Integer.parseInt(roomName.replace("票圈快讯", ""));
+                    } catch (Exception e) {
+                        return null;
+                    }
+                })
+                .filter(Objects::nonNull)
+                .sorted(Comparator.comparing(Integer::intValue).reversed())
+                .collect(Collectors.toList());
+        Integer maxRoomNum = CollectionUtils.isNotEmpty(roomNums) ? roomNums.get(0) : 0;
         for (ThirdPartWeComRoom room : roomList) {
-            addRoomUser(staff, room, staffUserList);
+            if (room.getAddUserStatus() != 1) {
+                continue;
+            }
+            List<Long> vids = new ArrayList<>();
+            List<ThirdPartWeComStaffUser> addUserList = new ArrayList<>();
+            Iterator<ThirdPartWeComStaffUser> iterator = staffUserList.iterator();
+            int size = memberMaxNums - room.getMemberCount();
+            while (iterator.hasNext() && size > 0) {
+                ThirdPartWeComStaffUser item = iterator.next();
+                vids.add(item.getUserId());
+                size--;
+                iterator.remove();
+                addUserList.add(item);
+            }
+            addRoomUser(staff, room, vids);
+            // 群成员添加存储
+            saveRoomUser(room, addUserList);
         }
         // 未加群客户创建新群
         if (CollectionUtils.isNotEmpty(staffUserList)) {
-            createNewRoom(staff, staffUserList, roomList.size());
+            createNewRoom(staff, staffUserList, maxRoomNum);
         }
+        userDetailJob.syncRoomList(staff.getThirdUuid(), staff);
     }
 
     private void addRoomUser(ThirdPartWeComStaff staff,
                              ThirdPartWeComRoom room,
-                             List<ThirdPartWeComStaffUser> staffUserList) {
+                             List<Long> vids) {
         if (room.getAddUserStatus() != 1 || room.getMemberCount() >= memberMaxNums) {
             return;
         }
-        List<Long> vids = new ArrayList<>();
-        Iterator<ThirdPartWeComStaffUser> iterator = staffUserList.iterator();
-        int size = memberMaxNums - room.getMemberCount();
-        while (iterator.hasNext() && size > 0) {
-            vids.add(iterator.next().getUserId());
-            size--;
-            iterator.remove();
-        }
         InvitationToRoomRequest request = new InvitationToRoomRequest();
         request.setUuid(staff.getThirdUuid());
         request.setRoomid(Long.parseLong(room.getThirdRoomId()));
         request.setVids(vids);
         apiClient.invitationToRoom(request);
-        // 达到最大成员数,关闭添加开关
-        if (size == 0) {
-            room.setAddUserStatus(0);
-            roomMapper.updateByPrimaryKeySelective(room);
-        }
-        // 达到发送消息最低成员数,开启发送消息开关
-        if (room.getMemberCount() + vids.size() >= sendMsgStatusNums) {
-            room.setSendStatus(1);
-            roomMapper.updateByPrimaryKeySelective(room);
-        }
     }
 
     private void createNewRoom(ThirdPartWeComStaff staff,
                                List<ThirdPartWeComStaffUser> staffUserList,
                                Integer roomNum) {
-        for (List<ThirdPartWeComStaffUser> partition : Lists.partition(staffUserList, memberMaxNums)) {
-            List<Long> vids = partition.stream().map(ThirdPartWeComStaffUser::getUserId).collect(Collectors.toList());
+        Iterator<ThirdPartWeComStaffUser> iterator = staffUserList.iterator();
+        while (iterator.hasNext()) {
+            List<Long> vids = new ArrayList<>();
+            List<ThirdPartWeComStaffUser> addUserList = new ArrayList<>();
+            int size = staffUserList.size() > memberMaxNums ? memberMaxNums : staffUserList.size();
+            while (iterator.hasNext() && size > 0) {
+                ThirdPartWeComStaffUser item = iterator.next();
+                vids.add(item.getUserId());
+                size--;
+                iterator.remove();
+                addUserList.add(item);
+            }
+            // 群创建
             CreateRoomWxRequest request = new CreateRoomWxRequest();
             request.setUuid(staff.getThirdUuid());
             request.setRoomName("票圈快讯" + (++roomNum));
             request.setVids(vids);
             CreateRoomWxResponse createRoomWxResponse = weComThirdPartyService.createRoom(request);
-
+            // 群管理设置 防骚扰
+            updateRoomManagement(staff, createRoomWxResponse);
+            // add room save
             ThirdPartWeComRoom roomDetail = new ThirdPartWeComRoom();
             roomDetail.setCorpId(staff.getCorpId());
             roomDetail.setStaffId(staff.getId());
             roomDetail.setThirdRoomId(createRoomWxResponse.getRoomid());
             roomDetail.setThirdCreateUserId(createRoomWxResponse.getCreateid());
-            roomDetail.setMemberCount(vids.size());
             roomDetail.setName(createRoomWxResponse.getRoomname());
-            roomDetail.setAddUserStatus(vids.size() == memberMaxNums ? 0 : 1);
-            roomDetail.setSendStatus(vids.size() > sendMsgStatusNums ? 1 : 0);
             roomDetail.setCreateTime(new Date());
             roomDetail.setUpdateTime(new Date());
             roomMapper.insertSelective(roomDetail);
+            // 群成员添加存储
+            saveRoomUser(roomDetail, addUserList);
+            // 循环添加群成员
+            while (true) {
+                GetRoomUserListRequest roomUserListRequest = new GetRoomUserListRequest(staff.getThirdUuid(),
+                        Long.valueOf(createRoomWxResponse.getRoomid()));
+                List<GetRoomUserListResponse.Member> userList = weComThirdPartyService.getRoomUserList(roomUserListRequest);
+                roomDetail.setMemberCount(userList.size());
+                roomDetail.setAddUserStatus(userList.size() == memberMaxNums ? 0 : 1);
+                roomDetail.setSendStatus(userList.size() > sendMsgStatusNums ? 1 : 0);
+                roomMapper.updateByPrimaryKeySelective(roomDetail);
+                if (!iterator.hasNext() || userList.size() == memberMaxNums) {
+                    break;
+                }
+                vids = new ArrayList<>();
+                size = Math.min(staffUserList.size(), memberMaxNums - userList.size());
+                while (iterator.hasNext() && size > 0) {
+                    ThirdPartWeComStaffUser item = iterator.next();
+                    vids.add(item.getUserId());
+                    size--;
+                    iterator.remove();
+                }
+                addRoomUser(staff, roomDetail, vids);
+                // 群成员添加存储
+                saveRoomUser(roomDetail, addUserList);
+            }
+        }
+    }
 
-            userDetailJob.syncRoomUserList(staff.getThirdUuid(), createRoomWxResponse.getRoomid());
+    private void updateRoomManagement(ThirdPartWeComStaff staff, CreateRoomWxResponse createRoomWxResponse) {
+        SetRoomManagementRequest setRoomManagementRequest = new SetRoomManagementRequest();
+        setRoomManagementRequest.setUuid(staff.getThirdUuid());
+        setRoomManagementRequest.setRoomid(Long.parseLong(createRoomWxResponse.getRoomid()));
+        setRoomManagementRequest.setNewFlag(69206023);
+        apiClient.setRoomManagement(setRoomManagementRequest);
+        // 查询防骚扰规则 并配置所有规则
+        QueryCRMAntiSpamRuleRequest antiSpamRuleRequest = new QueryCRMAntiSpamRuleRequest();
+        antiSpamRuleRequest.setUuid(staff.getThirdUuid());
+        List<AntiSpamRuleResponse.AntiSpamRule> antiSpamRuleList = weComThirdPartyService.queryCRMAntiSpamRule(antiSpamRuleRequest);
+        if (CollectionUtils.isNotEmpty(antiSpamRuleList)) {
+            // 设置防骚扰规则
+            SetRoomAntiRequest setRoomAntiRequest = new SetRoomAntiRequest();
+            setRoomAntiRequest.setUuid(staff.getThirdUuid());
+            setRoomAntiRequest.setRoomid(Long.parseLong(createRoomWxResponse.getRoomid()));
+            setRoomAntiRequest.setAntiIds(antiSpamRuleList.stream().map(AntiSpamRuleResponse.AntiSpamRule::getId).collect(Collectors.toList()));
+            apiClient.setRoomAnti(setRoomAntiRequest);
+        }
+        // todo 设置管理员
+        //apiClient.addRoomAdmins();
+    }
+
+    private void saveRoomUser(ThirdPartWeComRoom roomDetail,
+                              List<ThirdPartWeComStaffUser> addUserList) {
+        if (CollectionUtils.isEmpty(addUserList)) {
+            return;
+        }
+        List<ThirdPartWeComRoomUser> saveList = new ArrayList<>();
+        for (ThirdPartWeComStaffUser staffUser : addUserList) {
+            ThirdPartWeComRoomUser roomUser = new ThirdPartWeComRoomUser();
+            roomUser.setThirdRoomId(roomDetail.getThirdRoomId());
+            roomUser.setCreateTime(new Date());
+            roomUser.setUpdateTime(new Date());
+            roomUser.setUin(staffUser.getUserId());
+            saveList.add(roomUser);
+        }
+        if (CollectionUtils.isNotEmpty(saveList)) {
+            thirdPartWeComMapperExt.batchInsertThirdPartWeComRoomUser(saveList);
         }
     }
 

+ 2 - 10
api-module/src/main/java/com/tzld/piaoquan/api/job/wecom/thirdpart/WeComSendMsgJob.java

@@ -1,7 +1,6 @@
 package com.tzld.piaoquan.api.job.wecom.thirdpart;
 
 import com.alibaba.fastjson.JSONObject;
-import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
 import com.google.common.util.concurrent.ThreadFactoryBuilder;
 import com.tzld.piaoquan.api.dao.mapper.contentplatform.ext.ContentPlatformPlanMapperExt;
 import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ThirdPartWeComMsgMapper;
@@ -47,9 +46,6 @@ public class WeComSendMsgJob {
     @Autowired
     ThirdPartWeComMsgMapper thirdPartWeComMsgMapper;
 
-    @ApolloJsonValue("${wecom.thirdpart.send.msg.config:{}}")
-    private JSONObject sendMsgConfig;
-
     @Value("${send.room.msg.video.min.score:3}")
     private Double videoMinScore;
     @Value("${send.room.msg.duplicate.days:7}")
@@ -67,17 +63,13 @@ public class WeComSendMsgJob {
         List<ThirdPartWeComStaff> activeStaffList = weComThirdPartyService.getActiveStaffList();
         String time = DateUtil.getCurrentDateStr("HH:mm");
         for (ThirdPartWeComStaff staff : activeStaffList) {
-            if (!sendMsgConfig.containsKey(staff.getName())) {
-                continue;
-            }
             List<ThirdPartWeComRoom> roomList = weComThirdPartyService.getStaffRoomList(staff.getId());
-            JSONObject roomConfig = sendMsgConfig.getJSONObject(staff.getName());
             for (ThirdPartWeComRoom room : roomList) {
-                if (!roomConfig.containsKey(room.getName())) {
+                if (room.getSendStatus() != 1) {
                     continue;
                 }
                 pool.execute(() -> {
-                    List<String> timeList = roomConfig.getJSONArray(room.getName()).toJavaList(String.class);
+                    List<String> timeList = JSONObject.parseArray(room.getSendTime()).toJavaList(String.class);
                     if (timeList.contains(time)) {
                         // 选取视频
                         List<CgiReplyBucketData> cgiReplyBucketDataList = getCgiReplyBucketData(room.getThirdRoomId(), staff);

+ 34 - 0
api-module/src/main/java/com/tzld/piaoquan/api/job/wecom/thirdpart/WeComUserDetailJob.java

@@ -19,6 +19,7 @@ import com.xxl.job.core.handler.annotation.XxlJob;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 
 import java.util.*;
@@ -50,6 +51,12 @@ public class WeComUserDetailJob {
     @Autowired
     private RedisUtils redisUtils;
 
+    @Value("${create.room.send.msg.status.nums:20}")
+    private Integer sendMsgStatusNums;
+
+    @Value("${create.room.member.max.nums:40}")
+    private Integer memberMaxNums;
+
     private final static ExecutorService pool = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.SECONDS,
             new LinkedBlockingQueue<>(1000),
             new ThreadFactoryBuilder().setNameFormat("SyncUserDetailJob-%d").build(),
@@ -161,6 +168,16 @@ public class WeComUserDetailJob {
         return staffUserMapper.selectByExample(example);
     }
 
+
+    @XxlJob("syncRoomDetail")
+    public ReturnT<String> syncRoomDetail(String param) {
+        List<ThirdPartWeComStaff> activeStaffList = thirdPartyService.getActiveStaffList();
+        for (ThirdPartWeComStaff staff : activeStaffList) {
+            pool.execute(() -> syncRoomList(staff.getThirdUuid(), staff));
+        }
+        return ReturnT.SUCCESS;
+    }
+
     public void syncRoomList(String uuid, ThirdPartWeComStaff staff) {
         List<GetChatroomMembersResponse.RoomInfo> roomInfoList =
                 thirdPartyService.getChatroomMembers(new GetChatroomMembersRequest(uuid, 100, 0));
@@ -191,10 +208,27 @@ public class WeComUserDetailJob {
                 roomDetail.setMemberCount(roomInfo.getTotal());
                 roomDetail.setName(roomInfo.getNickname());
                 roomDetail.setUpdateTime(new Date());
+                if (staff.getAutoCreateRoom() == 1) {
+                    if (roomDetail.getMemberCount() >= memberMaxNums){
+                        roomDetail.setAddUserStatus(0);
+                    }
+                    if (roomDetail.getMemberCount() >= sendMsgStatusNums) {
+                        roomDetail.setSendStatus(1);
+                    }
+                }
                 roomMapper.updateByPrimaryKeySelective(roomDetail);
             }
             syncRoomUserList(uuid, roomDetail.getThirdRoomId());
         }
+        List<String> roomIds = roomInfoList.stream().map(GetChatroomMembersResponse.RoomInfo::getRoom_id).collect(Collectors.toList());
+        roomList.removeIf(room -> roomIds.contains(room.getThirdRoomId()));
+        if (CollectionUtils.isNotEmpty(roomList)) {
+            roomList.forEach(room -> {
+                room.setIsDelete(1);
+                room.setUpdateTime(new Date());
+                roomMapper.updateByPrimaryKeySelective(room);
+            });
+        }
     }
 
     public void syncRoomUserList(String uuid, String thirdRoomId) {

+ 23 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/AntiSpamRuleResponse.java

@@ -0,0 +1,23 @@
+package com.tzld.piaoquan.api.model.param.wecom.thirdpart;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class AntiSpamRuleResponse {
+    private String last_index_infoo;
+    private Long last_time;
+    private Boolean is_end;
+    private List<AntiSpamRule> list;
+
+    @Data
+    public static class AntiSpamRule {
+        private Long creator;
+        private Long update_ts;
+        private Long create_ts;
+        private String name;
+        private Long id;
+        private Integer type;
+    }
+}

+ 10 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/DisableRenameChatroomRequest.java

@@ -0,0 +1,10 @@
+package com.tzld.piaoquan.api.model.param.wecom.thirdpart;
+
+import lombok.Data;
+
+@Data
+public class DisableRenameChatroomRequest {
+    private String uuid;
+    private Long roomid;
+    private boolean status;
+}

+ 9 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/QueryCRMAntiSpamRuleRequest.java

@@ -0,0 +1,9 @@
+package com.tzld.piaoquan.api.model.param.wecom.thirdpart;
+
+import lombok.Data;
+
+@Data
+public class QueryCRMAntiSpamRuleRequest {
+    private String uuid;
+    private String lastIndexInfo;
+}

+ 11 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/SetRoomAntiRequest.java

@@ -0,0 +1,11 @@
+package com.tzld.piaoquan.api.model.param.wecom.thirdpart;
+
+import lombok.Data;
+import java.util.List;
+
+@Data
+public class SetRoomAntiRequest {
+    private String uuid;
+    private Long roomid;
+    private List<Long> antiIds;
+}

+ 14 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/param/wecom/thirdpart/UpdateRoomSendStatusRequest.java

@@ -0,0 +1,14 @@
+package com.tzld.piaoquan.api.model.param.wecom.thirdpart;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class UpdateRoomSendStatusRequest {
+    private String staffName;
+    private String roomName;
+    // 发送状态 0-关闭 1-开启
+    private Integer sendStatus;
+    private List<String> sendTimeList;
+}

+ 11 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/po/wecom/thirdpart/ThirdPartWeComRoom.java

@@ -25,6 +25,8 @@ public class ThirdPartWeComRoom {
 
     private String sendTime;
 
+    private Integer isDelete;
+
     private Date createTime;
 
     private Date updateTime;
@@ -117,6 +119,14 @@ public class ThirdPartWeComRoom {
         this.sendTime = sendTime;
     }
 
+    public Integer getIsDelete() {
+        return isDelete;
+    }
+
+    public void setIsDelete(Integer isDelete) {
+        this.isDelete = isDelete;
+    }
+
     public Date getCreateTime() {
         return createTime;
     }
@@ -150,6 +160,7 @@ public class ThirdPartWeComRoom {
         sb.append(", addUserStatus=").append(addUserStatus);
         sb.append(", sendStatus=").append(sendStatus);
         sb.append(", sendTime=").append(sendTime);
+        sb.append(", isDelete=").append(isDelete);
         sb.append(", createTime=").append(createTime);
         sb.append(", updateTime=").append(updateTime);
         sb.append("]");

+ 60 - 0
api-module/src/main/java/com/tzld/piaoquan/api/model/po/wecom/thirdpart/ThirdPartWeComRoomExample.java

@@ -816,6 +816,66 @@ public class ThirdPartWeComRoomExample {
             return (Criteria) this;
         }
 
+        public Criteria andIsDeleteIsNull() {
+            addCriterion("is_delete is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andIsDeleteIsNotNull() {
+            addCriterion("is_delete is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andIsDeleteEqualTo(Integer value) {
+            addCriterion("is_delete =", value, "isDelete");
+            return (Criteria) this;
+        }
+
+        public Criteria andIsDeleteNotEqualTo(Integer value) {
+            addCriterion("is_delete <>", value, "isDelete");
+            return (Criteria) this;
+        }
+
+        public Criteria andIsDeleteGreaterThan(Integer value) {
+            addCriterion("is_delete >", value, "isDelete");
+            return (Criteria) this;
+        }
+
+        public Criteria andIsDeleteGreaterThanOrEqualTo(Integer value) {
+            addCriterion("is_delete >=", value, "isDelete");
+            return (Criteria) this;
+        }
+
+        public Criteria andIsDeleteLessThan(Integer value) {
+            addCriterion("is_delete <", value, "isDelete");
+            return (Criteria) this;
+        }
+
+        public Criteria andIsDeleteLessThanOrEqualTo(Integer value) {
+            addCriterion("is_delete <=", value, "isDelete");
+            return (Criteria) this;
+        }
+
+        public Criteria andIsDeleteIn(List<Integer> values) {
+            addCriterion("is_delete in", values, "isDelete");
+            return (Criteria) this;
+        }
+
+        public Criteria andIsDeleteNotIn(List<Integer> values) {
+            addCriterion("is_delete not in", values, "isDelete");
+            return (Criteria) this;
+        }
+
+        public Criteria andIsDeleteBetween(Integer value1, Integer value2) {
+            addCriterion("is_delete between", value1, value2, "isDelete");
+            return (Criteria) this;
+        }
+
+        public Criteria andIsDeleteNotBetween(Integer value1, Integer value2) {
+            addCriterion("is_delete not between", value1, value2, "isDelete");
+            return (Criteria) this;
+        }
+
         public Criteria andCreateTimeIsNull() {
             addCriterion("create_time is null");
             return (Criteria) this;

+ 4 - 0
api-module/src/main/java/com/tzld/piaoquan/api/service/WeComThirdPartyService.java

@@ -38,4 +38,8 @@ public interface WeComThirdPartyService {
     List<ThirdPartWeComRoom> getStaffRoomList(Long staffId);
 
     CreateRoomWxResponse createRoom(CreateRoomWxRequest request);
+
+    List<AntiSpamRuleResponse.AntiSpamRule> queryCRMAntiSpamRule(QueryCRMAntiSpamRuleRequest request);
+
+    void updateRoomSendStatus(UpdateRoomSendStatusRequest request);
 }

+ 58 - 1
api-module/src/main/java/com/tzld/piaoquan/api/service/impl/WeComThirdPartyServiceImpl.java

@@ -2,6 +2,8 @@ package com.tzld.piaoquan.api.service.impl;
 
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.TypeReference;
+import com.tzld.piaoquan.api.common.enums.ExceptionEnum;
+import com.tzld.piaoquan.api.common.exception.CommonException;
 import com.tzld.piaoquan.api.component.WeComThirdPartyApiClient;
 import com.tzld.piaoquan.api.controller.GetRoomUserListResponse;
 import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ThirdPartWeComCorpMapper;
@@ -14,6 +16,7 @@ import com.tzld.piaoquan.growth.common.dao.mapper.CorpMapper;
 import com.tzld.piaoquan.growth.common.model.po.Corp;
 import com.tzld.piaoquan.growth.common.model.po.CorpExample;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -296,7 +299,7 @@ public class WeComThirdPartyServiceImpl implements WeComThirdPartyService {
     @Override
     public List<ThirdPartWeComRoom> getStaffRoomList(Long staffId) {
         ThirdPartWeComRoomExample example = new ThirdPartWeComRoomExample();
-        example.createCriteria().andStaffIdEqualTo(staffId);
+        example.createCriteria().andStaffIdEqualTo(staffId).andIsDeleteEqualTo(0);
         return thirdPartWeComRoomMapper.selectByExample(example);
     }
 
@@ -312,4 +315,58 @@ public class WeComThirdPartyServiceImpl implements WeComThirdPartyService {
         return commonResponse.getData();
     }
 
+    @Override
+    public List<AntiSpamRuleResponse.AntiSpamRule> queryCRMAntiSpamRule(QueryCRMAntiSpamRuleRequest request) {
+        List<AntiSpamRuleResponse.AntiSpamRule> result = new ArrayList<>();
+        String lastIndexInfo = "";
+        do {
+            request.setLastIndexInfo(lastIndexInfo);
+            String response = apiClient.queryCRMAntiSpamRule(request);
+            CommonResponse<AntiSpamRuleResponse> commonResponse =
+                    JSONObject.parseObject(response, new TypeReference<CommonResponse<AntiSpamRuleResponse>>() {
+                    });
+            if (commonResponse.getErrcode() != 0) {
+                log.error("query crm AntiSpamRule failed, response: {}", response);
+                return result;
+            }
+            result.addAll(commonResponse.getData().getList());
+            if (commonResponse.getData().getIs_end()) {
+                break;
+            }
+            lastIndexInfo = commonResponse.getData().getLast_index_infoo();
+        } while (true);
+        return result;
+    }
+
+    @Override
+    public void updateRoomSendStatus(UpdateRoomSendStatusRequest request) {
+        ThirdPartWeComStaff staff = getStaffByName(request.getStaffName());
+        if (Objects.isNull(staff)) {
+            throw new CommonException(ExceptionEnum.THIRD_PART_STAFF_NOT_FOUND);
+        }
+        ThirdPartWeComRoomExample example = new ThirdPartWeComRoomExample();
+        example.createCriteria().andStaffIdEqualTo(staff.getId()).andNameEqualTo(request.getRoomName());
+        List<ThirdPartWeComRoom> roomList = thirdPartWeComRoomMapper.selectByExample(example);
+        if (CollectionUtils.isEmpty(roomList)) {
+            throw new CommonException(ExceptionEnum.THIRD_PART_ROOM_NOT_FOUND);
+        }
+        for (ThirdPartWeComRoom room : roomList) {
+            room.setSendStatus(request.getSendStatus());
+            if (CollectionUtils.isNotEmpty(request.getSendTimeList())) {
+                room.setSendTime(JSONObject.toJSONString(request.getSendTimeList()));
+            }
+            thirdPartWeComRoomMapper.updateByPrimaryKeySelective(room);
+        }
+    }
+
+    private ThirdPartWeComStaff getStaffByName(String staffName) {
+        ThirdPartWeComStaffExample example = new ThirdPartWeComStaffExample();
+        example.createCriteria().andNameEqualTo(staffName);
+        List<ThirdPartWeComStaff> staffList = thirdPartWeComStaffMapper.selectByExample(example);
+        if (CollectionUtils.isEmpty(staffList)) {
+            return null;
+        }
+        return staffList.get(0);
+    }
+
 }

+ 20 - 5
api-module/src/main/resources/mapper/wecom/thirdpart/ThirdPartWeComRoomMapper.xml

@@ -13,6 +13,7 @@
     <result column="add_user_status" jdbcType="INTEGER" property="addUserStatus" />
     <result column="send_status" jdbcType="INTEGER" property="sendStatus" />
     <result column="send_time" jdbcType="VARCHAR" property="sendTime" />
+    <result column="is_delete" jdbcType="INTEGER" property="isDelete" />
     <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
     <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
   </resultMap>
@@ -76,7 +77,7 @@
   </sql>
   <sql id="Base_Column_List">
     id, corp_id, staff_id, third_room_id, third_create_user_id, member_count, `name`, 
-    room_url, add_user_status, send_status, send_time, create_time, update_time
+    room_url, add_user_status, send_status, send_time, is_delete, create_time, update_time
   </sql>
   <select id="selectByExample" parameterType="com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComRoomExample" resultMap="BaseResultMap">
     select
@@ -115,13 +116,13 @@
     insert into third_part_we_com_room (id, corp_id, staff_id, 
       third_room_id, third_create_user_id, member_count, 
       `name`, room_url, add_user_status, 
-      send_status, send_time, create_time, 
-      update_time)
+      send_status, send_time, is_delete, 
+      create_time, update_time)
     values (#{id,jdbcType=BIGINT}, #{corpId,jdbcType=BIGINT}, #{staffId,jdbcType=BIGINT}, 
       #{thirdRoomId,jdbcType=VARCHAR}, #{thirdCreateUserId,jdbcType=BIGINT}, #{memberCount,jdbcType=INTEGER}, 
       #{name,jdbcType=VARCHAR}, #{roomUrl,jdbcType=VARCHAR}, #{addUserStatus,jdbcType=INTEGER}, 
-      #{sendStatus,jdbcType=INTEGER}, #{sendTime,jdbcType=VARCHAR}, #{createTime,jdbcType=TIMESTAMP}, 
-      #{updateTime,jdbcType=TIMESTAMP})
+      #{sendStatus,jdbcType=INTEGER}, #{sendTime,jdbcType=VARCHAR}, #{isDelete,jdbcType=INTEGER}, 
+      #{createTime,jdbcType=TIMESTAMP}, #{updateTime,jdbcType=TIMESTAMP})
   </insert>
   <insert id="insertSelective" parameterType="com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComRoom">
     insert into third_part_we_com_room
@@ -159,6 +160,9 @@
       <if test="sendTime != null">
         send_time,
       </if>
+      <if test="isDelete != null">
+        is_delete,
+      </if>
       <if test="createTime != null">
         create_time,
       </if>
@@ -200,6 +204,9 @@
       <if test="sendTime != null">
         #{sendTime,jdbcType=VARCHAR},
       </if>
+      <if test="isDelete != null">
+        #{isDelete,jdbcType=INTEGER},
+      </if>
       <if test="createTime != null">
         #{createTime,jdbcType=TIMESTAMP},
       </if>
@@ -250,6 +257,9 @@
       <if test="record.sendTime != null">
         send_time = #{record.sendTime,jdbcType=VARCHAR},
       </if>
+      <if test="record.isDelete != null">
+        is_delete = #{record.isDelete,jdbcType=INTEGER},
+      </if>
       <if test="record.createTime != null">
         create_time = #{record.createTime,jdbcType=TIMESTAMP},
       </if>
@@ -274,6 +284,7 @@
       add_user_status = #{record.addUserStatus,jdbcType=INTEGER},
       send_status = #{record.sendStatus,jdbcType=INTEGER},
       send_time = #{record.sendTime,jdbcType=VARCHAR},
+      is_delete = #{record.isDelete,jdbcType=INTEGER},
       create_time = #{record.createTime,jdbcType=TIMESTAMP},
       update_time = #{record.updateTime,jdbcType=TIMESTAMP}
     <if test="_parameter != null">
@@ -313,6 +324,9 @@
       <if test="sendTime != null">
         send_time = #{sendTime,jdbcType=VARCHAR},
       </if>
+      <if test="isDelete != null">
+        is_delete = #{isDelete,jdbcType=INTEGER},
+      </if>
       <if test="createTime != null">
         create_time = #{createTime,jdbcType=TIMESTAMP},
       </if>
@@ -334,6 +348,7 @@
       add_user_status = #{addUserStatus,jdbcType=INTEGER},
       send_status = #{sendStatus,jdbcType=INTEGER},
       send_time = #{sendTime,jdbcType=VARCHAR},
+      is_delete = #{isDelete,jdbcType=INTEGER},
       create_time = #{createTime,jdbcType=TIMESTAMP},
       update_time = #{updateTime,jdbcType=TIMESTAMP}
     where id = #{id,jdbcType=BIGINT}

+ 22 - 18
api-module/src/main/resources/mapper/wecom/thirdpart/ext/ThirdPartWeComMapperExt.xml

@@ -3,7 +3,7 @@
 <mapper namespace="com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ext.ThirdPartWeComMapperExt">
 
   <insert id="batchInsertThirdPartWeComRoomUser">
-    insert into third_part_we_com_room_user (id, third_room_id, unionid, ex, mobile, acctid, join_scene, avatar, 
+    insert into third_part_we_com_room_user (id, third_room_id, unionid, sex, mobile, acctid, join_scene, avatar, 
        english_name, realname, room_notes, join_time, nickname, room_nickname, `position`, uin, invite_user_id, corp_id,
        create_time, update_time)
     values
@@ -16,27 +16,31 @@
   </insert>
 
   <insert id="batchInsertThirdPartWeComStaffUser">
-    insert into third_part_we_com_staff_user (id, third_room_id, unionid, ex, mobile, acctid, join_scene, avatar,
-       english_name, realname, room_notes, join_time, nickname, room_nickname, `position`, uin, invite_user_id, corp_id,
-       create_time, update_time)
+    insert into third_part_we_com_staff_user (id, third_staff_id, unionid, sex, mobile, company_remark,
+      acctid, avatar, `source`, english_name, remark_phone, realname, real_remarks, labelid, user_id,
+      nickname, `position`, corp_id, remarks, seq, `status`, create_time, update_time)
     values
     <foreach collection="records" item="item" separator=",">
-      (#{item.id}, #{item.thirdRoomId}, #{item.unionid}, #{item.sex}, #{item.mobile}, #{item.acctid}, #{item.joinScene},
-       #{item.avatar}, #{item.englishName}, #{item.realname}, #{item.roomNotes}, #{item.joinTime}, #{item.nickname},
-       #{item.roomNickname}, #{item.position}, #{item.uin}, #{item.inviteUserId}, #{item.corpId}, #{item.createTime},
-       #{item.updateTime})
+        (#{item.id}, #{item.thirdStaffId}, #{item.unionid}, #{item.sex}, #{item.mobile}, #{item.companyRemark},
+        #{item.acctid}, #{item.avatar}, #{item.source}, #{item.englishName}, #{item.remarkPhone}, #{item.realname},
+        #{item.realRemarks}, #{item.labelid}, #{item.userId}, #{item.nickname}, #{item.position}, #{item.corpId},
+        #{item.remarks}, #{item.seq}, #{item.status}, #{item.createTime}, #{item.updateTime})
     </foreach>
   </insert>
 
-  <select id="getNoGroupStaffUserList"
-          resultType="com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComStaffUser">
-      select staff_user.*
-      from third_part_we_com_staff staff
-       join third_part_we_com_staff_user staff_user on staff.third_staff_id = staff_user.third_staff_id
-       join third_part_we_com_room room on staff.id = room.staff_id
-       left join third_part_we_com_room_user room_user on room.third_room_id = room_user.third_room_id
-      where staff.third_staff_id = #{thirdStaffId}
-        and room_user.third_room_id is null
-  </select>
+    <select id="getNoGroupStaffUserList"
+            resultType="com.tzld.piaoquan.api.model.po.wecom.thirdpart.ThirdPartWeComStaffUser">
+        select staff_user.*
+        from third_part_we_com_staff staff
+         join third_part_we_com_staff_user staff_user on staff.third_staff_id = staff_user.third_staff_id
+        left join (select distinct room_user.uin
+                   from third_part_we_com_staff staff
+                    join third_part_we_com_room room on staff.id = room.staff_id
+                    join third_part_we_com_room_user room_user
+                         on room.third_room_id = room_user.third_room_id
+                   where staff.third_staff_id = #{thirdStaffId}) room_user on staff_user.user_id = room_user.uin
+        where staff.third_staff_id = #{thirdStaffId}
+          and room_user.uin is null
+    </select>
 
 </mapper>

+ 13 - 1
api-module/src/test/java/com/tzld/piaoquan/api/WeComThirdPartTest.java

@@ -1,6 +1,7 @@
 package com.tzld.piaoquan.api;
 
 import com.tzld.piaoquan.api.job.wecom.thirdpart.WeComAccountJob;
+import com.tzld.piaoquan.api.job.wecom.thirdpart.WeComCreateRoomJob;
 import com.tzld.piaoquan.api.job.wecom.thirdpart.WeComSendMsgJob;
 import com.tzld.piaoquan.api.job.wecom.thirdpart.WeComUserDetailJob;
 import lombok.extern.slf4j.Slf4j;
@@ -18,7 +19,8 @@ public class WeComThirdPartTest {
     WeComAccountJob weComAccountJob;
     @Autowired
     WeComUserDetailJob weComUserDetailJob;
-
+    @Autowired
+    WeComCreateRoomJob weComCreateRoomJob;
 
     @Test
     public void checkAccountOnline() {
@@ -30,9 +32,19 @@ public class WeComThirdPartTest {
         weComUserDetailJob.syncUserDetail("");
     }
 
+    @Test
+    public void syncRoomDetail() {
+        weComUserDetailJob.syncRoomDetail("");
+    }
+
     @Test
     public void autoSendAppMsg() {
         weComSendMsgJob.autoSendAppMsg("");
     }
 
+    @Test
+    public void autoCreateRoomJob() {
+        weComCreateRoomJob.autoCreateRoomJob("");
+    }
+
 }