Browse Source

Merge branch 'refs/heads/master' into 企微聊天

ct 3 weeks ago
parent
commit
16ef992302
22 changed files with 400 additions and 135 deletions
  1. 3 0
      fs-admin/src/main/java/com/fs/course/controller/FsUserCourseController.java
  2. 2 0
      fs-common/src/main/java/com/fs/common/constant/LiveKeysConstant.java
  3. 8 8
      fs-live-app/src/main/java/com/fs/live/websocket/handle/LiveChatHandler.java
  4. 4 8
      fs-live-app/src/main/java/com/fs/live/websocket/service/WebSocketServer.java
  5. 49 0
      fs-service/src/main/java/com/fs/course/domain/FsProjectAddressConfig.java
  6. 14 0
      fs-service/src/main/java/com/fs/course/mapper/FsProjectAddressConfigMapper.java
  7. 12 0
      fs-service/src/main/java/com/fs/course/service/IFsProjectAddressConfigService.java
  8. 23 0
      fs-service/src/main/java/com/fs/course/service/impl/FsProjectAddressConfigServiceImpl.java
  9. 24 10
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java
  10. 6 1
      fs-service/src/main/java/com/fs/course/vo/FsCourseWatchLogStatisticsListVO.java
  11. 1 1
      fs-service/src/main/java/com/fs/course/vo/FsUserCoursePeriodVO.java
  12. 18 0
      fs-service/src/main/java/com/fs/live/mapper/LiveMapper.java
  13. 6 11
      fs-service/src/main/java/com/fs/live/mapper/LiveWatchUserMapper.java
  14. 5 1
      fs-service/src/main/java/com/fs/live/service/ILiveWatchUserService.java
  15. 141 70
      fs-service/src/main/java/com/fs/live/service/impl/LiveWatchUserServiceImpl.java
  16. 0 3
      fs-service/src/main/java/com/fs/sop/mapper/QwSopTempRulesMapper.java
  17. 1 1
      fs-service/src/main/java/com/fs/sop/service/impl/QwSopTempRulesServiceImpl.java
  18. 12 17
      fs-service/src/main/java/com/fs/sop/service/impl/QwSopTempServiceImpl.java
  19. 8 0
      fs-service/src/main/resources/mapper/course/FsProjectAddressConfigMapper.xml
  20. 36 3
      fs-service/src/main/resources/mapper/live/LiveWatchUserMapper.xml
  21. 1 1
      fs-service/src/main/resources/mapper/sop/QwSopTempMapper.xml
  22. 26 0
      fs-user-app/src/main/java/com/fs/app/controller/CommonController.java

+ 3 - 0
fs-admin/src/main/java/com/fs/course/controller/FsUserCourseController.java

@@ -3,6 +3,7 @@ package com.fs.course.controller;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.json.JSONUtil;
 import com.fs.common.annotation.Log;
+import com.fs.common.annotation.RepeatSubmit;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
@@ -337,7 +338,9 @@ public class FsUserCourseController extends BaseController {
     /**
      * 同步课程模板
      */
+    @PreAuthorize("@ss.hasPermi('course:userCourseVideo:sync')")
     @Log(title = "同步课程模板", businessType = BusinessType.UPDATE)
+    @RepeatSubmit
     @PostMapping("/syncTemplate/{courseId}")
     public AjaxResult syncTemplate(@PathVariable Long courseId) {
         sopTempService.syncTemplate(courseId);

+ 2 - 0
fs-common/src/main/java/com/fs/common/constant/LiveKeysConstant.java

@@ -27,6 +27,8 @@ public class LiveKeysConstant {
     public static final String LIVE_HOME_PAGE_CONFIG_DRAW = "live:config:%s:draw:%s"; //抽奖记录
     public static final String TOP_MSG = "topMsg"; //抽奖记录
 
+    public static final String LIVE_FLAG_CACHE = "live:flag:%s"; //直播间直播/回放状态缓存
+    public static final Integer LIVE_FLAG_CACHE_EXPIRE = 60; //直播间状态缓存过期时间(秒)
 
 
 }

+ 8 - 8
fs-live-app/src/main/java/com/fs/live/websocket/handle/LiveChatHandler.java

@@ -71,7 +71,7 @@ public class LiveChatHandler extends SimpleChannelInboundHandler<TextWebSocketFr
 
             if (userType == 0) {
                 // 加入房间
-                liveWatchUserService.joinWithoutLocation(liveId, userId);
+                LiveWatchUser liveWatchUser = liveWatchUserService.joinWithoutLocation(liveId, userId);
                 room.put(userId, ctx.channel());
 
                 FsUser fsUser = fsUserService.selectFsUserByUserId(userId);
@@ -80,7 +80,6 @@ public class LiveChatHandler extends SimpleChannelInboundHandler<TextWebSocketFr
                     return;
                 }
 
-                LiveWatchUserVO liveWatchUserVO = liveWatchUserService.selectWatchUserByLiveIdAndUserId(liveId, userId);
 
                 SendMsgVo sendMsgVo = new SendMsgVo();
                 sendMsgVo.setLiveId(liveId);
@@ -88,7 +87,7 @@ public class LiveChatHandler extends SimpleChannelInboundHandler<TextWebSocketFr
                 sendMsgVo.setUserType(userType);
                 sendMsgVo.setCmd("entry");
                 sendMsgVo.setMsg("用户进入");
-                sendMsgVo.setData(JSONObject.toJSONString(liveWatchUserVO));
+                sendMsgVo.setData(JSONObject.toJSONString(liveWatchUser));
                 sendMsgVo.setNickName(fsUser.getNickname());
                 sendMsgVo.setAvatar(fsUser.getAvatar());
 
@@ -176,8 +175,9 @@ public class LiveChatHandler extends SimpleChannelInboundHandler<TextWebSocketFr
                     liveMsg.setCreateTime(new Date());
 
                     if (userType == 0) {
-                        LiveWatchUser liveWatchUser = liveWatchUserService.getByLiveIdAndUserId(msg.getLiveId(), msg.getUserId());
-                        if(liveWatchUser.getMsgStatus() == 1){
+                        Map<String, Integer> liveFlagWithCache = liveWatchUserService.getLiveFlagWithCache(liveId);
+                        LiveWatchUser liveWatchUser = liveWatchUserService.selectLiveWatchUserByFlag(msg.getLiveId(), msg.getUserId(), liveFlagWithCache.get("liveFlag"),  liveFlagWithCache.get("replayFlag"));
+                        if(liveWatchUser != null && liveWatchUser.getMsgStatus() == 1){
                             sendMessage(channelHandlerContext.channel(), JSONObject.toJSONString(R.error("你以被禁言")));
                             return;
                         }
@@ -219,14 +219,14 @@ public class LiveChatHandler extends SimpleChannelInboundHandler<TextWebSocketFr
 
         if (userType == 0) {
             FsUser fsUser = fsUserService.selectFsUserByUserId(userId);
-            liveWatchUserService.close(liveId, userId);
+            LiveWatchUser close = liveWatchUserService.close(liveId, userId);
             room.remove(userId);
 
             if (room.isEmpty()) {
                 rooms.remove(liveId);
             }
 
-            LiveWatchUserVO liveWatchUserVO = liveWatchUserService.selectWatchUserByLiveIdAndUserId(liveId, userId);
+
 
             SendMsgVo sendMsgVo = new SendMsgVo();
             sendMsgVo.setLiveId(liveId);
@@ -234,7 +234,7 @@ public class LiveChatHandler extends SimpleChannelInboundHandler<TextWebSocketFr
             sendMsgVo.setUserType(userType);
             sendMsgVo.setCmd("out");
             sendMsgVo.setMsg("用户离开");
-            sendMsgVo.setData(JSONObject.toJSONString(liveWatchUserVO));
+            sendMsgVo.setData(JSONObject.toJSONString(close));
             sendMsgVo.setNickName(fsUser.getNickname());
             sendMsgVo.setAvatar(fsUser.getAvatar());
 

+ 4 - 8
fs-live-app/src/main/java/com/fs/live/websocket/service/WebSocketServer.java

@@ -134,8 +134,7 @@ public class WebSocketServer {
             if (isFirstViewer) {
                 redisCache.incr(UNIQUE_VIEWERS_KEY + liveId, 1);
             }
-            LiveWatchUser liveWatchUser = liveWatchUserService.getByLiveIdAndUserId(liveId, userId);
-            liveWatchUserVO.setMsgStatus(liveWatchUser.getMsgStatus());
+            liveWatchUserVO.setMsgStatus(liveWatchUserVO.getMsgStatus());
             SendMsgVo sendMsgVo = new SendMsgVo();
             sendMsgVo.setLiveId(liveId);
             sendMsgVo.setUserId(userId);
@@ -199,10 +198,7 @@ public class WebSocketServer {
             if (Objects.isNull(fsUser)) {
                 throw new BaseException("用户信息错误");
             }
-
-            LiveWatchUser liveWatchUserVO = liveWatchUserService.close(liveId, userId);
             room.remove(userId);
-
             if (room.isEmpty()) {
                 rooms.remove(liveId);
             }
@@ -213,7 +209,7 @@ public class WebSocketServer {
             // 从在线用户Set中移除用户ID
             String onlineUsersSetKey = ONLINE_USERS_SET_KEY + liveId;
             redisCache.redisTemplate.opsForSet().remove(onlineUsersSetKey, String.valueOf(userId));
-
+            LiveWatchUser liveWatchUserVO = liveWatchUserService.close(liveId, userId);
             SendMsgVo sendMsgVo = new SendMsgVo();
             sendMsgVo.setLiveId(liveId);
             sendMsgVo.setUserId(userId);
@@ -261,8 +257,8 @@ public class WebSocketServer {
                     liveMsg.setCreateTime(new Date());
 
                     if (userType == 0) {
-                        LiveWatchUser liveWatchUser = liveWatchUserService.getByLiveIdAndUserId(msg.getLiveId(), msg.getUserId());
-                        if(liveWatchUser.getMsgStatus() == 1){
+                        List<LiveWatchUser> liveWatchUser = liveWatchUserService.getByLiveIdAndUserId(msg.getLiveId(), msg.getUserId());
+                        if(!liveWatchUser.isEmpty() && liveWatchUser.get(0).getMsgStatus() == 1){
                             sendMessage(session, JSONObject.toJSONString(R.error("你已被禁言")));
                             return;
                         }

+ 49 - 0
fs-service/src/main/java/com/fs/course/domain/FsProjectAddressConfig.java

@@ -0,0 +1,49 @@
+package com.fs.course.domain;
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+public class FsProjectAddressConfig {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 项目名称
+     */
+    private String name;
+
+    /**
+     * 唯一编码
+     */
+    private String code;
+
+    /**
+     * api接口地址
+     */
+    private String addressUrl;
+
+    /**
+     * 存储桶地址
+     */
+    private String bucketPath;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 修改时间
+     */
+    private LocalDateTime updateTime;
+
+    /**
+     * 发送类型 1个微 2企微
+     */
+    private Integer sendType;
+}

+ 14 - 0
fs-service/src/main/java/com/fs/course/mapper/FsProjectAddressConfigMapper.java

@@ -0,0 +1,14 @@
+package com.fs.course.mapper;
+
+import com.fs.course.domain.FsProjectAddressConfig;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+public interface FsProjectAddressConfigMapper {
+
+    /**
+     * 根据code查询url
+     */
+    @Select("select * from fs_project_address_config where code = #{code}")
+    FsProjectAddressConfig selectDomainByCode(@Param("code") String code);
+}

+ 12 - 0
fs-service/src/main/java/com/fs/course/service/IFsProjectAddressConfigService.java

@@ -0,0 +1,12 @@
+package com.fs.course.service;
+
+
+import com.fs.course.domain.FsProjectAddressConfig;
+
+public interface IFsProjectAddressConfigService {
+
+    /**
+     * 根据code查询url
+     */
+    FsProjectAddressConfig selectDomainByCode(String code);
+}

+ 23 - 0
fs-service/src/main/java/com/fs/course/service/impl/FsProjectAddressConfigServiceImpl.java

@@ -0,0 +1,23 @@
+package com.fs.course.service.impl;
+
+import com.fs.course.domain.FsProjectAddressConfig;
+import com.fs.course.mapper.FsProjectAddressConfigMapper;
+import com.fs.course.service.IFsProjectAddressConfigService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+@Service
+public class FsProjectAddressConfigServiceImpl implements IFsProjectAddressConfigService {
+
+    @Resource
+    private FsProjectAddressConfigMapper fsProjectAddressConfigMapper;
+
+    /**
+     * 根据code查询url
+     */
+    @Override
+    public FsProjectAddressConfig selectDomainByCode(String code) {
+        return fsProjectAddressConfigMapper.selectDomainByCode(code);
+    }
+}

+ 24 - 10
fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java

@@ -514,7 +514,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         FsUser fsUser = fsUserMapper.selectFsUserByUserId(param.getUserId());
         //用户不存在唤起重新授权
         if (fsUser==null){
-            return R.error(504,"未授权");
+            return R.error(401,"未授权");
         }
 
         if (fsUser.getStatus()==0){
@@ -557,10 +557,10 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
 
 
-        //服务号授权的,缺mpOpenId的重新登录 linkType = 4为app看课 不需要mp
-        if (param.getLinkType() != 4 && config.getMiniAppAuthType()==2 && StringUtil.strIsNullOrEmpty(fsUser.getMpOpenId())){
-            return R.error(401,"授权后可继续!");
-        }
+//        //服务号授权的,缺mpOpenId的重新登录 linkType = 4为app看课 不需要mp
+//        if (param.getLinkType() != 4 && config.getMiniAppAuthType()==2 && StringUtil.strIsNullOrEmpty(fsUser.getMpOpenId())){
+//            return R.error(401,"授权后可继续!");
+//        }
 
         boolean oneCompanyCourse = config.isOneCompanyCourse();
         if(oneCompanyCourse && fsUser.getQwExtId() != null){
@@ -698,10 +698,13 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
     private R handleRoom(FsUserCourseVideoAddKfUParam param,FsUser user) {
         //查询客户列表
         List<QwExternalContact> contacts = qwExternalContactMapper.selectQwExternalContactListVOByfsUserId(user.getUserId());
-        log.info("查出来的企微客户数量:"+contacts.size());
-        if (!contacts.isEmpty()){
+        List<QwExternalContact> nonNullContacts = contacts.stream()
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList());
+        log.info("查出来的企微客户数量:"+nonNullContacts.size());
+        if (!nonNullContacts.isEmpty()){
             //找出对应销售匹配的客户
-            QwExternalContact matchedContact = contacts.stream()
+            QwExternalContact matchedContact = nonNullContacts.stream()
                     .filter(contact -> contact.getQwUserId().equals(Long.parseLong(param.getQwUserId())))
                     .findFirst()
                     .orElse(null);
@@ -717,9 +720,20 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
                     createWatchLog(param);
                 }
                 return R.error(567,"群聊通用链接").put("qwExternalId", matchedContact.getId());
+            }else {
+                QwExternalContact contact = nonNullContacts.get(0);
+                log.info("匹配到的第一个企微用户:"+contact.getUserId());
+                log.info("企微id:"+contact.getId());
+                log.info("用户:"+param.getVideoId());
+                log.info("企微用户:"+param.getQwUserId());
+                param.setQwExternalId(contact.getId());
+                FsCourseWatchLog log = courseWatchLogMapper.getWatchCourseVideoByExt(contact.getId(), param.getVideoId(),param.getQwUserId());
+                if (log==null){
+                    createWatchLog(param);
+                }
+                return R.error(567,"群聊通用链接").put("qwExternalId", contact.getId());
             }
         }
-
         String msg = "<div style=\"color: red;margin-bottom: 15px;font-weight: bold;\">本课程为群会员独享<br>请长按二维码</div>\n" +
                 "\t\t\t\t\t<div style=\"color: #999;font-size: 14px;font-weight: bold;\">添加伴学助手免费领取会员权限</div>";
 
@@ -971,7 +985,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
             qwAddContactWayParam.setType(1);
             qwAddContactWayParam.setScene(2);
             qwAddContactWayParam.setUser(users);
-            qwAddContactWayParam.setSkip_verify(true);
+            qwAddContactWayParam.setSkip_verify(false);
             QwAddContactWayResult qwAddContactWayResult = qwApiService.addContactWay(qwAddContactWayParam, qwUser.getCorpId());
             if (qwAddContactWayResult.getErrcode() == 0) {
                 qwUser.setContactWay(qwAddContactWayResult.getQr_code());

+ 6 - 1
fs-service/src/main/java/com/fs/course/vo/FsCourseWatchLogStatisticsListVO.java

@@ -39,7 +39,7 @@ public class FsCourseWatchLogStatisticsListVO {
     @Excel(name = "员工名称")
     private String userName;
 
-    @Excel(name = "创建时间")
+    @Excel(name = "创建时间" ,dateFormat = "yyyy-MM-dd")
     @JsonFormat(pattern = "yyyy-MM-dd")
     private Date createTime;
 
@@ -48,18 +48,23 @@ public class FsCourseWatchLogStatisticsListVO {
     private String companyUserName;
 
     /** 发课数 */
+    @Excel(name = "发课数")
     private String  sendNumber;
 
     /** 已注册用户待看课数 */
+    @Excel(name = "已注册用户待看课数")
     private String  isUserWaitNumber;
 
     /** 未注册用户待看课数 */
+    @Excel(name = "未注册用户待看课数")
     private String  noUserWaitNumber;
 
     /** 上线率 */
+    @Excel(name = "上线率")
     private String  onLineRate;
 
     /** 完课率 */
+    @Excel(name = "完课率")
     private String  finishedRate;
 
     /** 消耗红包金额 */

+ 1 - 1
fs-service/src/main/java/com/fs/course/vo/FsUserCoursePeriodVO.java

@@ -89,5 +89,5 @@ public class FsUserCoursePeriodVO implements Serializable {
     @Excel(name = "营期线", width = 31, dateFormat = "yyyy-MM-dd")
     private Date periodLine;
     /** 是否需要单独注册会员,1-是,0-否(用于个微销售分享看课) */
-    private Integer isNeedRegisterMember;
+    private String isNeedRegisterMember;
 }

+ 18 - 0
fs-service/src/main/java/com/fs/live/mapper/LiveMapper.java

@@ -152,4 +152,22 @@ public interface LiveMapper
 
     @Select("select * from live where is_audit = 1 and is_del = 0 and status in (1,2,4) and live_type in (2,3) order by create_time desc")
     List<Live> liveListAll();
+
+    /**
+     * 查询直播间是直播还是回放状态
+     * 判断标准:当前直播间开始时间 + 视频类型为1的视频时长,如果大于当前时间,返回1,否则返回0
+     * @param liveId 直播间ID
+     * @return 1表示直播中,0表示回放中
+     */
+    @Select("SELECT CASE " +
+            "WHEN l.start_time IS NOT NULL AND " +
+            "     (l.start_time + INTERVAL COALESCE(SUM(CASE WHEN lv.video_type = 1 THEN lv.duration ELSE 0 END), 0) SECOND) > NOW() " +
+            "THEN 1 " +
+            "ELSE 0 " +
+            "END AS liveFlag " +
+            "FROM live l " +
+            "LEFT JOIN live_video lv ON l.live_id = lv.live_id AND lv.video_type = 1 " +
+            "WHERE l.live_id = #{liveId} " +
+            "GROUP BY l.live_id, l.start_time")
+    Integer selectLiveFlagByLiveId(@Param("liveId") Long liveId);
 }

+ 6 - 11
fs-service/src/main/java/com/fs/live/mapper/LiveWatchUserMapper.java

@@ -87,30 +87,25 @@ public interface LiveWatchUserMapper {
 
     /**
      * 根据直播间ID和用户ID查询观看用户信息
-     * @param liveId    直播间ID
-     * @param userId    观看用户ID
+     * @param params    参数Map,包含liveId、userId、liveFlag、replayFlag
      * @return LiveWatchUserVO
      */
-    LiveWatchUserVO selectWatchUserByLiveIdAndUserId(@Param("liveId") Long liveId, @Param("userId") Long userId);
+    LiveWatchUserVO selectWatchUserByLiveIdAndUserId(@Param("params") Map<String, Object> params);
 
 
 
     List<LiveWatchUserVO> selectOnlineUserList(LiveWatchUser param);
 
-    List<LiveWatchUser> checkOnlineNoRewardUser(@Param("liveId") Long liveId,@Param("now") Date now);
+    List<LiveWatchUser> checkOnlineNoRewardUser(@Param("params") Map<String, Object> params);
 
-    @Select("select a.*,fu.nickname as nick_name from (select lws.* from live_watch_user lws where live_id=#{liveId} and online = 0 and " +
-            "user_id in (select user_id from live_lottery_registration where live_id = #{liveId} and lottery_id=#{lotteryId} and registration_id >= " +
-            "(SELECT FLOOR(RAND() * (SELECT MAX(registration_id) FROM live_lottery_registration)))) ) a left join fs_user fu on fu.user_id = a.user_id")
-    List<LiveWatchUser> selectLiveWatchAndRegisterUser(@Param("liveId") Long liveId,@Param("lotteryId") Long lotteryId);
+    List<LiveWatchUser> selectLiveWatchAndRegisterUser(@Param("params") Map<String, Object> params);
 
-    @Select("select * from live_watch_user where live_id = #{liveId} and user_id = #{userId}")
-    LiveWatchUser selectUserByLiveIdAndUserId(@Param("liveId") long liveId,@Param("userId")  long userId);
+    List<LiveWatchUser> selectUserByLiveIdAndUserId(@Param("params") Map<String, Object> params);
 
     /**
      * 根据唯一索引查询:live_id, user_id, live_flag, replay_flag
      */
-    LiveWatchUser selectByUniqueIndex(@Param("liveId") Long liveId, @Param("userId") Long userId, 
+    LiveWatchUser selectByUniqueIndex(@Param("liveId") Long liveId, @Param("userId") Long userId,
                                       @Param("liveFlag") Integer liveFlag, @Param("replayFlag") Integer replayFlag);
 
     /**

+ 5 - 1
fs-service/src/main/java/com/fs/live/service/ILiveWatchUserService.java

@@ -73,7 +73,9 @@ public interface ILiveWatchUserService {
      */
     int deleteLiveWatchUserById(Long id);
 
-    LiveWatchUser getByLiveIdAndUserId(long liveId, long userId);
+    List<LiveWatchUser> getByLiveIdAndUserId(long liveId, long userId);
+
+    Map<String, Integer> getLiveFlagWithCache(Long liveId);
 
     LiveWatchUser join(long liveId, long userId, String location);
     LiveWatchUser joinWithoutLocation(long liveId, long userId);
@@ -121,4 +123,6 @@ public interface ILiveWatchUserService {
     void updateGlobalVisible(long liveId, int i);
 
     void updateSingleVisible(long liveId, Integer status,long userId);
+
+    LiveWatchUser selectLiveWatchUserByFlag(Long liveId, Long userId, Integer liveFlag, Integer replayFlag);
 }

+ 141 - 70
fs-service/src/main/java/com/fs/live/service/impl/LiveWatchUserServiceImpl.java

@@ -95,6 +95,12 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
         } else if ("silenced".equals(liveWatchUser.getTabName())) {
             liveWatchUser.setMsgStatus(1);
         }
+        // 先查缓存,获取liveFlag和replayFlag
+        if (liveWatchUser != null && liveWatchUser.getLiveId() != null) {
+            Map<String, Integer> flagMap = getLiveFlagWithCache(liveWatchUser.getLiveId());
+            liveWatchUser.setLiveFlag(flagMap.get("liveFlag"));
+            liveWatchUser.setReplayFlag(flagMap.get("replayFlag"));
+        }
         return baseMapper.selectLiveWatchUserList(liveWatchUser);
     }
 
@@ -149,8 +155,48 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
     }
 
     @Override
-    public LiveWatchUser getByLiveIdAndUserId(long liveId, long userId) {
-        return baseMapper.selectUserByLiveIdAndUserId(liveId, userId);
+    public List<LiveWatchUser> getByLiveIdAndUserId(long liveId, long userId) {
+        // 先查缓存,获取liveFlag和replayFlag
+        Map<String, Integer> flagMap = getLiveFlagWithCache(liveId);
+        Map<String, Object> params = new HashMap<>();
+        params.put("liveId", liveId);
+        params.put("userId", userId);
+        params.put("liveFlag", flagMap.get("liveFlag"));
+        params.put("replayFlag", flagMap.get("replayFlag"));
+        return baseMapper.selectUserByLiveIdAndUserId(params);
+    }
+
+    /**
+     * 获取直播间的直播/回放状态(带缓存)
+     * @param liveId 直播间ID
+     * @return Map包含liveFlag和replayFlag
+     */
+    @Override
+    public Map<String, Integer> getLiveFlagWithCache(Long liveId) {
+        String cacheKey = String.format(LiveKeysConstant.LIVE_FLAG_CACHE, liveId);
+
+        // 先查缓存
+        Map<String, Integer> cached = redisCache.getCacheObject(cacheKey);
+        if (cached != null && cached.containsKey("liveFlag") && cached.containsKey("replayFlag")) {
+            return cached;
+        }
+
+        // 缓存不存在,查询数据库
+        Integer liveFlag = liveMapper.selectLiveFlagByLiveId(liveId);
+        if (liveFlag == null) {
+            liveFlag = 0;
+        }
+        Integer replayFlag = 1 - liveFlag; // 反数
+
+        // 构建结果
+        Map<String, Integer> result = new HashMap<>();
+        result.put("liveFlag", liveFlag);
+        result.put("replayFlag", replayFlag);
+
+        // 缓存结果,过期时间1分钟
+        redisCache.setCacheObject(cacheKey, result, LiveKeysConstant.LIVE_FLAG_CACHE_EXPIRE, TimeUnit.SECONDS);
+
+        return result;
     }
 
     @Override
@@ -164,37 +210,10 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
             throw new RuntimeException("直播间不存在");
         }
 
-        // 查询直播间录播视频时长(video_type IN (1, 2))
-        List<LiveVideo> videos = liveVideoMapper.selectByLiveIdAndType(liveId,1);
-        long totalDuration = 0L;
-        if (videos != null && !videos.isEmpty()) {
-            totalDuration = videos.stream()
-                    .filter(v -> v.getVideoType() != null && (v.getVideoType() == 1 || v.getVideoType() == 2))
-                    .filter(v -> v.getDuration() != null)
-                    .mapToLong(LiveVideo::getDuration)
-                    .sum();
-        }
-
-        // 判断是直播还是回放:开播时间 + 视频时长
-        Integer liveFlag = 0;
-        Integer replayFlag = 0;
-
-        if (live.getStartTime() != null) {
-            // 将 LocalDateTime 转换为 Date
-            Date startTime = java.sql.Timestamp.valueOf(live.getStartTime());
-            // 计算结束时间:开播时间 + 视频时长(秒)
-            Date endTime = new Date(startTime.getTime() + totalDuration * 1000);
-
-            if (now.before(endTime)) {
-                // 当前时间 < 开播时间 + 视频时长,说明是直播
-                liveFlag = 1;
-                replayFlag = 0;
-            } else {
-                // 当前时间 >= 开播时间 + 视频时长,说明是回放
-                liveFlag = 0;
-                replayFlag = 1;
-            }
-        }
+        // 获取直播/回放状态(带缓存)
+        Map<String, Integer> flagMap = getLiveFlagWithCache(liveId);
+        Integer liveFlag = flagMap.get("liveFlag");
+        Integer replayFlag = flagMap.get("replayFlag");
 
         // 使用唯一索引查询:live_id, user_id, live_flag, replay_flag
         LiveWatchUser liveWatchUser = baseMapper.selectByUniqueIndex(liveId, userId, liveFlag, replayFlag);
@@ -232,62 +251,65 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
 
     @Override
     public LiveWatchUser joinWithoutLocation(long liveId, long userId) {
-        LiveWatchUser liveWatchUser = getByLiveIdAndUserId(liveId, userId);
         FsUserScrm fsUserVO = fsUserService.selectFsUserByUserId(userId);
         Date now = DateUtils.getNowDate();
 
         // 查询直播间信息
         Live live = liveMapper.selectLiveByLiveId(liveId);
-
-        // 判断用户进入时间:如果进入时间大于直播结束时间,说明是回放
-        boolean isReplay = false;
-        if (live != null && live.getFinishTime() != null) {
-            Date finishTime = java.sql.Timestamp.valueOf(live.getFinishTime());
-            isReplay = now.after(finishTime);
+        if (live == null) {
+            throw new RuntimeException("直播间不存在");
         }
 
-        if(liveWatchUser != null) {
-            liveWatchUser.setUpdateTime(now);
-            liveWatchUser.setOnline(0);
+        // 获取直播/回放状态(带缓存)
+        Map<String, Integer> flagMap = getLiveFlagWithCache(liveId);
+        Integer liveFlag = flagMap.get("liveFlag");
+        Integer replayFlag = flagMap.get("replayFlag");
 
-            // 更新进入标记
-            if (isReplay) {
-                liveWatchUser.setReplayFlag(1);
-            } else {
-                liveWatchUser.setLiveFlag(1);
-            }
+        // 使用唯一索引查询:live_id, user_id, live_flag, replay_flag
+        LiveWatchUser liveWatchUser = baseMapper.selectByUniqueIndex(liveId, userId, liveFlag, replayFlag);
 
+        if (liveWatchUser != null) {
+            // 存在则更新
+            liveWatchUser.setUpdateTime(now);
+            liveWatchUser.setOnline(0);
             baseMapper.updateLiveWatchUser(liveWatchUser);
-        }else{
+        } else {
+            // 不存在则插入
             liveWatchUser = new LiveWatchUser();
             liveWatchUser.setLiveId(liveId);
             liveWatchUser.setUserId(userId);
             liveWatchUser.setAvatar(fsUserVO.getAvatar());
             liveWatchUser.setMsgStatus(0);
             liveWatchUser.setOnline(0);
-
-            // 设置进入标记
-            if (isReplay) {
-                liveWatchUser.setReplayFlag(1);
-                liveWatchUser.setLiveFlag(0);
-            } else {
-                liveWatchUser.setLiveFlag(1);
-                liveWatchUser.setReplayFlag(0);
-            }
-
+            liveWatchUser.setLiveFlag(liveFlag);
+            liveWatchUser.setReplayFlag(replayFlag);
             liveWatchUser.setCreateTime(now);
             liveWatchUser.setUpdateTime(now);
             baseMapper.insertLiveWatchUser(liveWatchUser);
         }
+
         liveWatchUser.setAvatar(fsUserVO.getAvatar());
         liveWatchUser.setNickName(fsUserVO.getNickname());
-        String hashKey  = String.format(LiveKeysConstant.LIVE_WATCH_USERS, liveId);
+        String hashKey = String.format(LiveKeysConstant.LIVE_WATCH_USERS, liveId);
         redisCache.hashPut(hashKey, String.valueOf(userId), JSON.toJSONString(liveWatchUser));
         return liveWatchUser;
     }
     @Override
     public LiveWatchUser close(long liveId, long userId) {
-        LiveWatchUser liveWatchUser = getByLiveIdAndUserId(liveId, userId);
+
+        // 查询直播间信息
+        Live live = liveMapper.selectLiveByLiveId(liveId);
+        if (live == null) {
+            throw new RuntimeException("直播间不存在");
+        }
+
+        // 获取直播/回放状态(带缓存)
+        Map<String, Integer> flagMap = getLiveFlagWithCache(liveId);
+        Integer liveFlag = flagMap.get("liveFlag");
+        Integer replayFlag = flagMap.get("replayFlag");
+
+        // 使用唯一索引查询:live_id, user_id, live_flag, replay_flag
+        LiveWatchUser liveWatchUser = baseMapper.selectByUniqueIndex(liveId, userId, liveFlag, replayFlag);
         // 设置在线时长
         try {
             Long onlineSeconds = liveWatchUser.getOnlineSeconds();
@@ -311,6 +333,13 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
      */
     @Override
     public List<LiveWatchUserVO> selectWatchUserList(Map<String, Object> params) {
+        // 先查缓存,获取liveFlag和replayFlag
+        if (params != null && params.containsKey("liveId")) {
+            Long liveId = Long.valueOf(params.get("liveId").toString());
+            Map<String, Integer> flagMap = getLiveFlagWithCache(liveId);
+            params.put("liveFlag", flagMap.get("liveFlag"));
+            params.put("replayFlag", flagMap.get("replayFlag"));
+        }
         return baseMapper.selectWatchUserListByLiveId(params);
     }
 
@@ -322,11 +351,14 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
      */
     @Override
     public int changeUserState(Long liveId, Long userId) {
-        LiveWatchUser liveWatchUser = getByLiveIdAndUserId(liveId, userId);
-        if (Objects.nonNull(liveWatchUser)) {
-            liveWatchUser.setMsgStatus(Math.abs(1 - liveWatchUser.getMsgStatus()));
-            liveWatchUser.setUpdateTime(DateUtils.getNowDate());
-            return baseMapper.updateLiveWatchUser(liveWatchUser);
+        List<LiveWatchUser> liveWatchUser = getByLiveIdAndUserId(liveId, userId);
+        if (!liveWatchUser.isEmpty()) {
+            for (LiveWatchUser watchUser : liveWatchUser) {
+                watchUser.setMsgStatus(Math.abs(1 - watchUser.getMsgStatus()));
+                watchUser.setUpdateTime(DateUtils.getNowDate());
+                baseMapper.updateLiveWatchUser(watchUser);
+            }
+            return 1;
         }
         return 0;
     }
@@ -339,17 +371,37 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
      */
     @Override
     public LiveWatchUserVO selectWatchUserByLiveIdAndUserId(Long liveId, Long userId) {
-        return baseMapper.selectWatchUserByLiveIdAndUserId(liveId, userId);
+        // 先查缓存,获取liveFlag和replayFlag
+        Map<String, Integer> flagMap = getLiveFlagWithCache(liveId);
+        Map<String, Object> params = new HashMap<>();
+        params.put("liveId", liveId);
+        params.put("userId", userId);
+        params.put("liveFlag", flagMap.get("liveFlag"));
+        params.put("replayFlag", flagMap.get("replayFlag"));
+        return baseMapper.selectWatchUserByLiveIdAndUserId(params);
     }
 
     @Override
     public List<LiveWatchUserVO> selectOnlineUserList(LiveWatchUser param) {
+        // 先查缓存,获取liveFlag和replayFlag
+        if (param != null && param.getLiveId() != null) {
+            Map<String, Integer> flagMap = getLiveFlagWithCache(param.getLiveId());
+            param.setLiveFlag(flagMap.get("liveFlag"));
+            param.setReplayFlag(flagMap.get("replayFlag"));
+        }
         return baseMapper.selectOnlineUserList(param);
     }
 
     @Override
     public List<LiveWatchUser> checkOnlineNoRewardUser(Long liveId, Date now) {
-        return baseMapper.checkOnlineNoRewardUser(liveId,now);
+        // 先查缓存,获取liveFlag和replayFlag
+        Map<String, Integer> flagMap = getLiveFlagWithCache(liveId);
+        Map<String, Object> params = new HashMap<>();
+        params.put("liveId", liveId);
+        params.put("now", now);
+        params.put("liveFlag", flagMap.get("liveFlag"));
+        params.put("replayFlag", flagMap.get("replayFlag"));
+        return baseMapper.checkOnlineNoRewardUser(params);
     }
 
     @Override
@@ -362,7 +414,14 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
 
     @Override
     public List<LiveWatchUser> selectLiveWatchAndRegisterUser(Long liveId, Long lotteryId) {
-        return baseMapper.selectLiveWatchAndRegisterUser(liveId, lotteryId);
+        // 先查缓存,获取liveFlag和replayFlag
+        Map<String, Integer> flagMap = getLiveFlagWithCache(liveId);
+        Map<String, Object> params = new HashMap<>();
+        params.put("liveId", liveId);
+        params.put("lotteryId", lotteryId);
+        params.put("liveFlag", flagMap.get("liveFlag"));
+        params.put("replayFlag", flagMap.get("replayFlag"));
+        return baseMapper.selectLiveWatchAndRegisterUser(params);
     }
 
     @Override
@@ -419,6 +478,13 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
 
     @Override
     public List<LiveWatchUserVO> dashBoardWatchUserList(Map<String, Object> param) {
+        // 先查缓存,获取liveFlag和replayFlag
+        if (param != null && param.containsKey("liveId")) {
+            Long liveId = Long.valueOf(param.get("liveId").toString());
+            Map<String, Integer> flagMap = getLiveFlagWithCache(liveId);
+            param.put("liveFlag", flagMap.get("liveFlag"));
+            param.put("replayFlag", flagMap.get("replayFlag"));
+        }
         if (param != null && param.containsKey("all") && "1".equals(param.get("all"))) {
             return baseMapper.selectWatchUserListAllByLiveId(param);
         } else {
@@ -439,4 +505,9 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
         baseMapper.updateSingleVisible(liveId, status,userId);
     }
 
+    @Override
+    public LiveWatchUser selectLiveWatchUserByFlag(Long liveId, Long userId, Integer liveFlag, Integer replayFlag) {
+        return baseMapper.selectByUniqueIndex(liveId, userId, liveFlag, replayFlag);
+    }
+
 }

+ 0 - 3
fs-service/src/main/java/com/fs/sop/mapper/QwSopTempRulesMapper.java

@@ -80,7 +80,4 @@ public interface QwSopTempRulesMapper extends BaseMapper<QwSopTempRules> {
     List<QwSopTempRules> listByTempIdAndNameAndDayNum(@Param("id") String id, @Param("dayNum") Integer dayNum);
 
     void deleteByIdList(@Param("ids") List<String> ids);
-
-    @Select("select * from qw_sop_temp_rules where course_id = #{courseId} ")
-    List<QwSopTempRules> selectQwSopTempRulesListByCourseId(@Param("courseId")Long courseId);
 }

+ 1 - 1
fs-service/src/main/java/com/fs/sop/service/impl/QwSopTempRulesServiceImpl.java

@@ -244,7 +244,7 @@ public class QwSopTempRulesServiceImpl extends ServiceImpl<QwSopTempRulesMapper,
     @Override
     @DataSource(DataSourceType.SOP)
     public List<QwSopTempRules> listByCourseId(Long courseId) {
-        return qwSopTempRulesMapper.selectQwSopTempRulesListByCourseId(courseId);
+        return list(new QueryWrapper<QwSopTempRules>().eq("course_id", courseId));
     }
 
     @Override

+ 12 - 17
fs-service/src/main/java/com/fs/sop/service/impl/QwSopTempServiceImpl.java

@@ -638,14 +638,24 @@ public class QwSopTempServiceImpl implements IQwSopTempService {
         if (CollectionUtils.isEmpty(tempIds)) {
             return;
         }
+        // 只弄课程模板的
         List<QwSopTemp> tempList = qwSopTempMapper.selectListByIds(tempIds);
         tempList = tempList.stream().filter(f -> Objects.equals(f.getStatus(), "1")).collect(Collectors.toList());
         if (CollectionUtils.isEmpty(tempList)) {
             return;
         }
-        List<QwSopTempContent> contentList = qwSopTempContentService.listByTempIds(tempIds);
 
-        CountDownLatch latch = new CountDownLatch(tempList.size());
+        // 获取这些规则关联的模板ID集合
+        Set<String> sopTempIds = tempList.stream()
+                .map(QwSopTemp::getId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toSet());
+
+        List<QwSopTempContent> contentList = qwSopTempContentService.listByTempIds(sopTempIds);
+
+        qwSopTempDayService.removeByTempIds(tempIds);
+        qwSopTempRulesService.removeByTempIds(tempIds);
+        qwSopTempContentService.removeByTempIds(tempIds);
         // 对每个模板执行同步操作
         for (QwSopTemp temp : tempList) {
             // 构造timeList timeDesc time
@@ -676,23 +686,8 @@ public class QwSopTempServiceImpl implements IQwSopTempService {
             // 插入课程id
             temp.setCourseId(courseId);
             temp.setOpenOfficial("1");
-            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-            temp.setCreateTime(sdf.format(new Date()));
-            temp.setId(UUID.randomUUID().toString());
-            qwSopTempMapper.insertQwSopTemp(temp);
             // 重新生成该模板的规则和内容
             threadPoolTaskExecutor.execute(() -> createSopTempRules(temp));
-            latch.countDown();
-        }
-
-        try {
-            latch.await();
-            qwSopTempMapper.deleteQwSopTempByIds(tempIds.toArray(new String[0]));
-            qwSopTempDayService.removeByTempIds(tempIds);
-            qwSopTempRulesService.removeByTempIds(tempIds);
-            qwSopTempContentService.removeByTempIds(tempIds);
-        } catch (InterruptedException e) {
-            log.error("等待线程执行完成时被中断", e);
         }
     }
 

+ 8 - 0
fs-service/src/main/resources/mapper/course/FsProjectAddressConfigMapper.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fs.course.mapper.FsProjectAddressConfigMapper">
+
+
+</mapper>

+ 36 - 3
fs-service/src/main/resources/mapper/live/LiveWatchUserMapper.xml

@@ -32,6 +32,8 @@
         <where>
             <if test="liveId != null "> and live_id = #{liveId}</if>
             <if test="userId != null "> and user_id = #{userId}</if>
+            <if test="liveFlag != null "> and live_flag = #{liveFlag}</if>
+            <if test="replayFlag != null "> and replay_flag = #{replayFlag}</if>
             <if test="msgStatus != null "> and msg_status = #{msgStatus}</if>
             <if test="online != null "> and online = #{online}</if>
             <if test="onlineSeconds != null "> and online_seconds = #{onlineSeconds}</if>
@@ -56,6 +58,8 @@
         from live_watch_user lwu
         left join fs_user fu on lwu.user_id = fu.user_id
         where lwu.live_id = #{params.liveId} and fu.status = 1
+        <if test="params.liveFlag != null "> and lwu.live_flag = #{params.liveFlag}</if>
+        <if test="params.replayFlag != null "> and lwu.replay_flag = #{params.replayFlag}</if>
         <if test="params.msgStatus != null "> and msg_status = #{params.msgStatus}</if>
         <if test="params.online != null "> and online = #{params.online}</if>
         <if test="params.userName != null and params.userName != ''"> and fu.nick_name like concat('%',#{params.userName},'%')</if>
@@ -75,6 +79,8 @@
         from live_watch_user lwu
         left join fs_user fu on lwu.user_id = fu.user_id
         where lwu.live_id = #{params.liveId} and fu.status = 1
+        <if test="params.liveFlag != null "> and lwu.live_flag = #{params.liveFlag}</if>
+        <if test="params.replayFlag != null "> and lwu.replay_flag = #{params.replayFlag}</if>
         <if test="params.userName != null and params.userName != ''"> and fu.nick_name like concat('%',#{params.userName},'%')</if>
         order by lwu.create_time desc
 
@@ -97,7 +103,9 @@
             lwu.single_visible  singleVisible
         from live_watch_user lwu
                  left join fs_user fu on lwu.user_id = fu.user_id
-        where lwu.live_id = #{liveId} and lwu.user_id = #{userId}
+        where lwu.live_id = #{params.liveId} and lwu.user_id = #{params.userId}
+        <if test="params.liveFlag != null "> and lwu.live_flag = #{params.liveFlag}</if>
+        <if test="params.replayFlag != null "> and lwu.replay_flag = #{params.replayFlag}</if>
     </select>
 
     <select id="selectOnlineUserList" parameterType="LiveWatchUser" resultType="com.fs.live.vo.LiveWatchUserVO">
@@ -109,6 +117,8 @@
         left join fs_user fu on lwu.user_id = fu.user_id
         <where>
             <if test="liveId != null "> and live_id = #{liveId}</if>
+            <if test="liveFlag != null "> and live_flag = #{liveFlag}</if>
+            <if test="replayFlag != null "> and replay_flag = #{replayFlag}</if>
             <if test="online != null "> and online = #{online}</if>
         </where>
     </select>
@@ -187,18 +197,41 @@
     <select id="checkOnlineNoRewardUser" resultType="com.fs.live.domain.LiveWatchUser">
         SELECT lwu.*
         FROM live_watch_user lwu
-        WHERE lwu.live_id = #{liveId}
+        WHERE lwu.live_id = #{params.liveId}
           AND lwu.online = 0
+          <if test="params.liveFlag != null "> and lwu.live_flag = #{params.liveFlag}</if>
+          <if test="params.replayFlag != null "> and lwu.replay_flag = #{params.replayFlag}</if>
           AND NOT EXISTS (
             SELECT 1
             FROM live_reward_record lrr
             WHERE lrr.user_id = lwu.user_id
               AND lrr.live_id = lwu.live_id
               and lrr.source_type = 3
-              AND DATE(lrr.create_time) = DATE(#{now})
+              AND DATE(lrr.create_time) = DATE(#{params.now})
         )
     </select>
 
+    <select id="selectLiveWatchAndRegisterUser" resultType="com.fs.live.domain.LiveWatchUser">
+        select a.*,fu.nickname as nick_name from (
+            select lws.* from live_watch_user lws 
+            where live_id=#{params.liveId} and online = 0
+            <if test="params.liveFlag != null "> and live_flag = #{params.liveFlag}</if>
+            <if test="params.replayFlag != null "> and replay_flag = #{params.replayFlag}</if>
+            and user_id in (
+                select user_id from live_lottery_registration 
+                where live_id = #{params.liveId} and lottery_id=#{params.lotteryId} 
+                and registration_id >= (SELECT FLOOR(RAND() * (SELECT MAX(registration_id) FROM live_lottery_registration)))
+            )
+        ) a left join fs_user fu on fu.user_id = a.user_id
+    </select>
+
+    <select id="selectUserByLiveIdAndUserId" resultType="com.fs.live.domain.LiveWatchUser">
+        select * from live_watch_user 
+        where live_id = #{params.liveId} and user_id = #{params.userId}
+        <if test="params.liveFlag != null "> and live_flag = #{params.liveFlag}</if>
+        <if test="params.replayFlag != null "> and replay_flag = #{params.replayFlag}</if>
+    </select>
+
     <!-- 根据唯一索引查询:live_id, user_id, live_flag, replay_flag -->
     <select id="selectByUniqueIndex" resultMap="LiveWatchUserResult">
         <include refid="selectLiveWatchUserVo"/>

+ 1 - 1
fs-service/src/main/resources/mapper/sop/QwSopTempMapper.xml

@@ -68,7 +68,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         select * from qw_sop_temp_temp
     </select>
     <select id="selectListByIds" resultType="com.fs.sop.domain.QwSopTemp">
-        select * from qw_sop_temp  where id in
+        select * from qw_sop_temp  where send_type = 11 and id in
         <foreach item="id" collection="ids" open="(" separator="," close=")">
             #{id}
         </foreach>

+ 26 - 0
fs-user-app/src/main/java/com/fs/app/controller/CommonController.java

@@ -33,6 +33,8 @@ import com.fs.company.domain.CompanyMoneyLogs;
 import com.fs.company.service.ICompanyMoneyLogsService;
 import com.fs.core.utils.OrderCodeUtils;
 import com.fs.course.config.CourseConfig;
+import com.fs.course.domain.FsProjectAddressConfig;
+import com.fs.course.service.IFsProjectAddressConfigService;
 import com.fs.course.service.IHuaweiVodService;
 import com.fs.event.TemplateBean;
 import com.fs.event.TemplateEvent;
@@ -78,6 +80,7 @@ import org.springframework.web.multipart.MultipartFile;
 import java.io.*;
 import java.math.BigDecimal;
 import java.util.*;
+import java.util.concurrent.TimeUnit;
 
 import static com.fs.common.utils.SecurityUtils.getUserId;
 
@@ -134,6 +137,8 @@ public class CommonController {
 
 	@Autowired
 	private IQwAppContactWayService qwAppContactWayService;
+	@Autowired
+	private IFsProjectAddressConfigService projectAddressConfigService;
 
 //	@Autowired
 //	private RocketMQTemplate rocketMQTemplate;
@@ -636,4 +641,25 @@ public class CommonController {
 		return ResponseResult.ok(config.getIsOpenIM());
 	}
 
+	@ApiOperation("获取项目对应api请求域名地址")
+	@GetMapping("/getDomain")
+	public R getDomain(@RequestParam String projectCode) {
+		String redisKey = "projectCode:" + projectCode;
+		FsProjectAddressConfig config = redisCache.getCacheObject(redisKey);
+		if (Objects.isNull(config)) {
+			config = projectAddressConfigService.selectDomainByCode(projectCode);
+			redisCache.setCacheObject(redisKey, config, 5, TimeUnit.MINUTES);
+		}
+		String addressUrl = "";
+		String imgPath = "";
+		Integer sendType = null;
+
+		if (Objects.nonNull(config)) {
+			addressUrl = config.getAddressUrl();
+			imgPath = config.getBucketPath();
+			sendType = config.getSendType();
+		}
+
+		return R.ok().put("addressUrl", addressUrl).put("imgpath", imgPath).put("sendType", sendType);
+	}
 }