Skip to content

Commit 146af3a

Browse files
committed
切换上游 api 库 #459
1 parent b2ddb9f commit 146af3a

File tree

9 files changed

+377
-72
lines changed

9 files changed

+377
-72
lines changed

electron/server/netease/index.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { FastifyInstance, FastifyRequest, FastifyReply } from "fastify";
22
import { pathCase } from "change-case";
3-
import NeteaseCloudMusicApi from "NeteaseCloudMusicApi";
3+
import NeteaseCloudMusicApi from "@neteaseapireborn/api";
44
import log from "../../main/logger";
55

66
// 获取数据
@@ -33,12 +33,12 @@ const initNcmAPI = async (fastify: FastifyInstance) => {
3333
// 主信息
3434
fastify.get("/netease", (_, reply) => {
3535
reply.send({
36-
name: "NeteaseCloudMusicApi",
37-
version: "4.25.0",
38-
description: "网易云音乐 Node.js API service",
39-
author: "@binaryify",
36+
name: "@neteaseapireborn/api",
37+
version: "4.29.2",
38+
description: "网易云音乐 API Enhanced",
39+
author: "@MoeFurina",
4040
license: "MIT",
41-
url: "https://gitlab.com/Binaryify/neteasecloudmusicapi",
41+
url: "https://github.com/NeteaseCloudMusicApiEnhanced/api-enhanced",
4242
});
4343
});
4444

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"@electron-toolkit/utils": "^3.0.0",
4141
"@imsyy/color-utils": "^1.0.2",
4242
"@material/material-color-utilities": "^0.3.0",
43+
"@neteaseapireborn/api": "^4.29.2",
4344
"@pixi/app": "^7.4.3",
4445
"@pixi/core": "^7.4.3",
4546
"@pixi/display": "^7.4.3",
@@ -48,7 +49,6 @@
4849
"@pixi/filter-color-matrix": "^7.4.3",
4950
"@pixi/sprite": "^7.4.3",
5051
"@vueuse/core": "^12.8.2",
51-
"NeteaseCloudMusicApi": "^4.27.0",
5252
"axios": "^1.11.0",
5353
"change-case": "^5.4.4",
5454
"dayjs": "^1.11.13",

pnpm-lock.yaml

Lines changed: 270 additions & 30 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/Layout/Menu.vue

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,15 @@ const menuOptions = computed<MenuOption[] | MenuGroupOption[]>(() => {
176176
children: [...likedPlaylist.value],
177177
},
178178
]
179-
: [];
179+
: [
180+
{
181+
key: "local",
182+
link: "local",
183+
label: "本地歌曲",
184+
show: isElectron,
185+
icon: renderIcon("FolderMusic"),
186+
},
187+
];
180188
});
181189
182190
// 生成歌单列表

src/components/Search/SearchInp.vue

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
/>
2929
</Transition>
3030
<!-- 默认内容 -->
31-
<SearchDefault @to-search="toSearch" />
31+
<SearchDefault v-if="settingStore.useOnlineService" @to-search="toSearch" />
3232
<!-- 搜索结果 -->
3333
<SearchSuggest @to-search="toSearch" />
3434
<!-- 右键菜单 -->
@@ -37,7 +37,7 @@
3737
</template>
3838

3939
<script setup lang="ts">
40-
import { useStatusStore, useDataStore } from "@/stores";
40+
import { useStatusStore, useDataStore, useSettingStore } from "@/stores";
4141
import { searchDefault } from "@/api/search";
4242
import SearchInpMenu from "@/components/Menu/SearchInpMenu.vue";
4343
import player from "@/utils/player";
@@ -47,13 +47,16 @@ import { formatSongsList } from "@/utils/format";
4747
const router = useRouter();
4848
const dataStore = useDataStore();
4949
const statusStore = useStatusStore();
50+
const settingStore = useSettingStore();
5051
5152
// 右键菜单
5253
const searchInpMenuRef = ref<InstanceType<typeof SearchInpMenu> | null>(null);
5354
5455
// 搜索框数据
5556
const searchInputRef = ref<HTMLInputElement | null>(null);
56-
const searchPlaceholder = ref<string>("搜索音乐 / 视频");
57+
const searchPlaceholder = ref<string>(
58+
settingStore.useOnlineService ? "搜索音乐 / 视频" : "搜索本地音乐",
59+
);
5760
const searchRealkeyword = ref<string>("");
5861
5962
// 搜索框输入限制
@@ -94,14 +97,23 @@ const updatePlaceholder = async () => {
9497
9598
// 前往搜索
9699
const toSearch = async (key: any, type: string = "keyword") => {
100+
// 关闭搜索框
101+
statusStore.searchFocus = false;
102+
searchInputRef.value?.blur();
97103
// 未输入内容且不存在推荐
98104
if (!key && searchPlaceholder.value === "搜索音乐 / 视频") return;
99105
if (!key && searchPlaceholder.value !== "搜索音乐 / 视频" && searchRealkeyword.value) {
100106
key = searchRealkeyword.value?.trim();
101107
}
102-
// 关闭搜索框
103-
statusStore.searchFocus = false;
104-
searchInputRef.value?.blur();
108+
// 本地搜索
109+
if (!settingStore.useOnlineService) {
110+
// 跳转本地搜索页面
111+
router.push({
112+
name: "search",
113+
query: { keyword: key },
114+
});
115+
return;
116+
}
105117
// 更新推荐
106118
updatePlaceholder();
107119
// 前往搜索
@@ -143,9 +155,10 @@ const toSearch = async (key: any, type: string = "keyword") => {
143155
};
144156
145157
onMounted(() => {
146-
updatePlaceholder();
147158
// 每分钟更新
148-
useIntervalFn(updatePlaceholder, 60 * 1000);
159+
if (settingStore.useOnlineService) {
160+
useIntervalFn(updatePlaceholder, 60 * 1000, { immediate: true });
161+
}
149162
});
150163
</script>
151164

src/components/Search/SearchSuggest.vue

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@
2727
<!-- 搜索建议 -->
2828
<Transition name="fade" mode="out-in" @after-leave="calcSearchSuggestHeights">
2929
<div
30-
v-if="Object.keys(searchSuggestData)?.length && searchSuggestData?.order"
30+
v-if="
31+
Object.keys(searchSuggestData)?.length &&
32+
searchSuggestData?.order &&
33+
settingStore.useOnlineService
34+
"
3135
ref="searchSuggestRef"
3236
class="all-suggest"
3337
>
@@ -60,13 +64,14 @@
6064

6165
<script setup lang="ts">
6266
import { searchSuggest } from "@/api/search";
63-
import { useStatusStore } from "@/stores";
67+
import { useStatusStore, useSettingStore } from "@/stores";
6468
6569
const emit = defineEmits<{
6670
toSearch: [key: number | string, type: string];
6771
}>();
6872
6973
const statusStore = useStatusStore();
74+
const settingStore = useSettingStore();
7075
7176
// 搜索建议数据
7277
const searchSuggestData = ref<any>({});
@@ -125,7 +130,7 @@ const calcSearchSuggestHeights = () => {
125130
watchDebounced(
126131
() => statusStore.searchInputValue,
127132
(val) => {
128-
if (!val || val === "") return;
133+
if (!val || val === "" || !settingStore.useOnlineService) return;
129134
getSearchSuggest(val);
130135
},
131136
{ debounce: 300 },

src/components/Setting/GeneralSetting.vue

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -142,13 +142,7 @@
142142
<n-text class="name">在线服务</n-text>
143143
<n-text class="tip" :depth="3">是否开启软件的在线服务</n-text>
144144
</div>
145-
<n-switch
146-
class="set"
147-
:disabled="true"
148-
:value="useOnlineService"
149-
:round="false"
150-
@update:value="modeChange"
151-
/>
145+
<n-switch class="set" :value="useOnlineService" :round="false" @update:value="modeChange" />
152146
</n-card>
153147
<n-card class="set-item">
154148
<div class="label">
@@ -256,12 +250,13 @@
256250

257251
<script setup lang="ts">
258252
import type { SelectOption } from "naive-ui";
259-
import { useMusicStore, useSettingStore, useStatusStore } from "@/stores";
260-
import { isElectron } from "@/utils/helper";
253+
import { useDataStore, useMusicStore, useSettingStore, useStatusStore } from "@/stores";
254+
import { isDev, isElectron } from "@/utils/helper";
261255
import { isEmpty } from "lodash-es";
262256
import themeColor from "@/assets/data/themeColor.json";
263257
import player from "@/utils/player";
264258
259+
const dataStore = useDataStore();
265260
const musicStore = useMusicStore();
266261
const settingStore = useSettingStore();
267262
const statusStore = useStatusStore();
@@ -319,26 +314,40 @@ const modeChange = (val: boolean) => {
319314
if (val) {
320315
window.$dialog.warning({
321316
title: "开启在线服务",
322-
content: "确定开启软件的在线服务?更改将在重启后生效",
317+
content: "确定开启软件的在线服务?更改将在热重载后生效",
323318
positiveText: "开启",
324319
negativeText: "取消",
325320
onPositiveClick: () => {
326321
useOnlineService.value = true;
327322
settingStore.useOnlineService = true;
323+
// 清理播放数据
324+
dataStore.$reset();
325+
musicStore.$reset();
326+
// 清空本地数据
327+
localStorage.removeItem("data-store");
328+
localStorage.removeItem("music-store");
329+
// 热重载
330+
window.location.reload();
328331
},
329332
});
330333
} else {
331334
window.$dialog.warning({
332335
title: "关闭在线服务",
333336
content:
334-
"确定关闭软件的在线服务?将关闭包括搜索、登录、在线音乐播放等在内的全部在线服务,软件将会变为本地播放器!更改将在软件重启后生效",
337+
"确定关闭软件的在线服务?将关闭包括搜索、登录、在线音乐播放等在内的全部在线服务,并且将会退出登录状态,软件将会变为本地播放器!更改将在重启后生效",
335338
positiveText: "关闭",
336339
negativeText: "取消",
337340
onPositiveClick: () => {
338341
useOnlineService.value = false;
339342
settingStore.useOnlineService = false;
343+
// 清理播放数据
344+
dataStore.$reset();
345+
musicStore.$reset();
346+
// 清空本地数据
347+
localStorage.removeItem("data-store");
348+
localStorage.removeItem("music-store");
340349
// 重启
341-
window.electron.ipcRenderer.send("win-reload");
350+
if (!isDev) window.electron.ipcRenderer.send("win-reload");
342351
},
343352
onNegativeClick: () => {
344353
useOnlineService.value = true;

src/components/UI/s-image.vue

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
</Transition>
99
<!-- 真实图片 -->
1010
<img
11-
v-if="src"
11+
v-if="imgSrc"
1212
ref="imgRef"
1313
:src="imgSrc"
1414
:key="imgSrc"
@@ -69,10 +69,27 @@ const imageError = (e: Event) => {
6969
};
7070
7171
// 可视状态变化
72-
watchOnce(isCanLook, (show) => {
73-
emit("update:show", show);
74-
if (show) imgSrc.value = props.src;
75-
});
72+
watch(
73+
isCanLook,
74+
(show) => {
75+
emit("update:show", show);
76+
if (show) imgSrc.value = props.src;
77+
},
78+
{ immediate: true },
79+
);
80+
81+
// 监听 src 变化
82+
watch(
83+
() => props.src,
84+
(val) => {
85+
isLoaded.value = false;
86+
if (isCanLook.value) {
87+
imgSrc.value = val;
88+
} else {
89+
imgSrc.value = undefined;
90+
}
91+
},
92+
);
7693
</script>
7794

7895
<style lang="scss" scoped>

src/utils/player.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -610,10 +610,11 @@ class Player {
610610
return;
611611
}
612612
this.player.play();
613-
statusStore.playStatus = true;
614613
// 淡入
615614
await new Promise<void>((resolve) => {
616615
this.player.once("play", () => {
616+
// 在淡入开始时立即设置播放状态
617+
statusStore.playStatus = true;
617618
this.player.fade(0, statusStore.playVolume, this.getFadeTime());
618619
resolve();
619620
});
@@ -631,12 +632,14 @@ class Player {
631632
return;
632633
}
633634

635+
// 立即设置播放状态
636+
if (changeStatus) statusStore.playStatus = false;
637+
634638
// 淡出
635639
await new Promise<void>((resolve) => {
636640
this.player.fade(statusStore.playVolume, 0, this.getFadeTime());
637641
this.player.once("fade", () => {
638642
this.player.pause();
639-
if (changeStatus) statusStore.playStatus = false;
640643
resolve();
641644
});
642645
});
@@ -905,8 +908,18 @@ class Player {
905908
const statusStore = useStatusStore();
906909
// 获取配置
907910
const { showTip, play } = options;
911+
912+
// 处理随机播放模式
913+
let processedData = cloneDeep(data);
914+
if (statusStore.playSongMode === "shuffle") {
915+
// 保存原始播放列表
916+
await dataStore.setOriginalPlayList(cloneDeep(data));
917+
// 随机排序
918+
processedData = this.shuffleArray(processedData);
919+
}
920+
908921
// 更新列表
909-
await dataStore.setPlayList(cloneDeep(data));
922+
await dataStore.setPlayList(processedData);
910923
// 关闭特殊模式
911924
if (statusStore.playHeartbeatMode) this.toggleHeartMode(false);
912925
if (statusStore.personalFmMode) statusStore.personalFmMode = false;
@@ -916,15 +929,15 @@ class Player {
916929
if (musicStore.playSong.id === song.id) {
917930
if (play) await this.play();
918931
} else {
919-
// 查找索引
920-
statusStore.playIndex = data.findIndex((item) => item.id === song.id);
932+
// 查找索引(在处理后的列表中查找)
933+
statusStore.playIndex = processedData.findIndex((item) => item.id === song.id);
921934
// 播放
922935
await this.pause(false);
923936
await this.initPlayer();
924937
}
925938
} else {
926939
statusStore.playIndex =
927-
statusStore.playSongMode === "shuffle" ? Math.floor(Math.random() * data.length) : 0;
940+
statusStore.playSongMode === "shuffle" ? Math.floor(Math.random() * processedData.length) : 0;
928941
// 播放
929942
await this.pause(false);
930943
await this.initPlayer();

0 commit comments

Comments
 (0)