问题:容器内 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 图标与上述入口配套。
103 lines
2.6 KiB
TypeScript
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 },
|
|
)
|
|
}
|