diff --git a/apps/backend/src/services/platforms/kuaishou-industry/openapi-client.ts b/apps/backend/src/services/platforms/kuaishou-industry/openapi-client.ts index b3fa17c7..d07c5999 100644 --- a/apps/backend/src/services/platforms/kuaishou-industry/openapi-client.ts +++ b/apps/backend/src/services/platforms/kuaishou-industry/openapi-client.ts @@ -33,11 +33,12 @@ export async function requestKuaishouIndustryOpenApi( input: KuaishouIndustryOpenApiCallInput, ): Promise { let config = getKuaishouIndustryConfig() + const apiLabel = formatKuaishouOpenApiLabel(input.apiMethod) if (!config.enabled) { logKuaishouOpenApi( input, - `快手 OpenAPI 未启用,跳过 ${input.apiMethod}`, + `快手 OpenAPI 未启用,跳过 ${apiLabel}`, undefined, ) return { success: true, skippedReason: 'disabled' } @@ -56,7 +57,7 @@ export async function requestKuaishouIndustryOpenApi( } catch (error) { logKuaishouOpenApi( input, - `快手 OpenAPI token 准备失败 ${input.apiMethod}`, + `快手 OpenAPI token 准备失败 ${apiLabel}`, resolveKuaishouOpenApiErrorDetail(error), 'warn', ) @@ -71,7 +72,7 @@ export async function requestKuaishouIndustryOpenApi( if (!config.accessToken) { logKuaishouOpenApi( input, - `快手 OpenAPI accessToken 缺失 ${input.apiMethod}`, + `快手 OpenAPI accessToken 缺失 ${apiLabel}`, undefined, 'warn', ) @@ -110,7 +111,7 @@ export async function requestKuaishouIndustryOpenApi( }) input.onRequest?.(requestLog) - logKuaishouOpenApi(input, `发起快手 OpenAPI ${input.apiMethod}`, requestLog) + logKuaishouOpenApi(input, `发起快手 OpenAPI ${apiLabel}`, requestLog) try { const startedAt = Date.now() @@ -134,8 +135,8 @@ export async function requestKuaishouIndustryOpenApi( logKuaishouOpenApi( input, success - ? `快手 OpenAPI 调用成功 ${input.apiMethod}` - : `快手 OpenAPI 调用失败 ${input.apiMethod}`, + ? `快手 OpenAPI 调用成功 ${apiLabel}` + : `快手 OpenAPI 调用失败 ${apiLabel}`, { durationMs, httpStatus: res.status, @@ -156,7 +157,7 @@ export async function requestKuaishouIndustryOpenApi( const errorDetail = resolveKuaishouOpenApiErrorDetail(error) logKuaishouOpenApi( input, - `快手 OpenAPI 调用异常 ${input.apiMethod}`, + `快手 OpenAPI 调用异常 ${apiLabel}`, { ...errorDetail, request: requestLog, @@ -187,6 +188,7 @@ export function buildKuaishouOpenApiRequestLog({ url, method: httpMethod || 'POST', contentType: 'application/x-www-form-urlencoded', + apiName: resolveKuaishouOpenApiName(signParams.method), apiMethod: signParams.method, appkey: signParams.appkey, access_token: signParams.access_token, @@ -251,3 +253,25 @@ function logKuaishouOpenApi( logIntegration('[kuaishou-industry/openapi]', message, detail, { level }) } + +function formatKuaishouOpenApiLabel(method: unknown): string { + const apiMethod = String(method || '').trim() + const apiName = resolveKuaishouOpenApiName(apiMethod) + return apiName ? `${apiName}(${apiMethod})` : apiMethod +} + +function resolveKuaishouOpenApiName(method: unknown): string { + const apiMethod = String(method || '').trim() + const names: Record = { + 'integration.callback.virtual.eticket.send': '电子凭证发货回调', + 'integration.callback.virtual.eticket.consume': '电子凭证核销回调', + 'integration.callback.virtual.eticket.destroy': '电子凭证销毁回调', + 'integration.callback.virtual.eticket.reverse': '电子凭证冲正回调', + 'open.virtual.eticket.checkavailable': '检查电子凭证有效性', + 'open.seller.order.refund.pcursor.list': '售后单列表', + 'open.seller.order.refund.approve': '商家同意退款', + 'open.seller.order.refund.disagree.refund': '商家不同意退款', + } + + return names[apiMethod] || '' +} diff --git a/apps/frontend/src/pages/admin/AdminKuaishouIndustryPage.tsx b/apps/frontend/src/pages/admin/AdminKuaishouIndustryPage.tsx index 65302d0d..aa74da4b 100644 --- a/apps/frontend/src/pages/admin/AdminKuaishouIndustryPage.tsx +++ b/apps/frontend/src/pages/admin/AdminKuaishouIndustryPage.tsx @@ -49,6 +49,7 @@ import { formatAdminDateTime } from '@/utils/admin-time' import { stringifyDisplayJson } from '@/utils/date-time' type DateRangeValue = [Dayjs | null, Dayjs | null] | null +type IndustryTab = 'vouchers' | 'refunds' | 'result' type VoucherFilterState = { oid: string @@ -74,6 +75,7 @@ type RefundListState = { const DEFAULT_ETICKET_TYPE = 'DINING_OPEN_TICKET' export default function AdminKuaishouIndustryPage() { + const [activeTab, setActiveTab] = useState('vouchers') const [voucherLoading, setVoucherLoading] = useState(false) const [actionLoading, setActionLoading] = useState('') const [vouchers, setVouchers] = useState([]) @@ -289,6 +291,7 @@ export default function AdminKuaishouIndustryPage() { const response = await consumeAdminKuaishouIndustryVoucher(buildVoucherToolPayload()) setLastResultTitle('手动核销') setLastResult(response.data) + setActiveTab('result') showSuccess('手动核销已完成') await loadVouchers() } catch (error) { @@ -304,6 +307,7 @@ export default function AdminKuaishouIndustryPage() { const response = await resendAdminKuaishouIndustryVoucherCode(buildVoucherToolPayload()) setLastResultTitle('重发发码回调') setLastResult(response.data) + setActiveTab('result') if (response.data.success) { showSuccess('发码回调已重发') } else { @@ -361,6 +365,7 @@ export default function AdminKuaishouIndustryPage() { const response = await action() setLastResultTitle(title) setLastResult(response.data) + setActiveTab('result') afterSuccess?.(response.data) if (response.data.success) { showSuccess(`${title}已执行`) @@ -407,6 +412,8 @@ export default function AdminKuaishouIndustryPage() { setActiveTab(key as IndustryTab)} items={[ { key: 'vouchers', @@ -768,6 +775,8 @@ export default function AdminKuaishouIndustryPage() { } function renderResultTab() { + const summary = resolveOpenApiResultSummary(lastResult) + return ( {lastResult ? ( -
{stringifyDisplayJson(lastResult)}
+ + +
{stringifyDisplayJson(lastResult)}
+
) : ( )} @@ -809,6 +826,40 @@ function extractRefundRows(response: Record | null): Array + : {} + const response = result.response && typeof result.response === 'object' && !Array.isArray(result.response) + ? result.response as Record + : null + const success = Boolean(result.success) + const code = String(response?.code || response?.sub_code || '').trim() + const resultCode = String(response?.result || '').trim() + const message = String( + response?.error_msg || + response?.msg || + response?.sub_msg || + response?.message || + result.error || + '', + ).trim() + const status = Number(result.httpStatus || 0) || 0 + const durationMs = Number(result.durationMs || 0) || 0 + const markers = [ + status ? `HTTP ${status}` : '', + resultCode ? `result=${resultCode}` : '', + code ? `code=${code}` : '', + durationMs ? `${durationMs}ms` : '', + ].filter(Boolean) + + return { + success, + title: success ? '接口返回成功' : '接口返回失败', + description: [markers.join(' / '), message].filter(Boolean).join(',') || '请查看下方原始响应。', + } +} + function getVoucherStatusColor(status: string) { const normalized = String(status || '').toUpperCase() if (normalized === 'CONSUMED') return 'green'