Compare commits
81 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
337ba0f42a | ||
![]() |
42eb767979 | ||
326e764f29 | |||
3896f6df85 | |||
6cf1b91b85 | |||
61665d749d | |||
![]() |
bf470b1c79 | ||
58ea4b3071 | |||
69d2a464cb | |||
97419396f6 | |||
![]() |
5861ce2655 | ||
![]() |
a51f6c6e2e | ||
![]() |
9d490fbbda | ||
9dc9b50b1d | |||
e06a4b9f89 | |||
![]() |
5b0e087dcd | ||
796f1502b6 | |||
![]() |
a9a2a16618 | ||
![]() |
c48769872d | ||
![]() |
9830e0d3b3 | ||
52798ce478 | |||
35ed6f0b1b | |||
![]() |
50e127c505 | ||
![]() |
f2cf55e293 | ||
![]() |
520fbcf177 | ||
d9c50d4750 | |||
![]() |
3f2c7877ed | ||
![]() |
78de817ca9 | ||
![]() |
6b2ae0f50d | ||
b3fda1650b | |||
d7b8733123 | |||
81a6f0ee43 | |||
7f9bd444dd | |||
![]() |
049ee30611 | ||
![]() |
0d83336140 | ||
bf96853b68 | |||
![]() |
4080fa4ce5 | ||
![]() |
d069086ea4 | ||
![]() |
b4bbcb4d7d | ||
![]() |
23ad7f14f9 | ||
![]() |
4619edaad8 | ||
![]() |
593224a478 | ||
![]() |
8717b32306 | ||
![]() |
7188b7a500 | ||
![]() |
3d9fda6230 | ||
![]() |
4c160a7bb3 | ||
![]() |
d2b61c6d95 | ||
![]() |
de06ae4b92 | ||
![]() |
595bd526d4 | ||
![]() |
960aee1b68 | ||
![]() |
ec89859f60 | ||
![]() |
64b7eded58 | ||
![]() |
a4754cb513 | ||
![]() |
00df9d643b | ||
![]() |
d9ef0b8fa6 | ||
![]() |
02d0d55a9d | ||
![]() |
801e48b660 | ||
![]() |
c08fc2bb79 | ||
![]() |
2334fae638 | ||
![]() |
880626acfc | ||
![]() |
8f9e974aad | ||
962101f37a | |||
![]() |
9738eec256 | ||
![]() |
7caffa67cc | ||
![]() |
5bfea2b020 | ||
![]() |
a496d61524 | ||
![]() |
0427eebee7 | ||
![]() |
60c7ff577d | ||
![]() |
025be43257 | ||
![]() |
e5e0823e7a | ||
![]() |
865d3f8f22 | ||
![]() |
b992471374 | ||
![]() |
bc369ad2dc | ||
a6f8b2cd25 | |||
97e23b2ad1 | |||
83b06b7648 | |||
![]() |
64262ad748 | ||
![]() |
6b2ab8eed7 | ||
![]() |
4ddb774b32 | ||
![]() |
09a8f99ab8 | ||
![]() |
0922190012 |
4
.vscode/settings.json
vendored
Normal file
4
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"java.configuration.updateBuildConfiguration": "automatic",
|
||||
"java.compile.nullAnalysis.mode": "automatic"
|
||||
}
|
@ -18,7 +18,10 @@ services:
|
||||
--max_allowed_packet=128M
|
||||
--default-authentication-plugin=caching_sha2_password
|
||||
ports:
|
||||
- 13306:3306
|
||||
- 25523:3306
|
||||
# 添加数据卷挂载,将MySQL数据持久化到宿主机目录
|
||||
volumes:
|
||||
- /home/visionx/AIOL/mysql-jeecg:/var/lib/mysql
|
||||
networks:
|
||||
- jeecg-boot
|
||||
|
||||
@ -40,7 +43,7 @@ services:
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: vector_db
|
||||
ports:
|
||||
- 5432:5432
|
||||
- 25524:5432
|
||||
restart: always
|
||||
networks:
|
||||
- jeecg-boot
|
||||
@ -56,7 +59,7 @@ services:
|
||||
image: jeecg-boot-system
|
||||
hostname: jeecg-boot-system
|
||||
ports:
|
||||
- 8080:8080
|
||||
- 25525:8080
|
||||
networks:
|
||||
- jeecg-boot
|
||||
jeecg-vue:
|
||||
@ -69,8 +72,9 @@ services:
|
||||
networks:
|
||||
- jeecg-boot
|
||||
ports:
|
||||
- 80:80
|
||||
- 25526:80
|
||||
|
||||
networks:
|
||||
jeecg-boot:
|
||||
name: jeecg_boot
|
||||
|
||||
|
@ -165,7 +165,7 @@ public class JeecgBootExceptionHandler {
|
||||
public Result<?> handleMaxUploadSizeExceededException(MaxUploadSizeExceededException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
addSysLog(e);
|
||||
return Result.error("文件大小超出10MB限制, 请压缩或降低文件质量! ");
|
||||
return Result.error("文件大小超出限制, 请压缩或降低文件质量! ");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -16,6 +16,16 @@
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>jeecg-boot-base-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>jeecg-system-local-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>jeecg-system-biz</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -0,0 +1,51 @@
|
||||
package org.jeecg.modules.biz.constant;
|
||||
|
||||
/**
|
||||
* entity_link 表类型常量定义
|
||||
* source_type:主体类型
|
||||
* target_type:内容类型
|
||||
*/
|
||||
public final class EntityLinkConst {
|
||||
|
||||
private EntityLinkConst() {}
|
||||
|
||||
/** 主体类型 */
|
||||
public static final class SourceType {
|
||||
private SourceType() {}
|
||||
// 课程
|
||||
public static final String COURSE = "course";
|
||||
// 课程分类
|
||||
public static final String COURSE_CATEGORY = "course_category";
|
||||
// 课程章节
|
||||
public static final String COURSE_SECTION = "course_section";
|
||||
// 专题(字典/专题)
|
||||
public static final String SUBJECT = "subject";
|
||||
// 活动
|
||||
public static final String ACTIVITY = "activity";
|
||||
}
|
||||
|
||||
/** 内容类型 */
|
||||
public static final class TargetType {
|
||||
private TargetType() {}
|
||||
// 资源(对应资源表)
|
||||
public static final String RESOURCE = "resource";
|
||||
// 作业(对应作业表)
|
||||
public static final String HOMEWORK = "homework";
|
||||
// 考试(对应考试表)
|
||||
public static final String EXAM = "exam";
|
||||
// 课程
|
||||
public static final String COURSE = "course";
|
||||
// 题库
|
||||
public static final String REPO = "repo";
|
||||
}
|
||||
|
||||
/** 资源类型 0:视频,1:图片,2:文档 */
|
||||
public static final class ResourceType {
|
||||
private ResourceType() {}
|
||||
public static final int VIDEO = 0;
|
||||
public static final int IMAGE = 1;
|
||||
public static final int DOCUMENT = 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,71 @@
|
||||
package org.jeecg.modules.biz.controller;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.config.shiro.IgnoreAuth;
|
||||
import org.jeecg.modules.biz.service.ActivityBizService;
|
||||
import org.jeecg.modules.gen.activity.entity.Activity;
|
||||
import org.jeecg.modules.gen.aioltag.entity.AiolTag;
|
||||
import org.jeecg.modules.gen.aioltag.mapper.AiolTagMapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/biz/activity")
|
||||
@Tag(name = "活动")
|
||||
@Slf4j
|
||||
public class ActivityBizController {
|
||||
|
||||
@Autowired
|
||||
private ActivityBizService activityBizService;
|
||||
@Autowired
|
||||
private AiolTagMapper aiolTagMapper;
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "查询活动列表")
|
||||
@IgnoreAuth
|
||||
public Result<List<Activity>> list() {
|
||||
return Result.OK(activityBizService.getActivityList());
|
||||
}
|
||||
|
||||
@GetMapping("/selected")
|
||||
@Operation(summary = "查询精选活动")
|
||||
@IgnoreAuth
|
||||
public Result<List<Activity>> getSelectedActivities() {
|
||||
// 1. 从 aiol_tag 表查询 target_type='activity' 的 target_id 列表
|
||||
QueryWrapper<AiolTag> tagWrapper = new QueryWrapper<>();
|
||||
tagWrapper.eq("target_type", "activity");
|
||||
List<AiolTag> tags = aiolTagMapper.selectList(tagWrapper);
|
||||
|
||||
if (tags == null || tags.isEmpty()) {
|
||||
return Result.OK(List.of());
|
||||
}
|
||||
|
||||
// 2. 提取 target_id 列表
|
||||
List<String> activityIds = tags.stream()
|
||||
.map(AiolTag::getTargetId)
|
||||
.filter(id -> id != null && !id.trim().isEmpty())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (activityIds.isEmpty()) {
|
||||
return Result.OK(List.of());
|
||||
}
|
||||
|
||||
// 3. 根据 target_id 列表查询活动数据
|
||||
QueryWrapper<Activity> activityWrapper = new QueryWrapper<>();
|
||||
activityWrapper.in("id", activityIds);
|
||||
List<Activity> activities = activityBizService.list(activityWrapper);
|
||||
|
||||
return Result.OK(activities);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package org.jeecg.modules.biz.controller;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.config.shiro.IgnoreAuth;
|
||||
import org.jeecg.modules.biz.dto.CommentWithUserInfo;
|
||||
import org.jeecg.modules.biz.service.ICommentBizService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
|
||||
@Tag(name = "评论")
|
||||
@RestController
|
||||
@RequestMapping("/biz/comment")
|
||||
@Slf4j
|
||||
public class CommentBizController {
|
||||
|
||||
@Autowired
|
||||
private ICommentBizService commentBizService;
|
||||
|
||||
@GetMapping("/course/{courseId}/list")
|
||||
@Operation(summary = "查询课程评论列表", description = "根据课程ID查询课程评论列表,包含用户信息")
|
||||
@IgnoreAuth
|
||||
public Result<List<CommentWithUserInfo>> queryCourseCommentList(@PathVariable("courseId") String courseId) {
|
||||
List<CommentWithUserInfo> list = commentBizService.getCommentList("course", courseId);
|
||||
return Result.OK(list);
|
||||
}
|
||||
|
||||
// @GetMapping("/activity/{activityId}/list")
|
||||
// @Operation(summary = "查询活动评论列表", description = "根据活动ID查询活动评论列表,包含用户信息")
|
||||
// public Result<List<CommentWithUserInfo>> queryActivityCommentList(@PathVariable("activityId") String activityId) {
|
||||
// List<CommentWithUserInfo> list = commentBizService.getCommentList("activity", activityId);
|
||||
// return Result.OK(list);
|
||||
// }
|
||||
|
||||
// @GetMapping("/{targetType}/{targetId}/list")
|
||||
// @Operation(summary = "查询通用评论列表", description = "根据目标类型和目标ID查询评论列表,包含用户信息")
|
||||
// public Result<List<CommentWithUserInfo>> queryCommentList(
|
||||
// @PathVariable("targetType") String targetType,
|
||||
// @PathVariable("targetId") String targetId) {
|
||||
// List<CommentWithUserInfo> list = commentBizService.getCommentList(targetType, targetId);
|
||||
// return Result.OK(list);
|
||||
// }
|
||||
}
|
@ -0,0 +1,271 @@
|
||||
package org.jeecg.modules.biz.controller;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.system.vo.DictModel;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.config.shiro.IgnoreAuth;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
||||
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||
import org.jeecg.modules.biz.dto.CourseWithTeacherInfo;
|
||||
import org.jeecg.modules.biz.dto.TeacherInfo;
|
||||
import org.jeecg.modules.biz.service.CourseBizService;
|
||||
import org.jeecg.modules.gen.course.entity.Course;
|
||||
import org.jeecg.modules.gen.coursecategory.entity.CourseCategory;
|
||||
import org.jeecg.modules.gen.coursesection.entity.CourseSection;
|
||||
import org.jeecg.modules.gen.homework.entity.Homework;
|
||||
import org.jeecg.modules.gen.resource.entity.Resource;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.Comparator;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@Tag(name = "课程")
|
||||
@RestController
|
||||
@RequestMapping("/biz/course")
|
||||
@Slf4j
|
||||
public class CourseBizController {
|
||||
|
||||
@Autowired
|
||||
private CourseBizService courseBizService;
|
||||
@Autowired
|
||||
private ISysBaseAPI sysBaseApi;
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "查询课程列表", description = "可根据分类、难度、专题进行检索,三个参数可任意传递其中之一、之二或全部,每个参数可传递多个值,用英文逗号分割,不传参或传递all则查询所有课程,携带讲师信息")
|
||||
@IgnoreAuth
|
||||
public Result<List<CourseWithTeacherInfo>> queryCourseList(
|
||||
@RequestParam(value = "categoryId", required = false) String categoryId,
|
||||
@RequestParam(value = "difficulty", required = false) String difficulty,
|
||||
@RequestParam(value = "subject", required = false) String topic,
|
||||
@RequestParam(value = "sort", required = false) String sort) {
|
||||
List<CourseWithTeacherInfo> list = courseBizService.getCourseList(categoryId, difficulty, topic);
|
||||
if (sort != null) {
|
||||
switch (sort) {
|
||||
case "hottest":
|
||||
list = list.stream()
|
||||
.sorted(Comparator.comparing(Course::getEnrollCount, Comparator.nullsLast(Integer::compareTo)).reversed())
|
||||
.collect(Collectors.toList());
|
||||
break;
|
||||
case "latest":
|
||||
list = list.stream()
|
||||
.sorted(Comparator.comparing(Course::getCreateTime, Comparator.nullsLast(java.util.Date::compareTo)).reversed())
|
||||
.collect(Collectors.toList());
|
||||
break;
|
||||
case "recommend":
|
||||
default:
|
||||
// 不处理,直接返回
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Result.OK(list);
|
||||
}
|
||||
|
||||
@GetMapping("/detail")
|
||||
@Operation(summary = "查询课程详情", description = "根据课程ID查询课程详情")
|
||||
@IgnoreAuth
|
||||
public Result<Course> queryCourseDetail(@RequestParam(value = "id") String id) {
|
||||
Course course = courseBizService.getById(id);
|
||||
return Result.OK(course);
|
||||
}
|
||||
|
||||
@GetMapping("/subject/list")
|
||||
@Operation(summary = "查询课程专题列表", description = "返回字典值")
|
||||
@IgnoreAuth
|
||||
public Result<List<LabelValue>> querySubjectList() {
|
||||
List<DictModel> list = sysBaseApi.getDictItems("course_subject");
|
||||
List<LabelValue> simple = list.stream()
|
||||
.map(d -> new LabelValue(d.getValue(), d.getLabel() != null ? d.getLabel() : d.getText()))
|
||||
.collect(Collectors.toList());
|
||||
return Result.OK(simple);
|
||||
}
|
||||
|
||||
/** 仅返回 value、label 的简单对象 */
|
||||
private static record LabelValue(String value, String label) {
|
||||
}
|
||||
|
||||
@GetMapping("/difficulty/list")
|
||||
@Operation(summary = "查询课程难度列表", description = "返回字典值")
|
||||
@IgnoreAuth
|
||||
public Result<List<LabelValue>> queryDifficultyList() {
|
||||
List<DictModel> list = sysBaseApi.getDictItems("course_difficulty");
|
||||
List<LabelValue> simple = list.stream()
|
||||
.map(d -> new LabelValue(d.getValue(), d.getLabel() != null ? d.getLabel() : d.getText()))
|
||||
.collect(Collectors.toList());
|
||||
return Result.OK(simple);
|
||||
}
|
||||
|
||||
@GetMapping("/category/list")
|
||||
@Operation(summary = "查询课程分类列表", description = "根据sortOrder降序排序")
|
||||
@IgnoreAuth
|
||||
public Result<List<CourseCategory>> queryCategoryList() {
|
||||
List<CourseCategory> list = courseBizService.getCourseCategoryList();
|
||||
return Result.OK(list);
|
||||
}
|
||||
|
||||
@GetMapping("/{courseId}/section")
|
||||
@Operation(summary = "查询课程章节列表", description = "根据课程id查询章节列表,type表示章节类型:0=视频、1=资料、2=考试、3=作业;level表示章节层级,0=一级章节、1=二级章节,通过parentId记录父子关系,前端需自行组织树形结构;当前层级的顺序通过sortOrder排序")
|
||||
@IgnoreAuth
|
||||
public Result<List<CourseSection>> querySectionList(@PathVariable(value = "courseId") String courseId) {
|
||||
List<CourseSection> list = courseBizService.getCourseSectionList(courseId);
|
||||
return Result.OK(list);
|
||||
}
|
||||
|
||||
@GetMapping("/{courseId}/section_video/{sectionId}")
|
||||
@Operation(summary = "查询视频章节详情", description = "该接口需要携带用户登录token。根据章节id查询章节详情,不同类型的章节,返回的内容不同")
|
||||
public Result<List<Resource>> querySectionDetail(@PathVariable(value = "courseId") String courseId, @PathVariable(value = "sectionId") String sectionId) {
|
||||
// TODO GC 获取用户id,根据courseId判断当前用户是否报名课程,只有已报名的课程才能查看章节详情
|
||||
|
||||
List<Resource> list = courseBizService.getCourseSectionDetail(0, sectionId, Resource.class);
|
||||
return Result.OK(list);
|
||||
}
|
||||
|
||||
@GetMapping("/{courseId}/section_document/{sectionId}")
|
||||
@Operation(summary = "查询文档章节详情", description = "该接口需要携带用户登录token。根据章节id查询章节详情,不同类型的章节,返回的内容不同")
|
||||
public Result<List<Resource>> querySectionDocumentDetail(@PathVariable(value = "courseId") String courseId, @PathVariable(value = "sectionId") String sectionId) {
|
||||
// TODO GC 获取用户id,根据courseId判断当前用户是否报名课程,只有已报名的课程才能查看章节详情
|
||||
|
||||
List<Resource> list = courseBizService.getCourseSectionDetail(1, sectionId, Resource.class);
|
||||
return Result.OK(list);
|
||||
}
|
||||
|
||||
@GetMapping("/{courseId}/section_homework/{sectionId}")
|
||||
@Operation(summary = "查询作业章节详情", description = "该接口需要携带用户登录token。根据章节id查询章节详情,不同类型的章节,返回的内容不同")
|
||||
public Result<List<Homework>> querySectionHomeworkDetail(@PathVariable(value = "courseId") String courseId, @PathVariable(value = "sectionId") String sectionId) {
|
||||
// TODO GC 获取用户id,根据courseId判断当前用户是否报名课程,只有已报名的课程才能查看章节详情
|
||||
|
||||
List<Homework> list = courseBizService.getCourseSectionDetail(3, sectionId, Homework.class);
|
||||
return Result.OK(list);
|
||||
}
|
||||
|
||||
@GetMapping("/{courseId}/teachers")
|
||||
@Operation(summary = "查询课程的授课教师")
|
||||
@IgnoreAuth
|
||||
public Result<List<TeacherInfo>> queryTeacherList(@PathVariable(value = "courseId") String courseId) {
|
||||
List<TeacherInfo> list = courseBizService.getCourseTeacherList(courseId);
|
||||
return Result.OK(list);
|
||||
}
|
||||
|
||||
@PostMapping("/{courseId}/enroll")
|
||||
@Operation(summary = "报名课程", description = "该接口需要携带用户登录token。根据课程id报名课程。返回值为报名结果,报名成功返回success")
|
||||
public Result<String> enrollCourse(@PathVariable(value = "courseId") String courseId, HttpServletRequest request, HttpServletResponse response) {
|
||||
String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||
String username = JwtUtil.getUsername(token);
|
||||
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
||||
String result = courseBizService.enrollCourse(courseId, sysUser.getId());
|
||||
return Result.OK(result);
|
||||
}
|
||||
|
||||
@GetMapping("/{courseId}/is_enrolled")
|
||||
@Operation(summary = "查询课程是否已报名", description = "该接口需要携带用户登录token。根据课程id查询课程是否已报名。判断返回值的result是否为true")
|
||||
public Result<Boolean> isEnrolled(@PathVariable(value = "courseId") String courseId, HttpServletRequest request, HttpServletResponse response) {
|
||||
String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||
String username = JwtUtil.getUsername(token);
|
||||
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
||||
|
||||
boolean isEnrolled = courseBizService.isEnrolled(courseId, sysUser.getId());
|
||||
return Result.OK(isEnrolled);
|
||||
}
|
||||
|
||||
@GetMapping("/teacher_list")
|
||||
@Operation(summary = "查询当前教师创建的课程")
|
||||
public Result<List<Course>> queryTeacherCourseList(
|
||||
@RequestParam(value = "keyword", required = false) String keyword,
|
||||
@RequestParam(value = "status", required = false) Integer status,
|
||||
HttpServletRequest request, HttpServletResponse response) {
|
||||
String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||
String username = JwtUtil.getUsername(token);
|
||||
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
||||
|
||||
QueryWrapper<Course> wrapper = new QueryWrapper<Course>().eq("create_by", sysUser.getUsername());
|
||||
|
||||
// 课程名关键词检索
|
||||
if (keyword != null && !keyword.trim().isEmpty()) {
|
||||
wrapper.like("name", keyword.trim());
|
||||
}
|
||||
|
||||
// 状态检索:0 未开始;1进行中;2已结束
|
||||
if (status != null) {
|
||||
wrapper.eq("status", status);
|
||||
}
|
||||
|
||||
List<Course> list = courseBizService.list(wrapper);
|
||||
return Result.OK(list);
|
||||
}
|
||||
|
||||
@PostMapping("/{courseId}/add_students")
|
||||
@Operation(summary = "批量导入学生", description = "请求体为JSON格式,包含ids字段,ids为逗号分隔的学生ID字符串")
|
||||
public Result<Map<String, Object>> addStudents(@PathVariable(value = "courseId") String courseId, @RequestBody Map<String, Object> requestBody, HttpServletRequest request) {
|
||||
String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||
String username = JwtUtil.getUsername(token);
|
||||
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
||||
|
||||
// 从Map中获取ids字段
|
||||
String ids = (String) requestBody.get("ids");
|
||||
if (ids == null || ids.trim().isEmpty()) {
|
||||
return Result.error("ids字段不能为空");
|
||||
}
|
||||
|
||||
return Result.OK(courseBizService.addStudents(courseId, ids, sysUser));
|
||||
}
|
||||
|
||||
@GetMapping("/{courseId}/progress")
|
||||
@Operation(summary = "查询课程学习进度")
|
||||
public Result<Map<String, Object>> queryCourseProgress(@PathVariable(value = "courseId") String courseId, HttpServletRequest request, HttpServletResponse response) {
|
||||
String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||
String username = JwtUtil.getUsername(token);
|
||||
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
||||
|
||||
Map<String, Object> progress = courseBizService.getCourseProgress(courseId, sysUser.getId());
|
||||
return Result.OK(progress);
|
||||
}
|
||||
|
||||
@GetMapping("/count")
|
||||
@Operation(summary = "查询课程总数", description = "返回系统中所有课程的总数量")
|
||||
@IgnoreAuth
|
||||
public Result<Long> queryCourseCount() {
|
||||
long count = courseBizService.count();
|
||||
return Result.OK(count);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@GetMapping("/test")
|
||||
@IgnoreAuth
|
||||
public Result<String> test() {
|
||||
return Result.OK("test");
|
||||
}
|
||||
|
||||
@GetMapping("/test2")
|
||||
public Result<String> test2(HttpServletRequest request, HttpServletResponse response) {
|
||||
String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
|
||||
String username = JwtUtil.getUsername(token);
|
||||
LoginUser sysUser = sysBaseApi.getUserByName(username);
|
||||
return Result.OK(sysUser.toString());
|
||||
}
|
||||
|
||||
@GetMapping("/test3")
|
||||
@IgnoreAuth
|
||||
public Result<Long> test3() {
|
||||
long count = courseBizService.count();
|
||||
return Result.OK(count);
|
||||
}
|
||||
}
|
@ -0,0 +1,436 @@
|
||||
package org.jeecg.modules.biz.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.modules.gen.exam.entity.Exam;
|
||||
import org.jeecg.modules.gen.exam.service.IExamService;
|
||||
import org.jeecg.modules.gen.examanswer.entity.ExamAnswer;
|
||||
import org.jeecg.modules.gen.examanswer.service.IExamAnswerService;
|
||||
import org.jeecg.modules.gen.examrecord.entity.ExamRecord;
|
||||
import org.jeecg.modules.gen.examrecord.service.IExamRecordService;
|
||||
import org.jeecg.modules.gen.paper.entity.Paper;
|
||||
import org.jeecg.modules.gen.paper.service.IPaperService;
|
||||
import org.jeecg.modules.gen.paperquestion.entity.PaperQuestion;
|
||||
import org.jeecg.modules.gen.paperquestion.service.IPaperQuestionService;
|
||||
import org.jeecg.modules.gen.question.controller.QuestionController;
|
||||
import org.jeecg.modules.gen.question.entity.Question;
|
||||
import org.jeecg.modules.gen.question.entity.QuestionRequest;
|
||||
import org.jeecg.modules.gen.question.service.IQuestionService;
|
||||
import org.jeecg.modules.gen.questionoption.entity.QuestionOption;
|
||||
import org.jeecg.modules.gen.questionoption.service.IQuestionOptionService;
|
||||
import org.jeecg.modules.gen.questionrepo.entity.QuestionRepo;
|
||||
import org.jeecg.modules.gen.questionrepo.service.IQuestionRepoService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/biz/exam")
|
||||
@Tag(name = "考试")
|
||||
@Slf4j
|
||||
public class ExamBizController {
|
||||
@Autowired
|
||||
private IPaperService paperService;
|
||||
@Autowired
|
||||
private IExamService examService;
|
||||
@Autowired
|
||||
private IPaperQuestionService paperQuestionService;
|
||||
@Autowired
|
||||
private IExamAnswerService examAnswerService;
|
||||
@Autowired
|
||||
private IExamRecordService examRecordService;
|
||||
@Autowired
|
||||
private IQuestionService questionService;
|
||||
@Autowired
|
||||
private IQuestionRepoService questionRepoService;
|
||||
@Autowired
|
||||
private IQuestionOptionService questionOptionService;
|
||||
|
||||
//获取考试试题
|
||||
@RequestMapping("/getExamQuestions/{examId}")
|
||||
@Operation(summary = "获取考试试题")
|
||||
@Transactional
|
||||
public Result<?> getExamQuestions(@PathVariable String examId, @RequestParam String studentId) {
|
||||
Exam exam = examService.getById(examId);
|
||||
if(exam.getPaperId().isEmpty()){
|
||||
return Result.error("考试未关联试卷");
|
||||
}
|
||||
Paper paper = paperService.getById(exam.getPaperId());
|
||||
//题目id集合
|
||||
List<String> questionIds;
|
||||
List<PaperQuestion> paperQuestions = new ArrayList<>();
|
||||
//随机组卷
|
||||
if(paper.getGenerateMode()==1){
|
||||
List<QuestionRepo> list = questionRepoService.list(
|
||||
new LambdaQueryWrapper<QuestionRepo>().
|
||||
eq(QuestionRepo::getRepoId, paper.getRepoId())
|
||||
);
|
||||
//筛选试卷
|
||||
questionIds = random(list, paper.getRules());
|
||||
}else {
|
||||
//固定组卷
|
||||
// 获取试卷中的试题关联信息
|
||||
paperQuestions = paperQuestionService.getQuestions(paper.getId());
|
||||
|
||||
// 如果没有试题关联信息,直接返回空列表
|
||||
if (CollectionUtils.isEmpty(paperQuestions)) {
|
||||
return Result.OK("试卷中没有试题");
|
||||
}
|
||||
// 提取所有试题ID
|
||||
questionIds = paperQuestions.stream()
|
||||
.map(PaperQuestion::getQuestionId)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
if (CollectionUtils.isEmpty(questionIds)) {
|
||||
return Result.OK("试卷中没有试题");
|
||||
}
|
||||
// 从题目表查询试题内容
|
||||
List<Question> questions = questionService.listByIds(questionIds);
|
||||
|
||||
List<Question> sortedQuestions = questions;
|
||||
// 将试题内容按试卷中的顺序排序
|
||||
if(paper.getGenerateMode()==0){
|
||||
Map<String, Question> questionMap = questions.stream()
|
||||
.collect(Collectors.toMap(Question::getId, question -> question));
|
||||
sortedQuestions = paperQuestions.stream()
|
||||
.sorted(Comparator.comparing(PaperQuestion::getOrderNo))
|
||||
.map(paperQuestion -> questionMap.get(paperQuestion.getQuestionId()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
//获取复选题id
|
||||
List<String> type5Ids = sortedQuestions.stream()
|
||||
.filter(question -> question.getType() == 5)
|
||||
.map(Question::getId)
|
||||
.collect(Collectors.toList());
|
||||
//获取复选题所包含的题目
|
||||
List<Question> type5Questions = new ArrayList<>();
|
||||
if (!type5Ids.isEmpty()) {
|
||||
type5Questions = questionService.list(
|
||||
new LambdaQueryWrapper<Question>()
|
||||
.in(Question::getParentId, type5Ids)
|
||||
);
|
||||
}
|
||||
// 创建一个映射,用于快速查找父ID对应的子题目
|
||||
Map<String, List<Question>> parentToChildrenMap = type5Questions.stream()
|
||||
.collect(Collectors.groupingBy(Question::getParentId));
|
||||
|
||||
// 将子题目添加到原始列表中,保持原有顺序
|
||||
List<Question> resultQuestions = new ArrayList<>();
|
||||
for (Question question : questions) {
|
||||
resultQuestions.add(question);
|
||||
if (question.getType() == 5) {
|
||||
List<Question> children = parentToChildrenMap.getOrDefault(question.getId(), Collections.emptyList());
|
||||
resultQuestions.addAll(children);
|
||||
}
|
||||
}
|
||||
//创建考试答题初始化记录
|
||||
List<ExamAnswer> examAnswerList = new ArrayList<>();
|
||||
for (Question resultQuestion : resultQuestions) {
|
||||
ExamAnswer examAnswer = new ExamAnswer();
|
||||
examAnswer.setExamId(examId);
|
||||
examAnswer.setUserId(studentId);
|
||||
if (resultQuestion != null && StringUtils.isNotEmpty(resultQuestion.getParentId())) {
|
||||
examAnswer.setParentQuestionId(resultQuestion.getParentId());
|
||||
}
|
||||
examAnswer.setQuestionId(resultQuestion.getId());
|
||||
examAnswerList.add(examAnswer);
|
||||
}
|
||||
examAnswerService.saveBatch(examAnswerList);
|
||||
//创建考试记录
|
||||
ExamRecord examRecord = new ExamRecord();
|
||||
examRecord.setExamId(examId);
|
||||
examRecord.setUserId(studentId);
|
||||
examRecord.setStatus(0);
|
||||
examRecordService.save(examRecord);
|
||||
// 返回排序后的试题总列表
|
||||
return Result.OK(resultQuestions);
|
||||
}
|
||||
|
||||
@PostMapping("/submitAnswer")
|
||||
@Operation(summary = "提交答案")
|
||||
public Result<?> submitAnswer(@RequestBody ExamAnswer examAnswer) {
|
||||
// 创建查询条件
|
||||
LambdaUpdateWrapper<ExamAnswer> updateWrapper = new LambdaUpdateWrapper<>();
|
||||
updateWrapper.eq(ExamAnswer::getExamId, examAnswer.getExamId())
|
||||
.eq(ExamAnswer::getUserId, examAnswer.getUserId())
|
||||
.eq(ExamAnswer::getQuestionId, examAnswer.getQuestionId());
|
||||
|
||||
// 更新答案
|
||||
if (examAnswer.getAnswer() != null) {
|
||||
updateWrapper.set(ExamAnswer::getAnswer, examAnswer.getAnswer());
|
||||
}
|
||||
// 执行更新
|
||||
return examAnswerService.update(updateWrapper) ? Result.OK() : Result.error("提交答案失败");
|
||||
}
|
||||
|
||||
@PostMapping("/submitExam")
|
||||
@Operation(summary = "提交考试")
|
||||
@Transactional
|
||||
public Result<?> submitExam(@RequestBody ExamRecord examRecord,
|
||||
HttpServletRequest req) {
|
||||
examRecord.setIpAddress(getClientIp(req));
|
||||
examRecord.setDeviceInfo(getDeviceInfo(req));
|
||||
//修改状态
|
||||
examRecord.setStatus(1);
|
||||
// 创建更新条件
|
||||
LambdaUpdateWrapper<ExamRecord> updateWrapper = new LambdaUpdateWrapper<>();
|
||||
updateWrapper.eq(ExamRecord::getExamId, examRecord.getExamId())
|
||||
.eq(ExamRecord::getUserId, examRecord.getUserId());
|
||||
// 更新ip
|
||||
if (examRecord.getIpAddress() != null) {
|
||||
updateWrapper.set(ExamRecord::getIpAddress, examRecord.getIpAddress());
|
||||
}
|
||||
// 更新设备信息
|
||||
if (examRecord.getDeviceInfo() != null) {
|
||||
updateWrapper.set(ExamRecord::getDeviceInfo, examRecord.getDeviceInfo());
|
||||
}
|
||||
// 阅卷
|
||||
List<ExamAnswer> gradedAnswers = gradeExam(examRecord.getExamId(), examRecord.getUserId());
|
||||
examAnswerService.updateBatchById(gradedAnswers);
|
||||
// 更新考试状态,提交时间
|
||||
updateWrapper.
|
||||
set(ExamRecord::getStatus,1).
|
||||
set(ExamRecord::getSubmittedAt, new Date());
|
||||
// 更新
|
||||
return examRecordService.update(updateWrapper) ? Result.OK() : Result.error("提交考试失败");
|
||||
}
|
||||
|
||||
@GetMapping("/queryExamProgress")
|
||||
@Operation(summary = "查询考试进度")
|
||||
public Result<?> queryExamProgress(@RequestParam String examId, @RequestParam String userId) {
|
||||
Exam byId = examService.getById(examId);
|
||||
if(byId == null){
|
||||
return Result.error("考试不存在");
|
||||
}
|
||||
//判断考试结束时间
|
||||
if(byId.getEndTime().before(new Date())){
|
||||
return Result.error("考试已结束");
|
||||
}
|
||||
ExamRecord one = examRecordService.getOne(
|
||||
new LambdaQueryWrapper<ExamRecord>()
|
||||
.eq(ExamRecord::getExamId, examId)
|
||||
.eq(ExamRecord::getUserId, userId)
|
||||
);
|
||||
if(one == null){
|
||||
return Result.error("用户暂未考试,可获取考试题目");
|
||||
}
|
||||
return Result.OK(examAnswerService.
|
||||
list(new LambdaQueryWrapper<ExamAnswer>().
|
||||
eq(ExamAnswer::getExamId, examId).
|
||||
eq(ExamAnswer::getUserId, userId))
|
||||
);
|
||||
}
|
||||
|
||||
//根据考试规则随机组卷
|
||||
public List<String> random(List<QuestionRepo> list, String rules) {
|
||||
JSONObject ruleJson = JSON.parseObject(rules);
|
||||
|
||||
// 根据规则筛选和随机抽取题目
|
||||
Map<Integer, List<String>> typeQuestions = new HashMap<>();
|
||||
|
||||
// 先按题目类型分组
|
||||
list.forEach(qr -> {
|
||||
Question question = questionService.getById(qr.getQuestionId());
|
||||
if (!typeQuestions.containsKey(question.getType())) {
|
||||
typeQuestions.put(question.getType(), new ArrayList<>());
|
||||
}
|
||||
typeQuestions.get(question.getType()).add(question.getId());
|
||||
});
|
||||
|
||||
// 根据规则随机抽取题目
|
||||
List<String> questionIds = new ArrayList<>();
|
||||
for (Integer type : typeQuestions.keySet()) {
|
||||
int count = ruleJson.getInteger("type"+type + "_count"); // 例如:single_choice_count
|
||||
List<String> typeQuestionIds = typeQuestions.get(type);
|
||||
|
||||
// 随机抽取指定数量的题目
|
||||
if (typeQuestionIds.size() <= count) {
|
||||
questionIds.addAll(typeQuestionIds);
|
||||
} else {
|
||||
// 打乱顺序后取前count个
|
||||
Collections.shuffle(typeQuestionIds);
|
||||
questionIds.addAll(typeQuestionIds.subList(0, count));
|
||||
}
|
||||
}
|
||||
return questionIds;
|
||||
}
|
||||
|
||||
//获取ip信息
|
||||
public String getClientIp(HttpServletRequest request) {
|
||||
String ip = request.getHeader("X-Forwarded-For");
|
||||
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_CLIENT_IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getRemoteAddr();
|
||||
}
|
||||
// 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
|
||||
if (ip != null && ip.contains(",")) {
|
||||
ip = ip.split(",")[0].trim();
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量阅卷
|
||||
* @param examId 考试ID
|
||||
* @param userId 用户ID
|
||||
* @return 阅卷后的答题列表
|
||||
*/
|
||||
private List<ExamAnswer> gradeExam(String examId, String userId) {
|
||||
// 获取学生的答题列表
|
||||
List<ExamAnswer> examAnswerList = examAnswerService.list(new LambdaQueryWrapper<ExamAnswer>()
|
||||
.eq(ExamAnswer::getExamId, examId)
|
||||
.eq(ExamAnswer::getUserId, userId)
|
||||
);
|
||||
|
||||
// 提取所有题目ID
|
||||
List<String> questionIds = examAnswerList.stream()
|
||||
.map(ExamAnswer::getQuestionId)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 查询题目
|
||||
List<Question> questions = questionService.list(new LambdaQueryWrapper<Question>()
|
||||
.in(Question::getId, questionIds)
|
||||
.lt(Question::getType, 3)
|
||||
);
|
||||
|
||||
// 创建题目ID到题目的映射
|
||||
Map<String, Question> questionMap = questions.stream()
|
||||
.collect(Collectors.toMap(Question::getId, question -> question));
|
||||
|
||||
// 获取 选择、多选、判断 题目ID列表
|
||||
List<String> questionIdsFromQuestions = questions.stream()
|
||||
.map(Question::getId)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 查询这些题目的正确选项
|
||||
List<QuestionOption> questionOptions = questionOptionService.list(new LambdaQueryWrapper<QuestionOption>()
|
||||
.in(QuestionOption::getQuestionId, questionIdsFromQuestions)
|
||||
.eq(QuestionOption::getIzCorrent, 1)
|
||||
);
|
||||
|
||||
// 将选项转换为Map,结构为:题目ID -> 正确答案选项ID列表
|
||||
Map<String, List<String>> correctAnswerMap = questionOptions.stream()
|
||||
.collect(Collectors.groupingBy(
|
||||
QuestionOption::getQuestionId,
|
||||
Collectors.mapping(QuestionOption::getId, Collectors.toList())
|
||||
));
|
||||
|
||||
// 遍历学生的答案,进行评分
|
||||
for (ExamAnswer examAnswer : examAnswerList) {
|
||||
String studentAnswer = examAnswer.getAnswer();
|
||||
Question question = questionMap.get(examAnswer.getQuestionId());
|
||||
List<String> correctAnswers = correctAnswerMap.get(examAnswer.getQuestionId());
|
||||
|
||||
// 比较答案并设置分数
|
||||
if (studentAnswer != null && question != null && correctAnswers != null) {
|
||||
// 将学生答案按逗号分割成列表
|
||||
List<String> studentAnswers = Arrays.asList(studentAnswer.split(","));
|
||||
double score = 0.0;
|
||||
|
||||
// 根据题目类型进行评分
|
||||
if (question.getType() == 1 || question.getType() == 2) { // 单选题或判断题
|
||||
if (studentAnswers.get(0).equals(correctAnswers.get(0))) {
|
||||
score = question.getScore(); // 使用题目设定的分值
|
||||
}
|
||||
} else if (question.getType() == 3) { // 多选题
|
||||
// 检查学生答案数量是否正确
|
||||
if (studentAnswers.size() == correctAnswers.size()) {
|
||||
// 检查每个答案是否都正确
|
||||
boolean allCorrect = studentAnswers.stream()
|
||||
.allMatch(correctAnswers::contains);
|
||||
|
||||
if (allCorrect) {
|
||||
score = question.getScore(); // 使用题目设定的分值
|
||||
}
|
||||
}
|
||||
}
|
||||
examAnswer.setIzCorrect(score> 0.0 ? 1 : 0);
|
||||
examAnswer.setScore(score);
|
||||
} else {
|
||||
examAnswer.setScore(0.0); // 答案为空或题目不存在
|
||||
}
|
||||
}
|
||||
return examAnswerList;
|
||||
}
|
||||
|
||||
//获取设备信息
|
||||
public String getDeviceInfo(HttpServletRequest request) {
|
||||
// 获取User-Agent
|
||||
String userAgent = request.getHeader("User-Agent");
|
||||
// 解析设备信息
|
||||
String deviceInfo = parseDeviceInfo(userAgent);
|
||||
return deviceInfo;
|
||||
}
|
||||
private String parseDeviceInfo(String userAgent) {
|
||||
if (userAgent == null) {
|
||||
return "Unknown";
|
||||
}
|
||||
StringBuilder deviceInfo = new StringBuilder();
|
||||
// 判断操作系统
|
||||
if (userAgent.indexOf("Windows") > -1) {
|
||||
deviceInfo.append("Windows");
|
||||
} else if (userAgent.indexOf("Mac") > -1) {
|
||||
deviceInfo.append("Mac");
|
||||
} else if (userAgent.indexOf("X11") > -1) {
|
||||
deviceInfo.append("Unix");
|
||||
} else if (userAgent.indexOf("Android") > -1) {
|
||||
deviceInfo.append("Android");
|
||||
} else if (userAgent.indexOf("iPhone") > -1 || userAgent.indexOf("iPad") > -1) {
|
||||
deviceInfo.append("iOS");
|
||||
} else {
|
||||
deviceInfo.append("Unknown OS");
|
||||
}
|
||||
deviceInfo.append(" | ");
|
||||
// 判断浏览器
|
||||
if (userAgent.indexOf("MSIE") > -1) {
|
||||
deviceInfo.append("MSIE");
|
||||
} else if (userAgent.indexOf("Firefox") > -1) {
|
||||
deviceInfo.append("Firefox");
|
||||
} else if (userAgent.indexOf("Chrome") > -1) {
|
||||
deviceInfo.append("Chrome");
|
||||
} else if (userAgent.indexOf("Safari") > -1) {
|
||||
deviceInfo.append("Safari");
|
||||
} else if (userAgent.indexOf("Opera") > -1) {
|
||||
deviceInfo.append("Opera");
|
||||
} else {
|
||||
deviceInfo.append("Unknown Browser");
|
||||
}
|
||||
// 可以添加更多设备信息的判断,如:
|
||||
// 判断是否是移动设备
|
||||
boolean isMobile = userAgent.indexOf("Mobile") > -1 ||
|
||||
userAgent.indexOf("Android") > -1 ||
|
||||
userAgent.indexOf("iPhone") > -1;
|
||||
deviceInfo.append(" | ").append(isMobile ? "Mobile" : "PC");
|
||||
return deviceInfo.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package org.jeecg.modules.biz.controller;
|
||||
|
||||
import org.jeecg.modules.biz.dto.StudentSubmitHomework;
|
||||
import org.jeecg.modules.gen.homeworksubmit.entity.HomeworkSubmit;
|
||||
import org.jeecg.modules.gen.homeworksubmit.service.IHomeworkSubmitService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import java.util.List;
|
||||
|
||||
import org.jeecg.modules.biz.service.IHomeworkBizService;
|
||||
import org.jeecg.modules.gen.homework.entity.Homework;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/biz/homework")
|
||||
@Tag(name = "作业")
|
||||
@Slf4j
|
||||
public class HomeworkBizController {
|
||||
|
||||
@Autowired
|
||||
private IHomeworkBizService homeworkBizService;
|
||||
@Autowired
|
||||
private IHomeworkSubmitService homeworkSubmitService;
|
||||
|
||||
@GetMapping("/course/{courseId}")
|
||||
@Operation(summary = "查询课程作业")
|
||||
public Result<List<Homework>> list(@PathVariable String courseId) {
|
||||
return Result.OK(homeworkBizService.listByCourseId(courseId));
|
||||
}
|
||||
|
||||
@PostMapping("submit")
|
||||
@Operation(summary = "提交作业")
|
||||
public Result<String> submit(@RequestBody StudentSubmitHomework studentSubmitHomework) {
|
||||
return Result.OK(homeworkSubmitService.submit(studentSubmitHomework)?"提交成功":"提交失败");
|
||||
}
|
||||
|
||||
@GetMapping("submitted/{studentId}")
|
||||
@Operation(summary = "查询我已提交的作业")
|
||||
public Result<List<HomeworkSubmit>> submitted(@PathVariable String studentId) {
|
||||
return Result.OK(homeworkSubmitService.submitted(studentId));
|
||||
}
|
||||
|
||||
@PostMapping("correct/{homeworkSubmitId}")
|
||||
@Operation(summary = "教师批改作业")
|
||||
public Result<Integer> correct(@PathVariable String homeworkSubmitId, @RequestParam Integer score,
|
||||
@RequestParam String comment,@RequestParam String teacherId) {
|
||||
return Result.OK(homeworkSubmitService.correct(homeworkSubmitId, score,comment, teacherId));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,173 @@
|
||||
package org.jeecg.modules.biz.controller;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.config.shiro.IgnoreAuth;
|
||||
import org.jeecg.modules.biz.dto.CommentWithUserInfo;
|
||||
import org.jeecg.modules.biz.service.ICommentBizService;
|
||||
import org.jeecg.modules.gen.contentconfig.entity.ContentConfig;
|
||||
import org.jeecg.modules.gen.contentconfig.mapper.ContentConfigMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.data.redis.core.ZSetOperations.TypedTuple;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.modules.gen.course.entity.Course;
|
||||
import org.jeecg.modules.gen.course.mapper.CourseMapper;
|
||||
|
||||
@Tag(name = "首页")
|
||||
@RestController
|
||||
@RequestMapping("/biz/index")
|
||||
@Slf4j
|
||||
public class IndexBizController {
|
||||
@Autowired
|
||||
private ContentConfigMapper contentConfigMapper;
|
||||
@Autowired
|
||||
private ICommentBizService commentBizService;
|
||||
@Autowired(required = false)
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
@Autowired
|
||||
private CourseMapper courseMapper;
|
||||
|
||||
private static final String HOT_SEARCH_ZSET_KEY = "hot:search";
|
||||
|
||||
@GetMapping("/content")
|
||||
@Operation(summary = "查询首页内容")
|
||||
@IgnoreAuth
|
||||
public Result<String> queryContent(@RequestParam String contentKey) {
|
||||
ContentConfig contentConfig = contentConfigMapper.selectOne(new QueryWrapper<ContentConfig>().eq("content_key", contentKey));
|
||||
if (contentConfig == null) {
|
||||
return Result.error("内容配置不存在");
|
||||
}
|
||||
return Result.OK(contentConfig.getContentValue());
|
||||
}
|
||||
|
||||
@GetMapping("/statistics")
|
||||
@Operation(summary = "查询首页数据统计")
|
||||
@IgnoreAuth
|
||||
public Result<Map<String, Object>> queryStatistics() {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
|
||||
// 定义统计项的配置键
|
||||
String[] statisticsKeys = {"xxsp", "mszj", "pxjc", "zysc", "zxsy"};
|
||||
|
||||
// 从配置表查询每个统计项的值
|
||||
for (String key : statisticsKeys) {
|
||||
ContentConfig contentConfig = contentConfigMapper.selectOne(
|
||||
new QueryWrapper<ContentConfig>().eq("content_key", key)
|
||||
);
|
||||
|
||||
if (contentConfig != null && contentConfig.getContentValue() != null) {
|
||||
try {
|
||||
// 尝试解析为数字,如果失败则使用默认值0
|
||||
Integer value = Integer.parseInt(contentConfig.getContentValue());
|
||||
map.put(key, value);
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("配置项 {} 的值 {} 不是有效数字,使用默认值0", key, contentConfig.getContentValue());
|
||||
map.put(key, 0);
|
||||
}
|
||||
} else {
|
||||
log.warn("配置项 {} 不存在,使用默认值0", key);
|
||||
map.put(key, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return Result.OK(map);
|
||||
}
|
||||
|
||||
@GetMapping("/selected_comments")
|
||||
@Operation(summary = "查询精选评论")
|
||||
@IgnoreAuth
|
||||
public Result<List<CommentWithUserInfo>> querySelectedComments() {
|
||||
// 查询精选评论(包含用户信息)
|
||||
List<CommentWithUserInfo> comments = commentBizService.getAllSelectedComments();
|
||||
return Result.OK(comments);
|
||||
}
|
||||
|
||||
@GetMapping("/hot_search")
|
||||
@Operation(summary = "查询热门搜索记录(关键词+搜索次数,Redis ZSet 排名)")
|
||||
@IgnoreAuth
|
||||
public Result<List<Map<String, Object>>> queryHotSearch(@RequestParam(defaultValue = "10") Integer limit) {
|
||||
if (limit == null || limit <= 0) {
|
||||
limit = 10;
|
||||
}
|
||||
if (stringRedisTemplate == null) {
|
||||
return Result.error("Redis 未配置,无法查询热门搜索");
|
||||
}
|
||||
|
||||
Set<TypedTuple<String>> tuples = stringRedisTemplate.opsForZSet()
|
||||
.reverseRangeWithScores(HOT_SEARCH_ZSET_KEY, 0, limit - 1);
|
||||
|
||||
List<Map<String, Object>> result = new ArrayList<>();
|
||||
if (tuples != null) {
|
||||
for (TypedTuple<String> tuple : tuples) {
|
||||
if (tuple == null) {
|
||||
continue;
|
||||
}
|
||||
Map<String, Object> item = new HashMap<>();
|
||||
item.put("keyword", tuple.getValue());
|
||||
item.put("count", tuple.getScore() == null ? 0 : tuple.getScore().longValue());
|
||||
result.add(item);
|
||||
}
|
||||
}
|
||||
return Result.OK(result);
|
||||
}
|
||||
|
||||
@GetMapping("/search")
|
||||
@Operation(summary = "全局搜索(课程:name/description/school)")
|
||||
@IgnoreAuth
|
||||
public Result<List<Course>> globalSearch(
|
||||
@RequestParam String keyword,
|
||||
@RequestParam(required = false, defaultValue = "20") Integer limit
|
||||
) {
|
||||
if (limit == null || limit <= 0) {
|
||||
limit = 20;
|
||||
}
|
||||
if (limit > 100) {
|
||||
limit = 100;
|
||||
}
|
||||
|
||||
if (keyword == null || keyword.trim().isEmpty()) {
|
||||
return Result.OK(new ArrayList<>());
|
||||
}
|
||||
|
||||
if (keyword.trim().length() < 2) {
|
||||
return Result.error("关键词长度至少为2个字符");
|
||||
}
|
||||
|
||||
// 记录关键词到 Redis 热搜
|
||||
if (stringRedisTemplate != null) {
|
||||
try {
|
||||
stringRedisTemplate.opsForZSet().incrementScore(HOT_SEARCH_ZSET_KEY, keyword.trim(), 1D);
|
||||
} catch (Exception e) {
|
||||
log.warn("记录热搜关键词到 Redis 失败: {}", keyword, e);
|
||||
}
|
||||
}
|
||||
|
||||
String kw = keyword.trim();
|
||||
QueryWrapper<Course> wrapper = new QueryWrapper<>();
|
||||
wrapper.lambda()
|
||||
.like(Course::getName, kw)
|
||||
.or()
|
||||
.like(Course::getDescription, kw)
|
||||
.or()
|
||||
.like(Course::getSchool, kw);
|
||||
|
||||
List<Course> list = courseMapper.selectList(wrapper.last("limit " + limit));
|
||||
return Result.OK(list);
|
||||
}
|
||||
}
|
@ -0,0 +1,207 @@
|
||||
package org.jeecg.modules.biz.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.modules.biz.constant.EntityLinkConst;
|
||||
import org.jeecg.modules.biz.dto.QuestionAnswerDTO;
|
||||
import org.jeecg.modules.biz.service.EntityLinkBizService;
|
||||
import org.jeecg.modules.gen.question.entity.Question;
|
||||
import org.jeecg.modules.gen.question.service.IQuestionService;
|
||||
import org.jeecg.modules.gen.questionanswer.entity.QuestionAnswer;
|
||||
import org.jeecg.modules.gen.questionanswer.service.IQuestionAnswerService;
|
||||
import org.jeecg.modules.gen.questionoption.entity.QuestionOption;
|
||||
import org.jeecg.modules.gen.questionoption.service.IQuestionOptionService;
|
||||
import org.jeecg.modules.gen.questionrepo.service.IQuestionRepoService;
|
||||
import org.jeecg.modules.gen.repo.entity.Repo;
|
||||
import org.jeecg.modules.gen.repo.mapper.RepoMapper;
|
||||
import org.jeecg.modules.gen.repo.service.IRepoService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/biz/repo")
|
||||
@Tag(name = "题库")
|
||||
@Tag(name = "题库题目")
|
||||
@Slf4j
|
||||
public class RepoBizController {
|
||||
|
||||
@Autowired
|
||||
private RepoMapper repoMapper;
|
||||
@Autowired
|
||||
private IRepoService repoService;
|
||||
@Autowired
|
||||
private IQuestionRepoService questionRepoService;
|
||||
@Autowired
|
||||
private EntityLinkBizService entityLinkBizService;
|
||||
@Autowired
|
||||
private IQuestionService questionService;
|
||||
@Autowired
|
||||
private IQuestionOptionService questionOptionService;
|
||||
@Autowired
|
||||
private IQuestionAnswerService questionAnswerService;
|
||||
|
||||
@PostMapping("course_add")
|
||||
@Operation(summary = "获取课程下的题库")
|
||||
@Transactional
|
||||
public Result<Integer> correct(@RequestBody Map<String, Object> data) {
|
||||
String title = (String) data.get("title");
|
||||
String remark = (String) data.get("remark");
|
||||
String courseId = (String) data.get("courseId");
|
||||
|
||||
Repo repo = new Repo();
|
||||
repo.setTitle(title);
|
||||
repo.setRemark(remark);
|
||||
|
||||
repoMapper.insert(repo);
|
||||
entityLinkBizService.save(EntityLinkConst.SourceType.COURSE, courseId, EntityLinkConst.TargetType.REPO, repo.getId());
|
||||
return Result.OK(repo.getId());
|
||||
}
|
||||
|
||||
@GetMapping("repoList")
|
||||
@Operation(summary = "获取所有题库")
|
||||
public Result<List<Repo>> repoList() {
|
||||
return Result.ok(repoService.list());
|
||||
}
|
||||
|
||||
|
||||
@PostMapping(value = "/courseAdd")
|
||||
@Operation(summary = "课程新建题库")
|
||||
public Result<String> courseAdd(@RequestBody Repo repo) {
|
||||
return repoService.save(repo) ? Result.OK("添加成功!") : Result.error("添加失败!");
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/questionList/{repoId}")
|
||||
@Operation(summary = "查询题库下题目")
|
||||
public Result<List<Question>> questionList(@PathVariable String repoId) {
|
||||
// 获取题库中的题目ID列表
|
||||
List<String> repoQuestionIds = questionRepoService.questionList(repoId);
|
||||
if (repoQuestionIds.isEmpty()) {
|
||||
return Result.error("该题库下没有题目或该题库不存在");
|
||||
}
|
||||
// 根据ID列表查询题目
|
||||
List<Question> questions = questionService.listByIds(repoQuestionIds);
|
||||
if(questions.isEmpty()){
|
||||
return Result.error("题目不存在");
|
||||
}
|
||||
//获取复选题id
|
||||
List<String> type5Ids = questions.stream()
|
||||
.filter(question -> question.getType() == 5)
|
||||
.map(Question::getId)
|
||||
.collect(Collectors.toList());
|
||||
//获取复选题所包含的题目
|
||||
List<Question> type5Questions = new ArrayList<>();
|
||||
if (!type5Ids.isEmpty()) {
|
||||
type5Questions = questionService.list(
|
||||
new LambdaQueryWrapper<Question>()
|
||||
.in(Question::getParentId, type5Ids)
|
||||
);
|
||||
}
|
||||
// 创建一个映射,用于快速查找父ID对应的子题目
|
||||
Map<String, List<Question>> parentToChildrenMap = type5Questions.stream()
|
||||
.collect(Collectors.groupingBy(Question::getParentId));
|
||||
|
||||
// 将子题目添加到原始列表中,保持原有顺序
|
||||
List<Question> resultQuestions = new ArrayList<>();
|
||||
for (Question question : questions) {
|
||||
resultQuestions.add(question);
|
||||
if (question.getType() == 5) {
|
||||
List<Question> children = parentToChildrenMap.getOrDefault(question.getId(), Collections.emptyList());
|
||||
resultQuestions.addAll(children);
|
||||
}
|
||||
}
|
||||
return Result.ok(resultQuestions);
|
||||
}
|
||||
|
||||
@GetMapping("course_list")
|
||||
@Operation(summary = "获取课程下的题库")
|
||||
public Result<List<Repo>> courseList(@RequestParam String courseId) {
|
||||
List<String> targetIds = entityLinkBizService.listTargetIds(EntityLinkConst.SourceType.COURSE, courseId, EntityLinkConst.TargetType.REPO);
|
||||
|
||||
if (targetIds.size() > 0) {
|
||||
List<Repo> list = repoMapper.selectByIds(targetIds);
|
||||
return Result.OK(list);
|
||||
} else {
|
||||
return Result.OK(new ArrayList<>());
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/repoList/{questionId}")
|
||||
@Operation(summary = "查询题目详情")
|
||||
public Result<?> questionDetail(@PathVariable String questionId) {
|
||||
Question rootQuestion = questionService.getById(questionId);
|
||||
if (rootQuestion == null) {
|
||||
return Result.error("题目不存在");
|
||||
}
|
||||
QuestionAnswerDTO questionAnswerDTO = new QuestionAnswerDTO();
|
||||
questionAnswerDTO.setQuestion(rootQuestion);
|
||||
if (rootQuestion.getType() >= 0 && rootQuestion.getType() <= 2) {
|
||||
questionAnswerDTO.setAnswer(choiceDetail(questionId));
|
||||
return Result.ok(questionAnswerDTO);
|
||||
} else if (rootQuestion.getType() == 3 || rootQuestion.getType() == 4) {
|
||||
questionAnswerDTO.setAnswer(answerDetail(questionId));
|
||||
return Result.ok(questionAnswerDTO);
|
||||
} else {
|
||||
//查询复合题所包含的题目
|
||||
List<Question> list = questionService.list(
|
||||
new LambdaQueryWrapper<Question>().
|
||||
eq(Question::getParentId, questionId)
|
||||
);
|
||||
//根据题目类型进行分组(false:选择多选判断题,true:填空简答题)
|
||||
Map<Boolean, List<Question>> groupedQuestions = list.stream()
|
||||
.collect(Collectors.partitioningBy(
|
||||
q -> q.getType() > 2
|
||||
));
|
||||
//获取选择题,多选题,判断题答案
|
||||
List<Question> question = groupedQuestions.get(false);
|
||||
if (!question.isEmpty()) {
|
||||
question.forEach(q -> {
|
||||
QuestionAnswerDTO qad = new QuestionAnswerDTO();
|
||||
qad.setQuestion(q);
|
||||
qad.setAnswer(choiceDetail(q.getId()));
|
||||
questionAnswerDTO.getChildren().add(qad);
|
||||
});
|
||||
}
|
||||
//获取填空题,简答题答案
|
||||
List<Question> question1 = groupedQuestions.get(true);
|
||||
if (!question1.isEmpty()) {
|
||||
question1.forEach(q -> {
|
||||
QuestionAnswerDTO qad = new QuestionAnswerDTO();
|
||||
qad.setQuestion(q);
|
||||
qad.setAnswer(answerDetail(q.getId()));
|
||||
questionAnswerDTO.getChildren().add(qad);
|
||||
});
|
||||
}
|
||||
return Result.ok(questionAnswerDTO);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//查询选择题,多选题,判断题答案
|
||||
public List<QuestionOption> choiceDetail(String questionId) {
|
||||
return questionOptionService.list(
|
||||
new LambdaQueryWrapper<QuestionOption>().
|
||||
eq(QuestionOption::getQuestionId, questionId).
|
||||
orderByAsc(QuestionOption::getOrderNo)
|
||||
);
|
||||
}
|
||||
|
||||
//查询填空题,简答题答案
|
||||
public List<QuestionAnswer> answerDetail(String questionId) {
|
||||
return questionAnswerService.list(
|
||||
new LambdaQueryWrapper<QuestionAnswer>().
|
||||
eq(QuestionAnswer::getQuestionId, questionId).
|
||||
orderByAsc(QuestionAnswer::getOrderNo)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package org.jeecg.modules.biz.controller;
|
||||
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.config.shiro.IgnoreAuth;
|
||||
import org.jeecg.modules.biz.constant.EntityLinkConst;
|
||||
import org.jeecg.modules.biz.service.EntityLinkBizService;
|
||||
import org.jeecg.modules.biz.service.ResourceBizService;
|
||||
import org.jeecg.modules.gen.resource.entity.Resource;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
|
||||
@Tag(name = "资源")
|
||||
@RestController
|
||||
@RequestMapping("/biz/resource")
|
||||
@Slf4j
|
||||
public class ResourceBizController {
|
||||
|
||||
@Autowired
|
||||
private ResourceBizService resourceBizService;
|
||||
|
||||
@Autowired
|
||||
private EntityLinkBizService entityLinkBizService;
|
||||
|
||||
@GetMapping("/feature")
|
||||
@Operation(summary = "查询精品资源")
|
||||
@IgnoreAuth
|
||||
public Result<List<Resource>> queryFeatureResource() {
|
||||
List<Resource> list = resourceBizService.list(new QueryWrapper<Resource>().eq("iz_featured", 1));
|
||||
return Result.OK(list);
|
||||
}
|
||||
|
||||
@GetMapping("/video")
|
||||
@Operation(summary = "按课程分类查询视频资源")
|
||||
@IgnoreAuth
|
||||
public Result<List<Resource>> queryVideoResource(@RequestParam("categoryId") String courseCategoryId) {
|
||||
List<String> targetIds = entityLinkBizService.listTargetIds(EntityLinkConst.SourceType.COURSE_CATEGORY, courseCategoryId, EntityLinkConst.TargetType.RESOURCE);
|
||||
List<Resource> list = new ArrayList<>();
|
||||
for (String targetId : targetIds) {
|
||||
Resource resource = resourceBizService.getById(targetId);
|
||||
if (resource.getType() == EntityLinkConst.ResourceType.VIDEO) {
|
||||
list.add(resource);
|
||||
}
|
||||
}
|
||||
return Result.OK(list);
|
||||
}
|
||||
|
||||
@GetMapping("/image")
|
||||
@Operation(summary = "按课程分类查询图片资源")
|
||||
@IgnoreAuth
|
||||
public Result<List<Resource>> queryImageResource(@RequestParam("categoryId") String courseCategoryId) {
|
||||
List<String> targetIds = entityLinkBizService.listTargetIds(EntityLinkConst.SourceType.COURSE_CATEGORY, courseCategoryId, EntityLinkConst.TargetType.RESOURCE);
|
||||
List<Resource> list = new ArrayList<>();
|
||||
for (String targetId : targetIds) {
|
||||
Resource resource = resourceBizService.getById(targetId);
|
||||
if (resource.getType() == EntityLinkConst.ResourceType.IMAGE) {
|
||||
list.add(resource);
|
||||
}
|
||||
}
|
||||
return Result.OK(list);
|
||||
}
|
||||
|
||||
@PostMapping("/upload")
|
||||
@Operation(summary = "课程视频文件上传", description = "课程视频文件上传,返回各清晰度的m3u8文件地址")
|
||||
public Result<Map<String, String>> upload(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws Exception {
|
||||
if (file == null || file.isEmpty()) return Result.error("没有找到上传的文件");
|
||||
Map<String, String> qualityUrls = resourceBizService.uploadHls(file, request);
|
||||
return Result.OK(qualityUrls);
|
||||
}
|
||||
}
|
@ -0,0 +1,204 @@
|
||||
package org.jeecg.modules.biz.controller;
|
||||
|
||||
import org.jeecg.config.shiro.IgnoreAuth;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.jeecg.modules.biz.dto.TeacherInfo;
|
||||
import org.jeecg.modules.biz.dto.UserInfoResponse;
|
||||
import org.jeecg.modules.biz.service.UserBizService;
|
||||
import org.jeecg.modules.gen.userinfo.entity.UserInfo;
|
||||
import org.jeecg.modules.gen.userinfo.mapper.UserInfoMapper;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.jeecg.modules.system.service.*;
|
||||
import org.jeecg.common.system.vo.DictModel;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.util.PasswordUtil;
|
||||
import org.jeecg.common.util.RedisUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Tag(name = "03-用户管理")
|
||||
@RestController
|
||||
@RequestMapping("/biz/user")
|
||||
@Slf4j
|
||||
public class UserBizController {
|
||||
|
||||
@Autowired
|
||||
private ISysUserService sysUserService;
|
||||
@Autowired
|
||||
private RedisUtil redisUtil;
|
||||
@Autowired
|
||||
private UserBizService userBizService;
|
||||
@Autowired
|
||||
private UserInfoMapper userInfoMapper;
|
||||
@Autowired
|
||||
private ISysBaseAPI sysBaseApi;
|
||||
|
||||
@PostMapping("/login")
|
||||
@Operation(summary = "用户登录")
|
||||
@IgnoreAuth
|
||||
public Result<JSONObject> login(@RequestBody Map<String, String> user, HttpServletRequest request) {
|
||||
Result<JSONObject> result = new Result<JSONObject>();
|
||||
String username = user.get("username");
|
||||
String password = user.get("password");
|
||||
if (isLoginFailOvertimes(username)) {
|
||||
return result.error500("该用户登录失败次数过多,请于10分钟后再次登录!");
|
||||
}
|
||||
|
||||
// step.2 校验用户是否存在且有效
|
||||
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysUser::getUsername, username);
|
||||
SysUser sysUser = sysUserService.getOne(queryWrapper);
|
||||
Result<?> checkResult = sysUserService.checkUserIsEffective(sysUser);
|
||||
if (!checkResult.isSuccess()) {
|
||||
return result.error500(checkResult.getMessage());
|
||||
}
|
||||
|
||||
// step.3 校验用户名或密码是否正确
|
||||
String userpassword = PasswordUtil.encrypt(username, password, sysUser.getSalt());
|
||||
String syspassword = sysUser.getPassword();
|
||||
if (!syspassword.equals(userpassword)) {
|
||||
addLoginFailOvertimes(username);
|
||||
result.error500("用户名或密码错误");
|
||||
return result;
|
||||
}
|
||||
|
||||
// step.4 登录成功获取用户信息
|
||||
JSONObject obj = new JSONObject(new LinkedHashMap<>());
|
||||
// 1.生成token
|
||||
String token = JwtUtil.sign(username, syspassword);
|
||||
// 设置token缓存有效时间
|
||||
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
|
||||
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000);
|
||||
obj.put("token", token);
|
||||
|
||||
// TODO 查询用户信息
|
||||
|
||||
result.setResult(obj);
|
||||
result.success("登录成功");
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录失败超出次数5 返回true
|
||||
*
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
private boolean isLoginFailOvertimes(String username) {
|
||||
String key = CommonConstant.LOGIN_FAIL + username;
|
||||
Object failTime = redisUtil.get(key);
|
||||
if (failTime != null) {
|
||||
Integer val = Integer.parseInt(failTime.toString());
|
||||
if (val > 5) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录登录失败次数
|
||||
*
|
||||
* @param username
|
||||
*/
|
||||
private void addLoginFailOvertimes(String username) {
|
||||
String key = CommonConstant.LOGIN_FAIL + username;
|
||||
Object failTime = redisUtil.get(key);
|
||||
Integer val = 0;
|
||||
if (failTime != null) {
|
||||
val = Integer.parseInt(failTime.toString());
|
||||
}
|
||||
// 10分钟,一分钟为60s
|
||||
redisUtil.set(key, ++val, 600);
|
||||
}
|
||||
|
||||
@GetMapping("/all_teachers")
|
||||
@Operation(summary = "查询师资力量", description = "categoryId为all则查询全部")
|
||||
@IgnoreAuth
|
||||
public Result<List<TeacherInfo>> queryAllTeachers(@RequestParam("categoryId") String categoryId) {
|
||||
List<TeacherInfo> list = userBizService.queryAllTeachers(categoryId);
|
||||
return Result.OK(list);
|
||||
}
|
||||
|
||||
@GetMapping("/info")
|
||||
@Operation(summary = "查询用户信息", description = "通过JWT token获取当前用户的详细信息,包括基本信息、角色和扩展信息")
|
||||
public Result<UserInfoResponse> queryUserInfo(HttpServletRequest request) {
|
||||
try {
|
||||
// 1. 从JWT中获取用户名
|
||||
String username = JwtUtil.getUserNameByToken(request);
|
||||
if (username == null || username.trim().isEmpty()) {
|
||||
return Result.error(401, "用户未登录或token无效");
|
||||
}
|
||||
|
||||
// 2. 根据用户名查询系统用户信息
|
||||
SysUser sysUser = sysUserService.getUserByName(username);
|
||||
if (sysUser == null) {
|
||||
return Result.error(404, "用户不存在");
|
||||
}
|
||||
|
||||
// 3. 查询用户角色
|
||||
List<String> roles = sysUserService.getUserRolesSet(username).stream()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 4. 根据用户ID查询user_info表信息
|
||||
UserInfo userInfo = userInfoMapper.selectOne(
|
||||
new QueryWrapper<UserInfo>().eq("user_id", sysUser.getId()));
|
||||
|
||||
// 5. 构建返回结果
|
||||
UserInfoResponse response = new UserInfoResponse();
|
||||
|
||||
// 基本用户信息
|
||||
UserInfoResponse.BaseInfo baseInfo = new UserInfoResponse.BaseInfo();
|
||||
BeanUtils.copyProperties(sysUser, baseInfo);
|
||||
response.setBaseInfo(baseInfo);
|
||||
response.setRoles(roles);
|
||||
|
||||
// 扩展用户信息
|
||||
if (userInfo != null) {
|
||||
UserInfoResponse.ExtendedInfo extendedInfo = new UserInfoResponse.ExtendedInfo();
|
||||
BeanUtils.copyProperties(userInfo, extendedInfo);
|
||||
response.setExtendedInfo(extendedInfo);
|
||||
}
|
||||
|
||||
return Result.OK(response);
|
||||
} catch (Exception e) {
|
||||
log.error("查询用户信息失败:" + e.getMessage(), e);
|
||||
return Result.error(500, "查询用户信息失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/schools")
|
||||
@Operation(summary = "查询学校列表")
|
||||
@IgnoreAuth
|
||||
public Result<List<String>> querySchools() {
|
||||
List<DictModel> list = sysBaseApi.getDictItems("school_list");
|
||||
List<String> schools = list.stream()
|
||||
.map(d -> d.getLabel())
|
||||
.collect(Collectors.toList());
|
||||
return Result.OK(schools);
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package org.jeecg.modules.biz.dto;
|
||||
|
||||
import org.jeecg.modules.gen.comment.entity.Comment;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Schema(description = "评论信息(包含用户信息)")
|
||||
public class CommentWithUserInfo extends Comment {
|
||||
@Schema(description = "用户姓名")
|
||||
private String userName;
|
||||
|
||||
@Schema(description = "用户头像")
|
||||
private String userAvatar;
|
||||
|
||||
@Schema(description = "用户标签")
|
||||
private String userTag;
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package org.jeecg.modules.biz.dto;
|
||||
|
||||
import org.jeecg.modules.gen.course.entity.Course;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Schema(description = "课程信息(包含讲师信息)")
|
||||
public class CourseWithTeacherInfo extends Course {
|
||||
@Schema(description = "授课讲师列表")
|
||||
private List<TeacherInfo> teacherList;
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package org.jeecg.modules.biz.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import org.jeecg.modules.gen.question.entity.Question;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class QuestionAnswerDTO {
|
||||
//题目内容
|
||||
private Question question;
|
||||
//答案
|
||||
private List<?> answer;
|
||||
//子题目列表
|
||||
private List<QuestionAnswerDTO> children = new ArrayList<>();
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package org.jeecg.modules.biz.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Schema(description = "学生提交作业")
|
||||
public class StudentSubmitHomework {
|
||||
/**作业id*/
|
||||
@Schema(description = "作业id")
|
||||
private String homeworkId;
|
||||
/**学生id*/
|
||||
@Schema(description = "学生id")
|
||||
private String studentId;
|
||||
/**作业内容*/
|
||||
@Schema(description = "作业内容")
|
||||
private String content;
|
||||
/**附件*/
|
||||
@Schema(description = "附件")
|
||||
private String attachment;
|
||||
/**状态*/
|
||||
@Schema(description = "状态")
|
||||
private Integer status;
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package org.jeecg.modules.biz.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Schema(description = "讲师信息")
|
||||
public class TeacherInfo {
|
||||
@Schema(description = "讲师ID")
|
||||
private String id;
|
||||
|
||||
@Schema(description = "讲师姓名")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "讲师头像")
|
||||
private String avatar;
|
||||
|
||||
@Schema(description = "职称")
|
||||
private String title;
|
||||
|
||||
@Schema(description = "标签")
|
||||
private String tag;
|
||||
|
||||
@Schema(description = "显示顺序")
|
||||
private Integer sortOrder;
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
package org.jeecg.modules.biz.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@Schema(description = "用户信息响应对象")
|
||||
public class UserInfoResponse {
|
||||
|
||||
@Schema(description = "用户基本信息")
|
||||
private BaseInfo baseInfo;
|
||||
|
||||
@Schema(description = "用户角色列表")
|
||||
private List<String> roles;
|
||||
|
||||
@Schema(description = "扩展用户信息")
|
||||
private ExtendedInfo extendedInfo;
|
||||
|
||||
@Data
|
||||
@Schema(description = "用户基本信息")
|
||||
public static class BaseInfo {
|
||||
@Schema(description = "用户ID")
|
||||
private String id;
|
||||
|
||||
@Schema(description = "用户名")
|
||||
private String username;
|
||||
|
||||
@Schema(description = "真实姓名")
|
||||
private String realname;
|
||||
|
||||
@Schema(description = "头像")
|
||||
private String avatar;
|
||||
|
||||
@Schema(description = "手机号")
|
||||
private String phone;
|
||||
|
||||
@Schema(description = "邮箱")
|
||||
private String email;
|
||||
|
||||
@Schema(description = "性别(1-男,2-女)")
|
||||
private Integer sex;
|
||||
|
||||
@Schema(description = "生日")
|
||||
private Date birthday;
|
||||
|
||||
@Schema(description = "状态(1-正常,2-冻结)")
|
||||
private Integer status;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Schema(description = "扩展用户信息")
|
||||
public static class ExtendedInfo {
|
||||
@Schema(description = "专业")
|
||||
private String major;
|
||||
|
||||
@Schema(description = "学院")
|
||||
private String college;
|
||||
|
||||
@Schema(description = "学历")
|
||||
private String education;
|
||||
|
||||
@Schema(description = "职称")
|
||||
private String title;
|
||||
|
||||
@Schema(description = "标签")
|
||||
private String tag;
|
||||
|
||||
@Schema(description = "显示顺序")
|
||||
private Integer sortOrder;
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package org.jeecg.modules.biz.service;
|
||||
|
||||
import org.jeecg.modules.gen.activity.entity.Activity;
|
||||
import java.util.List;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
public interface ActivityBizService extends IService<Activity> {
|
||||
/**
|
||||
* 查询活动列表
|
||||
* @return
|
||||
*/
|
||||
List<Activity> getActivityList();
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
package org.jeecg.modules.biz.service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.modules.biz.dto.CourseWithTeacherInfo;
|
||||
import org.jeecg.modules.biz.dto.TeacherInfo;
|
||||
import org.jeecg.modules.gen.course.entity.Course;
|
||||
import org.jeecg.modules.gen.coursecategory.entity.CourseCategory;
|
||||
import org.jeecg.modules.gen.coursesection.entity.CourseSection;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
|
||||
/**
|
||||
* 课程业务
|
||||
*/
|
||||
public interface CourseBizService extends IService<Course> {
|
||||
|
||||
/**
|
||||
* 上传视频并切片为 HLS(m3u8+ts),按配置(local|minio|alioss)上传,返回 m3u8 的路径/URL
|
||||
* @param file 上传的视频文件
|
||||
* @param request 用于读取 header 或环境配置
|
||||
* @return m3u8 路径/URL
|
||||
* @throws Exception 处理异常
|
||||
*/
|
||||
String uploadHls(MultipartFile file, HttpServletRequest request) throws Exception;
|
||||
|
||||
/**
|
||||
* 根据分类、难度、专题查询课程列表(包含讲师信息)
|
||||
* @param categoryId
|
||||
* @param difficulty
|
||||
* @param topic
|
||||
* @return
|
||||
*/
|
||||
List<CourseWithTeacherInfo> getCourseList(String categoryId, String difficulty, String topic);
|
||||
|
||||
/**
|
||||
* 查询课程分类列表
|
||||
* @return
|
||||
*/
|
||||
List<CourseCategory> getCourseCategoryList();
|
||||
|
||||
/**
|
||||
* 查询指定课程下的章节列表
|
||||
* @param courseId
|
||||
* @return
|
||||
*/
|
||||
List<CourseSection> getCourseSectionList(String courseId);
|
||||
|
||||
/**
|
||||
* 查询章节详情(泛型)
|
||||
* @param type 章节类型:0=视频、1=资料、2=考试、3=作业
|
||||
* @param sectionId 章节ID
|
||||
* @param clazz 期望返回的实体类型
|
||||
* @return 指定类型的列表
|
||||
*/
|
||||
<T> List<T> getCourseSectionDetail(Integer type, String sectionId, Class<T> clazz);
|
||||
|
||||
/**
|
||||
* 查询课程的授课教师
|
||||
* @param courseId
|
||||
* @return
|
||||
*/
|
||||
List<TeacherInfo> getCourseTeacherList(String courseId);
|
||||
|
||||
/**
|
||||
* 报名课程
|
||||
* @param courseId
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
String enrollCourse(String courseId, String id);
|
||||
|
||||
/**
|
||||
* 查询课程是否已报名
|
||||
* @param courseId
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
boolean isEnrolled(String courseId, String id);
|
||||
|
||||
/**
|
||||
* 批量导入学生
|
||||
* @param courseId
|
||||
* @param ids
|
||||
* @param sysUser
|
||||
* @return
|
||||
*/
|
||||
Map<String, Object> addStudents(String courseId, String ids, LoginUser sysUser);
|
||||
|
||||
|
||||
Map<String, Object> getCourseProgress(String courseId, String id);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,26 @@
|
||||
package org.jeecg.modules.biz.service;
|
||||
|
||||
import org.jeecg.modules.gen.entitylink.entity.EntityLink;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import java.util.List;
|
||||
|
||||
public interface EntityLinkBizService extends IService<EntityLink>{
|
||||
/**
|
||||
* 根据主体与内容类型查询绑定的 target_id 列表
|
||||
* @param sourceType 主体类型
|
||||
* @param sourceId 主体ID
|
||||
* @param targetType 内容类型
|
||||
* @return target_id 列表(去重)
|
||||
*/
|
||||
List<String> listTargetIds(String sourceType, String sourceId, String targetType);
|
||||
|
||||
/**
|
||||
* 保存主体与内容类型的绑定关系
|
||||
* @param sourceType 主体类型
|
||||
* @param sourceId 主体ID
|
||||
* @param targetType 内容类型
|
||||
* @param targetId 内容ID
|
||||
*/
|
||||
void save(String sourceType, String sourceId, String targetType, String targetId);
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package org.jeecg.modules.biz.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jeecg.modules.biz.dto.CommentWithUserInfo;
|
||||
import org.jeecg.modules.gen.comment.entity.*;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
public interface ICommentBizService extends IService<Comment> {
|
||||
|
||||
/**
|
||||
* 根据目标类型和目标ID查询评论列表(包含用户信息)
|
||||
* @param targetType 目标类型
|
||||
* @param targetId 目标ID
|
||||
* @return
|
||||
*/
|
||||
List<CommentWithUserInfo> getCommentList(String targetType, String targetId);
|
||||
|
||||
/**
|
||||
* 查询所有精选评论列表(包含用户信息)
|
||||
* @return
|
||||
*/
|
||||
List<CommentWithUserInfo> getAllSelectedComments();
|
||||
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package org.jeecg.modules.biz.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jeecg.modules.gen.homework.entity.Homework;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
public interface IHomeworkBizService extends IService<Homework> {
|
||||
|
||||
/**
|
||||
* 查询某课程章节下的作业
|
||||
* @param courseId
|
||||
* @return
|
||||
*/
|
||||
List<Homework> listByCourseId(String courseId);
|
||||
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package org.jeecg.modules.biz.service;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jeecg.modules.gen.resource.entity.Resource;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* 资源业务
|
||||
*/
|
||||
public interface ResourceBizService extends IService<Resource> {
|
||||
|
||||
/**
|
||||
* 上传视频并切片为 HLS(m3u8+ts),按配置(local|minio|alioss)上传,返回各清晰度的 m3u8 路径/URL
|
||||
* @param file 上传的视频文件
|
||||
* @param request 用于读取 header 或环境配置
|
||||
* @return 各清晰度的 m3u8 路径/URL,Map的key为清晰度名称(如"480p", "720p", "1080p"),value为对应的URL
|
||||
* @throws Exception 处理异常
|
||||
*/
|
||||
Map<String, String> uploadHls(MultipartFile file, HttpServletRequest request) throws Exception;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,16 @@
|
||||
package org.jeecg.modules.biz.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jeecg.modules.biz.dto.TeacherInfo;
|
||||
import org.jeecg.modules.gen.userinfo.entity.UserInfo;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
public interface UserBizService extends IService<UserInfo> {
|
||||
/**
|
||||
* 师资力量
|
||||
* @return
|
||||
*/
|
||||
List<TeacherInfo> queryAllTeachers(String categoryId);
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package org.jeecg.modules.biz.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jeecg.modules.biz.service.ActivityBizService;
|
||||
import org.jeecg.modules.gen.activity.entity.Activity;
|
||||
import org.jeecg.modules.gen.activity.mapper.ActivityMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
||||
@Service
|
||||
public class ActivityBizServiceImpl extends ServiceImpl<ActivityMapper, Activity> implements ActivityBizService {
|
||||
|
||||
@Override
|
||||
public List<Activity> getActivityList() {
|
||||
return baseMapper.selectList(null);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
package org.jeecg.modules.biz.service.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jeecg.modules.biz.dto.CommentWithUserInfo;
|
||||
import org.jeecg.modules.biz.service.ICommentBizService;
|
||||
import org.jeecg.modules.gen.comment.entity.Comment;
|
||||
import org.jeecg.modules.gen.comment.mapper.CommentMapper;
|
||||
import org.jeecg.modules.gen.userinfo.entity.UserInfo;
|
||||
import org.jeecg.modules.gen.userinfo.mapper.UserInfoMapper;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.jeecg.modules.system.mapper.SysUserMapper;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
||||
@Service
|
||||
public class CommentBizServiceImpl extends ServiceImpl<CommentMapper, Comment> implements ICommentBizService {
|
||||
|
||||
@Autowired
|
||||
private UserInfoMapper userInfoMapper;
|
||||
@Autowired
|
||||
private SysUserMapper sysUserMapper;
|
||||
|
||||
@Override
|
||||
public List<CommentWithUserInfo> getCommentList(String targetType, String targetId) {
|
||||
// 1. 根据目标类型和目标ID查询评论列表
|
||||
QueryWrapper<Comment> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("target_type", targetType)
|
||||
.eq("target_id", targetId)
|
||||
.orderByDesc("iz_top") // 置顶评论在前
|
||||
.orderByDesc("create_time"); // 按时间倒序
|
||||
|
||||
List<Comment> comments = this.list(queryWrapper);
|
||||
|
||||
// 2. 根据userid关联查询用户信息,构建包含用户信息的评论列表
|
||||
List<CommentWithUserInfo> result = new ArrayList<>();
|
||||
for (Comment comment : comments) {
|
||||
CommentWithUserInfo commentWithUser = new CommentWithUserInfo();
|
||||
// 复制评论基本信息
|
||||
BeanUtils.copyProperties(comment, commentWithUser);
|
||||
|
||||
// 查询用户基本信息
|
||||
SysUser sysUser = sysUserMapper.selectById(comment.getUserId());
|
||||
if (sysUser != null) {
|
||||
commentWithUser.setUserName(sysUser.getRealname());
|
||||
commentWithUser.setUserAvatar(sysUser.getAvatar());
|
||||
|
||||
// 查询用户扩展信息
|
||||
UserInfo userInfo = userInfoMapper.selectOne(
|
||||
new QueryWrapper<UserInfo>().eq("user_id", comment.getUserId())
|
||||
);
|
||||
if (userInfo != null) {
|
||||
commentWithUser.setUserTag(userInfo.getTag());
|
||||
}
|
||||
}
|
||||
|
||||
result.add(commentWithUser);
|
||||
}
|
||||
|
||||
// 3. 返回评论列表
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CommentWithUserInfo> getAllSelectedComments() {
|
||||
// 1. 查询所有评论,按置顶和时间排序
|
||||
QueryWrapper<Comment> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.orderByDesc("iz_top") // 置顶评论在前
|
||||
.orderByDesc("create_time"); // 按时间倒序
|
||||
|
||||
List<Comment> comments = this.list(queryWrapper);
|
||||
|
||||
// 2. 根据userid关联查询用户信息,构建包含用户信息的评论列表
|
||||
List<CommentWithUserInfo> result = new ArrayList<>();
|
||||
for (Comment comment : comments) {
|
||||
CommentWithUserInfo commentWithUser = new CommentWithUserInfo();
|
||||
// 复制评论基本信息
|
||||
BeanUtils.copyProperties(comment, commentWithUser);
|
||||
|
||||
// 查询用户基本信息
|
||||
SysUser sysUser = sysUserMapper.selectById(comment.getUserId());
|
||||
if (sysUser != null) {
|
||||
commentWithUser.setUserName(sysUser.getRealname());
|
||||
commentWithUser.setUserAvatar(sysUser.getAvatar());
|
||||
|
||||
// 查询用户扩展信息
|
||||
UserInfo userInfo = userInfoMapper.selectOne(
|
||||
new QueryWrapper<UserInfo>().eq("user_id", comment.getUserId())
|
||||
);
|
||||
if (userInfo != null) {
|
||||
commentWithUser.setUserTag(userInfo.getTag());
|
||||
}
|
||||
}
|
||||
|
||||
result.add(commentWithUser);
|
||||
}
|
||||
|
||||
// 3. 返回评论列表
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,681 @@
|
||||
package org.jeecg.modules.biz.service.impl;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.CommonUtils;
|
||||
import org.jeecg.common.util.MinioUtil;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import org.jeecg.common.util.oss.OssBootUtil;
|
||||
import org.jeecg.modules.biz.constant.EntityLinkConst;
|
||||
import org.jeecg.modules.biz.dto.CourseWithTeacherInfo;
|
||||
import org.jeecg.modules.biz.dto.TeacherInfo;
|
||||
import org.jeecg.modules.biz.service.CourseBizService;
|
||||
import org.jeecg.modules.biz.service.EntityLinkBizService;
|
||||
import org.jeecg.modules.gen.course.entity.Course;
|
||||
import org.jeecg.modules.gen.course.mapper.CourseMapper;
|
||||
import org.jeecg.modules.gen.coursecategory.entity.CourseCategory;
|
||||
import org.jeecg.modules.gen.coursecategory.mapper.CourseCategoryMapper;
|
||||
import org.jeecg.modules.gen.coursesection.entity.CourseSection;
|
||||
import org.jeecg.modules.gen.coursesection.mapper.CourseSectionMapper;
|
||||
import org.jeecg.modules.gen.coursesignup.entity.CourseSignup;
|
||||
import org.jeecg.modules.gen.coursesignup.mapper.CourseSignupMapper;
|
||||
import org.jeecg.modules.gen.courseteacher.entity.CourseTeacher;
|
||||
import org.jeecg.modules.gen.courseteacher.mapper.CourseTeacherMapper;
|
||||
import org.jeecg.modules.gen.homework.mapper.HomeworkMapper;
|
||||
import org.jeecg.modules.gen.learnprogress.entity.LearnProgress;
|
||||
import org.jeecg.modules.gen.learnprogress.mapper.LearnProgressMapper;
|
||||
import org.jeecg.modules.gen.resource.mapper.ResourceMapper;
|
||||
import org.jeecg.modules.gen.userinfo.entity.UserInfo;
|
||||
import org.jeecg.modules.gen.userinfo.mapper.UserInfoMapper;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.jeecg.modules.system.mapper.SysUserMapper;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.Date;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class CourseBizServiceImpl extends ServiceImpl<CourseMapper, Course> implements CourseBizService {
|
||||
|
||||
@Autowired
|
||||
private CourseMapper courseMapper;
|
||||
|
||||
@Autowired
|
||||
private CourseCategoryMapper courseCategoryMapper;
|
||||
|
||||
@Autowired
|
||||
private CourseSectionMapper courseSectionMapper;
|
||||
|
||||
@Autowired
|
||||
private EntityLinkBizService entityLinkBizService;
|
||||
|
||||
@Autowired
|
||||
private ResourceMapper resourceMapper;
|
||||
|
||||
@Autowired
|
||||
private CourseTeacherMapper courseTeacherMapper;
|
||||
|
||||
@Autowired
|
||||
private UserInfoMapper userInfoMapper;
|
||||
|
||||
@Autowired
|
||||
private SysUserMapper sysUserMapper;
|
||||
|
||||
@Autowired
|
||||
private HomeworkMapper homeworkMapper;
|
||||
|
||||
@Autowired
|
||||
private CourseSignupMapper courseSignupMapper;
|
||||
|
||||
@Autowired
|
||||
private LearnProgressMapper learnProgressMapper;
|
||||
|
||||
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
/**
|
||||
* 将Map转换为JSON字符串
|
||||
*/
|
||||
private String toJsonString(Map<String, Object> map) {
|
||||
try {
|
||||
return objectMapper.writeValueAsString(map);
|
||||
} catch (Exception e) {
|
||||
log.error("JSON转换失败", e);
|
||||
return map.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> getCourseSectionDetail(Integer type, String sectionId, Class<T> clazz) {
|
||||
// 1. 查询章节是否存在
|
||||
// 2. 根据章节类型,查询entitylink表,获取关联的实体id
|
||||
// 3. 根据实体id,查询实体表,获取实体详情
|
||||
// 4. 返回实体详情
|
||||
|
||||
// 1. 查询章节是否存在
|
||||
CourseSection section = courseSectionMapper.selectById(sectionId);
|
||||
if (section == null) {
|
||||
throw new RuntimeException("章节不存在");
|
||||
}
|
||||
|
||||
// 2. 根据章节类型,查询entitylink表,获取关联的实体id
|
||||
String sourceType = EntityLinkConst.SourceType.COURSE_SECTION;
|
||||
String sourceId = section.getId();
|
||||
String targetType = null;
|
||||
// 和数据字典对应
|
||||
// 视频和资料章节的区别在于资料可能存在多份资料,而视频只有一份
|
||||
switch (type) {
|
||||
case 0:
|
||||
// 视频章节
|
||||
targetType = EntityLinkConst.TargetType.RESOURCE;
|
||||
break;
|
||||
case 1:
|
||||
// 资料章节
|
||||
targetType = EntityLinkConst.TargetType.RESOURCE;
|
||||
break;
|
||||
case 2:
|
||||
// 考试章节
|
||||
targetType = EntityLinkConst.TargetType.EXAM;
|
||||
break;
|
||||
case 3:
|
||||
// 作业章节
|
||||
targetType = EntityLinkConst.TargetType.HOMEWORK;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
List<String> targetIds = entityLinkBizService.listTargetIds(sourceType, sourceId, targetType);
|
||||
if (targetIds.isEmpty()) {
|
||||
throw new RuntimeException("章节没有关联的实体");
|
||||
}
|
||||
|
||||
// 3. 根据实体id,查询实体表,获取实体详情
|
||||
List<T> result = new ArrayList<>();
|
||||
for (String targetId : targetIds) {
|
||||
switch (type) {
|
||||
case 0:
|
||||
// 视频章节
|
||||
result.add(clazz.cast(resourceMapper.selectById(targetId)));
|
||||
break;
|
||||
case 1:
|
||||
// 资料章节
|
||||
result.add(clazz.cast(resourceMapper.selectById(targetId)));
|
||||
break;
|
||||
case 2:
|
||||
// TODO 考试章节
|
||||
break;
|
||||
case 3:
|
||||
// 作业章节
|
||||
result.add(clazz.cast(homeworkMapper.selectById(targetId)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 返回实体详情
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CourseSection> getCourseSectionList(String courseId) {
|
||||
return courseSectionMapper.selectList(new QueryWrapper<CourseSection>().eq("course_id", courseId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CourseCategory> getCourseCategoryList() {
|
||||
return courseCategoryMapper.selectList(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CourseWithTeacherInfo> getCourseList(String categoryId, String difficulty, String topic) {
|
||||
QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
|
||||
|
||||
// 根据分类查询 - 支持多个分类ID,用逗号分隔
|
||||
if (!"all".equals(categoryId) && categoryId != null) {
|
||||
String[] categoryIds = categoryId.split(",");
|
||||
Set<String> allCourseIds = new HashSet<>();
|
||||
|
||||
for (String catId : categoryIds) {
|
||||
catId = catId.trim();
|
||||
if (!catId.isEmpty()) {
|
||||
List<String> courseIds = entityLinkBizService.listTargetIds(
|
||||
EntityLinkConst.SourceType.COURSE_CATEGORY, catId, EntityLinkConst.TargetType.COURSE);
|
||||
allCourseIds.addAll(courseIds);
|
||||
}
|
||||
}
|
||||
|
||||
if (!allCourseIds.isEmpty()) {
|
||||
queryWrapper.in("id", allCourseIds);
|
||||
}
|
||||
}
|
||||
|
||||
// 根据专题查询 - 支持多个专题值,用逗号分隔
|
||||
if (!"all".equals(topic) && topic != null) {
|
||||
String[] topics = topic.split(",");
|
||||
List<String> validTopics = new ArrayList<>();
|
||||
for (String topicValue : topics) {
|
||||
topicValue = topicValue.trim();
|
||||
if (!topicValue.isEmpty()) {
|
||||
validTopics.add(topicValue);
|
||||
}
|
||||
}
|
||||
|
||||
if (!validTopics.isEmpty()) {
|
||||
queryWrapper.and(wrapper -> {
|
||||
for (int i = 0; i < validTopics.size(); i++) {
|
||||
String topicValue = validTopics.get(i);
|
||||
if (i == 0) {
|
||||
// 第一个条件,直接开始
|
||||
wrapper.and(subWrapper -> {
|
||||
subWrapper.like("subject", topicValue + ",") // 开头匹配
|
||||
.or().like("subject", "," + topicValue + ",") // 中间匹配
|
||||
.or().like("subject", "," + topicValue) // 结尾匹配
|
||||
.or().eq("subject", topicValue); // 单独匹配
|
||||
});
|
||||
} else {
|
||||
// 后续条件用OR连接,表示任一专题匹配即可
|
||||
wrapper.or(subWrapper -> {
|
||||
subWrapper.like("subject", topicValue + ",") // 开头匹配
|
||||
.or().like("subject", "," + topicValue + ",") // 中间匹配
|
||||
.or().like("subject", "," + topicValue) // 结尾匹配
|
||||
.or().eq("subject", topicValue); // 单独匹配
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 根据难度查询 - 支持多个难度值,用逗号分隔
|
||||
if (!"all".equals(difficulty) && difficulty != null) {
|
||||
String[] difficulties = difficulty.split(",");
|
||||
List<String> difficultyList = new ArrayList<>();
|
||||
for (String diff : difficulties) {
|
||||
diff = diff.trim();
|
||||
if (!diff.isEmpty()) {
|
||||
difficultyList.add(diff);
|
||||
}
|
||||
}
|
||||
if (!difficultyList.isEmpty()) {
|
||||
queryWrapper.in("difficulty", difficultyList);
|
||||
}
|
||||
}
|
||||
List<Course> courseList = courseMapper.selectList(queryWrapper);
|
||||
|
||||
// 构建包含讲师信息的课程列表
|
||||
List<CourseWithTeacherInfo> result = new ArrayList<>();
|
||||
for (Course course : courseList) {
|
||||
CourseWithTeacherInfo courseWithTeacher = new CourseWithTeacherInfo();
|
||||
// 复制课程基本信息
|
||||
BeanUtils.copyProperties(course, courseWithTeacher);
|
||||
|
||||
// 获取讲师信息
|
||||
List<TeacherInfo> teacherList = getCourseTeacherList(course.getId());
|
||||
courseWithTeacher.setTeacherList(teacherList);
|
||||
|
||||
result.add(courseWithTeacher);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String uploadHls(MultipartFile file, HttpServletRequest request) throws Exception {
|
||||
// 读取上传类型(header 优先)
|
||||
String headerUploadType = request.getHeader("uploadType");
|
||||
String configUploadType = SpringContextUtils.getApplicationContext().getEnvironment().getProperty("jeecg.uploadType", "minio");
|
||||
String uploadType = (headerUploadType != null && headerUploadType.trim().length() > 0) ? headerUploadType : configUploadType;
|
||||
|
||||
// 1) 保存临时原始视频
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
String tmpRoot = System.getProperty("java.io.tmpdir");
|
||||
Path tmpVideoDir = Path.of(tmpRoot, "jeecg", "video", uuid);
|
||||
Path hlsDir = Path.of(tmpRoot, "jeecg", "hls", uuid);
|
||||
Files.createDirectories(tmpVideoDir);
|
||||
Files.createDirectories(hlsDir);
|
||||
|
||||
String original = CommonUtils.getFileName(Objects.requireNonNull(file.getOriginalFilename()));
|
||||
Path tmpVideoFile = tmpVideoDir.resolve(original);
|
||||
Files.copy(file.getInputStream(), tmpVideoFile, StandardCopyOption.REPLACE_EXISTING);
|
||||
|
||||
// 2) ffmpeg 切片
|
||||
Path m3u8Path = hlsDir.resolve(uuid + ".m3u8");
|
||||
List<String> cmd = Arrays.asList(
|
||||
"ffmpeg", "-i", tmpVideoFile.toString(),
|
||||
"-c:v", "libx264", "-c:a", "aac",
|
||||
"-hls_time", "10", "-hls_playlist_type", "vod",
|
||||
m3u8Path.toString());
|
||||
Process p = new ProcessBuilder(cmd).redirectErrorStream(true).start();
|
||||
boolean ok = p.waitFor(10, TimeUnit.MINUTES) && p.exitValue() == 0;
|
||||
if (!ok) {
|
||||
deleteQuietly(hlsDir.toFile());
|
||||
deleteQuietly(tmpVideoDir.toFile());
|
||||
throw new RuntimeException("ffmpeg切片超时");
|
||||
}
|
||||
|
||||
// 3) 上传切片
|
||||
String m3u8Url = "";
|
||||
String base = "video/hls/" + uuid;
|
||||
try (Stream<Path> paths = Files.list(hlsDir)) {
|
||||
for (Path f : (Iterable<Path>) paths::iterator) {
|
||||
if (!Files.isRegularFile(f)) continue;
|
||||
String rel = base + "/" + f.getFileName().toString();
|
||||
try (InputStream in = Files.newInputStream(f)) {
|
||||
if ("minio".equals(uploadType)) {
|
||||
String tmpUrl = MinioUtil.upload(in, rel);
|
||||
if (f.getFileName().toString().endsWith(".m3u8")) {
|
||||
m3u8Url = tmpUrl;
|
||||
}
|
||||
} else if ("alioss".equals(uploadType)) {
|
||||
OssBootUtil.upload(in, rel);
|
||||
if (f.getFileName().toString().endsWith(".m3u8")) {
|
||||
m3u8Url = rel; // 可在网关拼域名
|
||||
}
|
||||
} else {
|
||||
String uploadpath = SpringContextUtils.getApplicationContext().getEnvironment().getProperty("jeecg.path.upload");
|
||||
Path target = Path.of(uploadpath, rel);
|
||||
Files.createDirectories(target.getParent());
|
||||
Files.copy(f, target, StandardCopyOption.REPLACE_EXISTING);
|
||||
if (f.getFileName().toString().endsWith(".m3u8")) {
|
||||
m3u8Url = rel; // local 返回相对路径
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
deleteQuietly(hlsDir.toFile());
|
||||
deleteQuietly(tmpVideoDir.toFile());
|
||||
}
|
||||
|
||||
return m3u8Url;
|
||||
}
|
||||
|
||||
/** 删除临时目录文件 */
|
||||
private static void deleteQuietly(File file) {
|
||||
try {
|
||||
if (file == null || !file.exists()) return;
|
||||
if (file.isDirectory()) {
|
||||
File[] children = file.listFiles();
|
||||
if (children != null) {
|
||||
for (File c : children) deleteQuietly(c);
|
||||
}
|
||||
}
|
||||
file.delete();
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TeacherInfo> getCourseTeacherList(String courseId) {
|
||||
List<CourseTeacher> list = courseTeacherMapper.selectList(new QueryWrapper<CourseTeacher>().eq("course_id", courseId));
|
||||
|
||||
List<TeacherInfo> result = new ArrayList<>();
|
||||
for (CourseTeacher item : list) {
|
||||
UserInfo userInfo = userInfoMapper.selectOne(new QueryWrapper<UserInfo>().eq("user_id", item.getTeacherId()));
|
||||
SysUser sysUser = sysUserMapper.selectById(item.getTeacherId());
|
||||
|
||||
TeacherInfo teacherInfo = new TeacherInfo();
|
||||
teacherInfo.setId(item.getTeacherId());
|
||||
teacherInfo.setName(sysUser.getRealname());
|
||||
teacherInfo.setAvatar(sysUser.getAvatar());
|
||||
teacherInfo.setTitle(userInfo.getTitle());
|
||||
teacherInfo.setTag(userInfo.getTag());
|
||||
teacherInfo.setSortOrder(userInfo.getSortOrder());
|
||||
result.add(teacherInfo);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String enrollCourse(String courseId, String userId) {
|
||||
// 1. 参数校验
|
||||
if (courseId == null || courseId.trim().isEmpty()) {
|
||||
throw new RuntimeException("课程ID不能为空");
|
||||
}
|
||||
if (userId == null || userId.trim().isEmpty()) {
|
||||
throw new RuntimeException("用户ID不能为空");
|
||||
}
|
||||
|
||||
// 2. 查询课程是否存在
|
||||
Course course = courseMapper.selectById(courseId);
|
||||
if (course == null) {
|
||||
throw new RuntimeException("课程不存在");
|
||||
}
|
||||
|
||||
// 3. 检查用户是否已报名
|
||||
QueryWrapper<CourseSignup> signupQuery = new QueryWrapper<>();
|
||||
signupQuery.eq("user_id", userId).eq("course_id", courseId);
|
||||
CourseSignup existingSignup = courseSignupMapper.selectOne(signupQuery);
|
||||
if (existingSignup != null) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("success", true);
|
||||
result.put("code", "already_enrolled");
|
||||
result.put("message", "用户已经报名该课程");
|
||||
return toJsonString(result);
|
||||
}
|
||||
|
||||
// 4. 检查课程是否可以报名
|
||||
if (course.getStatus() != null && course.getStatus() != 1) {
|
||||
throw new RuntimeException("课程当前状态不允许报名");
|
||||
}
|
||||
|
||||
// 5. 检查报名人数是否已满
|
||||
if (course.getMaxEnroll() != null && course.getEnrollCount() != null) {
|
||||
if (course.getEnrollCount() >= course.getMaxEnroll()) {
|
||||
throw new RuntimeException("报名人数已满");
|
||||
}
|
||||
}
|
||||
|
||||
// 6. 创建报名记录
|
||||
CourseSignup signup = new CourseSignup();
|
||||
signup.setUserId(userId);
|
||||
signup.setCourseId(courseId);
|
||||
signup.setCreateTime(new Date());
|
||||
signup.setCreateBy(userId);
|
||||
|
||||
int insertResult = courseSignupMapper.insert(signup);
|
||||
if (insertResult <= 0) {
|
||||
throw new RuntimeException("报名失败");
|
||||
}
|
||||
|
||||
// 7. 更新课程报名人数
|
||||
int currentEnrollCount = course.getEnrollCount() == null ? 0 : course.getEnrollCount();
|
||||
course.setEnrollCount(currentEnrollCount + 1);
|
||||
courseMapper.updateById(course);
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("success", true);
|
||||
result.put("code", "success");
|
||||
result.put("message", "报名成功");
|
||||
return toJsonString(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnrolled(String courseId, String userId) {
|
||||
QueryWrapper<CourseSignup> signupQuery = new QueryWrapper<>();
|
||||
signupQuery.eq("user_id", userId).eq("course_id", courseId);
|
||||
CourseSignup existingSignup = courseSignupMapper.selectOne(signupQuery);
|
||||
return existingSignup != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Map<String, Object> addStudents(String courseId, String ids, LoginUser teacher) {
|
||||
// 1. 参数校验
|
||||
if (courseId == null || courseId.trim().isEmpty()) {
|
||||
throw new RuntimeException("课程ID不能为空");
|
||||
}
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
throw new RuntimeException("学生ID列表不能为空");
|
||||
}
|
||||
if (teacher == null || teacher.getId() == null) {
|
||||
throw new RuntimeException("教师信息不能为空");
|
||||
}
|
||||
|
||||
// 2. 查询课程是否存在
|
||||
Course course = courseMapper.selectById(courseId);
|
||||
if (course == null) {
|
||||
throw new RuntimeException("课程不存在");
|
||||
}
|
||||
|
||||
// 3. 权限校验 - 检查当前登录用户是否是课程的创建人
|
||||
if (!teacher.getUsername().equals(course.getCreateBy())) {
|
||||
throw new RuntimeException("只有课程创建者才能添加学生");
|
||||
}
|
||||
|
||||
// 4. 过滤有效的学生ID
|
||||
List<String> validStudentIds = new ArrayList<>();
|
||||
for (String studentId : ids.split(",")) {
|
||||
if (studentId != null && !studentId.trim().isEmpty()) {
|
||||
validStudentIds.add(studentId.trim());
|
||||
}
|
||||
}
|
||||
|
||||
if (validStudentIds.isEmpty()) {
|
||||
throw new RuntimeException("没有有效的学生ID");
|
||||
}
|
||||
|
||||
// 5. 检查哪些学生已经报名
|
||||
QueryWrapper<CourseSignup> existingQuery = new QueryWrapper<>();
|
||||
existingQuery.eq("course_id", courseId).in("user_id", validStudentIds);
|
||||
List<CourseSignup> existingSignups = courseSignupMapper.selectList(existingQuery);
|
||||
|
||||
Set<String> alreadyEnrolledIds = new HashSet<>();
|
||||
for (CourseSignup signup : existingSignups) {
|
||||
alreadyEnrolledIds.add(signup.getUserId());
|
||||
}
|
||||
|
||||
// 6. 过滤出需要新增的学生ID
|
||||
List<String> newStudentIds = new ArrayList<>();
|
||||
for (String studentId : validStudentIds) {
|
||||
if (!alreadyEnrolledIds.contains(studentId)) {
|
||||
newStudentIds.add(studentId);
|
||||
}
|
||||
}
|
||||
|
||||
if (newStudentIds.isEmpty()) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("success", false);
|
||||
result.put("code", "all_already_enrolled");
|
||||
result.put("message", "所有学生都已经报名");
|
||||
result.put("addedCount", 0);
|
||||
result.put("alreadyEnrolledCount", alreadyEnrolledIds.size());
|
||||
return result;
|
||||
}
|
||||
|
||||
// 7. 检查报名人数限制
|
||||
int currentEnrollCount = course.getEnrollCount() == null ? 0 : course.getEnrollCount();
|
||||
if (course.getMaxEnroll() != null) {
|
||||
if (currentEnrollCount + newStudentIds.size() > course.getMaxEnroll()) {
|
||||
throw new RuntimeException("添加学生后将超过最大报名人数限制,当前:" + currentEnrollCount + ",最大:" + course.getMaxEnroll() + ",新增:" + newStudentIds.size());
|
||||
}
|
||||
}
|
||||
|
||||
// 8. 批量创建报名记录
|
||||
List<CourseSignup> newSignups = new ArrayList<>();
|
||||
Date now = new Date();
|
||||
for (String studentId : newStudentIds) {
|
||||
CourseSignup signup = new CourseSignup();
|
||||
signup.setUserId(studentId);
|
||||
signup.setCourseId(courseId);
|
||||
signup.setCreateTime(now);
|
||||
signup.setCreateBy(teacher.getId());
|
||||
newSignups.add(signup);
|
||||
}
|
||||
|
||||
// 9. 批量插入报名记录
|
||||
for (CourseSignup signup : newSignups) {
|
||||
int insertResult = courseSignupMapper.insert(signup);
|
||||
if (insertResult <= 0) {
|
||||
throw new RuntimeException("插入报名记录失败,学生ID: " + signup.getUserId());
|
||||
}
|
||||
}
|
||||
|
||||
// 10. 更新课程报名人数
|
||||
course.setEnrollCount(currentEnrollCount + newStudentIds.size());
|
||||
courseMapper.updateById(course);
|
||||
|
||||
// 11. 返回结果
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
if (alreadyEnrolledIds.isEmpty()) {
|
||||
result.put("success", true);
|
||||
result.put("code", "success");
|
||||
result.put("message", "所有学生都成功添加");
|
||||
result.put("addedCount", newStudentIds.size());
|
||||
result.put("alreadyEnrolledCount", 0);
|
||||
} else {
|
||||
result.put("success", true);
|
||||
result.put("code", "partial_success");
|
||||
result.put("message", "部分学生添加成功,部分学生已经报名");
|
||||
result.put("addedCount", newStudentIds.size());
|
||||
result.put("alreadyEnrolledCount", alreadyEnrolledIds.size());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getCourseProgress(String courseId, String userId) {
|
||||
// 1. 参数校验
|
||||
if (courseId == null || courseId.trim().isEmpty()) {
|
||||
throw new RuntimeException("课程ID不能为空");
|
||||
}
|
||||
if (userId == null || userId.trim().isEmpty()) {
|
||||
throw new RuntimeException("用户ID不能为空");
|
||||
}
|
||||
|
||||
// 2. 分别查询视频、考试、作业章节
|
||||
List<CourseSection> videoSections = getCourseSectionsByType(courseId, 0); // 视频
|
||||
List<CourseSection> examSections = getCourseSectionsByType(courseId, 2); // 考试
|
||||
List<CourseSection> homeworkSections = getCourseSectionsByType(courseId, 3); // 作业
|
||||
|
||||
// 3. 分别查询各类型章节的完成情况
|
||||
int videoCompleted = getCompletedSectionCount(courseId, userId, videoSections);
|
||||
int examCompleted = getCompletedSectionCount(courseId, userId, examSections);
|
||||
int homeworkCompleted = getCompletedSectionCount(courseId, userId, homeworkSections);
|
||||
|
||||
// 4. 计算各类型进度百分比
|
||||
int videoProgress = calculateProgress(videoCompleted, videoSections.size());
|
||||
int examProgress = calculateProgress(examCompleted, examSections.size());
|
||||
int homeworkProgress = calculateProgress(homeworkCompleted, homeworkSections.size());
|
||||
|
||||
// 5. 计算总进度
|
||||
int totalSections = videoSections.size() + examSections.size() + homeworkSections.size();
|
||||
int totalCompleted = videoCompleted + examCompleted + homeworkCompleted;
|
||||
int totalProgress = calculateProgress(totalCompleted, totalSections);
|
||||
|
||||
// 6. 构建返回结果
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
|
||||
// 视频进度
|
||||
Map<String, Object> videoInfo = new HashMap<>();
|
||||
videoInfo.put("total", videoSections.size());
|
||||
videoInfo.put("completed", videoCompleted);
|
||||
videoInfo.put("progress", videoProgress);
|
||||
result.put("video", videoInfo);
|
||||
|
||||
// 考试进度
|
||||
Map<String, Object> examInfo = new HashMap<>();
|
||||
examInfo.put("total", examSections.size());
|
||||
examInfo.put("completed", examCompleted);
|
||||
examInfo.put("progress", examProgress);
|
||||
result.put("exam", examInfo);
|
||||
|
||||
// 作业进度
|
||||
Map<String, Object> homeworkInfo = new HashMap<>();
|
||||
homeworkInfo.put("total", homeworkSections.size());
|
||||
homeworkInfo.put("completed", homeworkCompleted);
|
||||
homeworkInfo.put("progress", homeworkProgress);
|
||||
result.put("homework", homeworkInfo);
|
||||
|
||||
// 总进度
|
||||
Map<String, Object> totalInfo = new HashMap<>();
|
||||
totalInfo.put("total", totalSections);
|
||||
totalInfo.put("completed", totalCompleted);
|
||||
totalInfo.put("progress", totalProgress);
|
||||
result.put("total", totalInfo);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据类型查询课程章节
|
||||
*/
|
||||
private List<CourseSection> getCourseSectionsByType(String courseId, Integer type) {
|
||||
QueryWrapper<CourseSection> query = new QueryWrapper<>();
|
||||
query.eq("course_id", courseId).eq("type", type).eq("level", 2);
|
||||
return courseSectionMapper.selectList(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取已完成的章节数量
|
||||
*/
|
||||
private int getCompletedSectionCount(String courseId, String userId, List<CourseSection> sections) {
|
||||
if (sections.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
List<String> sectionIds = sections.stream()
|
||||
.map(CourseSection::getId)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
QueryWrapper<LearnProgress> progressQuery = new QueryWrapper<>();
|
||||
progressQuery.eq("user_id", userId)
|
||||
.eq("course_id", courseId)
|
||||
.in("section_id", sectionIds)
|
||||
.eq("status", 2); // status=2表示学习完成
|
||||
|
||||
return Math.toIntExact(learnProgressMapper.selectCount(progressQuery));
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算进度百分比
|
||||
*/
|
||||
private int calculateProgress(int completed, int total) {
|
||||
if (total == 0) {
|
||||
return 100; // 如果没有章节,认为已完成
|
||||
}
|
||||
return Math.round((float) completed / total * 100);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,36 @@
|
||||
package org.jeecg.modules.biz.service.impl;
|
||||
|
||||
import org.jeecg.modules.biz.service.EntityLinkBizService;
|
||||
import org.jeecg.modules.gen.entitylink.entity.EntityLink;
|
||||
import org.jeecg.modules.gen.entitylink.mapper.EntityLinkMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class EntityLinkBizServiceImpl extends ServiceImpl<EntityLinkMapper, EntityLink> implements EntityLinkBizService {
|
||||
@Override
|
||||
public List<String> listTargetIds(String sourceType, String sourceId, String targetType) {
|
||||
LambdaQueryWrapper<EntityLink> qw = new LambdaQueryWrapper<>();
|
||||
qw.eq(EntityLink::getSourceType, sourceType)
|
||||
.eq(EntityLink::getSourceId, sourceId)
|
||||
.eq(EntityLink::getTargetType, targetType)
|
||||
.select(EntityLink::getTargetId);
|
||||
return this.list(qw).stream()
|
||||
.map(EntityLink::getTargetId)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(String sourceType, String sourceId, String targetType, String targetId) {
|
||||
EntityLink entityLink = new EntityLink();
|
||||
entityLink.setSourceType(sourceType);
|
||||
entityLink.setSourceId(sourceId);
|
||||
entityLink.setTargetType(targetType);
|
||||
entityLink.setTargetId(targetId);
|
||||
this.save(entityLink);
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package org.jeecg.modules.biz.service.impl;
|
||||
|
||||
import org.jeecg.modules.biz.constant.EntityLinkConst;
|
||||
import org.jeecg.modules.biz.service.EntityLinkBizService;
|
||||
import org.jeecg.modules.biz.service.IHomeworkBizService;
|
||||
import org.jeecg.modules.gen.homework.entity.Homework;
|
||||
import org.jeecg.modules.gen.homework.mapper.HomeworkMapper;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class HomeworkBizServiceImpl extends ServiceImpl<HomeworkMapper, Homework> implements IHomeworkBizService {
|
||||
|
||||
@Autowired
|
||||
private EntityLinkBizService entityLinkBizService;
|
||||
|
||||
@Override
|
||||
public List<Homework> listByCourseId(String courseId) {
|
||||
List<String> homeworkIds = entityLinkBizService.listTargetIds(EntityLinkConst.SourceType.COURSE, courseId, EntityLinkConst.TargetType.HOMEWORK);
|
||||
if (homeworkIds.size() > 0) {
|
||||
return this.listByIds(homeworkIds);
|
||||
} else {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,324 @@
|
||||
package org.jeecg.modules.biz.service.impl;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.util.CommonUtils;
|
||||
import org.jeecg.common.util.MinioUtil;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import org.jeecg.common.util.oss.OssBootUtil;
|
||||
import org.jeecg.modules.biz.service.ResourceBizService;
|
||||
import org.jeecg.modules.gen.resource.mapper.ResourceMapper;
|
||||
import org.jeecg.modules.gen.resource.entity.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ResourceBizServiceImpl extends ServiceImpl<ResourceMapper, Resource> implements ResourceBizService {
|
||||
|
||||
/**
|
||||
* 视频清晰度配置
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public static class VideoQuality {
|
||||
private String name; // 清晰度名称
|
||||
private String outputDir; // 输出目录
|
||||
private int width; // 宽度
|
||||
private int height; // 高度
|
||||
private String bitrate; // 视频比特率
|
||||
private String audioRate; // 音频比特率
|
||||
}
|
||||
|
||||
// 预定义的清晰度配置
|
||||
private static final List<VideoQuality> QUALITY_CONFIGS = Arrays.asList(
|
||||
new VideoQuality("480p", "480p", 854, 480, "1000k", "96k"),
|
||||
new VideoQuality("720p", "720p", 1280, 720, "2500k", "128k"),
|
||||
new VideoQuality("1080p", "1080p", 1920, 1080, "5000k", "192k")
|
||||
);
|
||||
|
||||
private static final int SEGMENT_TIME = 10; // HLS切片时长(秒)
|
||||
private static final ExecutorService executorService = Executors.newFixedThreadPool(3);
|
||||
|
||||
@Override
|
||||
public Map<String, String> uploadHls(MultipartFile file, HttpServletRequest request) throws Exception {
|
||||
// 读取上传类型
|
||||
String configUploadType = SpringContextUtils.getApplicationContext().getEnvironment().getProperty("jeecg.uploadType", "minio");
|
||||
String uploadType = configUploadType;
|
||||
|
||||
// 1) 保存临时原始视频
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
String tmpRoot = System.getProperty("java.io.tmpdir");
|
||||
Path tmpVideoDir = Path.of(tmpRoot, "jeecg", "video", uuid);
|
||||
Path hlsBaseDir = Path.of(tmpRoot, "jeecg", "hls", uuid);
|
||||
Files.createDirectories(tmpVideoDir);
|
||||
Files.createDirectories(hlsBaseDir);
|
||||
|
||||
String original = CommonUtils.getFileName(Objects.requireNonNull(file.getOriginalFilename()));
|
||||
Path tmpVideoFile = tmpVideoDir.resolve(original);
|
||||
Files.copy(file.getInputStream(), tmpVideoFile, StandardCopyOption.REPLACE_EXISTING);
|
||||
|
||||
log.info("开始多清晰度视频处理,文件: {}", original);
|
||||
|
||||
try {
|
||||
// 2) 并行处理多个清晰度
|
||||
List<CompletableFuture<Map<String, String>>> futures = new ArrayList<>();
|
||||
|
||||
for (VideoQuality quality : QUALITY_CONFIGS) {
|
||||
CompletableFuture<Map<String, String>> future = CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
return processVideoQuality(tmpVideoFile, hlsBaseDir, quality, uploadType, uuid);
|
||||
} catch (Exception e) {
|
||||
log.error("处理{}清晰度失败", quality.getName(), e);
|
||||
throw new RuntimeException("处理" + quality.getName() + "清晰度失败: " + e.getMessage());
|
||||
}
|
||||
}, executorService);
|
||||
futures.add(future);
|
||||
}
|
||||
|
||||
// 3) 等待所有清晰度处理完成
|
||||
CompletableFuture<Void> allFutures = CompletableFuture.allOf(
|
||||
futures.toArray(new CompletableFuture[0])
|
||||
);
|
||||
|
||||
// 设置超时时间为30分钟
|
||||
allFutures.get(30, TimeUnit.MINUTES);
|
||||
|
||||
// 4) 收集结果 - 各清晰度的index.m3u8地址
|
||||
Map<String, String> qualityUrls = new HashMap<>();
|
||||
for (CompletableFuture<Map<String, String>> future : futures) {
|
||||
qualityUrls.putAll(future.get());
|
||||
}
|
||||
|
||||
log.info("多清晰度视频处理完成,各清晰度地址: {}", qualityUrls);
|
||||
return qualityUrls;
|
||||
|
||||
} finally {
|
||||
// 清理临时文件
|
||||
deleteQuietly(hlsBaseDir.toFile());
|
||||
deleteQuietly(tmpVideoDir.toFile());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理单个清晰度的视频切片
|
||||
*/
|
||||
private Map<String, String> processVideoQuality(Path inputFile, Path hlsBaseDir, VideoQuality quality, String uploadType, String uuid) throws Exception {
|
||||
log.info("开始处理 {} 清晰度...", quality.getName());
|
||||
|
||||
// 创建清晰度输出目录
|
||||
Path outputDir = hlsBaseDir.resolve(quality.getOutputDir());
|
||||
Files.createDirectories(outputDir);
|
||||
|
||||
Path playlistPath = outputDir.resolve("index.m3u8");
|
||||
|
||||
// 构建FFmpeg命令 - 参考Go代码
|
||||
List<String> args = Arrays.asList(
|
||||
"ffmpeg", "-i", inputFile.toString(),
|
||||
"-vf", String.format("scale=%d:%d", quality.getWidth(), quality.getHeight()),
|
||||
"-c:v", "libx264",
|
||||
"-b:v", quality.getBitrate(),
|
||||
"-c:a", "aac",
|
||||
"-b:a", quality.getAudioRate(),
|
||||
"-hls_time", String.valueOf(SEGMENT_TIME),
|
||||
"-hls_playlist_type", "vod",
|
||||
"-hls_segment_filename", outputDir.resolve("segment%d.ts").toString(),
|
||||
"-y", // 覆盖已存在的文件
|
||||
playlistPath.toString()
|
||||
);
|
||||
|
||||
// 执行FFmpeg并处理日志
|
||||
executeFFmpegWithLogging(args, quality.getName());
|
||||
|
||||
log.info("{} 清晰度处理完成", quality.getName());
|
||||
|
||||
// 上传切片文件
|
||||
return uploadQualityFiles(outputDir, quality, uploadType, uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传单个清晰度的所有文件
|
||||
*/
|
||||
private Map<String, String> uploadQualityFiles(Path outputDir, VideoQuality quality, String uploadType, String uuid) throws Exception {
|
||||
Map<String, String> urls = new HashMap<>();
|
||||
String basePrefix = "video/hls/" + uuid + "/" + quality.getOutputDir();
|
||||
String m3u8Url = "";
|
||||
|
||||
try (Stream<Path> paths = Files.list(outputDir)) {
|
||||
for (Path file : (Iterable<Path>) paths::iterator) {
|
||||
if (!Files.isRegularFile(file)) continue;
|
||||
|
||||
String fileName = file.getFileName().toString();
|
||||
String relativePath = basePrefix + "/" + fileName;
|
||||
|
||||
try (InputStream in = Files.newInputStream(file)) {
|
||||
String fileUrl = "";
|
||||
if ("minio".equals(uploadType)) {
|
||||
fileUrl = MinioUtil.upload(in, relativePath);
|
||||
} else if ("alioss".equals(uploadType)) {
|
||||
OssBootUtil.upload(in, relativePath);
|
||||
fileUrl = relativePath; // 可在网关拼域名
|
||||
} else {
|
||||
// 本地存储
|
||||
String uploadpath = SpringContextUtils.getApplicationContext().getEnvironment().getProperty("jeecg.path.upload");
|
||||
Path target = Path.of(uploadpath, relativePath);
|
||||
Files.createDirectories(target.getParent());
|
||||
Files.copy(file, target, StandardCopyOption.REPLACE_EXISTING);
|
||||
fileUrl = relativePath;
|
||||
}
|
||||
|
||||
if (fileName.endsWith(".m3u8")) {
|
||||
m3u8Url = fileUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
urls.put(quality.getName(), m3u8Url);
|
||||
return urls;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行FFmpeg命令并处理日志输出
|
||||
*/
|
||||
private void executeFFmpegWithLogging(List<String> args, String qualityName) throws Exception {
|
||||
// 打印FFmpeg命令
|
||||
log.info("执行FFmpeg命令[{}]: {}", qualityName, String.join(" ", args));
|
||||
|
||||
ProcessBuilder pb = new ProcessBuilder(args);
|
||||
pb.redirectErrorStream(true); // 将错误输出重定向到标准输出
|
||||
Process process = pb.start();
|
||||
|
||||
// 使用单独的线程来读取FFmpeg输出,避免阻塞
|
||||
StringBuilder ffmpegOutput = new StringBuilder();
|
||||
Thread logThread = new Thread(() -> {
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
synchronized (ffmpegOutput) {
|
||||
ffmpegOutput.append(line).append("\n");
|
||||
}
|
||||
|
||||
// 输出详细日志到DEBUG级别
|
||||
log.debug("FFmpeg[{}]: {}", qualityName, line);
|
||||
|
||||
// 过滤并输出关键进度信息
|
||||
if (line.contains("frame=") && line.contains("time=")) {
|
||||
// 提取进度信息
|
||||
String progressInfo = extractProgressInfo(line);
|
||||
if (progressInfo != null) {
|
||||
log.info("FFmpeg进度[{}]: {}", qualityName, progressInfo);
|
||||
}
|
||||
}
|
||||
|
||||
// 输出警告和错误信息
|
||||
if (line.toLowerCase().contains("warning") || line.toLowerCase().contains("error")) {
|
||||
log.warn("FFmpeg[{}]: {}", qualityName, line);
|
||||
}
|
||||
|
||||
// 输出关键状态信息
|
||||
if (line.contains("Stream mapping:") || line.contains("Press [q] to stop") ||
|
||||
line.contains("video:") || line.contains("audio:")) {
|
||||
log.info("FFmpeg[{}]: {}", qualityName, line);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("读取FFmpeg输出时发生错误[{}]", qualityName, e);
|
||||
}
|
||||
});
|
||||
|
||||
logThread.setDaemon(true);
|
||||
logThread.start();
|
||||
|
||||
// 等待进程完成
|
||||
boolean finished = process.waitFor(15, TimeUnit.MINUTES);
|
||||
int exitCode = process.exitValue();
|
||||
|
||||
// 等待日志线程完成
|
||||
logThread.join(5000); // 最多等待5秒
|
||||
|
||||
if (!finished || exitCode != 0) {
|
||||
synchronized (ffmpegOutput) {
|
||||
log.error("FFmpeg处理[{}]失败,退出码: {}", qualityName, exitCode);
|
||||
log.error("FFmpeg完整输出[{}]:\n{}", qualityName, ffmpegOutput.toString());
|
||||
}
|
||||
throw new RuntimeException(String.format("FFmpeg处理%s失败,退出码: %d", qualityName, exitCode));
|
||||
}
|
||||
|
||||
log.info("FFmpeg处理[{}]成功完成", qualityName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从FFmpeg输出行中提取进度信息
|
||||
*/
|
||||
private String extractProgressInfo(String line) {
|
||||
try {
|
||||
// FFmpeg进度行格式示例:
|
||||
// frame= 1234 fps= 25 q=23.0 size= 12345kB time=00:01:23.45 bitrate=1234.5kbits/s speed=1.23x
|
||||
if (line.contains("time=") && line.contains("bitrate=")) {
|
||||
// 提取时间和比特率信息
|
||||
String time = "";
|
||||
String bitrate = "";
|
||||
String speed = "";
|
||||
String frame = "";
|
||||
|
||||
String[] parts = line.split("\\s+");
|
||||
for (String part : parts) {
|
||||
if (part.startsWith("time=")) {
|
||||
time = part.substring(5);
|
||||
} else if (part.startsWith("bitrate=")) {
|
||||
bitrate = part.substring(8);
|
||||
} else if (part.startsWith("speed=")) {
|
||||
speed = part.substring(6);
|
||||
} else if (part.startsWith("frame=")) {
|
||||
frame = part.substring(6);
|
||||
}
|
||||
}
|
||||
|
||||
if (!time.isEmpty()) {
|
||||
return String.format("frame=%s time=%s bitrate=%s speed=%s", frame, time, bitrate, speed);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 解析失败时忽略,返回原始行
|
||||
return line.trim();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** 删除临时目录文件 */
|
||||
private static void deleteQuietly(File file) {
|
||||
try {
|
||||
if (file == null || !file.exists()) return;
|
||||
if (file.isDirectory()) {
|
||||
File[] children = file.listFiles();
|
||||
if (children != null) {
|
||||
for (File c : children) deleteQuietly(c);
|
||||
}
|
||||
}
|
||||
file.delete();
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,93 @@
|
||||
package org.jeecg.modules.biz.service.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.jeecg.modules.biz.constant.EntityLinkConst;
|
||||
import org.jeecg.modules.biz.dto.TeacherInfo;
|
||||
import org.jeecg.modules.biz.service.EntityLinkBizService;
|
||||
import org.jeecg.modules.biz.service.UserBizService;
|
||||
import org.jeecg.modules.gen.course.entity.Course;
|
||||
import org.jeecg.modules.gen.course.mapper.CourseMapper;
|
||||
import org.jeecg.modules.gen.courseteacher.entity.CourseTeacher;
|
||||
import org.jeecg.modules.gen.courseteacher.mapper.CourseTeacherMapper;
|
||||
import org.jeecg.modules.gen.entitylink.mapper.EntityLinkMapper;
|
||||
import org.jeecg.modules.gen.userinfo.entity.UserInfo;
|
||||
import org.jeecg.modules.gen.userinfo.mapper.UserInfoMapper;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.jeecg.modules.system.mapper.SysUserMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class UserBizServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserBizService {
|
||||
|
||||
@Autowired
|
||||
private CourseMapper courseMapper;
|
||||
@Autowired
|
||||
private EntityLinkMapper entityLinkMapper;
|
||||
@Autowired
|
||||
private EntityLinkBizService entityLinkBizService;
|
||||
@Autowired
|
||||
private CourseTeacherMapper courseTeacherMapper;
|
||||
@Autowired
|
||||
private UserInfoMapper userInfoMapper;
|
||||
@Autowired
|
||||
private SysUserMapper sysUserMapper;
|
||||
|
||||
@Override
|
||||
public List<TeacherInfo> queryAllTeachers(String categoryId) {
|
||||
// categoryId为all则查询全部
|
||||
// TODO 存入redis缓存
|
||||
|
||||
// 1 根据课程分类,查询该分类下的课程; all 则查询全部课程
|
||||
// 2 遍历课程,根据课程id查询该课程的授课教师
|
||||
// 3 将授课教师信息封装成TeacherInfo对象
|
||||
// 4 返回授课教师列表(去重)
|
||||
|
||||
// 1 根据课程分类,查询该分类下的课程
|
||||
List<String> courseIds;
|
||||
if ("all".equals(categoryId)) {
|
||||
// 查询全部课程
|
||||
List<Course> courseList = courseMapper.selectList(null);
|
||||
courseIds = courseList.stream().map(Course::getId).collect(Collectors.toList());
|
||||
} else {
|
||||
courseIds = entityLinkBizService.listTargetIds(EntityLinkConst.SourceType.COURSE_CATEGORY, categoryId, EntityLinkConst.TargetType.COURSE);
|
||||
}
|
||||
Set<String> teacherIds = new HashSet<>();
|
||||
List<TeacherInfo> result = new ArrayList<>();
|
||||
for (String courseId : courseIds) {
|
||||
// 2 根据课程id查询该课程的授课教师
|
||||
List<CourseTeacher> courseTeachers = courseTeacherMapper.selectList(new LambdaQueryWrapper<CourseTeacher>().eq(CourseTeacher::getCourseId, courseId));
|
||||
// 3 将授课教师信息封装成TeacherInfo对象
|
||||
for (CourseTeacher courseTeacher : courseTeachers) {
|
||||
// 4 将授课教师信息封装成TeacherInfo对象,去重
|
||||
UserInfo userInfo = userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getUserId, courseTeacher.getTeacherId()));
|
||||
SysUser sysUser = sysUserMapper.selectById(courseTeacher.getTeacherId());
|
||||
TeacherInfo teacherInfo = new TeacherInfo();
|
||||
teacherInfo.setId(courseTeacher.getTeacherId());
|
||||
teacherInfo.setName(sysUser.getRealname());
|
||||
teacherInfo.setAvatar(sysUser.getAvatar());
|
||||
teacherInfo.setTitle(userInfo.getTitle());
|
||||
teacherInfo.setTag(userInfo.getTag());
|
||||
teacherInfo.setSortOrder(userInfo.getSortOrder());
|
||||
if (!teacherIds.contains(courseTeacher.getTeacherId())) {
|
||||
result.add(teacherInfo);
|
||||
teacherIds.add(courseTeacher.getTeacherId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,182 @@
|
||||
package org.jeecg.modules.gen.activity.controller;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.gen.activity.entity.Activity;
|
||||
import org.jeecg.modules.gen.activity.service.IActivityService;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
/**
|
||||
* @Description: 活动
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-14
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Tag(name="活动")
|
||||
@RestController
|
||||
@RequestMapping("/gen/activity/activity")
|
||||
@Slf4j
|
||||
public class ActivityController extends JeecgController<Activity, IActivityService> {
|
||||
@Autowired
|
||||
private IActivityService activityService;
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
*
|
||||
* @param activity
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
//@AutoLog(value = "活动-分页列表查询")
|
||||
@Operation(summary="活动-分页列表查询")
|
||||
@GetMapping(value = "/list")
|
||||
public Result<IPage<Activity>> queryPageList(Activity activity,
|
||||
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||
HttpServletRequest req) {
|
||||
|
||||
|
||||
QueryWrapper<Activity> queryWrapper = QueryGenerator.initQueryWrapper(activity, req.getParameterMap());
|
||||
Page<Activity> page = new Page<Activity>(pageNo, pageSize);
|
||||
IPage<Activity> pageList = activityService.page(page, queryWrapper);
|
||||
return Result.OK(pageList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param activity
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "活动-添加")
|
||||
@Operation(summary="活动-添加")
|
||||
@RequiresPermissions("gen.activity:activity:add")
|
||||
@PostMapping(value = "/add")
|
||||
public Result<String> add(@RequestBody Activity activity) {
|
||||
activityService.save(activity);
|
||||
|
||||
return Result.OK("添加成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*
|
||||
* @param activity
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "活动-编辑")
|
||||
@Operation(summary="活动-编辑")
|
||||
@RequiresPermissions("gen.activity:activity:edit")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result<String> edit(@RequestBody Activity activity) {
|
||||
activityService.updateById(activity);
|
||||
return Result.OK("编辑成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "活动-通过id删除")
|
||||
@Operation(summary="活动-通过id删除")
|
||||
@RequiresPermissions("gen.activity:activity:delete")
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||
activityService.removeById(id);
|
||||
return Result.OK("删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "活动-批量删除")
|
||||
@Operation(summary="活动-批量删除")
|
||||
@RequiresPermissions("gen.activity:activity:deleteBatch")
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||
this.activityService.removeByIds(Arrays.asList(ids.split(",")));
|
||||
return Result.OK("批量删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
//@AutoLog(value = "活动-通过id查询")
|
||||
@Operation(summary="活动-通过id查询")
|
||||
@GetMapping(value = "/queryById")
|
||||
public Result<Activity> queryById(@RequestParam(name="id",required=true) String id) {
|
||||
Activity activity = activityService.getById(id);
|
||||
if(activity==null) {
|
||||
return Result.error("未找到对应数据");
|
||||
}
|
||||
return Result.OK(activity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
* @param activity
|
||||
*/
|
||||
@RequiresPermissions("gen.activity:activity:exportXls")
|
||||
@RequestMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(HttpServletRequest request, Activity activity) {
|
||||
return super.exportXls(request, activity, Activity.class, "活动");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过excel导入数据
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("gen.activity:activity:importExcel")
|
||||
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||
return super.importExcel(request, response, Activity.class);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
package org.jeecg.modules.gen.activity.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Date;
|
||||
import java.math.BigDecimal;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import org.jeecg.common.constant.ProvinceCityArea;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import lombok.Data;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
import org.jeecg.common.aspect.annotation.Dict;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* @Description: 活动
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-14
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Data
|
||||
@TableName("activity")
|
||||
@Accessors(chain = true)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Schema(description="活动")
|
||||
public class Activity implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**主键*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
@Schema(description = "主键")
|
||||
private java.lang.String id;
|
||||
/**标题*/
|
||||
@Excel(name = "标题", width = 15)
|
||||
@Schema(description = "标题")
|
||||
private java.lang.String title;
|
||||
/**介绍*/
|
||||
@Excel(name = "介绍", width = 15)
|
||||
@Schema(description = "介绍")
|
||||
private java.lang.String introduction;
|
||||
/**说明图片*/
|
||||
@Excel(name = "说明图片", width = 15)
|
||||
@Schema(description = "说明图片")
|
||||
private java.lang.String imgs;
|
||||
/**头图*/
|
||||
@Excel(name = "头图", width = 15)
|
||||
@Schema(description = "头图")
|
||||
private java.lang.String banner;
|
||||
/**介绍视频*/
|
||||
@Excel(name = "介绍视频", width = 15)
|
||||
@Schema(description = "介绍视频")
|
||||
private java.lang.String video;
|
||||
/**报名人数上限*/
|
||||
@Excel(name = "报名人数上限", width = 15)
|
||||
@Schema(description = "报名人数上限")
|
||||
private java.lang.Integer maxNum;
|
||||
/**开始时间*/
|
||||
@Excel(name = "开始时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
@Schema(description = "开始时间")
|
||||
private java.util.Date startTime;
|
||||
/**结束时间*/
|
||||
@Excel(name = "结束时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
@Schema(description = "结束时间")
|
||||
private java.util.Date endTime;
|
||||
/**扩展字段*/
|
||||
@Excel(name = "扩展字段", width = 15)
|
||||
@Schema(description = "扩展字段")
|
||||
private java.lang.String extra;
|
||||
/**附件*/
|
||||
@Excel(name = "附件", width = 15)
|
||||
@Schema(description = "附件")
|
||||
private java.lang.String attachment;
|
||||
/**状态*/
|
||||
@Excel(name = "状态", width = 15, dicCode = "course_status")
|
||||
@Dict(dicCode = "course_status")
|
||||
@Schema(description = "状态")
|
||||
private java.lang.String status;
|
||||
/**创建人*/
|
||||
@Schema(description = "创建人")
|
||||
private java.lang.String createBy;
|
||||
/**创建日期*/
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
@Schema(description = "创建日期")
|
||||
private java.util.Date createTime;
|
||||
/**更新人*/
|
||||
@Schema(description = "更新人")
|
||||
private java.lang.String updateBy;
|
||||
/**更新日期*/
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
@Schema(description = "更新日期")
|
||||
private java.util.Date updateTime;
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package org.jeecg.modules.gen.activity.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.jeecg.modules.gen.activity.entity.Activity;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* @Description: 活动
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-14
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface ActivityMapper extends BaseMapper<Activity> {
|
||||
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
<?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="org.jeecg.modules.gen.activity.mapper.ActivityMapper">
|
||||
|
||||
</mapper>
|
@ -0,0 +1,14 @@
|
||||
package org.jeecg.modules.gen.activity.service;
|
||||
|
||||
import org.jeecg.modules.gen.activity.entity.Activity;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* @Description: 活动
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-14
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface IActivityService extends IService<Activity> {
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package org.jeecg.modules.gen.activity.service.impl;
|
||||
|
||||
import org.jeecg.modules.gen.activity.entity.Activity;
|
||||
import org.jeecg.modules.gen.activity.mapper.ActivityMapper;
|
||||
import org.jeecg.modules.gen.activity.service.IActivityService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
||||
/**
|
||||
* @Description: 活动
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-14
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Service
|
||||
public class ActivityServiceImpl extends ServiceImpl<ActivityMapper, Activity> implements IActivityService {
|
||||
|
||||
}
|
@ -0,0 +1,182 @@
|
||||
package org.jeecg.modules.gen.activitysignup.controller;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.gen.activitysignup.entity.ActivitySignup;
|
||||
import org.jeecg.modules.gen.activitysignup.service.IActivitySignupService;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
/**
|
||||
* @Description: 活动报名
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-21
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Tag(name="活动报名")
|
||||
@RestController
|
||||
@RequestMapping("/gen/activitysignup/activitySignup")
|
||||
@Slf4j
|
||||
public class ActivitySignupController extends JeecgController<ActivitySignup, IActivitySignupService> {
|
||||
@Autowired
|
||||
private IActivitySignupService activitySignupService;
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
*
|
||||
* @param activitySignup
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
//@AutoLog(value = "活动报名-分页列表查询")
|
||||
@Operation(summary="活动报名-分页列表查询")
|
||||
@GetMapping(value = "/list")
|
||||
public Result<IPage<ActivitySignup>> queryPageList(ActivitySignup activitySignup,
|
||||
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||
HttpServletRequest req) {
|
||||
|
||||
|
||||
QueryWrapper<ActivitySignup> queryWrapper = QueryGenerator.initQueryWrapper(activitySignup, req.getParameterMap());
|
||||
Page<ActivitySignup> page = new Page<ActivitySignup>(pageNo, pageSize);
|
||||
IPage<ActivitySignup> pageList = activitySignupService.page(page, queryWrapper);
|
||||
return Result.OK(pageList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param activitySignup
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "活动报名-添加")
|
||||
@Operation(summary="活动报名-添加")
|
||||
@RequiresPermissions("gen.activitysignup:activity_signup:add")
|
||||
@PostMapping(value = "/add")
|
||||
public Result<String> add(@RequestBody ActivitySignup activitySignup) {
|
||||
activitySignupService.save(activitySignup);
|
||||
|
||||
return Result.OK("添加成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*
|
||||
* @param activitySignup
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "活动报名-编辑")
|
||||
@Operation(summary="活动报名-编辑")
|
||||
@RequiresPermissions("gen.activitysignup:activity_signup:edit")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result<String> edit(@RequestBody ActivitySignup activitySignup) {
|
||||
activitySignupService.updateById(activitySignup);
|
||||
return Result.OK("编辑成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "活动报名-通过id删除")
|
||||
@Operation(summary="活动报名-通过id删除")
|
||||
@RequiresPermissions("gen.activitysignup:activity_signup:delete")
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||
activitySignupService.removeById(id);
|
||||
return Result.OK("删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "活动报名-批量删除")
|
||||
@Operation(summary="活动报名-批量删除")
|
||||
@RequiresPermissions("gen.activitysignup:activity_signup:deleteBatch")
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||
this.activitySignupService.removeByIds(Arrays.asList(ids.split(",")));
|
||||
return Result.OK("批量删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
//@AutoLog(value = "活动报名-通过id查询")
|
||||
@Operation(summary="活动报名-通过id查询")
|
||||
@GetMapping(value = "/queryById")
|
||||
public Result<ActivitySignup> queryById(@RequestParam(name="id",required=true) String id) {
|
||||
ActivitySignup activitySignup = activitySignupService.getById(id);
|
||||
if(activitySignup==null) {
|
||||
return Result.error("未找到对应数据");
|
||||
}
|
||||
return Result.OK(activitySignup);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
* @param activitySignup
|
||||
*/
|
||||
@RequiresPermissions("gen.activitysignup:activity_signup:exportXls")
|
||||
@RequestMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(HttpServletRequest request, ActivitySignup activitySignup) {
|
||||
return super.exportXls(request, activitySignup, ActivitySignup.class, "活动报名");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过excel导入数据
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("gen.activitysignup:activity_signup:importExcel")
|
||||
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||
return super.importExcel(request, response, ActivitySignup.class);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
package org.jeecg.modules.gen.activitysignup.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Date;
|
||||
import java.math.BigDecimal;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import org.jeecg.common.constant.ProvinceCityArea;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import lombok.Data;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
import org.jeecg.common.aspect.annotation.Dict;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* @Description: 活动报名
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-21
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Data
|
||||
@TableName("activity_signup")
|
||||
@Accessors(chain = true)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Schema(description="活动报名")
|
||||
public class ActivitySignup implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**主键*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
@Schema(description = "主键")
|
||||
private java.lang.String id;
|
||||
/**姓名*/
|
||||
@Excel(name = "姓名", width = 15)
|
||||
@Schema(description = "姓名")
|
||||
private java.lang.String name;
|
||||
/**年龄*/
|
||||
@Excel(name = "年龄", width = 15)
|
||||
@Schema(description = "年龄")
|
||||
private java.lang.String age;
|
||||
/**手机号*/
|
||||
@Excel(name = "手机号", width = 15)
|
||||
@Schema(description = "手机号")
|
||||
private java.lang.String phone;
|
||||
/**邮箱*/
|
||||
@Excel(name = "邮箱", width = 15)
|
||||
@Schema(description = "邮箱")
|
||||
private java.lang.String email;
|
||||
/**扩展字段*/
|
||||
@Excel(name = "扩展字段", width = 15)
|
||||
@Schema(description = "扩展字段")
|
||||
private java.lang.String extra;
|
||||
/**附件*/
|
||||
@Excel(name = "附件", width = 15)
|
||||
@Schema(description = "附件")
|
||||
private java.lang.String attachment;
|
||||
/**创建人*/
|
||||
@Schema(description = "创建人")
|
||||
private java.lang.String createBy;
|
||||
/**创建日期*/
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
@Schema(description = "创建日期")
|
||||
private java.util.Date createTime;
|
||||
/**更新人*/
|
||||
@Schema(description = "更新人")
|
||||
private java.lang.String updateBy;
|
||||
/**更新日期*/
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
@Schema(description = "更新日期")
|
||||
private java.util.Date updateTime;
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package org.jeecg.modules.gen.activitysignup.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.jeecg.modules.gen.activitysignup.entity.ActivitySignup;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* @Description: 活动报名
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-21
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface ActivitySignupMapper extends BaseMapper<ActivitySignup> {
|
||||
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
<?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="org.jeecg.modules.gen.activitysignup.mapper.ActivitySignupMapper">
|
||||
|
||||
</mapper>
|
@ -0,0 +1,14 @@
|
||||
package org.jeecg.modules.gen.activitysignup.service;
|
||||
|
||||
import org.jeecg.modules.gen.activitysignup.entity.ActivitySignup;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* @Description: 活动报名
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-21
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface IActivitySignupService extends IService<ActivitySignup> {
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package org.jeecg.modules.gen.activitysignup.service.impl;
|
||||
|
||||
import org.jeecg.modules.gen.activitysignup.entity.ActivitySignup;
|
||||
import org.jeecg.modules.gen.activitysignup.mapper.ActivitySignupMapper;
|
||||
import org.jeecg.modules.gen.activitysignup.service.IActivitySignupService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
||||
/**
|
||||
* @Description: 活动报名
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-21
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Service
|
||||
public class ActivitySignupServiceImpl extends ServiceImpl<ActivitySignupMapper, ActivitySignup> implements IActivitySignupService {
|
||||
|
||||
}
|
@ -0,0 +1,182 @@
|
||||
package org.jeecg.modules.gen.aioltag.controller;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.gen.aioltag.entity.AiolTag;
|
||||
import org.jeecg.modules.gen.aioltag.service.IAiolTagService;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
/**
|
||||
* @Description: 标签
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-28
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Tag(name="标签")
|
||||
@RestController
|
||||
@RequestMapping("/gen/aioltag/aiolTag")
|
||||
@Slf4j
|
||||
public class AiolTagController extends JeecgController<AiolTag, IAiolTagService> {
|
||||
@Autowired
|
||||
private IAiolTagService aiolTagService;
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
*
|
||||
* @param aiolTag
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
//@AutoLog(value = "标签-分页列表查询")
|
||||
@Operation(summary="标签-分页列表查询")
|
||||
@GetMapping(value = "/list")
|
||||
public Result<IPage<AiolTag>> queryPageList(AiolTag aiolTag,
|
||||
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||
HttpServletRequest req) {
|
||||
|
||||
|
||||
QueryWrapper<AiolTag> queryWrapper = QueryGenerator.initQueryWrapper(aiolTag, req.getParameterMap());
|
||||
Page<AiolTag> page = new Page<AiolTag>(pageNo, pageSize);
|
||||
IPage<AiolTag> pageList = aiolTagService.page(page, queryWrapper);
|
||||
return Result.OK(pageList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param aiolTag
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "标签-添加")
|
||||
@Operation(summary="标签-添加")
|
||||
@RequiresPermissions("gen.aioltag:aiol_tag:add")
|
||||
@PostMapping(value = "/add")
|
||||
public Result<String> add(@RequestBody AiolTag aiolTag) {
|
||||
aiolTagService.save(aiolTag);
|
||||
|
||||
return Result.OK("添加成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*
|
||||
* @param aiolTag
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "标签-编辑")
|
||||
@Operation(summary="标签-编辑")
|
||||
@RequiresPermissions("gen.aioltag:aiol_tag:edit")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result<String> edit(@RequestBody AiolTag aiolTag) {
|
||||
aiolTagService.updateById(aiolTag);
|
||||
return Result.OK("编辑成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "标签-通过id删除")
|
||||
@Operation(summary="标签-通过id删除")
|
||||
@RequiresPermissions("gen.aioltag:aiol_tag:delete")
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||
aiolTagService.removeById(id);
|
||||
return Result.OK("删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "标签-批量删除")
|
||||
@Operation(summary="标签-批量删除")
|
||||
@RequiresPermissions("gen.aioltag:aiol_tag:deleteBatch")
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||
this.aiolTagService.removeByIds(Arrays.asList(ids.split(",")));
|
||||
return Result.OK("批量删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
//@AutoLog(value = "标签-通过id查询")
|
||||
@Operation(summary="标签-通过id查询")
|
||||
@GetMapping(value = "/queryById")
|
||||
public Result<AiolTag> queryById(@RequestParam(name="id",required=true) String id) {
|
||||
AiolTag aiolTag = aiolTagService.getById(id);
|
||||
if(aiolTag==null) {
|
||||
return Result.error("未找到对应数据");
|
||||
}
|
||||
return Result.OK(aiolTag);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
* @param aiolTag
|
||||
*/
|
||||
@RequiresPermissions("gen.aioltag:aiol_tag:exportXls")
|
||||
@RequestMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(HttpServletRequest request, AiolTag aiolTag) {
|
||||
return super.exportXls(request, aiolTag, AiolTag.class, "标签");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过excel导入数据
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("gen.aioltag:aiol_tag:importExcel")
|
||||
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||
return super.importExcel(request, response, AiolTag.class);
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package org.jeecg.modules.learn.gen.entity;
|
||||
package org.jeecg.modules.gen.aioltag.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
@ -20,23 +20,39 @@ import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* @Description: 课程
|
||||
* @Description: 标签
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-07
|
||||
* @Date: 2025-08-28
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Data
|
||||
@TableName("course")
|
||||
@TableName("aiol_tag")
|
||||
@Accessors(chain = true)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Schema(description="课程")
|
||||
public class Course implements Serializable {
|
||||
@Schema(description="标签")
|
||||
public class AiolTag implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**主键*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
@Schema(description = "主键")
|
||||
private java.lang.String id;
|
||||
/**标签名*/
|
||||
@Excel(name = "标签名", width = 15)
|
||||
@Schema(description = "标签名")
|
||||
private java.lang.String name;
|
||||
/**目标类型*/
|
||||
@Excel(name = "目标类型", width = 15)
|
||||
@Schema(description = "目标类型")
|
||||
private java.lang.String targetType;
|
||||
/**目标id*/
|
||||
@Excel(name = "目标id", width = 15)
|
||||
@Schema(description = "目标id")
|
||||
private java.lang.String targetId;
|
||||
/**描述*/
|
||||
@Excel(name = "描述", width = 15)
|
||||
@Schema(description = "描述")
|
||||
private java.lang.String description;
|
||||
/**创建人*/
|
||||
@Schema(description = "创建人")
|
||||
private java.lang.String createBy;
|
||||
@ -53,24 +69,4 @@ public class Course implements Serializable {
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
@Schema(description = "更新日期")
|
||||
private java.util.Date updateTime;
|
||||
/**所属部门*/
|
||||
@Schema(description = "所属部门")
|
||||
private java.lang.String sysOrgCode;
|
||||
/**课程名*/
|
||||
@Excel(name = "课程名", width = 15)
|
||||
@Schema(description = "课程名")
|
||||
private java.lang.String name;
|
||||
/**图片*/
|
||||
@Excel(name = "图片", width = 15)
|
||||
@Schema(description = "图片")
|
||||
private java.lang.String cover;
|
||||
/**描述*/
|
||||
@Excel(name = "描述", width = 15)
|
||||
@Schema(description = "描述")
|
||||
private java.lang.String description;
|
||||
/**所属分类*/
|
||||
@Excel(name = "所属分类", width = 15, dictTable = "demo", dicText = "name", dicCode = "id")
|
||||
@Dict(dictTable = "demo", dicText = "name", dicCode = "id")
|
||||
@Schema(description = "所属分类")
|
||||
private java.lang.String categoryId;
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package org.jeecg.modules.gen.aioltag.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.jeecg.modules.gen.aioltag.entity.AiolTag;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* @Description: 标签
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-28
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface AiolTagMapper extends BaseMapper<AiolTag> {
|
||||
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
<?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="org.jeecg.modules.gen.aioltag.mapper.AiolTagMapper">
|
||||
|
||||
</mapper>
|
@ -0,0 +1,14 @@
|
||||
package org.jeecg.modules.gen.aioltag.service;
|
||||
|
||||
import org.jeecg.modules.gen.aioltag.entity.AiolTag;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* @Description: 标签
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-28
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface IAiolTagService extends IService<AiolTag> {
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package org.jeecg.modules.gen.aioltag.service.impl;
|
||||
|
||||
import org.jeecg.modules.gen.aioltag.entity.AiolTag;
|
||||
import org.jeecg.modules.gen.aioltag.mapper.AiolTagMapper;
|
||||
import org.jeecg.modules.gen.aioltag.service.IAiolTagService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
||||
/**
|
||||
* @Description: 标签
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-28
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Service
|
||||
public class AiolTagServiceImpl extends ServiceImpl<AiolTagMapper, AiolTag> implements IAiolTagService {
|
||||
|
||||
}
|
@ -0,0 +1,182 @@
|
||||
package org.jeecg.modules.gen.comment.controller;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.gen.comment.entity.Comment;
|
||||
import org.jeecg.modules.gen.comment.service.ICommentService;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
/**
|
||||
* @Description: 评论
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-16
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Tag(name="评论")
|
||||
@RestController
|
||||
@RequestMapping("/gen/comment/comment")
|
||||
@Slf4j
|
||||
public class CommentController extends JeecgController<Comment, ICommentService> {
|
||||
@Autowired
|
||||
private ICommentService commentService;
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
*
|
||||
* @param comment
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
//@AutoLog(value = "评论-分页列表查询")
|
||||
@Operation(summary="评论-分页列表查询")
|
||||
@GetMapping(value = "/list")
|
||||
public Result<IPage<Comment>> queryPageList(Comment comment,
|
||||
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||
HttpServletRequest req) {
|
||||
|
||||
|
||||
QueryWrapper<Comment> queryWrapper = QueryGenerator.initQueryWrapper(comment, req.getParameterMap());
|
||||
Page<Comment> page = new Page<Comment>(pageNo, pageSize);
|
||||
IPage<Comment> pageList = commentService.page(page, queryWrapper);
|
||||
return Result.OK(pageList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param comment
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "评论-添加")
|
||||
@Operation(summary="评论-添加")
|
||||
@RequiresPermissions("gen.comment:comment:add")
|
||||
@PostMapping(value = "/add")
|
||||
public Result<String> add(@RequestBody Comment comment) {
|
||||
commentService.save(comment);
|
||||
|
||||
return Result.OK("添加成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*
|
||||
* @param comment
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "评论-编辑")
|
||||
@Operation(summary="评论-编辑")
|
||||
@RequiresPermissions("gen.comment:comment:edit")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result<String> edit(@RequestBody Comment comment) {
|
||||
commentService.updateById(comment);
|
||||
return Result.OK("编辑成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "评论-通过id删除")
|
||||
@Operation(summary="评论-通过id删除")
|
||||
@RequiresPermissions("gen.comment:comment:delete")
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||
commentService.removeById(id);
|
||||
return Result.OK("删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "评论-批量删除")
|
||||
@Operation(summary="评论-批量删除")
|
||||
@RequiresPermissions("gen.comment:comment:deleteBatch")
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||
this.commentService.removeByIds(Arrays.asList(ids.split(",")));
|
||||
return Result.OK("批量删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
//@AutoLog(value = "评论-通过id查询")
|
||||
@Operation(summary="评论-通过id查询")
|
||||
@GetMapping(value = "/queryById")
|
||||
public Result<Comment> queryById(@RequestParam(name="id",required=true) String id) {
|
||||
Comment comment = commentService.getById(id);
|
||||
if(comment==null) {
|
||||
return Result.error("未找到对应数据");
|
||||
}
|
||||
return Result.OK(comment);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
* @param comment
|
||||
*/
|
||||
@RequiresPermissions("gen.comment:comment:exportXls")
|
||||
@RequestMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(HttpServletRequest request, Comment comment) {
|
||||
return super.exportXls(request, comment, Comment.class, "评论");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过excel导入数据
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("gen.comment:comment:importExcel")
|
||||
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||
return super.importExcel(request, response, Comment.class);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package org.jeecg.modules.gen.comment.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* @Description: 评论
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-16
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Data
|
||||
@TableName("comment")
|
||||
@Accessors(chain = true)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Schema(description="评论")
|
||||
public class Comment implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**主键*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
@Schema(description = "主键")
|
||||
private java.lang.String id;
|
||||
/**用户id*/
|
||||
@Excel(name = "用户id", width = 15)
|
||||
@Schema(description = "用户id")
|
||||
private java.lang.String userId;
|
||||
/**目标类型*/
|
||||
@Excel(name = "目标类型", width = 15)
|
||||
@Schema(description = "目标类型")
|
||||
private java.lang.String targetType;
|
||||
/**目标id*/
|
||||
@Excel(name = "目标id", width = 15)
|
||||
@Schema(description = "目标id")
|
||||
private java.lang.String targetId;
|
||||
/**内容*/
|
||||
@Excel(name = "内容", width = 15)
|
||||
@Schema(description = "内容")
|
||||
private java.lang.String content;
|
||||
/**图片*/
|
||||
@Excel(name = "图片", width = 15)
|
||||
@Schema(description = "图片")
|
||||
private java.lang.String imgs;
|
||||
/**是否置顶*/
|
||||
@Excel(name = "是否置顶", width = 15)
|
||||
@Schema(description = "是否置顶")
|
||||
private java.lang.Integer izTop;
|
||||
/**点赞数*/
|
||||
@Excel(name = "点赞数", width = 15)
|
||||
@Schema(description = "点赞数")
|
||||
private java.lang.Integer likeCount;
|
||||
/**创建人*/
|
||||
@Schema(description = "创建人")
|
||||
private java.lang.String createBy;
|
||||
/**创建日期*/
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
@Schema(description = "创建日期")
|
||||
private java.util.Date createTime;
|
||||
/**更新人*/
|
||||
@Schema(description = "更新人")
|
||||
private java.lang.String updateBy;
|
||||
/**更新日期*/
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
@Schema(description = "更新日期")
|
||||
private java.util.Date updateTime;
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package org.jeecg.modules.gen.comment.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.jeecg.modules.gen.comment.entity.Comment;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* @Description: 评论
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-16
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface CommentMapper extends BaseMapper<Comment> {
|
||||
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
<?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="org.jeecg.modules.gen.comment.mapper.CommentMapper">
|
||||
|
||||
</mapper>
|
@ -0,0 +1,14 @@
|
||||
package org.jeecg.modules.gen.comment.service;
|
||||
|
||||
import org.jeecg.modules.gen.comment.entity.Comment;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* @Description: 评论
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-16
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface ICommentService extends IService<Comment> {
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package org.jeecg.modules.gen.comment.service.impl;
|
||||
|
||||
import org.jeecg.modules.gen.comment.entity.Comment;
|
||||
import org.jeecg.modules.gen.comment.mapper.CommentMapper;
|
||||
import org.jeecg.modules.gen.comment.service.ICommentService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
||||
/**
|
||||
* @Description: 评论
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-16
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Service
|
||||
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements ICommentService {
|
||||
|
||||
}
|
@ -0,0 +1,182 @@
|
||||
package org.jeecg.modules.gen.contentconfig.controller;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.gen.contentconfig.entity.ContentConfig;
|
||||
import org.jeecg.modules.gen.contentconfig.service.IContentConfigService;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
/**
|
||||
* @Description: 内容配置
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-25
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Tag(name="内容配置")
|
||||
@RestController
|
||||
@RequestMapping("/gen/contentconfig/contentConfig")
|
||||
@Slf4j
|
||||
public class ContentConfigController extends JeecgController<ContentConfig, IContentConfigService> {
|
||||
@Autowired
|
||||
private IContentConfigService contentConfigService;
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
*
|
||||
* @param contentConfig
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
//@AutoLog(value = "内容配置-分页列表查询")
|
||||
@Operation(summary="内容配置-分页列表查询")
|
||||
@GetMapping(value = "/list")
|
||||
public Result<IPage<ContentConfig>> queryPageList(ContentConfig contentConfig,
|
||||
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||
HttpServletRequest req) {
|
||||
|
||||
|
||||
QueryWrapper<ContentConfig> queryWrapper = QueryGenerator.initQueryWrapper(contentConfig, req.getParameterMap());
|
||||
Page<ContentConfig> page = new Page<ContentConfig>(pageNo, pageSize);
|
||||
IPage<ContentConfig> pageList = contentConfigService.page(page, queryWrapper);
|
||||
return Result.OK(pageList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param contentConfig
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "内容配置-添加")
|
||||
@Operation(summary="内容配置-添加")
|
||||
@RequiresPermissions("gen.contentconfig:content_config:add")
|
||||
@PostMapping(value = "/add")
|
||||
public Result<String> add(@RequestBody ContentConfig contentConfig) {
|
||||
contentConfigService.save(contentConfig);
|
||||
|
||||
return Result.OK("添加成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*
|
||||
* @param contentConfig
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "内容配置-编辑")
|
||||
@Operation(summary="内容配置-编辑")
|
||||
@RequiresPermissions("gen.contentconfig:content_config:edit")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result<String> edit(@RequestBody ContentConfig contentConfig) {
|
||||
contentConfigService.updateById(contentConfig);
|
||||
return Result.OK("编辑成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "内容配置-通过id删除")
|
||||
@Operation(summary="内容配置-通过id删除")
|
||||
@RequiresPermissions("gen.contentconfig:content_config:delete")
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||
contentConfigService.removeById(id);
|
||||
return Result.OK("删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "内容配置-批量删除")
|
||||
@Operation(summary="内容配置-批量删除")
|
||||
@RequiresPermissions("gen.contentconfig:content_config:deleteBatch")
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||
this.contentConfigService.removeByIds(Arrays.asList(ids.split(",")));
|
||||
return Result.OK("批量删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
//@AutoLog(value = "内容配置-通过id查询")
|
||||
@Operation(summary="内容配置-通过id查询")
|
||||
@GetMapping(value = "/queryById")
|
||||
public Result<ContentConfig> queryById(@RequestParam(name="id",required=true) String id) {
|
||||
ContentConfig contentConfig = contentConfigService.getById(id);
|
||||
if(contentConfig==null) {
|
||||
return Result.error("未找到对应数据");
|
||||
}
|
||||
return Result.OK(contentConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
* @param contentConfig
|
||||
*/
|
||||
@RequiresPermissions("gen.contentconfig:content_config:exportXls")
|
||||
@RequestMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(HttpServletRequest request, ContentConfig contentConfig) {
|
||||
return super.exportXls(request, contentConfig, ContentConfig.class, "内容配置");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过excel导入数据
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("gen.contentconfig:content_config:importExcel")
|
||||
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||
return super.importExcel(request, response, ContentConfig.class);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package org.jeecg.modules.gen.contentconfig.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Date;
|
||||
import java.math.BigDecimal;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import org.jeecg.common.constant.ProvinceCityArea;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import lombok.Data;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
import org.jeecg.common.aspect.annotation.Dict;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* @Description: 内容配置
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-25
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Data
|
||||
@TableName("content_config")
|
||||
@Accessors(chain = true)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Schema(description="内容配置")
|
||||
public class ContentConfig implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**主键*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
@Schema(description = "主键")
|
||||
private java.lang.String id;
|
||||
/**配置标识*/
|
||||
@Excel(name = "配置标识", width = 15)
|
||||
@Schema(description = "配置标识")
|
||||
private java.lang.String contentKey;
|
||||
/**配置值*/
|
||||
@Excel(name = "配置值", width = 15)
|
||||
@Schema(description = "配置值")
|
||||
private java.lang.String contentValue;
|
||||
/**值类型*/
|
||||
@Excel(name = "值类型", width = 15)
|
||||
@Schema(description = "值类型")
|
||||
private java.lang.String valueType;
|
||||
/**描述*/
|
||||
@Excel(name = "描述", width = 15)
|
||||
@Schema(description = "描述")
|
||||
private java.lang.String description;
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package org.jeecg.modules.gen.contentconfig.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.jeecg.modules.gen.contentconfig.entity.ContentConfig;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* @Description: 内容配置
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-25
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface ContentConfigMapper extends BaseMapper<ContentConfig> {
|
||||
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
<?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="org.jeecg.modules.gen.contentconfig.mapper.ContentConfigMapper">
|
||||
|
||||
</mapper>
|
@ -0,0 +1,14 @@
|
||||
package org.jeecg.modules.gen.contentconfig.service;
|
||||
|
||||
import org.jeecg.modules.gen.contentconfig.entity.ContentConfig;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* @Description: 内容配置
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-25
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface IContentConfigService extends IService<ContentConfig> {
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package org.jeecg.modules.gen.contentconfig.service.impl;
|
||||
|
||||
import org.jeecg.modules.gen.contentconfig.entity.ContentConfig;
|
||||
import org.jeecg.modules.gen.contentconfig.mapper.ContentConfigMapper;
|
||||
import org.jeecg.modules.gen.contentconfig.service.IContentConfigService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
||||
/**
|
||||
* @Description: 内容配置
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-25
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Service
|
||||
public class ContentConfigServiceImpl extends ServiceImpl<ContentConfigMapper, ContentConfig> implements IContentConfigService {
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package org.jeecg.modules.learn.gen.controller;
|
||||
package org.jeecg.modules.gen.course.controller;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
@ -14,9 +14,8 @@ import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.config.shiro.IgnoreAuth;
|
||||
import org.jeecg.modules.learn.gen.entity.Course;
|
||||
import org.jeecg.modules.learn.gen.service.ICourseService;
|
||||
import org.jeecg.modules.gen.course.entity.Course;
|
||||
import org.jeecg.modules.gen.course.service.ICourseService;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
@ -40,19 +39,19 @@ import io.swagger.v3.oas.annotations.Operation;
|
||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
/**
|
||||
* @Description: 课程
|
||||
* @Description: 课程表
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-07
|
||||
* @Date: 2025-08-09
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Tag(name="课程")
|
||||
@RestController
|
||||
@RequestMapping("/gen/course")
|
||||
@RequestMapping("/gen/course/course")
|
||||
@Slf4j
|
||||
public class CourseController extends JeecgController<Course, ICourseService> {
|
||||
@Autowired
|
||||
private ICourseService courseService;
|
||||
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
*
|
||||
@ -62,8 +61,8 @@ public class CourseController extends JeecgController<Course, ICourseService> {
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
//@AutoLog(value = "课程-分页列表查询")
|
||||
@Operation(summary="课程-分页列表查询")
|
||||
//@AutoLog(value = "课程表-分页列表查询")
|
||||
@Operation(summary="课程表-分页列表查询")
|
||||
@GetMapping(value = "/list")
|
||||
public Result<IPage<Course>> queryPageList(Course course,
|
||||
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||
@ -71,11 +70,7 @@ public class CourseController extends JeecgController<Course, ICourseService> {
|
||||
HttpServletRequest req) {
|
||||
|
||||
|
||||
// 自定义查询规则
|
||||
Map<String, QueryRuleEnum> customeRuleMap = new HashMap<>();
|
||||
// 自定义多选的查询规则为:LIKE_WITH_OR
|
||||
customeRuleMap.put("categoryId", QueryRuleEnum.LIKE_WITH_OR);
|
||||
QueryWrapper<Course> queryWrapper = QueryGenerator.initQueryWrapper(course, req.getParameterMap(),customeRuleMap);
|
||||
QueryWrapper<Course> queryWrapper = QueryGenerator.initQueryWrapper(course, req.getParameterMap());
|
||||
Page<Course> page = new Page<Course>(pageNo, pageSize);
|
||||
IPage<Course> pageList = courseService.page(page, queryWrapper);
|
||||
return Result.OK(pageList);
|
||||
@ -89,9 +84,14 @@ public class CourseController extends JeecgController<Course, ICourseService> {
|
||||
*/
|
||||
@AutoLog(value = "课程-添加")
|
||||
@Operation(summary="课程-添加")
|
||||
@RequiresPermissions("gen:course:add")
|
||||
@RequiresPermissions("gen.course:course:add")
|
||||
@PostMapping(value = "/add")
|
||||
public Result<String> add(@RequestBody Course course) {
|
||||
// 判断开始时间是否晚于结束时间
|
||||
if (course.getStartTime().after(course.getEndTime())) {
|
||||
return Result.error("开始时间不能晚于结束时间");
|
||||
}
|
||||
|
||||
courseService.save(course);
|
||||
|
||||
return Result.OK("添加成功!");
|
||||
@ -105,9 +105,15 @@ public class CourseController extends JeecgController<Course, ICourseService> {
|
||||
*/
|
||||
@AutoLog(value = "课程-编辑")
|
||||
@Operation(summary="课程-编辑")
|
||||
@RequiresPermissions("gen:course:edit")
|
||||
@RequiresPermissions("gen.course:course:edit")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result<String> edit(@RequestBody Course course) {
|
||||
|
||||
// 判断开始时间是否晚于结束时间
|
||||
if (course.getStartTime().after(course.getEndTime())) {
|
||||
return Result.error("开始时间不能晚于结束时间");
|
||||
}
|
||||
|
||||
courseService.updateById(course);
|
||||
return Result.OK("编辑成功!");
|
||||
}
|
||||
@ -120,7 +126,7 @@ public class CourseController extends JeecgController<Course, ICourseService> {
|
||||
*/
|
||||
@AutoLog(value = "课程-通过id删除")
|
||||
@Operation(summary="课程-通过id删除")
|
||||
@RequiresPermissions("gen:course:delete")
|
||||
@RequiresPermissions("gen.course:course:delete")
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||
courseService.removeById(id);
|
||||
@ -133,9 +139,9 @@ public class CourseController extends JeecgController<Course, ICourseService> {
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "课程-批量删除")
|
||||
@Operation(summary="课程-批量删除")
|
||||
@RequiresPermissions("gen:course:deleteBatch")
|
||||
@AutoLog(value = "课程表-批量删除")
|
||||
@Operation(summary="课程表-批量删除")
|
||||
@RequiresPermissions("gen.course:course:deleteBatch")
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||
this.courseService.removeByIds(Arrays.asList(ids.split(",")));
|
||||
@ -148,8 +154,8 @@ public class CourseController extends JeecgController<Course, ICourseService> {
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
//@AutoLog(value = "课程-通过id查询")
|
||||
@Operation(summary="课程-通过id查询")
|
||||
//@AutoLog(value = "课程表-通过id查询")
|
||||
@Operation(summary="课程表-通过id查询")
|
||||
@GetMapping(value = "/queryById")
|
||||
public Result<Course> queryById(@RequestParam(name="id",required=true) String id) {
|
||||
Course course = courseService.getById(id);
|
||||
@ -165,10 +171,10 @@ public class CourseController extends JeecgController<Course, ICourseService> {
|
||||
* @param request
|
||||
* @param course
|
||||
*/
|
||||
@RequiresPermissions("gen:course:exportXls")
|
||||
@RequiresPermissions("gen.course:course:exportXls")
|
||||
@RequestMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(HttpServletRequest request, Course course) {
|
||||
return super.exportXls(request, course, Course.class, "课程");
|
||||
return super.exportXls(request, course, Course.class, "课程表");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -178,7 +184,7 @@ public class CourseController extends JeecgController<Course, ICourseService> {
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("gen:course:importExcel")
|
||||
@RequiresPermissions("gen.course:course:importExcel")
|
||||
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||
return super.importExcel(request, response, Course.class);
|
@ -0,0 +1,140 @@
|
||||
package org.jeecg.modules.gen.course.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Date;
|
||||
import java.math.BigDecimal;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import org.jeecg.common.constant.ProvinceCityArea;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import lombok.Data;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
import org.jeecg.common.aspect.annotation.Dict;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* @Description: 课程表
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-09
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Data
|
||||
@TableName("course")
|
||||
@Accessors(chain = true)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Schema(description="课程表")
|
||||
public class Course implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**主键*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
@Schema(description = "主键")
|
||||
private java.lang.String id;
|
||||
/**课程名*/
|
||||
@Excel(name = "课程名", width = 15)
|
||||
@Schema(description = "课程名")
|
||||
private java.lang.String name;
|
||||
/**封面图*/
|
||||
@Excel(name = "封面图", width = 15)
|
||||
@Schema(description = "封面图")
|
||||
private java.lang.String cover;
|
||||
/**介绍视频*/
|
||||
@Excel(name = "介绍视频", width = 15)
|
||||
@Schema(description = "介绍视频")
|
||||
private java.lang.String video;
|
||||
/**学校*/
|
||||
@Excel(name = "学校", width = 15)
|
||||
@Schema(description = "学校")
|
||||
private java.lang.String school;
|
||||
/**课程概述*/
|
||||
@Excel(name = "课程概述", width = 15)
|
||||
@Schema(description = "课程概述")
|
||||
private java.lang.String description;
|
||||
/**课程类型*/
|
||||
@Excel(name = "课程类型", width = 15, dicCode = "course_type")
|
||||
@Dict(dicCode = "course_type")
|
||||
@Schema(description = "课程类型")
|
||||
private java.lang.Integer type;
|
||||
/**授课目标*/
|
||||
@Excel(name = "授课目标", width = 15)
|
||||
@Schema(description = "授课目标")
|
||||
private java.lang.String target;
|
||||
/**课程难度*/
|
||||
@Excel(name = "课程难度", width = 15, dicCode = "course_difficulty")
|
||||
@Dict(dicCode = "course_difficulty")
|
||||
@Schema(description = "课程难度")
|
||||
private java.lang.Integer difficulty;
|
||||
/**所属专题*/
|
||||
@Excel(name = "所属专题", width = 15, dicCode = "course_subject")
|
||||
@Dict(dicCode = "course_subject")
|
||||
@Schema(description = "所属专题")
|
||||
private java.lang.String subject;
|
||||
/**课程大纲*/
|
||||
@Excel(name = "课程大纲", width = 15)
|
||||
@Schema(description = "课程大纲")
|
||||
private java.lang.String outline;
|
||||
/**预备知识*/
|
||||
@Excel(name = "预备知识", width = 15)
|
||||
@Schema(description = "预备知识")
|
||||
private java.lang.String prerequisite;
|
||||
/**参考资料*/
|
||||
@Excel(name = "参考资料", width = 15)
|
||||
@Schema(description = "参考资料")
|
||||
private java.lang.String reference;
|
||||
/**学时安排*/
|
||||
@Excel(name = "学时安排", width = 15)
|
||||
@Schema(description = "学时安排")
|
||||
private java.lang.String arrangement;
|
||||
/**开课时间*/
|
||||
@Excel(name = "开课时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
@Schema(description = "开课时间")
|
||||
private java.util.Date startTime;
|
||||
/**结课时间*/
|
||||
@Excel(name = "结课时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
@Schema(description = "结课时间")
|
||||
private java.util.Date endTime;
|
||||
/**已报名人数*/
|
||||
@Excel(name = "已报名人数", width = 15)
|
||||
@Schema(description = "已报名人数")
|
||||
private java.lang.Integer enrollCount;
|
||||
/**最大报名人数*/
|
||||
@Excel(name = "最大报名人数", width = 15)
|
||||
@Schema(description = "最大报名人数")
|
||||
private java.lang.Integer maxEnroll;
|
||||
/**状态*/
|
||||
@Excel(name = "状态", width = 15, dicCode = "course_status")
|
||||
@Dict(dicCode = "course_status")
|
||||
@Schema(description = "状态")
|
||||
private java.lang.Integer status;
|
||||
/**常见问题*/
|
||||
@Excel(name = "常见问题", width = 15)
|
||||
@Schema(description = "常见问题")
|
||||
private java.lang.String question;
|
||||
/**创建人*/
|
||||
@Schema(description = "创建人")
|
||||
private java.lang.String createBy;
|
||||
/**创建时间*/
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
@Schema(description = "创建时间")
|
||||
private java.util.Date createTime;
|
||||
/**更新人*/
|
||||
@Schema(description = "更新人")
|
||||
private java.lang.String updateBy;
|
||||
/**更新时间*/
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
@Schema(description = "更新时间")
|
||||
private java.util.Date updateTime;
|
||||
}
|
@ -1,15 +1,15 @@
|
||||
package org.jeecg.modules.learn.gen.mapper;
|
||||
package org.jeecg.modules.gen.course.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.jeecg.modules.learn.gen.entity.Course;
|
||||
import org.jeecg.modules.gen.course.entity.Course;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* @Description: 课程
|
||||
* @Description: 课程表
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-07
|
||||
* @Date: 2025-08-09
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface CourseMapper extends BaseMapper<Course> {
|
@ -0,0 +1,5 @@
|
||||
<?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="org.jeecg.modules.gen.course.mapper.CourseMapper">
|
||||
|
||||
</mapper>
|
@ -1,12 +1,12 @@
|
||||
package org.jeecg.modules.learn.gen.service;
|
||||
package org.jeecg.modules.gen.course.service;
|
||||
|
||||
import org.jeecg.modules.learn.gen.entity.Course;
|
||||
import org.jeecg.modules.gen.course.entity.Course;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* @Description: 课程
|
||||
* @Description: 课程表
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-07
|
||||
* @Date: 2025-08-09
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface ICourseService extends IService<Course> {
|
@ -1,16 +1,16 @@
|
||||
package org.jeecg.modules.learn.gen.service.impl;
|
||||
package org.jeecg.modules.gen.course.service.impl;
|
||||
|
||||
import org.jeecg.modules.learn.gen.entity.Course;
|
||||
import org.jeecg.modules.learn.gen.mapper.CourseMapper;
|
||||
import org.jeecg.modules.learn.gen.service.ICourseService;
|
||||
import org.jeecg.modules.gen.course.entity.Course;
|
||||
import org.jeecg.modules.gen.course.mapper.CourseMapper;
|
||||
import org.jeecg.modules.gen.course.service.ICourseService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
||||
/**
|
||||
* @Description: 课程
|
||||
* @Description: 课程表
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-07
|
||||
* @Date: 2025-08-09
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Service
|
@ -0,0 +1,182 @@
|
||||
package org.jeecg.modules.gen.coursecategory.controller;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.gen.coursecategory.entity.CourseCategory;
|
||||
import org.jeecg.modules.gen.coursecategory.service.ICourseCategoryService;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
/**
|
||||
* @Description: 课程分类表
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-09
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Tag(name="课程分类表")
|
||||
@RestController
|
||||
@RequestMapping("/gen/coursecategory/courseCategory")
|
||||
@Slf4j
|
||||
public class CourseCategoryController extends JeecgController<CourseCategory, ICourseCategoryService> {
|
||||
@Autowired
|
||||
private ICourseCategoryService courseCategoryService;
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
*
|
||||
* @param courseCategory
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
//@AutoLog(value = "课程分类表-分页列表查询")
|
||||
@Operation(summary="课程分类表-分页列表查询")
|
||||
@GetMapping(value = "/list")
|
||||
public Result<IPage<CourseCategory>> queryPageList(CourseCategory courseCategory,
|
||||
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||
HttpServletRequest req) {
|
||||
|
||||
|
||||
QueryWrapper<CourseCategory> queryWrapper = QueryGenerator.initQueryWrapper(courseCategory, req.getParameterMap());
|
||||
Page<CourseCategory> page = new Page<CourseCategory>(pageNo, pageSize);
|
||||
IPage<CourseCategory> pageList = courseCategoryService.page(page, queryWrapper);
|
||||
return Result.OK(pageList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param courseCategory
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "课程分类表-添加")
|
||||
@Operation(summary="课程分类表-添加")
|
||||
@RequiresPermissions("gen.coursecategory:course_category:add")
|
||||
@PostMapping(value = "/add")
|
||||
public Result<String> add(@RequestBody CourseCategory courseCategory) {
|
||||
courseCategoryService.save(courseCategory);
|
||||
|
||||
return Result.OK("添加成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*
|
||||
* @param courseCategory
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "课程分类表-编辑")
|
||||
@Operation(summary="课程分类表-编辑")
|
||||
@RequiresPermissions("gen.coursecategory:course_category:edit")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result<String> edit(@RequestBody CourseCategory courseCategory) {
|
||||
courseCategoryService.updateById(courseCategory);
|
||||
return Result.OK("编辑成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "课程分类表-通过id删除")
|
||||
@Operation(summary="课程分类表-通过id删除")
|
||||
@RequiresPermissions("gen.coursecategory:course_category:delete")
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||
courseCategoryService.removeById(id);
|
||||
return Result.OK("删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "课程分类表-批量删除")
|
||||
@Operation(summary="课程分类表-批量删除")
|
||||
@RequiresPermissions("gen.coursecategory:course_category:deleteBatch")
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||
this.courseCategoryService.removeByIds(Arrays.asList(ids.split(",")));
|
||||
return Result.OK("批量删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
//@AutoLog(value = "课程分类表-通过id查询")
|
||||
@Operation(summary="课程分类表-通过id查询")
|
||||
@GetMapping(value = "/queryById")
|
||||
public Result<CourseCategory> queryById(@RequestParam(name="id",required=true) String id) {
|
||||
CourseCategory courseCategory = courseCategoryService.getById(id);
|
||||
if(courseCategory==null) {
|
||||
return Result.error("未找到对应数据");
|
||||
}
|
||||
return Result.OK(courseCategory);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
* @param courseCategory
|
||||
*/
|
||||
@RequiresPermissions("gen.coursecategory:course_category:exportXls")
|
||||
@RequestMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(HttpServletRequest request, CourseCategory courseCategory) {
|
||||
return super.exportXls(request, courseCategory, CourseCategory.class, "课程分类表");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过excel导入数据
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("gen.coursecategory:course_category:importExcel")
|
||||
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||
return super.importExcel(request, response, CourseCategory.class);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package org.jeecg.modules.gen.coursecategory.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Date;
|
||||
import java.math.BigDecimal;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import org.jeecg.common.constant.ProvinceCityArea;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import lombok.Data;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
import org.jeecg.common.aspect.annotation.Dict;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* @Description: 课程分类表
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-09
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Data
|
||||
@TableName("course_category")
|
||||
@Accessors(chain = true)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Schema(description="课程分类表")
|
||||
public class CourseCategory implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**主键*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
@Schema(description = "主键")
|
||||
private java.lang.String id;
|
||||
/**分类名*/
|
||||
@Excel(name = "分类名", width = 15)
|
||||
@Schema(description = "分类名")
|
||||
private java.lang.String name;
|
||||
/**排序*/
|
||||
@Excel(name = "排序", width = 15)
|
||||
@Schema(description = "排序")
|
||||
private java.lang.Integer sortOrder;
|
||||
/**创建人*/
|
||||
@Schema(description = "创建人")
|
||||
private java.lang.String createBy;
|
||||
/**创建时间*/
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
@Schema(description = "创建时间")
|
||||
private java.util.Date createTime;
|
||||
/**更新人*/
|
||||
@Schema(description = "更新人")
|
||||
private java.lang.String updateBy;
|
||||
/**更新时间*/
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
@Schema(description = "更新时间")
|
||||
private java.util.Date updateTime;
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package org.jeecg.modules.gen.coursecategory.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.jeecg.modules.gen.coursecategory.entity.CourseCategory;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* @Description: 课程分类表
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-09
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface CourseCategoryMapper extends BaseMapper<CourseCategory> {
|
||||
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
<?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="org.jeecg.modules.gen.coursecategory.mapper.CourseCategoryMapper">
|
||||
|
||||
</mapper>
|
@ -0,0 +1,14 @@
|
||||
package org.jeecg.modules.gen.coursecategory.service;
|
||||
|
||||
import org.jeecg.modules.gen.coursecategory.entity.CourseCategory;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* @Description: 课程分类表
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-09
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface ICourseCategoryService extends IService<CourseCategory> {
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package org.jeecg.modules.gen.coursecategory.service.impl;
|
||||
|
||||
import org.jeecg.modules.gen.coursecategory.entity.CourseCategory;
|
||||
import org.jeecg.modules.gen.coursecategory.mapper.CourseCategoryMapper;
|
||||
import org.jeecg.modules.gen.coursecategory.service.ICourseCategoryService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
||||
/**
|
||||
* @Description: 课程分类表
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-09
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Service
|
||||
public class CourseCategoryServiceImpl extends ServiceImpl<CourseCategoryMapper, CourseCategory> implements ICourseCategoryService {
|
||||
|
||||
}
|
@ -0,0 +1,182 @@
|
||||
package org.jeecg.modules.gen.coursesection.controller;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.gen.coursesection.entity.CourseSection;
|
||||
import org.jeecg.modules.gen.coursesection.service.ICourseSectionService;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
/**
|
||||
* @Description: 课程章节
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-16
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Tag(name="课程章节")
|
||||
@RestController
|
||||
@RequestMapping("/gen/coursesection/courseSection")
|
||||
@Slf4j
|
||||
public class CourseSectionController extends JeecgController<CourseSection, ICourseSectionService> {
|
||||
@Autowired
|
||||
private ICourseSectionService courseSectionService;
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
*
|
||||
* @param courseSection
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
//@AutoLog(value = "课程章节-分页列表查询")
|
||||
@Operation(summary="课程章节-分页列表查询")
|
||||
@GetMapping(value = "/list")
|
||||
public Result<IPage<CourseSection>> queryPageList(CourseSection courseSection,
|
||||
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||
HttpServletRequest req) {
|
||||
|
||||
|
||||
QueryWrapper<CourseSection> queryWrapper = QueryGenerator.initQueryWrapper(courseSection, req.getParameterMap());
|
||||
Page<CourseSection> page = new Page<CourseSection>(pageNo, pageSize);
|
||||
IPage<CourseSection> pageList = courseSectionService.page(page, queryWrapper);
|
||||
return Result.OK(pageList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param courseSection
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "课程章节-添加")
|
||||
@Operation(summary="课程章节-添加")
|
||||
@RequiresPermissions("gen.coursesection:course_section:add")
|
||||
@PostMapping(value = "/add")
|
||||
public Result<String> add(@RequestBody CourseSection courseSection) {
|
||||
courseSectionService.save(courseSection);
|
||||
|
||||
return Result.OK("添加成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*
|
||||
* @param courseSection
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "课程章节-编辑")
|
||||
@Operation(summary="课程章节-编辑")
|
||||
@RequiresPermissions("gen.coursesection:course_section:edit")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result<String> edit(@RequestBody CourseSection courseSection) {
|
||||
courseSectionService.updateById(courseSection);
|
||||
return Result.OK("编辑成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "课程章节-通过id删除")
|
||||
@Operation(summary="课程章节-通过id删除")
|
||||
@RequiresPermissions("gen.coursesection:course_section:delete")
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||
courseSectionService.removeById(id);
|
||||
return Result.OK("删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "课程章节-批量删除")
|
||||
@Operation(summary="课程章节-批量删除")
|
||||
@RequiresPermissions("gen.coursesection:course_section:deleteBatch")
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||
this.courseSectionService.removeByIds(Arrays.asList(ids.split(",")));
|
||||
return Result.OK("批量删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
//@AutoLog(value = "课程章节-通过id查询")
|
||||
@Operation(summary="课程章节-通过id查询")
|
||||
@GetMapping(value = "/queryById")
|
||||
public Result<CourseSection> queryById(@RequestParam(name="id",required=true) String id) {
|
||||
CourseSection courseSection = courseSectionService.getById(id);
|
||||
if(courseSection==null) {
|
||||
return Result.error("未找到对应数据");
|
||||
}
|
||||
return Result.OK(courseSection);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
* @param courseSection
|
||||
*/
|
||||
@RequiresPermissions("gen.coursesection:course_section:exportXls")
|
||||
@RequestMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(HttpServletRequest request, CourseSection courseSection) {
|
||||
return super.exportXls(request, courseSection, CourseSection.class, "课程章节");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过excel导入数据
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("gen.coursesection:course_section:importExcel")
|
||||
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||
return super.importExcel(request, response, CourseSection.class);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package org.jeecg.modules.gen.coursesection.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Date;
|
||||
import java.math.BigDecimal;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import org.jeecg.common.constant.ProvinceCityArea;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import lombok.Data;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
import org.jeecg.common.aspect.annotation.Dict;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* @Description: 课程章节
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-16
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Data
|
||||
@TableName("course_section")
|
||||
@Accessors(chain = true)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Schema(description="课程章节")
|
||||
public class CourseSection implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**主键*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
@Schema(description = "主键")
|
||||
private java.lang.String id;
|
||||
/**课程id*/
|
||||
@Excel(name = "课程id", width = 15)
|
||||
@Schema(description = "课程id")
|
||||
private java.lang.String courseId;
|
||||
/**章节名*/
|
||||
@Excel(name = "章节名", width = 15)
|
||||
@Schema(description = "章节名")
|
||||
private java.lang.String name;
|
||||
/**章节类型*/
|
||||
@Excel(name = "章节类型", width = 15, dicCode = "course_section_type")
|
||||
@Dict(dicCode = "course_section_type")
|
||||
@Schema(description = "章节类型")
|
||||
private java.lang.Integer type;
|
||||
/**排序号*/
|
||||
@Excel(name = "排序号", width = 15)
|
||||
@Schema(description = "排序号")
|
||||
private java.lang.Integer sortOrder;
|
||||
/**父章节id*/
|
||||
@Excel(name = "父章节id", width = 15)
|
||||
@Schema(description = "父章节id")
|
||||
private java.lang.String parentId;
|
||||
/**章节层级*/
|
||||
@Excel(name = "章节层级", width = 15, dicCode = "course_section_level")
|
||||
@Dict(dicCode = "course_section_level")
|
||||
@Schema(description = "章节层级")
|
||||
private java.lang.Integer level;
|
||||
/**创建人*/
|
||||
@Schema(description = "创建人")
|
||||
private java.lang.String createBy;
|
||||
/**创建日期*/
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
@Schema(description = "创建日期")
|
||||
private java.util.Date createTime;
|
||||
/**更新人*/
|
||||
@Schema(description = "更新人")
|
||||
private java.lang.String updateBy;
|
||||
/**更新日期*/
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
@Schema(description = "更新日期")
|
||||
private java.util.Date updateTime;
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package org.jeecg.modules.gen.coursesection.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.jeecg.modules.gen.coursesection.entity.CourseSection;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* @Description: 课程章节
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-16
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface CourseSectionMapper extends BaseMapper<CourseSection> {
|
||||
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
<?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="org.jeecg.modules.gen.coursesection.mapper.CourseSectionMapper">
|
||||
|
||||
</mapper>
|
@ -0,0 +1,14 @@
|
||||
package org.jeecg.modules.gen.coursesection.service;
|
||||
|
||||
import org.jeecg.modules.gen.coursesection.entity.CourseSection;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* @Description: 课程章节
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-16
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface ICourseSectionService extends IService<CourseSection> {
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package org.jeecg.modules.gen.coursesection.service.impl;
|
||||
|
||||
import org.jeecg.modules.gen.coursesection.entity.CourseSection;
|
||||
import org.jeecg.modules.gen.coursesection.mapper.CourseSectionMapper;
|
||||
import org.jeecg.modules.gen.coursesection.service.ICourseSectionService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
||||
/**
|
||||
* @Description: 课程章节
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-16
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Service
|
||||
public class CourseSectionServiceImpl extends ServiceImpl<CourseSectionMapper, CourseSection> implements ICourseSectionService {
|
||||
|
||||
}
|
@ -0,0 +1,182 @@
|
||||
package org.jeecg.modules.gen.coursesignup.controller;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.gen.coursesignup.entity.CourseSignup;
|
||||
import org.jeecg.modules.gen.coursesignup.service.ICourseSignupService;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
/**
|
||||
* @Description: 课程报名
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-19
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Tag(name="课程报名")
|
||||
@RestController
|
||||
@RequestMapping("/gen/coursesignup/courseSignup")
|
||||
@Slf4j
|
||||
public class CourseSignupController extends JeecgController<CourseSignup, ICourseSignupService> {
|
||||
@Autowired
|
||||
private ICourseSignupService courseSignupService;
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
*
|
||||
* @param courseSignup
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
//@AutoLog(value = "课程报名-分页列表查询")
|
||||
@Operation(summary="课程报名-分页列表查询")
|
||||
@GetMapping(value = "/list")
|
||||
public Result<IPage<CourseSignup>> queryPageList(CourseSignup courseSignup,
|
||||
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||
HttpServletRequest req) {
|
||||
|
||||
|
||||
QueryWrapper<CourseSignup> queryWrapper = QueryGenerator.initQueryWrapper(courseSignup, req.getParameterMap());
|
||||
Page<CourseSignup> page = new Page<CourseSignup>(pageNo, pageSize);
|
||||
IPage<CourseSignup> pageList = courseSignupService.page(page, queryWrapper);
|
||||
return Result.OK(pageList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param courseSignup
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "课程报名-添加")
|
||||
@Operation(summary="课程报名-添加")
|
||||
@RequiresPermissions("gen.coursesignup:course_signup:add")
|
||||
@PostMapping(value = "/add")
|
||||
public Result<String> add(@RequestBody CourseSignup courseSignup) {
|
||||
courseSignupService.save(courseSignup);
|
||||
|
||||
return Result.OK("添加成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*
|
||||
* @param courseSignup
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "课程报名-编辑")
|
||||
@Operation(summary="课程报名-编辑")
|
||||
@RequiresPermissions("gen.coursesignup:course_signup:edit")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result<String> edit(@RequestBody CourseSignup courseSignup) {
|
||||
courseSignupService.updateById(courseSignup);
|
||||
return Result.OK("编辑成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "课程报名-通过id删除")
|
||||
@Operation(summary="课程报名-通过id删除")
|
||||
@RequiresPermissions("gen.coursesignup:course_signup:delete")
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||
courseSignupService.removeById(id);
|
||||
return Result.OK("删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "课程报名-批量删除")
|
||||
@Operation(summary="课程报名-批量删除")
|
||||
@RequiresPermissions("gen.coursesignup:course_signup:deleteBatch")
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||
this.courseSignupService.removeByIds(Arrays.asList(ids.split(",")));
|
||||
return Result.OK("批量删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
//@AutoLog(value = "课程报名-通过id查询")
|
||||
@Operation(summary="课程报名-通过id查询")
|
||||
@GetMapping(value = "/queryById")
|
||||
public Result<CourseSignup> queryById(@RequestParam(name="id",required=true) String id) {
|
||||
CourseSignup courseSignup = courseSignupService.getById(id);
|
||||
if(courseSignup==null) {
|
||||
return Result.error("未找到对应数据");
|
||||
}
|
||||
return Result.OK(courseSignup);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
* @param courseSignup
|
||||
*/
|
||||
@RequiresPermissions("gen.coursesignup:course_signup:exportXls")
|
||||
@RequestMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(HttpServletRequest request, CourseSignup courseSignup) {
|
||||
return super.exportXls(request, courseSignup, CourseSignup.class, "课程报名");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过excel导入数据
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("gen.coursesignup:course_signup:importExcel")
|
||||
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||
return super.importExcel(request, response, CourseSignup.class);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package org.jeecg.modules.gen.coursesignup.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Date;
|
||||
import java.math.BigDecimal;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import org.jeecg.common.constant.ProvinceCityArea;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import lombok.Data;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
import org.jeecg.common.aspect.annotation.Dict;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* @Description: 课程报名
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-19
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Data
|
||||
@TableName("course_signup")
|
||||
@Accessors(chain = true)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Schema(description="课程报名")
|
||||
public class CourseSignup implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**主键*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
@Schema(description = "主键")
|
||||
private java.lang.String id;
|
||||
/**用户id*/
|
||||
@Excel(name = "用户id", width = 15)
|
||||
@Schema(description = "用户id")
|
||||
private java.lang.String userId;
|
||||
/**课程id*/
|
||||
@Excel(name = "课程id", width = 15)
|
||||
@Schema(description = "课程id")
|
||||
private java.lang.String courseId;
|
||||
/**创建人*/
|
||||
@Schema(description = "创建人")
|
||||
private java.lang.String createBy;
|
||||
/**创建日期*/
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
@Schema(description = "创建日期")
|
||||
private java.util.Date createTime;
|
||||
/**更新人*/
|
||||
@Schema(description = "更新人")
|
||||
private java.lang.String updateBy;
|
||||
/**更新日期*/
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
@Schema(description = "更新日期")
|
||||
private java.util.Date updateTime;
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package org.jeecg.modules.gen.coursesignup.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.jeecg.modules.gen.coursesignup.entity.CourseSignup;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* @Description: 课程报名
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-19
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface CourseSignupMapper extends BaseMapper<CourseSignup> {
|
||||
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
<?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="org.jeecg.modules.gen.coursesignup.mapper.CourseSignupMapper">
|
||||
|
||||
</mapper>
|
@ -0,0 +1,14 @@
|
||||
package org.jeecg.modules.gen.coursesignup.service;
|
||||
|
||||
import org.jeecg.modules.gen.coursesignup.entity.CourseSignup;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* @Description: 课程报名
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-19
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface ICourseSignupService extends IService<CourseSignup> {
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package org.jeecg.modules.gen.coursesignup.service.impl;
|
||||
|
||||
import org.jeecg.modules.gen.coursesignup.entity.CourseSignup;
|
||||
import org.jeecg.modules.gen.coursesignup.mapper.CourseSignupMapper;
|
||||
import org.jeecg.modules.gen.coursesignup.service.ICourseSignupService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
||||
/**
|
||||
* @Description: 课程报名
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-19
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Service
|
||||
public class CourseSignupServiceImpl extends ServiceImpl<CourseSignupMapper, CourseSignup> implements ICourseSignupService {
|
||||
|
||||
}
|
@ -0,0 +1,182 @@
|
||||
package org.jeecg.modules.gen.courseteacher.controller;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.gen.courseteacher.entity.CourseTeacher;
|
||||
import org.jeecg.modules.gen.courseteacher.service.ICourseTeacherService;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
/**
|
||||
* @Description: 授课教师
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-14
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Tag(name="授课教师")
|
||||
@RestController
|
||||
@RequestMapping("/gen/courseteacher/courseTeacher")
|
||||
@Slf4j
|
||||
public class CourseTeacherController extends JeecgController<CourseTeacher, ICourseTeacherService> {
|
||||
@Autowired
|
||||
private ICourseTeacherService courseTeacherService;
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
*
|
||||
* @param courseTeacher
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
//@AutoLog(value = "授课教师-分页列表查询")
|
||||
@Operation(summary="授课教师-分页列表查询")
|
||||
@GetMapping(value = "/list")
|
||||
public Result<IPage<CourseTeacher>> queryPageList(CourseTeacher courseTeacher,
|
||||
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||
HttpServletRequest req) {
|
||||
|
||||
|
||||
QueryWrapper<CourseTeacher> queryWrapper = QueryGenerator.initQueryWrapper(courseTeacher, req.getParameterMap());
|
||||
Page<CourseTeacher> page = new Page<CourseTeacher>(pageNo, pageSize);
|
||||
IPage<CourseTeacher> pageList = courseTeacherService.page(page, queryWrapper);
|
||||
return Result.OK(pageList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param courseTeacher
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "授课教师-添加")
|
||||
@Operation(summary="授课教师-添加")
|
||||
@RequiresPermissions("gen.courseteacher:course_teacher:add")
|
||||
@PostMapping(value = "/add")
|
||||
public Result<String> add(@RequestBody CourseTeacher courseTeacher) {
|
||||
courseTeacherService.save(courseTeacher);
|
||||
|
||||
return Result.OK("添加成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*
|
||||
* @param courseTeacher
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "授课教师-编辑")
|
||||
@Operation(summary="授课教师-编辑")
|
||||
@RequiresPermissions("gen.courseteacher:course_teacher:edit")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result<String> edit(@RequestBody CourseTeacher courseTeacher) {
|
||||
courseTeacherService.updateById(courseTeacher);
|
||||
return Result.OK("编辑成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "授课教师-通过id删除")
|
||||
@Operation(summary="授课教师-通过id删除")
|
||||
@RequiresPermissions("gen.courseteacher:course_teacher:delete")
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||
courseTeacherService.removeById(id);
|
||||
return Result.OK("删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "授课教师-批量删除")
|
||||
@Operation(summary="授课教师-批量删除")
|
||||
@RequiresPermissions("gen.courseteacher:course_teacher:deleteBatch")
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||
this.courseTeacherService.removeByIds(Arrays.asList(ids.split(",")));
|
||||
return Result.OK("批量删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
//@AutoLog(value = "授课教师-通过id查询")
|
||||
@Operation(summary="授课教师-通过id查询")
|
||||
@GetMapping(value = "/queryById")
|
||||
public Result<CourseTeacher> queryById(@RequestParam(name="id",required=true) String id) {
|
||||
CourseTeacher courseTeacher = courseTeacherService.getById(id);
|
||||
if(courseTeacher==null) {
|
||||
return Result.error("未找到对应数据");
|
||||
}
|
||||
return Result.OK(courseTeacher);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
* @param courseTeacher
|
||||
*/
|
||||
@RequiresPermissions("gen.courseteacher:course_teacher:exportXls")
|
||||
@RequestMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(HttpServletRequest request, CourseTeacher courseTeacher) {
|
||||
return super.exportXls(request, courseTeacher, CourseTeacher.class, "授课教师");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过excel导入数据
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("gen.courseteacher:course_teacher:importExcel")
|
||||
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||
return super.importExcel(request, response, CourseTeacher.class);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
package org.jeecg.modules.gen.courseteacher.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Date;
|
||||
import java.math.BigDecimal;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import org.jeecg.common.constant.ProvinceCityArea;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import lombok.Data;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
import org.jeecg.common.aspect.annotation.Dict;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* @Description: 授课教师
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-14
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Data
|
||||
@TableName("course_teacher")
|
||||
@Accessors(chain = true)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Schema(description="授课教师")
|
||||
public class CourseTeacher implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**主键*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
@Schema(description = "主键")
|
||||
private java.lang.String id;
|
||||
/**课程id*/
|
||||
@Excel(name = "课程id", width = 15)
|
||||
@Schema(description = "课程id")
|
||||
private java.lang.String courseId;
|
||||
/**教师id*/
|
||||
@Excel(name = "教师id", width = 15)
|
||||
@Schema(description = "教师id")
|
||||
private java.lang.String teacherId;
|
||||
/**授课角色*/
|
||||
@Excel(name = "授课角色", width = 15, dicCode = "course_role")
|
||||
@Dict(dicCode = "course_role")
|
||||
@Schema(description = "授课角色")
|
||||
private java.lang.String role;
|
||||
/**显示顺序*/
|
||||
@Excel(name = "显示顺序", width = 15)
|
||||
@Schema(description = "显示顺序")
|
||||
private java.lang.Integer sortOrder;
|
||||
/**创建人*/
|
||||
@Schema(description = "创建人")
|
||||
private java.lang.String createBy;
|
||||
/**创建日期*/
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
@Schema(description = "创建日期")
|
||||
private java.util.Date createTime;
|
||||
/**更新人*/
|
||||
@Schema(description = "更新人")
|
||||
private java.lang.String updateBy;
|
||||
/**更新日期*/
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
@Schema(description = "更新日期")
|
||||
private java.util.Date updateTime;
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package org.jeecg.modules.gen.courseteacher.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.jeecg.modules.gen.courseteacher.entity.CourseTeacher;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* @Description: 授课教师
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-14
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface CourseTeacherMapper extends BaseMapper<CourseTeacher> {
|
||||
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
<?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="org.jeecg.modules.gen.courseteacher.mapper.CourseTeacherMapper">
|
||||
|
||||
</mapper>
|
@ -0,0 +1,14 @@
|
||||
package org.jeecg.modules.gen.courseteacher.service;
|
||||
|
||||
import org.jeecg.modules.gen.courseteacher.entity.CourseTeacher;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* @Description: 授课教师
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-14
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface ICourseTeacherService extends IService<CourseTeacher> {
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package org.jeecg.modules.gen.courseteacher.service.impl;
|
||||
|
||||
import org.jeecg.modules.gen.courseteacher.entity.CourseTeacher;
|
||||
import org.jeecg.modules.gen.courseteacher.mapper.CourseTeacherMapper;
|
||||
import org.jeecg.modules.gen.courseteacher.service.ICourseTeacherService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
||||
/**
|
||||
* @Description: 授课教师
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-14
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Service
|
||||
public class CourseTeacherServiceImpl extends ServiceImpl<CourseTeacherMapper, CourseTeacher> implements ICourseTeacherService {
|
||||
|
||||
}
|
@ -0,0 +1,182 @@
|
||||
package org.jeecg.modules.gen.entitylink.controller;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.gen.entitylink.entity.EntityLink;
|
||||
import org.jeecg.modules.gen.entitylink.service.IEntityLinkService;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
/**
|
||||
* @Description: 主体绑定
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-12
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Tag(name="主体绑定")
|
||||
@RestController
|
||||
@RequestMapping("/gen/entitylink/entityLink")
|
||||
@Slf4j
|
||||
public class EntityLinkController extends JeecgController<EntityLink, IEntityLinkService> {
|
||||
@Autowired
|
||||
private IEntityLinkService entityLinkService;
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
*
|
||||
* @param entityLink
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
//@AutoLog(value = "主体绑定-分页列表查询")
|
||||
@Operation(summary="主体绑定-分页列表查询")
|
||||
@GetMapping(value = "/list")
|
||||
public Result<IPage<EntityLink>> queryPageList(EntityLink entityLink,
|
||||
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||
HttpServletRequest req) {
|
||||
|
||||
|
||||
QueryWrapper<EntityLink> queryWrapper = QueryGenerator.initQueryWrapper(entityLink, req.getParameterMap());
|
||||
Page<EntityLink> page = new Page<EntityLink>(pageNo, pageSize);
|
||||
IPage<EntityLink> pageList = entityLinkService.page(page, queryWrapper);
|
||||
return Result.OK(pageList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param entityLink
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "主体绑定-添加")
|
||||
@Operation(summary="主体绑定-添加")
|
||||
@RequiresPermissions("gen.entitylink:entity_link:add")
|
||||
@PostMapping(value = "/add")
|
||||
public Result<String> add(@RequestBody EntityLink entityLink) {
|
||||
entityLinkService.save(entityLink);
|
||||
|
||||
return Result.OK("添加成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*
|
||||
* @param entityLink
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "主体绑定-编辑")
|
||||
@Operation(summary="主体绑定-编辑")
|
||||
@RequiresPermissions("gen.entitylink:entity_link:edit")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
|
||||
public Result<String> edit(@RequestBody EntityLink entityLink) {
|
||||
entityLinkService.updateById(entityLink);
|
||||
return Result.OK("编辑成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "主体绑定-通过id删除")
|
||||
@Operation(summary="主体绑定-通过id删除")
|
||||
@RequiresPermissions("gen.entitylink:entity_link:delete")
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
|
||||
entityLinkService.removeById(id);
|
||||
return Result.OK("删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "主体绑定-批量删除")
|
||||
@Operation(summary="主体绑定-批量删除")
|
||||
@RequiresPermissions("gen.entitylink:entity_link:deleteBatch")
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
|
||||
this.entityLinkService.removeByIds(Arrays.asList(ids.split(",")));
|
||||
return Result.OK("批量删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
//@AutoLog(value = "主体绑定-通过id查询")
|
||||
@Operation(summary="主体绑定-通过id查询")
|
||||
@GetMapping(value = "/queryById")
|
||||
public Result<EntityLink> queryById(@RequestParam(name="id",required=true) String id) {
|
||||
EntityLink entityLink = entityLinkService.getById(id);
|
||||
if(entityLink==null) {
|
||||
return Result.error("未找到对应数据");
|
||||
}
|
||||
return Result.OK(entityLink);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
* @param entityLink
|
||||
*/
|
||||
@RequiresPermissions("gen.entitylink:entity_link:exportXls")
|
||||
@RequestMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(HttpServletRequest request, EntityLink entityLink) {
|
||||
return super.exportXls(request, entityLink, EntityLink.class, "主体绑定");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过excel导入数据
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("gen.entitylink:entity_link:importExcel")
|
||||
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||
return super.importExcel(request, response, EntityLink.class);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package org.jeecg.modules.gen.entitylink.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Date;
|
||||
import java.math.BigDecimal;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import org.jeecg.common.constant.ProvinceCityArea;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import lombok.Data;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
import org.jeecg.common.aspect.annotation.Dict;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* @Description: 主体绑定
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-12
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Data
|
||||
@TableName("entity_link")
|
||||
@Accessors(chain = true)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Schema(description="主体绑定")
|
||||
public class EntityLink implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**主键*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
@Schema(description = "主键")
|
||||
private java.lang.String id;
|
||||
/**主体类型*/
|
||||
@Excel(name = "主体类型", width = 15)
|
||||
@Schema(description = "主体类型")
|
||||
private java.lang.String sourceType;
|
||||
/**主体id*/
|
||||
@Excel(name = "主体id", width = 15)
|
||||
@Schema(description = "主体id")
|
||||
private java.lang.String sourceId;
|
||||
/**内容类型*/
|
||||
@Excel(name = "内容类型", width = 15)
|
||||
@Schema(description = "内容类型")
|
||||
private java.lang.String targetType;
|
||||
/**内容id*/
|
||||
@Excel(name = "内容id", width = 15)
|
||||
@Schema(description = "内容id")
|
||||
private java.lang.String targetId;
|
||||
/**排序*/
|
||||
@Excel(name = "排序", width = 15)
|
||||
@Schema(description = "排序")
|
||||
private java.lang.Integer sortOrder;
|
||||
/**创建人*/
|
||||
@Schema(description = "创建人")
|
||||
private java.lang.String createBy;
|
||||
/**创建日期*/
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
@Schema(description = "创建日期")
|
||||
private java.util.Date createTime;
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package org.jeecg.modules.gen.entitylink.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.jeecg.modules.gen.entitylink.entity.EntityLink;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* @Description: 主体绑定
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-12
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface EntityLinkMapper extends BaseMapper<EntityLink> {
|
||||
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
<?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="org.jeecg.modules.gen.entitylink.mapper.EntityLinkMapper">
|
||||
|
||||
</mapper>
|
@ -0,0 +1,14 @@
|
||||
package org.jeecg.modules.gen.entitylink.service;
|
||||
|
||||
import org.jeecg.modules.gen.entitylink.entity.EntityLink;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* @Description: 主体绑定
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-12
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface IEntityLinkService extends IService<EntityLink> {
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package org.jeecg.modules.gen.entitylink.service.impl;
|
||||
|
||||
import org.jeecg.modules.gen.entitylink.entity.EntityLink;
|
||||
import org.jeecg.modules.gen.entitylink.mapper.EntityLinkMapper;
|
||||
import org.jeecg.modules.gen.entitylink.service.IEntityLinkService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
||||
/**
|
||||
* @Description: 主体绑定
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2025-08-12
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Service
|
||||
public class EntityLinkServiceImpl extends ServiceImpl<EntityLinkMapper, EntityLink> implements IEntityLinkService {
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user