Initial setup of project files and directory structure.

This commit is contained in:
liu
2026-01-29 10:29:58 +08:00
parent b3488fa51a
commit 981b4ecf42
9 changed files with 1121 additions and 0 deletions

142
00-开发前后端格式.md Normal file
View File

@@ -0,0 +1,142 @@
## 00 - 开发前后端格式
### 1. 项目概述
**MangTool** 是一个基于 **Java Spring Boot + Vue 3** 的个人开发工具箱,专注于音乐库管理和日志处理两大核心模块,特点是:**开箱即用、模块化扩展、安全可靠**。
- **后端技术栈**Spring Boot、WebSocket、异步任务、文件处理引擎FFmpeg、Jaudiotagger、SVNKit 等)
- **前端技术栈**Vue 3、Vite、Element Plus、组合式 API、基于组件的单页应用
### 1.1 开发环境版本
- **Node.js**v20.19.5
- **npm**10.8.2
- **Java**1.8.0_472OpenJDK 64-Bit Server VM
- **Maven**Apache Maven 3.8.7
### 2. 前后端整体架构
```mermaid
graph TB
subgraph "前端 (Vue 3)"
A[前端组件] --> B[API 封装层]
B --> C[WebSocket 客户端]
end
subgraph "后端 (Spring Boot)"
D[REST 控制器] --> E[业务服务层]
E --> F[文件处理引擎]
E --> G[WebSocket 服务]
F --> H[FFmpeg 集成]
F --> I[Jaudiotagger]
F --> J[SVNKit]
end
C -- WebSocket 实时进度 --> G
B -- HTTP REST API --> D
F --> K[本地文件系统]
```
- **HTTP API**:前端通过 axios 封装的请求模块调用后端 REST 接口
- **WebSocket**:用于长时间批处理任务的实时进度推送
- **文件系统访问**:所有音频、日志等文件操作都集中在后端完成,前端只处理路径和参数
### 3. 项目目录结构
```text
mangtool/
├── backend/ # Spring Boot 后端
│ ├── src/main/java/com/music/
│ │ ├── config/ # 配置类 (CORS, WebSocket, Async)
│ │ ├── controller/ # REST 控制器
│ │ ├── service/ # 业务服务层(核心逻辑)
│ │ ├── dto/ # 数据传输对象
│ │ ├── common/ # 通用工具 (Result, ErrorCode)
│ │ └── exception/ # 全局异常处理
│ └── pom.xml # Maven 依赖配置
├── frontend/ # Vue 3 前端
│ ├── src/
│ │ ├── components/ # 功能模块组件 (*Tab.vue)
│ │ ├── api/ # API 模块化封装
│ │ ├── composables/ # 组合式函数 (useWebSocket)
│ │ └── App.vue # 主界面与导航
│ └── vite.config.js # Vite 配置
└── docker/ # 容器化部署配置
```
### 4. 统一后端返回格式
- **强制要求**:所有后端接口统一返回 `Result<T>`,禁止直接返回实体类或 `ResponseEntity`
```java
public class Result<T> {
private int code; // 0=成功非0=错误
private String message; // 提示信息
private T data; // 业务数据
}
```
- **全局异常处理**:通过 `GlobalExceptionHandler` 捕获 `BusinessException`,并转换为统一的 `Result` 响应
### 5. 前端 API 调用规范
- **模块划分**`frontend/src/api/` 下按功能拆分:`aggregate.js`, `convert.js`, `dedup.js`
- **统一请求实例**:所有 API 模块都通过封装好的 axios 实例 `request` 发送请求
**响应拦截器约定**
- 后端只返回 `Result<T>` 格式
- 前端拦截器自动判断 `code`
- `code === 0`:直接返回 `data`
- 其他:弹出错误信息,并返回 `Promise.reject`
### 6. WebSocket 进度推送规范
**消息结构ProgressMessage DTO**
```java
public class ProgressMessage {
private String taskId; // 任务 ID
private String type; // 任务类型
private int total; // 总数
private int processed; // 已处理
private int success; // 成功数
private int failed; // 失败数
private String currentFile; // 当前处理文件
private String message; // 进度消息
private boolean completed; // 是否完成
}
```
- **服务端**:通过 WebSocket 节流推送进度,避免频繁推送导致前端卡顿
- **前端**:统一封装 `useWebSocket` 组合式函数,在各个 Tab 组件中复用,用于展示进度条 / 当前文件 / 完成状态
### 7. 测试用例需求
#### 7.1 后端测试
**单元测试**:
- 测试统一返回格式 `Result<T>` 的构建与序列化
- 测试全局异常处理器对 `BusinessException` 的捕获与转换
- 测试 WebSocket 消息推送的节流机制
- 测试路径验证拦截器的安全规则
**集成测试**:
- 测试完整的 HTTP 请求响应流程(包含正常与异常情况)
- 测试 WebSocket 连接建立、消息推送、断开重连
- 测试 CORS 配置是否正确允许前端跨域访问
#### 7.2 前端测试
**单元测试**:
- 测试 API 响应拦截器对不同 code 值的处理逻辑
- 测试 `useWebSocket` 组合式函数的连接管理与消息接收
- 测试各个组件的参数校验与错误提示
**集成测试**:
- 测试前后端联调:完整的任务提交、进度推送、结果展示流程
- 测试异常场景:网络断开、后端服务异常、超时等情况的用户提示
**E2E 测试**:
- 模拟真实用户操作,验证完整的业务流程
- 测试不同浏览器的兼容性

99
01-音频文件汇聚.md Normal file
View File

@@ -0,0 +1,99 @@
## 01 - 音频文件汇聚
### 1. 功能概述
- **功能名称**:音频文件汇聚
- **后端服务**`AggregatorService`
- **前端组件**`AggregateTab.vue`
**主要用途**
- 将分散在多级子目录中的音频文件全部扁平化汇聚到一个目标目录,便于后续统一转换、整理或入库。
### 2. 前端交互设计AggregateTab.vue
- **核心参数**
- **源目录**:递归扫描的起始目录
- **目标目录**:所有音频文件最终聚合到的目录
- **模式选择**:移动模式 / 复制模式
- **交互要点**
- 使用统一的目录浏览组件选择路径
- 提交后通过 WebSocket 订阅后台任务进度(总数/已处理/当前文件等)
- 任务完成后给出简单统计信息(成功/失败数量)
### 3. 后端核心设计AggregatorService
#### 3.1 支持的音频格式
- 支持常见格式:`MP3`, `FLAC`, `WAV`, `M4A`, `AAC`, `OGG`, `WMA`, `APE`
- 文件过滤通常通过扩展名白名单实现
#### 3.2 目录遍历策略
- 使用 `Files.walkFileTree()` 或等价方式进行深度递归遍历
- 忽略非文件或不在白名单中的扩展名
- 移动模式下,在任务结束后可清理空目录
#### 3.3 冲突解决机制
当目标目录中已存在同名文件时:
- **不覆盖原文件**
- 自动重命名为:`文件名 (1).ext`, `文件名 (2).ext` ...
- 确保每个文件都有唯一文件名,不丢数据
### 4. 任务模式
- **移动模式**
- 汇聚成功后删除源目录中的原始文件
- 适合“整理后不再保留原结构”的场景
- **复制模式**
- 保留源目录结构,只在目标目录生成一份扁平化副本
- 适合试运行或备份场景
### 5. 典型使用流程
1. 在前端选择源目录与目标目录
2. 选择模式(移动 / 复制)
3. 点击开始任务,前端调用后端 `/aggregate` 类接口
4. 后端创建任务并异步执行,周期性通过 WebSocket 推送进度
5. 前端展示列表或进度条,任务完成时给出汇总信息
### 6. 与其他模块的配合
- 通常作为 **音频格式智能处理**、**音乐整理** 等功能的预处理步骤
- 通过汇聚将文件位置统一到一个目录,简化后续模块的输入路径配置
### 7. 测试用例需求
#### 7.1 后端测试
**单元测试**:
- 测试音频格式白名单过滤逻辑
- 测试文件名冲突解决机制(自动重命名为"文件名(1).ext")
- 测试深度递归遍历的准确性
- 测试移动模式下空目录清理功能
- 测试复制模式下文件完整性保证
**集成测试**:
- 准备多层级测试目录结构,包含各种音频格式
- 测试汇聚任务的完整执行流程
- 测试进度推送的准确性(总数/已处理/当前文件)
- 测试异常场景:磁盘空间不足、权限不足、文件被占用等
#### 7.2 前端测试
**单元测试**:
- 测试源目录与目标目录的路径校验
- 测试模式选择(移动/复制)的状态管理
- 测试进度条与统计信息的实时更新
**集成测试**:
- 测试完整的用户操作流程:选择目录→选择模式→提交任务→查看进度→查看结果
- 测试任务中断与恢复的用户体验
**测试数据**:
- 小规模场景:10 个文件,3 层目录
- 中等规模场景:1000 个文件,10 层目录
- 大规模场景:10000+ 个文件,包含重复文件名
- 边界场景:空目录、单个文件、超长文件名、特殊字符文件名

View File

@@ -0,0 +1,103 @@
## 02 - 音频格式智能处理
### 1. 功能概述
- **功能名称**:音频格式智能处理
- **后端服务**`ConvertService`
- **前端组件**`ConvertTab.vue`
**主要用途**
- 针对无损音频格式(如 WAV/APE 等)智能转换为 FLAC提高兼容性和标签支持能力
- 对于有损格式和已为 FLAC 的文件自动跳过,避免无意义的二次压缩。
### 2. 智能分类策略
- **无损格式转 FLAC**
- 支持:`WAV`, `APE`, `AIFF`, `WV`, `TTA`
- 统一转换为 `FLAC`保证后续工具如标签编辑器、Navidrome有良好兼容性
- **有损格式自动跳过**
- 包括:`MP3`, `M4A`, `AAC`, `OGG`, `OPUS`, `WMA`
- 保持原样,不做任何处理
- **已是 FLAC 的文件直接跳过**
- 避免重复转换和无意义的文件改动
### 3. FFmpeg 集成方案
- 使用 `ProcessBuilder` 调用系统中的 `ffmpeg` 命令行进行转码:
- 典型命令示例(伪代码):
- `ffmpeg -i input.wav -compression_level 5 output.flac`
- **转码参数约定**
- 压缩级别:`5`(在压缩率与速度之间做平衡)
- 保留原始采样率、声道数和位深度,确保音质无损
- **错误处理**
- 转码失败时记录日志,并在进度信息中体现失败计数
### 4. 任务模式(移动 / 复制)
- **移动模式**
- 转换成功后删除源文件,仅保留 FLAC 文件
- 适用于已经确认不再需要原始无损格式的场景
- **复制模式**
- 保留源文件,在目标目录生成 FLAC 副本
- 适合试运行或希望保留源文件做长期归档的场景
### 5. 前端交互流程
1. 用户在前端选择:
- 输入目录(待扫描的音频文件目录)
- 输出目录FLAC 目标目录,可与输入目录相同或独立)
- 模式(移动 / 复制)
2. 点击开始任务后,前端调用后端 `/convert` 类接口
3. 后端创建异步任务并开始遍历、分类、转码
4. 通过 WebSocket 周期性推送进度:
- 总文件数、已处理数量、成功/失败数
- 当前处理文件路径
5. 前端组件展示进度条与当前文件,并在任务完成时弹出结果摘要
### 6. 与其他模块的配合
- 常与 **01-音频文件汇聚** 搭配:先汇聚到一个扁平目录,再执行智能转码
- 转码完成后通常交由 **05-音乐整理** 进行目录重组和标签检查
-**06-整理入库** 前确保所有无损源文件已经统一为 FLAC,减少后续维护成本
### 7. 测试用例需求
#### 7.1 后端测试
**单元测试**:
- 测试音频格式分类逻辑(无损/有损/FLAC)
- 测试 FFmpeg 命令构建的正确性
- 测试转码参数配置(压缩级别、采样率保留等)
- 测试转码失败时的错误处理与日志记录
- 测试文件删除逻辑(移动模式下的源文件清理)
**集成测试**:
- 准备各种格式的测试音频文件(WAV、APE、FLAC、MP3、M4A 等)
- 测试完整的转码任务执行流程
- 验证转码后的 FLAC 文件音质无损(采样率、位深度、声道数)
- 测试混合格式目录的智能分类与跳过逻辑
- 测试异常场景:FFmpeg 未安装、损坏的音频文件、磁盘空间不足
#### 7.2 前端测试
**单元测试**:
- 测试输入/输出目录的路径校验
- 测试模式选择的状态管理
- 测试进度信息展示(成功/失败/跳过计数)
**集成测试**:
- 测试完整的用户操作流程
- 测试任务进度的实时更新
- 测试结果摘要的准确性
**测试数据**:
- 纯无损文件目录:WAV、APE、AIFF 混合
- 纯有损文件目录:MP3、M4A、OGG 混合
- 混合格式目录:包含无损、有损、FLAC
- 边界场景:超大文件(>1GB)、损坏文件、无效文件扩展名
**性能测试**:
- 测试批量转码任务的并发性能
- 测试大文件转码的内存占用
- 测试 WebSocket 进度推送的频率与性能影响

125
03-音乐去重.md Normal file
View File

@@ -0,0 +1,125 @@
## 03 - 音乐去重
### 1. 功能概述
- **功能名称**:音乐去重
- **后端服务**`DedupService`
- **前端组件**`DedupTab.vue`
**主要用途**
- 在大型音乐库中识别并处理重复文件,减少存储占用,保持库结构干净整洁。
> 去重结果高度依赖音频元数据(标签)的质量,建议先用专业刮削工具整理好标签。
### 2. 前置条件与推荐工具
- 去重算法依赖以下标签信息:
- 艺术家Artist
- 标题Title
- 专辑Album
- 时长(带一定误差容忍)
- **推荐刮削工具**
- `MusicBrainz Picard`(开源免费,专业级)
- `音乐标签` PC 版(中文界面,更易上手)
### 3. 双重去重策略
#### 3.1 MD5 哈希去重
- 对每个音频文件计算 MD5 值
- 相同 MD5 值视为完全相同的二进制文件
- 适用于“完全拷贝”的重复场景(如不同目录下的同一文件)
#### 3.2 元数据匹配去重
- 按以下字段组合匹配:
- 艺术家 + 标题 + 专辑 + 时长(允许 ±5 秒误差)
- 对候选重复组内的文件进行打分,选出“保留对象”:
- **格式优先**`FLAC` > 其他无损 > 有损
- **码率优先**:码率越高得分越多
- **文件大小**:更大的文件通常音质更好
- **文件名匹配度**:文件名包含艺术家/标题会加分
### 4. 智能评分与选择策略
- 为候选重复组内每个文件计算综合评分:
- 格式加权FLAC 加较高权重
- 码率加权:高码率文件加分
- 文件大小:极小文件(疑似样本或损坏)会被减分
- 文件名噪声惩罚:数字前缀、无意义后缀、过多符号会被扣分
- 最终选择得分最高的文件作为“保留文件”,其他作为“候选删除/移动对象”。
### 5. 安全机制与执行模式
- **移动模式**
- 将重复文件移动到指定“回收站”目录,可后续人工检查与恢复
- **复制模式**
- 将重复文件复制到回收站目录,原库保持不变,适合试运行和验证规则
- 建议先使用 **复制模式** 验证规则效果,再切换到 **移动模式** 正式清理。
### 6. 前端交互流程
1. 用户选择音乐库根目录和回收站目录
2. 勾选去重策略(是否启用 MD5、是否启用元数据匹配
3. 执行任务后,通过 WebSocket 获取去重进度与当前处理文件
4. 任务结束时展示:
- 扫描文件总数
- 识别的重复组数量
- 实际移动/复制的文件数量
### 7. 建议使用顺序
- 通常在完成以下步骤后使用去重:
1. 使用刮削软件整理标签
2. 可选:使用 **01-音频文件汇聚** 汇总散落文件
3. 可选:使用 **02-音频格式智能处理** 统一为 FLAC
- 去重完成后再交由 **05-音乐整理****06-整理入库** 进一步规范库结构。
### 8. 测试用例需求
#### 8.1 后端测试
**单元测试**:
- 测试 MD5 哈希计算的准确性与性能
- 测试元数据匹配逻辑(艺术家+标题+专辑+时长容差)
- 测试文件评分算法(格式、码率、文件大小、文件名匹配度)
- 测试重复组筛选与保留文件选择逻辑
- 测试文件名噪声识别与惩罚规则
**集成测试**:
- 准备测试数据集:
- 完全相同的文件副本(MD5 去重场景)
- 相同歌曲的不同版本(不同格式、不同码率)
- 标签不完整的文件(测试容错性)
- 测试完整的去重任务执行流程
- 验证去重结果的准确性:保留文件是否为最优选择
- 测试移动/复制模式的正确执行
- 测试异常场景:无标签文件、损坏文件、权限不足
#### 8.2 前端测试
**单元测试**:
- 测试音乐库与回收站目录的路径校验
- 测试去重策略勾选的状态管理
- 测试去重结果统计的展示
**集成测试**:
- 测试完整的用户操作流程
- 测试去重结果预览(如果有)
- 测试任务进度与当前处理文件展示
**测试数据**:
- 小规模场景:100 个文件,10 对重复
- 中等规模场景:5000 个文件,500 对重复
- 大规模场景:50000+ 个文件,测试性能
- 边界场景:
- 全部文件都是重复
- 完全没有重复
- 标签缺失或错误
- 多个版本的重复组(3 个以上相同歌曲)
**质量验证**:
- 人工抽查去重结果,验证保留文件的合理性
- 对比专业去重工具(如 Mp3tag)的结果
- 验证不同格式/码率的优先级规则

View File

@@ -0,0 +1,120 @@
## 04 - 音乐元数据繁体转简体
### 1. 功能概述
- **功能名称**:音乐元数据繁体转简体
- **后端服务**`ZhConvertService` + `TraditionalFilterService`
- **前端组件**`TraditionalFilterTab.vue`
**主要用途**
- 批量检测并转换音乐标签中的繁体中文,统一为简体中文,提升搜索与展示的一致性。
> 本功能为独立模块,建议在“音乐整理”和“整理入库”之前执行,保持处理流程清晰。
### 2. 繁体检测逻辑
- 对字段内容逐字符扫描,判断是否为繁体字
- 统计:
- 中文字符总数
- 其中繁体字符数量
- 计算繁体占比:
- \( ratio = 繁体字符数 / 总中文字符数 \)
- 支持配置“触发阈值”,只有繁体比例超过阈值的内容才会被列入待处理列表
### 3. 支持字段
- 标题Title
- 艺术家Artist
- 专辑Album
- 专辑艺人AlbumArtist
### 4. 处理模式
- **预览模式**
- 只扫描并列出检测到繁体的文件与字段
- 不对原文件做任何修改
- 适合先评估影响范围
- **执行模式**
- 对选中的字段进行繁体→简体转换
- 可选择“覆盖原文件”或“输出到目标目录”
### 5. 前端交互流程
1. 用户选择扫描目录和输出目录(可选)
2. 配置繁体占比阈值(例如 10%
3. 选择处理模式(预览 / 执行)
4. 启动任务后,通过 WebSocket 获取进度:
- 已扫描文件数
- 检测到的繁体标签条目数量
5. 对于预览模式,前端可展示:
- 文件路径
- 原始标签内容
- 转换后的预览内容
### 6. 使用建议与流水线位置
- 推荐使用顺序:
1. 通过刮削工具(如 MusicBrainz Picard补全英文/日文等元数据
2. 使用本模块统一处理中文标签的繁简体问题
3. 再通过 **05-音乐整理** 做目录重组和命名规范化
4. 最后通过 **06-整理入库** 将整理好的内容合并入主库
- 这样可以保证:
- 标签内容在进入主库前已完成繁简统一
- 同一艺人/专辑不会因繁简混用出现在不同目录下。
### 7. 测试用例需求
#### 7.1 后端测试
**单元测试**:
- 测试繁体字符识别逻辑的准确性
- 测试繁体占比计算算法
- 测试繁简转换的正确性(覆盖常用繁体字)
- 测试阈值判断逻辑(不同占比的处理)
- 测试各标签字段(Title/Artist/Album/AlbumArtist)的独立处理
**集成测试**:
- 准备测试音频文件:
- 纯繁体标签
- 繁简混合标签
- 纯简体标签(验证不会误转)
- 英文/日文标签(验证不受影响)
- 测试预览模式:只扫描不修改
- 测试执行模式:实际修改标签
- 验证转换后的标签准确性
- 测试覆盖原文件与输出到目标目录两种模式
- 测试异常场景:无标签文件、只读文件、损坏文件
#### 7.2 前端测试
**单元测试**:
- 测试繁体占比阈值配置的校验
- 测试处理模式选择的状态管理
- 测试预览结果的展示格式
**集成测试**:
- 测试完整的预览流程
- 测试完整的执行流程
- 测试转换前后对比展示
**测试数据**:
- 标准繁体:
- 周杰倫 → 周杰伦
- 我的歌聲裡 → 我的歌声里
- 愛情轉移 → 爱情转移
- 繁简混合:
- 周杰倫的愛情故事 → 周杰伦的爱情故事
- 多音字与特殊字:
- 幹什麼 → 干什么
- 後來 → 后来
- 边界场景:
- 纯英文标签(不应改变)
- 日文汉字(部分繁体,需谨慎处理)
- 空标签或特殊字符
**质量验证**:
- 对比专业繁简转换工具的结果
- 人工抽查转换结果,确保无误转
- 验证不同繁体占比阈值的效果

151
05-音乐整理.md Normal file
View File

@@ -0,0 +1,151 @@
## 05 - 音乐整理
### 1. 功能概述
- **功能名称**:音乐整理
- **后端服务**`RenameService` + `OrganizeService`
- **前端组件**`RenameTab.vue`
**主要用途**
- 将已整理好标签的音频文件按 Navidrome 标准目录结构重命名、分组,并生成封面、歌词与整理报告。
### 2. 目标目录结构规范
- 标准结构示例:
- `艺术家/专辑(年份)/曲号 - 标题.ext`
- 示例:
- `周杰伦/七里香(2004)/01 - 七里香.flac`
- `Adele/21(2011)/01 - Rolling In The Deep.flac`
### 3. A-Z 索引分组策略
- **正常艺术家**
- 中文艺术家:按拼音首字母分组(如“周杰伦” → `Z/周杰伦/...`
- 英文艺术家按首字母分组如“Adele” → `A/Adele/...`
- **合辑**
- 统一归入 `Various Artists` 目录,不参与 A-Z 分组
- **特殊字符开头**
- 数字或特殊符号开头的艺术家统一归入 `#/` 分组
- **多音字处理**
- 使用 Pinyin4j 默认取第一个读音,绝大多数场景可以接受
### 4. 质量隔离机制
- 根据标签完整度对文件进行分层处理:
- **严格模式**:必须同时包含 `Title + Artist + Album` 才参与整理
- **宽松模式**:只要有 `Title` 即可参与整理
- 对于缺少必要标签的文件:
- 自动移动到 `_Manual_Fix_Required_/Missing_XXX/` 等目录
- 便于后续集中使用标签工具(如 MusicBrainz Picard修复
### 5. 附加功能
#### 5.1 封面提取
- 从音频文件内嵌封面中提取 `cover.jpg` 到专辑目录
- 按专辑粒度判断:
- 只要专辑中任一文件含有封面,即视为该专辑有封面,并提取一次
#### 5.2 歌词提取
- 从音频文件中提取内嵌歌词到 `.lrc` 文件
- 按单曲粒度判断:
- 每个文件独立检查是否含有歌词
#### 5.3 整理报告生成
- 整理结束后自动生成报告文件:
- 文件名:`report_YYYYMMDD_HHMMSS.txt`
- 位置:目标目录下 `_Reports/` 子目录
- 报告内容包括:
- 生成时间、扫描文件数
- 缺失封面的专辑列表
- 缺失歌词的文件列表
- 统计摘要(总专辑数、无封面专辑数及百分比、无歌词文件数及百分比)
### 6. 前端交互流程
1. 用户选择“源目录”(通常是经过汇聚、转码、去重后的 staging 目录)
2. 选择“目标目录”(正式库或 staging 输出目录)
3. 配置:
- 严格 / 宽松 模式
- 是否提取封面
- 是否提取歌词
- 是否生成报告
4. 执行任务,通过 WebSocket 订阅进度与当前处理文件
5. 整理完成后,可在 `_Reports/` 中查看整理报告,对问题文件做二次处理。
### 7. 建议使用顺序
- 推荐整体流水线:
1. 01-音频文件汇聚
2. 02-音频格式智能处理
3. 03-音乐去重
4. 04-音乐元数据繁体转简体
5. **05-音乐整理(本模块)**
6. 06-整理入库
- 这样可以保证进入主库前,目录结构、文件命名、标签内容和资源(封面/歌词)都已基本规范。
### 8. 测试用例需求
#### 8.1 后端测试
**单元测试**:
- 测试中文拼音首字母提取的准确性(含多音字)
- 测试英文首字母分组逻辑
- 测试特殊字符处理(数字、符号归入"#"分组)
- 测试合辑识别与 Various Artists 归类
- 测试标签完整度检查(严格/宽松模式)
- 测试目录结构生成:"艺术家/专辑(年份)/曲号 - 标题.ext"
- 测试封面提取逻辑(按专辑粒度)
- 测试歌词提取逻辑(按单曲粒度)
- 测试整理报告生成(缺失封面/歌词统计)
**集成测试**:
- 准备测试音频文件:
- 完整标签的文件(中文/英文/日文艺术家)
- 标签不完整的文件(缺 Title/Artist/Album)
- 含内嵌封面的文件
- 含内嵌歌词的文件
- 合辑文件(AlbumArtist = Various Artists)
- 测试严格模式:缺标签文件移动到 _Manual_Fix_Required_/
- 测试宽松模式:只要有 Title 即可整理
- 测试 A-Z 分组的正确性
- 验证生成的目录结构符合 Navidrome 规范
- 验证封面与歌词文件的提取与命名
- 验证整理报告的准确性
- 测试异常场景:无效标签、特殊字符、超长文件名
#### 8.2 前端测试
**单元测试**:
- 测试源目录与目标目录的路径校验
- 测试模式选择(严格/宽松)的状态管理
- 测试功能开关(提取封面/歌词/生成报告)的状态管理
- 测试进度信息的实时更新
**集成测试**:
- 测试完整的用户操作流程
- 测试整理报告的查看与下载
- 测试不同配置组合的效果
**测试数据**:
- 小规模场景:50 首歌曲,5 个艺术家,10 个专辑
- 中等规模场景:5000 首歌曲,200 个艺术家,500 个专辑
- 大规模场景:50000+ 首歌曲,测试性能与报告生成
- 边界场景:
- 中英日混合艺术家
- 多音字艺术家(如:曲婉婷、单依纯)
- 特殊字符开头的艺术家
- 合辑专辑
- 缺失各种标签的文件
- 超长文件名与路径
**质量验证**:
- 验证生成的目录结构在 Navidrome 中的兼容性
- 抽查 A-Z 分组的准确性
- 验证封面图片的完整性与格式
- 验证歌词文件的格式与内容
- 验证整理报告的统计准确性

120
06-整理入库.md Normal file
View File

@@ -0,0 +1,120 @@
## 06 - 整理入库
### 1. 功能概述
- **功能名称**:整理入库
- **后端服务**`LibraryMergeService`
- **前端组件**`MergeTab.vue`
**主要用途**
- 将整理好的 staging 目录智能合并到 Navidrome 主库中,统一升级音频、歌词与封面资源。
### 2. 全资源同步策略
- **音频文件同步**
-`艺术家/专辑/曲目` 结构合并
- 若目标库已存在同路径文件,则进入“智能升级决策”
- **歌词文件同步**
- 同步 `.lrc` 文件,与对应音频文件保持相对路径一致
- **封面图片同步**
- 比较已有封面与新封面
- 优先保留分辨率/体积更大的版本
### 3. 智能升级策略
- **文件大小优先**
- 对于同一首歌曲的多份文件,一般认为文件越大音质越好
- 若新文件明显“更大”,则视为可升级版本
- **关联资源同步**
- 当音频被升级替换时,对应歌词文件也一并同步
- **图片优选**
- 对比封面图片分辨率和文件大小
- 保留清晰度更高的一份,避免重复占用
### 4. 前端交互流程
1. 用户选择:
- **源目录**:整理完成后的 staging 目录
- **目标目录**Navidrome 主库根目录
2. 配置合并策略(如:是否启用智能升级、是否保留旧版本备份)
3. 启动任务后,通过 WebSocket 订阅:
- 已合并的专辑/曲目数
- 升级替换的文件数
- 发生冲突和跳过的条目
4. 任务完成后,可查看合并报告(若有实现)或通过日志排查异常情况。
### 5. 使用建议与整体流程位置
- 整理入库通常作为音乐处理流水线的最后一步:
1. 01-音频文件汇聚
2. 02-音频格式智能处理
3. 03-音乐去重
4. 04-音乐元数据繁体转简体
5. 05-音乐整理
6. **06-整理入库(本模块)**
- 建议在正式合并前:
- 对 staging 目录做一次整体浏览(目录浏览组件或文件管理器)
- 确认结构与文件数量基本符合预期,再执行"整理入库"。
### 6. 测试用例需求
#### 6.1 后端测试
**单元测试**:
- 测试文件大小比较逻辑(判断是否需要升级)
- 测试路径匹配算法(艺术家/专辑/曲目结构)
- 测试封面图片优选逻辑(分辨率、文件大小)
- 测试歌词文件同步逻辑
- 测试冲突处理策略
**集成测试**:
- 准备测试数据:
- Staging 目录:新整理的音乐库
- 主库目录:已有部分内容的 Navidrome 库
- 包含升级场景:同一歌曲的低质量与高质量版本
- 包含冲突场景:同路径不同内容
- 测试完整的合并流程
- 验证智能升级策略的准确性
- 验证关联资源(歌词/封面)的同步
- 测试合并结果的完整性
- 测试备份功能(如果启用)
- 测试异常场景:磁盘空间不足、权限不足、文件被占用
#### 6.2 前端测试
**单元测试**:
- 测试源目录与目标目录的路径校验
- 测试合并策略配置的状态管理
- 测试合并结果统计的展示
**集成测试**:
- 测试完整的用户操作流程
- 测试合并进度的实时更新
- 测试冲突与跳过条目的展示
- 测试合并报告的查看
**测试数据**:
- 全新合并场景:主库为空,全部是新增
- 增量合并场景:主库已有内容,部分新增部分升级
- 纯升级场景:所有文件都是已有歌曲的高质量版本
- 边界场景:
- 同一歌曲的多个版本(Live、Remix、不同母带)
- 封面分辨率差异巨大的情况
- 歌词文件编码不一致
- 超大文件合并(测试性能)
**质量验证**:
- 合并后在 Navidrome 中验证:
- 艺术家与专辑列表的完整性
- 歌曲播放的正常性
- 封面显示的正确性
- 歌词显示的正确性
- 验证升级决策的合理性
- 抽查合并前后的文件完整性
**安全性测试**:
- 验证备份机制(如果启用)
- 测试合并失败后的回滚能力
- 测试主库数据不会因合并失败而损坏

View File

@@ -0,0 +1,59 @@
## 07 - 全局配置: 路径配置
### 1. 功能概述
- **功能名称**:全局路径配置
- **核心逻辑**:通过配置一个**全局根目录 (WorkDir)**,自动派生出音频处理流水线(汇聚 -> 转换 -> 去重 -> 繁简转换 -> 整理 -> 入库)中各个阶段所需的标准子目录。
- **设计目标**:一键配置,全流程自动化运行,减少用户在每个环节手动输入路径的操作。
### 2. 全局根路径设计
用户只需在设置界面指定一个 `根路径 (BasePath)`,系统将自动在该路径下维护以下结构:
| 目录名称 | 变量名示例 | 物理路径 (假设根为 `/MusicWork`) | 用途说明 |
| :--- | :--- | :--- | :--- |
| **Input** | `SRC_ACC_DIR` | `/MusicWork/Input` | 默认存放待处理的原始杂乱音频 |
| **Staging_Aggregated** | `DST_ACC_DIR` | `/MusicWork/Staging_Aggregated` | 扁平化汇聚后的核心工作区 |
| **Staging_Format_Issues**| `DST_CONV_ISSUE` | `/MusicWork/Staging_Format_Issues` | 存放转换失败或格式不达标的文件 |
| **Staging_Duplicates** | `DST_DEDUP_TRASH`| `/MusicWork/Staging_Duplicates` | 存放被识别为重复的文件 |
| **Staging_T2S_Output** | `DST_ZH_CONV` | `/MusicWork/Staging_T2S_Output` | 存放完成繁简转换后的文件 |
| **Staging_Organized** | `DST_ORG_DIR` | `/MusicWork/Staging_Organized` | 存放最终按 A-Z 结构整理好的文件 |
| **Library_Final** | `DST_LIB_FINAL` | `/MusicWork/Library_Final` | 最终入库合并的目标主库 |
### 3. 各模块路径映射关系 (Pipeline)
根据流水线顺序,各模块的路径使用逻辑如下:
1. **音频文件汇聚 (01)**
- **源目录**`${ROOT}/Input` (用户可自定义修改,默认从此开始)
- **目标目录**`${ROOT}/Staging_Aggregated` (固定)
2. **音频格式智能处理 (02)**
- **源目录**`${ROOT}/Staging_Aggregated` (固定,使用汇聚后的结果)
- **转换后异常目录**`${ROOT}/Staging_Format_Issues` (固定)
3. **音乐去重 (03)**
- **源目录**`${ROOT}/Staging_Aggregated` (固定)
- **重复文件存放目录**`${ROOT}/Staging_Duplicates` (固定)
4. **元数据繁简转换 (04)**
- **源目录**`${ROOT}/Staging_Aggregated` (固定)
- **转换后输出目录**`${ROOT}/Staging_T2S_Output` (固定)
5. **音乐整理 (05)**
- **源目录**`${ROOT}/Staging_Aggregated` (或根据流程选择输出目录)
- **整理后固定目录**`${ROOT}/Staging_Organized` (固定)
6. **整理入库 (06)**
- **源目录**`${ROOT}/Staging_Organized` (固定,取自音乐整理的输出)
- **主库固定目录**`${ROOT}/Library_Final` (固定)
### 4. 前端交互设计
- **配置入口**:全局设置 (Settings) 页面。
- **交互流程**
1. 用户点击“选择根目录”。
2. 系统展示派生出的子目录预览列表。
3. 点击“保存”,系统自动创建尚未存在的子目录。
4. 各功能页面的路径输入框默认填充上述对应的自动路径。
### 5. 后端实现建议
- **ConfigService**: 负责保存 `BasePath` 并提供获取各子路径的方法(如 `getAggregatedDir()`)。
- **初始化逻辑**: 在保存 `BasePath` 时,调用 `Files.createDirectories()` 确保整个工作流目录结构就绪。
- **路径解析**: 使用 `Paths.get(basePath, subDirName)` 确保跨平台路径兼容。

202
08-路径.md Normal file
View File

@@ -0,0 +1,202 @@
# 路径配置跨平台兼容性优化方案
## 1. 问题背景
在跨平台部署后端服务时不同操作系统Windows、Linux、macOS的路径格式存在差异可能导致路径处理错误。主要问题包括
- 路径分隔符不同Windows使用`\`Linux/macOS使用`/`
- 路径表示方式不同如Windows的盘符C:\与Linux的根目录/
- 相同路径的不同表示形式:如`C:\Users\test``C:/Users/test`
## 2. 优化目标
- 确保路径配置在不同操作系统上都能正确工作
- 统一路径在前端和后端之间的传输格式
- 提高路径处理的健壮性和安全性
- 保持与现有系统功能的兼容性
## 3. 优化方案
### 3.1 前端路径处理优化
#### 3.1.1 路径拼接逻辑
- **修改文件**`frontend/src/components/SettingsTab.vue`
- **优化内容**
- 将所有路径转换为POSIX格式使用`/`作为分隔符)
- 添加路径验证,检查是否包含非法字符
- 确保传递给后端的路径格式统一
#### 3.1.2 核心代码变更
```javascript
// 确保路径使用平台无关的表示方式,统一使用 / 作为分隔符
const normalizedRoot = root.replace(/\\/g, '/');
// 路径验证:检查是否包含非法字符
const invalidChars = /[<>:"|?*]/;
if (invalidChars.test(basePath.value)) {
message.value = { text: '路径包含非法字符,请检查', type: 'error' };
return;
}
```
### 3.2 后端路径处理优化
#### 3.2.1 路径工具类
- **创建文件**`backend/src/main/java/com/music/common/PathUtils.java`
- **核心功能**
- 路径规范化:将不同表示形式的路径转换为统一格式
- 跨平台路径转换支持POSIX格式与平台特定格式互转
- 路径验证:检查路径是否包含非法字符
- 路径拼接:使用平台无关的方式拼接路径
#### 3.2.2 ConfigService优化
- **修改文件**`backend/src/main/java/com/music/service/ConfigService.java`
- **优化内容**
- 在保存配置时验证并规范化basePath
- 在加载配置时规范化basePath
- 确保配置文件中存储的路径格式正确
#### 3.2.3 Config类优化
- **修改文件**`backend/src/main/java/com/music/dto/Config.java`
- **优化内容**
- 确保派生路径使用POSIX格式
- 统一路径分隔符为`/`
## 4. 实现细节
### 4.1 路径工具类核心方法
| 方法名 | 功能描述 |
| :--- | :--- |
| `normalizePath(String path)` | 规范化路径,去除`..`等相对路径部分 |
| `toPosixPath(String path)` | 将路径转换为POSIX格式使用`/` |
| `toPlatformPath(String path)` | 将路径转换为平台特定格式 |
| `isValidPath(String path)` | 验证路径是否合法 |
| `joinPath(String parent, String child)` | 拼接路径,使用平台无关的方式 |
### 4.2 路径验证规则
- 禁止包含以下非法字符:`< > : " | ? *`
- 路径必须是有效的文件系统路径
- 路径长度不能超过系统限制
## 5. 测试方案
### 5.1 单元测试
- **测试文件**`backend/src/test/java/com/music/common/PathUtilsTest.java`
- **测试场景**
- Windows路径规范化
- Linux路径规范化
- 跨平台路径转换
- 路径验证
- 路径拼接
### 5.2 集成测试
- 在不同操作系统上部署服务
- 测试路径配置功能
- 验证配置文件跨平台迁移
### 5.3 测试用例示例
```java
@Test
void testToPosixPath() {
// 测试Windows路径转POSIX路径
String windowsPath = "C:\\Users\\test\\MusicWork";
String posixPath = PathUtils.toPosixPath(windowsPath);
assertEquals("C:/Users/test/MusicWork", posixPath);
}
@Test
void testIsValidPath() {
// 测试合法路径
assertTrue(PathUtils.isValidPath("C:\\Users\\test\\MusicWork"));
// 测试非法路径
assertFalse(PathUtils.isValidPath("C:\\Users\\test\\Music<Work"));
}
```
## 6. 部署与迁移
### 6.1 部署注意事项
- 无需额外配置,优化后的代码会自动处理跨平台路径
- 确保配置文件中的路径格式正确
### 6.2 配置文件迁移
- 旧配置文件会在加载时自动规范化
- 迁移到新平台时,无需手动修改配置文件
## 7. 最佳实践
### 7.1 前端开发
- 始终使用`/`作为路径分隔符
- 在发送路径给后端前,先进行规范化处理
- 添加路径验证,确保路径格式正确
### 7.2 后端开发
- 使用`PathUtils`工具类处理所有路径操作
- 接收前端路径时,先进行规范化处理
- 保存路径时,使用平台无关的格式
## 8. 效果评估
- **兼容性**支持Windows、Linux、macOS等主流操作系统
- **健壮性**:能够处理各种格式的路径
- **安全性**:防止非法路径字符导致的安全问题
- **易用性**:开发人员无需关心平台差异
## 9. 经验教训与优化案例
### 9.1 案例Windows路径非法字符检测问题
#### 问题描述
用户在输入Windows 11路径"Z:\音视频"时,系统提示"路径包含非法字符,请检查"但该路径在Windows系统中是合法的。
#### 根本原因
前端正则表达式`/[<>:"|?*]/`将冒号`:`列为非法字符但在Windows路径中冒号是合法的用于分隔盘符和路径`Z:\音视频`)。
#### 解决方案
1. **前端修复**:修改正则表达式,移除冒号,并在验证前提取路径中的盘符部分
2. **后端同步**确保后端PathUtils类的验证逻辑与前端保持一致
3. **测试用例补充**添加中文路径和Windows盘符路径的测试用例
#### 修复代码示例
```javascript
// 前端修复后的验证逻辑
let pathToValidate = basePath.value;
// 移除盘符部分(如果有)
if (pathToValidate.match(/^[A-Za-z]:/)) {
pathToValidate = pathToValidate.substring(2);
}
const invalidChars = /[<>"|?*]/;
if (invalidChars.test(pathToValidate)) {
message.value = { text: '路径包含非法字符,请检查', type: 'error' };
return;
}
```
### 9.2 经验教训
1. **跨平台兼容性考虑**:在设计路径验证规则时,必须考虑不同操作系统的路径格式差异
2. **正则表达式精确性**避免将合法的路径分隔符如Windows的盘符冒号误判为非法字符
3. **前后端逻辑一致性**:确保前端和后端使用相同的路径验证规则
4. **充分测试**:添加覆盖不同平台、不同路径格式的测试用例
5. **用户友好提示**:提供更具体的错误提示,帮助用户理解问题所在
## 10. 后续优化方向
- 优化路径错误提示,提供更具体的错误信息
- 添加路径长度验证,防止超长路径
- 支持长路径前缀如Windows的`\\?\`
- 考虑添加路径自动修复功能
## 11. 总结
通过对前端和后端路径处理的优化,解决了跨平台部署时的路径兼容性问题。优化后的系统能够:
- 自动处理不同平台的路径格式
- 统一前端和后端之间的路径传输格式
- 正确处理Windows路径中的盘符冒号
- 支持中文路径
- 提高路径处理的健壮性和安全性
- 保持与现有系统功能的兼容性
这将使后端服务能够在不同操作系统上无缝部署和运行,提高了系统的可移植性和可靠性。通过本次修复案例,我们也积累了宝贵的跨平台路径处理经验,为未来的系统优化奠定了基础。