diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..c03bb81 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,25 @@ +# 文档目录说明 + +本目录用于统一管理项目总方案文档与各阶段开发落地文档,避免所有内容持续堆积在单一总文档中。 + +## 文档组织规则 + +- 总方案文档:记录项目背景、总体需求、架构设计、统一规则、里程碑规划 +- 阶段落地文档:记录某一阶段的实现内容、关键文件、测试策略、验收结果、偏差说明 + +## 当前文档索引 + +### 1. 总方案文档 + +- `docs/总方案/音乐元数据标准化与归档系统 需求梳理 + 架构技术方案.md` + +### 2. 阶段落地文档 + +- `docs/P0-基础架构-开发落地说明.md` +- `docs/P1-元数据解析与校验-开发落地说明.md` + +## 后续约定 + +- 后续 P2、P3、P4 等阶段继续沿用当前命名方式新增阶段文档 +- 若总方案文档发生结构性更新,优先同步仓库内 `docs/总方案/` 版本 +- 若阶段验收、测试结果、实现清单发生变化,应更新对应阶段文档,而不是直接堆入总方案文档 diff --git a/docs/总方案/音乐元数据标准化与归档系统 需求梳理 + 架构技术方案.md b/docs/总方案/音乐元数据标准化与归档系统 需求梳理 + 架构技术方案.md new file mode 100644 index 0000000..f12a9e6 --- /dev/null +++ b/docs/总方案/音乐元数据标准化与归档系统 需求梳理 + 架构技术方案.md @@ -0,0 +1,587 @@ +# 音乐元数据标准化与归档系统 需求梳理+架构技术方案 +**文档版本**:V1.0 +**修订日期**:2026年03月15日 +**文档状态**:正式版 +**技术约束**:后端Java + GraalVM原生编译、前端Vue技术栈 +**核心适配**:Navidrome音乐服务器官方最佳实践 + +--- + +## 一、文档概述 +### 1.1 文档目的 +本文档完整梳理「音乐元数据标准化与归档系统」的业务需求、架构设计、核心规则、技术实现与落地路径,为系统开发、测试、部署提供全流程指导,确保系统最终实现**元数据零错误识别、目录结构100%适配Navidrome、全流程自动化+人工兜底可控**的核心目标。 + +### 1.2 适用范围 +- 业务范围:个人/家庭级音乐库元数据标准化、自动归档、全生命周期管理 +- 技术范围:后端Java服务开发、GraalVM原生编译适配、Vue前端可视化界面开发、Navidrome音乐库适配 +- 读者对象:开发人员、测试人员、系统运维人员、最终用户 + +### 1.3 术语定义 +| 术语 | 全称 | 说明 | +|------|------|------| +| 元数据 | Music Metadata | 音乐文件内嵌的标签信息,包括歌曲标题、歌手、专辑、封面、曲目编号等核心信息 | +| 音频指纹 | Acoustic Fingerprint | 基于音频内容生成的唯一特征码,不受元数据、格式、比特率影响,用于精准识别歌曲 | +| 归档 | Archiving | 按规范规则重命名文件、生成标准化目录结构,将音乐文件整理到目标音乐库的过程 | +| 增量入库 | Incremental Storage | 仅处理新增的音乐文件,跳过已处理完成的文件,避免重复归档 | +| 原生镜像 | Native Image | 基于GraalVM将Java程序编译为平台相关的可执行文件,实现极速启动、低内存占用 | + +--- + +## 二、项目背景与目标 +### 2.1 项目背景 +个人/家庭音乐库的文件来源多样(CD抓取、网络下载、音频转录等),普遍存在以下核心痛点: +1. 元数据不规范:字段缺失、乱码、格式不统一,导致Navidrome等流媒体服务器无法正确识别歌手、专辑、封面、歌词等信息 +2. 目录结构混乱:无统一归档规则,文件存放分散,Navidrome扫描后出现歌手分裂、专辑错乱、曲目排序错误等问题 +3. 重复文件冗余:同一首歌存在多个版本,占用存储空间,音乐库管理混乱 +4. 无标准化管理能力:缺失元数据的文件无统一兜底处理流程,最终成为音乐库中的“无效文件” + +### 2.2 核心目标 +1. **标准化适配**:建立严格的元数据校验规则,确保处理后的音乐文件100%被Navidrome及主流播放器完整识别 +2. **自动化归档**:按预设规则自动完成音乐文件的目录整理、重命名、元数据写入,无需人工干预合规文件 +3. **全流程可控**:对不符合规范的文件进行精准标记、全链路记录,通过可视化界面实现人工补全兜底 +4. **增量高效处理**:支持重复调用,仅处理新增文件,内置多级去重能力,避免重复入库 +5. **高性能轻量化**:基于GraalVM实现原生编译,实现毫秒级启动、低内存占用,适配家庭级单机部署场景 + +### 2.3 次要目标 +1. 支持多格式音频文件的元数据读写,覆盖主流无损/有损音频格式 +2. 提供可视化的处理进度监控、处理报告、数据统计能力 +3. 不修改、不删除用户原始源文件,保障源文件安全 +4. 提供可配置的规则扩展能力,适配不同播放器的元数据规范 + +--- + +## 三、需求详细梳理 +### 3.1 功能性需求 +#### 3.1.1 音乐源接入模块 +支持两种核心输入方式,覆盖批量处理与单文件快速处理场景: +1. **本地目录批量接入** + - 支持用户指定本地音乐源目录,支持多级目录递归扫描 + - 支持配置文件格式过滤,仅扫描指定后缀的音频文件 + - 支持扫描断点续传,异常中断后可从断点继续扫描,无需重新全量扫描 + - 支持扫描进度实时反馈,前端展示已扫描文件数、待处理文件数 +2. **前端页面文件上传** + - 支持单个/多个音乐文件批量上传,支持拖拽上传 + - 支持大文件分片上传,断点续传 + - 上传完成后自动触发元数据校验与处理流程 + - 支持上传文件格式校验,拒绝非支持的音频格式 + +#### 3.1.2 元数据解析与校验模块(核心) +1. **全格式元数据解析**:支持MP3(ID3v1/v2)、FLAC(Vorbis Comment)、M4A(MP4 Metadata)、OGG、WAV主流音频格式的元数据读取与写入 +2. **编码自动检测与校验**:自动检测元数据原始编码,强制校验是否为UTF-8编码,非UTF-8编码且无法正常转换的直接标记失败 +3. **一票否决制强制校验**:明确核心必填字段,任一必填字段不满足规范要求,直接标记为处理失败,不进行任何猜测式补全,仅记录失败原因 +4. **非必填字段提示**:对建议字段的缺失/不规范进行记录,不影响归档,仅在处理报告中提示用户补全 +5. **元数据快照存储**:对所有处理文件的原始元数据进行快照存储,用于后续人工处理溯源与回滚 + +#### 3.1.3 元数据权威补全模块 +仅保留**基于音频指纹的权威API补全**作为唯一自动补全手段,无任何文件名/目录结构的猜测式补全,确保元数据准确性: +1. **音频指纹提取**:对校验失败的文件,自动提取音频指纹,生成唯一特征码 +2. **权威API对接**:对接AcoustID音频指纹识别API、MusicBrainz开源音乐元数据库API,获取歌曲权威元数据 +3. **补全数据二次校验**:API返回的元数据必须再次通过「一票否决制」强制校验,校验通过方可写入文件,校验不通过仍标记为失败 +4. **API调用限流与容错**:内置API调用频率限制、超时重试、异常降级机制,避免因第三方API故障导致处理流程中断 + +#### 3.1.4 文件去重与增量入库模块 +1. **多级去重算法** + - 一级快速去重:计算文件SHA-256哈希值,与数据库中已归档文件哈希比对,完全一致直接跳过 + - 二级特征去重:哈希不同,但「歌手+歌曲标题+专辑+音频时长」完全一致,标记为疑似重复,进入人工确认队列,不自动归档 + - 三级指纹去重:音频指纹一致,判定为同一首歌的不同版本,标记为疑似重复,进入人工确认队列 +2. **增量入库能力** + - 每次处理任务启动时,先扫描源目录生成文件哈希清单,与已处理完成的清单比对,仅对新增/修改的文件进行处理 + - 支持全量重扫配置,用户可手动触发全量文件重新校验 + - 已标记为失败的文件,支持手动触发重新处理,无需重新扫描全目录 + +#### 3.1.5 自动分类归档模块 +严格遵循双规则归档,100%适配Navidrome官方推荐最佳实践,归档文件默认采用**复制模式**,不修改/删除原始源文件: +1. **一级分类规则**:按专辑艺术家名称首字母分为A-Z 26个目录,非字母开头(中文、数字、符号等)的专辑艺术家统一归入`#`目录 +2. **底层目录规则**:严格遵循Navidrome官方规范,最终目录结构为: + ``` + 目标音乐库根目录/ + ├── A/ + │ └── 专辑艺术家名称/ + │ └── 专辑名称/ + │ ├── 01 - 歌曲标题.flac + │ ├── 02 - 歌曲标题.flac + │ ├── cover.jpg + │ └── 01 - 歌曲标题.lrc + ├── B/ + │ └── 专辑艺术家名称/ + ... + └── #/ + └── 非字母开头专辑艺术家名称/ + └── 专辑名称/ + └── 01 - 歌曲标题.mp3 + ``` +3. **文件名规范化规则**:统一命名格式为`2位曲目编号 - 歌曲标题.文件扩展名`,曲目编号不足2位补前导零,去除文件名中不支持的特殊字符 +4. **封面与歌词归档规则** + - 封面:必须内嵌到音频文件中,同时在专辑目录下生成`cover.jpg`(Navidrome优先读取),自动缩放为800x800正方形分辨率,格式为JPG + - 歌词:支持内嵌LRC时间轴歌词,同时在同级目录下生成`与歌曲同名.lrc`文件,强制UTF-8编码 +5. **归档冲突处理**:目标目录已存在同名文件时,自动比对哈希值,哈希一致则跳过,哈希不一致则保留两个文件并标记冲突,等待人工处理 + +#### 3.1.6 失败文件统一管理模块(核心兜底) +对所有处理失败的文件进行全生命周期管理,提供可视化人工处理界面,确保所有文件可追溯、可兜底: +1. **失败文件全信息记录**:记录文件原始路径、文件名、哈希值、失败原因、原始元数据快照、失败时间、处理状态 +2. **失败原因结构化存储**:精准标记失败类型,包括:必填字段缺失、编码乱码、封面不符合规范、API未匹配、曲目编号格式错误等 +3. **可视化列表管理** + - 支持按失败类型、处理状态、时间范围、歌手/专辑名称筛选搜索 + - 支持批量重新提交处理、批量删除操作 + - 列表展示文件核心信息、失败原因摘要、处理状态、操作按钮 +4. **元数据人工编辑页面** + - 内置音频预览播放器,支持试听文件,确认歌曲信息 + - 核心必填字段表单编辑,带必填校验与格式校验 + - 封面上传/在线搜索获取功能,自动缩放裁剪 + - 歌词上传/在线搜索获取功能,支持LRC格式校验 + - 对接MusicBrainz API提供字段自动补全建议,提升人工处理效率 +5. **人工处理提交流程**:编辑完成后提交,系统自动重新执行全流程校验,校验通过则完成归档,更新状态为已解决;校验不通过则更新失败原因,返回编辑页面 + +#### 3.1.7 系统管理模块 +1. **基础配置管理**:目标音乐库根目录配置、归档模式(复制/移动)配置、封面分辨率配置、API密钥配置、必填字段可配置开关 +2. **任务管理**:处理任务的创建、暂停、继续、终止,任务进度实时监控,历史任务记录查询 +3. **处理报告**:每次任务完成后生成详细报告,包括处理总数、成功数、失败数、重复数、失败原因统计、文件清单导出 +4. **日志管理**:系统操作日志、处理日志、错误日志的查询与导出,支持日志级别配置 +5. **数据备份与恢复**:支持系统数据库、配置文件的手动/自动备份与恢复 + +### 3.2 非功能性需求 +1. **性能需求** + - 批量处理能力:单机环境下,每秒可处理≥5个音频文件(不含第三方API调用时间) + - 启动速度:基于GraalVM原生编译后,服务启动时间≤500ms + - 内存占用:原生镜像运行时,稳态内存占用≤200MB + - 大文件支持:支持最大2GB的单音频文件处理 +2. **兼容性需求** + - 音频格式:兼容MP3、FLAC、M4A、OGG、WAV主流音频格式 + - 系统兼容:支持Windows、Linux、macOS三大主流操作系统 + - Navidrome兼容:严格适配Navidrome最新稳定版,确保扫描零错误、识别零异常 + - 浏览器兼容:前端界面支持Chrome、Edge、Firefox主流浏览器 +3. **稳定性需求** + - 异常容错:单个文件处理失败不影响整体任务流程,异常文件自动标记并跳过 + - 断点续传:扫描、处理、上传流程均支持断点续传,异常中断后可恢复 + - 数据安全:不修改、不删除原始源文件,元数据写入前自动备份原始文件 + - 服务可用性:全年可用率≥99.9%,无内存泄漏、无进程崩溃问题 +4. **易用性需求** + - 前端界面简洁直观,核心功能3步内可完成操作 + - 处理进度可视化,失败原因清晰易懂,人工编辑门槛低 + - 提供一键批量处理能力,无需复杂配置即可完成标准化归档 +5. **安全性需求** + - 文件操作权限控制:仅对用户授权的目录进行读写操作 + - 无网络泄露:本地文件处理全程不传输原始音频文件,仅音频指纹特征码用于第三方API查询 + - 配置加密:第三方API密钥等敏感配置采用加密存储 + +### 3.3 约束条件 +1. **技术栈约束**:后端必须采用Java语言开发,基于GraalVM实现原生编译;前端必须采用Vue技术栈开发 +2. **兼容性约束**:归档目录结构、元数据规范必须严格遵循Navidrome官方最佳实践,不得自定义非兼容规则 +3. **数据安全约束**:默认采用复制模式归档,禁止未经用户授权修改、删除原始源文件 +4. **元数据规则约束**:必填字段不满足规范必须标记为失败,禁止任何无权威来源的猜测式自动补全 + +--- + +## 四、整体架构设计 +### 4.1 分层架构设计 +采用经典的DDD分层架构,实现业务与技术解耦,便于扩展与维护,同时适配GraalVM原生编译要求: + +| 层级 | 核心职责 | 核心组件 | +|------|----------|----------| +| 接入层 | 负责系统对外的所有接入入口,处理用户请求与文件接入 | Vue前端界面、HTTP接口服务、本地目录扫描器、文件上传服务 | +| 应用层 | 编排核心业务流程,处理事务控制,不包含核心业务规则 | 任务管理服务、文件处理流程编排服务、失败文件管理服务、系统配置服务 | +| 领域层 | 实现系统核心业务规则与领域逻辑,是系统的核心 | 元数据校验规则、归档规则、去重规则、音频指纹识别领域服务、元数据读写领域服务 | +| 基础设施层 | 为上层提供技术能力支撑,封装底层技术实现,适配GraalVM原生编译 | 文件操作组件、元数据读写组件、音频指纹提取组件、第三方API客户端、数据库访问组件、图片处理组件、日志组件 | +| 数据层 | 负责系统数据持久化与文件存储 | 关系型数据库、本地文件系统、目标音乐库目录 | + +### 4.2 核心业务全流程 +```mermaid +graph TD + A[任务启动:目录扫描/文件上传] --> B[生成文件清单,计算SHA-256哈希] + B --> C{哈希比对:是否已归档?} + C -->|是| D[标记为已重复,跳过处理] + C -->|否| E[读取文件原始元数据,生成快照] + E --> F{核心必填字段校验:是否全部合规?} + F -->|是| G[进入去重二次校验] + F -->|否| H[提取音频指纹,调用AcoustID+MusicBrainz API] + H --> I{API是否返回完整合规元数据?} + I -->|是| J[写入API元数据到文件,二次校验必填字段] + J --> K{二次校验是否通过?} + K -->|是| G + K -->|否| L[标记为处理失败,记录结构化失败原因] + I -->|否| L + L --> M[存入失败文件数据库,状态为待处理] + M --> N[前端失败管理页面人工编辑补全] + N --> E + G -->{二次去重:是否疑似重复?} + -->|是| O[标记为疑似重复,进入人工确认队列] + -->|否| P[按Navidrome规范生成目录与文件名] + P --> Q[写入标准化元数据、封面、歌词] + Q --> R[复制文件到目标音乐库归档目录] + R --> S[更新数据库,标记为处理完成] + S --> T[任务结束,生成处理报告] +``` + +### 4.3 部署架构设计 +系统支持两种部署模式,优先适配家庭用户单机部署场景,同时支持Docker容器化部署: + +#### 4.3.1 单机部署模式(推荐) +基于GraalVM原生镜像部署,无需安装JDK环境,解压即可运行,适配Windows/Linux/macOS: +1. 前端Vue项目打包为静态资源,内置到后端原生镜像中,单文件启动 +2. 数据库采用嵌入式H2数据库,无需额外安装数据库服务 +3. 直接读写本地文件系统,无网络转发损耗,性能最优 + +#### 4.3.2 Docker容器化部署模式 +1. 基于GraalVM原生镜像构建Docker镜像,镜像体积小(≤100MB),启动速度快 +2. 支持目录挂载,将源音乐目录、目标音乐库目录、配置目录挂载到宿主机 +3. 支持Docker Compose一键部署,适配NAS、家庭服务器等Linux环境 + +--- + +## 五、元数据标准化核心规则(强制执行) +### 5.1 字段规范与一票否决制 +#### 5.1.1 核心必填字段(缺一不可,不满足直接标记失败) +| 字段名 | 英文标识 | 强制规范要求 | Navidrome依赖等级 | +|--------|----------|--------------|--------------------| +| 歌曲标题 | title | 非空、无乱码、UTF-8编码、长度≥1字符,去除首尾空格 | ⭐⭐⭐⭐⭐ | +| 歌手 | artist | 非空、无乱码、UTF-8编码、长度≥1字符,去除首尾空格 | ⭐⭐⭐⭐⭐ | +| 专辑艺术家 | album_artist | 非空、无乱码、UTF-8编码、长度≥1字符,合辑/单曲默认与artist一致,必须显式存在 | ⭐⭐⭐⭐⭐ | +| 专辑名 | album | 非空、无乱码、UTF-8编码、长度≥1字符,去除首尾空格 | ⭐⭐⭐⭐⭐ | +| 曲目编号 | track | 格式必须为「序号/总曲目数」,序号与总曲目数均为正整数,序号≤总曲目数,序号不足2位补前导零 | ⭐⭐⭐⭐⭐ | +| 专辑封面 | cover | 必须内嵌到音频文件中,图片格式为JPG/PNG,分辨率≥300x300,宽高比1:1 | ⭐⭐⭐⭐⭐ | + +#### 5.1.2 建议补充字段(缺失不标记失败,仅提示补全) +| 字段名 | 英文标识 | 规范要求 | +|--------|----------|----------| +| 发行年份 | year | 4位数字格式,范围1900-当前年份 | +| 流派 | genre | 标准音乐流派术语,多个流派用分号分隔 | +| 歌词 | lyrics | UTF-8编码,支持LRC时间轴格式,内嵌到音频文件中 | +| 光盘编号 | disc | 格式为「序号/总光盘数」,多光盘专辑必填 | +| 备注 | comment | 用于记录版本信息(Live/Remix等),无乱码 | + +### 5.2 元数据清洗强制规则 +仅对合规字段进行标准化清洗,不修改字段核心含义,清洗后仍需满足必填规范: +1. **编码规范**:所有元数据强制转换为UTF-8编码,无法正常转换、出现乱码的字段直接标记失败 +2. **特殊字符处理**:去除字段首尾空格、换行符、不可见特殊字符;目录/文件名不支持的字符`\ / : * ? " < > |`统一替换为`_` +3. **分隔符规范**:多个歌手/流派统一用英文分号+空格`; `分隔,替换原有的`&`、`feat.`、`/`等分隔符 +4. **大小写规范**:英文单词首字母大写,特殊冠词(a/an/the)句中非首字母小写,统一格式 +5. **版本信息规范**:歌曲标题中的Live/Remix/伴奏等版本信息,统一移至comment字段,标题仅保留歌曲核心名称 + +### 5.3 唯一自动补全规则 +仅支持**基于音频指纹的权威API补全**,禁止任何基于文件名、目录结构的猜测式补全: +1. 补全数据源仅认可AcoustID+MusicBrainz返回的权威元数据,其他第三方数据源不纳入自动补全范围 +2. API返回的元数据必须完整覆盖所有核心必填字段,且符合规范要求,方可自动写入 +3. 写入前必须进行二次校验,任一必填字段不满足规范,仍标记为失败,不进行部分字段补全 +4. 人工编辑场景下,可提供MusicBrainz API搜索建议,由用户手动确认后写入,不自动覆盖 + +--- + +## 六、数据库设计 +采用嵌入式H2数据库,适配GraalVM原生编译,支持单机运行无需额外部署,核心表结构如下: + +### 6.1 文件处理记录表(t_file_process) +记录所有文件的全流程处理信息,是系统的核心主表 +| 字段名 | 数据类型 | 主键 | 非空 | 说明 | +|--------|----------|------|------|------| +| id | BIGINT | 是 | 是 | 自增主键 | +| file_hash | VARCHAR(64) | 否 | 是 | 文件SHA-256哈希值,唯一索引 | +| source_file_path | VARCHAR(1000) | 否 | 是 | 原始源文件完整路径 | +| source_file_name | VARCHAR(200) | 否 | 是 | 原始文件名 | +| file_extension | VARCHAR(10) | 否 | 是 | 文件扩展名 | +| file_size | BIGINT | 否 | 是 | 文件大小(字节) | +| audio_duration | INT | 否 | 否 | 音频时长(秒) | +| raw_metadata | TEXT | 否 | 是 | 原始元数据快照,JSON格式存储 | +| process_status | VARCHAR(20) | 否 | 是 | 处理状态:PENDING(待处理)/PROCESSING(处理中)/SUCCESS(已完成)/FAIL(处理失败)/DUPLICATE(已重复)/CONFLICT(冲突) | +| fail_reason | TEXT | 否 | 否 | 失败原因,结构化JSON格式存储 | +| target_file_path | VARCHAR(1000) | 否 | 否 | 归档后目标文件完整路径 | +| task_id | BIGINT | 否 | 是 | 所属处理任务ID | +| created_at | DATETIME | 否 | 是 | 记录创建时间 | +| updated_at | DATETIME | 否 | 是 | 最后更新时间 | + +### 6.2 失败文件管理表(t_fail_file) +专门存储处理失败的文件信息,用于人工兜底处理 +| 字段名 | 数据类型 | 主键 | 非空 | 说明 | +|--------|----------|------|------|------| +| id | BIGINT | 是 | 是 | 自增主键 | +| file_process_id | BIGINT | 否 | 是 | 关联文件处理记录表ID,外键 | +| file_hash | VARCHAR(64) | 否 | 是 | 文件SHA-256哈希值,唯一索引 | +| source_file_path | VARCHAR(1000) | 否 | 是 | 原始源文件完整路径 | +| file_name | VARCHAR(200) | 否 | 是 | 文件名 | +| fail_type | VARCHAR(50) | 否 | 是 | 失败类型:MISSING_FIELD(字段缺失)/ENCODING_ERROR(编码乱码)/COVER_INVALID(封面无效)/API_NO_MATCH(API未匹配)/TRACK_FORMAT_ERROR(曲目格式错误)/OTHER(其他) | +| fail_detail | TEXT | 否 | 是 | 失败详细原因,结构化JSON格式 | +| raw_metadata | TEXT | 否 | 是 | 原始元数据快照,JSON格式 | +| edit_metadata | TEXT | 否 | 否 | 人工编辑后的元数据草稿,JSON格式 | +| status | VARCHAR(20) | 否 | 是 | 处理状态:PENDING(待处理)/EDITING(编辑中)/RESOLVED(已解决)/DISCARDED(已废弃) | +| created_at | DATETIME | 否 | 是 | 失败记录创建时间 | +| updated_at | DATETIME | 否 | 是 | 最后编辑时间 | +| resolved_at | DATETIME | 否 | 否 | 解决时间 | + +### 6.3 处理任务表(t_process_task) +记录每次批量处理任务的信息,用于任务管理与进度追踪 +| 字段名 | 数据类型 | 主键 | 非空 | 说明 | +|--------|----------|------|------|------| +| id | BIGINT | 是 | 是 | 自增主键 | +| task_name | VARCHAR(100) | 否 | 是 | 任务名称 | +| task_type | VARCHAR(20) | 否 | 是 | 任务类型:DIR_SCAN(目录扫描)/UPLOAD(文件上传)/REPROCESS(重新处理) | +| source_path | VARCHAR(1000) | 否 | 否 | 源目录路径(目录扫描任务) | +| total_file_count | INT | 否 | 是 | 总文件数 | +| processed_count | INT | 否 | 是 | 已处理文件数 | +| success_count | INT | 否 | 是 | 处理成功数 | +| fail_count | INT | 否 | 是 | 处理失败数 | +| duplicate_count | INT | 否 | 是 | 重复文件数 | +| task_status | VARCHAR(20) | 否 | 是 | 任务状态:RUNNING(运行中)/PAUSED(已暂停)/FINISHED(已完成)/TERMINATED(已终止)/ERROR(异常中断) | +| start_time | DATETIME | 否 | 是 | 任务启动时间 | +| end_time | DATETIME | 否 | 否 | 任务结束时间 | +| created_by | VARCHAR(50) | 否 | 是 | 创建人 | +| remark | VARCHAR(500) | 否 | 否 | 任务备注 | + +### 6.4 系统配置表(t_system_config) +存储系统全局配置信息,支持可视化配置修改 +| 字段名 | 数据类型 | 主键 | 非空 | 说明 | +|--------|----------|------|------|------| +| id | BIGINT | 是 | 是 | 自增主键 | +| config_key | VARCHAR(100) | 否 | 是 | 配置键,唯一索引 | +| config_value | TEXT | 否 | 否 | 配置值 | +| config_name | VARCHAR(100) | 否 | 是 | 配置名称 | +| config_desc | VARCHAR(500) | 否 | 否 | 配置描述 | +| is_editable | TINYINT | 否 | 是 | 是否可前端编辑:0-否,1-是 | +| created_at | DATETIME | 否 | 是 | 创建时间 | +| updated_at | DATETIME | 否 | 是 | 最后更新时间 | + +--- + +## 七、技术栈选型与实现方案 +### 7.1 后端技术栈(Java + GraalVM) +| 技术组件 | 选型 | 版本要求 | 选型说明 | +|----------|------|----------|----------| +| 核心框架 | Spring Boot 3.x | ≥3.2.0 | 原生支持GraalVM Native Image,生态完善,适配嵌入式开发 | +| 原生编译支持 | Spring Native | 与Spring Boot版本一致 | 官方提供的GraalVM原生编译适配方案,解决反射、动态代理等原生镜像兼容问题 | +| 数据库访问 | MyBatis-Plus | ≥3.5.5 | 轻量级ORM框架,适配GraalVM原生编译,简化数据库操作 | +| 嵌入式数据库 | H2 Database | ≥2.2.224 | 嵌入式关系型数据库,无需额外部署,单文件运行,完美适配原生镜像 | +| 元数据读写 | Jaudiotagger | ≥2.2.7 | 业界主流Java音频元数据处理库,支持全格式音频标签读写,API简单易用 | +| 编码检测 | juniversalchardet | ≥2.4.0 | Mozilla开源编码检测库,自动识别元数据原始编码,适配中文/日文等多语言 | +| 音频指纹提取 | AcoustID4J + FFmpeg | 最新稳定版 | AcoustID4J对接指纹识别API,FFmpeg提取音频特征,适配全格式音频 | +| 图片处理 | Thumbnailator | ≥0.4.20 | 轻量级图片处理库,支持封面缩放、裁剪、格式转换,API简洁,适配原生编译 | +| HTTP客户端 | Spring Cloud OpenFeign | 最新稳定版 | 声明式HTTP客户端,对接第三方API,适配GraalVM原生编译 | +| 文件上传 | Spring Boot Standard Servlet | 原生支持 | 支持大文件分片上传、断点续传,适配大音频文件处理 | +| 日志框架 | Logback | 与Spring Boot版本一致 | 适配原生编译,高性能日志框架,支持日志分级、滚动输出 | + +#### 7.1.1 GraalVM原生编译核心实现方案 +1. **环境要求**:GraalVM JDK 21+,安装Native Image组件 +2. **原生镜像适配** + - 对反射类、动态代理类、资源文件提前注册到`reflect-config.json`、`proxy-config.json`、`resource-config.json`配置文件中 + - 使用Spring Boot 3.x原生AOT提前处理,在编译期生成代理类、解析注解,避免运行期反射导致的原生镜像兼容问题 + - 对第三方库(Jaudiotagger、juniversalchardet等)进行原生镜像适配,解决第三方库的反射、资源加载问题 +3. **构建命令**:通过Spring Boot Maven插件一键构建原生镜像,命令如下: + ```bash + mvn clean native:compile -Pnative + ``` +4. **产物输出**:构建完成后生成平台相关的可执行文件,无需JDK环境,直接双击即可运行 + +### 7.2 前端技术栈(Vue) +| 技术组件 | 选型 | 版本要求 | 选型说明 | +|----------|------|----------|----------| +| 核心框架 | Vue 3 | ≥3.4.0 | 组合式API,性能优异,生态完善,符合用户技术栈要求 | +| 构建工具 | Vite | ≥5.0.0 | 极速冷启动、热更新,开发体验优异,打包体积小 | +| UI组件库 | Element Plus | ≥2.6.0 | 适配Vue 3,组件丰富,界面美观,支持暗黑模式,适配桌面端管理系统 | +| 状态管理 | Pinia | ≥2.1.0 | Vue 3官方推荐状态管理库,轻量简洁,支持TypeScript | +| 路由管理 | Vue Router | ≥4.2.0 | Vue官方路由库,适配Vue 3,支持嵌套路由、路由守卫 | +| HTTP请求 | Axios | ≥1.6.0 | 业界主流HTTP客户端,支持请求拦截、响应拦截、超时重试 | +| 文件上传 | vue-simple-uploader | ≥1.0.0 | 支持大文件分片上传、断点续传、拖拽上传,适配大音频文件 | +| 音频播放 | vue3-audio | 最新稳定版 | 适配Vue 3的音频播放器组件,支持文件预览试听 | +| 图表可视化 | ECharts | ≥5.4.0 | 百度开源图表库,性能优异,支持处理报告数据可视化展示 | +| 代码规范 | TypeScript + ESLint | 最新稳定版 | 类型安全,代码规范统一,提升可维护性 | + +#### 7.2.1 前端核心页面设计 +1. **仪表盘首页**:展示音乐库统计数据、近期任务处理情况、失败文件数量、磁盘占用情况,核心功能快捷入口 +2. **任务管理页面**:处理任务的创建、暂停、继续、终止,任务进度实时展示,历史任务查询,处理报告查看与导出 +3. **文件上传页面**:支持单个/多个文件拖拽上传,上传进度展示,上传完成后自动触发处理流程 +4. **失败文件管理页面**:失败文件列表筛选、搜索,批量操作,人工编辑入口,处理状态跟踪 +5. **元数据编辑页面**:音频预览播放器,元数据表单编辑,封面上传/搜索,歌词上传/搜索,校验与提交功能 +6. **系统配置页面**:全局配置可视化编辑,包括目标音乐库目录、归档模式、封面规格、API密钥配置等 +7. **日志管理页面**:系统日志查询、筛选、导出,日志级别配置 + +--- + +## 八、核心API接口设计 +采用RESTful风格设计,统一返回格式,适配前后端分离架构,核心接口如下: + +### 8.1 统一返回格式 +```json +{ + "code": 200, + "message": "操作成功", + "data": {}, + "timestamp": 1710000000000 +} +``` +- 成功状态码:200 +- 业务异常状态码:400-499 +- 系统异常状态码:500 + +### 8.2 核心接口清单 +| 接口分类 | 请求方式 | 接口路径 | 接口说明 | +|----------|----------|----------|----------| +| 任务管理 | POST | /api/v1/task/create-dir-task | 创建目录扫描处理任务 | +| 任务管理 | GET | /api/v1/task/list | 分页查询任务列表 | +| 任务管理 | GET | /api/v1/task/{id}/detail | 查询任务详情与进度 | +| 任务管理 | PUT | /api/v1/task/{id}/pause | 暂停任务 | +| 任务管理 | PUT | /api/v1/task/{id}/resume | 继续任务 | +| 任务管理 | PUT | /api/v1/task/{id}/terminate | 终止任务 | +| 任务管理 | GET | /api/v1/task/{id}/report | 获取任务处理报告 | +| 文件上传 | POST | /api/v1/file/upload | 音频文件分片上传 | +| 文件上传 | POST | /api/v1/file/upload/merge | 分片上传完成后合并文件 | +| 元数据处理 | POST | /api/v1/metadata/validate | 手动校验文件元数据合规性 | +| 元数据处理 | POST | /api/v1/metadata/reprocess/{id} | 重新处理指定失败文件 | +| 失败文件管理 | GET | /api/v1/fail-file/list | 分页查询失败文件列表 | +| 失败文件管理 | GET | /api/v1/fail-file/{id}/detail | 查询失败文件详情与原始元数据 | +| 失败文件管理 | PUT | /api/v1/fail-file/{id}/edit | 保存人工编辑的元数据草稿 | +| 失败文件管理 | POST | /api/v1/fail-file/{id}/submit | 提交编辑后的元数据,重新触发处理流程 | +| 失败文件管理 | POST | /api/v1/fail-file/batch-reprocess | 批量重新处理失败文件 | +| 系统配置 | GET | /api/v1/config/list | 查询系统配置列表 | +| 系统配置 | PUT | /api/v1/config/update | 更新系统配置 | +| 系统配置 | POST | /api/v1/config/backup | 手动备份系统配置与数据库 | + +--- + +## 九、部署与运维方案 +### 9.1 环境要求 +#### 9.1.1 开发环境 +| 组件 | 版本要求 | +|------|----------| +| JDK | GraalVM JDK 21+ | +| Maven | ≥3.9.0 | +| Node.js | ≥18.0.0 | +| FFmpeg | 最新稳定版 | +| 操作系统 | Windows 10+/macOS 12+/Linux 内核4.15+ | + +#### 9.1.2 生产环境(原生镜像运行) +| 组件 | 最低要求 | 推荐配置 | +|------|----------|----------| +| CPU | 2核4线程 | 4核8线程 | +| 内存 | 512MB | 2GB | +| 磁盘 | 剩余空间≥1GB | 剩余空间≥10GB(与音乐库大小匹配) | +| 操作系统 | Windows 10+/macOS 12+/Linux 内核4.15+ | Linux 64位(NAS/家庭服务器) | +| 依赖 | FFmpeg(音频指纹提取) | FFmpeg最新稳定版 | + +### 9.2 部署步骤 +#### 9.2.1 原生镜像单机部署(Windows/Linux/macOS) +1. **构建原生镜像**:通过Maven命令构建对应平台的原生可执行文件 +2. **环境准备**:目标机器安装FFmpeg,配置环境变量 +3. **文件部署**:将可执行文件、配置文件、数据库目录复制到目标机器 +4. **配置修改**:修改application.yml配置文件,设置目标音乐库目录、API密钥等配置 +5. **服务启动**: + - Windows:双击可执行文件即可启动 + - Linux/macOS:赋予执行权限后,`./music-metadata-tool`启动 +6. **访问验证**:浏览器访问`http://localhost:8080`,进入前端管理界面 + +#### 9.2.2 Docker容器化部署 +1. **构建Docker镜像**:基于GraalVM原生镜像构建Docker镜像,Dockerfile示例如下: + ```dockerfile + # 构建阶段 + FROM ghcr.io/graalvm/graalvm-community:21 AS builder + WORKDIR /app + COPY . . + RUN gu install native-image + RUN mvn clean native:compile -Pnative -DskipTests + + # 运行阶段 + FROM alpine:3.19 + WORKDIR /app + # 安装依赖 + RUN apk add --no-cache ffmpeg libc6-compat + # 复制原生可执行文件 + COPY --from=builder /app/target/music-metadata-tool /app/music-metadata-tool + # 复制配置文件 + COPY src/main/resources/application.yml /app/config/application.yml + # 暴露端口 + EXPOSE 8080 + # 挂载目录 + VOLUME ["/app/config", "/app/data", "/music/source", "/music/library"] + # 启动命令 + ENTRYPOINT ["/app/music-metadata-tool", "--spring.config.location=/app/config/application.yml"] + ``` +2. **Docker Compose部署**:编写docker-compose.yml文件,一键启动服务 +3. **目录挂载**:将源音乐目录、目标音乐库目录、配置目录、数据目录挂载到宿主机 +4. **启动服务**:`docker-compose up -d`启动容器,浏览器访问对应端口即可使用 + +### 9.3 运维方案 +1. **日志管理**:系统日志按天滚动输出,保留30天日志,支持日志级别动态调整,异常日志自动标记告警 +2. **数据备份**:支持手动/自动备份数据库与配置文件,默认每天凌晨自动备份,保留最近7个备份文件 +3. **监控告警**:内置服务健康检查接口,支持Prometheus监控指标采集,磁盘空间不足、任务异常失败时自动告警 +4. **版本升级**:原生镜像版本升级只需替换可执行文件,重启服务即可完成,兼容历史数据;Docker版本升级只需替换镜像版本 +5. **故障恢复**:提供数据库恢复、配置回滚功能,任务异常中断后可自动恢复,无需重新全量处理 + +--- + +## 十、测试方案 +### 10.1 单元测试 +- 测试范围:核心领域层逻辑,包括元数据校验规则、去重算法、归档规则、编码转换等核心方法 +- 测试框架:JUnit 5 + Mockito +- 覆盖率要求:核心业务逻辑代码覆盖率≥90% +- 重点测试场景:必填字段校验、边界值测试、异常场景测试、编码转换测试 + +### 10.2 集成测试 +- 测试范围:第三方API对接、元数据读写、数据库操作、文件操作等组件集成能力 +- 重点测试场景:AcoustID/MusicBrainz API对接、音频文件元数据写入与读取、数据库CRUD操作、大文件上传与处理 + +### 10.3 功能测试 +| 测试模块 | 核心测试点 | +|----------|------------| +| 音乐源接入 | 多级目录递归扫描、断点续传、大文件分片上传、格式过滤、异常文件拒绝 | +| 元数据校验 | 必填字段一票否决、编码乱码识别、格式规范校验、合规文件正常通过 | +| 元数据补全 | API正常补全、补全数据二次校验、API异常容错、无猜测式补全 | +| 去重与增量入库 | 哈希去重、特征去重、增量文件识别、重复文件跳过、异常去重处理 | +| 自动归档 | 目录结构生成、文件名规范化、封面/歌词归档、Navidrome适配、冲突处理 | +| 失败文件管理 | 失败原因记录、列表筛选、人工编辑、重新提交流程、批量操作 | +| 系统管理 | 配置修改、任务管理、处理报告生成、日志查询、数据备份与恢复 | + +### 10.4 兼容性测试 +1. **音频格式兼容**:覆盖MP3、FLAC、M4A、OGG、WAV格式的元数据读写与处理测试 +2. **系统兼容**:Windows、Linux、macOS三大操作系统的原生镜像部署与运行测试 +3. **Navidrome兼容**:处理后的音乐库导入Navidrome最新稳定版,验证扫描识别率、歌手/专辑/封面/歌词展示、曲目排序等核心场景 +4. **浏览器兼容**:Chrome、Edge、Firefox主流浏览器的前端界面功能测试 + +### 10.5 性能测试 +- 批量处理性能:1000个音频文件批量处理,验证处理速度、内存占用、CPU使用率 +- 启动性能:原生镜像启动时间测试,验证是否≤500ms +- 大文件处理:2GB单音频文件上传、处理、归档全流程测试 +- 并发性能:多个任务同时运行,验证系统稳定性与处理能力 + +--- + +## 十一、风险与应对措施 +| 风险类型 | 风险描述 | 风险等级 | 应对措施 | +|----------|----------|----------|----------| +| 技术风险 | GraalVM原生镜像第三方库兼容问题,部分库存在反射、动态代理导致的编译失败 | 中 | 1. 提前对第三方库进行原生镜像适配验证;2. 优先选择支持GraalVM原生镜像的库;3. 提前注册反射、代理配置,通过Spring AOT提前处理 | +| 业务风险 | 第三方API调用限流、故障,导致元数据补全失败 | 中 | 1. 内置API调用限流、超时重试机制;2. 提供API密钥配置,用户可使用自己的密钥;3. 异常时直接标记失败,不中断整体任务,后续支持手动重试 | +| 数据风险 | 元数据写入导致音频文件损坏、原始文件丢失 | 高 | 1. 默认采用复制模式,不修改原始源文件;2. 元数据写入前自动备份源文件;3. 写入后校验文件完整性,异常时自动回滚;4. 提供移动模式开关,用户手动确认后开启 | +| 性能风险 | 超大音乐库(10万+文件)全量扫描与处理性能瓶颈 | 中 | 1. 多线程并发处理,可配置线程数;2. 扫描与处理流程解耦,异步处理;3. 哈希比对优化,建立哈希索引,提升去重速度;4. 断点续传,支持分批次处理 | +| 兼容性风险 | 小众音频格式元数据读写异常 | 低 | 1. 优先适配主流音频格式,小众格式提前校验,不支持的格式直接标记失败;2. 完善异常捕获,单个文件处理失败不影响整体任务 | +| 安全风险 | 目录越权访问,误操作非授权目录文件 | 高 | 1. 目录白名单机制,仅对用户授权的目录进行读写;2. 严格校验文件路径,禁止路径穿越;3. 默认只读访问源目录,仅对目标目录有写入权限 | + +--- + +## 十二、阶段文档索引与实施说明 + +为避免总方案文档随着阶段推进不断膨胀,P0、P1 及后续阶段的“开发落地说明、测试结果、验收证据、偏差说明”统一沉淀到项目仓库内的阶段文档中;本总文档仅保留全局设计、总体规则、阶段索引与里程碑说明。 + +### 12.1 文档组织规则 + +- 总方案文档:保留项目背景、需求、总体架构、统一规则、阶段规划 +- 阶段落地文档:写入每个阶段的实现内容、关键文件、测试策略、验收结果、已知偏差 +- 阶段落地文档统一存放于:`music-metadata-system/docs/` + +### 12.2 当前阶段文档索引 + +| 阶段 | 文档 | 说明 | +|------|------|------| +| P0 | `music-metadata-system/docs/P0-基础架构-开发落地说明.md` | 记录基础架构、数据库底座、统一异常与响应规范的落地情况 | +| P1 | `music-metadata-system/docs/P1-元数据解析与校验-开发落地说明.md` | 记录元数据读取、快照存储、一票否决校验、真实文件测试与覆盖率结果 | + +### 12.3 当前状态摘要 + +- P0 已完成基础工程、数据库底座、基础持久化层和统一异常处理能力建设 +- P1 已完成元数据读取、编码检测与修复尝试、快照持久化、一票否决校验、目录扫描与去重相关验收能力 +- 详细实现、测试与验收结果请以对应阶段文档为准 + +## 十三、项目里程碑规划 +| 阶段 | 周期 | 核心交付物 | 完成标准 | +|------|------|------------|----------| +| 第一阶段:需求确认与架构设计 | 1周 | 需求规格说明书、架构设计文档、数据库设计文档、API接口文档 | 需求与架构方案确认完成,核心规则与技术选型敲定 | +| 第二阶段:核心后端模块开发 | 3周 | 元数据解析与校验模块、文件去重模块、自动归档模块、API对接模块、数据库访问层 | 核心业务流程可跑通,音频文件可完成标准化校验与归档,适配Navidrome规范 | +| 第三阶段:前端界面开发 | 2周 | Vue前端工程、所有核心页面、前后端接口联调 | 前端界面可正常访问,所有功能可通过界面操作完成 | +| 第四阶段:GraalVM原生编译适配 | 1周 | 原生镜像适配配置、可执行文件构建脚本、Docker镜像构建文件 | 可正常构建对应平台的原生镜像,镜像可正常启动与运行,无兼容问题 | +| 第五阶段:测试与Bug修复 | 2周 | 测试用例、测试报告、Bug修复记录 | 完成所有测试场景,核心功能无Bug,系统稳定运行,性能达标 | +| 第六阶段:部署与上线 | 1周 | 部署文档、用户操作手册、正式版安装包、Docker镜像 | 系统可正常部署运行,用户可通过手册完成操作,正式版交付 | +| 合计 | 10周 | 完整系统、全量文档、交付物 | 系统所有功能实现,满足所有需求与约束条件,可正式投入使用 |