فهرست منبع

fix 群成员人数限制

Eric 1 سال پیش
والد
کامیت
06669979ab

+ 1 - 1
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/ImGroupController.java

@@ -65,7 +65,7 @@ public class ImGroupController extends BaseController {
     @PostMapping(value = "/getDetail/{groupId}")
     @PreAuthorize("@pcs.hasPermissions('imGroup/detail')")
     public HttpResponseResult<ImGroup> getDetail(@ApiParam(value = "群编号", required = true) @PathVariable("groupId") String groupId) throws Exception {
-        ImGroup group = imGroupService.getById(groupId);
+        ImGroup group = imGroupService.getGroupById(groupId);
         if (group == null) {
             return failed(HttpStatus.NO_CONTENT, "群组不存在");
         }

+ 1 - 1
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/ImGroupController.java

@@ -145,7 +145,7 @@ public class ImGroupController extends BaseController {
     @ApiOperation("获取群详情")
     @PostMapping(value = "/getDetail/{groupId}")
     public HttpResponseResult<ImGroup> getDetail(@ApiParam(value = "群编号", required = true) @PathVariable("groupId") String groupId) throws Exception {
-        ImGroup group = imGroupService.getById(groupId);
+        ImGroup group = imGroupService.getGroupById(groupId);
         if (group == null) {
             return failed(HttpStatus.NO_CONTENT, "群组不存在");
         }

+ 5 - 0
cooleshow-common/src/main/java/com/yonge/cooleshow/common/constant/SysConfigConstant.java

@@ -429,4 +429,9 @@ public interface SysConfigConstant {
      * 草稿保存时长
      */
     String USER_MUSIC_DRAFT_TIME = "user_music_draft_time";
+
+    /**
+     * 群成员人数限制
+     */
+    String GROUP_MEMBER_LIMIT = "group_member_limit";
 }

+ 12 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/ImGroup.java

@@ -75,6 +75,10 @@ public class ImGroup implements Serializable {
     @ApiModelProperty(value = "群聊配置")
     private String configJson;
 
+    @TableField(exist = false) // 不映射数据库字段,返回群成员人数限制
+    @ApiModelProperty("群成员人数限制")
+    private Integer groupMemberLimit;
+
     public Long getCourseGroupId() {
         return courseGroupId;
     }
@@ -178,5 +182,13 @@ public class ImGroup implements Serializable {
     public void setConfigJson(String configJson) {
         this.configJson = configJson;
     }
+
+    public Integer getGroupMemberLimit() {
+        return groupMemberLimit;
+    }
+
+    public void setGroupMemberLimit(Integer groupMemberLimit) {
+        this.groupMemberLimit = groupMemberLimit;
+    }
 }
 

+ 7 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/ImGroupMemberService.java

@@ -92,5 +92,12 @@ public interface ImGroupMemberService extends IService<ImGroupMember> {
     List<ImGroupMember> findChatGroupAllMemberInfo(Map<String, Object> params);
 
     IPage<ImGroupMemberWrapper.ImGroupMember> selectPage(@Param("page") IPage<ImGroupMemberWrapper.ImGroupMember> page,@Param("query") ImGroupMemberWrapper.ImGroupMemberQuery query);
+
+    /**
+     * 获取群成员数量
+     * @param groupId 群ID
+     * @return int
+     */
+    int countGroupMember(String groupId);
 }
 

+ 7 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/ImGroupService.java

@@ -144,6 +144,13 @@ public interface ImGroupService extends IService<ImGroup> {
      */
     ImGroup findGroupInfoById(String groupId, Long userId);
 
+    /**
+     * 获取群信息
+     * @param groupId 群ID
+     * @return ImGroup
+     */
+    ImGroup getGroupById(String groupId);
+
     void getAndSaveImHistoryMessage(String date) throws Exception;
 
     /**

+ 102 - 45
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImGroupMemberAuditServiceImpl.java

@@ -6,6 +6,7 @@ import com.yonge.cooleshow.biz.dal.dao.ImGroupMemberAuditDao;
 import com.yonge.cooleshow.biz.dal.entity.ImGroup;
 import com.yonge.cooleshow.biz.dal.entity.ImGroupMember;
 import com.yonge.cooleshow.biz.dal.entity.ImGroupMemberAudit;
+import com.yonge.cooleshow.biz.dal.entity.SysConfig;
 import com.yonge.cooleshow.biz.dal.enums.AuditStatusEnum;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.ImGroupMemberRoleType;
@@ -14,19 +15,28 @@ import com.yonge.cooleshow.biz.dal.queryInfo.ImGroupMemberAuditQueryInfo;
 import com.yonge.cooleshow.biz.dal.service.ImGroupMemberAuditService;
 import com.yonge.cooleshow.biz.dal.service.ImGroupMemberService;
 import com.yonge.cooleshow.biz.dal.service.ImGroupService;
+import com.yonge.cooleshow.biz.dal.service.SysConfigService;
 import com.yonge.cooleshow.biz.dal.service.SysUserService;
 import com.yonge.cooleshow.biz.dal.vo.AuditUserInfo;
+import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.payment.util.DistributedLock;
 import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext;
-import io.rong.models.group.GroupMember;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import lombok.extern.slf4j.Slf4j;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
 
 import javax.annotation.Resource;
-import java.util.*;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
 import java.util.stream.Collectors;
 
 /**
@@ -35,11 +45,10 @@ import java.util.stream.Collectors;
  * @author zx
  * @since 2022-03-22 17:18:51
  */
+@Slf4j
 @Service("imGroupMemberAuditService")
 public class ImGroupMemberAuditServiceImpl extends ServiceImpl<ImGroupMemberAuditDao, ImGroupMemberAudit> implements ImGroupMemberAuditService {
 
-    private final static Logger log = LoggerFactory.getLogger(ImGroupMemberAuditServiceImpl.class);
-
     @Resource
     private ImGroupService imGroupService;
     @Resource
@@ -49,6 +58,12 @@ public class ImGroupMemberAuditServiceImpl extends ServiceImpl<ImGroupMemberAudi
     @Resource
     private SysMessageServiceImpl sysMessageService;
 
+    @Autowired
+    private RedissonClient redissonClient;
+
+    @Autowired
+    private SysConfigService sysConfigService;
+
     @Override
     public ImGroupMemberAuditDao getDao() {
         return this.baseMapper;
@@ -79,36 +94,58 @@ public class ImGroupMemberAuditServiceImpl extends ServiceImpl<ImGroupMemberAudi
         if(Objects.nonNull(baseMapper.findOne(auditParams))){
             throw new BizException("您有待审核的申请,请勿重复提交");
         }
-        Date date = new Date();
-        //是否自动通过审核
-        imGroupMemberAudit.setAuditStatus(imGroup.getAutoPassFlag() && autoJoin?AuditStatusEnum.OPEN:AuditStatusEnum.AUDITING);
-        imGroupMemberAudit.setUpdateTime(date);
-        imGroupMemberAudit.setCreateTime(date);
-        baseMapper.insert(imGroupMemberAudit);
-        if(imGroup.getAutoPassFlag() && Optional.ofNullable(autoJoin).orElse(false)){
-            //处理本地群成员
-            List<ImGroupMember> groupMembers = imGroupMemberService.initGroupMember(imGroup.getId(),
-                    imGroupMemberAudit.getUserId(), false,
-                    imGroupMemberAudit.getRoleType());
-            //同步群成员数量
-            imGroupService.getDao().updateMemberNum(imGroup.getId());
-            //加入融云群
-            imGroupMemberService.join(groupMembers,groupId);
-        } else {
-            Map<Long,String> receivers = new HashMap<>(1);
-            // 群创建人
-            SysUser user = sysUserService.findUserById(imGroup.getCreateBy());
-            // 申请人
-            SysUser auditUser = sysUserService.findUserById(imGroupMemberAudit.getUserId());
-
-            receivers.put(user.getId(), user.getPhone());
+
+        // 增加群成员校验锁,当群成员人数达到限制时,不允许再次加入
+        String lockName = "klx:group_member_apply_lock:" + groupId;
+        DistributedLock.of(redissonClient).runIfLockToFunction(lockName, (x)-> {
+
             try {
-                sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.STUDENT_JOIN_FANSGROUP,
-                           receivers, null, 0, null, ClientEnum.TEACHER.getCode(), auditUser.getUsername(),imGroup.getName());
+
+                // 统计群成员数量,大于等于群组最大人数时,不允许加入
+                int memberCount = imGroupMemberService.countGroupMember(groupId);
+                // 查询群成员人数限制
+                SysConfig byParamName = sysConfigService.findByParamName(SysConfigConstant.GROUP_MEMBER_LIMIT);
+                if (Objects.nonNull(byParamName) && memberCount >= Integer.parseInt(byParamName.getParamValue())) {
+                    throw new BizException("群成员数量已达上限");
+                }
+
+                Date date = new Date();
+                //是否自动通过审核
+                imGroupMemberAudit.setAuditStatus(imGroup.getAutoPassFlag() && autoJoin?AuditStatusEnum.OPEN:AuditStatusEnum.AUDITING);
+                imGroupMemberAudit.setUpdateTime(date);
+                imGroupMemberAudit.setCreateTime(date);
+                baseMapper.insert(imGroupMemberAudit);
+                if(imGroup.getAutoPassFlag() && Optional.ofNullable(autoJoin).orElse(false)){
+                    //处理本地群成员
+                    List<ImGroupMember> groupMembers = imGroupMemberService.initGroupMember(imGroup.getId(),
+                        imGroupMemberAudit.getUserId(), false,
+                        imGroupMemberAudit.getRoleType());
+                    //同步群成员数量
+                    imGroupService.getDao().updateMemberNum(imGroup.getId());
+                    //加入融云群
+                    imGroupMemberService.join(groupMembers,groupId);
+                } else {
+                    Map<Long,String> receivers = new HashMap<>(1);
+                    // 群创建人
+                    SysUser user = sysUserService.findUserById(imGroup.getCreateBy());
+                    // 申请人
+                    SysUser auditUser = sysUserService.findUserById(imGroupMemberAudit.getUserId());
+
+                    receivers.put(user.getId(), user.getPhone());
+                    try {
+                        sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.STUDENT_JOIN_FANSGROUP,
+                            receivers, null, 0, null, ClientEnum.TEACHER.getCode(), auditUser.getUsername(),imGroup.getName());
+                    } catch (Exception e) {
+                        log.warn("学生入群消息发送失败,{}",e.getMessage());
+                    }
+                }
             } catch (Exception e) {
-                log.warn("学生入群消息发送失败,{}",e.getMessage());
+                log.error("加入群组申请失败,{}", e.getMessage(), e);
+                throw new BizException("加入群组申请失败");
             }
-        }
+            return true;
+        }, null, 10L);
+
     }
 
     @Override
@@ -117,18 +154,38 @@ public class ImGroupMemberAuditServiceImpl extends ServiceImpl<ImGroupMemberAudi
         Optional.of(auditStatus).filter(e->e != AuditStatusEnum.AUDITING).orElseThrow(()->new BizException("操作失败:审核状态异常"));
         ImGroup imGroup = Optional.ofNullable(imGroupService.getById(groupId)).orElseThrow(() ->new BizException("群组信息不存在"));
         Optional.of(sysUserService.getUserId()).filter(imGroup.getCreateBy()::equals).orElseThrow(()->new BizException("操作失败:您没有审核权限"));
-        //修改审核状态
-        baseMapper.batchUpdateAuditStatus(auditIds,auditStatus.getCode());
-        if(auditStatus == AuditStatusEnum.OPEN){
-            List<ImGroupMemberAudit> imGroupMemberAudit = baseMapper.findByIds(auditIds);
-            Set<Long> userIds = imGroupMemberAudit.stream().map(ImGroupMemberAudit::getUserId).collect(Collectors.toSet());
-            List<ImGroupMember> groupMembers = imGroupMemberService.initGroupMembers(groupId,userIds, ImGroupMemberRoleType.STUDENT);
-            //同步群成员数量
-            imGroupService.getDao().updateMemberNum(imGroup.getId());
-            //加入融云群
-            imGroupMemberService.join(groupMembers,imGroup.getId());
-            sendMessage(auditIds);
-        }
+
+        // 增加群成员校验锁,当群成员人数达到限制时,不允许再次加入
+        String lockName = "klx:group_member_audit_lock:" + groupId;
+        DistributedLock.of(redissonClient).runIfLockToFunction(lockName, (x)-> {
+            try {
+                // 统计群成员数量,大于等于群组最大人数时,不允许加入
+                int memberCount = imGroupMemberService.countGroupMember(groupId);
+                // 查询群成员人数限制
+                SysConfig config = sysConfigService.findByParamName(SysConfigConstant.GROUP_MEMBER_LIMIT);
+                if (Objects.nonNull(config) && memberCount >= Integer.parseInt(config.getParamValue())) {
+                    throw new BizException("群成员数量已达上限");
+                }
+
+                //修改审核状态
+                baseMapper.batchUpdateAuditStatus(auditIds,auditStatus.getCode());
+                if(auditStatus == AuditStatusEnum.OPEN){
+                    List<ImGroupMemberAudit> imGroupMemberAudit = baseMapper.findByIds(auditIds);
+                    Set<Long> userIds = imGroupMemberAudit.stream().map(ImGroupMemberAudit::getUserId).collect(Collectors.toSet());
+                    List<ImGroupMember> groupMembers = imGroupMemberService.initGroupMembers(groupId,userIds, ImGroupMemberRoleType.STUDENT);
+                    //同步群成员数量
+                    imGroupService.getDao().updateMemberNum(imGroup.getId());
+                    //加入融云群
+                    imGroupMemberService.join(groupMembers,imGroup.getId());
+                    sendMessage(auditIds);
+                }
+            } catch (Exception e) {
+                log.error("加入群组审核失败,{}", e.getMessage(), e);
+                throw new BizException("加入群组审核失败");
+            }
+            return true;
+        }, null, 10L);
+
     }
 
     /**

+ 14 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImGroupMemberServiceImpl.java

@@ -266,5 +266,19 @@ public class ImGroupMemberServiceImpl extends ServiceImpl<ImGroupMemberDao, ImGr
     public IPage<ImGroupMemberWrapper.ImGroupMember> selectPage(IPage<ImGroupMemberWrapper.ImGroupMember> page, ImGroupMemberWrapper.ImGroupMemberQuery query) {
         return page.setRecords(imGroupMemberDao.selectPage(page, query));
     }
+
+    /**
+     * 获取群成员数量
+     *
+     * @param groupId 群ID
+     * @return int
+     */
+    @Override
+    public int countGroupMember(String groupId) {
+        if (org.apache.commons.lang3.StringUtils.isEmpty(groupId)) {
+            return 0;
+        }
+        return lambdaQuery().eq(ImGroupMember::getGroupId, groupId).count();
+    }
 }
 

+ 25 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImGroupServiceImpl.java

@@ -612,6 +612,13 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
     public ImGroup findGroupInfoById(String groupId, Long userId) {
 
         ImGroup group = imGroupService.getById(groupId);
+        if (Objects.nonNull(group)) {
+            // 查询群成员人数限制
+            SysConfig byParamName = sysConfigService.findByParamName(SysConfigConstant.GROUP_MEMBER_LIMIT);
+            if (Objects.nonNull(byParamName)) {
+                group.setGroupMemberLimit(Integer.parseInt(byParamName.getParamValue()));
+            }
+        }
 
         // 异步执行自动加入群组功能
         ThreadPool.getExecutor().submit(() -> {
@@ -664,6 +671,24 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
         return group;
     }
 
+    /**
+     * 获取群信息
+     *
+     * @param groupId 群ID
+     * @return ImGroup
+     */
+    @Override
+    public ImGroup getGroupById(String groupId) {
+        ImGroup group = imGroupService.getById(groupId);
+        if (Objects.nonNull(group)) {
+            // 查询群成员人数限制
+            SysConfig byParamName = sysConfigService.findByParamName(SysConfigConstant.GROUP_MEMBER_LIMIT);
+            if (Objects.nonNull(byParamName)) {
+                group.setGroupMemberLimit(Integer.parseInt(byParamName.getParamValue()));
+            }
+        }
+        return group;
+    }
 
 
     /**