From 1b6ebd9c7cefc05a2262378cd40a6cac1d36de9e Mon Sep 17 00:00:00 2001 From: imsyy Date: Fri, 21 Nov 2025 17:41:34 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20=E6=94=AF=E6=8C=81=E8=A7=A3?= =?UTF-8?q?=E9=94=81=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 + components.d.ts | 1 + package.json | 2 + pnpm-lock.yaml | 91 ++++++++++++++++++++++ src/api/song.ts | 11 +-- src/components/Modal/SongUnlockManager.vue | 62 +++++++++++++++ src/components/Player/MainAMLyric.vue | 2 +- src/components/Setting/AboutSetting.vue | 35 +++++---- src/components/Setting/LyricsSetting.vue | 4 +- src/components/Setting/PlaySetting.vue | 37 +++++++-- src/stores/setting.ts | 8 ++ src/style/main.scss | 7 +- src/utils/modal.ts | 15 ++++ src/utils/player-utils/song.ts | 45 +++++++---- src/utils/songManager.ts | 10 +++ 15 files changed, 283 insertions(+), 51 deletions(-) create mode 100644 src/components/Modal/SongUnlockManager.vue diff --git a/README.md b/README.md index 3a1dd9d..e5c9221 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,12 @@ ## 💬 交流群 + + ![交流群](/screenshots/welcome.png) + + ## 👀 Demo - [SPlayer](https://music.imsyy.top/) diff --git a/components.d.ts b/components.d.ts index aacf9eb..9e04eca 100644 --- a/components.d.ts +++ b/components.d.ts @@ -146,6 +146,7 @@ declare module 'vue' { SongList: typeof import('./src/components/List/SongList.vue')['default'] SongListCard: typeof import('./src/components/Card/SongListCard.vue')['default'] SongListMenu: typeof import('./src/components/Menu/SongListMenu.vue')['default'] + SongUnlockManager: typeof import('./src/components/Modal/SongUnlockManager.vue')['default'] SvgIcon: typeof import('./src/components/Global/SvgIcon.vue')['default'] TextContainer: typeof import('./src/components/Global/TextContainer.vue')['default'] UpdateApp: typeof import('./src/components/Modal/UpdateApp.vue')['default'] diff --git a/package.json b/package.json index eced8d9..50016be 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "@pixi/filter-color-matrix": "^7.4.3", "@pixi/sprite": "^7.4.3", "@vueuse/core": "^13.9.0", + "@vueuse/integrations": "^14.0.0", "axios": "^1.13.2", "axios-retry": "^4.5.0", "change-case": "^5.4.4", @@ -72,6 +73,7 @@ "pinia": "^3.0.4", "pinia-plugin-persistedstate": "^4.7.1", "plyr": "^3.8.3", + "sortablejs": "^1", "vue-virt-list": "^1.6.1" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 11d06ef..d7690aa 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -60,6 +60,9 @@ importers: '@vueuse/core': specifier: ^13.9.0 version: 13.9.0(vue@3.5.24(typescript@5.9.3)) + '@vueuse/integrations': + specifier: ^14.0.0 + version: 14.0.0(async-validator@4.2.5)(axios@1.13.2)(change-case@5.4.4)(qrcode@1.5.4)(sortablejs@1.15.6)(vue@3.5.24(typescript@5.9.3)) axios: specifier: ^1.13.2 version: 1.13.2 @@ -129,6 +132,9 @@ importers: plyr: specifier: ^3.8.3 version: 3.8.3 + sortablejs: + specifier: ^1 + version: 1.15.6 vue-virt-list: specifier: ^1.6.1 version: 1.6.1(vue@3.5.24(typescript@5.9.3)) @@ -1514,14 +1520,69 @@ packages: peerDependencies: vue: ^3.5.0 + '@vueuse/core@14.0.0': + resolution: {integrity: sha512-d6tKRWkZE8IQElX2aHBxXOMD478fHIYV+Dzm2y9Ag122ICBpNKtGICiXKOhWU3L1kKdttDD9dCMS4bGP3jhCTQ==} + peerDependencies: + vue: ^3.5.0 + + '@vueuse/integrations@14.0.0': + resolution: {integrity: sha512-5A0X7q9qyLtM3xyghq5nK/NEESf7cpcZlkQgXTMuW4JWiAMYxc1ImdhhGrk4negFBsq3ejvAlRmLdNrkcTzk1Q==} + peerDependencies: + async-validator: ^4 + axios: ^1 + change-case: ^5 + drauu: ^0.4 + focus-trap: ^7 + fuse.js: ^7 + idb-keyval: ^6 + jwt-decode: ^4 + nprogress: ^0.2 + qrcode: ^1.5 + sortablejs: ^1 + universal-cookie: ^7 || ^8 + vue: ^3.5.0 + peerDependenciesMeta: + async-validator: + optional: true + axios: + optional: true + change-case: + optional: true + drauu: + optional: true + focus-trap: + optional: true + fuse.js: + optional: true + idb-keyval: + optional: true + jwt-decode: + optional: true + nprogress: + optional: true + qrcode: + optional: true + sortablejs: + optional: true + universal-cookie: + optional: true + '@vueuse/metadata@13.9.0': resolution: {integrity: sha512-1AFRvuiGphfF7yWixZa0KwjYH8ulyjDCC0aFgrGRz8+P4kvDFSdXLVfTk5xAN9wEuD1J6z4/myMoYbnHoX07zg==} + '@vueuse/metadata@14.0.0': + resolution: {integrity: sha512-6yoGqbJcMldVCevkFiHDBTB1V5Hq+G/haPlGIuaFZHpXC0HADB0EN1ryQAAceiW+ryS3niUwvdFbGiqHqBrfVA==} + '@vueuse/shared@13.9.0': resolution: {integrity: sha512-e89uuTLMh0U5cZ9iDpEI2senqPGfbPRTHM/0AaQkcxnpqjkZqDYP8rpfm7edOz8s+pOCOROEy1PIveSW8+fL5g==} peerDependencies: vue: ^3.5.0 + '@vueuse/shared@14.0.0': + resolution: {integrity: sha512-mTCA0uczBgurRlwVaQHfG0Ja7UdGe4g9mwffiJmvLiTtp1G4AQyIjej6si/k8c8pUwTfVpNufck+23gXptPAkw==} + peerDependencies: + vue: ^3.5.0 + '@xmldom/xmldom@0.8.11': resolution: {integrity: sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==} engines: {node: '>=10.0.0'} @@ -3932,6 +3993,9 @@ packages: resolution: {integrity: sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==} engines: {node: '>=0.10.0'} + sortablejs@1.15.6: + resolution: {integrity: sha512-aNfiuwMEpfBM/CN6LY0ibyhxPfPbyFeBTYJKCvzkJ2GkUpazIt3H+QIPAMHwqQ7tMKaHz1Qj+rJJCqljnf4p3A==} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -5876,12 +5940,37 @@ snapshots: '@vueuse/shared': 13.9.0(vue@3.5.24(typescript@5.9.3)) vue: 3.5.24(typescript@5.9.3) + '@vueuse/core@14.0.0(vue@3.5.24(typescript@5.9.3))': + dependencies: + '@types/web-bluetooth': 0.0.21 + '@vueuse/metadata': 14.0.0 + '@vueuse/shared': 14.0.0(vue@3.5.24(typescript@5.9.3)) + vue: 3.5.24(typescript@5.9.3) + + '@vueuse/integrations@14.0.0(async-validator@4.2.5)(axios@1.13.2)(change-case@5.4.4)(qrcode@1.5.4)(sortablejs@1.15.6)(vue@3.5.24(typescript@5.9.3))': + dependencies: + '@vueuse/core': 14.0.0(vue@3.5.24(typescript@5.9.3)) + '@vueuse/shared': 14.0.0(vue@3.5.24(typescript@5.9.3)) + vue: 3.5.24(typescript@5.9.3) + optionalDependencies: + async-validator: 4.2.5 + axios: 1.13.2 + change-case: 5.4.4 + qrcode: 1.5.4 + sortablejs: 1.15.6 + '@vueuse/metadata@13.9.0': {} + '@vueuse/metadata@14.0.0': {} + '@vueuse/shared@13.9.0(vue@3.5.24(typescript@5.9.3))': dependencies: vue: 3.5.24(typescript@5.9.3) + '@vueuse/shared@14.0.0(vue@3.5.24(typescript@5.9.3))': + dependencies: + vue: 3.5.24(typescript@5.9.3) + '@xmldom/xmldom@0.8.11': {} abbrev@1.1.1: {} @@ -8598,6 +8687,8 @@ snapshots: dependencies: is-plain-obj: 1.1.0 + sortablejs@1.15.6: {} + source-map-js@1.2.1: {} source-map-support@0.5.21: diff --git a/src/api/song.ts b/src/api/song.ts index b27fa40..bb71aea 100644 --- a/src/api/song.ts +++ b/src/api/song.ts @@ -1,5 +1,6 @@ import { isElectron } from "@/utils/env"; import { songLevelData } from "@/utils/meta"; +import { SongUnlockServer } from "@/utils/songManager"; import request from "@/utils/request"; // 获取歌曲详情 @@ -47,16 +48,12 @@ export const songUrl = ( }; // 获取解锁歌曲 URL -export const unlockSongUrl = ( - id: number, - keyword: string, - server: "netease" | "kuwo" | "bodian", -) => { - const params = server === "netease" ? { id } : { keyword }; +export const unlockSongUrl = (id: number, keyword: string, server: SongUnlockServer) => { + const params = server === SongUnlockServer.NETEASE ? { id } : { keyword }; return request({ baseURL: "/api/unblock", url: `/${server}`, - params, + params: { ...params, noCookie: true }, }); }; diff --git a/src/components/Modal/SongUnlockManager.vue b/src/components/Modal/SongUnlockManager.vue new file mode 100644 index 0000000..c3ef673 --- /dev/null +++ b/src/components/Modal/SongUnlockManager.vue @@ -0,0 +1,62 @@ + + + + + diff --git a/src/components/Player/MainAMLyric.vue b/src/components/Player/MainAMLyric.vue index 560b6ca..b978619 100644 --- a/src/components/Player/MainAMLyric.vue +++ b/src/components/Player/MainAMLyric.vue @@ -34,7 +34,7 @@