feat: 全站多语言支持 (i18n),lang=en 显示英文,其余默认中文

新增 src/lib/locale.ts 作为统一多语言入口,覆盖前台支付链路、
管理后台、API/服务层错误文案,共 35 个文件。URL 参数 lang 全链路透传,
包括 Stripe return_url、页面跳转、layout html lang 属性等。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
erio
2026-03-09 18:33:57 +08:00
parent 5cebe85079
commit 2492031e13
35 changed files with 1997 additions and 579 deletions

View File

@@ -1,56 +1,99 @@
'use client';
import type { Locale } from '@/lib/locale';
interface OrderStatusProps {
status: string;
onBack: () => void;
dark?: boolean;
locale?: Locale;
}
const STATUS_CONFIG: Record<string, { label: string; color: string; icon: string; message: string }> = {
COMPLETED: {
label: '充值成功',
color: 'text-green-600',
icon: '✓',
message: '余额已到账,感谢您的充值!',
const STATUS_CONFIG: Record<Locale, Record<string, { label: string; color: string; icon: string; message: string }>> = {
zh: {
COMPLETED: {
label: '充值成功',
color: 'text-green-600',
icon: '✓',
message: '余额已到账,感谢您的充值!',
},
PAID: {
label: '充值中',
color: 'text-blue-600',
icon: '⟳',
message: '支付成功,正在充值余额中...',
},
RECHARGING: {
label: '充值中',
color: 'text-blue-600',
icon: '⟳',
message: '正在充值余额中,请稍候...',
},
FAILED: {
label: '充值失败',
color: 'text-red-600',
icon: '✗',
message: '充值失败,请联系管理员处理。',
},
EXPIRED: {
label: '订单超时',
color: 'text-gray-500',
icon: '⏰',
message: '订单已超时,请重新创建订单。',
},
CANCELLED: {
label: '已取消',
color: 'text-gray-500',
icon: '✗',
message: '订单已取消。',
},
},
PAID: {
label: '充值中',
color: 'text-blue-600',
icon: '⟳',
message: '支付成功,正在充值余额中...',
},
RECHARGING: {
label: '充值中',
color: 'text-blue-600',
icon: '⟳',
message: '正在充值余额中,请稍候...',
},
FAILED: {
label: '充值失败',
color: 'text-red-600',
icon: '✗',
message: '充值失败,请联系管理员处理。',
},
EXPIRED: {
label: '订单超时',
color: 'text-gray-500',
icon: '⏰',
message: '订单已超时,请重新创建订单。',
},
CANCELLED: {
label: '已取消',
color: 'text-gray-500',
icon: '✗',
message: '订单已取消。',
en: {
COMPLETED: {
label: 'Recharge Successful',
color: 'text-green-600',
icon: '✓',
message: 'Your balance has been credited. Thank you for your payment.',
},
PAID: {
label: 'Recharging',
color: 'text-blue-600',
icon: '⟳',
message: 'Payment received. Recharging your balance...',
},
RECHARGING: {
label: 'Recharging',
color: 'text-blue-600',
icon: '⟳',
message: 'Recharging your balance. Please wait...',
},
FAILED: {
label: 'Recharge Failed',
color: 'text-red-600',
icon: '✗',
message: 'Recharge failed. Please contact the administrator.',
},
EXPIRED: {
label: 'Order Expired',
color: 'text-gray-500',
icon: '',
message: 'This order has expired. Please create a new order.',
},
CANCELLED: {
label: 'Cancelled',
color: 'text-gray-500',
icon: '✗',
message: 'The order has been cancelled.',
},
},
};
export default function OrderStatus({ status, onBack, dark = false }: OrderStatusProps) {
const config = STATUS_CONFIG[status] || {
export default function OrderStatus({ status, onBack, dark = false, locale = 'zh' }: OrderStatusProps) {
const config = STATUS_CONFIG[locale][status] || {
label: status,
color: 'text-gray-600',
icon: '?',
message: '未知状态',
message: locale === 'en' ? 'Unknown status' : '未知状态',
};
return (
@@ -65,7 +108,7 @@ export default function OrderStatus({ status, onBack, dark = false }: OrderStatu
dark ? 'bg-blue-600 hover:bg-blue-500' : 'bg-blue-600 hover:bg-blue-700',
].join(' ')}
>
{status === 'COMPLETED' ? '完成' : '返回充值'}
{status === 'COMPLETED' ? (locale === 'en' ? 'Done' : '完成') : locale === 'en' ? 'Back to Recharge' : '返回充值'}
</button>
</div>
);