Browse Source

Merge remote-tracking branch 'origin/saas_2022_05_17_activity' into saas_2022_05_17_activity

zouxuan 3 years ago
parent
commit
d835c09b95

+ 2 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/TempLittleArtistTrainingCampDao.java

@@ -35,5 +35,7 @@ public interface TempLittleArtistTrainingCampDao extends BaseMapper<TempLittleAr
     <T> IPage<T> queryUserTrainingDetail(Page<T> page, @Param("param") Map<String, Object> param);
 
     List<ImGroup> queryCampImGroup(String imGroupIds);
+
+    Integer queryUserTrainingPlayTime(@Param("param") Map<String, Object> param);
 }
 

+ 12 - 6
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/TempLittleArtistTrainingCamp.java

@@ -19,13 +19,13 @@ import java.io.Serializable;
  */
 @ApiModel(value = "temp_little_artist_training_camp-小小艺术家训练营活动")
 public class TempLittleArtistTrainingCamp implements Serializable {
-    //筹备中
-    public static final String READY = "READY";
+    //未开始-未到报名时间
+    public static final String NOT_START = "NOT_START";
     //报名中
     public static final String APPLY = "APPLY";
-    //未开始
-    public static final String NOT_START = "NOT_START";
-    //进行中
+    //筹备中 - 报名结束-还未到训练时间
+    public static final String READY = "READY";
+    //进行中 - 训练周期内
     public static final String ING = "ING";
     //已结束
     public static final String END = "END";
@@ -59,7 +59,7 @@ public class TempLittleArtistTrainingCamp implements Serializable {
     private Date trainEndDate;
 
     @TableField("state_")
-    @ApiModelProperty(value = "筹备中 READY,报名中 APPLY,未开始 NOT_START,进行中 ING,已结束 END")
+    @ApiModelProperty(value = "未开始 NOT_START,报名中 APPLY,筹备中 READY,进行中 ING,已结束 END")
     private String state;
 
     @TableField("im_group_ids_")
@@ -143,10 +143,16 @@ public class TempLittleArtistTrainingCamp implements Serializable {
         this.trainEndDate = trainEndDate;
     }
 
+    /**
+     * 未开始 NOT_START,报名中 APPLY,筹备中 READY,进行中 ING,已结束 END
+     */
     public String getState() {
         return state;
     }
 
+    /**
+     * 未开始 NOT_START,报名中 APPLY,筹备中 READY,进行中 ING,已结束 END
+     */
     public void setState(String state) {
         this.state = state;
     }

+ 63 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/vo/TempCampUserQualificationsVo.java

@@ -0,0 +1,63 @@
+package com.ym.mec.biz.dal.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel(value = "训练营资格信息")
+public class TempCampUserQualificationsVo {
+
+    @ApiModelProperty(value = "训练营资格 有资格0  无资格1")
+    private Integer qualifications;
+
+    @ApiModelProperty(value = "训练营标题")
+    private String campTitle;
+
+    @ApiModelProperty(value = "用户名称")
+    private String userName;
+
+    @ApiModelProperty(value = "训练营内容文案")
+    private String content;
+
+    @ApiModelProperty(value = "训练营id")
+    private Integer campId;
+
+    public Integer getQualifications() {
+        return qualifications;
+    }
+
+    public void setQualifications(Integer qualifications) {
+        this.qualifications = qualifications;
+    }
+
+    public String getCampTitle() {
+        return campTitle;
+    }
+
+    public void setCampTitle(String campTitle) {
+        this.campTitle = campTitle;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public Integer getCampId() {
+        return campId;
+    }
+
+    public void setCampId(Integer campId) {
+        this.campId = campId;
+    }
+}

+ 58 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/vo/TempCampUserTrainingPlayTimeVo.java

@@ -0,0 +1,58 @@
+package com.ym.mec.biz.dal.vo;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.Date;
+
+@ApiModel(value = "训练营-用户训练信息")
+public class TempCampUserTrainingPlayTimeVo {
+
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    @ApiModelProperty(value = "训练开始日期")
+    private Date trainStartDate;
+
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    @ApiModelProperty(value = "训练结束日期")
+    private Date trainEndDate;
+
+    @ApiModelProperty(value = "训练时长")
+    private Integer playTime;
+
+    @ApiModelProperty(value = "是否完成 0完成 1未完成")
+    private Integer isFinish;
+
+    public Date getTrainStartDate() {
+        return trainStartDate;
+    }
+
+    public void setTrainStartDate(Date trainStartDate) {
+        this.trainStartDate = trainStartDate;
+    }
+
+    public Date getTrainEndDate() {
+        return trainEndDate;
+    }
+
+    public void setTrainEndDate(Date trainEndDate) {
+        this.trainEndDate = trainEndDate;
+    }
+
+    public Integer getPlayTime() {
+        return playTime;
+    }
+
+    public void setPlayTime(Integer playTime) {
+        this.playTime = playTime;
+    }
+
+    public Integer getIsFinish() {
+        return isFinish;
+    }
+
+    public void setIsFinish(Integer isFinish) {
+        this.isFinish = isFinish;
+    }
+}

+ 20 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/TempLittleArtistTrainingCampService.java

@@ -6,6 +6,7 @@ import com.ym.mec.biz.dal.dto.TempLittleArtistTrainingCampDto;
 import com.ym.mec.biz.dal.entity.ImGroup;
 import com.ym.mec.biz.dal.entity.TempLittleArtistTrainingCamp;
 import com.ym.mec.biz.dal.vo.TempCampUserTrainingDetailVo;
+import com.ym.mec.biz.dal.vo.TempCampUserTrainingPlayTimeVo;
 import com.ym.mec.biz.dal.vo.TempCampUserVo;
 import com.ym.mec.biz.dal.vo.TempUserTrainingTimeDetailVo;
 import com.ym.mec.common.page.PageInfo;
@@ -89,6 +90,25 @@ public interface TempLittleArtistTrainingCampService extends IService<TempLittle
      * @param imGroupIds 群组id,多个用逗号隔开
      */
     List<ImGroup> queryCampImGroup(String imGroupIds);
+
+    /**
+     * 查询训练营周期表
+     *
+     * @return result:
+     * <p>user 学员信息
+     * <p>campList 训练营信息
+     */
+    Map<String, Object> queryCampCycle();
+
+    /**
+     * 定时任务-修改训练营状态
+     */
+    void checkCampState();
+
+    /**
+     * 云教练训练是否达标
+     */
+    TempCampUserTrainingPlayTimeVo queryUserTrainingPlayTime();
 }
 
 

+ 6 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/TempLittleArtistTrainingCampUserRelationService.java

@@ -3,6 +3,7 @@ package com.ym.mec.biz.service;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.ym.mec.biz.dal.dao.TempLittleArtistTrainingCampUserRelationDao;
 import com.ym.mec.biz.dal.entity.TempLittleArtistTrainingCampUserRelation;
+import com.ym.mec.biz.dal.vo.TempCampUserQualificationsVo;
 
 /**
  * 训练营与学生关系表(TempLittleArtistTrainingCampUserRelation)表服务接口
@@ -13,5 +14,10 @@ import com.ym.mec.biz.dal.entity.TempLittleArtistTrainingCampUserRelation;
 public interface TempLittleArtistTrainingCampUserRelationService extends IService<TempLittleArtistTrainingCampUserRelation> {
 
     TempLittleArtistTrainingCampUserRelationDao getDao();
+
+    /**
+     * 查询当前登录学生有没有资格参加训练营
+     */
+    TempCampUserQualificationsVo checkCampQualifications();
 }
 

+ 116 - 64
mec-biz/src/main/java/com/ym/mec/biz/service/impl/ImLiveBroadcastRoomServiceImpl.java

@@ -132,6 +132,12 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
             throw new BizException(DateUtil.format(liveStartTime, "yyyy年MM月dd日 HH点mm分") + " 可进入直播间准备");
         }
         if (room.getLiveState() == 2) {
+            //如果直播结束了还是推广状态则将推广修改为取消
+            if (room.getPopularize() == 1) {
+                this.update(Wrappers.<ImLiveBroadcastRoom>lambdaUpdate()
+                        .set(ImLiveBroadcastRoom::getPopularize, 0)
+                        .eq(ImLiveBroadcastRoom::getId, room.getId()));
+            }
             throw new BizException("直播已结束!");
         }
         return room;
@@ -295,6 +301,16 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
      */
     @Override
     public ImLiveBroadcastRoomVo queryPopularizeRoom() {
+        //查询该学生信息-获取分部
+        SysUser user = getSysUser();
+        //查询哪些分部无法推广直播间
+        String popularizeOrgan = sysConfigDao.findConfigValue("live_popularize_organ");
+        if (StringUtils.isNotBlank(popularizeOrgan)) {
+            List<String> organList = WrapperUtil.toList(popularizeOrgan);
+            if (organList.contains(user.getOrganId().toString())) {
+                return null;
+            }
+        }
         Map<String, Object> param = new HashMap<>();
         param.put("tenantId", TenantContextHolder.getTenantId());
         param.put("popularize", 1);
@@ -443,9 +459,11 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
         //总观看人数
         List<ImLiveBroadcastRoomMember> memberList = new ArrayList<>();
         //获取直播间所有人数据写入 im_live_broadcast_room_member
-        RMap<Integer, RoomUserInfoVo> roomTotalUserCache = getTotalUserCache(roomUid);
+        RMap<Integer, String> roomTotalUserCache = getTotalUserCache(roomUid);
         if (roomTotalUserCache.isExists()) {
-            List<RoomUserInfoVo> roomTotalUser = new ArrayList<>(roomTotalUserCache.values());
+            List<RoomUserInfoVo> roomTotalUser = roomTotalUserCache.values().parallelStream()
+                    .map(a -> JSONObject.toJavaObject(JSONObject.parseObject(a), RoomUserInfoVo.class))
+                    .collect(Collectors.toList());
             for (RoomUserInfoVo v : roomTotalUser) {
                 ImLiveBroadcastRoomMember member = new ImLiveBroadcastRoomMember();
                 member.setTenantId(v.getTenantId());
@@ -563,47 +581,32 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
             Integer userId = Integer.valueOf(userid);
 
             //从房间累计用户信息中查询该用户的信息
-            RMap<Integer, RoomUserInfoVo> roomTotalUser = getTotalUserCache(roomUid);
+            RMap<Integer, String> roomTotalUser = getTotalUserCache(roomUid);
             //该房间未查询到用户数据则不处理
             if (!roomTotalUser.isExists() && !roomTotalUser.containsKey(userId)) {
                 return;
             }
             //查询用户数据
-            RoomUserInfoVo userInfo = roomTotalUser.get(userId);
+            RoomUserInfoVo userInfo = JSONObject.toJavaObject(JSONObject.parseObject(roomTotalUser.get(userId)), RoomUserInfoVo.class);
             //如果有动态观看时间则证明主播开播过,需要计算当前用户观看时长
             if (Objects.nonNull(userInfo.getDynamicLookTime())) {
                 userInfo.setTotalViewTime(getLookMinutes(userInfo.getDynamicLookTime(), userInfo.getTotalViewTime()));
                 userInfo.setDynamicLookTime(null);
             }
-            roomTotalUser.fastPut(userId, userInfo);
-
+            roomTotalUser.fastPut(userId, JSONObject.toJSONString(userInfo));
             //查询在线人员列表
-            RMap<Integer, BaseRoomUserVo> onlineUserInfo = getOnlineUserCache(roomUid);
+            RMap<Integer, String> onlineUserInfo = getOnlineUserCache(roomUid);
             if (!onlineUserInfo.isExists()) {
                 return;
             }
-            //发消息给主播 告知现在人数
-            int size = 0;
-            ImRoomMessage message = new ImRoomMessage();
-            message.setIsIncludeSender(1);
-            message.setObjectName(ImRoomMessage.MEMBER_COUNT);
-            message.setToChatroomId(roomUid);
+            //在线人数
+            int count = 0;
             //大于1就发送实际人数,如果是最后一个人离开房间则发送一条0人数消息给主播
             if (onlineUserInfo.size() > 1) {
-                size = onlineUserInfo.size();
-            }
-            HashMap<String, Integer> sendMap = new HashMap<>();
-            sendMap.put("count", size);
-            message.setFromUserId(userId.toString());
-            message.setContent(sendMap);
-            //发送消息
-            try {
-                imFeignService.publishRoomMsg(message);
-                log.info("opsRoom>>>> sendLiveOnlineNum>>>> speakerId  room:{}", JSONObject.toJSONString(message));
-            } catch (Exception e) {
-                log.error("opsRoom>>>> sendLiveOnlineNum>>>>  speakerId error {}", e.getMessage());
-                log.error("opsRoom>>>> sendLiveOnlineNum>>>>  speakerId sendMessage {} :", JSONObject.toJSONString(message));
+                count = onlineUserInfo.size();
             }
+            //向直播间发送当前在线人数消息
+            this.sendOnlineUserCount(roomUid, userId, count);
             //从在线人员列表删除该人员
             onlineUserInfo.fastRemove(userId);
             log.info("opsRoom>>>> looker userInfo: {}", JSONObject.toJSONString(userInfo));
@@ -611,27 +614,60 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
     }
 
     /**
+     * 向直播间发送当前在线人数消息
+     *
+     * @param roomUid    房间uid
+     * @param fromUserId 发送人id
+     * @param count      人数
+     */
+    private void sendOnlineUserCount(String roomUid, Integer fromUserId, Integer count) {
+        //校验传入参数,房间uid和发送人id不能为空
+        if (!WrapperUtil.checkObj(roomUid, fromUserId, count)) {
+            log.info(" sendOnlineUserCount>>>> param is null   roomUid: {}  fromUserId:{}  count:{}", roomUid, fromUserId, count);
+            return;
+        }
+        ImRoomMessage message = new ImRoomMessage();
+        message.setIsIncludeSender(1);
+        message.setObjectName(ImRoomMessage.MEMBER_COUNT);
+        message.setToChatroomId(roomUid);
+        HashMap<String, Integer> sendMap = new HashMap<>();
+        sendMap.put("count", count);
+        message.setFromUserId(fromUserId.toString());
+        message.setContent(sendMap);
+        //发送消息
+        try {
+            imFeignService.publishRoomMsg(message);
+            log.info(" sendOnlineUserCount>>>> message: {}", JSONObject.toJSONString(message));
+        } catch (Exception e) {
+            log.error("sendOnlineUserCount>>>> error {}", e.getMessage());
+            log.error("sendOnlineUserCount>>>> sendMessage {} :", JSONObject.toJSONString(message));
+        }
+    }
+
+    /**
      * 查询userId是不是主讲人
+     *
+     * @return true 是主讲人 false 不是主讲人
      */
     private boolean isSpeaker(ImUserState user, Date now, String userid) {
         RBucket<RoomSpeakerInfo> speakerCache = redissonClient.getBucket(LIVE_SPEAKER_INFO.replace(USER_ID, userid));
-        if (speakerCache.isExists()) {
-            RoomSpeakerInfo speakerInfo = speakerCache.get();
-            //主讲人进入房间
-            if (user.getStatus().equals("0")) {
-                speakerInfo.setJoinRoomTime(now);
-                log.info("opsRoom>>>> join speakerCache {}", JSONObject.toJSONString(speakerInfo));
-                speakerCache.set(speakerInfo);
-                return true;
-            }
-            //主讲人退出房间关闭录像
-            closeLive(speakerInfo);
-            speakerInfo.setExitRoomTime(now);
-            log.info("opsRoom>>>> exit speakerCache {}", JSONObject.toJSONString(speakerInfo));
+        if (!speakerCache.isExists()) {
+            return false;
+        }
+        RoomSpeakerInfo speakerInfo = speakerCache.get();
+        //主讲人进入房间
+        if (user.getStatus().equals("0")) {
+            speakerInfo.setJoinRoomTime(now);
+            log.info("opsRoom>>>> join speakerCache {}", JSONObject.toJSONString(speakerInfo));
             speakerCache.set(speakerInfo);
             return true;
         }
-        return false;
+        //主讲人退出房间关闭录像
+        closeLive(speakerInfo);
+        speakerInfo.setExitRoomTime(now);
+        log.info("opsRoom>>>> exit speakerCache {}", JSONObject.toJSONString(speakerInfo));
+        speakerCache.set(speakerInfo);
+        return true;
     }
 
     /**
@@ -675,16 +711,14 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
         }
         //记录用户当前房间uid
         redissonClient.getBucket(LIVE_USER_ROOM.replace(USER_ID, userId.toString())).set(roomUid, 12L, TimeUnit.HOURS);
-        //在线人员列表
-        RMap<Integer, BaseRoomUserVo> onlineUserInfo = getOnlineUserCache(roomUid);
         //房间累计用户信息-指只要进入到该房间的用户都要记录
-        RMap<Integer, RoomUserInfoVo> roomTotalUser = getTotalUserCache(roomUid);
+        RMap<Integer, String> roomTotalUser = getTotalUserCache(roomUid);
         //判断是否第一次进房间
         RoomUserInfoVo userInfo;
         Date now = new Date();
         if (roomTotalUser.containsKey(userId)) {
             //多次进入更新动态进入时间
-            userInfo = roomTotalUser.get(userId);
+            userInfo = JSONObject.toJavaObject(JSONObject.parseObject(roomTotalUser.get(userId)), RoomUserInfoVo.class);
         } else {
             //第一次进该房间 写入用户首次进入时间
             userInfo = getUserInfo(userId);
@@ -700,9 +734,13 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
                 userInfo.setDynamicLookTime(now);
             }
         }
-        roomTotalUser.fastPut(userId, userInfo);
+        roomTotalUser.fastPut(userId, JSONObject.toJSONString(userInfo));
+        //在线人员列表
+        RMap<Integer, String> onlineUserInfo = getOnlineUserCache(roomUid);
         //进入房间写如在线人员列表
-        onlineUserInfo.fastPut(userId, userInfo);
+        onlineUserInfo.fastPut(userId, JSONObject.toJSONString(userInfo));
+        //向直播间发送当前在线人数消息
+//        this.sendOnlineUserCount(roomUid, userId, count);
         log.info("joinRoom>>>> userInfo: {}", JSONObject.toJSONString(userInfo));
     }
 
@@ -807,15 +845,17 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
         //加锁-避免快速点击开启直播和关闭直后异步执行后直播数据错误
         boolean b = this.runIfLockCanGet(LIVE_LOOK_LOCK.replace(ROOM_UID, roomUid), () -> {
             //查询所有在直播间的用户并计算观看时长
-            RMap<Integer, RoomUserInfoVo> roomTotalUser = getTotalUserCache(roomUid);
+            RMap<Integer, String> roomTotalUser = getTotalUserCache(roomUid);
             if (!roomTotalUser.isExists()) {
                 return;
             }
             //查询在线人员列表
-            RMap<Integer, BaseRoomUserVo> onlineUserInfo = getOnlineUserCache(roomUid);
-            roomTotalUser.forEach((id, userInfo) -> {
+            RMap<Integer, String> onlineUserInfo = getOnlineUserCache(roomUid);
+            boolean onlineUserInfoExists = onlineUserInfo.isExists();
+            roomTotalUser.forEach((id, userInfoStr) -> {
+                RoomUserInfoVo userInfo = JSONObject.toJavaObject(JSONObject.parseObject(userInfoStr), RoomUserInfoVo.class);
                 //获取当前用户是否在房间状态 true在 false不在
-                if (onlineUserInfo.isExists() && onlineUserInfo.containsKey(id)) {
+                if (onlineUserInfoExists && onlineUserInfo.containsKey(id)) {
                     if (type.equals(1)) {
                         //开启直播后对当前在房间的用户写入观看时间
                         userInfo.setDynamicLookTime(new Date());
@@ -825,7 +865,7 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
                     } else {
                         return;
                     }
-                    roomTotalUser.fastPut(id, userInfo);
+                    roomTotalUser.fastPut(id, JSONObject.toJSONString(userInfo));
                 }
             });
         }, 2, 1, TimeUnit.MINUTES);
@@ -1020,11 +1060,11 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
      */
     @Override
     public List<BaseRoomUserVo> queryRoomLimitOnlineUserInfo(String roomUid) {
-        RMap<Integer, BaseRoomUserVo> onlineUserCache = getOnlineUserCache(roomUid);
-        return onlineUserCache.values().stream()
-                .filter(Objects::nonNull)
-                .limit(200)
-                .collect(Collectors.toList());
+        RMap<Integer, String> onlineUserCache = getOnlineUserCache(roomUid);
+        return onlineUserCache.values().parallelStream()
+                        .map(a -> JSONObject.toJavaObject(JSONObject.parseObject(a), BaseRoomUserVo.class))
+                        .limit(200)
+                        .collect(Collectors.toList());
     }
 
     /**
@@ -1034,9 +1074,9 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
      */
     @Override
     public List<BaseRoomUserVo> queryRoomOnlineUserInfo(String roomUid) {
-        RMap<Integer, BaseRoomUserVo> onlineUserInfo = getOnlineUserCache(roomUid);
-        return onlineUserInfo.values().stream()
-                .filter(Objects::nonNull)
+        RMap<Integer, String> onlineUserInfo = getOnlineUserCache(roomUid);
+        return onlineUserInfo.values().parallelStream()
+                .map(a -> JSONObject.toJavaObject(JSONObject.parseObject(a), BaseRoomUserVo.class))
                 .collect(Collectors.toList());
     }
 
@@ -1046,17 +1086,29 @@ public class ImLiveBroadcastRoomServiceImpl extends ServiceImpl<ImLiveBroadcastR
      * @param roomUid 直播间uid
      */
     private List<RoomUserInfoVo> queryTotalRoomUserInfo(String roomUid) {
-        RMap<Integer, RoomUserInfoVo> roomTotalUser = getTotalUserCache(roomUid);
-        return roomTotalUser.values().stream()
-                .filter(Objects::nonNull)
+        RMap<Integer, String> roomTotalUser = getTotalUserCache(roomUid);
+        return roomTotalUser.values().parallelStream()
+                .map(a -> JSONObject.toJavaObject(JSONObject.parseObject(a), RoomUserInfoVo.class))
                 .collect(Collectors.toList());
     }
 
-    private RMap<Integer, BaseRoomUserVo> getOnlineUserCache(String roomUid) {
+    /**
+     * 获取直播间在线用户信息缓存
+     *
+     * @param roomUid 直播间uid
+     * @return RMap key:userId value:BaseRoomUserVo -> jsonToString
+     */
+    private RMap<Integer, String> getOnlineUserCache(String roomUid) {
         return redissonClient.getMap(LIVE_ROOM_ONLINE_USER_LIST.replace(ROOM_UID, roomUid));
     }
 
-    private RMap<Integer, RoomUserInfoVo> getTotalUserCache(String roomUid) {
+    /**
+     * 获取直播间所有用户信息缓存
+     *
+     * @param roomUid 直播间uid
+     * @return RMap key:userId value:RoomUserInfoVo -> jsonToString
+     */
+    private RMap<Integer, String> getTotalUserCache(String roomUid) {
         return redissonClient.getMap(LIVE_ROOM_TOTAL_USER_LIST.replace(ROOM_UID, roomUid));
     }
 

+ 124 - 5
mec-biz/src/main/java/com/ym/mec/biz/service/impl/TempLittleArtistTrainingCampServiceImpl.java

@@ -12,6 +12,7 @@ import com.ym.mec.biz.dal.entity.ImGroup;
 import com.ym.mec.biz.dal.entity.TempLittleArtistTrainingCamp;
 import com.ym.mec.biz.dal.entity.TempLittleArtistTrainingCampUserRelation;
 import com.ym.mec.biz.dal.vo.TempCampUserTrainingDetailVo;
+import com.ym.mec.biz.dal.vo.TempCampUserTrainingPlayTimeVo;
 import com.ym.mec.biz.dal.vo.TempCampUserVo;
 import com.ym.mec.biz.dal.vo.TempUserTrainingTimeDetailVo;
 import com.ym.mec.biz.service.TempLittleArtistTrainingCampService;
@@ -27,10 +28,12 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.util.*;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 /**
@@ -56,20 +59,31 @@ public class TempLittleArtistTrainingCampServiceImpl extends ServiceImpl<TempLit
     /**
      * 新建训练营
      */
+    @Transactional(rollbackFor = Exception.class)
     @Override
     public void add(TempLittleArtistTrainingCampDto dto) {
         SysUser user = getUser();
         TempLittleArtistTrainingCamp entity = new TempLittleArtistTrainingCamp();
         BeanUtils.copyProperties(dto, entity);
-        entity.setState(TempLittleArtistTrainingCamp.READY);
+        Date now = new Date();
+        //训练时间必需大于报名时间
+        if (dto.getTrainStartDate().getTime() > dto.getApplyStartDate().getTime()) {
+            throw new BizException("训练时间必需大于报名时间");
+        }
+        entity.setState(TempLittleArtistTrainingCamp.NOT_START);
+        //当前时间大于等于报名开始时间  当前时间小于等于报名结束时间
+        if (now.getTime() >= dto.getApplyStartDate().getTime() && now.getTime() <= dto.getApplyEndDate().getTime()) {
+            entity.setState(TempLittleArtistTrainingCamp.APPLY);
+        }
         entity.setCreateBy(user.getId());
-        entity.setCreateTime(new Date());
+        entity.setCreateTime(now);
         this.save(entity);
     }
 
     /**
      * 修改训练营
      */
+    @Transactional(rollbackFor = Exception.class)
     @Override
     public void update(TempLittleArtistTrainingCampDto dto) {
         SysUser user = getUser();
@@ -90,12 +104,13 @@ public class TempLittleArtistTrainingCampServiceImpl extends ServiceImpl<TempLit
     /**
      * 删除训练营
      */
+    @Transactional(rollbackFor = Exception.class)
     @Override
     public void delete(Integer id) {
         TempLittleArtistTrainingCamp entity = Optional.ofNullable(id)
                 .map(this::getById)
                 .orElseThrow(() -> new BizException("训练营不存在"));
-        entity.setDelFlag(0);
+        entity.setDelFlag(1);
         this.updateById(entity);
     }
 
@@ -226,12 +241,116 @@ public class TempLittleArtistTrainingCampServiceImpl extends ServiceImpl<TempLit
         return baseMapper.queryCampImGroup(imGroupIds);
     }
 
+    /**
+     * 查询训练营周期表
+     *
+     * @return result:
+     * <p>user 学员信息
+     * <p>campList 训练营信息
+     */
+    @Override
+    public Map<String, Object> queryCampCycle() {
+        SysUser user = getUser();
+        //查询未删除的训练营
+        List<TempLittleArtistTrainingCamp> campList = this.list(Wrappers.<TempLittleArtistTrainingCamp>lambdaQuery()
+                .eq(TempLittleArtistTrainingCamp::getDelFlag, 0));
+        //查询该学员是否购买过该训练营
+        TempLittleArtistTrainingCampUserRelation userRelation = tempLittleArtistTrainingCampUserRelationService.getOne(Wrappers.<TempLittleArtistTrainingCampUserRelation>lambdaQuery()
+                .eq(TempLittleArtistTrainingCampUserRelation::getUserId, user.getId()));
+        Map<String, Object> result = new HashMap<>();
+        result.put("user", userRelation);
+        if (CollectionUtils.isNotEmpty(campList)) {
+            campList.sort(Comparator.comparing(TempLittleArtistTrainingCamp::getApplyStartDate));
+        }
+        result.put("campList", campList);
+        return result;
+    }
+
+    /**
+     * 定时任务-修改训练营状态
+     */
+    @Override
+    public void checkCampState() {
+        //查询未结束 并 未删除的训练营
+        List<TempLittleArtistTrainingCamp> campList = this.list(Wrappers.<TempLittleArtistTrainingCamp>lambdaQuery()
+                .eq(TempLittleArtistTrainingCamp::getDelFlag, 0)
+                .ne(TempLittleArtistTrainingCamp::getState, TempLittleArtistTrainingCamp.END));
+        if (CollectionUtils.isEmpty(campList)) {
+            return;
+        }
+        Date now = DateUtil.stringToDate(LocalDate.now() + " 00:00:00");
+        //将训练营数据根据状态分组,未开始 NOT_START,报名中 APPLY,筹备中 READY,进行中 ING,已结束 END
+        Map<String, List<TempLittleArtistTrainingCamp>> stateMap = WrapperUtil.groupList(campList, TempLittleArtistTrainingCamp::getState);
+        //未开始 NOT_START 修改为 报名中 APPLY
+        opsState(now, stateMap, TempLittleArtistTrainingCamp.NOT_START, TempLittleArtistTrainingCamp::getApplyStartDate, TempLittleArtistTrainingCamp.APPLY);
+        //报名中 APPLY 修改为 筹备中 READY
+        opsState(now, stateMap, TempLittleArtistTrainingCamp.APPLY, TempLittleArtistTrainingCamp::getApplyEndDate, TempLittleArtistTrainingCamp.READY);
+        //筹备中 READY 修改为 进行中 ING
+        opsState(now, stateMap, TempLittleArtistTrainingCamp.READY, TempLittleArtistTrainingCamp::getTrainStartDate, TempLittleArtistTrainingCamp.ING);
+        //进行中 ING 修改为 已结束 END
+        opsState(now, stateMap, TempLittleArtistTrainingCamp.ING, TempLittleArtistTrainingCamp::getTrainEndDate, TempLittleArtistTrainingCamp.END);
+        //修改数据
+        campList.forEach(this::updateById);
+    }
+
+    /**
+     * 修改训练营状态
+     *
+     * @param now       当前时间
+     * @param stateMap  训练营状态分组
+     * @param oldState  原状态
+     * @param dateField 时间字段
+     * @param newState  新状态
+     */
+    private void opsState(Date now, Map<String, List<TempLittleArtistTrainingCamp>> stateMap, String oldState,
+                          Function<TempLittleArtistTrainingCamp, Date> dateField, String newState) {
+        List<TempLittleArtistTrainingCamp> list = stateMap.get(oldState);
+        if (CollectionUtils.isNotEmpty(list)) {
+            list.forEach(camp -> {
+                if ( now.getTime() >=  dateField.apply(camp).getTime()) {
+                    camp.setState(newState);
+                }
+            });
+        }
+    }
+
+    /**
+     * 云教练训练是否达标
+     */
+    @Override
+    public TempCampUserTrainingPlayTimeVo queryUserTrainingPlayTime() {
+        SysUser user = getUser();
+        //查询训练营人员关系
+        TempLittleArtistTrainingCampUserRelation campUser = tempLittleArtistTrainingCampUserRelationService.getOne(Wrappers.<TempLittleArtistTrainingCampUserRelation>lambdaQuery()
+                .eq(TempLittleArtistTrainingCampUserRelation::getUserId, user.getId()));
+        if (Objects.isNull(campUser)) {
+            return null;
+        }
+        //查询训练营
+        TempLittleArtistTrainingCamp camp = this.getOne(Wrappers.<TempLittleArtistTrainingCamp>lambdaQuery()
+                .eq(TempLittleArtistTrainingCamp::getId, campUser.getActivityId())
+                .eq(TempLittleArtistTrainingCamp::getDelFlag, 0));
+        if (Objects.isNull(camp)) {
+            return null;
+        }
+
+        TempCampUserTrainingPlayTimeVo vo = new TempCampUserTrainingPlayTimeVo();
+        Map<String, Object> param = new HashMap<>();
+        param.put("userId", user.getId());
+        param.put("startTime", DateUtil.dateToString(camp.getTrainStartDate()) + " 00:00:00");
+        param.put("endTime", DateUtil.dateToString(camp.getTrainEndDate()) + " 23:59:59");
+        Integer playTime = baseMapper.queryUserTrainingPlayTime(param);
+        vo.setPlayTime(playTime);
+        vo.setTrainStartDate(camp.getTrainStartDate());
+        vo.setTrainEndDate(camp.getTrainEndDate());
+        vo.setIsFinish(playTime >= 1200 ? 0 : 1);
+        return vo;
+    }
+
     private SysUser getUser() {
-        //修改机构基础信息
         return Optional.ofNullable(sysUserFeignService.queryUserInfo())
                 .orElseThrow(() -> new BizException("用户信息获取失败,请刷新页面或者重新登录!"));
     }
 
-
 }
 

+ 63 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/TempLittleArtistTrainingCampUserRelationServiceImpl.java

@@ -1,13 +1,25 @@
 package com.ym.mec.biz.service.impl;
 
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ym.mec.auth.api.client.SysUserFeignService;
+import com.ym.mec.auth.api.entity.SysUser;
 import com.ym.mec.biz.dal.dao.TempLittleArtistTrainingCampUserRelationDao;
 import com.ym.mec.biz.dal.entity.TempLittleArtistTrainingCampUserRelation;
+import com.ym.mec.biz.dal.vo.TempCampUserQualificationsVo;
+import com.ym.mec.biz.service.SysConfigService;
 import com.ym.mec.biz.service.TempLittleArtistTrainingCampUserRelationService;
+import com.ym.mec.common.exception.BizException;
+import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.Consumer;
+
 /**
  * 训练营与学生关系表(TempLittleArtistTrainingCampUserRelation)表服务实现类
  *
@@ -18,11 +30,62 @@ import org.springframework.stereotype.Service;
 public class TempLittleArtistTrainingCampUserRelationServiceImpl extends ServiceImpl<TempLittleArtistTrainingCampUserRelationDao, TempLittleArtistTrainingCampUserRelation> implements TempLittleArtistTrainingCampUserRelationService {
 
     private final static Logger log = LoggerFactory.getLogger(TempLittleArtistTrainingCampUserRelationServiceImpl.class);
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private SysConfigService sysConfigService;
 
     @Override
     public TempLittleArtistTrainingCampUserRelationDao getDao() {
         return this.baseMapper;
     }
 
+    /**
+     * 查询当前登录学生有没有资格参加训练营
+     */
+    @Override
+    public TempCampUserQualificationsVo checkCampQualifications() {
+        TempCampUserQualificationsVo vo = new TempCampUserQualificationsVo();
+        vo.setQualifications(1);//训练营资格 有资格0  无资格1
+        SysUser user = getUser();
+        if (!user.getUserType().contains("STUDENT")) {
+            return vo;
+        }
+        TempLittleArtistTrainingCampUserRelation relation = this.getOne(Wrappers.<TempLittleArtistTrainingCampUserRelation>lambdaQuery()
+                .eq(TempLittleArtistTrainingCampUserRelation::getUserId, user.getId()));
+        //该学员未购买
+        if (Objects.isNull(relation)) {
+            return vo;
+        }
+        //已报名
+        if (relation.getState().equals(TempLittleArtistTrainingCampUserRelation.APPLY)) {
+            return vo;
+        }
+
+        //小小训训练营文案及标题-默认
+        vo.setContent("小小艺术家好习惯养成训练营邀请函");
+        vo.setCampTitle("恭喜你获得小小艺术家好习惯养成训练营体验资格,请及时通过训练营登记界面选择您要参加的训练营周期,不要浪费资格哦!");
+        //取配置中的文案及标题
+        this.setValue("temp_little_artist_training_camp_content", vo::setContent);
+        this.setValue("temp_little_artist_training_camp_title", vo::setCampTitle);
+
+        vo.setCampId(relation.getActivityId());
+        vo.setUserName(user.getUsername());
+        vo.setQualifications(0);//训练营资格 有资格0  无资格1
+        return vo;
+    }
+
+    private void setValue(String key, Consumer<String> consumer) {
+        Optional.of(key)
+                .map(sysConfigService::findByParamName)
+                .filter(s -> StringUtils.isNotBlank(s.getParanValue()))
+                .ifPresent(sysConfig -> consumer.accept(sysConfig.getParanValue()));
+    }
+
+    private SysUser getUser() {
+        return Optional.ofNullable(sysUserFeignService.queryUserInfo())
+                .orElseThrow(() -> new BizException("用户信息获取失败,请刷新页面或者重新登录!"));
+    }
+
 }
 

+ 8 - 0
mec-biz/src/main/resources/config/mybatis/TempLittleArtistTrainingCampMapper.xml

@@ -144,4 +144,12 @@
         where find_in_set(id_, #{imGroupIds})
     </select>
 
+    <select id="queryUserTrainingPlayTime"  resultType="int" parameterType="java.util.Map">
+        SELECT ifnull(sum(`play_time_`), 0) as playTime
+        FROM `sys_music_compare_record`
+        WHERE user_id_ = #{param.userId}
+          and create_time_ &gt;= #{param.startTime}
+          AND create_time_ &lt;= #{param.endTime}
+    </select>
+
 </mapper>

+ 28 - 3
mec-student/src/main/java/com/ym/mec/student/controller/TempLittleArtistTrainingCampController.java

@@ -3,10 +3,9 @@ package com.ym.mec.student.controller;
 import com.ym.mec.biz.dal.dto.TempLittleArtistTrainingCampDto;
 import com.ym.mec.biz.dal.entity.ImGroup;
 import com.ym.mec.biz.dal.entity.TempLittleArtistTrainingCamp;
-import com.ym.mec.biz.dal.vo.TempCampUserTrainingDetailVo;
-import com.ym.mec.biz.dal.vo.TempCampUserVo;
-import com.ym.mec.biz.dal.vo.TempUserTrainingTimeDetailVo;
+import com.ym.mec.biz.dal.vo.*;
 import com.ym.mec.biz.service.TempLittleArtistTrainingCampService;
+import com.ym.mec.biz.service.TempLittleArtistTrainingCampUserRelationService;
 import com.ym.mec.common.controller.BaseController;
 import com.ym.mec.common.entity.HttpResponseResult;
 import com.ym.mec.common.page.PageInfo;
@@ -33,6 +32,8 @@ public class TempLittleArtistTrainingCampController extends BaseController {
      */
     @Resource
     private TempLittleArtistTrainingCampService tempLittleArtistTrainingCampService;
+    @Resource
+    private TempLittleArtistTrainingCampUserRelationService tempLittleArtistTrainingCampUserRelationService;
 
     @ApiOperation("添加训练营")
     @PostMapping(value = "/add")
@@ -110,5 +111,29 @@ public class TempLittleArtistTrainingCampController extends BaseController {
         return succeed(tempLittleArtistTrainingCampService.queryCampImGroup(imGroupIds));
     }
 
+    /**
+     * 查询训练营周期表
+     *
+     * @return result:
+     * <p>user 学员信息
+     * <p>campList 训练营信息
+     */
+    @ApiOperation(value="查询训练营周期表", notes="user 学员信息,campList 训练营信息")
+    @GetMapping(value = "/queryCampCycle")
+    public HttpResponseResult<Map<String, Object>> queryCampCycle(){
+        return succeed(tempLittleArtistTrainingCampService.queryCampCycle());
+    }
+
+    @ApiOperation(value="云教练训练是否达标数据查询")
+    @GetMapping(value = "/queryUserTrainingPlayTime")
+    public HttpResponseResult<TempCampUserTrainingPlayTimeVo> queryUserTrainingPlayTime(){
+        return succeed(tempLittleArtistTrainingCampService.queryUserTrainingPlayTime());
+    }
+
+    @ApiOperation(value="查询当前登录学生有没有资格参加训练营")
+    @GetMapping(value = "/checkCampQualifications")
+    public HttpResponseResult<TempCampUserQualificationsVo> checkCampQualifications(){
+        return succeed(tempLittleArtistTrainingCampUserRelationService.checkCampQualifications());
+    }
 }
 

+ 31 - 5
mec-web/src/main/java/com/ym/mec/web/controller/TempLittleArtistTrainingCampController.java

@@ -3,10 +3,9 @@ package com.ym.mec.web.controller;
 import com.ym.mec.biz.dal.dto.TempLittleArtistTrainingCampDto;
 import com.ym.mec.biz.dal.entity.ImGroup;
 import com.ym.mec.biz.dal.entity.TempLittleArtistTrainingCamp;
-import com.ym.mec.biz.dal.vo.TempCampUserTrainingDetailVo;
-import com.ym.mec.biz.dal.vo.TempCampUserVo;
-import com.ym.mec.biz.dal.vo.TempUserTrainingTimeDetailVo;
+import com.ym.mec.biz.dal.vo.*;
 import com.ym.mec.biz.service.TempLittleArtistTrainingCampService;
+import com.ym.mec.biz.service.TempLittleArtistTrainingCampUserRelationService;
 import com.ym.mec.common.controller.BaseController;
 import com.ym.mec.common.entity.HttpResponseResult;
 import com.ym.mec.common.page.PageInfo;
@@ -33,6 +32,8 @@ public class TempLittleArtistTrainingCampController extends BaseController {
      */
     @Resource
     private TempLittleArtistTrainingCampService tempLittleArtistTrainingCampService;
+    @Resource
+    private TempLittleArtistTrainingCampUserRelationService tempLittleArtistTrainingCampUserRelationService;
 
     @ApiOperation("添加训练营")
     @PostMapping(value = "/add")
@@ -100,15 +101,40 @@ public class TempLittleArtistTrainingCampController extends BaseController {
     })
     @ApiOperation("分页查询-训练营详情")
     @PostMapping(value = "/queryUserTrainingDetail")
-    public HttpResponseResult<PageInfo<TempCampUserTrainingDetailVo>> queryUserTrainingDetail(@RequestBody Map<String, Object> param){
+    public HttpResponseResult<PageInfo<TempCampUserTrainingDetailVo>> queryUserTrainingDetail(@RequestBody Map<String, Object> param) {
         return succeed(tempLittleArtistTrainingCampService.queryUserTrainingDetail(param));
     }
 
     @ApiOperation("根据群组Id查询群组信息")
     @GetMapping(value = "/queryCampImGroup")
-    public HttpResponseResult<List<ImGroup>> queryCampImGroup(@ApiParam(value = "群组id,多个用逗号隔开", required = true) String imGroupIds){
+    public HttpResponseResult<List<ImGroup>> queryCampImGroup(@ApiParam(value = "群组id,多个用逗号隔开", required = true) String imGroupIds) {
         return succeed(tempLittleArtistTrainingCampService.queryCampImGroup(imGroupIds));
     }
 
+    /**
+     * 查询训练营周期表
+     *
+     * @return result:
+     * <p>user 学员信息
+     * <p>campList 训练营信息
+     */
+    @ApiOperation(value = "查询训练营周期表", notes = "user 学员信息,campList 训练营信息")
+    @GetMapping(value = "/queryCampCycle")
+    public HttpResponseResult<Map<String, Object>> queryCampCycle() {
+        return succeed(tempLittleArtistTrainingCampService.queryCampCycle());
+    }
+
+    @ApiOperation(value = "云教练训练是否达标数据查询")
+    @GetMapping(value = "/queryUserTrainingPlayTime")
+    public HttpResponseResult<TempCampUserTrainingPlayTimeVo> queryUserTrainingPlayTime() {
+        return succeed(tempLittleArtistTrainingCampService.queryUserTrainingPlayTime());
+    }
+
+    @ApiOperation(value = "查询当前登录学生有没有资格参加训练营")
+    @GetMapping(value = "/checkCampQualifications")
+    public HttpResponseResult<TempCampUserQualificationsVo> checkCampQualifications() {
+        return succeed(tempLittleArtistTrainingCampUserRelationService.checkCampQualifications());
+    }
+
 }