后台新增:学员的最近课时学习记录api,学员的线上课学习进度api

This commit is contained in:
none 2023-04-17 17:50:48 +08:00
parent ad07f20dd7
commit 6e65fc9aa0
14 changed files with 255 additions and 24 deletions

View File

@ -37,11 +37,11 @@ import java.util.List;
@Slf4j
public class ExceptionController {
@ExceptionHandler(Exception.class)
public JsonResponse exceptionHandler(Exception e) {
log.error(e.getMessage());
return JsonResponse.error("系统错误", 500);
}
// @ExceptionHandler(Exception.class)
// public JsonResponse exceptionHandler(Exception e) {
// log.error(e.getMessage());
// return JsonResponse.error("系统错误", 500);
// }
@ExceptionHandler(ServiceException.class)
public JsonResponse serviceExceptionHandler(ServiceException e) {

View File

@ -29,8 +29,8 @@ import xyz.playedu.api.request.backend.CourseUserDestroyRequest;
import xyz.playedu.api.service.UserCourseRecordService;
import xyz.playedu.api.service.UserService;
import xyz.playedu.api.types.JsonResponse;
import xyz.playedu.api.types.paginate.CourseUserPaginateFilter;
import xyz.playedu.api.types.paginate.PaginationResult;
import xyz.playedu.api.types.paginate.UserCourseRecordPaginateFilter;
import java.util.ArrayList;
import java.util.HashMap;
@ -64,7 +64,7 @@ public class CourseUserController {
String email = MapUtils.getString(params, "email");
String idCard = MapUtils.getString(params, "id_card");
CourseUserPaginateFilter filter = new CourseUserPaginateFilter();
UserCourseRecordPaginateFilter filter = new UserCourseRecordPaginateFilter();
filter.setCourseId(courseId);
filter.setName(name);
filter.setEmail(email);

View File

@ -15,6 +15,7 @@
*/
package xyz.playedu.api.controller.backend;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
@ -28,19 +29,18 @@ import xyz.playedu.api.BCtx;
import xyz.playedu.api.constant.BPermissionConstant;
import xyz.playedu.api.constant.CConfig;
import xyz.playedu.api.constant.SystemConstant;
import xyz.playedu.api.domain.Department;
import xyz.playedu.api.domain.User;
import xyz.playedu.api.domain.UserDepartment;
import xyz.playedu.api.domain.*;
import xyz.playedu.api.event.UserDestroyEvent;
import xyz.playedu.api.exception.NotFoundException;
import xyz.playedu.api.middleware.BackendPermissionMiddleware;
import xyz.playedu.api.request.backend.UserImportRequest;
import xyz.playedu.api.request.backend.UserRequest;
import xyz.playedu.api.service.DepartmentService;
import xyz.playedu.api.service.UserService;
import xyz.playedu.api.service.*;
import xyz.playedu.api.service.internal.UserDepartmentService;
import xyz.playedu.api.types.JsonResponse;
import xyz.playedu.api.types.paginate.PaginationResult;
import xyz.playedu.api.types.paginate.UserCourseHourRecordPaginateFilter;
import xyz.playedu.api.types.paginate.UserCourseRecordPaginateFilter;
import xyz.playedu.api.types.paginate.UserPaginateFilter;
import xyz.playedu.api.util.HelperUtil;
@ -65,6 +65,14 @@ public class UserController {
@Autowired private ApplicationContext context;
@Autowired private UserCourseHourRecordService userCourseHourRecordService;
@Autowired private UserCourseRecordService userCourseRecordService;
@Autowired private CourseHourService courseHourService;
@Autowired private CourseService courseService;
@BackendPermissionMiddleware(slug = BPermissionConstant.USER_INDEX)
@GetMapping("/index")
public JsonResponse index(@RequestParam HashMap<String, Object> params) {
@ -352,4 +360,85 @@ public class UserController {
return JsonResponse.success();
}
@GetMapping("/{id}/latest-learn-hours")
@SneakyThrows
public JsonResponse latestLearnHours(
@PathVariable(name = "id") Integer id, @RequestParam HashMap<String, Object> params) {
Integer page = MapUtils.getInteger(params, "page", 1);
Integer size = MapUtils.getInteger(params, "size", 10);
String sortField = MapUtils.getString(params, "sort_field");
String sortAlgo = MapUtils.getString(params, "sort_algo");
Integer isFinished = MapUtils.getInteger(params, "is_finished");
UserCourseHourRecordPaginateFilter filter = new UserCourseHourRecordPaginateFilter();
filter.setSortAlgo(sortAlgo);
filter.setSortField(sortField);
filter.setUserId(id);
filter.setIsFinished(isFinished);
PaginationResult<UserCourseHourRecord> result =
userCourseHourRecordService.paginate(page, size, filter);
HashMap<String, Object> data = new HashMap<>();
data.put("data", result.getData());
data.put("total", result.getTotal());
data.put(
"hours",
courseHourService
.chunk(
result.getData().stream()
.map(UserCourseHourRecord::getHourId)
.toList())
.stream()
.collect(Collectors.groupingBy(CourseHour::getId)));
return JsonResponse.data(data);
}
@GetMapping("/{id}/latest-learn-courses")
public JsonResponse latestLearnCourses(
@PathVariable(name = "id") Integer id, @RequestParam HashMap<String, Object> params) {
Integer page = MapUtils.getInteger(params, "page", 1);
Integer size = MapUtils.getInteger(params, "size", 10);
String sortField = MapUtils.getString(params, "sort_field");
String sortAlgo = MapUtils.getString(params, "sort_algo");
Integer isFinished = MapUtils.getInteger(params, "is_finished");
UserCourseRecordPaginateFilter filter = new UserCourseRecordPaginateFilter();
filter.setSortAlgo(sortAlgo);
filter.setSortField(sortField);
filter.setUserId(id);
filter.setIsFinished(isFinished);
PaginationResult<UserCourseRecord> result =
userCourseRecordService.paginate(page, size, filter);
HashMap<String, Object> data = new HashMap<>();
data.put("data", result.getData());
data.put("total", result.getTotal());
data.put(
"courses",
courseService
.chunks(
result.getData().stream()
.map(UserCourseRecord::getCourseId)
.toList())
.stream()
.collect(Collectors.groupingBy(Course::getId)));
return JsonResponse.data(data);
}
@GetMapping("/{id}/learn-stats")
@SneakyThrows
public JsonResponse learn(@PathVariable(name = "id") Integer id) {
User user = userService.findOrFail(id);
// 学习时长统计
// 今天昨天本周本月
// 最近一个月的每天学习时长
return JsonResponse.data(null);
}
}

View File

@ -21,6 +21,7 @@ import org.apache.ibatis.annotations.Mapper;
import xyz.playedu.api.domain.UserCourseHourRecord;
import xyz.playedu.api.types.mapper.UserCourseHourRecordCountMapper;
import xyz.playedu.api.types.paginate.UserCourseHourRecordPaginateFilter;
import java.util.List;
@ -35,4 +36,8 @@ public interface UserCourseHourRecordMapper extends BaseMapper<UserCourseHourRec
List<UserCourseHourRecordCountMapper> getUserCourseHourCount(
Integer userId, List<Integer> courseIds, Integer isFinished);
List<UserCourseHourRecord> paginate(UserCourseHourRecordPaginateFilter filter);
Long paginateCount(UserCourseHourRecordPaginateFilter filter);
}

View File

@ -20,7 +20,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import xyz.playedu.api.domain.UserCourseRecord;
import xyz.playedu.api.types.paginate.CourseUserPaginateFilter;
import xyz.playedu.api.types.paginate.UserCourseRecordPaginateFilter;
import java.util.List;
@ -31,7 +31,7 @@ import java.util.List;
*/
@Mapper
public interface UserCourseRecordMapper extends BaseMapper<UserCourseRecord> {
List<UserCourseRecord> paginate(CourseUserPaginateFilter filter);
List<UserCourseRecord> paginate(UserCourseRecordPaginateFilter filter);
long paginateTotal(CourseUserPaginateFilter filter);
long paginateTotal(UserCourseRecordPaginateFilter filter);
}

View File

@ -19,6 +19,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
import xyz.playedu.api.domain.UserCourseHourRecord;
import xyz.playedu.api.types.mapper.UserCourseHourRecordCountMapper;
import xyz.playedu.api.types.paginate.PaginationResult;
import xyz.playedu.api.types.paginate.UserCourseHourRecordPaginateFilter;
import java.util.List;
@ -49,4 +51,7 @@ public interface UserCourseHourRecordService extends IService<UserCourseHourReco
List<UserCourseHourRecordCountMapper> getUserCourseHourCount(
Integer userId, List<Integer> courseIds, Integer isFinished);
PaginationResult<UserCourseHourRecord> paginate(
int page, int size, UserCourseHourRecordPaginateFilter filter);
}

View File

@ -18,8 +18,8 @@ package xyz.playedu.api.service;
import com.baomidou.mybatisplus.extension.service.IService;
import xyz.playedu.api.domain.UserCourseRecord;
import xyz.playedu.api.types.paginate.CourseUserPaginateFilter;
import xyz.playedu.api.types.paginate.PaginationResult;
import xyz.playedu.api.types.paginate.UserCourseRecordPaginateFilter;
import java.util.List;
@ -37,7 +37,7 @@ public interface UserCourseRecordService extends IService<UserCourseRecord> {
List<UserCourseRecord> chunk(Integer userId, List<Integer> courseIds);
PaginationResult<UserCourseRecord> paginate(
int page, int size, CourseUserPaginateFilter filter);
int page, int size, UserCourseRecordPaginateFilter filter);
void destroy(Integer courseId, List<Integer> ids);

View File

@ -43,9 +43,11 @@ import java.util.stream.Collectors;
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements CourseService {
@Autowired private CourseDepartmentService courseDepartmentService;
@Autowired
private CourseDepartmentService courseDepartmentService;
@Autowired private ResourceCourseCategoryService courseCategoryService;
@Autowired
private ResourceCourseCategoryService courseCategoryService;
@Override
public PaginationResult<Course> paginate(int page, int size, CoursePaginateFiler filter) {
@ -201,6 +203,9 @@ public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> impleme
@Override
public List<Course> chunks(List<Integer> ids) {
if (ids == null || ids.size() == 0) {
return new ArrayList<>();
}
return list(query().getWrapper().in("id", ids));
}

View File

@ -26,6 +26,8 @@ import xyz.playedu.api.event.UserCourseHourFinishedEvent;
import xyz.playedu.api.mapper.UserCourseHourRecordMapper;
import xyz.playedu.api.service.UserCourseHourRecordService;
import xyz.playedu.api.types.mapper.UserCourseHourRecordCountMapper;
import xyz.playedu.api.types.paginate.PaginationResult;
import xyz.playedu.api.types.paginate.UserCourseHourRecordPaginateFilter;
import java.util.ArrayList;
import java.util.Date;
@ -137,4 +139,18 @@ public class UserCourseHourRecordServiceImpl
public void remove(Integer userId, Integer courseId) {
remove(query().getWrapper().eq("user_id", userId).eq("course_id", courseId));
}
@Override
public PaginationResult<UserCourseHourRecord> paginate(
int page, int size, UserCourseHourRecordPaginateFilter filter) {
int pageStart = (page - 1) * size;
filter.setPageStart(pageStart);
filter.setPageSize(size);
PaginationResult<UserCourseHourRecord> pageResult = new PaginationResult<>();
pageResult.setData(getBaseMapper().paginate(filter));
pageResult.setTotal(getBaseMapper().paginateCount(filter));
return pageResult;
}
}

View File

@ -22,8 +22,8 @@ import org.springframework.stereotype.Service;
import xyz.playedu.api.domain.UserCourseRecord;
import xyz.playedu.api.mapper.UserCourseRecordMapper;
import xyz.playedu.api.service.UserCourseRecordService;
import xyz.playedu.api.types.paginate.CourseUserPaginateFilter;
import xyz.playedu.api.types.paginate.PaginationResult;
import xyz.playedu.api.types.paginate.UserCourseRecordPaginateFilter;
import java.util.ArrayList;
import java.util.Date;
@ -98,7 +98,7 @@ public class UserCourseRecordServiceImpl
@Override
public PaginationResult<UserCourseRecord> paginate(
int page, int size, CourseUserPaginateFilter filter) {
int page, int size, UserCourseRecordPaginateFilter filter) {
Integer pageStart = (page - 1) * size;
filter.setPageStart(pageStart);
filter.setPageSize(size);

View File

@ -0,0 +1,33 @@
/*
* 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.types.paginate;
import lombok.Data;
/**
* @Author 杭州白书科技有限公司
*
* @create 2023/4/17 17:10
*/
@Data
public class UserCourseHourRecordPaginateFilter {
private Integer userId;
private Integer pageStart;
private Integer pageSize;
private String sortField;
private String sortAlgo;
private Integer isFinished;
}

View File

@ -23,7 +23,7 @@ import lombok.Data;
* @create 2023/3/24 16:10
*/
@Data
public class CourseUserPaginateFilter {
public class UserCourseRecordPaginateFilter {
private Integer courseId;
private String email;
private String name;
@ -32,4 +32,6 @@ public class CourseUserPaginateFilter {
private String sortAlgo;
private Integer pageStart;
private Integer pageSize;
private Integer userId;
private Integer isFinished;
}

View File

@ -19,8 +19,7 @@
</resultMap>
<sql id="Base_Column_List">
id
,user_id,course_id,
id,user_id,course_id,
hour_id,total_duration,finished_duration,
real_duration,is_finished,finished_at,
created_at,updated_at
@ -51,4 +50,69 @@
</if>
GROUP BY `course_id`;
</select>
<select id="paginate" resultType="xyz.playedu.api.domain.UserCourseHourRecord">
SELECT *
FROM `user_course_hour_records` as `t`
<where>
<if test="userId != null">
AND `t`.`user_id` = #{userId}
</if>
<if test="isFinished != null">
AND `t`.`is_finisehd` = #{isFinished}
</if>
</where>
<if test="sortAlgo == 'asc'">
<choose>
<when test="sortField == 'finished_at'">
ORDER BY `t`.`finished_at` ASC
</when>
<when test="sortField == 'created_at'">
ORDER BY `t`.`created_at` ASC
</when>
<when test="sortField == 'updated_at'">
ORDER BY `t`.`updated_at` ASC
</when>
<when test="sortField == 'real_duration'">
ORDER BY `t`.`real_duration` ASC
</when>
<otherwise>
ORDER BY `t`.`id` ASC
</otherwise>
</choose>
</if>
<if test="sortAlgo != 'asc'">
<choose>
<when test="sortField == 'finished_at'">
ORDER BY `t`.`finished_at` DESC
</when>
<when test="sortField == 'created_at'">
ORDER BY `t`.`created_at` DESC
</when>
<when test="sortField == 'updated_at'">
ORDER BY `t`.`updated_at` DESC
</when>
<when test="sortField == 'real_duration'">
ORDER BY `t`.`real_duration` DESC
</when>
<otherwise>
ORDER BY `t`.`id` DESC
</otherwise>
</choose>
</if>
LIMIT #{pageStart}, #{pageSize};
</select>
<select id="paginateCount" resultType="java.lang.Long">
SELECT count(1)
FROM `user_course_hour_records` as `t`
<where>
<if test="userId != null">
AND `t`.`user_id` = #{userId}
</if>
<if test="isFinished != null">
AND `t`.`is_finisehd` = #{isFinished}
</if>
</where>
</select>
</mapper>

View File

@ -31,6 +31,12 @@
<if test="courseId != null">
AND `user_course_records`.`course_id` = #{courseId}
</if>
<if test="isFinished != null">
AND `user_course_records`.`is_finished` = #{isFinished}
</if>
<if test="userId != null">
AND `user_course_records`.`user_id` = #{userId}
</if>
<if test="name != null and name != ''">
AND `users`.`name` LIKE concat('%',#{name},'%')
</if>
@ -50,6 +56,12 @@
<if test="courseId != null">
AND `user_course_records`.`course_id` = #{courseId}
</if>
<if test="isFinished != null">
AND `user_course_records`.`is_finished` = #{isFinished}
</if>
<if test="userId != null">
AND `user_course_records`.`user_id` = #{userId}
</if>
<if test="name != null and name != ''">
AND `users`.`name` LIKE concat('%',#{name},'%')
</if>