最近半年陆陆续续帮不少学弟学妹看过SpringBoot+Vue3的毕设项目,发现文档管理这一类的题目出现频率特别高。原因也好理解:业务边界清晰、功能点好展示、技术栈主流,做出来既有完整的前后端交互,又有文件读写这种实打实的业务逻辑,答辩证的时候特别有话讲。
这次分享的是一个基于Java SpringBoot + Vue3 + MyBatis + MySQL的江理工文档管理系统源码,前后端分离架构。简单来说,它解决的是高校里课程资料、实验报告、社团文件“散落在各个QQ群、U盘、网盘里找不到”的痛点,做成一个统一的在线文档管理平台。系统包含用户登录认证、文件上传下载、分类管理、在线预览、后台管理等完整模块,适合拿来当毕业设计、课程设计,也适合想完整跑通一个前后端分离项目的同学练手。
我把整个项目的开发过程、数据库设计、核心代码实现、以及部署踩坑记录全部梳理一遍,尽量把设计时为什么这么做的理由也讲明白,而不是光贴一堆代码。
1. 项目定位与技术选型思路
1.1 文档管理系统的核心业务拆解
做任何项目之前,先把业务边界摸清楚。文档管理系统听起来很宽泛,但落到高校场景里,核心就是四个字:存、找、管、下。
“存”是文件上传,要解决文件存哪里、怎么命名、怎么避免重名;“找”是文件检索,最基本的按文件名模糊搜索、按分类筛选;“管”是文件维护,分类结构怎么组织、谁能删除和修改;“下”是文件下载,同时记录下载次数这类统计信息。如果把范围再扩大一点,还可以加用户管理、操作日志、回收站等模块,但核心骨架就是上面四条。
我给这个系统定的功能清单是这样的:
- 用户模块:注册、登录、JWT令牌鉴权,区分普通用户和管理员
- 文件模块:上传、下载、删除、重命名、文件列表分页查询
- 分类模块:多级分类维护,文件挂载到分类下
- 预览模块:图片和PDF浏览器内直接预览,Office文件方案见后面说明
- 管理模块:管理员可管理用户状态、查看全站文件、统计下载量
这个功能规模对毕设来说不多不少。少了显得单薄,答辩时没什么可演示的;太多了开发周期失控,光是调试Bug就能让人崩溃。我见过有些同学一上来就想做在线编辑文档、多人协同,这种需求对一个React+WebSocket+CRDT团队来说都够呛,何况一个人搞前后端。先做好核心,把骨架搭稳,比什么都重要。
1.2 为什么选SpringBoot+Vue3+MyBatis这套组合
这套技术栈放在2024年依然是国内Java后端、以及高校项目里最主流的选择,几乎没有之一。
后端选SpringBoot,理由不必多说:自动配置让项目从零到能跑只需要几分钟,内嵌Tomcat省去部署Web容器的麻烦,生态里随便一搜就是海量解决方案。最关键的是,SpringBoot对各种场景的starter封装得非常完善,比如文件上传、参数校验、拦截器,这些在文档系统里全都要用上。
前端选Vue3是顺势而为。Vue2还在用Options API那一套,Vue3的Composition API在处理复杂业务逻辑时明显更顺手,再加上<script setup>语法糖,写起来简洁直接。UI组件库选Element Plus,表格、表单、上传、分页这些组件基本都是现成的,不用从零手搓样式,开发效率直线上升。
持久层选MyBatis而不是JPA,理由很实际:文档管理系统的查询条件组合比较灵活——按文件名模糊查、按分类查、按上传者查、按时间范围查,这些动态查询用MyBatis的动态SQL来写非常顺手。而且MyBatis的SQL是手写的,可控性强,出现问题排查起来直观。配合分页插件PageHelper,分页查询只需要一行代码。
数据库选MySQL没什么悬念,开源免费、资料多、高校机房和毕业设计场景的标配。8.0版本在性能和功能上比5.7完善不少,我这次用的是8.0。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 数据库设计与后端核心实现
2.1 数据库表结构设计,一张图讲清楚
表设计是整个系统的地基,地基打不好,后面写代码处处别扭。我设计了四张核心表:用户表、分类表、文件信息表、操作日志表。
用户表存账号密码和角色:
sql复制CREATE TABLE `sys_user` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID',
`username` varchar(50) NOT NULL COMMENT '登录账号',
`password` varchar(100) NOT NULL COMMENT '密码(BCrypt加密)',
`nickname` varchar(50) DEFAULT NULL COMMENT '显示昵称',
`avatar` varchar(255) DEFAULT NULL COMMENT '头像地址',
`role` tinyint NOT NULL DEFAULT '1' COMMENT '角色:0管理员 1普通用户',
`status` tinyint NOT NULL DEFAULT '1' COMMENT '状态:1正常 0禁用',
`create_time` datetime NOT NULL COMMENT '创建时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
密码字段我用BCrypt加密存储,Spring Security里的BCryptPasswordEncoder就能生成和校验。有些同学直接把明文密码放数据库里,答辩时老师一问数据安全就卡壳,不太好。
分类表设计成支持多级分类的结构:
sql复制CREATE TABLE `doc_category` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL COMMENT '分类名称',
`parent_id` bigint NOT NULL DEFAULT '0' COMMENT '父分类ID,0表示顶级',
`sort_order` int DEFAULT '0' COMMENT '排序权重',
`create_time` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='文档分类表';
文件信息表是核心表,字段设计上有个关键决策:数据库里存的是文件元信息,而不是文件本身。文件实体放在服务器磁盘上,数据库里只记录路径、大小、类型这些描述性字段。这里有个容易踩坑的点:很多初学者喜欢把文件转成二进制BLOB存数据库,短小文件无所谓,一旦有几十MB的视频文件,数据库瞬间膨胀,查询性能直线下降。
sql复制CREATE TABLE `doc_file` (
`id` bigint NOT NULL AUTO_INCREMENT,
`file_name` varchar(255) NOT NULL COMMENT '原始文件名',
`file_path` varchar(500) NOT NULL COMMENT '存储路径',
`file_size` bigint NOT NULL COMMENT '文件大小(字节)',
`file_type` varchar(50) DEFAULT NULL COMMENT '文件类型(扩展名)',
`category_id` bigi
