feat: align with upstream 1.5.9.9

This commit is contained in:
2026-09-12 18:21:11 +08:00
commit 34f0679117
805 changed files with 376275 additions and 0 deletions
+32
View File
@@ -0,0 +1,32 @@
import { getQqUserAvatar } from '~~/server/utils/qq_music_sdk'
export default defineEventHandler(async (event) => {
const query = getQuery(event)
const uin = String(query.uin || '').trim()
const k = String(query.k || '').trim()
const size = Number(query.size || 140)
if (!uin && !k) {
throw createError({ statusCode: 400, message: '缺少 uin 或 k 参数' })
}
if (!Number.isFinite(size) || size <= 0) {
throw createError({ statusCode: 400, message: 'size 参数无效' })
}
try {
return {
success: true,
data: await getQqUserAvatar({
uin: uin || undefined,
k: k || undefined,
size
})
}
} catch (error: any) {
throw createError({
statusCode: 502,
message: error?.message || '获取 QQ 用户头像失败'
})
}
})
@@ -0,0 +1,41 @@
import { checkQqCookie } from '~~/server/utils/qq_music_sdk'
// 校验 QQ 音乐登录 Cookie 是否有效;无效时前端据此清理本地登录态
export default defineEventHandler(async (event) => {
const body = await readBody(event)
const cookie = String(body?.cookie || '').trim()
if (!cookie) {
throw createError({ statusCode: 400, message: '缺少 cookie 参数' })
}
try {
const result = await checkQqCookie({ cookie })
return {
success: true,
data: {
valid: result.valid,
isVip: result.isVip,
signals: result.signals,
user: result.profile
? {
userId: result.profile.userId,
id: result.profile.userId,
nickname: result.profile.nickname,
userName: result.profile.nickname,
avatarUrl: result.profile.avatarUrl
}
: undefined,
authDiagnostic: result.authDiagnostic
}
}
} catch (error: any) {
// 网络等异常不属于「登录失效」,向上抛错让前端保留本地状态
console.warn('[qq/check-cookie] 校验 QQ 登录态失败:', error?.message || error)
throw createError({
statusCode: 502,
message: error?.message || '校验 QQ 登录状态失败'
})
}
})
@@ -0,0 +1,77 @@
import {
checkQqLogin,
getQqCookieDiagnostic,
getQqUserAvatar,
normalizeQqCookie
} from '~~/server/utils/qq_music_sdk'
const getSessionCookie = (session: any) => {
if (typeof session?.cookie === 'string') return session.cookie
if (Array.isArray(session?.cookieList)) return session.cookieList.join('; ')
return ''
}
const normalizeLoginStatus = (data: any) => {
if (data?.isOk) return 'success'
if (data?.refresh) return 'expired'
return 'waiting'
}
export default defineEventHandler(async (event) => {
const body = await readBody(event)
const ptqrtoken = body?.ptqrtoken
const qrsig = String(body?.qrsig || '').trim()
if (!ptqrtoken || !qrsig) {
throw createError({ statusCode: 400, message: '缺少 ptqrtoken 或 qrsig 参数' })
}
try {
const data: any = await checkQqLogin(ptqrtoken, qrsig)
const session = data?.session || null
const cookie = normalizeQqCookie(getSessionCookie(session))
const cookieObject = session?.cookieObject || {}
const uin = cookieObject.qqmusic_uin || session?.uin || session?.loginUin || cookieObject.uin || ''
let avatarUrl = ''
if (data?.isOk && uin) {
try {
const avatar = await getQqUserAvatar({ uin, size: 140 })
avatarUrl = avatar?.avatarUrl || ''
} catch (avatarError) {
console.warn('[qq/check-login] 获取 QQ 头像失败:', avatarError)
}
}
return {
success: true,
data: {
...data,
status: normalizeLoginStatus(data),
cookie: cookie || undefined,
authDiagnostic: getQqCookieDiagnostic(cookie),
user: data?.isOk
? {
userId: uin,
id: uin,
nickname: uin ? `QQ ${uin}` : 'QQ音乐账号',
userName: uin ? `QQ ${uin}` : 'QQ音乐账号',
avatarUrl,
raw: session
}
: undefined,
session: session
? {
...session,
cookie
}
: session
}
}
} catch (error: any) {
throw createError({
statusCode: 502,
message: error?.message || '检查 QQ 登录状态失败'
})
}
})
@@ -0,0 +1,66 @@
import {
checkQqWxLogin,
getQqCookieDiagnostic,
normalizeQqCookie
} from '~~/server/utils/qq_music_sdk'
const getSessionCookie = (session: any) => {
if (typeof session?.cookie === 'string') return session.cookie
if (Array.isArray(session?.cookieList)) return session.cookieList.join('; ')
return ''
}
const normalizeLoginStatus = (data: any) => {
// 微信取消登录(refused)同样归入过期态,前端引导重新出码
if (data?.isOk) return 'success'
if (data?.refresh) return 'expired'
return 'waiting'
}
export default defineEventHandler(async (event) => {
const body = await readBody(event)
const uuid = String(body?.uuid || '').trim()
if (!uuid) {
throw createError({ statusCode: 400, message: '缺少 uuid 参数' })
}
try {
const data: any = await checkQqWxLogin(uuid)
const session = data?.session || null
const cookie = normalizeQqCookie(getSessionCookie(session))
const cookieObject = session?.cookieObject || {}
const uin = cookieObject.qqmusic_uin || session?.uin || session?.loginUin || cookieObject.uin || ''
return {
success: true,
data: {
...data,
status: normalizeLoginStatus(data),
cookie: cookie || undefined,
authDiagnostic: getQqCookieDiagnostic(cookie),
user: data?.isOk
? {
userId: uin,
id: uin,
nickname: `微信 ${String(uin).slice(-4)}`,
userName: `微信 ${String(uin).slice(-4)}`,
avatarUrl: '',
raw: session
}
: undefined,
session: session
? {
...session,
cookie
}
: session
}
}
} catch (error: any) {
throw createError({
statusCode: 502,
message: error?.message || '检查微信登录状态失败'
})
}
})
@@ -0,0 +1,16 @@
import { getQqWxLoginQr } from '~~/server/utils/qq_music_sdk'
// 获取 QQ 音乐微信扫码登录二维码
export default defineEventHandler(async () => {
try {
return {
success: true,
data: await getQqWxLoginQr()
}
} catch (error: any) {
throw createError({
statusCode: 502,
message: error?.message || '获取微信登录二维码失败'
})
}
})
+15
View File
@@ -0,0 +1,15 @@
import { getQqLoginQr } from '~~/server/utils/qq_music_sdk'
export default defineEventHandler(async () => {
try {
return {
success: true,
data: await getQqLoginQr()
}
} catch (error: any) {
throw createError({
statusCode: 502,
message: error?.message || '获取 QQ 登录二维码失败'
})
}
})
@@ -0,0 +1,26 @@
import { getQqPlaylistSongs } from '~~/server/utils/qq_music_sdk'
// 获取 QQ 音乐歌单内歌曲列表;favSongs=true 时返回"我喜欢"歌曲
export default defineEventHandler(async (event) => {
const body = await readBody(event)
const cookie = String(body?.cookie || '').trim()
const disstid = String(body?.disstid || '').trim()
const favSongs = Boolean(body?.favSongs)
const limit = Math.min(Math.max(Number(body?.limit) || 100, 1), 500)
const offset = Math.max(Number(body?.offset) || 0, 0)
if (!cookie || (!disstid && !favSongs)) {
throw createError({ statusCode: 400, message: '缺少 cookie 或 disstid 参数' })
}
try {
const result = await getQqPlaylistSongs({ disstid, favSongs, cookie, limit, offset })
return { success: true, data: result }
} catch (error: any) {
console.warn('[qq/playlist-songs] 获取歌单歌曲失败:', error?.message || error)
throw createError({
statusCode: 502,
message: error?.message || '获取歌单歌曲失败'
})
}
})
@@ -0,0 +1,22 @@
import { getQqUserPlaylists } from '~~/server/utils/qq_music_sdk'
// 获取用户创建(含"我喜欢")与收藏的 QQ 音乐歌单
export default defineEventHandler(async (event) => {
const body = await readBody(event)
const cookie = String(body?.cookie || '').trim()
if (!cookie) {
throw createError({ statusCode: 400, message: '缺少 cookie 参数' })
}
try {
const result = await getQqUserPlaylists({ cookie })
return { success: true, data: result }
} catch (error: any) {
console.warn('[qq/playlists] 获取用户歌单失败:', error?.message || error)
throw createError({
statusCode: 502,
message: error?.message || '获取用户歌单失败'
})
}
})