mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-09-24 16:05:44 +08:00
feat(payment): localize config-field names in error messages
之前错误提示里直接显示原始字段名(certSerial / apiV3Key),用户看不懂。 在 extractI18nErrorMessage 内加 localizeMetadata:自动把 metadata.key 和 metadata.keys(斜杠分隔)对应到 admin.settings.payment.field_<key> 的 i18n 标签,查不到才回退原文。 - 「微信支付配置缺少必填项:certSerial」 → 「微信支付配置缺少必填项:证书序列号」 - 「publicKey/publicKeyId must be provided together」 → 「公钥 / 公钥 ID 必须同时配置」
This commit is contained in:
@@ -48,10 +48,45 @@ export function extractApiErrorMetadata(err: unknown): Record<string, unknown> |
|
||||
type TranslateFn = (key: string, params?: Record<string, unknown>) => string
|
||||
type TranslateWithExistsFn = TranslateFn & { te?: (key: string) => boolean }
|
||||
|
||||
/**
|
||||
* Translate a value via i18n if a matching key exists, otherwise return the original.
|
||||
* Example: "certSerial" → t('admin.settings.payment.field_certSerial') → "证书序列号".
|
||||
*/
|
||||
function tryTranslate(t: TranslateFn, key: string, fallback: string): string {
|
||||
const translated = t(key)
|
||||
if (translated === key) return fallback
|
||||
const te = (t as TranslateWithExistsFn).te
|
||||
if (te && !te(key)) return fallback
|
||||
return translated
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace raw config field names in metadata (e.g. "certSerial") with their
|
||||
* localized UI labels (e.g. "证书序列号"), using the provider-config field i18n namespace.
|
||||
* Handles both single `key` and `/`-joined `keys` patterns used by wxpay errors.
|
||||
*/
|
||||
function localizeMetadata(metadata: Record<string, unknown>, t: TranslateFn): Record<string, unknown> {
|
||||
const out: Record<string, unknown> = { ...metadata }
|
||||
if (typeof out.key === 'string') {
|
||||
out.key = tryTranslate(t, `admin.settings.payment.field_${out.key}`, out.key)
|
||||
}
|
||||
if (typeof out.keys === 'string') {
|
||||
out.keys = out.keys
|
||||
.split('/')
|
||||
.map(k => tryTranslate(t, `admin.settings.payment.field_${k}`, k))
|
||||
.join(' / ')
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a localized error message from an API error by looking up
|
||||
* `<namespace>.<REASON>` in i18n and substituting metadata as placeholders.
|
||||
*
|
||||
* Config-field names in metadata (`key` / `keys`) are automatically translated
|
||||
* to their UI labels before substitution, so error messages read like
|
||||
* "缺少必填项:证书序列号" instead of "缺少必填项:certSerial".
|
||||
*
|
||||
* @param err - The caught error
|
||||
* @param t - Vue i18n translate function
|
||||
* @param namespace- i18n key prefix, e.g. "payment.errors"
|
||||
@@ -66,7 +101,8 @@ export function extractI18nErrorMessage(
|
||||
const code = extractApiErrorCode(err)
|
||||
if (code) {
|
||||
const key = `${namespace}.${code}`
|
||||
const metadata = extractApiErrorMetadata(err) ?? {}
|
||||
const rawMetadata = extractApiErrorMetadata(err) ?? {}
|
||||
const metadata = localizeMetadata(rawMetadata, t)
|
||||
const translated = t(key, metadata)
|
||||
// Vue i18n returns the key itself when missing; detect that and fall back.
|
||||
if (translated !== key) return translated
|
||||
|
||||
Reference in New Issue
Block a user