This commit is contained in:
王昊 2025-11-23 16:14:44 +08:00
parent 89eefe8d1c
commit 86bd9f610b
21 changed files with 232 additions and 95 deletions

View File

@ -17,7 +17,7 @@ import java.util.Optional;
* 1.1 章节管理新增/编辑/删除/拖拽排序/三级目录树
*/
@RestController
@RequestMapping("/textbook/chapter")
@RequestMapping("/backend/v1/jc/chapter")
public class BookChapterController {
@Autowired

View File

@ -9,7 +9,7 @@ import xyz.playedu.jc.service.IBookPaperService;
import java.util.List;
@RestController
@RequestMapping("/textbook/paper")
@RequestMapping("/backend/v1/jc/paper")
public class BookPaperController {
@Autowired
@ -20,7 +20,7 @@ public class BookPaperController {
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<BookPaper> wrapper =
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<>();
wrapper.eq(BookPaper::getBookId, bookId)
.orderByAsc(BookPaper::getSort)
// .orderByAsc(BookPaper::getSort)
.orderByAsc(BookPaper::getId);
List<BookPaper> list = bookPaperService.list(wrapper);
return JsonResponse.data(list);

View File

@ -9,7 +9,7 @@ import xyz.playedu.jc.service.IBookDepartmentUserService;
import java.util.List;
@RestController
@RequestMapping("/textbook/scope")
@RequestMapping("/backend/v1/jc/scope")
public class BookScopeController {
@Autowired

View File

@ -4,6 +4,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import xyz.playedu.common.types.JsonResponse;
import xyz.playedu.jc.domain.ChapterContent;
import xyz.playedu.jc.domain.dto.ChapterContentSaveDTO;
import xyz.playedu.jc.service.IChapterContentService;
/**
@ -12,30 +13,40 @@ import xyz.playedu.jc.service.IChapterContentService;
* 章节内容 后台接口
*/
@RestController
@RequestMapping("/textbook/chapter-content")
@RequestMapping("/backend/v1/jc/chapter-content")
public class ChapterContentController {
@Autowired
private IChapterContentService chapterContentService;
/** 获取章节内容 */
@GetMapping("/{chapterId}")
public JsonResponse detail(@PathVariable("chapterId") Integer chapterId) {
ChapterContent content = chapterContentService.getByChapterId(chapterId);
return JsonResponse.data(content);
}
/** 保存 / 更新章节内容(富文本 + 资源关联 + 知识点关联) */
@PostMapping("/{chapterId}")
public JsonResponse save(@PathVariable("chapterId") Integer chapterId,
@RequestBody ChapterContent body) {
body.setChapterId(chapterId);
// 如果该章节已存在内容则更新否则新增
ChapterContent old = chapterContentService.getByChapterId(chapterId);
if (old == null) {
chapterContentService.save(body);
} else {
body.setId(old.getId());
chapterContentService.updateById(body);
}
@RequestBody ChapterContentSaveDTO dto) {
chapterContentService.saveOrUpdate(chapterId, dto);
return JsonResponse.success();
}
/** 设置/取消重点标记 */
@PostMapping("/{chapterId}/highlight")
public JsonResponse highlight(@PathVariable("chapterId") Integer chapterId,
@RequestParam("highlight") Boolean highlight) {
chapterContentService.highlight(chapterId, Boolean.TRUE.equals(highlight));
return JsonResponse.success();
}
/** OCR 导入(这里只是预留接口,具体调用你自己本地 OCR 模块) */
@PostMapping("/{chapterId}/ocr")
public JsonResponse ocrImport(@PathVariable("chapterId") Integer chapterId) {
// TODO: 在这里接入你的本地 OCR 服务把结果写入章节内容
return JsonResponse.success();
}
}

View File

@ -11,7 +11,7 @@ import xyz.playedu.jc.service.JCIResourceService;
import java.util.List;
@RestController
@RequestMapping("/textbook/resource")
@RequestMapping("/backend/v1/jc/resource")
public class JCResourceController {
@Autowired

View File

@ -2,22 +2,39 @@ package xyz.playedu.api.controller.backend.jc;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import xyz.playedu.common.annotation.Log;
import xyz.playedu.common.constant.BusinessTypeConstant;
import xyz.playedu.common.types.JsonResponse;
import xyz.playedu.common.types.paginate.PaginationResult;
import xyz.playedu.jc.domain.Textbook;
import xyz.playedu.jc.service.ITextbookService;
import xyz.playedu.knowledge.domain.KnowledgeMessages;
import java.util.HashMap;
import java.util.List;
/**
* 教材管理 后台接口
*/
@RestController
@RequestMapping("/textbook")
@RequestMapping("/backend/v1/jc/textbook")
public class TextbookController {
@Autowired
private ITextbookService textbookService;
@GetMapping("/index")
public JsonResponse index(@RequestParam HashMap<String, Object> params) {
/** 调用服务层分页查询方法Service 层已包含完整的分页信息 */
PaginationResult<Textbook> result = textbookService.paginate(params);
/** 直接返回 Service 层的结果 */
return JsonResponse.data(result);
}
@GetMapping("/list")
public JsonResponse list() {
List<Textbook> list = textbookService.list();
@ -47,4 +64,15 @@ public class TextbookController {
textbookService.removeById(id);
return JsonResponse.success();
}
/** 教材发布 / 下架 */
@PostMapping("/{id}/publish")
public JsonResponse publish(@PathVariable("id") Integer id,
@RequestParam("status") Integer status) {
Textbook textbook = new Textbook();
textbook.setId(id);
// textbook.setStatus(status);
textbookService.updateById(textbook);
return JsonResponse.success();
}
}

View File

@ -19,6 +19,7 @@ import xyz.playedu.common.service.*;
import xyz.playedu.common.util.PrivacyUtil;
import xyz.playedu.common.util.StringUtil;
import static xyz.playedu.framework.tenant.context.TenantContextHolder.getRequiredTenantId;
import static xyz.playedu.framework.tenant.context.TenantContextHolder.getTenantId;
@Component
@ -49,9 +50,12 @@ public class BackendBus {
if (roleIds.isEmpty()&&platformRoleIds.isEmpty()) {
return permissions;
}
System.out.println("getTenantId()"+getTenantId());
System.out.println("platformRoleIds"+platformRoleIds);
System.out.println("platFormRole"+platFormRole);
List<Integer> permissionIds;
if (getTenantId() == -1L&&platformRoleIds.contains(platFormRole.getId())){
// if (getTenantId() == -1L&&platformRoleIds.contains(platFormRole.getId())){
if (getRequiredTenantId() == -1L&&platformRoleIds.contains(platFormRole.getId())){
HashMap<String, Boolean> slugsByIds = new HashMap<>();
slugsByIds.put("tenantManage", true);
slugsByIds.put("equInfoManage", true);

View File

@ -16,20 +16,17 @@ import java.util.Date;
@TableName("jc_book_department_user")
public class BookDepartmentUser {
@TableId(type = IdType.AUTO)
private Integer id;
/** 教材ID */
@TableField("book_id")
private Integer bookId;
/** 部门ID */
@TableField("department_id")
private Integer departmentId;
/** 指派范围ID */
@TableField("range_id")
private Integer rangeId;
/** 用户ID */
@TableField("user_id")
private Integer userId;
@TableField("type")
private Integer type;
@TableField("creator")
private String creator;

View File

@ -27,17 +27,10 @@ public class BookPaper {
@TableField("paper_id")
private Integer paperId;
/** 章节ID可选 */
@TableField("chapter_id")
private Integer chapterId;
/** 类型 1-随堂 2-单元 3-期末 等 */
@TableField("type")
private Integer type;
/** 排序 */
@TableField("sort")
private Integer sort;
/** 其它规则[试题顺序,选项顺序,考试次数,考试时长,及格分,阅卷方式] */
@TableField("extra")
private String extra;
@TableField("creator")
private String creator;

View File

@ -20,6 +20,9 @@ public class ChapterContent {
@TableId(type = IdType.AUTO)
private Integer id;
/** 教材id */
@TableField("book_id")
private Integer bookId;
/** 章节ID */
@TableField("chapter_id")
private Integer chapterId;
@ -27,14 +30,17 @@ public class ChapterContent {
/** 富文本内容 */
@TableField("content")
private String content;
/** 内容类型html等当前默认为html前端不用显示此字段 */
@TableField("type")
private String type;
/** 关联资源ID逗号分隔 */
@TableField("resource_ids")
private String resourceIds;
/** 关联知识点ID逗号分隔 */
@TableField("knowledge_ids")
private String knowledgeIds;
// /** 关联资源ID逗号分隔 */
// @TableField("resource_ids")
// private String resourceIds;
//
// /** 关联知识点ID逗号分隔 */
// @TableField("knowledge_ids")
// private String knowledgeIds;
/** 创建人 */
@TableField("creator")

View File

@ -31,33 +31,35 @@ public class JCResource {
@TableField("name")
private String name;
@TableField("konwledge_code")
private String konwledgeCode;
/** 文本描述 AI分析或自动填入 */
@TableField("txt_desc")
private String txtDesc;
/** 资源类型 video/ppt/image/audio/... */
@TableField("type")
private String type;
/** 文件后缀 */
@TableField("ext")
private String ext;
/** 文件类型 */
@TableField("extension")
private String extension;
/** 文件大小(字节) */
@TableField("size")
private Long size;
/** 时长(秒),仅视频/音频 */
@TableField("duration")
private Integer duration;
/** 存储磁盘 */
@TableField("disk")
private Integer disk;
/** 访问URL */
@TableField("url")
private String url;
@TableField("path")
private String path;
/** 封面图 */
@TableField("cover")
private String cover;
/** 状态 0-禁用 1-启用 */
@TableField("status")
private Integer status;
@TableField("creator")
private String creator;

View File

@ -24,12 +24,16 @@ public class Textbook {
private String title;
/** 封面地址 */
@TableField("cover")
private String cover;
@TableField("thumb")
private String thumb;
/** 简介 */
@TableField("description")
private String description;
@TableField("short_desc")
private String shortDesc;
/** 学科专业信息 */
@TableField("major")
private String major;
/** 作者 */
@TableField("author")
@ -39,21 +43,12 @@ public class Textbook {
@TableField("isbn")
private String isbn;
/** 章节总数(最小层级总节点数) */
@TableField("chapter_num")
private String chapterNum;
/** 出版社 */
@TableField("publisher")
private String publisher;
/** 适用专业/课程 */
@TableField("subject")
private String subject;
/** 发布状态 0-未发布 1-已发布 */
@TableField("status")
private Integer status;
/** 版本号 */
@TableField("version")
private String version;
@TableField("publish_unit")
private String publishUnit;
/** 发布时间 */
@TableField("publish_time")

View File

@ -2,6 +2,7 @@ package xyz.playedu.jc.service;
import com.baomidou.mybatisplus.extension.service.IService;
import xyz.playedu.jc.domain.ChapterContent;
import xyz.playedu.jc.domain.dto.ChapterContentSaveDTO;
/**
* 章节内容 Service
@ -9,4 +10,8 @@ import xyz.playedu.jc.domain.ChapterContent;
public interface IChapterContentService extends IService<ChapterContent> {
ChapterContent getByChapterId(Integer chapterId);
void saveOrUpdate(Integer chapterId, ChapterContentSaveDTO dto);
void highlight(Integer chapterId, boolean highlight);
}

View File

@ -1,11 +1,15 @@
package xyz.playedu.jc.service;
import com.baomidou.mybatisplus.extension.service.IService;
import xyz.playedu.common.types.paginate.PaginationResult;
import xyz.playedu.jc.domain.Textbook;
import java.util.HashMap;
/**
* 教材 Service
*/
public interface ITextbookService extends IService<Textbook> {
PaginationResult<Textbook> paginate(HashMap<String, Object> params);
}

View File

@ -4,9 +4,12 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import xyz.playedu.jc.domain.ChapterContent;
import xyz.playedu.jc.domain.dto.ChapterContentSaveDTO;
import xyz.playedu.jc.mapper.ChapterContentMapper;
import xyz.playedu.jc.service.IChapterContentService;
import java.util.stream.Collectors;
@Service
public class ChapterContentServiceImpl
extends ServiceImpl<ChapterContentMapper, ChapterContent>
@ -18,4 +21,37 @@ public class ChapterContentServiceImpl
wrapper.eq(ChapterContent::getChapterId, chapterId);
return getOne(wrapper, false);
}
@Override
public void saveOrUpdate(Integer chapterId, ChapterContentSaveDTO dto) {
ChapterContent exist = getByChapterId(chapterId);
String resourceIds = dto.getResourceIds() == null ? null :
dto.getResourceIds().stream()
.map(String::valueOf).collect(Collectors.joining(","));
String knowledgeIds = dto.getKnowledgeIds() == null ? null :
dto.getKnowledgeIds().stream()
.map(String::valueOf).collect(Collectors.joining(","));
if (exist == null) {
ChapterContent entity = new ChapterContent();
entity.setChapterId(chapterId);
entity.setContent(dto.getContent());
save(entity);
} else {
exist.setContent(dto.getContent());
// exist.setHighlight(Boolean.TRUE.equals(dto.getHighlight()) ? 1 : 0);
updateById(exist);
}
}
@Override
public void highlight(Integer chapterId, boolean highlight) {
ChapterContent exist = getByChapterId(chapterId);
if (exist == null) {
return;
}
// exist.setHighlight(highlight ? 1 : 0);
updateById(exist);
}
}

View File

@ -1,16 +1,88 @@
package xyz.playedu.jc.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Service;
import xyz.playedu.common.types.paginate.PaginationResult;
import xyz.playedu.jc.domain.Textbook;
import xyz.playedu.jc.mapper.TextbookMapper;
import xyz.playedu.jc.service.ITextbookService;
import xyz.playedu.knowledge.domain.KnowledgeMessages;
import java.util.ArrayList;
import java.util.HashMap;
/**
* 教材 Service 实现
*/
@Slf4j
@Service
public class TextbookServiceImpl
extends ServiceImpl<TextbookMapper, Textbook>
implements ITextbookService {
/**
* 分页查询消息列表
* 支持与 getMessages 相同的动态查询条件
*
* @param params 查询参数 Map支持的参数与 getMessages 相同
* @return 分页结果包含数据列表和总数
*/
@Override
public PaginationResult<Textbook> paginate(HashMap<String, Object> params) {
try {
/** 获取分页参数默认第1页每页10条 */
Integer page = MapUtils.getInteger(params, "page", 1);
Integer size = MapUtils.getInteger(params, "size", 10);
/** 创建分页对象 */
Page<Textbook> pageParam = new Page<>(page, size);
/** 创建 Lambda 条件构造器,用于构建类型安全的查询条件 */
LambdaQueryWrapper<Textbook> queryWrapper = new LambdaQueryWrapper<>();
/** 固定条件只查询未删除的记录km_is_del = false */
// queryWrapper.eq(Textbook::getKmIsDel, false);
/** 动态添加查询条件会话ID */
if (MapUtils.getString(params, "title") != null && !MapUtils.getString(params, "title").isEmpty()) {
queryWrapper.eq(Textbook::getTitle, MapUtils.getString(params, "title"));
}
/** 添加排序条件:按创建时间降序排列 */
queryWrapper.orderByDesc(Textbook::getCreateTime);
/** 执行分页查询 */
IPage<Textbook> pageResult = this.page(pageParam, queryWrapper);
/** 计算总页数 */
Long total = pageResult.getTotal();
Long pages = (total + size - 1) / size; // 向上取整
/** 构建返回结果,包含完整的分页信息 */
PaginationResult<Textbook> result = new PaginationResult<>();
result.setData(pageResult.getRecords());
result.setTotal(total);
result.setCurrent(page); // 当前页码
result.setSize(size); // 每页大小
result.setPages(pages); // 总页数
return result;
} catch (Exception e) {
log.error("分页查询消息失败,参数:{}", params, e);
/** 返回空结果 */
PaginationResult<Textbook> emptyResult = new PaginationResult<>();
emptyResult.setData(new ArrayList<>());
emptyResult.setTotal(0L);
emptyResult.setCurrent(MapUtils.getInteger(params, "page", 1));
emptyResult.setSize(MapUtils.getInteger(params, "size", 10));
emptyResult.setPages(0L);
return emptyResult;
}
}
}

View File

@ -5,10 +5,7 @@
<mapper namespace="xyz.playedu.jc.mapper.BookDepartmentUserMapper">
<resultMap id="BookDepartmentUserResultMap" type="xyz.playedu.jc.domain.BookDepartmentUser">
<id column="id" property="id"/>
<result column="book_id" property="bookId"/>
<result column="department_id" property="departmentId"/>
<result column="user_id" property="userId"/>
<result column="creator" property="creator"/>
<result column="updater" property="updater"/>
<result column="create_time" property="createTime"/>

View File

@ -8,9 +8,6 @@
<id column="id" property="id"/>
<result column="book_id" property="bookId"/>
<result column="paper_id" property="paperId"/>
<result column="chapter_id" property="chapterId"/>
<result column="type" property="type"/>
<result column="sort" property="sort"/>
<result column="creator" property="creator"/>
<result column="updater" property="updater"/>
<result column="create_time" property="createTime"/>

View File

@ -8,8 +8,6 @@
<id column="id" property="id"/>
<result column="chapter_id" property="chapterId"/>
<result column="content" property="content"/>
<result column="resource_ids" property="resourceIds"/>
<result column="knowledge_ids" property="knowledgeIds"/>
<result column="creator" property="creator"/>
<result column="updater" property="updater"/>
<result column="create_time" property="createTime"/>

View File

@ -10,12 +10,8 @@
<result column="chapter_id" property="chapterId"/>
<result column="name" property="name"/>
<result column="type" property="type"/>
<result column="ext" property="ext"/>
<result column="size" property="size"/>
<result column="duration" property="duration"/>
<result column="url" property="url"/>
<result column="cover" property="cover"/>
<result column="status" property="status"/>
<result column="creator" property="creator"/>
<result column="updater" property="updater"/>
<result column="create_time" property="createTime"/>

View File

@ -7,14 +7,10 @@
<resultMap id="TextbookResultMap" type="xyz.playedu.jc.domain.Textbook">
<id column="id" property="id"/>
<result column="title" property="title"/>
<result column="cover" property="cover"/>
<result column="description" property="description"/>
<result column="author" property="author"/>
<result column="isbn" property="isbn"/>
<result column="publisher" property="publisher"/>
<result column="subject" property="subject"/>
<result column="status" property="status"/>
<result column="version" property="version"/>
<result column="publish_time" property="publishTime"/>
<result column="creator" property="creator"/>
<result column="updater" property="updater"/>