音乐推荐系统
基于 Spring Boot 4.0.5 + Vue 3 构建的全栈音乐推荐应用,集成热度推荐、基于内容推荐与协同过滤三种算法,提供完整的用户端音乐发现体验与管理端后台。
目录
1. 项目概述
音乐推荐系统是一个面向普通用户与管理员的全功能音乐平台。用户可以浏览、搜索、播放歌曲,创建和管理个人歌单,收藏喜爱的歌单,查看播放历史,并根据个人行为获取个性化音乐推荐。管理员可在后台进行歌曲管理、用户管理、推荐系统状态监控等操作。
核心亮点:
- 三算法混合推荐:热度推荐、基于内容推荐、协同过滤三者按比例混合,兼顾流行性与个性化
- 行为驱动:用户的每一次播放、点赞、收藏、跳过均被记录并反映到推荐结果中
- 冷启动兼容:新用户无行为数据时自动退化为全热度推荐,保证体验连贯
- Guava 内存缓存:推荐结果缓存 30 分钟,最大支持 10,000 个用户,大幅降低重复计算开销
- 前后端分离:Vue 3 SPA 前端通过 Vite 代理对接 Spring Boot RESTful API,支持独立部署
2. 技术栈
后端
| 技术 | 版本 | 用途 |
|---|---|---|
| Java | 21 | 运行时环境 |
| Spring Boot | 4.0.5 | 核心框架 |
| Spring Security | 随 Boot | JWT 鉴权与接口保护 |
| Spring Boot Actuator | 随 Boot | 健康检查端点 |
| MyBatis-Plus | 3.5.8 | ORM,逻辑删除、分页、条件构造 |
| MySQL | 8.x | 关系型数据库 |
| JWT (jjwt) | 0.12.6 | Token 签发与验证 |
| Guava Cache | 33.0.0-jre | 推荐结果内存缓存 |
| Lombok | 随 Boot | 减少样板代码 |
| SpringDoc OpenAPI | 2.3.0 | Swagger UI 接口文档 |
| Spring Validation | 随 Boot | 参数校验 |
前端
| 技术 | 版本 | 用途 |
|---|---|---|
| Vue 3 | ^3.4.0 | UI 框架 |
| Vite | ^5.0.11 | 构建工具与开发服务器 |
| Vue Router | ^4.2.5 | 客户端路由 |
| Pinia | ^2.1.7 | 全局状态管理 |
| Axios | ^1.6.5 | HTTP 请求封装 |
| Element Plus | ^2.5.2 | UI 组件库 |
| Sass | ^1.70.0 | CSS 预处理 |
基础设施
| 工具 | 用途 |
|---|---|
| Docker / Docker Compose | 容器化部署 |
| Nginx | 前端静态资源托管与反向代理 |
| Maven | 后端构建管理 |
| npm | 前端包管理 |
3. 系统架构
┌─────────────────────────────────────────────────────┐
│ 浏览器 / 客户端 │
│ Vue 3 SPA(端口 3003) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐ │
│ │ 用户页面 │ │ 管理后台 │ │ 播放器 │ │ 搜索 │ │
│ └──────────┘ └──────────┘ └──────────┘ └─────────┘ │
│ Pinia 状态管理 │ Vue Router 路由 │
│ Axios HTTP 请求(/api, /search, /uploads) │
└───────────────────┬─────────────────────────────────┘
│ HTTP / JSON
▼ Vite Proxy / Nginx 反向代理
┌─────────────────────────────────────────────────────┐
│ Spring Boot 后端(端口 8080) │
│ ┌──────────────────────────────────────────────┐ │
│ │ Controller 层(REST API) │ │
│ │ Auth │ User │ Song │ Playlist │ Recommend │ │
│ │ Behavior │ Search │ Admin │ │
│ └──────────────────────┬───────────────────────┘ │
│ │ │
│ ┌──────────────────────▼───────────────────────┐ │
│ │ Service 层(业务逻辑) │ │
│ │ ┌─────────────────────────────────────────┐ │ │
│ │ │ 推荐引擎(algorithm/) │ │ │
│ │ │ HotRecommend │ ContentBased │ Collab │ │ │
│ │ │ RecommendCache(Guava,30min,10000u) │ │ │
│ │ └─────────────────────────────────────────┘ │ │
│ └──────────────────────┬───────────────────────┘ │
│ │ │
│ ┌──────────────────────▼───────────────────────┐ │
│ │ Mapper 层(MyBatis-Plus) │ │
│ └──────────────────────┬───────────────────────┘ │
│ │ │
│ ┌──────────────────────▼───────────────────────┐ │
│ │ Spring Security(JWT 过滤器链) │ │
│ └──────────────────────────────────────────────┘ │
└───────────────────┬─────────────────────────────────┘
│ JDBC
▼
┌─────────────────────────────────────────────────────┐
│ MySQL 数据库(music_recommend) │
│ user │ song │ playlist │ playlist_song │
│ user_behavior │ admin │ recommend_record │
│ song_comment │ user_playlist_collect │ search_history│
└─────────────────────────────────────────────────────┘
请求处理流程:
- 前端发起 HTTP 请求,携带
Authorization: Bearer <token>头 - Spring Security 的
JwtAuthenticationFilter拦截请求,解析并验证 JWT - 验证通过后进入对应 Controller,执行业务逻辑
- Service 层调用 Mapper 查询数据库,或调用推荐引擎计算结果(优先命中 Guava 缓存)
- 返回统一格式
Result<T>JSON 响应
4. 页面介绍
4.1 用户端页面
用户端采用深色系音乐风格 UI,左侧固定侧边导航,顶部搜索栏,底部常驻播放器控制条。
登录 / 注册页(/login、/register)
- 用户名 + 密码登录,支持跳转注册
- 注册仅需用户名和密码(邮箱、手机号可选)
- 默认测试账号:
xiaoa/123456
首页(/home)
- 热门歌曲:展示播放量最高的 Top 10 歌曲卡片,点击立即播放
- 个性化推荐入口:展示推荐歌曲预览及「查看更多」跳转
- 新歌速递:按上架时间倒序展示近期新增歌曲
- 推荐歌单:展示平台热门公开歌单
音乐推荐页(/recommend)
- 顶部 Tab 切换:个性化推荐 、每日推荐 、私人 FM 、热门榜单 、按曲风
- 个性化推荐:根据用户历史行为(播放/点赞/收藏)混合三种算法计算,登录后可用
- 每日推荐:以当天日期为种子生成固定列表,同一天内刷新结果不变
- 私人 FM:随机排列的个性化推荐列表,适合连续播放发现新歌
- 热门榜单:全站播放量 Top 排行,无需登录可访问
- 按曲风:选择流行、民谣、摇滚、电子等类型筛选对应风格歌曲
搜索页(/search)
- 顶部输入框实时联想,显示搜索建议下拉列表
- 搜索结果分 歌曲 、艺人 、专辑 、歌单 四个 Tab
- 支持歌曲直接播放,支持将搜索结果歌曲添加至歌单
- 侧边展示热门搜索关键词和历史搜索记录
歌曲详情页(/song/:id)
- 展示封面、标题、歌手、专辑、时长等元数据
- 操作按钮:播放、点赞 / 取消点赞、添加到歌单
- 相似歌曲推荐列表(同曲风/同艺人)
- 用户评论区域:分页展示评论,登录后可发表评论
我的歌单页(/my-playlists)
- 展示当前用户创建的所有歌单和已收藏的公开歌单
- 点击新建歌单:填写名称、描述,选择公开/私密
- 歌单卡片支持点击进入详情,长按或右键显示删除选项
歌单详情页(/playlist/:id)
- 展示歌单封面、名称、描述、创建者、歌曲数量
- 歌曲列表支持逐首播放或全部播放
- 歌单所有者可对歌曲执行移除操作
- 他人公开歌单支持一键收藏
个人中心页(/profile)
- 基本信息:修改昵称、邮箱、手机号、性别
- 头像设置:点击头像上传新图片
- 修改密码:需输入当前密码进行验证
- 我的点赞:分页展示用户点赞过的全部歌曲
- 用户统计:播放总数、点赞数、歌单数量一览
播放历史页(/history)
- 按时间倒序展示用户所有播放记录
- 支持单条删除和一键清空全部历史
底部播放器(全局组件 Footer.vue)
- 常驻所有用户端页面底部
- 显示当前播放歌曲封面、名称、歌手
- 控制按钮:上一首、播放/暂停、下一首
- 进度条:可拖拽跳转播放位置,展示已播放时长 / 总时长
- 音量滑块控制
- 播放模式切换:顺序播放、随机播放、单曲循环
- 播放队列按钮:弹出当前播放列表,可点击切换歌曲
4.2 管理后台页面
管理后台路由前缀为 /admin,采用左侧折叠菜单 + 顶部面包屑布局,仅 ADMIN 角色账号可访问。
管理员登录页(/admin/login)
- 独立的管理员认证入口,与用户端完全隔离
- 默认账号:
admin/123456 - 登录成功后跳转至数据看板
数据看板(/admin/dashboard)
展示系统全局实时统计数据:
| 指标 | 说明 |
|---|---|
| 用户总数 | 注册用户总量 |
| 歌曲总数 | 平台歌曲库数量 |
| 今日播放量 | 当天用户播放行为计数 |
| 总播放量 | 累计历史播放次数 |
| 推荐点击率 | 被推荐歌曲的点击比例(%) |
用户管理页(/admin/users)
- 分页展示所有注册用户,字段:用户名、昵称、邮箱、手机号、注册时间、状态
- 顶部搜索框支持按用户名 / 昵称 / 邮箱 / 手机号模糊搜索
- 操作列:
- 禁用:将用户状态置为禁用,该账号无法再登录
- 启用:恢复已禁用用户的登录权限
歌曲管理页(/admin/songs)
- 分页展示全量歌曲库,字段:封面缩略图、歌曲名、歌手、专辑、曲风、时长、播放量、点赞数、创建时间
- 搜索框支持按歌名 / 歌手关键词筛选
- 添加歌曲 (弹窗):
- 填写歌曲名称(必填)、歌手(必填)、专辑、音乐类型、时长
- 上传封面图片(JPG/PNG,最大 5MB)
- 上传音频文件(MP3/WAV/FLAC/M4A,最大 20MB)
- 提交后文件存至服务器,元数据入库,列表自动刷新
- 编辑歌曲(弹窗):可修改名称、歌手、专辑、类型、时长,不重新上传文件
- 删除歌曲:逻辑删除,歌曲从前端不可见,数据库记录保留
推荐管理页(/admin/recommend)
- 展示当前 Guava 推荐缓存状态:缓存条目数、命中率等
- 重新训练按钮:清空全部用户推荐缓存,下次请求时重新计算
行为日志页(/admin/logs)
- 展示用户行为流水记录:用户 ID、歌曲 ID、行为类型(播放/点赞/跳过/收藏)、行为时间
- 支持按用户 ID 和行为类型过滤
5. 数据库设计
数据库名:music_recommend,字符集:utf8mb4,全表使用 MyBatis-Plus 逻辑删除(deleted 字段)。
4.1 用户表(user)
存储系统注册用户的基本信息。
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BIGINT PK AUTO | 用户 ID |
| username | VARCHAR(50) UNIQUE | 用户名,登录凭证 |
| password | VARCHAR(255) | BCrypt 加密密码 |
| nickname | VARCHAR(50) | 昵称 |
| avatar | VARCHAR(255) | 头像 URL |
| VARCHAR(100) | 邮箱 | |
| phone | VARCHAR(20) | 手机号 |
| gender | TINYINT | 性别:0-女,1-男,2-未知 |
| status | TINYINT | 状态:0-禁用,1-正常 |
| deleted | TINYINT | 逻辑删除标志 |
| create_time / update_time | DATETIME | 时间戳 |
4.2 歌曲表(song)
平台全量歌曲库,是推荐算法的核心数据来源。
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BIGINT PK AUTO | 歌曲 ID |
| title | VARCHAR(100) | 歌曲名称 |
| artist | VARCHAR(100) | 歌手 |
| album | VARCHAR(100) | 专辑 |
| duration | INT | 时长(秒) |
| cover_url | VARCHAR(255) | 封面图片 URL |
| audio_url | VARCHAR(255) NOT NULL | 音频文件 URL |
| genre | VARCHAR(50) | 音乐类型(流行/民谣/摇滚等) |
| play_count | BIGINT DEFAULT 0 | 播放次数,热度算法核心字段 |
| like_count | BIGINT DEFAULT 0 | 点赞数,热度算法核心字段 |
| deleted | TINYINT | 逻辑删除标志 |
热度评分公式:
score = play_count × 0.7 + like_count × 0.3
4.3 歌单表(playlist)
用户创建的歌曲合集,支持公开与私密两种权限。
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BIGINT PK AUTO | 歌单 ID |
| name | VARCHAR(100) | 歌单名称 |
| description | VARCHAR(500) | 描述 |
| cover_url | VARCHAR(255) | 封面 URL |
| user_id | BIGINT | 创建者用户 ID |
| play_count | BIGINT | 播放次数 |
| is_public | TINYINT | 0-私有,1-公开 |
4.4 歌单歌曲关联表(playlist_song)
多对多关联歌单与歌曲,支持逻辑删除实现移除操作。
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BIGINT PK AUTO | 主键 |
| playlist_id | BIGINT | 歌单 ID |
| song_id | BIGINT | 歌曲 ID |
| deleted | TINYINT | 逻辑删除标志 |
4.5 用户行为表(user_behavior)
记录用户与歌曲的每次交互,是个性化推荐的核心数据来源。
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BIGINT PK AUTO | 主键 |
| user_id | BIGINT | 用户 ID |
| song_id | BIGINT | 歌曲 ID |
| behavior_type | INT | 1-播放,2-点赞,3-收藏,5-跳过 |
| behavior_time | DATETIME | 行为发生时间 |
| play_duration | INT | 播放时长(秒),仅播放行为有值 |
4.6 管理员表(admin)
管理员账户独立存储,与普通用户隔离。
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BIGINT PK AUTO | 主键 |
| username | VARCHAR(50) UNIQUE | 管理员账号 |
| password | VARCHAR(255) | BCrypt 加密密码 |
| nickname | VARCHAR(50) | 昵称 |
| role | VARCHAR(20) | 角色:ADMIN / SUPER_ADMIN |
4.7 推荐记录表(recommend_record)
记录系统向用户推送的每一条推荐结果,可用于后续效果分析。
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BIGINT PK AUTO | 主键 |
| user_id | BIGINT | 用户 ID |
| song_id | BIGINT | 推荐歌曲 ID |
| recommend_time | DATETIME | 推荐时间 |
| is_clicked | TINYINT | 是否点击:0-未点击,1-已点击 |
| recommend_type | VARCHAR(20) | 推荐类型:HOT / CONTENT_BASED / COLLABORATIVE / HYBRID |
4.8 歌曲评论表(song_comment)
用户对歌曲的文字评论。
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BIGINT PK AUTO | 主键 |
| user_id | BIGINT | 评论用户 ID |
| song_id | BIGINT | 被评论歌曲 ID |
| content | VARCHAR(500) | 评论内容 |
4.9 用户收藏歌单表(user_playlist_collect)
记录用户收藏的他人公开歌单,使用联合唯一键防止重复收藏。
4.10 搜索历史表(search_history)
记录用户的搜索关键词历史,支持热门关键词统计。
6. 推荐算法
推荐引擎位于 algorithm/ 包下,由三种独立算法组成,最终在 RecommendServiceImpl 中按比例混合。
6.1 热度推荐(HotRecommendAlgorithm)
最简洁且效果稳定的推荐策略,无需用户数据,适合新用户冷启动和全局榜单。
评分公式:
热度得分 = play_count × 0.7 + like_count × 0.3
播放量权重高于点赞数,因为播放是更高频、更真实的用户行为。系统直接通过 SQL 按得分降序取 Top N 返回。
6.2 基于内容推荐(ContentBasedAlgorithm)
根据用户历史行为分析其音乐偏好,推荐偏好类型下的高热度歌曲。
行为权重定义:
| 行为类型 | 权重 | 含义 |
|---|---|---|
| PLAY(播放) | 1.0 | 基础兴趣信号 |
| LIKE(点赞) | 2.0 | 强烈喜好信号 |
| ADD_TO_PLAYLIST(收藏) | 1.5 | 中等喜好信号 |
算法流程:
- 查询用户所有历史行为记录
- 关联歌曲获取每首歌的
genre - 按行为权重累计每个
genre的偏好得分,得到genreWeights排名 - 按偏好
genre从高到低,依次从歌曲库中取按热度排序的歌曲 - 过滤掉用户已经听过的歌曲,直到凑满目标数量
6.3 协同过滤推荐(CollaborativeFilteringAlgorithm)
基于"物品相似度"的简化协同过滤,挖掘与用户喜爱歌曲属性相近的其他歌曲。
相似度权重定义:
| 相似维度 | 权重 |
|---|---|
| 相同 genre(曲风) | 0.6 |
| 相同 artist(艺人) | 0.4 |
算法流程:
- 获取用户点赞和收藏的歌曲集合(作为"种子歌曲")
- 对每首种子歌曲,查找同 genre 或同 artist 的候选歌曲
- 候选歌曲累加相似度得分(多首种子歌曲共同指向则得分更高)
- 排除用户已听歌曲,按累积得分降序返回 Top N
6.4 混合推荐策略(RecommendServiceImpl)
三种算法按固定比例混合,取各自结果合并去重后随机打乱,保证推荐多样性。
总推荐数量 N = 热度推荐(50%)+ 基于内容(25%)+ 协同过滤(25%)
完整推荐流程:
请求进入
│
▼ 命中 Guava 缓存(30min TTL)?
是 ──► 直接返回缓存结果
│
否
▼
calculateRecommendations(userId, limit)
├── HotRecommend.recommend(limit/2)
├── ContentBased.recommend(userId, limit/4)
└── Collaborative.recommend(userId, limit/4)
│
▼ mergeAndShuffle(去重合并,随机打乱)
│
▼ 数量不足?用热门补充
│
▼ 结果存入 RecommendCache
│
▼ 异步写入 recommend_record(推荐日志)
│
▼ 返回推荐列表
冷启动处理: 若基于内容和协同过滤均返回空(用户无行为记录),则自动退化为全量热度推荐,确保新用户首次使用体验。
6.5 特殊推荐模式
| 模式 | 说明 |
|---|---|
| 私人 FM | 取个性化推荐结果后随机打乱,每次调用顺序不同 |
| 每日推荐 | 以 当天日期 + userId 为随机种子对热歌 Shuffle,同一天结果稳定,不同天结果不同 |
| 新歌推荐 | 按 create_time 倒序从歌曲库取最新入库歌曲 |
| 曲风推荐 | 指定 genre,按热度排序返回该类型歌曲 |
6.6 推荐缓存
使用 Guava Cache 实现推荐结果的内存缓存:
- 缓存容量:最大 10,000 个用户的推荐结果
- 过期策略:写入后 30 分钟自动失效
- Key 格式 :
"recommend:" + userId - 失效触发 :用户发生行为(
@CacheEvict)、手动清除、管理员触发全量刷新
7. 后端模块详解
后端采用标准的 Spring Boot 分层架构,包结构如下:
com.xiaoa.yingletuijian
├── algorithm/ 推荐算法(热度/内容/协同过滤/缓存)
├── common/ 统一响应 Result<T>、异常 BusinessException
├── config/ Spring 配置(Security、MyBatis-Plus、文件上传)
├── controller/ REST 控制器
├── dto/ 请求数据传输对象
├── entity/ 数据库实体类
├── enums/ 枚举(BehaviorType、RecommendType)
├── mapper/ MyBatis-Plus Mapper 接口(含 @Select/@Update 注解 SQL)
├── security/ JwtAuthenticationFilter
├── service/ 业务接口
│ └── impl/ 业务实现
├── utils/ 工具类(JwtUtil、UserContext)
└── vo/ 响应视图对象
7.1 统一响应格式
所有接口返回 Result<T> 包装类:
json
{
"code": 200,
"message": "success",
"data": { ... },
"total": 100,
"pages": 5
}
错误时 code 为非 200 值,message 携带错误描述。
7.2 逻辑删除
所有业务表均包含 deleted 字段,由 MyBatis-Plus 全局配置自动处理:
- 删除操作执行
UPDATE ... SET deleted = 1,而非物理DELETE - 查询时自动追加
AND deleted = 0条件
7.3 行为记录与缓存失效
UserBehaviorService 中所有记录行为的方法均标注 @CacheEvict(value = "recommend", key = "#userId"),确保用户产生新行为后下次请求会重新计算推荐结果,而不是返回已过期的缓存。
8. 前端模块详解
前端基于 Vue 3 Composition API,目录结构如下:
frontend/src
├── api/ 后端接口封装(按业务域拆分)
│ ├── auth.js 注册/登录/刷新 Token
│ ├── song.js 歌曲查询、播放、点赞、评论
│ ├── playlist.js 歌单增删改查、收藏
│ ├── recommend.js 各类推荐接口
│ ├── behavior.js 行为记录、播放历史
│ ├── search.js 综合搜索、搜索建议、热词
│ ├── user.js 用户信息、头像、密码
│ └── admin.js 管理端接口
├── components/ 可复用 UI 组件
│ ├── Header.vue 顶部导航栏(含搜索框)
│ ├── Sidebar.vue 侧边导航
│ ├── Footer.vue 底部播放器控制栏
│ ├── SongCard.vue 歌曲卡片(封面/标题/艺人/操作)
│ ├── PlaylistCard.vue 歌单卡片
│ ├── SongList.vue 歌曲列表(支持批量操作)
│ ├── SearchSuggest.vue 搜索建议下拉框
│ ├── PlaylistDialog.vue 添加到歌单弹窗
│ ├── CreatePlaylistDialog.vue 新建歌单弹窗
│ ├── Loading.vue 加载状态占位
│ └── Empty.vue 空数据占位
├── views/
│ ├── user/
│ │ ├── Login.vue 用户登录页
│ │ ├── Register.vue 用户注册页
│ │ ├── Home.vue 首页(热门歌曲 + 推荐入口)
│ │ ├── Recommend.vue 个性化推荐页
│ │ ├── SongDetail.vue 歌曲详情页(歌词/评论/相似推荐)
│ │ ├── Search.vue 搜索结果页
│ │ ├── MyPlaylists.vue 我的歌单页
│ │ ├── PlaylistDetail.vue 歌单详情页
│ │ ├── Profile.vue 个人中心(信息/头像/密码)
│ │ └── History.vue 播放历史页
│ └── admin/
│ ├── AdminLogin.vue 管理员登录
│ ├── AdminLayout.vue 管理后台布局
│ ├── Dashboard.vue 数据统计看板
│ ├── UserManagement.vue 用户列表(启用/禁用)
│ └── SongManagement.vue 歌曲管理(新增/编辑/删除)
├── store/
│ ├── user.js 当前登录用户信息、Token
│ ├── player.js 播放器状态(当前歌曲/播放列表/进度)
│ └── playlist.js 歌单数据缓存
├── router/
│ └── index.js 路由表(路由守卫:未登录跳转 /login,管理员路由前缀 /admin)
└── utils/
├── request.js Axios 实例(请求拦截自动注入 Token,响应拦截处理 401)
├── storage.js localStorage Token 存取封装
└── format.js 时间/时长格式化工具函数
8.1 状态管理
user.js(Pinia):存储当前用户信息和 Token,登录后持久化到 localStorageplayer.js(Pinia):管理播放器核心状态------当前播放歌曲、播放列表队列、播放进度、音量、播放模式(顺序/随机/单曲循环)playlist.js(Pinia):缓存用户歌单列表,减少重复请求
8.2 路由守卫
router/index.js 中配置全局前置守卫:
- 访问需要登录的页面时,检测
user.store中的 Token;未登录则重定向到/login - 访问
/admin/**路径时,额外校验用户角色是否为管理员
8.3 请求拦截器
utils/request.js 基于 Axios 封装:
- 请求拦截 :自动在 Header 中注入
Authorization: Bearer <token> - 响应拦截:捕获 401 状态码,清除本地 Token 并跳转登录页;统一处理网络错误提示
9. API 接口总览
9.1 认证接口(/api/auth)
| 方法 | 路径 | 说明 | 是否需要登录 |
|---|---|---|---|
| POST | /api/auth/register | 用户注册 | 否 |
| POST | /api/auth/login | 用户登录,返回 token + 用户信息 | 否 |
| POST | /api/auth/logout | 退出登录 | 否 |
| POST | /api/auth/refresh | 刷新 Token | 是 |
| GET | /api/auth/validate | 验证 Token 有效性 | 是 |
9.2 用户接口(/api/user)
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/user/info | 获取当前用户信息 |
| GET | /api/user/{id} | 根据 ID 获取用户信息 |
| PUT | /api/user/info | 更新用户信息(昵称/邮箱/手机/性别) |
| POST | /api/user/avatar | 上传头像(字段名:avatar) |
| PUT | /api/user/password | 修改密码(字段:old_password/new_password) |
| GET | /api/user/likes | 获取点赞歌曲列表(分页) |
| GET | /api/user/stats | 获取用户统计(播放数/点赞数/歌单数) |
9.3 歌曲接口(/api/songs)
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/songs | 分页查询歌曲列表(支持 keyword/genre/sort) |
| GET | /api/songs/hot | 获取热门歌曲 Top N |
| GET | /api/songs/search | 关键词搜索歌曲 |
| GET | /api/songs/{id} | 获取歌曲详情 |
| GET | /api/songs/{id}/play | 播放歌曲(增加播放次数) |
| POST | /api/songs/{id}/like | 点赞歌曲 |
| DELETE | /api/songs/{id}/like | 取消点赞 |
| GET | /api/songs/{id}/similar | 获取相似歌曲 |
| GET | /api/songs/{id}/comments | 分页获取评论 |
| POST | /api/songs/{id}/comments | 发表评论 |
9.4 歌单接口(/api/playlists)
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /api/playlists | 创建歌单 |
| GET | /api/playlists/my | 获取我的歌单列表 |
| GET | /api/playlists/public | 获取公开歌单(分页) |
| GET | /api/playlists/{id} | 获取歌单详情(含歌曲列表) |
| PUT | /api/playlists/{id} | 更新歌单信息 |
| DELETE | /api/playlists/{id} | 删除歌单 |
| POST | /api/playlists/{id}/songs | 批量添加歌曲(body: {song_ids:[...]} ) |
| DELETE | /api/playlists/{id}/songs/{songId} | 从歌单移除歌曲 |
| POST | /api/playlists/{id}/collect | 收藏歌单 |
| DELETE | /api/playlists/{id}/collect | 取消收藏 |
9.5 推荐接口(/api/recommend)
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/recommend/personal | 个性化混合推荐(需登录) |
| GET | /api/recommend/hot | 热门推荐 |
| GET | /api/recommend/fm | 私人 FM |
| GET | /api/recommend/new | 最新上架歌曲 |
| GET | /api/recommend/genre | 按曲风推荐(参数:genre) |
| GET | /api/recommend/daily | 每日推荐(日期确定性推荐) |
| GET | /api/recommend/playlists | 推荐公开歌单 |
| DELETE | /api/recommend/cache | 清除当前用户推荐缓存 |
9.6 行为记录接口(/api/behavior)
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /api/behavior/play | 记录播放行为 |
| POST | /api/behavior/like | 记录点赞行为 |
| POST | /api/behavior/skip | 记录跳过行为 |
| GET | /api/behavior/history | 获取播放历史(分页) |
| DELETE | /api/behavior/history | 清除全部播放历史 |
| DELETE | /api/behavior/history/{id} | 删除单条历史记录 |
| GET | /api/behavior/preferences | 获取用户偏好统计 |
| GET | /api/behavior/search/history | 获取搜索历史 |
| DELETE | /api/behavior/search/history | 清除搜索历史 |
9.7 搜索接口(/search)
前端通过 Vite proxy 将
/search转发到后端,不含/api前缀。
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /search/suggest | 搜索建议(实时联想) |
| GET | /search | 综合搜索(歌曲/艺人/专辑/歌单) |
| GET | /search/songs | 仅搜索歌曲 |
| GET | /search/artists | 搜索艺人 |
| GET | /search/albums | 搜索专辑 |
| GET | /search/playlists | 搜索公开歌单 |
| GET | /search/hot | 热门搜索关键词 |
| GET | /search/history | 获取搜索历史(需登录) |
| DELETE | /search/history | 删除搜索历史 |
9.8 管理端接口(/api/admin,需 ADMIN 角色)
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /api/admin/login | 管理员登录(独立认证) |
| GET | /api/admin/info | 获取当前管理员信息 |
| GET | /api/admin/users | 用户列表(分页+关键词搜索) |
| POST | /api/admin/users/{id}/disable | 禁用用户 |
| POST | /api/admin/users/{id}/enable | 启用用户 |
| GET | /api/admin/songs | 歌曲列表(管理视图) |
| POST | /api/admin/songs | 新增歌曲 |
| PUT | /api/admin/songs/{id} | 编辑歌曲 |
| DELETE | /api/admin/songs/{id} | 删除歌曲 |
| GET | /api/admin/statistics | 数据统计概览 |
| GET | /api/admin/logs/behavior | 用户行为日志(分页,支持过滤) |
| GET | /api/admin/recommend/status | 推荐缓存状态 |
| POST | /api/admin/recommend/train | 触发全量推荐缓存刷新 |
9.9 健康检查
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /actuator/health | Spring Boot Actuator 健康检查(无需登录) |
返回示例:
json
{
"status": "UP",
"components": {
"db": { "status": "UP" },
"diskSpace": { "status": "UP" }
}
}
10. 安全与认证
10.1 用户认证流程
登录请求(POST /api/auth/login)
│
▼ UserService.login()
├── 查询用户(findByUsername)
├── 校验账号状态(status = 1)
├── 验证密码(BCryptPasswordEncoder.matches)
└── 签发 JWT(JwtUtil.generateToken,有效期 7 天)
│
▼ 返回 { token, userInfo }
10.2 JWT 过滤器
JwtAuthenticationFilter 在每次请求的 Spring Security 过滤器链中执行:
- 提取
Authorization: Bearer <token>头 - 调用
JwtUtil.validateToken验证签名与有效期 - 解析
username和role,构建UsernamePasswordAuthenticationToken - 写入
SecurityContextHolder,后续业务代码通过UserContext.getCurrentUserId()获取当前用户 ID
10.3 接口权限配置
| 接口范围 | 权限要求 |
|---|---|
/api/auth/**、/api/songs/list、/api/songs/hot、/api/songs/{id}、/api/songs/search |
公开访问(无需登录) |
/uploads/** |
公开访问(静态资源) |
/actuator/health |
公开访问(健康检查) |
/api/admin/** |
需要 ROLE_ADMIN 角色 |
| 其余所有接口 | 需要有效 JWT Token(已登录用户) |
10.4 密码安全
用户密码使用 BCryptPasswordEncoder 存储,每次注册和修改密码时加盐哈希,数据库中不存储明文密码。
11. 部署与运行
11.1 环境要求
- JDK 21+
- Node.js 18+
- MySQL 8.0+
- Maven 3.8+
11.2 本地开发
第一步:初始化数据库
bash
mysql -u root -p < docs/init_database.sql
初始化完成后,数据库 music_recommend 中包含完整的表结构和以下初始数据:
- 管理员账号:
admin/123456 - 测试用户账号:
xiaoa/123456 - 15 首测试歌曲
第二步:启动后端
bash
# 修改 application.yaml 中的数据库密码(如有需要)
mvn spring-boot:run
后端服务启动于 http://localhost:8080。
第三步:启动前端
bash
cd frontend
npm install
npm run dev
前端开发服务器启动于 http://localhost:3003,API 请求通过 Vite proxy 转发到 http://localhost:8080。
第四步:访问
| 地址 | 说明 |
|---|---|
| http://localhost:3003 | 用户前端 |
| http://localhost:3003/admin/login | 管理后台登录 |
| http://localhost:8080/swagger-ui.html | Swagger API 文档 |
| http://localhost:8080/actuator/health | 健康检查 |
11.3 生产构建
bash
# 前端构建
cd frontend && npm run build
# 后端打包(跳过测试)
mvn clean package -DskipTests
11.4 Docker 部署
项目提供完整的 Docker Compose 配置,支持一键启动前后端服务:
bash
# 构建并启动所有服务
docker-compose up -d
环境变量配置(docker-compose.yml):
| 环境变量 | 默认值 | 说明 |
|---|---|---|
| SPRING_DATASOURCE_URL | jdbc:mysql://localhost:3306/music_recommend?.. | 数据库连接地址 |
| SPRING_DATASOURCE_USERNAME | root | 数据库用户名 |
| SPRING_DATASOURCE_PASSWORD | 123456 | 数据库密码 |
| FILE_UPLOAD_PATH | /uploads/music/ | 文件上传目录(容器内路径) |
11.5 关键配置说明
src/main/resources/application.yaml
| 配置项 | 值 | 说明 |
|---|---|---|
| server.port | 8080 | 后端端口 |
| spring.datasource.url | jdbc:mysql://localhost:3306/music_recommend | 数据库地址 |
| jwt.secret | music-recommend-secret-key-... | JWT 签名密钥(生产环境请替换) |
| jwt.expiration | 604800000 | Token 有效期(7 天,毫秒) |
| file.upload-path | D:/uploads/music/ | 文件本地存储路径(Linux 部署时需改) |
12. 使用指南
12.1 用户注册与登录
注册新账号
访问 http://localhost:3003/register(或部署地址对应路径),填写用户名、密码即可完成注册。注册成功后自动跳转到首页。

用户登录
- 访问
http://localhost:3003/login - 输入注册时填写的用户名和密码
- 登录成功后跳转到首页,顶部导航栏显示当前用户昵称

登录成功后 JWT Token 会保存到浏览器 localStorage,有效期 7 天,期间刷新页面无需重新登录。
管理员登录
管理后台入口与用户端独立,使用不同的账号体系:
- 访问
http://localhost:3003/admin/login(部署后对应/admin/login路径) - 输入管理员账号和密码
- 默认内置账号:用户名
admin,密码123456(由数据库初始化脚本写入) - 登录成功后跳转到管理后台数据看板

安全提示: 生产环境请及时修改默认管理员密码。管理员账号独立存储于
admin表,与普通用户账号完全隔离,不能通过用户端登录入口访问后台。
12.2 用户端功能使用
登录后可使用以下核心功能:
浏览与播放
- 首页展示热门歌曲和个性化推荐入口,点击歌曲卡片即可播放
- 底部播放器栏支持上一首/下一首/暂停/音量调节/播放模式切换(顺序、随机、单曲循环)
- 点击歌曲标题进入歌曲详情页,可查看相似歌曲和用户评论

搜索
- 顶部搜索框输入关键词,支持按歌曲名、歌手名搜索
- 输入过程中实时显示搜索建议下拉列表
- 搜索结果支持按歌曲、艺人、专辑、歌单分类筛选
歌单管理
-
点击"我的歌单"创建个人歌单,支持设置名称、描述、公开/私密
-
播放任意歌曲时,点击"添加到歌单"可将歌曲加入已有歌单
-
可收藏他人的公开歌单

个人中心 -
修改昵称、邮箱、手机号、性别等基本信息
-
上传自定义头像
-
修改登录密码(需输入原密码验证)
-
查看点赞的歌曲列表、播放历史记录

12.3 管理后台使用
管理员登录后台后,左侧导航栏包含以下功能模块:
数据看板(Dashboard)
首页展示系统概况统计数据:用户总数、歌曲总数、今日播放量、总播放量、推荐点击率。

用户管理
- 分页浏览所有注册用户列表,支持按用户名/昵称/邮箱关键词搜索
- 对指定用户执行禁用操作:被禁用用户登录时提示账号异常,无法进入系统
- 对已禁用用户执行启用 操作,恢复其登录权限

歌曲管理
- 分页浏览全量歌曲库,支持按歌名/歌手搜索
- 点击添加歌曲 打开上传对话框:
- 填写歌曲名称(必填)、歌手(必填)、专辑、音乐类型、时长(秒)
- 点击"选择封面图片"上传 JPG/PNG 封面,建议尺寸 500×500,最大 5MB
- 点击"选择音频文件"上传 MP3/WAV/FLAC 等格式音频,最大 20MB
- 点击添加 按钮,文件上传至服务器
uploads/目录,元数据写入数据库
- 点击歌曲行中的编辑按钮,可修改歌曲名称、歌手、专辑、类型、时长(编辑模式不重新上传文件)
- 点击删除执行逻辑删除,歌曲从前端不可见但数据库保留记录
文件存储说明: 上传的封面保存在
<upload-path>/covers/,音频保存在<upload-path>/audios/,文件名以 UUID 重命名防止冲突。本地开发默认路径为D:/uploads/music/,Docker 部署时挂载至/uploads/music/。
推荐管理
- 查看当前 Guava 缓存命中率、缓存条目数等状态信息
- 点击重新训练清空全部推荐缓存,用户下次请求时重新计算个性化推荐
13. 项目结构
yingletuijian/
├── docs/
│ ├── init_database.sql 数据库初始化脚本(10 张表 + 初始数据)
│ └── 项目介绍.md 本文档
├── frontend/ Vue 3 前端
│ ├── src/
│ │ ├── api/ 后端接口封装(8 个模块)
│ │ ├── components/ 公共 UI 组件(11 个)
│ │ ├── views/ 页面组件
│ │ │ ├── user/ 用户端页面(10 个)
│ │ │ └── admin/ 管理端页面(5 个)
│ │ ├── store/ Pinia 状态管理(3 个 store)
│ │ ├── router/ Vue Router 路由配置
│ │ └── utils/ 工具函数(请求/存储/格式化)
│ ├── vite.config.js Vite 配置(开发代理:/api, /search, /uploads)
│ └── package.json
├── src/main/java/com/xiaoa/yingletuijian/
│ ├── algorithm/ 推荐算法
│ │ ├── HotRecommendAlgorithm.java
│ │ ├── ContentBasedAlgorithm.java
│ │ ├── CollaborativeFilteringAlgorithm.java
│ │ └── cache/RecommendCache.java
│ ├── common/ Result<T>、BusinessException
│ ├── config/ SecurityConfig、MyBatis-Plus 配置
│ ├── controller/ REST 控制器(8 个)
│ ├── dto/ 请求 DTO(登录/注册/歌曲/行为)
│ ├── entity/ 数据库实体(10 个)
│ ├── enums/ BehaviorType、RecommendType
│ ├── mapper/ MyBatis-Plus Mapper(10 个)
│ ├── security/ JwtAuthenticationFilter
│ ├── service/ 业务接口 + 实现(6 个 service)
│ ├── utils/ JwtUtil、UserContext
│ └── vo/ 响应 VO(用户/歌曲/歌单/行为/统计)
├── src/main/resources/
│ ├── application.yaml 主配置文件
│ └── mapper/ MyBatis XML(如有)
├── Dockerfile 后端镜像构建文件
├── docker-compose.yml 多服务编排(后端 + 前端 Nginx)
└── pom.xml Maven 依赖管理
