zhb 1 месяц назад
Родитель
Сommit
4cd9a161ab

+ 2 - 2
components/cwg-complex-search.vue

@@ -13,7 +13,7 @@
                             </template>
                             </template>
                             <template v-else-if="field.type === 'select'">
                             <template v-else-if="field.type === 'select'">
                                 <cwg-combox v-model:value="formData[field.key]" :options="field.options"
                                 <cwg-combox v-model:value="formData[field.key]" :options="field.options"
-                                    :placeholder="field.placeholder || '请选择'" clearable @change="handleSearch" />
+                                    :placeholder="field.placeholder || '请选择'" :clearable="false" @change="handleSearch" />
                             </template>
                             </template>
                             <template v-else-if="field.type === 'date'">
                             <template v-else-if="field.type === 'date'">
                                 <uni-datetime-picker v-model="formData[field.key]" type="date"
                                 <uni-datetime-picker v-model="formData[field.key]" type="date"
@@ -77,7 +77,7 @@
                         </template>
                         </template>
                         <template v-else-if="field.type === 'select'">
                         <template v-else-if="field.type === 'select'">
                             <uni-data-select v-model:value="tempFormData[field.key]" :localdata="field.options"
                             <uni-data-select v-model:value="tempFormData[field.key]" :localdata="field.options"
-                                :placeholder="field.placeholder || '请选择'" clearable v-if="shouldUseSelect(field)" />
+                                :placeholder="field.placeholder || '请选择'" :clearable="false" v-if="shouldUseSelect(field)" />
                             <view class="chip-group" v-else>
                             <view class="chip-group" v-else>
                                 <view class="chip-list">
                                 <view class="chip-list">
                                     <view v-for="opt in field.options" :key="opt.value" class="chip" :class="{
                                     <view v-for="opt in field.options" :key="opt.value" class="chip" :class="{

+ 8 - 5
composables/useAccountOptions.js

@@ -1,11 +1,12 @@
-import { ref, onMounted } from 'vue'
+import { ref, onMounted, computed } from 'vue'
 import { customApi } from '@/service/custom'
 import { customApi } from '@/service/custom'
 import Config from '@/config/index'
 import Config from '@/config/index'
 const { Code } = Config
 const { Code } = Config
+import useUserStore from '@/stores/use-user-store'
 
 
 export function useAccountOptions() {
 export function useAccountOptions() {
+    const { loginOptions, saveLoginOptions } = useUserStore()
     // 响应式数据
     // 响应式数据
-    const loginOptions = ref([])
     const isLoaded = ref(false)
     const isLoaded = ref(false)
     // 获取账户列表(核心方法)
     // 获取账户列表(核心方法)
     const getDateList = async () => {
     const getDateList = async () => {
@@ -14,12 +15,12 @@ export function useAccountOptions() {
             const res = await customApi.CustomDropdown({ platform: '' })
             const res = await customApi.CustomDropdown({ platform: '' })
             if (res.code === Code.StatusOK) {
             if (res.code === Code.StatusOK) {
                 // 格式化下拉选项
                 // 格式化下拉选项
-                loginOptions.value = res.data.map(item => ({
+                const loginOptions = res.data.map(item => ({
                     ...item,
                     ...item,
                     value: item.login,
                     value: item.login,
                     text: item.login
                     text: item.login
                 }))
                 }))
-
+                saveLoginOptions(loginOptions)
             } else {
             } else {
                 uni.showToast({
                 uni.showToast({
                     title: res.msg || '获取账户失败',
                     title: res.msg || '获取账户失败',
@@ -40,7 +41,9 @@ export function useAccountOptions() {
     }
     }
     // ✨ 自动执行(页面挂载后自动调用)
     // ✨ 自动执行(页面挂载后自动调用)
     onMounted(() => {
     onMounted(() => {
-        getDateList()
+        if (!loginOptions || loginOptions.length === 0) {
+            getDateList()
+        }
     })
     })
     return {
     return {
         loginOptions,
         loginOptions,

+ 6 - 6
composables/useMenuSplit.ts

@@ -205,12 +205,12 @@ export function useMenuSplit() {
             children: [
             children: [
                 { path: '/pages/analytics/analystViews', label: 'News.Announcement', icon: 'icon-application' },
                 { path: '/pages/analytics/analystViews', label: 'News.Announcement', icon: 'icon-application' },
                 { path: '/pages/analytics/news', label: 'News.NewsInformation', icon: 'icon-application' },
                 { path: '/pages/analytics/news', label: 'News.NewsInformation', icon: 'icon-application' },
-                {
-                    path: `https://www.${host}.com/${locale.value}/economic-calendar`,
-                    label: 'News.FinancialCalendar',
-                    icon: 'icon-application',
-                    isExternal: true,
-                },
+                // {
+                //     path: `https://www.${host}.com/${locale.value}/economic-calendar`,
+                //     label: 'News.FinancialCalendar',
+                //     icon: 'icon-application',
+                //     isExternal: true,
+                // },
             ],
             ],
         },
         },
         {
         {

+ 14 - 1
pages/customer/components/TerminalChangePasswordDialog.vue

@@ -31,7 +31,7 @@
 </template>
 </template>
 
 
 <script setup>
 <script setup>
-import { ref, computed } from 'vue'
+import { ref, computed, watch } from 'vue'
 import { customApi } from '@/service/custom';
 import { customApi } from '@/service/custom';
 import { useI18n } from 'vue-i18n'
 import { useI18n } from 'vue-i18n'
 import { showToast } from "@/utils/toast";
 import { showToast } from "@/utils/toast";
@@ -84,6 +84,10 @@ const noticeItems = computed(() => [
 const flag = ref(false); // 防止重复提交
 const flag = ref(false); // 防止重复提交
 
 
 const save = async () => {
 const save = async () => {
+    if (!/^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[~!@&%$^*./\\(\\)\\+\\=#_-])[A-Za-z0-9~!@&%$^*./\\(\\)\\+\\=#_-]{8,16}$/.test(passwordInfo.value.oldPassword)) {
+        showToast(t('vaildate.password.format'));
+        return;
+    }
     if (!rule1.value || !rule2.value || !rule4.value) {
     if (!rule1.value || !rule2.value || !rule4.value) {
         return;
         return;
     }
     }
@@ -125,6 +129,15 @@ const save = async () => {
         flag.value = false;
         flag.value = false;
     }
     }
 }
 }
+watch(() => props.visible, (newVal) => {
+    if (newVal) {
+        passwordInfo.value = {
+            oldPassword: '',
+            newPassword: ''
+        }
+        flag.value = false;
+    }
+})
 </script>
 </script>
 
 
 <style scoped lang="scss">
 <style scoped lang="scss">

+ 0 - 184
pages/customer/components/TerminalNickNameDialog copy.vue

@@ -1,184 +0,0 @@
-<template>
-    <cwg-popup :title="'账户昵称'" :visible="props.visible" :showFooters="false"
-        @update:visible="$emit('update:visible', $event)">
-        <view class="popup-content">
-            <text class="account-number">{{ accountLabel }} {{ account.login }}</text>
-            <text class="account-hint">{{ hint }}</text>
-
-            <view class="form-item">
-                <view class="input-label">账户昵称</view>
-                <input class="input-field" v-model="nickName" :maxlength="36" :placeholder="placeholder"
-                    @input="onInput" />
-                <text class="input-hint">{{ constraint }}</text>
-            </view>
-            <view class="save-btn">
-                <view class="btn primary" @click="save" :disabled="!isValid || !nickName.trim()" v-t="'Btn.Save'" />
-            </view>
-        </view>
-    </cwg-popup>
-</template>
-
-<script setup>
-import { ref, computed, onMounted } from 'vue'
-import { customApi } from '@/service/custom';
-import { useI18n } from 'vue-i18n'
-const { t, locale } = useI18n()
-const props = defineProps({
-    visible: { type: Boolean, default: false },
-    // 账户编号
-    account: { type: Object, default: {} },
-    // 标题
-    title: { type: String, default: '账户昵称' },
-    // 账户标签前缀
-    accountLabel: { type: String, default: '账户: #' },
-    // 提示文字
-    hint: { type: String, default: '为账户定制名称,以便快速查找。' },
-    // 输入框占位符
-    placeholder: { type: String, default: '为账户定制名称,以便快速查找。' },
-    // 特殊字符限制说明
-    constraint: { type: String, default: '昵称不可包含特殊字符:< > " \' & ? ^ * # @' }
-})
-const emit = defineEmits(['update:visible', 'save'])
-
-const nickName = ref(props.account.nickName)
-
-// 特殊字符正则
-const specialCharsRegex = /[<>"\'&?^*#@]/
-
-// 校验昵称是否合法
-const isValid = computed(() => {
-    if (!nickName.value) return false
-    return !specialCharsRegex.test(nickName.value)
-})
-
-// 输入时实时校验(可选,可去掉)
-const onInput = (e) => {
-    // 实时过滤非法字符(也可以只是校验)
-}
-// 保存昵称
-const save = async () => {
-    if (!isValid.value) {
-        uni.showToast({
-            title: '昵称包含非法字符,请重新输入',
-            icon: 'none'
-        })
-        return
-    }
-    const nickname = nickName.value.trim()
-    if (!nickname) {
-        uni.showToast({
-            title: '昵称不能为空',
-            icon: 'none'
-        })
-        return
-    }
-    const res = await customApi.updateNick({ nickName: nickname, login: props.account.login })
-    if (res.code == 200) {
-        emit('update:visible', false)
-        emit('save', nickname)
-    }
-}
-</script>
-
-<style scoped lang="scss">
-@import "@/uni.scss";
-
-@media (min-width: 768px) {
-    :deep(.cwg-dialog) {
-        background-color: var(--color-white);
-        border-radius: px2rpx(8);
-        width: px2rpx(480) !important;
-    }
-}
-
-.popup-content {
-    padding: px2rpx(16);
-}
-
-.account-number {
-    display: block;
-    font-size: px2rpx(14);
-    color: #141d22;
-    margin-bottom: px2rpx(40);
-}
-
-.account-hint {
-    display: block;
-    font-size: px2rpx(13);
-    color: #141d22;
-    margin-bottom: px2rpx(40);
-}
-
-.form-item {
-    margin-bottom: px2rpx(20);
-}
-
-.input-label {
-    font-size: px2rpx(12);
-    color: #141d22;
-    margin-bottom: px2rpx(4);
-}
-
-.input-field {
-    width: 100%;
-    height: px2rpx(40);
-    border: 1px solid #ddd;
-    border-radius: px2rpx(6);
-    padding: 0 px2rpx(12);
-    font-size: px2rpx(14);
-    box-sizing: border-box;
-}
-
-.input-hint {
-    display: block;
-    font-size: px2rpx(11);
-    color: #999;
-    margin-top: px2rpx(6);
-    line-height: 1.4;
-}
-
-.save-btn {
-    width: 100%;
-    height: px2rpx(40);
-    color: #fff;
-    border-radius: px2rpx(8);
-    font-size: px2rpx(16);
-    font-weight: 500;
-    display: flex;
-    justify-content: flex-end;
-
-    border: none;
-
-
-    .btn {
-        background: transparent;
-        border: 1px solid rgba(108, 133, 149, 0);
-        border-radius: px2rpx(8);
-        padding: px2rpx(8) px2rpx(20);
-        font-size: px2rpx(14);
-        color: #2e3a47;
-        display: inline-flex;
-        align-items: center;
-        justify-content: center;
-        gap: px2rpx(8);
-        cursor: pointer;
-        transition: all 0.2s;
-        height: px2rpx(40);
-        box-sizing: border-box;
-        background-color: rgba(108, 133, 149, 0.08);
-
-        &.primary {
-            background-color: var(--color-navy-700);
-            color: #fff;
-
-            svg {
-                stroke: #fff;
-            }
-
-            &:hover {
-                background-color: var(--color-navy-600);
-            }
-        }
-    }
-}
-</style>

+ 50 - 14
pages/customer/deposit.vue

@@ -7,7 +7,7 @@
                 <view class="b-card">
                 <view class="b-card">
                     <view class="card-top">
                     <view class="card-top">
                         <text class="tit"><text class="iconfont icon-caret-right"></text>{{ t('Custom.Deposit.Title1')
                         <text class="tit"><text class="iconfont icon-caret-right"></text>{{ t('Custom.Deposit.Title1')
-                        }}</text>
+                            }}</text>
                         <cwg-combox :clearable="false" v-model:value="loginValue" :options="loginComboxOptions"
                         <cwg-combox :clearable="false" v-model:value="loginValue" :options="loginComboxOptions"
                             :placeholder="t('placeholder.choose')" />
                             :placeholder="t('placeholder.choose')" />
                     </view>
                     </view>
@@ -18,10 +18,11 @@
                 <view class="b-card">
                 <view class="b-card">
                     <view class="card-top">
                     <view class="card-top">
                         <text class="tit"><text class="iconfont icon-caret-right"></text>{{ t('Custom.Deposit.Title2')
                         <text class="tit"><text class="iconfont icon-caret-right"></text>{{ t('Custom.Deposit.Title2')
-                        }}</text>
-                        <view v-for="(group, index) in sortedTableData" :key="index">
-                            <view class="channelType" v-if="group.length" v-t="groupTitleMap[group[0].type]" />
-                            <PaymentMethodsList :list="group" @select="isShowStep3" />
+                            }}</text>
+                        <cwg-asset-tabs v-if="tabsConfig.length > 0" v-model="activeTab" :tabs="tabsConfig" />
+                        <uni-loading v-if="currentTableData.length == 0" />
+                        <view v-if="currentTableData.length">
+                            <PaymentMethodsList :list="currentTableData" @select="isShowStep3" />
                         </view>
                         </view>
                         <view v-if="step3" class="reselect-btn">
                         <view v-if="step3" class="reselect-btn">
                             <button class="s-btn reselect" type="primary" @click="showTable">{{
                             <button class="s-btn reselect" type="primary" @click="showTable">{{
@@ -40,13 +41,13 @@
                             <view class="tips" v-if="(introduce.introduce || introduce.enIntroduce)">
                             <view class="tips" v-if="(introduce.introduce || introduce.enIntroduce)">
                                 <view>
                                 <view>
                                     <rich-text class="attention"
                                     <rich-text class="attention"
-                                        :nodes="(locale === 'cn' || locale === 'zhHant') ? introduce.introduce : introduce.enIntroduce"></rich-text>
+                                        :nodes="isZh ? introduce.introduce : introduce.enIntroduce"></rich-text>
 
 
                                 </view>
                                 </view>
                             </view>
                             </view>
                             <view class="btn-bottom">
                             <view class="btn-bottom">
                                 <text class="btn crm-cursor" @click="isStep3Open()">{{ t('Btn.Confirm')
                                 <text class="btn crm-cursor" @click="isStep3Open()">{{ t('Btn.Confirm')
-                                    }}</text>
+                                }}</text>
                             </view>
                             </view>
 
 
                         </view>
                         </view>
@@ -84,7 +85,7 @@
                                     <uni-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
                                     <uni-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
                                         <text class="tit"><text class="iconfont icon-caret-right"></text>{{
                                         <text class="tit"><text class="iconfont icon-caret-right"></text>{{
                                             t('news_add_field.Label.Title4')
                                             t('news_add_field.Label.Title4')
-                                            }}</text>
+                                        }}</text>
                                     </uni-col>
                                     </uni-col>
                                     <uni-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
                                     <uni-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
                                         <uni-forms-item>
                                         <uni-forms-item>
@@ -116,7 +117,7 @@
                                                         WireTransferAccount.bankUname || '--'
                                                         WireTransferAccount.bankUname || '--'
                                                     }}</text></view>
                                                     }}</text></view>
                                             <view class="row"><text class="label">{{ t('Custom.Deposit.bankName')
                                             <view class="row"><text class="label">{{ t('Custom.Deposit.bankName')
-                                                    }}</text><text class="content">{{ WireTransferAccount.bankName ||
+                                            }}</text><text class="content">{{ WireTransferAccount.bankName ||
                                                         '--'
                                                         '--'
                                                     }}</text></view>
                                                     }}</text></view>
                                             <view class="row"><text class="label SpecialColor">{{
                                             <view class="row"><text class="label SpecialColor">{{
@@ -125,7 +126,7 @@
                                                         WireTransferAccount.bankCardNum || '--'
                                                         WireTransferAccount.bankCardNum || '--'
                                                     }}</text></view>
                                                     }}</text></view>
                                             <view class="row"><text class="label">{{ t('Custom.Deposit.bankAddr')
                                             <view class="row"><text class="label">{{ t('Custom.Deposit.bankAddr')
-                                                    }}</text><text class="content">{{ WireTransferAccount.bankAddr ||
+                                            }}</text><text class="content">{{ WireTransferAccount.bankAddr ||
                                                         '--'
                                                         '--'
                                                     }}</text></view>
                                                     }}</text></view>
                                             <view class="row"><text class="label SpecialColor">{{
                                             <view class="row"><text class="label SpecialColor">{{
@@ -134,7 +135,7 @@
                                                         WireTransferAccount.swiftCode || '--'
                                                         WireTransferAccount.swiftCode || '--'
                                                     }}</text></view>
                                                     }}</text></view>
                                             <view class="row"><text class="label">{{ t('Custom.Deposit.bankCode')
                                             <view class="row"><text class="label">{{ t('Custom.Deposit.bankCode')
-                                                    }}</text><text class="content">{{ WireTransferAccount.bankCode ||
+                                            }}</text><text class="content">{{ WireTransferAccount.bankCode ||
                                                         '--'
                                                         '--'
                                                     }}</text></view>
                                                     }}</text></view>
                                             <view class="row"><text class="label SpecialColor">{{
                                             <view class="row"><text class="label SpecialColor">{{
@@ -161,7 +162,7 @@
                                                         + '-' +
                                                         + '-' +
                                                         WireTransferAccount.type }}</text></view>
                                                         WireTransferAccount.type }}</text></view>
                                             <view class="row"><text class="label">{{ t('Custom.Withdraw.Title6')
                                             <view class="row"><text class="label">{{ t('Custom.Withdraw.Title6')
-                                                    }}</text><text class="content">{{ WireTransferAccount.address ||
+                                            }}</text><text class="content">{{ WireTransferAccount.address ||
                                                         '--'
                                                         '--'
                                                     }}</text></view>
                                                     }}</text></view>
                                             <view class="row"><text class="label">QR Code</text>
                                             <view class="row"><text class="label">QR Code</text>
@@ -263,7 +264,7 @@
                                                     <text>{{ t('news_add_field1.activitiesNZ.itemDeposit2') }}</text>
                                                     <text>{{ t('news_add_field1.activitiesNZ.itemDeposit2') }}</text>
                                                     <text class="clause crm-cursor" @click="dialogClauseNZ = true">{{
                                                     <text class="clause crm-cursor" @click="dialogClauseNZ = true">{{
                                                         t('news_add_field1.activitiesNZ.itemDeposit3')
                                                         t('news_add_field1.activitiesNZ.itemDeposit3')
-                                                    }}</text>
+                                                        }}</text>
                                                     <text>{{ t('news_add_field1.activitiesNZ.itemDeposit4') }}</text>
                                                     <text>{{ t('news_add_field1.activitiesNZ.itemDeposit4') }}</text>
                                                 </view>
                                                 </view>
                                             </uni-forms-item>
                                             </uni-forms-item>
@@ -465,7 +466,7 @@ const handleFileUpdate = (val, type) => {
         params.requiteVoucherUrl = val
         params.requiteVoucherUrl = val
     }
     }
 }
 }
-
+const isZh = computed(() => ['cn', 'zhHant'].includes(locale.value))
 function isPdf(url, image) {
 function isPdf(url, image) {
     let res = !!url
     let res = !!url
     if (image) {
     if (image) {
@@ -546,6 +547,41 @@ const tableData = reactive({
     Electronic_Wallet: [],
     Electronic_Wallet: [],
     Ucard_Wallet: []
     Ucard_Wallet: []
 })
 })
+//通道table-选择前后
+const activeTab = ref(1)
+// 🔥 自动过滤掉空数据的 tab
+const tabsConfig = computed(() => {
+    const allTabs = [
+        { text: t('Custom.Deposit.Channel3'), value: 1, type: 'Digital_Currency' },
+        { text: t('Custom.Deposit.Channel2'), value: 2, type: 'China_UnionPay' },
+        { text: t('Custom.Deposit.Channel4'), value: 3, type: 'Electronic_Wallet' },
+        { text: t('Custom.Deposit.Channel1'), value: 4, type: 'International_Transfer' },
+        { text: t('card.title'), value: 5, type: 'Ucard_Wallet' },
+    ]
+    // ✅ 只保留有数据的 tab
+    return allTabs.filter(tab => {
+        console.log(tableData[tab.type], tab.type);
+        return tableData[tab.type]?.length > 0
+    })
+})
+// 当前选中的 tab 项
+const currentTab = computed(() => tabsConfig.value.find(t => t.value === activeTab.value))
+
+// 当前要渲染的表格数据
+const currentTableData = computed(() => {
+    const type = currentTab.value?.type
+    return type ? tableData[type] || [] : []
+})
+// ✅ 监听 tab 变化,自动选中第一个有数据的 tab
+watch(
+    tabsConfig,
+    (newTabs) => {
+        if (newTabs.length > 0) {
+            activeTab.value = newTabs[0].value // 选中第一个
+        }
+    },
+    { immediate: true }
+)
 const bankDate = ref([])
 const bankDate = ref([])
 const channelData = reactive({})
 const channelData = reactive({})
 const WireTransferAccount = reactive({})
 const WireTransferAccount = reactive({})

+ 2 - 0
pages/customer/index.vue

@@ -14,4 +14,6 @@ import AccountList from './components/AccountList.vue';
 import TransactionCharts from './components/TransactionCharts.vue';
 import TransactionCharts from './components/TransactionCharts.vue';
 import ActivitiesSwiper from './components/ActivitiesSwiper.vue';
 import ActivitiesSwiper from './components/ActivitiesSwiper.vue';
 import Timeline from './components/Timeline.vue';
 import Timeline from './components/Timeline.vue';
+import { useAccountOptions } from '@/composables/useAccountOptions'
+useAccountOptions()
 </script>
 </script>

+ 7 - 7
pages/customer/payment-history.vue

@@ -4,7 +4,7 @@
         <view class="info-card">
         <view class="info-card">
             <cwg-complex-search :fields="filterFields" v-model="searchParams" @search="handleSearch"
             <cwg-complex-search :fields="filterFields" v-model="searchParams" @search="handleSearch"
                 @reset="handleReset" />
                 @reset="handleReset" />
-            <cwg-tabel ref="tableRef" :columns="columns" :immediate="false":mobilePrimaryFields="mobilePrimaryFields"
+            <cwg-tabel ref="tableRef" :columns="columns" :immediate="false" :mobilePrimaryFields="mobilePrimaryFields"
                 :queryParams="search" :api="listApi" :show-operation="false" :showPagination="false">
                 :queryParams="search" :api="listApi" :show-operation="false" :showPagination="false">
                 <template #avatar="{ row }">
                 <template #avatar="{ row }">
                     <image :src="row.avatar" class="avatar" mode="widthFix" />
                     <image :src="row.avatar" class="avatar" mode="widthFix" />
@@ -122,7 +122,7 @@ const { t, locale } = useI18n();
 import { financialApi } from '@/service/financial';
 import { financialApi } from '@/service/financial';
 import { useConfirm } from '@/hooks/useConfirm'
 import { useConfirm } from '@/hooks/useConfirm'
 import { useAccountOptions } from '@/composables/useAccountOptions'
 import { useAccountOptions } from '@/composables/useAccountOptions'
-const { loginOptions, isLoaded } = useAccountOptions()
+const { loginOptions } = useAccountOptions()
 const search = ref({})
 const search = ref({})
 const typeMap = computed(() => ([
 const typeMap = computed(() => ([
     { value: null, text: t('Custom.PaymentHistory.All') },
     { value: null, text: t('Custom.PaymentHistory.All') },
@@ -236,7 +236,7 @@ const filterFields = computed(() => [
     {
     {
         key: 'orderStatus', type: 'select', label: t('Custom.PaymentHistory.Status'), placeholder: t('placeholder.choose'), options: orderStatusMap.value, defaultValue: null
         key: 'orderStatus', type: 'select', label: t('Custom.PaymentHistory.Status'), placeholder: t('placeholder.choose'), options: orderStatusMap.value, defaultValue: null
     },
     },
-    isLoaded.value && { key: 'login', type: 'select', label: t('Custom.PaymentHistory.TradingAccount'), placeholder: t('placeholder.login'), options: loginOptions.value || [] },
+    { key: 'login', type: 'select', label: t('Custom.PaymentHistory.TradingAccount'), placeholder: t('placeholder.login'), options: loginOptions || [] },
     { key: 'date', label: t('placeholder.Start') + ' - ' + t('placeholder.End'), type: 'daterange' }
     { key: 'date', label: t('placeholder.Start') + ' - ' + t('placeholder.End'), type: 'daterange' }
 ])
 ])
 
 
@@ -244,8 +244,8 @@ const searchParams = ref({})
 
 
 const handleSearch = (params) => {
 const handleSearch = (params) => {
     search.value = params
     search.value = params
-    search.value.platform = loginOptions.value.find(item => item.value === params.login)?.platform || ''
-    if(!search.value.platform) return
+    search.value.platform = loginOptions.find(item => item.value === params.login)?.platform || ''
+    if (!search.value.platform) return
     nextTick(() => {
     nextTick(() => {
         tableRef.value.refreshTable()
         tableRef.value.refreshTable()
     })
     })
@@ -253,8 +253,8 @@ const handleSearch = (params) => {
 
 
 const handleReset = (params) => {
 const handleReset = (params) => {
     search.value = params
     search.value = params
-    search.value.platform = loginOptions.value.find(item => item.value === params.login)?.platform || ''
-    if(!search.value.platform) return
+    search.value.platform = loginOptions.find(item => item.value === params.login)?.platform || ''
+    if (!search.value.platform) return
     nextTick(() => {
     nextTick(() => {
         tableRef.value.refreshTable()
         tableRef.value.refreshTable()
     })
     })

+ 0 - 7
pages/customer/recording-history.vue

@@ -35,8 +35,6 @@ import { computed, ref, nextTick } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useI18n } from 'vue-i18n';
 const { t, locale } = useI18n();
 const { t, locale } = useI18n();
 import { customApi } from '@/service/custom';
 import { customApi } from '@/service/custom';
-import { useAccountOptions } from '@/composables/useAccountOptions'
-const { loginOptions, isLoaded } = useAccountOptions()
 import useUserStore from "@/stores/use-user-store";
 import useUserStore from "@/stores/use-user-store";
 const userStore = useUserStore();
 const userStore = useUserStore();
 const userInfo = computed(() => userStore.userInfo);
 const userInfo = computed(() => userStore.userInfo);
@@ -244,15 +242,12 @@ const getColumnsByType = (type: number) => {
 // 动态传入筛选字段配置
 // 动态传入筛选字段配置
 const filterFields = computed(() => [
 const filterFields = computed(() => [
     { key: 'type', type: 'select', label: t('Custom.PaymentHistory.payType'), placeholder: t('placeholder.choose'), options: typeMap.value, defaultValue: 1 },
     { key: 'type', type: 'select', label: t('Custom.PaymentHistory.payType'), placeholder: t('placeholder.choose'), options: typeMap.value, defaultValue: 1 },
-    isLoaded.value && { key: 'login', type: 'select', label: t('Custom.PaymentHistory.TradingAccount'), placeholder: t('placeholder.login'), options: loginOptions.value || [] },
     { key: 'date', label: t('placeholder.Start') + ' - ' + t('placeholder.End'), type: 'daterange' }
     { key: 'date', label: t('placeholder.Start') + ' - ' + t('placeholder.End'), type: 'daterange' }
 ])
 ])
 const searchParams = ref({})
 const searchParams = ref({})
 const tableRef = ref(null)
 const tableRef = ref(null)
 const handleSearch = (params) => {
 const handleSearch = (params) => {
     search.value = params
     search.value = params
-    search.value.platform = loginOptions.value.find(item => item.value === params.login)?.platform || ''
-    if(!search.value.platform) return
     nextTick(() => {
     nextTick(() => {
         tableRef.value.refreshTable()
         tableRef.value.refreshTable()
     })
     })
@@ -260,8 +255,6 @@ const handleSearch = (params) => {
 
 
 const handleReset = (params) => {
 const handleReset = (params) => {
     search.value = params
     search.value = params
-    search.value.platform = loginOptions.value.find(item => item.value === params.login)?.platform || ''
-    if(!search.value.platform) return
     nextTick(() => {
     nextTick(() => {
         tableRef.value.refreshTable()
         tableRef.value.refreshTable()
     })
     })

+ 4 - 4
pages/customer/trade-history.vue

@@ -33,7 +33,7 @@ import { useI18n } from 'vue-i18n';
 const { t, locale } = useI18n();
 const { t, locale } = useI18n();
 import { customApi } from '@/service/custom';
 import { customApi } from '@/service/custom';
 import { useAccountOptions } from '@/composables/useAccountOptions'
 import { useAccountOptions } from '@/composables/useAccountOptions'
-const { loginOptions, isLoaded } = useAccountOptions()
+const { loginOptions } = useAccountOptions()
 const search = ref()
 const search = ref()
 const typeMap = computed(() => ([
 const typeMap = computed(() => ([
     { value: null, text: t('Custom.PaymentHistory.All') },
     { value: null, text: t('Custom.PaymentHistory.All') },
@@ -136,14 +136,14 @@ const mobilePrimaryFields = computed(() => [
 
 
 // 动态传入筛选字段配置
 // 动态传入筛选字段配置
 const filterFields = computed(() => [
 const filterFields = computed(() => [
-    isLoaded.value && { key: 'login', type: 'select', label: t('Custom.PaymentHistory.TradingAccount'), placeholder: t('placeholder.login'), options: loginOptions.value || [] },
+    { key: 'login', type: 'select', label: t('Custom.PaymentHistory.TradingAccount'), placeholder: t('placeholder.login'), options: loginOptions || [] },
     { key: 'date', label: t('placeholder.Start') + ' - ' + t('placeholder.End'), type: 'daterange' }
     { key: 'date', label: t('placeholder.Start') + ' - ' + t('placeholder.End'), type: 'daterange' }
 ])
 ])
 const searchParams = ref({})
 const searchParams = ref({})
 const tableRef = ref(null)
 const tableRef = ref(null)
 const handleSearch = (params) => {
 const handleSearch = (params) => {
     search.value = params
     search.value = params
-    search.value.platform = loginOptions.value.find(item => item.value === params.login)?.platform || ''
+    search.value.platform = loginOptions.find(item => item.value === params.login)?.platform || ''
     if (!search.value.platform) return
     if (!search.value.platform) return
     nextTick(() => {
     nextTick(() => {
         tableRef.value.refreshTable()
         tableRef.value.refreshTable()
@@ -152,7 +152,7 @@ const handleSearch = (params) => {
 
 
 const handleReset = (params) => {
 const handleReset = (params) => {
     search.value = params
     search.value = params
-    search.value.platform = loginOptions.value.find(item => item.value === params.login)?.platform || ''
+    search.value.platform = loginOptions.find(item => item.value === params.login)?.platform || ''
     if (!search.value.platform) return
     if (!search.value.platform) return
     nextTick(() => {
     nextTick(() => {
         tableRef.value.refreshTable()
         tableRef.value.refreshTable()

+ 4 - 4
pages/customer/trade-position.vue

@@ -32,7 +32,7 @@ import { useI18n } from 'vue-i18n';
 const { t, locale } = useI18n();
 const { t, locale } = useI18n();
 import { customApi } from '@/service/custom';
 import { customApi } from '@/service/custom';
 import { useAccountOptions } from '@/composables/useAccountOptions'
 import { useAccountOptions } from '@/composables/useAccountOptions'
-const { loginOptions, isLoaded } = useAccountOptions()
+const { loginOptions } = useAccountOptions()
 const search = ref()
 const search = ref()
 const typeMap = computed(() => ([
 const typeMap = computed(() => ([
     { value: null, text: t('Custom.PaymentHistory.All') },
     { value: null, text: t('Custom.PaymentHistory.All') },
@@ -130,14 +130,14 @@ const mobilePrimaryFields = computed(() => [
 
 
 // 动态传入筛选字段配置
 // 动态传入筛选字段配置
 const filterFields = computed(() => [
 const filterFields = computed(() => [
-    isLoaded.value && { key: 'login', type: 'select', label: t('Custom.PaymentHistory.TradingAccount'), placeholder: t('placeholder.login'), options: loginOptions.value || [] },
+    { key: 'login', type: 'select', label: t('Custom.PaymentHistory.TradingAccount'), placeholder: t('placeholder.login'), options: loginOptions || [] },
     { key: 'date', label: t('placeholder.Start') + ' - ' + t('placeholder.End'), type: 'daterange' }
     { key: 'date', label: t('placeholder.Start') + ' - ' + t('placeholder.End'), type: 'daterange' }
 ])
 ])
 const searchParams = ref({})
 const searchParams = ref({})
 const tableRef = ref(null)
 const tableRef = ref(null)
 const handleSearch = (params) => {
 const handleSearch = (params) => {
     search.value = params
     search.value = params
-    search.value.platform = loginOptions.value.find(item => item.value === params.login)?.platform || ''
+    search.value.platform = loginOptions.find(item => item.value === params.login)?.platform || ''
     if(!search.value.platform) return
     if(!search.value.platform) return
     nextTick(() => {
     nextTick(() => {
         tableRef.value.refreshTable()
         tableRef.value.refreshTable()
@@ -146,7 +146,7 @@ const handleSearch = (params) => {
 
 
 const handleReset = (params) => {
 const handleReset = (params) => {
     search.value = params
     search.value = params
-    search.value.platform = loginOptions.value.find(item => item.value === params.login)?.platform || ''
+    search.value.platform = loginOptions.find(item => item.value === params.login)?.platform || ''
     if(!search.value.platform) return
     if(!search.value.platform) return
     nextTick(() => {
     nextTick(() => {
         tableRef.value.refreshTable()
         tableRef.value.refreshTable()

+ 51 - 12
pages/customer/withdrawal.vue

@@ -22,14 +22,14 @@
         <view class="b-card">
         <view class="b-card">
           <view class="card-top">
           <view class="card-top">
             <text class="tit"><text class="iconfont icon-caret-right"></text>{{ t('Custom.Deposit.Title22') }}</text>
             <text class="tit"><text class="iconfont icon-caret-right"></text>{{ t('Custom.Deposit.Title22') }}</text>
-            <view v-for="(group, groupKey) in tableData" :key="groupKey">
-              <!-- 通道分组标题 -->
-              <view class="channelType" v-if="group.length" v-t="groupTitleMap[groupKey]" />
-              <PaymentMethodsList :list="group" @select="isShowStep3" />
+            <cwg-asset-tabs v-if="tabsConfig.length > 0" v-model="activeTab" :tabs="tabsConfig" />
+            <uni-loading v-if="currentTableData.length == 0" />
+            <view v-if="currentTableData.length">
+              <PaymentMethodsList :list="currentTableData" @select="isShowStep3" />
             </view>
             </view>
             <view v-if="step3" class="reselect-btn">
             <view v-if="step3" class="reselect-btn">
               <button class="s-btn reselect" type="primary" @click="showTable">{{ t('Custom.Deposit.Reselect')
               <button class="s-btn reselect" type="primary" @click="showTable">{{ t('Custom.Deposit.Reselect')
-                }}</button>
+              }}</button>
             </view>
             </view>
           </view>
           </view>
         </view>
         </view>
@@ -112,8 +112,8 @@
                     <uni-forms-item :label="t('blockchain.item5')">
                     <uni-forms-item :label="t('blockchain.item5')">
                       <view class="proof">
                       <view class="proof">
                         <template v-if="form.addressProve && (form.addressProve.slice(-3).toLowerCase() === 'pdf')">
                         <template v-if="form.addressProve && (form.addressProve.slice(-3).toLowerCase() === 'pdf')">
-                          <cwg-link type="pdf1"
-                            :url="imgUrl + form.addressProve" target="_blank" class="state crm_state_blue">PDF</cwg-link>
+                          <cwg-link type="pdf1" :url="imgUrl + form.addressProve" target="_blank"
+                            class="state crm_state_blue">PDF</cwg-link>
                         </template>
                         </template>
                         <image v-else :src="imgUrl + form.addressProve" mode="aspectFit"
                         <image v-else :src="imgUrl + form.addressProve" mode="aspectFit"
                           style="width: 100rpx; height: 100rpx;" @click="previewImage(imgUrl + form.addressProve)" />
                           style="width: 100rpx; height: 100rpx;" @click="previewImage(imgUrl + form.addressProve)" />
@@ -142,7 +142,7 @@
                       </text>
                       </text>
                       <text v-if="channelData.type == 'BANK'">{{
                       <text v-if="channelData.type == 'BANK'">{{
                         t('Custom.Withdraw.addBank')
                         t('Custom.Withdraw.addBank')
-                        }}</text>
+                      }}</text>
                       <text v-if="channelData.type == 'BANK'" class="add-btn crm-cursor"
                       <text v-if="channelData.type == 'BANK'" class="add-btn crm-cursor"
                         @click="openAddBankCard('add_bankCard')">
                         @click="openAddBankCard('add_bankCard')">
                         {{ t('Custom.Withdraw.addBank1') }}
                         {{ t('Custom.Withdraw.addBank1') }}
@@ -267,7 +267,7 @@
                 <uni-col :span="24" v-if="channelData.type != 'BANK_TELEGRAPHIC' && isStep3">
                 <uni-col :span="24" v-if="channelData.type != 'BANK_TELEGRAPHIC' && isStep3">
                   <view class="tit">
                   <view class="tit">
                     <text>{{ t('Custom.Withdraw.Title3') + '(' + channelData.currency + ')'
                     <text>{{ t('Custom.Withdraw.Title3') + '(' + channelData.currency + ')'
-                      }}</text>
+                    }}</text>
                   </view>
                   </view>
                 </uni-col>
                 </uni-col>
                 <uni-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" v-if="channelData.type !== 'BANK_TELEGRAPHIC'">
                 <uni-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" v-if="channelData.type !== 'BANK_TELEGRAPHIC'">
@@ -328,7 +328,7 @@
         :loginDoc="loginValueDoc" @confirm="submit" />
         :loginDoc="loginValueDoc" @confirm="submit" />
       <!-- 协议弹窗 -->
       <!-- 协议弹窗 -->
       <cwg-tips-popup v-model:visible="dialogCheckTip"
       <cwg-tips-popup v-model:visible="dialogCheckTip"
-        :introduce="isZh.value ? introduce.introduce : introduce.enIntroduce" />
+        :introduce="isZh ? introduce.introduce : introduce.enIntroduce" />
       <!-- 等待弹窗 -->
       <!-- 等待弹窗 -->
       <cwg-wait-popup v-model:visible="dialogCheckWait" type="center" :mask-click="false" :showFooters="false" />
       <cwg-wait-popup v-model:visible="dialogCheckWait" type="center" :mask-click="false" :showFooters="false" />
       <!-- 最后失败弹窗 -->
       <!-- 最后失败弹窗 -->
@@ -405,14 +405,53 @@ const dialogCheckTip = ref(false)
 const isChannel = ref(true)
 const isChannel = ref(true)
 const pictLoading = ref(false)
 const pictLoading = ref(false)
 const tableData = reactive({
 const tableData = reactive({
-  Ucard_Wallet: [],
+
   Digital_Currency: [],
   Digital_Currency: [],
   China_UnionPay: [],
   China_UnionPay: [],
   Electronic_Wallet: [],
   Electronic_Wallet: [],
   International_Transfer: [],
   International_Transfer: [],
   CHANNEL_TYPE_CARD: [],
   CHANNEL_TYPE_CARD: [],
   CHANNEL_TYPE_ALI_WALLET: [],
   CHANNEL_TYPE_ALI_WALLET: [],
-}) //通道table-选择前后
+  Ucard_Wallet: [],
+})
+//通道table-选择前后
+const activeTab = ref(1)
+// 🔥 自动过滤掉空数据的 tab
+const tabsConfig = computed(() => {
+
+  const allTabs = [
+    { text: t('Custom.Deposit.Channel3'), value: 1, type: 'Digital_Currency' },
+    { text: t('Custom.Deposit.Channel2'), value: 2, type: 'China_UnionPay' },
+    { text: t('Custom.Deposit.Channel4'), value: 3, type: 'Electronic_Wallet' },
+    { text: t('Custom.Deposit.Channel1'), value: 4, type: 'International_Transfer' },
+    { text: t('PersonalManagement.Label.CreditCard'), value: 5, type: 'CHANNEL_TYPE_CARD' },
+    { text: t('card.title'), value: 6, type: 'Ucard_Wallet' },
+    { text: t('Label.Ali'), value: 7, type: 'CHANNEL_TYPE_ALI_WALLET' },
+  ]
+  // ✅ 只保留有数据的 tab
+  return allTabs.filter(tab => {
+    console.log(tableData[tab.type], tab.type);
+    return tableData[tab.type]?.length > 0
+  })
+})
+// 当前选中的 tab 项
+const currentTab = computed(() => tabsConfig.value.find(t => t.value === activeTab.value))
+
+// 当前要渲染的表格数据
+const currentTableData = computed(() => {
+  const type = currentTab.value?.type
+  return type ? tableData[type] || [] : []
+})
+// ✅ 监听 tab 变化,自动选中第一个有数据的 tab
+watch(
+  tabsConfig,
+  (newTabs) => {
+    if (newTabs.length > 0) {
+      activeTab.value = newTabs[0].value // 选中第一个
+    }
+  },
+  { immediate: true }
+)
 const bankDate = ref([]) //通道下的银行列表
 const bankDate = ref([]) //通道下的银行列表
 const channelData = ref({}) //当前选择的通道信息
 const channelData = ref({}) //当前选择的通道信息
 const WireTransferAccount = ref({}) //银行电汇信息
 const WireTransferAccount = ref({}) //银行电汇信息

+ 67 - 20
pages/ib/withdraw.vue

@@ -7,17 +7,16 @@
                 <view class="b-card">
                 <view class="b-card">
                     <view class="card-top">
                     <view class="card-top">
                         <text class="tit">{{ t('Custom.Deposit.Title22')
                         <text class="tit">{{ t('Custom.Deposit.Title22')
-                            }}</text>
-                        <view v-for="(group, groupKey) in tableData" :key="groupKey">
-
-                            <!-- 通道分组标题 -->
-                            <view class="channelType" v-if="group.length" v-t="groupTitleMap[groupKey]" />
-                            <PaymentMethodsList :list="group" @select="isShowStep3" />
+                        }}</text>
+                        <cwg-asset-tabs v-if="tabsConfig.length > 0" v-model="activeTab" :tabs="tabsConfig" />
+                        <uni-loading v-if="currentTableData.length == 0" />
+                        <view v-if="currentTableData.length">
+                            <PaymentMethodsList :list="currentTableData" @select="isShowStep3" />
                         </view>
                         </view>
                         <view v-if="step3" class="reselect-btn">
                         <view v-if="step3" class="reselect-btn">
                             <button class="s-btn reselect" type="primary" @click="showTable">{{
                             <button class="s-btn reselect" type="primary" @click="showTable">{{
                                 t('Custom.Deposit.Reselect')
                                 t('Custom.Deposit.Reselect')
-                                }}</button>
+                            }}</button>
                         </view>
                         </view>
                     </view>
                     </view>
                 </view>
                 </view>
@@ -114,7 +113,7 @@
                                     v-if="channelData.type == 'DIGITAL_CURRENCY' && isStep3 && form.addressProve">
                                     v-if="channelData.type == 'DIGITAL_CURRENCY' && isStep3 && form.addressProve">
                                     <uni-forms-item :label="t('blockchain.item5')">
                                     <uni-forms-item :label="t('blockchain.item5')">
                                         <div style="height: 100%; width: 100%" v-if="form.addressProve">
                                         <div style="height: 100%; width: 100%" v-if="form.addressProve">
-                                            <cwg-link type="pdf1" 
+                                            <cwg-link type="pdf1"
                                                 v-if="form.addressProve && (form.addressProve.slice(-3).toLowerCase() === 'pdf')"
                                                 v-if="form.addressProve && (form.addressProve.slice(-3).toLowerCase() === 'pdf')"
                                                 :url="imgUrl + form.addressProve" target="_blank"
                                                 :url="imgUrl + form.addressProve" target="_blank"
                                                 style="text-decoration: none; min-width: auto; width: auto; color: #ffffff; padding: 5px 10px;"
                                                 style="text-decoration: none; min-width: auto; width: auto; color: #ffffff; padding: 5px 10px;"
@@ -152,7 +151,7 @@
                                             </text>
                                             </text>
                                             <text v-if="channelData.type == 'BANK'">{{
                                             <text v-if="channelData.type == 'BANK'">{{
                                                 t('Custom.Withdraw.addBank')
                                                 t('Custom.Withdraw.addBank')
-                                                }}</text>
+                                            }}</text>
                                             <text v-if="channelData.type == 'BANK'" class="add-btn crm-cursor"
                                             <text v-if="channelData.type == 'BANK'" class="add-btn crm-cursor"
                                                 @click="openAddBankCard('add_bankCard')">
                                                 @click="openAddBankCard('add_bankCard')">
                                                 {{ t('Custom.Withdraw.addBank1') }}
                                                 {{ t('Custom.Withdraw.addBank1') }}
@@ -238,37 +237,44 @@
                                             :placeholder="t('placeholder.choose')" @change="chooseBank" />
                                             :placeholder="t('placeholder.choose')" @change="chooseBank" />
                                     </uni-forms-item>
                                     </uni-forms-item>
                                 </uni-col>
                                 </uni-col>
-                                <uni-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
+                                <uni-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12"
+                                    v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
                                     <uni-forms-item :label="t('Custom.Withdraw.UserName')">
                                     <uni-forms-item :label="t('Custom.Withdraw.UserName')">
                                         <uni-easyinput disabled v-model="form.bankUname" />
                                         <uni-easyinput disabled v-model="form.bankUname" />
                                     </uni-forms-item>
                                     </uni-forms-item>
                                 </uni-col>
                                 </uni-col>
-                                <uni-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
+                                <uni-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12"
+                                    v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
                                     <uni-forms-item :label="t('Custom.Withdraw.BankCardNum')">
                                     <uni-forms-item :label="t('Custom.Withdraw.BankCardNum')">
                                         <uni-easyinput disabled v-model="form.bankCardNum" />
                                         <uni-easyinput disabled v-model="form.bankCardNum" />
                                     </uni-forms-item>
                                     </uni-forms-item>
                                 </uni-col>
                                 </uni-col>
-                                <uni-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
+                                <uni-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12"
+                                    v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
                                     <uni-forms-item :label="t('Custom.Withdraw.BankName')">
                                     <uni-forms-item :label="t('Custom.Withdraw.BankName')">
                                         <uni-easyinput disabled v-model="form.bankName" />
                                         <uni-easyinput disabled v-model="form.bankName" />
                                     </uni-forms-item>
                                     </uni-forms-item>
                                 </uni-col>
                                 </uni-col>
-                                <uni-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
+                                <uni-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12"
+                                    v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
                                     <uni-forms-item :label="t('Custom.Withdraw.swiftCode')">
                                     <uni-forms-item :label="t('Custom.Withdraw.swiftCode')">
                                         <uni-easyinput disabled v-model="form.swiftCode" />
                                         <uni-easyinput disabled v-model="form.swiftCode" />
                                     </uni-forms-item>
                                     </uni-forms-item>
                                 </uni-col>
                                 </uni-col>
-                                <uni-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
+                                <uni-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12"
+                                    v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
                                     <uni-forms-item :label="t('Custom.Withdraw.bankCode')">
                                     <uni-forms-item :label="t('Custom.Withdraw.bankCode')">
                                         <uni-easyinput disabled v-model="form.customBankCode" />
                                         <uni-easyinput disabled v-model="form.customBankCode" />
                                     </uni-forms-item>
                                     </uni-forms-item>
                                 </uni-col>
                                 </uni-col>
-                                <uni-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
+                                <uni-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12"
+                                    v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
                                     <uni-forms-item :label="t('Custom.Withdraw.bankAddr')">
                                     <uni-forms-item :label="t('Custom.Withdraw.bankAddr')">
                                         <uni-easyinput disabled v-model="form.bankAddr" />
                                         <uni-easyinput disabled v-model="form.bankAddr" />
                                     </uni-forms-item>
                                     </uni-forms-item>
                                 </uni-col>
                                 </uni-col>
-                                <uni-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
+                                <uni-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12"
+                                    v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
                                     <!-- Account Agency NO -->
                                     <!-- Account Agency NO -->
                                     <uni-forms-item :label="'Account Agency NO'" name="agencyNo">
                                     <uni-forms-item :label="'Account Agency NO'" name="agencyNo">
                                         <uni-easyinput v-model="form.agencyNo" />
                                         <uni-easyinput v-model="form.agencyNo" />
@@ -287,13 +293,15 @@
                                         <text>{{ t('Custom.Withdraw.Title3') }}</text>
                                         <text>{{ t('Custom.Withdraw.Title3') }}</text>
                                     </view>
                                     </view>
                                 </uni-col>
                                 </uni-col>
-                                <uni-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
+                                <uni-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12"
+                                    v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
                                     <uni-forms-item :label="t('Custom.Withdraw.CurrencyType')" name="currency">
                                     <uni-forms-item :label="t('Custom.Withdraw.CurrencyType')" name="currency">
                                         <cwg-combox filterable v-model:value="form.currency"
                                         <cwg-combox filterable v-model:value="form.currency"
                                             :options="[{ text: 'USD', value: 'USD' }]" />
                                             :options="[{ text: 'USD', value: 'USD' }]" />
                                     </uni-forms-item>
                                     </uni-forms-item>
                                 </uni-col>
                                 </uni-col>
-                                <uni-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
+                                <uni-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12"
+                                    v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
                                     <uni-forms-item :label="t('Custom.Withdraw.amount')" name="amount"
                                     <uni-forms-item :label="t('Custom.Withdraw.amount')" name="amount"
                                         :error-message="amountErrorMessage">
                                         :error-message="amountErrorMessage">
                                         <uni-easyinput v-model.trim="form.amount" type="number"
                                         <uni-easyinput v-model.trim="form.amount" type="number"
@@ -305,10 +313,11 @@
                                 <uni-col :span="24" v-if="channelData.type != 'BANK_TELEGRAPHIC' && isStep3">
                                 <uni-col :span="24" v-if="channelData.type != 'BANK_TELEGRAPHIC' && isStep3">
                                     <view class="tit">
                                     <view class="tit">
                                         <text>{{ t('Custom.Withdraw.Title3') + '(' + channelData.currency + ')'
                                         <text>{{ t('Custom.Withdraw.Title3') + '(' + channelData.currency + ')'
-                                            }}</text>
+                                        }}</text>
                                     </view>
                                     </view>
                                 </uni-col>
                                 </uni-col>
-                                <uni-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" v-if="channelData.type != 'BANK_TELEGRAPHIC' && isStep3">
+                                <uni-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12"
+                                    v-if="channelData.type != 'BANK_TELEGRAPHIC' && isStep3">
                                     <uni-forms-item name="amount" :error-message="amountErrorMessage">
                                     <uni-forms-item name="amount" :error-message="amountErrorMessage">
                                         <uni-easyinput v-model.trim="form.amount" autocomplete="off" type="number"
                                         <uni-easyinput v-model.trim="form.amount" autocomplete="off" type="number"
                                             @blur="validateAmount" />
                                             @blur="validateAmount" />
@@ -470,6 +479,44 @@ const tableData = reactive({
     CHANNEL_TYPE_ALI_WALLET: [],
     CHANNEL_TYPE_ALI_WALLET: [],
     UCARD_WALLET: []
     UCARD_WALLET: []
 })
 })
+
+//通道table-选择前后
+const activeTab = ref(1)
+// 🔥 自动过滤掉空数据的 tab
+const tabsConfig = computed(() => {
+    const allTabs = [
+        { text: t('Custom.Deposit.Channel3'), value: 1, type: 'Digital_Currency' },
+        { text: t('Custom.Deposit.Channel2'), value: 2, type: 'China_UnionPay' },
+        { text: t('Custom.Deposit.Channel4'), value: 3, type: 'Electronic_Wallet' },
+        { text: t('Custom.Deposit.Channel1'), value: 4, type: 'International_Transfer' },
+        { text: t('PersonalManagement.Label.CreditCard'), value: 5, type: 'CHANNEL_TYPE_CARD' },
+        { text: t('card.title'), value: 6, type: 'UCARD_WALLET' },
+        { text: t('Label.Ali'), value: 7, type: 'CHANNEL_TYPE_ALI_WALLET' },
+    ]
+    // ✅ 只保留有数据的 tab
+    return allTabs.filter(tab => {
+        console.log(tableData[tab.type], tab.type);
+        return tableData[tab.type]?.length > 0
+    })
+})
+// 当前选中的 tab 项
+const currentTab = computed(() => tabsConfig.value.find(t => t.value === activeTab.value))
+
+// 当前要渲染的表格数据
+const currentTableData = computed(() => {
+    const type = currentTab.value?.type
+    return type ? tableData[type] || [] : []
+})
+// ✅ 监听 tab 变化,自动选中第一个有数据的 tab
+watch(
+    tabsConfig,
+    (newTabs) => {
+        if (newTabs.length > 0) {
+            activeTab.value = newTabs[0].value // 选中第一个
+        }
+    },
+    { immediate: true }
+)
 const bankDate = ref([])
 const bankDate = ref([])
 const channelData = ref({})
 const channelData = ref({})
 const WireTransferAccount = ref({})
 const WireTransferAccount = ref({})

+ 21 - 0
stores/use-user-store.ts

@@ -21,11 +21,13 @@ const ACCOUNT_INFO_KEY = "accountInfo";
 const ID_TYPE_OPTIONS_KEY = "reasonsOptions";
 const ID_TYPE_OPTIONS_KEY = "reasonsOptions";
 const APP_VERSION = 'appVersion'
 const APP_VERSION = 'appVersion'
 const PROBLEM_DETAILS_KEY = "problemDetails";
 const PROBLEM_DETAILS_KEY = "problemDetails";
+const LOGIN_OPTIONS_KEY = "loginOptions";
 const useUserStore = defineStore("userStore", () => {
 const useUserStore = defineStore("userStore", () => {
   const userInfo = ref<UserInfo | null>(null);
   const userInfo = ref<UserInfo | null>(null);
   const accountInfo = ref<AccountInfo | null>(null);
   const accountInfo = ref<AccountInfo | null>(null);
   const isLoggedIn = ref(false);
   const isLoggedIn = ref(false);
   const reasonsOptions = ref<any>(null);
   const reasonsOptions = ref<any>(null);
+  const loginOptions = ref<any>(null);
   const appVersion = ref<any>(null);
   const appVersion = ref<any>(null);
   const problemDetails = ref<any>(null);
   const problemDetails = ref<any>(null);
   const initUserInfo = () => {
   const initUserInfo = () => {
@@ -48,6 +50,16 @@ const useUserStore = defineStore("userStore", () => {
       }
       }
     }
     }
   };
   };
+  const initLoginOptions = () => {
+    const encryptedInfo = ls.get(LOGIN_OPTIONS_KEY);
+    if (encryptedInfo) {
+      const decryptedInfo = crypt.decrypt(encryptedInfo);
+      if (decryptedInfo) {
+        loginOptions.value = JSON.parse(decryptedInfo);
+        isLoggedIn.value = true;
+      }
+    }
+  }
   const initProblemDetails = () => {
   const initProblemDetails = () => {
     const encryptedInfo = ls.get(PROBLEM_DETAILS_KEY);
     const encryptedInfo = ls.get(PROBLEM_DETAILS_KEY);
     if (encryptedInfo) {
     if (encryptedInfo) {
@@ -83,6 +95,11 @@ const useUserStore = defineStore("userStore", () => {
     const encryptedInfo = crypt.encrypt(JSON.stringify(info));
     const encryptedInfo = crypt.encrypt(JSON.stringify(info));
     ls.set(STORAGE_KEY, encryptedInfo);
     ls.set(STORAGE_KEY, encryptedInfo);
   };
   };
+  const saveLoginOptions = (info: any) => {
+    loginOptions.value = info;
+    const encryptedInfo = crypt.encrypt(JSON.stringify(info));
+    ls.set(LOGIN_OPTIONS_KEY, encryptedInfo);
+  };
   const saveProblemDetails = (info: any) => {
   const saveProblemDetails = (info: any) => {
     problemDetails.value = info;
     problemDetails.value = info;
     const encryptedInfo = crypt.encrypt(JSON.stringify(info));
     const encryptedInfo = crypt.encrypt(JSON.stringify(info));
@@ -108,6 +125,7 @@ const useUserStore = defineStore("userStore", () => {
     isLoggedIn.value = false;
     isLoggedIn.value = false;
     userToken.value = "";
     userToken.value = "";
     reasonsOptions.value = null;
     reasonsOptions.value = null;
+    loginOptions.value = null;
     ls.remove(STORAGE_KEY);
     ls.remove(STORAGE_KEY);
   };
   };
 
 
@@ -115,15 +133,18 @@ const useUserStore = defineStore("userStore", () => {
   initUserInfo();
   initUserInfo();
   initAccountInfo();
   initAccountInfo();
   initAppVersion();
   initAppVersion();
+  initLoginOptions();
   initProblemDetails();
   initProblemDetails();
   return {
   return {
     userInfo,
     userInfo,
     accountInfo,
     accountInfo,
     isLoggedIn,
     isLoggedIn,
     reasonsOptions,
     reasonsOptions,
+    loginOptions,
     appVersion,
     appVersion,
     problemDetails,
     problemDetails,
     saveProblemDetails,
     saveProblemDetails,
+    saveLoginOptions,
     saveAppVersion,
     saveAppVersion,
     saveReasonsOptions,
     saveReasonsOptions,
     saveUserInfo,
     saveUserInfo,

+ 10 - 2
uni_modules/uni-loading/components/uni-loading/uni-loading.vue

@@ -1,5 +1,5 @@
 <template>
 <template>
-	<view>
+	<view class="loading-container">
 	 <Loading1 v-if="loadingType==1"/>
 	 <Loading1 v-if="loadingType==1"/>
 	 <Loading2 v-if="loadingType==2"/>
 	 <Loading2 v-if="loadingType==2"/>
 	 <Loading3 v-if="loadingType==3"/>
 	 <Loading3 v-if="loadingType==3"/>
@@ -31,6 +31,14 @@
 	}
 	}
 </script>
 </script>
 
 
-<style>
+<style lang="scss" scoped>
+@import "@/uni.scss";
 
 
+.loading-container {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    height: 200px;
+}
 </style>
 </style>