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 fc73057..cde5258 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 @@ -61,10 +61,9 @@ public class MarkdownController { @Parameters({ @Parameter(name = "id", description = "Markdown文件ID", required = true), }) - @PostMapping("/delete") - public R deleteMarkdown(String id) { - long l = Long.parseLong(id); - if (markdownFileService.deleteMarkdownFile(l)) { + @DeleteMapping("/{id}") + public R deleteMarkdown(@PathVariable Long id) { + if (markdownFileService.deleteMarkdownFile(id)) { return R.success(); } return R.fail(); diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/entity/TrashItemVo.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/entity/TrashItemVo.java index 4e8368e..91c8ad7 100644 --- a/biji-houdaun/src/main/java/com/test/bijihoudaun/entity/TrashItemVo.java +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/entity/TrashItemVo.java @@ -13,7 +13,7 @@ public class TrashItemVo { private String id; @Schema(description = "项目名称(笔记标题或分组名称)") - private String name; + private String title; @Schema(description = "项目类型(note 或 group)") private String type; diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/mapper/GroupingMapper.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/mapper/GroupingMapper.java index 48ecb89..ee642fe 100644 --- a/biji-houdaun/src/main/java/com/test/bijihoudaun/mapper/GroupingMapper.java +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/mapper/GroupingMapper.java @@ -3,7 +3,13 @@ package com.test.bijihoudaun.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.test.bijihoudaun.entity.Grouping; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; + +import java.util.List; @Mapper public interface GroupingMapper extends BaseMapper { + + @Select("SELECT * FROM grouping WHERE is_deleted = 1") + List selectDeleted(); } 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 d7f8483..32efec9 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 @@ -15,6 +15,7 @@ public interface MarkdownFileMapper extends BaseMapper { @Select("SELECT mf.*, g.grouping as groupingName " + "FROM markdown_file mf " + "LEFT JOIN grouping g ON mf.grouping_id = g.id " + + "WHERE mf.is_deleted = 0 " + "ORDER BY mf.updated_at DESC " + "LIMIT #{limit}") List selectRecentWithGrouping(@Param("limit") int limit); @@ -22,7 +23,10 @@ public interface MarkdownFileMapper extends BaseMapper { @Select("SELECT mf.*, g.grouping as groupingName " + "FROM markdown_file mf " + "LEFT JOIN grouping g ON mf.grouping_id = g.id " + - "WHERE mf.grouping_id = #{groupingId} " + + "WHERE mf.grouping_id = #{groupingId} AND mf.is_deleted = 0 " + "ORDER BY mf.updated_at DESC") List selectByGroupingIdWithGrouping(@Param("groupingId") String groupingId); + + @Select("SELECT * FROM markdown_file WHERE is_deleted = 1") + List selectDeleted(); } 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 e52f470..c42357f 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 @@ -54,12 +54,19 @@ public class GroupingServiceImpl @Override @Transactional public void deleteGrouping(Long id) { - LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); - updateWrapper.eq(MarkdownFile::getGroupingId, id) - .set(MarkdownFile::getGroupingId, 999L); - markdownFileMapper.update(null, updateWrapper); + // 1. 使用 LambdaUpdateWrapper 软删除分组本身,确保 isDeleted 和 deletedAt 都被更新 + LambdaUpdateWrapper groupingUpdateWrapper = new LambdaUpdateWrapper<>(); + groupingUpdateWrapper.eq(Grouping::getId, id) + .set(Grouping::getIsDeleted, 1) + .set(Grouping::getDeletedAt, new java.util.Date()); + this.update(groupingUpdateWrapper); - this.removeById(id); + // 2. 将该分组下的所有笔记也一并软删除 + LambdaUpdateWrapper markdownFileUpdateWrapper = new LambdaUpdateWrapper<>(); + markdownFileUpdateWrapper.eq(MarkdownFile::getGroupingId, id) + .set(MarkdownFile::getIsDeleted, 1) + .set(MarkdownFile::getDeletedAt, new java.util.Date()); + markdownFileMapper.update(null, markdownFileUpdateWrapper); } @Override 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 54d2b4c..8e2e1ec 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 @@ -1,6 +1,7 @@ package com.test.bijihoudaun.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.test.bijihoudaun.entity.MarkdownFile; import com.test.bijihoudaun.entity.MarkdownFileVO; @@ -52,7 +53,11 @@ public class MarkdownFileServiceImpl @Override public boolean deleteMarkdownFile(Long id) { - return this.removeById(id); + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.eq(MarkdownFile::getId, id) + .set(MarkdownFile::getIsDeleted, 1) + .set(MarkdownFile::getDeletedAt, new Date()); + return this.update(updateWrapper); } @Override diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/service/impl/TrashServiceImpl.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/service/impl/TrashServiceImpl.java index 1432fc1..06ef803 100644 --- a/biji-houdaun/src/main/java/com/test/bijihoudaun/service/impl/TrashServiceImpl.java +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/service/impl/TrashServiceImpl.java @@ -26,13 +26,13 @@ public class TrashServiceImpl implements TrashService { @Override public List getTrashItems() { - // 查询已删除的笔记 - List deletedNotes = markdownFileMapper.selectList(new QueryWrapper().eq("is_deleted", 1)) + // 调用自定义的Mapper方法查询已删除的笔记,绕过全局逻辑删除过滤器 + List deletedNotes = markdownFileMapper.selectDeleted() .stream() .map(file -> { TrashItemVo vo = new TrashItemVo(); vo.setId(String.valueOf(file.getId())); - vo.setName(file.getTitle()); + vo.setTitle(file.getTitle()); vo.setType("note"); vo.setDeletedAt(file.getDeletedAt()); vo.setDeletedBy(String.valueOf(file.getDeletedBy())); @@ -40,13 +40,13 @@ public class TrashServiceImpl implements TrashService { }) .collect(Collectors.toList()); - // 查询已删除的分组 - List deletedGroups = groupingMapper.selectList(new QueryWrapper().eq("is_deleted", 1)) + // 调用自定义的Mapper方法查询已删除的分组 + List deletedGroups = groupingMapper.selectDeleted() .stream() .map(group -> { TrashItemVo vo = new TrashItemVo(); vo.setId(String.valueOf(group.getId())); - vo.setName(group.getGrouping()); + vo.setTitle(group.getGrouping()); vo.setType("group"); vo.setDeletedAt(group.getDeletedAt()); vo.setDeletedBy(String.valueOf(group.getDeletedBy())); diff --git a/biji-qianduan/src/api/CommonApi.js b/biji-qianduan/src/api/CommonApi.js index f4eaf91..3340eb7 100644 --- a/biji-qianduan/src/api/CommonApi.js +++ b/biji-qianduan/src/api/CommonApi.js @@ -40,7 +40,7 @@ export const uploadImage = (file) => { } // 删除Markdown文件 -export const deleteMarkdown = (id) => axiosApi.post(`/api/markdown/delete?id=${id}`); +export const deleteMarkdown = (id) => axiosApi.delete(`/api/markdown/${id}`); // 根据分组ID获取Markdown文件列表 export const markdownList = (groupingId) => axiosApi.get(`/api/markdown/grouping/${groupingId}`); diff --git a/biji-qianduan/src/components/HomePage.vue b/biji-qianduan/src/components/HomePage.vue index 29985ed..8d973a6 100644 --- a/biji-qianduan/src/components/HomePage.vue +++ b/biji-qianduan/src/components/HomePage.vue @@ -548,29 +548,41 @@ const debouncedSave = (value) => { const handleSave = async (content) => { saveStatus.value = '正在保存...'; try { - const newImageUrls = extractImageUrls(content); - const deletedImages = originalImages.value.filter(url => !newImageUrls.includes(url)); + // 构造一个干净的、只包含必要字段的 payload + const payload = { + id: editData.value.id, // 可能是 null,用于创建 + title: editData.value.title, + groupingId: editData.value.groupingId, + content: content, + fileName: editData.value.fileName || `${editData.value.title}.md`, + }; - if (deletedImages.length > 0) { - await deleteImages({ imageUrls: deletedImages }); + // 调用后端接口 + const response = await updateMarkdown(payload); + + // 使用后端返回的完整、最新的数据更新前端状态 + // 这对于新创建的笔记至关重要,因为它会获得一个新的 ID + editData.value = response.data; + + // 如果当前正在预览这个文件,也更新 selectedFile + if (selectedFile.value && (!selectedFile.value.id || selectedFile.value.id === response.data.id)) { + selectedFile.value = response.data; } - originalImages.value = newImageUrls; - - const payload = { - ...editData.value, - content: content, - }; - const response = await updateMarkdown(payload); - editData.value = response.data; - selectedFile.value = editData.value; saveStatus.value = '已保存'; ElMessage.success('保存成功'); - await fetchGroupings(); + + // 刷新文件列表以反映更改(例如,新文件出现) await fetchMarkdownFiles(); + // 如果当前在某个分类下,也刷新该分类的列表 + if (activeMenu.value.startsWith('group-')) { + const groupId = activeMenu.value.split('-'); + await selectFile({ id: groupId, grouping: currentGroupName.value }); + } + } catch (error) { saveStatus.value = '保存失败'; - ElMessage.error('保存失败: ' + error.message); + ElMessage.error('保存失败: ' + (error.response?.data?.message || error.message)); } }; diff --git a/mydatabase.db b/mydatabase.db index 99eb939..69dd3fd 100644 Binary files a/mydatabase.db and b/mydatabase.db differ