diff --git a/.eslintrc.backup.json b/.eslintrc.backup.json index a9c2595..cfdd018 100644 --- a/.eslintrc.backup.json +++ b/.eslintrc.backup.json @@ -1,8 +1,5 @@ { - "extends": [ - "@electron-toolkit/eslint-config-ts", - "@electron-toolkit/eslint-config-prettier" - ], + "extends": ["@electron-toolkit/eslint-config-ts", "@electron-toolkit/eslint-config-prettier"], "rules": { "vue/require-default-prop": "off", "vue/multi-word-component-names": "off", @@ -10,4 +7,4 @@ "@typescript-eslint/no-explicit-any": "warn", "no-console": "warn" } -} \ No newline at end of file +} diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index de1a408..8724372 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -19,7 +19,13 @@ export default defineConfig({ { text: 'CeruMusic', items: [ - { text: '使用教程', link: '/guide/' }, + { text: '安装教程', link: '/guide/' }, + { + text:'使用教程', + items:[ + { text: '音乐播放列表', link: '/guide/used/playList' }, + ] + }, { text: '软件设计文档', link: '/guide/design' } ] }, diff --git a/docs/alist-config.md b/docs/alist-config.md deleted file mode 100644 index 7b297c2..0000000 --- a/docs/alist-config.md +++ /dev/null @@ -1,142 +0,0 @@ -# Alist 下载配置说明 - -## 概述 - -项目已从 GitHub 下载方式切换到 Alist API 下载方式,包括: - -- 桌面应用的自动更新功能 (`src/main/autoUpdate.ts`) -- 官方网站的下载功能 (`website/script.js`) - -## 配置步骤 - -### 1. 修改 Alist 域名 - -#### 桌面应用配置 - -在 `src/main/autoUpdate.ts` 文件中,Alist 域名已配置为: - -```typescript -const ALIST_BASE_URL = 'http://47.96.72.224:5244' -``` - -#### 网站配置 - -在 `website/script.js` 文件中,Alist 域名已配置为: - -```javascript -const ALIST_BASE_URL = 'http://47.96.72.224:5244' -``` - -如需修改域名,请同时更新这两个文件中的 `ALIST_BASE_URL` 配置。 - -### 2. 认证信息 - -已配置的认证信息: - -- 用户名: `ceruupdata` -- 密码: `123456` - -### 3. 文件路径格式 - -文件在 Alist 中的路径格式为:`/{version}/{文件名}` - -例如: - -- 版本 `v1.0.0` 的安装包 `app-setup.exe` 路径为:`/v1.0.0/app-setup.exe` - -## 工作原理 - -### 桌面应用自动更新 - -1. **认证**: 使用配置的用户名和密码向 Alist API 获取认证 token -2. **获取文件信息**: 使用 token 调用 `/api/fs/get` 接口获取文件信息和签名 -3. **下载**: 使用带签名的直接下载链接下载文件 -4. **备用方案**: 如果 Alist 失败,自动回退到原始 URL 下载 - -### 网站下载功能 - -1. **获取版本列表**: 调用 `/api/fs/list` 获取根目录下的版本文件夹 -2. **获取文件列表**: 获取最新版本文件夹中的所有文件 -3. **平台匹配**: 根据用户平台自动匹配对应的安装包文件 -4. **生成下载链接**: 获取文件的直接下载链接 -5. **备用方案**: 如果 Alist 失败,自动回退到 GitHub API - -## API 接口 - -### 认证接口 - -``` -POST /api/auth/login -{ - "username": "ceruupdata", - "password": "123456" -} -``` - -### 获取文件信息接口 - -``` -POST /api/fs/get -Headers: Authorization: {token} # 注意:直接使用 token,不需要 "Bearer " 前缀 -{ - "path": "/{version}/{fileName}" -} -``` - -### 获取文件列表接口 - -``` -POST /api/fs/list -Headers: Authorization: {token} # 注意:直接使用 token,不需要 "Bearer " 前缀 -{ - "path": "/", - "password": "", - "page": 1, - "per_page": 100, - "refresh": false -} -``` - -### 下载链接格式 - -``` -{ALIST_BASE_URL}/d/{filePath}?sign={sign} -``` - -## 测试方法 - -项目包含了一个测试脚本来验证 Alist 连接: - -```bash -node scripts/test-alist.js -``` - -该脚本会: - -1. 测试服务器连通性 -2. 测试用户认证 -3. 测试文件列表获取 -4. 测试文件信息获取 - -## 备用机制 - -两个组件都实现了备用机制: - -### 桌面应用 - -- 主要:使用 Alist API 下载 -- 备用:如果 Alist 失败,使用原始 URL 下载 - -### 网站 - -- 主要:使用 Alist API 获取版本和文件信息 -- 备用:如果 Alist 失败,回退到 GitHub API -- 最终备用:跳转到 GitHub releases 页面 - -## 注意事项 - -1. 确保 Alist 服务器可以正常访问 -2. 确保配置的用户名和密码有权限访问相应的文件路径 -3. 文件必须按照指定的路径格式存放在 Alist 中 -4. 网站会自动检测用户操作系统并推荐对应的下载版本 -5. 所有下载都会显示文件大小信息 diff --git a/docs/alist-migration-summary.md b/docs/alist-migration-summary.md deleted file mode 100644 index f1ae928..0000000 --- a/docs/alist-migration-summary.md +++ /dev/null @@ -1,99 +0,0 @@ -# Alist 迁移完成总结 - -## 修改概述 - -项目已成功从 GitHub 下载方式迁移到 Alist API 下载方式。 - -## 修改的文件 - -### 1. 桌面应用自动更新 (`src/main/autoUpdate.ts`) - -- ✅ 添加了 Alist API 配置 -- ✅ 实现了 Alist 认证功能 -- ✅ 实现了 Alist 文件下载功能 -- ✅ 添加了备用机制(Alist 失败时回退到原始 URL) -- ✅ 修复了 Authorization 头格式(使用直接 token 而非 Bearer 格式) - -### 2. 官方网站下载功能 (`website/script.js`) - -- ✅ 添加了 Alist API 配置 -- ✅ 实现了 Alist 认证功能 -- ✅ 实现了版本列表获取功能 -- ✅ 实现了文件列表获取功能 -- ✅ 实现了平台文件匹配功能 -- ✅ 添加了多层备用机制(Alist → GitHub API → GitHub 页面) -- ✅ 修复了 Authorization 头格式 - -### 3. 配置文档 - -- ✅ 创建了详细的配置说明 (`docs/alist-config.md`) -- ✅ 创建了迁移总结文档 (`docs/alist-migration-summary.md`) - -### 4. 测试脚本 - -- ✅ 创建了 Alist 连接测试脚本 (`scripts/test-alist.js`) -- ✅ 创建了认证格式测试脚本 (`scripts/auth-test.js`) - -## 配置信息 - -### Alist 服务器配置 - -- **服务器地址**: `http://47.96.72.224:5244` -- **用户名**: `ceruupdate` -- **密码**: `123456` -- **文件路径格式**: `/{version}/{文件名}` - -### Authorization 头格式 - -经过测试确认,正确的格式是: - -``` -Authorization: {token} -``` - -**注意**: 不需要 "Bearer " 前缀 - -## 功能特性 - -### 桌面应用 - -1. **智能下载**: 优先使用 Alist API,失败时自动回退 -2. **进度显示**: 支持下载进度显示和节流 -3. **错误处理**: 完善的错误处理和日志记录 - -### 网站 - -1. **自动检测**: 自动检测用户操作系统并推荐对应版本 -2. **版本信息**: 自动获取最新版本信息和文件大小 -3. **多层备用**: Alist → GitHub API → GitHub 页面的三层备用机制 -4. **用户体验**: 加载状态、成功通知、错误提示 - -## 测试结果 - -✅ **Alist 连接测试**: 通过 -✅ **认证测试**: 通过 -✅ **文件列表获取**: 通过 -✅ **Authorization 头格式**: 已修复并验证 - -## 可用文件 - -测试显示 Alist 服务器当前包含以下文件: - -- `v1.2.1/` (版本目录) -- `1111` -- `L3YxLjIuMS8tMS4yLjEtYXJtNjQtbWFjLnppcA==` -- `file2.msi` -- `file.msi` - -## 后续维护 - -1. **添加新版本**: 在 Alist 中创建新的版本目录(如 `v1.2.2/`) -2. **上传文件**: 将对应平台的安装包上传到版本目录中 -3. **文件命名**: 确保文件名包含平台标识(如 `windows`, `mac`, `linux` 等) - -## 备注 - -- 所有修改都保持了向后兼容性 -- 实现了完善的错误处理和备用机制 -- 用户体验不会因为迁移而受到影响 -- 可以随时回退到 GitHub 下载方式 diff --git a/docs/guide/used/assets/image-20250916132204465.png b/docs/guide/used/assets/image-20250916132204465.png new file mode 100644 index 0000000..1e10e79 Binary files /dev/null and b/docs/guide/used/assets/image-20250916132204465.png differ diff --git a/docs/guide/used/assets/image-20250916132248046.png b/docs/guide/used/assets/image-20250916132248046.png new file mode 100644 index 0000000..1e10e79 Binary files /dev/null and b/docs/guide/used/assets/image-20250916132248046.png differ diff --git a/docs/guide/used/assets/image-20250916133531421.png b/docs/guide/used/assets/image-20250916133531421.png new file mode 100644 index 0000000..a32364e Binary files /dev/null and b/docs/guide/used/assets/image-20250916133531421.png differ diff --git a/docs/guide/used/assets/image-20250916134406714.png b/docs/guide/used/assets/image-20250916134406714.png new file mode 100644 index 0000000..4d6e0a8 Binary files /dev/null and b/docs/guide/used/assets/image-20250916134406714.png differ diff --git a/docs/guide/used/assets/image-20250916134511291.png b/docs/guide/used/assets/image-20250916134511291.png new file mode 100644 index 0000000..27f651e Binary files /dev/null and b/docs/guide/used/assets/image-20250916134511291.png differ diff --git a/docs/guide/used/assets/image-20250916134615679.png b/docs/guide/used/assets/image-20250916134615679.png new file mode 100644 index 0000000..e667713 Binary files /dev/null and b/docs/guide/used/assets/image-20250916134615679.png differ diff --git a/docs/guide/used/assets/image-20250916134820742.png b/docs/guide/used/assets/image-20250916134820742.png new file mode 100644 index 0000000..eca94ff Binary files /dev/null and b/docs/guide/used/assets/image-20250916134820742.png differ diff --git a/docs/guide/used/playList.md b/docs/guide/used/playList.md new file mode 100644 index 0000000..2cf5cd1 --- /dev/null +++ b/docs/guide/used/playList.md @@ -0,0 +1,25 @@ +# 音乐播放列表-机制分析 + +## 基础使用 + +1. 默认情况下,播放**「搜索」「歌单」**双击中的歌曲时,会自动将该歌曲添加到**「列表」**中的末尾后并不会播放,这与手动将歌曲添加到**「列表」**等价,亦或是通过点击歌曲前面小三角播放image-20250916132248046可以添加到歌曲开头也可进行该歌曲添加到**「列表」**中的开头并播放。歌曲会按照你选择的播放顺序进行播放。 +2. 对于**「列表」**歌曲的顺序可通过展开长按**1.5s**后可以进行拖拽排序,歌曲排序实时保存到本地**LocalStorage**image-20250916133531421 + +## 歌曲列表的导出和分享 + +3. 可进入设置 + + ![image-20250916134511291](assets/image-20250916134511291.png) + + 点击**【播放列表】**=> + + ![image-20250916134615679](assets/image-20250916134615679.png) + + 即可操作你想要的功能 + +4. 播放列表还可以导出为歌单 + + ![image-20250916134820742](assets/image-20250916134820742.png) + + 歌单将自动选取第一首 **\*有效封面** 为歌单 + diff --git a/docs/webdav-sync-setup.md b/docs/webdav-sync-setup.md deleted file mode 100644 index 79ee21f..0000000 --- a/docs/webdav-sync-setup.md +++ /dev/null @@ -1,150 +0,0 @@ -# WebDAV 同步配置指南 - -本项目包含两个 GitHub Actions 工作流,用于自动将 GitHub Releases 同步到 alist(WebDAV 服务器)。 - -## 工作流说明 - -### 1. 手动同步工作流 (`sync-releases-to-webdav.yml`) - -- **触发方式**: 手动触发 (workflow_dispatch) -- **功能**: 同步现有的所有版本或指定版本到 WebDAV -- **参数**: - - `tag_name`: 可选,指定要同步的版本标签(如 v1.0.0),留空则同步所有版本 - -### 2. 自动同步工作流 (集成在 `main.yml` 中) - -- **触发方式**: 在 AutoBuild 完成后自动触发 -- **功能**: 自动将新构建的版本同步到 WebDAV -- **参数**: 无需手动设置,自动获取发布信息 - -### 3. 独立自动同步工作流 (`auto-sync-release.yml`) - -- **触发方式**: 当新版本发布时自动触发 (on release published) -- **功能**: 备用的自动同步机制 -- **参数**: 无需手动设置,自动获取发布信息 - -## 配置要求 - -在 GitHub 仓库的 Settings > Secrets and variables > Actions 中添加以下密钥: - -### 必需的 Secrets - -1. **WEBDAV_BASE_URL** - - 描述: WebDAV 服务器的基础 URL - - 示例: `https://your-alist-domain.com/dav` - - 注意: 不要在末尾添加斜杠 - -2. **WEBDAV_USERNAME** - - 描述: WebDAV 服务器的用户名 - - 示例: `admin` - -3. **WEBDAV_PASSWORD** - - 描述: WebDAV 服务器的密码 - - 示例: `your-password` - -4. **GITHUB_TOKEN** - - 描述: GitHub 访问令牌(通常自动提供) - - 注意: 如果默认的 `GITHUB_TOKEN` 权限不足,可能需要创建个人访问令牌 - -## 使用方法 - -### 手动同步现有版本 - -1. 进入 GitHub 仓库的 Actions 页面 -2. 选择 "Sync Existing Releases to WebDAV" 工作流 -3. 点击 "Run workflow" -4. 可选择指定版本标签或留空同步所有版本 -5. 点击 "Run workflow" 开始执行 - -### 自动同步新版本 - -现在有两种自动同步方式: - -1. **集成同步** (推荐): 在主构建工作流 (`main.yml`) 中集成了 WebDAV 同步,当您推送 `v*` 标签时,会自动执行: - - 构建应用 → 创建 Release → 同步到 WebDAV -2. **独立同步**: 当您手动发布 Release 时,`auto-sync-release.yml` 工作流会自动触发 - -推荐使用集成同步方式,因为它确保了构建和同步的一致性。 - -## 文件结构 - -同步后的文件将按以下结构存储在 alist 中: - -``` -/yd/ceru/ -├── v1.0.0/ -│ ├── app-setup.exe -│ ├── app.dmg -│ └── app.AppImage -├── v1.1.0/ -│ ├── app-setup.exe -│ ├── app.dmg -│ └── app.AppImage -└── ... -``` - -## 故障排除 - -### 常见问题 - -1. **上传失败** - - 检查 WebDAV 服务器是否正常运行 - - 验证用户名和密码是否正确 - - 确认 WebDAV URL 格式正确 - -2. **权限错误** - - 确保 WebDAV 用户有写入权限 - - 检查目标目录是否存在且可写 - -3. **文件大小不匹配** - - 网络问题导致下载不完整 - - GitHub API 限制或临时故障 - -4. **目录创建失败** - - WebDAV 服务器不支持 MKCOL 方法 - - 权限不足或路径错误 - -### 调试步骤 - -1. 查看 Actions 运行日志 -2. 检查 WebDAV 服务器日志 -3. 验证所有 Secrets 配置正确 -4. 测试 WebDAV 连接是否正常 - -## 安全注意事项 - -1. **密钥管理** - - 不要在代码中硬编码密码 - - 定期更换 WebDAV 密码 - - 使用强密码 - -2. **权限控制** - - 为 WebDAV 用户设置最小必要权限 - - 考虑使用专用的同步账户 - -3. **网络安全** - - 建议使用 HTTPS 连接 - - 考虑 IP 白名单限制 - -## 自定义配置 - -如需修改同步路径或其他配置,请编辑对应的工作流文件: - -- 修改存储路径: 更改 `remote_path` 变量 -- 调整重试逻辑: 修改错误处理部分 -- 添加通知: 集成 Slack、邮件等通知服务 - -## 支持的文件类型 - -工作流支持同步所有类型的 Release 资源文件,包括但不限于: - -- 可执行文件 (.exe, .dmg, .AppImage) -- 压缩包 (.zip, .tar.gz, .7z) -- 安装包 (.msi, .deb, .rpm) -- 其他二进制文件 - -## 版本兼容性 - -- GitHub Actions: 支持最新版本 -- alist: 支持 WebDAV 协议的版本 -- 操作系统: Ubuntu Latest (工作流运行环境) diff --git a/src/main/index.ts b/src/main/index.ts index bc1fcec..4e40db5 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -7,7 +7,6 @@ import musicService from './services/music' import pluginService from './services/plugin' import aiEvents from './events/ai' import './services/musicSdk/index' - // 获取单实例锁 const gotTheLock = app.requestSingleInstanceLock() diff --git a/src/main/window/index.ts b/src/main/window/index.ts index 6c400dc..5cd69c7 100644 --- a/src/main/window/index.ts +++ b/src/main/window/index.ts @@ -61,8 +61,7 @@ export default function useWindow( app.whenReady().then(() => { // Set app user model id for windows - electronApp.setAppUserModelId('com.cerulean.music') - + // electronApp.setAppUserModelId('com.cerulean.music') // Default open or close DevTools by F12 in development // and ignore CommandOrControl + R in production. // see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils diff --git a/src/renderer/auto-imports.d.ts b/src/renderer/auto-imports.d.ts index 9d24007..b0b0357 100644 --- a/src/renderer/auto-imports.d.ts +++ b/src/renderer/auto-imports.d.ts @@ -5,6 +5,4 @@ // Generated by unplugin-auto-import // biome-ignore lint: disable export {} -declare global { - -} +declare global {} diff --git a/src/renderer/components.d.ts b/src/renderer/components.d.ts index e69de29..ab1a287 100644 --- a/src/renderer/components.d.ts +++ b/src/renderer/components.d.ts @@ -0,0 +1,52 @@ +/* eslint-disable */ +// @ts-nocheck +// Generated by unplugin-vue-components +// Read more: https://github.com/vuejs/core/pull/3399 +// biome-ignore lint: disable +export {} + +/* prettier-ignore */ +declare module 'vue' { + export interface GlobalComponents { + AIFloatBallSettings: typeof import('./src/components/Settings/AIFloatBallSettings.vue')['default'] + AudioVisualizer: typeof import('./src/components/Play/AudioVisualizer.vue')['default'] + FloatBall: typeof import('./src/components/AI/FloatBall.vue')['default'] + FullPlay: typeof import('./src/components/Play/FullPlay.vue')['default'] + GlobalAudio: typeof import('./src/components/Play/GlobalAudio.vue')['default'] + MusicCache: typeof import('./src/components/Settings/MusicCache.vue')['default'] + PlaylistActions: typeof import('./src/components/Play/PlaylistActions.vue')['default'] + PlaylistDrawer: typeof import('./src/components/Play/PlaylistDrawer.vue')['default'] + PlaylistSettings: typeof import('./src/components/Settings/PlaylistSettings.vue')['default'] + PlayMusic: typeof import('./src/components/Play/PlayMusic.vue')['default'] + RouterLink: typeof import('vue-router')['RouterLink'] + RouterView: typeof import('vue-router')['RouterView'] + SearchComponent: typeof import('./src/components/Search/SearchComponent.vue')['default'] + ShaderBackground: typeof import('./src/components/Play/ShaderBackground.vue')['default'] + SongVirtualList: typeof import('./src/components/Music/SongVirtualList.vue')['default'] + TAlert: typeof import('tdesign-vue-next')['Alert'] + TAside: typeof import('tdesign-vue-next')['Aside'] + TBadge: typeof import('tdesign-vue-next')['Badge'] + TButton: typeof import('tdesign-vue-next')['Button'] + TCard: typeof import('tdesign-vue-next')['Card'] + TContent: typeof import('tdesign-vue-next')['Content'] + TDialog: typeof import('tdesign-vue-next')['Dialog'] + TDropdown: typeof import('tdesign-vue-next')['Dropdown'] + TForm: typeof import('tdesign-vue-next')['Form'] + TFormItem: typeof import('tdesign-vue-next')['FormItem'] + ThemeSelector: typeof import('./src/components/ThemeSelector.vue')['default'] + TIcon: typeof import('tdesign-vue-next')['Icon'] + TImage: typeof import('tdesign-vue-next')['Image'] + TInput: typeof import('tdesign-vue-next')['Input'] + TitleBarControls: typeof import('./src/components/TitleBarControls.vue')['default'] + TLayout: typeof import('tdesign-vue-next')['Layout'] + TLoading: typeof import('tdesign-vue-next')['Loading'] + TSlider: typeof import('tdesign-vue-next')['Slider'] + TSwitch: typeof import('tdesign-vue-next')['Switch'] + TTextarea: typeof import('tdesign-vue-next')['Textarea'] + TTooltip: typeof import('tdesign-vue-next')['Tooltip'] + UpdateExample: typeof import('./src/components/UpdateExample.vue')['default'] + UpdateProgress: typeof import('./src/components/UpdateProgress.vue')['default'] + UpdateSettings: typeof import('./src/components/Settings/UpdateSettings.vue')['default'] + Versions: typeof import('./src/components/Versions.vue')['default'] + } +} diff --git a/src/renderer/src/components/Play/PlayMusic.vue b/src/renderer/src/components/Play/PlayMusic.vue index 1b86717..971abd1 100644 --- a/src/renderer/src/components/Play/PlayMusic.vue +++ b/src/renderer/src/components/Play/PlayMusic.vue @@ -215,10 +215,7 @@ const playSong = async (song: SongList) => { // 开始播放 try { - const startResult = start() - if (startResult && typeof startResult.then === 'function') { - await startResult - } + start() } catch (error) { console.error('启动播放失败:', error) // 如果是 AbortError,尝试重新播放 @@ -835,13 +832,11 @@ watch(showFullPlay, (val) => { :disabled="isLoadingSong" @click.stop="() => !isLoadingSong && togglePlayPause()" > - +
- - - - -
+ + +