Prechádzať zdrojové kódy

红德堂-V1.2 课程统计转化漏斗v2

Long 1 týždeň pred
rodič
commit
3d380472f0

+ 10 - 1
fs-company-app/src/main/java/com/fs/app/controller/FsUserController.java

@@ -4,7 +4,6 @@ package com.fs.app.controller;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.fs.app.annotation.Login;
-import com.fs.app.annotation.LoginUser;
 import com.fs.app.config.ImageStorageConfig;
 import com.fs.app.param.FsUserProjectUpdateParam;
 import com.fs.app.param.FsUserTagUpdateParam;
@@ -267,6 +266,16 @@ public class FsUserController extends AppBaseController {
         return ResponseResult.ok(list);
     }
 
+    @Login
+    @GetMapping("/graphic/detailsV2")
+    @ApiOperation("详情-邀请看课数据漏斗")
+    public ResponseResult<List<FsUserGraphicStatisticsVO>> graphicStatisticsDetailsV2(@ApiParam(value = "视频ID", required = true) @RequestParam Long videoId,
+                                                                                      @ApiParam(value = "营期ID", required = true) @RequestParam Long periodId) {
+        long companyUserId = Long.parseLong(getUserId());
+        List<FsUserGraphicStatisticsVO> vo = fsUserService.graphicStatisticsDetailsV2(companyUserId, videoId, periodId);
+        return ResponseResult.ok(vo);
+    }
+
     @Login
     @ApiOperation("修改用户备注、姓名")
     @PostMapping("/changeUserInfo")

+ 5 - 0
fs-service/src/main/java/com/fs/his/mapper/FsUserMapper.java

@@ -615,4 +615,9 @@ public interface FsUserMapper
      * 查询外部用户列表(isExternal = 0)
      */
     List<FsUserVO> selectExternalUserList(FsUserParam fsUser);
+
+    /**
+     * 邀请看课数据漏斗统计
+     */
+    Map<String, Object> countCourseInviteFunnel(@Param("companyUserId") Long companyUserId, @Param("videoId") Long videoId, @Param("periodId") Long periodId);
 }

+ 2 - 1
fs-service/src/main/java/com/fs/his/service/IFsUserService.java

@@ -21,7 +21,6 @@ import com.fs.his.param.FsUserDisabledUsersParam;
 import com.fs.his.param.FsUserParam;
 import com.fs.his.vo.*;
 import com.fs.hisStore.domain.FsStoreOrderScrm;
-import com.fs.hisStore.domain.FsUserScrm;
 import com.fs.hisStore.vo.FsCompanyUserListQueryVO;
 import com.fs.live.vo.HisFsUserVO;
 import com.fs.qw.dto.FsUserTransferParamDTO;
@@ -186,6 +185,8 @@ public interface IFsUserService
 
     List<FsUserGraphicStatisticsVO> graphicStatistics(UserStatisticsCommonParam param);
 
+    List<FsUserGraphicStatisticsVO> graphicStatisticsDetailsV2(Long companyUserId, Long videoId, Long periodId);
+
     List<FsCourseAnalysisVO> courseAnalysis(CourseAnalysisParam param);
 
     CompanyUserSummaryCountVO companyUserSummaryCount(Long userId, String companyUserId);

+ 23 - 13
fs-service/src/main/java/com/fs/his/service/impl/FsUserServiceImpl.java

@@ -1,6 +1,5 @@
 package com.fs.his.service.impl;
 
-import java.io.IOException;
 import java.lang.reflect.Field;
 import java.math.BigDecimal;
 import java.math.BigInteger;
@@ -20,7 +19,6 @@ import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.IdUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
@@ -31,10 +29,8 @@ import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.ResponseResult;
 import com.fs.common.core.domain.entity.SysDictData;
 import com.fs.common.core.page.TableDataInfo;
-import com.fs.common.core.redis.RedisCache;
 import com.fs.common.enums.ImTypeEnum;
 import com.fs.common.exception.CustomException;
-import com.fs.common.exception.base.BaseException;
 import com.fs.common.param.LoginMaWxParam;
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.DictUtils;
@@ -76,13 +72,11 @@ import com.fs.im.config.ImTypeConfig;
 import com.fs.im.service.OpenIMService;
 import com.fs.hisStore.domain.FsStoreOrderScrm;
 import com.fs.hisStore.domain.FsUserBillScrm;
-import com.fs.hisStore.domain.FsUserScrm;
 import com.fs.hisStore.enums.BillDetailEnum;
 import com.fs.hisStore.mapper.FsStoreOrderScrmMapper;
 import com.fs.hisStore.service.IFsUserBillScrmService;
 import com.fs.hisStore.vo.FsCompanyUserListQueryVO;
 import com.fs.live.vo.HisFsUserVO;
-import com.fs.qw.cache.IQwExternalContactCacheService;
 import com.fs.qw.dto.FsUserTransferParamDTO;
 import com.fs.qw.param.QwFsUserParam;
 import com.fs.qw.vo.QwFsUserVO;
@@ -105,14 +99,7 @@ import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClients;
 import org.apache.http.util.Asserts;
-import org.apache.http.util.EntityUtils;
 import org.redisson.api.RLock;
 import org.redisson.api.RedissonClient;
 import org.slf4j.Logger;
@@ -1150,6 +1137,29 @@ public class FsUserServiceImpl implements IFsUserService {
         return list;
     }
 
+    @Override
+    public List<FsUserGraphicStatisticsVO> graphicStatisticsDetailsV2(Long companyUserId, Long videoId, Long periodId) {
+        Map<String, Object> result = fsUserMapper.countCourseInviteFunnel(companyUserId, videoId, periodId);
+        List<FsUserGraphicStatisticsVO> list = new LinkedList<>();
+        list.add(new FsUserGraphicStatisticsVO("邀请看课人数(未发送成功人" + toInt(result.get("sendFailed")) + "+发送成功" + toInt(result.get("sendSuccess")) + "人)", toInt(result.get("inviteTotal")), toInt(result.get("inviteTotal"))));
+        list.add(new FsUserGraphicStatisticsVO("未看课" + toInt(result.get("notWatched")) + "人", toInt(result.get("notWatched")), toInt(result.get("notWatched"))));
+        list.add(new FsUserGraphicStatisticsVO("未完播" + toInt(result.get("watchingIncomplete")) + "人", toInt(result.get("watchingIncomplete")),toInt(result.get("watchingIncomplete"))));
+        list.add(new FsUserGraphicStatisticsVO("完播" + toInt(result.get("watchedComplete")) + "人", toInt(result.get("watchedComplete")), toInt(result.get("watchedComplete"))));
+        list.add(new FsUserGraphicStatisticsVO("链接失效后未看课" + toInt(result.get("expiredNotWatched")) + "人", toInt(result.get("expiredNotWatched")), toInt(result.get("expiredNotWatched"))));
+        list.sort(Comparator.comparingInt(FsUserGraphicStatisticsVO::getValue).reversed());
+        return list;
+    }
+
+    private int toInt(Object obj) {
+        if (obj == null) {
+            return 0;
+        }
+        if (obj instanceof Number) {
+            return ((Number) obj).intValue();
+        }
+        return Integer.parseInt(obj.toString());
+    }
+
     @Override
     public List<FsCourseAnalysisVO> courseAnalysis(CourseAnalysisParam param) {
         //1、查询课程视频信息

+ 22 - 0
fs-service/src/main/resources/mapper/his/FsUserMapper.xml

@@ -2731,4 +2731,26 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         ORDER BY fu.user_id DESC
     </select>
 
+    <!-- 邀请看课数据漏斗统计 -->
+    <select id="countCourseInviteFunnel" resultType="Map">
+        SELECT
+            COUNT(DISTINCT d.user_id) AS inviteTotal,
+            COUNT(DISTINCT CASE WHEN d.status = 0 AND d.send_status = 1 THEN d.user_id END) AS sendSuccess,
+            COUNT(DISTINCT CASE WHEN d.status = 1 OR d.send_status = 2 THEN d.user_id END) AS sendFailed,
+            COUNT(DISTINCT CASE WHEN d.status = 0 AND d.send_status = 1 AND w.log_id IS NULL THEN d.user_id END) AS notWatched,
+            COUNT(DISTINCT CASE WHEN w.log_type IN (1, 4) THEN d.user_id END) AS watchingIncomplete,
+            COUNT(DISTINCT CASE WHEN w.log_type = 2 THEN d.user_id END) AS watchedComplete,
+            COUNT(DISTINCT CASE WHEN d.status = 0 AND d.send_status = 1 AND w.log_id IS NULL AND pd.status = 2 THEN d.user_id END) AS expiredNotWatched
+        FROM fs_im_msg_send_detail d
+        JOIN fs_im_msg_send_log l ON l.log_id = d.log_id
+            AND l.company_user_id = #{companyUserId}
+            AND l.video_id = #{videoId}
+            AND l.period_id = #{periodId}
+        LEFT JOIN fs_course_watch_log w ON w.user_id = d.user_id
+            AND w.video_id = l.video_id
+            AND w.course_id = l.course_id
+            AND w.period_id = l.period_id
+        LEFT JOIN fs_user_course_period_days pd ON pd.id = l.period_days_id
+    </select>
+
 </mapper>