diff --git a/README.md b/README.md index 9784b1b..0623ee6 100644 --- a/README.md +++ b/README.md @@ -111,7 +111,7 @@ ### 10. Subsonic 协议与全网检索支持 -全面适配 Subsonic 协议,支持使用各类 Subsonic 客户端(如音流、Feishin 等)连接并播放本站资源。支持在 Subsonic 客户端中通过 `wy:`, `kg:`, `tx:`, `kw:`, `mg:` 等指定平台前缀,或 `online:` / `local:` 强制指定全网在线或本地搜索。 +全面适配 Subsonic 协议,支持使用各类 Subsonic 客户端(如音流、Feishin 等)连接并播放本站资源。可通过客户端的音乐目录选择本地、全部在线或指定平台,也可在关键词前使用 `wy:`、`kg:`、`tx:`、`kw:`、`mg:` 指定平台,使用 `all:` / `online:` 或 `local:` 强制全部在线或本地搜索。
@@ -210,8 +210,8 @@ services:
# - FRONTEND_PASSWORD=123456
# - ENABLE_WEBPLAYER_AUTH=true
# - WEBPLAYER_PASSWORD=yourpassword
- # - ADMIN_PATH=
- # - PLAYER_PATH=/music
+ # - ADMIN_PATH=/music
+ # - PLAYER_PATH=/
```
### 方式三:直接运行 (Git Clone)
@@ -235,8 +235,8 @@ npm start
### 3. 访问说明
-- **Web 播放器**: `http://your-ip:9527` (默认根路径,可通过 `PLAYER_PATH` 修改)
-- **同步管理后台**: `http://your-ip:9527/admin` (默认路径 `/admin`,可通过 `ADMIN_PATH` 修改,默认密码: `123456`)
+- **Web 播放器**: `http://your-ip:9527` (默认路径,可通过 `PLAYER_PATH` 修改)
+- **同步管理后台**: `http://your-ip:9527/music` (默认路径,可通过 `ADMIN_PATH` 修改,默认密码: `123456`)
---
@@ -246,7 +246,7 @@ npm start
- **Backend (Express + WebSocket)**: 核心同步逻辑与 WebDAV 备份。
- **WebPlayer (Vanilla JS)**: 负责音乐播放业务,默认访问路径为根路径 `/`。
-- **Console (Vanilla JS)**: 位于 `/admin` 路径,负责用户与数据管理。
+- **Console (Vanilla JS)**: 位于 `/music` 路径,负责用户与数据管理。
---
@@ -258,8 +258,8 @@ npm start
| --------------------------------------- | ------------------------------------ | ------------------------------------------------------------------ | ------------------ |
| `PORT` | `port` | 服务端口 | `9527` |
| `BIND_IP` | `bindIP` | 绑定 IP | `0.0.0.0` |
-| `ADMIN_PATH` | `admin.path` | 后台管理界面访问路径 (默认为 `/admin`) | `/admin` |
-| `PLAYER_PATH` | `player.path` | Web 播放器访问路径 (默认为空,即根路径 `/`) | (空) |
+| `ADMIN_PATH` | `admin.path` | 后台管理界面访问路径 | `/music` |
+| `PLAYER_PATH` | `player.path` | Web 播放器访问路径 (默认为根路径 `/`) | `/` |
| `SUBSONIC_ENABLE` | `subsonic.enable` | 是否启用 Subsonic 协议支持 (服务默认开启) | `true` |
| `SUBSONIC_PATH` | `subsonic.path` | Subsonic 访问路径 (默认为 `/rest`) | `/rest` |
| `FRONTEND_PASSWORD` | `frontend.password` | Web 管理界面访问密码 | `123456` |
diff --git a/changelog.md b/changelog.md
index 386be08..1c1d7a0 100644
--- a/changelog.md
+++ b/changelog.md
@@ -2,6 +2,22 @@
## v2.0.1 (2026-07-23)
+### 🌟 新增功能
+
+- **Subsonic 歌单管理接口补全 (#311)**:
+ - **歌单增删改支持**: 实现 `createPlaylist`、`deletePlaylist`,并补全 `updatePlaylist` 的歌曲添加、删除、改名及位置调整能力;兼容重复参数、逗号分隔参数与 `songIdToAdd`、`songIndexToAdd` 等常用客户端调用方式。
+ - **数据持久化与添加位置**: Subsonic 歌单变更后自动创建快照,并统一遵循用户的 `LIST_ADD_MUSIC_LOCATION_TYPE` 配置。
+- **Subsonic 多平台搜索增强**:
+ - **搜索范围选择**: 音乐目录新增本地曲库、全部在线平台及网易云、QQ、酷我、酷狗、咪咕等独立平台入口;关键词支持 `all:` / `online:`、`local:` 及各平台前缀搜索。
+ - **稳定分页结果**: 对多平台结果进行交错合并与短期缓存,避免客户端翻页时出现重复、跳项或搜索结果不全。
+- **Web 播放器歌单操作增强**:
+ - **全列表快捷收藏**: 搜索结果、收藏歌曲、歌单详情、排行榜、本地音乐、缓存与下载任务、歌手及专辑歌曲等位置均可直接添加到歌单。
+ - **加入状态预检查**: 打开歌单选择器时先检查歌曲是否已存在;未加入的歌单保持默认绿色样式,已存在的歌单显示红色对号,添加后保持当前列表页码。
+ - **歌单导出**: 支持将默认列表、收藏列表及自定义歌单导出为本地 JSON 文件。
+- **列表分页与后台入口**:
+ - **首页与末页快捷跳转**: 搜索、收藏、歌单广场、排行榜、本地音乐及歌手歌曲列表新增首页和末页按钮,并根据总页数更新可用状态。
+ - **后台快捷菜单**: Web 播放器侧边栏新增后台管理入口。
+
### 🔧 修复与优化
- **非管理员下载与缓存权限独立控制 (#284)**:
@@ -17,6 +33,16 @@
- **下拉选择器布局修复**: 「歌词字体」选择器与「读取」按钮、「播放失败策略优先级」等下拉项改用 `flex items-center justify-between`,手机和电脑上按钮均固定显示在下拉框右侧,不再单独折行。
- **设置面板底部安全距离**: 系统、显示、逻辑三个设置 Tab 页底部新增移动端安全间距,防止最后一项内容被手机浏览器底部导航栏遮挡,确保「后台管理」等按钮可正常点击。
- **弹出提示气泡防溢出**: 设置项问号图标的悬浮提示气泡新增视口边缘检测,显示时自动计算并修正横向偏移,防止气泡内容超出屏幕左右边缘显示不全。
+- **播放失败自动恢复**:
+ - **异常暂停自动换源**: 修复解析到播放地址后播放器停留在“暂停中”且不继续换源的问题;播放异常暂停或地址加载失败时自动进入恢复流程。
+ - **连续换源尝试**: 修复首次跨平台切换失败后恢复流程提前结束的问题,能够继续尝试尚未使用的可用平台。
+- **歌曲添加位置配置修复**:
+ - **底部添加配置生效**: 修复 `LIST_ADD_MUSIC_LOCATION_TYPE=bottom` 在 Web 播放器及服务端歌单接口中不生效的问题,未显式指定位置时统一读取用户配置。
+- **歌曲删除与分页状态修复**:
+ - **令牌认证兼容**: 修复已使用令牌登录但未保存明文密码时无法从列表删除歌曲的问题,并在认证失效后自动刷新令牌重试。
+ - **保持当前页**: 添加或删除歌曲后刷新当前列表数据,不再自动跳回第一页。
+- **默认访问路径调整**:
+ - **播放器作为首页**: 默认 `PLAYER_PATH` 调整为 `/`,访问域名直接进入 Web 播放器;后台管理默认迁移到 `/music`,并同步更新管理界面、配置示例及中英文文档。
## v2.0.0 (2026-07-22)
diff --git a/config.js b/config.js
index 20ae1dd..453a8b4 100644
--- a/config.js
+++ b/config.js
@@ -73,7 +73,7 @@ module.exports = {
// 环境变量: MAX_SNAPSHOT_NUM
"maxSnapshotNum": 10,
- // 添加歌曲到列表时的位置 (top: 顶部, bottom: 底部)
+ // 添加歌曲到列表时的位置,Web 播放器与 Subsonic API 均使用此配置 (top: 顶部, bottom: 底部)
// 环境变量: LIST_ADD_MUSIC_LOCATION_TYPE
"list.addMusicLocationType": "top",
@@ -144,13 +144,13 @@ module.exports = {
// 环境变量: PROXY_ALL_ADDRESS (例如: http://127.0.0.1:7890)
"proxy.all.address": "",
- // 后台管理界面访问路径(默认为 /admin)
+ // 后台管理界面访问路径(默认为 /music)
// 环境变量: ADMIN_PATH
- "admin.path": "/admin",
+ "admin.path": "/music",
- // Web播放器访问路径(默认为空,即根路径 /)
+ // Web播放器访问路径(默认为根路径 /)
// 环境变量: PLAYER_PATH
- "player.path": "",
+ "player.path": "/",
// Subsonic 协议配置
// 是否启用 Subsonic 协议支持 (服务默认开启)
@@ -199,4 +199,4 @@ module.exports = {
// 是否允许运行 VM 模式自定义源脚本 (默认关闭)
// 环境变量: SYSTEM_ALLOW_UNSAFE_VM
"system.allowUnsafeVM": false
-}
\ No newline at end of file
+}
diff --git a/docs/en/guide/configuration.md b/docs/en/guide/configuration.md
index 97394fa..06c039a 100644
--- a/docs/en/guide/configuration.md
+++ b/docs/en/guide/configuration.md
@@ -28,8 +28,8 @@ This module manages the Node.js listening process and the basic settings of the
| :-------------------- | :------------ | :------- | :-------------------------------------------------------------------------------------------------------------------------------------------------- |
| `PORT` | `9527` | Integer | **Service listening port**. It is recommended to avoid using other high-frequency ports in the host (such as 80, 443, 3306). |
| `BIND_IP` | `0.0.0.0` | String | **Scope of service binding IP interfaces**. Set to `127.0.0.1` to accept only local Lookback calls; set to `0.0.0.0` means listening to all internal and external available network adapters of the host simultaneously. |
-| `ADMIN_PATH` | `'/admin'` | String | **Backend management interface path**. Default is `/admin`. |
-| `PLAYER_PATH` | `''` | String | **Web player access path**. Default is empty, i.e., root `/`. |
+| `ADMIN_PATH` | `'/music'` | String | **Backend management interface path**. Default is `/music`. |
+| `PLAYER_PATH` | `'/'` | String | **Web player access path**. Default is the root path `/`. |
| `SERVER_NAME` | `My Sync Server` | String | **Sync service name**. Showed in client connections. |
| `PROXY_HEADER` | `x-real-ip` | String | **Reverse proxy remote IP penetration identifier**. When the system runs behind reverse proxies or load balancers such as Nginx, it is used to extract the true client source IP address to ensure accurate traceability of equipment audit logs. |
| `PROXY_ALL_ENABLED` | `false` | Boolean | **Enable global outgoing request proxy**. If enabled, network requests from the server (e.g. search, resolving) will go through the proxy. |
diff --git a/docs/guide/configuration.md b/docs/guide/configuration.md
index 944d053..57e2e03 100644
--- a/docs/guide/configuration.md
+++ b/docs/guide/configuration.md
@@ -28,8 +28,8 @@ LX Music Sync Server 构建了统一的基础模型骨架(位于 `src/defaultC
| :-------------------- | :------------ | :------- | :-------------------------------------------------------------------------------------------------------------------------------------------------- |
| `PORT` | `9527` | Integer | **服务监听端口**。建议避免使用主机中其他高频占用的端口(如 80、443、3306)。 |
| `BIND_IP` | `0.0.0.0` | String | **服务绑定的 IP 接口范围**。设定为 `127.0.0.1` 仅接受本机 Lookback 调用;设定为 `0.0.0.0` 意味着同时监听主机所有内外部可用网络适配器。 |
-| `ADMIN_PATH` | `'/admin'` | String | **后台管理界面访问路径**。默认为 `/admin`。 |
-| `PLAYER_PATH` | `''` | String | **Web 播放器访问路径**。默认为空(即根路径 `/`)。 |
+| `ADMIN_PATH` | `'/music'` | String | **后台管理界面访问路径**。默认为 `/music`。 |
+| `PLAYER_PATH` | `'/'` | String | **Web 播放器访问路径**。默认为根路径 `/`。 |
| `SERVER_NAME` | `My Sync Server` | String | **同步服务名称**。在客户端连接时显示的服务器标识名称。 |
| `PROXY_HEADER` | `x-real-ip` | String | **逆向代理远端 IP 穿透标识**。当系统运行于 Nginx 等反向代理或负载均衡器后方时,用于提取客户端真实的源端 IP 地址,保障设备审计日志的准确溯源。 |
| `PROXY_ALL_ENABLED` | `false` | Boolean | **启用全局外发请求代理**。开启后,服务端发起的网络请求(如搜索、播放链接解析)将通过指定的代理服务器。 |
diff --git a/package.json b/package.json
index 8f8cd7c..2b338ce 100644
--- a/package.json
+++ b/package.json
@@ -5,6 +5,7 @@
"scripts": {
"prebuild": "node scripts/download-binary.js && node scripts/update-build-hash.js",
"build": "rimraf server && tsc --project tsconfig.json && tsc-alias -p tsconfig.json",
+ "test": "node --test test/*.test.cjs",
"prestart": "node scripts/download-binary.js && node scripts/update-build-hash.js",
"start": "node ./index.js",
"predev": "node scripts/update-build-hash.js",
diff --git a/public/app.js b/public/app.js
index 612a2c7..986de35 100644
--- a/public/app.js
+++ b/public/app.js
@@ -319,7 +319,7 @@ class App {
window.location.href = 'filemanager.html';
return;
case 'music':
- window.location.href = (window.CONFIG && window.CONFIG['player.path']) || '/music';
+ window.location.href = (window.CONFIG && window.CONFIG['player.path']) || '/';
return;
}
}
@@ -1785,13 +1785,13 @@ class App {
form.elements['admin.path'].value = config['admin.path'] ?? '';
}
if (form.elements['player.path']) {
- const pPath = config['player.path'] ?? '/music';
+ const pPath = config['player.path'] ?? '/';
form.elements['player.path'].value = pPath === '' ? '/' : pPath;
}
// [新增] 同时更新侧边栏链接
const navPlayerLink = document.getElementById('nav-player-link');
- if (navPlayerLink) navPlayerLink.href = (config['player.path'] === '' ? '/' : (config['player.path'] ?? '/music'));
+ if (navPlayerLink) navPlayerLink.href = (config['player.path'] === '' ? '/' : (config['player.path'] ?? '/'));
// Subsonic 配置
if (form.elements['subsonic.enable']) {
@@ -1922,7 +1922,7 @@ class App {
// 更新侧边栏播放器链接
const navPlayerLink = document.getElementById('nav-player-link');
- if (navPlayerLink) navPlayerLink.href = playerPath === '' ? '/' : (playerPath ?? '/music');
+ if (navPlayerLink) navPlayerLink.href = playerPath === '' ? '/' : (playerPath ?? '/');
if (!silent) {
if (res.warning) {
diff --git a/public/index.html b/public/index.html
index 2e19c6d..9af1554 100644
--- a/public/index.html
+++ b/public/index.html
@@ -1044,8 +1044,11 @@
wy:歌名 / tx:歌名 ➔ 客户端搜索框输入前缀可强制在线搜索平台
+ 💡 Subsonic 客户端搜索:直接输入歌曲名时使用上方“默认在线搜索模式”。也可在搜索框中使用以下前缀:all:歌名 / online:歌名:搜索全部已启用在线平台local:歌名:只搜索本地歌单wy:歌名、tx:歌名、kw:歌名、kg:歌名、mg:歌名:指定网易、QQ、酷我、酷狗或咪咕