zhb 5 месяцев назад
Родитель
Сommit
7b1c847871
55 измененных файлов с 2119 добавлено и 315 удалено
  1. 3 1
      App.vue
  2. 30 1
      api/ucard.ts
  3. 8 3
      components/cwg-input.vue
  4. 9 2
      components/cwg-page-wrapper.vue
  5. 51 0
      components/cwg-progress.vue
  6. 1 1
      config/index.ts
  7. 257 0
      hooks/useAppUpdate.ts
  8. 42 0
      hooks/useProgress.ts
  9. 18 5
      js_sdk/wa-permission/permission.js
  10. 32 12
      locale/ar.json
  11. 88 17
      locale/cn.json
  12. 32 12
      locale/de.json
  13. 32 13
      locale/en.json
  14. 33 13
      locale/es.json
  15. 32 12
      locale/fa.json
  16. 34 14
      locale/id.json
  17. 32 12
      locale/ko.json
  18. 34 14
      locale/ms.json
  19. 34 14
      locale/pt.json
  20. 32 12
      locale/th.json
  21. 34 14
      locale/tr.json
  22. 34 14
      locale/vn.json
  23. 30 10
      locale/zhHant.json
  24. 4 1
      manifest.json
  25. 35 0
      pages.json
  26. 1 1
      pages/card/operations.vue
  27. 18 0
      pages/mine/about.vue
  28. 265 0
      pages/mine/cog.vue
  29. 30 0
      pages/mine/help-detail.vue
  30. 155 0
      pages/mine/help.vue
  31. 16 66
      pages/mine/index.vue
  32. 1 0
      pages/mine/info.vue
  33. 332 0
      pages/mine/permission.vue
  34. 50 0
      pages/mine/privacy.vue
  35. 2 2
      pages/recharge-record/list.vue
  36. 23 8
      pages/wallet/components/DynamicForm.vue
  37. 65 7
      pages/wallet/composable/useOrderFields.ts
  38. 5 3
      pages/wallet/global-detail.vue
  39. 22 25
      pages/wallet/global-order.vue
  40. 16 3
      pages/wallet/index.vue
  41. 5 0
      static/icons/cjwt.svg
  42. 1 0
      static/icons/cog-outline.svg
  43. 8 0
      static/icons/dqbb.svg
  44. 3 0
      static/icons/gy.svg
  45. 7 0
      static/icons/kksq.svg
  46. 6 0
      static/icons/qbye.svg
  47. 5 0
      static/icons/qchc.svg
  48. 4 0
      static/icons/sz.svg
  49. 5 0
      static/icons/xgmm.svg
  50. 11 0
      static/icons/xxtz.svg
  51. 6 0
      static/icons/ys.svg
  52. 8 0
      static/icons/yszc.svg
  53. 10 2
      static/svg-icons-lib.js
  54. 27 0
      stores/use-card-store.ts
  55. 41 1
      stores/use-user-store.ts

+ 3 - 1
App.vue

@@ -11,6 +11,8 @@ import {
 	updateRoute
 } from "@/hooks/useRoute";
 import useGlobalStore from "@/stores/use-global-store";
+import { useAppUpdate } from '@/hooks/useAppUpdate'
+const { checkUpdate } = useAppUpdate()
 
 const globalStore = useGlobalStore()
 onLoad((options) => {
@@ -21,8 +23,8 @@ onShow((options) => {
 })
 onLaunch((options) => {
 	updateRoute();
+	checkUpdate()
 })
-
 onMounted(() => {
 	const sysInfo = uni.getSystemInfoSync();
 	globalStore.setBarHeight(sysInfo.statusBarHeight);

+ 30 - 1
api/ucard.ts

@@ -590,6 +590,35 @@ export const ucardApi = {
     params: object = {}
   ): Promise<BaseResponse<any>> {
     return post("/wasabi/api/card/withdraw/page", params);
+  },
+  // 字段参数列表
+  getGlobalFieldParams(
+    params: object = {}
+  ): Promise<BaseResponse<any>> {
+    return post("/wasabi/api/global/field/params", params);
+  },
+  // app版本详情
+  getAppVersionDetail(
+    params: object = {}
+  ): Promise<BaseResponse<any>> {
+    return post("/wasabi/api/card/app/version/detail", params);
+  },
+  // app隐私政策
+  getAppPrivacyPolicyPage(
+    params: object = {}
+  ): Promise<BaseResponse<any>> {
+    return post("/wasabi/api/card/app/privacy/policy/page", params);
+  },
+  // app常见问题分页列表
+  getAppCommonProblemPage(
+    params: object = {}
+  ): Promise<BaseResponse<any>> {
+    return post("/wasabi/api/card/app/common/problem/page", params);
+  },
+  // app常见问题类型
+  getAppCommonProblemDropdown(
+    params: object = {}
+  ): Promise<BaseResponse<any>> {
+    return post("/wasabi/api/card/app/common/problem/type/dropdown", params);
   }
-
 };

+ 8 - 3
components/cwg-input.vue

@@ -114,6 +114,7 @@ const props = defineProps({
   showSearch: Boolean,
   isUploadD: { type: Boolean, default: false },
   value: { type: [String, Number] },
+  selectedValueDoc: { type: [String, Number] },
   placeholder: String,
   direction: { type: String, default: "down" },
   disabled: Boolean,
@@ -133,6 +134,8 @@ const props = defineProps({
     default: (val) => dayjs(val).format("YYYY-MM-DD"),
   },
 });
+console.log(props,'props');
+
 const emit = defineEmits([
   "update:value",
   "blur",
@@ -140,12 +143,13 @@ const emit = defineEmits([
   "clear",
   "confirm",
   "change",
+  "change1",
 ]);
 
 const isUploading = ref(false);
 const uploader = ref([]);
 const inputValueDoc = ref("");
-const selectedValue = ref([]);
+const selectedValueDoc = ref([]);
 const showPicker = ref(false);
 const onConfirm = (value) => {
   let selectedText = value.text || ''
@@ -154,6 +158,7 @@ const onConfirm = (value) => {
   }
   inputValueDoc.value = selectedText
   showPicker.value = false
+  emit("update:selectedValueDoc", selectedText);
 }
 // 处理输入框点击事件
 function handleInputClick() {
@@ -326,7 +331,7 @@ watch(
     } else if (props.type === "select") {
       const matched = props.columns.find((opt) => opt.value === newVal);
       inputValueDoc.value = matched?.text || "";
-      selectedValue.value = matched ? [matched.value] : [];
+      selectedValueDoc.value = matched ? [matched.value] : [];
     } else if (props.type === "upload") {
       uploader.value = props.value
         ? [{ url: absoluteUrl(String(props.value)) }]
@@ -336,7 +341,7 @@ watch(
     } else if (props.type === "dropdown") {
       const matched = props.columns.find((opt) => opt.value === newVal);
       inputValueDoc.value = matched?.text || "";
-      selectedValue.value = matched ? [matched.value] : [];
+      selectedValueDoc.value = matched ? [matched.value] : [];
     } else {
       inputValueDoc.value = newVal || "";
     }

+ 9 - 2
components/cwg-page-wrapper.vue

@@ -1,6 +1,7 @@
 <template>
   <view class="page-wrapper">
-    <cwg-header />
+    <cwg-progress />
+    <cwg-header v-if="!isHeaderFixed" />
     <view :style="{ height: `calc(${statusBarHeight}px + 60px)` }" />
     <slot></slot>
     <view :style="{ height: isTabBarPage ? '60px' : '0px' }" />
@@ -9,10 +10,16 @@
 </template>
 
 <script setup>
-import { ref, onMounted,computed } from "vue";
+import { ref, onMounted, computed, } from "vue";
 import { onLoad, onShow } from '@dcloudio/uni-app'
 import { updateRoute } from '@/hooks/useRoute'
 import useGlobalStore from '@/stores/use-global-store'
+const props = defineProps({
+  isHeaderFixed: {
+    type: Boolean,
+    default: false
+  }
+})
 const globalStore = useGlobalStore()
 const statusBarHeight = computed(() => globalStore.statusBarHeight);
 const isTabBarPage = ref(false)

+ 51 - 0
components/cwg-progress.vue

@@ -0,0 +1,51 @@
+<template>
+  <u-overlay :show="visible">
+    <view class="overlay-center">
+      <view class="progress-box">
+        <u-loading-icon :text="text" textSize="18" />
+        <u-line-progress :percentage="progress" activeColor="#ea002a" inactiveColor="#ececec" :showText="false"
+          height="4" />
+      </view>
+    </view>
+  </u-overlay>
+</template>
+
+
+<script setup lang="ts">
+import { useProgress } from '@/hooks/useProgress'
+
+// 使用全局进度管理
+const { visible, progress, text } = useProgress()
+</script>
+
+<style lang="scss" scoped>
+.overlay-center {
+  position: fixed;
+  left: 0;
+  top: 0;
+  width: 100vw;
+  height: 100vh;
+
+  display: flex;
+  align-items: center; // 垂直居中
+  justify-content: center; // 水平居中
+}
+
+.progress-box {
+  width: 70%;
+  max-width: 600rpx;
+
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  gap: 20px;
+
+  padding: 40px;
+  background: #fff;
+  border-radius: 12px;
+}
+
+:deep(.u-line-progress) {
+  width: 100%;
+}
+</style>

+ 1 - 1
config/index.ts

@@ -1,7 +1,7 @@
 const config = {
   // Host00: 'https://secure.cwgrd.com',
   // Host85: 'https://ucard.cwgrd.com',
-  // Host85: 'http://192.168.0.18:8700',
+  // Host85: 'http://192.168.0.25:8700',
   Host00: "https://ucard.44a5c8109e4.com",
   Host85: "https://ucard.44a5c8109e4.com",
   

+ 257 - 0
hooks/useAppUpdate.ts

@@ -0,0 +1,257 @@
+import { ref, onUnmounted } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { useProgress } from './useProgress'
+import useUserStore from '@/stores/use-user-store'
+import { ucardApi } from '@/api/ucard'
+
+const LAST_CHECK_KEY = 'last_update_check_time'
+const SKIP_VERSION_KEY = 'skip_update_version'
+const DOWNLOAD_CACHE_KEY = 'app_download_cache'
+
+export function useAppUpdate() {
+    const { t } = useI18n()
+    const userStore = useUserStore()
+    const progress = useProgress()
+
+    const checking = ref(false)
+    const updating = ref(false)
+
+    let downloadTask: any = null
+    let networkListener: any = null
+    let downloadUrl = ''
+    let savedFilePath = '_downloads/app_update.wgt'
+    let currentNetworkType = ''
+
+    /* ================== 对外入口 ================== */
+
+    async function checkUpdate() {
+        // #ifdef APP-PLUS
+        if (checking.value) return
+        checking.value = true
+
+        try {
+            const platform = uni.getSystemInfoSync().platform
+            const equipmentType = platform === 'ios' ? 'ios' : 'Android'
+            const res = await ucardApi.getAppVersionDetail({ equipmentType })
+            if (res.code !== 200 || !res.data) return
+
+            const update = res.data
+            const currentVersion = await getCurrentVersion()
+            const needUpdate = compareVersion(update.version, currentVersion) > 0
+
+            userStore.saveAppVersion({
+                currentVersion,
+                version: update.version,
+                isUpdate: !needUpdate
+            })
+
+            if (!needUpdate) return
+
+            const skip = uni.getStorageSync(SKIP_VERSION_KEY)
+            if (!update.forceUpdate && skip === update.version) return
+
+            if (update.forceUpdate) {
+                showForceUpdate(update)
+            } else {
+                showOptionalUpdate(update)
+            }
+        } finally {
+            checking.value = false
+        }
+        // #endif
+    }
+
+    /* ================== 更新流程 ================== */
+
+    function showForceUpdate(update: any) {
+        uni.showModal({
+            title: t('mine.p22'),
+            content: t('mine.p23'),
+            showCancel: false,
+            confirmText: t('mine.p35'),
+            success: () => doUpdate(update)
+        })
+    }
+
+    function showOptionalUpdate(update: any) {
+        uni.showModal({
+            title: t('mine.p24'),
+            content: t('mine.p25', { version: 'v' + update.version }),
+            confirmText: t('mine.p35'),
+            cancelText: t('mine.p36'),
+            success: res => {
+                if (res.confirm) doUpdate(update)
+                else uni.setStorageSync(SKIP_VERSION_KEY, update.version)
+            }
+        })
+    }
+
+    function doUpdate(update: any) {
+        const platform = uni.getSystemInfoSync().platform
+        if (platform === 'ios') {
+            plus.runtime.openURL(update.iosStoreUrl)
+            return
+        }
+        downloadWgt(update.wgtUrl)
+    }
+
+
+    /* ================== 下载核心 ================== */
+
+    function downloadWgt(url: string) {
+        // #ifdef APP-PLUS
+        if (downloadTask) return
+        downloadUrl = url
+        updating.value = true
+        progress.show(t('mine.p29'))
+        // 获取当前网络类型
+        uni.getNetworkType({
+            success: (res) => {
+                currentNetworkType = res.networkType
+            }
+        })
+        startNetworkMonitor()
+        downloadTask = plus.downloader.createDownload(
+            url,
+            { filename: savedFilePath },
+            (download, status) => {
+                if (status === 200 || status === 206) {
+                    clearCache()
+                    stopNetworkMonitor()
+                    installWgt(download.filename)
+                } else {
+                    fail(t('mine.p28'))
+                }
+            }
+        )
+        downloadTask.addEventListener('statechanged', (d: any) => {
+            const state = d.state
+            if (state === 3 && d.totalSize) { // 下载中
+                const p = Math.floor((d.downloadedSize / d.totalSize) * 100)
+                progress.update(p, `${t('mine.p29')} ${p}%`)
+                saveCache(p)
+            }
+        })
+        downloadTask.start()
+        // #endif
+    }
+    /* ================== 网络处理 ================== */
+
+    function startNetworkMonitor() {
+        // #ifdef APP-PLUS
+        networkListener = uni.onNetworkStatusChange(res => {
+            if (!downloadTask || !updating.value) return
+            // 只要有网络变化,直接尝试恢复下载
+            if (!res.isConnected) {
+                currentNetworkType = 'none'
+                try {
+                    downloadTask.pause && downloadTask.pause()
+                } catch (e) {
+                    console.error('暂停下载失败:', e)
+                }
+                return
+            }
+
+            // 网络恢复或切换,直接 resume,不依赖 state
+            currentNetworkType = res.networkType
+            try {
+                if (downloadTask.resume) {
+                    downloadTask.resume()
+                } else {
+                    downloadTask.start()
+                }
+            } catch (e) {
+                // 失败时尝试用 start 重试
+                try {
+                    downloadTask.start()
+                } catch (e2) {
+                    console.error('start() 也失败:', e2)
+                }
+            }
+        })
+        // #endif
+    }
+    function stopNetworkMonitor() {
+        if (networkListener) {
+            uni.offNetworkStatusChange(networkListener)
+            networkListener = null
+        }
+        currentNetworkType = ''
+    }
+
+    /* ================== 安装 ================== */
+
+    function installWgt(path: string) {
+        plus.runtime.install(
+            path,
+            { force: false },
+            () => {
+                progress.hide()
+                updating.value = false
+                uni.showModal({
+                    title: t('mine.p37'),
+                    content: t('mine.p38'),
+                    showCancel: false,
+                    success: () => plus.runtime.restart()
+                })
+            },
+            () => fail(t('mine.p33'))
+        )
+    }
+
+    /* ================== 缓存(仅 UI) ================== */
+
+    function saveCache(progress: number) {
+        uni.setStorageSync(DOWNLOAD_CACHE_KEY, {
+            url: downloadUrl,
+            progress,
+            time: Date.now()
+        })
+    }
+
+    function clearCache() {
+        uni.removeStorageSync(DOWNLOAD_CACHE_KEY)
+    }
+
+    /* ================== 兜底失败 ================== */
+
+    function fail(msg: string) {
+        progress.hide()
+        updating.value = false
+        stopNetworkMonitor()
+        if (downloadTask) {
+            try { downloadTask.abort() } catch { }
+            downloadTask = null
+        }
+        uni.showToast({ title: msg, icon: 'none' })
+    }
+
+    onUnmounted(() => {
+        stopNetworkMonitor()
+    })
+
+    return { checkUpdate }
+}
+
+/* ================== 工具 ================== */
+
+function getCurrentVersion(): Promise<string> {
+    return new Promise(resolve => {
+        plus.runtime.getProperty(plus.runtime.appid, info => {
+            resolve(info.version)
+        })
+    })
+}
+
+function compareVersion(v1: string, v2: string) {
+    const a1 = v1.split('.')
+    const a2 = v2.split('.')
+    const len = Math.max(a1.length, a2.length)
+    for (let i = 0; i < len; i++) {
+        const n1 = parseInt(a1[i] || '0')
+        const n2 = parseInt(a2[i] || '0')
+        if (n1 > n2) return 1
+        if (n1 < n2) return -1
+    }
+    return 0
+}

+ 42 - 0
hooks/useProgress.ts

@@ -0,0 +1,42 @@
+import { ref } from 'vue'
+
+/** 全局进度管理 */
+const visible = ref(false)
+const progress = ref(0)
+const text = ref('')
+
+export function useProgress() {
+    /**
+     * 显示进度
+     */
+    function show(t = '加载中') {
+        text.value = t
+        progress.value = 0
+        visible.value = true
+    }
+
+    /**
+     * 更新进度
+     */
+    function update(p: number, t?: string) {
+        progress.value = Math.min(100, Math.max(0, p))
+        if (t) text.value = t
+    }
+
+    /**
+     * 隐藏进度
+     */
+    function hide() {
+        visible.value = false
+        progress.value = 0
+    }
+
+    return {
+        visible,
+        progress,
+        text,
+        show,
+        update,
+        hide
+    }
+}

+ 18 - 5
js_sdk/wa-permission/permission.js

@@ -82,7 +82,7 @@ function judgeIosPermissionRecord() {
 function judgeIosPermissionCamera() {
 	var result = false;
 	var AVCaptureDevice = plus.ios.import("AVCaptureDevice");
-	var authStatus = AVCaptureDevice.authorizationStatusForMediaType('vide');
+	var authStatus = AVCaptureDevice.authorizationStatusForMediaType('video');
 	console.log("authStatus:" + authStatus);
 	if (authStatus == 3) {
 		result = true;
@@ -157,10 +157,12 @@ function judgeIosPermissionMemo() {
 
 // Android权限查询
 function requestAndroidPermission(permissionID) {
+
 	return new Promise((resolve, reject) => {
 		plus.android.requestPermissions(
 			[permissionID], // 理论上支持多个权限同时查询,但实际上本函数封装只处理了一个权限的情况。有需要的可自行扩展封装
-			function(resultObj) {
+			function (resultObj) {
+
 				var result = 0;
 				for (var i = 0; i < resultObj.granted.length; i++) {
 					var grantedPermission = resultObj.granted[i];
@@ -183,7 +185,7 @@ function requestAndroidPermission(permissionID) {
 				// gotoAppPermissionSetting()
 				// }
 			},
-			function(error) {
+			function (error) {
 				console.log('申请权限错误:' + error.code + " = " + error.message);
 				resolve({
 					code: error.code,
@@ -242,6 +244,16 @@ function gotoAppPermissionSetting() {
 		mainActivity.startActivity(intent);
 	}
 }
+function checkAndroidPermission(permissionID) {
+	return new Promise((resolve) => {
+		const context = plus.android.runtimeMainActivity()
+		plus.android.importClass(context)
+
+		let result = context.checkCallingOrSelfPermission(permissionID)
+		
+		resolve(result == 0 ? 1 : 0)
+	})
+}
 
 // 检查系统的设备服务是否开启
 // var checkSystemEnableLocation = async function () {
@@ -268,5 +280,6 @@ export const permission = {
 	judgeIosPermission: judgeIosPermission,
 	requestAndroidPermission: requestAndroidPermission,
 	checkSystemEnableLocation: checkSystemEnableLocation,
-	gotoAppPermissionSetting: gotoAppPermissionSetting
-}
+	gotoAppPermissionSetting: gotoAppPermissionSetting,
+	checkAndroidPermission: checkAndroidPermission
+}

+ 32 - 12
locale/ar.json

@@ -178,7 +178,7 @@
     "i2": "تغيير كلمة المرور",
     "i3": "المعلومات الشخصية",
     "i4": "سجلات طلب البطاقات",
-    "i5": "حول PayouCard",
+    "i5": "حول C Pay",
     "i6": "تسجيل الخروج"
   },
   "activeState": {
@@ -3018,14 +3018,16 @@
       "t15": "تم رفض المراجعة",
       "t16": "سحب",
       "t17": "سحب نقدي",
-      "t18": "إعادة شحن",
-      "t19": "استرداد",
+      "t18": "إعادة شحن البطاقة",
+      "t19": "استرداد البطاقة",
       "t20": "إيداع يدوي",
       "t21": "سحب يدوي",
       "t22": "الكل",
-      "t23": "خصم طلب الحوالة السريعة",
-      "t24": "استرداد طلب الحوالة السريعة",
-      "t25": "إيداع العملات المشفرة",
+      "t23": "خصم طلب التحويل السريع",
+      "t24": "استرداد طلب التحويل السريع",
+      "t25": "إيداع المحفظة",
+      "t26": "سحب المحفظة",
+      "t27": "استرداد سحب المحفظة",
       "v1": "معلومات التسجيل",
       "v2": "تعديل المعلومات",
       "v3": "الحصول على رابط التحقق من الوجه",
@@ -3378,14 +3380,14 @@
   },
   "global": {
     "title": "سجل التحويل",
-    "title1": "تحويل CWG",
+    "title1": "التحويل العالمي",
     "title2": "طلب جديد",
     "title3": "تفاصيل الطلب",
-    "Tips": "نصائح التحويل:",
-    "Tips1": "1. يرجى التحقق من الرصيد المتاح في حسابك الحالي قبل تقديم طلب التحويل لتجنب التأثير على عملياتك التجارية.",
-    "Tips2": "2. يرجى إدخال مبلغ التحويل بعد اختيار عملة التحويل/نوع التحويل/طريقة الدفع، وتعبئة/تأكيد المعلومات التالية.",
-    "Tips3": "3. رسوم الخدمة هي مبلغ تقديري، يمكن عرض الرسوم الفعلية بعد إتمام التحويل.",
-    "Tips4": "4. سنقوم بمعالجة طلبك بمجرد استلامه. عادةً ما تستغرق المعالجة ما يصل إلى 24 ساعة. لتجنب التأثير على عملياتك التجارية، يرجى الانتباه إلى وقت تقديم الطلب.",
+    "Tips": "تذكير ودّي من Global Remittance:",
+    "Tips1": "1. يرجى التأكد من أن لديك رصيد متاح كافٍ في حسابك قبل تقديم طلب التحويل لتجنب أي تأثير على عملياتك التجارية.",
+    "Tips2": "2. بعد اختيار العملة/نوع التحويل/طريقة الدفع، يرجى التأكد من إدخال المبلغ الصحيح للتحويل وإكمال جميع الحقول المطلوبة.",
+    "Tips3": "3. المبلغ المستلم هو مبلغ تقديري؛ قد يختلف المبلغ الفعلي قليلاً بسبب تقلبات سعر الصرف.",
+    "Tips4": "4. بعد تقديم الطلب، سيتم معالجة تحويلك وإتمام الدفع في غضون يوم عمل واحد. سيعتمد الوقت الفعلي للوصول على سرعة معالجة البنك المستقبل. لتجنب التأثير على عملياتك التجارية، يرجى التأكد من تقديم طلب التحويل في الوقت المناسب.",
     "t1": "الدافع",
     "t2": "حساب الدافع",
     "t3": "عملة التحويل/نوع التحويل/طريقة الدفع",
@@ -5589,5 +5591,23 @@
     "unit": "الرجاء إدخال وحدة المعاملة",
     "p1": "وحدة المعاملة",
     "p2": "المبلغ"
+  },
+  "WalletApply": {
+    "title": "سجل سحب المحفظة",
+    "title1": "سحب",
+    "title2": "طلب السحب",
+    "p1": "عنوان محفظة مشفرة",
+    "p2": "يرجى إدخال عنوان المحفظة المشفرة",
+    "p3": "مبلغ السحب",
+    "p4": "يرجى إدخال مبلغ السحب (USDT)",
+    "p5": "(الرصيد المتاح {userBalance} USDT)",
+    "p6": "لا يمكن أن يتجاوز المبلغ المدخل {userBalance} USDT",
+    "p7": "يرجى إدخال رقم صالح"
+  },
+  "Blockchain1": {
+    "title": "سجل شحن المحفظة",
+    "p2": "انسخ عنوان المحفظة أو امسح الرمز لنسخه",
+    "p3": "إنشاء عنوان محفظة",
+    "p4": "نسخ عنوان المحفظة"
   }
 }

+ 88 - 17
locale/cn.json

@@ -57,7 +57,17 @@
       "pay-password": "修改密码",
       "info": "个人信息",
       "improve": "完善信息",
-      "kyc": "KYC认证"
+      "kyc": "KYC认证",
+      "cog": "设置",
+      "help": "常见问题",
+      "help-detail": "常见问题",
+      "permission": "权限管理",
+      "privacy": "隐私政策",
+      "clearCache": "清除缓存",
+      "currentVersion": "当前版本",
+      "newVersion": "已是最新版本",
+      "hasNewVersion": "有新版本可更新",
+      "about": "关于C Pay"
     },
     "wallet": {
       "global-detail": "订单详情",
@@ -125,7 +135,50 @@
     "p": "您确定要退出登录吗?",
     "b1": "退出登录",
     "b2": "取消",
-    "language": "语言设置"
+    "language": "语言设置",
+    "p1": "地理位置",
+    "p2": "获取您的位置信息",
+    "p3": "关于位置",
+    "p4": "相机",
+    "p5": "拍摄照片和视频",
+    "p6": "关于相机",
+    "p7": "相册",
+    "p8": "访问您的照片和视频",
+    "p9": "关于相册",
+    "p10": "粘贴板",
+    "p11": "读取剪贴板内容",
+    "p12": "已开启",
+    "p13": "去设置",
+    "p14": "提示:首次使用相关功能时需要授权。如您曾拒绝授权,可在系统设置中重新开启。",
+    "p15": "C Pays App隐私政策",
+    "p16": "相机的使用",
+    "p17": "相册的使用",
+    "p18": "位置信息的使用",
+    "p19": "缓存大小",
+    "p20": "清除缓存",
+    "p21": "清除成功",
+    "p22": "版本更新",
+    "p23": "当前版本过低,请立即更新后继续使用",
+    "p24": "发现新版本",
+    "p25": "发现新版本 {version},是否更新?",
+    "p26": "正在下载更新",
+    "p27": "下载完成",
+    "p28": "下载失败",
+    "p29": "下载中",
+    "p30": "下载完成,是否安装?",
+    "p31": "正在安装更新",
+    "p32": "安装完成",
+    "p33": "安装失败",
+    "p34": "安装中",
+    "p35": "更新",
+    "p36": "跳过",
+    "p37": "更新成功",
+    "p38": "应用将重启以完成更新",
+    "p39": "继续下载",
+    "p40": "下载中断",
+    "p41": "网络异常导致下载中断,是否继续下载?",
+    "p42": "继续",
+    "p43": "取消"
   },
   "login": {
     "title": "登录",
@@ -183,7 +236,6 @@
     "i2": "修改密码",
     "i3": "个人信息",
     "i4": "开卡记录",
-    "i5": "关于PayouCard",
     "i6": "退出登录"
   },
   "activeState": {
@@ -2977,15 +3029,16 @@
       "t15": "审核拒绝",
       "t16": "提款",
       "t17": "取款",
-      "t18": "充值",
-      "t19": "退款",
+      "t18": "充值",
+      "t19": "退款",
       "t20": "手动转入",
       "t21": "手动转出",
       "t22": "全部",
       "t23": "速汇订单扣款",
       "t24": "速汇订单退款",
-      "t25": "加密货币转入",
-      "t26": "扣款",
+      "t25": "钱包充值",
+      "t26": "钱包提现",
+      "t27": "钱包提现退款",
       "v1": "注册信息",
       "v2": "修改信息",
       "v3": "获取人脸认证链接",
@@ -3338,14 +3391,14 @@
   },
   "global": {
     "title": "速汇记录",
-    "title1": "CWG速汇",
+    "title1": "全球速汇",
     "title2": "新增订单",
     "title3": "订单详情",
-    "Tips": "转账温馨提示:",
-    "Tips1": "1. 请在提交转账申请前检查您当前账户的可用金额,避免影响你的交易操作。",
-    "Tips2": "2. 在选择转账币种/转账类型/支付方式后输入转账金额,并填写、确认以下信息。",
-    "Tips3": "3. 手续费为预估金额,实际手续费在转账完成后查看。",
-    "Tips4": "4. 我们在收到申请后,会在第一时间处理,处理时间一般在24小时内完成,为避免影响您的交易操作,请注意您提交申请的时间。",
+    "Tips": "全球速汇温馨提示:",
+    "Tips1": "1. 请在提交转账申请前,确认账户内有足够的可用余额,以免影响您的交易操作。",
+    "Tips2": "2. 在选择转账币种/转账类型/支付方式后,请确保填写正确的转账金额,并完成所有必填项。",
+    "Tips3": "3. 到账金额为预计金额,实际到账金额可能会因汇率波动产生细微差异。",
+    "Tips4": "4. 订单提交后,您的转账将在1个工作日内处理并完成打款。具体到账时间将依据收款银行的处理速度有所不同。为避免影响您的交易操作,请确保在合适的时间提交转账申请。",
     "t1": "付款人",
     "t2": "付款账户",
     "t3": "转账币种/转账类型/支付方式",
@@ -5512,13 +5565,13 @@
     "unEnable": "未启用",
     "deleteConfirm": "确认删除这些内容吗?",
     "deleteTitle": "提示",
-    "title": "加密货币交易记录",
+    "title": "钱包充值记录",
     "title1": "编辑区块链",
     "title2": "新增区块链",
     "p1": "加密货币交易",
-    "p2": "复制支付链接或者手机扫码复制链接",
-    "p3": "查询支付链接",
-    "p4": "复制支付链接"
+    "p2": "复制钱包地址或者手机扫码复制地址",
+    "p3": "生成钱包地址",
+    "p4": "复制钱包地址"
   },
   "BlockchainRate": {
     "pageT1": "货币",
@@ -5549,5 +5602,23 @@
     "unit": "请输入交易单位",
     "p1": "交易单位",
     "p2": "金额"
+  },
+  "WalletApply": {
+    "title": "钱包提现记录",
+    "title1": "提现",
+    "title2": "提现申请",
+    "p1": "加密钱包地址",
+    "p2": "请输入加密钱包地址",
+    "p3": "提现金额",
+    "p4": "请输入提现金额(USDT)",
+    "p5": "(可用余额{userBalance} USDT)",
+    "p6": "输入的金额不能超过 {userBalance} USDT",
+    "p7": "请输入有效数字"
+  },
+  "Blockchain1": {
+    "title": "钱包充值记录",
+    "p2": "复制钱包地址或者手机扫码复制地址",
+    "p3": "生成钱包地址",
+    "p4": "复制钱包地址"
   }
 }

+ 32 - 12
locale/de.json

@@ -178,7 +178,7 @@
     "i2": "Passwort ändern",
     "i3": "Persönliche Informationen",
     "i4": "Kartenantragsverläufe",
-    "i5": "Über PayouCard",
+    "i5": "Über C Pay",
     "i6": "Abmelden"
   },
   "activeState": {
@@ -3029,14 +3029,16 @@
       "t15": "Überprüfung abgelehnt",
       "t16": "Abhebung",
       "t17": "Bargeldabhebung",
-      "t18": "Aufladen",
-      "t19": "Rückerstattung",
+      "t18": "Kartenaufladung",
+      "t19": "Kartenrückerstattung",
       "t20": "Manuelle Einzahlung",
       "t21": "Manuelle Auszahlung",
       "t22": "Alle",
-      "t23": "Abbuchung für Schnellüberweisungsauftrag",
-      "t24": "Rückerstattung für Schnellüberweisungsauftrag",
-      "t25": "Krypto-Einzahlung",
+      "t23": "Abbuchung Schnellüberweisung",
+      "t24": "Rückerstattung Schnellüberweisung",
+      "t25": "Wallet-Aufladung",
+      "t26": "Wallet-Auszahlung",
+      "t27": "Rückerstattung Wallet-Auszahlung",
       "v1": "Registrierungsinformationen",
       "v2": "Informationen bearbeiten",
       "v3": "Gesichtsverifizierungslink abrufen",
@@ -3389,14 +3391,14 @@
   },
   "global": {
     "title": "Übertragungsprotokoll",
-    "title1": "CWG Überweisung",
+    "title1": "Globale Übertragung",
     "title2": "Neue Bestellung",
     "title3": "Bestelldetails",
-    "Tips": "Übertragungstipps:",
-    "Tips1": "1. Bitte überprüfen Sie das verfügbare Guthaben auf Ihrem aktuellen Konto, bevor Sie eine Überweisungsanfrage einreichen, um Beeinträchtigungen Ihrer Transaktionen zu vermeiden.",
-    "Tips2": "2. Bitte geben Sie den Überweisungsbetrag ein, nachdem Sie die Überweisungswährung/Überweisungstyp/Zahlungsmethode ausgewählt haben, und füllen Sie die folgenden Informationen aus/bestätigen Sie diese.",
-    "Tips3": "3. Die Servicegebühr ist ein geschätzter Betrag, die tatsächliche Servicegebühr kann nach Abschluss der Überweisung eingesehen werden.",
-    "Tips4": "4. Wir werden Ihre Anfrage umgehend bearbeiten, sobald wir sie erhalten. Die Bearbeitungszeit dauert in der Regel bis zu 24 Stunde. Achten Sie auf den Zeitpunkt Ihrer Anfrage, um Beeinträchtigungen Ihrer Transaktionen zu vermeiden.",
+    "Tips": "Freundliche Erinnerung von Global Remittance:",
+    "Tips1": "1. Stellen Sie bitte sicher, dass Ihr Konto über ausreichend verfügbares Guthaben verfügt, bevor Sie den Überweisungsantrag einreichen, um Beeinträchtigungen Ihrer Transaktionen zu vermeiden.",
+    "Tips2": "2. Nachdem Sie die Überweisungswährung/Überweisungstyp/Zahlungsmethode ausgewählt haben, stellen Sie bitte sicher, dass Sie den richtigen Überweisungsbetrag eingeben und alle erforderlichen Felder ausfüllen.",
+    "Tips3": "3. Der empfangene Betrag ist ein geschätzter Betrag; der tatsächliche Betrag kann aufgrund von Wechselkursschwankungen leicht abweichen.",
+    "Tips4": "4. Nachdem der Auftrag eingereicht wurde, wird Ihre Überweisung innerhalb eines Werktages bearbeitet und die Zahlung abgeschlossen. Die tatsächliche Ankunftszeit hängt von der Bearbeitungsgeschwindigkeit der empfangenden Bank ab. Um Ihre Transaktionen nicht zu beeinträchtigen, stellen Sie bitte sicher, dass Sie den Überweisungsantrag zu einem geeigneten Zeitpunkt einreichen.",
     "t1": "Zahler",
     "t2": "Zahlungskonto",
     "t3": "Überweisungswährung/Überweisungstyp/Zahlungsmethode",
@@ -5600,5 +5602,23 @@
     "unit": "Bitte Transaktionseinheit eingeben",
     "p1": "Transaktionseinheit",
     "p2": "Betrag"
+  },
+  "WalletApply": {
+    "title": "Auszahlungsverlauf der Wallet",
+    "title1": "Auszahlung",
+    "title2": "Auszahlungsantrag",
+    "p1": "Krypto-Wallet-Adresse",
+    "p2": "Bitte geben Sie die Krypto-Wallet-Adresse ein",
+    "p3": "Auszahlungsbetrag",
+    "p4": "Bitte geben Sie den Auszahlungsbetrag ein (USDT)",
+    "p5": "(Verfügbares Guthaben {userBalance} USDT)",
+    "p6": "Der eingegebene Betrag darf {userBalance} USDT nicht überschreiten",
+    "p7": "Bitte geben Sie eine gültige Zahl ein"
+  },
+  "Blockchain1": {
+    "title": "Wallet-Aufladeverlauf",
+    "p2": "Wallet-Adresse kopieren oder per QR-Code scannen",
+    "p3": "Wallet-Adresse generieren",
+    "p4": "Wallet-Adresse kopieren"
   }
 }

+ 32 - 13
locale/en.json

@@ -182,7 +182,7 @@
     "i2": "Change Password",
     "i3": "Personal Information",
     "i4": "Card Application Records",
-    "i5": "About PayouCard",
+    "i5": "About C Pay",
     "i6": "Logout"
   },
   "activeState": {
@@ -3382,15 +3382,16 @@
       "t15": "Review Rejected",
       "t16": "Withdrawal",
       "t17": "Cash Withdrawal",
-      "t18": "Top-up",
-      "t19": "Refund",
+      "t18": "Card Top-up",
+      "t19": "Card Refund",
       "t20": "Manual Deposit",
       "t21": "Manual Withdrawal",
       "t22": "All",
-      "t23": "Fast Remittance Order Deduction",
-      "t24": "Fast Remittance Order Refund",
-      "t25": "Crypto Deposit",
-      "t26": "Deduction",
+      "t23": "Fast Transfer Order Deduction",
+      "t24": "Fast Transfer Order Refund",
+      "t25": "Wallet Top-up",
+      "t26": "Wallet Withdrawal",
+      "t27": "Wallet Withdrawal Refund",
       "v1": "Registration Information",
       "v2": "Modify Information",
       "v3": "Get Face Verification Link",
@@ -3743,14 +3744,14 @@
   },
   "global": {
     "title": "Transfer Record",
-    "title1": "CWG Remittance",
+    "title1": "Global Transfer",
     "title2": "New Order",
     "title3": "Order Details",
-    "Tips": "Transfer Tips:",
-    "Tips1": "1. Please check the available balance in your current account before submitting a transfer request to avoid affecting your transaction operations.",
-    "Tips2": "2. Please enter the transfer amount after selecting the transfer currency/type/payment method, and fill in/confirm the following information.",
-    "Tips3": "3. The service fee is an estimated amount, the actual service fee can be viewed after the transfer is completed.",
-    "Tips4": "4. We will process your application as soon as we receive it. Processing usually takes within 24 hour. To avoid affecting your transaction operations, please pay attention to the time you submit the application.",
+    "Tips": "Global Remittance Friendly Reminder:",
+    "Tips1": "1. Please ensure that you have sufficient available balance in your account before submitting the transfer request to avoid any impact on your transaction operations.",
+    "Tips2": "2. After selecting the transfer currency/transfer type/payment method, please ensure to fill in the correct transfer amount and complete all required fields.",
+    "Tips3": "3. The received amount is an estimated amount; the actual amount may vary slightly due to exchange rate fluctuations.",
+    "Tips4": "4. After the order is submitted, your transfer will be processed and the payment will be completed within 1 business day. The actual arrival time will depend on the processing speed of the receiving bank. To avoid affecting your transaction, please ensure that you submit the transfer request at an appropriate time.",
     "t1": "Payer",
     "t2": "Payer Account",
     "t3": "Transfer Currency/Transfer Type/Payment Method",
@@ -5954,5 +5955,23 @@
     "unit": "Please enter transaction unit",
     "p1": "Transaction Unit",
     "p2": "Amount"
+  },
+  "WalletApply": {
+    "title": "Wallet Withdrawal Records",
+    "title1": "Withdraw",
+    "title2": "Withdrawal Request",
+    "p1": "Crypto Wallet Address",
+    "p2": "Please enter the crypto wallet address",
+    "p3": "Withdrawal Amount",
+    "p4": "Please enter the withdrawal amount (USDT)",
+    "p5": "(Available balance {userBalance} USDT)",
+    "p6": "The entered amount cannot exceed {userBalance} USDT",
+    "p7": "Please enter a valid number"
+  },
+  "Blockchain1": {
+    "title": "Wallet Top-up Records",
+    "p2": "Copy the wallet address or scan the QR code to copy",
+    "p3": "Generate Wallet Address",
+    "p4": "Copy Wallet Address"
   }
 }

+ 33 - 13
locale/es.json

@@ -178,7 +178,7 @@
     "i2": "Cambiar contraseña",
     "i3": "Información personal",
     "i4": "Registro de tarjetas",
-    "i5": "Acerca de PayouCard",
+    "i5": "Acerca de C Pay",
     "i6": "Cerrar sesión"
   },
   "activeState": {
@@ -3030,14 +3030,16 @@
       "t15": "Revisión Rechazada",
       "t16": "Retiro",
       "t17": "Retiro de efectivo",
-      "t18": "Recarga",
-      "t19": "Reembolso",
+      "t18": "Recarga de tarjeta",
+      "t19": "Reembolso de tarjeta",
       "t20": "Depósito manual",
       "t21": "Retiro manual",
-      "t22": "Todo",
-      "t23": "Deducción de orden de remesa",
-      "t24": "Reembolso de orden de remesa",
-      "t25": "Depósito de criptomonedas",
+      "t22": "Todos",
+      "t23": "Deducción de orden de transferencia rápida",
+      "t24": "Reembolso de orden de transferencia rápida",
+      "t25": "Recarga de billetera",
+      "t26": "Retiro de billetera",
+      "t27": "Reembolso de retiro de billetera",
       "v1": "Información de registro",
       "v2": "Modificar información",
       "v3": "Obtener enlace de verificación facial",
@@ -3390,14 +3392,14 @@
   },
   "global": {
     "title": "Registro de Transferencias",
-    "title1": "CWG Remesas",
+    "title1": "Transferencia Global",
     "title2": "Nuevo Pedido",
     "title3": "Detalles del Pedido",
-    "Tips": "Consejos para Transferencias:",
-    "Tips1": "1. Por favor, verifique el saldo disponible en su cuenta antes de enviar una solicitud de transferencia para evitar afectar sus operaciones comerciales.",
-    "Tips2": "2. Por favor, ingrese el monto de la transferencia después de seleccionar la moneda del transferido/tipo de transferencia/metodo de pago y complete/ confirme la siguiente información.",
-    "Tips3": "3. La tarifa de servicio es una cantidad estimada, la tarifa real se puede ver después de completar la transferencia.",
-    "Tips4": "4. Procesaremos su solicitud tan pronto como la recibamos. El tiempo de procesamiento generalmente se completa dentro de 24 hora. Para evitar afectar sus operaciones comerciales, por favor tenga en cuenta la hora en que envía su solicitud.",
+    "Tips": "Recordatorio amistoso de Global Remittance:",
+    "Tips1": "1. Asegúrese de tener suficiente saldo disponible en su cuenta antes de enviar la solicitud de transferencia para evitar cualquier impacto en sus operaciones de transacción.",
+    "Tips2": "2. Después de seleccionar la moneda de transferencia/tipo de transferencia/metodo de pago, asegúrese de ingresar el monto correcto de la transferencia y completar todos los campos requeridos.",
+    "Tips3": "3. El monto recibido es un monto estimado; el monto real puede variar ligeramente debido a las fluctuaciones en la tasa de cambio.",
+    "Tips4": "4. Después de enviar el pedido, su transferencia será procesada y el pago completado dentro de 1 día hábil. El tiempo real de llegada dependerá de la velocidad de procesamiento del banco receptor. Para evitar afectar su transacción, asegúrese de enviar la solicitud de transferencia en un momento adecuado.",
     "t1": "Pagador",
     "t2": "Cuenta del Pagador",
     "t3": "Moneda de Transferencia/Tipo de Transferencia/Metodo de Pago",
@@ -5601,5 +5603,23 @@
     "unit": "Por favor ingrese la unidad de transacción",
     "p1": "Unidad de transacción",
     "p2": "Monto"
+  },
+  "WalletApply": {
+    "title": "Registros de retiro de la billetera",
+    "title1": "Retirar",
+    "title2": "Solicitud de retiro",
+    "p1": "Dirección de billetera criptográfica",
+    "p2": "Por favor ingrese la dirección de la billetera criptográfica",
+    "p3": "Monto del retiro",
+    "p4": "Ingrese el monto del retiro (USDT)",
+    "p5": "(Saldo disponible {userBalance} USDT)",
+    "p6": "El monto ingresado no puede exceder {userBalance} USDT",
+    "p7": "Por favor ingrese un número válido"
+  },
+  "Blockchain1": {
+    "title": "Registros de recarga de billetera",
+    "p2": "Copie la dirección de la billetera o escanee el código QR",
+    "p3": "Generar dirección de billetera",
+    "p4": "Copiar dirección de billetera"
   }
 }

+ 32 - 12
locale/fa.json

@@ -178,7 +178,7 @@
     "i2": "تغییر رمز عبور",
     "i3": "اطلاعات شخصی",
     "i4": "سوابق کارت",
-    "i5": "درباره PayouCard",
+    "i5": "درباره C Pay",
     "i6": "خروج"
   },
   "activeState": {
@@ -3030,14 +3030,16 @@
       "t15": "بررسی رد شد",
       "t16": "برداشت",
       "t17": "برداشت نقدی",
-      "t18": "شارژ",
-      "t19": "بازپرداخت",
+      "t18": "شارژ کارت",
+      "t19": "بازپرداخت کارت",
       "t20": "واریز دستی",
       "t21": "برداشت دستی",
       "t22": "همه",
-      "t23": "کسر سفارش حواله",
-      "t24": "بازپرداخت سفارش حواله",
-      "t25": "واریز ارز دیجیتال",
+      "t23": "کسر سفارش انتقال سریع",
+      "t24": "بازپرداخت سفارش انتقال سریع",
+      "t25": "شارژ کیف پول",
+      "t26": "برداشت کیف پول",
+      "t27": "بازپرداخت برداشت کیف پول",
       "v1": "اطلاعات ثبت‌نام",
       "v2": "ویرایش اطلاعات",
       "v3": "دریافت لینک تأیید چهره",
@@ -3390,14 +3392,14 @@
   },
   "global": {
     "title": "سابقه انتقال",
-    "title1": "انتقال CWG",
+    "title1": "انتقال جهانی",
     "title2": "سفارش جدید",
     "title3": "جزئیات سفارش",
-    "Tips": "نکات انتقال:",
-    "Tips1": "1. قبل از ارسال درخواست انتقال، موجودی قابل استفاده در حساب خود را بررسی کنید تا از تأثیرگذاری بر عملیات تراکنش خود جلوگیری کنید.",
-    "Tips2": "2. پس از انتخاب ارز انتقال/نوع انتقال/روش پرداخت، مبلغ انتقال را وارد کرده و اطلاعات زیر را تکمیل/تأیید کنید.",
-    "Tips3": "3. هزینه خدمات یک مقدار تقریبی است، هزینه واقعی خدمات پس از تکمیل انتقال قابل مشاهده است.",
-    "Tips4": "4. ما درخواست شما را بلافاصله پس از دریافت آن پردازش خواهیم کرد. زمان پردازش معمولاً در کمتر از 24 ساعت تکمیل می‌شود. برای جلوگیری از تأثیرگذاری بر عملیات تراکنش خود، لطفاً به زمان ارسال درخواست توجه کنید.",
+    "Tips": "یادآوری دوستانه از Global Remittance:",
+    "Tips1": "1. لطفاً قبل از ارسال درخواست انتقال، اطمینان حاصل کنید که موجودی کافی در حساب خود دارید تا از تاثیرات منفی بر عملیات تراکنش شما جلوگیری شود.",
+    "Tips2": "2. پس از انتخاب ارز انتقال/نوع انتقال/روش پرداخت، لطفاً اطمینان حاصل کنید که مبلغ انتقال را به درستی وارد کرده و تمام فیلدهای مورد نیاز را تکمیل کرده‌اید.",
+    "Tips3": "3. مبلغ دریافتی مبلغ تخمینی است؛ مبلغ واقعی ممکن است به دلیل نوسانات نرخ ارز کمی متفاوت باشد.",
+    "Tips4": "4. پس از ارسال سفارش، انتقال شما پردازش شده و پرداخت در عرض 1 روز کاری تکمیل خواهد شد. زمان واقعی رسیدن به حساب به سرعت پردازش بانک دریافت‌کننده بستگی خواهد داشت. برای جلوگیری از تاثیر بر عملیات تراکنش شما، لطفاً اطمینان حاصل کنید که درخواست انتقال را در زمان مناسب ارسال کنید.",
     "t1": "پرداخت‌کننده",
     "t2": "حساب پرداخت‌کننده",
     "t3": "ارز انتقال/نوع انتقال/روش پرداخت",
@@ -5601,5 +5603,23 @@
     "unit": "لطفاً واحد تراکنش را وارد کنید",
     "p1": "واحد تراکنش",
     "p2": "مقدار"
+  },
+  "WalletApply": {
+    "title": "سوابق برداشت کیف پول",
+    "title1": "برداشت",
+    "title2": "درخواست برداشت",
+    "p1": "آدرس کیف پول رمزارزی",
+    "p2": "لطفاً آدرس کیف پول رمزارزی را وارد کنید",
+    "p3": "مبلغ برداشت",
+    "p4": "لطفاً مبلغ برداشت را وارد کنید (USDT)",
+    "p5": "(موجودی قابل استفاده {userBalance} USDT)",
+    "p6": "مبلغ وارد شده نمی‌تواند بیشتر از {userBalance} USDT باشد",
+    "p7": "لطفاً یک عدد معتبر وارد کنید"
+  },
+  "Blockchain1": {
+    "title": "سوابق شارژ کیف پول",
+    "p2": "آدرس کیف پول را کپی کنید یا کد QR را اسکن کنید",
+    "p3": "ایجاد آدرس کیف پول",
+    "p4": "کپی آدرس کیف پول"
   }
 }

+ 34 - 14
locale/id.json

@@ -178,7 +178,7 @@
     "i2": "Ubah kata sandi",
     "i3": "Informasi pribadi",
     "i4": "Riwayat kartu",
-    "i5": "Tentang PayouCard",
+    "i5": "Tentang C Pay",
     "i6": "Keluar"
   },
   "activeState": {
@@ -3030,14 +3030,16 @@
       "t15": "Peninjauan Ditolak",
       "t16": "Penarikan",
       "t17": "Penarikan tunai",
-      "t18": "Isi ulang",
-      "t19": "Refund",
-      "t20": "Setoran manual",
-      "t21": "Penarikan manual",
+      "t18": "Isi Ulang Kartu",
+      "t19": "Pengembalian Dana Kartu",
+      "t20": "Setoran Manual",
+      "t21": "Penarikan Manual",
       "t22": "Semua",
-      "t23": "Potongan pesanan remitansi",
-      "t24": "Pengembalian pesanan remitansi",
-      "t25": "Setoran kripto",
+      "t23": "Potongan Pesanan Transfer Cepat",
+      "t24": "Pengembalian Pesanan Transfer Cepat",
+      "t25": "Isi Ulang Dompet",
+      "t26": "Penarikan Dompet",
+      "t27": "Pengembalian Penarikan Dompet",
       "v1": "Informasi Pendaftaran",
       "v2": "Ubah Informasi",
       "v3": "Dapatkan Tautan Verifikasi Wajah",
@@ -3390,14 +3392,14 @@
   },
   "global": {
     "title": "Rekaman Transfer",
-    "title1": "Transfer CWG",
+    "title1": "Transfer Global",
     "title2": "Pesanan Baru",
     "title3": "Detail Pesanan",
-    "Tips": "Tips Transfer:",
-    "Tips1": "1. Harap periksa saldo yang tersedia di akun Anda sebelum mengajukan permintaan transfer untuk menghindari mempengaruhi operasi transaksi Anda.",
-    "Tips2": "2. Harap masukkan jumlah transfer setelah memilih mata uang transfer/jenis transfer/metode pembayaran, dan lengkapi/konfirmasi informasi berikut.",
-    "Tips3": "3. Biaya layanan adalah jumlah perkiraan, biaya layanan yang sebenarnya dapat dilihat setelah transfer selesai.",
-    "Tips4": "4. Kami akan memproses permintaan Anda segera setelah kami menerimanya. Waktu pemrosesan biasanya selesai dalam waktu 24 jam. Untuk menghindari mempengaruhi operasi transaksi Anda, harap perhatikan waktu pengajuan permintaan.",
+    "Tips": "Peringatan Ramah dari Global Remittance:",
+    "Tips1": "1. Pastikan Anda memiliki saldo yang cukup tersedia di akun Anda sebelum mengirimkan permintaan transfer untuk menghindari gangguan pada transaksi Anda.",
+    "Tips2": "2. Setelah memilih mata uang transfer/jenis transfer/metode pembayaran, pastikan untuk mengisi jumlah transfer yang benar dan menyelesaikan semua kolom yang wajib diisi.",
+    "Tips3": "3. Jumlah yang diterima adalah jumlah perkiraan; jumlah yang sebenarnya dapat sedikit bervariasi karena fluktuasi nilai tukar.",
+    "Tips4": "4. Setelah pesanan diajukan, transfer Anda akan diproses dan pembayaran akan diselesaikan dalam 1 hari kerja. Waktu kedatangan yang sebenarnya akan bergantung pada kecepatan pemrosesan bank penerima. Untuk menghindari mempengaruhi transaksi Anda, pastikan Anda mengajukan permintaan transfer pada waktu yang tepat.",
     "t1": "Pemberi Pembayaran",
     "t2": "Akun Pemberi Pembayaran",
     "t3": "Mata Uang Transfer/Tipe Transfer/Metode Pembayaran",
@@ -5601,5 +5603,23 @@
     "unit": "Silakan masukkan unit transaksi",
     "p1": "Unit Transaksi",
     "p2": "Jumlah"
+  },
+  "WalletApply": {
+    "title": "Riwayat Penarikan Dompet",
+    "title1": "Tarik",
+    "title2": "Permohonan Penarikan",
+    "p1": "Alamat Dompet Kripto",
+    "p2": "Silakan masukkan alamat dompet kripto",
+    "p3": "Jumlah Penarikan",
+    "p4": "Silakan masukkan jumlah penarikan (USDT)",
+    "p5": "(Saldo tersedia {userBalance} USDT)",
+    "p6": "Jumlah yang dimasukkan tidak boleh melebihi {userBalance} USDT",
+    "p7": "Silakan masukkan angka yang valid"
+  },
+  "Blockchain1": {
+    "title": "Riwayat Isi Ulang Dompet",
+    "p2": "Salin alamat dompet atau pindai kode QR",
+    "p3": "Buat Alamat Dompet",
+    "p4": "Salin Alamat Dompet"
   }
 }

+ 32 - 12
locale/ko.json

@@ -178,7 +178,7 @@
     "i2": "비밀번호 변경",
     "i3": "개인 정보",
     "i4": "카드 기록",
-    "i5": "PayouCard 소개",
+    "i5": "C Pay 소개",
     "i6": "로그아웃"
   },
   "activeState": {
@@ -3030,14 +3030,16 @@
       "t15": "검토 거부됨",
       "t16": "출금",
       "t17": "현금 출금",
-      "t18": "충전",
-      "t19": "환불",
+      "t18": "카드 충전",
+      "t19": "카드 환불",
       "t20": "수동 입금",
       "t21": "수동 출금",
       "t22": "전체",
-      "t23": "송금 주문 공제",
-      "t24": "송금 주문 환불",
-      "t25": "암호화폐 입금",
+      "t23": "빠른 송금 주문 차감",
+      "t24": "빠른 송금 주문 환불",
+      "t25": "지갑 충전",
+      "t26": "지갑 출금",
+      "t27": "지갑 출금 환불",
       "v1": "등록 정보",
       "v2": "정보 수정",
       "v3": "얼굴 인증 링크 받기",
@@ -3390,14 +3392,14 @@
   },
   "global": {
     "title": "이체 기록",
-    "title1": "CWG 송금",
+    "title1": "글로벌 이체",
     "title2": "새 주문",
     "title3": "주문 세부 정보",
-    "Tips": "이체 팁:",
-    "Tips1": "1. 이체 요청을 제출하기 전에 현재 계좌의 사용 가능한 잔액을 확인하여 거래 작업에 영향을 미치지 않도록 하세요.",
-    "Tips2": "2. 이체 금액을 입력한 후 이체 통화/이체 유형/결제 방법을 선택하고 아래 정보를 작성/확인하세요.",
-    "Tips3": "3. 서비스 수수료는 추정 금액으로, 실제 서비스 수수료는 이체 완료 후 확인할 수 있습니다.",
-    "Tips4": "4. 우리는 신청을 받은 즉시 처리할 것입니다. 처리 시간은 보통 24 시간 이내에 완료됩니다. 거래 작업에 영향을 미치지 않도록 신청 시간을 주의하세요.",
+    "Tips": "Global Remittance 친절한 안내:",
+    "Tips1": "1. 거래 작업에 영향을 미치지 않도록 이체 요청을 제출하기 전에 계좌에 충분한 사용 가능한 잔액이 있는지 확인하십시오.",
+    "Tips2": "2. 이체 통화/이체 유형/지불 방법을 선택한 후에는 올바른 이체 금액을 입력하고 모든 필수 항목을 완료했는지 확인하십시오.",
+    "Tips3": "3. 수취 금액은 예상 금액이며, 실제 수취 금액은 환율 변동에 따라 약간의 차이가 있을 수 있습니다.",
+    "Tips4": "4. 주문이 제출되면, 귀하의 이체는 1영업일 이내에 처리되고 지급됩니다. 실제 도착 시간은 수취 은행의 처리 속도에 따라 다릅니다. 거래 작업에 영향을 미치지 않도록 적절한 시간에 이체 요청을 제출하십시오.",
     "t1": "지불자",
     "t2": "지불 계좌",
     "t3": "이체 통화/이체 유형/결제 방법",
@@ -5601,5 +5603,23 @@
     "unit": "거래 단위를 입력하세요",
     "p1": "거래 단위",
     "p2": "금액"
+  },
+  "WalletApply": {
+    "title": "지갑 출금 기록",
+    "title1": "출금",
+    "title2": "출금 신청",
+    "p1": "암호화폐 지갑 주소",
+    "p2": "암호화폐 지갑 주소를 입력하세요",
+    "p3": "출금 금액",
+    "p4": "출금 금액을 입력하세요 (USDT)",
+    "p5": "(사용 가능 잔액 {userBalance} USDT)",
+    "p6": "입력한 금액은 {userBalance} USDT를 초과할 수 없습니다",
+    "p7": "유효한 숫자를 입력하세요"
+  },
+  "Blockchain1": {
+    "title": "지갑 충전 기록",
+    "p2": "지갑 주소를 복사하거나 QR 코드를 스캔하세요",
+    "p3": "지갑 주소 생성",
+    "p4": "지갑 주소 복사"
   }
 }

+ 34 - 14
locale/ms.json

@@ -178,7 +178,7 @@
     "i2": "Ubah kata laluan",
     "i3": "Maklumat peribadi",
     "i4": "Rekod permohonan kad",
-    "i5": "Tentang PayouCard",
+    "i5": "Tentang C Pay",
     "i6": "Log keluar"
   },
   "activeState": {
@@ -3030,14 +3030,16 @@
       "t15": "Semakan Ditolak",
       "t16": "Pengeluaran",
       "t17": "Pengeluaran tunai",
-      "t18": "Tambah nilai",
-      "t19": "Bayaran balik",
-      "t20": "Deposit manual",
-      "t21": "Pengeluaran manual",
+      "t18": "Tambah Nilai Kad",
+      "t19": "Bayaran Balik Kad",
+      "t20": "Deposit Manual",
+      "t21": "Pengeluaran Manual",
       "t22": "Semua",
-      "t23": "Potongan pesanan remitans",
-      "t24": "Bayaran balik pesanan remitans",
-      "t25": "Deposit kripto",
+      "t23": "Potongan Pesanan Pemindahan Pantas",
+      "t24": "Bayaran Balik Pesanan Pemindahan Pantas",
+      "t25": "Tambah Nilai Dompet",
+      "t26": "Pengeluaran Dompet",
+      "t27": "Bayaran Balik Pengeluaran Dompet",
       "v1": "Maklumat Pendaftaran",
       "v2": "Ubah Maklumat",
       "v3": "Dapatkan Pautan Pengesahan Wajah",
@@ -3390,14 +3392,14 @@
   },
   "global": {
     "title": "Rekod Pemindahan",
-    "title1": "Pemindahan CWG",
+    "title1": "Pemindahan Global",
     "title2": "Pesanan Baru",
     "title3": "Butiran Pesanan",
-    "Tips": "Tips Pemindahan:",
-    "Tips1": "1. Sila semak baki yang tersedia dalam akaun anda sebelum menghantar permintaan pemindahan untuk mengelakkan gangguan pada operasi transaksi anda.",
-    "Tips2": "2. Sila masukkan jumlah pemindahan selepas memilih mata wang pemindahan/jenis pemindahan/kaedah pembayaran, dan lengkapi/ sahkan maklumat berikut.",
-    "Tips3": "3. Caj perkhidmatan adalah anggaran, caj perkhidmatan sebenar boleh dilihat selepas pemindahan selesai.",
-    "Tips4": "4. Kami akan memproses permintaan anda sebaik sahaja kami menerimanya. Masa pemprosesan biasanya diselesaikan dalam 24 jam. Untuk mengelakkan gangguan pada operasi transaksi anda, sila ambil perhatian waktu permintaan anda dihantar.",
+    "Tips": "Peringatan Mesra dari Global Remittance:",
+    "Tips1": "1. Sila pastikan bahawa anda mempunyai baki yang mencukupi di dalam akaun anda sebelum menghantar permohonan pemindahan untuk mengelakkan sebarang kesan terhadap operasi transaksi anda.",
+    "Tips2": "2. Selepas memilih mata wang pemindahan/jenis pemindahan/cara pembayaran, pastikan anda mengisi jumlah pemindahan yang betul dan melengkapkan semua medan yang diperlukan.",
+    "Tips3": "3. Jumlah yang diterima adalah jumlah anggaran; jumlah sebenar mungkin berbeza sedikit disebabkan oleh turun naik kadar pertukaran.",
+    "Tips4": "4. Setelah pesanan dihantar, pemindahan anda akan diproses dan pembayaran akan diselesaikan dalam 1 hari bekerja. Masa ketibaan sebenar akan bergantung pada kelajuan pemprosesan bank penerima. Untuk mengelakkan mempengaruhi transaksi anda, pastikan anda menghantar permohonan pemindahan pada masa yang sesuai.",
     "t1": "Pembayar",
     "t2": "Akaun Pembayar",
     "t3": "Mata Wang Pemindahan/Jenis Pemindahan/Kaedah Pembayaran",
@@ -5601,5 +5603,23 @@
     "unit": "Sila masukkan unit transaksi",
     "p1": "Unit Transaksi",
     "p2": "Jumlah"
+  },
+  "WalletApply": {
+    "title": "Rekod Pengeluaran Dompet",
+    "title1": "Keluarkan",
+    "title2": "Permohonan Pengeluaran",
+    "p1": "Alamat Dompet Kripto",
+    "p2": "Sila masukkan alamat dompet kripto",
+    "p3": "Jumlah Pengeluaran",
+    "p4": "Sila masukkan jumlah pengeluaran (USDT)",
+    "p5": "(Baki tersedia {userBalance} USDT)",
+    "p6": "Jumlah yang dimasukkan tidak boleh melebihi {userBalance} USDT",
+    "p7": "Sila masukkan nombor yang sah"
+  },
+  "Blockchain1": {
+    "title": "Rekod Tambah Nilai Dompet",
+    "p2": "Salin alamat dompet atau imbas kod QR",
+    "p3": "Jana Alamat Dompet",
+    "p4": "Salin Alamat Dompet"
   }
 }

+ 34 - 14
locale/pt.json

@@ -178,7 +178,7 @@
     "i2": "Alterar senha",
     "i3": "Informações pessoais",
     "i4": "Registros de solicitação",
-    "i5": "Sobre o PayouCard",
+    "i5": "Sobre o C Pay",
     "i6": "Sair"
   },
   "activeState": {
@@ -3030,14 +3030,16 @@
       "t15": "Revisão Rejeitada",
       "t16": "Levantamento",
       "t17": "Levantamento em dinheiro",
-      "t18": "Carregar",
-      "t19": "Reembolso",
-      "t20": "Depósito manual",
-      "t21": "Levantamento manual",
+      "t18": "Recarga de Cartão",
+      "t19": "Reembolso de Cartão",
+      "t20": "Depósito Manual",
+      "t21": "Saque Manual",
       "t22": "Todos",
-      "t23": "Dedução de ordem de remessa",
-      "t24": "Reembolso de ordem de remessa",
-      "t25": "Depósito de criptomoedas",
+      "t23": "Dedução de Pedido de Transferência Rápida",
+      "t24": "Reembolso de Pedido de Transferência Rápida",
+      "t25": "Recarga da Carteira",
+      "t26": "Saque da Carteira",
+      "t27": "Reembolso de Saque da Carteira",
       "v1": "Informações de Registro",
       "v2": "Modificar Informações",
       "v3": "Obter Link de Verificação Facial",
@@ -3390,14 +3392,14 @@
   },
   "global": {
     "title": "Registro de Transferência",
-    "title1": "Transferência CWG",
+    "title1": "Transferência Global",
     "title2": "Novo Pedido",
     "title3": "Detalhes do Pedido",
-    "Tips": "Dicas de Transferência:",
-    "Tips1": "1. Por favor, verifique o saldo disponível na sua conta antes de enviar uma solicitação de transferência para evitar impactar suas operações de transação.",
-    "Tips2": "2. Por favor, insira o valor da transferência após selecionar a moeda da transferência/tipo de transferência/método de pagamento e preencha/confirme as seguintes informações.",
-    "Tips3": "3. A taxa de serviço é um valor estimado, a taxa de serviço real pode ser visualizada após a conclusão da transferência.",
-    "Tips4": "4. Processaremos sua solicitação assim que a recebermos. O tempo de processamento normalmente é concluído em até 24 hora. Para evitar impactos nas suas operações de transação, por favor, preste atenção ao horário em que enviar sua solicitação.",
+    "Tips": "Lembrete amigável da Global Remittance:",
+    "Tips1": "1. Certifique-se de que você tem saldo suficiente disponível em sua conta antes de enviar o pedido de transferência para evitar impactos nas suas operações de transação.",
+    "Tips2": "2. Após selecionar a moeda de transferência/tipo de transferência/método de pagamento, certifique-se de preencher o valor correto da transferência e completar todos os campos obrigatórios.",
+    "Tips3": "3. O valor recebido é uma estimativa; o valor real pode variar ligeiramente devido às flutuações na taxa de câmbio.",
+    "Tips4": "4. Após o pedido ser submetido, sua transferência será processada e o pagamento será concluído em 1 dia útil. O tempo real de chegada dependerá da velocidade de processamento do banco receptor. Para evitar impactos na sua transação, certifique-se de enviar o pedido de transferência no momento adequado.",
     "t1": "Pagador",
     "t2": "Conta do Pagador",
     "t3": "Moeda de Transferência/Tipo de Transferência/Método de Pagamento",
@@ -5601,5 +5603,23 @@
     "unit": "Por favor, insira a unidade de transação",
     "p1": "Unidade de Transação",
     "p2": "Valor"
+  },
+  "WalletApply": {
+    "title": "Registros de Saque da Carteira",
+    "title1": "Sacar",
+    "title2": "Solicitação de Saque",
+    "p1": "Endereço da Carteira Cripto",
+    "p2": "Por favor, insira o endereço da carteira cripto",
+    "p3": "Valor do Saque",
+    "p4": "Insira o valor do saque (USDT)",
+    "p5": "(Saldo disponível {userBalance} USDT)",
+    "p6": "O valor inserido não pode exceder {userBalance} USDT",
+    "p7": "Por favor, insira um número válido"
+  },
+  "Blockchain1": {
+    "title": "Registros de Recarga da Carteira",
+    "p2": "Copie o endereço da carteira ou escaneie o código QR",
+    "p3": "Gerar Endereço da Carteira",
+    "p4": "Copiar Endereço da Carteira"
   }
 }

+ 32 - 12
locale/th.json

@@ -178,7 +178,7 @@
     "i2": "เปลี่ยนรหัสผ่าน",
     "i3": "ข้อมูลส่วนตัว",
     "i4": "ประวัติการสมัคร",
-    "i5": "เกี่ยวกับ PayouCard",
+    "i5": "เกี่ยวกับ C Pay",
     "i6": "ออกจากระบบ"
   },
   "activeState": {
@@ -3030,14 +3030,16 @@
       "t15": "การตรวจสอบถูกปฏิเสธ",
       "t16": "ถอนเงิน",
       "t17": "ถอนเงินสด",
-      "t18": "เติมเงิน",
-      "t19": "คืนเงิน",
+      "t18": "เติมเงินบัตร",
+      "t19": "คืนเงินบัตร",
       "t20": "ฝากเงินด้วยตนเอง",
       "t21": "ถอนเงินด้วยตนเอง",
       "t22": "ทั้งหมด",
-      "t23": "หักยอดคำสั่งโอนเงิน",
-      "t24": "คืนเงินคำสั่งโอนเงิน",
-      "t25": "ฝากสกุลเงินดิจิทัล",
+      "t23": "หักคำสั่งโอนด่วน",
+      "t24": "คืนเงินคำสั่งโอนด่วน",
+      "t25": "เติมเงินกระเป๋าเงิน",
+      "t26": "ถอนกระเป๋าเงิน",
+      "t27": "คืนเงินการถอนกระเป๋าเงิน",
       "v1": "ข้อมูลการลงทะเบียน",
       "v2": "แก้ไขข้อมูล",
       "v3": "รับลิงก์ยืนยันใบหน้า",
@@ -3390,14 +3392,14 @@
   },
   "global": {
     "title": "ประวัติการโอน",
-    "title1": "CWG โอนเงิน",
+    "title1": "การโอนทั่วโลก",
     "title2": "คำสั่งซื้อใหม่",
     "title3": "รายละเอียดคำสั่งซื้อ",
-    "Tips": "เคล็ดลับการโอน:",
-    "Tips1": "1. กรุณาตรวจสอบยอดเงินที่สามารถใช้งานได้ในบัญชีของคุณก่อนที่จะส่งคำขอโอนเพื่อหลีกเลี่ยงผลกระทบต่อการดำเนินธุรกรรมของคุณ.",
-    "Tips2": "2. กรุณากรอกจำนวนเงินโอนหลังจากเลือกสกุลเงิน/ประเภทการโอน/วิธีการชำระเงิน และกรอก/ยืนยันข้อมูลต่อไปนี้.",
-    "Tips3": "3. ค่าธรรมเนียมบริการเป็นจำนวนประมาณ, ค่าธรรมเนียมจริงจะสามารถดูได้หลังจากที่โอนเสร็จสิ้น.",
-    "Tips4": "4. เราจะดำเนินการคำขอของคุณทันทีที่ได้รับ คำขอจะได้รับการดำเนินการภายใน 24 ชั่วโมงโดยปกติ เพื่อหลีกเลี่ยงผลกระทบต่อการดำเนินธุรกรรมของคุณ กรุณาสังเกตเวลาในการส่งคำขอ.",
+    "Tips": "คำแนะนำจาก Global Remittance:",
+    "Tips1": "1. กรุณาตรวจสอบให้แน่ใจว่าคุณมียอดเงินที่เพียงพอในบัญชีของคุณก่อนการส่งคำขอโอนเงิน เพื่อหลีกเลี่ยงผลกระทบต่อการทำธุรกรรมของคุณ.",
+    "Tips2": "2. หลังจากเลือกสกุลเงินการโอน/ประเภทการโอน/วิธีการชำระเงินแล้ว กรุณากรอกจำนวนเงินการโอนที่ถูกต้องและกรอกข้อมูลที่จำเป็นทั้งหมด.",
+    "Tips3": "3. จำนวนเงินที่ได้รับเป็นจำนวนเงินโดยประมาณ; จำนวนเงินที่แท้จริงอาจแตกต่างเล็กน้อยเนื่องจากความผันผวนของอัตราแลกเปลี่ยน.",
+    "Tips4": "4. หลังจากส่งคำสั่งซื้อแล้ว การโอนเงินของคุณจะได้รับการดำเนินการและชำระเงินภายใน 1 วันทำการ เวลาที่ถึงจริงจะขึ้นอยู่กับความเร็วในการประมวลผลของธนาคารที่รับเงิน. เพื่อหลีกเลี่ยงผลกระทบต่อการทำธุรกรรมของคุณ กรุณาตรวจสอบให้แน่ใจว่าคุณส่งคำขอโอนเงินในเวลาที่เหมาะสม.",
     "t1": "ผู้โอนเงิน",
     "t2": "บัญชีผู้โอน",
     "t3": "สกุลเงินการโอน/ประเภทการโอน/วิธีการชำระเงิน",
@@ -5601,5 +5603,23 @@
     "unit": "กรุณากรอกหน่วยธุรกรรม",
     "p1": "หน่วยธุรกรรม",
     "p2": "จำนวนเงิน"
+  },
+  "WalletApply": {
+    "title": "ประวัติการถอนกระเป๋าเงิน",
+    "title1": "ถอนเงิน",
+    "title2": "คำขอถอนเงิน",
+    "p1": "ที่อยู่กระเป๋าเงินคริปโต",
+    "p2": "กรุณากรอกที่อยู่กระเป๋าเงินคริปโต",
+    "p3": "จำนวนเงินที่ถอน",
+    "p4": "กรุณากรอกจำนวนเงินที่ถอน (USDT)",
+    "p5": "(ยอดคงเหลือที่ใช้ได้ {userBalance} USDT)",
+    "p6": "จำนวนเงินที่กรอกต้องไม่เกิน {userBalance} USDT",
+    "p7": "กรุณากรอกตัวเลขที่ถูกต้อง"
+  },
+  "Blockchain1": {
+    "title": "ประวัติการเติมเงินกระเป๋าเงิน",
+    "p2": "คัดลอกที่อยู่กระเป๋าเงินหรือสแกน QR",
+    "p3": "สร้างที่อยู่กระเป๋าเงิน",
+    "p4": "คัดลอกที่อยู่กระเป๋าเงิน"
   }
 }

+ 34 - 14
locale/tr.json

@@ -178,7 +178,7 @@
     "i2": "Şifre değiştir",
     "i3": "Kişisel bilgiler",
     "i4": "Başvuru kayıtları",
-    "i5": "PayouCard hakkında",
+    "i5": "C Pay hakkında",
     "i6": "Çıkış yap"
   },
   "activeState": {
@@ -3030,14 +3030,16 @@
       "t15": "İnceleme Reddedildi",
       "t16": "Para Çekme",
       "t17": "Nakit Çekme",
-      "t18": "Bakiye Yükleme",
-      "t19": "İade",
-      "t20": "Manuel Yatırım",
-      "t21": "Manuel Çekim",
+      "t18": "Kart Yükleme",
+      "t19": "Kart İadesi",
+      "t20": "Manuel Yatırma",
+      "t21": "Manuel Çekme",
       "t22": "Tümü",
-      "t23": "Havale sipariş kesintisi",
-      "t24": "Havale sipariş iadesi",
-      "t25": "Kripto para yatırma",
+      "t23": "Hızlı Transfer Siparişi Kesintisi",
+      "t24": "Hızlı Transfer Siparişi İadesi",
+      "t25": "Cüzdan Yükleme",
+      "t26": "Cüzdan Çekimi",
+      "t27": "Cüzdan Çekim İadesi",
       "v1": "Kayıt Bilgileri",
       "v2": "Bilgileri Değiştir",
       "v3": "Yüz Doğrulama Bağlantısı Al",
@@ -3390,14 +3392,14 @@
   },
   "global": {
     "title": "Transfer Kaydı",
-    "title1": "CWG Transferi",
+    "title1": "Küresel Transfer",
     "title2": "Yeni Sipariş",
     "title3": "Sipariş Detayları",
-    "Tips": "Transfer İpuçları:",
-    "Tips1": "1. Transfer talebini göndermeden önce mevcut hesabınızdaki kullanılabilir bakiyeyi kontrol edin, böylece ticaret işlemlerinizin etkilenmesini engellersiniz.",
-    "Tips2": "2. Transfer miktarını girdikten sonra transfer para birimi/transfer tipi/ödeme yöntemini seçin ve aşağıdaki bilgileri doldurun/onaylayın.",
-    "Tips3": "3. Hizmet ücreti tahmini bir tutardır, gerçek hizmet ücreti transfer tamamlandığında görüntülenebilir.",
-    "Tips4": "4. Başvurunuzu aldığımızda hemen işlem yapacağız. İşlem süresi genellikle 24 saat içinde tamamlanır. Ticaret işlemlerinizi etkilememek için başvuru saatinize dikkat edin.",
+    "Tips": "Global Remittance'dan Dostça Hatırlatma:",
+    "Tips1": "1. İşlem operasyonlarınızı etkileyebileceğinden, transfer talebini göndermeden önce hesabınızda yeterli kullanılabilir bakiyenin olduğundan emin olun.",
+    "Tips2": "2. Transfer para birimi/transfer türü/ödeme yöntemi seçtikten sonra, doğru transfer tutarını girdiğinizden ve tüm gerekli alanları tamamladığınızdan emin olun.",
+    "Tips3": "3. Alınan tutar tahmini bir tutardır; gerçek tutar, döviz kuru dalgalanmaları nedeniyle biraz farklılık gösterebilir.",
+    "Tips4": "4. Sipariş gönderildikten sonra, transferiniz 1 iş günü içinde işleme alınacak ve ödeme tamamlanacaktır. Gerçek varış zamanı, alıcı bankanın işlem hızına bağlı olacaktır. İşlem operasyonlarınıza etki etmemek için transfer talebini uygun bir zamanda gönderdiğinizden emin olun.",
     "t1": "Ödeyen",
     "t2": "Ödeme Hesabı",
     "t3": "Transfer Para Birimi/Transfer Tipi/Ödeme Yöntemi",
@@ -5601,5 +5603,23 @@
     "unit": "Lütfen işlem birimini girin",
     "p1": "İşlem Birimi",
     "p2": "Miktar"
+  },
+  "WalletApply": {
+    "title": "Cüzdan Çekim Kayıtları",
+    "title1": "Çek",
+    "title2": "Çekim Talebi",
+    "p1": "Kripto Cüzdan Adresi",
+    "p2": "Lütfen kripto cüzdan adresini girin",
+    "p3": "Çekim Tutarı",
+    "p4": "Lütfen çekim tutarını girin (USDT)",
+    "p5": "(Kullanılabilir bakiye {userBalance} USDT)",
+    "p6": "Girilen tutar {userBalance} USDT'yi aşamaz",
+    "p7": "Lütfen geçerli bir sayı girin"
+  },
+  "Blockchain1": {
+    "title": "Cüzdan Yükleme Kayıtları",
+    "p2": "Cüzdan adresini kopyalayın veya QR kodu tarayın",
+    "p3": "Cüzdan Adresi Oluştur",
+    "p4": "Cüzdan Adresini Kopyala"
   }
 }

+ 34 - 14
locale/vn.json

@@ -178,7 +178,7 @@
     "i2": "Đổi mật khẩu",
     "i3": "Thông tin cá nhân",
     "i4": "Lịch sử đăng ký",
-    "i5": "Về PayouCard",
+    "i5": "Về C Pay",
     "i6": "Đăng xuất"
   },
   "activeState": {
@@ -3029,14 +3029,16 @@
       "t15": "Duyệt thất bại",
       "t16": "Rút tiền",
       "t17": "Rút tiền mặt",
-      "t18": "Nạp tiền",
-      "t19": "Hoàn tiền",
-      "t20": "Nạp thủ công",
-      "t21": "Rút thủ công",
+      "t18": "Nạp thẻ",
+      "t19": "Hoàn tiền thẻ",
+      "t20": "Nạp tiền thủ công",
+      "t21": "Rút tiền thủ công",
       "t22": "Tất cả",
-      "t23": "Khấu trừ đơn hàng chuyển tiền",
-      "t24": "Hoàn tiền đơn hàng chuyển tiền",
-      "t25": "Nạp tiền mã hóa",
+      "t23": "Khấu trừ đơn chuyển nhanh",
+      "t24": "Hoàn tiền đơn chuyển nhanh",
+      "t25": "Nạp ví",
+      "t26": "Rút ví",
+      "t27": "Hoàn tiền rút ví",
       "v1": "Thông tin đăng ký",
       "v2": "Chỉnh sửa thông tin",
       "v3": "Nhận liên kết xác minh khuôn mặt",
@@ -3389,14 +3391,14 @@
   },
   "global": {
     "title": "Lịch sử chuyển tiền",
-    "title1": "Chuyển tiền CWG",
+    "title1": "Chuyển tiền toàn cầu",
     "title2": "Đơn hàng mới",
     "title3": "Chi tiết đơn hàng",
-    "Tips": "Lời khuyên chuyển tiền:",
-    "Tips1": "1. Vui lòng kiểm tra số dư khả dụng trong tài khoản của bạn trước khi gửi yêu cầu chuyển tiền để tránh ảnh hưởng đến các giao dịch của bạn.",
-    "Tips2": "2. Vui lòng nhập số tiền chuyển sau khi chọn loại tiền tệ/chuyển tiền/phương thức thanh toán, và điền/xác nhận thông tin sau.",
-    "Tips3": "3. Phí dịch vụ là số ước tính, phí dịch vụ thực tế sẽ được hiển thị sau khi hoàn thành chuyển tiền.",
-    "Tips4": "4. Chúng tôi sẽ xử lý yêu cầu của bạn ngay khi nhận được, quá trình xử lý thường hoàn thành trong vòng 24 giờ. Để tránh ảnh hưởng đến giao dịch của bạn, vui lòng chú ý đến thời gian bạn gửi yêu cầu.",
+    "Tips": "Lưu ý từ Global Remittance:",
+    "Tips1": "1. Vui lòng đảm bảo rằng bạn có đủ số dư khả dụng trong tài khoản trước khi gửi yêu cầu chuyển tiền để tránh ảnh hưởng đến các giao dịch của bạn.",
+    "Tips2": "2. Sau khi chọn loại tiền tệ/chuyển tiền/phương thức thanh toán, vui lòng đảm bảo điền đúng số tiền chuyển và hoàn thành tất cả các trường yêu cầu.",
+    "Tips3": "3. Số tiền nhận được là số tiền ước tính; số tiền thực tế có thể thay đổi nhẹ do sự dao động của tỷ giá hối đoái.",
+    "Tips4": "4. Sau khi đơn hàng được gửi, chuyển tiền của bạn sẽ được xử lý và thanh toán trong vòng 1 ngày làm việc. Thời gian thực tế đến sẽ phụ thuộc vào tốc độ xử lý của ngân hàng nhận. Để tránh ảnh hưởng đến giao dịch của bạn, vui lòng đảm bảo gửi yêu cầu chuyển tiền vào thời điểm thích hợp.",
     "t1": "Người gửi tiền",
     "t2": "Tài khoản người gửi",
     "t3": "Tiền tệ chuyển tiền/Loại chuyển tiền/Phương thức thanh toán",
@@ -5600,5 +5602,23 @@
     "unit": "Vui lòng nhập đơn vị giao dịch",
     "p1": "Đơn vị giao dịch",
     "p2": "Số tiền"
+  },
+  "WalletApply": {
+    "title": "Lịch sử rút ví",
+    "title1": "Rút tiền",
+    "title2": "Yêu cầu rút tiền",
+    "p1": "Địa chỉ ví tiền mã hóa",
+    "p2": "Vui lòng nhập địa chỉ ví tiền mã hóa",
+    "p3": "Số tiền rút",
+    "p4": "Vui lòng nhập số tiền rút (USDT)",
+    "p5": "(Số dư khả dụng {userBalance} USDT)",
+    "p6": "Số tiền nhập không được vượt quá {userBalance} USDT",
+    "p7": "Vui lòng nhập số hợp lệ"
+  },
+  "Blockchain1": {
+    "title": "Lịch sử nạp ví",
+    "p2": "Sao chép địa chỉ ví hoặc quét mã QR",
+    "p3": "Tạo địa chỉ ví",
+    "p4": "Sao chép địa chỉ ví"
   }
 }

+ 30 - 10
locale/zhHant.json

@@ -178,7 +178,7 @@
     "i2": "修改密碼",
     "i3": "個人資訊",
     "i4": "開卡紀錄",
-    "i5": "關於 PayouCard",
+    "i5": "關於 C Pay",
     "i6": "登出"
   },
   "activeState": {
@@ -3011,14 +3011,16 @@
       "t15": "審核拒絕",
       "t16": "提款",
       "t17": "取款",
-      "t18": "充值",
-      "t19": "退款",
+      "t18": "充值",
+      "t19": "退款",
       "t20": "手動轉入",
       "t21": "手動轉出",
       "t22": "全部",
       "t23": "速匯訂單扣款",
       "t24": "速匯訂單退款",
-      "t25": "加密貨幣轉入",
+      "t25": "錢包充值",
+      "t26": "錢包提現",
+      "t27": "錢包提現退款",
       "v1": "註冊資訊",
       "v2": "修改資訊",
       "v3": "取得人臉認證連結",
@@ -3371,14 +3373,14 @@
   },
   "global": {
     "title": "速匯記錄",
-    "title1": "CWG速匯",
+    "title1": "全球速匯",
     "title2": "新增訂單",
     "title3": "訂單詳情",
-    "Tips": "轉帳溫馨提示:",
-    "Tips1": "1. 請在提交轉帳申請前檢查您當前帳戶的可用金額,避免影響你的交易操作。",
-    "Tips2": "2. 在選擇轉帳幣種/轉帳類型/支付方式後輸入轉帳金額,並填寫、確認以下資訊。",
-    "Tips3": "3. 手續費為預估金額,實際手續費在轉帳完成後查看。",
-    "Tips4": "4. 我們在收到申請後,會在第一時間處理,處理時間一般在24小時內完成,為避免影響您的交易操作,請注意您提交申請的時間。",
+    "Tips": "全球速匯溫馨提示:",
+    "Tips1": "1. 請在提交轉帳申請前,確認帳戶內有足夠的可用餘額,以免影響您的交易操作。",
+    "Tips2": "2. 在選擇轉帳幣種/轉帳類型/支付方式後,請確保填寫正確的轉帳金額,並完成所有必填項。",
+    "Tips3": "3. 到帳金額為預計金額,實際到帳金額可能會因匯率波動產生細微差異。",
+    "Tips4": "4. 訂單提交後,您的轉帳將在1個工作日內處理並完成打款。具體到帳時間將依據收款銀行的處理速度有所不同。為避免影響您的交易操作,請確保在合適的時間提交轉帳申請。",
     "t1": "付款人",
     "t2": "付款帳戶",
     "t3": "轉帳幣種/轉帳類型/支付方式",
@@ -5582,5 +5584,23 @@
     "unit": "請輸入交易單位",
     "p1": "交易單位",
     "p2": "金額"
+  },
+  "WalletApply": {
+    "title": "錢包提現記錄",
+    "title1": "提現",
+    "title2": "提現申請",
+    "p1": "加密錢包地址",
+    "p2": "請輸入加密錢包地址",
+    "p3": "提現金額",
+    "p4": "請輸入提現金額(USDT)",
+    "p5": "(可用餘額 {userBalance} USDT)",
+    "p6": "輸入的金額不能超過 {userBalance} USDT",
+    "p7": "請輸入有效數字"
+  },
+  "Blockchain1": {
+    "title": "錢包充值記錄",
+    "p2": "複製錢包地址或使用手機掃碼複製地址",
+    "p3": "生成錢包地址",
+    "p4": "複製錢包地址"
   }
 }

+ 4 - 1
manifest.json

@@ -176,7 +176,7 @@
     "h5" : {
         "template" : "template.h5.html",
         "router" : {
-            "mode" : "history",
+            "mode" : "hash",
             "base" : ""
         },
         "sdkConfigs" : {
@@ -191,6 +191,9 @@
         },
         "uniStatistics" : {
             "enable" : true
+        },
+        "devServer" : {
+            "https" : false
         }
     },
     "vueVersion" : "3",

+ 35 - 0
pages.json

@@ -94,6 +94,41 @@
 				"navigationStyle": "custom"
 			}
 		},
+		{
+			"path": "pages/mine/permission",
+			"style": {
+				"navigationBarTitleText": "",
+				"navigationStyle": "custom"
+			}
+		},
+		{
+			"path": "pages/mine/privacy",
+			"style": {
+				"navigationBarTitleText": "",
+				"navigationStyle": "custom"
+			}
+		},
+		{
+			"path": "pages/mine/help",
+			"style": {
+				"navigationBarTitleText": "",
+				"navigationStyle": "custom"
+			}
+		},
+		{
+			"path": "pages/mine/help-detail",
+			"style": {
+				"navigationBarTitleText": "",
+				"navigationStyle": "custom"
+			}
+		},
+		{
+			"path": "pages/mine/cog",
+			"style": {
+				"navigationBarTitleText": "",
+				"navigationStyle": "custom"
+			}
+		},
 		{
 			"path": "pages/mine/pay-password",
 			"style": {

+ 1 - 1
pages/card/operations.vue

@@ -1,5 +1,5 @@
 <template>
-  <cwg-page-wrapper>
+  <cwg-page-wrapper :isHeaderFixed="true">
     <cwg-header :showBack="true" :title="title[type]">
       <view v-if="type == 2" @click="goRechargeRecord">
         <cwg-icon name="icon_history" :size="24" color="#000" />

Разница между файлами не показана из-за своего большого размера
+ 18 - 0
pages/mine/about.vue


+ 265 - 0
pages/mine/cog.vue

@@ -0,0 +1,265 @@
+<template>
+    <cwg-page-wrapper>
+        <view class="page">
+            <view class="group">
+                <view class="group-item" @click="router.push('/pages/mine/pay-password')">
+                    <cwg-icon color="#000" icon="xgmm" />
+                    <text class="item-text">{{ t("language.i2") }}</text>
+                    <text class="version item-text"></text>
+                    <cwg-icon color="#817f7f" icon="chevron-right" />
+                </view>
+                <view class="group-item" @click="router.push('/pages/mine/language')">
+                    <cwg-icon color="#000" icon="web" />
+                    <text class="item-text">{{ t("language.i1") }}</text>
+                    <text class="version item-text">{{ t(`language.${lang}`) }}</text>
+                    <cwg-icon color="#817f7f" icon="chevron-right" />
+                </view>
+            </view>
+
+            <!-- <view class="group">
+                <view class="group-item" @click="router.push('/pages/mine/pay-password')">
+                    <cwg-icon color="#000" icon="xxtz" />
+                    <text class="item-text">消息通知设置</text>
+                    <text class="version item-text"></text>
+                    <cwg-icon color="#817f7f" icon="chevron-right" />
+                </view>
+            </view> -->
+            <view class="group">
+                <view class="group-item" @click="router.push('/pages/mine/permission')">
+                    <cwg-icon color="#000" icon="yszc" />
+                    <text class="item-text">{{ t('pages.mine.permission') }}</text>
+                    <text class="version item-text"></text>
+                    <cwg-icon color="#817f7f" icon="chevron-right" />
+                </view>
+            </view>
+            <view class="group">
+                <view class="group-item" @click="router.push('/pages/mine/privacy')">
+                    <cwg-icon color="#000" icon="ys" />
+                    <text class="item-text">{{ t('pages.mine.privacy') }}</text>
+                    <text class="version item-text"></text>
+                    <cwg-icon color="#817f7f" icon="chevron-right" />
+                </view>
+            </view>
+            <view class="group">
+                <view class="group-item">
+                    <cwg-icon color="#000" icon="qchc" />
+                    <text class="item-text">{{ t('pages.mine.clearCache') }}</text>
+                    <text class="version item-text">{{ a }}</text>
+                    <cwg-icon color="#817f7f" icon="chevron-right" />
+                </view>
+            </view>
+
+            <view class="group" v-if="appVersion?.currentVersion">
+                <view class="group-item">
+                    <cwg-icon color="#000" icon="dqbb" />
+                    <text class="item-text">{{ t('pages.mine.currentVersion') }} v{{ appVersion.currentVersion }}</text>
+                    <text class="version item-text" @click="checkUpdate">{{ isUploadD }}</text>
+                    <cwg-icon color="#817f7f" icon="chevron-right" />
+                </view>
+            </view>
+
+            <view class="group">
+                <view class="group-item">
+                    <cwg-icon color="#000" icon="gy" />
+                    <text class="item-text">{{ t('pages.mine.about') }}</text>
+                    <text class="version item-text"></text>
+                    <cwg-icon color="#817f7f" icon="chevron-right" />
+                </view>
+            </view>
+
+            <view class="fixed-btn">
+                <view class="cwg-button">
+                    <u-button type="primary" block :loading="loading" @click="showLogoutPopup = true">{{
+                        t("language.i6") }}</u-button>
+                </view>
+            </view>
+            <u-modal class="code-dialog" :show="showLogoutPopup" title="" :show-confirm-button="false"
+                :show-cancel-button="false" :close-on-click-overlay="false">
+                <view class="modal-class">
+                    <view class="p1 title">{{ t('mine.logout') }}</view>
+                    <view class="p1">{{ t('mine.p') }}</view>
+                    <view class="cwg-button ok-button">
+                        <u-button type="primary" block @click="handleLogout('confirm')">{{
+                            t("mine.b1")
+                        }}</u-button>
+                    </view>
+                    <view class="cwg-button no-button">
+                        <u-button type="primary" block @click="handleLogout">{{
+                            t("mine.b2")
+                        }}</u-button>
+                    </view>
+                </view>
+            </u-modal>
+        </view>
+    </cwg-page-wrapper>
+
+</template>
+
+<script setup lang="ts">
+import { onLoad } from '@dcloudio/uni-app'
+import { ref, computed } from "vue";
+import { useI18n } from "vue-i18n";
+import useRouter from "@/hooks/useRouter";
+import { userApi } from "@/api/user";
+import { lang } from "@/composables/config";
+import useUserStore from "@/stores/use-user-store";
+import { showToast } from "@/utils/toast";
+import { useAppUpdate } from '@/hooks/useAppUpdate'
+const { checkUpdate } = useAppUpdate()
+const { t } = useI18n();
+const userStore = useUserStore();
+const router = useRouter();
+const a = computed(() => {
+    try {
+        const res = uni.getStorageInfoSync();
+        const currentSizeMB = (res.currentSize / 1024).toFixed(2);
+        return `${currentSizeMB} MB`;
+    } catch (e) {
+        return 0
+    }
+});
+const appVersion = computed(() => userStore.appVersion);
+const isUploadD = computed(() => appVersion.value?.isUpdate ? t('pages.mine.newVersion') : t('pages.mine.hasNewVersion'));
+const showLogoutPopup = ref(false);
+async function handleLogout(action: string) {
+    if (action === "confirm") {
+        try {
+            const res = await userApi.logout();
+            if (res.code === 200) {
+                userStore.clearUserInfo();
+                router.push("/pages/login/index");
+            }
+        } catch (error) {
+            showToast(error.message || "退出登录失败");
+        }
+    }
+    showLogoutPopup.value = false;
+}
+</script>
+
+<style scoped lang="scss">
+@import "@/uni.scss";
+
+:deep(.u-modal__content) {
+    padding: px2rpx(24) px2rpx(40);
+
+    .p1 {
+        color: #363130;
+        font-family: "League Spartan";
+        font-size: px2rpx(17);
+        font-style: normal;
+        font-weight: 400;
+        line-height: normal;
+        margin-bottom: px2rpx(32);
+    }
+
+    .modal-class {
+        width: px2rpx(300);
+
+    }
+
+    .title {
+        color: #1a1a1a;
+        text-align: center;
+        font-family: Roboto;
+        font-size: px2rpx(22);
+        font-style: normal;
+        font-weight: 600;
+        line-height: px2rpx(22);
+    }
+
+    .no-button {
+        width: 100%;
+        margin: px2rpx(12) 0;
+
+        .u-button {
+            background-color: #ffbdc8 !important;
+        }
+    }
+
+    .ok-button {
+        margin: px2rpx(4) 0;
+        /* background-color: #EA002A; */
+    }
+}
+
+.user-card {
+    width: 100%;
+    display: inline-flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+    gap: px2rpx(24);
+    padding-bottom: px2rpx(48);
+
+    .avatar {
+        width: px2rpx(64);
+        height: px2rpx(64);
+        border-radius: 50%;
+        background: #d8d8d8 url("/static/images/avatars.png") center/cover no-repeat;
+        border: 4rpx solid #fff;
+    }
+
+    .phone {
+        color: #1a1a1a;
+        font-family: Roboto;
+        font-size: px2rpx(22);
+        font-style: normal;
+        font-weight: 600;
+        line-height: px2rpx(4);
+    }
+}
+
+.user-info .group {
+    background: var(--action-bg);
+    border-radius: px2rpx(16);
+    margin-top: px2rpx(24);
+    overflow: hidden;
+}
+
+.group-item {
+    display: flex;
+    align-items: center;
+    padding: px2rpx(16) 0;
+    color: #000;
+    font-size: px2rpx(16);
+    /* border-bottom: 2rpx solid var(--action-bg); */
+    position: relative;
+}
+
+.group-item:last-child {
+    border-bottom: none;
+}
+
+svg {
+    width: px2rpx(24);
+    height: px2rpx(24);
+    color: #000;
+    font-size: px2rpx(24);
+}
+
+.group-item .version {
+    margin-left: auto;
+    color: #817f7f;
+    font-size: px2rpx(16);
+}
+
+.item-text {
+    margin-left: px2rpx(12);
+}
+
+.code-dialog {
+    display: flex;
+    justify-content: center;
+    gap: px2rpx(12);
+    padding: px2rpx(16);
+
+    :deep(.u-popup__content) {
+        width: 90% !important;
+    }
+
+    :deep(.u-modal) {
+        width: 100% !important;
+    }
+}
+</style>

+ 30 - 0
pages/mine/help-detail.vue

@@ -0,0 +1,30 @@
+<template>
+    <cwg-page-wrapper class="permission-page">
+
+        <view class="content">
+            <view class="privacy" v-html="problemDetails.answer"></view>
+        </view>
+    </cwg-page-wrapper>
+</template>
+
+<script setup lang="ts">
+import { onLoad } from '@dcloudio/uni-app'
+import { computed } from 'vue'
+import useUserStore from "@/stores/use-user-store";
+const userStore = useUserStore();
+const problemDetails = computed(() => {
+    return userStore.problemDetails;
+});
+</script>
+
+<style lang="scss" scoped>
+@import "@/uni.scss";
+
+.permission-page {
+    min-height: 100vh;
+    background-color: #f5f5f5;
+    padding: px2rpx(12) !important;
+
+    .content {}
+}
+</style>

+ 155 - 0
pages/mine/help.vue

@@ -0,0 +1,155 @@
+<template>
+    <cwg-page-wrapper class="permission-page">
+        <view class="content">
+            <u-collapse :border="false" @close="close" @open="open" class="u-collapses" v-if="treeData.length > 0">
+                <u-collapse-item :border="false" v-for="value in treeData" :title="value.type" :name="value.id"
+                    :key="value.id" :class="value.id !== typeId ? 'u-collapse-items' : 'u-collapse-item'">
+                    <view class="u-collapse-content" v-for="(item, index) in value.children" :key="item.id"
+                        @click="openProblem(item)">
+                        <view class="answer">{{ Number(index) + 1 }}</view>
+                        <view class="question">{{ item.problem }}</view>
+                    </view>
+                </u-collapse-item>
+            </u-collapse>
+            <cwg-empty-state v-if="treeData.length === 0" />
+        </view>
+    </cwg-page-wrapper>
+</template>
+
+<script setup lang="ts">
+import { onLoad } from '@dcloudio/uni-app'
+import { ref, onMounted } from 'vue'
+import { ucardApi } from '@/api/ucard'
+import { useI18n } from "vue-i18n";
+import useUserStore from "@/stores/use-user-store";
+const userStore = useUserStore();
+const { t, locale } = useI18n();
+const list = ref([]);
+const dropdownList = ref([]);
+const treeData = ref([]);
+const typeId = ref(null);
+
+const open = (name) => {
+    typeId.value = name;
+};
+const close = (name) => {
+    typeId.value = null;
+};
+const openProblem = (item) => {
+    userStore.saveProblemDetails(item);
+    uni.navigateTo({
+        url: `/pages/mine/help-detail`
+    });
+};
+const getAppCommonProblemPage = async () => {
+    const res = await ucardApi.getAppCommonProblemPage({ page: { current: 1, row: 100 }, language: locale.value });
+    if (res.code === 200) {
+        list.value = res.data
+    }
+};
+const getAppCommonProblemDropdown = async () => {
+    const res = await ucardApi.getAppCommonProblemDropdown({ language: locale.value });
+    if (res.code === 200) {
+        dropdownList.value = res.data
+    }
+};
+
+// 将数据处理成树形结构
+const buildTreeData = () => {
+    treeData.value = dropdownList.value.map(dropdown => {
+        const children = list.value.filter(item => item.typeId === dropdown.id);
+        if (children.length === 0) return null;
+        return { ...dropdown, children }
+    }).filter(item => item !== null);
+};
+
+const loadData = async () => {
+    await getAppCommonProblemDropdown();
+    await getAppCommonProblemPage();
+    buildTreeData();
+};
+
+onMounted(() => {
+    loadData();
+})
+</script>
+
+<style lang="scss" scoped>
+@import "@/uni.scss";
+
+.permission-page {
+    min-height: 100vh;
+    background: #f5f5f5;
+    padding: px2rpx(12) !important;
+
+    .u-collapses {
+        border-radius: px2rpx(8);
+        overflow: hidden;
+    }
+
+    .u-collapse-item {
+        background: #fff;
+        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+
+        :deep(.u-cell__body) {
+            // background: linear-gradient(90deg, #eb4e6b 0%, #e7afba 100%);
+            background: rgba(208, 37, 55, 0.03);
+            border-radius: px2rpx(8);
+            // color: #fff;
+            transition: all 0.35s cubic-bezier(0.4, 0, 0.2, 1);
+        }
+
+        :deep(.u-collapse-item__content) {
+            border-radius: px2rpx(8);
+            z-index: 3;
+            background: #fff;
+            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+            overflow: hidden;
+        }
+
+        :deep(.u-collapse-item__content__text) {
+            transition: opacity 0.25s ease-in-out;
+        }
+    }
+
+    .u-collapse-items {
+        border-radius: px2rpx(8);
+        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+
+        :deep(.u-cell__body) {
+            background: #fff;
+            border-radius: px2rpx(8);
+            color: #333;
+            transition: all 0.35s cubic-bezier(0.4, 0, 0.2, 1);
+        }
+
+        :deep(.u-collapse-item__content) {
+            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+            overflow: hidden;
+        }
+
+        :deep(.u-collapse-item__content__text) {
+            transition: opacity 0.25s ease-in-out;
+        }
+    }
+
+    .u-collapse-content {
+        display: flex;
+        align-items: center;
+        transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.25s ease-in-out;
+
+        &:active {
+            transform: scale(0.98);
+            opacity: 0.8;
+        }
+
+        .question {
+            flex: 1;
+            padding: px2rpx(16);
+            font-size: px2rpx(16);
+            color: #333;
+        }
+    }
+
+}
+</style>

+ 16 - 66
pages/mine/index.vue

@@ -1,10 +1,15 @@
 <template>
-	<cwg-page-wrapper>
+	<cwg-page-wrapper :isHeaderFixed="true">
 		<view class="page">
+			<cwg-header :title="t('pages.mine.index')">
+				<div class="language-switch" @click="router.push('/pages/mine/cog')">
+					<cwg-icon color="#000" icon="cog-outline" />
+				</div>
+			</cwg-header>
 			<view class="user-card">
 				<view class="avatar"></view>
 				<view class="user-info">
-					<view class="phone">{{ userInfo?.customInfo?.email }}</view>
+					<view class="phone">{{ userInfo?.email }}</view>
 				</view>
 			</view>
 			<view class="group">
@@ -15,85 +20,45 @@
 					<text class="item-text version" v-if="isPersonalInfoCompleted">{{ t("State.ToCertified") }}</text>
 					<cwg-icon color="#000" icon="chevron-right" />
 				</view>
-				<view class="group-item" @click="router.push('/pages/mine/language')">
-					<cwg-icon color="#000" icon="web" />
-					<text class="item-text">{{ t("language.i1") }}</text>
-					<text class="version item-text">{{ t(`language.${lang}`) }}</text>
-					<cwg-icon color="#000" icon="chevron-right" />
-				</view>
 				<view class="group-item" @click="router.push('/pages/apply-record/list')">
-					<cwg-icon color="#000" icon="history" />
+					<cwg-icon color="#000" icon="kksq" />
 					<text class="item-text">{{ t("card.tab15") }}</text>
 					<text class="version item-text"></text>
 					<cwg-icon color="#000" icon="chevron-right" />
 				</view>
 				<view class="group-item" @click="router.push('/pages/wallet/balance')">
-					<cwg-icon color="#000" icon="history" />
+					<cwg-icon color="#000" icon="qbye" />
 					<text class="item-text">{{ t("card.tab17") }}</text>
 					<text class="version item-text"></text>
 					<cwg-icon color="#000" icon="chevron-right" />
 				</view>
-			</view>
-			<view class="group">
-				<view class="group-item" @click="router.push('/pages/mine/pay-password')">
-					<cwg-icon color="#000" icon="lock-reset" />
-					<text class="item-text">{{ t("language.i2") }}</text>
+				<view class="group-item" @click="router.push('/pages/mine/help')">
+					<cwg-icon color="#000" icon="cjwt" />
+					<text class="item-text">{{ t('pages.mine.help') }}</text>
 					<text class="version item-text"></text>
 					<cwg-icon color="#000" icon="chevron-right" />
 				</view>
-			</view>
-			<!-- <view class="group">
-	          <view class="group-item">
-	              <cwg-icon color="#000" icon="information-outline"/>
-	              <text class="item-text">{{ t('language.i5') }}</text>
-	              <text class="version item-text"></text>
-	              <cwg-icon color="#000" icon="chevron-right" />
-	          </view>
-	      </view> -->
-			<view class="group">
-				<view class="group-item" @click="showLogoutPopup = true">
-					<cwg-icon color="#000" icon="logout" />
-					<text class="item-text">{{ t("language.i6") }}</text>
+				<view class="group-item" @click="router.push('/pages/mine/cog')">
+					<cwg-icon color="#000" icon="sz" />
+					<text class="item-text">{{ t('pages.mine.cog') }}</text>
 					<text class="version item-text"></text>
 					<cwg-icon color="#000" icon="chevron-right" />
 				</view>
 			</view>
-			<u-modal class="code-dialog" :show="showLogoutPopup" title="" :show-confirm-button="false"
-				:show-cancel-button="false" :close-on-click-overlay="false">
-				<view class="modal-class">
-					<view class="p1 title">{{ t('mine.logout') }}</view>
-					<view class="p1">{{ t('mine.p') }}</view>
-
-					<view class="cwg-button ok-button">
-						<u-button type="primary" block @click="handleLogout('confirm')">{{
-							t("mine.b1")
-						}}</u-button>
-					</view>
-					<view class="cwg-button no-button">
-						<u-button type="primary" block @click="handleLogout">{{
-							t("mine.b2")
-						}}</u-button>
-					</view>
-				</view>
-			</u-modal>
 		</view>
 	</cwg-page-wrapper>
 
 </template>
 
 <script setup lang="ts">
-import { ref, onMounted, watch, computed } from "vue";
+import { ref, computed } from "vue";
 import { useI18n } from "vue-i18n";
 import useRouter from "@/hooks/useRouter";
-import { userApi } from "@/api/user";
-import { lang } from "@/composables/config";
 import useUserStore from "@/stores/use-user-store";
-import { showToast } from "@/utils/toast";
 const { t } = useI18n();
 const userStore = useUserStore();
 const router = useRouter();
 const userInfo = computed(() => userStore.userInfo);
-
 // 判断是否已完成个人信息认证
 const isPersonalInfoCompleted = computed(() => {
 	if (userInfo?.approveStatus == 2) {
@@ -110,21 +75,6 @@ function openProfile() {
 		router.push('/pages/mine/improve');
 	}
 }
-const showLogoutPopup = ref(false);
-async function handleLogout(action: string) {
-	if (action === "confirm") {
-		try {
-			const res = await userApi.logout();
-			if (res.code === 200) {
-				userStore.clearUserInfo();
-				router.push("/pages/login/index");
-			}
-		} catch (error) {
-			showToast(error.message || "退出登录失败");
-		}
-	}
-	showLogoutPopup.value = false;
-}
 </script>
 
 <style scoped lang="scss">

+ 1 - 0
pages/mine/info.vue

@@ -76,6 +76,7 @@
 </template>
 
 <script setup lang="ts">
+import { onLoad } from '@dcloudio/uni-app'
 import { ref, onMounted, watch, computed, reactive } from "vue";
 import InfoRow from './components/InfoRow.vue';
 import VerificationRow from './components/VerificationRow.vue';

+ 332 - 0
pages/mine/permission.vue

@@ -0,0 +1,332 @@
+<template>
+    <cwg-page-wrapper class="permission-page">
+        <view class="content">
+            <view class="permission-list">
+                <view v-for="item in permissionList" :key="item.key" class="permission-item"
+                    @click="onPermissionClick(item)">
+                    <view class="item-left">
+                        <view class="item-info">
+                            <view class="item-title">{{ item.title }}</view>
+                            <view class="item-desc">{{ item.desc }}
+                                <text class="item-description" v-if="item.description"
+                                    @click.stop="goDetail(item)">《{{ item.description }}》</text>
+                            </view>
+                        </view>
+                    </view>
+
+                    <view class="item-right">
+                        <view :class="['status', item.status]">
+                            {{ item.status }}
+                        </view>
+                        <cwg-icon color="#817f7f" icon="chevron-right" />
+                    </view>
+                </view>
+            </view>
+
+            <view class="tips">
+                <text class="tips-text">
+                    {{ t('mine.p14') }}
+                </text>
+            </view>
+        </view>
+    </cwg-page-wrapper>
+</template>
+
+<script setup lang="ts">
+import { ref, onMounted } from 'vue'
+import { permission } from '@/js_sdk/wa-permission/permission.js'
+import { onLoad } from '@dcloudio/uni-app'
+import useRouter from "@/hooks/useRouter";
+import { useI18n } from "vue-i18n";
+const { t } = useI18n();
+const router = useRouter();
+// #ifdef APP-PLUS
+let isIos = false
+try {
+    isIos = (plus.os.name === "iOS")
+} catch (e) {
+    console.error('检测平台失败:', e)
+}
+// #endif
+
+/* =======================
+ * 权限列表配置(核心)
+ * ======================= */
+const permissionList = ref([
+    // {
+    //     key: 'location',
+    //     title: t('mine.p1'),
+    //     desc: t('mine.p2'),
+    //     icon: 'location',
+    //     iconBg: 'location',
+    //     iosPermission: 'location',
+    //     androidPermission: 'android.permission.ACCESS_FINE_LOCATION',
+    //     status: t('mine.p13'),
+    //     type: 4,
+    //     description: t('mine.p3')
+    // },
+    {
+        key: 'camera',
+        title: t('mine.p4'),
+        desc: t('mine.p5'),
+        icon: 'camera',
+        iconBg: 'camera',
+        iosPermission: 'camera',
+        androidPermission: 'android.permission.CAMERA',
+        status: t('mine.p13'),
+        type: 2,
+        description: t('mine.p6')
+    },
+    // {
+    //     key: 'microphone',
+    //     title: '麦克风',
+    //     desc: '录制音频',
+    //     icon: 'sound',
+    //     iconBg: 'microphone',
+    //     iosPermission: 'record',
+    //     androidPermission: 'android.permission.RECORD_AUDIO',
+    //     status: t('mine.p13')
+    // },
+    {
+        key: 'album',
+        title: t('mine.p7'),
+        desc: t('mine.p8'),
+        icon: 'image',
+        iconBg: 'album',
+        iosPermission: 'photoLibrary',
+        androidPermission: 'android.permission.READ_EXTERNAL_STORAGE',
+        status: t('mine.p13'),
+        type: 3,
+        description: t('mine.p9')
+    },
+    {
+        key: 'clipboard',
+        title: t('mine.p10'),
+        desc: t('mine.p11'),
+        icon: 'list',
+        iconBg: 'clipboard',
+        iosPermission: null,
+        androidPermission: null,
+        status: t('mine.p12'),
+    }
+])
+
+const goDetail = (item: any) => {
+    let type = item.type;
+    console.log(item, 111111);
+
+    router.push({
+        path: "/pages/mine/privacy",
+        query: {
+            type
+        },
+    });
+}
+
+/* =======================
+ * 点击入口 - 检查权限并引导授权
+ * ======================= */
+const onPermissionClick = async (item: any) => {
+    // 粘贴板无需授权,直接提示
+    if (!item.iosPermission && !item.androidPermission) {
+        uni.showToast({
+            title: '该权限无需授权',
+            icon: 'success'
+        })
+        return
+    }
+
+    // #ifdef APP-PLUS
+    permission.gotoAppPermissionSetting()
+    // #endif
+
+    // #ifndef APP-PLUS
+    uni.showToast({
+        title: '当前平台无需授权',
+        icon: 'success'
+    })
+    // #endif
+}
+
+/* =======================
+ * 初始化检查权限 - 遍历所有权限进行检查
+ * ======================= */
+const checkAllPermissions = async () => {
+    // #ifdef APP-PLUS
+    try {
+        for (const item of permissionList.value) {
+            // 粘贴板无需检查
+            if (!item.iosPermission && !item.androidPermission) {
+                item.status = t('mine.p12')
+                continue
+            }
+
+            if (isIos) {
+                // iOS 权限检查
+                const hasPermission = permission.judgeIosPermission(item.iosPermission)
+                item.status = hasPermission ? t('mine.p12') : t('mine.p13')
+                console.log(`${item.title} iOS 初始状态:`, item.status)
+            } else {
+                // Android 权限请求
+                const result = await permission.checkAndroidPermission(item.androidPermission)
+                console.log(`${item.title} Android 权限结果:`, result)
+
+                if (result === 1) {
+                    item.status = t('mine.p12')
+                } else if (result === -1) {
+                    item.status = t('mine.p13')
+                } else {
+                    item.status = t('mine.p13')
+                }
+            }
+        }
+    } catch (error) {
+        console.error('检查权限失败:', error)
+    }
+    // #endif
+
+    // #ifndef APP-PLUS
+    // 非 APP 平台全部标记为已授权
+    permissionList.value.forEach(item => {
+        item.status = t('mine.p12')
+    })
+    // #endif
+}
+onMounted(() => {
+    checkAllPermissions()
+})
+</script>
+
+<style lang="scss" scoped>
+@import "@/uni.scss";
+
+.permission-page {
+    min-height: 100vh;
+    background-color: #f5f5f5;
+    padding: px2rpx(12) !important;
+
+    .content {
+        .permission-list {
+            background-color: #fff;
+            border-radius: px2rpx(16);
+            overflow: hidden;
+
+            .permission-item {
+                display: flex;
+                align-items: center;
+                justify-content: space-between;
+                padding: px2rpx(32) px2rpx(12);
+                border-bottom: 1px solid #f0f0f0;
+
+                &:last-child {
+                    border-bottom: none;
+                }
+
+                &:active {
+                    background-color: #f8f8f8;
+                }
+
+                .item-left {
+                    display: flex;
+                    align-items: center;
+                    flex: 1;
+
+                    .icon-wrapper {
+                        width: px2rpx(44);
+                        height: px2rpx(44);
+                        border-radius: px2rpx(8);
+                        display: flex;
+                        align-items: center;
+                        justify-content: center;
+                        margin-right: px2rpx(24);
+
+                        &.location {
+                            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+                        }
+
+                        &.camera {
+                            background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
+                        }
+
+                        &.microphone {
+                            background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
+                        }
+
+                        &.album {
+                            background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
+                        }
+
+                        &.clipboard {
+                            background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);
+                        }
+                    }
+
+                    .item-info {
+                        flex: 1;
+
+                        .item-title {
+                            font-size: px2rpx(18);
+                            font-weight: 500;
+                            color: #333;
+                            display: block;
+                            margin-bottom: px2rpx(8);
+                        }
+
+                        .item-desc {
+                            font-size: px2rpx(16);
+                            color: #999;
+                            display: block;
+                        }
+
+                        .item-description {
+                            font-size: px2rpx(14);
+                            color: var(--main-yellow);
+                        }
+                    }
+                }
+
+                .item-right {
+                    display: flex;
+                    align-items: center;
+                    gap: px2rpx(4);
+
+                    .status {
+                        font-size: px2rpx(16);
+                        padding: px2rpx(8) px2rpx(12);
+                        border-radius: px2rpx(4);
+
+                        &.未授权 {
+                            color: #999;
+                            background-color: #f5f5f5;
+                        }
+
+                        &.已授权 {
+                            color: #52c41a;
+                            background-color: #f6ffed;
+                        }
+
+                        &.已拒绝 {
+                            color: #ff4d4f;
+                            background-color: #fff1f0;
+                        }
+                    }
+                }
+            }
+        }
+
+        .tips {
+            margin-top: px2rpx(24);
+            padding: px2rpx(24);
+            background-color: #fffbe6;
+            border-radius: px2rpx(16);
+            border: 1px solid #ffe58f;
+
+            .tips-text {
+                font-size: px2rpx(12);
+                color: #d48806;
+                line-height: 1.6;
+            }
+        }
+    }
+}
+</style>

+ 50 - 0
pages/mine/privacy.vue

@@ -0,0 +1,50 @@
+<template>
+    <cwg-page-wrapper class="permission-page" :isHeaderFixed="true">
+        <cwg-header :title="title" :showBack="true" />
+        <view class="content">
+            <view class="privacy" v-html="privacy"></view>
+        </view>
+    </cwg-page-wrapper>
+</template>
+
+<script setup lang="ts">
+import { ref, onMounted, computed } from 'vue'
+import { ucardApi } from '@/api/ucard'
+import { onLoad } from '@dcloudio/uni-app'
+import { useI18n } from "vue-i18n";
+const { t } = useI18n();
+const type = ref(1);
+onLoad((o) => {
+    type.value = o?.type || 1;
+    getPrivacy();
+});
+const titleMap: Record<number, string> = {
+    1: t('mine.p15'),
+    2: t('mine.p16'),
+    3: t('mine.p17'),
+    4: t('mine.p18'),
+};
+const title = computed(() => {
+    return titleMap[type.value]
+});
+const privacy = ref('');
+const getPrivacy = async () => {
+    const res = await ucardApi.getAppPrivacyPolicyPage({ page: { current: 1, row: 10 }, type: type.value });
+    if (res.code === 200) {
+        privacy.value = res.data[0].content;
+    }
+};
+
+</script>
+
+<style lang="scss" scoped>
+@import "@/uni.scss";
+
+.permission-page {
+    min-height: 100vh;
+    background-color: #f5f5f5;
+    padding: px2rpx(12) !important;
+
+    .content {}
+}
+</style>

+ 2 - 2
pages/recharge-record/list.vue

@@ -1,5 +1,5 @@
 <template>
-  <cwg-page-wrapper>
+  <cwg-page-wrapper :isHeaderFixed="true">
     <view class="bank-transaction-page">
       <cwg-header color="#000" :title="pageTitle" />
       <!-- Tabs -->
@@ -14,7 +14,7 @@
         <view :class="['tab-item', { 'tab-active': activeTab === 'transaction' }]" @click="activeTab = 'transaction'">
           <cwg-icon class="icons" name="list" :size="18" :color="activeTab === 'transaction' ? '#ea002a' : '#9ca3af'" />
           <view :class="['tab-text', { 'tab-text-active': activeTab === 'transaction' }]">{{ t('Shop.Index.Transaction')
-            }}</view>
+          }}</view>
           <view v-if="activeTab === 'transaction'" class="tab-indicator" />
         </view>
 

+ 23 - 8
pages/wallet/components/DynamicForm.vue

@@ -30,10 +30,10 @@
                 :placeholder="tDescription(field)" @change="clearFieldValidate(field)" />
               <!-- 下拉选择 -->
               <cwg-input :rulesKey="field.fieldName" :label="tFieldTitle(field)" :required="field.required"
-                :disabled="field.disabled || !!field.fixedValue" v-else-if="field.fieldType === 'select'"
-                v-model:value="form[field.fieldName]" :fkey="field.fieldName" type="select"
+                :disabled="false" v-else-if="field.fieldType === 'select'" v-model:value="form[field.fieldName]"
+                v-model:selectedValueDoc="form[field.fieldName + 'Value']" :fkey="field.fieldName" type="select"
                 :columns="field.availableDtos.map(i => ({ text: i.value, value: i.valueId }))"
-                :placeholder="tDescription(field)" @change="clearFieldValidate(field)" />
+                :placeholder="tDescription(field)" @change="clearFieldValidate(field)" @change1="change11()" />
               <!-- 文件上传 -->
               <template v-else-if="field.fieldType === 'file'">
                 <cwg-input :rulesKey="field.fieldName" :label="tFieldTitle(field)" :required="field.required"
@@ -80,7 +80,7 @@ import { useI18n } from "vue-i18n";
 import { uploadApi } from "@/api/upload";
 import Config from "@/config";
 const { Host00 } = Config;
-const isNoList = ['payoutMethod', 'transferType', 'payoutCurrency', 'transferAmount', 'senderAddress', 'senderDateOfBirth', 'senderCity', 'senderNationality']
+const isNoList = ['payoutMethod', 'transferType', 'payoutCurrency', 'transferAmount', 'senderAddress', 'senderDateOfBirth', 'senderCity', 'senderNationality', 'senderGender']
 
 // props
 const props = defineProps({
@@ -129,6 +129,8 @@ watch(
   form,
   (val) => {
     Object.assign(props.globalForm, val);
+    console.log(val, 22222);
+
   },
   { deep: true, immediate: true }
 );
@@ -190,13 +192,15 @@ watch(
       // 有 fixedValue 时回显
       if (field.fieldType == 'file') {
         props.globalForm[field.fieldName] = field.rfiValueUrl;
+      } else if (field.fieldType == 'select') {
+        // props.globalForm[field.fieldName] = field.rfiValue;
       } else if (field.fixedValue !== undefined && field.fixedValue !== null) {
         props.globalForm[field.fieldName] = field.fixedValue;
       } else if (field.rfiValue !== undefined && field.rfiValue !== null) {
         props.globalForm[field.fieldName] = field.rfiValue;
       } else if (!(field.fieldName in props.globalForm)) {
         // 没有则初始化为空
-        props.globalForm[field.fieldName] = null;
+        props.globalForm[field.fieldName] = undefined;
       }
 
       // 设置校验规则
@@ -248,14 +252,24 @@ const groupedFields = computed(() => {
       groups[key] = groupsMap[key];
     }
   });
-  console.log(groups, 12121212);
-
   return groups;
 });
 
 
 
-const clearFieldValidate = (field) => {
+const clearFieldValidate = (e, field) => {
+  console.log(e, field, 212121);
+
+  nextTick(() => {
+    if (formRef.value && formRef.value.validateField) {
+      formRef.value.validateField(field.fieldName);
+    }
+  });
+};
+const change11 = (e) => {
+  console.log(e, 212121);
+  return
+
   nextTick(() => {
     if (formRef.value && formRef.value.validateField) {
       formRef.value.validateField(field.fieldName);
@@ -263,6 +277,7 @@ const clearFieldValidate = (field) => {
   });
 };
 
+
 // 表单验证方法
 const validateForm = async () => {
   try {

+ 65 - 7
pages/wallet/composable/useOrderFields.ts

@@ -1,31 +1,84 @@
 import { computed, } from 'vue'
 import { useI18n } from 'vue-i18n'
-
+import useCardStore from '@/stores/use-card-store';
 /**
  * 订单字段处理 Composable
  * 将 detailData 中的字段数据转换为分组列表,支持缓存数据立即渲染
  */
 export function useOrderFields(detailData: any) {
     const { t } = useI18n()
+    const cardStore = useCardStore()
 
     /** 1️⃣ 字段解析(一维数组) */
     const fieldList = computed(() => {
         const dt = detailData.value
-        if (!dt || !dt.fieldDtos || !Array.isArray(dt.fieldDtos)) {
+
+        if (!dt) {
             return []
         }
-        return [...dt.fieldDtos]
-            .sort((a, b) => (a.sorting || 0) - (b.sorting || 0))
-            .map(item => {
+
+        // 检查 dt 是否已经加载了数据(通过检查是否有属性)
+        const hasData = Object.keys(dt).length > 0
+
+        if (!hasData) {
+            console.log('数据尚未加载,返回空数组');
+            return []
+        }
+
+        // fieldDtos 存在且不为空数组时使用 fieldDtos
+        if (dt.fieldDtos && Array.isArray(dt.fieldDtos) && dt.fieldDtos.length > 0) {
+            console.log('使用 fieldDtos 分支,数量:', dt.fieldDtos.length);
+            return [...dt.fieldDtos]
+                .sort((a, b) => (a.sorting || 0) - (b.sorting || 0))
+                .map(item => {
+                    const key = Object.keys(dt).find(
+                        k => k.toLowerCase() === item.fieldName.toLowerCase()
+                    )
+                    const i18nKey = `global.fieldName.${item.fieldName}.fieldTitle`
+                    let name = t(i18nKey)
+                    if (name === i18nKey) {
+                        name = item.fieldName
+                    }
+                    let value = key ? dt[key] : item.fixedValue
+                    if (
+                        item.fieldType === 'select' &&
+                        key &&
+                        !['transferType', 'payoutMethod'].includes(key)
+                    ) {
+                        value = dt[key + 'Value'] || value
+                    }
+                    if (item.fieldName === 'transferAmount' && dt.payoutCurrency) {
+                        value = `${value} ${dt.payoutCurrency}`
+                    }
+
+                    return {
+                        name,
+                        value: value ?? '',
+                        type: item.fieldUserType || 'other',
+                        fieldName: item.fieldName,
+                        fieldType: item.fieldType,
+                        options: item.options || null
+                    }
+                })
+        }
+
+        // 使用 globalFieldParams
+        console.log('使用 globalFieldParams 分支');
+        console.log('globalFieldParams:', cardStore.globalFieldParams);
+
+        return cardStore.globalFieldParams
+            .map((item: any) => {
                 const key = Object.keys(dt).find(
-                    k => k.toLowerCase() === item.fieldName.toLowerCase()
+                    k => k === item.fieldName
                 )
+
                 const i18nKey = `global.fieldName.${item.fieldName}.fieldTitle`
                 let name = t(i18nKey)
                 if (name === i18nKey) {
                     name = item.fieldName
                 }
-                let value = key ? dt[key] : item.fixedValue
+                let value = key ? dt[key] : ''
+
                 if (
                     item.fieldType === 'select' &&
                     key &&
@@ -46,6 +99,11 @@ export function useOrderFields(detailData: any) {
                     options: item.options || null
                 }
             })
+            .filter(field => {
+                // 过滤掉 value 为空的字段
+                const val = field.value
+                return val !== '' && val !== null && val !== undefined
+            })
     })
 
     /** 2️⃣ 分组字段(按类型分组) */

+ 5 - 3
pages/wallet/global-detail.vue

@@ -130,7 +130,6 @@ async function reasonsRefusalList() {
     const res = await ucardApi.reasonsRefusalList();
     if (res.code === 200) {
       pickFields(res.data);
-
       getApproveDesc()
     } else {
       uni.$u.toast(res.msg || t("login.msg0"));
@@ -317,11 +316,14 @@ async function getOrderDetail(id: string | number) {
 
 // 页面加载时,先使用缓存数据渲染,然后获取最新数据
 onLoad((e) => {
-  const cachedData = cardStore.detailData
+  const cachedData = cardStore.orderDetail
   if (cachedData) {
     try {
       const clonedData = JSON.parse(JSON.stringify(cachedData))
-      detailData.value = clonedData
+      Object.assign(detailData.value, clonedData)
+      nextTick()
+      console.log(clonedData, detailData.value, 'clonedDataclonedDataclonedDataclonedData');
+
       processComplianceData()
     } catch (error) {
       console.error('加载缓存数据失败:', error)

+ 22 - 25
pages/wallet/global-order.vue

@@ -15,19 +15,21 @@
             </view>
             <view class="form-item">
               <cwg-input :label="t('global.p1')" v-model:value="globalForm.payoutCurrency" fkey="payoutCurrency"
-                type="select" :columns="currencyListSelect" @change="handlePayoutCurrencyChange"
-                :disabled="!currencyList.length" :placeholder="t('global.p1')" />
+                v-model:selectedValueDoc="globalForm['payoutCurrencyValue']" type="select" :columns="currencyListSelect"
+                @change="handlePayoutCurrencyChange" :disabled="!currencyList.length" :placeholder="t('global.p1')" />
             </view>
             <view class="form-item">
               <cwg-input :label="t('global.p2')" v-model:value="globalForm.payType" fkey="payType" type="select"
-                :columns="transferTypeListSelect" @change="handlePayTypeChange"
-                :disabled="!globalForm.payoutCurrency || !transferTypeList.length" :placeholder="t('global.p2')" />
+                v-model:selectedValueDoc="globalForm['transferTypeValue']" :columns="transferTypeListSelect"
+                @change="handlePayTypeChange" :disabled="!globalForm.payoutCurrency || !transferTypeList.length"
+                :placeholder="t('global.p2')" />
             </view>
 
             <view class="form-item" v-if="payoutMethodListSelect.length">
               <cwg-input :label="t('global.p3')" v-model:value="globalForm.payMethod" fkey="payMethod" type="select"
-                :columns="payoutMethodListSelect" @change="handlePayMethodChange"
-                :disabled="!globalForm.payType || !payoutMethodList.length" :placeholder="t('global.p3')" />
+                v-model:selectedValueDoc="globalForm['payoutMethodValue']" :columns="payoutMethodListSelect"
+                @change="handlePayMethodChange" :disabled="!globalForm.payType || !payoutMethodList.length"
+                :placeholder="t('global.p3')" />
             </view>
           </view>
         </template>
@@ -456,14 +458,18 @@ function btnClick() {
 // Function to merge dynamic fields and sender data
 const setData = async (data: any) => {
   const senderData = getSenderData();
+  console.log(senderData, 'senderData');
+
   const mergedFields = await Promise.all(
     data.map(async (field: any) => {
       const { fieldName } = field;
       const key = Object.keys(senderData).find(
-        (k) => k.toLowerCase() === field.fieldName.toLowerCase()
+        (k) => k.toLowerCase() === fieldName.toLowerCase()
       );
       let fixedValue = key ? senderData[key] : field.fixedValue;
-      if (field.fieldName === "receiverBankCity") {
+      console.log(key, fixedValue, 1222222);
+
+      if (fieldName === "receiverBankCity") {
         try {
           const res = await ucardApi.globalQueryBankCities({
             payoutCurrency: businessForm.value.fieldData.payoutCurrency,
@@ -482,7 +488,7 @@ const setData = async (data: any) => {
       }
       // 如果币种为 CNY,且字段是 senderIdType,则从下拉数据中移除 valueId 为 "2" 的选项
       if (
-        field.fieldName === "senderIdType" &&
+        fieldName === "senderIdType" &&
         businessForm.value.fieldData &&
         businessForm.value.fieldData.payoutCurrency === "CNY" &&
         Array.isArray(field.availableDtos)
@@ -499,7 +505,7 @@ const setData = async (data: any) => {
         }
       }
       if (
-        field.fieldName === "senderIdNumber" &&
+        fieldName === "senderIdNumber" &&
         businessForm.value.fieldData &&
         businessForm.value.fieldData.payoutCurrency === "CNY"
       ) {
@@ -508,11 +514,13 @@ const setData = async (data: any) => {
       }
       // Handle select fields
       if (field.fieldType === "select") {
-        let rValue = globalForm.value[fieldName];
+        let rValue = globalForm.value[fieldName] || fixedValue;
         const label = field.availableDtos?.find(
           (item: any) => item.valueId === rValue
-        )?.value ?? null;
-        globalForm.value[fieldName + "Value"] = label ?? fixedValue;
+        ) ?? null;
+        fixedValue = label?.valueId || fixedValue;
+        globalForm.value[fieldName + "Value"] = label?.value ?? null;
+        globalForm.value[fieldName] = fixedValue;
       }
       return { ...field, fixedValue };
     })
@@ -526,18 +534,7 @@ const selectReceiver = (a, isCurrencyChange = false) => {
   const sameCardList = receiverUserList.value.filter(
     (item) => item.receiverBankAccountNumber === cardNumber
   );
-  const receiverFields = [
-    'receiverFirstName', 'receiverLastName', 'receiverNativeFirstName', 'receiverNativeLastName',
-    'receiverBankAccountNumber', 'receiverIdNumber', 'receiverIdType', 'receiverIdTypeValue',
-    'receiverMobileNumber', 'receiverMobileAreaCode', 'receiverBankId', 'receiverBankIdValue',
-    'receiverBankCity', 'receiverBankCityValue', 'receiverBankState', 'receiverBankStateValue',
-    'receiverBankAccountType', 'receiverBankAccountTypeValue', 'receiverBankBranchCode',
-    'receiverGender', 'receiverGenderValue', 'receiverDateOfBirth', 'receiverAddress',
-    'receiverZipCode', 'receiverCity', 'receiverRegion', 'receiverRegionValue',
-    'receiverState', 'receiverStateValue', 'receiverNationality', 'receiverNationalityValue',
-    'receiverOccupation', 'receiverOccupationValue'
-  ];
-
+  const receiverFields = cardStore.globalFieldParams.filter(item => item.fieldUserType === 'receiver' && !['transferType', 'payoutMethod', 'payoutCurrency'].includes(item.fieldName)).map(item => item.fieldName)
   if (!sameCardList.length) {
     receiverFields.forEach(field => {
       globalForm.value[field] = undefined;

+ 16 - 3
pages/wallet/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <cwg-page-wrapper>
+  <cwg-page-wrapper :isHeaderFixed="true">
     <view class="page">
       <cwg-header class="wallet-header" :title="t('wallet1.title')" />
       <view class="wallet-banner">
@@ -38,14 +38,14 @@
         <view class="cwg-button">
           <u-button type="primary" block @click="goToGlobalRemit">{{
             t("global.title1")
-            }}</u-button>
+          }}</u-button>
         </view>
         <view class="trans-header">
           <view class="record-title">{{ t("global.title") }} </view>
 
           <view class="all" @click="goRechargeRecord">{{
             t("card.Status.t22")
-            }}</view>
+          }}</view>
 
         </view>
 
@@ -119,6 +119,18 @@ async function getBalance() {
     });
   } catch (error) { }
 }
+async function getGlobalFieldParams() {
+  try {
+    const res = await ucardApi.getGlobalFieldParams();
+    const sorted = res.data
+      .sort((a, b) => {
+        return (a.sorting || 0) - (b.sorting || 0);
+      }).map((item) => {
+        return { fieldUserType: item.fieldUserType, fieldName: item.fieldName, fieldType: item.fieldType }
+      });
+    cardStore.saveGlobalFieldParams(sorted);
+  } catch (error) { }
+}
 function imageSrc(currency: string) {
   return `/static/images/currency/${currency}.png`;
 }
@@ -206,6 +218,7 @@ onMounted(() => {
   getGlobalCurrenciesDropdown()
   getGlobalOrdersList()
   getBalance();
+  getGlobalFieldParams()
 });
 </script>
 

+ 5 - 0
static/icons/cjwt.svg

@@ -0,0 +1,5 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M19.5 3H4.5C3.67158 3 3 3.67158 3 4.5V19.5C3 20.3285 3.67158 21 4.5 21H19.5C20.3285 21 21 20.3285 21 19.5V4.5C21 3.67158 20.3285 3 19.5 3Z" stroke="#1A1A1A" stroke-width="2" stroke-linejoin="round"/>
+<path d="M12 14.3125V12.3125C13.6568 12.3125 15 10.9693 15 9.3125C15 7.65565 13.6568 6.3125 12 6.3125C10.3432 6.3125 9 7.65565 9 9.3125" stroke="#1A1A1A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M12 18.8125C12.6904 18.8125 13.25 18.2529 13.25 17.5625C13.25 16.8722 12.6904 16.3125 12 16.3125C11.3097 16.3125 10.75 16.8722 10.75 17.5625C10.75 18.2529 11.3097 18.8125 12 18.8125Z" fill="#1A1A1A"/>
+</svg>

+ 1 - 0
static/icons/cog-outline.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12,8A4,4 0 0,1 16,12A4,4 0 0,1 12,16A4,4 0 0,1 8,12A4,4 0 0,1 12,8M12,10A2,2 0 0,0 10,12A2,2 0 0,0 12,14A2,2 0 0,0 14,12A2,2 0 0,0 12,10M10,22C9.75,22 9.54,21.82 9.5,21.58L9.13,18.93C8.5,18.68 7.96,18.34 7.44,17.94L4.95,18.95C4.73,19.03 4.46,18.95 4.34,18.73L2.34,15.27C2.21,15.05 2.27,14.78 2.46,14.63L4.57,12.97L4.5,12L4.57,11L2.46,9.37C2.27,9.22 2.21,8.95 2.34,8.73L4.34,5.27C4.46,5.05 4.73,4.96 4.95,5.05L7.44,6.05C7.96,5.66 8.5,5.32 9.13,5.07L9.5,2.42C9.54,2.18 9.75,2 10,2H14C14.25,2 14.46,2.18 14.5,2.42L14.87,5.07C15.5,5.32 16.04,5.66 16.56,6.05L19.05,5.05C19.27,4.96 19.54,5.05 19.66,5.27L21.66,8.73C21.79,8.95 21.73,9.22 21.54,9.37L19.43,11L19.5,12L19.43,13L21.54,14.63C21.73,14.78 21.79,15.05 21.66,15.27L19.66,18.73C19.54,18.95 19.27,19.04 19.05,18.95L16.56,17.95C16.04,18.34 15.5,18.68 14.87,18.93L14.5,21.58C14.46,21.82 14.25,22 14,22H10M11.25,4L10.88,6.61C9.68,6.86 8.62,7.5 7.85,8.39L5.44,7.35L4.69,8.65L6.8,10.2C6.4,11.37 6.4,12.64 6.8,13.8L4.68,15.36L5.43,16.66L7.86,15.62C8.63,16.5 9.68,17.14 10.87,17.38L11.24,20H12.76L13.13,17.39C14.32,17.14 15.37,16.5 16.14,15.62L18.57,16.66L19.32,15.36L17.2,13.81C17.6,12.64 17.6,11.37 17.2,10.2L19.31,8.65L18.56,7.35L16.15,8.39C15.38,7.5 14.32,6.86 13.12,6.62L12.75,4H11.25Z" /></svg>

+ 8 - 0
static/icons/dqbb.svg

@@ -0,0 +1,8 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M14 20H3.5C2.67158 20 2 19.3285 2 18.5V5.5C2 4.67158 2.67158 4 3.5 4H20.5C21.3285 4 22 4.67158 22 5.5V11.5294" stroke="#1A1A1A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M19.5 20.5V14.5" stroke="#1A1A1A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M17 17L19.5 14.5L22 17" stroke="#1A1A1A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M2 5.5C2 4.67158 2.67158 4 3.5 4H20.5C21.3285 4 22 4.67158 22 5.5V10H2V5.5Z" stroke="#1A1A1A" stroke-width="2"/>
+<path d="M4 7C4 6.44772 4.44772 6 5 6C5.55228 6 6 6.44772 6 7C6 7.55228 5.55228 8 5 8C4.44772 8 4 7.55229 4 7Z" fill="#1A1A1A"/>
+<path d="M7 7C7 6.44772 7.44772 6 8 6C8.55228 6 9 6.44772 9 7C9 7.55228 8.55228 8 8 8C7.44772 8 7 7.55229 7 7Z" fill="#1A1A1A"/>
+</svg>

+ 3 - 0
static/icons/gy.svg

@@ -0,0 +1,3 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M12 17C12.2833 17 12.5208 16.9042 12.7125 16.7125C12.9042 16.5208 13 16.2833 13 16V12C13 11.7167 12.9042 11.4792 12.7125 11.2875C12.5208 11.0958 12.2833 11 12 11C11.7167 11 11.4792 11.0958 11.2875 11.2875C11.0958 11.4792 11 11.7167 11 12V16C11 16.2833 11.0958 16.5208 11.2875 16.7125C11.4792 16.9042 11.7167 17 12 17ZM12 9C12.2833 9 12.5208 8.90417 12.7125 8.7125C12.9042 8.52083 13 8.28333 13 8C13 7.71667 12.9042 7.47917 12.7125 7.2875C12.5208 7.09583 12.2833 7 12 7C11.7167 7 11.4792 7.09583 11.2875 7.2875C11.0958 7.47917 11 7.71667 11 8C11 8.28333 11.0958 8.52083 11.2875 8.7125C11.4792 8.90417 11.7167 9 12 9ZM12 22C10.6167 22 9.31667 21.7375 8.1 21.2125C6.88333 20.6875 5.825 19.975 4.925 19.075C4.025 18.175 3.3125 17.1167 2.7875 15.9C2.2625 14.6833 2 13.3833 2 12C2 10.6167 2.2625 9.31667 2.7875 8.1C3.3125 6.88333 4.025 5.825 4.925 4.925C5.825 4.025 6.88333 3.3125 8.1 2.7875C9.31667 2.2625 10.6167 2 12 2C13.3833 2 14.6833 2.2625 15.9 2.7875C17.1167 3.3125 18.175 4.025 19.075 4.925C19.975 5.825 20.6875 6.88333 21.2125 8.1C21.7375 9.31667 22 10.6167 22 12C22 13.3833 21.7375 14.6833 21.2125 15.9C20.6875 17.1167 19.975 18.175 19.075 19.075C18.175 19.975 17.1167 20.6875 15.9 21.2125C14.6833 21.7375 13.3833 22 12 22ZM12 20C14.2333 20 16.125 19.225 17.675 17.675C19.225 16.125 20 14.2333 20 12C20 9.76667 19.225 7.875 17.675 6.325C16.125 4.775 14.2333 4 12 4C9.76667 4 7.875 4.775 6.325 6.325C4.775 7.875 4 9.76667 4 12C4 14.2333 4.775 16.125 6.325 17.675C7.875 19.225 9.76667 20 12 20Z" fill="#1A1A1A"/>
+</svg>

+ 7 - 0
static/icons/kksq.svg

@@ -0,0 +1,7 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M22 9V4H2V9" stroke="#1A1A1A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M22 9H2V20H22V9Z" stroke="#1A1A1A" stroke-width="2" stroke-linejoin="round"/>
+<path d="M6 14.5H7" stroke="#1A1A1A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M10 14.5H11" stroke="#1A1A1A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M14 14.5H15" stroke="#1A1A1A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>

+ 6 - 0
static/icons/qbye.svg

@@ -0,0 +1,6 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M9.6416 6.78523L16.1978 3L18.3887 6.79473L9.6416 6.78523Z" stroke="#1A1A1A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M3 7.7498C3 7.22512 3.42533 6.7998 3.95 6.7998H21.05C21.5747 6.7998 22 7.22512 22 7.7498V21.0498C22 21.5745 21.5747 21.9998 21.05 21.9998H3.95C3.42533 21.9998 3 21.5745 3 21.0498V7.7498Z" stroke="#1A1A1A" stroke-width="2" stroke-linejoin="round"/>
+<path d="M17.8438 16.7754H22.0001V12.0254H17.8438C16.4666 12.0254 15.3501 13.0887 15.3501 14.4004C15.3501 15.7121 16.4666 16.7754 17.8438 16.7754Z" stroke="#1A1A1A" stroke-width="2" stroke-linejoin="round"/>
+<path d="M22 8.9375V20.3375" stroke="#1A1A1A" stroke-width="1.9" stroke-linecap="round"/>
+</svg>

+ 5 - 0
static/icons/qchc.svg

@@ -0,0 +1,5 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M20 12H4V21H20V12Z" stroke="#1A1A1A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M2 6.5H9V3H15V6.5H22V12H2V6.5Z" stroke="#1A1A1A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M8 16V21" stroke="#1A1A1A" stroke-width="2" stroke-linecap="round"/>
+</svg>

+ 4 - 0
static/icons/sz.svg

@@ -0,0 +1,4 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M17.0002 20.5L22 12L17.0002 3.5H7.0001L2 12L7.0001 20.5H17.0002Z" stroke="#1A1A1A" stroke-width="2" stroke-linejoin="round"/>
+<path d="M12 14.5C13.3807 14.5 14.5 13.3807 14.5 12C14.5 10.6193 13.3807 9.5 12 9.5C10.6193 9.5 9.5 10.6193 9.5 12C9.5 13.3807 10.6193 14.5 12 14.5Z" stroke="#1A1A1A" stroke-width="2" stroke-linejoin="round"/>
+</svg>

+ 5 - 0
static/icons/xgmm.svg

@@ -0,0 +1,5 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M11.4341 12.1493C12.7052 13.397 13.2069 15.2265 12.7485 16.9434C12.2902 18.6602 10.9422 20.0012 9.21625 20.4571C7.4903 20.913 5.6511 20.414 4.39687 19.1495C2.51104 17.2073 2.53801 14.1199 4.45749 12.2105C6.377 10.3012 9.48065 10.2743 11.4332 12.1502L11.4341 12.1493Z" stroke="#1A1A1A" stroke-width="2" stroke-linejoin="round"/>
+<path d="M11.5 12L20 3.5" stroke="#1A1A1A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M15.1523 8.44981L17.8666 11.1498L21.0333 7.9998L18.319 5.2998L15.1523 8.44981Z" stroke="#1A1A1A" stroke-width="2" stroke-linejoin="round"/>
+</svg>

+ 11 - 0
static/icons/xxtz.svg

@@ -0,0 +1,11 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_1012_7841)">
+<path d="M3 19V9C3 5.134 6.134 2 10 2C13.866 2 17 5.134 17 9V19M0 19H20" stroke="#1A1A1A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M10 22C11.3807 22 12.5 20.8807 12.5 19.5V19H7.5V19.5C7.5 20.8807 8.6193 22 10 22Z" stroke="#1A1A1A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+<defs>
+<clipPath id="clip0_1012_7841">
+<rect width="24" height="24" fill="white"/>
+</clipPath>
+</defs>
+</svg>

+ 6 - 0
static/icons/ys.svg

@@ -0,0 +1,6 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M19 2H5C4.44772 2 4 2.44772 4 3V21C4 21.5523 4.44772 22 5 22H19C19.5523 22 20 21.5523 20 21V3C20 2.44772 19.5523 2 19 2Z" stroke="#1A1A1A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M8 2H12.5V10L10.25 8L8 10V2Z" stroke="#1A1A1A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M8 14H13" stroke="#1A1A1A" stroke-width="2" stroke-linecap="round"/>
+<path d="M8 17H16" stroke="#1A1A1A" stroke-width="2" stroke-linecap="round"/>
+</svg>

+ 8 - 0
static/icons/yszc.svg

@@ -0,0 +1,8 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M1 9V4.5C1 3.67158 1.67158 3 2.5 3H17.5C18.3285 3 19 3.67158 19 4.5V9" stroke="#1A1A1A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M8.5 13L14.5 6.5" stroke="#1A1A1A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M11 10.5L13 12.5" stroke="#1A1A1A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M13.5 8L15.5 10" stroke="#1A1A1A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M1 15V19.5C1 20.3285 1.67158 21 2.5 21H17.5C18.3285 21 19 20.3285 19 19.5V15" stroke="#1A1A1A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M7 17.5C8.38071 17.5 9.5 16.3807 9.5 15C9.5 13.6193 8.38071 12.5 7 12.5C5.61929 12.5 4.5 13.6193 4.5 15C4.5 16.3807 5.61929 17.5 7 17.5Z" stroke="#1A1A1A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>

Разница между файлами не показана из-за своего большого размера
+ 10 - 2
static/svg-icons-lib.js


+ 27 - 0
stores/use-card-store.ts

@@ -7,6 +7,7 @@ import crypt from "../composables/crypt";
 const CARD_KEY = "cardList";
 const APPLY_CARD_KEY = "applyList";
 const CURRENCY_LIST_KEY = "currencyList"; // 新增币种列表的本地存储键
+const GLOBAL_FIELD_PARAMS_KEY = "globalFieldParams"; // 新增币种列表的本地存储键
 const ORDER_DETAIL_KEY = "orderDetailEncrypted"; // 订单详情加密缓存键
 
 const useCardStore = defineStore("cardStore", () => {
@@ -16,6 +17,8 @@ const useCardStore = defineStore("cardStore", () => {
 
   // 新增币种列表
   const currencyList = ref([]);
+  // 新增币种列表
+  const globalFieldParams = ref([]);
 
   // 订单详情(使用加密存储)
   const orderDetail = ref<any | null>(null);
@@ -67,6 +70,20 @@ const useCardStore = defineStore("cardStore", () => {
       }
     }
   };
+  // 初始化参数列表(解密)
+  const initGlobalFieldParams = () => {
+    const encryptedDetail = ls.get(GLOBAL_FIELD_PARAMS_KEY);
+    if (encryptedDetail) {
+      const decryptedDetail = crypt.decrypt(encryptedDetail);
+      if (decryptedDetail) {
+        try {
+          globalFieldParams.value = JSON.parse(decryptedDetail);
+        } catch (e) {
+          globalFieldParams.value = null;
+        }
+      }
+    }
+  };
 
   // 保存用户卡
   const saveUserCard = (info: any) => {
@@ -95,6 +112,13 @@ const useCardStore = defineStore("cardStore", () => {
     const encryptedDetail = crypt.encrypt(JSON.stringify(detail));
     ls.set(ORDER_DETAIL_KEY, encryptedDetail);
   };
+  // 保存参数列表(加密)
+  const saveGlobalFieldParams = (params: any) => {
+    globalFieldParams.value = params;
+    const encryptedParams = crypt.encrypt(JSON.stringify(params));
+    ls.set(GLOBAL_FIELD_PARAMS_KEY, encryptedParams);
+  };
+
 
   // 清空订单详情(缓存 + 内存)
   const clearOrderDetail = () => {
@@ -114,16 +138,19 @@ const useCardStore = defineStore("cardStore", () => {
   initApplyCard();
   initCurrencyList();
   initOrderDetail();
+  initGlobalFieldParams();
 
   return {
     userCard,
     applyCard,
     currencyList, // 新增币种列表
     orderDetail, // 订单详情(已解密)
+    globalFieldParams, // 新增参数列表
     saveUserCard,
     saveApplyCard,
     saveCurrencyList, // 新增保存币种列表的操作
     saveOrderDetail, // 保存订单详情(加密)
+    saveGlobalFieldParams, // 新增保存参数列表的操作
     clearOrderDetail, // 清空订单详情
   };
 });

+ 41 - 1
stores/use-user-store.ts

@@ -19,11 +19,15 @@ export interface AccountInfo {
 const STORAGE_KEY = "user";
 const ACCOUNT_INFO_KEY = "accountInfo";
 const ID_TYPE_OPTIONS_KEY = "reasonsOptions";
+const APP_VERSION = 'appVersion'
+const PROBLEM_DETAILS_KEY = "problemDetails";
 const useUserStore = defineStore("userStore", () => {
   const userInfo = ref<UserInfo | null>(null);
   const accountInfo = ref<AccountInfo | null>(null);
   const isLoggedIn = ref(false);
   const reasonsOptions = ref<any>(null);
+  const appVersion = ref<any>(null);
+  const problemDetails = ref<any>(null);
   const initUserInfo = () => {
     const encryptedInfo = ls.get(STORAGE_KEY);
     if (encryptedInfo) {
@@ -34,6 +38,26 @@ const useUserStore = defineStore("userStore", () => {
       }
     }
   };
+  const initAppVersion = () => {
+    const encryptedInfo = ls.get(APP_VERSION);
+    if (encryptedInfo) {
+      const decryptedInfo = crypt.decrypt(encryptedInfo);
+      if (decryptedInfo) {
+        userInfo.value = JSON.parse(decryptedInfo);
+        isLoggedIn.value = true;
+      }
+    }
+  };
+  const initProblemDetails = () => {
+    const encryptedInfo = ls.get(PROBLEM_DETAILS_KEY);
+    if (encryptedInfo) {
+      const decryptedInfo = crypt.decrypt(encryptedInfo);
+      if (decryptedInfo) {
+        problemDetails.value = JSON.parse(decryptedInfo);
+        isLoggedIn.value = true;
+      }
+    }
+  };
   const initReasonsOptions = () => {
     const encryptedInfo = ls.get(ID_TYPE_OPTIONS_KEY);
     if (encryptedInfo) {
@@ -59,6 +83,16 @@ const useUserStore = defineStore("userStore", () => {
     const encryptedInfo = crypt.encrypt(JSON.stringify(info));
     ls.set(STORAGE_KEY, encryptedInfo);
   };
+  const saveProblemDetails = (info: any) => {
+    problemDetails.value = info;
+    const encryptedInfo = crypt.encrypt(JSON.stringify(info));
+    ls.set(PROBLEM_DETAILS_KEY, encryptedInfo);
+  };
+  const saveAppVersion = (info: any) => {
+    appVersion.value = info;
+    const encryptedInfo = crypt.encrypt(JSON.stringify(info));
+    ls.set(APP_VERSION, encryptedInfo);
+  };
   const saveReasonsOptions = (info: any) => {
     reasonsOptions.value = info;
     const encryptedInfo = crypt.encrypt(JSON.stringify(info));
@@ -76,16 +110,22 @@ const useUserStore = defineStore("userStore", () => {
     reasonsOptions.value = null;
     ls.remove(STORAGE_KEY);
   };
+
   initReasonsOptions();
   initUserInfo();
   initAccountInfo();
+  initAppVersion();
+  initProblemDetails();
   return {
     userInfo,
     accountInfo,
     isLoggedIn,
     reasonsOptions,
+    appVersion,
+    problemDetails,
+    saveProblemDetails,
+    saveAppVersion,
     saveReasonsOptions,
-    initReasonsOptions,
     saveUserInfo,
     saveAccountInfo,
     clearUserInfo,

Некоторые файлы не были показаны из-за большого количества измененных файлов