瀏覽代碼

feat(qw): 实现客户E级判定逻辑并优化评级策略

- 新增连续3天未看课判定逻辑,标记为E级
- 修改评级策略,E级不再通过分数评定
- 调整定时任务时间及判定条件
- 优化createBaseLog方法,增加isDaysNotStudy参数
- 修改日志描述,统一使用3天周期表述
- 分数低于D级最低分时默认评为D级
- E级客户不发送消息,设置sendStatus为5
- 修复restoreByIsDaysNotStudy方法的判定天数描述
xw 2 周之前
父節點
當前提交
4caea1132d

+ 10 - 8
fs-qw-task/src/main/java/com/fs/app/task/qwTask.java

@@ -314,13 +314,13 @@ public class qwTask {
 
 
     /**
-     * 凌晨 2点35开始,将营期小于7天中标记为 是否7天未看课的(E级) 客户的 但是看课了的恢复一下
+     * 凌晨 2点35开始,将营期小于3天中标记为 是否3天未看课的(E级) 客户的 但是看课了的恢复一下
      */
     @Scheduled(cron = "0 35 2 * * ?")
     @Async
     public void processSopUserLogsInfoByIsDaysNotStudy() {
         long startTimeMillis = System.currentTimeMillis();
-        log.info("====== 开始选择和处理 是否7天未看课的(E级) 客户的 恢复一下 ======");
+        log.info("====== 开始选择和处理 是否3天未看课的(E级) 客户的 恢复一下 ======");
 
         logsInfoByIsDaysNotStudy.restoreByIsDaysNotStudy();
 
@@ -329,9 +329,10 @@ public class qwTask {
     }
 
     /**
-     * 定时任务:客户评级处理
+     * 定时任务:客户评级处理(ABCD级)
      * 执行时间:每天凌晨 3:45:00
-     * 功能:对SOP营期用户进行分级评级
+     * 功能:对SOP营期用户进行分级评级(营期开始满7天后开始评级)
+     * 评级依据:最近7天的看课记录
      * 备注:异步执行,避免阻塞其他任务
      */
     @Scheduled(cron = "0 45 3 * * ?")
@@ -339,7 +340,7 @@ public class qwTask {
     public void processQwSopExternalContactRatingTimer() {
         // 记录任务开始时间
         long startTimeMillis = System.currentTimeMillis();
-        log.info("====== 开始选择和处理 sop营期-用户分级 ======");
+        log.info("====== 开始选择和处理 sop营期-用户分级(ABCD级) ======");
 
         // 执行用户分级评级
         qwExternalContactRatingService.ratingUserLogs();
@@ -350,18 +351,19 @@ public class qwTask {
     }
 
     /**
-     * 凌晨4点35开始 客户超过7天没有看课的 标记E级
+     * 凌晨3点30开始 客户连续3天没有看课的 标记E级
+     * 判定标准:连续3天无看课记录
      */
     @Scheduled(cron = "0 30 3 * * ?")
     @Async
     public void processQwSopExternalContactRatingMoreSevenDaysTimer() {
         long startTimeMillis = System.currentTimeMillis();
-        log.info("====== 开始选择和处理 sop营期-用户超7天的看课情况 ======");
+        log.info("====== 开始选择和处理 sop营期-用户连续3天未看课情况(E级) ======");
 
         qwExternalContactRatingMoreSevenDaysService.ratingMoreSevenDaysUserLogs();
 
         long endTimeMillis = System.currentTimeMillis();
-        log.info("====== sop营期-用户超7天处理完成,耗时 {} 毫秒 ======", (endTimeMillis - startTimeMillis));
+        log.info("====== sop营期-用户连续3天未看课处理完成,耗时 {} 毫秒 ======", (endTimeMillis - startTimeMillis));
     }
 
 

+ 24 - 13
fs-qw-task/src/main/java/com/fs/app/taskService/impl/QwExternalContactRatingMoreSevenDaysServiceImpl.java

@@ -203,35 +203,46 @@ public class QwExternalContactRatingMoreSevenDaysServiceImpl implements QwExtern
                 return null;
             }
 
+            // 查询最近 notStudyDays(3天) 的看课记录
             List<QwRatingVO> ratingVOS = fsCourseWatchLogMapper
                     .selectFsCourseWatchLogByExtIdRatingMoreStudyDays(externalId, config.getNotStudyDays());
 
-            if (ratingVOS == null || ratingVOS.isEmpty() || ratingVOS.size() < 6) {
-                log.info("没有记录或不满足条件不评级或看课记录小于6 不评级,externalId: {}", externalId);
-                return null;
+            // 如果连续3天没有看课记录,标记为E级
+            if (ratingVOS == null || ratingVOS.isEmpty()) {
+                log.info("连续{}天没有看课记录,标记为E级,externalId: {}", config.getNotStudyDays(), externalId);
+                QwExternalContact externalContact = new QwExternalContact();
+                externalContact.setId(externalId);
+                externalContact.setLevel(5);  // E级
+                externalContact.setIsDaysNotStudy(1);
+                return externalContact;
             }
 
+            // 判断连续3天的总观看时长是否大于0
+            boolean hasWatchDuration = getScoreMoreStudyLevel(ratingVOS);
 
-            //判断 7天的时长是否大于0
-            boolean scoreMoreStudyLevel = getScoreMoreStudyLevel(ratingVOS);
-
-            if (!scoreMoreStudyLevel) {
+            if (!hasWatchDuration) {
+                // 有记录但观看时长为0,也认为连续3天未看课,标记为E级
+                log.info("连续{}天看课时长为0,标记为E级,externalId: {}", config.getNotStudyDays(), externalId);
                 QwExternalContact externalContact = new QwExternalContact();
                 externalContact.setId(externalId);
-                externalContact.setLevel(5);
+                externalContact.setLevel(5);  // E级
                 externalContact.setIsDaysNotStudy(1);
                 return externalContact;
-            }else {
+            } else {
+                // 有看课记录且时长>0,不是E级,恢复为ABCD评级(保持原有level)
+                log.info("最近{}天有看课记录,不是E级,externalId: {}", config.getNotStudyDays(), externalId);
                 QwExternalContact externalContact = new QwExternalContact();
                 externalContact.setId(externalId);
-                externalContact.setLevel(ratingVOS.get(0).getLevel());
-                externalContact.setIsDaysNotStudy(0);
+                // 保持原有的ABCD评级,不修改
+                if (ratingVOS.get(0).getLevel() != null) {
+                    externalContact.setLevel(ratingVOS.get(0).getLevel());
+                }
+                externalContact.setIsDaysNotStudy(0);  // 标记为非连续未看课
                 return externalContact;
             }
 
-
         } catch (Exception e) {
-            log.error("计算用户积分异常,用户:{}", logsInfo, e);
+            log.error("判断E级客户异常,用户:{}", logsInfo, e);
             return null;
         }
     }

+ 5 - 2
fs-qw-task/src/main/java/com/fs/app/taskService/impl/QwExternalContactRatingServiceImpl.java

@@ -315,7 +315,7 @@ public class QwExternalContactRatingServiceImpl implements QwExternalContactRati
     }
 
 
-    //评级
+    //评级(ABCD等级,E级不通过分数评定)
     public int getScoreLevel(List<QwRatingVO> qwRatingVOS, QwRatingConfig config) {
 
         AtomicDouble watchCount= new AtomicDouble();
@@ -345,6 +345,7 @@ public class QwExternalContactRatingServiceImpl implements QwExternalContactRati
         // 转换为 int 类型
         int score = roundedResult.intValue();
 
+        // ABCD评级(E级不通过分数评定,由独立定时任务判断连续未看课天数)
         if (score >= config.getALevelMin()) {
             return 1; // A 等级
         } else if (score >= config.getBLevelMin() && score < config.getBLevelMax()) {
@@ -354,7 +355,9 @@ public class QwExternalContactRatingServiceImpl implements QwExternalContactRati
         } else if (score >= config.getDLevelMin() && score < config.getDLevelMax()) {
             return 4; // D 等级
         } else {
-            throw new IllegalArgumentException("分数不在任何等级范围内: " + score);
+            // 分数低于D级最低分,默认为D级
+            log.warn("分数{}低于D级最低分,默认评为D级", score);
+            return 4; // D 等级
         }
     }
     //升降等级

+ 12 - 3
fs-qw-task/src/main/java/com/fs/app/taskService/impl/SopLogsTaskServiceImpl.java

@@ -715,7 +715,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
             QwGroupChat groupChat = groupChatMap.get(logVo.getChatId());
             ruleTimeVO.setSendType(6);
             ruleTimeVO.setType(2);
-            QwSopLogs sopLogs = createBaseLog(formattedSendTime, logVo, ruleTimeVO, groupChat.getChatId(), groupChat.getName(), null, isOfficial, null);
+            QwSopLogs sopLogs = createBaseLog(formattedSendTime, logVo, ruleTimeVO, groupChat.getChatId(), groupChat.getName(), null, isOfficial, null,null);
             handleLogBasedOnType(sopLogs, content, logVo, sendTime, courseId, videoId,
                     type, qwUserId, companyUserId, companyId, groupChat.getChatId(), welcomeText, qwUserName,
                     null, true, miniAppId, groupChat,config, miniMap, null, sendMsgType,companies);
@@ -744,7 +744,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                     String externalUserName = contactId.getExternalUserName();
                     Long fsUserId = contactId.getFsUserId();
                     Integer grade = contactId.getGrade();
-                    QwSopLogs sopLogs = createBaseLog(formattedSendTime, logVo, ruleTimeVO, contactId.getExternalContactId(), externalUserName, fsUserId, isOfficial, contactId.getExternalId());
+                    QwSopLogs sopLogs = createBaseLog(formattedSendTime, logVo, ruleTimeVO, contactId.getExternalContactId(), externalUserName, fsUserId, isOfficial, contactId.getExternalId(),contactId.getIsDaysNotStudy());
                     handleLogBasedOnType(sopLogs, content, logVo, sendTime, courseId, videoId,
                             type, qwUserId, companyUserId, companyId, externalId, welcomeText, qwUserName, fsUserId, false, miniAppId,
                             null,config, miniMap, grade, sendMsgType,companies);
@@ -790,7 +790,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
     private QwSopLogs createBaseLog(String formattedSendTime, SopUserLogsVo logVo,
                                     QwSopRuleTimeVO ruleTimeVO, String externalContactId,
                                     String externalUserName, Long fsUserId,Integer isOfficial,
-                                    Long externalId) {
+                                    Long externalId,Integer isDaysNotStudy) {
         QwSopLogs sopLogs = new QwSopLogs();
         sopLogs.setSendTime(formattedSendTime);
         sopLogs.setQwUserid(logVo.getQwUserId());
@@ -798,6 +798,15 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
         sopLogs.setLogType(ruleTimeVO.getType());
         sopLogs.setTakeRecords(0);
 
+        if (isOfficial != 1 && Integer.valueOf(1).equals(isDaysNotStudy)) {
+            sopLogs.setSendStatus(5L);
+            sopLogs.setRemark("E级客户不发送");
+        }else {
+            sopLogs.setSendStatus(3L);
+        }
+
+        sopLogs.setReceivingStatus(0L);
+
         if (isOfficial == 1) {
 
             if (logVo.getIsSampSend()== 1) {

+ 5 - 2
fs-service/src/main/java/com/fs/sop/service/impl/SopUserLogsServiceImpl.java

@@ -1020,7 +1020,7 @@ public class SopUserLogsServiceImpl  implements ISopUserLogsService {
         }
     }
 
-    //评级
+    //评级(ABCD等级,E级不通过分数评定)
     public int getScoreLevel(List<QwRatingVO> qwRatingVOS, QwRatingConfig config) {
 
         AtomicDouble watchCount= new AtomicDouble();
@@ -1050,6 +1050,7 @@ public class SopUserLogsServiceImpl  implements ISopUserLogsService {
         // 转换为 int 类型
         int score = roundedResult.intValue();
 
+        // ABCD评级(E级不通过分数评定,由独立定时任务判断连续未看课天数)
         if (score >= config.getALevelMin()) {
             return 1; // A 等级
         } else if (score >= config.getBLevelMin() && score < config.getBLevelMax()) {
@@ -1059,7 +1060,9 @@ public class SopUserLogsServiceImpl  implements ISopUserLogsService {
         } else if (score >= config.getDLevelMin() && score < config.getDLevelMax()) {
             return 4; // D 等级
         } else {
-            throw new IllegalArgumentException("分数不在任何等级范围内: " + score);
+            // 分数低于D级最低分,默认为D级
+            logger.warn("分数{}低于D级最低分,默认评为D级", score);
+            return 4; // D 等级
         }
     }
     //升降等级