手把手教你搭建一个「学生证书管理系统」— Spring Boot + Vue 3 全栈毕设开源项目
🎓 手把手教你搭建一个「学生证书管理系统」— Spring Boot + Vue 3 全栈毕设开源项目
适合人群:Java/Vue 初学者、正在做毕设的同学、想学习全栈项目实战的新手
技术栈:Spring Boot 4.0 + Vue 3 + Element Plus + JWT + MySQL/H2
代码量:后端 ~1500 行,前端 ~1200 行,适合新手
开源地址:文末附完整项目结构
📖 目录
- 项目是干什么的?
- 系统功能一览
- 技术栈选型——为什么选这些?
- 数据库设计——两张表搞定
- 后端核心实现——逐层拆解
- 前端核心实现——页面是怎么跑起来的
- 项目亮点——毕设答辩加分项
- 如何跑起来?
- 总结 & 可扩展方向
1. 项目是干什么的?
简单说,这是一个 学生提交证书 + 教师审核 + 导出报表 的 Web 系统。
真实场景:大学里经常需要学生提交各种证书(四六级、计算机等级、竞赛获奖等),辅导员或教务老师要一个个收集、审核、汇总。用 Excel 传来传去很乱,这个系统就是解决这个痛点的。
两种用户角色:
| 角色 | 能干什么 |
|---|---|
| 🧑🎓 学生 | 注册登录 → 提交证书(名称+机构+日期+编号+附件图片/PDF)→ 查看审核结果 |
| 👩🏫 教师 | 注册登录 → 查看所有学生证书 → 审核(通过/拒绝+意见)→ 导出 Excel / ZIP 压缩包 |
2. 系统功能一览
2.1 学生端
注册/登录 → 首页仪表盘 → 我的证书列表 → 提交新证书 → 编辑/删除证书 → 查看审核意见
- 注册:选择"学生"角色,填写用户名、密码、姓名
- 提交证书:填写证书名称、颁发机构、获得日期、证书编号,还可以拖拽上传证书图片/PDF
- 证书列表:按状态筛选(待审核 / 已通过 / 已拒绝)
- 编辑/删除:审核前可以修改或删除
2.2 教师端
注册/登录 → 首页仪表盘 → 证书审核页 → 通过/拒绝 + 审核意见 → 导出 Excel / ZIP
- 审核:看到所有学生的证书,点击"通过"或"拒绝",填写审核意见
- 导出 Excel:导出所有证书的文字信息(名称、学生、状态等),方便打印
- 导出 ZIP:按学生姓名分文件夹,打包所有证书图片 + 一份汇总 CSV
2.3 系统截图(文字版)
点击展开页面结构说明┌──────────────────────────────────────────────┐
│ 侧边栏 │ 主内容区 │
│ ┌─────────────┐ │ ┌──────────────┐ │
│ │ 🏫 系统名 │ │ │ 页面标题 │ │
│ ├─────────────┤ │ ├──────────────┤ │
│ │ 📊 首页 │ │ │ │ │
│ │ 📄 我的证书 │ │ │ 表格/表单/ │ │
│ │ ➕ 提交证书 │ │ │ 数据展示 │ │
│ └─────────────┘ │ │ │ │
│ (可折叠) │ └──────────────┘ │
└──────────────────────────────────────────────┘
3. 技术栈选型——为什么选这些?
后端
| 技术 | 作用 | 为什么选它? |
|---|---|---|
| Spring Boot 4.0 | 后端框架 | Java 生态最主流,自动配置省心,新手友好 |
| Spring Security | 权限控制 | 和 Spring Boot 无缝集成,注解式鉴权 |
| JWT | 身份认证 | 无状态,不用存 Session,适合前后端分离 |
| JPA/Hibernate | 数据库操作 | 不用手写 SQL,Entity 类直接映射成表 |
| H2 内存数据库 | 开发环境 | 零安装!程序启动就有数据库,毕设演示超方便 |
| Apache POI | Excel 导出 | Java 操作 Excel 的事实标准 |
前端
| 技术 | 作用 | 为什么选它? |
|---|---|---|
| Vue 3 | 前端框架 | 中文文档最好,上手快,组合式 API 更灵活 |
| Element Plus | UI 组件库 | 饿了么出品,组件丰富(表格/表单/弹窗全有) |
| Vue Router | 路由管理 | 页面跳转 + 路由守卫,不登录就跳回登录页 |
| Pinia | 状态管理 | Vue 官方推荐,比 Vuex 简洁太多 |
| Axios | HTTP 请求 | 拦截器自动带 JWT Token,自动处理 401 |
💡 新手选型口诀
“Spring Boot 做后端、Vue 3 做前端、Element Plus 画界面、JWT 管登录、H2 省装数据库”
这套组合是 2024-2026 年毕设最常见的搭配,网上资料最多,出问题最好查。
4. 数据库设计——两张表搞定
整个系统只需要 两张表,这可能是你见过最简单的毕设数据库设计了。
4.1 用户表(users)
CREATE TABLE users (
id BIGINT AUTO_INCREMENT PRIMARY KEY, -- 用户ID,自增
username VARCHAR(50) NOT NULL UNIQUE, -- 登录用户名
password VARCHAR(255) NOT NULL, -- 密码(BCrypt加密)
name VARCHAR(100) NOT NULL, -- 真实姓名
role VARCHAR(20) NOT NULL, -- STUDENT 或 TEACHER
email VARCHAR(100), -- 邮箱(选填)
phone VARCHAR(20), -- 电话(选填)
created_at DATETIME, -- 注册时间
updated_at DATETIME -- 更新时间
);
4.2 证书表(certificates)
CREATE TABLE certificates (
id BIGINT AUTO_INCREMENT PRIMARY KEY, -- 证书ID
name VARCHAR(200) NOT NULL, -- 证书名称
issuing_org VARCHAR(200) NOT NULL, -- 颁发机构
issue_date DATE NOT NULL, -- 获得日期
cert_number VARCHAR(100) NOT NULL, -- 证书编号
file_path VARCHAR(500), -- 附件存储路径
file_name VARCHAR(255), -- 原始文件名
file_type VARCHAR(50), -- 文件类型
file_size BIGINT, -- 文件大小(字节)
status VARCHAR(20) NOT NULL DEFAULT 'PENDING', -- 审核状态
user_id BIGINT NOT NULL, -- 提交学生(外键)
reviewer_id BIGINT, -- 审核教师(外键)
review_comment VARCHAR(500), -- 审核意见
created_at DATETIME,
updated_at DATETIME,
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (reviewer_id) REFERENCES users(id)
);
📊 两张表的关系
┌──────────────┐ ┌──────────────────────┐
│ users │ 1─────N │ certificates │
│ │ │ │
│ id (PK) │◄────────│ user_id (FK) │
│ username │ │ reviewer_id (FK) │──┐
│ role │ │ name, issuing_org... │ │
│ name │ │ status: PENDING/ │ │
└──────────────┘ │ APPROVED/REJECTED │ │
▲ │ file_path │ │
└─────────────────│ reviewer_id (FK) │──┘
└──────────────────────┘
- 一个学生可以提交多个证书(一对多)
- 一个教师可以审核多个证书(一对多)
- 证书状态流转:PENDING(待审核)→ APPROVED(通过)/ REJECTED(拒绝)
5. 后端核心实现——逐层拆解
后端采用经典的 Controller → Service → Repository 三层架构:
请求进来 → Controller(接收参数)→ Service(处理业务)→ Repository(操作数据库)→ 返回 JSON
5.1 项目结构一览
backend/src/main/java/com/example/studentms/
├── StudentMsApplication.java # Spring Boot 启动类
├── config/ # 配置层
│ ├── SecurityConfig.java # Spring Security 安全配置
│ ├── JwtUtil.java # JWT 生成/解析/验证工具
│ ├── JwtAuthFilter.java # JWT 过滤器(每个请求先过这里)
│ ├── WebConfig.java # 跨域配置
│ └── PasswordEncoderConfig.java # 密码加密器
├── entity/ # 实体层(对应数据库表)
│ ├── User.java # 用户实体
│ └── Certificate.java # 证书实体
├── dto/ # 数据传输对象(前端传什么、后端回什么)
│ ├── LoginRequest.java # 登录请求
│ ├── RegisterRequest.java # 注册请求
│ ├── LoginResponse.java # 登录响应(含 JWT Token)
│ ├── CertificateRequest.java # 证书提交/编辑请求
│ ├── CertificateResponse.java # 证书列表/详情响应
│ └── ReviewRequest.java # 审核请求
├── repository/ # 数据访问层(JPA 接口)
│ ├── UserRepository.java # 用户查询
│ └── CertificateRepository.java # 证书查询
├── service/ # 业务逻辑层
│ ├── AuthService.java # 注册/登录逻辑
│ ├── CertificateService.java # 证书 CRUD + 审核
│ ├── FileStorageService.java # 文件存储服务
│ └── ExportService.java # Excel / ZIP 导出
├── controller/ # 控制器层(路由入口)
│ ├── AuthController.java # /api/auth/* 注册登录
│ ├── CertificateController.java # /api/certificates/* 证书操作
│ └── FileController.java # /api/files/* 文件下载
└── exception/ # 异常处理
├── BusinessException.java # 自定义业务异常
└── GlobalExceptionHandler.java # 全局异常拦截
💡 新手提示:这就是典型的 Spring Boot 分层结构,毕设按这个结构来写,答辩时层次清晰、涨分!
5.2 认证流程——JWT 是怎么工作的?
这是很多新手最困惑的地方,我画个流程图就清楚了:
【注册】
用户填表单 → POST /api/auth/register → 密码用 BCrypt 加密 → 存入数据库
【登录】
用户填用户名密码 → POST /api/auth/login
→ 查数据库验证密码(BCrypt 比对)
→ 生成 JWT Token(包含用户名+角色,24小时有效)
→ 返回 Token 给前端
→ 前端存到 localStorage
【后续请求】
前端每次请求都在 Header 里带 "Authorization: Bearer <Token>"
→ JwtAuthFilter 拦截请求
→ 解析 Token,验证签名和有效期
→ 把用户信息放入 SecurityContext
→ Controller 通过 @AuthenticationPrincipal 拿到当前用户
核心代码(JwtUtil.java):
// 生成 Token:把用户名和角色写进去,签名,设有效期
public String generateToken(UserDetails userDetails) {
String role = userDetails.getAuthorities().stream()
.findFirst().map(GrantedAuthority::getAuthority)
.orElse("ROLE_STUDENT");
return Jwts.builder()
.subject(userDetails.getUsername()) // 存用户名
.claim("role", role) // 存角色
.issuedAt(new Date()) // 签发时间
.expiration(new Date(System.currentTimeMillis() + expiration)) // 过期时间
.signWith(getKey()) // HMAC-SHA256 签名
.compact();
}
5.3 权限控制——学生和教师怎么区分?
用 Spring Security 的注解,超级简单:
// SecurityConfig.java 中的 URL 级别控制
.requestMatchers("/api/auth/**").permitAll() // 注册登录 - 谁都能访问
.requestMatchers("/api/certificates/all",
"/api/certificates/export").hasRole("TEACHER") // 只有教师能访问
.requestMatchers("/api/certificates/**").hasAnyRole("STUDENT", "TEACHER") // 学生教师都能访问
用户实体 实现 UserDetails 接口,把角色映射成 Spring Security 的权限:
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return List.of(new SimpleGrantedAuthority("ROLE_" + role.name()));
// STUDENT → ROLE_STUDENT
// TEACHER → ROLE_TEACHER
}
5.4 证书 CRUD —— 核心业务代码
以"学生提交证书"为例,展示完整的数据流转:
// CertificateController.java —— 接收前端请求
@PostMapping
public ResponseEntity<CertificateResponse> create(
@RequestPart("data") @Valid CertificateRequest request, // JSON 数据
@RequestPart(value = "file", required = false) MultipartFile file, // 附件文件
@AuthenticationPrincipal UserDetails userDetails) { // 当前登录用户
User student = authService.getCurrentUser(userDetails.getUsername());
CertificateResponse response = certificateService.create(request, file, student);
return ResponseEntity.ok(response); // 返回 200 + JSON
}
// CertificateService.java —— 处理业务逻辑
@Transactional
public CertificateResponse create(CertificateRequest request, MultipartFile file, User student) {
// 1. 创建实体对象
Certificate certificate = new Certificate();
certificate.setName(request.getName());
certificate.setIssuingOrg(request.getIssuingOrg());
certificate.setIssueDate(request.getIssueDate());
certificate.setCertNumber(request.getCertNumber());
certificate.setUser(student); // 关联学生
certificate.setStatus(Certificate.Status.PENDING); // 默认待审核
// 2. 处理文件上传
if (file != null && !file.isEmpty()) {
String storedName = fileStorageService.store(file); // 存到 uploads/ 目录
certificate.setFilePath(storedName);
certificate.setFileName(file.getOriginalFilename());
certificate.setFileSize(file.getSize());
}
// 3. 保存到数据库
certificate = certificateRepository.save(certificate);
// 4. 转成 DTO 返回(不直接暴露 Entity)
return toResponse(certificate);
}
💡 关键概念:为什么要有 DTO?
Entity 直接和数据库挂钩,包含敏感字段(如 password);DTO 只返回前端需要的字段。Entity → DTO 转换 是后端开发的铁律。
5.5 Excel 导出——Apache POI 实战
// ExportService.java
public void exportToExcel(OutputStream outputStream, String status) {
List<Certificate> certificates = certificateService.getCertificatesForExport(status);
try (Workbook workbook = new XSSFWorkbook()) { // 创建 .xlsx 工作簿
Sheet sheet = workbook.createSheet("证书列表");
// 1. 创建表头行(加粗 + 灰色背景)
Row header = sheet.createRow(0);
String[] columns = {"序号", "证书名称", "颁发机构", "获得日期",
"证书编号", "学生姓名", "审核状态", "审核意见", "提交时间"};
for (int i = 0; i < columns.length; i++) {
Cell cell = header.createCell(i);
cell.setCellValue(columns[i]);
cell.setCellStyle(headerStyle); // 加粗、背景色
}
// 2. 填充数据行
int rowIdx = 1;
for (Certificate c : certificates) {
Row row = sheet.createRow(rowIdx++);
row.createCell(0).setCellValue(rowIdx - 1); // 序号
row.createCell(1).setCellValue(c.getName()); // 证书名
row.createCell(2).setCellValue(c.getIssuingOrg());// 颁发机构
// ... 其他列
}
// 3. 自动调整列宽
for (int i = 0; i < columns.length; i++) {
sheet.autoSizeColumn(i);
}
workbook.write(outputStream); // 写出到 HTTP 响应的 OutputStream
}
}
学习 POI 只需要记住三个对象:
- Workbook = 整个 Excel 文件
- Sheet = 一个工作表
- Row / Cell = 行 / 单元格
5.6 ZIP 导出——按学生分文件夹打包
这是本项目的一个独特功能,不只是导出 Excel,还把所有学生上传的证书图片/PDF 按学生分文件夹打成 ZIP:
// ZIP 内部结构:
// 张三_zhangsan/
// OCJP认证_OCJP-001.pdf
// 英语六级_ENG-2025001.jpg
// 李四_lisi/
// 计算机二级_CS-2025032.pdf
// index.csv ← 所有证书的总汇总表
核心代码逻辑:先按学生分组 → 遍历每个学生的证书 → 读取上传的文件写入 ZIP → 追加 index.csv。
6. 前端核心实现——页面是怎么跑起来的
6.1 项目结构
frontend/src/
├── main.ts # 入口:创建 Vue 应用,挂载 Router 和 Pinia
├── App.vue # 根组件
├── api/ # API 请求封装
│ ├── index.ts # Axios 实例 + 拦截器
│ ├── auth.ts # 登录/注册 API
│ └── certificate.ts # 证书相关 API
├── router/
│ └── index.ts # 路由配置 + 导航守卫
├── stores/
│ └── auth.ts # Pinia 状态管理(用户信息)
├── components/
│ └── AppLayout.vue # 主布局:侧边栏 + 顶栏 + 内容区
└── views/
├── Login.vue # 登录页
├── Register.vue # 注册页
├── student/
│ ├── StudentDashboard.vue # 学生首页(统计数据)
│ ├── CertificateList.vue # 证书列表(筛选/查看/删除)
│ └── CertificateForm.vue # 提交/编辑证书表单
└── teacher/
├── TeacherDashboard.vue # 教师首页
├── CertificateReview.vue # 审核页面
└── CertificateExport.vue # 导出页面
6.2 路由设计——页面怎么跳转的?
// router/index.ts
const routes = [
// 公开页面(未登录也能访问)
{ path: '/login', component: Login, meta: { guest: true } },
{ path: '/register', component: Register, meta: { guest: true } },
// 学生专区(需要登录 + STUDENT 角色)
{ path: '/student', component: AppLayout, meta: { requiresAuth: true, role: 'STUDENT' },
children: [
{ path: '', component: StudentDashboard },
{ path: 'certificates', component: CertificateList },
{ path: 'certificates/new', component: CertificateForm },
{ path: 'certificates/:id/edit', component: CertificateForm },
]
},
// 教师专区(需要登录 + TEACHER 角色)
{ path: '/teacher', component: AppLayout, meta: { requiresAuth: true, role: 'TEACHER' },
children: [
{ path: '', component: TeacherDashboard },
{ path: 'certificates', component: CertificateReview },
{ path: 'export', component: CertificateExport },
]
},
// 其他路径全部重定向到登录页
{ path: '/:pathMatch(.*)*', redirect: '/login' }
]
6.3 路由守卫——不登录就进不来!
// 每次跳转页面前都会执行这个函数
router.beforeEach((to, from, next) => {
const token = localStorage.getItem('token')
const role = localStorage.getItem('role')
// 已登录用户访问登录/注册页 → 跳到对应首页
if (to.meta.guest && token) {
return next(role === 'TEACHER' ? '/teacher' : '/student')
}
// 没登录访问需要登录的页面 → 跳回登录页
if (to.meta.requiresAuth && !token) {
return next('/login')
}
// 学生访问教师页面(或反过来)→ 跳回自己的首页
if (to.meta.role && to.meta.role !== role) {
return next(role === 'TEACHER' ? '/teacher' : '/student')
}
next() // 放行
})
这就是前端权限控制的核心——三行判断,覆盖所有越权情况。
6.4 Axios 拦截器——自动带 Token、自动处理错误
// api/index.ts
// 请求拦截器:每次请求自动带上 JWT Token
api.interceptors.request.use((config) => {
const token = localStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
// FormData 请求不要设 Content-Type,让浏览器自动处理 multipart 边界
if (config.data instanceof FormData) {
delete config.headers['Content-Type']
}
return config
})
// 响应拦截器:统一处理错误
api.interceptors.response.use(
(response) => response, // 正常响应直接返回
(error) => {
if (error.response?.status === 401) {
// Token 过期 → 清空登录状态 → 跳转登录页
localStorage.clear()
router.push('/login')
} else if (error.response?.status === 403) {
ElMessage.error('权限不足')
} else {
ElMessage.error(error.response?.data?.message || '请求失败')
}
return Promise.reject(error)
}
)
有了这两个拦截器,每个 API 调用都不用手动处理 Token 和错误提示,代码清爽很多。
6.5 Pinia 状态管理——登录信息全局共享
// stores/auth.ts
export const useAuthStore = defineStore('auth', () => {
const token = ref(localStorage.getItem('token') || '')
const role = ref(localStorage.getItem('role') || '')
const name = ref(localStorage.getItem('name') || '')
const isStudent = () => role.value === 'STUDENT'
const isTeacher = () => role.value === 'TEACHER'
async function login(data: LoginRequest) {
const res = await authApi.login(data)
token.value = res.token
role.value = res.role
name.value = res.name
// 同步存到 localStorage,防止刷新后丢失
localStorage.setItem('token', res.token)
localStorage.setItem('role', res.role)
localStorage.setItem('name', res.name)
}
function logout() {
token.value = ''
role.value = ''
name.value = ''
localStorage.clear()
}
return { token, role, name, isStudent, isTeacher, login, logout }
})
💡 新手提示:为什么既用 Pinia 又用 localStorage?
Pinia 存内存中,刷新就没了;localStorage 持久化。两个都存,Pinia 用来响应式更新 UI,localStorage 用来刷新后恢复状态。
7. 项目亮点——毕设答辩加分项
看完上面,你可能觉得"这不就是一个增删改查的系统吗?"。确实骨架是 CRUD,但这个项目有几个让答辩老师眼前一亮的设计:
⭐ 亮点 1:双角色权限体系
不是简单的"登录/没登录",而是 学生/教师两种角色 + URL 级别 + 数据级别的双重权限:
- URL 级别:教师才能访问
/api/certificates/all,学生只能访问/api/certificates(自己的) - 数据级别:学生只能看到自己的证书,Service 层校验
if (!certificate.getUser().getId().equals(student.getId())) throw 403
这是企业级权限控制的简化版,答辩时可以说"实现了 RBAC(基于角色的访问控制)"。
⭐ 亮点 2:H2 开发 + MySQL 生产 双环境切换
Spring Boot Profile 机制,改一行配置就能从 H2 内存数据库切到 MySQL:
# application.yml
spring:
profiles:
active: dev # 改成 prod 就切 MySQL
- dev 环境:H2 内存数据库,程序启动自动建表,演示时不需要装任何数据库
- prod 环境:MySQL,数据持久化,可以真正部署上线
⭐ 亮点 3:文件上传 + 在线预览
用 multipart/form-data 上传,支持拖拽,支持图片和 PDF。教师可以直接在浏览器预览学生上传的证书附件。
⭐ 亮点 4:双格式导出(Excel + ZIP)
大多数毕设只做 Excel 导出。这个项目还做了 ZIP 导出——按学生分文件夹打包证书图片 + index.csv 汇总表。这在真实场景中非常实用,答辩时可以强调"考虑了实际使用便利性"。
⭐ 亮点 5:前后端分离 + JWT 无状态认证
- 前后端完全解耦,可以分别部署到不同服务器
- JWT 让服务端不用存 Session,水平扩展友好
- 响应拦截器统一处理 401 过期跳转,用户体验好
8. 如何跑起来?
环境准备
| 工具 | 版本要求 | 安装方式 |
|---|---|---|
| Java | 25+ | 已安装即可 |
| Node.js | 22+ | winget install OpenJS.NodeJS.LTS |
| Maven | 不需要 | 项目自带 mvnw.cmd(Maven Wrapper) |
| MySQL | 不需要 | 开发环境用 H2 内存数据库 |
| IDE | 任意 | VS Code / IntelliJ IDEA 都可以 |
三步启动
第一步:启动后端
cd backend
./mvnw.cmd spring-boot:run
看到 Started StudentMsApplication 就成功了,后端跑在 http://localhost:8080。
可以访问 http://localhost:8080/h2-console 查看数据库(JDBC URL:
jdbc:h2:mem:studentms,用户名sa,密码空)
第二步:启动前端
cd frontend
npm install # 第一次运行需要装依赖
npm run dev
前端跑在 http://localhost:5173。
第三步:开始使用
- 打开 http://localhost:5173/register
- 先注册一个学生账号,再注册一个教师账号
- 学生登录 → 提交证书
- 教师登录 → 审核证书 → 导出 Excel / ZIP
切换 MySQL(如需部署)
- 在 MySQL 中建库:
CREATE DATABASE studentms CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
- 修改
application.yml:
spring:
profiles:
active: prod # 从 dev 改成 prod
- 编辑
application-prod.yml里的数据库连接信息。
9. 总结 & 可扩展方向
适合什么样的人?
| 你的情况 | 建议 |
|---|---|
| 刚开始学 Spring Boot | ✅ 看 entity、repository、controller 三层,理解 MVC 架构 |
| 刚开始学 Vue 3 | ✅ 看组件拆分、路由守卫、Pinia 状态管理 |
| 正在做毕设 | ✅ 直接拿去用,改改前端页面 + 加个你专业领域的字段 |
| 准备面试 | ✅ 把 JWT、RBAC、文件上传、Excel 导出说清楚,面试加分 |
可以继续扩展的方向
| 扩展点 | 难度 | 说明 |
|---|---|---|
| 批量审核 | ⭐ | 表格加复选框,一键批量通过 |
| 证书分类/标签 | ⭐ | certificates 表加 category 字段 |
| 数据可视化图表 | ⭐⭐ | 前端加 ECharts,按月份/状态统计证书数量 |
| 邮件通知 | ⭐⭐ | 审核通过后自动发邮件给学生 |
| Docker 部署 | ⭐⭐ | 写 Dockerfile + docker-compose.yml |
| Redis 缓存 | ⭐⭐⭐ | Token 黑名单、热点数据缓存 |
写在最后
这个项目麻雀虽小五脏俱全,覆盖了全栈开发的核心知识点:注册登录、角色权限、文件上传、CRUD、Excel/ZIP 导出、前后端联调。非常适合作为 Spring Boot + Vue 3 的入门实战项目,也完全可以当作毕设的基础框架,在此基础上加你自己的业务字段和功能。
如果对你有帮助,欢迎 点赞 👍 + 收藏 ⭐ + 关注 三连支持!有问题欢迎评论区交流~
需要源代码源代码评论区扣1
作者:林行
技术栈:Spring Boot 4.0 + Vue 3 + Element Plus + JWT + H2/MySQL
适用场景:毕业设计 / 课程设计 / 新手全栈学习
项目结构:完整前后端分离,后端 ~1500 行,前端 ~1200 行
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐
所有评论(0)