mirror of
https://github.com/PlayEdu/PlayEdu
synced 2025-06-25 05:42:42 +08:00
学员真实学习时长记录
This commit is contained in:
parent
79297f7264
commit
39f46d5ace
@ -1,11 +1,17 @@
|
||||
package xyz.playedu.api.bus;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
import xyz.playedu.api.PlayEduFCtx;
|
||||
import xyz.playedu.api.caches.UserLastLearnTimeCache;
|
||||
import xyz.playedu.api.domain.Course;
|
||||
import xyz.playedu.api.domain.CourseHour;
|
||||
import xyz.playedu.api.domain.User;
|
||||
import xyz.playedu.api.event.UserLearnCourseUpdateEvent;
|
||||
import xyz.playedu.api.exception.ServiceException;
|
||||
import xyz.playedu.api.service.CourseService;
|
||||
import xyz.playedu.api.service.UserService;
|
||||
|
||||
@ -24,6 +30,12 @@ public class UserBus {
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@Autowired
|
||||
private UserLastLearnTimeCache userLastLearnTimeCache;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext ctx;
|
||||
|
||||
public boolean canSeeCourse(User user, Course course) {
|
||||
List<Integer> courseDepIds = courseService.getDepIdsByCourseId(course.getId());
|
||||
if (courseDepIds == null || courseDepIds.size() == 0) {
|
||||
@ -37,4 +49,19 @@ public class UserBus {
|
||||
return CollectionUtils.intersection(courseDepIds, userDepIds).size() > 0;
|
||||
}
|
||||
|
||||
public void userLearnDurationRecord(User user, Course course, CourseHour hour) {
|
||||
Long curTime = System.currentTimeMillis();
|
||||
|
||||
// 最近一次学习时间
|
||||
Long lastTime = userLastLearnTimeCache.get(PlayEduFCtx.getUserId());
|
||||
// 最大周期为10s
|
||||
if (lastTime == null || curTime - lastTime > 10000) {
|
||||
lastTime = curTime - 10000;
|
||||
}
|
||||
|
||||
userLastLearnTimeCache.put(user.getId(), curTime);
|
||||
|
||||
ctx.publishEvent(new UserLearnCourseUpdateEvent(this, user.getId(), course.getId(), hour.getId(), lastTime, curTime));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -25,12 +25,13 @@ public class UserCanSeeCourseCache {
|
||||
public boolean check(User user, Course course, boolean isThrow) throws ServiceException {
|
||||
boolean result;
|
||||
if (RedisUtil.exists(key(user, course))) {
|
||||
result = "1".equals(RedisUtil.get(key(user, course)));
|
||||
String cacheResult = (String) RedisUtil.get(key(user, course));
|
||||
result = "1".equals(cacheResult);
|
||||
} else {
|
||||
result = userBus.canSeeCourse(user, course);
|
||||
put(user, course, result);
|
||||
}
|
||||
if (isThrow) {
|
||||
if (!result && isThrow) {
|
||||
throw new ServiceException("无权限观看");
|
||||
}
|
||||
return result;
|
||||
|
@ -0,0 +1,24 @@
|
||||
package xyz.playedu.api.caches;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import xyz.playedu.api.util.RedisUtil;
|
||||
|
||||
/**
|
||||
* @Author 杭州白书科技有限公司
|
||||
* @create 2023/3/22 13:57
|
||||
*/
|
||||
@Component
|
||||
public class UserLastLearnTimeCache {
|
||||
|
||||
private final static String groupName = "user-learn-last-timestamp";
|
||||
|
||||
private final static int expire = 9500;//9.5s
|
||||
|
||||
public Long get(Integer userId) {
|
||||
return (Long) RedisUtil.hGet(groupName, userId + "");
|
||||
}
|
||||
|
||||
public void put(Integer userId, Long timestamp) {
|
||||
RedisUtil.hSet(groupName, userId + "", timestamp);
|
||||
}
|
||||
}
|
@ -1,17 +1,16 @@
|
||||
package xyz.playedu.api.controller.frontend;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import xyz.playedu.api.PlayEduFCtx;
|
||||
import xyz.playedu.api.bus.UserBus;
|
||||
import xyz.playedu.api.caches.CourseCache;
|
||||
import xyz.playedu.api.caches.UserCanSeeCourseCache;
|
||||
import xyz.playedu.api.domain.*;
|
||||
import xyz.playedu.api.exception.NotFoundException;
|
||||
import xyz.playedu.api.exception.ServiceException;
|
||||
import xyz.playedu.api.request.frontend.CourseHourRecordRequest;
|
||||
import xyz.playedu.api.service.CourseHourService;
|
||||
import xyz.playedu.api.service.CourseService;
|
||||
import xyz.playedu.api.service.ResourceService;
|
||||
import xyz.playedu.api.service.UserCourseHourRecordService;
|
||||
import xyz.playedu.api.types.JsonResponse;
|
||||
@ -26,9 +25,6 @@ import java.util.HashMap;
|
||||
@RequestMapping("/api/v1/course/{courseId}/hour")
|
||||
public class HourController {
|
||||
|
||||
@Autowired
|
||||
private CourseService courseService;
|
||||
|
||||
@Autowired
|
||||
private CourseHourService hourService;
|
||||
|
||||
@ -39,13 +35,18 @@ public class HourController {
|
||||
private UserCourseHourRecordService userCourseHourRecordService;
|
||||
|
||||
@Autowired
|
||||
private UserCanSeeCourseCache userCanSeeCourseCache;
|
||||
private UserBus userBus;
|
||||
|
||||
|
||||
// ------- CACHE ----------
|
||||
@Autowired
|
||||
private UserCanSeeCourseCache userCanSeeCourseCache;
|
||||
@Autowired
|
||||
private CourseCache courseCache;
|
||||
|
||||
@GetMapping("/{id}/play")
|
||||
public JsonResponse play(@PathVariable(name = "courseId") Integer courseId, @PathVariable(name = "id") Integer id) throws NotFoundException, ServiceException {
|
||||
@SneakyThrows
|
||||
public JsonResponse play(@PathVariable(name = "courseId") Integer courseId, @PathVariable(name = "id") Integer id) {
|
||||
Course course = courseCache.findOrFail(courseId);
|
||||
userCanSeeCourseCache.check(PlayEduFCtx.getUser(), course, true);
|
||||
CourseHour hour = hourService.findOrFail(id, courseId);
|
||||
@ -60,7 +61,8 @@ public class HourController {
|
||||
}
|
||||
|
||||
@PostMapping("/{id}/record")
|
||||
public JsonResponse record(@PathVariable(name = "courseId") Integer courseId, @PathVariable(name = "id") Integer id, @RequestBody @Validated CourseHourRecordRequest req) throws NotFoundException, ServiceException {
|
||||
@SneakyThrows
|
||||
public JsonResponse record(@PathVariable(name = "courseId") Integer courseId, @PathVariable(name = "id") Integer id, @RequestBody @Validated CourseHourRecordRequest req) {
|
||||
Integer duration = req.getDuration();
|
||||
if (duration <= 0) {
|
||||
return JsonResponse.error("duration参数错误");
|
||||
@ -79,9 +81,12 @@ public class HourController {
|
||||
}
|
||||
|
||||
@PostMapping("/{id}/ping")
|
||||
public JsonResponse ping(@PathVariable(name = "courseId") Integer courseId, @PathVariable(name = "id") Integer id) throws NotFoundException, ServiceException {
|
||||
@SneakyThrows
|
||||
public JsonResponse ping(@PathVariable(name = "courseId") Integer courseId, @PathVariable(name = "id") Integer id) {
|
||||
Course course = courseCache.findOrFail(courseId);
|
||||
CourseHour hour = hourService.findOrFail(id, courseId);
|
||||
userCanSeeCourseCache.check(PlayEduFCtx.getUser(), course, true);
|
||||
userBus.userLearnDurationRecord(PlayEduFCtx.getUser(), course, hour);
|
||||
return JsonResponse.success();
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,6 @@ import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
@ -26,13 +24,12 @@ public class UserLearnDurationRecord implements Serializable {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@JsonProperty("user_id")
|
||||
private Integer userId;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private Date date;
|
||||
private Date createdDate;
|
||||
|
||||
/**
|
||||
* 已学习时长[微秒]
|
||||
@ -42,15 +39,23 @@ public class UserLearnDurationRecord implements Serializable {
|
||||
/**
|
||||
* 开始时间
|
||||
*/
|
||||
@JsonProperty("start_at")
|
||||
private Date startAt;
|
||||
|
||||
/**
|
||||
* 结束时间
|
||||
*/
|
||||
@JsonProperty("end_at")
|
||||
private Date endAt;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private Integer courseId;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private Integer hourId;
|
||||
|
||||
@TableField(exist = false)
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ -68,10 +73,12 @@ public class UserLearnDurationRecord implements Serializable {
|
||||
UserLearnDurationRecord other = (UserLearnDurationRecord) that;
|
||||
return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
|
||||
&& (this.getUserId() == null ? other.getUserId() == null : this.getUserId().equals(other.getUserId()))
|
||||
&& (this.getDate() == null ? other.getDate() == null : this.getDate().equals(other.getDate()))
|
||||
&& (this.getCreatedDate() == null ? other.getCreatedDate() == null : this.getCreatedDate().equals(other.getCreatedDate()))
|
||||
&& (this.getDuration() == null ? other.getDuration() == null : this.getDuration().equals(other.getDuration()))
|
||||
&& (this.getStartAt() == null ? other.getStartAt() == null : this.getStartAt().equals(other.getStartAt()))
|
||||
&& (this.getEndAt() == null ? other.getEndAt() == null : this.getEndAt().equals(other.getEndAt()));
|
||||
&& (this.getEndAt() == null ? other.getEndAt() == null : this.getEndAt().equals(other.getEndAt()))
|
||||
&& (this.getCourseId() == null ? other.getCourseId() == null : this.getCourseId().equals(other.getCourseId()))
|
||||
&& (this.getHourId() == null ? other.getHourId() == null : this.getHourId().equals(other.getHourId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -80,10 +87,12 @@ public class UserLearnDurationRecord implements Serializable {
|
||||
int result = 1;
|
||||
result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
|
||||
result = prime * result + ((getUserId() == null) ? 0 : getUserId().hashCode());
|
||||
result = prime * result + ((getDate() == null) ? 0 : getDate().hashCode());
|
||||
result = prime * result + ((getCreatedDate() == null) ? 0 : getCreatedDate().hashCode());
|
||||
result = prime * result + ((getDuration() == null) ? 0 : getDuration().hashCode());
|
||||
result = prime * result + ((getStartAt() == null) ? 0 : getStartAt().hashCode());
|
||||
result = prime * result + ((getEndAt() == null) ? 0 : getEndAt().hashCode());
|
||||
result = prime * result + ((getCourseId() == null) ? 0 : getCourseId().hashCode());
|
||||
result = prime * result + ((getHourId() == null) ? 0 : getHourId().hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -95,10 +104,12 @@ public class UserLearnDurationRecord implements Serializable {
|
||||
sb.append("Hash = ").append(hashCode());
|
||||
sb.append(", id=").append(id);
|
||||
sb.append(", userId=").append(userId);
|
||||
sb.append(", date=").append(date);
|
||||
sb.append(", createdDate=").append(createdDate);
|
||||
sb.append(", duration=").append(duration);
|
||||
sb.append(", startAt=").append(startAt);
|
||||
sb.append(", endAt=").append(endAt);
|
||||
sb.append(", courseId=").append(courseId);
|
||||
sb.append(", hourId=").append(hourId);
|
||||
sb.append(", serialVersionUID=").append(serialVersionUID);
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
|
@ -0,0 +1,85 @@
|
||||
package xyz.playedu.api.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
*
|
||||
* @TableName user_learn_duration_stats
|
||||
*/
|
||||
@TableName(value ="user_learn_duration_stats")
|
||||
@Data
|
||||
public class UserLearnDurationStats implements Serializable {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Integer id;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private Integer userId;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private Integer duration;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private Date createdDate;
|
||||
|
||||
@TableField(exist = false)
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object that) {
|
||||
if (this == that) {
|
||||
return true;
|
||||
}
|
||||
if (that == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != that.getClass()) {
|
||||
return false;
|
||||
}
|
||||
UserLearnDurationStats other = (UserLearnDurationStats) that;
|
||||
return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
|
||||
&& (this.getUserId() == null ? other.getUserId() == null : this.getUserId().equals(other.getUserId()))
|
||||
&& (this.getDuration() == null ? other.getDuration() == null : this.getDuration().equals(other.getDuration()))
|
||||
&& (this.getCreatedDate() == null ? other.getCreatedDate() == null : this.getCreatedDate().equals(other.getCreatedDate()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
|
||||
result = prime * result + ((getUserId() == null) ? 0 : getUserId().hashCode());
|
||||
result = prime * result + ((getDuration() == null) ? 0 : getDuration().hashCode());
|
||||
result = prime * result + ((getCreatedDate() == null) ? 0 : getCreatedDate().hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(getClass().getSimpleName());
|
||||
sb.append(" [");
|
||||
sb.append("Hash = ").append(hashCode());
|
||||
sb.append(", id=").append(id);
|
||||
sb.append(", userId=").append(userId);
|
||||
sb.append(", duration=").append(duration);
|
||||
sb.append(", createdDate=").append(createdDate);
|
||||
sb.append(", serialVersionUID=").append(serialVersionUID);
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package xyz.playedu.api.event;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @Author 杭州白书科技有限公司
|
||||
* @create 2023/3/22 14:14
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
public class UserLearnCourseUpdateEvent extends ApplicationEvent {
|
||||
|
||||
private Integer userId;
|
||||
private Integer courseId;
|
||||
private Integer hourId;
|
||||
private Long startAt;
|
||||
private Long endAt;
|
||||
|
||||
public UserLearnCourseUpdateEvent(Object source, Integer userId, Integer courseId, Integer hourId, Long startTime, Long endTime) {
|
||||
super(source);
|
||||
this.userId = userId;
|
||||
this.courseId = courseId;
|
||||
this.hourId = hourId;
|
||||
this.startAt = startTime;
|
||||
this.endAt = endTime;
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package xyz.playedu.api.listener;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
import xyz.playedu.api.event.UserLearnCourseUpdateEvent;
|
||||
import xyz.playedu.api.service.UserLearnDurationRecordService;
|
||||
import xyz.playedu.api.service.UserLearnDurationStatsService;
|
||||
|
||||
/**
|
||||
* @Author 杭州白书科技有限公司
|
||||
* @create 2023/3/22 14:18
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class UserLearnCourseUpdateListener {
|
||||
|
||||
@Autowired
|
||||
private UserLearnDurationRecordService userLearnDurationRecordService;
|
||||
|
||||
@Autowired
|
||||
private UserLearnDurationStatsService userLearnDurationStatsService;
|
||||
|
||||
@Async
|
||||
@EventListener
|
||||
public void storeLearnDuration(UserLearnCourseUpdateEvent event) {
|
||||
// 观看时长统计
|
||||
userLearnDurationStatsService.storeOrUpdate(event.getUserId(), event.getStartAt(), event.getEndAt());
|
||||
// 观看记录
|
||||
userLearnDurationRecordService.store(event.getUserId(), event.getCourseId(), event.getHourId(), event.getStartAt(), event.getEndAt());
|
||||
}
|
||||
|
||||
}
|
@ -7,7 +7,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
/**
|
||||
* @author tengteng
|
||||
* @description 针对表【user_learn_duration_records】的数据库操作Mapper
|
||||
* @createDate 2023-03-20 16:41:12
|
||||
* @createDate 2023-03-22 13:55:17
|
||||
* @Entity xyz.playedu.api.domain.UserLearnDurationRecord
|
||||
*/
|
||||
@Mapper
|
||||
|
@ -0,0 +1,20 @@
|
||||
package xyz.playedu.api.mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import xyz.playedu.api.domain.UserLearnDurationStats;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* @author tengteng
|
||||
* @description 针对表【user_learn_duration_stats】的数据库操作Mapper
|
||||
* @createDate 2023-03-22 13:55:29
|
||||
* @Entity xyz.playedu.api.domain.UserLearnDurationStats
|
||||
*/
|
||||
@Mapper
|
||||
public interface UserLearnDurationStatsMapper extends BaseMapper<UserLearnDurationStats> {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -4,10 +4,10 @@ import xyz.playedu.api.domain.UserLearnDurationRecord;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* @author tengteng
|
||||
* @description 针对表【user_learn_duration_records】的数据库操作Service
|
||||
* @createDate 2023-03-20 16:41:12
|
||||
*/
|
||||
* @author tengteng
|
||||
* @description 针对表【user_learn_duration_records】的数据库操作Service
|
||||
* @createDate 2023-03-20 16:41:12
|
||||
*/
|
||||
public interface UserLearnDurationRecordService extends IService<UserLearnDurationRecord> {
|
||||
|
||||
void store(Integer userId, Integer courseId, Integer hourId, Long startTime, Long endTime);
|
||||
}
|
||||
|
@ -0,0 +1,13 @@
|
||||
package xyz.playedu.api.service;
|
||||
|
||||
import xyz.playedu.api.domain.UserLearnDurationStats;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* @author tengteng
|
||||
* @description 针对表【user_learn_duration_stats】的数据库操作Service
|
||||
* @createDate 2023-03-22 13:55:29
|
||||
*/
|
||||
public interface UserLearnDurationStatsService extends IService<UserLearnDurationStats> {
|
||||
void storeOrUpdate(Integer userId, Long startTime, Long endTime);
|
||||
}
|
@ -1,20 +1,42 @@
|
||||
package xyz.playedu.api.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.SneakyThrows;
|
||||
import xyz.playedu.api.domain.UserLearnDurationRecord;
|
||||
import xyz.playedu.api.service.UserLearnDurationRecordService;
|
||||
import xyz.playedu.api.mapper.UserLearnDurationRecordMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author tengteng
|
||||
* @description 针对表【user_learn_duration_records】的数据库操作Service实现
|
||||
* @createDate 2023-03-20 16:41:12
|
||||
*/
|
||||
* @author tengteng
|
||||
* @description 针对表【user_learn_duration_records】的数据库操作Service实现
|
||||
* @createDate 2023-03-20 16:41:12
|
||||
*/
|
||||
@Service
|
||||
public class UserLearnDurationRecordServiceImpl extends ServiceImpl<UserLearnDurationRecordMapper, UserLearnDurationRecord>
|
||||
implements UserLearnDurationRecordService{
|
||||
implements UserLearnDurationRecordService {
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void store(Integer userId, Integer courseId, Integer hourId, Long startTime, Long endTime) {
|
||||
// 处理日期
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||
String date = simpleDateFormat.format(new Date(endTime));
|
||||
|
||||
UserLearnDurationRecord record = new UserLearnDurationRecord();
|
||||
record.setUserId(userId);
|
||||
record.setCourseId(courseId);
|
||||
record.setHourId(hourId);
|
||||
record.setStartAt(new Date(startTime));
|
||||
record.setEndAt(new Date(endTime));
|
||||
record.setDuration((int) (endTime - startTime));
|
||||
record.setCreatedDate(simpleDateFormat.parse(date));
|
||||
|
||||
save(record);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,50 @@
|
||||
package xyz.playedu.api.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.SneakyThrows;
|
||||
import xyz.playedu.api.domain.UserLearnDurationStats;
|
||||
import xyz.playedu.api.service.UserLearnDurationStatsService;
|
||||
import xyz.playedu.api.mapper.UserLearnDurationStatsMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author tengteng
|
||||
* @description 针对表【user_learn_duration_stats】的数据库操作Service实现
|
||||
* @createDate 2023-03-22 13:55:29
|
||||
*/
|
||||
@Service
|
||||
public class UserLearnDurationStatsServiceImpl extends ServiceImpl<UserLearnDurationStatsMapper, UserLearnDurationStats>
|
||||
implements UserLearnDurationStatsService {
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void storeOrUpdate(Integer userId, Long startTime, Long endTime) {
|
||||
// 处理日期
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||
String date = simpleDateFormat.format(new Date(endTime));
|
||||
// duration
|
||||
Long duration = endTime - startTime;
|
||||
|
||||
UserLearnDurationStats stats = getOne(query().getWrapper().eq("user_id", userId).eq("created_date", date));
|
||||
if (stats == null) {
|
||||
UserLearnDurationStats newStats = new UserLearnDurationStats();
|
||||
newStats.setUserId(userId);
|
||||
newStats.setDuration(Math.toIntExact(duration));
|
||||
newStats.setCreatedDate(simpleDateFormat.parse(date));
|
||||
save(newStats);
|
||||
return;
|
||||
}
|
||||
|
||||
UserLearnDurationStats newStats = new UserLearnDurationStats();
|
||||
newStats.setId(stats.getId());
|
||||
newStats.setDuration((int) (stats.getDuration() + duration));
|
||||
updateById(newStats);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -7,14 +7,17 @@
|
||||
<resultMap id="BaseResultMap" type="xyz.playedu.api.domain.UserLearnDurationRecord">
|
||||
<id property="id" column="id" jdbcType="BIGINT"/>
|
||||
<result property="userId" column="user_id" jdbcType="INTEGER"/>
|
||||
<result property="date" column="date" jdbcType="DATE"/>
|
||||
<result property="createdDate" column="created_date" jdbcType="DATE"/>
|
||||
<result property="duration" column="duration" jdbcType="INTEGER"/>
|
||||
<result property="startAt" column="start_at" jdbcType="TIMESTAMP"/>
|
||||
<result property="endAt" column="end_at" jdbcType="TIMESTAMP"/>
|
||||
<result property="courseId" column="course_id" jdbcType="INTEGER"/>
|
||||
<result property="hourId" column="hour_id" jdbcType="INTEGER"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
id,user_id,date,
|
||||
duration,start_at,end_at
|
||||
id,user_id,created_date,
|
||||
duration,start_at,end_at,
|
||||
course_id,hour_id
|
||||
</sql>
|
||||
</mapper>
|
||||
|
18
src/main/resources/mapper/UserLearnDurationStatsMapper.xml
Normal file
18
src/main/resources/mapper/UserLearnDurationStatsMapper.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<?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="xyz.playedu.api.mapper.UserLearnDurationStatsMapper">
|
||||
|
||||
<resultMap id="BaseResultMap" type="xyz.playedu.api.domain.UserLearnDurationStats">
|
||||
<id property="id" column="id" jdbcType="INTEGER"/>
|
||||
<result property="userId" column="user_id" jdbcType="INTEGER"/>
|
||||
<result property="duration" column="duration" jdbcType="INTEGER"/>
|
||||
<result property="createdDate" column="created_date" jdbcType="DATE"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
id,user_id,duration,
|
||||
created_date
|
||||
</sql>
|
||||
</mapper>
|
Loading…
x
Reference in New Issue
Block a user