feat: align with upstream 1.5.9.9
This commit is contained in:
@@ -0,0 +1,171 @@
|
||||
import {
|
||||
getTxSongPlayableInfo,
|
||||
TX_MUSICU_URL,
|
||||
txRequest,
|
||||
txSignedRequest
|
||||
} from '~~/server/utils/native_tx'
|
||||
import { SERVER_ERROR_CODES } from '~~/server/config/constants'
|
||||
import { createApiError } from '~~/server/utils/apiError'
|
||||
import {
|
||||
buildQqCommentRequestParam,
|
||||
normalizeQqCommentPage
|
||||
} from '~~/server/utils/qqComment'
|
||||
|
||||
interface QqCommentListData {
|
||||
Comments?: unknown
|
||||
comments?: unknown
|
||||
commentlist?: unknown
|
||||
list?: unknown
|
||||
Total?: unknown
|
||||
total?: unknown
|
||||
HasMore?: unknown
|
||||
hasMore?: unknown
|
||||
hasmore?: unknown
|
||||
}
|
||||
|
||||
interface QqCommentModuleData extends QqCommentListData {
|
||||
CommentList?: QqCommentListData
|
||||
comment?: QqCommentListData
|
||||
}
|
||||
|
||||
interface QqCommentResponse {
|
||||
code?: unknown
|
||||
request?: {
|
||||
code?: unknown
|
||||
data?: QqCommentModuleData
|
||||
}
|
||||
comment?: {
|
||||
code?: unknown
|
||||
data?: QqCommentModuleData
|
||||
}
|
||||
}
|
||||
|
||||
const getCommentListData = (response: QqCommentResponse) => {
|
||||
const data = response.request?.data || response.comment?.data || {}
|
||||
const list = data.CommentList || data.comment || data
|
||||
return {
|
||||
list,
|
||||
comments: list.Comments || list.comments || list.commentlist || list.list || []
|
||||
}
|
||||
}
|
||||
|
||||
const isSuccessfulResponse = (response: QqCommentResponse | undefined) => {
|
||||
if (!response || Number(response.code) !== 0) return false
|
||||
const moduleCode = response.request?.code ?? response.comment?.code
|
||||
return Number(moduleCode) === 0
|
||||
}
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const query = getQuery(event)
|
||||
const musicId = String(query.musicId || '').trim()
|
||||
const originalSongId = String(query.songId || '').trim()
|
||||
const cursor = String(query.cursor || '').trim()
|
||||
const rawPage = Number(query.page)
|
||||
const rawPageSize = Number(query.pageSize)
|
||||
const page = Number.isFinite(rawPage) ? Math.max(0, Math.floor(rawPage)) : 0
|
||||
const pageSize = Number.isFinite(rawPageSize)
|
||||
? Math.min(50, Math.max(1, Math.floor(rawPageSize)))
|
||||
: 20
|
||||
const type = query.type === 'latest' ? 'latest' : 'hot'
|
||||
if (!musicId) {
|
||||
throw createApiError(
|
||||
400,
|
||||
SERVER_ERROR_CODES.COMMON_INVALID_PARAMS,
|
||||
'缺少 musicId 参数'
|
||||
)
|
||||
}
|
||||
|
||||
let topid = /^\d+$/.test(originalSongId) ? originalSongId : ''
|
||||
if (!topid && /^\d+$/.test(musicId)) topid = musicId
|
||||
if (!topid) {
|
||||
try {
|
||||
const info = await getTxSongPlayableInfo(musicId)
|
||||
topid = String(info.songId || '').trim()
|
||||
} catch (error) {
|
||||
console.error('[QQ评论] 解析歌曲 ID 失败:', error instanceof Error ? error.message : error)
|
||||
throw createApiError(
|
||||
502,
|
||||
SERVER_ERROR_CODES.QQ_COMMENT_FETCH_FAILED,
|
||||
'QQ 音乐评论获取失败'
|
||||
)
|
||||
}
|
||||
}
|
||||
if (!topid) {
|
||||
throw createApiError(
|
||||
400,
|
||||
SERVER_ERROR_CODES.COMMON_INVALID_PARAMS,
|
||||
'QQ 音乐歌曲 ID 无效'
|
||||
)
|
||||
}
|
||||
|
||||
const requestBody = {
|
||||
comm: {
|
||||
ct: 11,
|
||||
cv: '1003006',
|
||||
v: '1003006',
|
||||
os_ver: '15',
|
||||
phonetype: '24122RKC7C',
|
||||
tmeAppID: 'qqmusiclight',
|
||||
nettype: 'NETWORK_WIFI',
|
||||
udid: '0',
|
||||
OpenUDID: '0',
|
||||
QIMEI36: '0',
|
||||
uin: '0'
|
||||
},
|
||||
request: {
|
||||
module: 'music.globalComment.CommentRead',
|
||||
method: type === 'hot' ? 'GetHotCommentList' : 'GetNewCommentList',
|
||||
param: buildQqCommentRequestParam({ topid, cursor, page, pageSize, type })
|
||||
}
|
||||
}
|
||||
|
||||
let response: QqCommentResponse | undefined
|
||||
try {
|
||||
response = (await txRequest(TX_MUSICU_URL, requestBody, {
|
||||
signal: AbortSignal.timeout(8000)
|
||||
})) as QqCommentResponse
|
||||
} catch (error) {
|
||||
console.warn('[QQ评论] 直连接口请求失败,尝试签名接口:', error)
|
||||
}
|
||||
|
||||
if (!isSuccessfulResponse(response)) {
|
||||
try {
|
||||
response = (await txSignedRequest(requestBody, {
|
||||
signal: AbortSignal.timeout(8000)
|
||||
})) as QqCommentResponse
|
||||
} catch (error) {
|
||||
console.error('[QQ评论] 签名接口请求失败:', error instanceof Error ? error.message : error)
|
||||
throw createApiError(
|
||||
502,
|
||||
SERVER_ERROR_CODES.QQ_COMMENT_FETCH_FAILED,
|
||||
'QQ 音乐评论获取失败'
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (!isSuccessfulResponse(response)) {
|
||||
throw createApiError(
|
||||
502,
|
||||
SERVER_ERROR_CODES.QQ_COMMENT_FETCH_FAILED,
|
||||
'QQ 音乐评论获取失败'
|
||||
)
|
||||
}
|
||||
const { list, comments: responseComments } = getCommentListData(response)
|
||||
const rawComments = Array.isArray(responseComments) ? responseComments : []
|
||||
const normalizedPage = normalizeQqCommentPage(rawComments)
|
||||
const commentItems = normalizedPage.comments
|
||||
|
||||
return {
|
||||
code: 200,
|
||||
data: {
|
||||
comments: commentItems,
|
||||
orphanReplies: normalizedPage.orphanReplies,
|
||||
total: Number(list.Total ?? list.total) || commentItems.length,
|
||||
more: Number(list.HasMore ?? list.hasMore ?? list.hasmore) === 1,
|
||||
nextCursor:
|
||||
Number(list.HasMore ?? list.hasMore ?? list.hasmore) === 1
|
||||
? String(rawComments.at(-1)?.SeqNo || rawComments.at(-1)?.seqNo || '')
|
||||
: ''
|
||||
}
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user