Refactor and enhance localization support; update language files and improve validation messages

- Updated localization files for Arabic and Traditional Chinese (Hong Kong).
- Added Arabic language support in the i18n configuration.
- Improved validation messages in the withdrawal schema.
- Refactored Vue components to ensure consistent usage of translation functions.
- Cleaned up CSS files for better formatting and consistency.
This commit is contained in:
2025-12-20 05:30:59 +07:00
parent 11bcbafd6e
commit 3d9785fdf2
16 changed files with 719 additions and 51 deletions

View File

@@ -1,4 +1,3 @@
Riwa-Ionic 项目提示词
你是一个专业的移动应用开发助手,负责协助开发基于 Ionic + Vue 3 + TypeScript + Capacitor 的跨平台移动应用项目。

View File

@@ -7,7 +7,7 @@ export default defineConfig({
videosFolder: "tests/e2e/videos",
screenshotsFolder: "tests/e2e/screenshots",
baseUrl: "http://localhost:5173",
// eslint-disable-next-line unused-imports/no-unused-vars
setupNodeEvents(on, config) {
// implement node event listeners here
},

View File

@@ -4,12 +4,12 @@ import { toastController } from "@ionic/vue";
import { logoGoogle, phonePortraitOutline } from "ionicons/icons";
import { authClient } from "@/auth";
const { t } = useI18n();
const emit = defineEmits<{
(e: "success", value: string): void;
}>();
const { t } = useI18n();
const model = defineModel({ type: String, required: true });
const inputInstance = useTemplateRef<InputInstance>("inputInstance");
@@ -48,7 +48,7 @@ async function submitSendVerification() {
}
else {
const toast = await toastController.create({
message: error?.message || t('auth.common.failedSendCode'),
message: error?.message || t("auth.common.failedSendCode"),
duration: 1500,
position: "bottom",
});

View File

@@ -1,20 +1,22 @@
<script lang='ts' setup>
import { toastController } from "@ionic/vue";
const { t } = useI18n();
const props = defineProps<{
email: string;
}>();
const emit = defineEmits<{
(e: "success", value: string): void;
}>();
const { t } = useI18n();
const model = defineModel({ type: String, required: true });
async function submitSignup() {
if (model.value.length !== 6) {
const toast = await toastController.create({
message: t('auth.common.validVerificationCodeError'),
message: t("auth.common.validVerificationCodeError"),
duration: 1500,
position: "bottom",
});

View File

@@ -4,12 +4,12 @@ import { toastController } from "@ionic/vue";
import { logoGoogle, phonePortraitOutline } from "ionicons/icons";
import { authClient } from "@/auth";
const { t } = useI18n();
const emit = defineEmits<{
(e: "success", value: string): void;
}>();
const { t } = useI18n();
const model = defineModel({ type: String, required: true });
const inputInstance = useTemplateRef<InputInstance>("inputInstance");
@@ -48,7 +48,7 @@ async function submitSendVerification() {
}
else {
const toast = await toastController.create({
message: error?.message || t('auth.common.failedSendCode'),
message: error?.message || t("auth.common.failedSendCode"),
duration: 1500,
position: "bottom",
});

View File

@@ -3,17 +3,18 @@ import type { PropType } from "vue";
import type { AuthUserSignup } from "@/auth/type";
import { toastController } from "@ionic/vue";
const { t } = useI18n();
const emit = defineEmits<{
(e: "success", value: AuthUserSignup): void;
}>();
const { t } = useI18n();
const model = defineModel({ type: Object as PropType<AuthUserSignup>, required: true });
async function submitSignup() {
if (model.value.verificationCode.length !== 6) {
const toast = await toastController.create({
message: t('auth.common.validVerificationCodeError'),
message: t("auth.common.validVerificationCodeError"),
duration: 1500,
position: "bottom",
});

View File

@@ -36,7 +36,7 @@ async function submitSignup() {
step.value = 1;
await modalController.dismiss(data.user);
const toast = await toastController.create({
message: t('auth.signup.emailVerified'),
message: t("auth.signup.emailVerified"),
duration: 1500,
position: "bottom",
});
@@ -45,7 +45,7 @@ async function submitSignup() {
}
else {
const toast = await toastController.create({
message: error?.message || t('auth.common.failedVerifyCode'),
message: error?.message || t("auth.common.failedVerifyCode"),
duration: 1500,
position: "bottom",
});

View File

@@ -1,2 +1,2 @@
export { default as Collapse } from './index.vue';
export type * from './types';
export { default as Collapse } from "./index.vue";
export type * from "./types";

View File

@@ -21,11 +21,21 @@ export function useLanguage() {
name: "Chinese (Simplified)",
nativeName: "简体中文",
},
{
code: "zh-HK",
name: "Chinese (Hong Kong)",
nativeName: "繁體中文",
},
{
code: "en-US",
name: "English (US)",
nativeName: "English",
},
{
code: "ar",
name: "Arabic",
nativeName: "العربية",
},
];
// 当前语言

325
src/locales/ar.json Normal file
View File

@@ -0,0 +1,325 @@
{
"wallet": {
"wallet": "المحفظة",
"recharge": "إعادة الشحن",
"withdraw": "سحب",
"transfer": "تحويل",
"balance": "الرصيد"
},
"recharge": {
"channel": {
"chainRecharge": "إعادة الشحن عبر البلوكشين",
"chainRechargeDesc": "تحويل العملات المشفرة من محفظة البلوكشين أو البورصة",
"fiatCurrency": "إعادة الشحن بالعملة الورقية",
"fiatCurrencyDesc": "تحويل العملة الورقية عبر البنك أو المؤسسات المالية الأخرى"
},
"fiat": {
"title": "إعادة الشحن بالعملة الورقية",
"bankAccount": "حساب البطاقة البنكية لإعادة الشحن",
"chooseCurrency": "اختر العملة",
"amount": "المبلغ",
"enterAmount": "الرجاء إدخال المبلغ",
"validAmountError": "الرجاء إدخال مبلغ صحيح.",
"note": "يرجى التأكد من إدخال المبلغ الصحيح. بعد التقديم، سيتم إضافة الأموال إلى حسابك بعد المراجعة الخلفية.",
"submit": "إرسال",
"submitSuccess": "تم التقديم بنجاح!"
}
},
"withdraw": {
"title": "سحب",
"chooseCurrency": "اختر العملة",
"chooseMethod": "اختر طريقة السحب",
"amount": "المبلغ",
"enterAmountMax": "الرجاء إدخال المبلغ (الحد الأقصى: {amount})",
"validAmountError": "الرجاء إدخال مبلغ صحيح.",
"bankAccountId": "معرف الحساب البنكي",
"enterBankAccountId": "الرجاء إدخال معرف الحساب البنكي",
"validBankAccountError": "الرجاء إدخال معرف حساب بنكي صحيح.",
"chooseChain": "اختر البلوكشين",
"cryptoAddress": "عنوان العملة المشفرة",
"enterCryptoAddress": "الرجاء إدخال عنوان العملة المشفرة",
"validCryptoAddressError": "الرجاء إدخال عنوان عملة مشفرة صحيح.",
"successMessage": "تم تقديم طلب السحب بنجاح!",
"submit": "إرسال",
"assetCode": {
"USDT": "USDT",
"OPTS": "OPTS"
},
"method": {
"bank": "التحويل البنكي",
"crypto": "العملة المشفرة",
"cash": "نقدا"
},
"validation": {
"assetCodeRequired": "الرجاء اختيار العملة",
"amountRequired": "الرجاء إدخال المبلغ",
"amountInvalid": "الرجاء إدخال صيغة رقمية صحيحة",
"amountExceedsBalance": "لا يمكن أن يتجاوز المبلغ الرصيد المتاح",
"amountTooSmall": "يجب أن يكون المبلغ أكبر من 0",
"methodRequired": "الرجاء اختيار طريقة السحب",
"bankAccountRequired": "الرجاء اختيار الحساب البنكي",
"chainRequired": "الرجاء اختيار شبكة البلوكشين",
"addressRequired": "الرجاء إدخال عنوان السحب",
"addressTooShort": "صيغة العنوان غير صحيحة، الطول قصير جدًا"
}
},
"bankCard": {
"management": "إدارة البطاقات البنكية",
"add": "إضافة بطاقة بنكية",
"empty": {
"title": "لا توجد بطاقة بنكية",
"description": "أضف بطاقة بنكية لإعادة الشحن والسحب السريع",
"addButton": "إضافة بطاقة بنكية"
},
"list": {
"addCard": "إضافة بطاقة بنكية",
"boundCards": "البطاقات البنكية المربوطة",
"defaultCard": "البطاقة البنكية الافتراضية",
"setDefault": "تعيين كافتراضي",
"edit": "تعديل",
"delete": "حذف",
"cancel": "إلغاء",
"debitCard": "بطاقة توفير"
},
"form": {
"tips": {
"title": "تذكير دافئ",
"description": "لضمان سلامة أموالك، يرجى التأكد من صحة معلومات البطاقة البنكية. ستُستخدم البطاقة البنكية المضافة لعمليات إعادة الشحن والسحب."
},
"bankName": "اسم البنك",
"bankNamePlaceholder": "الرجاء اختيار البنك الخاص بك",
"accountNumber": "رقم البطاقة البنكية",
"accountNumberPlaceholder": "الرجاء إدخال رقم البطاقة البنكية",
"accountNumberHelper": "يدعم أرقام البطاقات البنكية من 16-19 رقمًا",
"accountName": "اسم حامل البطاقة",
"accountNamePlaceholder": "الرجاء إدخال اسم حامل البطاقة",
"accountNameHelper": "الرجاء إدخال الاسم الحقيقي عند فتح الحساب البنكي",
"security": {
"title": "ضمان الأمان",
"encryption": "يتم نقل جميع معلومات البطاقة البنكية مشفرة بـ SSL",
"standard": "نلتزم بصرامة بمعايير الأمان على مستوى البنوك",
"privacy": "سيتم حماية معلوماتك الشخصية بشكل صحيح"
},
"submit": "تأكيد إضافة البطاقة البنكية",
"validation": {
"bankRequired": "الرجاء اختيار البنك",
"accountNumberRequired": "الرجاء إدخال رقم البطاقة البنكية",
"accountNameRequired": "الرجاء إدخال اسم حامل البطاقة"
}
},
"messages": {
"addSuccess": "تمت إضافة البطاقة البنكية بنجاح",
"setDefaultSuccess": "تم التعيين كبطاقة بنكية افتراضية",
"deleteSuccess": "تم حذف البطاقة البنكية بنجاح",
"deleteConfirm": "حذف البطاقة البنكية",
"deleteMessage": "هل أنت متأكد من حذف {bankName} ({accountName})؟ لا يمكن التراجع عن هذا الإجراء."
},
"tips": {
"encryption": "معلومات البطاقة البنكية محمية بالتشفير",
"support": "يدعم البنوك الرئيسية لإعادة الشحن والسحب السريع"
}
},
"trade": {
"title": "التداول",
"settings": {
"bankManagement": "إدارة البطاقات البنكية",
"mySubscribe": "اشتراكاتي"
}
},
"asset": {
"issue": {
"issuingAsset": "إصدار الأصول",
"myCompany": "شركتي",
"issuingApply": "طلب الإصدار",
"audit": "التدقيق والمراجعة",
"supervision": "الإشراف بالوكالة",
"apply": {
"title": "طلب الإصدار",
"base": "المعلومات الأساسية",
"issuePeriod": "فترة الإصدار",
"productName": "اسم المنتج",
"enterProductName": "الرجاء إدخال اسم المنتج",
"productCode": "رمز المنتج",
"enterProductCode": "الرجاء إدخال رمز المنتج",
"productType": "نوع المنتج",
"chooseProductType": "الرجاء اختيار نوع المنتج",
"productValue": "تقييم المنتج",
"enterProductValue": "الرجاء إدخال تقييم المنتج (بالدولار الأمريكي)",
"assetProof": "إثبات الأصول",
"enterAssetProof": "الرجاء إدخال إثبات الأصول",
"totalSupplyLimit": "الحد الأقصى لإجمالي الإصدار",
"enterTotalSupplyLimit": "الرجاء إدخال الحد الأقصى لإجمالي الإصدار",
"editionName": "اسم فترة الإصدار",
"enterEditionName": "الرجاء إدخال اسم فترة الإصدار",
"launchDate": "تاريخ الإصدار",
"enterLaunchDate": "الرجاء إدخال تاريخ الإصدار",
"perUserLimit": "الحد الأقصى للاشتراك الفردي",
"enterPerUserLimit": "الرجاء إدخال الحد الأقصى للاشتراك الفردي",
"totalSupply": "إجمالي الإصدار",
"enterTotalSupply": "الرجاء إدخال إجمالي الإصدار",
"subscriptionDeadline": "الموعد النهائي للاشتراك",
"enterSubscriptionDeadline": "الرجاء إدخال الموعد النهائي للاشتراك",
"unitPrice": "سعر الوحدة",
"enterUnitPrice": "الرجاء إدخال سعر الوحدة",
"dividendRate": "معدل الأرباح",
"enterDividendRate": "معدل الأرباح (مثل 0.01 يمثل 1٪)",
"issuePeriodIndex": "فترة الإصدار {index}",
"realEstate": "العقارات",
"snickers": "الحلوى",
"next": "التالي",
"back": "العودة",
"submit": "إرسال",
"addStep": "إضافة فترة إصدار",
"removeItem": "إزالة العنصر",
"validation": {
"nameRequired": "اسم المنتج مطلوب",
"codeRequired": "رمز المنتج مطلوب",
"categoryRequired": "نوع المنتج مطلوب",
"editionNameRequired": "اسم فترة الإصدار مطلوب",
"launchDateRequired": "تاريخ الإصدار مطلوب",
"launchDateNotPast": "لا يمكن أن يكون تاريخ الإصدار قبل التاريخ الحالي",
"perUserLimitRequired": "الحد الأقصى للاشتراك الفردي مطلوب",
"totalSupplyRequired": "إجمالي الإصدار مطلوب",
"subscriptionDeadlineRequired": "الموعد النهائي للاشتراك مطلوب",
"deadlineAfterLaunch": "لا يمكن أن يكون الموعد النهائي للاشتراك قبل تاريخ الإصدار",
"unitPriceRequired": "سعر الوحدة مطلوب",
"dividendRateRequired": "معدل الأرباح مطلوب"
},
"done": {
"title": "تم تقديم الطلب بنجاح",
"description": "تم تقديم طلب الإصدار الخاص بك بنجاح، وسنراجع طلبك خلال أيام العمل. يرجى انتظار نتيجة المراجعة بصبر.",
"viewProducts": "عرض منتجاتي"
}
}
},
"purchase": {
"purchaseAsset": "شراء الأصول",
"fiatPurchase": "الشراء بالعملة الورقية",
"cryptoPurchase": "الشراء بالعملة الرقمية",
"realEstate": "العقارات",
"assetExchange": "تبادل الأصول"
},
"balance": {
"assetBalance": "رصيد الأصول",
"fiat": "العملة الورقية",
"onChain": "على البلوكشين",
"wallet": "المحفظة",
"recharge": "إعادة الشحن"
},
"revenue": {
"myRevenue": "إيراداتي",
"totalRevenue": "إجمالي الإيرادات",
"monthlyRevenue": "الإيرادات الشهرية",
"pendingRevenue": "الإيرادات المعلقة",
"revenueDetails": "تفاصيل الإيرادات"
}
},
"market": {
"title": "السوق",
"search": {
"placeholder": "بحث"
},
"category": {
"all": "الكل"
},
"rwaList": {
"nameCode": "الاسم/الرمز",
"stage": "المرحلة",
"issueDate": "تاريخ الإصدار",
"subscriptionPrice": "سعر الاشتراك"
},
"tradeRwa": {
"tabs": {
"overview": "نظرة عامة",
"moment": "اللحظة"
},
"fields": {
"productCode": "رقم المنتج",
"valuation": "التقييم",
"unitPrice": "سعر الوحدة",
"totalSupply": "إجمالي الإصدار",
"perUserLimit": "الحد لكل شخص",
"launchDate": "وقت الإصدار",
"subscriptionDeadline": "الموعد النهائي للاشتراك"
},
"units": {
"shares": "أسهم"
},
"about": "حول",
"noDescription": "لا يوجد وصف.",
"subscribe": "اشترك",
"subscribeSuccess": "نجح الاشتراك"
},
"subscribeRwa": {
"title": "اشترك في RWA",
"maxSubscribePlaceholder": "الحد الأقصى للكمية القابلة للاشتراك: {max}",
"unitPrice": "سعر الوحدة",
"availableBalance": "الرصيد المتاح",
"confirmSubscribe": "تأكيد الاشتراك",
"enterQuantityError": "الرجاء إدخال كمية الاشتراك"
},
"loading": {
"loadingMore": "تحميل المزيد..."
}
},
"tabs": {
"riwa": "Riwa",
"market": "السوق",
"trade": "التداول",
"chat": "الدردشة",
"user": "حسابي"
},
"auth": {
"common": {
"close": "إغلاق",
"next": "التالي",
"submit": "إرسال",
"email": "البريد الإلكتروني",
"enterEmail": "الرجاء إدخال بريدك الإلكتروني",
"validEmailError": "الرجاء إدخال عنوان بريد إلكتروني صحيح.",
"orContinueWith": "أو المتابعة باستخدام",
"google": "Google",
"phoneNumber": "رقم الهاتف",
"validVerificationCodeError": "الرجاء إدخال رمز التحقق المكون من 6 أرقام صحيح.",
"failedSendCode": "فشل إرسال رمز التحقق.",
"failedVerifyCode": "فشل التحقق من رمز التحقق."
},
"login": {
"title": "تسجيل الدخول",
"loginButton": "تسجيل الدخول"
},
"signup": {
"title": "ما هو بريدك الإلكتروني؟",
"description": "ستستخدم هذا البريد الإلكتروني لتسجيل الدخول والوصول إلى جميع المحتويات التي نقدمها.",
"signupButton": "التسجيل",
"emailPlaceholder": "email@example.com",
"emailVerified": "تم التحقق من البريد الإلكتروني بنجاح!"
},
"verification": {
"title": "تحقق من بريدك الإلكتروني",
"description": "أرسلنا رمز تحقق إلى {email}. الرجاء إدخال الرمز أدناه للتحقق من عنوان بريدك الإلكتروني."
}
},
"settings": {
"title": "الإعدادات",
"language": "اللغة",
"aboutUs": "معلومات عنا",
"clearCache": "مسح ذاكرة التخزين المؤقت",
"checkUpdate": "التحقق من التحديثات",
"cacheCleared": "تم مسح ذاكرة التخزين المؤقت",
"updateAvailable": "تم العثور على إصدار جديد",
"currentVersion": "الإصدار الحالي",
"latestVersion": "أحدث إصدار",
"newVersion": "إصدار جديد",
"cancel": "إلغاء",
"updateNow": "تحديث الآن",
"alreadyLatest": "أنت تستخدم أحدث إصدار",
"checkUpdateFailed": "فشل التحقق من التحديثات",
"languageTitle": "اللغة / Language",
"theme": "المظهر",
"themeTitle": "مظهر الواجهة",
"themeLight": "فاتح",
"themeDark": "داكن",
"themeAuto": "تلقائي (حسب النظام)"
}
}

View File

@@ -1,16 +1,20 @@
import { createI18n } from "vue-i18n";
import ar from "./ar.json";
import enUS from "./en-US.json";
import zhCN from "./zh-CN.json";
import zhTW from "./zh-HK.json";
export type MessageSchema = typeof enUS;
const i18n = createI18n<MessageSchema, "en-US" | "zh-CN">({
const i18n = createI18n<MessageSchema, "en-US" | "zh-CN" | "zh-HK" | "ar">({
legacy: false,
locale: "zh-CN",
fallbackLocale: "en-US",
messages: {
"en-US": enUS,
"zh-CN": zhCN,
"zh-HK": zhTW,
"ar": ar,
},
});

325
src/locales/zh-HK.json Normal file
View File

@@ -0,0 +1,325 @@
{
"wallet": {
"wallet": "錢包",
"recharge": "充值",
"withdraw": "提現",
"transfer": "轉賬",
"balance": "餘額"
},
"recharge": {
"channel": {
"chainRecharge": "鏈上充值",
"chainRechargeDesc": "從鏈上錢包或交易所轉入加密貨幣",
"fiatCurrency": "法幣充值",
"fiatCurrencyDesc": "通過銀行或其他金融機構轉入法幣"
},
"fiat": {
"title": "法幣充值",
"bankAccount": "充值銀行卡賬戶",
"chooseCurrency": "選擇貨幣",
"amount": "金額",
"enterAmount": "請輸入金額",
"validAmountError": "請輸入有效的金額。",
"note": "請確保輸入正確的金額。提交後,資金將在後臺審核後計入您的賬戶。",
"submit": "提交",
"submitSuccess": "提交成功!"
}
},
"withdraw": {
"title": "提現",
"chooseCurrency": "選擇貨幣",
"chooseMethod": "選擇提現方式",
"amount": "金額",
"enterAmountMax": "請輸入金額(最大:{amount}",
"validAmountError": "請輸入有效的金額。",
"bankAccountId": "銀行賬戶ID",
"enterBankAccountId": "請輸入銀行賬戶ID",
"validBankAccountError": "請輸入有效的銀行賬戶ID。",
"chooseChain": "選擇鏈",
"cryptoAddress": "加密貨幣地址",
"enterCryptoAddress": "請輸入加密貨幣地址",
"validCryptoAddressError": "請輸入有效的加密貨幣地址。",
"successMessage": "提現申請提交成功!",
"submit": "提交",
"assetCode": {
"USDT": "USDT",
"OPTS": "OPTS"
},
"method": {
"bank": "銀行轉賬",
"crypto": "加密貨幣",
"cash": "現金"
},
"validation": {
"assetCodeRequired": "請選擇貨幣",
"amountRequired": "請輸入金額",
"amountInvalid": "請輸入有效的數字格式",
"amountExceedsBalance": "金額不能超過可用餘額",
"amountTooSmall": "金額必須大於0",
"methodRequired": "請選擇提現方式",
"bankAccountRequired": "請選擇銀行賬戶",
"chainRequired": "請選擇區塊鏈網絡",
"addressRequired": "請輸入提現地址",
"addressTooShort": "地址格式不正確,長度過短"
}
},
"bankCard": {
"management": "銀行卡管理",
"add": "添加銀行卡",
"empty": {
"title": "暫無銀行卡",
"description": "添加銀行卡以便快速充值和提現",
"addButton": "添加銀行卡"
},
"list": {
"addCard": "添加銀行卡",
"boundCards": "已綁定銀行卡",
"defaultCard": "默認銀行卡",
"setDefault": "設為默認",
"edit": "編輯",
"delete": "刪除",
"cancel": "取消",
"debitCard": "儲蓄卡"
},
"form": {
"tips": {
"title": "溫馨提示",
"description": "為了保障您的資金安全,請確保銀行卡信息真實有效。添加的銀行卡將用於充值和提現操作。"
},
"bankName": "銀行名稱",
"bankNamePlaceholder": "請選擇您的銀行",
"accountNumber": "銀行卡號",
"accountNumberPlaceholder": "請輸入銀行卡號",
"accountNumberHelper": "支持16-19位銀行卡號",
"accountName": "持卡人姓名",
"accountNamePlaceholder": "請輸入持卡人姓名",
"accountNameHelper": "請輸入銀行卡開戶時的真實姓名",
"security": {
"title": "安全保障",
"encryption": "所有銀行卡信息均經過SSL加密傳輸",
"standard": "我們嚴格遵循銀行級安全標準",
"privacy": "您的個人信息將被妥善保護"
},
"submit": "確認添加銀行卡",
"validation": {
"bankRequired": "請選擇銀行",
"accountNumberRequired": "請輸入銀行卡號",
"accountNameRequired": "請輸入持卡人姓名"
}
},
"messages": {
"addSuccess": "銀行卡添加成功",
"setDefaultSuccess": "已設置為默認銀行卡",
"deleteSuccess": "銀行卡刪除成功",
"deleteConfirm": "刪除銀行卡",
"deleteMessage": "確定要刪除 {bankName} ({accountName}) 嗎?此操作無法撤銷。"
},
"tips": {
"encryption": "銀行卡信息經過加密保護",
"support": "支持主流銀行快速充值提現"
}
},
"trade": {
"title": "交易",
"settings": {
"bankManagement": "銀行卡管理",
"mySubscribe": "我的申購"
}
},
"asset": {
"issue": {
"issuingAsset": "發行資產",
"myCompany": "我的企業",
"issuingApply": "發行申請",
"audit": "審核審計",
"supervision": "委託監管",
"apply": {
"title": "發行申請",
"base": "基礎信息",
"issuePeriod": "發行期",
"productName": "產品名稱",
"enterProductName": "請輸入產品名稱",
"productCode": "產品編碼",
"enterProductCode": "請輸入產品編碼",
"productType": "產品類型",
"chooseProductType": "請選擇產品類型",
"productValue": "產品估值",
"enterProductValue": "請輸入產品估值(美元)",
"assetProof": "資產證明",
"enterAssetProof": "請輸入資產證明",
"totalSupplyLimit": "總發行量上限",
"enterTotalSupplyLimit": "請輸入總發行量上限",
"editionName": "發行期名稱",
"enterEditionName": "請輸入發行期名稱",
"launchDate": "發行日期",
"enterLaunchDate": "請輸入發行日期",
"perUserLimit": "個人申購上限",
"enterPerUserLimit": "請輸入個人申購上限",
"totalSupply": "發行總量",
"enterTotalSupply": "請輸入發行總量",
"subscriptionDeadline": "申購截止日期",
"enterSubscriptionDeadline": "請輸入申購截止日期",
"unitPrice": "單價",
"enterUnitPrice": "請輸入單價",
"dividendRate": "分紅率",
"enterDividendRate": "分紅率(如0.01代表1%)",
"issuePeriodIndex": "發行期 {index}",
"realEstate": "房地產",
"snickers": "糖果",
"next": "下一步",
"back": "返回",
"submit": "提交",
"addStep": "添加發行期",
"removeItem": "移除項目",
"validation": {
"nameRequired": "產品名稱是必填項",
"codeRequired": "產品編碼是必填項",
"categoryRequired": "產品類型是必填項",
"editionNameRequired": "發行期名稱是必填項",
"launchDateRequired": "發行日期是必填項",
"launchDateNotPast": "發行日期不能小於當前日期",
"perUserLimitRequired": "個人申購上限是必填項",
"totalSupplyRequired": "發行總量是必填項",
"subscriptionDeadlineRequired": "申購截止日期是必填項",
"deadlineAfterLaunch": "申購截止日期不能小於發行日期",
"unitPriceRequired": "單價是必填項",
"dividendRateRequired": "分紅率是必填項"
},
"done": {
"title": "申請提交成功",
"description": "您的發行申請已成功提交,我們將在工作日內對您的申請進行審核。請耐心等待審核結果。",
"viewProducts": "查看我的產品"
}
}
},
"purchase": {
"purchaseAsset": "購買資產",
"fiatPurchase": "法幣購買",
"cryptoPurchase": "數字貨幣購買",
"realEstate": "房地產",
"assetExchange": "資產交換"
},
"balance": {
"assetBalance": "資產餘額",
"fiat": "法幣",
"onChain": "鏈上",
"wallet": "錢包",
"recharge": "充值"
},
"revenue": {
"myRevenue": "我的收益",
"totalRevenue": "總收益",
"monthlyRevenue": "月度收益",
"pendingRevenue": "待確認收益",
"revenueDetails": "收益明細"
}
},
"market": {
"title": "市場",
"search": {
"placeholder": "搜索"
},
"category": {
"all": "全部"
},
"rwaList": {
"nameCode": "名稱/代碼",
"stage": "階段",
"issueDate": "發行日期",
"subscriptionPrice": "申購單價"
},
"tradeRwa": {
"tabs": {
"overview": "概覽",
"moment": "動態"
},
"fields": {
"productCode": "產品編號",
"valuation": "估值",
"unitPrice": "單價",
"totalSupply": "總發行量",
"perUserLimit": "每人限量",
"launchDate": "發行時間",
"subscriptionDeadline": "認購截止時間"
},
"units": {
"shares": "份"
},
"about": "About",
"noDescription": "暫無描述。",
"subscribe": "申購",
"subscribeSuccess": "申購成功"
},
"subscribeRwa": {
"title": "申購RWA",
"maxSubscribePlaceholder": "最大可申購數量: {max}",
"unitPrice": "單價",
"availableBalance": "可用餘額",
"confirmSubscribe": "確認申購",
"enterQuantityError": "請輸入申購數量"
},
"loading": {
"loadingMore": "加載更多..."
}
},
"tabs": {
"riwa": "Riwa",
"market": "市場",
"trade": "交易",
"chat": "聊天",
"user": "我的"
},
"auth": {
"common": {
"close": "關閉",
"next": "下一步",
"submit": "提交",
"email": "郵箱",
"enterEmail": "請輸入您的郵箱",
"validEmailError": "請輸入有效的郵箱地址。",
"orContinueWith": "或使用以下方式繼續",
"google": "Google",
"phoneNumber": "手機號碼",
"validVerificationCodeError": "請輸入有效的6位驗證碼。",
"failedSendCode": "發送驗證碼失敗。",
"failedVerifyCode": "驗證碼驗證失敗。"
},
"login": {
"title": "登錄",
"loginButton": "登錄"
},
"signup": {
"title": "您的郵箱是什麼?",
"description": "您將使用此郵箱登錄並訪問我們提供的所有內容。",
"signupButton": "註冊",
"emailPlaceholder": "email@example.com",
"emailVerified": "郵箱驗證成功!"
},
"verification": {
"title": "驗證您的郵箱",
"description": "我們已向 {email} 發送了一個驗證碼。請在下方輸入代碼以驗證您的郵箱地址。"
}
},
"settings": {
"title": "設置",
"language": "語言",
"aboutUs": "關於我們",
"clearCache": "清除緩存",
"checkUpdate": "檢查更新",
"cacheCleared": "緩存已清除",
"updateAvailable": "發現新版本",
"currentVersion": "當前版本",
"latestVersion": "最新版本",
"newVersion": "新版本",
"cancel": "取消",
"updateNow": "立即更新",
"alreadyLatest": "已是最新版本",
"checkUpdateFailed": "檢查更新失敗",
"languageTitle": "語言 / Language",
"theme": "主題",
"themeTitle": "外觀主題",
"themeLight": "淺色",
"themeDark": "深色",
"themeAuto": "跟隨系統"
}
}

View File

@@ -3,7 +3,7 @@
--min-height: 50px;
}
.ui-select::part(label){
.ui-select::part(label) {
font-size: 14px;
font-weight: 500;
}

View File

@@ -37,9 +37,9 @@ html:root {
--ion-color-warning-tint: #ffca22;
--ion-color-danger: #ff3344;
--ion-color-danger-rgb: 255,51,68;
--ion-color-danger-rgb: 255, 51, 68;
--ion-color-danger-contrast: #000000;
--ion-color-danger-contrast-rgb: 0,0,0;
--ion-color-danger-contrast-rgb: 0, 0, 0;
--ion-color-danger-shade: #e02d3c;
--ion-color-danger-tint: #ff4757;
@@ -157,9 +157,9 @@ html.ion-palette-dark {
--ion-color-warning-tint: #ffca22;
--ion-color-danger: #ff3344;
--ion-color-danger-rgb: 255,51,68;
--ion-color-danger-rgb: 255, 51, 68;
--ion-color-danger-contrast: #000000;
--ion-color-danger-contrast-rgb: 0,0,0;
--ion-color-danger-contrast-rgb: 0, 0, 0;
--ion-color-danger-shade: #e02d3c;
--ion-color-danger-tint: #ff4757;

View File

@@ -9,32 +9,34 @@ export function createWithdrawSchema(t: (key: string, params?: any) => string, m
amount: yup
.string()
.required(t("withdraw.validation.amountRequired"))
.test("is-number", t("withdraw.validation.amountInvalid"), value => {
.test("is-number", t("withdraw.validation.amountInvalid"), (value) => {
return /^\d+(\.\d+)?$/.test(value || "");
})
.test("max-amount", t("withdraw.validation.amountExceedsBalance"), value => {
if (!value || maxAmount === "0") return false;
return parseFloat(value) <= parseFloat(maxAmount);
.test("max-amount", t("withdraw.validation.amountExceedsBalance"), (value) => {
if (!value || maxAmount === "0")
return false;
return Number.parseFloat(value) <= Number.parseFloat(maxAmount);
})
.test("min-amount", t("withdraw.validation.amountTooSmall"), value => {
if (!value) return false;
return parseFloat(value) > 0;
.test("min-amount", t("withdraw.validation.amountTooSmall"), (value) => {
if (!value)
return false;
return Number.parseFloat(value) > 0;
}),
withdrawMethod: yup.string().required(t("withdraw.validation.methodRequired")),
bankAccountId: yup.string().when("withdrawMethod", {
is: WithdrawMethodEnum.BANK,
then: (schema) => schema.required(t("withdraw.validation.bankAccountRequired")),
otherwise: (schema) => schema.optional(),
then: schema => schema.required(t("withdraw.validation.bankAccountRequired")),
otherwise: schema => schema.optional(),
}),
chain: yup.string().when("withdrawMethod", {
is: WithdrawMethodEnum.CRYPTO,
then: (schema) => schema.required(t("withdraw.validation.chainRequired")),
otherwise: (schema) => schema.optional(),
then: schema => schema.required(t("withdraw.validation.chainRequired")),
otherwise: schema => schema.optional(),
}),
toAddress: yup.string().when("withdrawMethod", {
is: WithdrawMethodEnum.CRYPTO,
then: (schema) => schema.required(t("withdraw.validation.addressRequired")).min(10, t("withdraw.validation.addressTooShort")),
otherwise: (schema) => schema.optional(),
then: schema => schema.required(t("withdraw.validation.addressRequired")).min(10, t("withdraw.validation.addressTooShort")),
otherwise: schema => schema.optional(),
}),
}),
);