Просмотр исходного кода

定时删除 immsg 和 im发课前校验

xgb 1 неделя назад
Родитель
Сommit
5d0cd8429e

+ 13 - 3
fs-admin/src/main/java/com/fs/his/task/Task.java

@@ -64,6 +64,7 @@ import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayQueryRequest;
 import com.fs.huifuPay.service.HuiFuService;
 import com.fs.im.dto.*;
 import com.fs.im.service.IFsImMsgSendDetailService;
+import com.fs.im.service.IFsImMsgSendLogService;
 import com.fs.im.service.IImService;
 import com.fs.im.service.OpenIMService;
 import com.fs.qw.domain.QwCompany;
@@ -238,6 +239,9 @@ public class Task {
     @Autowired
     private IFsImMsgSendDetailService fsImMsgSendDetailService;
 
+    @Autowired
+    private IFsImMsgSendLogService fsImMsgSendLogService;
+
 
     /**
      * 定时任务,处理ai禁止回复之后的消息
@@ -1877,7 +1881,7 @@ public class Task {
     }
 
     /**
-     * @Description: 定时删除数据
+     * @Description: 定时删除IM发课数据(detail + log)
      * @Param:
      * @Return:
      * @Author xgb
@@ -1885,9 +1889,15 @@ public class Task {
      */
     public void deleteDataIM(Integer days){
         if(days==null){
-            days=3;
+            days=30;
         }
-        fsImMsgSendDetailService.cleanOldData( days);
+        logger.info("定时清理IM数据:删除{}天前数据", days);
+
+        int detailCount = fsImMsgSendDetailService.cleanOldData(days);
+        logger.info("删除fs_im_msg_send_detail数据:{}条", detailCount);
+
+        int logCount = fsImMsgSendLogService.cleanOldData(days);
+        logger.info("删除fs_im_msg_send_log数据:{}条", logCount);
     }
 
 

+ 6 - 2
fs-service/src/main/java/com/fs/course/mapper/FsUserCourseMapper.java

@@ -317,10 +317,14 @@ public interface FsUserCourseMapper
     Integer selectTodayCourseWatchLogCountByUserIdAndProjectId(@Param("userId") Long userId, @Param("projectId") Long projectId);
 
     /**
-     * 批量查询当天哪些用户在此项目已有不同视频的看课记录,返回已有的 userId 集合
+     * 批量查询指定日期哪些用户在此项目已有不同视频的看课记录
      * @param videoId 当前视频ID,重复发同一节课不拦截
+     * @param startDate 发课日期 00:00:00
+     * @param endDate 发课日期 23:59:59
      */
-    List<Long> selectUserIdsWithTodayCourseWatchLog(@Param("userIds") List<Long> userIds, @Param("projectId") Long projectId, @Param("videoId") Long videoId);
+    List<Long> selectUserIdsWithTodayCourseWatchLog(@Param("userIds") List<Long> userIds, @Param("projectId") Long projectId,
+                                                     @Param("videoId") Long videoId,
+                                                     @Param("startDate") String startDate, @Param("endDate") String endDate);
 
     /**
      * 根据时间限制来进行处理

+ 10 - 0
fs-service/src/main/java/com/fs/im/mapper/FsImMsgSendDetailMapper.java

@@ -4,6 +4,7 @@ import java.util.List;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.fs.im.domain.FsImMsgSendDetail;
 import com.fs.im.vo.FsImMsgSendDetailVO;
+import org.apache.ibatis.annotations.Param;
 
 /**
  * openim消息记录详情Mapper接口
@@ -70,4 +71,13 @@ public interface FsImMsgSendDetailMapper extends BaseMapper<FsImMsgSendDetail>{
      */
     int deleteDataByDate(java.util.Date date);
 
+    /**
+     * 批量查询指定日期哪些用户在此项目已有待发送/已发送的不同课程
+     */
+    List<Long> selectUserIdsWithPendingSendForProject(@Param("userIds") List<Long> userIds,
+                                                       @Param("projectId") Long projectId,
+                                                       @Param("videoId") Long videoId,
+                                                       @Param("startDate") String startDate,
+                                                       @Param("endDate") String endDate);
+
 }

+ 5 - 0
fs-service/src/main/java/com/fs/im/mapper/FsImMsgSendLogMapper.java

@@ -78,4 +78,9 @@ public interface FsImMsgSendLogMapper extends BaseMapper<FsImMsgSendLog>{
     List<FsImMsgSendLogResponse> selectFsImMsgSendLogInfoList(FsImMsgSendLogRequest request);
 
     FsImMsgSendLogStatisticsResponse getFsImMsgSendStatistics(FsImMsgSendLogRequest request);
+
+    /**
+     * 删除指定日期之前的数据
+     */
+    int deleteDataByDate(java.util.Date date);
 }

+ 5 - 0
fs-service/src/main/java/com/fs/im/service/IFsImMsgSendLogService.java

@@ -103,6 +103,11 @@ public interface IFsImMsgSendLogService extends IService<FsImMsgSendLog>{
 
     R getFsImMsgSendStatistics(FsImMsgSendLogRequest request);
 
+    /**
+     * 清理指定天数之前的数据
+     */
+    int cleanOldData(int days);
+}
 //    /**
 //     * 导出 OpenIM 消息发送记录
 //     * @param request 请求参数

+ 11 - 1
fs-service/src/main/java/com/fs/im/service/impl/FsImMsgSendDetailServiceImpl.java

@@ -4,6 +4,8 @@ import java.util.Calendar;
 import java.util.List;
 import com.fs.common.utils.DateUtils;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.fs.im.mapper.FsImMsgSendDetailMapper;
@@ -19,6 +21,8 @@ import com.fs.im.service.IFsImMsgSendDetailService;
 @Service
 public class FsImMsgSendDetailServiceImpl extends ServiceImpl<FsImMsgSendDetailMapper, FsImMsgSendDetail> implements IFsImMsgSendDetailService {
 
+    private static final Logger log = LoggerFactory.getLogger(FsImMsgSendDetailServiceImpl.class);
+
     /**
      * 查询openim消息记录详情
      *
@@ -103,6 +107,12 @@ public class FsImMsgSendDetailServiceImpl extends ServiceImpl<FsImMsgSendDetailM
         Calendar calendar = Calendar.getInstance();
         calendar.add(Calendar.DAY_OF_MONTH, -days);
         java.util.Date cutoffDate = calendar.getTime();
-        return baseMapper.deleteDataByDate(cutoffDate);
+        int totalDeleted = 0;
+        int batchDeleted;
+        while ((batchDeleted = baseMapper.deleteDataByDate(cutoffDate)) > 0) {
+            totalDeleted += batchDeleted;
+            log.debug("删除fs_im_msg_send_detail数据:{}条,累计:{}条", batchDeleted, totalDeleted);
+        }
+        return totalDeleted;
     }
 }

+ 19 - 0
fs-service/src/main/java/com/fs/im/service/impl/FsImMsgSendLogServiceImpl.java

@@ -4,6 +4,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
+import java.util.Calendar;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.app.params.FsImMsgSendLogRequest;
 import com.fs.app.params.FsImMsgSendLogResponse;
@@ -19,6 +20,8 @@ import com.fs.im.domain.FsImMsgSendDetail;
 import com.fs.im.mapper.FsImMsgSendDetailMapper;
 import com.fs.im.vo.FsImMsgSendDetailVO;
 import com.fs.im.vo.FsImMsgSendLogVO;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.RedisTemplate;
@@ -37,6 +40,8 @@ import org.springframework.transaction.annotation.Transactional;
 @Service
 public class FsImMsgSendLogServiceImpl extends ServiceImpl<FsImMsgSendLogMapper, FsImMsgSendLog> implements IFsImMsgSendLogService {
 
+    private static final Logger log = LoggerFactory.getLogger(FsImMsgSendLogServiceImpl.class);
+
     @Autowired
     private FsImMsgSendDetailMapper fsImMsgSendDetailMapper;
 
@@ -210,4 +215,18 @@ public class FsImMsgSendLogServiceImpl extends ServiceImpl<FsImMsgSendLogMapper,
 
         return R.ok().put("data",data);
     }
+
+    @Override
+    public int cleanOldData(int days) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.add(Calendar.DAY_OF_MONTH, -days);
+        java.util.Date cutoffDate = calendar.getTime();
+        int totalDeleted = 0;
+        int batchDeleted;
+        while ((batchDeleted = baseMapper.deleteDataByDate(cutoffDate)) > 0) {
+            totalDeleted += batchDeleted;
+            log.debug("删除fs_im_msg_send_log数据:{}条,累计:{}条", batchDeleted, totalDeleted);
+        }
+        return totalDeleted;
+    }
 }

+ 29 - 5
fs-service/src/main/java/com/fs/im/service/impl/OpenIMServiceImpl.java

@@ -26,6 +26,7 @@ import com.fs.course.dto.BatchUrgeCourseDTO;
 import com.fs.course.mapper.FsCourseWatchLogMapper;
 import com.fs.course.mapper.FsUserCompanyUserMapper;
 import com.fs.course.mapper.FsUserCourseMapper;
+import com.fs.common.utils.DateUtils;
 import com.fs.fastGpt.service.AiHookService;
 import com.fs.his.domain.FsDoctor;
 import com.fs.his.domain.FsFollow;
@@ -1631,14 +1632,37 @@ public class OpenIMServiceImpl implements OpenIMService {
             List<Long> rawUserIds = userIds.stream()
                     .map(id -> Long.parseLong(id.substring(1)))
                     .collect(Collectors.toList());
-            Set<Long> duplicateUserIds = new HashSet<>(
-                    fsUserCourseMapper.selectUserIdsWithTodayCourseWatchLog(rawUserIds, project, batchSendCourseDTO.getVideoId()));
-            if (!duplicateUserIds.isEmpty()) {
+
+            // 确定查询日期:有 sendTime 用 sendTime,否则今天
+            Date checkDate = batchSendCourseDTO.getSendTime() != null ? batchSendCourseDTO.getSendTime() : new Date();
+            String startDate = DateUtils.parseDateToStr("yyyy-MM-dd 00:00:00", checkDate);
+            String endDate = DateUtils.parseDateToStr("yyyy-MM-dd 23:59:59", checkDate);
+            String todayStr = DateUtils.parseDateToStr("yyyy-MM-dd", new Date());
+            String checkDateStr = DateUtils.parseDateToStr("yyyy-MM-dd", checkDate);
+            boolean isToday = todayStr.equals(checkDateStr);
+
+            Set<Long> allDuplicates;
+            String failReason;
+            if (isToday) {
+                // 当天发课:只看课记录
+                allDuplicates = new HashSet<>(
+                        fsUserCourseMapper.selectUserIdsWithTodayCourseWatchLog(
+                                rawUserIds, project, batchSendCourseDTO.getVideoId(), startDate, endDate));
+                failReason = "同一项目当天已发过课程";
+            } else {
+                // 第二天及以后:查待发送/已发送的IM任务(看课记录还没产生)
+                allDuplicates = new HashSet<>(
+                        fsImMsgSendDetailMapper.selectUserIdsWithPendingSendForProject(
+                                rawUserIds, project, batchSendCourseDTO.getVideoId(), startDate, endDate));
+                failReason = "该用户在此项目已有相同日期的待发送课程";
+            }
+
+            if (!allDuplicates.isEmpty()) {
                 List<String> filtered = userIds.stream()
-                        .filter(uid -> duplicateUserIds.contains(Long.parseLong(uid.substring(1))))
+                        .filter(uid -> allDuplicates.contains(Long.parseLong(uid.substring(1))))
                         .collect(Collectors.toList());
                 userIds.removeAll(filtered);
-                createFailedCourseSendDetail(batchSendCourseDTO, filtered, "同一项目当天已发送过不同课程");
+                createFailedCourseSendDetail(batchSendCourseDTO, filtered, failReason);
             }
         }
 

+ 1 - 1
fs-service/src/main/resources/mapper/course/FsUserCourseMapper.xml

@@ -174,7 +174,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         </foreach>
           and uc.project = #{projectId}
           and cwl.video_id != #{videoId}
-          and cwl.create_time between curdate() and date_add(curdate(), interval 1 day)
+          and cwl.create_time between #{startDate} and #{endDate}
           and cwl.send_type = 1
     </select>
 

+ 16 - 0
fs-service/src/main/resources/mapper/im/FsImMsgSendDetailMapper.xml

@@ -106,6 +106,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     <delete id="deleteDataByDate" parameterType="java.util.Date">
         DELETE FROM fs_im_msg_send_detail
         WHERE create_time &lt; #{date}
+        LIMIT 1000
     </delete>
 
     <!--    <insert id="insertFsImMsgSendDetailBatch" parameterType="java.util.List" useGeneratedKeys="true" keyProperty="logDetailId">-->
@@ -151,4 +152,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         log_id = #{logId}
     </select>
 
+    <select id="selectUserIdsWithPendingSendForProject" resultType="java.lang.Long">
+        SELECT DISTINCT d.user_id
+        FROM fs_im_msg_send_detail d
+        INNER JOIN fs_im_msg_send_log l ON l.log_id = d.logId
+        WHERE d.user_id IN
+        <foreach collection="userIds" item="uid" open="(" separator="," close=")">
+            #{uid}
+        </foreach>
+          AND l.project_id = #{projectId}
+          AND l.video_id != #{videoId}
+          AND d.plan_send_time BETWEEN #{startDate} AND #{endDate}
+          AND d.send_status != 3
+          AND l.msg_type = 1
+    </select>
+
 </mapper>

+ 5 - 0
fs-service/src/main/resources/mapper/im/FsImMsgSendLogMapper.xml

@@ -287,5 +287,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         </where>
     </select>
 
+    <delete id="deleteDataByDate" parameterType="java.util.Date">
+        DELETE FROM fs_im_msg_send_log
+        WHERE create_time &lt; #{date}
+        LIMIT 1000
+    </delete>
 
 </mapper>