diff --git a/playedu-api/src/main/java/xyz/playedu/api/controller/frontend/HourController.java b/playedu-api/src/main/java/xyz/playedu/api/controller/frontend/HourController.java index b7b3572..c52ebdb 100644 --- a/playedu-api/src/main/java/xyz/playedu/api/controller/frontend/HourController.java +++ b/playedu-api/src/main/java/xyz/playedu/api/controller/frontend/HourController.java @@ -97,8 +97,7 @@ public class HourController { public JsonResponse play( @PathVariable(name = "courseId") Integer courseId, @PathVariable(name = "id") Integer id) { - Course course = courseCache.findOrFail(courseId); - userCanSeeCourseCache.check(FCtx.getUser(), course, true); + userCanSeeCourseCache.check(FCtx.getId(), courseId, true); CourseHour hour = hourService.findOrFail(id, courseId); Resource resource = resourceService.findOrFail(hour.getRid()); @@ -121,9 +120,8 @@ public class HourController { return JsonResponse.error("duration参数错误"); } - Course course = courseCache.findOrFail(courseId); CourseHour hour = hourService.findOrFail(id, courseId); - userCanSeeCourseCache.check(FCtx.getUser(), course, true); + userCanSeeCourseCache.check(FCtx.getId(), courseId, true); // 获取锁 String lockKey = String.format("record:%d", FCtx.getId()); @@ -135,11 +133,7 @@ public class HourController { try { boolean isFinished = userCourseHourRecordService.storeOrUpdate( - FCtx.getId(), - course.getId(), - hour.getId(), - duration, - hour.getDuration()); + FCtx.getId(), courseId, hour.getId(), duration, hour.getDuration()); if (isFinished) { ctx.publishEvent( new UserCourseHourFinishedEvent( @@ -158,9 +152,7 @@ public class HourController { 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(FCtx.getUser(), course, true); + userCanSeeCourseCache.check(FCtx.getId(), courseId, true); // 获取锁 String lockKey = String.format("ping:%d", FCtx.getId()); @@ -183,7 +175,7 @@ public class HourController { ctx.publishEvent( new UserLearnCourseUpdateEvent( - this, FCtx.getId(), course.getId(), hour.getId(), lastTime, curTime)); + this, FCtx.getId(), courseId, id, lastTime, curTime)); } finally { // 此处未考虑上面代码执行失败释放锁 redisDistributedLock.releaseLock(lockKey); diff --git a/playedu-course/src/main/java/xyz/playedu/course/bus/UserBus.java b/playedu-course/src/main/java/xyz/playedu/course/bus/UserBus.java index f89eaf4..bf5c1b5 100644 --- a/playedu-course/src/main/java/xyz/playedu/course/bus/UserBus.java +++ b/playedu-course/src/main/java/xyz/playedu/course/bus/UserBus.java @@ -19,11 +19,14 @@ import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import xyz.playedu.common.domain.User; +import xyz.playedu.common.domain.Department; +import xyz.playedu.common.service.DepartmentService; import xyz.playedu.common.service.UserService; -import xyz.playedu.course.domain.Course; +import xyz.playedu.common.util.StringUtil; import xyz.playedu.course.service.CourseService; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; /** @@ -38,34 +41,36 @@ public class UserBus { @Autowired private UserService userService; - public boolean canSeeCourse(User user, Course course) { - List courseDepIds = courseService.getDepIdsByCourseId(course.getId()); - if (courseDepIds == null || courseDepIds.size() == 0) { - // 线上课无所属部门=>任何学员都可以学习 + @Autowired private DepartmentService departmentService; + + public boolean canSeeCourse(Integer userId, Integer courseId) { + List courseDepIds = courseService.getDepIdsByCourseId(courseId); + if (StringUtil.isEmpty(courseDepIds)) { + // 线上课全部部门=>任何学员都可以学习 return true; } - List userDepIds = userService.getDepIdsByUserId(user.getId()); - if (userDepIds == null || userDepIds.size() == 0) { + + // 获取学员所属部门以及所有父级部门 + List allDepIds = new ArrayList<>(); + List userDepIds = userService.getDepIdsByUserId(userId); + if (StringUtil.isNotEmpty(userDepIds)) { + List departmentList = departmentService.chunk(userDepIds); + if (StringUtil.isNotEmpty(departmentList)) { + for (Department dep : departmentList) { + allDepIds.add(dep.getId()); + if (StringUtil.isNotEmpty(dep.getParentChain())) { + allDepIds.addAll( + Arrays.stream(dep.getParentChain().split(",")) + .map(Integer::valueOf) + .toList()); + } + } + } + } + + if (StringUtil.isEmpty(allDepIds)) { return false; } - return CollectionUtils.intersection(courseDepIds, userDepIds).size() > 0; + return CollectionUtils.intersection(courseDepIds, allDepIds).size() > 0; } - - // 注意,调用该方法需要考虑到并发写入问题 - /* public void userLearnDurationRecord(User user, Course course, CourseHour hour) { - Long curTime = System.currentTimeMillis(); - - // 最近一次学习时间 - Long lastTime = userLastLearnTimeCache.get(FCtx.getId()); - // 最大周期为10s+0.5s的网络延迟 - if (lastTime == null || curTime - lastTime > 10500) { - lastTime = curTime - 10000; - } - - userLastLearnTimeCache.put(user.getId(), curTime); - - ctx.publishEvent( - new UserLearnCourseUpdateEvent( - this, user.getId(), course.getId(), hour.getId(), lastTime, curTime)); - }*/ } diff --git a/playedu-course/src/main/java/xyz/playedu/course/caches/UserCanSeeCourseCache.java b/playedu-course/src/main/java/xyz/playedu/course/caches/UserCanSeeCourseCache.java index 022fa57..25a81db 100644 --- a/playedu-course/src/main/java/xyz/playedu/course/caches/UserCanSeeCourseCache.java +++ b/playedu-course/src/main/java/xyz/playedu/course/caches/UserCanSeeCourseCache.java @@ -18,11 +18,13 @@ package xyz.playedu.course.caches; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import xyz.playedu.common.domain.User; import xyz.playedu.common.exception.ServiceException; import xyz.playedu.common.util.RedisUtil; +import xyz.playedu.common.util.StringUtil; import xyz.playedu.course.bus.UserBus; -import xyz.playedu.course.domain.Course; + +import java.util.ArrayList; +import java.util.List; /** * @Author 杭州白书科技有限公司 @@ -38,14 +40,15 @@ public class UserCanSeeCourseCache { private static final int expire = 3600; // s - public boolean check(User user, Course course, boolean isThrow) throws ServiceException { + public boolean check(Integer userId, Integer courseId, boolean isThrow) + throws ServiceException { boolean result; - if (RedisUtil.exists(key(user, course))) { - String cacheResult = (String) RedisUtil.get(key(user, course)); + if (RedisUtil.exists(key(userId, courseId))) { + String cacheResult = (String) RedisUtil.get(key(userId, courseId)); result = "1".equals(cacheResult); } else { - result = userBus.canSeeCourse(user, course); - put(user, course, result); + result = userBus.canSeeCourse(userId, courseId); + put(userId, courseId, result); } if (!result && isThrow) { throw new ServiceException("无权限观看"); @@ -53,11 +56,21 @@ public class UserCanSeeCourseCache { return result; } - public void put(User user, Course course, boolean result) { - RedisUtil.set(key(user, course), result ? "1" : "0", expire); + public void put(Integer userId, Integer courseId, boolean result) { + RedisUtil.set(key(userId, courseId), result ? "1" : "0", expire); } - private String key(User user, Course course) { - return String.format(keyTemplate, course.getId(), user.getId()); + public void destroy(List userIds, Integer courseId) { + if (StringUtil.isNotEmpty(userIds)) { + List keyList = new ArrayList<>(); + for (Integer userId : userIds) { + keyList.add(key(userId, courseId)); + } + RedisUtil.del(keyList.toArray(new String[keyList.size()])); + } + } + + private String key(Integer userId, Integer courseId) { + return String.format(keyTemplate, courseId, userId); } }