mirror of
https://github.com/PlayEdu/PlayEdu
synced 2025-07-24 02:09:35 +08:00
学员的学习记录增加爱锁控制
This commit is contained in:
parent
abf6a36c4f
commit
246cfe6501
@ -60,6 +60,7 @@ public class UserBus {
|
|||||||
return CollectionUtils.intersection(courseDepIds, userDepIds).size() > 0;
|
return CollectionUtils.intersection(courseDepIds, userDepIds).size() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 注意,调用该方法需要考虑到并发写入问题
|
||||||
public void userLearnDurationRecord(User user, Course course, CourseHour hour) {
|
public void userLearnDurationRecord(User user, Course course, CourseHour hour) {
|
||||||
Long curTime = System.currentTimeMillis();
|
Long curTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
@ -32,8 +32,10 @@ import xyz.playedu.api.service.CourseService;
|
|||||||
import xyz.playedu.api.service.ResourceService;
|
import xyz.playedu.api.service.ResourceService;
|
||||||
import xyz.playedu.api.service.UserCourseHourRecordService;
|
import xyz.playedu.api.service.UserCourseHourRecordService;
|
||||||
import xyz.playedu.api.types.JsonResponse;
|
import xyz.playedu.api.types.JsonResponse;
|
||||||
|
import xyz.playedu.api.util.RedisDistributedLock;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author 杭州白书科技有限公司
|
* @Author 杭州白书科技有限公司
|
||||||
@ -58,6 +60,8 @@ public class HourController {
|
|||||||
@Autowired private UserCanSeeCourseCache userCanSeeCourseCache;
|
@Autowired private UserCanSeeCourseCache userCanSeeCourseCache;
|
||||||
@Autowired private CourseCache courseCache;
|
@Autowired private CourseCache courseCache;
|
||||||
|
|
||||||
|
@Autowired private RedisDistributedLock redisDistributedLock;
|
||||||
|
|
||||||
@GetMapping("/{id}")
|
@GetMapping("/{id}")
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public JsonResponse detail(
|
public JsonResponse detail(
|
||||||
@ -108,13 +112,23 @@ public class HourController {
|
|||||||
if (duration <= 0) {
|
if (duration <= 0) {
|
||||||
return JsonResponse.error("duration参数错误");
|
return JsonResponse.error("duration参数错误");
|
||||||
}
|
}
|
||||||
User user = FCtx.getUser();
|
|
||||||
Course course = courseCache.findOrFail(courseId);
|
Course course = courseCache.findOrFail(courseId);
|
||||||
userCanSeeCourseCache.check(user, course, true);
|
|
||||||
CourseHour hour = hourService.findOrFail(id, courseId);
|
CourseHour hour = hourService.findOrFail(id, courseId);
|
||||||
|
userCanSeeCourseCache.check(FCtx.getUser(), course, true);
|
||||||
|
|
||||||
|
// 获取锁
|
||||||
|
String lockKey = String.format("record:%d", FCtx.getId());
|
||||||
|
boolean tryLock = redisDistributedLock.tryLock(lockKey, 5, TimeUnit.SECONDS);
|
||||||
|
if (!tryLock) {
|
||||||
|
return JsonResponse.error("请稍后再试");
|
||||||
|
}
|
||||||
|
|
||||||
userCourseHourRecordService.storeOrUpdate(
|
userCourseHourRecordService.storeOrUpdate(
|
||||||
user.getId(), course.getId(), hour.getId(), duration, hour.getDuration());
|
FCtx.getId(), course.getId(), hour.getId(), duration, hour.getDuration());
|
||||||
|
|
||||||
|
// 此处未考虑上面代码执行失败释放锁
|
||||||
|
redisDistributedLock.releaseLock(lockKey);
|
||||||
|
|
||||||
return JsonResponse.success();
|
return JsonResponse.success();
|
||||||
}
|
}
|
||||||
@ -127,7 +141,19 @@ public class HourController {
|
|||||||
Course course = courseCache.findOrFail(courseId);
|
Course course = courseCache.findOrFail(courseId);
|
||||||
CourseHour hour = hourService.findOrFail(id, courseId);
|
CourseHour hour = hourService.findOrFail(id, courseId);
|
||||||
userCanSeeCourseCache.check(FCtx.getUser(), course, true);
|
userCanSeeCourseCache.check(FCtx.getUser(), course, true);
|
||||||
|
|
||||||
|
// 获取锁
|
||||||
|
String lockKey = String.format("ping:%d", FCtx.getId());
|
||||||
|
boolean tryLock = redisDistributedLock.tryLock(lockKey, 5, TimeUnit.SECONDS);
|
||||||
|
if (!tryLock) {
|
||||||
|
return JsonResponse.error("请稍后再试");
|
||||||
|
}
|
||||||
|
|
||||||
userBus.userLearnDurationRecord(FCtx.getUser(), course, hour);
|
userBus.userLearnDurationRecord(FCtx.getUser(), course, hour);
|
||||||
|
|
||||||
|
// 此处未考虑上面代码执行失败释放锁
|
||||||
|
redisDistributedLock.releaseLock(lockKey);
|
||||||
|
|
||||||
return JsonResponse.success();
|
return JsonResponse.success();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,6 @@ package xyz.playedu.api.listener;
|
|||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.event.EventListener;
|
import org.springframework.context.event.EventListener;
|
||||||
import org.springframework.scheduling.annotation.Async;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import xyz.playedu.api.event.UserCourseHourFinishedEvent;
|
import xyz.playedu.api.event.UserCourseHourFinishedEvent;
|
||||||
@ -39,7 +38,6 @@ public class UserCourseHourFinishedListener {
|
|||||||
|
|
||||||
@Autowired private CourseHourService hourService;
|
@Autowired private CourseHourService hourService;
|
||||||
|
|
||||||
@Async
|
|
||||||
@EventListener
|
@EventListener
|
||||||
public void userCourseProgressUpdate(UserCourseHourFinishedEvent evt) {
|
public void userCourseProgressUpdate(UserCourseHourFinishedEvent evt) {
|
||||||
Integer hourCount = hourService.getCountByCourseId(evt.getCourseId());
|
Integer hourCount = hourService.getCountByCourseId(evt.getCourseId());
|
||||||
|
@ -19,7 +19,6 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.event.EventListener;
|
import org.springframework.context.event.EventListener;
|
||||||
import org.springframework.scheduling.annotation.Async;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import xyz.playedu.api.event.UserLearnCourseUpdateEvent;
|
import xyz.playedu.api.event.UserLearnCourseUpdateEvent;
|
||||||
@ -39,7 +38,6 @@ public class UserLearnCourseUpdateListener {
|
|||||||
|
|
||||||
@Autowired private UserLearnDurationStatsService userLearnDurationStatsService;
|
@Autowired private UserLearnDurationStatsService userLearnDurationStatsService;
|
||||||
|
|
||||||
@Async
|
|
||||||
@EventListener
|
@EventListener
|
||||||
public void storeLearnDuration(UserLearnCourseUpdateEvent event) {
|
public void storeLearnDuration(UserLearnCourseUpdateEvent event) {
|
||||||
// 观看时长统计
|
// 观看时长统计
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package xyz.playedu.api.service.impl;
|
package xyz.playedu.api.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateTime;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
@ -42,10 +44,7 @@ public class UserLearnDurationStatsServiceImpl
|
|||||||
@Override
|
@Override
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public void storeOrUpdate(Integer userId, Long startTime, Long endTime) {
|
public void storeOrUpdate(Integer userId, Long startTime, Long endTime) {
|
||||||
// 处理日期
|
String date = new DateTime().toDateStr();
|
||||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
|
||||||
String date = simpleDateFormat.format(new Date(endTime));
|
|
||||||
// duration
|
|
||||||
Long duration = endTime - startTime;
|
Long duration = endTime - startTime;
|
||||||
|
|
||||||
UserLearnDurationStats stats =
|
UserLearnDurationStats stats =
|
||||||
@ -54,7 +53,7 @@ public class UserLearnDurationStatsServiceImpl
|
|||||||
UserLearnDurationStats newStats = new UserLearnDurationStats();
|
UserLearnDurationStats newStats = new UserLearnDurationStats();
|
||||||
newStats.setUserId(userId);
|
newStats.setUserId(userId);
|
||||||
newStats.setDuration(duration);
|
newStats.setDuration(duration);
|
||||||
newStats.setCreatedDate(simpleDateFormat.parse(date));
|
newStats.setCreatedDate(new DateTime(date));
|
||||||
save(newStats);
|
save(newStats);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user