Commit 06a8f54a authored by liuyang's avatar liuyang

记录用户观看课程数据

parent 8bc20f11
...@@ -6,6 +6,7 @@ import org.springframework.boot.web.servlet.ServletComponentScan; ...@@ -6,6 +6,7 @@ import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan;
import org.springframework.retry.annotation.EnableRetry; import org.springframework.retry.annotation.EnableRetry;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication @SpringBootApplication
@ComponentScan(basePackages = { @ComponentScan(basePackages = {
...@@ -14,6 +15,7 @@ import org.springframework.retry.annotation.EnableRetry; ...@@ -14,6 +15,7 @@ import org.springframework.retry.annotation.EnableRetry;
@ServletComponentScan @ServletComponentScan
@EnableCaching @EnableCaching
@EnableRetry @EnableRetry
@EnableScheduling
public class Application { public class Application {
public static void main(String[] args) { public static void main(String[] args) {
......
...@@ -30,4 +30,6 @@ public class BizConstants { ...@@ -30,4 +30,6 @@ public class BizConstants {
public static final String SMS_TEMPLATE_CODE = "T_LG_CAPTCHA"; public static final String SMS_TEMPLATE_CODE = "T_LG_CAPTCHA";
public static final String MOBILE_CAPTCHA_PREFIX = "CAPTCHA_"; public static final String MOBILE_CAPTCHA_PREFIX = "CAPTCHA_";
public static final String CACHE_KE_CONSUME_RECORD = "CONSUME_RECORD";
} }
package com.qkdata.biz.management.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.qkdata.common.base.entity.BasePO;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
/**
* <p>
* 课程消耗记录
* </p>
*
* @author liuyang
* @since 2021-06-09
*/
@Data
@TableName("course_consume_record")
public class CourseConsumeRecordPO {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.INPUT)
private String id;
/**
* 用户ID
*/
private Long userId;
/**
* 观看时长(秒)
*/
private Integer watchTime;
/**
* 课程ID
*/
private Long courseId;
/**
* 章节ID
*/
private Long chapterId;
@ApiModelProperty(example = "1619423186000")
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
@ApiModelProperty(example = "1619423186000")
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
}
package com.qkdata.biz.management.mapper;
import com.qkdata.biz.management.entity.CourseConsumeRecordPO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 课程消耗记录 Mapper 接口
* </p>
*
* @author liuyang
* @since 2021-06-09
*/
@Mapper
public interface CourseConsumeRecordMapper extends BaseMapper<CourseConsumeRecordPO> {
}
package com.qkdata.biz.management.service;
import com.qkdata.biz.management.entity.CourseConsumeRecordPO;
import com.qkdata.biz.management.mapper.CourseConsumeRecordMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* $!{table.comment} 服务类
* </p>
*
* @author liuyang
* @since 2021-06-09
*/
@Service
public class CourseConsumeRecordService extends ServiceImpl<CourseConsumeRecordMapper, CourseConsumeRecordPO> {
}
\ No newline at end of file
package com.qkdata.biz.management.service;
import com.google.common.collect.Lists;
import com.qkdata.biz.common.BizConstants;
import com.qkdata.biz.management.entity.CourseConsumeRecordPO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Set;
/**
* 定时任务
*/
@Slf4j
@Service
public class TimeTaskService {
@Autowired
@Qualifier("objectRedisTemplate")
private RedisTemplate redisTemplate;
@Autowired
private CourseConsumeRecordService recordService;
/**
* 每30分钟执行一次
*/
@Scheduled(cron = "0 */30 * * * ?")
public void saveConsumeRecord(){
log.debug("TimeTaskService saveConsumeRecord excute start=================");
Set<String> keys = redisTemplate.opsForHash().keys(BizConstants.CACHE_KE_CONSUME_RECORD);
List<CourseConsumeRecordPO> saveList = Lists.newArrayList();
for (String key : keys){
CourseConsumeRecordPO po = (CourseConsumeRecordPO) redisTemplate.opsForHash().get(BizConstants.CACHE_KE_CONSUME_RECORD,key);
saveList.add(po);
redisTemplate.opsForHash().delete(BizConstants.CACHE_KE_CONSUME_RECORD,key);
}
if (saveList.size() > 0){
recordService.saveOrUpdateBatch(saveList);
}
log.debug("TimeTaskService saveConsumeRecord excute end=================");
}
}
package com.qkdata.biz.web.controller; package com.qkdata.biz.web.controller;
import com.qkdata.biz.common.BizConstants; import com.qkdata.biz.common.BizConstants;
import com.qkdata.biz.web.vo.CourseConsumeRecordModel; import com.qkdata.biz.management.entity.CourseConsumeRecordPO;
import com.qkdata.biz.web.vo.SaveConsumeRecord;
import com.qkdata.common.base.model.Result; import com.qkdata.common.base.model.Result;
import com.qkdata.common.util.UserContext;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.Logical; import org.apache.shiro.authz.annotation.Logical;
...@@ -28,15 +30,23 @@ public class CourseConsumeRecordController { ...@@ -28,15 +30,23 @@ public class CourseConsumeRecordController {
@ApiOperation("记录课程消耗记录") @ApiOperation("记录课程消耗记录")
@PostMapping("/save") @PostMapping("/save")
@RequiresRoles(value = {BizConstants.ROLE_USER,BizConstants.ROLE_ENTERPRISE_ADMIN},logical = Logical.OR) @RequiresRoles(value = {BizConstants.ROLE_USER,BizConstants.ROLE_ENTERPRISE_ADMIN},logical = Logical.OR)
public Result<String> save(@RequestBody CourseConsumeRecordModel model){ public Result<String> save(@RequestBody SaveConsumeRecord model){
if(redisTemplate.hasKey(model.getUuid())){
CourseConsumeRecordModel cacheModel = (CourseConsumeRecordModel) redisTemplate.opsForValue().get(model.getUuid()); if(redisTemplate.opsForHash().hasKey(BizConstants.CACHE_KE_CONSUME_RECORD,model.getUuid())){
cacheModel.setLearnDuration(model.getLearnDuration()); CourseConsumeRecordPO cacheModel = (CourseConsumeRecordPO) redisTemplate.opsForHash().get(BizConstants.CACHE_KE_CONSUME_RECORD,model.getUuid());
redisTemplate.opsForValue().set(cacheModel.getUuid(),cacheModel); cacheModel.setWatchTime(model.getLearnDuration());
redisTemplate.opsForHash().put(BizConstants.CACHE_KE_CONSUME_RECORD,cacheModel.getId(),cacheModel);
}else { }else {
model.setStartTime(LocalDateTime.now()); CourseConsumeRecordPO po = new CourseConsumeRecordPO();
redisTemplate.opsForValue().set(model.getUuid(),model); po.setId(model.getUuid());
po.setUserId(UserContext.getUserId());
po.setCourseId(model.getCourseId());
po.setChapterId(model.getChaperId());
po.setWatchTime(model.getLearnDuration());
po.setCreateTime(LocalDateTime.now());
redisTemplate.opsForHash().put(BizConstants.CACHE_KE_CONSUME_RECORD,po.getId(),po);
} }
return Result.succeed("ok"); return Result.succeed("ok");
} }
} }
...@@ -8,7 +8,7 @@ import java.time.LocalDateTime; ...@@ -8,7 +8,7 @@ import java.time.LocalDateTime;
* 课程消耗记录 * 课程消耗记录
*/ */
@Data @Data
public class CourseConsumeRecordModel { public class SaveConsumeRecord {
/** /**
* 本次观看唯一标识 * 本次观看唯一标识
*/ */
......
ALTER TABLE `course_consume_record`
DROP COLUMN `video_id`,
MODIFY COLUMN `id` varchar(36) NOT NULL COMMENT '主键' FIRST,
MODIFY COLUMN `watch_time` int(11) NULL DEFAULT NULL COMMENT '观看时长(秒)' AFTER `user_id`;
\ No newline at end of file
<?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.qkdata.biz.management.mapper.CourseConsumeRecordMapper">
</mapper>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment