| .gitea/workflows | ||
| gradle/wrapper | ||
| images | ||
| src | ||
| .gitignore | ||
| build.gradle.kts | ||
| FRONTEND_GUIDE.md | ||
| FRONTEND.md | ||
| gradle.properties | ||
| gradlew | ||
| gradlew.bat | ||
| README.md | ||
| REPORT_GUIDE.md | ||
| REPORT.md | ||
| settings.gradle.kts | ||
VibeVault 期末大作业
本大作业要求你在给定的起始代码基础上,完成一个可运行、可测试、可说明的 VibeVault 后端系统。
一、学习目标
- 掌握端到端后端工程能力:从实体建模、REST API 设计到数据库与事务管理
- 应用三层架构与设计原则:通过 Controller / Service / Repository 分层
- 构建自动化测试安全网:使用 JUnit/AssertJ 等工具为核心业务编写测试
- 理解并实现基础安全机制:落地最小可用的认证与授权骨架
- 学会与 AI 协同开发:通过高质量 Prompt 使用大模型辅助开发
二、运行环境
- JDK 21
- Gradle(使用仓库内 Wrapper:
./gradlew) - Spring Boot 3.4.x
本地常用命令:
./gradlew test # 编译与测试
./gradlew bootRun # 运行应用
三、功能要求
🟢 Core 轨道(必做,约 60 分)
1. 实体层(model 包)
完善 User、Playlist、Song 三个 JPA 实体类:
-
User:用户实体,映射到
users表- 用户名必须唯一且不能为空
- 密码不能为空
- 包含角色字段(默认
ROLE_USER)
-
Playlist:歌单实体,映射到
playlists表- 每个歌单属于一个用户(多对一)
- 一个歌单包含多首歌曲(一对多)
- 删除歌单时应级联删除其中的歌曲
- 实现
addSong()和removeSong()方法维护双向关系
-
Song:歌曲实体,映射到
songs表- 每首歌曲属于一个歌单(多对一)
2. 仓库层(repository 包)
- UserRepository:提供根据用户名查找用户、检查用户名是否存在的方法
- PlaylistRepository:继承 JpaRepository 即可
3. 服务层(service 包)
实现 PlaylistServiceImpl 中的所有方法:
- 获取所有歌单
- 根据 ID 获取歌单(不存在时抛出
ResourceNotFoundException) - 创建新歌单
- 向歌单添加歌曲
- 从歌单移除歌曲
- 删除歌单
4. 控制器层(controller 包)
PlaylistController - 歌单 REST API:
| 端点 | 说明 | 状态码 |
|---|---|---|
GET /api/playlists |
获取所有歌单 | 200 |
GET /api/playlists/{id} |
获取指定歌单 | 200 / 404 |
POST /api/playlists |
创建新歌单 | 201 |
POST /api/playlists/{id}/songs |
添加歌曲 | 201 |
DELETE /api/playlists/{playlistId}/songs/{songId} |
移除歌曲 | 204 |
DELETE /api/playlists/{id} |
删除歌单 | 204 |
AuthController - 认证 API:
| 端点 | 说明 | 状态码 |
|---|---|---|
POST /api/auth/register |
用户注册 | 201 / 409(用户名已存在) |
POST /api/auth/login |
用户登录 | 200(返回 JWT)/ 401 |
5. 安全配置(security 和 config 包)
- 配置公开接口:
/api/auth/**、GET /api/playlists、GET /api/playlists/{id} - 其他接口需要认证
- 未认证访问受保护资源返回 401 Unauthorized
- 实现 JWT 生成、验证和过滤器
🟡 Advanced 轨道(进阶,约 10 分)
1. 事务与一致性
- 确保 Service 层的写操作都有事务支持
- 批量操作保证原子性
2. 高级查询
在 Repository 和 Service 层添加:
- 按所有者查询歌单
- 按名称模糊搜索歌单
- 复制歌单功能
对应的 Controller 端点:
| 端点 | 说明 |
|---|---|
GET /api/playlists/search?keyword=xxx |
搜索歌单 |
POST /api/playlists/{id}/copy?newName=xxx |
复制歌单 |
3. 统一异常处理
使用 @RestControllerAdvice 实现全局异常处理:
ResourceNotFoundException→ 404UnauthorizedException→ 403- 其他异常 → 合适的状态码
🔴 Challenge 轨道(挑战,约 10 分)
1. 所有权检查
- 只有歌单所有者可以修改/删除自己的歌单
- 非所有者操作他人歌单返回 403 Forbidden
2. 角色权限
- 支持用户角色(
ROLE_USER、ROLE_ADMIN) - 管理员可以删除任何用户的歌单
- 普通用户只能删除自己的歌单
四、报告要求(约 20 分)
📝 写作指导:请参考
REPORT_GUIDE.md和FRONTEND_GUIDE.md了解详细的写作要求和格式说明。
REPORT.md - 后端开发反思报告(10 分)
在 REPORT.md 文件中撰写后端开发反思报告,建议 800–1500 字,围绕以下三个问题展开:
- 问题解决(4 分):你遇到的最大挑战是什么?你是如何解决的?
- 反思深度(3 分):如果重新做一遍,你会有什么不同的设计决策?
- AI 使用(3 分):你如何使用 AI 辅助开发?有什么经验教训?
⚠️ 我们想听到的是你的思考,而非代码的复述。
FRONTEND.md - 前端开发反思报告(10 分)
在 FRONTEND.md 文件中撰写前端开发反思报告,建议 600–1200 字,围绕以下三个问题展开:
- 界面展示(5 分):提供 3–6 张截图展示你的界面,每张配简要说明
- 问题解决(3 分):你在前端开发中遇到的最大挑战是什么?
- 反思改进(2 分):如果重新做一遍,你会如何改进?
📁 截图位置:将截图保存到仓库根目录下的
images/文件夹
五、评分构成
| 项目 | 分值 | 说明 |
|---|---|---|
| Core 测试 | 60 分 | 实体、Service、Controller、基础安全 |
| Advanced 测试 | 10 分 | 事务、高级查询、统一异常处理 |
| Challenge 测试 | 10 分 | 所有权检查、角色权限 |
| REPORT.md | 10 分 | LLM 自动评分 |
| FRONTEND.md | 10 分 | LLM 自动评分 |
⚠️ 通过本地公开测试 ≠ 拿满分。隐藏测试会检查更多边界条件。
六、提交流程
- 克隆仓库到本地
- 完成代码开发
- 运行
./gradlew test确保公开测试通过 - 完成
REPORT.md和FRONTEND.md git add / commit / push到main分支- 触发自动评分(二选一):
- 在 commit message 中包含 "完成作业" 字样
- 或推送
submit开头的标签:git tag submit && git push origin submit
- 在 Gitea Actions 页面查看评分结果
💡 提示:普通提交不会触发自动评分,这样你可以在开发过程中自由提交而不用担心消耗评分次数。
七、学术诚信
- ❌ 禁止直接复制他人代码或报告
- ✅ 允许使用 AI 辅助,但必须完全理解生成的代码
- ⚠️ 教师可能通过口头问答或现场演示抽查
八、建议节奏
- 第 1 周:完成实体建模(JPA 注解)、Repository、Playlist.addSong/removeSong
- 第 2 周:完成 Service 层、Controller 层、认证接口
- 第 3 周:完成 Security 配置、Advanced 和 Challenge 任务
- 截止前:完成报告,最后一轮自测
九、代码结构说明
src/main/java/com/vibevault/
├── VibeVaultApplication.java # 启动类(已完成)
├── config/
│ └── SecurityConfig.java # 安全配置(待实现)
├── controller/
│ ├── AuthController.java # 认证控制器(待实现)
│ └── PlaylistController.java # 歌单控制器(待实现)
├── dto/
│ ├── PlaylistDTO.java # 歌单响应 DTO(已完成)
│ ├── PlaylistCreateDTO.java # 创建歌单请求 DTO(已完成)
│ ├── SongDTO.java # 歌曲响应 DTO(已完成)
│ └── SongCreateDTO.java # 添加歌曲请求 DTO(已完成)
├── exception/
│ ├── GlobalExceptionHandler.java # 全局异常处理(待实现)
│ ├── ResourceNotFoundException.java # 资源不存在异常(已完成)
│ └── UnauthorizedException.java # 未授权异常(已完成)
├── model/
│ ├── User.java # 用户实体(待添加 JPA 注解)
│ ├── Playlist.java # 歌单实体(待添加 JPA 注解)
│ └── Song.java # 歌曲实体(待添加 JPA 注解)
├── repository/
│ ├── UserRepository.java # 用户仓库(待添加查询方法)
│ └── PlaylistRepository.java # 歌单仓库(待添加查询方法)
├── security/
│ ├── JwtService.java # JWT 服务(待实现)
│ └── JwtAuthenticationFilter.java # JWT 过滤器(待实现)
└── service/
├── PlaylistService.java # 歌单服务接口(已完成)
└── PlaylistServiceImpl.java # 歌单服务实现(待实现)
祝你顺利完成!记住:理解永远比"跑通一次"更重要。