xdd hai 3 semanas
pai
achega
4d23a84654

+ 65 - 0
fs-admin/src/main/java/com/fs/task/FsCourseTask.java

@@ -0,0 +1,65 @@
+package com.fs.task;
+
+import com.fs.course.service.IFsCourseWatchLogService;
+import com.fs.qw.service.IQwWorkTaskService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * 后台统计相关 定时任务
+ */
+@Slf4j
+@Service("fsCourseTask")
+public class FsCourseTask {
+    @Autowired
+    private IFsCourseWatchLogService fsCourseWatchLogService;
+    @Autowired
+    private IQwWorkTaskService qwWorkTaskService;
+
+    /**
+     * 添加企微观看日志
+     * @throws Exception
+     */
+    public void addQwWatchLog() throws Exception
+    {
+        fsCourseWatchLogService.addCourseWatchLogDayNew();
+    }
+
+
+    /**
+     * 看课面板定时任务-1
+     * @throws Exception
+     */
+    public void qwWorkTask1() throws Exception
+    {
+        qwWorkTaskService.addQwWorkByCourse4();
+        qwWorkTaskService.addQwWorkByCourseLastTime();
+    }
+    /**
+     * 看课面板定时任务-2
+     * @throws Exception
+     */
+    public void qwWorkTask2() throws Exception
+    {
+        qwWorkTaskService.addQwWorkByCourse();
+        qwWorkTaskService.addQwWorkByFirstCourse();
+    }
+    /**
+     * 看课面板定时任务-3
+     * @throws Exception
+     */
+    public void qwWorkTask3() throws Exception
+    {
+        qwWorkTaskService.addQwWorkByConversionDay();
+    }
+    /**
+     * 看课面板定时任务-4
+     * @throws Exception
+     */
+    public void qwWorkTask4() throws Exception
+    {
+        qwWorkTaskService.delQwWorkTaskByOver();
+    }
+
+}

+ 29 - 41
fs-admin/src/main/java/com/fs/task/StoreTask.java

@@ -3,14 +3,9 @@ package com.fs.task;
 
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONUtil;
-import com.fs.common.core.domain.R;
 import com.fs.common.core.redis.RedisCache;
-import com.fs.company.domain.CompanyUser;
 import com.fs.company.service.ICompanyService;
-import com.fs.core.security.SecurityUtils;
 import com.fs.course.service.IFsCourseWatchLogService;
-import com.fs.course.service.impl.FsCourseWatchLogServiceImpl;
-import com.fs.crm.mapper.CrmCustomerMapper;
 import com.fs.erp.domain.ErpDeliverys;
 import com.fs.erp.domain.ErpGoods;
 import com.fs.erp.domain.ErpOrderQuery;
@@ -23,11 +18,10 @@ import com.fs.erp.service.IErpOrderService;
 import com.fs.pay.pay.domain.OrderResult;
 import com.fs.pay.pay.dto.OrderQueryDTO;
 import com.fs.pay.pay.service.PayService;
-import com.fs.pay.pay.service.impl.PayApiServiceImpl;
+import com.fs.qw.service.IQwWorkTaskService;
 import com.fs.store.config.StoreConfig;
 import com.fs.store.domain.*;
 import com.fs.store.dto.ExpressInfoDTO;
-import com.fs.store.dto.FsStoreCartDTO;
 import com.fs.store.enums.ShipperCodeEnum;
 import com.fs.store.mapper.FsStoreOrderItemMapper;
 import com.fs.store.mapper.FsStoreOrderMapper;
@@ -35,13 +29,8 @@ import com.fs.store.mapper.FsStorePaymentMapper;
 import com.fs.store.mapper.FsStoreProductAttrValueMapper;
 import com.fs.store.param.*;
 import com.fs.store.service.*;
-import com.fs.store.vo.FsStoreOrderItemVO;
-import com.fs.store.vo.FsStoreOrderTuiVO;
-import com.fs.store.vo.FsStoreOrderVO;
 import com.fs.system.service.ISysConfigService;
-import com.sun.media.sound.SF2GlobalRegion;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.ibatis.annotations.Param;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Component;
@@ -67,19 +56,19 @@ public class StoreTask
     @Autowired
     private RedisCache redisCache;
     @Autowired
-    IFsStoreOrderService orderService;
+    private IFsStoreOrderService orderService;
     @Autowired
     private IFsStoreCouponUserService couponUserService;
     @Autowired
-    IFsStoreAfterSalesService afterSalesService;
+    private IFsStoreAfterSalesService afterSalesService;
     @Autowired
-    IFsUserService userService;
+    private IFsUserService userService;
 
     @Autowired
-    IErpOrderService erpOrderService;
+    private IErpOrderService erpOrderService;
 
     @Autowired
-    PayService ybPayService;
+    private PayService ybPayService;
     @Autowired
     private FsStoreOrderMapper fsStoreOrderMapper;
 
@@ -92,10 +81,29 @@ public class StoreTask
     @Autowired
     private FsStorePaymentMapper fsStorePaymentMapper;
 
+
+    @Autowired
+    private IErpGoodsService erpGoodsService;
+    @Autowired
+    private ISysConfigService configService;
+    @Autowired
+    private FsStoreProductAttrValueMapper fsStoreProductAttrValueMapper;
+    @Autowired
+    private FsStorePaymentMapper paymentMapper;
+    @Autowired
+    private IFsStorePaymentService fsStorePaymentService;
+    @Autowired
+    private ICompanyService companyService;
+
+
+    @Autowired
+    private IFsExpressService expressService;
+
     @Autowired
-    private CrmCustomerMapper crmCustomerMapper;
+    private FsStoreOrderItemMapper itemMapper;
+
     @Autowired
-    private IFsCourseWatchLogService fsCourseWatchLogService;
+    private IFsStoreAfterSalesService fsStoreAfterSalesService;
 
     //每5分钟执行一次
     public void deliveryOp()
@@ -126,12 +134,6 @@ public class StoreTask
     }
 
 
-    @Autowired
-    IErpGoodsService erpGoodsService;
-    @Autowired
-    ISysConfigService configService;
-    @Autowired
-    private FsStoreProductAttrValueMapper fsStoreProductAttrValueMapper;
     public void storeProdUpdateCostPrice()
     {
         String json=configService.selectConfigByKey("store.config");
@@ -243,8 +245,6 @@ public class StoreTask
         }
 
     }
-    @Autowired
-    private IFsExpressService expressService;
 
     public void changeStatus(){
         List<Long> list  = fsStoreOrderMapper.selectOrderId();
@@ -266,12 +266,7 @@ public class StoreTask
         }
     }
 
-    @Autowired
-    private FsStorePaymentMapper paymentMapper;
-    @Autowired
-    private IFsStorePaymentService fsStorePaymentService;
-    @Autowired
-    private ICompanyService companyService;
+
 
     public void subCompanyMoney(){
         List<Long> list = paymentMapper.selectPaymentIds();
@@ -283,8 +278,6 @@ public class StoreTask
         }
     }
 
-    @Autowired
-    private FsStoreOrderItemMapper itemMapper;
 
     public void updateOrderItem() throws ParseException {
         List <Long> ids = itemMapper.selectOrderIdByNoErp();
@@ -344,8 +337,6 @@ public class StoreTask
 
     }
 
-    @Autowired
-    private IFsStoreAfterSalesService fsStoreAfterSalesService;
 
     public void selectPayMoneyLessOne(){
         List<FsStoreOrder> list = fsStoreOrderMapper.selectPayMoneyLessOne();
@@ -372,10 +363,7 @@ public class StoreTask
 
     }
 
-    public void addQwWatchLog() throws Exception
-    {
-        fsCourseWatchLogService.addCourseWatchLogDay();
-    }
+
 
 
 }

+ 121 - 0
fs-company/src/main/java/com/fs/qw/QwWorkTaskController.java

@@ -0,0 +1,121 @@
+package com.fs.qw;
+
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.ServletUtils;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.core.security.LoginUser;
+import com.fs.core.web.service.TokenService;
+import com.fs.course.mapper.FsCourseWatchLogMapper;
+import com.fs.qw.domain.QwWorkTask;
+import com.fs.qw.param.QwWorkTaskListParam;
+import com.fs.qw.service.IQwWorkTaskService;
+import com.fs.qw.vo.QwWorkTaskListVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 企微任务看板Controller
+ *
+ * @author fs
+ * @date 2025-03-25
+ */
+@RestController
+@RequestMapping("/qw/QwWorkTask")
+public class QwWorkTaskController extends BaseController
+{
+    @Autowired
+    private IQwWorkTaskService qwWorkTaskService;
+    @Autowired
+    private TokenService tokenService;
+    @Autowired
+    private FsCourseWatchLogMapper fsCourseWatchLogMapper;
+    /**
+     * 查询企微任务看板列表
+     */
+    @PreAuthorize("@ss.hasPermi('qw:QwWorkTask:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(QwWorkTaskListParam qwWorkTask)
+    {
+        startPage();
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        qwWorkTask.setCompanyId(loginUser.getCompany().getCompanyId());
+        if(ObjectUtils.isNull(qwWorkTask.getCompanyUserId())) {
+            qwWorkTask.setCompanyUserId(loginUser.getUser().getUserId());
+        }
+        List<QwWorkTaskListVO> list = qwWorkTaskService.selectQwWorkTaskListVONew(qwWorkTask);
+        for (QwWorkTaskListVO qwWorkTaskListVO : list) {
+            qwWorkTaskListVO.setLogs(fsCourseWatchLogMapper.selectFsCourseWatchLog7DayByExtId(qwWorkTaskListVO.getExtId()));
+        }
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出企微任务看板列表
+     */
+    @PreAuthorize("@ss.hasPermi('qw:QwWorkTask:export')")
+    @Log(title = "企微任务看板", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(QwWorkTask qwWorkTask)
+    {
+        List<QwWorkTask> list = qwWorkTaskService.selectQwWorkTaskList(qwWorkTask);
+        ExcelUtil<QwWorkTask> util = new ExcelUtil<QwWorkTask>(QwWorkTask.class);
+        return util.exportExcel(list, "企微任务看板数据");
+    }
+
+    /**
+     * 获取企微任务看板详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('qw:QwWorkTask:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(qwWorkTaskService.selectQwWorkTaskById(id));
+    }
+
+    /**
+     * 新增企微任务看板
+     */
+    @PreAuthorize("@ss.hasPermi('qw:QwWorkTask:add')")
+    @Log(title = "企微任务看板", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody QwWorkTask qwWorkTask)
+    {
+        return toAjax(qwWorkTaskService.insertQwWorkTask(qwWorkTask));
+    }
+
+    /**
+     * 修改企微任务看板
+     */
+    @PreAuthorize("@ss.hasPermi('qw:QwWorkTask:edit')")
+    @Log(title = "企微任务看板处理", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody QwWorkTask qwWorkTask)
+    {
+        QwWorkTask task = new QwWorkTask();
+        task.setId(qwWorkTask.getId());
+        task.setRemark(qwWorkTask.getRemark());
+        task.setStatus(1);
+        task.setUpdateTime(new Date());
+        return toAjax(qwWorkTaskService.updateQwWorkTask(task));
+    }
+
+    /**
+     * 删除企微任务看板
+     */
+    @PreAuthorize("@ss.hasPermi('qw:QwWorkTask:remove')")
+    @Log(title = "企微任务看板", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(qwWorkTaskService.deleteQwWorkTaskByIds(ids));
+    }
+}

+ 24 - 3
fs-company/src/main/java/com/fs/qw/vo/QwWorkTaskListVO.java

@@ -1,8 +1,14 @@
 package com.fs.qw.vo;
 
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fs.common.annotation.Excel;
 import lombok.Data;
 
+import java.util.Date;
+import java.util.List;
+
 @Data
 public class QwWorkTaskListVO {
     private Long id;
@@ -21,10 +27,12 @@ public class QwWorkTaskListVO {
     /** 类别 1先导 2 课程 3 大小转 4 转人工 */
     @Excel(name = "类别 1先导 2 课程 3 大小转 4 转人工")
     private Integer type;
+    private String typeText;
 
     /** 状态 0 待处理 1 已处理 3 过期 */
     @Excel(name = "状态 0 待处理 1 已处理 3 过期")
     private Integer status;
+    private String statusText;
 
     /** 分值 */
     @Excel(name = "分值")
@@ -35,12 +43,25 @@ public class QwWorkTaskListVO {
     private String sopId;
 
     /** 公司id */
-    @Excel(name = "公司id")
     private Long companyId;
+    @Excel(name = "公司名称")
+    private String companyName;
 
     /** 用户id */
-    @Excel(name = "用户id")
     private Long companyUserId;
-
+    /**
+     * 销售名称
+     */
+    @Excel(name = "销售名称")
+    private String companyUserName;
     private String title;
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    /** 更新时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updateTime;
+
+    List<Integer> logs;
 }

+ 51 - 25
fs-service-system/src/main/java/com/fs/course/mapper/FsCourseWatchLogMapper.java

@@ -190,14 +190,14 @@ public interface FsCourseWatchLogMapper extends BaseMapper<FsCourseWatchLog> {
     List<FsCourseWatchLog> selectFsCourseWatchLogFinish();
 
     @Select({"<script> " +
-            "SELECT " +
-            "o.video_id,o.company_id,o.user_id,DATE(o.create_time) create_time,concat(u.user_id,'_',u.nickname).qw_user_name,v.title videoName,uc.course_name,\n" +
+            "SELECT \n" +
+            "o.video_id,o.company_id,o.qw_user_id,DATE(o.create_time) create_time,qu.qw_user_name,v.title videoName,uc.course_name,\n" +
             "SUM(CASE WHEN o.log_type = '1' THEN 1 ELSE 0 END) AS type1,\n" +
             "SUM(CASE WHEN o.log_type = '2' THEN 1 ELSE 0 END) AS type2,\n" +
             "SUM(CASE WHEN o.log_type = '3' THEN 1 ELSE 0 END) AS type3,\n" +
             "SUM(CASE WHEN o.log_type = '4' THEN 1 ELSE 0 END) AS type4\n" +
             "FROM fs_course_watch_log o\n" +
-            "LEFT JOIN fs_user u on u.user_id=o.user_id\n" +
+            "LEFT JOIN qw_user qu on qu.id=o.qw_user_id\n" +
             "LEFT JOIN fs_user_course_video v on v.video_id=o.video_id \n" +
             "LEFT JOIN fs_user_course uc on uc.course_id=v.course_id\n" +
             "where o.company_id=#{companyId}  " +
@@ -207,13 +207,16 @@ public interface FsCourseWatchLogMapper extends BaseMapper<FsCourseWatchLog> {
             "<if test='eTime != null '> " +
             "      and DATE(o.create_time) &lt;= DATE(#{eTime})\n" +
             "</if>" +
+            "<if test ='nickName !=null and nickName!=\"\"'>\n" +
+            "   and qu.qw_user_name like concat( #{nickName}, '%')\n" +
+            "</if>" +
             "<if test ='courseId !=null'> " +
             "     and o.course_id = #{courseId} " +
             "</if>" +
             "<if test ='videoId !=null'> " +
             "     and o.video_id = #{videoId} " +
             "</if>" +
-            "GROUP BY o.video_id,o.user_id,DATE(o.create_time)\n" +
+            "GROUP BY o.video_id,o.qw_user_id,DATE(o.create_time)\n" +
             "ORDER BY o.video_id ,DATE(o.create_time) \n"+
             "</script>"})
     List<FsCourseWatchLogStatisticsListVO> selectFsCourseWatchLogStatisticsListVO(FsCourseWatchLogStatisticsListParam param);
@@ -226,38 +229,31 @@ public interface FsCourseWatchLogMapper extends BaseMapper<FsCourseWatchLog> {
     List<FsCourseUserStatisticsListVO> selectFsCourseUserStatisticsListVO(FsCourseUserStatisticsListParam param);
 
     @Select({"<script> " +
-            "SELECT" +
-            "    MIN(o.create_time) AS createTime," +
-            "    user.user_name as user_name," +
-            "    `user`.create_time AS userCreateTime" +
-            "FROM" +
-            "    fs_course_watch_log o" +
-            "LEFT JOIN" +
-            "\tcompany_user `user`" +
-            "ON o.company_user_id=`user`.user_id" +
-            "GROUP BY `user`.user_id"+
+            "select MIN(o.create_time) createTime,ANY_VALUE(qu.qw_user_name) qwUserName ,ext.name externalUserName,ext.create_time userCreateTime from fs_course_watch_log o LEFT JOIN qw_user qu on qu.id=o.qw_user_id LEFT JOIN qw_external_contact ext ON ext.id =  o.qw_external_contact_id where log_type=2 and o.company_id=#{companyId} " +
+            "<if test= 'sTime != null '> " +
+            "       and DATE(o.create_time) &gt;= DATE(#{sTime})\n" +
+            "</if>\n" +
+            "<if test='eTime != null '> " +
+            "      and DATE(o.create_time) &lt;= DATE(#{eTime})\n" +
+            "</if>" +
+            "<if test ='nickName !=null and nickName!=\"\"'>\n" +
+            "   and qu.qw_user_name like concat( #{nickName}, '%')\n" +
+            "</if>"+
+            " GROUP BY o.qw_external_contact_id"+
             "</script>"})
-    List<FsCourseOverVO>    selectFsCourseWatchLogOverStatisticsListVO(FsCourseOverParam param);
+    List<FsCourseOverVO> selectFsCourseWatchLogOverStatisticsListVO(FsCourseOverParam param);
 
 
     void batchUpdateWatchLogSendMsg(@Param("list") List<FsCourseWatchLog> logs);
 
-    @Select("SELECT l.qw_external_contact_id,l.log_type,l.qw_user_id,l.create_time,l.company_user_id as company_user_id,l.user_id as user_id,l.company_id as company_id,u.first_time,u.create_time lineTime FROM fs_course_watch_log  l " +
+    @Select("SELECT l.qw_external_contact_id,l.log_type,l.qw_user_id,l.create_time ,u.first_time,u.create_time lineTime FROM fs_course_watch_log  l " +
             "LEFT JOIN qw_external_contact u ON u.id=l.qw_external_contact_id  " +
             " WHERE  DATE(l.create_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY) and l.video_id =#{videoId}")
     List<FsQwCourseWatchLogVO> selectFsCourseWatchLogByNoDayAndVoidId(Long videoId);
-
-    @Select("SELECT l.qw_external_contact_id,l.log_type,l.qw_user_id,l.create_time lineTime,l.company_user_id as company_user_id,l.user_id as user_id,l.company_id as company_id FROM fs_course_watch_log l" +
-            " WHERE DATE(l.create_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY) and l.video_id =#{videoId}")
-    List<FsQwCourseWatchLogVO> selectFsCourseBeforeMonthWatchLogByVideoId(Long videoId);
-
-
-
     @Select("SELECT l.qw_external_contact_id,l.log_type,l.qw_user_id,l.create_time ,u.first_time,u.create_time lineTime FROM fs_course_watch_log  l " +
             "LEFT JOIN qw_external_contact u ON u.id=l.qw_external_contact_id  " +
             " WHERE  DATE(l.create_time) = DATE_SUB(CURDATE(), INTERVAL 2 DAY) and l.video_id =#{videoId}")
     List<FsQwCourseWatchLogVO> selectFsCourseWatchLogByNoDayAndVoidId2(Long videoId);
-
     @Select("SELECT l.qw_external_contact_id,l.log_type,l.qw_user_id,l.create_time ,u.first_time,u.create_time lineTime FROM fs_course_watch_log  l " +
             "LEFT JOIN qw_external_contact u ON u.id=l.qw_external_contact_id  " +
             " WHERE  DATE(l.create_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY) and l.sop_id =#{videoId}")
@@ -267,8 +263,38 @@ public interface FsCourseWatchLogMapper extends BaseMapper<FsCourseWatchLog> {
     @Select("SELECT qw_external_contact_id FROM fs_course_watch_log  WHERE log_type=2 and DATE(create_time) = CURDATE() ")
     List<Long> selectFsCourseWatchLogByFinish();
 
+    @Select("WITH date_series AS (\n" +
+            "  SELECT DATE_SUB(CURRENT_DATE(), INTERVAL 6-n DAY) AS report_date\n" +
+            "  FROM (\n" +
+            "    SELECT 0 AS n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 \n" +
+            "    UNION SELECT 4 UNION SELECT 5 UNION SELECT 6\n" +
+            "  ) days\n" +
+            "  ORDER BY n\n" +
+            "),\n" +
+            "daily_data AS (\n" +
+            "  SELECT \n" +
+            "    DATE(create_time) AS log_date,\n" +
+            "    log_type,\n" +
+            "    ROW_NUMBER() OVER (PARTITION BY DATE(create_time) ORDER BY create_time DESC) AS rn\n" +
+            "  FROM fs_course_watch_log\n" +
+            "  WHERE qw_external_contact_id = #{extId}\n" +
+            "    AND create_time >= DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY)\n" +
+            ")\n" +
+            "SELECT \n" +
+            "  IFNULL(dd.log_type, 0) AS log_type\n" +
+            "FROM date_series ds\n" +
+            "LEFT JOIN (\n" +
+            "  SELECT log_date, log_type FROM daily_data WHERE rn = 1\n" +
+            ") dd ON ds.report_date = dd.log_date\n" +
+            "ORDER BY ds.report_date ASC  ")
+    List<Integer> selectFsCourseWatchLog7DayByExtId(Long extId);
+
+    List<FsCourseWatchLogStatisticsListVO> selectFsCourseWatchLogStatisticsListVONew(FsCourseWatchLogStatisticsListParam param);
+
     @Select("SELECT min(create_time) FROM fs_course_watch_log WHERE user_id=#{userId} limit 1")
     Date queryFirstWatchDateLogByVideoId(@Param("userId") Long userId);
 
-    List<FsCourseWatchLogStatisticsListVO> selectFsCourseWatchLogStatisticsListVONew(FsCourseWatchLogStatisticsListParam param);
+    @Select("SELECT l.qw_external_contact_id,l.log_type,l.qw_user_id,l.create_time lineTime,l.company_user_id as company_user_id,l.user_id as user_id,l.company_id as company_id FROM fs_course_watch_log l" +
+            " WHERE DATE(l.create_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY) and l.video_id =#{videoId}")
+    List<FsQwCourseWatchLogVO> selectFsCourseBeforeMonthWatchLogByVideoId(Long videoId);
 }

+ 1 - 0
fs-service-system/src/main/java/com/fs/course/service/impl/FsCourseWatchLogServiceImpl.java

@@ -624,6 +624,7 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
 
     }
 
+
     public Long getVideoDuration(Long videoId){
         //将视频时长也存到redis
         String videoRedisKey = "h5user:video:duration:" + videoId;

+ 18 - 0
fs-service-system/src/main/java/com/fs/qw/mapper/QwWorkTaskMapper.java

@@ -1,5 +1,7 @@
 package com.fs.qw.mapper;
 
+import java.util.ArrayList;
+import java.util.List;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.fs.qw.domain.QwWorkTask;
 import com.fs.qw.param.QwWorkTaskListParam;
@@ -82,6 +84,8 @@ public interface QwWorkTaskMapper extends BaseMapper<QwWorkTask>{
             "order by t.score desc,t.id desc "+
             "</script>"})
     List<QwWorkTaskListVO> selectQwWorkTaskListVO(QwWorkTaskListParam qwWorkTask);
+    List<QwWorkTaskListVO> selectQwWorkTaskListVONew(QwWorkTaskListParam qwWorkTask);
+
     @Select("select ext_id from qw_work_task where type=2 and DATE(create_time) = CURDATE() ")
     List<Long> selectQwWorkTaskByType();
 
@@ -98,4 +102,18 @@ public interface QwWorkTaskMapper extends BaseMapper<QwWorkTask>{
             "</script>"
     })
     void updateQwWorkTaskStatus(@Param("overIds")List<Long> overIds);
+
+    @Select("select id,ext_id from qw_work_task where type=2 and status=1 and DATE(create_time) = CURDATE() ")
+    List<QwWorkTask> selectQwWorkTaskByTypeStatus1();
+    @Update({
+            "<script>",
+            "UPDATE qw_work_task",
+            "SET status = 3",
+            "WHERE id IN",
+            "<foreach item='id' collection='overIds' open='(' separator=',' close=')'>",
+            "   #{id}",
+            "</foreach>",
+            "</script>"
+    })
+    void updateQwWorkTaskStatus1(List<Long> overIds1);
 }

+ 25 - 3
fs-service-system/src/main/java/com/fs/qw/service/IQwWorkTaskService.java

@@ -61,20 +61,42 @@ public interface IQwWorkTaskService extends IService<QwWorkTask>{
      * @return 结果
      */
     int deleteQwWorkTaskById(Long id);
-
+    /**
+     * 根据用户首次上课情况,添加相应的企微任务。
+     * 用于处理首次课程触发的任务创建逻辑。
+     */
     void addQwWorkByFirstCourse();
 
-
+    /**
+     * 根据用户上课情况(通用逻辑),添加相应的企微任务。
+     * 用于处理一般课程事件触发的任务创建逻辑。
+     */
     void addQwWorkByCourse();
 
+    /**
+     * 根据转化日(或特定业务日期节点)情况,添加相应的企微任务。
+     * 用于处理基于特定日期或转化阶段的任务创建逻辑。
+     */
     void addQwWorkByConversionDay();
 
     List<QwWorkTaskListVO> selectQwWorkTaskListVO(QwWorkTaskListParam qwWorkTask);
+    List<QwWorkTaskListVO> selectQwWorkTaskListVONew(QwWorkTaskListParam qwWorkTask);
 
+    /**
+     * 根据特定课程逻辑(可能与课程编号4或第四阶段相关)添加企微任务。
+     * 用于处理与特定课程标识(如'4')相关的任务创建逻辑。
+     */
     void addQwWorkByCourse4();
 
+    /**
+     * 删除已完成、过期或不再需要的企微任务。
+     * 用于定期清理或处理生命周期结束的任务。
+     */
     void delQwWorkTaskByOver();
-
+    /**
+     * 根据用户最后一次上课时间或课程结束时间情况,添加相应的企微任务。
+     * 用于处理基于课程结束或最后活动时间的任务创建逻辑。
+     */
     void addQwWorkByCourseLastTime();
 
 }

+ 65 - 5
fs-service-system/src/main/java/com/fs/qw/service/impl/QwWorkTaskServiceImpl.java

@@ -1,7 +1,13 @@
 package com.fs.qw.service.impl;
 
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fs.common.utils.DateUtils;
+import com.fs.common.utils.DictUtils;
+import com.fs.company.cache.ICompanyCacheService;
+import com.fs.company.cache.ICompanyUserCacheService;
+import com.fs.company.domain.Company;
+import com.fs.company.domain.CompanyUser;
 import com.fs.course.mapper.FsCourseWatchLogMapper;
 import com.fs.course.mapper.FsUserCourseVideoMapper;
 import com.fs.course.vo.FsCourseWatchLogTaskVO;
@@ -17,6 +23,7 @@ import com.fs.sop.domain.QwSop;
 import com.fs.sop.domain.SopUserLogsInfo;
 import com.fs.sop.mapper.QwSopMapper;
 import com.fs.sop.mapper.SopUserLogsInfoMapper;
+import com.hc.openapi.tool.util.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -37,17 +44,18 @@ import java.util.stream.Collectors;
 public class QwWorkTaskServiceImpl extends ServiceImpl<QwWorkTaskMapper, QwWorkTask> implements IQwWorkTaskService {
     @Autowired
     private QwWorkTaskMapper qwWorkTaskMapper;
-    @Autowired
-    private FsUserCourseVideoMapper fsUserCourseVideoMapper;
-
     @Autowired
     private FsCourseWatchLogMapper fsCourseWatchLogMapper;
     @Autowired
     private QwSopMapper qwSopMapper;
     @Autowired
-    SopUserLogsInfoMapper sopUserLogsInfoMapper;
+    private SopUserLogsInfoMapper sopUserLogsInfoMapper;
+    @Autowired
+    private QwExternalContactMapper qwExternalContactMapper;
     @Autowired
-    QwExternalContactMapper qwExternalContactMapper;
+    private ICompanyCacheService companyCacheService;
+    @Autowired
+    private ICompanyUserCacheService companyUserCacheService;
     /**
      * 查询企微任务看板
      *
@@ -254,6 +262,38 @@ public class QwWorkTaskServiceImpl extends ServiceImpl<QwWorkTaskMapper, QwWorkT
         return qwWorkTaskMapper.selectQwWorkTaskListVO(qwWorkTask);
     }
 
+    @Override
+    public List<QwWorkTaskListVO> selectQwWorkTaskListVONew(QwWorkTaskListParam qwWorkTask) {
+        List<QwWorkTaskListVO> list = qwWorkTaskMapper.selectQwWorkTaskListVONew(qwWorkTask);
+        for (QwWorkTaskListVO item : list) {
+            if(ObjectUtils.isNotNull(item.getCompanyId())){
+                Company company = companyCacheService.selectCompanyById(item.getCompanyId());
+                if(ObjectUtils.isNotNull(company)){
+                    item.setCompanyName(String.format("%s_%d",company.getCompanyName(),company.getCompanyId()));
+                }
+            }
+            if(ObjectUtils.isNotNull(item.getCompanyUserId())){
+                CompanyUser companyUser = companyUserCacheService.selectCompanyUserById(item.getCompanyUserId());
+                if(ObjectUtils.isNotNull(companyUser)){
+                    item.setCompanyUserName(String.format("%s_%d", companyUser.getUserName(), companyUser.getUserId()));
+                }
+            }
+            if(ObjectUtils.isNotNull(item.getType())){
+                String kbBusinessType = DictUtils.getDictLabel("sys_qw_work_task_type", String.valueOf(item.getType()));
+                if(StringUtils.isNotBlank(kbBusinessType)){
+                    item.setTypeText(kbBusinessType);
+                }
+            }
+            if(ObjectUtils.isNotNull(item.getStatus())){
+                String kbProcessingStatus = DictUtils.getDictLabel("sys_qw_work_task_status", String.valueOf(item.getStatus()));
+                if(StringUtils.isNotBlank(kbProcessingStatus)){
+                    item.setStatusText(kbProcessingStatus);
+                }
+            }
+        }
+        return list;
+    }
+
     @Override
     public void addQwWorkByCourse4() {
         List<QwSop> qwSops = qwSopMapper.selectQwSopByIsRating();
@@ -401,6 +441,26 @@ public class QwWorkTaskServiceImpl extends ServiceImpl<QwWorkTaskMapper, QwWorkT
         }
     }
 
+    /**
+     * 根据SOP执行日志和特定条件,为符合要求的外部联系人添加企业微信工作任务。
+     * <p>
+     * 此方法仅在传入的 `day` 参数大于7时执行。
+     * 它会查询指定 `QwSop` 在过去 `day` 天内的用户执行日志 (`SopUserLogsInfo`)。
+     * 遍历日志,获取关联的外部联系人 (`QwExternalContact`)。
+     * 对联系人进行筛选:必须存在,且其级别 (`level`) 不能为 null、0 或 4。
+     * 对于通过筛选的联系人,调用内部的 `insertQwWorkTask` 方法来创建任务。
+     * </p>
+     *
+     * @param today   当前日期,用于计算查询日志的起始日期。
+     * @param day     回溯的天数。只有当 `day` 大于 7 时,才会执行添加任务的逻辑。
+     * @param qwSop   企业微信SOP(标准操作流程)对象,包含需要查询日志的SOP ID。
+     * @param title   要创建的企业微信工作任务的标题。
+     * @param map     一个映射表,键可能是外部联系人的级别 (`level`),值可能是传递给 `insertQwWorkTask` 的参数(例如优先级或特定配置)。
+     *                如果联系人级别在map中不存在,则使用默认值0。
+     * @author xdd
+     * @version 1.0
+     * @since yyyy-MM-dd // 建议替换为实际的编写或修改日期
+     */
     private void addQwWorkTask(LocalDate today, Integer day, QwSop qwSop, String title,Map<Integer, Integer> map) {
         if (day>7){
             DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

+ 9 - 3
fs-service-system/src/main/java/com/fs/qw/vo/QwWorkTaskListVO.java

@@ -3,8 +3,10 @@ package com.fs.qw.vo;
 import com.fs.common.annotation.Excel;
 import lombok.Data;
 
+import java.io.Serializable;
+
 @Data
-public class QwWorkTaskListVO {
+public class QwWorkTaskListVO implements Serializable {
     private Long id;
 
     /** 外部联系人id */
@@ -21,10 +23,12 @@ public class QwWorkTaskListVO {
     /** 类别 1先导 2 课程 3 大小转 4 转人工 */
     @Excel(name = "类别 1先导 2 课程 3 大小转 4 转人工")
     private Integer type;
+    private String typeText;
 
     /** 状态 0 待处理 1 已处理 3 过期 */
     @Excel(name = "状态 0 待处理 1 已处理 3 过期")
     private Integer status;
+    private String statusText;
 
     /** 分值 */
     @Excel(name = "分值")
@@ -35,12 +39,14 @@ public class QwWorkTaskListVO {
     private String sopId;
 
     /** 公司id */
-    @Excel(name = "公司id")
     private Long companyId;
+    @Excel(name = "公司")
+    private String companyName;
 
     /** 用户id */
-    @Excel(name = "用户id")
     private Long companyUserId;
+    @Excel(name = "销售id")
+    private String companyUserName;
 
     private String title;
 }

+ 42 - 42
fs-service-system/src/main/resources/mapper/course/FsCourseWatchLogMapper.xml

@@ -381,48 +381,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
           and fcwl.camp_period_time is not NULL
         ]]>
     </select>
-    <select id="selectFsCourseWatchLogStatisticsListVONew"
-            resultType="com.fs.course.vo.FsCourseWatchLogStatisticsListVO">
-        SELECT
-        o.company_user_id,o.user_id,DATE(o.create_time) create_time,
-        SUM(CASE WHEN o.log_type = '1' THEN 1 ELSE 0 END) AS type1,
-        SUM(CASE WHEN o.log_type = '2' THEN 1 ELSE 0 END) AS type2,
-        SUM(CASE WHEN o.log_type = '3' THEN 1 ELSE 0 END) AS type3,
-        SUM(CASE WHEN o.log_type = '4' THEN 1 ELSE 0 END) AS type4,
-        o.project as project,
-        o.course_id as course_id,
-        o.video_id as video_id
-        FROM fs_course_watch_log o
-        <where>
-            <if test="companyId != null">
-                o.company_id=#{companyId}
-            </if>
-            <if test= 'sTime != null '>
-                and DATE(o.create_time) &gt;= DATE(#{sTime})
-            </if>
-            <if test='eTime != null '>
-                and DATE(o.create_time) &lt;= DATE(#{eTime})
-            </if>
-            <if test ='courseId !=null'>
-                and o.course_id = #{courseId}
-            </if>
-            <if test ='videoId !=null'>
-                and o.video_id = #{videoId}
-            </if>
-            <if test="companyUserId != null">
-                and o.company_user_id = #{companyUserId}
-            </if>
-            <if test="project != null">
-                and o.project = #{project}
-            </if>
-            <if test="userId != null">
-                and o.user_id = #{userId}
-            </if>
-        </where>
-
-        GROUP BY o.video_id,o.user_id,DATE(o.create_time)
-        ORDER BY o.video_id ,DATE(o.create_time)
-    </select>
 
     <update id="batchUpdateWatchLog" parameterType="java.util.List">
         UPDATE fs_course_watch_log
@@ -486,4 +444,46 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             #{item.logId}
         </foreach>
     </update>
+    <select id="selectFsCourseWatchLogStatisticsListVONew"
+            resultType="com.fs.course.vo.FsCourseWatchLogStatisticsListVO">
+        SELECT
+        o.company_user_id,o.user_id,DATE(o.create_time) create_time,
+        SUM(CASE WHEN o.log_type = '1' THEN 1 ELSE 0 END) AS type1,
+        SUM(CASE WHEN o.log_type = '2' THEN 1 ELSE 0 END) AS type2,
+        SUM(CASE WHEN o.log_type = '3' THEN 1 ELSE 0 END) AS type3,
+        SUM(CASE WHEN o.log_type = '4' THEN 1 ELSE 0 END) AS type4,
+        o.project as project,
+        o.course_id as course_id,
+        o.video_id as video_id
+        FROM fs_course_watch_log o
+        <where>
+            <if test="companyId != null">
+                o.company_id=#{companyId}
+            </if>
+            <if test= 'sTime != null '>
+                and DATE(o.create_time) &gt;= DATE(#{sTime})
+            </if>
+            <if test='eTime != null '>
+                and DATE(o.create_time) &lt;= DATE(#{eTime})
+            </if>
+            <if test ='courseId !=null'>
+                and o.course_id = #{courseId}
+            </if>
+            <if test ='videoId !=null'>
+                and o.video_id = #{videoId}
+            </if>
+            <if test="companyUserId != null">
+                and o.company_user_id = #{companyUserId}
+            </if>
+            <if test="project != null">
+                and o.project = #{project}
+            </if>
+            <if test="userId != null">
+                and o.user_id = #{userId}
+            </if>
+        </where>
+
+        GROUP BY o.video_id,o.user_id,DATE(o.create_time)
+        ORDER BY o.video_id ,DATE(o.create_time)
+    </select>
 </mapper>

+ 154 - 0
fs-service-system/src/main/resources/mapper/qw/QwWorkTaskMapper.xml

@@ -0,0 +1,154 @@
+<?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.qw.mapper.QwWorkTaskMapper">
+
+    <resultMap type="QwWorkTask" id="QwWorkTaskResult">
+        <result property="id"    column="id"    />
+        <result property="extId"    column="ext_id"    />
+        <result property="qwUserId"    column="qw_user_id"    />
+        <result property="type"    column="type"    />
+        <result property="status"    column="status"    />
+        <result property="remark"    column="remark"    />
+        <result property="score"    column="score"    />
+        <result property="sopId"    column="sop_id"    />
+        <result property="companyId"    column="company_id"    />
+        <result property="companyUserId"    column="company_user_id"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateTime"    column="update_time"    />
+        <result property="title"    column="title"    />
+    </resultMap>
+
+    <sql id="selectQwWorkTaskVo">
+        select id, ext_id, qw_user_id, type,title, status, remark, score, sop_id, company_id, company_user_id, create_time, update_time from qw_work_task
+    </sql>
+
+    <select id="selectQwWorkTaskList" parameterType="QwWorkTask" resultMap="QwWorkTaskResult">
+        <include refid="selectQwWorkTaskVo"/>
+        <where>
+            <if test="extId != null "> and ext_id = #{extId}</if>
+            <if test="qwUserId != null "> and qw_user_id = #{qwUserId}</if>
+            <if test="type != null "> and type = #{type}</if>
+            <if test="status != null "> and status = #{status}</if>
+            <if test="score != null "> and score = #{score}</if>
+            <if test="sopId != null  and sopId != ''"> and sop_id = #{sopId}</if>
+            <if test="companyId != null "> and company_id = #{companyId}</if>
+            <if test="companyUserId != null "> and company_user_id = #{companyUserId}</if>
+        </where>
+    </select>
+
+    <select id="selectQwWorkTaskById" parameterType="Long" resultMap="QwWorkTaskResult">
+        <include refid="selectQwWorkTaskVo"/>
+        where id = #{id}
+    </select>
+    <select id="selectQwWorkTaskListVONew" resultType="com.fs.qw.vo.QwWorkTaskListVO">
+        select t.* from qw_work_task t
+        <where>
+            DATE(t.create_time) = CURDATE()
+            <if test="extId != null "> and t.ext_id = #{extId}</if>
+            <if test="qwUserId != null "> and t.qw_user_id = #{qwUserId}</if>
+            <if test="type != null "> and t.type = #{type}</if>
+            <if test="status != null "> and t.status = #{status}</if>
+            <if test="score != null "> and t.score = #{score}</if>
+            <if test="sopId != null  and sopId != ''"> and t.sop_id = #{sopId}</if>
+            <if test="companyId != null "> and t.company_id = #{companyId}</if>
+            <if test="companyUserId != null "> and t.company_user_id = #{companyUserId}</if>
+        </where>
+        order by t.score desc,t.id desc
+    </select>
+
+    <insert id="insertQwWorkTask" parameterType="QwWorkTask" useGeneratedKeys="true" keyProperty="id">
+        insert into qw_work_task
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="extId != null">ext_id,</if>
+            <if test="qwUserId != null">qw_user_id,</if>
+            <if test="type != null">type,</if>
+            <if test="status != null">status,</if>
+            <if test="remark != null">remark,</if>
+            <if test="score != null">score,</if>
+            <if test="sopId != null">sop_id,</if>
+            <if test="companyId != null">company_id,</if>
+            <if test="companyUserId != null">company_user_id,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateTime != null">update_time,</if>
+            <if test="title != null">title,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="extId != null">#{extId},</if>
+            <if test="qwUserId != null">#{qwUserId},</if>
+            <if test="type != null">#{type},</if>
+            <if test="status != null">#{status},</if>
+            <if test="remark != null">#{remark},</if>
+            <if test="score != null">#{score},</if>
+            <if test="sopId != null">#{sopId},</if>
+            <if test="companyId != null">#{companyId},</if>
+            <if test="companyUserId != null">#{companyUserId},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+            <if test="title != null">#{title},</if>
+         </trim>
+    </insert>
+
+    <update id="updateQwWorkTask" parameterType="QwWorkTask">
+        update qw_work_task
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="extId != null">ext_id = #{extId},</if>
+            <if test="qwUserId != null">qw_user_id = #{qwUserId},</if>
+            <if test="type != null">type = #{type},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="remark != null">remark = #{remark},</if>
+            <if test="score != null">score = #{score},</if>
+            <if test="sopId != null">sop_id = #{sopId},</if>
+            <if test="companyId != null">company_id = #{companyId},</if>
+            <if test="companyUserId != null">company_user_id = #{companyUserId},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="title != null">title = #{title},</if>
+        </trim>
+        where id = #{id}
+    </update>
+    <insert id="insertQwWorkTaskBatch" parameterType="java.util.List" useGeneratedKeys="true" keyProperty="id">
+        INSERT INTO qw_work_task (
+        ext_id,
+        qw_user_id,
+        status,
+        type,
+        title,
+        remark,
+        score,
+        sop_id,
+        company_id,
+        company_user_id,
+        create_time,
+        update_time
+        )
+        VALUES
+        <foreach collection="qwWorkTasks" item="log" separator=",">
+            (
+            #{log.extId},
+            #{log.qwUserId},
+            #{log.status},
+            #{log.type},
+            #{log.title},
+            #{log.remark},
+            #{log.score},
+            #{log.sopId},
+            #{log.companyId},
+            #{log.companyUserId},
+            #{log.createTime},
+            #{log.updateTime}
+            )
+        </foreach>
+    </insert>
+    <delete id="deleteQwWorkTaskById" parameterType="Long">
+        delete from qw_work_task where id = #{id}
+    </delete>
+
+    <delete id="deleteQwWorkTaskByIds" parameterType="String">
+        delete from qw_work_task where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>