feat(biji): 优化笔记展示功能并调整端口

-将服务器端口从 8083 改为 8084
- 在数据库中添加 grouping_id 字段
- 实现笔记分组展示功能
-优化笔记编辑页面布局
-重构后端接口返回类型
- 移除 MarkdownFile 实体中的 userId 字段
This commit is contained in:
ikmkj
2025-06-17 21:54:53 +08:00
parent 4557bd49f9
commit b1b74f5efd
7 changed files with 90 additions and 31 deletions

View File

@@ -8,7 +8,6 @@ import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@@ -33,12 +32,12 @@ public class MarkdownController {
@Parameter(name = "id", description = "文件ID", required = true)
})
@GetMapping("/{id}")
public ResponseEntity<String> getMarkdownContent(@PathVariable Long id) {
public R<String> getMarkdownContent(@PathVariable Long id) {
MarkdownFile file = markdownFileService.getMarkdownById(id);
if (file != null) {
return ResponseEntity.ok(file.getContent());
return R.success(file.getContent());
}
return ResponseEntity.notFound().build();
return R.fail();
}
@Operation(summary = "创建markdown文件")
@@ -49,7 +48,7 @@ public class MarkdownController {
@Parameter(name = "content", description = "内容",required = true)
})
@PostMapping
public ResponseEntity<MarkdownFile> createMarkdown(
public R<MarkdownFile> createMarkdown(
@RequestParam Long groupingId,
@RequestParam String title,
@RequestParam String fileName,
@@ -58,7 +57,7 @@ public class MarkdownController {
MarkdownFile file = markdownFileService.createMarkdownFile(
groupingId, title, fileName, content);
return ResponseEntity.ok(file);
return R.success(file);
}
@Operation(summary = "更新Markdown文件")
@@ -67,39 +66,38 @@ public class MarkdownController {
@Parameter(name = "content", description = "Markdown文件内容", required = true)
})
@PostMapping("/{id}")
public ResponseEntity<MarkdownFile> updateMarkdown(
public R<MarkdownFile> updateMarkdown(
@PathVariable Long id,
@RequestBody String content) {
MarkdownFile file = markdownFileService.updateMarkdownContent(id, content);
if (file != null) {
return ResponseEntity.ok(file);
return R.success(file);
}
return ResponseEntity.notFound().build();
return R.fail();
}
@Operation(summary = "获取所有Markdown文件")
@GetMapping
public ResponseEntity<List<MarkdownFile>> getAllMarkdownFiles() {
// 固定用户ID=1因为是个人笔记
public R<List<MarkdownFile>> getAllMarkdownFiles() {
List<MarkdownFile> files = markdownFileService.getAllMarkdownFiles();
return ResponseEntity.ok(files);
return R.success(files);
}
@Operation(summary = "删除Markdown文件")
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteMarkdown(@PathVariable Long id) {
public R<Void> deleteMarkdown(@PathVariable Long id) {
if (markdownFileService.deleteMarkdownFile(id)) {
return ResponseEntity.noContent().build();
return R.success();
}
return ResponseEntity.notFound().build();
return R.fail();
}
@Operation(summary = "根据分组ID获取Markdown文件")
@GetMapping("/grouping/{groupingId}")
public ResponseEntity<List<MarkdownFile>> getFilesByGroupingId(@PathVariable String groupingId) {
public R<List<MarkdownFile>> getFilesByGroupingId(@PathVariable String groupingId) {
List<MarkdownFile> files = markdownFileService.getFilesByGroupingId(groupingId);
return ResponseEntity.ok(files);
return R.success(files);
}
}

View File

@@ -18,8 +18,6 @@ public class MarkdownFile {
private Long id;
@Schema(description = "分组表id",implementation = Long.class)
private Long groupingId;
@Schema(description = "用户ID",implementation = Long.class)
private Long userId;
@Schema(description = "文本标题",implementation = String.class)
private String title;

View File

@@ -11,7 +11,6 @@ import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

View File

@@ -13,7 +13,7 @@ file:
#??
server:
port: 8083
port: 8084
## Snowflake ID?????

View File

@@ -2,22 +2,25 @@
<div class="home-page">
<el-container style="height: 100vh;">
<!-- 左侧菜单栏 -->
<el-aside width="300px" style="background-color: #f5f7fa; border-right: 1px solid #ebeef5;">
<div class="sidebar-header">
<h3>笔记分类</h3>
<el-aside :width="isCollapsed ? '64px' : '300px'" style="background-color: #f5f7fa; border-right: 1px solid #ebeef5; transition: width 0.3s;">
<div class="sidebar-header" :style="{ justifyContent: isCollapsed ? 'center' : 'space-between' }">
<h3 v-if="!isCollapsed">笔记分类</h3>
<el-button @click="isCollapsed = !isCollapsed" size="small" type="text">
{{ isCollapsed ? '展开' : '收起' }}
<el-icon v-if="isCollapsed">
<Expand />
</el-icon>
<span v-else>收起</span>
</el-button>
</div>
<el-menu
v-if="!isCollapsed"
v-show="!isCollapsed"
default-active="all"
class="el-menu-vertical-demo"
@select="handleMenuSelect"
>
<el-menu-item index="all">
<span>全部笔记</span>
<span>全部文档</span>
</el-menu-item>
<el-submenu v-for="group in groupings" :key="group.id" :index="'group-'+group.id">
@@ -53,6 +56,18 @@
</div>
</div>
<!-- 文件列表 -->
<div v-if="!selectedFile" class="file-list">
<div v-for="group in groupings" :key="group.id" class="group-section">
<h3>{{ group.grouping }}</h3>
<ul>
<li v-for="file in groupFiles[group.id]" :key="file.id" @click="selectFile(file)">
{{ file.title }}
</li>
</ul>
</div>
</div>
<div v-if="selectedFile" class="file-preview">
<div class="preview-header">
<h2>{{ selectedFile.title }}</h2>
@@ -79,6 +94,7 @@
import { ref, onMounted } from 'vue';
import axios from 'axios';
import { ElMessage } from 'element-plus';
import { Expand } from '@element-plus/icons-vue';
import MarkdownEditor from './MarkdownEditor.vue';
import VMdPreview from '@kangc/v-md-editor/lib/preview';
import '@kangc/v-md-editor/lib/style/preview.css';
@@ -90,10 +106,11 @@ VMdPreview.use(githubTheme);
export default {
components: {
MarkdownEditor,
[VMdPreview.name]: VMdPreview
[VMdPreview.name]: VMdPreview,
Expand
},
setup() {
const API_BASE_URL = 'http://localhost:8083';
const API_BASE_URL = 'http://localhost:8084';
const markdownFiles = ref([]);
const groupings = ref([]);
const groupFiles = ref({});
@@ -128,6 +145,11 @@ export default {
}
};
// 选择文件预览
const selectFile = (file) => {
selectedFile.value = file;
};
// 编辑笔记
const editNote = (file) => {
currentFileId.value = file.id;
@@ -154,7 +176,7 @@ export default {
const fileId = index.split('-')[1];
const file = markdownFiles.value.find(f => f.id == fileId);
if (file) {
selectedFile.value = file;
selectFile(file);
}
}
};
@@ -203,6 +225,7 @@ export default {
currentFileId,
selectedFile,
isCollapsed,
selectFile,
editNote,
deleteNote,
handleMarkdownUpload,
@@ -242,6 +265,35 @@ export default {
margin-left: 10px;
}
.file-list {
margin-top: 20px;
}
.group-section {
margin-bottom: 20px;
}
.group-section h3 {
margin-bottom: 10px;
font-size: 18px;
color: #333;
}
.group-section ul {
list-style: none;
padding: 0;
}
.group-section li {
padding: 8px 0;
border-bottom: 1px solid #eee;
cursor: pointer;
}
.group-section li:hover {
background-color: #f5f7fa;
}
.file-preview {
padding: 20px;
border: 1px solid #ebeef5;
@@ -263,4 +315,15 @@ export default {
border-radius: 4px;
background: #fff;
}
/* 修复菜单折叠样式 */
.el-menu-vertical-demo {
height: calc(100vh - 60px);
overflow-y: auto;
}
.sidebar-header {
height: 60px;
display: flex;
align-items: center;
}
</style>

Binary file not shown.

View File

@@ -16,6 +16,7 @@ CREATE TABLE "user" (
CREATE TABLE IF NOT EXISTS markdown_file (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
grouping_id TEXT,
title TEXT NOT NULL,
file_name TEXT NOT NULL,
content TEXT NOT NULL,