-[Documentation](https://xcq0607.github.io/lxserver/) | [SyncServer](md/lxserver_EN.md) | [Changelog](changelog.md) | [中文版](README.md)
+[SyncServer](md/lxserver_EN.md) | [Changelog](changelog.md) | [中文版](README.md)
---
This project features a powerful built-in **Web Player**, allowing you to enjoy music anywhere in your browser. It also serves as an enhanced [LX Music Data Sync Server](md/lxserver_EN.md).
@@ -117,6 +117,20 @@ When **"Enable Public Favorites and Songs"** is enabled in the backend settings,
+### 12. WebDAV / OpenList Music Mounting
+
+Mount **WebDAV** cloud drives (Nutstore, Nextcloud, Alist, etc.) and **OpenList (AList)** servers directly, seamlessly integrating your remote music library into the player:
+
+- **Multiple mount sources**: Configure multiple WebDAV mounts and OpenList servers at once, with connection testing and enable/disable.
+- **Directory tree & one-click add**: Embedded **WebDAV Directory** / **OpenList Directory** panels in the Local Music manager let you browse the remote directory tree and add audio to playlists in one click.
+- **Play-while-caching**: Remote audio is automatically downloaded to the local cache during playback, managed granularly via the cache control panel — smooth playback even on weak networks.
+- **Directory indexing & merged list**: Audio files under mounted directories are scanned automatically and merged into the local music main list for direct search and playback.
+- **Lyrics support**: `.lrc` lyrics files in the same directory are read automatically and displayed during playback.
+
+
+
+
+
## 🔒 Access Control & Security
To protect your privacy, the Web Player supports password protection.
### How to Enable
@@ -142,14 +156,58 @@ The Web Player is deeply optimized for mobile devices, providing a native App-li
## 🚀 Quick Start
-Built with **Node.js**, supporting multiple deployment methods.
+Built with **Node.js**, supporting multiple deployment methods. For NAS / VPS, **Docker Compose** is the recommended one-click deployment.
+
+### Option 1: NAS / Docker Compose One-Click Deployment (Recommended)
+
+Works on FeiNiu NAS, Synology NAS, and any Docker-capable host. This repo ships with `Dockerfile` and `docker-compose.yml`, so you can build and run directly.
+**Migrate existing data (optional)**: If you already have runtime data (users, OpenList, card keys, cloud drive config, cache), run the migration script first:
-### Option 1: Desktop Client
+```bash
+# Generates lxserver-nas-deploy.tar.gz (cleaned config.js + full data/)
+bash scripts/migrate-to-nas.sh
+```
+
+**Fresh install / migration, common steps:**
+
+```bash
+# 1. Put the project code in a fixed NAS directory
+mkdir -p /vol1/docker/lxserver
+# (for migration, extract the deploy package here as well)
+tar -xzf lxserver-nas-deploy.tar.gz -C /vol1/docker/lxserver
+
+# 2. Build and start (first build compiles TS, ~5-15 min)
+cd /vol1/docker/lxserver && docker compose up -d --build
+
+# 3. Access
+# Sync Dashboard: http://:9527/
+# Web Player: http://:9527/music/
+```
+
+> **Notes**:
+> - If the port is taken, change the left-hand host port under `ports` in `docker-compose.yml` (e.g. `"9000:9527"`).
+> - All data (users, OpenList, cloud drive config, cache) persists in `./data` — **backing up is just copying that directory**.
+> - Common env vars (higher priority than `config.js`) are documented as comments in `docker-compose.yml`: `LX_USER_` to add users, `FRONTEND_PASSWORD` for dashboard password, `ENABLE_WEBPLAYER_AUTH` / `WEBPLAYER_PASSWORD` for player password, `WEBDAV_URL` etc. to enable WebDAV sync.
+
+### Option 2: Manual Run (Git Clone)
+
+```bash
+# 1. Clone project
+git clone https://github.com/boy6656598/lxserver.git && cd lxserver
+
+# 2. Install dependencies and build
+npm ci && npm run build
+
+# 3. Start service
+npm start
+```
+
+### Option 3: Desktop Client
You can now run LX Music Sync Server more conveniently via our Desktop Client, available for Windows, macOS, and Linux.
-- **📦 Download Latest**: [GitHub Releases](https://github.com/XCQ0607/lxserver/releases/latest)
+- **📦 Download Latest**: [GitHub Releases](https://github.com/boy6656598/lxserver/releases/latest)
- **✨ Key Advantages**:
- **Single Window**: Integrated management dashboard and Web player for a unified experience.
- **System Tray**: Minimizes to tray on close, ensuring the sync service stays active in the background.
@@ -157,13 +215,9 @@ You can now run LX Music Sync Server more conveniently via our Desktop Client, a
- **Setup Wizard**: Guided data path selection on first launch, supports **Portable Mode**.
- **Multi-Arch Support**: Builds for Windows (x64/x86/ARM64 Setup & Portable), macOS (Intel x64 & Apple Silicon arm64), and Linux (amd64/arm64/armv7l deb/AppImage).
-### Option 2: Containerized Deployment via Docker
-
-This project supports pulling images from Docker Hub or GitHub Packages:
-- **Docker Hub**: `xcq0607/lxserver:latest`
-- **GitHub Packages**: `ghcr.io/xcq0607/lxserver:latest`
+### Option 4: Containerized Deployment via Docker
-**Docker Run Example:**
+> Image published on **GitHub Container Registry** (see below for building your own / publishing to Docker Hub):
```bash
docker run -d \
@@ -174,59 +228,39 @@ docker run -d \
-v $(pwd)/music:/server/music \
--name lx-sync-server \
--restart unless-stopped \
- xcq0607/lxserver:latest
+ ghcr.io/boy6656598/lxserver:latest
```
-**Docker Compose Example:**
-
-Create a `docker-compose.yml` file:
-
-```yaml
-version: '3'
-services:
- lx-sync-server:
- image: xcq0607/lxserver:latest
- container_name: lx-sync-server
- restart: unless-stopped
- ports:
- - "9527:9527"
- volumes:
- - ./data:/server/data
- - ./logs:/server/logs
- - ./cache:/server/cache
- - ./music:/server/music
- environment:
- - NODE_ENV=production
- # - FRONTEND_PASSWORD=123456
- # - ENABLE_WEBPLAYER_AUTH=true
- # - WEBPLAYER_PASSWORD=yourpassword
- # - ADMIN_PATH=
- # - PLAYER_PATH=/music
-```
-
-### Option 3: Manual Run (Git Clone)
+**Build the image from source (for customization or publishing to Docker Hub):**
```bash
-# 1. Clone project
-git clone https://github.com/XCQ0607/lxserver.git && cd lxserver
-
-# 2. Install dependencies and build
-npm ci && npm run build
-
-# 3. Start service
-npm start
+docker build -t lxserver .
+docker run -d \
+ -p 9527:9527 \
+ -v $(pwd)/data:/server/data \
+ -v $(pwd)/logs:/server/logs \
+ -v $(pwd)/cache:/server/cache \
+ -v $(pwd)/music:/server/music \
+ --name lx-sync-server \
+ --restart unless-stopped \
+ lxserver
```
-### Option 4: Using Release Build
+### Option 5: Using Release Build
1. Download the archive from GitHub Releases.
2. Extract and run `npm install --production`.
3. Execute `npm start`.
-### 3. Access Info
+### Synology Package (SPK)
+
+Synology users can also use the bundled SPK packaging (`packaging/synology-spk/`) for DSM 7 manual install, see [packaging/synology-spk/README.md](packaging/synology-spk/README.md).
+
+### Access Info
-- **Web Player**: `http://your-ip:9527/music` (Default path, configurable via `PLAYER_PATH`)
- **Sync Dashboard**: `http://your-ip:9527` (Default path, configurable via `ADMIN_PATH`, default password: `123456`)
+- **Web Player**: `http://your-ip:9527/music` (Default path, configurable via `PLAYER_PATH`)
+- **Subsonic**: `http://your-ip:9527/rest` (connectable by YinLiu, Feishin and other clients)
---
@@ -302,6 +336,19 @@ Some advanced options are only configurable by directly editing `config.js`:
> **Note**: The service currently supports two types of sync connection URLs: `Root Path` (URL configuration is `ip:port`) and `User Path` (URL configuration is `ip:port/username`). If the User Path is disabled, all sync user passwords must be completely unique.
+### 🎵 WebDAV / OpenList Music Mounting Config
+
+The music mounting feature is configured inside the **Web Player** (`/music`), with data persisted in the `./data` directory:
+
+| Data File | Description |
+| --- | --- |
+| `./data/webdav-mounts.json` | WebDAV mount source config (URL, credentials, root path, etc.) |
+| `./data/openlist.json` | OpenList server config |
+
+- **WebDAV mount**: Enter the WebDAV URL (e.g. `https://dav.example.com/music`, may include the root directory path), username and password; optionally set a root path and test the connection.
+- **OpenList server**: Enter the AList service URL, path prefix and access token (anonymous access optional).
+- Once enabled, the Web Player automatically scans remote audio, merges it into the local music list, and supports directory browsing, play-while-caching and same-directory lyrics.
+
---
## 🛡️ Data Collection & Privacy
@@ -324,29 +371,17 @@ Anonymous telemetry via PostHog is used for:
### 👥 Contributors
-
-
+
+
-## 📈 Star History
-
-
-
-
-
-
-
-
-
-
-
----
+## 📄 Open Source License---
## 📄 License
This project is released under the Apache License 2.0. The following agreement is a supplement to the Apache License 2.0. In case of conflict, this agreement shall prevail.
-Apache License 2.0 copyright (c) 2026 [xcq0607](https://github.com/xcq0607)
+Apache License 2.0 copyright (c) 2026 [boy6656598](https://github.com/boy6656598)
**Terminology**: "This Project" refers to LX Music Web Player; "User" refers to the user who agrees to this agreement; "Official Music Platforms" refers to the collective official platforms of the music sources built into this project, including Kuwo, Kugou, Migu, etc.; "Copyrighted Data" refers to data owned by others, including but not limited to images, audio, names, etc.
diff --git a/changelog.md b/changelog.md
index 9f50f5f1..2a3858ce 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,35 @@
# Changelog
+## v3.0.1 (2026-08-09)
+
+### 🌟 新增功能
+
+- **WebDAV 音乐挂载 (@bobcc4)**:
+ - **边播边缓存**: 挂载远程 WebDAV 音乐目录后,首次播放同时写入本地缓存,之后播放/拖拽秒开。
+ - **目录歌单**: 自动扫描挂载目录生成音乐列表,支持目录树浏览与收藏,收藏恢复播放无需重新连接。
+ - **连接自检**: 支持多挂载源,密码脱敏保存,连接失败友好提示。
+- **OpenList 音乐整合 (@bobcc4)**:
+ - **目录扫描**: 递归扫描 OpenList 网盘音乐目录并合并到本地音乐列表,内置目录树面板。
+ - **收藏与播放**: 收藏歌曲按 `url/serverId/path/sign` 恢复播放,`/d/` 直链 302 自动跟随,sign 过期实时刷新。
+- **Subsonic 客户端播放挂载音乐 (@bobcc4)**:
+ - 音流、Feishin 等 Subsonic 客户端可直接播放 WebDAV/OpenList 挂载音乐(内部流路由,支持 GET/HEAD/Range)。
+ - 播放路径归一化:兼容收藏中固化的路径与实时索引在「多斜杠、URL 编码」上的差异,索引匹配失败时兜底解析歌单固化播放地址。
+- **挂载歌曲同目录 .lrc 歌词 (@bobcc4)**:
+ - `getLyricsBySongId`/`getLyrics` 支持读取 WebDAV/OpenList 挂载音乐同目录的同名 `.lrc` 歌词文件。
+ - **编码自适应**: UTF-8 与 GBK/GB18030 自动识别(iconv-lite 解码),兼容 Docker/Alpine 环境。
+- **卡密注册与强制登录 (@bobcc4)**:
+ - 支持卡密批量生成、激活与导出;开启强制登录后未登录用户无法访问播放器。
+ - 新增用户管理、数据快照回滚、WebDAV 同步/备份等管理功能完善。
+
+### 🐛 修复
+
+- **OpenList 播放卡死**: 修复 needle 3.x 流式代理在约 130KB 后卡死的 bug,改用原生 http/https 转发。
+- **WebDAV/OpenList 歌曲无法播放**: 修复 Subsonic 客户端与刷新页面后的播放源丢失、路径翻倍问题。
+- **出站连接**: 强制 DNS 优先 IPv4;容器内自动解析 `host.docker.internal` 访问宿主机 Alist/WebDAV。
+- **Docker 镜像**: 排除 `downloads` 目录(APK 等下载物),避免镜像膨胀与误同步。
+
+---
+
## v2.0.0 (2026-07-22)
### 🌟 新增功能
diff --git a/config.js b/config.js
deleted file mode 100644
index 2bad39c8..00000000
--- a/config.js
+++ /dev/null
@@ -1,194 +0,0 @@
-/**
- * 配置文件
- * 配置优先级:WEBDAV备份数据 > 环境变量 > config.js (本文件) > src/defaultConfig.ts (默认配置)
- */
-module.exports = {
- // 同步服务名称
- // 环境变量: SERVER_NAME
- "serverName": "lxserver",
-
- // 是否使用代理转发请求到本服务器 (如果配置了 proxy.header,此项会自动设为 true)
- // 环境变量: 无 (通过 PROXY_HEADER 隐式开启)
- "proxy.enabled": false,
-
- // 代理转发的请求头 原始IP
- // 环境变量: PROXY_HEADER
- "proxy.header": "x-real-ip",
-
- // 服务绑定IP (0.0.0.0 允许外网访问,127.0.0.1 仅限本机)
- // 环境变量: BIND_IP
- "bindIP": "0.0.0.0",
-
- // 服务监听端口
- // 环境变量: PORT
- "port": 9527,
-
- // 是否开启用户路径 (baseurl/用户名)
- // 开启后连接URL需包含用户名,允许不同用户使用相同密码。关闭后仅使用密码鉴权,要求所有用户密码唯一。
- // 环境变量: USER_ENABLE_PATH (true/false)
- "user.enablePath": true,
-
- // 是否开启根路径 (baseurl)
- // 开启后连接URL即为根路径,不允许不同用户使用相同密码。
- // 环境变量: USER_ENABLE_ROOT (true/false)
- "user.enableRoot": false,
-
- // 是否启用公开用户权限限制 (开启后将限制公开用户的某些敏感操作,如上传、删除自定义源)
- // 环境变量: ENABLE_PUBLIC_USER_RESTRICTION (true/false)
- "user.enablePublicRestriction": true,
-
- // 是否开启公开收藏和歌曲 (开启后允许公开/未登录用户查看及播放公开收藏列表)
- // 环境变量: ENABLE_PUBLIC_FAVORITES (true/false)
- "user.enablePublicFavorites": false,
-
- // 是否开启非管理员访问本地音乐 (开启后允许未登录管理员的公开账号访问本地音乐)
- // 环境变量: ENABLE_PUBLIC_NON_ADMIN_LOCAL_MUSIC (true/false)
- "user.enablePublicNonAdminLocalMusic": false,
-
- // 是否开启非管理员访问公开收藏和歌曲 (开启后允许未登录管理员的公开账号查看公开收藏和歌曲)
- // 环境变量: ENABLE_PUBLIC_NON_ADMIN_ACCESS (true/false)
- "user.enablePublicNonAdminAccess": false,
-
- // 是否启用登录用户缓存限制 (开启后将限制非管理员登录用户的核心缓存设置)
- // 环境变量: ENABLE_LOGIN_USER_CACHE_RESTRICTION (true/false)
- "user.enableLoginCacheRestriction": false,
-
- // 是否启用缓存空间限制 (开启后超出容量将按 LRU 自动清理)
- // 环境变量: ENABLE_CACHE_SIZE_LIMIT (true/false)
- "user.enableCacheSizeLimit": false,
-
- // 缓存空间限制大小 (单位: MB)
- // 环境变量: CACHE_SIZE_LIMIT
- "user.cacheSizeLimit": 2000,
-
- // 最大快照数 (用于数据回滚)
- // 环境变量: MAX_SNAPSHOT_NUM
- "maxSnapshotNum": 10,
-
- // 添加歌曲到列表时的位置 (top: 顶部, bottom: 底部)
- // 环境变量: LIST_ADD_MUSIC_LOCATION_TYPE
- "list.addMusicLocationType": "top",
-
- // 是否禁用数据收集
- // 环境变量: DISABLE_TELEMETRY (true/false)
- // 说明:仅收集版本号、运行环境(Docker/Node)、OS类型等非敏感信息用于项目改进。绝对匿名,不收集IP。
- "disableTelemetry": false,
-
- // 前端管理控制台访问密码
- // 环境变量: FRONTEND_PASSWORD
- "frontend.password": "123456",
-
- // 用户列表
- // 环境变量: LX_USER_<用户名>=<密码> (例如: LX_USER_user1=123456)
- "users": [
- {
- "name": "admin",
- "password": "password"
- }
- ],
-
- // WebDAV 同步配置 (可选,用于数据备份)
- // 是否启用 WebDAV 同步与备份
- // 环境变量: WEBDAV_ENABLE (true/false)
- "webdav.enable": false,
-
- // WebDAV 服务地址
- // 环境变量: WEBDAV_URL
- "webdav.url": "",
-
- // WebDAV 用户名
- // 环境变量: WEBDAV_USERNAME
- "webdav.username": "",
-
- // WebDAV 密码
- // 环境变量: WEBDAV_PASSWORD
- "webdav.password": "",
-
- // WebDAV 增量同步远端路径
- // 环境变量: WEBDAV_SYNC_PATH
- "webdav.syncPath": "/lx-sync",
-
- // WebDAV 全量备份远端路径
- // 环境变量: WEBDAV_BACKUP_PATH
- "webdav.backupPath": "/lx-sync-backups",
-
- // 同步检测间隔 (分钟)
- // 环境变量: SYNC_INTERVAL
- "sync.interval": 60,
-
- // 全量备份间隔 (小时)
- // 环境变量: BACKUP_INTERVAL
- "sync.backupInterval": 24,
-
- // 是否启用 Web播放器 访问密码
- // 环境变量: ENABLE_WEBPLAYER_AUTH (true/false)
- "player.enableAuth": false,
-
- // Web播放器 访问密码
- // 环境变量: WEBPLAYER_PASSWORD
- "player.password": "123456",
-
- // 是否启用针对所有外发的请求代理 (目前主要用于离线音源的播放链接获取)
- // 环境变量: PROXY_ALL_ENABLED (true/false)
- "proxy.all.enabled": false,
-
- // 代理地址 (支持 http:// 或 socks5://)
- // 环境变量: PROXY_ALL_ADDRESS (例如: http://127.0.0.1:7890)
- "proxy.all.address": "",
-
- // 后台管理界面访问路径(默认为空,即根路径 /)
- // 环境变量: ADMIN_PATH
- "admin.path": "",
-
- // Web播放器访问路径(默认为 /music)
- // 环境变量: PLAYER_PATH
- "player.path": "/music",
-
- // Subsonic 协议配置
- // 是否启用 Subsonic 协议支持 (服务默认开启)
- // 环境变量: SUBSONIC_ENABLE
- "subsonic.enable": true,
-
- // Subsonic 访问路径 (默认为 /rest)
- // 环境变量: SUBSONIC_PATH
- "subsonic.path": "/rest",
-
- // 是否开启 Subsonic 调试日志模式
- // 环境变量: 无
- "subsonic.enableDebug": true,
-
- // 是否开启 Subsonic 在线全网搜索
- // 环境变量: 无
- "subsonic.onlineSearch": true,
-
- // Subsonic 在线搜索模式 (fallback: 回退模式, merge: 合并模式, local_only: 仅本地)
- // 环境变量: 无
- "subsonic.onlineSearchMode": "fallback",
-
- // Subsonic 在线搜索默认平台
- // 环境变量: 无
- "subsonic.onlineSearchSources": "wy,tx,kw,kg,mg",
-
- // 是否在 Subsonic 歌词中包含翻译
- // 环境变量: 无
- "subsonic.lyricTranslation": true,
-
- // 歌手信息源优先级 (多个源用逗号分隔,如 tx,wy)
- // 环境变量: SINGER_SOURCE_PRIORITY
- "singer.sourcePriority": [
- "tx",
- "wy"
- ],
-
- // 歌手歌曲最大抓取页数
- // 环境变量: 无
- "artist.maxFetchPages": 20,
-
- // 缓存文件命名规则 (simple / custom)
- // 环境变量: 无
- "cache.namingPattern": "simple",
-
- // 是否允许运行 VM 模式自定义源脚本 (默认关闭)
- // 环境变量: 无
- "system.allowUnsafeVM": false
-}
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
index f3b03212..8f7555a8 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,17 +1,74 @@
-version: '3.8'
+# lxserver 同步服务器 - Docker Compose 配置(适用于飞牛 NAS / 群晖 / 任意 Docker 主机)
+# 使用步骤:
+# 1. 将本项目代码放到 NAS 固定目录, 如 /vol1/docker/lxserver
+# 2. 将迁移生成的 config.js 与 data/ 目录放至同一目录(可省略, 首次启动会自动生成默认配置)
+# 3. docker compose up -d --build
+# 4. 浏览器访问 http://:9527/ (后台) 与 http://:9527/music/ (播放器)
+#
+# 注意:
+# - 构建耗时较长(需编译 TS 并下载 fpcalc), 首次启动约 5-15 分钟
+# - 所有数据(用户/OpenList/卡密/云盘配置/缓存)持久化在 ./data 目录, 备份只需复制该目录
services:
lx-sync-server:
- build: .
+ # 使用已发布到 ghcr.io 的官方镜像(推荐, 无需本地源码/Dockerfile)
+ image: ghcr.io/boy6656598/lxserver:3.0.1
+ # 如需从源码自行构建, 请注释掉上面 image 行, 并取消下面一行的注释
+ # build: .
container_name: lx-sync-server
restart: always
+ extra_hosts:
+ # 容器内访问宿主机服务的专用地址(如本机 NAS 上的 Alist/WebDAV):
+ # 后台填写地址时用 http://host.docker.internal:端口 替代 宿主机IP:端口
+ # (bridge 网络下直接访问宿主机内网 IP 可能被网络栈重置导致 socket hang up)
+ #
+ # 注意: 部分环境(如飞牛 NAS) 对 host-gateway 支持不稳定, 容器内可能无法解析
+ # host.docker.internal. 此时服务端会自动把该域名替换为探测到的宿主机网关 IP,
+ # 若仍失败可在下方 environment 中显式设置 LX_HOST_ADDR=<宿主机IP> 兜底.
+ - "host.docker.internal:host-gateway"
ports:
+ # 端口映射: 宿主机端口:容器端口. 若 9527 被占用, 改左侧为其他端口即可, 例如 "9000:9527"
- "9527:9527"
volumes:
- # 数据持久化
+ # 数据持久化: 映射到容器内 /server/data (Dockerfile 已设置 DATA_PATH=/server/data)
- ./data:/server/data
environment:
- # 环境变量配置,优先级高于 config.js
+ # 环境变量配置, 优先级高于 config.js
- NODE_ENV=production
- # 示例:通过环境变量设置用户
+
+ # ===== 可选配置(按需取消注释) =====
+
+ # 服务名称(显示在客户端)
+ # - SERVER_NAME=My Sync Server
+
+ # 监听端口(默认 9527, 一般无需修改)
+ # - PORT=9527
+
+ # 管理员后台访问密码(默认见 config.js 的 frontend.password)
+ # - FRONTEND_PASSWORD=你的后台密码
+
+ # 播放器访问密码与是否强制登录
+ # - ENABLE_WEBPLAYER_AUTH=true
+ # - WEBPLAYER_PASSWORD=123456
+
+ # 用户管理: 追加/覆盖用户账号, 格式 LX_USER_<用户名>=密码
+ # 复杂配置可使用 JSON: LX_USER_user1='{ "password": "123.456", "maxSnapshotNum": 10 }'
# - LX_USER_myuser=mypassword
+
+ # 同步与备份间隔(分钟)
+ # - SYNC_INTERVAL=60
+
+ # 是否启用 WEBDAV 同步(留空则关闭)
+ # - WEBDAV_URL=
+ # - WEBDAV_USERNAME=
+ # - WEBDAV_PASSWORD=
+
+ # 自定义配置文件路径(默认读取镜像内 /server/config.js)
+ # - CONFIG_PATH=/server/config.js
+
+ # 宿主机可达地址(可选兜底): 当 host.docker.internal 在容器内无法解析时,
+ # 服务端会自动把它替换为探测到的宿主机网关地址(通常为 docker0 网关, 如 172.17.0.1),
+ # 一般无需手动设置. 仅当自动探测仍失败时才取消下面注释.
+ # 注意: 应填容器内可达的 docker 网关地址(如 172.17.0.1); 填 NAS 内网 IP
+ # (如 192.168.2.100) 在 bridge 网络下可能被网络栈重置导致连接超时失败.
+ # - LX_HOST_ADDR=172.17.0.1
diff --git a/package.json b/package.json
index 8f8cd7cc..7f63c5b2 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "lx-music-sync-server",
- "version": "2.0.0",
+ "version": "3.0.1",
"private": true,
"scripts": {
"prebuild": "node scripts/download-binary.js && node scripts/update-build-hash.js",
diff --git a/public/app.js b/public/app.js
index 124ad90e..23d966eb 100644
--- a/public/app.js
+++ b/public/app.js
@@ -276,6 +276,7 @@ class App {
webdav: 'WebDAV同步',
files: '文件管理',
snapshots: '快照管理',
+ cards: '卡密管理',
about: '关于'
};
document.getElementById('page-title').textContent = titles[viewName] || viewName;
@@ -311,6 +312,15 @@ class App {
case 'snapshots':
this.loadSnapshots();
break;
+ case 'cards':
+ this.loadCards();
+ break;
+ case 'openlist':
+ this.loadOpenList();
+ break;
+ case 'webdav-mounts':
+ this.loadWebdavMounts();
+ break;
case 'about':
this.loadAbout();
break;
@@ -1956,6 +1966,356 @@ class App {
document.getElementById('modal').classList.add('hidden');
}
+ // ========== 卡密管理 ==========
+ async loadCards() {
+ try {
+ const res = await this.request('/api/card/list');
+ const cards = res.cards || [];
+ const tbody = document.getElementById('cards-table-body');
+ if (!tbody) return;
+
+ const total = cards.length;
+ const unused = cards.filter(c => c.status === 'unused').length;
+ const used = total - unused;
+ document.getElementById('cards-total-count').textContent = total;
+ document.getElementById('cards-unused-count').textContent = unused;
+ document.getElementById('cards-used-count').textContent = used;
+
+ if (!cards.length) {
+ tbody.innerHTML = '