diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/entity/MarkdownFile.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/entity/MarkdownFile.java index f9d6026..6c016b8 100644 --- a/biji-houdaun/src/main/java/com/test/bijihoudaun/entity/MarkdownFile.java +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/entity/MarkdownFile.java @@ -23,6 +23,7 @@ public class MarkdownFile implements Serializable { private Long id; @Schema(description = "分组表id",implementation = Long.class) + @JsonFormat(shape = JsonFormat.Shape.STRING) @TableField("grouping_id") private Long groupingId; diff --git a/biji-houdaun/src/main/java/com/test/bijihoudaun/entity/MarkdownFileVO.java b/biji-houdaun/src/main/java/com/test/bijihoudaun/entity/MarkdownFileVO.java index b1e1b84..2520985 100644 --- a/biji-houdaun/src/main/java/com/test/bijihoudaun/entity/MarkdownFileVO.java +++ b/biji-houdaun/src/main/java/com/test/bijihoudaun/entity/MarkdownFileVO.java @@ -9,4 +9,7 @@ import lombok.EqualsAndHashCode; public class MarkdownFileVO extends MarkdownFile { @TableField(exist = false) private String groupingName; + + @TableField(exist = false) + private Long groupingId; } \ No newline at end of file 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 df5319a..37209eb 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,7 +15,7 @@ import org.apache.ibatis.annotations.Update; @Mapper public interface MarkdownFileMapper extends BaseMapper { - @Select("SELECT mf.id, mf.grouping_id, mf.`title`, mf.file_name, mf.`content`, mf.created_at, mf.updated_at, mf.is_deleted, mf.deleted_at, mf.deleted_by, mf.is_private, g.`grouping` as groupingName " + + @Select("SELECT mf.id, mf.grouping_id as groupingId, mf.`title`, mf.file_name, mf.`content`, mf.created_at, mf.updated_at, mf.is_deleted, mf.deleted_at, mf.deleted_by, mf.is_private, g.`grouping` as groupingName " + "FROM `markdown_file` mf " + "LEFT JOIN `grouping` g ON mf.grouping_id = g.id " + "WHERE mf.is_deleted = 0 " + @@ -23,7 +23,7 @@ public interface MarkdownFileMapper extends BaseMapper { "LIMIT #{limit}") List selectRecentWithGrouping(@Param("limit") int limit); - @Select("SELECT mf.id, mf.grouping_id, mf.`title`, mf.file_name, mf.`content`, mf.created_at, mf.updated_at, mf.is_deleted, mf.deleted_at, mf.deleted_by, mf.is_private, g.`grouping` as groupingName " + + @Select("SELECT mf.id, mf.grouping_id as groupingId, mf.`title`, mf.file_name, mf.`content`, mf.created_at, mf.updated_at, mf.is_deleted, mf.deleted_at, mf.deleted_by, mf.is_private, g.`grouping` as groupingName " + "FROM `markdown_file` mf " + "LEFT JOIN `grouping` g ON mf.grouping_id = g.id " + "WHERE mf.grouping_id = #{groupingId} AND mf.is_deleted = 0 " + @@ -51,7 +51,7 @@ public interface MarkdownFileMapper extends BaseMapper { @Select("SELECT id, grouping_id, `title`, file_name, `content`, created_at, updated_at, is_deleted, deleted_at, deleted_by, is_private FROM `markdown_file` WHERE is_deleted = 0") List findAllIds(); - @Select("SELECT mf.id, mf.grouping_id, mf.`title`, mf.file_name, mf.`content`, mf.created_at, mf.updated_at, mf.is_deleted, mf.deleted_at, mf.deleted_by, mf.is_private, g.`grouping` as groupingName " + + @Select("SELECT mf.id, mf.grouping_id as groupingId, mf.`title`, mf.file_name, mf.`content`, mf.created_at, mf.updated_at, mf.is_deleted, mf.deleted_at, mf.deleted_by, mf.is_private, g.`grouping` as groupingName " + "FROM `markdown_file` mf " + "LEFT JOIN `grouping` g ON mf.grouping_id = g.id " + "WHERE mf.id = #{id} AND mf.is_deleted = 0") 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 9bf2c11..66fb8df 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 @@ -47,7 +47,32 @@ public class MarkdownFileServiceImpl this.save(markdownFile); id=l; } else { - this.updateById(markdownFile); + MarkdownFile existingFile = this.getById(markdownFile.getId()); + if (existingFile != null) { + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.eq(MarkdownFile::getId, markdownFile.getId()) + .set(MarkdownFile::getUpdatedAt, new Date()); + + if (markdownFile.getTitle() != null) { + updateWrapper.set(MarkdownFile::getTitle, markdownFile.getTitle()); + } + if (markdownFile.getContent() != null) { + updateWrapper.set(MarkdownFile::getContent, markdownFile.getContent()); + } + if (markdownFile.getGroupingId() != null) { + updateWrapper.set(MarkdownFile::getGroupingId, markdownFile.getGroupingId()); + } + if (markdownFile.getFileName() != null) { + updateWrapper.set(MarkdownFile::getFileName, markdownFile.getFileName()); + } + if (markdownFile.getIsPrivate() != null) { + updateWrapper.set(MarkdownFile::getIsPrivate, markdownFile.getIsPrivate()); + } + + this.update(updateWrapper); + } else { + this.updateById(markdownFile); + } id=markdownFile.getId(); } @@ -56,6 +81,10 @@ public class MarkdownFileServiceImpl MarkdownFileVO result = markdownFileMapper.selectByIdWithGrouping(id); if (result != null) { + // 确保 groupingId 被正确设置 + if (result.getGroupingId() == null && markdownFile.getGroupingId() != null) { + result.setGroupingId(markdownFile.getGroupingId()); + } return result; } return markdownFile; diff --git a/biji-qianduan/src/components/home/NoteEditor.vue b/biji-qianduan/src/components/home/NoteEditor.vue index 7a4fefe..7460b37 100644 --- a/biji-qianduan/src/components/home/NoteEditor.vue +++ b/biji-qianduan/src/components/home/NoteEditor.vue @@ -35,6 +35,8 @@ const saveStatus = ref(''); let saveTimeout = null; let lastSavedContent = ref(''); let isSaving = ref(false); +// 维护当前最新的笔记数据 +const currentData = ref({ ...props.editData }); const initVditor = () => { if (vditor.value) { @@ -49,12 +51,12 @@ const initVditor = () => { }, after: () => { isInitialized.value = true; - if (props.editData && props.editData.content) { - vditor.value.setValue(props.editData.content); - lastSavedContent.value = props.editData.content; + if (currentData.value && currentData.value.content) { + vditor.value.setValue(currentData.value.content); + lastSavedContent.value = currentData.value.content; } - if (props.editData && props.editData.id) { - currentId.value = props.editData.id; + if (currentData.value && currentData.value.id) { + currentId.value = currentData.value.id; } vditor.value.focus(); }, @@ -101,31 +103,42 @@ const save = async (value) => { try { saveStatus.value = '正在保存...'; + // 确保groupingId不会丢失:优先使用currentData中的值 + const groupingId = currentData.value.groupingId || props.editData.groupingId; + + // 将ID转为字符串以避免JavaScript精度丢失 + const idString = currentId.value ? String(currentId.value) : (currentData.value.id ? String(currentData.value.id) : null); + const groupingIdString = groupingId ? String(groupingId) : null; + const payload = { - id: currentId.value || props.editData.id || null, + id: idString, content: content, - title: props.editData.title, - groupingId: props.editData.groupingId, - fileName: props.editData.fileName, - isPrivate: props.editData.isPrivate + title: currentData.value.title || props.editData.title, + groupingId: groupingIdString, + fileName: currentData.value.fileName || props.editData.fileName, + isPrivate: currentData.value.isPrivate !== undefined ? currentData.value.isPrivate : props.editData.isPrivate }; + + const response = await updateMarkdown(payload); if (response && response.id) { currentId.value = response.id; lastSavedContent.value = content; + // 使用后端返回的数据,但确保groupingId不会丢失 + // 注意:后端返回的ID是字符串,保持字符串格式避免精度丢失 const updatedFile = { - ...props.editData, - id: response.id, + ...response, content: content, - groupingId: response.groupingId, - groupingName: response.groupingName, - title: response.title, - isPrivate: response.isPrivate + // 如果后端返回的groupingId为空,使用原来的值(保持字符串格式) + groupingId: response.groupingId || groupingIdString, + groupingName: response.groupingName || currentData.value.groupingName }; + // 更新currentData为最新数据 + currentData.value = updatedFile; emit('update:editData', updatedFile); saveStatus.value = '已保存'; } @@ -143,12 +156,17 @@ const handleBack = async () => { await save(content); } + // 确保groupingId不会丢失(保持字符串格式) + const groupingId = currentData.value.groupingId || props.editData.groupingId; + const groupingName = currentData.value.groupingName || props.editData.groupingName; + const returnData = { + ...currentData.value, ...props.editData, - id: currentId.value || props.editData.id, + id: currentId.value ? String(currentId.value) : (currentData.value.id ? String(currentData.value.id) : null), content: content, - groupingId: props.editData.groupingId, - groupingName: props.editData.groupingName + groupingId: groupingId ? String(groupingId) : null, + groupingName: groupingName }; emit('back', returnData); @@ -170,6 +188,8 @@ onBeforeUnmount(() => { watch(() => props.editData, (newVal, oldVal) => { if (vditor.value && isInitialized.value && newVal && newVal.id !== oldVal?.id) { + // 更新currentData为最新的props数据 + currentData.value = { ...newVal }; vditor.value.setValue(newVal.content || ''); lastSavedContent.value = newVal.content || ''; currentId.value = newVal.id; diff --git a/biji-qianduan/src/components/home/dialogs/CreateGroupDialog.vue b/biji-qianduan/src/components/home/dialogs/CreateGroupDialog.vue index 72723c5..b3bd7ed 100644 --- a/biji-qianduan/src/components/home/dialogs/CreateGroupDialog.vue +++ b/biji-qianduan/src/components/home/dialogs/CreateGroupDialog.vue @@ -2,23 +2,44 @@ - + + > + + - +