From 90626e73d9a59e8190cb5eb1242c1baeb8eacdf9 Mon Sep 17 00:00:00 2001 From: ikmkj Date: Wed, 4 Mar 2026 16:27:42 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E7=BB=9F=E4=B8=80ID=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E4=B8=BALong=E5=B9=B6=E4=BC=98=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=AE=89=E5=85=A8=E6=80=A7=E5=92=8C=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复用户删除接口的ID类型从Integer改为Long 移除未使用的Bouncy Castle依赖 添加dompurify依赖增强XSS防护 修复SQL表定义中的bigintBIGINT语法错误 优化图片预览接口的安全检查和错误处理 添加Vditor渲染引擎预加载和图片懒加载 统一分组和文件接口的ID类型为Long 增强前端用户状态管理,添加token过期检查 优化Markdown内容渲染流程和图片URL处理 --- biji-houdaun/pom.xml | 7 - .../common/advice/GlobalExceptionHandler.java | 12 ++ .../controller/GroupingController.java | 11 +- .../controller/ImageController.java | 103 +++++++----- .../controller/MarkdownController.java | 2 +- .../controller/UserController.java | 2 +- .../mapper/MarkdownFileMapper.java | 2 +- .../service/MarkdownFileService.java | 2 +- .../test/bijihoudaun/service/UserService.java | 2 +- .../service/impl/GroupingServiceImpl.java | 12 +- .../service/impl/ImageServiceImpl.java | 1 + .../service/impl/MarkdownFileServiceImpl.java | 10 +- .../service/impl/UserServiceImpl.java | 3 +- .../src/main/resources/application.yml | 26 ++- biji-qianduan/package-lock.json | 28 ++-- biji-qianduan/package.json | 5 +- biji-qianduan/src/api/CommonApi.js | 21 +-- biji-qianduan/src/components/HomePage.vue | 152 +++++++++++++++--- .../src/components/home/NoteEditor.vue | 25 ++- .../src/components/home/NotePreview.vue | 5 + biji-qianduan/src/stores/user.js | 14 +- sql/mysql/all.sql | 2 +- .../8357c5d3-eaa4-4aed-8306-ae91da62340b.png | Bin 0 -> 62050 bytes 23 files changed, 304 insertions(+), 143 deletions(-) create mode 100644 uploads/8357c5d3-eaa4-4aed-8306-ae91da62340b.png diff --git a/biji-houdaun/pom.xml b/biji-houdaun/pom.xml index 6386854..a4ddcbc 100644 --- a/biji-houdaun/pom.xml +++ b/biji-houdaun/pom.xml @@ -126,13 +126,6 @@ org.springframework.boot spring-boot-starter-validation - - - org.bouncycastle - bcprov-jdk18on - 1.76 - - diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/common/advice/GlobalExceptionHandler.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/common/advice/GlobalExceptionHandler.java index 8c927c3..dafb899 100644 --- a/biji-houdaun/src/main/java/com/test/bijihoudaun/common/advice/GlobalExceptionHandler.java +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/common/advice/GlobalExceptionHandler.java @@ -84,4 +84,16 @@ public class GlobalExceptionHandler { log.error("Unexpected error at {} - Error type: {}", request.getRequestURI(), e.getClass().getSimpleName()); return R.fail(ResultCode.FAILED.getCode(), "系统繁忙,请稍后再试"); } + + // 修复:处理 IllegalStateException(getWriter() 已调用等问题) + @ExceptionHandler(IllegalStateException.class) + public R handleIllegalStateException(IllegalStateException e, HttpServletRequest request) { + log.warn("Illegal state at {}: {}", request.getRequestURI(), e.getMessage()); + // 如果是图片预览相关请求,可能是响应已经提交 + if (request.getRequestURI().contains("/api/images/preview")) { + // 响应可能已经提交,直接返回 null,避免再次写入响应 + return null; + } + return R.fail(ResultCode.FAILED.getCode(), "请求处理失败"); + } } diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/controller/GroupingController.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/controller/GroupingController.java index 47d54a9..8036ce3 100644 --- a/biji-houdaun/src/main/java/com/test/bijihoudaun/controller/GroupingController.java +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/controller/GroupingController.java @@ -52,11 +52,9 @@ public class GroupingController { @PreAuthorize("hasRole('ADMIN')") @PutMapping("/{id}") public R updateGrouping( - @PathVariable String id, + @PathVariable Long id, @RequestBody Grouping grouping) { - - long l = Long.parseLong(id); - grouping.setId(l); + grouping.setId(id); Grouping updated = groupingService.updateGrouping(grouping); return R.success(updated); } @@ -64,9 +62,8 @@ public class GroupingController { @Operation(summary = "删除分组") @PreAuthorize("hasRole('ADMIN')") @DeleteMapping("/{id}") - public R deleteGrouping(@PathVariable String id) { - Long idLong = Long.parseLong(id); - groupingService.deleteGrouping(idLong); + public R deleteGrouping(@PathVariable Long id) { + groupingService.deleteGrouping(id); return R.success(); } } diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/controller/ImageController.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/controller/ImageController.java index 81e8117..56015f0 100644 --- a/biji-houdaun/src/main/java/com/test/bijihoudaun/controller/ImageController.java +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/controller/ImageController.java @@ -81,43 +81,48 @@ public class ImageController { @Operation(summary = "在线预览", description = "浏览器直接打开文件流") @GetMapping("/preview/{url}") public void preview(@PathVariable String url, HttpServletResponse resp) throws IOException { - // 修复:使用 try-with-resources 确保 PrintWriter 关闭 - try (PrintWriter writer = resp.getWriter()) { - if (StrUtil.isBlank(url)) { - resp.setStatus(404); - writer.write("{\"code\":404,\"msg\":\"文件不存在\",\"data\":null}"); - return; - } - - String sanitizedUrl = sanitizeFileName(url); - if (sanitizedUrl == null) { - resp.setStatus(403); - writer.write("{\"code\":403,\"msg\":\"非法文件路径\",\"data\":null}"); - return; - } - - Path basePath = Paths.get(rootPath).normalize().toAbsolutePath(); - Path filePath = basePath.resolve(sanitizedUrl).normalize(); - - if (!filePath.startsWith(basePath)) { - resp.setStatus(403); - writer.write("{\"code\":403,\"msg\":\"非法文件路径\",\"data\":null}"); - return; - } - - File file = filePath.toFile(); - if (!file.exists() || !file.isFile()) { - resp.setStatus(404); - writer.write("{\"code\":404,\"msg\":\"文件不存在\",\"data\":null}"); - return; - } - - String contentTypeFromFileExtension = getContentTypeFromFileExtension(url); - resp.setContentType(contentTypeFromFileExtension); - resp.setContentLengthLong(file.length()); - try (FileInputStream in = new FileInputStream(file)) { - StreamUtils.copy(in, resp.getOutputStream()); - } + // 注意:不能同时调用 resp.getWriter() 和 resp.getOutputStream() + + if (StrUtil.isBlank(url)) { + resp.setStatus(404); + resp.setContentType("application/json;charset=UTF-8"); + resp.getWriter().write("{\"code\":404,\"msg\":\"文件不存在\",\"data\":null}"); + return; + } + + String sanitizedUrl = sanitizeFileName(url); + if (sanitizedUrl == null) { + resp.setStatus(403); + resp.setContentType("application/json;charset=UTF-8"); + resp.getWriter().write("{\"code\":403,\"msg\":\"非法文件路径\",\"data\":null}"); + return; + } + + Path basePath = Paths.get(rootPath).normalize().toAbsolutePath(); + Path filePath = basePath.resolve(sanitizedUrl).normalize(); + + if (!filePath.startsWith(basePath)) { + resp.setStatus(403); + resp.setContentType("application/json;charset=UTF-8"); + resp.getWriter().write("{\"code\":403,\"msg\":\"非法文件路径\",\"data\":null}"); + return; + } + + File file = filePath.toFile(); + if (!file.exists() || !file.isFile()) { + resp.setStatus(404); + resp.setContentType("application/json;charset=UTF-8"); + resp.getWriter().write("{\"code\":404,\"msg\":\"文件不存在\",\"data\":null}"); + return; + } + + String contentTypeFromFileExtension = getContentTypeFromFileExtension(url); + resp.setContentType(contentTypeFromFileExtension); + resp.setContentLengthLong(file.length()); + // 文件流直接输出,不使用 try-with-resources 包装整个方法 + try (FileInputStream in = new FileInputStream(file)) { + StreamUtils.copy(in, resp.getOutputStream()); + resp.getOutputStream().flush(); } } @@ -125,7 +130,9 @@ public class ImageController { if (StrUtil.isBlank(fileName)) { return null; } - if (fileName.contains("..") || fileName.contains("/") || fileName.contains("\\") || fileName.contains(":")) { + // 修复:使用白名单验证文件名格式(只允许 UUID 格式) + // 例如:550e8400-e29b-41d4-a716-446655440000.jpg + if (!fileName.matches("^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}\\.[a-zA-Z0-9]+$")) { return null; } return fileName; @@ -162,6 +169,7 @@ public class ImageController { } String extension = fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase(); + // 使用更安全的 MIME 类型映射,只允许图片类型 switch (extension) { case "jpg": case "jpeg": @@ -177,8 +185,27 @@ public class ImageController { case "svg": return "image/svg+xml"; default: + // 对于未知的扩展名,返回通用的二进制流类型,避免执行风险 return "application/octet-stream"; } } + + /** + * 验证文件是否为允许的图片类型 + * @param contentType 文件内容类型 + * @return 是否允许 + */ + private boolean isAllowedImageType(String contentType) { + if (StrUtil.isBlank(contentType)) { + return false; + } + // 只允许标准的图片 MIME 类型 + return contentType.equals("image/jpeg") || + contentType.equals("image/png") || + contentType.equals("image/gif") || + contentType.equals("image/bmp") || + contentType.equals("image/webp") || + contentType.equals("image/svg+xml"); + } } diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/controller/MarkdownController.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/controller/MarkdownController.java index 5f4c9da..ad96ed7 100644 --- a/biji-houdaun/src/main/java/com/test/bijihoudaun/controller/MarkdownController.java +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/controller/MarkdownController.java @@ -85,7 +85,7 @@ public class MarkdownController { @Operation(summary = "根据分组ID获取Markdown文件") @GetMapping("/grouping/{groupingId}") - public R> getFilesByGroupingId(@PathVariable String groupingId) { + public R> getFilesByGroupingId(@PathVariable Long groupingId) { List files = markdownFileService.getFilesByGroupingId(groupingId); return R.success(files); } diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/controller/UserController.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/controller/UserController.java index 61ba17e..2f8ee6f 100644 --- a/biji-houdaun/src/main/java/com/test/bijihoudaun/controller/UserController.java +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/controller/UserController.java @@ -112,7 +112,7 @@ public class UserController { return R.fail("无法获取用户信息,删除失败"); } - userService.deleteUser(user.getId().intValue()); + userService.deleteUser(user.getId()); return R.success("用户删除成功"); } diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/mapper/MarkdownFileMapper.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/mapper/MarkdownFileMapper.java index 7e7db93..7fa8f3f 100644 --- a/biji-houdaun/src/main/java/com/test/bijihoudaun/mapper/MarkdownFileMapper.java +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/mapper/MarkdownFileMapper.java @@ -34,7 +34,7 @@ public interface MarkdownFileMapper extends BaseMapper { "LEFT JOIN `grouping` g ON mf.grouping_id = g.id " + "WHERE mf.grouping_id = #{groupingId} AND mf.is_deleted = 0 " + "ORDER BY mf.updated_at DESC") - List selectByGroupingIdWithGrouping(@Param("groupingId") String groupingId); + List selectByGroupingIdWithGrouping(@Param("groupingId") Long groupingId); /** * 查询已删除的笔记(不包含content大字段) diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/service/MarkdownFileService.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/service/MarkdownFileService.java index bfb29f4..0c9b7b9 100644 --- a/biji-houdaun/src/main/java/com/test/bijihoudaun/service/MarkdownFileService.java +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/service/MarkdownFileService.java @@ -28,7 +28,7 @@ public interface MarkdownFileService extends IService { * @param groupingId 分组ID * @return 文件列表 */ - List getFilesByGroupingId(String groupingId); + List getFilesByGroupingId(Long groupingId); /** * 删除Markdown文件 diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/service/UserService.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/service/UserService.java index 7f10596..0f73a77 100644 --- a/biji-houdaun/src/main/java/com/test/bijihoudaun/service/UserService.java +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/service/UserService.java @@ -27,7 +27,7 @@ public interface UserService extends IService { * 用户删除 * @param id 用户id */ - void deleteUser(Integer id); + void deleteUser(Long id); /** * 查询用户token是否过期 diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/service/impl/GroupingServiceImpl.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/service/impl/GroupingServiceImpl.java index e2937d7..58b6424 100644 --- a/biji-houdaun/src/main/java/com/test/bijihoudaun/service/impl/GroupingServiceImpl.java +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/service/impl/GroupingServiceImpl.java @@ -40,11 +40,15 @@ public class GroupingServiceImpl @Override public List getAllGroupings(Long parentId) { - if (ObjectUtil.isNull(parentId)){ - return groupingMapper.selectList(null); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + // 只查询未删除的分组 + queryWrapper.eq(Grouping::getIsDeleted, 0); + if (ObjectUtil.isNotNull(parentId)){ + queryWrapper.eq(Grouping::getParentId, parentId); } - return groupingMapper.selectList(new LambdaQueryWrapper() - .eq(Grouping::getParentId, parentId)); + // 限制最大返回数量,防止内存溢出 + queryWrapper.last("LIMIT 1000"); + return groupingMapper.selectList(queryWrapper); } @Override diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/service/impl/ImageServiceImpl.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/service/impl/ImageServiceImpl.java index 4091921..48359d7 100644 --- a/biji-houdaun/src/main/java/com/test/bijihoudaun/service/impl/ImageServiceImpl.java +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/service/impl/ImageServiceImpl.java @@ -103,6 +103,7 @@ public class ImageServiceImpl Image image = new Image(); image.setOriginalName(originalFilename); image.setStoredName(storedName); + // 返回相对路径,前端会根据环境自动拼接 baseURL image.setUrl("/api/images/preview/" + storedName); image.setSize(file.getSize()); image.setContentType(contentType); diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/service/impl/MarkdownFileServiceImpl.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/service/impl/MarkdownFileServiceImpl.java index 0fb1595..b741046 100644 --- a/biji-houdaun/src/main/java/com/test/bijihoudaun/service/impl/MarkdownFileServiceImpl.java +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/service/impl/MarkdownFileServiceImpl.java @@ -2,6 +2,7 @@ package com.test.bijihoudaun.service.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -105,7 +106,7 @@ public class MarkdownFileServiceImpl @Override - public List getFilesByGroupingId(String groupingId) { + public List getFilesByGroupingId(Long groupingId) { return markdownFileMapper.selectByGroupingIdWithGrouping(groupingId); } @@ -130,13 +131,12 @@ public class MarkdownFileServiceImpl @Override public List searchByTitle(String keyword) { - // 修复:转义特殊字符防止 SQL 注入 + // 修复:使用 LambdaQueryWrapper 避免 SQL 注入风险 if (keyword == null || keyword.trim().isEmpty()) { return List.of(); } - String escapedKeyword = keyword.replace("%", "\\%").replace("_", "\\_"); - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.like("title", escapedKeyword); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.like(MarkdownFile::getTitle, keyword); return this.list(queryWrapper); } diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/service/impl/UserServiceImpl.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/service/impl/UserServiceImpl.java index 787f918..6e73581 100644 --- a/biji-houdaun/src/main/java/com/test/bijihoudaun/service/impl/UserServiceImpl.java +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/service/impl/UserServiceImpl.java @@ -13,7 +13,6 @@ import com.test.bijihoudaun.service.UserService; import com.test.bijihoudaun.util.JwtTokenUtil; import com.test.bijihoudaun.util.LoginLockUtil; import com.test.bijihoudaun.util.PasswordUtils; -import com.test.bijihoudaun.util.UuidV7; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.GrantedAuthority; @@ -126,7 +125,7 @@ public class UserServiceImpl extends ServiceImpl implements Us } @Override - public void deleteUser(Integer id) { + public void deleteUser(Long id) { userMapper.deleteById(id); } diff --git a/biji-houdaun/src/main/resources/application.yml b/biji-houdaun/src/main/resources/application.yml index a81600d..4c28365 100644 --- a/biji-houdaun/src/main/resources/application.yml +++ b/biji-houdaun/src/main/resources/application.yml @@ -1,6 +1,6 @@ +# 服务器配置 server: port: 8084 - forward-headers-strategy: framework spring: web: @@ -12,13 +12,16 @@ spring: active: dev servlet: multipart: - max-file-size: 10MB # ???????5MB - max-request-size: 10MB # ???????5MB + max-file-size: 10MB + max-request-size: 10MB + +# 文件上传路径 file: upload-dir: uploads - -#?? +# 内存保护阈值 (MB) +memory: + threshold: 100 ## Snowflake ID????? @@ -29,11 +32,20 @@ worker: datacenter: id: 1 - - # JWT 配置 jwt: secret: ${JWT_SECRET:V2VsbCwgSSBzdXBwb3NlIHRoYXQgaWYgeW91J3JlIHJlYWRpbmcgdGhpcywgeW91J3JlIHByZXR0eSBjdXJpb3VzLg==} expiration: 86400 header: Authorization tokenHead: "Bearer " + +# 管理员用户名配置 +admin: + username: ${ADMIN_USERNAME:admin} + +# 日志配置 +logging: + level: + com.test.bijihoudaun: INFO + pattern: + console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n" diff --git a/biji-qianduan/package-lock.json b/biji-qianduan/package-lock.json index 5668fb1..275db52 100644 --- a/biji-qianduan/package-lock.json +++ b/biji-qianduan/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@kangc/v-md-editor": "^2.2.4", "codemirror": "^6.0.1", + "dompurify": "^3.3.1", "element-plus": "^2.7.6", "highlight.js": "^11.11.1", "html2canvas": "^1.4.1", @@ -2585,10 +2586,13 @@ } }, "node_modules/dompurify": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.6.tgz", - "integrity": "sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==", - "license": "(MPL-2.0 OR Apache-2.0)" + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.1.tgz", + "integrity": "sha512-qkdCKzLNtrgPFP1Vo+98FRzJnBRGe4ffyCea9IwHB1fyxPOeNTHpLKYGd4Uk9xvNoH0ZoOjwZxNptyMwqrId1Q==", + "license": "(MPL-2.0 OR Apache-2.0)", + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } }, "node_modules/element-plus": { "version": "2.10.4", @@ -3414,16 +3418,6 @@ "html2canvas": "^1.0.0-rc.5" } }, - "node_modules/jspdf/node_modules/dompurify": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.6.tgz", - "integrity": "sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==", - "license": "(MPL-2.0 OR Apache-2.0)", - "optional": true, - "optionalDependencies": { - "@types/trusted-types": "^2.0.7" - } - }, "node_modules/katex": { "version": "0.13.24", "resolved": "https://registry.npmjs.org/katex/-/katex-0.13.24.tgz", @@ -3705,6 +3699,12 @@ "web-worker": "^1.2.0" } }, + "node_modules/mermaid/node_modules/dompurify": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.6.tgz", + "integrity": "sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==", + "license": "(MPL-2.0 OR Apache-2.0)" + }, "node_modules/mermaid/node_modules/katex": { "version": "0.16.22", "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.22.tgz", diff --git a/biji-qianduan/package.json b/biji-qianduan/package.json index 86dd32a..f76a31e 100644 --- a/biji-qianduan/package.json +++ b/biji-qianduan/package.json @@ -13,6 +13,7 @@ "dependencies": { "@kangc/v-md-editor": "^2.2.4", "codemirror": "^6.0.1", + "dompurify": "^3.3.1", "element-plus": "^2.7.6", "highlight.js": "^11.11.1", "html2canvas": "^1.4.1", @@ -24,7 +25,7 @@ }, "devDependencies": { "@vitejs/plugin-vue": "^5.0.5", - "vite": "^5.3.1", - "terser": "^5.31.3" + "terser": "^5.31.3", + "vite": "^5.3.1" } } diff --git a/biji-qianduan/src/api/CommonApi.js b/biji-qianduan/src/api/CommonApi.js index 43cd4f1..7c11dec 100644 --- a/biji-qianduan/src/api/CommonApi.js +++ b/biji-qianduan/src/api/CommonApi.js @@ -2,8 +2,8 @@ import axiosApi from '@/utils/axios.js' -// 修复:使用 encodeURIComponent 编码 URL 参数,防止注入 -export const groupingId = (data) => axiosApi.get(`/api/markdown/grouping/${encodeURIComponent(data)}`) +// 根据分组ID获取Markdown文件列表 +export const groupingId = (groupingId) => axiosApi.get(`/api/markdown/grouping/${encodeURIComponent(groupingId)}`) // 获取所有分组 export const groupingAll = (data) => { if (data) { @@ -71,16 +71,17 @@ export const register = (data) => { const formData = new FormData() formData.append('username', data.username) formData.append('password', data.password) + formData.append('email', data.email || '') // 修复:添加 email 参数 formData.append('registrationCode', data.registrationCode) return axiosApi.post('/api/user/register', formData, { headers: { 'Content-Type': 'multipart/form-data' } - }) } // 更新分组名称 +// 修复:使用与后端 Grouping 实体类匹配的字段名 export const updateGroupingName = (id, newName) => { return axiosApi.put(`/api/groupings/${id}`, { grouping: newName }); } @@ -106,20 +107,6 @@ export const getRecentFiles = (limit = 16) => axiosApi.get(`/api/markdown/recent -// MD5哈希 -export const MD5 = (data, file) => { - const formData = new FormData() - if (data) formData.append('input', data) - if (file) formData.append('file', file) - return axiosApi.post('/api/common/md5', formData, { - headers: { - 'Content-Type': 'multipart/form-data' - } - }) -} - - - diff --git a/biji-qianduan/src/components/HomePage.vue b/biji-qianduan/src/components/HomePage.vue index 8f5becd..4081b8c 100644 --- a/biji-qianduan/src/components/HomePage.vue +++ b/biji-qianduan/src/components/HomePage.vue @@ -130,11 +130,12 @@ diff --git a/biji-qianduan/src/components/home/NoteEditor.vue b/biji-qianduan/src/components/home/NoteEditor.vue index d506a2e..cb5fb80 100644 --- a/biji-qianduan/src/components/home/NoteEditor.vue +++ b/biji-qianduan/src/components/home/NoteEditor.vue @@ -32,9 +32,9 @@ const vditor = ref(null); const currentId = ref(null); const isInitialized = ref(false); const saveStatus = ref(''); -let saveTimeout = null; -let lastSavedContent = ref(''); -let isSaving = ref(false); +const saveTimeout = ref(null); // 修复:使用 ref 替代 let,确保响应式追踪 +const lastSavedContent = ref(''); +const isSaving = ref(false); // 维护当前最新的笔记数据 const currentData = ref({ ...props.editData }); @@ -63,9 +63,9 @@ const initVditor = () => { input: (value) => { if (!isInitialized.value) return; - clearTimeout(saveTimeout); + clearTimeout(saveTimeout.value); saveStatus.value = '正在输入...'; - saveTimeout = setTimeout(() => { + saveTimeout.value = setTimeout(() => { if (!isSaving.value && value !== lastSavedContent.value) { save(value); } @@ -78,9 +78,14 @@ const initVditor = () => { if (!file) return; uploadImage(file).then(res => { - const url = res.url; + // 后端返回相对路径,拼接成完整 URL + const relativeUrl = res.url; const baseUrl = import.meta.env.VITE_API_BASE_URL || ''; - vditor.value.insertValue(`![${file.name}](${baseUrl}${url})`); + // 确保 URL 格式正确,避免双斜杠 + const fullUrl = baseUrl.endsWith('/') && relativeUrl.startsWith('/') + ? baseUrl + relativeUrl.substring(1) + : baseUrl + relativeUrl; + vditor.value.insertValue(`![${file.name}](${fullUrl})`); }).catch((error) => { // 错误已在 axios 拦截器中显示,这里不再重复显示 console.error('图片上传失败:', error); @@ -185,7 +190,11 @@ onMounted(() => { }); onBeforeUnmount(() => { - clearTimeout(saveTimeout); + // 修复:确保清理定时器 + if (saveTimeout.value) { + clearTimeout(saveTimeout.value); + saveTimeout.value = null; + } if (vditor.value) { vditor.value.destroy(); vditor.value = null; diff --git a/biji-qianduan/src/components/home/NotePreview.vue b/biji-qianduan/src/components/home/NotePreview.vue index 37aad2b..488e74d 100644 --- a/biji-qianduan/src/components/home/NotePreview.vue +++ b/biji-qianduan/src/components/home/NotePreview.vue @@ -46,6 +46,11 @@ 内容加载中... + +
+ + 正在渲染... +
diff --git a/biji-qianduan/src/stores/user.js b/biji-qianduan/src/stores/user.js index a9250e0..13dd5a3 100644 --- a/biji-qianduan/src/stores/user.js +++ b/biji-qianduan/src/stores/user.js @@ -5,6 +5,7 @@ export const useUserStore = defineStore('user', { state: () => ({ token: '', userInfo: null, + tokenExpiry: null, // 添加 Token 过期时间 }), actions: { async login(username, password) { @@ -12,6 +13,9 @@ export const useUserStore = defineStore('user', { const response = await loginApi({ username, password }); if (response && response.token) { this.token = response.token; + // 解析 JWT 获取过期时间 + const payload = JSON.parse(atob(response.token.split('.')[1])); + this.tokenExpiry = payload.exp * 1000; // 转换为毫秒 if (response.userInfo) { this.userInfo = response.userInfo; } @@ -26,10 +30,16 @@ export const useUserStore = defineStore('user', { logout() { this.token = ''; this.userInfo = null; + this.tokenExpiry = null; + }, + // 检查 Token 是否过期 + isTokenExpired() { + if (!this.tokenExpiry) return true; + return Date.now() >= this.tokenExpiry; }, }, getters: { - isLoggedIn: (state) => !!state.token, + isLoggedIn: (state) => !!state.token && Date.now() < (state.tokenExpiry || 0), // 添加:判断是否为管理员 isAdmin: (state) => state.userInfo?.role === 'ADMIN', }, @@ -38,7 +48,7 @@ export const useUserStore = defineStore('user', { strategies: [ { key: 'user-store', - storage: sessionStorage, + storage: sessionStorage, // 使用 sessionStorage,比 localStorage 更安全 } ], }, diff --git a/sql/mysql/all.sql b/sql/mysql/all.sql index 7eacc2e..84ae701 100644 --- a/sql/mysql/all.sql +++ b/sql/mysql/all.sql @@ -6,7 +6,7 @@ SET FOREIGN_KEY_CHECKS = 0; -- 1. 分组表 DROP TABLE IF EXISTS `grouping`; CREATE TABLE `grouping` ( - `id` bigintBIGINT(20) NOT NULL AUTO_INCREMENT, + `id` bigint(20) NOT NULL AUTO_INCREMENT, `grouping` VARCHAR(255) NOT NULL, `parentId` BIGINT(20) DEFAULT NULL, `is_deleted` TINYINT(1) DEFAULT 0, diff --git a/uploads/8357c5d3-eaa4-4aed-8306-ae91da62340b.png b/uploads/8357c5d3-eaa4-4aed-8306-ae91da62340b.png new file mode 100644 index 0000000000000000000000000000000000000000..94d005b3c0505ab7ddb6102d3c886a6436cdf45e GIT binary patch literal 62050 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

m8Sd9H7c*xwjzEEiwVG}tnn{ow3MVNZrEs! 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