个人学习路线与学习管理系统—— 项目设计与实现文档
一、项目简介
本项目“个人学习路线与学习管理系统”旨在帮助用户科学规划学习路径、记录学习笔记、管理知识成长过程。系统采用前后端分离架构设计,前端基于 Vue 3 + Element Plus 实现现代化界面,后端使用 Spring Boot 框架实现接口服务,数据库采用 MySQL 存储核心数据。系统实现了路线规划、笔记记录、富文本编辑、文件上传、用户登录注册等主要功能,适用于学生、程序员、自由学习者等多类用户群体。
二、核心需求分析
1. 用户与权限管理
- 支持用户注册、登录、注销;
- 记录用户基础信息(昵称、头像、注册时间等);
- 重要操作需鉴权,未登录用户不能访问私有资源。
2. 学习路线管理
- 路线广场展示所有学习路线(可分页、查询);
- 支持用户新建、编辑、删除个人学习路线;
- 每条路线包含标题、描述、创建时间等属性。
3. 笔记管理与富文本编辑
- 每条学习路线下可新建、编辑、删除多条笔记;
- 笔记内容支持 Markdown 富文本格式,图片、附件上传;
- 笔记卡片展示,支持封面、关键摘要自动预览。
4. 文件上传与附件管理
- 支持上传图片、PDF、PPT、Word等格式作为笔记附件;
- 附件可在笔记中预览与下载。
5. 系统易用性和可扩展性
- 响应式设计,适配主流 PC/移动端;
- 代码结构清晰,便于二次开发与维护。
三、技术架构与选型
1. 前端
-
技术栈:Vue 3、Element Plus、Vue Router、Vite、Axios
-
主要依赖:
- @kangc/v-md-editor 用于富文本 Markdown 编辑
- element-plus 提供丰富UI组件
-
特点:
- 组件化开发,易扩展
- 富文本与文件上传集成
2. 后端
-
技术栈:Spring Boot、MyBatis-Plus、Lombok
-
功能划分:
- Controller 层负责路由与接口
- Service 层负责业务逻辑
- Entity/Mapper 实体和数据访问
- 全局异常与统一返回封装
3. 数据库
- MySQL
- 设计有用户表、学习路线表、笔记表、文件/附件表
4. 其他
- 前后端通过 RESTful API 通信,接口标准统一
- 本地上传文件存储,支持外部静态资源访问
四、数据库设计说明
1. 用户表(user)
| 字段 | 类型 | 说明 |
|---|---|---|
| id | bigint | 用户唯一ID |
| username | varchar | 用户名 |
| password | varchar | 加密密码 |
| avatar | varchar | 头像链接 |
| reg_time | datetime | 注册时间 |
2. 学习路线表(study_route)
| 字段 | 类型 | 说明 |
|---|---|---|
| id | bigint | 路线ID |
| title | varchar | 路线标题 |
| description | varchar | 路线描述 |
| user_id | bigint | 创建人 |
| create_time | datetime | 创建时间 |
3. 笔记表(note)
| 字段 | 类型 | 说明 |
|---|---|---|
| id | bigint | 笔记ID |
| route_id | bigint | 所属路线ID |
| user_id | bigint | 创建者 |
| title | varchar | 标题 |
| content | text | Markdown内容 |
| cover_img | varchar | 封面图 |
| attachments | json | 附件列表 |
| create_time | datetime | 创建时间 |
4. 附件/文件表(可选,或用JSON嵌入note表)
| 字段 | 类型 | 说明 |
|---|---|---|
| id | bigint | 附件ID |
| note_id | bigint | 所属笔记 |
| file_name | varchar | 文件名 |
| file_url | varchar | 文件路径 |
| file_type | varchar | 文件类型 |
| upload_time | datetime | 上传时间 |
五、项目目录结构(建议结构)
后端(Spring Boot)
learning-backend/
├── src/
│ ├── main/
│ │ ├── java/com/yuchen/learning/
│ │ │ ├── controller/ # 控制器(接口层):前端HTTP请求的入口
│ │ │ ├── service/ # 服务层:业务逻辑聚合
│ │ │ ├── mapper/ # Mapper层:数据库CRUD操作
│ │ │ ├── entity/ # 实体类(Model):与数据库表一一对应
│ │ │ ├── common/ # 通用类:统一响应、异常等
│ │ │ ├── config/ # 配置类(如跨域CORS、文件上传等)
│ │ │ └── LearningApplication.java # 应用启动主类
│ │ └── resources/
│ │ ├── application.properties # 配置文件(端口、数据源等)
│ │ ├── mapper/ # 可选:自定义MyBatis XML
│ │ └── static/uploads/ # 静态资源文件夹
│ └── test/ # 测试类目录
└── pom.xml # Maven依赖清单
前端(Vue 3)
learning-frontend/
├── public/
│ └── favicon.ico # 网页图标
├── src/
│ ├── assets/ # 静态资源(图片、logo、banner等)
│ ├── components/ # Vue页面组件
│ │ ├── HeaderBar.vue # 顶部导航栏(通用)
│ │ ├── Login.vue # 登录页面
│ │ ├── Register.vue # 注册页面
│ │ ├── RouteList.vue # 路线广场(主页面,增删改查路线)
│ │ └── NoteList.vue # 笔记页面(展示/编辑/新建/删除笔记)
│ ├── router/
│ │ └── index.js # Vue Router 路由配置
│ ├── App.vue # 应用根组件
│ ├── main.js # 项目入口文件
│ └── api/ # 可选,封装axios请求
├── vite.config.js # Vite配置文件
├── package.json # 依赖声明
└── README.md # 项目说明文档
六、接口设计说明(举例)
| 功能 | URL | 方法 | 参数 | 用法说明 |
| 用户注册 | /api/user/register | POST | username, password, email | 注册新用户 |
| 用户登录 | /api/user/login | POST | username, password | 登录 |
| 路线列表 | /api/route/list | GET | 无 | 获取全部学习路线 |
| 新增路线 | /api/route/add | POST | title, description, userId | 添加路线 |
| 路线编辑 | /api/route/update | PUT | id, title, description, userId | 编辑路线 |
| 路线删除 | /api/route/delete/{id} | DELETE | id | 删除路线 |
| 路线详情 | /api/route/detail/{id} | GET | id | 路线详情 |
| 笔记列表 | /api/note/list | GET | routeId | 某路线下所有笔记 |
| 新增笔记 | /api/note/add | POST | routeId, userId, title, content, … | 新建笔记 |
| 编辑笔记 | /api/note/update | PUT | id, … | 修改笔记 |
| 删除笔记 | /api/note/delete/{id} | DELETE | id | 删除笔记 |
| 文件上传 | /api/file/upload | POST | file(form-data) | 上传图片/附件/封面 |
七、后端关键代码说明(Spring Boot + MyBatis-Plus)只展示部分代码
1. 统一返回封装
Result.java
public class Result<T> {
private Integer code;
private String msg;
private T data;
public static <T> Result<T> success(T data) {
Result<T> r = new Result<>();
r.code = 0; r.data = data; r.msg = "success";
return r;
}
public static <T> Result<T> fail(String msg) {
Result<T> r = new Result<>();
r.code = 1; r.msg = msg; r.data = null;
return r;
}
// getters/setters
}
- 用途:所有接口返回统一格式,便于前后端数据交互和异常处理。
2. 实体类举例
Note.java
(数据库note表)
@Data
@TableName("note")
public class Note {
@TableId(type = IdType.AUTO)
private Long id; // 笔记ID
private Long routeId; // 所属路线ID
private Long userId; // 笔记创建者ID
private String title; // 笔记标题
private String content; // 笔记内容(Markdown)
private String coverImg; // 封面图片URL
private String attachments; // 附件列表(JSON字符串)
private Timestamp createTime;// 创建时间
}
- 用途:映射数据库 note 表,MyBatis-Plus自动CRUD。
3. Controller 示例(部分)
@RestController
@RequestMapping("/api/note")
public class NoteController {
@Autowired private NoteService noteService;
@GetMapping("/list")
public Result<List<Note>> listNotes(@RequestParam Long routeId) {
List<Note> notes = noteService.listByRouteId(routeId);
return Result.success(notes);
}
@PostMapping("/add")
public Result<?> addNote(@RequestBody Note note) {
noteService.save(note);
return Result.success(null);
}
@PutMapping("/update")
public Result<?> updateNote(@RequestBody Note note) {
noteService.updateById(note);
return Result.success(null);
}
@DeleteMapping("/delete/{id}")
public Result<?> deleteNote(@PathVariable Long id) {
noteService.removeById(id);
return Result.success(null);
}
}
- 用途:提供笔记的增删改查接口,RESTful风格。
4. 文件上传 Controller
@PostMapping("/api/file/upload")
public Result<String> upload(@RequestParam("file") MultipartFile file) {
String fileName = ... // 生成存储路径
file.transferTo(new File(uploadPath + fileName));
return Result.success("/uploads/" + fileName);
}
- 用途:实现文件/图片/附件上传,返回可访问URL给前端。
5. 路线/用户的Controller、Service、Mapper实现与上述类似,不再重复。
八、前端详细讲解(Vue 3 + Element Plus)
1. main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import HeaderBar from './components/HeaderBar.vue'
const app = createApp(App)
app.component('HeaderBar', HeaderBar)
app.use(router)
app.use(ElementPlus)
app.mount('#app')
- 用途:入口文件,初始化全局依赖、注册HeaderBar组件。
2. App.vue
<template>
<HeaderBar />
<router-view />
<footer class="my-footer">
<span>作者:雨辰 | 本页面由灵感和代码共同驱动</span>
</footer>
</template>
- 用途:全局布局,HeaderBar顶部、页面内容中间、底部页脚。
3. router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Login from '../components/Login.vue'
import Register from '../components/Register.vue'
import RouteList from '../components/RouteList.vue'
import NoteList from '../components/NoteList.vue'
const routes = [
{ path: '/', redirect: '/login' },
{ path: '/login', component: Login },
{ path: '/register', component: Register },
{ path: '/route-list', component: RouteList, meta: { requiresAuth: true } },
{
path: '/route/:routeId/notes',
component: NoteList,
meta: { requiresAuth: true }
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
// 路由守卫:未登录不能访问管理页
router.beforeEach((to, from, next) => {
const isLogin = !!localStorage.getItem('loginUser')
if (to.meta.requiresAuth && !isLogin) {
next('/login')
} else {
next()
}
})
export default router
- 用途:页面跳转与访问权限控制。
4. 关键页面组件用法(以 RouteList.vue 为例)
<script setup>
import { ref, onMounted } from 'vue'
import axios from 'axios'
import { useRouter } from 'vue-router'
const router = useRouter()
const routes = ref([])
const newRoute = ref({ title: '', description: '' })
const userInfo = ref(JSON.parse(localStorage.getItem('loginUser') || '{}'))
onMounted(fetchRoutes)
async function fetchRoutes() {
const res = await axios.get('/api/route/list')
if (res.data.code === 0) {
routes.value = res.data.data
}
}
async function addRoute() {
if (!newRoute.value.title) return
await axios.post('/api/route/add', { ...newRoute.value, userId: userInfo.value.id })
newRoute.value.title = ''
newRoute.value.description = ''
fetchRoutes()
}
function viewNotes(routeId) {
router.push(`/route/${routeId}/notes`)
}
</script>
<template>
<div>
<el-form>
<el-input v-model="newRoute.title" placeholder="路线标题" />
<el-input v-model="newRoute.description" placeholder="路线描述" />
<el-button type="primary" @click="addRoute">新增路线</el-button>
</el-form>
<el-table :data="routes">
<el-table-column prop="id" label="ID" />
<el-table-column prop="title" label="标题" />
<el-table-column prop="description" label="描述" />
<el-table-column label="操作">
<template #default="scope">
<el-button @click="viewNotes(scope.row.id)">查看笔记</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
- 用途:展示所有学习路线,支持新增和跳转查看笔记。
5. NoteList.vue(笔记页面)
- 包含笔记列表展示、切换、编辑、删除、新建、富文本编辑(Markdown)、图片附件上传等核心功能。
九、界面截图
- 路线广场:展示所有路线,支持添加、编辑、删除、进入笔记
- 笔记管理:支持 Markdown 编辑、附件上传、卡片展示
- 登录注册:简洁明了
编辑
编辑
编辑
十、测试用例(举例)
1. 功能测试
| 模块 | 测试点 | 操作步骤 | 预期结果 |
|---|---|---|---|
| 注册登录 | 注册、登录 | 输入新用户/密码 | 登录成功 |
| 路线管理 | 新增、删除 | 新建、删除路线 | 列表增删正常 |
| 笔记编辑 | 编辑/上传附件 | 编辑保存、上传文件 | 笔记保存且可下载 |
| 权限控制 | 未登录访问 | 直接访问内部路由 | 跳转登录或禁止访问 |
2. 接口单测(可选)
- 使用 Apifox进行 API 测试
- 校验所有接口异常、权限处理、参数校验
十一、部署与运维手册
1. 访问地址
- 本地测试:http://localhost:5173
- 服务器:根据实际端口/域名访问
2. 使用方法
- 启动项目后,前端通过 axios 等工具调用接口
- 登录、注册 -> 获取用户信息后本地存储
- 路线/笔记增删改查都为常规 RESTful API
- 文件上传用于笔记附件、图片、封面图等
十二、结语
本项目以实际学习需求为导向,提供了一个完整的路线规划与知识记录管理平台,前后端代码结构清晰,功能完善,界面现代。适合个人学习管理、也可用于团队知识协作平台的开发基础。