mirror of
https://github.com/PlayEdu/PlayEdu
synced 2025-07-24 18:29:33 +08:00
commit
b8f06a3bdb
2
pom.xml
2
pom.xml
@ -10,7 +10,7 @@
|
||||
</parent>
|
||||
<groupId>xyz.playedu</groupId>
|
||||
<artifactId>playedu-api</artifactId>
|
||||
<version>0.1-beta.1</version>
|
||||
<version>1.0-beta.4</version>
|
||||
<name>playedu-api</name>
|
||||
<description>playedu-api</description>
|
||||
<properties>
|
||||
|
@ -60,6 +60,7 @@ public class UserBus {
|
||||
return CollectionUtils.intersection(courseDepIds, userDepIds).size() > 0;
|
||||
}
|
||||
|
||||
// 注意,调用该方法需要考虑到并发写入问题
|
||||
public void userLearnDurationRecord(User user, Course course, CourseHour hour) {
|
||||
Long curTime = System.currentTimeMillis();
|
||||
|
||||
|
@ -162,6 +162,15 @@ public class AdminPermissionCheck implements ApplicationRunner {
|
||||
setSlug(BPermissionConstant.USER_LEARN);
|
||||
}
|
||||
},
|
||||
new AdminPermission() {
|
||||
{
|
||||
setSort(50);
|
||||
setName("学习-删除");
|
||||
setSlug(
|
||||
BPermissionConstant
|
||||
.USER_LEARN_DESTROY);
|
||||
}
|
||||
},
|
||||
});
|
||||
// 线上课
|
||||
put(
|
||||
|
@ -42,6 +42,7 @@ public class BPermissionConstant {
|
||||
public static final String USER_UPDATE = "user-update";
|
||||
public static final String USER_DESTROY = "user-destroy";
|
||||
public static final String USER_LEARN = "user-learn";
|
||||
public static final String USER_LEARN_DESTROY = "user-learn-destroy";
|
||||
|
||||
public static final String COURSE = "course";
|
||||
public static final String COURSE_USER = "course-user";
|
||||
|
@ -190,6 +190,9 @@ public class DepartmentController {
|
||||
String idCard = MapUtils.getString(params, "id_card");
|
||||
String depIds = String.valueOf(id);
|
||||
|
||||
String courseIdsStr = MapUtils.getString(params, "course_ids");
|
||||
String showMode = MapUtils.getString(params, "show_mode");
|
||||
|
||||
UserPaginateFilter filter =
|
||||
new UserPaginateFilter() {
|
||||
{
|
||||
@ -204,21 +207,48 @@ public class DepartmentController {
|
||||
|
||||
PaginationResult<User> users = userService.paginate(page, size, filter);
|
||||
|
||||
// 部门关联线上课
|
||||
List<Course> courses =
|
||||
courseService.getDepCoursesAndShow(
|
||||
new ArrayList<>() {
|
||||
{
|
||||
add(id);
|
||||
}
|
||||
});
|
||||
List<Course> courses;
|
||||
if (courseIdsStr != null && courseIdsStr.trim().length() > 0) {
|
||||
// 指定了需要显示的线上课
|
||||
courses =
|
||||
courseService.chunks(
|
||||
Arrays.stream(courseIdsStr.split(",")).map(Integer::valueOf).toList());
|
||||
} else {
|
||||
if ("only_open".equals(showMode)) {
|
||||
// 公开(无关联部门)线上课
|
||||
courses = courseService.getOpenCoursesAndShow(10000);
|
||||
} else if ("only_dep".equals(showMode)) {
|
||||
// 部门关联线上课
|
||||
courses =
|
||||
courseService.getDepCoursesAndShow(
|
||||
new ArrayList<>() {
|
||||
{
|
||||
add(id);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 部门关联线上课
|
||||
courses =
|
||||
courseService.getDepCoursesAndShow(
|
||||
new ArrayList<>() {
|
||||
{
|
||||
add(id);
|
||||
}
|
||||
});
|
||||
List<Course> openCourses = courseService.getOpenCoursesAndShow(10000);
|
||||
;
|
||||
if (openCourses != null) {
|
||||
courses.addAll(openCourses);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<Integer> courseIds = courses.stream().map(Course::getId).toList();
|
||||
|
||||
// 学员的课程学习进度
|
||||
Map<Integer, List<UserCourseRecord>> userCourseRecords =
|
||||
userCourseRecordService
|
||||
.chunk(
|
||||
users.getData().stream().map(User::getId).toList(),
|
||||
courses.stream().map(Course::getId).toList())
|
||||
.chunk(users.getData().stream().map(User::getId).toList(), courseIds)
|
||||
.stream()
|
||||
.collect(Collectors.groupingBy(UserCourseRecord::getUserId));
|
||||
Map<Integer, Map<Integer, UserCourseRecord>> userCourseRecordsMap = new HashMap<>();
|
||||
|
@ -33,6 +33,8 @@ import xyz.playedu.api.constant.BPermissionConstant;
|
||||
import xyz.playedu.api.constant.CConfig;
|
||||
import xyz.playedu.api.constant.SystemConstant;
|
||||
import xyz.playedu.api.domain.*;
|
||||
import xyz.playedu.api.event.UserCourseHourRecordDestroyEvent;
|
||||
import xyz.playedu.api.event.UserCourseRecordDestroyEvent;
|
||||
import xyz.playedu.api.event.UserDestroyEvent;
|
||||
import xyz.playedu.api.exception.NotFoundException;
|
||||
import xyz.playedu.api.middleware.BackendPermissionMiddleware;
|
||||
@ -78,6 +80,8 @@ public class UserController {
|
||||
|
||||
@Autowired private UserLearnDurationStatsService userLearnDurationStatsService;
|
||||
|
||||
@Autowired private ApplicationContext ctx;
|
||||
|
||||
@BackendPermissionMiddleware(slug = BPermissionConstant.USER_INDEX)
|
||||
@GetMapping("/index")
|
||||
public JsonResponse index(@RequestParam HashMap<String, Object> params) {
|
||||
@ -370,7 +374,7 @@ public class UserController {
|
||||
@BackendPermissionMiddleware(slug = BPermissionConstant.USER_LEARN)
|
||||
@GetMapping("/{id}/learn-hours")
|
||||
@SneakyThrows
|
||||
public JsonResponse latestLearnHours(
|
||||
public JsonResponse learnHours(
|
||||
@PathVariable(name = "id") Integer id, @RequestParam HashMap<String, Object> params) {
|
||||
Integer page = MapUtils.getInteger(params, "page", 1);
|
||||
Integer size = MapUtils.getInteger(params, "size", 10);
|
||||
@ -438,6 +442,79 @@ public class UserController {
|
||||
return JsonResponse.data(data);
|
||||
}
|
||||
|
||||
@BackendPermissionMiddleware(slug = BPermissionConstant.USER_LEARN)
|
||||
@GetMapping("/{id}/all-courses")
|
||||
public JsonResponse allCourses(@PathVariable(name = "id") Integer id) {
|
||||
// 读取学员关联的部门
|
||||
List<Integer> depIds = userService.getDepIdsByUserId(id);
|
||||
List<Department> departments = new ArrayList<>();
|
||||
HashMap<Integer, List<Course>> depCourses = new HashMap<>();
|
||||
List<Integer> courseIds = new ArrayList<>();
|
||||
|
||||
if (depIds != null && depIds.size() > 0) {
|
||||
departments = departmentService.chunk(depIds);
|
||||
depIds.forEach(
|
||||
(depId) -> {
|
||||
List<Course> tmpCourses =
|
||||
courseService.getDepCoursesAndShow(
|
||||
new ArrayList<>() {
|
||||
{
|
||||
add(depId);
|
||||
}
|
||||
});
|
||||
depCourses.put(depId, tmpCourses);
|
||||
|
||||
if (tmpCourses != null && tmpCourses.size() > 0) {
|
||||
courseIds.addAll(tmpCourses.stream().map(Course::getId).toList());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 未关联部门课程
|
||||
List<Course> openCourses = courseService.getOpenCoursesAndShow(1000);
|
||||
if (openCourses != null && openCourses.size() > 0) {
|
||||
courseIds.addAll(openCourses.stream().map(Course::getId).toList());
|
||||
}
|
||||
|
||||
// 读取学员的线上课学习记录
|
||||
List<UserCourseRecord> userCourseRecords = new ArrayList<>();
|
||||
if (courseIds.size() > 0) {
|
||||
userCourseRecords = userCourseRecordService.chunk(id, courseIds);
|
||||
}
|
||||
|
||||
HashMap<String, Object> data = new HashMap<>();
|
||||
data.put("open_courses", openCourses);
|
||||
data.put("departments", departments);
|
||||
data.put("dep_courses", depCourses);
|
||||
data.put(
|
||||
"user_course_records",
|
||||
userCourseRecords.stream()
|
||||
.collect(Collectors.toMap(UserCourseRecord::getCourseId, e -> e)));
|
||||
|
||||
return JsonResponse.data(data);
|
||||
}
|
||||
|
||||
@BackendPermissionMiddleware(slug = BPermissionConstant.USER_LEARN)
|
||||
@GetMapping("/{id}/learn-course/{courseId}")
|
||||
@SneakyThrows
|
||||
public JsonResponse learnCourseDetail(
|
||||
@PathVariable(name = "id") Integer id,
|
||||
@PathVariable(name = "courseId") Integer courseId) {
|
||||
// 读取线上课下的所有课时
|
||||
List<CourseHour> hours = courseHourService.getHoursByCourseId(courseId);
|
||||
// 读取学员的课时学习记录
|
||||
List<UserCourseHourRecord> records = userCourseHourRecordService.getRecords(id, courseId);
|
||||
|
||||
HashMap<String, Object> data = new HashMap<>();
|
||||
data.put("hours", hours);
|
||||
data.put(
|
||||
"learn_records",
|
||||
records.stream()
|
||||
.collect(Collectors.toMap(UserCourseHourRecord::getHourId, e -> e)));
|
||||
|
||||
return JsonResponse.data(data);
|
||||
}
|
||||
|
||||
@BackendPermissionMiddleware(slug = BPermissionConstant.USER_LEARN)
|
||||
@GetMapping("/{id}/learn-stats")
|
||||
@SneakyThrows
|
||||
@ -484,4 +561,27 @@ public class UserController {
|
||||
|
||||
return JsonResponse.data(data);
|
||||
}
|
||||
|
||||
@BackendPermissionMiddleware(slug = BPermissionConstant.USER_LEARN_DESTROY)
|
||||
@DeleteMapping("/{id}/learn-course/{courseId}")
|
||||
@SneakyThrows
|
||||
public JsonResponse destroyUserCourse(
|
||||
@PathVariable(name = "id") Integer id,
|
||||
@PathVariable(name = "courseId") Integer courseId) {
|
||||
userCourseRecordService.destroy(id, courseId);
|
||||
ctx.publishEvent(new UserCourseRecordDestroyEvent(this, id, courseId));
|
||||
return JsonResponse.success();
|
||||
}
|
||||
|
||||
@BackendPermissionMiddleware(slug = BPermissionConstant.USER_LEARN_DESTROY)
|
||||
@DeleteMapping("/{id}/learn-course/{courseId}/hour/{hourId}")
|
||||
@SneakyThrows
|
||||
public JsonResponse destroyUserHour(
|
||||
@PathVariable(name = "id") Integer id,
|
||||
@PathVariable(name = "courseId") Integer courseId,
|
||||
@PathVariable(name = "hourId") Integer hourId) {
|
||||
userCourseHourRecordService.remove(id, courseId, hourId);
|
||||
ctx.publishEvent(new UserCourseHourRecordDestroyEvent(this, id, courseId, hourId));
|
||||
return JsonResponse.success();
|
||||
}
|
||||
}
|
||||
|
@ -28,11 +28,14 @@ import xyz.playedu.api.caches.UserCanSeeCourseCache;
|
||||
import xyz.playedu.api.domain.*;
|
||||
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;
|
||||
import xyz.playedu.api.util.RedisDistributedLock;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @Author 杭州白书科技有限公司
|
||||
@ -43,6 +46,8 @@ import java.util.HashMap;
|
||||
@RequestMapping("/api/v1/course/{courseId}/hour")
|
||||
public class HourController {
|
||||
|
||||
@Autowired private CourseService courseService;
|
||||
|
||||
@Autowired private CourseHourService hourService;
|
||||
|
||||
@Autowired private ResourceService resourceService;
|
||||
@ -55,6 +60,30 @@ public class HourController {
|
||||
@Autowired private UserCanSeeCourseCache userCanSeeCourseCache;
|
||||
@Autowired private CourseCache courseCache;
|
||||
|
||||
@Autowired private RedisDistributedLock redisDistributedLock;
|
||||
|
||||
@GetMapping("/{id}")
|
||||
@SneakyThrows
|
||||
public JsonResponse detail(
|
||||
@PathVariable(name = "courseId") Integer courseId,
|
||||
@PathVariable(name = "id") Integer id) {
|
||||
Course course = courseService.findOrFail(courseId);
|
||||
CourseHour courseHour = hourService.findOrFail(id, courseId);
|
||||
|
||||
UserCourseHourRecord userCourseHourRecord = null;
|
||||
if (FCtx.getId() != null && FCtx.getId() > 0) {
|
||||
// 学员已登录
|
||||
userCourseHourRecord = userCourseHourRecordService.find(FCtx.getId(), courseId, id);
|
||||
}
|
||||
|
||||
HashMap<String, Object> data = new HashMap<>();
|
||||
data.put("course", course);
|
||||
data.put("hour", courseHour);
|
||||
data.put("user_hour_record", userCourseHourRecord);
|
||||
|
||||
return JsonResponse.data(data);
|
||||
}
|
||||
|
||||
@GetMapping("/{id}/play")
|
||||
@SneakyThrows
|
||||
public JsonResponse play(
|
||||
@ -83,13 +112,23 @@ public class HourController {
|
||||
if (duration <= 0) {
|
||||
return JsonResponse.error("duration参数错误");
|
||||
}
|
||||
User user = FCtx.getUser();
|
||||
|
||||
Course course = courseCache.findOrFail(courseId);
|
||||
userCanSeeCourseCache.check(user, course, true);
|
||||
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(
|
||||
user.getId(), course.getId(), hour.getId(), duration, hour.getDuration());
|
||||
FCtx.getId(), course.getId(), hour.getId(), duration, hour.getDuration());
|
||||
|
||||
// 此处未考虑上面代码执行失败释放锁
|
||||
redisDistributedLock.releaseLock(lockKey);
|
||||
|
||||
return JsonResponse.success();
|
||||
}
|
||||
@ -102,7 +141,19 @@ public class HourController {
|
||||
Course course = courseCache.findOrFail(courseId);
|
||||
CourseHour hour = hourService.findOrFail(id, courseId);
|
||||
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);
|
||||
|
||||
// 此处未考虑上面代码执行失败释放锁
|
||||
redisDistributedLock.releaseLock(lockKey);
|
||||
|
||||
return JsonResponse.success();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2023 杭州白书科技有限公司
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package xyz.playedu.api.event;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @Author 杭州白书科技有限公司
|
||||
*
|
||||
* @create 2023/4/23 14:48
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class UserCourseHourRecordDestroyEvent extends ApplicationEvent {
|
||||
|
||||
private Integer userId;
|
||||
private Integer courseId;
|
||||
private Integer hourId;
|
||||
private Date at;
|
||||
|
||||
public UserCourseHourRecordDestroyEvent(
|
||||
Object source, Integer userId, Integer courseId, Integer hourId) {
|
||||
super(source);
|
||||
this.userId = userId;
|
||||
this.courseId = courseId;
|
||||
this.hourId = hourId;
|
||||
this.at = new Date();
|
||||
}
|
||||
}
|
@ -15,11 +15,8 @@
|
||||
*/
|
||||
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.UserCourseHourFinishedEvent;
|
||||
@ -33,7 +30,6 @@ import xyz.playedu.api.service.UserCourseRecordService;
|
||||
* @create 2023/3/20 17:41
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class UserCourseHourFinishedListener {
|
||||
|
||||
@Autowired private UserCourseRecordService userCourseRecordService;
|
||||
@ -42,20 +38,12 @@ public class UserCourseHourFinishedListener {
|
||||
|
||||
@Autowired private CourseHourService hourService;
|
||||
|
||||
@Async
|
||||
@EventListener
|
||||
public void userCourseProgressUpdate(UserCourseHourFinishedEvent evt) {
|
||||
Integer hourCount = hourService.getCountByCourseId(evt.getCourseId());
|
||||
Integer finishedCount =
|
||||
userCourseHourRecordService.getFinishedHourCount(
|
||||
evt.getUserId(), evt.getCourseId());
|
||||
log.info(
|
||||
"UserCourseHourFinishedListener courseId={} userId={} hourCount={}"
|
||||
+ " finishedCount={}",
|
||||
evt.getCourseId(),
|
||||
evt.getUserId(),
|
||||
hourCount,
|
||||
finishedCount);
|
||||
userCourseRecordService.storeOrUpdate(
|
||||
evt.getUserId(), evt.getCourseId(), hourCount, finishedCount);
|
||||
}
|
||||
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2023 杭州白书科技有限公司
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
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.stereotype.Component;
|
||||
|
||||
import xyz.playedu.api.event.UserCourseHourRecordDestroyEvent;
|
||||
import xyz.playedu.api.service.UserCourseRecordService;
|
||||
|
||||
/**
|
||||
* @Author 杭州白书科技有限公司
|
||||
*
|
||||
* @create 2023/4/23 14:51
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class UserCourseHourRecordDestroyListener {
|
||||
|
||||
@Autowired private UserCourseRecordService userCourseRecordService;
|
||||
|
||||
@EventListener
|
||||
public void updateUserCourseRecord(UserCourseHourRecordDestroyEvent e) {
|
||||
userCourseRecordService.decrease(e.getUserId(), e.getCourseId(), 1);
|
||||
}
|
||||
}
|
@ -19,7 +19,6 @@ 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;
|
||||
@ -39,7 +38,6 @@ public class UserLearnCourseUpdateListener {
|
||||
|
||||
@Autowired private UserLearnDurationStatsService userLearnDurationStatsService;
|
||||
|
||||
@Async
|
||||
@EventListener
|
||||
public void storeLearnDuration(UserLearnCourseUpdateEvent event) {
|
||||
// 观看时长统计
|
||||
|
@ -64,4 +64,6 @@ public interface DepartmentService extends IService<Department> {
|
||||
Long total();
|
||||
|
||||
Map<Integer, Integer> getDepartmentsUserCount();
|
||||
|
||||
List<Department> chunk(List<Integer> ids);
|
||||
}
|
||||
|
@ -49,6 +49,8 @@ public interface UserCourseHourRecordService extends IService<UserCourseHourReco
|
||||
|
||||
void remove(Integer userId, Integer courseId);
|
||||
|
||||
void remove(Integer userId, Integer courseId, Integer hourId);
|
||||
|
||||
List<UserCourseHourRecordCountMapper> getUserCourseHourCount(
|
||||
Integer userId, List<Integer> courseIds, Integer isFinished);
|
||||
|
||||
|
@ -43,7 +43,11 @@ public interface UserCourseRecordService extends IService<UserCourseRecord> {
|
||||
|
||||
void destroy(Integer courseId, List<Integer> ids);
|
||||
|
||||
void destroy(Integer userId, Integer courseId);
|
||||
|
||||
void removeByCourseId(Integer courseId);
|
||||
|
||||
List<UserCourseRecord> chunks(List<Integer> ids, List<String> fields);
|
||||
|
||||
void decrease(Integer userId, Integer courseId, int count);
|
||||
}
|
||||
|
@ -214,6 +214,9 @@ public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> impleme
|
||||
|
||||
@Override
|
||||
public List<Course> getDepCoursesAndShow(List<Integer> depIds) {
|
||||
if (depIds == null || depIds.size() == 0) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<Integer> courseIds = courseDepartmentService.getCourseIdsByDepIds(depIds);
|
||||
if (courseIds == null || courseIds.size() == 0) {
|
||||
return new ArrayList<>();
|
||||
|
@ -268,4 +268,12 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
|
||||
DepartmentsUserCountMapRes::getDepId,
|
||||
DepartmentsUserCountMapRes::getTotal));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Department> chunk(List<Integer> ids) {
|
||||
if (ids == null || ids.size() == 0) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return list(query().getWrapper().in("id", ids));
|
||||
}
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ public class ImageCaptchaServiceImpl implements ImageCaptchaService {
|
||||
return false;
|
||||
}
|
||||
String cacheValue = (String) queryResult;
|
||||
boolean verifyResult = cacheValue.equals(code);
|
||||
boolean verifyResult = cacheValue.equalsIgnoreCase(code);
|
||||
|
||||
if (verifyResult) { // 验证成功删除缓存->防止多次使用
|
||||
RedisUtil.del(cacheKey);
|
||||
|
@ -153,4 +153,13 @@ public class UserCourseHourRecordServiceImpl
|
||||
|
||||
return pageResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(Integer userId, Integer courseId, Integer hourId) {
|
||||
remove(
|
||||
query().getWrapper()
|
||||
.eq("user_id", userId)
|
||||
.eq("course_id", courseId)
|
||||
.eq("hour_id", hourId));
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ public class UserCourseRecordServiceImpl
|
||||
|
||||
boolean isFinished = finishedCount >= hourCount;
|
||||
Date finishedAt = isFinished ? new Date() : null;
|
||||
Integer progress = finishedCount * 100 / hourCount * 100;
|
||||
Integer progress = finishedCount * 10000 / hourCount;
|
||||
|
||||
if (record == null) {
|
||||
UserCourseRecord insertRecord = new UserCourseRecord();
|
||||
@ -132,4 +132,28 @@ public class UserCourseRecordServiceImpl
|
||||
public List<UserCourseRecord> chunks(List<Integer> ids, List<String> fields) {
|
||||
return list(query().getWrapper().in("id", ids).select(fields));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy(Integer userId, Integer courseId) {
|
||||
remove(query().getWrapper().in("user_id", userId).eq("course_id", courseId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decrease(Integer userId, Integer courseId, int count) {
|
||||
UserCourseRecord record = find(userId, courseId);
|
||||
if (record == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int finishedCount = record.getFinishedCount() - count;
|
||||
|
||||
UserCourseRecord newRecord = new UserCourseRecord();
|
||||
newRecord.setId(record.getId());
|
||||
newRecord.setFinishedCount(finishedCount);
|
||||
newRecord.setFinishedAt(null);
|
||||
newRecord.setProgress(finishedCount * 10000 / record.getHourCount());
|
||||
newRecord.setIsFinished(0);
|
||||
|
||||
updateById(newRecord);
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,8 @@
|
||||
*/
|
||||
package xyz.playedu.api.service.impl;
|
||||
|
||||
import cn.hutool.core.date.DateTime;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
@ -42,10 +44,7 @@ public class UserLearnDurationStatsServiceImpl
|
||||
@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
|
||||
String date = new DateTime().toDateStr();
|
||||
Long duration = endTime - startTime;
|
||||
|
||||
UserLearnDurationStats stats =
|
||||
@ -54,7 +53,7 @@ public class UserLearnDurationStatsServiceImpl
|
||||
UserLearnDurationStats newStats = new UserLearnDurationStats();
|
||||
newStats.setUserId(userId);
|
||||
newStats.setDuration(duration);
|
||||
newStats.setCreatedDate(simpleDateFormat.parse(date));
|
||||
newStats.setCreatedDate(new DateTime(date));
|
||||
save(newStats);
|
||||
return;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user