Files
BYW-VoiceHub/server/services/kugouService.ts
T
Henry_Du 381f3debf1 fix(admin+server): 酷狗 baseUrl 默认值移除 127.0.0.1 + 新增后台配置入口与推荐快捷地址
问题:容器内 SystemSettings.kugouApiBaseUrl 默认 http://127.0.0.1:3000 指向自己,sidecar 不可达。

修复:1) schema + migration 移除 kugouApiBaseUrl 默认值;kugouService + status API 兜底改空串(不再假设有 localhost),优先级 env(KUGOU_API_BASE) > DB。

2) 新增 POST /api/admin/kugou/settings:ADMIN+/SUPER 即时写 kugouApiBaseUrl 入库+刷新 CacheService。

3) KuGouImporter.client.vue 左栏新增 baseUrl 输入框(回车即存)+ 保存并测试按钮 + 两个推荐快捷按钮(容器宿主 http://172.19.0.1:3000、公网中继 https://bywmusic.bzw-hheb.top/kugou)+ 当前生效地址显式提示。

4) UI/Icon.vue 新增 server / globe / save 三个 SVG 图标与上述入口配套。
2026-09-19 13:40:59 +08:00

103 lines
2.6 KiB
TypeScript

import { ofetch } from 'ofetch'
import { db } from '~/drizzle/db'
import { systemSettings } from '~/drizzle/schema'
import { CacheService } from './cacheService'
export interface KuGouQrLoginStep1 {
status?: number
data?: {
qr_id?: string
login_id?: string
qrimg?: string
img?: string
extra?: any
}
error?: string
errcode?: number
}
export interface KuGouQrLoginStep2 {
status?: number
data?: {
status?: number
token?: string
cookie?: string
userinfo?: any
auth_params?: any
}
error?: string
errcode?: number
message?: string
}
let cacheService: CacheService | null = null
function getCache() {
if (!cacheService) cacheService = CacheService.getInstance()
return cacheService
}
async function readAdminSettings() {
try {
const c = getCache()
const cached = await c.getSystemSettings?.()
if (cached && (cached.kugouApiBaseUrl || cached.kugouAdminToken || cached.kugouAdminCookie)) {
return cached
}
} catch (_) {}
const rows = await db.select().from(systemSettings).limit(1)
return rows[0] || null
}
export interface KuGouCallOptions {
forceCookie?: string
forceToken?: string
}
export async function kuGouFetch<T = any>(
path: string,
query?: Record<string, any>,
options?: KuGouCallOptions,
): Promise<T> {
const settings = (await readAdminSettings()) as any
const base = (options?.forceToken ? null : settings?.kugouApiBaseUrl) || process.env.KUGOU_API_BASE || ''
const headers: Record<string, string> = {
'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128 Safari/537.36',
}
const cookie = options?.forceCookie || settings?.kugouAdminCookie
if (cookie) headers.Cookie = cookie
const url = base + path
return await ofetch<T>(url, {
query,
headers,
retry: 1,
timeout: 20000,
onRequest({ options }) {
const token = options?.forceToken || settings?.kugouAdminToken
if (token && options.query) {
;(options.query as any).token = token
}
},
})
}
export async function kuGouQrLoginCreate(platform: 'web' | 'android' | 'lite' = 'web') {
return await kuGouFetch<KuGouQrLoginStep1>(
platform === 'lite' ? '/login/qr/lite/create' : '/login/qr/create',
{ timestamp: Date.now() },
)
}
export async function kuGouQrLoginCheck(params: { qr_id?: string; login_id?: string; key?: string; cookie?: string }) {
return await kuGouFetch<KuGouQrLoginStep2>(
'/login/qr/check',
{
qr_id: params.qr_id,
login_id: params.login_id,
key: params.key,
timestamp: Date.now(),
},
{ forceCookie: params.cookie },
)
}