diff --git a/src/lib/client.ts b/src/lib/client.ts index fd584f6..4191e66 100644 --- a/src/lib/client.ts +++ b/src/lib/client.ts @@ -24,7 +24,8 @@ export const API = { netease: { startImport: async (link: string) => await post('/api/import/netease/start', { link }), - checkProgress: async (id: string) => await post('/api/import/netease/progress', { id }) + checkProgress: async (id: string) => await post('/api/import/netease/progress', { id }), + checkLogin: async () => await post('/admin/netease-login', {}) }, user: { diff --git a/src/lib/server/songs.ts b/src/lib/server/songs.ts index fb65ef2..e6e1f6a 100644 --- a/src/lib/server/songs.ts +++ b/src/lib/server/songs.ts @@ -11,7 +11,10 @@ import path from 'path' const CACHE_DIR = path.resolve('static/audio') -const checkNetease = async () => (await ne.login_status({}) as any).body.data.account +const neCookie = async () => (await db.collection('server_props') + .findOne({ name: 'global_settings' }))?.netease_login_cookie + ?.let((cookie: string) => ({ cookie })) +const checkNetease = async () => (await ne.login_status({ ...await neCookie() }) as any).body.data.account const eToString = (e: any) => e.message ?? e.body.message /** @@ -96,8 +99,9 @@ export const getLyricsProcessed = cached('lyrics_processed', export const getSongUrl = async (id: number | string) => { await fs.mkdir(CACHE_DIR, { recursive: true }) - const filePath = path.join(CACHE_DIR, `${id}/standard.mp3`) - const publicUrl = `/audio/${id}/standard.mp3` + const level = 'exhigh' + const filePath = path.join(CACHE_DIR, `${id}/${level}.mp3`) + const publicUrl = `/audio/${id}/${level}.mp3` if (await fs.exists(filePath)) return publicUrl // Check netease api status @@ -105,8 +109,9 @@ export const getSongUrl = async (id: number | string) => { console.log(`Downloading song ${id}...`) // @ts-ignore - const res = await ne.song_url_v1({ id: id.toString(), level: 'standard' }) + const res = await ne.song_url_v1({ id: id.toString(), level, ...await neCookie() }) const url = (res.body as any).data?.[0]?.url + console.log(`Download URL: ${url}`) if (!url) throw error(404, '没获取到歌曲 URL(是不是被下架了)') diff --git a/src/routes/admin/netease-login/+page.svelte b/src/routes/admin/netease-login/+page.svelte new file mode 100644 index 0000000..138f15b --- /dev/null +++ b/src/routes/admin/netease-login/+page.svelte @@ -0,0 +1,104 @@ + + + + + +
+
+
+

扫码登录

+

请使用网易云音乐 APP 扫码

+
+ +
+ {#if status === 'loading'} +
+
+

正在生成二维码...

+
+ {:else if status === 'waiting_scan'} +
+ QR Code +
+ {:else if status === 'waiting_confirm'} +
+
+
+
+
+

已扫描

+

请在手机上确认登录

+
+
+ {:else if status === 'success'} +
+
+
+
+
+

登录成功

+
+
+ {:else if status === 'error'} +
+
+
+
+

错误: {errorMessage}

+
+ {/if} +
+
+
diff --git a/src/routes/admin/netease-login/+server.ts b/src/routes/admin/netease-login/+server.ts new file mode 100644 index 0000000..99880ae --- /dev/null +++ b/src/routes/admin/netease-login/+server.ts @@ -0,0 +1,38 @@ +import * as ne from '@neteasecloudmusicapienhanced/api' +import { error, json } from '@sveltejs/kit' +import { loginWithSyncCode } from '$lib/server/user' +import type { RequestHandler } from './$types' +import { db } from '$lib/server/db' + +const globalSession = { + key: "", + qrImg: "", +} + +async function createQr() { + globalSession.key = (await ne.login_qr_key({}) as any).body.data.unikey + globalSession.qrImg = (await ne.login_qr_create({ key: globalSession.key, qrimg: true }) as any).body.data.qrimg +} + +export const POST: RequestHandler = async ({ request, cookies }) => { + if (!globalSession.key) await createQr() + + // Check key validity + const check = (await ne.login_qr_check({ key: globalSession.key }) as any).body + // 800: 过期, 801: 等待扫码, 802: 等待确认, 803: 登录成功 + if (check.code === 800) { + await createQr() + check.code = 801 + } + if (check.code === 801) return json({ code: 801, img: globalSession.qrImg }) + if (check.code === 802) return json({ code: 802 }) + if (check.code === 803) { + await db.collection('server_props').updateOne( + { name: 'global_settings' }, + { $set: { netease_login_cookie: check.cookie } }, + { upsert: true } + ) + return json({ code: 803, cookie: check.cookie }) + } + throw error(500, `未知返回值 ${check.code}`) +}