免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

SpringBoot+Vue档案管理系统源码拆解:从毕设到可复用脚手架

SpringBoot+Vue档案管理系统源码拆解:从毕设到可复用脚手架 简介一套基于 Spring Boot 的档案管理系统前后端源码面向计算机、电子信息工程等专业学生及毕业设计、课程设计开发者可覆盖档案信息入库、查询、更新等常见业务场景。系统采用 B/S 架构与 MVC 分层后端使用 Java、Spring Boot、MyBatis 提供接口服务前端基于 Vue 和 Ajax 构建交互页面数据库为 MySQL 5.7配合 JDK 1.8、Maven 3.6、IDEA 或 Eclipse 即可部署运行。压缩包共 440 个文件约 8.56MB其中包含 131 个 Java 源文件、50 个 Vue 组件、21 个 JS 脚本、17 个 XML 配置以及 161 个 SVG 图标、CSS/SCSS 样式、YML 配置并附有数据库备份与安装、启动、打包等构建运行脚本方便快速导入、运行和打包。已有 145 人学习下载。源码经过严格测试目录结构清晰适合作为毕业设计、课程设计或期末大作业也可在现有功能基础上进行二次开发与扩展。1. 档案管理系统到底拆什么一个毕业设计如何变成可复用的 SpringBoot 脚手架手头这套基于 SpringBoot 的档案管理系统表面看是一个典型的课设/毕设作品前端 Vue、后端 SpringBoot、数据库 MySQL 5.7压缩包里还躺着IndexMain.vue.bak、update-password.vue.bak这类备份文件。但真把它拆开你会发现它的价值不在于“档案管理”这个业务本身而在于一套完整的 B/S 开发链路——从 Maven 多模块依赖到 Mybatis 数据映射从 Vue 组件生命周期到前后端联调。哪怕你以后要做物资管理、学生选课这套骨架都是可以直接改表名继续用的。适合两类人一是准备做 SpringBoot 毕设但不知道代码怎么组织的人二是想快速把旧管理系统的前端页面迁移到 Vue Boot 组合的开发者。下面我按实际解压后最容易踩坑的顺序把这套代码一层层剥开。2. SpringBoot 后端骨架pom.xml、application.yml 与 Mybatis 数据源装配拿到压缩包后别急着双击2-run.bat先看后端目录结构。这个项目的后端是标准的 SpringBoot Mybatis 写法没有用 Mybatis-Plus 那种封装而是保留了最原始的UserMapper.xml手写 SQL 方式这对理解执行链路反而更友好。2.1 核心依赖为什么只用 SpringBoot 而不加一堆 starter打开pom.xml你看到的依赖会比我预期的少很多parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version2.3.4.RELEASE/version relativePath/ /parent dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.mybatis.spring.boot/groupId artifactIdmybatis-spring-boot-starter/artifactId version2.1.4/version /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId scoperuntime/scope /dependency dependency groupIdcom.alibaba/groupId artifactIddruid-spring-boot-starter/artifactId version1.2.6/version /dependency /dependencies这里有个容易忽略的点没有引入spring-boot-starter-data-jpa或spring-boot-starter-jdbc说明作者打算完全交给 Mybatis 管理数据库连接。我在实际改这种项目时会特意保留 Druid 连接池因为毕设环境里很多人数据库连接数乱配Druid 的maxActive50默认值足以扛住几十人同时点查询。如果你发现项目启动时控制台报“数据源未配置”九成是这个依赖没被 Maven 下载完整。2.2 application.yml 里的关键参数后端配置写在src/main/resources/application.yml注意这里的缩进和空格必须是两个空格用 Tab 必挂server: port: 8080 servlet: context-path: / spring: datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/archive_system?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: 123456 druid: initial-size: 5 min-idle: 5 max-active: 20 mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.example.archive.entity configuration: map-underscore-to-camel-case: truecontext-path: /表示接口路径不带前缀有的项目会改成/api如果你发现前端请求是http://localhost:8080/api/...这里就要对应改成/api。map-underscore-to-camel-case: true必须开启否则数据库create_time字段映射不到 Java 的createTime属性。Druid 的initial-size不要调太大本机开发建议保持 5调到 20 会在启动时频繁建立连接反而拖慢首次请求。2.3 Mybatis Mapper 装配的三种写法项目里 Mapper 接口和 XML 是分开的。接口放在com.example.archive.mapperXML 放在resources/mapper下。关键点在启动类SpringBootApplication MapperScan(com.example.archive.mapper) public class ArchiveApplication { public static void main(String[] args) { SpringApplication.run(ArchiveApplication.class, args); } }如果去掉MapperScan每个 Mapper 接口上都得单独加Mapper二选一即可但不能重复加——重复加虽然不报错但会导致 Spring 启动时产生无效代理。XML 文件里的 namespace 必须和接口全限定名一致比如接口是com.example.archive.mapper.UserMapperXML 里就得写mapper namespacecom.example.archive.mapper.UserMapper我见过不少报Invalid bound statement (not found)的案例都是因为 XML 的 namespace 写错。你解压后先搜索这个报错如果出现直接改 namespace 而不是重装依赖。3. Vue 前端结构与组件改造从 IndexMain.vue 到无登录调试这套系统的前端和后端是分离的。压缩包里那批.vue.bak文件其实是作者改代码时留下的备份比如IndexMain.vue.bak和IndexMain.vue并存说明当时调 Index 主页布局时反复改了很多版。对学习者来说这些备份反而能看出迭代痕迹。3.1 前端目录的坑静态资源在后端还是独立 Vue 项目解压后你会看到两类东西一类是src目录下直接存放的.vue文件比如IndexAsideStatic.vue、BreadCrumbs.vue这类组件另一类是单独的 frontend 或 web 目录。这个项目的前端是编译后扔进 SpringBoot 的static目录的。具体来说后端项目/src/main/resources/static/ ├── index.html ├── static/ │ ├── js/ │ └── css/那堆IndexMain.vue.bak是源码不在 static 里。生产环境访问时浏览器加载的是编译压缩后的 js而不是.vue源文件。如果你想改前端逻辑得找到src里的 Vue 源码改完用npm run build重新打包然后把生成的 dist 内容拷贝到 static 下面。有个常见误操作直接改static目录里的压缩 js然后刷新浏览器发现没变。因为浏览器缓存了旧文件。你需要在开发者工具的 Network 标签里勾选“Disable cache”再强制刷新。3.2 用 Vue devtools 快速锁定组件对应的后端接口我拿到这种项目第一步不是读代码而是用 Chrome 打开登录页按 F12 看网络请求。比如你在 Network 里看到POST /user/login那就在源码里搜login关键字// 登录接口封装在 api/login.js export function login(username, password) { return request({ url: /user/login, method: post, data: { username, password } }) }这里注意request是 axios 实例通常在utils/request.js里做了统一拦截。你在浏览器看到的状态码 401 或 403多半不是后端接口崩了而是 axios 拦截器把未登录的请求统一处理了。3.3 彻底跳过登录的调试技巧很多毕设项目的权限校验写在前端路由守卫里后端接口并没有真正校验 token。你可以临时用下面这个方式跳过登录快速验证后端接口// router/index.js 中注释掉 beforeEach 里的登录判断 router.beforeEach((to, from, next) { // 临时注释if (!sessionStorage.getItem(token) to.path ! /login) { // 临时注释 next(/login) // 临时注释 return // 临时注释 } next() })这样改动后刷新页面会直接进入主页但主页里调用的接口可能拿不到当前用户 ID因为后端接口从 token 里解析 user_id。此时你需要在 localStorage 里手动塞一个假 token。更稳妥的做法是用后端提供的注册接口先注册一个测试账号再用 Postman 调登录接口拿到真实 token塞进浏览器 localStorage 的对应 key 里。我一般用下面这段代码直接在 Console 执行localStorage.setItem(token, 你从Postman复制来的token) location.reload()注意不同项目的 token 存储 key 不一样有的叫token有的叫Authorization。先点开 Application 标签页的 Local Storage 看下现有 key 名。4. 档案业务核心逻辑分类、借阅、权限的数据库设计与接口实现档案管理系统和普通 CRUD 最大的区别在于档案有密级和借阅生命周期。这套代码里的数据库脚本通常叫archive.sql里面至少包含四类核心表档案表、分类表、用户表、借阅记录表。4.1 档案表与分类表的设计以archive_info表为例关键字段如下CREATE TABLE archive_info ( archive_id int(11) NOT NULL AUTO_INCREMENT, archive_no varchar(50) NOT NULL COMMENT 档案编号, title varchar(200) NOT NULL COMMENT 档案标题, category_id int(11) NOT NULL COMMENT 分类ID, secret_level tinyint(1) DEFAULT 1 COMMENT 密级1公开2内部3机密, storage_location varchar(100) DEFAULT NULL COMMENT 实体存放位置, status tinyint(1) DEFAULT 1 COMMENT 状态1在库2借出3销毁, create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (archive_id), KEY idx_category (category_id), KEY idx_secret (secret_level) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;注意archive_no这个字段在查询场景里经常被当成主键用。但实际设计时我强烈建议保留自增主键archive_id因为如果档案编号规则改了比如加上年份前缀自增主键不会受影响。分类表archive_category更简单但你在改的时候要留意有没有做递归树。很多雏形系统只做了一级分类后面对接前端树形下拉组件时会发现拿不到层级数据。如果你需要支持多级分类可以用一个parent_id字段实现ALTER TABLE archive_category ADD COLUMN parent_id int(11) DEFAULT 0 COMMENT 父分类ID0为根节点;4.2 借阅接口实现与状态流转借阅流程的核心是“状态机”思维在库 - 借出 - 归还。后端接口通常集中在ArchiveBorrowController中我挑借阅申请这一段说明。PostMapping(/borrow) public Result borrowArchive(RequestBody BorrowRequest request) { // 1. 检查档案是否存在且在库 ArchiveInfo archive archiveMapper.selectById(request.getArchiveId()); if (archive null) { return Result.error(档案不存在); } if (archive.getStatus() ! 1) { return Result.error(档案当前不可借阅); } // 2. 检查借阅人权限只允许比档案密级高或同级的用户借 User user userMapper.selectById(request.getUserId()); if (user.getSecretLevel() archive.getSecretLevel()) { return Result.error(当前用户密级不足无法借阅); } // 3. 插入借阅记录同时更新档案状态 int insert borrowRecordMapper.insert(request.getUserId(), archive.getArchiveId()); archiveMapper.updateStatus(archive.getArchiveId(), 2); return insert 0 ? Result.success() : Result.error(借阅失败); }上面的代码逻辑不算复杂但有个并发隐患如果两个人同时点击借阅同一份档案状态判断和更新之间存在时间差就会重复借出。要解决这个问题可以把“在库状态的更新”做成带条件的状态变更UPDATE archive_info SET status 2 WHERE archive_id #{archiveId} AND status 1这样即使请求同时到达数据库也会通过行锁保证只有一条更新成功。返回值影响行数为 0 时就说明别人抢先了一步。这是我从一个真实生产档案系统中搬过来的思路毕业设计里用到这一步答辩时会是明显的加分项。4.3 权限控制在 Mybatis 层怎么做数据过滤除了登录校验档案系统更关键的是“按密级过滤列表”。比如普通用户登录后应该只能看到secret_level 2的档案。如果你在 Service 层用 if 判断后循环过滤数据量大时会卡死。推荐在 SQL 层直接过滤select idselectByUserLevel resultTypeArchiveInfo SELECT * FROM archive_info WHERE status ! 3 AND secret_level lt; #{userLevel} if testkeyword ! null and keyword ! AND title LIKE CONCAT(%, #{keyword}, %) /if ORDER BY create_time DESC LIMIT #{offset}, #{pageSize} /select在这个 Mybatis XML 里lt;是 XML 对的转义如果你直接写XML 解析会报错。#{userLevel}的值是在 Controller 层通过session.getAttribute(userLevel)拿到的不要在 SQL 里写死。另外注意 SQL 里的LIKE用CONCAT拼接避免%#{keyword}%这种不能直接用的写法。这样设计的好处是前端永远只能拿到它权限范围内的数据即便有人绕过前端直接调接口也无法越权看到机密档案。5. 从压缩包到能跑三个 bat 脚本与浏览器验证排错压缩包根目录下躺着1-install.bat、2-run.bat、3-build.bat这三个文件是作者留给你的运行入口。如果你在 Windows 上解压别直接双击先右键用记事本打开看看内容。5.1 脚本执行顺序与参数坑最常见的顺序是先跑1-install.bat装 Maven 依赖然后跑2-run.bat启动后端最后用3-build.bat打包前端。但实际这几个脚本里往往写死了相对路径我遇到过下面的写法echo off cd /d D:\archive_system\backend mvn clean install -DskipTests如果你的解压路径不是D:\archive_system这个脚本就会闪退。解决办法是用下面这种相对定位cd /d %~dp0backend%~dp0表示当前 bat 所在目录这样不管你把压缩包解压到哪个盘哪个文件夹都能正确切到后端目录。5.2 启动后失败的三种表现第一种端口占用。双击 bat 后控制台立刻报Port 8080 was already in use。这是因为我上面提到的server.port8080被其他程序占了。不用改代码换启动参数mvn spring-boot:run -Dspring-boot.run.arguments--server.port8081第二种数据库密码不对。脚本里通常不会添加修改配置文件的操作如果你本机 MySQL 密码不是123456需要在application.yml里同步改掉。改完记得先重启 MySQL 服务再重新运行后端。第三种前端页面能打开但接口全部 404。这种现象在前后端分离项目里特别常见——你直接双击了index.htmlURL 变成了file:///C:/...而接口请求发到了file协议下当然找不到。正确做法是先启动后端然后用浏览器访问http://localhost:8080。5.3 验证接口是否健康的两个技巧技巧一用 curl 快速测登录接口不需要打开任何工具curl -X POST http://localhost:8080/user/login \ -H Content-Type: application/json \ -d {username:admin,password:admin123}如果返回{code:200,data:{token:...}}这串 JSON说明后端链路完全正常。如果返回 404就先查 controller 里的RequestMapping是不是带/api前缀如果返回 500看后台日志第一行异常堆栈。技巧二检查静态资源是否加载成功。在浏览器访问http://localhost:8080/index.html如果出现的是空白页按 F12 看 Console 有没有报Uncaught SyntaxError这通常表示static目录里的 js 文件是压缩版但没被正确编译。此时重新执行3-build.bat或者从frontend/dist里把打包好的文件重新覆盖到src/main/resources/static。覆盖时注意别把index.html和static的层级搞错——很多同学把 dist 里的东西直接往根目录倒导致路径全部错位。最简单的验证方法是正常状态下访问http://localhost:8080/js/chunk-xxx.js能返回内容而不是 404。这套档案系统代码里最有用的部分其实不是档案表的增删改查而是它把 SpringBoot 的自动装配、Maven 依赖管理、Vue 构建产物和传统 Web 应用部署方式揉到了一起。你花半天时间顺着1-install.bat到浏览器按下 F12 走通一遍之后再拿到任何xxx.vue.bak和xxx.bak混合的源码包都会先检查路径和数据库连接而不是急着找没有的“一键运行”。本文还有配套的精品资源点击获取
返回列表