文件本地上传+知识图谱功能
This commit is contained in:
parent
5ce697523a
commit
c66439995f
@ -12,4 +12,5 @@ import org.springframework.stereotype.Component;
|
|||||||
public class AIPlatformConfig {
|
public class AIPlatformConfig {
|
||||||
private String host;
|
private String host;
|
||||||
private String api_key;
|
private String api_key;
|
||||||
|
private String profile;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package xyz.playedu.api.controller.backend.jc;
|
package xyz.playedu.api.controller.backend.jc;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import xyz.playedu.common.annotation.Log;
|
import xyz.playedu.common.annotation.Log;
|
||||||
@ -7,6 +8,7 @@ import xyz.playedu.common.constant.BusinessTypeConstant;
|
|||||||
import xyz.playedu.common.types.JsonResponse;
|
import xyz.playedu.common.types.JsonResponse;
|
||||||
import xyz.playedu.common.types.paginate.PaginationResult;
|
import xyz.playedu.common.types.paginate.PaginationResult;
|
||||||
import xyz.playedu.jc.domain.Knowledge;
|
import xyz.playedu.jc.domain.Knowledge;
|
||||||
|
import xyz.playedu.jc.param.KnowledgeParam;
|
||||||
import xyz.playedu.jc.service.IKnowledgeService;
|
import xyz.playedu.jc.service.IKnowledgeService;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -22,48 +24,52 @@ public class KnowledgeController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private IKnowledgeService knowledgeService;
|
private IKnowledgeService knowledgeService;
|
||||||
|
|
||||||
/** 分页列表 */
|
|
||||||
@GetMapping("/index")
|
/**
|
||||||
public JsonResponse index(@RequestParam HashMap<String, Object> params) {
|
* 获取知识点卡片列表
|
||||||
PaginationResult<Knowledge> result = knowledgeService.paginate(params);
|
*/
|
||||||
return JsonResponse.data(result);
|
@GetMapping("/list")
|
||||||
|
public JsonResponse list(KnowledgeParam param) {
|
||||||
|
List<Knowledge> list = knowledgeService.listVo(param);
|
||||||
|
return JsonResponse.data(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 全量列表 */
|
|
||||||
@GetMapping("/list")
|
|
||||||
public JsonResponse list() {
|
|
||||||
List<Knowledge> list = knowledgeService.list();
|
/**
|
||||||
|
* 获取知识点树结构
|
||||||
|
*/
|
||||||
|
@GetMapping("/treeList")
|
||||||
|
public JsonResponse treeList(KnowledgeParam param) {
|
||||||
|
List<Knowledge> list = knowledgeService.treeList(param);
|
||||||
return JsonResponse.data(list);
|
return JsonResponse.data(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 详情 */
|
/** 详情 */
|
||||||
@GetMapping("/{id}")
|
@GetMapping("/{id}")
|
||||||
public JsonResponse detail(@PathVariable("id") Integer id) {
|
public JsonResponse detail(@PathVariable("id") Integer id) {
|
||||||
Knowledge one = knowledgeService.getById(id);
|
return JsonResponse.data( knowledgeService.getByIdVo(id));
|
||||||
return JsonResponse.data(one);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 新增 */
|
/** 新增 */
|
||||||
@Log(title = "新增知识点", businessType = BusinessTypeConstant.INSERT)
|
@Log(title = "新增知识点", businessType = BusinessTypeConstant.INSERT)
|
||||||
@PostMapping
|
@PostMapping("/saveOrUpdateVo")
|
||||||
public JsonResponse store(@RequestBody Knowledge knowledge) {
|
public JsonResponse saveOrUpdateVo(@RequestBody Knowledge knowledge) {
|
||||||
knowledgeService.save(knowledge);
|
knowledgeService.saveOrUpdateVo(knowledge);
|
||||||
return JsonResponse.success();
|
return JsonResponse.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 修改 */
|
|
||||||
@Log(title = "修改知识点", businessType = BusinessTypeConstant.UPDATE)
|
|
||||||
@PutMapping
|
|
||||||
public JsonResponse update(@RequestBody Knowledge knowledge) {
|
|
||||||
knowledgeService.updateById(knowledge);
|
|
||||||
return JsonResponse.success();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 删除 */
|
/** 删除 */
|
||||||
@Log(title = "删除知识点", businessType = BusinessTypeConstant.DELETE)
|
@Log(title = "删除知识点", businessType = BusinessTypeConstant.DELETE)
|
||||||
@DeleteMapping("/{id}")
|
@DeleteMapping("/{id}")
|
||||||
public JsonResponse destroy(@PathVariable("id") Integer id) {
|
public JsonResponse destroy(@PathVariable("id") Integer id) {
|
||||||
knowledgeService.removeById(id);
|
Knowledge byId = knowledgeService.getById(id);
|
||||||
|
LambdaQueryWrapper<Knowledge> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.likeRight(Knowledge::getKnowledgeCode, byId.getKnowledgeCode());
|
||||||
|
knowledgeService.remove(queryWrapper);
|
||||||
return JsonResponse.success();
|
return JsonResponse.success();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,60 @@
|
|||||||
|
package xyz.playedu.api.controller.backend.system;
|
||||||
|
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import xyz.playedu.common.config.PlatformConfig;
|
||||||
|
import xyz.playedu.common.config.ServerConfig;
|
||||||
|
import xyz.playedu.common.types.JsonResponse;
|
||||||
|
import xyz.playedu.common.util.FileUploadUtils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通用请求处理
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/common")
|
||||||
|
public class LocalFileController {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(LocalFileController.class);
|
||||||
|
private static final String FILE_DELIMETER = ",";
|
||||||
|
@Autowired
|
||||||
|
private ServerConfig serverConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通用上传请求(单个)
|
||||||
|
*/
|
||||||
|
@PostMapping("/upload")
|
||||||
|
public JsonResponse uploadFile(MultipartFile file) throws Exception {
|
||||||
|
// 上传文件路径
|
||||||
|
String filePath = PlatformConfig.getUploadPath();
|
||||||
|
// 上传并返回新文件名称
|
||||||
|
String fileName = FileUploadUtils.upload(filePath, file);
|
||||||
|
try {
|
||||||
|
String url = serverConfig.getUrl() + fileName;
|
||||||
|
JSONObject ajax = new JSONObject();
|
||||||
|
ajax.put("url", url);
|
||||||
|
ajax.put("path", fileName);
|
||||||
|
ajax.put("newFileName", FileUploadUtils.getName(fileName));
|
||||||
|
ajax.put("originalFilename", file.getOriginalFilename());
|
||||||
|
return JsonResponse.data(ajax);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return JsonResponse.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -54,6 +54,8 @@ public class UploadController {
|
|||||||
|
|
||||||
@Autowired private AppConfigService appConfigService;
|
@Autowired private AppConfigService appConfigService;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@PostMapping("/minio")
|
@PostMapping("/minio")
|
||||||
@Log(title = "上传-MinIO", businessType = BusinessTypeConstant.UPLOAD)
|
@Log(title = "上传-MinIO", businessType = BusinessTypeConstant.UPLOAD)
|
||||||
public JsonResponse uploadMinio(
|
public JsonResponse uploadMinio(
|
||||||
|
|||||||
@ -0,0 +1,49 @@
|
|||||||
|
package xyz.playedu.api.controller.frontend;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
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.jc.domain.Knowledge;
|
||||||
|
import xyz.playedu.jc.param.KnowledgeParam;
|
||||||
|
import xyz.playedu.jc.service.IKnowledgeService;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 知识点管理
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/jc/knowledge")
|
||||||
|
public class KnowledgeController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IKnowledgeService knowledgeService;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取知识点卡片列表
|
||||||
|
*/
|
||||||
|
@GetMapping("/list")
|
||||||
|
public JsonResponse list(KnowledgeParam param) {
|
||||||
|
List<Knowledge> list = knowledgeService.listVo(param);
|
||||||
|
return JsonResponse.data(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取知识点树结构
|
||||||
|
*/
|
||||||
|
@GetMapping("/treeList")
|
||||||
|
public JsonResponse treeList(KnowledgeParam param) {
|
||||||
|
List<Knowledge> list = knowledgeService.treeList(param);
|
||||||
|
return JsonResponse.data(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 详情 */
|
||||||
|
@GetMapping("/getDetail")
|
||||||
|
public JsonResponse detail(@RequestParam("id") Integer id) {
|
||||||
|
return JsonResponse.data( knowledgeService.stuGetByIdVo(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,10 +3,14 @@ server:
|
|||||||
tomcat:
|
tomcat:
|
||||||
max-swallow-size: 10000MB
|
max-swallow-size: 10000MB
|
||||||
connection-timeout: 600000
|
connection-timeout: 600000
|
||||||
|
|
||||||
ai:
|
ai:
|
||||||
platform:
|
platform:
|
||||||
host: "http://localhost:9380/"
|
host: "http://localhost:9380/"
|
||||||
api-key: "ragflow-VlZWVjMDg0ZjAzMTExZWZhZDhkZTU5ZD"
|
api-key: "ragflow-VlZWVjMDg0ZjAzMTExZWZhZDhkZTU5ZD"
|
||||||
|
platform:
|
||||||
|
config:
|
||||||
|
profile: D:/ruoyi/uploadPath
|
||||||
spring:
|
spring:
|
||||||
profiles:
|
profiles:
|
||||||
active: kafka,quartz,dev
|
active: kafka,quartz,dev
|
||||||
|
|||||||
@ -0,0 +1,50 @@
|
|||||||
|
package xyz.playedu.common.config;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@ConfigurationProperties(prefix = "platform.config")
|
||||||
|
public class PlatformConfig {
|
||||||
|
|
||||||
|
private static String profile;
|
||||||
|
|
||||||
|
|
||||||
|
public static String getProfile() {
|
||||||
|
return profile;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void setProfile(String profile) {
|
||||||
|
PlatformConfig.profile = profile;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 获取导入上传路径
|
||||||
|
*/
|
||||||
|
public static String getImportPath() {
|
||||||
|
return getProfile() + "/import";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取头像上传路径
|
||||||
|
*/
|
||||||
|
public static String getAvatarPath() {
|
||||||
|
return getProfile() + "/avatar";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取下载路径
|
||||||
|
*/
|
||||||
|
public static String getDownloadPath() {
|
||||||
|
return getProfile() + "/download/";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取上传路径
|
||||||
|
*/
|
||||||
|
public static String getUploadPath() {
|
||||||
|
return getProfile() + "/upload";
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
package xyz.playedu.common.config;
|
||||||
|
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import xyz.playedu.common.util.ServletUtils;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务相关配置
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class ServerConfig {
|
||||||
|
public static String getDomain(HttpServletRequest request) {
|
||||||
|
StringBuffer url = request.getRequestURL();
|
||||||
|
String contextPath = request.getServletContext().getContextPath();
|
||||||
|
return url.delete(url.length() - request.getRequestURI().length(), url.length()).append(contextPath).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取完整的请求路径,包括:域名,端口,上下文访问路径
|
||||||
|
*
|
||||||
|
* @return 服务地址
|
||||||
|
*/
|
||||||
|
public String getUrl() {
|
||||||
|
HttpServletRequest request = ServletUtils.getRequest();
|
||||||
|
return getDomain(request);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,171 @@
|
|||||||
|
package xyz.playedu.common.util;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.apache.commons.io.FilenameUtils;
|
||||||
|
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import xyz.playedu.common.config.PlatformConfig;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件上传工具类
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public class FileUploadUtils {
|
||||||
|
/**
|
||||||
|
* 默认大小 50M
|
||||||
|
*/
|
||||||
|
public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认的文件名最大长度 100
|
||||||
|
*/
|
||||||
|
public static final int DEFAULT_FILE_NAME_LENGTH = 100;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认上传的地址
|
||||||
|
*/
|
||||||
|
private static String defaultBaseDir = PlatformConfig.getProfile();
|
||||||
|
public static final String RESOURCE_PREFIX = "/profile";
|
||||||
|
|
||||||
|
public static String getDefaultBaseDir() {
|
||||||
|
return defaultBaseDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setDefaultBaseDir(String defaultBaseDir) {
|
||||||
|
FileUploadUtils.defaultBaseDir = defaultBaseDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 以默认配置进行文件上传
|
||||||
|
*
|
||||||
|
* @param file 上传的文件
|
||||||
|
* @return 文件名称
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static final String upload(MultipartFile file) throws IOException {
|
||||||
|
try {
|
||||||
|
return upload(getDefaultBaseDir(), file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IOException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据文件路径上传
|
||||||
|
*
|
||||||
|
* @param baseDir 相对应用的基目录
|
||||||
|
* @param file 上传的文件
|
||||||
|
* @return 文件名称
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static final String upload(String baseDir, MultipartFile file) throws IOException {
|
||||||
|
try {
|
||||||
|
return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IOException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件上传
|
||||||
|
*
|
||||||
|
* @param baseDir 相对应用的基目录
|
||||||
|
* @param file 上传的文件
|
||||||
|
* @param allowedExtension 上传文件类型
|
||||||
|
* @return 返回上传成功的文件名
|
||||||
|
* @throws IOException 比如读写文件出错时
|
||||||
|
*/
|
||||||
|
public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension)
|
||||||
|
throws Exception {
|
||||||
|
int fileNamelength = Objects.requireNonNull(file.getOriginalFilename()).length();
|
||||||
|
if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH) {
|
||||||
|
throw new Exception("文件名过长"+FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String fileName = extractFilename(file);
|
||||||
|
|
||||||
|
String absPath = getAbsoluteFile(baseDir, fileName).getAbsolutePath();
|
||||||
|
file.transferTo(Paths.get(absPath));
|
||||||
|
return getPathFileName(baseDir, fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编码文件名
|
||||||
|
*/
|
||||||
|
public static final String extractFilename(MultipartFile file) {
|
||||||
|
return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(),
|
||||||
|
FilenameUtils.getBaseName(file.getOriginalFilename()), Seq.getId(Seq.uploadSeqType), getExtension(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException {
|
||||||
|
File desc = new File(uploadDir + File.separator + fileName);
|
||||||
|
|
||||||
|
if (!desc.exists()) {
|
||||||
|
if (!desc.getParentFile().exists()) {
|
||||||
|
desc.getParentFile().mkdirs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String getPathFileName(String uploadDir, String fileName) throws IOException {
|
||||||
|
int dirLastIndex = PlatformConfig.getProfile().length() + 1;
|
||||||
|
String currentDir = StringUtils.substring(uploadDir, dirLastIndex);
|
||||||
|
return RESOURCE_PREFIX + "/" + currentDir + "/" + fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断MIME类型是否是允许的MIME类型
|
||||||
|
*
|
||||||
|
* @param extension
|
||||||
|
* @param allowedExtension
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static final boolean isAllowedExtension(String extension, String[] allowedExtension) {
|
||||||
|
for (String str : allowedExtension) {
|
||||||
|
if (str.equalsIgnoreCase(extension)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件名的后缀
|
||||||
|
*
|
||||||
|
* @param file 表单文件
|
||||||
|
* @return 后缀名
|
||||||
|
*/
|
||||||
|
public static final String getExtension(MultipartFile file) {
|
||||||
|
String extension = FilenameUtils.getExtension(file.getOriginalFilename());
|
||||||
|
if (StringUtils.isEmpty(extension)) {
|
||||||
|
extension = MimeTypeUtils.getExtension(Objects.requireNonNull(file.getContentType()));
|
||||||
|
}
|
||||||
|
return extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件名称 /profile/upload/2022/04/16/ruoyi.png -- ruoyi.png
|
||||||
|
*
|
||||||
|
* @param fileName 路径名称
|
||||||
|
* @return 没有文件路径的名称
|
||||||
|
*/
|
||||||
|
public static String getName(String fileName) {
|
||||||
|
if (fileName == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int lastUnixPos = fileName.lastIndexOf('/');
|
||||||
|
int lastWindowsPos = fileName.lastIndexOf('\\');
|
||||||
|
int index = Math.max(lastUnixPos, lastWindowsPos);
|
||||||
|
return fileName.substring(index + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
package xyz.playedu.common.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 媒体类型工具类
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public class MimeTypeUtils {
|
||||||
|
public static final String IMAGE_PNG = "image/png";
|
||||||
|
|
||||||
|
public static final String IMAGE_JPG = "image/jpg";
|
||||||
|
|
||||||
|
public static final String IMAGE_JPEG = "image/jpeg";
|
||||||
|
|
||||||
|
public static final String IMAGE_BMP = "image/bmp";
|
||||||
|
|
||||||
|
public static final String IMAGE_GIF = "image/gif";
|
||||||
|
|
||||||
|
public static final String[] IMAGE_EXTENSION = {"bmp", "gif", "jpg", "jpeg", "png"};
|
||||||
|
|
||||||
|
public static final String[] FLASH_EXTENSION = {"swf", "flv"};
|
||||||
|
|
||||||
|
public static final String[] MEDIA_EXTENSION = {"swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg",
|
||||||
|
"asf", "rm", "rmvb"};
|
||||||
|
|
||||||
|
public static final String[] VIDEO_EXTENSION = {"mp4", "avi", "rmvb"};
|
||||||
|
|
||||||
|
public static final String[] DEFAULT_ALLOWED_EXTENSION = {
|
||||||
|
// 图片
|
||||||
|
"bmp", "gif", "jpg", "jpeg", "png",
|
||||||
|
// word excel powerpoint
|
||||||
|
"doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt",
|
||||||
|
// 压缩文件
|
||||||
|
"rar", "zip", "gz", "bz2",
|
||||||
|
// 视频格式
|
||||||
|
"mp4", "avi", "rmvb",
|
||||||
|
// pdf
|
||||||
|
"pdf"};
|
||||||
|
|
||||||
|
public static String getExtension(String prefix) {
|
||||||
|
switch (prefix) {
|
||||||
|
case IMAGE_PNG:
|
||||||
|
return "png";
|
||||||
|
case IMAGE_JPG:
|
||||||
|
return "jpg";
|
||||||
|
case IMAGE_JPEG:
|
||||||
|
return "jpeg";
|
||||||
|
case IMAGE_BMP:
|
||||||
|
return "bmp";
|
||||||
|
case IMAGE_GIF:
|
||||||
|
return "gif";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,76 @@
|
|||||||
|
package xyz.playedu.common.util;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ruoyi 序列生成类
|
||||||
|
*/
|
||||||
|
public class Seq {
|
||||||
|
// 通用序列类型
|
||||||
|
public static final String commSeqType = "COMMON";
|
||||||
|
|
||||||
|
// 上传序列类型
|
||||||
|
public static final String uploadSeqType = "UPLOAD";
|
||||||
|
// 机器标识
|
||||||
|
private static final String machineCode = "A";
|
||||||
|
// 通用接口序列数
|
||||||
|
private static AtomicInteger commSeq = new AtomicInteger(1);
|
||||||
|
// 上传接口序列数
|
||||||
|
private static AtomicInteger uploadSeq = new AtomicInteger(1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取通用序列号
|
||||||
|
*
|
||||||
|
* @return 序列值
|
||||||
|
*/
|
||||||
|
public static String getId() {
|
||||||
|
return getId(commSeqType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认16位序列号 yyMMddHHmmss + 一位机器标识 + 3长度循环递增字符串
|
||||||
|
*
|
||||||
|
* @return 序列值
|
||||||
|
*/
|
||||||
|
public static String getId(String type) {
|
||||||
|
AtomicInteger atomicInt = commSeq;
|
||||||
|
if (uploadSeqType.equals(type)) {
|
||||||
|
atomicInt = uploadSeq;
|
||||||
|
}
|
||||||
|
return getId(atomicInt, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通用接口序列号 yyMMddHHmmss + 一位机器标识 + length长度循环递增字符串
|
||||||
|
*
|
||||||
|
* @param atomicInt 序列数
|
||||||
|
* @param length 数值长度
|
||||||
|
* @return 序列值
|
||||||
|
*/
|
||||||
|
public static String getId(AtomicInteger atomicInt, int length) {
|
||||||
|
String result = DateUtil.format(DateUtil.date(), "yyyyMMddHHmmss");
|
||||||
|
result += machineCode;
|
||||||
|
result += getSeq(atomicInt, length);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 序列循环递增字符串[1, 10 的 (length)幂次方), 用0左补齐length位数
|
||||||
|
*
|
||||||
|
* @return 序列值
|
||||||
|
*/
|
||||||
|
private synchronized static String getSeq(AtomicInteger atomicInt, int length) {
|
||||||
|
// 先取值再+1
|
||||||
|
int value = atomicInt.getAndIncrement();
|
||||||
|
|
||||||
|
// 如果更新后值>=10 的 (length)幂次方则重置为1
|
||||||
|
int maxSeq = (int) Math.pow(10, length);
|
||||||
|
if (atomicInt.get() >= maxSeq) {
|
||||||
|
atomicInt.set(1);
|
||||||
|
}
|
||||||
|
// 转字符串,用0左补齐
|
||||||
|
return StringUtils.padl(value, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,72 @@
|
|||||||
|
package xyz.playedu.common.util;
|
||||||
|
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import jakarta.servlet.http.HttpSession;
|
||||||
|
import org.springframework.web.context.request.RequestAttributes;
|
||||||
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 客户端工具类
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public class ServletUtils {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取request
|
||||||
|
*/
|
||||||
|
public static HttpServletRequest getRequest() {
|
||||||
|
return getRequestAttributes().getRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取response
|
||||||
|
*/
|
||||||
|
public static HttpServletResponse getResponse() {
|
||||||
|
return getRequestAttributes().getResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取session
|
||||||
|
*/
|
||||||
|
public static HttpSession getSession() {
|
||||||
|
return getRequest().getSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ServletRequestAttributes getRequestAttributes() {
|
||||||
|
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
|
||||||
|
return (ServletRequestAttributes) attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将字符串渲染到客户端
|
||||||
|
*
|
||||||
|
* @param response 渲染对象
|
||||||
|
* @param string 待渲染的字符串
|
||||||
|
*/
|
||||||
|
public static void renderString(HttpServletResponse response, String string) {
|
||||||
|
try {
|
||||||
|
response.setStatus(200);
|
||||||
|
response.setContentType("application/json");
|
||||||
|
response.setCharacterEncoding("utf-8");
|
||||||
|
response.getWriter().print(string);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
|
|||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import xyz.playedu.framework.tenant.core.db.TenantBaseDO;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
@ -14,7 +15,7 @@ import java.util.Date;
|
|||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@TableName("jc_book_chapter")
|
@TableName("jc_book_chapter")
|
||||||
public class BookChapter {
|
public class BookChapter extends TenantBaseDO {
|
||||||
|
|
||||||
@TableId(type = IdType.AUTO)
|
@TableId(type = IdType.AUTO)
|
||||||
private Integer id;
|
private Integer id;
|
||||||
@ -34,23 +35,11 @@ public class BookChapter {
|
|||||||
/** 章节名 */
|
/** 章节名 */
|
||||||
@TableField("name")
|
@TableField("name")
|
||||||
private String name;
|
private String name;
|
||||||
|
/** 层级 */
|
||||||
|
private Integer level;
|
||||||
|
|
||||||
/** 排序 */
|
/** 排序 */
|
||||||
@TableField("sort")
|
@TableField("sort")
|
||||||
private Integer sort;
|
private Integer sort;
|
||||||
|
|
||||||
@TableField("create_time")
|
|
||||||
private Date createTime;
|
|
||||||
|
|
||||||
@TableField("update_time")
|
|
||||||
private Date updateTime;
|
|
||||||
|
|
||||||
@TableField("creator")
|
|
||||||
private String creator;
|
|
||||||
|
|
||||||
@TableField("updater")
|
|
||||||
private String updater;
|
|
||||||
|
|
||||||
@TableField("tenant_id")
|
|
||||||
private String tenantId;
|
|
||||||
}
|
}
|
||||||
@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
|
|||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import xyz.playedu.framework.tenant.core.db.TenantBaseDO;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
@ -14,7 +15,7 @@ import java.util.Date;
|
|||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@TableName("jc_book_department_user")
|
@TableName("jc_book_department_user")
|
||||||
public class BookDepartmentUser {
|
public class BookDepartmentUser extends TenantBaseDO {
|
||||||
|
|
||||||
/** 教材ID */
|
/** 教材ID */
|
||||||
@TableField("book_id")
|
@TableField("book_id")
|
||||||
@ -28,18 +29,4 @@ public class BookDepartmentUser {
|
|||||||
@TableField("type")
|
@TableField("type")
|
||||||
private Integer type;
|
private Integer type;
|
||||||
|
|
||||||
@TableField("creator")
|
|
||||||
private String creator;
|
|
||||||
|
|
||||||
@TableField("updater")
|
|
||||||
private String updater;
|
|
||||||
|
|
||||||
@TableField("create_time")
|
|
||||||
private Date createTime;
|
|
||||||
|
|
||||||
@TableField("update_time")
|
|
||||||
private Date updateTime;
|
|
||||||
|
|
||||||
@TableField("tenant_id")
|
|
||||||
private String tenantId;
|
|
||||||
}
|
}
|
||||||
@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
|
|||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import xyz.playedu.framework.tenant.core.db.TenantBaseDO;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
@ -14,7 +15,7 @@ import java.util.Date;
|
|||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@TableName("jc_book_paper")
|
@TableName("jc_book_paper")
|
||||||
public class BookPaper {
|
public class BookPaper extends TenantBaseDO {
|
||||||
|
|
||||||
@TableId(type = IdType.AUTO)
|
@TableId(type = IdType.AUTO)
|
||||||
private Integer id;
|
private Integer id;
|
||||||
@ -32,18 +33,4 @@ public class BookPaper {
|
|||||||
@TableField("extra")
|
@TableField("extra")
|
||||||
private String extra;
|
private String extra;
|
||||||
|
|
||||||
@TableField("creator")
|
|
||||||
private String creator;
|
|
||||||
|
|
||||||
@TableField("updater")
|
|
||||||
private String updater;
|
|
||||||
|
|
||||||
@TableField("create_time")
|
|
||||||
private Date createTime;
|
|
||||||
|
|
||||||
@TableField("update_time")
|
|
||||||
private Date updateTime;
|
|
||||||
|
|
||||||
@TableField("tenant_id")
|
|
||||||
private String tenantId;
|
|
||||||
}
|
}
|
||||||
@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
|
|||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import xyz.playedu.framework.tenant.core.db.TenantBaseDO;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
@ -15,7 +16,7 @@ import java.util.Date;
|
|||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@TableName("jc_chapter_content")
|
@TableName("jc_chapter_content")
|
||||||
public class ChapterContent {
|
public class ChapterContent extends TenantBaseDO {
|
||||||
|
|
||||||
@TableId(type = IdType.AUTO)
|
@TableId(type = IdType.AUTO)
|
||||||
private Integer id;
|
private Integer id;
|
||||||
@ -34,28 +35,9 @@ public class ChapterContent {
|
|||||||
@TableField("type")
|
@TableField("type")
|
||||||
private String type;
|
private String type;
|
||||||
|
|
||||||
// /** 关联资源ID(逗号分隔) */
|
private String knowledgeCode;
|
||||||
// @TableField("resource_ids")
|
|
||||||
// private String resourceIds;
|
|
||||||
//
|
|
||||||
// /** 关联知识点ID(逗号分隔) */
|
|
||||||
// @TableField("knowledge_ids")
|
|
||||||
// private String knowledgeIds;
|
|
||||||
|
|
||||||
/** 创建人 */
|
/** 章节名称 */
|
||||||
@TableField("creator")
|
@TableField(exist = false)
|
||||||
private String creator;
|
private String chapterName;
|
||||||
|
|
||||||
/** 更新人 */
|
|
||||||
@TableField("updater")
|
|
||||||
private String updater;
|
|
||||||
|
|
||||||
@TableField("create_time")
|
|
||||||
private Date createTime;
|
|
||||||
|
|
||||||
@TableField("update_time")
|
|
||||||
private Date updateTime;
|
|
||||||
|
|
||||||
@TableField("tenant_id")
|
|
||||||
private String tenantId;
|
|
||||||
}
|
}
|
||||||
@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
|
|||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import xyz.playedu.framework.tenant.core.db.TenantBaseDO;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
@ -14,7 +15,7 @@ import java.util.Date;
|
|||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@TableName("jc_discussion")
|
@TableName("jc_discussion")
|
||||||
public class Discussion {
|
public class Discussion extends TenantBaseDO {
|
||||||
|
|
||||||
@TableId(type = IdType.AUTO)
|
@TableId(type = IdType.AUTO)
|
||||||
private Integer id;
|
private Integer id;
|
||||||
@ -51,20 +52,12 @@ public class Discussion {
|
|||||||
@TableField("status")
|
@TableField("status")
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
|
||||||
/** 创建人(可以是用户名) */
|
/** 知识点编码 */
|
||||||
@TableField("creator")
|
@TableField(exist = false)
|
||||||
private String creator;
|
private String knowledgeCode;
|
||||||
|
@TableField(exist = false)
|
||||||
|
private String chapterName;
|
||||||
|
@TableField(exist = false)
|
||||||
|
private String orderType;
|
||||||
|
|
||||||
/** 更新人 */
|
|
||||||
@TableField("updater")
|
|
||||||
private String updater;
|
|
||||||
|
|
||||||
@TableField("create_time")
|
|
||||||
private Date createTime;
|
|
||||||
|
|
||||||
@TableField("update_time")
|
|
||||||
private Date updateTime;
|
|
||||||
|
|
||||||
@TableField("tenant_id")
|
|
||||||
private String tenantId;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
|
|||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import xyz.playedu.framework.tenant.core.db.TenantBaseDO;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
@ -14,7 +15,7 @@ import java.util.Date;
|
|||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@TableName("jc_discussion_detail")
|
@TableName("jc_discussion_detail")
|
||||||
public class DiscussionDetail {
|
public class DiscussionDetail extends TenantBaseDO {
|
||||||
|
|
||||||
@TableId(type = IdType.AUTO)
|
@TableId(type = IdType.AUTO)
|
||||||
private Integer id;
|
private Integer id;
|
||||||
@ -46,19 +47,4 @@ public class DiscussionDetail {
|
|||||||
/** 讨论内容 */
|
/** 讨论内容 */
|
||||||
@TableField("content")
|
@TableField("content")
|
||||||
private String content;
|
private String content;
|
||||||
|
|
||||||
@TableField("create_time")
|
|
||||||
private Date createTime;
|
|
||||||
|
|
||||||
@TableField("update_time")
|
|
||||||
private Date updateTime;
|
|
||||||
|
|
||||||
@TableField("creator")
|
|
||||||
private String creator;
|
|
||||||
|
|
||||||
@TableField("updater")
|
|
||||||
private String updater;
|
|
||||||
|
|
||||||
@TableField("tenant_id")
|
|
||||||
private String tenantId;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,8 +31,8 @@ public class JCResource {
|
|||||||
@TableField("name")
|
@TableField("name")
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@TableField("konwledge_code")
|
@TableField("knowledge_code")
|
||||||
private String konwledgeCode;
|
private String knowledgeCode;
|
||||||
|
|
||||||
|
|
||||||
/** 文本描述 AI分析或自动填入 */
|
/** 文本描述 AI分析或自动填入 */
|
||||||
|
|||||||
@ -5,8 +5,10 @@ import com.baomidou.mybatisplus.annotation.TableField;
|
|||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import xyz.playedu.framework.tenant.core.db.TenantBaseDO;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 知识点表
|
* 知识点表
|
||||||
@ -14,7 +16,7 @@ import java.util.Date;
|
|||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@TableName("jc_knowledge")
|
@TableName("jc_knowledge")
|
||||||
public class Knowledge {
|
public class Knowledge extends TenantBaseDO {
|
||||||
|
|
||||||
@TableId(type = IdType.AUTO)
|
@TableId(type = IdType.AUTO)
|
||||||
private Integer id;
|
private Integer id;
|
||||||
@ -31,9 +33,9 @@ public class Knowledge {
|
|||||||
@TableField("name")
|
@TableField("name")
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
/** 知识点code(字段名拼写为 konwledge_code) */
|
/** 知识点code(字段名拼写为 knowledge_code) */
|
||||||
@TableField("konwledge_code")
|
@TableField("knowledge_code")
|
||||||
private String konwledgeCode;
|
private String knowledgeCode;
|
||||||
|
|
||||||
/** 知识点介绍 */
|
/** 知识点介绍 */
|
||||||
@TableField("desc")
|
@TableField("desc")
|
||||||
@ -41,11 +43,14 @@ public class Knowledge {
|
|||||||
|
|
||||||
/** 层级 */
|
/** 层级 */
|
||||||
@TableField("level")
|
@TableField("level")
|
||||||
private String level;
|
private Integer level;
|
||||||
|
|
||||||
/** 知识点类型 */
|
/** 知识点类型 */
|
||||||
@TableField("type")
|
@TableField("type")
|
||||||
private String type;
|
private String type;
|
||||||
|
/** 是否是真实知识点 */
|
||||||
|
@TableField("is_real")
|
||||||
|
private String isReal;
|
||||||
|
|
||||||
/** 当前层级排序 */
|
/** 当前层级排序 */
|
||||||
@TableField("order_num")
|
@TableField("order_num")
|
||||||
@ -54,19 +59,7 @@ public class Knowledge {
|
|||||||
/** 预留JSON */
|
/** 预留JSON */
|
||||||
@TableField("extra_json")
|
@TableField("extra_json")
|
||||||
private String extraJson;
|
private String extraJson;
|
||||||
|
//子节点
|
||||||
@TableField("create_time")
|
@TableField(exist = false)
|
||||||
private Date createTime;
|
private List<Knowledge> children;
|
||||||
|
|
||||||
@TableField("update_time")
|
|
||||||
private Date updateTime;
|
|
||||||
|
|
||||||
@TableField("creator")
|
|
||||||
private String creator;
|
|
||||||
|
|
||||||
@TableField("updater")
|
|
||||||
private String updater;
|
|
||||||
|
|
||||||
@TableField("tenant_id")
|
|
||||||
private String tenantId;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
|
|||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import xyz.playedu.framework.tenant.core.db.TenantBaseDO;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
@ -14,7 +15,7 @@ import java.util.Date;
|
|||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@TableName("jc_note")
|
@TableName("jc_note")
|
||||||
public class Note {
|
public class Note extends TenantBaseDO {
|
||||||
|
|
||||||
@TableId(type = IdType.AUTO)
|
@TableId(type = IdType.AUTO)
|
||||||
private Integer id;
|
private Integer id;
|
||||||
@ -50,19 +51,11 @@ public class Note {
|
|||||||
/** 存储笔记信息的JSON(位置信息等) */
|
/** 存储笔记信息的JSON(位置信息等) */
|
||||||
@TableField("extra_json")
|
@TableField("extra_json")
|
||||||
private String extraJson;
|
private String extraJson;
|
||||||
|
/** 知识点编码 */
|
||||||
@TableField("create_time")
|
@TableField(exist = false)
|
||||||
private Date createTime;
|
private String knowledgeCode;
|
||||||
|
@TableField(exist = false)
|
||||||
@TableField("update_time")
|
private String chapterName;
|
||||||
private Date updateTime;
|
@TableField(exist = false)
|
||||||
|
private String orderType;
|
||||||
@TableField("creator")
|
|
||||||
private String creator;
|
|
||||||
|
|
||||||
@TableField("updater")
|
|
||||||
private String updater;
|
|
||||||
|
|
||||||
@TableField("tenant_id")
|
|
||||||
private String tenantId;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
|
|||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import xyz.playedu.framework.tenant.core.db.TenantBaseDO;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
@ -14,7 +15,7 @@ import java.util.Date;
|
|||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@TableName("jc_textbook")
|
@TableName("jc_textbook")
|
||||||
public class Textbook {
|
public class Textbook extends TenantBaseDO {
|
||||||
|
|
||||||
@TableId(type = IdType.AUTO)
|
@TableId(type = IdType.AUTO)
|
||||||
private Integer id;
|
private Integer id;
|
||||||
@ -54,20 +55,4 @@ public class Textbook {
|
|||||||
@TableField("publish_time")
|
@TableField("publish_time")
|
||||||
private Date publishTime;
|
private Date publishTime;
|
||||||
|
|
||||||
/** 创建人 */
|
|
||||||
@TableField("creator")
|
|
||||||
private String creator;
|
|
||||||
|
|
||||||
/** 更新人 */
|
|
||||||
@TableField("updater")
|
|
||||||
private String updater;
|
|
||||||
|
|
||||||
@TableField("create_time")
|
|
||||||
private Date createTime;
|
|
||||||
|
|
||||||
@TableField("update_time")
|
|
||||||
private Date updateTime;
|
|
||||||
|
|
||||||
@TableField("tenant_id")
|
|
||||||
private String tenantId;
|
|
||||||
}
|
}
|
||||||
@ -1,10 +1,15 @@
|
|||||||
package xyz.playedu.jc.mapper;
|
package xyz.playedu.jc.mapper;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
import xyz.playedu.jc.domain.Discussion;
|
import xyz.playedu.jc.domain.Discussion;
|
||||||
|
import xyz.playedu.jc.domain.Note;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 讨论 Mapper
|
* 讨论 Mapper
|
||||||
*/
|
*/
|
||||||
public interface DiscussionMapper extends BaseMapper<Discussion> {
|
public interface DiscussionMapper extends BaseMapper<Discussion> {
|
||||||
|
List<Discussion> listVo(@Param("param") Discussion note);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,14 @@
|
|||||||
package xyz.playedu.jc.mapper;
|
package xyz.playedu.jc.mapper;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
import xyz.playedu.jc.domain.Note;
|
import xyz.playedu.jc.domain.Note;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 笔记 Mapper
|
* 笔记 Mapper
|
||||||
*/
|
*/
|
||||||
public interface NoteMapper extends BaseMapper<Note> {
|
public interface NoteMapper extends BaseMapper<Note> {
|
||||||
|
List<Note> listVo(@Param("param") Note note);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,13 @@
|
|||||||
|
package xyz.playedu.jc.param;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class KnowledgeParam {
|
||||||
|
//书本id
|
||||||
|
private Integer bookId;
|
||||||
|
//知识点名称
|
||||||
|
private String name;
|
||||||
|
//知识点code
|
||||||
|
private String knowledgeCode;
|
||||||
|
}
|
||||||
@ -1,15 +1,24 @@
|
|||||||
package xyz.playedu.jc.service;
|
package xyz.playedu.jc.service;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import xyz.playedu.common.types.paginate.PaginationResult;
|
import xyz.playedu.common.types.paginate.PaginationResult;
|
||||||
import xyz.playedu.jc.domain.Knowledge;
|
import xyz.playedu.jc.domain.Knowledge;
|
||||||
|
import xyz.playedu.jc.param.KnowledgeParam;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 知识点 Service
|
* 知识点 Service
|
||||||
*/
|
*/
|
||||||
public interface IKnowledgeService extends IService<Knowledge> {
|
public interface IKnowledgeService extends IService<Knowledge> {
|
||||||
|
List<Knowledge> listVo(KnowledgeParam param);
|
||||||
|
|
||||||
|
List<Knowledge> treeList(KnowledgeParam param);
|
||||||
|
void saveOrUpdateVo(Knowledge data);
|
||||||
|
JSONObject getByIdVo(Integer id);
|
||||||
|
JSONObject stuGetByIdVo(Integer id);
|
||||||
|
|
||||||
|
|
||||||
PaginationResult<Knowledge> paginate(HashMap<String, Object> params);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,75 +1,255 @@
|
|||||||
package xyz.playedu.jc.service.impl;
|
package xyz.playedu.jc.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.collections4.MapUtils;
|
import org.apache.commons.collections4.MapUtils;
|
||||||
|
import org.checkerframework.checker.units.qual.A;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import xyz.playedu.common.context.FCtx;
|
||||||
|
import xyz.playedu.common.domain.User;
|
||||||
import xyz.playedu.common.types.paginate.PaginationResult;
|
import xyz.playedu.common.types.paginate.PaginationResult;
|
||||||
import xyz.playedu.jc.domain.Knowledge;
|
import xyz.playedu.jc.domain.*;
|
||||||
import xyz.playedu.jc.mapper.KnowledgeMapper;
|
import xyz.playedu.jc.mapper.*;
|
||||||
|
import xyz.playedu.jc.param.KnowledgeParam;
|
||||||
import xyz.playedu.jc.service.IKnowledgeService;
|
import xyz.playedu.jc.service.IKnowledgeService;
|
||||||
|
import xyz.playedu.jc.service.ITextbookService;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 知识点 Service 实现
|
* 知识点 Service 实现
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
public class KnowledgeServiceImpl
|
public class KnowledgeServiceImpl extends ServiceImpl<KnowledgeMapper, Knowledge> implements IKnowledgeService {
|
||||||
extends ServiceImpl<KnowledgeMapper, Knowledge>
|
@Autowired
|
||||||
implements IKnowledgeService {
|
private ChapterContentMapper contentMapper;
|
||||||
|
@Autowired
|
||||||
|
private JCResourceMapper resourceMapper;
|
||||||
|
@Autowired
|
||||||
|
private BookChapterMapper chapterMapper;
|
||||||
|
@Autowired
|
||||||
|
private NoteMapper noteMapper;
|
||||||
|
@Autowired
|
||||||
|
private DiscussionMapper discussionMapper;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PaginationResult<Knowledge> paginate(HashMap<String, Object> params) {
|
public List<Knowledge> listVo(KnowledgeParam param) {
|
||||||
try {
|
//获取知识点卡片
|
||||||
Integer page = MapUtils.getInteger(params, "page", 1);
|
|
||||||
Integer size = MapUtils.getInteger(params, "size", 10);
|
|
||||||
|
|
||||||
Page<Knowledge> pageParam = new Page<>(page, size);
|
|
||||||
LambdaQueryWrapper<Knowledge> queryWrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<Knowledge> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(Knowledge::getBookId, param.getBookId())
|
||||||
Integer bookId = MapUtils.getInteger(params, "bookId");
|
.eq(Knowledge::getIsReal,"1").orderByAsc(Knowledge::getOrderNum);
|
||||||
if (bookId != null) {
|
return list(queryWrapper);
|
||||||
queryWrapper.eq(Knowledge::getBookId, bookId);
|
}
|
||||||
|
@Override
|
||||||
|
public JSONObject getByIdVo(Integer id) {
|
||||||
|
JSONObject res = new JSONObject();
|
||||||
|
Knowledge knowledge = this.getById(id);
|
||||||
|
res.put("knowledge", knowledge);
|
||||||
|
//获取各个板块该知识点下的资源
|
||||||
|
LambdaQueryWrapper<ChapterContent> contentWrapper = new LambdaQueryWrapper<>();
|
||||||
|
contentWrapper.select(ChapterContent::getId,ChapterContent::getChapterId).like(ChapterContent::getKnowledgeCode, knowledge.getKnowledgeCode()).eq(ChapterContent::getBookId, knowledge.getBookId());
|
||||||
|
List<ChapterContent> contents = contentMapper.selectList(contentWrapper);
|
||||||
|
for (ChapterContent content : contents) {
|
||||||
|
BookChapter bookChapter = chapterMapper.selectById(content.getChapterId());
|
||||||
|
content.setChapterName(bookChapter.getName());
|
||||||
|
}
|
||||||
|
res.put("contents", contents);
|
||||||
|
LambdaQueryWrapper<JCResource> resourceWrapper = new LambdaQueryWrapper<>();
|
||||||
|
resourceWrapper.like(JCResource::getKnowledgeCode, knowledge.getKnowledgeCode()).eq(JCResource::getBookId, knowledge.getBookId());
|
||||||
|
res.put("resources", resourceMapper.selectList(resourceWrapper));
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
Integer parentId = MapUtils.getInteger(params, "parentId");
|
@Override
|
||||||
if (parentId != null) {
|
public JSONObject stuGetByIdVo(Integer id) {
|
||||||
|
Knowledge knowledge = this.getById(id);
|
||||||
|
//获取当前学生信息
|
||||||
|
User user = FCtx.getUser();
|
||||||
|
JSONObject res = this.getByIdVo(id);
|
||||||
|
//获取笔记信息
|
||||||
|
Note param = new Note();
|
||||||
|
param.setBookId(knowledge.getBookId());
|
||||||
|
param.setKnowledgeCode(knowledge.getKnowledgeCode());
|
||||||
|
param.setUserId(user.getId());
|
||||||
|
List<Note> notes = noteMapper.listVo(param);
|
||||||
|
res.put("notes", notes);
|
||||||
|
//获取讨论信息
|
||||||
|
Discussion discussion = new Discussion();
|
||||||
|
discussion.setBookId(knowledge.getBookId());
|
||||||
|
discussion.setKnowledgeCode(knowledge.getKnowledgeCode());
|
||||||
|
discussion.setUserId(user.getId());
|
||||||
|
List<Discussion> discussions = discussionMapper.listVo(discussion);
|
||||||
|
res.put("discussions", discussions);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Knowledge> treeList(KnowledgeParam param) {
|
||||||
|
//获取全部知识点
|
||||||
|
LambdaQueryWrapper<Knowledge> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(Knowledge::getBookId, param.getBookId()).orderByAsc(Knowledge::getOrderNum);
|
||||||
|
List<Knowledge> allKnowledges = this.list(queryWrapper);
|
||||||
|
// 处理为树结构
|
||||||
|
return buildTree(allKnowledges);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveOrUpdateVo(Knowledge data) {
|
||||||
|
if (ObjectUtil.isEmpty(data.getId())){
|
||||||
|
Knowledge knowledge = this.getById(data.getId());
|
||||||
|
knowledge.setDesc(data.getDesc());
|
||||||
|
knowledge.setName(data.getName());
|
||||||
|
knowledge.setType(data.getType());
|
||||||
|
this.updateById(knowledge);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ObjectUtil.isNotEmpty(data.getParentId())||data.getParentId()==0){
|
||||||
|
data.setLevel(1);
|
||||||
|
data.setKnowledgeCode(generateKnowledgeCode(data.getParentId()));
|
||||||
|
this.save(data);
|
||||||
|
}else {
|
||||||
|
Knowledge byId = this.getById(data.getParentId());
|
||||||
|
data.setLevel(byId.getLevel()+1);
|
||||||
|
data.setKnowledgeCode(generateKnowledgeCode(data.getParentId()));
|
||||||
|
this.save(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private List<Knowledge> buildTree(List<Knowledge> knowledges) {
|
||||||
|
// 创建一个map来存储id到对象的映射,方便快速查找
|
||||||
|
HashMap<Integer, Knowledge> knowledgeMap = new HashMap<>();
|
||||||
|
for (Knowledge knowledge : knowledges) {
|
||||||
|
knowledgeMap.put(knowledge.getId(), knowledge);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 存储最终的根节点
|
||||||
|
List<Knowledge> rootNodes = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Knowledge knowledge : knowledges) {
|
||||||
|
Integer parentId = knowledge.getParentId();
|
||||||
|
if (parentId == null || parentId == 0) { // 假设没有父节点的是根节点
|
||||||
|
rootNodes.add(knowledge);
|
||||||
|
} else {
|
||||||
|
Knowledge parent = knowledgeMap.get(parentId);
|
||||||
|
if (parent != null) {
|
||||||
|
if (parent.getChildren() == null) {
|
||||||
|
parent.setChildren(new ArrayList<>());
|
||||||
|
}
|
||||||
|
parent.getChildren().add(knowledge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rootNodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成知识点编码
|
||||||
|
* @param parentId 父节点ID,0或null代表顶级节点
|
||||||
|
* @return 知识点编码,如A01、A01A01等
|
||||||
|
*/
|
||||||
|
public String generateKnowledgeCode(Integer parentId) {
|
||||||
|
if (parentId == null || parentId == 0) {
|
||||||
|
// 顶级节点编码生成逻辑
|
||||||
|
// 查询当前最大的顶级节点编码
|
||||||
|
LambdaQueryWrapper<Knowledge> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.isNull(Knowledge::getParentId).or().eq(Knowledge::getParentId, 0);
|
||||||
|
queryWrapper.orderByDesc(Knowledge::getId);
|
||||||
|
List<Knowledge> topKnowledges = this.list(queryWrapper);
|
||||||
|
|
||||||
|
if (topKnowledges.isEmpty()) {
|
||||||
|
return "A01";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取最后一个顶级节点的编码
|
||||||
|
String lastCode = topKnowledges.get(0).getKnowledgeCode();
|
||||||
|
if (lastCode == null || lastCode.isEmpty()) {
|
||||||
|
return "A01";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析并递增编码
|
||||||
|
return incrementCode(lastCode, 3); // 顶级节点固定3位编码
|
||||||
|
} else {
|
||||||
|
// 子节点编码生成逻辑
|
||||||
|
Knowledge parent = this.getById(parentId);
|
||||||
|
if (parent == null || parent.getKnowledgeCode() == null) {
|
||||||
|
throw new RuntimeException("父节点不存在或无编码");
|
||||||
|
}
|
||||||
|
|
||||||
|
String parentCode = parent.getKnowledgeCode();
|
||||||
|
// 查询该父节点下的所有子节点
|
||||||
|
LambdaQueryWrapper<Knowledge> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
queryWrapper.eq(Knowledge::getParentId, parentId);
|
queryWrapper.eq(Knowledge::getParentId, parentId);
|
||||||
|
queryWrapper.orderByDesc(Knowledge::getId);
|
||||||
|
List<Knowledge> childKnowledges = this.list(queryWrapper);
|
||||||
|
|
||||||
|
if (childKnowledges.isEmpty()) {
|
||||||
|
// 第一个子节点
|
||||||
|
return parentCode + "A01";
|
||||||
}
|
}
|
||||||
|
|
||||||
String name = MapUtils.getString(params, "name");
|
// 获取最后一个子节点的编码
|
||||||
if (name != null && !name.isEmpty()) {
|
String lastChildCode = childKnowledges.get(0).getKnowledgeCode();
|
||||||
queryWrapper.like(Knowledge::getName, name);
|
if (lastChildCode == null || lastChildCode.length() <= parentCode.length()) {
|
||||||
|
return parentCode + "A01";
|
||||||
}
|
}
|
||||||
|
|
||||||
queryWrapper.orderByAsc(Knowledge::getOrderNum);
|
// 提取子节点部分并递增
|
||||||
|
String childPart = lastChildCode.substring(parentCode.length());
|
||||||
|
String newChildPart = incrementCode(childPart, 3); // 子节点部分固定3位编码
|
||||||
|
|
||||||
IPage<Knowledge> pageResult = this.page(pageParam, queryWrapper);
|
return parentCode + newChildPart;
|
||||||
|
|
||||||
Long total = pageResult.getTotal();
|
|
||||||
PaginationResult<Knowledge> result = new PaginationResult<>();
|
|
||||||
result.setData(pageResult.getRecords());
|
|
||||||
result.setTotal(total);
|
|
||||||
result.setCurrent(page);
|
|
||||||
result.setSize(size);
|
|
||||||
result.setPages((total + size - 1) / size);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("分页查询知识点失败,参数:{}", params, e);
|
|
||||||
PaginationResult<Knowledge> 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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 递增编码
|
||||||
|
* @param code 当前编码
|
||||||
|
* @param length 编码长度
|
||||||
|
* @return 递增后的编码
|
||||||
|
*/
|
||||||
|
private String incrementCode(String code, int length) {
|
||||||
|
if (code == null || code.isEmpty()) {
|
||||||
|
return "A01";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分离字母和数字部分
|
||||||
|
StringBuilder letters = new StringBuilder();
|
||||||
|
StringBuilder digits = new StringBuilder();
|
||||||
|
|
||||||
|
for (char c : code.toCharArray()) {
|
||||||
|
if (Character.isLetter(c)) {
|
||||||
|
letters.append(c);
|
||||||
|
} else if (Character.isDigit(c)) {
|
||||||
|
digits.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (digits.isEmpty()) {
|
||||||
|
return "A01";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 递增数字部分
|
||||||
|
int num = Integer.parseInt(digits.toString());
|
||||||
|
num++;
|
||||||
|
|
||||||
|
// 格式化回固定长度
|
||||||
|
String format = "%0" + length + "d";
|
||||||
|
return letters.toString() + String.format(format, num);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,9 +5,34 @@
|
|||||||
|
|
||||||
<mapper namespace="xyz.playedu.jc.mapper.DiscussionMapper">
|
<mapper namespace="xyz.playedu.jc.mapper.DiscussionMapper">
|
||||||
|
|
||||||
<!--
|
<select id="listVo" resultType="xyz.playedu.jc.domain.Discussion">
|
||||||
目前使用 MyBatis-Plus 的通用 CRUD,这里可以先留空。
|
select discussion.*, chapter.name as chapterName
|
||||||
如果后续有复杂查询,可以在这里新增 <select> / <update> 等。
|
from jc_discussion discussion
|
||||||
-->
|
inner join jc_chapter_content content on discussion.chapter_id = content.chapter_id
|
||||||
|
inner join jc_book_chapter chapter on content.chapter_id = chapter.id
|
||||||
|
<where>
|
||||||
|
<if test="param.bookId != null">
|
||||||
|
and discussion.book_id = #{param.bookId}
|
||||||
|
</if>
|
||||||
|
<if test="param.userId != null">
|
||||||
|
and discussion.user_id = #{param.userId}
|
||||||
|
</if>
|
||||||
|
<if test="param.chapterId != null">
|
||||||
|
and discussion.chapter_id = #{param.chapterId}
|
||||||
|
</if>
|
||||||
|
<if test="param.knowledgeCode != null and knowledgeCode!=''">
|
||||||
|
and content.knowledge_code like concat('%',#{param.knowledgeCode},'%')
|
||||||
|
</if>
|
||||||
|
|
||||||
|
</where>
|
||||||
|
<choose>
|
||||||
|
<when test="orderType == 'time'">
|
||||||
|
order by discussion.create_time desc
|
||||||
|
</when>
|
||||||
|
<otherwise>
|
||||||
|
order by chapter.level asc, chapter.sort asc
|
||||||
|
</otherwise>
|
||||||
|
</choose>
|
||||||
|
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
@ -4,40 +4,6 @@
|
|||||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
<mapper namespace="xyz.playedu.jc.mapper.KnowledgeMapper">
|
<mapper namespace="xyz.playedu.jc.mapper.KnowledgeMapper">
|
||||||
|
|
||||||
<resultMap id="KnowledgeResultMap" type="xyz.playedu.jc.domain.Knowledge">
|
|
||||||
<id column="id" property="id"/>
|
|
||||||
<result column="book_id" property="bookId"/>
|
|
||||||
<result column="parent_id" property="parentId"/>
|
|
||||||
<result column="name" property="name"/>
|
|
||||||
<result column="konwledge_code" property="konwledgeCode"/>
|
|
||||||
<result column="desc" property="desc"/>
|
|
||||||
<result column="level" property="level"/>
|
|
||||||
<result column="type" property="type"/>
|
|
||||||
<result column="order_num" property="orderNum"/>
|
|
||||||
<result column="extra_json" property="extraJson"/>
|
|
||||||
<result column="create_time" property="createTime"/>
|
|
||||||
<result column="update_time" property="updateTime"/>
|
|
||||||
<result column="creator" property="creator"/>
|
|
||||||
<result column="updater" property="updater"/>
|
|
||||||
<result column="tenant_id" property="tenantId"/>
|
|
||||||
</resultMap>
|
|
||||||
|
|
||||||
<sql id="Base_Column_List">
|
|
||||||
id,
|
|
||||||
book_id,
|
|
||||||
parent_id,
|
|
||||||
name,
|
|
||||||
konwledge_code,
|
|
||||||
`desc`,
|
|
||||||
`level`,
|
|
||||||
`type`,
|
|
||||||
order_num,
|
|
||||||
extra_json,
|
|
||||||
create_time,
|
|
||||||
update_time,
|
|
||||||
creator,
|
|
||||||
updater,
|
|
||||||
tenant_id
|
|
||||||
</sql>
|
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
@ -4,38 +4,35 @@
|
|||||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
<mapper namespace="xyz.playedu.jc.mapper.NoteMapper">
|
<mapper namespace="xyz.playedu.jc.mapper.NoteMapper">
|
||||||
|
|
||||||
<resultMap id="NoteResultMap" type="xyz.playedu.jc.domain.Note">
|
<select id="listVo" resultType="xyz.playedu.jc.domain.Note">
|
||||||
<id column="id" property="id"/>
|
select note.*, chapter.name as chapterName
|
||||||
<result column="book_id" property="bookId"/>
|
from jc_note note
|
||||||
<result column="user_id" property="userId"/>
|
inner join jc_chapter_content content on note.chapter_id = content.chapter_id
|
||||||
<result column="chapter_id" property="chapterId"/>
|
inner join jc_book_chapter chapter on content.chapter_id = chapter.id
|
||||||
<result column="content" property="content"/>
|
<where>
|
||||||
<result column="txt" property="txt"/>
|
<if test="param.bookId != null">
|
||||||
<result column="section_id" property="sectionId"/>
|
and note.book_id = #{param.bookId}
|
||||||
<result column="section_origin_id" property="sectionOriginId"/>
|
</if>
|
||||||
<result column="extra_json" property="extraJson"/>
|
<if test="param.userId != null">
|
||||||
<result column="create_time" property="createTime"/>
|
and note.user_id = #{param.userId}
|
||||||
<result column="update_time" property="updateTime"/>
|
</if>
|
||||||
<result column="creator" property="creator"/>
|
<if test="param.chapterId != null">
|
||||||
<result column="updater" property="updater"/>
|
and note.chapter_id = #{param.chapterId}
|
||||||
<result column="tenant_id" property="tenantId"/>
|
</if>
|
||||||
</resultMap>
|
<if test="param.knowledgeCode != null and knowledgeCode!=''">
|
||||||
|
and content.knowledge_code like concat('%',#{param.knowledgeCode},'%')
|
||||||
|
</if>
|
||||||
|
|
||||||
<sql id="Base_Column_List">
|
</where>
|
||||||
id,
|
<choose>
|
||||||
book_id,
|
<when test="orderType == 'time'">
|
||||||
user_id,
|
order by note.create_time desc
|
||||||
chapter_id,
|
</when>
|
||||||
content,
|
<otherwise>
|
||||||
txt,
|
order by chapter.level asc, chapter.sort asc
|
||||||
section_id,
|
</otherwise>
|
||||||
section_origin_id,
|
</choose>
|
||||||
extra_json,
|
|
||||||
create_time,
|
</select>
|
||||||
update_time,
|
|
||||||
creator,
|
|
||||||
updater,
|
|
||||||
tenant_id
|
|
||||||
</sql>
|
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user