课程 重构

This commit is contained in:
GoCo 2025-08-31 11:55:37 +08:00
parent 337ba0f42a
commit 67068a03b6
287 changed files with 26684 additions and 3 deletions

View File

@ -0,0 +1,36 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-boot-module</artifactId>
<version>3.8.2</version>
</parent>
<artifactId>jeecg-module-aiol</artifactId>
<packaging>jar</packaging>
<name>jeecg-module-aiol</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<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>

View File

@ -0,0 +1,51 @@
package org.jeecg.modules.aiol.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;
}
}

View File

@ -0,0 +1,182 @@
package org.jeecg.modules.aiol.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.aiol.entity.AiolComment;
import org.jeecg.modules.aiol.service.IAiolCommentService;
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-31
* @Version: V1.0
*/
@Tag(name="评论")
@RestController
@RequestMapping("/aiol/aiolComment")
@Slf4j
public class AiolCommentController extends JeecgController<AiolComment, IAiolCommentService> {
@Autowired
private IAiolCommentService aiolCommentService;
/**
* 分页列表查询
*
* @param aiolComment
* @param pageNo
* @param pageSize
* @param req
* @return
*/
//@AutoLog(value = "评论-分页列表查询")
@Operation(summary="评论-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<AiolComment>> queryPageList(AiolComment aiolComment,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<AiolComment> queryWrapper = QueryGenerator.initQueryWrapper(aiolComment, req.getParameterMap());
Page<AiolComment> page = new Page<AiolComment>(pageNo, pageSize);
IPage<AiolComment> pageList = aiolCommentService.page(page, queryWrapper);
return Result.OK(pageList);
}
/**
* 添加
*
* @param aiolComment
* @return
*/
@AutoLog(value = "评论-添加")
@Operation(summary="评论-添加")
@RequiresPermissions("aiol:aiol_comment:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody AiolComment aiolComment) {
aiolCommentService.save(aiolComment);
return Result.OK("添加成功!");
}
/**
* 编辑
*
* @param aiolComment
* @return
*/
@AutoLog(value = "评论-编辑")
@Operation(summary="评论-编辑")
@RequiresPermissions("aiol:aiol_comment:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<String> edit(@RequestBody AiolComment aiolComment) {
aiolCommentService.updateById(aiolComment);
return Result.OK("编辑成功!");
}
/**
* 通过id删除
*
* @param id
* @return
*/
@AutoLog(value = "评论-通过id删除")
@Operation(summary="评论-通过id删除")
@RequiresPermissions("aiol:aiol_comment:delete")
@DeleteMapping(value = "/delete")
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
aiolCommentService.removeById(id);
return Result.OK("删除成功!");
}
/**
* 批量删除
*
* @param ids
* @return
*/
@AutoLog(value = "评论-批量删除")
@Operation(summary="评论-批量删除")
@RequiresPermissions("aiol:aiol_comment:deleteBatch")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
this.aiolCommentService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK("批量删除成功!");
}
/**
* 通过id查询
*
* @param id
* @return
*/
//@AutoLog(value = "评论-通过id查询")
@Operation(summary="评论-通过id查询")
@GetMapping(value = "/queryById")
public Result<AiolComment> queryById(@RequestParam(name="id",required=true) String id) {
AiolComment aiolComment = aiolCommentService.getById(id);
if(aiolComment==null) {
return Result.error("未找到对应数据");
}
return Result.OK(aiolComment);
}
/**
* 导出excel
*
* @param request
* @param aiolComment
*/
@RequiresPermissions("aiol:aiol_comment:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, AiolComment aiolComment) {
return super.exportXls(request, aiolComment, AiolComment.class, "评论");
}
/**
* 通过excel导入数据
*
* @param request
* @param response
* @return
*/
@RequiresPermissions("aiol:aiol_comment:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, AiolComment.class);
}
}

View File

@ -0,0 +1,182 @@
package org.jeecg.modules.aiol.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.aiol.entity.AiolCourseCategory;
import org.jeecg.modules.aiol.service.IAiolCourseCategoryService;
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-31
* @Version: V1.0
*/
@Tag(name="课程分类")
@RestController
@RequestMapping("/aiol/aiolCourseCategory")
@Slf4j
public class AiolCourseCategoryController extends JeecgController<AiolCourseCategory, IAiolCourseCategoryService> {
@Autowired
private IAiolCourseCategoryService aiolCourseCategoryService;
/**
* 分页列表查询
*
* @param aiolCourseCategory
* @param pageNo
* @param pageSize
* @param req
* @return
*/
//@AutoLog(value = "课程分类-分页列表查询")
@Operation(summary="课程分类-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<AiolCourseCategory>> queryPageList(AiolCourseCategory aiolCourseCategory,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<AiolCourseCategory> queryWrapper = QueryGenerator.initQueryWrapper(aiolCourseCategory, req.getParameterMap());
Page<AiolCourseCategory> page = new Page<AiolCourseCategory>(pageNo, pageSize);
IPage<AiolCourseCategory> pageList = aiolCourseCategoryService.page(page, queryWrapper);
return Result.OK(pageList);
}
/**
* 添加
*
* @param aiolCourseCategory
* @return
*/
@AutoLog(value = "课程分类-添加")
@Operation(summary="课程分类-添加")
@RequiresPermissions("aiol:aiol_course_category:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody AiolCourseCategory aiolCourseCategory) {
aiolCourseCategoryService.save(aiolCourseCategory);
return Result.OK("添加成功!");
}
/**
* 编辑
*
* @param aiolCourseCategory
* @return
*/
@AutoLog(value = "课程分类-编辑")
@Operation(summary="课程分类-编辑")
@RequiresPermissions("aiol:aiol_course_category:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<String> edit(@RequestBody AiolCourseCategory aiolCourseCategory) {
aiolCourseCategoryService.updateById(aiolCourseCategory);
return Result.OK("编辑成功!");
}
/**
* 通过id删除
*
* @param id
* @return
*/
@AutoLog(value = "课程分类-通过id删除")
@Operation(summary="课程分类-通过id删除")
@RequiresPermissions("aiol:aiol_course_category:delete")
@DeleteMapping(value = "/delete")
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
aiolCourseCategoryService.removeById(id);
return Result.OK("删除成功!");
}
/**
* 批量删除
*
* @param ids
* @return
*/
@AutoLog(value = "课程分类-批量删除")
@Operation(summary="课程分类-批量删除")
@RequiresPermissions("aiol:aiol_course_category:deleteBatch")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
this.aiolCourseCategoryService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK("批量删除成功!");
}
/**
* 通过id查询
*
* @param id
* @return
*/
//@AutoLog(value = "课程分类-通过id查询")
@Operation(summary="课程分类-通过id查询")
@GetMapping(value = "/queryById")
public Result<AiolCourseCategory> queryById(@RequestParam(name="id",required=true) String id) {
AiolCourseCategory aiolCourseCategory = aiolCourseCategoryService.getById(id);
if(aiolCourseCategory==null) {
return Result.error("未找到对应数据");
}
return Result.OK(aiolCourseCategory);
}
/**
* 导出excel
*
* @param request
* @param aiolCourseCategory
*/
@RequiresPermissions("aiol:aiol_course_category:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, AiolCourseCategory aiolCourseCategory) {
return super.exportXls(request, aiolCourseCategory, AiolCourseCategory.class, "课程分类");
}
/**
* 通过excel导入数据
*
* @param request
* @param response
* @return
*/
@RequiresPermissions("aiol:aiol_course_category:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, AiolCourseCategory.class);
}
}

View File

@ -0,0 +1,412 @@
package org.jeecg.modules.aiol.controller;
import java.util.*;
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.constant.CommonConstant;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.query.QueryRuleEnum;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.config.shiro.IgnoreAuth;
import org.jeecg.modules.aiol.dto.CourseWithTeacherInfo;
import org.jeecg.modules.aiol.dto.TeacherInfo;
import org.jeecg.modules.aiol.entity.*;
import org.jeecg.modules.aiol.service.IAiolCourseService;
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-31
* @Version: V1.0
*/
@Tag(name = "课程")
@RestController
@RequestMapping("/aiol/aiolCourse")
@Slf4j
public class AiolCourseController extends JeecgController<AiolCourse, IAiolCourseService> {
@Autowired
private IAiolCourseService aiolCourseService;
/**
* 分页列表查询
*
* @param aiolCourse
* @param pageNo
* @param pageSize
* @param req
* @return
*/
//@AutoLog(value = "课程-分页列表查询")
@Operation(summary = "课程-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<AiolCourse>> queryPageList(AiolCourse aiolCourse,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<AiolCourse> queryWrapper = QueryGenerator.initQueryWrapper(aiolCourse, req.getParameterMap());
Page<AiolCourse> page = new Page<AiolCourse>(pageNo, pageSize);
IPage<AiolCourse> pageList = aiolCourseService.page(page, queryWrapper);
return Result.OK(pageList);
}
/**
* 添加
*
* @param aiolCourse
* @return
*/
@AutoLog(value = "课程-添加")
@Operation(summary = "课程-添加")
@RequiresPermissions("aiol:aiol_course:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody AiolCourse aiolCourse) {
aiolCourseService.save(aiolCourse);
return Result.OK("添加成功!");
}
/**
* 编辑
*
* @param aiolCourse
* @return
*/
@AutoLog(value = "课程-编辑")
@Operation(summary = "课程-编辑")
@RequiresPermissions("aiol:aiol_course:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
public Result<String> edit(@RequestBody AiolCourse aiolCourse) {
aiolCourseService.updateById(aiolCourse);
return Result.OK("编辑成功!");
}
/**
* 通过id删除
*
* @param id
* @return
*/
@AutoLog(value = "课程-通过id删除")
@Operation(summary = "课程-通过id删除")
@RequiresPermissions("aiol:aiol_course:delete")
@DeleteMapping(value = "/delete")
public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
aiolCourseService.removeById(id);
return Result.OK("删除成功!");
}
/**
* 批量删除
*
* @param ids
* @return
*/
@AutoLog(value = "课程-批量删除")
@Operation(summary = "课程-批量删除")
@RequiresPermissions("aiol:aiol_course:deleteBatch")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
this.aiolCourseService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK("批量删除成功!");
}
/**
* 通过id查询
*
* @param id
* @return
*/
//@AutoLog(value = "课程-通过id查询")
@Operation(summary = "课程-通过id查询")
@GetMapping(value = "/queryById")
public Result<AiolCourse> queryById(@RequestParam(name = "id", required = true) String id) {
AiolCourse aiolCourse = aiolCourseService.getById(id);
if (aiolCourse == null) {
return Result.error("未找到对应数据");
}
return Result.OK(aiolCourse);
}
/**
* 导出excel
*
* @param request
* @param aiolCourse
*/
@RequiresPermissions("aiol:aiol_course:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, AiolCourse aiolCourse) {
return super.exportXls(request, aiolCourse, AiolCourse.class, "课程");
}
/**
* 通过excel导入数据
*
* @param request
* @param response
* @return
*/
@RequiresPermissions("aiol:aiol_course:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, AiolCourse.class);
}
@Autowired
private ISysBaseAPI sysBaseApi;
@GetMapping("/query_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 = aiolCourseService.getCourseList(categoryId, difficulty, topic);
if (sort != null) {
switch (sort) {
case "hottest":
list = list.stream()
.sorted(Comparator.comparing(AiolCourse::getEnrollCount, Comparator.nullsLast(Integer::compareTo)).reversed())
.collect(Collectors.toList());
break;
case "latest":
list = list.stream()
.sorted(Comparator.comparing(AiolCourse::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<AiolCourse> queryCourseDetail(@RequestParam(value = "id") String id) {
AiolCourse course = aiolCourseService.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);
}
/**
* 仅返回 valuelabel 的简单对象
*/
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<AiolCourseCategory>> queryCategoryList() {
List<AiolCourseCategory> list = aiolCourseService.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<AiolCourseSection>> querySectionList(@PathVariable(value = "courseId") String courseId) {
List<AiolCourseSection> list = aiolCourseService.getCourseSectionList(courseId);
return Result.OK(list);
}
@GetMapping("/{courseId}/section_video/{sectionId}")
@Operation(summary = "查询视频章节详情", description = "该接口需要携带用户登录token。根据章节id查询章节详情不同类型的章节返回的内容不同")
public Result<List<AiolResource>> querySectionDetail(@PathVariable(value = "courseId") String courseId, @PathVariable(value = "sectionId") String sectionId) {
// TODO GC 获取用户id根据courseId判断当前用户是否报名课程只有已报名的课程才能查看章节详情
List<AiolResource> list = aiolCourseService.getCourseSectionDetail(0, sectionId, AiolResource.class);
return Result.OK(list);
}
@GetMapping("/{courseId}/section_document/{sectionId}")
@Operation(summary = "查询文档章节详情", description = "该接口需要携带用户登录token。根据章节id查询章节详情不同类型的章节返回的内容不同")
public Result<List<AiolResource>> querySectionDocumentDetail(@PathVariable(value = "courseId") String courseId, @PathVariable(value = "sectionId") String sectionId) {
// TODO GC 获取用户id根据courseId判断当前用户是否报名课程只有已报名的课程才能查看章节详情
List<AiolResource> list = aiolCourseService.getCourseSectionDetail(1, sectionId, AiolResource.class);
return Result.OK(list);
}
@GetMapping("/{courseId}/section_homework/{sectionId}")
@Operation(summary = "查询作业章节详情", description = "该接口需要携带用户登录token。根据章节id查询章节详情不同类型的章节返回的内容不同")
public Result<List<AiolHomework>> querySectionHomeworkDetail(@PathVariable(value = "courseId") String courseId, @PathVariable(value = "sectionId") String sectionId) {
// TODO GC 获取用户id根据courseId判断当前用户是否报名课程只有已报名的课程才能查看章节详情
List<AiolHomework> list = aiolCourseService.getCourseSectionDetail(3, sectionId, AiolHomework.class);
return Result.OK(list);
}
@GetMapping("/{courseId}/teachers")
@Operation(summary = "查询课程的授课教师")
@IgnoreAuth
public Result<List<TeacherInfo>> queryTeacherList(@PathVariable(value = "courseId") String courseId) {
List<TeacherInfo> list = aiolCourseService.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 = aiolCourseService.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 = aiolCourseService.isEnrolled(courseId, sysUser.getId());
return Result.OK(isEnrolled);
}
@GetMapping("/teacher_list")
@Operation(summary = "查询当前教师创建的课程")
public Result<List<AiolCourse>> 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<AiolCourse> wrapper = new QueryWrapper<AiolCourse>().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<AiolCourse> list = aiolCourseService.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(aiolCourseService.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 = aiolCourseService.getCourseProgress(courseId, sysUser.getId());
return Result.OK(progress);
}
@GetMapping("/count")
@Operation(summary = "查询课程总数", description = "返回系统中所有课程的总数量")
@IgnoreAuth
public Result<Long> queryCourseCount() {
long count = aiolCourseService.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 = aiolCourseService.count();
return Result.OK(count);
}
}

View File

@ -0,0 +1,182 @@
package org.jeecg.modules.aiol.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.aiol.entity.AiolCourseSection;
import org.jeecg.modules.aiol.service.IAiolCourseSectionService;
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-31
* @Version: V1.0
*/
@Tag(name="课程章节")
@RestController
@RequestMapping("/aiol/aiolCourseSection")
@Slf4j
public class AiolCourseSectionController extends JeecgController<AiolCourseSection, IAiolCourseSectionService> {
@Autowired
private IAiolCourseSectionService aiolCourseSectionService;
/**
* 分页列表查询
*
* @param aiolCourseSection
* @param pageNo
* @param pageSize
* @param req
* @return
*/
//@AutoLog(value = "课程章节-分页列表查询")
@Operation(summary="课程章节-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<AiolCourseSection>> queryPageList(AiolCourseSection aiolCourseSection,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<AiolCourseSection> queryWrapper = QueryGenerator.initQueryWrapper(aiolCourseSection, req.getParameterMap());
Page<AiolCourseSection> page = new Page<AiolCourseSection>(pageNo, pageSize);
IPage<AiolCourseSection> pageList = aiolCourseSectionService.page(page, queryWrapper);
return Result.OK(pageList);
}
/**
* 添加
*
* @param aiolCourseSection
* @return
*/
@AutoLog(value = "课程章节-添加")
@Operation(summary="课程章节-添加")
@RequiresPermissions("aiol:aiol_course_section:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody AiolCourseSection aiolCourseSection) {
aiolCourseSectionService.save(aiolCourseSection);
return Result.OK("添加成功!");
}
/**
* 编辑
*
* @param aiolCourseSection
* @return
*/
@AutoLog(value = "课程章节-编辑")
@Operation(summary="课程章节-编辑")
@RequiresPermissions("aiol:aiol_course_section:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<String> edit(@RequestBody AiolCourseSection aiolCourseSection) {
aiolCourseSectionService.updateById(aiolCourseSection);
return Result.OK("编辑成功!");
}
/**
* 通过id删除
*
* @param id
* @return
*/
@AutoLog(value = "课程章节-通过id删除")
@Operation(summary="课程章节-通过id删除")
@RequiresPermissions("aiol:aiol_course_section:delete")
@DeleteMapping(value = "/delete")
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
aiolCourseSectionService.removeById(id);
return Result.OK("删除成功!");
}
/**
* 批量删除
*
* @param ids
* @return
*/
@AutoLog(value = "课程章节-批量删除")
@Operation(summary="课程章节-批量删除")
@RequiresPermissions("aiol:aiol_course_section:deleteBatch")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
this.aiolCourseSectionService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK("批量删除成功!");
}
/**
* 通过id查询
*
* @param id
* @return
*/
//@AutoLog(value = "课程章节-通过id查询")
@Operation(summary="课程章节-通过id查询")
@GetMapping(value = "/queryById")
public Result<AiolCourseSection> queryById(@RequestParam(name="id",required=true) String id) {
AiolCourseSection aiolCourseSection = aiolCourseSectionService.getById(id);
if(aiolCourseSection==null) {
return Result.error("未找到对应数据");
}
return Result.OK(aiolCourseSection);
}
/**
* 导出excel
*
* @param request
* @param aiolCourseSection
*/
@RequiresPermissions("aiol:aiol_course_section:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, AiolCourseSection aiolCourseSection) {
return super.exportXls(request, aiolCourseSection, AiolCourseSection.class, "课程章节");
}
/**
* 通过excel导入数据
*
* @param request
* @param response
* @return
*/
@RequiresPermissions("aiol:aiol_course_section:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, AiolCourseSection.class);
}
}

View File

@ -0,0 +1,182 @@
package org.jeecg.modules.aiol.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.aiol.entity.AiolCourseSignup;
import org.jeecg.modules.aiol.service.IAiolCourseSignupService;
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-31
* @Version: V1.0
*/
@Tag(name="课程报名")
@RestController
@RequestMapping("/aiol/aiolCourseSignup")
@Slf4j
public class AiolCourseSignupController extends JeecgController<AiolCourseSignup, IAiolCourseSignupService> {
@Autowired
private IAiolCourseSignupService aiolCourseSignupService;
/**
* 分页列表查询
*
* @param aiolCourseSignup
* @param pageNo
* @param pageSize
* @param req
* @return
*/
//@AutoLog(value = "课程报名-分页列表查询")
@Operation(summary="课程报名-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<AiolCourseSignup>> queryPageList(AiolCourseSignup aiolCourseSignup,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<AiolCourseSignup> queryWrapper = QueryGenerator.initQueryWrapper(aiolCourseSignup, req.getParameterMap());
Page<AiolCourseSignup> page = new Page<AiolCourseSignup>(pageNo, pageSize);
IPage<AiolCourseSignup> pageList = aiolCourseSignupService.page(page, queryWrapper);
return Result.OK(pageList);
}
/**
* 添加
*
* @param aiolCourseSignup
* @return
*/
@AutoLog(value = "课程报名-添加")
@Operation(summary="课程报名-添加")
@RequiresPermissions("aiol:aiol_course_signup:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody AiolCourseSignup aiolCourseSignup) {
aiolCourseSignupService.save(aiolCourseSignup);
return Result.OK("添加成功!");
}
/**
* 编辑
*
* @param aiolCourseSignup
* @return
*/
@AutoLog(value = "课程报名-编辑")
@Operation(summary="课程报名-编辑")
@RequiresPermissions("aiol:aiol_course_signup:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<String> edit(@RequestBody AiolCourseSignup aiolCourseSignup) {
aiolCourseSignupService.updateById(aiolCourseSignup);
return Result.OK("编辑成功!");
}
/**
* 通过id删除
*
* @param id
* @return
*/
@AutoLog(value = "课程报名-通过id删除")
@Operation(summary="课程报名-通过id删除")
@RequiresPermissions("aiol:aiol_course_signup:delete")
@DeleteMapping(value = "/delete")
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
aiolCourseSignupService.removeById(id);
return Result.OK("删除成功!");
}
/**
* 批量删除
*
* @param ids
* @return
*/
@AutoLog(value = "课程报名-批量删除")
@Operation(summary="课程报名-批量删除")
@RequiresPermissions("aiol:aiol_course_signup:deleteBatch")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
this.aiolCourseSignupService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK("批量删除成功!");
}
/**
* 通过id查询
*
* @param id
* @return
*/
//@AutoLog(value = "课程报名-通过id查询")
@Operation(summary="课程报名-通过id查询")
@GetMapping(value = "/queryById")
public Result<AiolCourseSignup> queryById(@RequestParam(name="id",required=true) String id) {
AiolCourseSignup aiolCourseSignup = aiolCourseSignupService.getById(id);
if(aiolCourseSignup==null) {
return Result.error("未找到对应数据");
}
return Result.OK(aiolCourseSignup);
}
/**
* 导出excel
*
* @param request
* @param aiolCourseSignup
*/
@RequiresPermissions("aiol:aiol_course_signup:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, AiolCourseSignup aiolCourseSignup) {
return super.exportXls(request, aiolCourseSignup, AiolCourseSignup.class, "课程报名");
}
/**
* 通过excel导入数据
*
* @param request
* @param response
* @return
*/
@RequiresPermissions("aiol:aiol_course_signup:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, AiolCourseSignup.class);
}
}

View File

@ -0,0 +1,182 @@
package org.jeecg.modules.aiol.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.aiol.entity.AiolCourseTeacher;
import org.jeecg.modules.aiol.service.IAiolCourseTeacherService;
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-31
* @Version: V1.0
*/
@Tag(name="授课教师")
@RestController
@RequestMapping("/aiol/aiolCourseTeacher")
@Slf4j
public class AiolCourseTeacherController extends JeecgController<AiolCourseTeacher, IAiolCourseTeacherService> {
@Autowired
private IAiolCourseTeacherService aiolCourseTeacherService;
/**
* 分页列表查询
*
* @param aiolCourseTeacher
* @param pageNo
* @param pageSize
* @param req
* @return
*/
//@AutoLog(value = "授课教师-分页列表查询")
@Operation(summary="授课教师-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<AiolCourseTeacher>> queryPageList(AiolCourseTeacher aiolCourseTeacher,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<AiolCourseTeacher> queryWrapper = QueryGenerator.initQueryWrapper(aiolCourseTeacher, req.getParameterMap());
Page<AiolCourseTeacher> page = new Page<AiolCourseTeacher>(pageNo, pageSize);
IPage<AiolCourseTeacher> pageList = aiolCourseTeacherService.page(page, queryWrapper);
return Result.OK(pageList);
}
/**
* 添加
*
* @param aiolCourseTeacher
* @return
*/
@AutoLog(value = "授课教师-添加")
@Operation(summary="授课教师-添加")
@RequiresPermissions("aiol:aiol_course_teacher:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody AiolCourseTeacher aiolCourseTeacher) {
aiolCourseTeacherService.save(aiolCourseTeacher);
return Result.OK("添加成功!");
}
/**
* 编辑
*
* @param aiolCourseTeacher
* @return
*/
@AutoLog(value = "授课教师-编辑")
@Operation(summary="授课教师-编辑")
@RequiresPermissions("aiol:aiol_course_teacher:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<String> edit(@RequestBody AiolCourseTeacher aiolCourseTeacher) {
aiolCourseTeacherService.updateById(aiolCourseTeacher);
return Result.OK("编辑成功!");
}
/**
* 通过id删除
*
* @param id
* @return
*/
@AutoLog(value = "授课教师-通过id删除")
@Operation(summary="授课教师-通过id删除")
@RequiresPermissions("aiol:aiol_course_teacher:delete")
@DeleteMapping(value = "/delete")
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
aiolCourseTeacherService.removeById(id);
return Result.OK("删除成功!");
}
/**
* 批量删除
*
* @param ids
* @return
*/
@AutoLog(value = "授课教师-批量删除")
@Operation(summary="授课教师-批量删除")
@RequiresPermissions("aiol:aiol_course_teacher:deleteBatch")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
this.aiolCourseTeacherService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK("批量删除成功!");
}
/**
* 通过id查询
*
* @param id
* @return
*/
//@AutoLog(value = "授课教师-通过id查询")
@Operation(summary="授课教师-通过id查询")
@GetMapping(value = "/queryById")
public Result<AiolCourseTeacher> queryById(@RequestParam(name="id",required=true) String id) {
AiolCourseTeacher aiolCourseTeacher = aiolCourseTeacherService.getById(id);
if(aiolCourseTeacher==null) {
return Result.error("未找到对应数据");
}
return Result.OK(aiolCourseTeacher);
}
/**
* 导出excel
*
* @param request
* @param aiolCourseTeacher
*/
@RequiresPermissions("aiol:aiol_course_teacher:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, AiolCourseTeacher aiolCourseTeacher) {
return super.exportXls(request, aiolCourseTeacher, AiolCourseTeacher.class, "授课教师");
}
/**
* 通过excel导入数据
*
* @param request
* @param response
* @return
*/
@RequiresPermissions("aiol:aiol_course_teacher:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, AiolCourseTeacher.class);
}
}

View File

@ -0,0 +1,182 @@
package org.jeecg.modules.aiol.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.aiol.entity.AiolEntityLink;
import org.jeecg.modules.aiol.service.IAiolEntityLinkService;
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-31
* @Version: V1.0
*/
@Tag(name="主体绑定")
@RestController
@RequestMapping("/aiol/aiolEntityLink")
@Slf4j
public class AiolEntityLinkController extends JeecgController<AiolEntityLink, IAiolEntityLinkService> {
@Autowired
private IAiolEntityLinkService aiolEntityLinkService;
/**
* 分页列表查询
*
* @param aiolEntityLink
* @param pageNo
* @param pageSize
* @param req
* @return
*/
//@AutoLog(value = "主体绑定-分页列表查询")
@Operation(summary="主体绑定-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<AiolEntityLink>> queryPageList(AiolEntityLink aiolEntityLink,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<AiolEntityLink> queryWrapper = QueryGenerator.initQueryWrapper(aiolEntityLink, req.getParameterMap());
Page<AiolEntityLink> page = new Page<AiolEntityLink>(pageNo, pageSize);
IPage<AiolEntityLink> pageList = aiolEntityLinkService.page(page, queryWrapper);
return Result.OK(pageList);
}
/**
* 添加
*
* @param aiolEntityLink
* @return
*/
@AutoLog(value = "主体绑定-添加")
@Operation(summary="主体绑定-添加")
@RequiresPermissions("aiol:aiol_entity_link:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody AiolEntityLink aiolEntityLink) {
aiolEntityLinkService.save(aiolEntityLink);
return Result.OK("添加成功!");
}
/**
* 编辑
*
* @param aiolEntityLink
* @return
*/
@AutoLog(value = "主体绑定-编辑")
@Operation(summary="主体绑定-编辑")
@RequiresPermissions("aiol:aiol_entity_link:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<String> edit(@RequestBody AiolEntityLink aiolEntityLink) {
aiolEntityLinkService.updateById(aiolEntityLink);
return Result.OK("编辑成功!");
}
/**
* 通过id删除
*
* @param id
* @return
*/
@AutoLog(value = "主体绑定-通过id删除")
@Operation(summary="主体绑定-通过id删除")
@RequiresPermissions("aiol:aiol_entity_link:delete")
@DeleteMapping(value = "/delete")
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
aiolEntityLinkService.removeById(id);
return Result.OK("删除成功!");
}
/**
* 批量删除
*
* @param ids
* @return
*/
@AutoLog(value = "主体绑定-批量删除")
@Operation(summary="主体绑定-批量删除")
@RequiresPermissions("aiol:aiol_entity_link:deleteBatch")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
this.aiolEntityLinkService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK("批量删除成功!");
}
/**
* 通过id查询
*
* @param id
* @return
*/
//@AutoLog(value = "主体绑定-通过id查询")
@Operation(summary="主体绑定-通过id查询")
@GetMapping(value = "/queryById")
public Result<AiolEntityLink> queryById(@RequestParam(name="id",required=true) String id) {
AiolEntityLink aiolEntityLink = aiolEntityLinkService.getById(id);
if(aiolEntityLink==null) {
return Result.error("未找到对应数据");
}
return Result.OK(aiolEntityLink);
}
/**
* 导出excel
*
* @param request
* @param aiolEntityLink
*/
@RequiresPermissions("aiol:aiol_entity_link:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, AiolEntityLink aiolEntityLink) {
return super.exportXls(request, aiolEntityLink, AiolEntityLink.class, "主体绑定");
}
/**
* 通过excel导入数据
*
* @param request
* @param response
* @return
*/
@RequiresPermissions("aiol:aiol_entity_link:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, AiolEntityLink.class);
}
}

View File

@ -0,0 +1,182 @@
package org.jeecg.modules.aiol.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.aiol.entity.AiolHomework;
import org.jeecg.modules.aiol.service.IAiolHomeworkService;
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-31
* @Version: V1.0
*/
@Tag(name="作业")
@RestController
@RequestMapping("/aiol/aiolHomework")
@Slf4j
public class AiolHomeworkController extends JeecgController<AiolHomework, IAiolHomeworkService> {
@Autowired
private IAiolHomeworkService aiolHomeworkService;
/**
* 分页列表查询
*
* @param aiolHomework
* @param pageNo
* @param pageSize
* @param req
* @return
*/
//@AutoLog(value = "作业-分页列表查询")
@Operation(summary="作业-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<AiolHomework>> queryPageList(AiolHomework aiolHomework,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<AiolHomework> queryWrapper = QueryGenerator.initQueryWrapper(aiolHomework, req.getParameterMap());
Page<AiolHomework> page = new Page<AiolHomework>(pageNo, pageSize);
IPage<AiolHomework> pageList = aiolHomeworkService.page(page, queryWrapper);
return Result.OK(pageList);
}
/**
* 添加
*
* @param aiolHomework
* @return
*/
@AutoLog(value = "作业-添加")
@Operation(summary="作业-添加")
@RequiresPermissions("aiol:aiol_homework:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody AiolHomework aiolHomework) {
aiolHomeworkService.save(aiolHomework);
return Result.OK("添加成功!");
}
/**
* 编辑
*
* @param aiolHomework
* @return
*/
@AutoLog(value = "作业-编辑")
@Operation(summary="作业-编辑")
@RequiresPermissions("aiol:aiol_homework:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<String> edit(@RequestBody AiolHomework aiolHomework) {
aiolHomeworkService.updateById(aiolHomework);
return Result.OK("编辑成功!");
}
/**
* 通过id删除
*
* @param id
* @return
*/
@AutoLog(value = "作业-通过id删除")
@Operation(summary="作业-通过id删除")
@RequiresPermissions("aiol:aiol_homework:delete")
@DeleteMapping(value = "/delete")
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
aiolHomeworkService.removeById(id);
return Result.OK("删除成功!");
}
/**
* 批量删除
*
* @param ids
* @return
*/
@AutoLog(value = "作业-批量删除")
@Operation(summary="作业-批量删除")
@RequiresPermissions("aiol:aiol_homework:deleteBatch")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
this.aiolHomeworkService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK("批量删除成功!");
}
/**
* 通过id查询
*
* @param id
* @return
*/
//@AutoLog(value = "作业-通过id查询")
@Operation(summary="作业-通过id查询")
@GetMapping(value = "/queryById")
public Result<AiolHomework> queryById(@RequestParam(name="id",required=true) String id) {
AiolHomework aiolHomework = aiolHomeworkService.getById(id);
if(aiolHomework==null) {
return Result.error("未找到对应数据");
}
return Result.OK(aiolHomework);
}
/**
* 导出excel
*
* @param request
* @param aiolHomework
*/
@RequiresPermissions("aiol:aiol_homework:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, AiolHomework aiolHomework) {
return super.exportXls(request, aiolHomework, AiolHomework.class, "作业");
}
/**
* 通过excel导入数据
*
* @param request
* @param response
* @return
*/
@RequiresPermissions("aiol:aiol_homework:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, AiolHomework.class);
}
}

View File

@ -0,0 +1,182 @@
package org.jeecg.modules.aiol.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.aiol.entity.AiolLearnProgress;
import org.jeecg.modules.aiol.service.IAiolLearnProgressService;
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-31
* @Version: V1.0
*/
@Tag(name="学习进度")
@RestController
@RequestMapping("/aiol/aiolLearnProgress")
@Slf4j
public class AiolLearnProgressController extends JeecgController<AiolLearnProgress, IAiolLearnProgressService> {
@Autowired
private IAiolLearnProgressService aiolLearnProgressService;
/**
* 分页列表查询
*
* @param aiolLearnProgress
* @param pageNo
* @param pageSize
* @param req
* @return
*/
//@AutoLog(value = "学习进度-分页列表查询")
@Operation(summary="学习进度-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<AiolLearnProgress>> queryPageList(AiolLearnProgress aiolLearnProgress,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<AiolLearnProgress> queryWrapper = QueryGenerator.initQueryWrapper(aiolLearnProgress, req.getParameterMap());
Page<AiolLearnProgress> page = new Page<AiolLearnProgress>(pageNo, pageSize);
IPage<AiolLearnProgress> pageList = aiolLearnProgressService.page(page, queryWrapper);
return Result.OK(pageList);
}
/**
* 添加
*
* @param aiolLearnProgress
* @return
*/
@AutoLog(value = "学习进度-添加")
@Operation(summary="学习进度-添加")
@RequiresPermissions("aiol:aiol_learn_progress:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody AiolLearnProgress aiolLearnProgress) {
aiolLearnProgressService.save(aiolLearnProgress);
return Result.OK("添加成功!");
}
/**
* 编辑
*
* @param aiolLearnProgress
* @return
*/
@AutoLog(value = "学习进度-编辑")
@Operation(summary="学习进度-编辑")
@RequiresPermissions("aiol:aiol_learn_progress:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<String> edit(@RequestBody AiolLearnProgress aiolLearnProgress) {
aiolLearnProgressService.updateById(aiolLearnProgress);
return Result.OK("编辑成功!");
}
/**
* 通过id删除
*
* @param id
* @return
*/
@AutoLog(value = "学习进度-通过id删除")
@Operation(summary="学习进度-通过id删除")
@RequiresPermissions("aiol:aiol_learn_progress:delete")
@DeleteMapping(value = "/delete")
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
aiolLearnProgressService.removeById(id);
return Result.OK("删除成功!");
}
/**
* 批量删除
*
* @param ids
* @return
*/
@AutoLog(value = "学习进度-批量删除")
@Operation(summary="学习进度-批量删除")
@RequiresPermissions("aiol:aiol_learn_progress:deleteBatch")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
this.aiolLearnProgressService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK("批量删除成功!");
}
/**
* 通过id查询
*
* @param id
* @return
*/
//@AutoLog(value = "学习进度-通过id查询")
@Operation(summary="学习进度-通过id查询")
@GetMapping(value = "/queryById")
public Result<AiolLearnProgress> queryById(@RequestParam(name="id",required=true) String id) {
AiolLearnProgress aiolLearnProgress = aiolLearnProgressService.getById(id);
if(aiolLearnProgress==null) {
return Result.error("未找到对应数据");
}
return Result.OK(aiolLearnProgress);
}
/**
* 导出excel
*
* @param request
* @param aiolLearnProgress
*/
@RequiresPermissions("aiol:aiol_learn_progress:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, AiolLearnProgress aiolLearnProgress) {
return super.exportXls(request, aiolLearnProgress, AiolLearnProgress.class, "学习进度");
}
/**
* 通过excel导入数据
*
* @param request
* @param response
* @return
*/
@RequiresPermissions("aiol:aiol_learn_progress:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, AiolLearnProgress.class);
}
}

View File

@ -0,0 +1,182 @@
package org.jeecg.modules.aiol.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.aiol.entity.AiolQuestion;
import org.jeecg.modules.aiol.service.IAiolQuestionService;
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-31
* @Version: V1.0
*/
@Tag(name="题目")
@RestController
@RequestMapping("/aiol/aiolQuestion")
@Slf4j
public class AiolQuestionController extends JeecgController<AiolQuestion, IAiolQuestionService> {
@Autowired
private IAiolQuestionService aiolQuestionService;
/**
* 分页列表查询
*
* @param aiolQuestion
* @param pageNo
* @param pageSize
* @param req
* @return
*/
//@AutoLog(value = "题目-分页列表查询")
@Operation(summary="题目-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<AiolQuestion>> queryPageList(AiolQuestion aiolQuestion,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<AiolQuestion> queryWrapper = QueryGenerator.initQueryWrapper(aiolQuestion, req.getParameterMap());
Page<AiolQuestion> page = new Page<AiolQuestion>(pageNo, pageSize);
IPage<AiolQuestion> pageList = aiolQuestionService.page(page, queryWrapper);
return Result.OK(pageList);
}
/**
* 添加
*
* @param aiolQuestion
* @return
*/
@AutoLog(value = "题目-添加")
@Operation(summary="题目-添加")
@RequiresPermissions("aiol:aiol_question:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody AiolQuestion aiolQuestion) {
aiolQuestionService.save(aiolQuestion);
return Result.OK("添加成功!");
}
/**
* 编辑
*
* @param aiolQuestion
* @return
*/
@AutoLog(value = "题目-编辑")
@Operation(summary="题目-编辑")
@RequiresPermissions("aiol:aiol_question:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<String> edit(@RequestBody AiolQuestion aiolQuestion) {
aiolQuestionService.updateById(aiolQuestion);
return Result.OK("编辑成功!");
}
/**
* 通过id删除
*
* @param id
* @return
*/
@AutoLog(value = "题目-通过id删除")
@Operation(summary="题目-通过id删除")
@RequiresPermissions("aiol:aiol_question:delete")
@DeleteMapping(value = "/delete")
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
aiolQuestionService.removeById(id);
return Result.OK("删除成功!");
}
/**
* 批量删除
*
* @param ids
* @return
*/
@AutoLog(value = "题目-批量删除")
@Operation(summary="题目-批量删除")
@RequiresPermissions("aiol:aiol_question:deleteBatch")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
this.aiolQuestionService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK("批量删除成功!");
}
/**
* 通过id查询
*
* @param id
* @return
*/
//@AutoLog(value = "题目-通过id查询")
@Operation(summary="题目-通过id查询")
@GetMapping(value = "/queryById")
public Result<AiolQuestion> queryById(@RequestParam(name="id",required=true) String id) {
AiolQuestion aiolQuestion = aiolQuestionService.getById(id);
if(aiolQuestion==null) {
return Result.error("未找到对应数据");
}
return Result.OK(aiolQuestion);
}
/**
* 导出excel
*
* @param request
* @param aiolQuestion
*/
@RequiresPermissions("aiol:aiol_question:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, AiolQuestion aiolQuestion) {
return super.exportXls(request, aiolQuestion, AiolQuestion.class, "题目");
}
/**
* 通过excel导入数据
*
* @param request
* @param response
* @return
*/
@RequiresPermissions("aiol:aiol_question:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, AiolQuestion.class);
}
}

View File

@ -0,0 +1,182 @@
package org.jeecg.modules.aiol.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.aiol.entity.AiolResource;
import org.jeecg.modules.aiol.service.IAiolResourceService;
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-31
* @Version: V1.0
*/
@Tag(name="资源")
@RestController
@RequestMapping("/aiol/aiolResource")
@Slf4j
public class AiolResourceController extends JeecgController<AiolResource, IAiolResourceService> {
@Autowired
private IAiolResourceService aiolResourceService;
/**
* 分页列表查询
*
* @param aiolResource
* @param pageNo
* @param pageSize
* @param req
* @return
*/
//@AutoLog(value = "资源-分页列表查询")
@Operation(summary="资源-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<AiolResource>> queryPageList(AiolResource aiolResource,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<AiolResource> queryWrapper = QueryGenerator.initQueryWrapper(aiolResource, req.getParameterMap());
Page<AiolResource> page = new Page<AiolResource>(pageNo, pageSize);
IPage<AiolResource> pageList = aiolResourceService.page(page, queryWrapper);
return Result.OK(pageList);
}
/**
* 添加
*
* @param aiolResource
* @return
*/
@AutoLog(value = "资源-添加")
@Operation(summary="资源-添加")
@RequiresPermissions("aiol:aiol_resource:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody AiolResource aiolResource) {
aiolResourceService.save(aiolResource);
return Result.OK("添加成功!");
}
/**
* 编辑
*
* @param aiolResource
* @return
*/
@AutoLog(value = "资源-编辑")
@Operation(summary="资源-编辑")
@RequiresPermissions("aiol:aiol_resource:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<String> edit(@RequestBody AiolResource aiolResource) {
aiolResourceService.updateById(aiolResource);
return Result.OK("编辑成功!");
}
/**
* 通过id删除
*
* @param id
* @return
*/
@AutoLog(value = "资源-通过id删除")
@Operation(summary="资源-通过id删除")
@RequiresPermissions("aiol:aiol_resource:delete")
@DeleteMapping(value = "/delete")
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
aiolResourceService.removeById(id);
return Result.OK("删除成功!");
}
/**
* 批量删除
*
* @param ids
* @return
*/
@AutoLog(value = "资源-批量删除")
@Operation(summary="资源-批量删除")
@RequiresPermissions("aiol:aiol_resource:deleteBatch")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
this.aiolResourceService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK("批量删除成功!");
}
/**
* 通过id查询
*
* @param id
* @return
*/
//@AutoLog(value = "资源-通过id查询")
@Operation(summary="资源-通过id查询")
@GetMapping(value = "/queryById")
public Result<AiolResource> queryById(@RequestParam(name="id",required=true) String id) {
AiolResource aiolResource = aiolResourceService.getById(id);
if(aiolResource==null) {
return Result.error("未找到对应数据");
}
return Result.OK(aiolResource);
}
/**
* 导出excel
*
* @param request
* @param aiolResource
*/
@RequiresPermissions("aiol:aiol_resource:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, AiolResource aiolResource) {
return super.exportXls(request, aiolResource, AiolResource.class, "资源");
}
/**
* 通过excel导入数据
*
* @param request
* @param response
* @return
*/
@RequiresPermissions("aiol:aiol_resource:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, AiolResource.class);
}
}

View File

@ -0,0 +1,182 @@
package org.jeecg.modules.aiol.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.aiol.entity.AiolUserInfo;
import org.jeecg.modules.aiol.service.IAiolUserInfoService;
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-31
* @Version: V1.0
*/
@Tag(name="用户信息")
@RestController
@RequestMapping("/aiol/aiolUserInfo")
@Slf4j
public class AiolUserInfoController extends JeecgController<AiolUserInfo, IAiolUserInfoService> {
@Autowired
private IAiolUserInfoService aiolUserInfoService;
/**
* 分页列表查询
*
* @param aiolUserInfo
* @param pageNo
* @param pageSize
* @param req
* @return
*/
//@AutoLog(value = "用户信息-分页列表查询")
@Operation(summary="用户信息-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<AiolUserInfo>> queryPageList(AiolUserInfo aiolUserInfo,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<AiolUserInfo> queryWrapper = QueryGenerator.initQueryWrapper(aiolUserInfo, req.getParameterMap());
Page<AiolUserInfo> page = new Page<AiolUserInfo>(pageNo, pageSize);
IPage<AiolUserInfo> pageList = aiolUserInfoService.page(page, queryWrapper);
return Result.OK(pageList);
}
/**
* 添加
*
* @param aiolUserInfo
* @return
*/
@AutoLog(value = "用户信息-添加")
@Operation(summary="用户信息-添加")
@RequiresPermissions("aiol:aiol_user_info:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody AiolUserInfo aiolUserInfo) {
aiolUserInfoService.save(aiolUserInfo);
return Result.OK("添加成功!");
}
/**
* 编辑
*
* @param aiolUserInfo
* @return
*/
@AutoLog(value = "用户信息-编辑")
@Operation(summary="用户信息-编辑")
@RequiresPermissions("aiol:aiol_user_info:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<String> edit(@RequestBody AiolUserInfo aiolUserInfo) {
aiolUserInfoService.updateById(aiolUserInfo);
return Result.OK("编辑成功!");
}
/**
* 通过id删除
*
* @param id
* @return
*/
@AutoLog(value = "用户信息-通过id删除")
@Operation(summary="用户信息-通过id删除")
@RequiresPermissions("aiol:aiol_user_info:delete")
@DeleteMapping(value = "/delete")
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
aiolUserInfoService.removeById(id);
return Result.OK("删除成功!");
}
/**
* 批量删除
*
* @param ids
* @return
*/
@AutoLog(value = "用户信息-批量删除")
@Operation(summary="用户信息-批量删除")
@RequiresPermissions("aiol:aiol_user_info:deleteBatch")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
this.aiolUserInfoService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK("批量删除成功!");
}
/**
* 通过id查询
*
* @param id
* @return
*/
//@AutoLog(value = "用户信息-通过id查询")
@Operation(summary="用户信息-通过id查询")
@GetMapping(value = "/queryById")
public Result<AiolUserInfo> queryById(@RequestParam(name="id",required=true) String id) {
AiolUserInfo aiolUserInfo = aiolUserInfoService.getById(id);
if(aiolUserInfo==null) {
return Result.error("未找到对应数据");
}
return Result.OK(aiolUserInfo);
}
/**
* 导出excel
*
* @param request
* @param aiolUserInfo
*/
@RequiresPermissions("aiol:aiol_user_info:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, AiolUserInfo aiolUserInfo) {
return super.exportXls(request, aiolUserInfo, AiolUserInfo.class, "用户信息");
}
/**
* 通过excel导入数据
*
* @param request
* @param response
* @return
*/
@RequiresPermissions("aiol:aiol_user_info:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, AiolUserInfo.class);
}
}

View File

@ -0,0 +1,20 @@
package org.jeecg.modules.aiol.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.jeecg.modules.aiol.entity.AiolComment;
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(description = "评论信息(包含用户信息)")
public class CommentWithUserInfo extends AiolComment {
@Schema(description = "用户姓名")
private String userName;
@Schema(description = "用户头像")
private String userAvatar;
@Schema(description = "用户标签")
private String userTag;
}

View File

@ -0,0 +1,16 @@
package org.jeecg.modules.aiol.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.jeecg.modules.aiol.entity.AiolCourse;
import java.util.List;
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(description = "课程信息(包含讲师信息)")
public class CourseWithTeacherInfo extends AiolCourse {
@Schema(description = "授课讲师列表")
private List<TeacherInfo> teacherList;
}

View File

@ -0,0 +1,17 @@
package org.jeecg.modules.aiol.dto;
import lombok.Data;
import org.jeecg.modules.aiol.entity.AiolQuestion;
import java.util.ArrayList;
import java.util.List;
@Data
public class QuestionAnswerDTO {
//题目内容
private AiolQuestion question;
//答案
private List<?> answer;
//子题目列表
private List<QuestionAnswerDTO> children = new ArrayList<>();
}

View File

@ -0,0 +1,25 @@
package org.jeecg.modules.aiol.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;
}

View File

@ -0,0 +1,26 @@
package org.jeecg.modules.aiol.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;
}

View File

@ -0,0 +1,74 @@
package org.jeecg.modules.aiol.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;
}
}

View File

@ -0,0 +1,84 @@
package org.jeecg.modules.aiol.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-31
* @Version: V1.0
*/
@Data
@TableName("aiol_comment")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@Schema(description="评论")
public class AiolComment 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;
}

View File

@ -0,0 +1,140 @@
package org.jeecg.modules.aiol.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-31
* @Version: V1.0
*/
@Data
@TableName("aiol_course")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@Schema(description="课程")
public class AiolCourse implements Serializable {
private static final long serialVersionUID = 1L;
/**主键*/
@TableId(type = IdType.ASSIGN_ID)
@Schema(description = "主键")
private String id;
/**课程名*/
@Excel(name = "课程名", width = 15)
@Schema(description = "课程名")
private String name;
/**封面图*/
@Excel(name = "封面图", width = 15)
@Schema(description = "封面图")
private String cover;
/**介绍视频*/
@Excel(name = "介绍视频", width = 15)
@Schema(description = "介绍视频")
private String video;
/**学校*/
@Excel(name = "学校", width = 15)
@Schema(description = "学校")
private String school;
/**课程概述*/
@Excel(name = "课程概述", width = 15)
@Schema(description = "课程概述")
private String description;
/**课程类型*/
@Excel(name = "课程类型", width = 15, dicCode = "course_type")
@Dict(dicCode = "course_type")
@Schema(description = "课程类型")
private Integer type;
/**授课目标*/
@Excel(name = "授课目标", width = 15)
@Schema(description = "授课目标")
private String target;
/**课程难度*/
@Excel(name = "课程难度", width = 15, dicCode = "course_difficulty")
@Dict(dicCode = "course_difficulty")
@Schema(description = "课程难度")
private Integer difficulty;
/**所属专题*/
@Excel(name = "所属专题", width = 15, dicCode = "course_subject")
@Dict(dicCode = "course_subject")
@Schema(description = "所属专题")
private String subject;
/**课程大纲*/
@Excel(name = "课程大纲", width = 15)
@Schema(description = "课程大纲")
private String outline;
/**预备知识*/
@Excel(name = "预备知识", width = 15)
@Schema(description = "预备知识")
private String prerequisite;
/**参考资料*/
@Excel(name = "参考资料", width = 15)
@Schema(description = "参考资料")
private String reference;
/**学时安排*/
@Excel(name = "学时安排", width = 15)
@Schema(description = "学时安排")
private 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 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 Date endTime;
/**已报名人数*/
@Excel(name = "已报名人数", width = 15)
@Schema(description = "已报名人数")
private Integer enrollCount;
/**最大报名人数*/
@Excel(name = "最大报名人数", width = 15)
@Schema(description = "最大报名人数")
private Integer maxEnroll;
/**状态*/
@Excel(name = "状态", width = 15, dicCode = "course_status")
@Dict(dicCode = "course_status")
@Schema(description = "状态")
private Integer status;
/**常见问题*/
@Excel(name = "常见问题", width = 15)
@Schema(description = "常见问题")
private String question;
/**创建人*/
@Schema(description = "创建人")
private String createBy;
/**创建时间*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@Schema(description = "创建时间")
private Date createTime;
/**更新人*/
@Schema(description = "更新人")
private String updateBy;
/**更新时间*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@Schema(description = "更新时间")
private Date updateTime;
}

View File

@ -0,0 +1,64 @@
package org.jeecg.modules.aiol.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-31
* @Version: V1.0
*/
@Data
@TableName("aiol_course_category")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@Schema(description="课程分类")
public class AiolCourseCategory 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;
}

View File

@ -0,0 +1,82 @@
package org.jeecg.modules.aiol.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-31
* @Version: V1.0
*/
@Data
@TableName("aiol_course_section")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@Schema(description="课程章节")
public class AiolCourseSection 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;
}

View File

@ -0,0 +1,64 @@
package org.jeecg.modules.aiol.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-31
* @Version: V1.0
*/
@Data
@TableName("aiol_course_signup")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@Schema(description="课程报名")
public class AiolCourseSignup 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;
}

View File

@ -0,0 +1,73 @@
package org.jeecg.modules.aiol.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-31
* @Version: V1.0
*/
@Data
@TableName("aiol_course_teacher")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@Schema(description="授课教师")
public class AiolCourseTeacher 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;
}

View File

@ -0,0 +1,68 @@
package org.jeecg.modules.aiol.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-31
* @Version: V1.0
*/
@Data
@TableName("aiol_entity_link")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@Schema(description="主体绑定")
public class AiolEntityLink 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;
}

View File

@ -0,0 +1,93 @@
package org.jeecg.modules.aiol.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-31
* @Version: V1.0
*/
@Data
@TableName("aiol_homework")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@Schema(description="作业")
public class AiolHomework 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 description;
/**附件*/
@Excel(name = "附件", width = 15)
@Schema(description = "附件")
private java.lang.String attachment;
/**满分*/
@Excel(name = "满分", width = 15)
@Schema(description = "满分")
private java.lang.Integer maxScore;
/**及格分数*/
@Excel(name = "及格分数", width = 15)
@Schema(description = "及格分数")
private java.lang.Integer passScore;
/**开始时间*/
@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, dicCode = "course_status")
@Dict(dicCode = "course_status")
@Schema(description = "状态")
private java.lang.Integer 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;
}

View File

@ -0,0 +1,80 @@
package org.jeecg.modules.aiol.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-31
* @Version: V1.0
*/
@Data
@TableName("aiol_learn_progress")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@Schema(description="学习进度")
public class AiolLearnProgress 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;
/**章节id*/
@Excel(name = "章节id", width = 15)
@Schema(description = "章节id")
private java.lang.String sectionId;
/**进度*/
@Excel(name = "进度", width = 15)
@Schema(description = "进度")
private java.lang.Integer progress;
/**时长*/
@Excel(name = "时长", width = 15)
@Schema(description = "时长")
private java.lang.Integer duration;
/**状态*/
@Excel(name = "状态", width = 15)
@Schema(description = "状态")
private java.lang.Integer 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;
}

View File

@ -0,0 +1,82 @@
package org.jeecg.modules.aiol.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-31
* @Version: V1.0
*/
@Data
@TableName("aiol_question")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@Schema(description="题目")
public class AiolQuestion 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 parentId;
/**题目类型*/
@Excel(name = "题目类型", width = 15, dicCode = "question_type")
@Dict(dicCode = "question_type")
@Schema(description = "题目类型")
private java.lang.Integer type;
/**题干*/
@Excel(name = "题干", width = 15)
@Schema(description = "题干")
private java.lang.String content;
/**题目解析*/
@Excel(name = "题目解析", width = 15)
@Schema(description = "题目解析")
private java.lang.String analysis;
/**难度*/
@Excel(name = "难度", width = 15, dicCode = "question_difficulty")
@Dict(dicCode = "question_difficulty")
@Schema(description = "难度")
private java.lang.Integer difficulty;
/**分值*/
@Excel(name = "分值", width = 15)
@Schema(description = "分值")
private java.lang.Integer score;
/**创建人*/
@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;
}

View File

@ -0,0 +1,103 @@
package org.jeecg.modules.aiol.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-31
* @Version: V1.0
*/
@Data
@TableName("aiol_resource")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@Schema(description="资源")
public class AiolResource 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 description;
/**资源类型*/
@Excel(name = "资源类型", width = 15, dicCode = "resource_type")
@Dict(dicCode = "resource_type")
@Schema(description = "资源类型")
private java.lang.Integer type;
/**文件url*/
@Excel(name = "文件url", width = 15)
@Schema(description = "文件url")
private java.lang.String fileUrl;
/**缩略图url*/
@Excel(name = "缩略图url", width = 15)
@Schema(description = "缩略图url")
private java.lang.String thumbnailUrl;
/**时长*/
@Excel(name = "时长", width = 15)
@Schema(description = "时长")
private java.lang.Integer duration;
/**文件大小*/
@Excel(name = "文件大小", width = 15)
@Schema(description = "文件大小")
private java.lang.Integer fileSize;
/**文件元数据*/
@Excel(name = "文件元数据", width = 15)
@Schema(description = "文件元数据")
private java.lang.String metadata;
/**是否精选*/
@Excel(name = "是否精选", width = 15, dicCode = "resource_iz_featured")
@Dict(dicCode = "resource_iz_featured")
@Schema(description = "是否精选")
private java.lang.Integer izFeatured;
/**状态*/
@Excel(name = "状态", width = 15, dicCode = "resource_status")
@Dict(dicCode = "resource_status")
@Schema(description = "状态")
private java.lang.Integer status;
/**创建人*/
@Excel(name = "创建人", width = 15)
@Schema(description = "创建人")
private java.lang.String createdBy;
/**创建时间*/
@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 createdTime;
/**更新人*/
@Excel(name = "更新人", width = 15)
@Schema(description = "更新人")
private java.lang.String updatedBy;
/**更新时间*/
@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 updatedTime;
}

View File

@ -0,0 +1,84 @@
package org.jeecg.modules.aiol.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-31
* @Version: V1.0
*/
@Data
@TableName("aiol_user_info")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@Schema(description="用户信息")
public class AiolUserInfo 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 major;
/**学院*/
@Excel(name = "学院", width = 15)
@Schema(description = "学院")
private java.lang.String college;
/**学历*/
@Excel(name = "学历", width = 15)
@Schema(description = "学历")
private java.lang.String education;
/**职称*/
@Excel(name = "职称", width = 15)
@Schema(description = "职称")
private java.lang.String title;
/**标签*/
@Excel(name = "标签", width = 15)
@Schema(description = "标签")
private java.lang.String tag;
/**显示顺序*/
@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;
}

View File

@ -0,0 +1,17 @@
package org.jeecg.modules.aiol.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.aiol.entity.AiolComment;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @Description: 评论
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
public interface AiolCommentMapper extends BaseMapper<AiolComment> {
}

View File

@ -0,0 +1,17 @@
package org.jeecg.modules.aiol.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.aiol.entity.AiolCourseCategory;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @Description: 课程分类
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
public interface AiolCourseCategoryMapper extends BaseMapper<AiolCourseCategory> {
}

View File

@ -0,0 +1,17 @@
package org.jeecg.modules.aiol.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.aiol.entity.AiolCourse;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @Description: 课程
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
public interface AiolCourseMapper extends BaseMapper<AiolCourse> {
}

View File

@ -0,0 +1,17 @@
package org.jeecg.modules.aiol.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.aiol.entity.AiolCourseSection;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @Description: 课程章节
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
public interface AiolCourseSectionMapper extends BaseMapper<AiolCourseSection> {
}

View File

@ -0,0 +1,17 @@
package org.jeecg.modules.aiol.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.aiol.entity.AiolCourseSignup;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @Description: 课程报名
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
public interface AiolCourseSignupMapper extends BaseMapper<AiolCourseSignup> {
}

View File

@ -0,0 +1,17 @@
package org.jeecg.modules.aiol.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.aiol.entity.AiolCourseTeacher;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @Description: 授课教师
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
public interface AiolCourseTeacherMapper extends BaseMapper<AiolCourseTeacher> {
}

View File

@ -0,0 +1,17 @@
package org.jeecg.modules.aiol.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.aiol.entity.AiolEntityLink;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @Description: 主体绑定
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
public interface AiolEntityLinkMapper extends BaseMapper<AiolEntityLink> {
}

View File

@ -0,0 +1,17 @@
package org.jeecg.modules.aiol.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.aiol.entity.AiolHomework;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @Description: 作业
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
public interface AiolHomeworkMapper extends BaseMapper<AiolHomework> {
}

View File

@ -0,0 +1,17 @@
package org.jeecg.modules.aiol.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.aiol.entity.AiolLearnProgress;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @Description: 学习进度
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
public interface AiolLearnProgressMapper extends BaseMapper<AiolLearnProgress> {
}

View File

@ -0,0 +1,17 @@
package org.jeecg.modules.aiol.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.aiol.entity.AiolQuestion;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @Description: 题目
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
public interface AiolQuestionMapper extends BaseMapper<AiolQuestion> {
}

View File

@ -0,0 +1,17 @@
package org.jeecg.modules.aiol.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.aiol.entity.AiolResource;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @Description: 资源
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
public interface AiolResourceMapper extends BaseMapper<AiolResource> {
}

View File

@ -0,0 +1,17 @@
package org.jeecg.modules.aiol.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.aiol.entity.AiolUserInfo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @Description: 用户信息
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
public interface AiolUserInfoMapper extends BaseMapper<AiolUserInfo> {
}

View File

@ -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.aiol.mapper.AiolCommentMapper">
</mapper>

View File

@ -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.aiol.mapper.AiolCourseCategoryMapper">
</mapper>

View File

@ -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.aiol.mapper.AiolCourseMapper">
</mapper>

View File

@ -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.aiol.mapper.AiolCourseSectionMapper">
</mapper>

View File

@ -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.aiol.mapper.AiolCourseSignupMapper">
</mapper>

View File

@ -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.aiol.mapper.AiolCourseTeacherMapper">
</mapper>

View File

@ -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.aiol.mapper.AiolEntityLinkMapper">
</mapper>

View File

@ -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.aiol.mapper.AiolHomeworkMapper">
</mapper>

View File

@ -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.aiol.mapper.AiolLearnProgressMapper">
</mapper>

View File

@ -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.aiol.mapper.AiolQuestionMapper">
</mapper>

View File

@ -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.aiol.mapper.AiolResourceMapper">
</mapper>

View File

@ -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.aiol.mapper.AiolUserInfoMapper">
</mapper>

View File

@ -0,0 +1,14 @@
package org.jeecg.modules.aiol.service;
import org.jeecg.modules.aiol.entity.AiolComment;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @Description: 评论
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
public interface IAiolCommentService extends IService<AiolComment> {
}

View File

@ -0,0 +1,14 @@
package org.jeecg.modules.aiol.service;
import org.jeecg.modules.aiol.entity.AiolCourseCategory;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @Description: 课程分类
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
public interface IAiolCourseCategoryService extends IService<AiolCourseCategory> {
}

View File

@ -0,0 +1,14 @@
package org.jeecg.modules.aiol.service;
import org.jeecg.modules.aiol.entity.AiolCourseSection;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @Description: 课程章节
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
public interface IAiolCourseSectionService extends IService<AiolCourseSection> {
}

View File

@ -0,0 +1,97 @@
package org.jeecg.modules.aiol.service;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.aiol.dto.CourseWithTeacherInfo;
import org.jeecg.modules.aiol.dto.TeacherInfo;
import org.jeecg.modules.aiol.entity.AiolCourse;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.aiol.entity.AiolCourseCategory;
import org.jeecg.modules.aiol.entity.AiolCourseSection;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
/**
* @Description: 课程
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
public interface IAiolCourseService extends IService<AiolCourse> {
/**
* 上传视频并切片为 HLSm3u8+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<AiolCourseCategory> getCourseCategoryList();
/**
* 查询指定课程下的章节列表
* @param courseId
* @return
*/
List<AiolCourseSection> 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);
}

View File

@ -0,0 +1,14 @@
package org.jeecg.modules.aiol.service;
import org.jeecg.modules.aiol.entity.AiolCourseSignup;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @Description: 课程报名
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
public interface IAiolCourseSignupService extends IService<AiolCourseSignup> {
}

View File

@ -0,0 +1,14 @@
package org.jeecg.modules.aiol.service;
import org.jeecg.modules.aiol.entity.AiolCourseTeacher;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @Description: 授课教师
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
public interface IAiolCourseTeacherService extends IService<AiolCourseTeacher> {
}

View File

@ -0,0 +1,32 @@
package org.jeecg.modules.aiol.service;
import org.jeecg.modules.aiol.entity.AiolEntityLink;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* @Description: 主体绑定
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
public interface IAiolEntityLinkService extends IService<AiolEntityLink> {
/**
* 根据主体与内容类型查询绑定的 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);
}

View File

@ -0,0 +1,14 @@
package org.jeecg.modules.aiol.service;
import org.jeecg.modules.aiol.entity.AiolHomework;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @Description: 作业
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
public interface IAiolHomeworkService extends IService<AiolHomework> {
}

View File

@ -0,0 +1,14 @@
package org.jeecg.modules.aiol.service;
import org.jeecg.modules.aiol.entity.AiolLearnProgress;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @Description: 学习进度
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
public interface IAiolLearnProgressService extends IService<AiolLearnProgress> {
}

View File

@ -0,0 +1,14 @@
package org.jeecg.modules.aiol.service;
import org.jeecg.modules.aiol.entity.AiolQuestion;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @Description: 题目
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
public interface IAiolQuestionService extends IService<AiolQuestion> {
}

View File

@ -0,0 +1,14 @@
package org.jeecg.modules.aiol.service;
import org.jeecg.modules.aiol.entity.AiolResource;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @Description: 资源
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
public interface IAiolResourceService extends IService<AiolResource> {
}

View File

@ -0,0 +1,14 @@
package org.jeecg.modules.aiol.service;
import org.jeecg.modules.aiol.entity.AiolUserInfo;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @Description: 用户信息
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
public interface IAiolUserInfoService extends IService<AiolUserInfo> {
}

View File

@ -0,0 +1,19 @@
package org.jeecg.modules.aiol.service.impl;
import org.jeecg.modules.aiol.entity.AiolComment;
import org.jeecg.modules.aiol.mapper.AiolCommentMapper;
import org.jeecg.modules.aiol.service.IAiolCommentService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
/**
* @Description: 评论
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
@Service
public class AiolCommentServiceImpl extends ServiceImpl<AiolCommentMapper, AiolComment> implements IAiolCommentService {
}

View File

@ -0,0 +1,19 @@
package org.jeecg.modules.aiol.service.impl;
import org.jeecg.modules.aiol.entity.AiolCourseCategory;
import org.jeecg.modules.aiol.mapper.AiolCourseCategoryMapper;
import org.jeecg.modules.aiol.service.IAiolCourseCategoryService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
/**
* @Description: 课程分类
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
@Service
public class AiolCourseCategoryServiceImpl extends ServiceImpl<AiolCourseCategoryMapper, AiolCourseCategory> implements IAiolCourseCategoryService {
}

View File

@ -0,0 +1,19 @@
package org.jeecg.modules.aiol.service.impl;
import org.jeecg.modules.aiol.entity.AiolCourseSection;
import org.jeecg.modules.aiol.mapper.AiolCourseSectionMapper;
import org.jeecg.modules.aiol.service.IAiolCourseSectionService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
/**
* @Description: 课程章节
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
@Service
public class AiolCourseSectionServiceImpl extends ServiceImpl<AiolCourseSectionMapper, AiolCourseSection> implements IAiolCourseSectionService {
}

View File

@ -0,0 +1,664 @@
package org.jeecg.modules.aiol.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
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.aiol.constant.EntityLinkConst;
import org.jeecg.modules.aiol.dto.CourseWithTeacherInfo;
import org.jeecg.modules.aiol.dto.TeacherInfo;
import org.jeecg.modules.aiol.entity.*;
import org.jeecg.modules.aiol.mapper.*;
import org.jeecg.modules.aiol.service.IAiolCourseService;
import org.jeecg.modules.aiol.service.IAiolEntityLinkService;
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.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
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;
/**
* @Description: 课程
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
@Service
public class AiolCourseServiceImpl extends ServiceImpl<AiolCourseMapper, AiolCourse> implements IAiolCourseService {
@Autowired
private AiolCourseMapper courseMapper;
@Autowired
private AiolCourseCategoryMapper courseCategoryMapper;
@Autowired
private AiolCourseSectionMapper courseSectionMapper;
@Autowired
private IAiolEntityLinkService entityLinkBizService;
@Autowired
private AiolResourceMapper resourceMapper;
@Autowired
private AiolCourseTeacherMapper courseTeacherMapper;
@Autowired
private AiolUserInfoMapper userInfoMapper;
@Autowired
private SysUserMapper sysUserMapper;
@Autowired
private AiolHomeworkMapper homeworkMapper;
@Autowired
private AiolCourseSignupMapper courseSignupMapper;
@Autowired
private AiolLearnProgressMapper 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. 查询章节是否存在
AiolCourseSection 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<AiolCourseSection> getCourseSectionList(String courseId) {
return courseSectionMapper.selectList(new QueryWrapper<AiolCourseSection>().eq("course_id", courseId));
}
@Override
public List<AiolCourseCategory> getCourseCategoryList() {
return courseCategoryMapper.selectList(null);
}
@Override
public List<CourseWithTeacherInfo> getCourseList(String categoryId, String difficulty, String topic) {
QueryWrapper<AiolCourse> 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<AiolCourse> courseList = courseMapper.selectList(queryWrapper);
// 构建包含讲师信息的课程列表
List<CourseWithTeacherInfo> result = new ArrayList<>();
for (AiolCourse 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<AiolCourseTeacher> list = courseTeacherMapper.selectList(new QueryWrapper<AiolCourseTeacher>().eq("course_id", courseId));
List<TeacherInfo> result = new ArrayList<>();
for (AiolCourseTeacher item : list) {
AiolUserInfo userInfo = userInfoMapper.selectOne(new QueryWrapper<AiolUserInfo>().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. 查询课程是否存在
AiolCourse course = courseMapper.selectById(courseId);
if (course == null) {
throw new RuntimeException("课程不存在");
}
// 3. 检查用户是否已报名
QueryWrapper<AiolCourseSignup> signupQuery = new QueryWrapper<>();
signupQuery.eq("user_id", userId).eq("course_id", courseId);
AiolCourseSignup 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. 创建报名记录
AiolCourseSignup signup = new AiolCourseSignup();
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<AiolCourseSignup> signupQuery = new QueryWrapper<>();
signupQuery.eq("user_id", userId).eq("course_id", courseId);
AiolCourseSignup 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. 查询课程是否存在
AiolCourse 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<AiolCourseSignup> existingQuery = new QueryWrapper<>();
existingQuery.eq("course_id", courseId).in("user_id", validStudentIds);
List<AiolCourseSignup> existingSignups = courseSignupMapper.selectList(existingQuery);
Set<String> alreadyEnrolledIds = new HashSet<>();
for (AiolCourseSignup 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<AiolCourseSignup> newSignups = new ArrayList<>();
Date now = new Date();
for (String studentId : newStudentIds) {
AiolCourseSignup signup = new AiolCourseSignup();
signup.setUserId(studentId);
signup.setCourseId(courseId);
signup.setCreateTime(now);
signup.setCreateBy(teacher.getId());
newSignups.add(signup);
}
// 9. 批量插入报名记录
for (AiolCourseSignup 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<AiolCourseSection> videoSections = getCourseSectionsByType(courseId, 0); // 视频
List<AiolCourseSection> examSections = getCourseSectionsByType(courseId, 2); // 考试
List<AiolCourseSection> 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<AiolCourseSection> getCourseSectionsByType(String courseId, Integer type) {
QueryWrapper<AiolCourseSection> 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<AiolCourseSection> sections) {
if (sections.isEmpty()) {
return 0;
}
List<String> sectionIds = sections.stream()
.map(AiolCourseSection::getId)
.collect(Collectors.toList());
QueryWrapper<AiolLearnProgress> 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);
}
}

View File

@ -0,0 +1,19 @@
package org.jeecg.modules.aiol.service.impl;
import org.jeecg.modules.aiol.entity.AiolCourseSignup;
import org.jeecg.modules.aiol.mapper.AiolCourseSignupMapper;
import org.jeecg.modules.aiol.service.IAiolCourseSignupService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
/**
* @Description: 课程报名
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
@Service
public class AiolCourseSignupServiceImpl extends ServiceImpl<AiolCourseSignupMapper, AiolCourseSignup> implements IAiolCourseSignupService {
}

View File

@ -0,0 +1,19 @@
package org.jeecg.modules.aiol.service.impl;
import org.jeecg.modules.aiol.entity.AiolCourseTeacher;
import org.jeecg.modules.aiol.mapper.AiolCourseTeacherMapper;
import org.jeecg.modules.aiol.service.IAiolCourseTeacherService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
/**
* @Description: 授课教师
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
@Service
public class AiolCourseTeacherServiceImpl extends ServiceImpl<AiolCourseTeacherMapper, AiolCourseTeacher> implements IAiolCourseTeacherService {
}

View File

@ -0,0 +1,44 @@
package org.jeecg.modules.aiol.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.jeecg.modules.aiol.entity.AiolEntityLink;
import org.jeecg.modules.aiol.mapper.AiolEntityLinkMapper;
import org.jeecg.modules.aiol.service.IAiolEntityLinkService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.List;
import java.util.stream.Collectors;
/**
* @Description: 主体绑定
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
@Service
public class AiolEntityLinkServiceImpl extends ServiceImpl<AiolEntityLinkMapper, AiolEntityLink> implements IAiolEntityLinkService {
@Override
public List<String> listTargetIds(String sourceType, String sourceId, String targetType) {
LambdaQueryWrapper<AiolEntityLink> qw = new LambdaQueryWrapper<>();
qw.eq(AiolEntityLink::getSourceType, sourceType)
.eq(AiolEntityLink::getSourceId, sourceId)
.eq(AiolEntityLink::getTargetType, targetType)
.select(AiolEntityLink::getTargetId);
return this.list(qw).stream()
.map(AiolEntityLink::getTargetId)
.distinct()
.collect(Collectors.toList());
}
@Override
public void save(String sourceType, String sourceId, String targetType, String targetId) {
AiolEntityLink entityLink = new AiolEntityLink();
entityLink.setSourceType(sourceType);
entityLink.setSourceId(sourceId);
entityLink.setTargetType(targetType);
entityLink.setTargetId(targetId);
this.save(entityLink);
}
}

View File

@ -0,0 +1,19 @@
package org.jeecg.modules.aiol.service.impl;
import org.jeecg.modules.aiol.entity.AiolHomework;
import org.jeecg.modules.aiol.mapper.AiolHomeworkMapper;
import org.jeecg.modules.aiol.service.IAiolHomeworkService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
/**
* @Description: 作业
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
@Service
public class AiolHomeworkServiceImpl extends ServiceImpl<AiolHomeworkMapper, AiolHomework> implements IAiolHomeworkService {
}

View File

@ -0,0 +1,19 @@
package org.jeecg.modules.aiol.service.impl;
import org.jeecg.modules.aiol.entity.AiolLearnProgress;
import org.jeecg.modules.aiol.mapper.AiolLearnProgressMapper;
import org.jeecg.modules.aiol.service.IAiolLearnProgressService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
/**
* @Description: 学习进度
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
@Service
public class AiolLearnProgressServiceImpl extends ServiceImpl<AiolLearnProgressMapper, AiolLearnProgress> implements IAiolLearnProgressService {
}

View File

@ -0,0 +1,19 @@
package org.jeecg.modules.aiol.service.impl;
import org.jeecg.modules.aiol.entity.AiolQuestion;
import org.jeecg.modules.aiol.mapper.AiolQuestionMapper;
import org.jeecg.modules.aiol.service.IAiolQuestionService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
/**
* @Description: 题目
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
@Service
public class AiolQuestionServiceImpl extends ServiceImpl<AiolQuestionMapper, AiolQuestion> implements IAiolQuestionService {
}

View File

@ -0,0 +1,19 @@
package org.jeecg.modules.aiol.service.impl;
import org.jeecg.modules.aiol.entity.AiolResource;
import org.jeecg.modules.aiol.mapper.AiolResourceMapper;
import org.jeecg.modules.aiol.service.IAiolResourceService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
/**
* @Description: 资源
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
@Service
public class AiolResourceServiceImpl extends ServiceImpl<AiolResourceMapper, AiolResource> implements IAiolResourceService {
}

View File

@ -0,0 +1,19 @@
package org.jeecg.modules.aiol.service.impl;
import org.jeecg.modules.aiol.entity.AiolUserInfo;
import org.jeecg.modules.aiol.mapper.AiolUserInfoMapper;
import org.jeecg.modules.aiol.service.IAiolUserInfoService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
/**
* @Description: 用户信息
* @Author: jeecg-boot
* @Date: 2025-08-31
* @Version: V1.0
*/
@Service
public class AiolUserInfoServiceImpl extends ServiceImpl<AiolUserInfoMapper, AiolUserInfo> implements IAiolUserInfoService {
}

View File

@ -0,0 +1,119 @@
<template>
<view>
<!--标题和返回-->
<cu-custom :bgColor="NavBarColor" isBack :backRouterName="backRouteName">
<block slot="backText">返回</block>
<block slot="content">评论</block>
</cu-custom>
<!--表单区域-->
<view>
<form>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">用户id</text></view>
<input placeholder="请输入用户id" v-model="model.userId"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">目标类型</text></view>
<input placeholder="请输入目标类型" v-model="model.targetType"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">目标id</text></view>
<input placeholder="请输入目标id" v-model="model.targetId"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">内容</text></view>
<input placeholder="请输入内容" v-model="model.content"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">图片</text></view>
<input placeholder="请输入图片" v-model="model.imgs"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">是否置顶</text></view>
<input type="number" placeholder="请输入是否置顶" v-model="model.izTop"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">点赞数</text></view>
<input type="number" placeholder="请输入点赞数" v-model="model.likeCount"/>
</view>
</view>
<view class="padding">
<button class="cu-btn block bg-blue margin-tb-sm lg" @click="onSubmit">
<text v-if="loading" class="cuIcon-loading2 cuIconfont-spin"></text>提交
</button>
</view>
</form>
</view>
</view>
</template>
<script>
import myDate from '@/components/my-componets/my-date.vue'
export default {
name: "AiolCommentForm",
components:{ myDate },
props:{
formData:{
type:Object,
default:()=>{},
required:false
}
},
data(){
return {
CustomBar: this.CustomBar,
NavBarColor: this.NavBarColor,
loading:false,
model: {},
backRouteName:'index',
url: {
queryById: "/aiol/aiolComment/queryById",
add: "/aiol/aiolComment/add",
edit: "/aiol/aiolComment/edit",
},
}
},
created(){
this.initFormData();
},
methods:{
initFormData(){
if(this.formData){
let dataId = this.formData.dataId;
this.$http.get(this.url.queryById,{params:{id:dataId}}).then((res)=>{
if(res.data.success){
console.log("表单数据",res);
this.model = res.data.result;
}
})
}
},
onSubmit() {
let myForm = {...this.model};
this.loading = true;
let url = myForm.id?this.url.edit:this.url.add;
this.$http.post(url,myForm).then(res=>{
console.log("res",res)
this.loading = false
this.$Router.push({name:this.backRouteName})
}).catch(()=>{
this.loading = false
});
}
}
}
</script>

View File

@ -0,0 +1,44 @@
<template>
<view>
<!--标题和返回-->
<cu-custom :bgColor="NavBarColor" isBack>
<block slot="backText">返回</block>
<block slot="content">评论</block>
</cu-custom>
<!--滚动加载列表-->
<mescroll-body ref="mescrollRef" bottom="88" @init="mescrollInit" :up="upOption" :down="downOption" @down="downCallback" @up="upCallback">
<view class="cu-list menu">
<view class="cu-item" v-for="(item,index) in list" :key="index" @click="goHome">
<view class="flex" style="width:100%">
<text class="text-lg" style="color: #000;">
{{ item.createBy}}
</text>
</view>
</view>
</view>
</mescroll-body>
</view>
</template>
<script>
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
import Mixin from "@/common/mixin/Mixin.js";
export default {
name: '评论',
mixins: [MescrollMixin,Mixin],
data() {
return {
CustomBar:this.CustomBar,
NavBarColor:this.NavBarColor,
url: "/aiol/aiolComment/list",
};
},
methods: {
goHome(){
this.$Router.push({name: "index"})
}
}
}
</script>

View File

@ -0,0 +1,89 @@
<template>
<view>
<!--标题和返回-->
<cu-custom :bgColor="NavBarColor" isBack :backRouterName="backRouteName">
<block slot="backText">返回</block>
<block slot="content">课程分类</block>
</cu-custom>
<!--表单区域-->
<view>
<form>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">分类名</text></view>
<input placeholder="请输入分类名" v-model="model.name"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">排序</text></view>
<input type="number" placeholder="请输入排序" v-model="model.sortOrder"/>
</view>
</view>
<view class="padding">
<button class="cu-btn block bg-blue margin-tb-sm lg" @click="onSubmit">
<text v-if="loading" class="cuIcon-loading2 cuIconfont-spin"></text>提交
</button>
</view>
</form>
</view>
</view>
</template>
<script>
import myDate from '@/components/my-componets/my-date.vue'
export default {
name: "AiolCourseCategoryForm",
components:{ myDate },
props:{
formData:{
type:Object,
default:()=>{},
required:false
}
},
data(){
return {
CustomBar: this.CustomBar,
NavBarColor: this.NavBarColor,
loading:false,
model: {},
backRouteName:'index',
url: {
queryById: "/aiol/aiolCourseCategory/queryById",
add: "/aiol/aiolCourseCategory/add",
edit: "/aiol/aiolCourseCategory/edit",
},
}
},
created(){
this.initFormData();
},
methods:{
initFormData(){
if(this.formData){
let dataId = this.formData.dataId;
this.$http.get(this.url.queryById,{params:{id:dataId}}).then((res)=>{
if(res.data.success){
console.log("表单数据",res);
this.model = res.data.result;
}
})
}
},
onSubmit() {
let myForm = {...this.model};
this.loading = true;
let url = myForm.id?this.url.edit:this.url.add;
this.$http.post(url,myForm).then(res=>{
console.log("res",res)
this.loading = false
this.$Router.push({name:this.backRouteName})
}).catch(()=>{
this.loading = false
});
}
}
}
</script>

View File

@ -0,0 +1,44 @@
<template>
<view>
<!--标题和返回-->
<cu-custom :bgColor="NavBarColor" isBack>
<block slot="backText">返回</block>
<block slot="content">课程分类</block>
</cu-custom>
<!--滚动加载列表-->
<mescroll-body ref="mescrollRef" bottom="88" @init="mescrollInit" :up="upOption" :down="downOption" @down="downCallback" @up="upCallback">
<view class="cu-list menu">
<view class="cu-item" v-for="(item,index) in list" :key="index" @click="goHome">
<view class="flex" style="width:100%">
<text class="text-lg" style="color: #000;">
{{ item.createBy}}
</text>
</view>
</view>
</view>
</mescroll-body>
</view>
</template>
<script>
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
import Mixin from "@/common/mixin/Mixin.js";
export default {
name: '课程分类',
mixins: [MescrollMixin,Mixin],
data() {
return {
CustomBar:this.CustomBar,
NavBarColor:this.NavBarColor,
url: "/aiol/aiolCourseCategory/list",
};
},
methods: {
goHome(){
this.$Router.push({name: "index"})
}
}
}
</script>

View File

@ -0,0 +1,181 @@
<template>
<view>
<!--标题和返回-->
<cu-custom :bgColor="NavBarColor" isBack :backRouterName="backRouteName">
<block slot="backText">返回</block>
<block slot="content">课程</block>
</cu-custom>
<!--表单区域-->
<view>
<form>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">课程名</text></view>
<input placeholder="请输入课程名" v-model="model.name"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">封面图</text></view>
<input placeholder="请输入封面图" v-model="model.cover"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">介绍视频</text></view>
<input placeholder="请输入介绍视频" v-model="model.video"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">学校</text></view>
<input placeholder="请输入学校" v-model="model.school"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">课程概述</text></view>
<input placeholder="请输入课程概述" v-model="model.description"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">课程类型</text></view>
<input type="number" placeholder="请输入课程类型" v-model="model.type"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">授课目标</text></view>
<input placeholder="请输入授课目标" v-model="model.target"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">课程难度</text></view>
<input type="number" placeholder="请输入课程难度" v-model="model.difficulty"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">所属专题</text></view>
<input placeholder="请输入所属专题" v-model="model.subject"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">课程大纲</text></view>
<input placeholder="请输入课程大纲" v-model="model.outline"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">预备知识</text></view>
<input placeholder="请输入预备知识" v-model="model.prerequisite"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">参考资料</text></view>
<input placeholder="请输入参考资料" v-model="model.reference"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">学时安排</text></view>
<input placeholder="请输入学时安排" v-model="model.arrangement"/>
</view>
</view>
<my-date label="开课时间:" v-model="model.startTime" placeholder="请输入开课时间"></my-date>
<my-date label="结课时间:" v-model="model.endTime" placeholder="请输入结课时间"></my-date>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">已报名人数</text></view>
<input type="number" placeholder="请输入已报名人数" v-model="model.enrollCount"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">最大报名人数</text></view>
<input type="number" placeholder="请输入最大报名人数" v-model="model.maxEnroll"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">状态</text></view>
<input type="number" placeholder="请输入状态" v-model="model.status"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">常见问题</text></view>
<input placeholder="请输入常见问题" v-model="model.question"/>
</view>
</view>
<view class="padding">
<button class="cu-btn block bg-blue margin-tb-sm lg" @click="onSubmit">
<text v-if="loading" class="cuIcon-loading2 cuIconfont-spin"></text>提交
</button>
</view>
</form>
</view>
</view>
</template>
<script>
import myDate from '@/components/my-componets/my-date.vue'
export default {
name: "AiolCourseForm",
components:{ myDate },
props:{
formData:{
type:Object,
default:()=>{},
required:false
}
},
data(){
return {
CustomBar: this.CustomBar,
NavBarColor: this.NavBarColor,
loading:false,
model: {},
backRouteName:'index',
url: {
queryById: "/aiol/aiolCourse/queryById",
add: "/aiol/aiolCourse/add",
edit: "/aiol/aiolCourse/edit",
},
}
},
created(){
this.initFormData();
},
methods:{
initFormData(){
if(this.formData){
let dataId = this.formData.dataId;
this.$http.get(this.url.queryById,{params:{id:dataId}}).then((res)=>{
if(res.data.success){
console.log("表单数据",res);
this.model = res.data.result;
}
})
}
},
onSubmit() {
let myForm = {...this.model};
this.loading = true;
let url = myForm.id?this.url.edit:this.url.add;
this.$http.post(url,myForm).then(res=>{
console.log("res",res)
this.loading = false
this.$Router.push({name:this.backRouteName})
}).catch(()=>{
this.loading = false
});
}
}
}
</script>

View File

@ -0,0 +1,44 @@
<template>
<view>
<!--标题和返回-->
<cu-custom :bgColor="NavBarColor" isBack>
<block slot="backText">返回</block>
<block slot="content">课程</block>
</cu-custom>
<!--滚动加载列表-->
<mescroll-body ref="mescrollRef" bottom="88" @init="mescrollInit" :up="upOption" :down="downOption" @down="downCallback" @up="upCallback">
<view class="cu-list menu">
<view class="cu-item" v-for="(item,index) in list" :key="index" @click="goHome">
<view class="flex" style="width:100%">
<text class="text-lg" style="color: #000;">
{{ item.createBy}}
</text>
</view>
</view>
</view>
</mescroll-body>
</view>
</template>
<script>
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
import Mixin from "@/common/mixin/Mixin.js";
export default {
name: '课程',
mixins: [MescrollMixin,Mixin],
data() {
return {
CustomBar:this.CustomBar,
NavBarColor:this.NavBarColor,
url: "/aiol/aiolCourse/list",
};
},
methods: {
goHome(){
this.$Router.push({name: "index"})
}
}
}
</script>

View File

@ -0,0 +1,113 @@
<template>
<view>
<!--标题和返回-->
<cu-custom :bgColor="NavBarColor" isBack :backRouterName="backRouteName">
<block slot="backText">返回</block>
<block slot="content">课程章节</block>
</cu-custom>
<!--表单区域-->
<view>
<form>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">课程id</text></view>
<input placeholder="请输入课程id" v-model="model.courseId"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">章节名</text></view>
<input placeholder="请输入章节名" v-model="model.name"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">章节类型</text></view>
<input type="number" placeholder="请输入章节类型" v-model="model.type"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">排序号</text></view>
<input type="number" placeholder="请输入排序号" v-model="model.sortOrder"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">父章节id</text></view>
<input placeholder="请输入父章节id" v-model="model.parentId"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">章节层级</text></view>
<input type="number" placeholder="请输入章节层级" v-model="model.level"/>
</view>
</view>
<view class="padding">
<button class="cu-btn block bg-blue margin-tb-sm lg" @click="onSubmit">
<text v-if="loading" class="cuIcon-loading2 cuIconfont-spin"></text>提交
</button>
</view>
</form>
</view>
</view>
</template>
<script>
import myDate from '@/components/my-componets/my-date.vue'
export default {
name: "AiolCourseSectionForm",
components:{ myDate },
props:{
formData:{
type:Object,
default:()=>{},
required:false
}
},
data(){
return {
CustomBar: this.CustomBar,
NavBarColor: this.NavBarColor,
loading:false,
model: {},
backRouteName:'index',
url: {
queryById: "/aiol/aiolCourseSection/queryById",
add: "/aiol/aiolCourseSection/add",
edit: "/aiol/aiolCourseSection/edit",
},
}
},
created(){
this.initFormData();
},
methods:{
initFormData(){
if(this.formData){
let dataId = this.formData.dataId;
this.$http.get(this.url.queryById,{params:{id:dataId}}).then((res)=>{
if(res.data.success){
console.log("表单数据",res);
this.model = res.data.result;
}
})
}
},
onSubmit() {
let myForm = {...this.model};
this.loading = true;
let url = myForm.id?this.url.edit:this.url.add;
this.$http.post(url,myForm).then(res=>{
console.log("res",res)
this.loading = false
this.$Router.push({name:this.backRouteName})
}).catch(()=>{
this.loading = false
});
}
}
}
</script>

View File

@ -0,0 +1,44 @@
<template>
<view>
<!--标题和返回-->
<cu-custom :bgColor="NavBarColor" isBack>
<block slot="backText">返回</block>
<block slot="content">课程章节</block>
</cu-custom>
<!--滚动加载列表-->
<mescroll-body ref="mescrollRef" bottom="88" @init="mescrollInit" :up="upOption" :down="downOption" @down="downCallback" @up="upCallback">
<view class="cu-list menu">
<view class="cu-item" v-for="(item,index) in list" :key="index" @click="goHome">
<view class="flex" style="width:100%">
<text class="text-lg" style="color: #000;">
{{ item.createBy}}
</text>
</view>
</view>
</view>
</mescroll-body>
</view>
</template>
<script>
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
import Mixin from "@/common/mixin/Mixin.js";
export default {
name: '课程章节',
mixins: [MescrollMixin,Mixin],
data() {
return {
CustomBar:this.CustomBar,
NavBarColor:this.NavBarColor,
url: "/aiol/aiolCourseSection/list",
};
},
methods: {
goHome(){
this.$Router.push({name: "index"})
}
}
}
</script>

View File

@ -0,0 +1,89 @@
<template>
<view>
<!--标题和返回-->
<cu-custom :bgColor="NavBarColor" isBack :backRouterName="backRouteName">
<block slot="backText">返回</block>
<block slot="content">课程报名</block>
</cu-custom>
<!--表单区域-->
<view>
<form>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">用户id</text></view>
<input placeholder="请输入用户id" v-model="model.userId"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">课程id</text></view>
<input placeholder="请输入课程id" v-model="model.courseId"/>
</view>
</view>
<view class="padding">
<button class="cu-btn block bg-blue margin-tb-sm lg" @click="onSubmit">
<text v-if="loading" class="cuIcon-loading2 cuIconfont-spin"></text>提交
</button>
</view>
</form>
</view>
</view>
</template>
<script>
import myDate from '@/components/my-componets/my-date.vue'
export default {
name: "AiolCourseSignupForm",
components:{ myDate },
props:{
formData:{
type:Object,
default:()=>{},
required:false
}
},
data(){
return {
CustomBar: this.CustomBar,
NavBarColor: this.NavBarColor,
loading:false,
model: {},
backRouteName:'index',
url: {
queryById: "/aiol/aiolCourseSignup/queryById",
add: "/aiol/aiolCourseSignup/add",
edit: "/aiol/aiolCourseSignup/edit",
},
}
},
created(){
this.initFormData();
},
methods:{
initFormData(){
if(this.formData){
let dataId = this.formData.dataId;
this.$http.get(this.url.queryById,{params:{id:dataId}}).then((res)=>{
if(res.data.success){
console.log("表单数据",res);
this.model = res.data.result;
}
})
}
},
onSubmit() {
let myForm = {...this.model};
this.loading = true;
let url = myForm.id?this.url.edit:this.url.add;
this.$http.post(url,myForm).then(res=>{
console.log("res",res)
this.loading = false
this.$Router.push({name:this.backRouteName})
}).catch(()=>{
this.loading = false
});
}
}
}
</script>

View File

@ -0,0 +1,44 @@
<template>
<view>
<!--标题和返回-->
<cu-custom :bgColor="NavBarColor" isBack>
<block slot="backText">返回</block>
<block slot="content">课程报名</block>
</cu-custom>
<!--滚动加载列表-->
<mescroll-body ref="mescrollRef" bottom="88" @init="mescrollInit" :up="upOption" :down="downOption" @down="downCallback" @up="upCallback">
<view class="cu-list menu">
<view class="cu-item" v-for="(item,index) in list" :key="index" @click="goHome">
<view class="flex" style="width:100%">
<text class="text-lg" style="color: #000;">
{{ item.createBy}}
</text>
</view>
</view>
</view>
</mescroll-body>
</view>
</template>
<script>
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
import Mixin from "@/common/mixin/Mixin.js";
export default {
name: '课程报名',
mixins: [MescrollMixin,Mixin],
data() {
return {
CustomBar:this.CustomBar,
NavBarColor:this.NavBarColor,
url: "/aiol/aiolCourseSignup/list",
};
},
methods: {
goHome(){
this.$Router.push({name: "index"})
}
}
}
</script>

View File

@ -0,0 +1,101 @@
<template>
<view>
<!--标题和返回-->
<cu-custom :bgColor="NavBarColor" isBack :backRouterName="backRouteName">
<block slot="backText">返回</block>
<block slot="content">授课教师</block>
</cu-custom>
<!--表单区域-->
<view>
<form>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">课程id</text></view>
<input placeholder="请输入课程id" v-model="model.courseId"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">教师id</text></view>
<input placeholder="请输入教师id" v-model="model.teacherId"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">授课角色</text></view>
<input placeholder="请输入授课角色" v-model="model.role"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">显示顺序</text></view>
<input type="number" placeholder="请输入显示顺序" v-model="model.sortOrder"/>
</view>
</view>
<view class="padding">
<button class="cu-btn block bg-blue margin-tb-sm lg" @click="onSubmit">
<text v-if="loading" class="cuIcon-loading2 cuIconfont-spin"></text>提交
</button>
</view>
</form>
</view>
</view>
</template>
<script>
import myDate from '@/components/my-componets/my-date.vue'
export default {
name: "AiolCourseTeacherForm",
components:{ myDate },
props:{
formData:{
type:Object,
default:()=>{},
required:false
}
},
data(){
return {
CustomBar: this.CustomBar,
NavBarColor: this.NavBarColor,
loading:false,
model: {},
backRouteName:'index',
url: {
queryById: "/aiol/aiolCourseTeacher/queryById",
add: "/aiol/aiolCourseTeacher/add",
edit: "/aiol/aiolCourseTeacher/edit",
},
}
},
created(){
this.initFormData();
},
methods:{
initFormData(){
if(this.formData){
let dataId = this.formData.dataId;
this.$http.get(this.url.queryById,{params:{id:dataId}}).then((res)=>{
if(res.data.success){
console.log("表单数据",res);
this.model = res.data.result;
}
})
}
},
onSubmit() {
let myForm = {...this.model};
this.loading = true;
let url = myForm.id?this.url.edit:this.url.add;
this.$http.post(url,myForm).then(res=>{
console.log("res",res)
this.loading = false
this.$Router.push({name:this.backRouteName})
}).catch(()=>{
this.loading = false
});
}
}
}
</script>

View File

@ -0,0 +1,44 @@
<template>
<view>
<!--标题和返回-->
<cu-custom :bgColor="NavBarColor" isBack>
<block slot="backText">返回</block>
<block slot="content">授课教师</block>
</cu-custom>
<!--滚动加载列表-->
<mescroll-body ref="mescrollRef" bottom="88" @init="mescrollInit" :up="upOption" :down="downOption" @down="downCallback" @up="upCallback">
<view class="cu-list menu">
<view class="cu-item" v-for="(item,index) in list" :key="index" @click="goHome">
<view class="flex" style="width:100%">
<text class="text-lg" style="color: #000;">
{{ item.createBy}}
</text>
</view>
</view>
</view>
</mescroll-body>
</view>
</template>
<script>
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
import Mixin from "@/common/mixin/Mixin.js";
export default {
name: '授课教师',
mixins: [MescrollMixin,Mixin],
data() {
return {
CustomBar:this.CustomBar,
NavBarColor:this.NavBarColor,
url: "/aiol/aiolCourseTeacher/list",
};
},
methods: {
goHome(){
this.$Router.push({name: "index"})
}
}
}
</script>

View File

@ -0,0 +1,107 @@
<template>
<view>
<!--标题和返回-->
<cu-custom :bgColor="NavBarColor" isBack :backRouterName="backRouteName">
<block slot="backText">返回</block>
<block slot="content">主体绑定</block>
</cu-custom>
<!--表单区域-->
<view>
<form>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">主体类型</text></view>
<input placeholder="请输入主体类型" v-model="model.sourceType"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">主体id</text></view>
<input placeholder="请输入主体id" v-model="model.sourceId"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">内容类型</text></view>
<input placeholder="请输入内容类型" v-model="model.targetType"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">内容id</text></view>
<input placeholder="请输入内容id" v-model="model.targetId"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">排序</text></view>
<input type="number" placeholder="请输入排序" v-model="model.sortOrder"/>
</view>
</view>
<view class="padding">
<button class="cu-btn block bg-blue margin-tb-sm lg" @click="onSubmit">
<text v-if="loading" class="cuIcon-loading2 cuIconfont-spin"></text>提交
</button>
</view>
</form>
</view>
</view>
</template>
<script>
import myDate from '@/components/my-componets/my-date.vue'
export default {
name: "AiolEntityLinkForm",
components:{ myDate },
props:{
formData:{
type:Object,
default:()=>{},
required:false
}
},
data(){
return {
CustomBar: this.CustomBar,
NavBarColor: this.NavBarColor,
loading:false,
model: {},
backRouteName:'index',
url: {
queryById: "/aiol/aiolEntityLink/queryById",
add: "/aiol/aiolEntityLink/add",
edit: "/aiol/aiolEntityLink/edit",
},
}
},
created(){
this.initFormData();
},
methods:{
initFormData(){
if(this.formData){
let dataId = this.formData.dataId;
this.$http.get(this.url.queryById,{params:{id:dataId}}).then((res)=>{
if(res.data.success){
console.log("表单数据",res);
this.model = res.data.result;
}
})
}
},
onSubmit() {
let myForm = {...this.model};
this.loading = true;
let url = myForm.id?this.url.edit:this.url.add;
this.$http.post(url,myForm).then(res=>{
console.log("res",res)
this.loading = false
this.$Router.push({name:this.backRouteName})
}).catch(()=>{
this.loading = false
});
}
}
}
</script>

View File

@ -0,0 +1,44 @@
<template>
<view>
<!--标题和返回-->
<cu-custom :bgColor="NavBarColor" isBack>
<block slot="backText">返回</block>
<block slot="content">主体绑定</block>
</cu-custom>
<!--滚动加载列表-->
<mescroll-body ref="mescrollRef" bottom="88" @init="mescrollInit" :up="upOption" :down="downOption" @down="downCallback" @up="upCallback">
<view class="cu-list menu">
<view class="cu-item" v-for="(item,index) in list" :key="index" @click="goHome">
<view class="flex" style="width:100%">
<text class="text-lg" style="color: #000;">
{{ item.createBy}}
</text>
</view>
</view>
</view>
</mescroll-body>
</view>
</template>
<script>
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
import Mixin from "@/common/mixin/Mixin.js";
export default {
name: '主体绑定',
mixins: [MescrollMixin,Mixin],
data() {
return {
CustomBar:this.CustomBar,
NavBarColor:this.NavBarColor,
url: "/aiol/aiolEntityLink/list",
};
},
methods: {
goHome(){
this.$Router.push({name: "index"})
}
}
}
</script>

View File

@ -0,0 +1,115 @@
<template>
<view>
<!--标题和返回-->
<cu-custom :bgColor="NavBarColor" isBack :backRouterName="backRouteName">
<block slot="backText">返回</block>
<block slot="content">作业</block>
</cu-custom>
<!--表单区域-->
<view>
<form>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">标题</text></view>
<input placeholder="请输入标题" v-model="model.title"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">说明</text></view>
<input placeholder="请输入说明" v-model="model.description"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">附件</text></view>
<input placeholder="请输入附件" v-model="model.attachment"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">满分</text></view>
<input type="number" placeholder="请输入满分" v-model="model.maxScore"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">及格分数</text></view>
<input type="number" placeholder="请输入及格分数" v-model="model.passScore"/>
</view>
</view>
<my-date label="开始时间:" v-model="model.startTime" placeholder="请输入开始时间"></my-date>
<my-date label="结束时间:" v-model="model.endTime" placeholder="请输入结束时间"></my-date>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">状态</text></view>
<input type="number" placeholder="请输入状态" v-model="model.status"/>
</view>
</view>
<view class="padding">
<button class="cu-btn block bg-blue margin-tb-sm lg" @click="onSubmit">
<text v-if="loading" class="cuIcon-loading2 cuIconfont-spin"></text>提交
</button>
</view>
</form>
</view>
</view>
</template>
<script>
import myDate from '@/components/my-componets/my-date.vue'
export default {
name: "AiolHomeworkForm",
components:{ myDate },
props:{
formData:{
type:Object,
default:()=>{},
required:false
}
},
data(){
return {
CustomBar: this.CustomBar,
NavBarColor: this.NavBarColor,
loading:false,
model: {},
backRouteName:'index',
url: {
queryById: "/aiol/aiolHomework/queryById",
add: "/aiol/aiolHomework/add",
edit: "/aiol/aiolHomework/edit",
},
}
},
created(){
this.initFormData();
},
methods:{
initFormData(){
if(this.formData){
let dataId = this.formData.dataId;
this.$http.get(this.url.queryById,{params:{id:dataId}}).then((res)=>{
if(res.data.success){
console.log("表单数据",res);
this.model = res.data.result;
}
})
}
},
onSubmit() {
let myForm = {...this.model};
this.loading = true;
let url = myForm.id?this.url.edit:this.url.add;
this.$http.post(url,myForm).then(res=>{
console.log("res",res)
this.loading = false
this.$Router.push({name:this.backRouteName})
}).catch(()=>{
this.loading = false
});
}
}
}
</script>

View File

@ -0,0 +1,44 @@
<template>
<view>
<!--标题和返回-->
<cu-custom :bgColor="NavBarColor" isBack>
<block slot="backText">返回</block>
<block slot="content">作业</block>
</cu-custom>
<!--滚动加载列表-->
<mescroll-body ref="mescrollRef" bottom="88" @init="mescrollInit" :up="upOption" :down="downOption" @down="downCallback" @up="upCallback">
<view class="cu-list menu">
<view class="cu-item" v-for="(item,index) in list" :key="index" @click="goHome">
<view class="flex" style="width:100%">
<text class="text-lg" style="color: #000;">
{{ item.createBy}}
</text>
</view>
</view>
</view>
</mescroll-body>
</view>
</template>
<script>
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
import Mixin from "@/common/mixin/Mixin.js";
export default {
name: '作业',
mixins: [MescrollMixin,Mixin],
data() {
return {
CustomBar:this.CustomBar,
NavBarColor:this.NavBarColor,
url: "/aiol/aiolHomework/list",
};
},
methods: {
goHome(){
this.$Router.push({name: "index"})
}
}
}
</script>

View File

@ -0,0 +1,113 @@
<template>
<view>
<!--标题和返回-->
<cu-custom :bgColor="NavBarColor" isBack :backRouterName="backRouteName">
<block slot="backText">返回</block>
<block slot="content">学习进度</block>
</cu-custom>
<!--表单区域-->
<view>
<form>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">用户id</text></view>
<input placeholder="请输入用户id" v-model="model.userId"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">课程id</text></view>
<input placeholder="请输入课程id" v-model="model.courseId"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">章节id</text></view>
<input placeholder="请输入章节id" v-model="model.sectionId"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">进度</text></view>
<input type="number" placeholder="请输入进度" v-model="model.progress"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">时长</text></view>
<input type="number" placeholder="请输入时长" v-model="model.duration"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">状态</text></view>
<input type="number" placeholder="请输入状态" v-model="model.status"/>
</view>
</view>
<view class="padding">
<button class="cu-btn block bg-blue margin-tb-sm lg" @click="onSubmit">
<text v-if="loading" class="cuIcon-loading2 cuIconfont-spin"></text>提交
</button>
</view>
</form>
</view>
</view>
</template>
<script>
import myDate from '@/components/my-componets/my-date.vue'
export default {
name: "AiolLearnProgressForm",
components:{ myDate },
props:{
formData:{
type:Object,
default:()=>{},
required:false
}
},
data(){
return {
CustomBar: this.CustomBar,
NavBarColor: this.NavBarColor,
loading:false,
model: {},
backRouteName:'index',
url: {
queryById: "/aiol/aiolLearnProgress/queryById",
add: "/aiol/aiolLearnProgress/add",
edit: "/aiol/aiolLearnProgress/edit",
},
}
},
created(){
this.initFormData();
},
methods:{
initFormData(){
if(this.formData){
let dataId = this.formData.dataId;
this.$http.get(this.url.queryById,{params:{id:dataId}}).then((res)=>{
if(res.data.success){
console.log("表单数据",res);
this.model = res.data.result;
}
})
}
},
onSubmit() {
let myForm = {...this.model};
this.loading = true;
let url = myForm.id?this.url.edit:this.url.add;
this.$http.post(url,myForm).then(res=>{
console.log("res",res)
this.loading = false
this.$Router.push({name:this.backRouteName})
}).catch(()=>{
this.loading = false
});
}
}
}
</script>

View File

@ -0,0 +1,44 @@
<template>
<view>
<!--标题和返回-->
<cu-custom :bgColor="NavBarColor" isBack>
<block slot="backText">返回</block>
<block slot="content">学习进度</block>
</cu-custom>
<!--滚动加载列表-->
<mescroll-body ref="mescrollRef" bottom="88" @init="mescrollInit" :up="upOption" :down="downOption" @down="downCallback" @up="upCallback">
<view class="cu-list menu">
<view class="cu-item" v-for="(item,index) in list" :key="index" @click="goHome">
<view class="flex" style="width:100%">
<text class="text-lg" style="color: #000;">
{{ item.createBy}}
</text>
</view>
</view>
</view>
</mescroll-body>
</view>
</template>
<script>
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
import Mixin from "@/common/mixin/Mixin.js";
export default {
name: '学习进度',
mixins: [MescrollMixin,Mixin],
data() {
return {
CustomBar:this.CustomBar,
NavBarColor:this.NavBarColor,
url: "/aiol/aiolLearnProgress/list",
};
},
methods: {
goHome(){
this.$Router.push({name: "index"})
}
}
}
</script>

View File

@ -0,0 +1,113 @@
<template>
<view>
<!--标题和返回-->
<cu-custom :bgColor="NavBarColor" isBack :backRouterName="backRouteName">
<block slot="backText">返回</block>
<block slot="content">题目</block>
</cu-custom>
<!--表单区域-->
<view>
<form>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">父题目id</text></view>
<input placeholder="请输入父题目id" v-model="model.parentId"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">题目类型</text></view>
<input type="number" placeholder="请输入题目类型" v-model="model.type"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">题干</text></view>
<input placeholder="请输入题干" v-model="model.content"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">题目解析</text></view>
<input placeholder="请输入题目解析" v-model="model.analysis"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">难度</text></view>
<input type="number" placeholder="请输入难度" v-model="model.difficulty"/>
</view>
</view>
<view class="cu-form-group">
<view class="flex align-center">
<view class="title"><text space="ensp">分值</text></view>
<input type="number" placeholder="请输入分值" v-model="model.score"/>
</view>
</view>
<view class="padding">
<button class="cu-btn block bg-blue margin-tb-sm lg" @click="onSubmit">
<text v-if="loading" class="cuIcon-loading2 cuIconfont-spin"></text>提交
</button>
</view>
</form>
</view>
</view>
</template>
<script>
import myDate from '@/components/my-componets/my-date.vue'
export default {
name: "AiolQuestionForm",
components:{ myDate },
props:{
formData:{
type:Object,
default:()=>{},
required:false
}
},
data(){
return {
CustomBar: this.CustomBar,
NavBarColor: this.NavBarColor,
loading:false,
model: {},
backRouteName:'index',
url: {
queryById: "/aiol/aiolQuestion/queryById",
add: "/aiol/aiolQuestion/add",
edit: "/aiol/aiolQuestion/edit",
},
}
},
created(){
this.initFormData();
},
methods:{
initFormData(){
if(this.formData){
let dataId = this.formData.dataId;
this.$http.get(this.url.queryById,{params:{id:dataId}}).then((res)=>{
if(res.data.success){
console.log("表单数据",res);
this.model = res.data.result;
}
})
}
},
onSubmit() {
let myForm = {...this.model};
this.loading = true;
let url = myForm.id?this.url.edit:this.url.add;
this.$http.post(url,myForm).then(res=>{
console.log("res",res)
this.loading = false
this.$Router.push({name:this.backRouteName})
}).catch(()=>{
this.loading = false
});
}
}
}
</script>

View File

@ -0,0 +1,44 @@
<template>
<view>
<!--标题和返回-->
<cu-custom :bgColor="NavBarColor" isBack>
<block slot="backText">返回</block>
<block slot="content">题目</block>
</cu-custom>
<!--滚动加载列表-->
<mescroll-body ref="mescrollRef" bottom="88" @init="mescrollInit" :up="upOption" :down="downOption" @down="downCallback" @up="upCallback">
<view class="cu-list menu">
<view class="cu-item" v-for="(item,index) in list" :key="index" @click="goHome">
<view class="flex" style="width:100%">
<text class="text-lg" style="color: #000;">
{{ item.createBy}}
</text>
</view>
</view>
</view>
</mescroll-body>
</view>
</template>
<script>
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
import Mixin from "@/common/mixin/Mixin.js";
export default {
name: '题目',
mixins: [MescrollMixin,Mixin],
data() {
return {
CustomBar:this.CustomBar,
NavBarColor:this.NavBarColor,
url: "/aiol/aiolQuestion/list",
};
},
methods: {
goHome(){
this.$Router.push({name: "index"})
}
}
}
</script>

Some files were not shown because too many files have changed in this diff Show More