liujc 11 tháng trước cách đây
mục cha
commit
9dbd5dc8ca
18 tập tin đã thay đổi với 397 bổ sung110 xóa
  1. 1 1
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/ImGroupController.java
  2. 1 1
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/ImGroupController.java
  3. 2 2
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherCourseScheduleController.java
  4. 3 2
      cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/WebCourseScheduleController.java
  5. 5 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/constant/SysConfigConstant.java
  6. 13 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/CourseScheduleStudentPaymentDao.java
  7. 5 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/CourseScheduleStudentPayment.java
  8. 12 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/ImGroup.java
  9. 21 4
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CourseScheduleService.java
  10. 7 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/ImGroupMemberService.java
  11. 9 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/ImGroupService.java
  12. 8 2
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseGroupServiceImpl.java
  13. 32 17
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseScheduleServiceImpl.java
  14. 113 44
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImGroupMemberAuditServiceImpl.java
  15. 14 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImGroupMemberServiceImpl.java
  16. 112 34
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImGroupServiceImpl.java
  17. 16 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantGroupServiceImpl.java
  18. 23 1
      cooleshow-user/user-biz/src/main/resources/config/mybatis/CourseScheduleStudentPaymentMapper.xml

+ 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, "群组不存在");
         }

+ 2 - 2
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherCourseScheduleController.java

@@ -215,8 +215,8 @@ public class TeacherCourseScheduleController extends BaseController {
         if (user == null || null == user.getId()) {
             return failed(HttpStatus.FORBIDDEN, "请登录");
         }
-        courseScheduleService.arrangeCourse(arrangeCourseVo, user.getId());
-        return succeed();
+        String message = courseScheduleService.arrangeCourse(arrangeCourseVo, user.getId());
+        return succeed(message);
     }
 
     @ApiOperation("根据月份查询消耗时长")

+ 3 - 2
cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/WebCourseScheduleController.java

@@ -23,6 +23,7 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.validation.annotation.Validated;
@@ -211,8 +212,8 @@ public class WebCourseScheduleController extends BaseController {
         if (user == null || null == user.getId()) {
             return failed(HttpStatus.FORBIDDEN, "请登录");
         }
-        courseScheduleService.arrangeCourse(arrangeCourseVo, user.getId());
-        return succeed();
+        String message = courseScheduleService.arrangeCourse(arrangeCourseVo, user.getId());
+        return succeed(message);
     }
 
     @ApiOperation("根据月份查询消耗时长")

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

@@ -440,4 +440,9 @@ public interface SysConfigConstant {
      * 添加客服好友时,客服发送消息标题
      */
     String CUSTOMER_SERVICE_ADD_MSG_TITLE = "customer_service_add_msg_title";
+
+    /**
+     * 群成员人数限制
+     */
+    String GROUP_MEMBER_LIMIT = "group_member_limit";
 }

+ 13 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/CourseScheduleStudentPaymentDao.java

@@ -30,7 +30,7 @@ public interface CourseScheduleStudentPaymentDao extends BaseMapper<CourseSchedu
      * @author zx
      * @date 2022/3/23 16:18
      */
-    Set<Long> queryStudentIds(@Param("courseGroupId") Long courseGroupId,
+    List<Long> queryStudentIds(@Param("courseGroupId") Long courseGroupId,
                               @Param("courseGroupType") String courseGroupType);
 
     /**
@@ -87,5 +87,17 @@ public interface CourseScheduleStudentPaymentDao extends BaseMapper<CourseSchedu
     List<CourseScheduleStudentVo> selectUser();
 
     List<BasicUserInfoDto> queryNoJoinStu(@Param("scheduleId") String scheduleId, @Param("studentIds") List<String> studentIds);
+
+    /**
+     * 更新用户入群状态
+     * @param courseGroupId 课程组id
+     * @param courseGroupType 课程组类型
+     * @param groupJoin 入群状态
+     * @param studentIds 学员id
+     */
+    void updateGroupJoinStatus(@Param("courseGroupId") Long courseGroupId,
+                               @Param("courseGroupType") String courseGroupType,
+                               @Param("groupJoin") Boolean groupJoin,
+                               @Param("studentIds") List<Long> studentIds);
 }
 

+ 5 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/CourseScheduleStudentPayment.java

@@ -65,5 +65,10 @@ public class CourseScheduleStudentPayment implements Serializable {
     @ApiModelProperty(value = "类型 practice陪练课 live直播课")
     private String courseType;
 
+    @TableField(value = "group_join_")
+    @ApiModelProperty("入群标记")
+    private Boolean groupJoin;
+
+
 }
 

+ 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;
+    }
 }
 

+ 21 - 4
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CourseScheduleService.java

@@ -10,11 +10,21 @@ import com.yonge.cooleshow.biz.dal.dto.search.PracticeTeacherSearch;
 import com.yonge.cooleshow.biz.dal.entity.CourseCalendarEntity;
 import com.yonge.cooleshow.biz.dal.entity.CourseSchedule;
 import com.yonge.cooleshow.biz.dal.entity.TeacherSubjectPrice;
-import com.yonge.cooleshow.biz.dal.entity.UserOrderDetail;
-import com.yonge.cooleshow.biz.dal.vo.*;
+import com.yonge.cooleshow.biz.dal.vo.ArrangeCourseVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseAdjustVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseScheduleRecordVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseStudent;
+import com.yonge.cooleshow.biz.dal.vo.CourseStudentVo;
+import com.yonge.cooleshow.biz.dal.vo.MyCourseVo;
+import com.yonge.cooleshow.biz.dal.vo.PianoClassVo;
+import com.yonge.cooleshow.biz.dal.vo.PianoRoomTimeVo;
+import com.yonge.cooleshow.biz.dal.vo.PracticeTeacherVo;
+import com.yonge.cooleshow.biz.dal.vo.StudentHomePage;
+import com.yonge.cooleshow.biz.dal.vo.TeacherLiveCourseInfoVo;
+import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
-import com.yonge.cooleshow.biz.dal.wrapper.course.CourseScheduleWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.course.CourseScheduleWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.toolset.base.page.PageInfo;
@@ -247,7 +257,14 @@ public interface CourseScheduleService extends IService<CourseSchedule> {
 
     PageInfo<CourseStudentVo> selectStudent(Map<String, Object> param);
 
-    void arrangeCourse(ArrangeCourseVo arrangeCourseVo, Long teacherId);
+    String arrangeCourse(ArrangeCourseVo arrangeCourseVo, Long teacherId);
+
+    /**
+     * 校验排课
+     * @param arrangeCourseVo 排课参数
+     * @param teacherId 老师id
+     */
+    String checkArrangeCourse(ArrangeCourseVo arrangeCourseVo, Long teacherId);
 
     Map<String, Object> selectConsumeTime(String month, Long teacherId);
 

+ 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);
 }
 

+ 9 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/ImGroupService.java

@@ -85,10 +85,11 @@ public interface ImGroupService extends IService<ImGroup> {
     * @description: 成课后自动创建群聊,建议放在最后执行
      * @param courseGroupId 课程组编号
      * @param courseGroupType 课程组类型
+     * @param noGroupJoinUserIds 未加入群聊的用户编号
     * @author zx
     * @date 2022/3/22 11:17
     */
-    String autoCreate(Long courseGroupId,String courseGroupType) throws Exception;
+    String autoCreate(Long courseGroupId,String courseGroupType, List<Long> noGroupJoinUserIds) throws Exception;
 
     List<GroupMemberWrapper.ImGroupMember> getImGroupMembers(List<ImGroupMember> groupMemberList);
 
@@ -144,6 +145,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;
 
     /**

+ 8 - 2
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseGroupServiceImpl.java

@@ -5,7 +5,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.beust.jcommander.internal.Lists;
+import com.google.common.collect.Lists;
 import com.microsvc.toolkit.config.jwt.utils.JwtUserInfo;
 import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
@@ -1250,9 +1250,15 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
                 if (courseGroup.getPreStudentNum() >= courseGroup.getMixStudentNum() &&courseGroup.getStatus().equals(CourseGroupEnum.APPLY.getCode())) {
                     //人数达标则修改课程组为进行中状态
                     courseGroup.setStatus(CourseGroupEnum.ING.getCode());
+                    List<Long> noGroupJoinUserIds = Lists.newArrayList();
                     //创建群聊 并添加人员到群中
-                    String imGroupId = imGroupService.autoCreate(courseGroup.getId(), courseGroup.getType());
+                    String imGroupId = imGroupService.autoCreate(courseGroup.getId(), courseGroup.getType(), noGroupJoinUserIds);
 
+                    // 排除未进群的学生
+                    if (CollectionUtils.isNotEmpty(noGroupJoinUserIds)) {
+                        noGroupJoinUserIds.forEach(userIds::remove);
+                    }
+                    // 更新已进群用户身份
                     imGroupMemberService.initGroupMembers(imGroupId, userIds, ImGroupMemberRoleType.STUDENT);
                     //添加老师进群
                     imGroupMemberService.initGroupMembers(imGroupId, Collections.singleton(courseGroup.getTeacherId()), ImGroupMemberRoleType.TEACHER);

+ 32 - 17
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseScheduleServiceImpl.java

@@ -10,9 +10,11 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
 import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.dao.*;
+import com.yonge.cooleshow.biz.dal.dto.BasicUserInfo;
 import com.yonge.cooleshow.biz.dal.dto.PracticeScheduleDto;
 import com.yonge.cooleshow.biz.dal.dto.UserAccountRecordDto;
 import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
@@ -54,7 +56,6 @@ import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
-import java.text.MessageFormat;
 import java.text.SimpleDateFormat;
 import java.time.Instant;
 import java.time.LocalDate;
@@ -1954,16 +1955,23 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
      * @Author: cy
      * @Date: 2022/5/27
      */
-    public void arrangeCourse(ArrangeCourseVo arrangeCourseVo, Long teacherId) {
-        DistributedLock.of(redissonClient)
-                .runIfLockCanGet(CacheNameEnum.LOCK_EXECUTE_ORDER.getRedisKey("teacherId:" + teacherId)
-                        , () -> this.checkArrangeCourse(arrangeCourseVo, teacherId), 60L, TimeUnit.SECONDS);
+    public String arrangeCourse(ArrangeCourseVo arrangeCourseVo, Long teacherId) {
+
+        // 返回未加入群用户消息
+        return DistributedLock.of(redissonClient)
+            .runIfLockCanGet(CacheNameEnum.LOCK_EXECUTE_ORDER.getRedisKey("teacherId:" + teacherId)
+                , () -> this.checkArrangeCourse(arrangeCourseVo, teacherId), 60L, TimeUnit.SECONDS);
     }
 
+    /**
+     * 校验排课
+     * @param arrangeCourseVo 排课参数
+     * @param teacherId 老师id
+     */
     @Transactional(rollbackFor = Exception.class)
-    public void checkArrangeCourse(ArrangeCourseVo arrangeCourseVo, Long teacherId) {
+    public String checkArrangeCourse(ArrangeCourseVo arrangeCourseVo, Long teacherId) {
         Integer classNum = arrangeCourseVo.getClassNum();//课时数
-        Integer singleClssTime = arrangeCourseVo.getSingleClssTime();//单课时长
+        Integer singleClassTime = arrangeCourseVo.getSingleClssTime();//单课时长
         List<Long> studentIds = arrangeCourseVo.getStudentIds();//学员id集合
 
         String formula = sysConfigService.findConfigValue(SysConfigConstant.PIANO_ROOM_TIME_FORMULA);
@@ -1971,13 +1979,13 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
         if (n == null) {
             throw new BizException("公式转换失败");
         }
-        Integer consumTime = classNum * singleClssTime * n;//消耗时长 课程数*单课时长*人数
+        Integer consumTime = classNum * singleClassTime * n;//消耗时长 课程数*单课时长*人数
 
         List<CourseTimeEntity> timeList = arrangeCourseVo.getTimeList();//选课时间
         Integer consumeTime = arrangeCourseVo.getConsumeTime();
 
         log.info("classNum:" + classNum);
-        log.info("singleClssTime:" + singleClssTime);
+        log.info("singleClssTime:" + singleClassTime);
         log.info("n:" + n);
         log.info("消耗时长:" + consumTime);
         log.info("传入时长:" + consumeTime);
@@ -2002,7 +2010,7 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
             if (timeList.get(i).getStartTime().before(new Date())) {
                 throw new BizException("上课时间必须大于当前时间");
             }
-            if (!DateUtil.offsetMinute(timeList.get(i).getStartTime(), singleClssTime).equals(timeList.get(i).getEndTime())) {
+            if (!DateUtil.offsetMinute(timeList.get(i).getStartTime(), singleClassTime).equals(timeList.get(i).getEndTime())) {
                 throw new BizException("第{}节课结束时间计算错误", i + 1);
             }
         }
@@ -2059,7 +2067,7 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
         courseGroup.setTeacherId(teacherId);
         courseGroup.setName(arrangeCourseVo.getCourseName());
         courseGroup.setSubjectId(arrangeCourseVo.getSubjectId());
-        courseGroup.setSingleCourseMinutes(singleClssTime);
+        courseGroup.setSingleCourseMinutes(singleClassTime);
         courseGroup.setCourseNum(classNum);
         courseGroup.setStatus(CourseGroupEnum.ING.getCode());
         courseGroup.setCreatedBy(teacherId);
@@ -2079,7 +2087,7 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
             schedule.setLock(0);
             schedule.setStatus(CourseScheduleEnum.NOT_START.getCode());
             schedule.setCreatedBy(teacherId);
-            schedule.setSingleCourseTime(singleClssTime);
+            schedule.setSingleCourseTime(singleClassTime);
             baseMapper.insert(schedule);
 
             //添加payment
@@ -2113,14 +2121,14 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
                             roomTimeLock.setFrozenTime(frozenTimeLock + consumTime);
                             pianoRoomTimeDao.update(roomTimeLock, Wrappers.<PianoRoomTime>lambdaQuery().eq(PianoRoomTime::getTeacherId, teacherId));
                             return null;
-                        }, null, 10l);
+                        }, null, 10L);
 
+        List<Long> noGroupJoinUserIds = Lists.newArrayList();
         //创建群聊
         try {
-            imGroupService.autoCreate(courseGroup.getId(), CourseScheduleEnum.PIANO_ROOM_CLASS.getCode());
+            imGroupService.autoCreate(courseGroup.getId(), CourseScheduleEnum.PIANO_ROOM_CLASS.getCode(), noGroupJoinUserIds);
         } catch (Exception e) {
-            log.error("琴房课程组id:{},创建群聊失败:{}", courseGroup.getId(), e);
-            e.printStackTrace();
+            log.error("琴房课程组id:{},创建群聊失败", courseGroup.getId(), e);
         }
 
         for (Long studentId : studentIds) {
@@ -2131,6 +2139,13 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
         }
         //清除老师缓存
         redissonClient.getBucket(CacheNameEnum.TEACHER_TOTAL.getRedisKey(teacherId)).delete();
+
+        String message = "";
+        if (CollectionUtils.isNotEmpty(noGroupJoinUserIds)) {
+            // 返回未加入群用户消息
+            message = "群成员人数达到上限,有" + noGroupJoinUserIds.size() + "位学生未进入课程群";
+        }
+        return message;
     }
 
     /**
@@ -2450,7 +2465,7 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
                                     .set(PianoRoomTime::getRemainTime, remainTime - diffTime)
                                     .set(PianoRoomTime::getFrozenTime, frozenTime + diffTime));
                             return null;
-                        }, null, 10l);
+                        }, null, 10L);
 
         //删除原学员
         paymentDao.delete(Wrappers.<CourseScheduleStudentPayment>lambdaQuery().eq(CourseScheduleStudentPayment::getCourseId, courseId));

+ 113 - 44
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,55 @@ 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)-> {
+
+            // 统计群成员数量,大于等于群组最大人数时,不允许加入
+            if (!verifyGroupMemberJoinLimit(groupId, 1)) {
+                SysConfig config = sysConfigService.findByParamName(SysConfigConstant.GROUP_MEMBER_LIMIT);
+                throw new BizException("群成员人数上限为:" + config.getParamValue() + "人");
+            }
+
             try {
-                sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.STUDENT_JOIN_FANSGROUP,
-                           receivers, null, 0, null, ClientEnum.TEACHER.getCode(), auditUser.getUsername(),imGroup.getName());
+                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 +151,53 @@ 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)-> {
+
+            // 校验群成员加入限制
+            String[] split = auditIds.split(",");
+            if (AuditStatusEnum.OPEN.equals(auditStatus) && !verifyGroupMemberJoinLimit(groupId, split.length)) {
+                SysConfig config = sysConfigService.findByParamName(SysConfigConstant.GROUP_MEMBER_LIMIT);
+                throw new BizException("群成员人数上限为:" + config.getParamValue() + "人");
+            }
+            try {
+                //修改审核状态
+                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);
+
+    }
+
+    /**
+     * 校验群成员加入限制
+     * @param groupId 群组ID
+     */
+    private Boolean verifyGroupMemberJoinLimit(String groupId, int addNum) {
+        // 统计群成员数量,大于等于群组最大人数时,不允许加入
+        int memberCount = imGroupMemberService.countGroupMember(groupId);
+        // 查询群成员人数限制
+        SysConfig config = sysConfigService.findByParamName(SysConfigConstant.GROUP_MEMBER_LIMIT);
+        if (Objects.nonNull(config) && Integer.parseInt(config.getParamValue()) > 0
+            && (memberCount + addNum) > Integer.parseInt(config.getParamValue())) {
+            return false;
         }
+        return true;
     }
 
     /**

+ 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();
+    }
 }
 

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

@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
 import com.microsvc.toolkit.middleware.common.http.ImageUtil;
 import com.microsvc.toolkit.middleware.im.ImPluginContext;
 import com.microsvc.toolkit.middleware.im.message.GroupMemberWrapper;
@@ -33,6 +34,7 @@ import com.yonge.cooleshow.biz.dal.dto.search.StudentSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.TeacherSearch;
 import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.CourseScheduleEnum;
 import com.yonge.cooleshow.biz.dal.enums.ImGroupMemberRoleType;
 import com.yonge.cooleshow.biz.dal.enums.ImGroupType;
 import com.yonge.cooleshow.biz.dal.enums.RoleEnum;
@@ -64,6 +66,7 @@ import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.entity.UploadReturnBean;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.base.util.ThreadPool;
+import com.yonge.toolset.payment.util.DistributedLock;
 import com.yonge.toolset.utils.date.DateUtil;
 import io.rong.RongCloud;
 import io.rong.methods.message.history.History;
@@ -304,6 +307,12 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
     @Override
     @Transactional(rollbackFor = Exception.class)
     public String create(ImGroupWrapper.ImGroup imGroup) throws Exception {
+        // 群成员数量限制校验
+        SysConfig config = sysConfigService.findByParamName(SysConfigConstant.GROUP_MEMBER_LIMIT);
+        if (config != null && Integer.parseInt(config.getParamValue()) < (imGroup.getStudentIdList().size() + 1)) {
+            throw new BizException("群成员人数上限为:" + config.getParamValue() + "人");
+        }
+
         Date now = new Date();
         if (imGroup.getType() == null) {
             imGroup.setType(ImGroupType.FAN.getCode());
@@ -359,31 +368,52 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
             throw new BizException("添加的群成员不能为空");
 
         }
-        List<ImGroupMember> groupMemberList = imGroupMemberService.initGroupMembers(groupId,
-                studentIdList, ImGroupMemberRoleType.STUDENT);
-        imGroupMemberService.join(groupMemberList, groupId);
-
-        // 如果是机构群,学生自动添加老师好友
-        if (ImGroupType.ORG.equals(imGroup.getType())) {
-            List<ImGroupMember> teacherList = imGroupMemberService.lambdaQuery()
-                    .eq(ImGroupMember::getGroupId, groupId)
-                    .eq(ImGroupMember::getRoleType, ImGroupMemberRoleType.TEACHER)
-                    .list();
-            teacherList.forEach(teacher -> imUserFriendService.saveUserFriend(teacher.getUserId(), studentIdList));
-        }
+        // 增加群成员校验锁,当群成员人数达到限制时,不允许再次加入
+        String lockName = "klx:group_member_add_lock:" + groupId;
+        DistributedLock.of(redissonClient).runIfLockToFunction(lockName, (x)-> {
+            // 群成员数量限制校验
+            int memberCount = imGroupMemberService.countGroupMember(groupId);
+            // 查询群成员人数限制
+            SysConfig config = sysConfigService.findByParamName(SysConfigConstant.GROUP_MEMBER_LIMIT);
+            if (Objects.nonNull(config) && Integer.parseInt(config.getParamValue()) > 0
+                && (memberCount + studentIdList.size()) > Integer.parseInt(config.getParamValue())) {
+                throw new BizException("群成员人数上限为:" + config.getParamValue() + "人");
+            }
+
+            try {
+                List<ImGroupMember> groupMemberList = imGroupMemberService.initGroupMembers(groupId,
+                    studentIdList, ImGroupMemberRoleType.STUDENT);
+                imGroupMemberService.join(groupMemberList, groupId);
+
+                // 如果是机构群,学生自动添加老师好友
+                if (ImGroupType.ORG.equals(imGroup.getType())) {
+                    List<ImGroupMember> teacherList = imGroupMemberService.lambdaQuery()
+                        .eq(ImGroupMember::getGroupId, groupId)
+                        .eq(ImGroupMember::getRoleType, ImGroupMemberRoleType.TEACHER)
+                        .list();
+                    teacherList.forEach(teacher -> imUserFriendService.saveUserFriend(teacher.getUserId(), studentIdList));
+                }
+            } catch (Exception e) {
+                log.error("加入群组失败,{}", e.getMessage(), e);
+                throw new BizException(e.getMessage());
+            }
+            return true;
+        }, null, 10L);
+
     }
 
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public String autoCreate(Long courseGroupId, String courseGroupType) throws Exception {
+    public String autoCreate(Long courseGroupId, String courseGroupType, List<Long> noGroupJoinUserIds) throws Exception {
         //获取课程组
         CourseGroup courseGroup = courseGroupService.getById(courseGroupId);
         if (courseGroup.getTeacherId() == null) {
             return null;
         }
-        //获取学员列表
-        Set<Long> studentIds = courseScheduleStudentPaymentDao.queryStudentIds(courseGroupId, courseGroupType);
+        //获取学员列表,按购买时间顺序升序排列返回
+        List<Long> studentIds = courseScheduleStudentPaymentDao.queryStudentIds(courseGroupId, courseGroupType);
+        // studentIds集合中所有null元素移除
         studentIds.removeAll(Collections.singleton(null));
         if (CollectionUtils.isEmpty(studentIds)) {
             return null;
@@ -391,7 +421,7 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
         Date now = new Date();
         Long teacherId = courseGroup.getTeacherId();
         //保存老师学员关联的通讯录xz
-        imUserFriendService.saveUserFriend(teacherId, studentIds);
+        imUserFriendService.saveUserFriend(teacherId, Sets.newHashSet(studentIds));
 
         //创建群聊
         ImGroup imGroup = new ImGroup();
@@ -408,25 +438,48 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
         imGroup.setCourseGroupId(courseGroupId);
 //        this.baseMapper.insert(imGroup);
 
-
         String groupId = createImGroup(imGroup);
-//        // 添加学生
-        List<ImGroupMember> groupMembers = imGroupMemberService.initGroupMembers(groupId, studentIds,
-                ImGroupMemberRoleType.STUDENT);
-        List<com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupMemberWrapper.ImGroupMember> groupMemberList = Lists.newArrayList();
-        for (ImGroupMember groupMember : groupMembers) {
-            groupMemberList.add(com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupMemberWrapper.ImGroupMember.builder()
-                    .groupId(groupMember.getGroupId())
-                    .userId(groupMember.getUserId())
-                    .clientType(groupMember.getRoleType().getCode())
-                    .avatar(groupMember.getAvatar())
-                    .nickname(groupMember.getNickname())
-                    .isAdmin(groupMember.getIsAdmin())
-                    .imUserId(getImUserId(groupMember.getUserId().toString(), groupMember.getRoleType().getCode()))
-                    .roleType(groupMember.getRoleType().getCode())
-                    .build());
+
+        // 直播课、琴房课校验群成员人数限制
+        if (CourseScheduleEnum.PIANO_ROOM_CLASS.getCode().equals(courseGroupType)
+            || CourseScheduleEnum.LIVE.getCode().equals(courseGroupType)) {
+
+            // 增加群成员人数限制,若超过限制则不添加到群组
+            SysConfig config = sysConfigService.findByParamName(SysConfigConstant.GROUP_MEMBER_LIMIT);
+            if (Objects.nonNull(config) && Integer.parseInt(config.getParamValue()) > 0) {
+                int groupMemberLimit = Integer.parseInt(config.getParamValue());
+                if ((CollectionUtils.size(studentIds) + 1) > groupMemberLimit) {
+
+                    // 已加入群组用户标记
+                    List<Long> userIds = Lists.newArrayList(studentIds);
+                    studentIds = userIds.subList(0, groupMemberLimit - 1);
+                    // 未加入群组用户标记
+                    noGroupJoinUserIds.addAll(userIds.subList(groupMemberLimit - 1, userIds.size()));
+                    // 重置用户入群加入标记
+                    courseScheduleStudentPaymentDao.updateGroupJoinStatus(courseGroupId, courseGroupType, false,
+                        noGroupJoinUserIds);
+                }
+            }
+        }
+
+        if (!studentIds.isEmpty()) {
+            // 添加学生
+            List<ImGroupMember> groupMembers = imGroupMemberService.initGroupMembers(groupId, Sets.newHashSet(studentIds), ImGroupMemberRoleType.STUDENT);
+            List<com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupMemberWrapper.ImGroupMember> groupMemberList = Lists.newArrayList();
+            for (ImGroupMember groupMember : groupMembers) {
+                groupMemberList.add(com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupMemberWrapper.ImGroupMember.builder()
+                        .groupId(groupMember.getGroupId())
+                        .userId(groupMember.getUserId())
+                        .clientType(groupMember.getRoleType().getCode())
+                        .avatar(groupMember.getAvatar())
+                        .nickname(groupMember.getNickname())
+                        .isAdmin(groupMember.getIsAdmin())
+                        .imUserId(getImUserId(groupMember.getUserId().toString(), groupMember.getRoleType().getCode()))
+                        .roleType(groupMember.getRoleType().getCode())
+                        .build());
+            }
+            imGroupCoreService.saveImGroupMemberList(groupId, groupMemberList);
         }
-        imGroupCoreService.saveImGroupMemberList(groupId, groupMemberList);
         //处理本地群成员列表
         // 添加老师
 //        List<ImGroupMember> groupMembers = imGroupMemberService.initGroupMember(imGroupId, imGroup.getCreateBy(),
@@ -436,7 +489,7 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
 //        this.rtcCreate(courseGroup.getTeacherId(), imGroupId, imGroup.getName(),imGroup.getImg());
 //        //加入融云群
 //        imGroupMemberService.join(groupMembers, imGroupId);
-        return groupId.toString();
+        return groupId;
     }
 
 
@@ -612,6 +665,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 +724,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;
+    }
 
 
     /**

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

@@ -17,6 +17,7 @@ import com.yonge.cooleshow.biz.dal.entity.ImGroup;
 import com.yonge.cooleshow.biz.dal.entity.ImGroupMember;
 import com.yonge.cooleshow.biz.dal.entity.Student;
 import com.yonge.cooleshow.biz.dal.entity.Subject;
+import com.yonge.cooleshow.biz.dal.entity.SysConfig;
 import com.yonge.cooleshow.biz.dal.entity.Teacher;
 import com.yonge.cooleshow.biz.dal.entity.TenantGroup;
 import com.yonge.cooleshow.biz.dal.entity.TenantGroupAlbum;
@@ -28,6 +29,7 @@ import com.yonge.cooleshow.biz.dal.mapper.TenantGroupAlbumMapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantGroupMapper;
 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.service.TenantGroupService;
 import com.yonge.cooleshow.biz.dal.service.im.ImGroupCoreService;
@@ -36,6 +38,7 @@ import com.yonge.cooleshow.biz.dal.wrapper.StudentWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantGroupAlbumWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantGroupWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupWrapper;
+import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.mybatis.support.PageUtil;
 import lombok.extern.slf4j.Slf4j;
@@ -71,6 +74,8 @@ public class TenantGroupServiceImpl extends ServiceImpl<TenantGroupMapper, Tenan
     private SysUserService sysUserService;
     @Autowired
     private TenantGroupAlbumMapper tenantGroupAlbumMapper;
+    @Autowired
+    private SysConfigService sysConfigService;
 
     /**
      * 查询详情
@@ -162,6 +167,12 @@ public class TenantGroupServiceImpl extends ServiceImpl<TenantGroupMapper, Tenan
 
         this.save(entity);
         if (adminId != null && Boolean.TRUE.equals(imGroupCreate)) {
+            // 群成员数量限制校验
+            SysConfig config = sysConfigService.findByParamName(SysConfigConstant.GROUP_MEMBER_LIMIT);
+            if (config != null && Integer.parseInt(config.getParamValue()) < (userIds.size() + 1)) {
+                throw new BizException("群成员人数上限为:" + config.getParamValue() + "人");
+            }
+
             // 建群
             try {
                 ImGroupWrapper.ImGroup imGroup = new ImGroupWrapper.ImGroup();
@@ -231,6 +242,11 @@ public class TenantGroupServiceImpl extends ServiceImpl<TenantGroupMapper, Tenan
             ImGroup imGroup = imGroupService.getById(oldImGroupId);
             // 群被删除过,并且需要重新建群
             if (imGroup == null) {
+                SysConfig config = sysConfigService.findByParamName(SysConfigConstant.GROUP_MEMBER_LIMIT);
+                if (config != null && Integer.parseInt(config.getParamValue()) < (tenantGroup.getUserIds().size() + 1)) {
+                    throw new BizException("群成员人数上限为:" + config.getParamValue() + "人");
+                }
+
                 String imGroupId = createImGroup(entity.getAdminId(), tenantGroup.getName());
                 entity.setImGroupId(imGroupId);
 

+ 23 - 1
cooleshow-user/user-biz/src/main/resources/config/mybatis/CourseScheduleStudentPaymentMapper.xml

@@ -13,12 +13,13 @@
         <result column="created_time_" jdbcType="TIMESTAMP" property="createdTime"/>
         <result column="updated_time_" jdbcType="TIMESTAMP" property="updatedTime"/>
         <result column="course_type_" jdbcType="VARCHAR" property="courseType"/>
+        <result column="group_join_" jdbcType="TINYINT" property="groupJoin"/>
     </resultMap>
 
     <sql id="Base_Column_List">
         id_
         , user_id_, course_group_id_, course_id_, order_no_, original_price_, expect_price_,
-        actual_price_, created_time_, updated_time_, course_type_
+        actual_price_, created_time_, updated_time_, course_type_, group_join_
     </sql>
 
     <insert id="insertBatch" keyColumn="id_" keyProperty="id" useGeneratedKeys="true"
@@ -77,6 +78,26 @@
             </if>
         </where>
     </update>
+    <!--更新用户课程组入群状态-->
+    <update id="updateGroupJoinStatus">
+        UPDATE course_schedule_student_payment cssp
+        <set>
+            <if test="groupJoin != null">
+                cssp.group_join_ = #{groupJoin}
+            </if>
+        </set>
+        <where>
+            <if test="courseGroupId != null">
+                AND cssp.course_group_id_ = #{courseGroupId}
+            </if>
+            <if test="courseGroupType != null and courseGroupType != ''">
+                AND cssp.course_type_ = #{courseGroupType}
+            </if>
+            <if test="studentIds != null and studentIds.size > 0">
+                AND cssp.user_id_ IN <foreach collection="studentIds" item="studentId" open="(" close=")" separator=",">#{studentId}</foreach>
+            </if>
+        </where>
+    </update>
     <select id="queryStudentIds" resultType="java.lang.Long">
         SELECT DISTINCT user_id_ FROM course_schedule_student_payment
         <where>
@@ -87,6 +108,7 @@
                 AND course_type_ = #{courseGroupType}
             </if>
         </where>
+        ORDER BY created_time_ ASC
     </select>
     <select id="queryByCourseId" resultMap="BaseResultMap">
         SELECT <include refid="Base_Column_List"/> FROM course_schedule_student_payment