zhb 2 месяцев назад
Родитель
Сommit
dc99bd65e3

+ 149 - 55
components/AddBankDialog.vue

@@ -8,7 +8,7 @@
                 </view>
             </view>
             <uni-forms ref="formRef" :rules="rules" :model="form" labelWidth="200" label-position="top"
-                class="crm-form">
+                validate-trigger="submit" class="crm-form">
                 <uni-row class="form-row uni-row1">
                     <template v-if="form.type === 1">
                         <uni-col :xs="24">
@@ -22,25 +22,26 @@
                         </uni-col>
                         <uni-col :xs="24">
                             <uni-forms-item :label="t('PersonalManagement.Label.BankAccountName')">
-                                <uni-easyinput :clearable="false" v-model="form.bankUname"
+                                <uni-easyinput :clearable="false" v-model="username"
                                     :placeholder="locale == 'es' ? 'Introduzca el nombre de la red' : t('placeholder.input')" />
                             </uni-forms-item>
                         </uni-col>
                         <uni-col :xs="24">
-                            <uni-forms-item :label="t('PersonalManagement.Label.BankName')">
+                            <uni-forms-item :label="t('PersonalManagement.Label.BankName')" name="bankName">
                                 <cwg-combox :clearable="false" :filterable="true" v-model:value="form.bankName"
                                     :options="bankOptions" :placeholder="t('placeholder.choose')"
                                     @change="onStateChange" />
                             </uni-forms-item>
                         </uni-col>
                         <uni-col :xs="24">
-                            <uni-forms-item :label="t('PersonalManagement.Label.BankAccount')">
+                            <uni-forms-item :label="t('PersonalManagement.Label.BankAccount')" name="bankCardNum">
                                 <uni-easyinput :clearable="false" v-model="form.bankCardNum"
                                     :placeholder="locale == 'es' ? 'Introduzca la dirección de la billetera' : t('placeholder.input')" />
                             </uni-forms-item>
                         </uni-col>
                         <uni-col :xs="24">
-                            <uni-forms-item :label="t('PersonalManagement.Label.AccountOpeningBranch')">
+                            <uni-forms-item :label="t('PersonalManagement.Label.AccountOpeningBranch')"
+                                name="bankBranchName">
                                 <uni-easyinput :clearable="false" v-model="form.bankBranchName"
                                     :placeholder="locale == 'es' ? 'Introduzca la dirección de la billetera' : t('placeholder.input')" />
                             </uni-forms-item>
@@ -49,14 +50,14 @@
                     <template v-if="form.type === 4">
                         <!-- 区块链名称 -->
                         <uni-col :xs="24">
-                            <uni-forms-item prop="addressName" :label="t('blockchain.item3')">
+                            <uni-forms-item name="addressName" :label="t('blockchain.item3')">
                                 <uni-easyinput :clearable="false" v-model="form.addressName"
                                     :placeholder="t('placeholder.input')" />
                             </uni-forms-item>
                         </uni-col>
                         <!-- 钱包地址 -->
                         <uni-col :xs="24">
-                            <uni-forms-item prop="address" :label="t('blockchain.item4')">
+                            <uni-forms-item name="address" :label="t('blockchain.item4')">
                                 <uni-easyinput :clearable="false" v-model="form.address"
                                     :placeholder="t('placeholder.input')" />
                             </uni-forms-item>
@@ -65,36 +66,36 @@
                     <template v-if="form.type === 2">
                         <uni-col :xs="24">
                             <uni-forms-item :label="t('PersonalManagement.Label.BankAccountName')">
-                                <uni-easyinput :clearable="false" v-model="form.bankUname" :disabled="true"
+                                <uni-easyinput :clearable="false" v-model="username" :disabled="true"
                                     :placeholder="locale == 'es' ? 'Introduzca el nombre de la red' : t('placeholder.input')" />
                             </uni-forms-item>
                         </uni-col>
                         <uni-col :xs="24">
-                            <uni-forms-item :label="t('PersonalManagement.Label.BankAccount')">
+                            <uni-forms-item :label="t('PersonalManagement.Label.BankAccount')" name="bankCardNum">
                                 <uni-easyinput :clearable="false" v-model="form.bankCardNum"
                                     :placeholder="locale == 'es' ? 'Introduzca la dirección de la billetera' : t('placeholder.input')" />
                             </uni-forms-item>
                         </uni-col>
                         <uni-col :xs="24">
-                            <uni-forms-item :label="t('PersonalManagement.Label.BankName')">
+                            <uni-forms-item :label="t('PersonalManagement.Label.BankName')" name="bankName">
                                 <uni-easyinput :clearable="false" v-model="form.bankName"
                                     :placeholder="locale == 'es' ? 'Introduzca el nombre del banco' : t('placeholder.input')" />
                             </uni-forms-item>
                         </uni-col>
                         <uni-col :xs="24">
-                            <uni-forms-item :label="t('PersonalManagement.Label.BankAddress')">
+                            <uni-forms-item :label="t('PersonalManagement.Label.BankAddress')" name="bankAddr">
                                 <uni-easyinput :clearable="false" v-model="form.bankAddr"
                                     :placeholder="locale == 'es' ? 'Introduzca la dirección del banco' : t('placeholder.input')" />
                             </uni-forms-item>
                         </uni-col>
                         <uni-col :xs="24">
-                            <uni-forms-item :label="t('PersonalManagement.Label.SwiftBIC')">
+                            <uni-forms-item :label="t('PersonalManagement.Label.SwiftBIC')" name="swiftCode">
                                 <uni-easyinput :clearable="false" v-model="form.swiftCode"
                                     :placeholder="locale == 'es' ? 'Introduzca el SWIFT/BIC' : t('placeholder.input')" />
                             </uni-forms-item>
                         </uni-col>
                         <uni-col :xs="24">
-                            <uni-forms-item :label="t('PersonalManagement.Label.BankCode')">
+                            <uni-forms-item :label="t('PersonalManagement.Label.BankCode')" name="bankCode">
                                 <uni-easyinput :clearable="false" v-model="form.bankCode"
                                     :placeholder="locale == 'es' ? 'Introduzca el código del banco' : t('placeholder.input')" />
                             </uni-forms-item>
@@ -110,18 +111,19 @@
                     <template v-if="form.type === 3">
                         <uni-col :xs="24">
                             <uni-forms-item :label="t('PersonalManagement.Label.CreditCardAccountName')">
-                                <uni-easyinput :clearable="false" v-model="form.bankUname" :disabled="true"
+                                <uni-easyinput :clearable="false" v-model="username" :disabled="true"
                                     :placeholder="t('placeholder.input')" />
                             </uni-forms-item>
                         </uni-col>
                         <uni-col :xs="24">
-                            <uni-forms-item :label="t('PersonalManagement.Label.CreditCardAccount')">
+                            <uni-forms-item :label="t('PersonalManagement.Label.CreditCardAccount')" name="bankCardNum">
                                 <uni-easyinput :clearable="false" v-model="form.bankCardNum"
                                     :placeholder="locale == 'es' ? 'Introduzca el número de tarjeta' : t('placeholder.input')" />
                             </uni-forms-item>
                         </uni-col>
                         <uni-col :xs="24">
-                            <uni-forms-item :label="t('PersonalManagement.Label.ExpirationYear')">
+                            <uni-forms-item :label="t('PersonalManagement.Label.ExpirationYear')"
+                                name="expiryYearMonth">
                                 <uni-easyinput :clearable="false" v-model="form.expiryYearMonth"
                                     :placeholder="locale == 'es' ? 'Introduzca MM/AA' : t('placeholder.input')" />
                             </uni-forms-item>
@@ -151,8 +153,9 @@
 <script setup lang="ts">
 import { ref, nextTick, computed, onMounted } from 'vue';
 import { useI18n } from 'vue-i18n';
-import { Validators } from '@/utils/validators';
 import { personalApi } from '@/service/personal';
+import useUserStore from '@/stores/use-user-store'
+const userStore = useUserStore()
 const { t, locale } = useI18n();
 const typeMap = {
     4: 'blockchain.item2',
@@ -160,38 +163,47 @@ const typeMap = {
     2: 'PersonalManagement.Title.BankWireTransfer',
     3: 'PersonalManagement.Label.CreditCard'
 }
+const username = computed(() => {
+    let first = userStore?.userInfo?.customInfo.firstName;
+    let middle = userStore?.userInfo?.customInfo.middle;
+    let lastName = userStore?.userInfo?.customInfo
+        .lastName;
+    return (first ? first + " " : "") +
+        (middle ? middle + " " : "") +
+        (lastName ? lastName : "");
+})
 interface AddBankForm {
     addressName: string;
     address: string;
     checkboxGroup: string[];
 }
 const hobbys = computed(() => {
-  let value = [
-    { value: 1, text: t('blockchain.item8') },
-  ]
-  switch (form.value.type){
-      case 1:
-        value = [
-          { value: 1, text: t('PersonalManagement.Title.DefaultBank') },
-        ]
-      break;
-      case 2:
-        value = [
-          { value: 1, text: t('PersonalManagement.Title.DefaultWire') },
-        ]
-      break;
-      case 3:
-        value = [
-          { value: 1, text: t('PersonalManagement.Title.DefaultCredit') },
-        ]
-      break;
-      case 4:
-        value = [
-          { value: 1, text: t('blockchain.item8') },
-        ]
-      break;
-  }
-  return value
+    let value = [
+        { value: 1, text: t('blockchain.item8') },
+    ]
+    switch (form.value.type) {
+        case 1:
+            value = [
+                { value: 1, text: t('PersonalManagement.Title.DefaultBank') },
+            ]
+            break;
+        case 2:
+            value = [
+                { value: 1, text: t('PersonalManagement.Title.DefaultWire') },
+            ]
+            break;
+        case 3:
+            value = [
+                { value: 1, text: t('PersonalManagement.Title.DefaultCredit') },
+            ]
+            break;
+        case 4:
+            value = [
+                { value: 1, text: t('blockchain.item8') },
+            ]
+            break;
+    }
+    return value
 
 });
 const emit = defineEmits(["success"]);
@@ -201,10 +213,89 @@ const formRef = ref<any>(null);
 
 const form = ref<AddBankForm>({});
 
-const rules = {
-    addressName: [Validators.required(t('blockchain.item3') + t('common.cannotbeempty'))],
-    address: [Validators.required(t('blockchain.item4') + t('common.cannotbeempty'))]
-};
+const rules = computed(() => ({
+    bankName: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty'),
+                trigger: 'blur',
+            },
+        ],
+    },
+    bankCardNum: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty'),
+                trigger: 'change',
+            },
+        ],
+    },
+    bankBranchName: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty'),
+                trigger: 'blur',
+            },
+        ],
+    },
+    bankAddr: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty'),
+                trigger: 'blur',
+            },
+        ],
+    },
+    swiftCode: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty'),
+                trigger: 'blur',
+            },
+        ],
+    },
+    bankCode: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty'),
+                trigger: 'blur',
+            },
+        ],
+    },
+    expiryYearMonth: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty'),
+                trigger: 'blur',
+            },
+        ],
+    },
+    addressName: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty'),
+                trigger: 'blur',
+            },
+        ],
+    },
+    address: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty'),
+                trigger: 'blur',
+            },
+        ],
+    },
+}));
 
 // 打开弹窗
 const open = async (type: number) => {
@@ -231,10 +322,7 @@ const resetForm = () => {
 const submit = async () => {
     try {
         // 校验表单
-        const valid = await formRef.value?.validate();
-        if (!valid) {
-            return;
-        }
+        await formRef.value?.validate();
         // 调用 API 添加钱包
         const submitData = {
             ...form.value,
@@ -243,7 +331,7 @@ const submit = async () => {
             defaultBank: form.value?.defaultBank && form.value?.defaultBank[0] ? 1 : 0,
         };
         let res = await personalApi.customBankAdd({
-            bankUname: 'username',
+            bankUname: username.value,
             ...submitData,
         });
         if (res.code == 200) {
@@ -253,9 +341,15 @@ const submit = async () => {
             uni.showToast({ title: res.msg || t('common.error'), icon: 'none' });
         }
         close();
-    } catch (error: any) {
-        console.log(error);
-        uni.showToast({ title: error.message || error.msg || t('common.error'), icon: 'none' });
+    } catch (error) {
+        console.log(error, 12121);
+
+        if (error instanceof Array) {
+            uni.showToast({ title: error[0].errorMessage, icon: 'none' });
+            return
+        } else {
+            uni.showToast({ title: error.msg || t('common.error'), icon: 'none' });
+        }
     }
 };
 

+ 20 - 3
components/cwg-tips-popup.vue

@@ -1,8 +1,12 @@
 <template>
     <cwg-popup v-model:visible="visible" type="center" :mask-click="false" :show-footers="true">
         <view class="popup-content">
-            <view v-if="content" class="des1" style="font-size: 16px; line-height: 1.6; margin: 30px 0 50px" v-t="content"/>
-            <view v-else class="des1" style="font-size: 16px; line-height: 1.6; margin: 30px 0 50px" v-t="content"></view>
+            <view v-if="title" class="des1"
+                style="font-size: 16px;font-weight: bold; line-height: 1.6; margin: 30px 0 50px" v-t="title" />
+            <view v-if="content" class="des1" style="font-size: 15px; line-height: 1.6; margin: 30px 0 50px"
+                v-t="content" />
+            <view v-else class="des1" style="font-size: 15px; line-height: 1.6; margin: 30px 0 50px" v-t="content">
+            </view>
             <rich-text class="popup-text" :nodes="introduce"></rich-text>
         </view>
         <template #footer>
@@ -21,11 +25,20 @@ const props = defineProps({
         type: Boolean,
         default: false
     },
+    // 弹窗标题
+    title: {
+        type: String,
+        default: ''
+    },
     // 弹窗内容
     content: {
         type: String,
         default: ''
     },
+    content: {
+        type: String,
+        default: ''
+    },
     // 弹窗富文本内容
     introduce: {
         type: String,
@@ -49,5 +62,9 @@ const tosubmitConfirm = () => {
 </script>
 
 <style lang="scss" scoped>
-
+.popup-content {
+    p {
+        text-align: left;
+    }
+}
 </style>

+ 2 - 1
pages/customer/components/WithdrawCheckConfirmPopup.vue

@@ -9,7 +9,7 @@
         <cwg-label-line-value :label="t('news_add_field.Label.Title4')" :value="selectCodes" v-if="code" />
         <cwg-label-line-value :label="t('Custom.Withdraw.Title3')" :value="params.amount + ' ' + channelData.currency"
           v-if="params.amount" />
-        <cwg-label-line-value :label="t('Custom.Withdraw.item7')" :value="''">
+        <cwg-label-line-value :label="t('Custom.Withdraw.item7')" :value="''" v-if="type !== 'IB'">
           <template #operation1>
             <view v-if="FreeNumber > 0 && dialogCheckConfirm_form.feeAmount > 0">
               <text style="text-decoration:line-through">
@@ -48,6 +48,7 @@ const props = defineProps({
   userName: String,
   FreeNumber: Number,
   dialogCheckConfirm_form: Object,
+  type: String,
   // 其他可能需要的 props
 });
 const emit = defineEmits(['update:visible', 'confirm', 'cancel']);

+ 38 - 18
pages/customer/deposit.vue

@@ -7,7 +7,7 @@
                 <view class="b-card">
                     <view class="card-top">
                         <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"
                             :placeholder="t('placeholder.choose')" />
                     </view>
@@ -18,7 +18,7 @@
                 <view class="b-card">
                     <view class="card-top">
                         <text class="tit"><text class="iconfont icon-caret-right"></text>{{ t('Custom.Deposit.Title2')
-                        }}</text>
+                            }}</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" />
@@ -36,14 +36,19 @@
                 <view class="b-card">
                     <view class="card-top">
                         <!-- 注意事项(第一步确认) -->
-                        <view v-if="!isStep3">
-                            <view class="step3-attention">
-                                <rich-text class="attention"
-                                    :nodes="(locale === 'cn' || locale === 'zhHant') ? introduce.introduce : introduce.enIntroduce"></rich-text>
-                                <view class="btn-bottom">
-                                    <text class="btn crm-cursor" @click="isStep3Open()">{{ t('Btn.Confirm') }}</text>
+                        <view v-if="!isStep3" class="step3-attention">
+                            <view class="tips" v-if="(introduce.introduce || introduce.enIntroduce)">
+                                <view>
+                                    <rich-text class="attention"
+                                        :nodes="(locale === 'cn' || locale === 'zhHant') ? introduce.introduce : introduce.enIntroduce"></rich-text>
+
                                 </view>
                             </view>
+                            <view class="btn-bottom">
+                                <text class="btn crm-cursor" @click="isStep3Open()">{{ t('Btn.Confirm')
+                                }}</text>
+                            </view>
+
                         </view>
 
                         <!-- 表单(确认后显示) -->
@@ -79,7 +84,7 @@
                                     <uni-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
                                         <text class="tit"><text class="iconfont icon-caret-right"></text>{{
                                             t('news_add_field.Label.Title4')
-                                            }}</text>
+                                        }}</text>
                                     </uni-col>
                                     <uni-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
                                         <uni-forms-item>
@@ -111,7 +116,7 @@
                                                         WireTransferAccount.bankUname || '--'
                                                     }}</text></view>
                                             <view class="row"><text class="label">{{ t('Custom.Deposit.bankName')
-                                                    }}</text><text class="content">{{ WireTransferAccount.bankName ||
+                                            }}</text><text class="content">{{ WireTransferAccount.bankName ||
                                                         '--'
                                                     }}</text></view>
                                             <view class="row"><text class="label SpecialColor">{{
@@ -120,7 +125,7 @@
                                                         WireTransferAccount.bankCardNum || '--'
                                                     }}</text></view>
                                             <view class="row"><text class="label">{{ t('Custom.Deposit.bankAddr')
-                                                    }}</text><text class="content">{{ WireTransferAccount.bankAddr ||
+                                            }}</text><text class="content">{{ WireTransferAccount.bankAddr ||
                                                         '--'
                                                     }}</text></view>
                                             <view class="row"><text class="label SpecialColor">{{
@@ -129,7 +134,7 @@
                                                         WireTransferAccount.swiftCode || '--'
                                                     }}</text></view>
                                             <view class="row"><text class="label">{{ t('Custom.Deposit.bankCode')
-                                                    }}</text><text class="content">{{ WireTransferAccount.bankCode ||
+                                            }}</text><text class="content">{{ WireTransferAccount.bankCode ||
                                                         '--'
                                                     }}</text></view>
                                             <view class="row"><text class="label SpecialColor">{{
@@ -156,7 +161,7 @@
                                                         + '-' +
                                                         WireTransferAccount.type }}</text></view>
                                             <view class="row"><text class="label">{{ t('Custom.Withdraw.Title6')
-                                                    }}</text><text class="content">{{ WireTransferAccount.address ||
+                                            }}</text><text class="content">{{ WireTransferAccount.address ||
                                                         '--'
                                                     }}</text></view>
                                             <view class="row"><text class="label">QR Code</text>
@@ -233,7 +238,7 @@
                                             <uni-forms-item :label="t('Custom.Deposit.UploadRemittanceVoucher')">
                                                 <view class="upload-box">
                                                     <button class="btn-upload" @click="chooseImage">{{ t('upload')
-                                                        }}</button>
+                                                    }}</button>
                                                     <image v-if="imageUrl" :src="imageUrl" mode="aspectFit"
                                                         class="img-preview" />
                                                 </view>
@@ -261,7 +266,7 @@
                                                     <text>{{ t('news_add_field1.activitiesNZ.itemDeposit2') }}</text>
                                                     <text class="clause crm-cursor" @click="dialogClauseNZ = true">{{
                                                         t('news_add_field1.activitiesNZ.itemDeposit3')
-                                                    }}</text>
+                                                        }}</text>
                                                     <text>{{ t('news_add_field1.activitiesNZ.itemDeposit4') }}</text>
                                                 </view>
                                             </uni-forms-item>
@@ -2083,14 +2088,29 @@ watch(() => params.agree6, (newVal) => {
     }
 
     .step3-attention {
-        background: var(--color-error-50, #fff1f0);
+        // background: var(--color-error-50, #fff1f0);
         border-radius: px2rpx(12);
-        padding: px2rpx(16);
         margin-bottom: px2rpx(20);
 
+        .tips {
+            line-height: 1.8;
+            font-size: px2rpx(12);
+            color: #909399;
+            background-color: #f9f9f9;
+            padding: px2rpx(12);
+            border-radius: px2rpx(4);
+            border-left: px2rpx(2) solid #409eff;
+
+            .title {
+                font-weight: 600;
+                margin-bottom: px2rpx(6);
+                color: #606266;
+            }
+        }
+
         .attention {
             font-size: px2rpx(14);
-            color: var(--color-error-600, #cf1322);
+            //  color: var(--color-error-600, #cf1322);
             line-height: 1.6;
         }
 

+ 19 - 4
pages/customer/style.scss

@@ -152,14 +152,29 @@
   }
 
   .step3-attention {
-    background: var(--color-error-50, #fff1f0);
+    // background: var(--color-error-50, #fff1f0);
     border-radius: px2rpx(12);
-    padding: px2rpx(16);
     margin-bottom: px2rpx(20);
 
+    .tips {
+      line-height: 1.8;
+      font-size: px2rpx(12);
+      color: #909399;
+      background-color: #f9f9f9;
+      padding: px2rpx(12);
+      border-radius: px2rpx(4);
+      border-left: px2rpx(2) solid #409eff;
+
+      .title {
+        font-weight: 600;
+        margin-bottom: px2rpx(6);
+        color: #606266;
+      }
+    }
+
     .attention {
       font-size: px2rpx(14);
-      color: var(--color-error-600, #cf1322);
+      //  color: var(--color-error-600, #cf1322);
       line-height: 1.6;
     }
 
@@ -347,4 +362,4 @@
       transform: rotate(360deg);
     }
   }
-}
+}

+ 23 - 5
pages/customer/withdrawal.vue

@@ -41,12 +41,15 @@
           <view class="card-top">
             <!-- 注意事项 -->
             <view v-if="!isStep3" class="step3-attention">
-              <rich-text class="attention" :nodes="isZh ? introduce.introduce : introduce.enIntroduce"></rich-text>
+              <view class="tips" v-if="(introduce.introduce || introduce.enIntroduce)">
+                <view>
+                  <rich-text class="attention" :nodes="isZh ? introduce.introduce : introduce.enIntroduce" />
+                </view>
+              </view>
               <view class="btn-bottom">
                 <text class="btn crm-cursor" @click="isStep3 = true">{{ t('Btn.Confirm') }}</text>
               </view>
             </view>
-
             <!-- 表单 -->
             <uni-forms ref="formRef" :model="form" :rules="rules" labelWidth="200" label-position="top" v-if="isStep3"
               class="base-info-form" validate-trigger="submit">
@@ -1788,14 +1791,29 @@ onMounted(() => {
   }
 
   .step3-attention {
-    background: var(--color-error-50, #fff1f0);
+    // background: var(--color-error-50, #fff1f0);
     border-radius: px2rpx(12);
-    padding: px2rpx(16);
     margin-bottom: px2rpx(20);
 
+    .tips {
+      line-height: 1.8;
+      font-size: px2rpx(12);
+      color: #909399;
+      background-color: #f9f9f9;
+      padding: px2rpx(12);
+      border-radius: px2rpx(4);
+      border-left: px2rpx(2) solid #409eff;
+
+      .title {
+        font-weight: 600;
+        margin-bottom: px2rpx(6);
+        color: #606266;
+      }
+    }
+
     .attention {
       font-size: px2rpx(14);
-      color: var(--color-error-600, #cf1322);
+      //  color: var(--color-error-600, #cf1322);
       line-height: 1.6;
     }
 

+ 1614 - 8
pages/ib/withdraw.vue

@@ -1,23 +1,1629 @@
 <template>
     <cwg-page-wrapper class="create-page" :isHeaderFixed="true">
         <cwg-header :title="t('Home.page_ib.item5')" />
-        <view class="account-section">
+        <view class="custom-withdraw">
+            <!-- 步骤2:支付通道列表 -->
+            <view class="box box-step2">
+                <view class="b-card">
+                    <view class="card-top">
+                        <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" />
+                        </view>
+                        <view v-if="step3" class="reselect-btn">
+                            <button class="s-btn reselect" type="primary" @click="showTable">{{
+                                t('Custom.Deposit.Reselect')
+                                }}</button>
+                        </view>
+                    </view>
+                </view>
+            </view>
+
+            <!-- 步骤3:填写出金信息 -->
+            <view class="box box-step3" v-if="step3">
+                <view class="b-card">
+                    <view class="card-top">
+                        <!-- 注意事项 -->
+                        <view v-if="!isStep3" class="step3-attention">
+                            <view class="tips" v-if="(introduce.introduce || introduce.enIntroduce)">
+                                <view>
+                                    <rich-text class="attention"
+                                        :nodes="isZh ? introduce.introduce : introduce.enIntroduce" />
+                                </view>
+                            </view>
+                            <view class="btn-bottom">
+                                <text class="btn crm-cursor" @click="isStep3 = true">{{ t('Btn.Confirm') }}</text>
+                            </view>
+                        </view>
+                        <!-- 表单 -->
+                        <uni-forms ref="formRef" :model="form" :rules="rules" label-width="200" label-position="top"
+                            v-if="isStep3" class="form" validate-trigger="submit">
+                            <uni-row class="demo-uni-row uni-row1">
+                                <!-- 银行选择区域(当有银行列表时) -->
+                                <uni-col :span="24" v-if="bankDate.length && isStep3">
+                                    <view class="tit">
+                                        <text>{{ t('Custom.Withdraw.Title5') }}</text>
+                                    </view>
+                                </uni-col>
+                                <uni-col :span="24" v-if="bankDate.length && isStep3">
+                                    <uni-forms-item name="bankCode">
+                                        <cwg-combox filterable v-model:value="form.bankCode" :options="bankOptions"
+                                            :placeholder="t('placeholder.choose')" />
+                                    </uni-forms-item>
+                                </uni-col>
+
+                                <!-- 电子钱包标题 -->
+                                <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8"
+                                    v-if="['CHANNEL_TYPE_WALLET', 'CHANNEL_TYPE_ALI_WALLET'].includes(channelData.type)">
+                                    <view class="tit">
+                                        <text>{{ getWalletLabel }}</text>
+                                    </view>
+                                </uni-col>
+
+                                <!-- 电子钱包地址输入 -->
+                                <uni-col :span="24"
+                                    v-if="(channelData.type == 'CHANNEL_TYPE_WALLET' || channelData.type == 'CHANNEL_TYPE_ALI_WALLET') && isStep3">
+                                    <uni-forms-item name="address">
+                                        <uni-easyinput v-model="form.address" :placeholder="t('placeholder.input')"
+                                            autocomplete="off" />
+                                    </uni-forms-item>
+                                </uni-col>
+
+                                <!-- 数字货币区域 -->
+                                <uni-col :span="24" class="card-tit"
+                                    v-if="channelData.type == 'DIGITAL_CURRENCY' && isStep3">
+                                    <div
+                                        style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap;">
+                                        <view class="tit">
+
+                                            <text>{{ t('Custom.Withdraw.Title6') }}</text>
+                                        </view>
+                                        <div class="add-back">
+                                            <text>{{ t('blockchain.item10') }}</text>
+                                            <text class="add-btn crm-cursor"
+                                                @click="openAddBankCard('add_bankBlockchain')">
+                                                {{ t('Custom.Withdraw.addBank1') }}
+                                            </text>
+                                        </div>
+                                    </div>
+                                </uni-col>
+                                <uni-col :span="24" v-if="channelData.type == 'DIGITAL_CURRENCY' && isStep3">
+                                    <uni-forms-item>
+                                        <cwg-combox filterable v-model:value="myId" :options="digitalOptions"
+                                            :placeholder="t('placeholder.choose')" @change="onDigitalCurrencyChange"
+                                            :disabled="!ruleForm.bankBlockchain.length" />
+                                    </uni-forms-item>
+                                </uni-col>
+                                <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8"
+                                    v-if="channelData.type == 'DIGITAL_CURRENCY' && isStep3">
+                                    <uni-forms-item :label="t('blockchain.item3')">
+                                        <uni-easyinput disabled v-model="form.addressName" />
+                                    </uni-forms-item>
+                                </uni-col>
+                                <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8"
+                                    v-if="channelData.type == 'DIGITAL_CURRENCY' && isStep3">
+                                    <uni-forms-item :label="t('blockchain.item4')">
+                                        <uni-easyinput disabled v-model="form.address" />
+                                    </uni-forms-item>
+                                </uni-col>
+                                <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8"
+                                    v-if="channelData.type == 'DIGITAL_CURRENCY' && isStep3 && form.addressProve">
+                                    <uni-forms-item :label="t('blockchain.item5')">
+                                        <div style="height: 100%; width: 100%" v-if="form.addressProve">
+                                            <a v-if="form.addressProve && (form.addressProve.slice(-3).toLowerCase() === 'pdf')"
+                                                :href="imgUrl + form.addressProve" target="_blank"
+                                                style="text-decoration: none; min-width: auto; width: auto; color: #ffffff; padding: 5px 10px;"
+                                                class="state crm_state_blue">
+                                                PDF
+                                            </a>
+                                            <image v-else style="width: 50px; height: 50px"
+                                                :src="imgUrl + form.addressProve" mode="aspectFill"
+                                                @click="previewImage(imgUrl + form.addressProve)" />
+                                        </div>
+                                    </uni-forms-item>
+                                </uni-col>
+                                <uni-col :span="24" v-if="channelData.type == 'DIGITAL_CURRENCY' && isStep3">
+                                    <view class="tit" style="margin: 0 0 20px">
+                                        <i class="iconfont iconi"></i>
+                                        <text>{{ t('Custom.Deposit.Des') }}</text>
+                                    </view>
+                                </uni-col>
+
+                                <!-- 银行卡/电汇/信用卡区域 -->
+                                <uni-col :span="24" class="card-tit"
+                                    v-if="isStep3 && (channelData.type == 'BANK_TELEGRAPHIC' || channelData.type == 'BANK' || channelData.type == 'CHANNEL_TYPE_CARD')">
+                                    <div
+                                        style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap;">
+                                        <view class="tit">
+
+                                            <text>{{ t('Custom.Withdraw.Title4') }}</text>
+                                        </view>
+                                        <div class="add-back">
+                                            <text v-if="channelData.type == 'BANK_TELEGRAPHIC'">{{
+                                                t('Custom.Withdraw.addWire') }}</text>
+                                            <text v-if="channelData.type == 'BANK_TELEGRAPHIC'"
+                                                class="add-btn crm-cursor" @click="openAddBankCard('add_wireTransfer')">
+                                                {{ t('Custom.Withdraw.addBank1') }}
+                                            </text>
+                                            <text v-if="channelData.type == 'BANK'">{{
+                                                t('Custom.Withdraw.addBank')
+                                                }}</text>
+                                            <text v-if="channelData.type == 'BANK'" class="add-btn crm-cursor"
+                                                @click="openAddBankCard('add_bankCard')">
+                                                {{ t('Custom.Withdraw.addBank1') }}
+                                            </text>
+                                            <text v-if="channelData.type == 'CHANNEL_TYPE_CARD'">{{
+                                                t('PersonalManagement.Label.addCreditCard') }}</text>
+                                            <text v-if="channelData.type == 'CHANNEL_TYPE_CARD'"
+                                                class="add-btn crm-cursor" @click="openAddBankCard('add_CreditCard')">
+                                                {{ t('Custom.Withdraw.addBank1') }}
+                                            </text>
+                                        </div>
+                                    </div>
+                                </uni-col>
+
+                                <!-- 网银支付信息(BANK) -->
+                                <uni-col :span="24" v-if="channelData.type == 'BANK' && isStep3">
+                                    <uni-forms-item>
+                                        <cwg-combox v-model:value="myId" :options="bankCardOptions"
+                                            :placeholder="t('placeholder.choose')" @change="chooseBank" />
+                                    </uni-forms-item>
+                                </uni-col>
+                                <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8"
+                                    v-if="channelData.type == 'BANK' && isStep3">
+                                    <uni-forms-item :label="t('Custom.Withdraw.UserName')">
+                                        <uni-easyinput disabled v-model="form.bankUname" />
+                                    </uni-forms-item>
+                                </uni-col>
+                                <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8"
+                                    v-if="channelData.type == 'BANK' && isStep3">
+                                    <uni-forms-item :label="t('Custom.Withdraw.BankCardNum')">
+                                        <uni-easyinput disabled v-model="form.bankCardNum" />
+                                    </uni-forms-item>
+                                </uni-col>
+                                <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8"
+                                    v-if="channelData.type == 'BANK' && isStep3">
+                                    <uni-forms-item :label="t('Custom.Withdraw.BankName')">
+                                        <uni-easyinput disabled v-model="form.bankName" />
+                                    </uni-forms-item>
+                                </uni-col>
+                                <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8"
+                                    v-if="channelData.type == 'BANK' && isStep3">
+                                    <uni-forms-item :label="t('Custom.Withdraw.bankBranchName')">
+                                        <uni-easyinput disabled v-model="form.bankBranchName" />
+                                    </uni-forms-item>
+                                </uni-col>
+
+                                <!-- 信用卡信息 -->
+                                <uni-col :span="24" v-if="channelData.type == 'CHANNEL_TYPE_CARD' && isStep3">
+                                    <uni-forms-item>
+                                        <cwg-combox v-model:value="myId" :options="bankCardOptions"
+                                            :placeholder="t('placeholder.choose')" @change="chooseBank" />
+                                    </uni-forms-item>
+                                </uni-col>
+                                <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8"
+                                    v-if="channelData.type == 'CHANNEL_TYPE_CARD' && isStep3">
+                                    <uni-forms-item :label="t('PersonalManagement.Label.CreditCardAccountName')">
+                                        <uni-easyinput disabled v-model="form.bankUname" />
+                                    </uni-forms-item>
+                                </uni-col>
+                                <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8"
+                                    v-if="channelData.type == 'CHANNEL_TYPE_CARD' && isStep3">
+                                    <uni-forms-item :label="t('PersonalManagement.Label.CreditCardAccount')">
+                                        <uni-easyinput disabled v-model="form.bankCardNum" />
+                                    </uni-forms-item>
+                                </uni-col>
+                                <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8"
+                                    v-if="channelData.type == 'CHANNEL_TYPE_CARD' && isStep3">
+                                    <uni-forms-item label="CVV">
+                                        <uni-easyinput disabled v-model="form.cvv" />
+                                    </uni-forms-item>
+                                </uni-col>
+                                <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8"
+                                    v-if="channelData.type == 'CHANNEL_TYPE_CARD' && isStep3">
+                                    <uni-forms-item :label="t('PersonalManagement.Label.ExpirationYear')">
+                                        <uni-easyinput disabled v-model="form.expiryYearMonth" />
+                                    </uni-forms-item>
+                                </uni-col>
+
+                                <!-- 电汇信息 -->
+                                <uni-col :span="24" v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
+                                    <uni-forms-item>
+                                        <cwg-combox v-model:value="myId" :options="bankCardOptions"
+                                            :placeholder="t('placeholder.choose')" @change="chooseBank" />
+                                    </uni-forms-item>
+                                </uni-col>
+                                <uni-col :span="8" v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
+                                    <uni-forms-item :label="t('Custom.Withdraw.UserName')">
+                                        <uni-easyinput disabled v-model="form.bankUname" />
+                                    </uni-forms-item>
+                                </uni-col>
+                                <uni-col :span="8" v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
+                                    <uni-forms-item :label="t('Custom.Withdraw.BankCardNum')">
+                                        <uni-easyinput disabled v-model="form.bankCardNum" />
+                                    </uni-forms-item>
+                                </uni-col>
+                                <uni-col :span="8" v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
+                                    <uni-forms-item :label="t('Custom.Withdraw.BankName')">
+                                        <uni-easyinput disabled v-model="form.bankName" />
+                                    </uni-forms-item>
+                                </uni-col>
+                                <uni-col :span="8" v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
+                                    <uni-forms-item :label="t('Custom.Withdraw.swiftCode')">
+                                        <uni-easyinput disabled v-model="form.swiftCode" />
+                                    </uni-forms-item>
+                                </uni-col>
+                                <uni-col :span="8" v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
+                                    <uni-forms-item :label="t('Custom.Withdraw.bankCode')">
+                                        <uni-easyinput disabled v-model="form.customBankCode" />
+                                    </uni-forms-item>
+                                </uni-col>
+                                <uni-col :span="8" v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
+                                    <uni-forms-item :label="t('Custom.Withdraw.bankAddr')">
+                                        <uni-easyinput disabled v-model="form.bankAddr" />
+                                    </uni-forms-item>
+                                </uni-col>
+                                <uni-col :span="8" v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
+                                    <!-- Account Agency NO -->
+                                    <uni-forms-item :label="'Account Agency NO'" name="agencyNo">
+                                        <uni-easyinput v-model="form.agencyNo" />
+                                    </uni-forms-item>
+                                </uni-col>
+                                <uni-col :span="8"
+                                    v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3 && channelData.code == 'PAY_RETAILER_REMIT_PAY_KEY_BRW'">
+                                    <uni-forms-item label="CPF" name="cpf">
+                                        <uni-easyinput v-model="form.cpf" />
+                                    </uni-forms-item>
+                                </uni-col>
+
+                                <!-- 电汇金额区域 -->
+                                <uni-col :span="24" v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
+                                    <view class="tit">
+                                        <text>{{ t('Custom.Withdraw.Title3') }}</text>
+                                    </view>
+                                </uni-col>
+                                <uni-col :span="8" v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
+                                    <uni-forms-item :label="t('Custom.Withdraw.CurrencyType')" name="currency">
+                                        <cwg-combox filterable v-model:value="form.currency"
+                                            :options="[{ text: 'USD', value: 'USD' }]" />
+                                    </uni-forms-item>
+                                </uni-col>
+                                <uni-col :span="8" v-if="channelData.type == 'BANK_TELEGRAPHIC' && isStep3">
+                                    <uni-forms-item :label="t('Custom.Withdraw.amount')" name="amount"
+                                        :error-message="amountErrorMessage">
+                                        <uni-easyinput v-model.trim="form.amount" type="number"
+                                            @blur="validateAmount" />
+                                    </uni-forms-item>
+                                </uni-col>
+
+                                <!-- 非电汇的金额区域 -->
+                                <uni-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8"
+                                    v-if="channelData.type != 'BANK_TELEGRAPHIC' && isStep3">
+                                    <uni-forms-item name="amount" :error-message="amountErrorMessage">
+                                        <template #label>
+                                            <view class="tit">
+                                                <text>{{ t('Custom.Withdraw.Title3') + '(' + channelData.currency + ')'
+                                                    }}</text>
+                                            </view>
+                                        </template>
+                                        <uni-easyinput v-model.trim="form.amount" autocomplete="off" type="number"
+                                            @blur="validateAmount" />
+                                    </uni-forms-item>
+                                </uni-col>
+                            </uni-row>
+                            <view class="agree">
+                                <uni-forms-item name="agree2">
+                                    <checkbox-group :value="form.agree2 ? ['1'] : []" @change="onAgree2Change">
+                                        <label class="checkbox">
+                                            <checkbox value="1" />
+                                            <view class="crm-cursor"
+                                                style="text-decoration: underline; display: inline-block; margin-left: 10px;"
+                                                @click.stop="dialogCheckTip = true">
+                                                {{ t('Custom.Withdraw.Des') }}
+                                            </view>
+                                        </label>
+                                    </checkbox-group>
+                                </uni-forms-item>
+                            </view>
+                            <view class="agree" v-if="dialogTipsIsShow">
+                                <uni-forms-item name="agree3">
+                                    <checkbox-group :value="form.agree3 ? ['1'] : []" @change="onAgree3Change">
+                                        <label class="checkbox">
+                                            <checkbox value="1" />
+                                            <view class="crm-cursor" style="display: inline-block; margin-left: 10px;">
+                                                * {{ t('Custom.Withdraw.item1') }}<br />
+                                                {{ t('Custom.Withdraw.item1_1') }}<br />
+                                                {{ t('Custom.Withdraw.item1_2') }}
+                                            </view>
+                                        </label>
+                                    </checkbox-group>
+                                </uni-forms-item>
+                            </view>
+                            <button class="s-btn" type="primary" @click="openTips">{{ t('Btn.Submit') }}</button>
+
+                        </uni-forms>
+                    </view>
+                </view>
+            </view>
+            <!-- 提示弹窗 -->
+            <cwg-tips-popup v-model:visible="dialogTips" content="Custom.Withdraw.item2" @confirm="closeTipsConfirm" />
+            <cwg-tips-popup v-model:visible="dialogCheckInto" content="ApplicationDialog.Des42_1"
+                title="ApplicationDialog.Des41_1" @confirm="closeTipsConfirm" />
+            <cwg-tips-popup v-model:visible="dialogCheckInto1" content="ApplicationDialog.Des42"
+                title="ApplicationDialog.Des41" @confirm="closeTipsConfirm" />
+            <!-- 弹窗:确认信息 -->
+            <cwg-check-confirm-popup v-model:visible="dialogCheckConfirm" :title="t('Home.page_customer.item3')"
+                :channelData="channelData" :code="code" :selectCodes="selectCodes" :params="form"
+                :FreeNumber="FreeNumber" :userName="userName" :dialogCheckConfirm_form="dialogCheckConfirm_form"
+                :login="loginValue" type="IB" @confirm="submit" />
+            <!-- 协议弹窗 -->
+            <cwg-tips-popup v-model:visible="dialogCheckTip"
+                :introduce="isZh ? introduce.introduce : introduce.enIntroduce" />
+            <!-- 等待弹窗 -->
+            <cwg-wait-popup v-model:visible="dialogCheckWait" type="center" :mask-click="false" :showFooters="false" />
+            <!-- 最后失败弹窗 -->
+            <cwg-error-popup v-model:visible="dialogError" @confirm="closeDia" :responseMessage="RES" />
+            <!-- 最后成功弹窗 -->
+            <cwg-success-popup v-model:visible="dialogSuccess" @confirm="closeDia" />
+            <!-- 功能关闭弹出 -->
+            <cwg-function-disabled-popup v-model:visible="InfoStatus5" :showFooters="false" @confirm="toHome" />
+            <!-- kyc成功弹窗 -->
+            <cwg-kyc-popup v-model:visible="dialogKyc" :qrText="text1" />
+            <!--验证码-->
+            <!-- 新增银行弹窗 -->
+            <add-bank-dialog ref="addBankDialogRef" @success="addSuccess" />
         </view>
     </cwg-page-wrapper>
 </template>
 
-<script setup lang="ts">
-import { ref, reactive, computed, onMounted, onUnmounted } from 'vue'
+<script setup>
+import { ref, reactive, computed, onMounted, onUnmounted, watch } from 'vue'
 import { onLoad } from '@dcloudio/uni-app'
-import { useI18n } from 'vue-i18n' // uni-app 中已集成,但需配置
-import { customApi } from '@/service/custom'
-import { financialApi } from '@/service/financial'
-import Config from '@/config/index'
+import { showToast } from "@/utils/toast";
+import useUserStore from '@/stores/use-user-store'
+import { customApi } from "@/service/custom"
+import { financialApi } from "@/service/financial"
+import Config from "@/config/index"
 import AddBankDialog from '@/components/AddBankDialog.vue';
-import PaymentMethodsList from './components/PaymentMethodsList.vue'
+import CwgCheckConfirmPopup from '../customer/components/WithdrawCheckConfirmPopup.vue'
+import CwgKycPopup from '../customer/components/KycPopup.vue'
+import PaymentMethodsList from '../customer/components/PaymentMethodsList.vue'
+import { useI18n } from 'vue-i18n'
+
 const { t, locale } = useI18n()
+const { Code, Host80 } = Config
+
 const isZh = computed(() => ['cn', 'zhHant'].includes(locale.value))
+// ---------- 辅助函数:替代原 this.Session ----------
+
+// 弹窗辅助(替代原 this.$pigeon)
+const $pigeon = {
+    MessageError(msg) {
+        uni.showToast({ title: msg, icon: 'none' })
+    },
+    MessageWarning(msg) {
+        uni.showToast({ title: msg, icon: 'none' })
+    },
+    MessageConfirm(content, title, confirmText, cancelText, confirmCallback, cancelCallback) {
+        uni.showModal({
+            title,
+            content,
+            confirmText,
+            cancelText,
+            success(res) {
+                if (res.confirm) confirmCallback && confirmCallback()
+                else cancelCallback && cancelCallback()
+            }
+        })
+    }
+}
+
+// 获取 metaInfo(用于二维码)
+const getMetaInfo = () => {
+    const systemInfo = uni.getSystemInfoSync()
+    return {
+        userAgent: systemInfo.platform,
+        screenWidth: systemInfo.screenWidth,
+        screenHeight: systemInfo.screenHeight,
+        deviceType: 'h5'
+    }
+}
+
+// ---------- 响应式数据(完全保留原 data 结构) ----------
+const dialogFreeNumber = ref(false)
+const FreeNumber = ref(0)
+const InfoStatus5 = ref(false)
+const metaInfo = ref(null)
+const text1 = ref("")
+const flag = ref(false)
+const RES = ref("")
+const openType = ref("")
+const dialogInfoTradingAdd = ref(false)
+const ruleForm = reactive({
+    bankInfo: [],
+    bankWrit: [],
+    xykInfo: [],
+    bankBlockchain: []
+})
+const imgUrl = Host80
+const loginOptions = ref([])
+const loginValue = ref("")
+const code = ref("")
+const bankValid = ref("")
+const requestUrl = ref("")
+const isStep3 = ref(false)
+const step2 = ref(false)
+const step3 = ref(false)
+const dialogCheckTip = ref(false)
+const isChannel = ref(true)
+const pictLoading = ref(false)
+const tableData = reactive({
+    International_Transfer: [],
+    China_UnionPay: [],
+    Digital_Currency: [],
+    CHANNEL_TYPE_CARD: [],
+    Electronic_Wallet: [],
+    CHANNEL_TYPE_ALI_WALLET: [],
+    UCARD_WALLET: []
+})
+const bankDate = ref([])
+const channelData = ref({})
+const WireTransferAccount = ref({})
+const formRef = ref(null)
+const form = reactive({
+    currency: "USD",
+    amount: ""
+})
+const mAmount = reactive({
+    minAmount: "",
+    maxAmount: ""
+})
+const introduce = reactive({
+    introduce: "",
+    enIntroduce: ""
+})
+const bankInfoList = ref([])
+const bank = ref("")
+const myId = ref("")
+const bankPayType = ref("")
+const step3_bank_cur = ref("")
+const agree2 = ref(false)
+const form1 = ref({})
+const dialogCheck = ref(false)
+const dialogKyc = ref(false)
+const dialogVisible = ref(false)
+const dialogCheckWait = ref(false)
+const dialogCheckInto = ref(false)
+const dialogCheckInto1 = ref(false)
+const dialogNewBank = ref(false)
+const params = reactive({
+    bankCardNum: "",
+    bankUname: "",
+    bankName: "",
+    bankBranchName: "",
+    bankAddr: "",
+    swiftCode: "",
+    bankFront: "",
+    bankBack: "",
+    defaultBank: false
+})
+const dialogTips = ref(false)
+const dialogTipsIsShow = ref(true)
+const dialogCheckConfirm = ref(false)
+const dialogCheckConfirm_form = reactive({
+    amount: "",
+    feeAmount: ""
+})
+// 验证规则(保留原结构,实际验证需配合表单组件)
+const rules = computed(() => ({
+    bankCardNum: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty'),
+                trigger: 'blur',
+            },
+        ],
+    },
+    bankUname: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty'),
+                trigger: 'blur',
+            },
+        ],
+    },
+    bankName: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty'),
+                trigger: 'blur',
+            },
+        ],
+    },
+    bankBranchName: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty'),
+                trigger: 'blur',
+            },
+        ],
+    },
+    bankAddr: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty'),
+                trigger: 'blur',
+            },
+        ],
+    },
+    swiftCode: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty'),
+                trigger: 'blur',
+            },
+        ],
+    },
+    defaultBank: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.select.empty'),
+                trigger: 'change',
+            },
+        ],
+    },
+    bankCode: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.select.empty'),
+                trigger: 'change',
+            },
+        ],
+    },
+    message: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty'),
+                trigger: 'blur',
+            },
+        ],
+    },
+    address: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty'),
+                trigger: 'blur',
+            },
+        ],
+    },
+    amount: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.amount.format1'),
+            },
+            {
+                validateFunction: (rule, value, data, callback) => {
+                    if (value && (Number(mAmount.minAmount) > Number(value) || Number(mAmount.maxAmount) < Number(value))) {
+                        callback(t('vaildate.amount.amount') + mAmount.minAmount + ' - ' + mAmount.maxAmount);
+                        return false;
+                    }
+                    if (/^[0-9]+([.]{1}[0-9]{1,2})?$/.test(value)) {
+                        return true;
+                    } else {
+                        callback(t('vaildate.amount.format'));
+                        return false;
+                    }
+                },
+                trigger: 'blur',
+            },
+        ],
+    },
+    agree2: {
+        rules: [
+            {
+                validateFunction: (rule, value, data, callback) => {
+                    if (form.agree2) {
+                        return true;
+                    } else {
+                        callback(t('vaildate.agree.empty'));
+                        return false;
+                    }
+                },
+                trigger: 'change',
+            },
+        ],
+    },
+    agree3: {
+        rules: [
+            {
+                validateFunction: (rule, value, data, callback) => {
+                    if (form.agree3) {
+                        return true;
+                    } else {
+                        callback(t('vaildate.agree.empty'));
+                        return false;
+                    }
+                },
+                trigger: 'change',
+            },
+        ],
+    },
+    agencyNo: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty'),
+                trigger: 'blur',
+            },
+        ],
+    },
+    cpf: {
+        rules: [
+            {
+                required: true,
+                errorMessage: t('vaildate.input.empty'),
+                trigger: 'blur',
+            },
+        ],
+    },
+}));
+const amountErrorMessage = ref('')
+const validateAmount = () => {
+    const amount = form.amount
+    if (!amount && amount !== 0) {
+        amountErrorMessage.value = t('vaildate.amount.format1')
+        return false
+    }
+    if (mAmount.minAmount && mAmount.maxAmount) {
+        const min = Number(mAmount.minAmount);
+        const max = Number(mAmount.maxAmount);
+        const numValue = Number(amount);
+        if (numValue < min || numValue > max) {
+            amountErrorMessage.value = t('vaildate.amount.amount') + min + '-' + max
+            return false
+        }
+    }
+    if (!/^[0-9]+([.]{1}[0-9]{1,2})?$/.test(amount)) {
+        amountErrorMessage.value = t('vaildate.amount.format1')
+        return false
+    }
+    amountErrorMessage.value = ''
+    return true
+}
+// ---------- 计算属性 ----------
+const loginComboxOptions = computed(() => {
+    return loginOptions.value.map((item, index) => ({
+        text: item.label,
+        value: item.login
+    }))
+})
+const digitalOptions = computed(() => {
+    return ruleForm.bankBlockchain.map((item, index) => ({
+        text: `${item.addressName}-${item.address}`,
+        value: item.id
+    }))
+})
+const groupTitleMap = {
+    'Ucard_Wallet': 'card.title',
+    'Digital_Currency': 'Custom.Deposit.Channel3',
+    'China_UnionPay': 'Custom.Deposit.Channel2',
+    'Electronic_Wallet': 'Custom.Deposit.Channel4',
+    'International_Transfer': 'Custom.Deposit.Channel1',
+    'CHANNEL_TYPE_CARD': 'PersonalManagement.Label.CreditCard',
+    'CHANNEL_TYPE_ALI_WALLET': 'Label.Ali'
+}
+const getWalletLabel = computed(() => {
+    if (channelData.value.type === 'CHANNEL_TYPE_WALLET') return t('Custom.Withdraw.Title7')
+    if (channelData.value.type === 'CHANNEL_TYPE_ALI_WALLET') return t('Label.AliAccout')
+    return ''
+})
+const bankCardOptions = computed(() => {
+    return bankList.value.map((item, index) => ({
+        text: getBankLabel(item),
+        value: item.id
+    }))
+})
+const getBankLabel = (item) => {
+    if (channelData.value.type === 'BANK' || channelData.value.type === 'BANK_TELEGRAPHIC') {
+        return `${item.bankName}-${item.bankCardNum}`
+    } else if (channelData.value.type === 'CHANNEL_TYPE_CARD') {
+        return item.bankCardNum
+    }
+    return ''
+}
+const bankList = computed(() => {
+    if (channelData.value.type === 'BANK') return ruleForm.bankInfo
+    if (channelData.value.type === 'BANK_TELEGRAPHIC') return ruleForm.bankWrit
+    if (channelData.value.type === 'CHANNEL_TYPE_CARD') return ruleForm.xykInfo
+    return []
+})
+const bankOptions = computed(() => {
+    return bankDate.value.map((item, index) => ({
+        text: (locale.value === 'cn' || locale.value === 'zhHant') ? item.name : item.enName,
+        value: item.code
+    }))
+})
+// 最后确认
+const dialogSuccess = computed(() => dialogCheck.value && dialogVisible.value)
+// 最后失败
+const dialogError = computed(() => dialogCheck.value && !dialogVisible.value)
+const userStore = useUserStore()
+const ibInfo = computed(() => {
+    return userStore?.userInfo?.ibInfo || {}
+})
+const getInfoStatus5 = computed(() => {
+    if (ibInfo.value.closeFunctions && ibInfo.value.closeFunctions.length > 0) {
+        return ibInfo.value.closeFunctions.indexOf("8") !== -1
+    }
+    return false
+})
+
+
+const isFree = computed(() => {
+    let flagVal = false
+    const startTime1 = "2024/11/01 00:00:00"
+    const timezone = 2 // 目标时区偏移小时数
+    const now = new Date()
+    const utc = now.getTime() + now.getTimezoneOffset() * 60000
+    const targetTime = new Date(utc + timezone * 3600000).getTime()
+    const start = new Date(startTime1).getTime()
+    if (targetTime > start) flagVal = true
+    return flagVal
+})
+
+// ---------- 方法 ----------
+const getFreeNumber = async () => {
+    if (!isFree.value) return
+    if (getInfoStatus5.value === false) {
+        dialogFreeNumber.value = true
+    }
+    const res = await financialApi.remainingReductionNumber({})
+    if (res.code === Code.StatusOK) {
+        FreeNumber.value = res.data || 0
+    } else {
+        $pigeon.MessageError(res.msg)
+    }
+}
+
+const toHome = () => {
+    uni.reLaunch({ url: "/pages/ib/index" })
+    InfoStatus5.value = false
+}
+
+const isShowDialog = () => {
+    const startTime1 = "2025/2/15 00:00:00"
+    const timezone = 8
+    const now = new Date()
+    const utc = now.getTime() + now.getTimezoneOffset() * 60000
+    const targetTime = new Date(utc + timezone * 3600000).getTime()
+    const start = new Date(startTime1).getTime()
+    if (targetTime > start) {
+        dialogCheckInto.value = false
+        // dialogCheckInto1.value = true
+    } else {
+        dialogCheckInto.value = true
+        dialogCheckInto1.value = false
+    }
+}
+const onAgree3Change = (e) => {
+    form.agree3 = e.detail.value.length > 0
+}
+const onAgree2Change = (e) => {
+    form.agree2 = e.detail.value.length > 0
+}
+const selectChange = () => {
+    // 强制更新视图
+}
+
+// const openAddBankCard = (type) => {
+//     if (type === "add_bankCard") {
+//         if (ruleForm.bankInfo.length === 2) {
+//             $pigeon.MessageConfirm(
+//                 t("Msg.UnionPayCARDS"),
+//                 t("Msg.SystemPrompt"),
+//                 t("Btn.Confirm"),
+//                 t("Btn.Cancel"),
+//                 async () => { },
+//                 () => { }
+//             )
+//         } else {
+//             openType.value = "add_bankCard"
+//             dialogInfoTradingAdd.value = true
+//         }
+//     } else if (type === "add_wireTransfer") {
+//         if (ruleForm.bankWrit.length === 2) {
+//             $pigeon.MessageConfirm(
+//                 t("Msg.WireTransfers"),
+//                 t("Msg.SystemPrompt"),
+//                 t("Btn.Confirm"),
+//                 t("Btn.Cancel"),
+//                 async () => { },
+//                 () => { }
+//             )
+//         } else {
+//             openType.value = "add_wireTransfer"
+//             dialogInfoTradingAdd.value = true
+//         }
+//     } else if (type === "add_CreditCard") {
+//         openType.value = "add_CreditCard"
+//         dialogInfoTradingAdd.value = true
+//     } else if (type === "add_bankBlockchain") {
+//         if (ruleForm.bankBlockchain.length === 2) {
+//             $pigeon.MessageConfirm(
+//                 t("blockchain.item9"),
+//                 t("Msg.SystemPrompt"),
+//                 t("Btn.Confirm"),
+//                 t("Btn.Cancel"),
+//                 async () => { },
+//                 () => { }
+//             )
+//         } else {
+//             openType.value = "add_bankBlockchain"
+//             dialogInfoTradingAdd.value = true
+//         }
+//     }
+// }
+// 新增银行信息
+const addBankDialogRef = ref(null);
+function openAddBankCard(type) {
+    console.log(type, 121212)
+    switch (type) {
+        case 'add_bankBlockchain':
+            openAddCrypto()
+            break;
+        case 'add_bankCard':
+            openAddUnionpay()
+            break;
+        case 'add_wireTransfer':
+            openAddBank()
+            break;
+        case 'add_CreditCard':
+            openAddCredit()
+            break;
+    }
+}
+function openAddCrypto() {
+    const wallets = bankCardOptions.value || []
+    console.log(wallets, 12121212);
+    // 1️⃣ 没有钱包
+    if (wallets.length === 0) {
+        addBankDialogRef.value?.open(4);
+        return;
+    }
+    // 2️⃣ 是否存在未认证钱包
+    const hasUnAuth = wallets.some(
+        item => item.authStatus === 0 || item.approveStatus === 1
+    );
+    if (hasUnAuth) {
+        uni.showToast({
+            title: "加密钱包未认证",
+            icon: "none"
+        });
+        return;
+    }
+    // 3️⃣ 是否达到上限
+    if (wallets.length >= 2) {
+        uni.showToast({
+            title: t('blockchain.item9'),
+            icon: "none"
+        });
+        return;
+    }
+    // 4️⃣ 正常打开
+    addBankDialogRef.value?.open(4);
+}
+function openAddUnionpay() {
+    const wallets = bankCardOptions.value || []
+    console.log(wallets, 12121212);
+
+    if (wallets.length === 0) {
+        addBankDialogRef.value?.open(1);
+        return;
+    }
+    if (wallets.length >= 2) {
+        uni.showToast({
+            title: t('Msg.UnionPayCARDS'),
+            icon: "none"
+        });
+        return;
+    }
+    addBankDialogRef.value?.open(1);
+}
+function openAddBank() {
+    const wallets = bankCardOptions.value || []
+    console.log(wallets, 121212)
+    if (wallets.length === 0) {
+        addBankDialogRef.value?.open(2);
+        return;
+    }
+    if (wallets.length >= 2) {
+        uni.showToast({
+            title: t('Msg.WireTransfers'),
+            icon: "none"
+        });
+        return;
+    }
+    addBankDialogRef.value?.open(2);
+}
+function openAddCredit() {
+    const wallets = bankCardOptions.value || []
+    console.log(wallets, 12121212);
+    if (wallets.length === 0) {
+        addBankDialogRef.value?.open(3);
+        return;
+    }
+    addBankDialogRef.value?.open(3);
+}
+// 新增银行信息成功回调
+const addSuccess = (e) => {
+    getBankInfo();
+}
+
+const closeDiaAdd = () => {
+    dialogInfoTradingAdd.value = false
+}
+
+const closeAdd = (val) => {
+    dialogInfoTradingAdd.value = val
+}
+
+const confirmToReload = () => {
+    dialogInfoTradingAdd.value = false
+    getBankInfo()
+}
+
+const getBankInfo = async () => {
+    const res = await financialApi.customBankList({})
+    if (res.code === Code.StatusOK) {
+        ruleForm.bankInfo = []
+        ruleForm.bankWrit = []
+        ruleForm.xykInfo = []
+        ruleForm.bankBlockchain = []
+        res.data.forEach(item => {
+            if (item.type === 1) {
+                item.customBankCode = item.bankCode
+                item.bankCode = null
+                ruleForm.bankInfo.push(item)
+            } else if (item.type === 2) {
+                item.customBankCode = item.bankCode
+                item.bankCode = null
+                ruleForm.bankWrit.push(item)
+            } else if (item.type === 3) {
+                item.customBankCode = item.bankCode
+                item.bankCode = null
+                item.expiryYearMonth = (item.expiryYear || "") + "/" + (item.expiryMonth || "")
+                ruleForm.xykInfo.push(item)
+            } else if (item.type === 4) {
+                item.customBankCode = item.bankCode
+                item.bankCode = null
+                ruleForm.bankBlockchain.push(item)
+            }
+            if (channelData.value.type === "BANK" && item.defaultBank && item.type === 1) {
+                Object.assign(form, item)
+                myId.value = form.id
+            }
+            if (channelData.value.type === "BANK_TELEGRAPHIC" && item.defaultBank && item.type === 2) {
+                Object.assign(form, item)
+                myId.value = form.id
+            }
+            if (channelData.value.type === "CHANNEL_TYPE_CARD" && item.defaultBank && item.type === 3) {
+                myId.value = item.id
+                Object.assign(form, item)
+            }
+            if (channelData.value.type === "DIGITAL_CURRENCY" && item.defaultBank && item.type === 4) {
+                myId.value = item.id
+                Object.assign(form, item)
+            }
+        })
+    } else {
+        $pigeon.MessageError(res.msg)
+    }
+}
+const onDigitalCurrencyChange = (val) => {
+    const item = ruleForm.bankBlockchain.find(b => b.id === val)
+    chooseBank(item)
+}
+const chooseBank = (id) => {
+    const item = bankList.value.find(b => b.id === id)
+    if (!item) {
+        showToast(t("Msg.item11"));
+        return;
+    }
+    let codeCache = ""
+    if (form.bankCode) codeCache = form.bankCode
+    Object.assign(form, item)
+    form.agree2 = false
+    form.agree3 = false
+    if (channelData.value.type === "BANK_TELEGRAPHIC") {
+        form.currency = "USD"
+        if (codeCache) form.bankCode = codeCache
+    }
+}
+
+const openTips = async () => {
+    if (channelData.value.type === "BANK_TELEGRAPHIC" && !myId.value) {
+        $pigeon.MessageWarning(t("vaildate.withdrawBank.empty"))
+        return
+    }
+    if (channelData.value.type === "BANK" && !myId.value) {
+        $pigeon.MessageWarning(t("vaildate.withdrawBank.empty"))
+        return
+    }
+    if (channelData.value.type === "CHANNEL_TYPE_CARD" && !myId.value) {
+        $pigeon.MessageWarning(t("vaildate.withdrawBank.empty"))
+        return
+    }
+    if (channelData.value.type === "DIGITAL_CURRENCY" && !myId.value) {
+        $pigeon.MessageWarning(t("blockchain.item11"))
+        return
+    }
+    // 此处模拟表单验证,实际应调用 uni-forms 的 validate
+    try {
+        if (formRef.value) {
+            const valid = await formRef.value.validate()
+            if (dialogTipsIsShow.value) {
+                dialogTips.value = true
+            } else {
+                submit("form")
+            }
+        }
+    } catch (error) {
+        if (error instanceof Array) {
+            showToast(error[0].errorMessage);
+            return
+        } else {
+            RES.value = error.msg;
+        }
+    }
+}
+
+const openTipsConfirm = () => {
+    dialogCheckConfirm.value = false
+    submit("form")
+}
+
+const closeTipsConfirm = () => {
+    dialogTips.value = false
+    dialogCheckConfirm.value = true
+}
+
+const closeDia = () => {
+    isStep3.value = false
+    step2.value = false
+    showTable()
+    loginValue.value = ""
+    dialogCheck.value = false
+    dialogVisible.value = false
+}
+
+const qrCode = async (serial) => {
+    metaInfo.value = getMetaInfo()
+    const res = await customApi.getWebsdkLink1({
+        serial,
+        metaInfo: metaInfo.value
+    })
+    if (res.code === Code.StatusOK) {
+        text1.value = JSON.parse(res.data).url
+        dialogKyc.value = true
+        flag.value = false
+    } else {
+        flag.value = false
+    }
+}
+
+const submit = async (formName) => {
+    if (channelData.value.type === "BANK_TELEGRAPHIC" && !myId.value) {
+        $pigeon.MessageWarning(t("vaildate.withdrawBank.empty"))
+        return
+    }
+    if (channelData.value.type === "BANK" && !myId.value) {
+        $pigeon.MessageWarning(t("vaildate.withdrawBank.empty"))
+        return
+    }
+    if (channelData.value.type === "CHANNEL_TYPE_CARD" && !myId.value) {
+        $pigeon.MessageWarning(t("vaildate.withdrawBank.empty"))
+        return
+    }
+    if (channelData.value.type === "DIGITAL_CURRENCY" && !myId.value) {
+        $pigeon.MessageWarning(t("blockchain.item11"))
+        return
+    }
+    // 模拟表单验证
+    try {
+        if (formRef.value) {
+            await formRef.value.validate()
+            if (flag.value) return
+            flag.value = true
+            dialogCheckWait.value = true
+            form.amount = Number(form.amount)
+            let res
+            if (channelData.value.type === "DIGITAL_CURRENCY") {
+                res = await financialApi.ibWithdrawAapplyDigitalCurrency(channelData.value.requestUrl, {
+                    // login: loginValue.value,
+                    payType: channelData.value.code,
+                    ...form
+                })
+            } else if (["CHANNEL_TYPE_WALLET", "UCARD_WALLET", "CHANNEL_TYPE_ALI_WALLET"].includes(channelData.value.type)) {
+                res = await financialApi.ibWithdrawAapplyDigitalCurrency(channelData.value.requestUrl, {
+                    // login: loginValue.value,
+                    payType: channelData.value.code,
+                    ...form
+                })
+            } else if (channelData.value.type === "BANK" || channelData.value.type === "BANK_TELEGRAPHIC") {
+                res = await financialApi.ibWithdrawApplyBank(channelData.value.requestUrl, {
+                    // login: loginValue.value,
+                    payType: channelData.value.code,
+                    ...form
+                })
+            } else if (channelData.value.type === "CHANNEL_TYPE_CARD") {
+                res = await financialApi.WithdrawApplyBank(channelData.value.requestUrl, {
+                    // login: loginValue.value,
+                    payType: channelData.value.code,
+                    ...form
+                })
+            }
+
+            if (res && res.code === Code.StatusOK) {
+                dialogCheck.value = true
+                dialogVisible.value = true
+                // qrCode(res.data)
+                flag.value = false
+            } else {
+                RES.value = res?.msg || "error"
+                dialogCheck.value = true
+                dialogVisible.value = false
+                flag.value = false
+            }
+            dialogCheckWait.value = false
+        }
+    } catch (error) {
+        if (error instanceof Array) {
+            showToast(error[0].errorMessage);
+            return
+        } else {
+            RES.value = error.msg;
+            dialogCheck.value = true;
+            dialogCheckWait.value = false;
+            dialogVisible.value = false;
+            flag.value = false;
+        }
+    }
+
+
+}
+
+const Initialize = () => {
+    loginValue.value = ""
+    isStep3.value = false
+    step2.value = false
+    step3.value = false
+    showTable()
+}
+
+const isShowStep3 = (row) => {
+    if (row.bankValid && isChannel.value) {
+        getBankList(row)
+        isChannel.value = false
+        step3.value = true
+        channelData.value = row
+        mAmount.minAmount = row.minAmount
+        mAmount.maxAmount = row.maxAmount
+    } else {
+        step3.value = true
+        bankDate.value = []
+        channelData.value = row
+        mAmount.minAmount = row.minAmount
+        mAmount.maxAmount = row.maxAmount
+    }
+    if (row.code === "UNION_PAY_TELEGRAPHIC") {
+        WireTransferAccount.value = JSON.parse(row.property)
+    }
+    if (["BANK", "BANK_TELEGRAPHIC", "CHANNEL_TYPE_CARD", "DIGITAL_CURRENCY"].includes(row.type)) {
+        getBankInfo()
+        step3_bank_cur.value = "bank"
+        form.login = loginValue.value
+        form.payType = row.code
+        bankPayType.value = row.code
+    }
+    // 重置 tableData
+    tableData.International_Transfer = []
+    tableData.China_UnionPay = []
+    tableData.Digital_Currency = []
+    tableData.CHANNEL_TYPE_CARD = []
+    tableData.Electronic_Wallet = []
+    tableData.CHANNEL_TYPE_ALI_WALLET = []
+    tableData.UCARD_WALLET = []
+    if (row.type === "BANK_TELEGRAPHIC") tableData.International_Transfer[0] = row
+    if (row.type === "BANK") tableData.China_UnionPay[0] = row
+    if (row.type === "DIGITAL_CURRENCY") tableData.Digital_Currency[0] = row
+    if (row.type === "CHANNEL_TYPE_WALLET") tableData.Electronic_Wallet[0] = row
+    if (row.type === "UCARD_WALLET") tableData.UCARD_WALLET[0] = row
+    if (row.type === "CHANNEL_TYPE_CARD") tableData.CHANNEL_TYPE_CARD[0] = row
+    if (row.type === "CHANNEL_TYPE_ALI_WALLET") tableData.CHANNEL_TYPE_ALI_WALLET[0] = row
+    introduce.introduce = row.introduce
+    introduce.enIntroduce = row.enIntroduce
+}
+
+const showTable = () => {
+    myId.value = null
+    step3.value = false
+    isStep3.value = false
+    isChannel.value = true
+    getDepositList()
+    // 重置表单
+    form.currency = "USD"
+    form.amount = ""
+    // 其他重置...
+}
+
+const getDateList = async () => {
+    const res = await customApi.CustomDropdown({ platform: "" })
+    if (res.code === Code.StatusOK) {
+        loginOptions.value = res.data
+    } else {
+        $pigeon.MessageError(res.msg)
+    }
+}
+
+const getDepositList = async () => {
+    pictLoading.value = true
+    tableData.International_Transfer = []
+    tableData.China_UnionPay = []
+    tableData.Digital_Currency = []
+    tableData.CHANNEL_TYPE_CARD = []
+    tableData.Electronic_Wallet = []
+    tableData.CHANNEL_TYPE_ALI_WALLET = []
+    tableData.UCARD_WALLET = []
+    const res = await financialApi.RemitChannelList({})
+    if (res.code === Code.StatusOK) {
+        res.data.forEach(item => {
+            if (item.type === "BANK_TELEGRAPHIC") tableData.International_Transfer.push(item)
+            if (item.type === "BANK") tableData.China_UnionPay.push(item)
+            if (item.type === "DIGITAL_CURRENCY") tableData.Digital_Currency.push(item)
+            if (item.type === "CHANNEL_TYPE_WALLET") tableData.Electronic_Wallet.push(item)
+            if (item.type === "UCARD_WALLET") tableData.UCARD_WALLET.push(item)
+            if (item.type === "CHANNEL_TYPE_CARD") tableData.CHANNEL_TYPE_CARD.push(item)
+            if (item.type === "CHANNEL_TYPE_ALI_WALLET") tableData.CHANNEL_TYPE_ALI_WALLET.push(item)
+        })
+        pictLoading.value = false
+    } else {
+        $pigeon.MessageError(res.msg)
+        pictLoading.value = false
+    }
+}
+
+const getBankList = async (row) => {
+    const res = await financialApi.BankList({ channelCode: row.code })
+    if (res.code === Code.StatusOK) {
+        const bank = res.data
+        const data = []
+        bank.forEach(j => {
+            if (!j.minAmount && j.minAmount !== 0) j.minAmount = row.minAmount
+            if (!j.maxAmount && j.maxAmount !== 0) j.maxAmount = row.maxAmount
+            j.payType = row.code
+            data.push(j)
+        })
+        bankDate.value = data
+    } else {
+        $pigeon.MessageError(res.msg)
+    }
+}
+
+const cancelBank = () => {
+    dialogNewBank.value = false
+    // 重置 params 表单
+    Object.assign(params, {
+        bankCardNum: "",
+        bankUname: "",
+        bankName: "",
+        bankBranchName: "",
+        bankAddr: "",
+        swiftCode: "",
+        bankFront: "",
+        bankBack: "",
+        defaultBank: false
+    })
+}
+
+// ---------- 生命周期 ----------
+onMounted(() => {
+    if (getInfoStatus5.value) {
+        InfoStatus5.value = true
+        return
+    }
+    getFreeNumber()
+    isShowDialog()
+    // getDateList()
+    getDepositList()
+})
+
+// 监听 value 变化
+watch(loginValue, (newVal) => {
+    if (newVal) {
+        step2.value = true
+        showTable()
+    }
+})
+
+// 监听 form.amount 变化
+watch(() => form.amount, (newVal) => {
+    if (newVal && channelData.value.rate) {
+        form.amount1 = (newVal * channelData.value.rate).toFixed(2)
+    }
+})
 </script>
+
 <style lang="scss" scoped>
 @import "@/uni.scss";
+
+.custom-withdraw {
+
+    .box {
+        margin-bottom: px2rpx(20);
+
+        .b-card {
+            background: #fff;
+            border-radius: px2rpx(12);
+            padding: px2rpx(20);
+            box-shadow: 0 px2rpx(4) px2rpx(12) rgba(0, 0, 0, 0.03);
+
+            .card-top {
+                .tit {
+                    font-size: px2rpx(16);
+                    font-weight: 600;
+                    margin-bottom: px2rpx(16);
+                    display: flex;
+                    align-items: center;
+                    color: var(--color-navy-900);
+                    position: relative;
+                    padding-left: 20px;
+
+                    &:after {
+                        content: '';
+                        position: absolute;
+                        left: 0;
+                        top: 50%;
+                        transform: translateY(-50%);
+                        width: 0;
+                        height: 0;
+                        border-top: 6px solid transparent;
+                        border-bottom: 6px solid transparent;
+                        border-left: 8px solid currentColor;
+                    }
+
+                    .iconfont {
+                        margin-right: px2rpx(8);
+                        color: var(--color-primary);
+                        font-size: px2rpx(18);
+                    }
+                }
+            }
+
+            .channelType {
+                font-size: px2rpx(15);
+                font-weight: 600;
+                margin: px2rpx(24) 0 px2rpx(12);
+                color: var(--color-navy-700);
+                padding-left: px2rpx(8);
+                border-left: px2rpx(4) solid var(--color-primary);
+            }
+        }
+    }
+
+    .reselect-btn {
+        margin-top: px2rpx(20);
+        display: flex;
+        justify-content: flex-end;
+    }
+
+    .s-btn {
+        &.reselect {
+            background-color: var(--color-zinc-100);
+            color: var(--color-navy-700);
+            border: none;
+            font-size: px2rpx(14);
+            padding: px2rpx(8) px2rpx(20);
+            border-radius: px2rpx(8);
+
+            &:active {
+                background-color: var(--color-zinc-200);
+            }
+        }
+
+        &[type="primary"] {
+            width: 100%;
+            height: px2rpx(48);
+            background: var(--color-navy-900);
+            color: #fff;
+            border-radius: px2rpx(12);
+            font-size: px2rpx(16);
+            font-weight: 600;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            border: none;
+            margin-top: px2rpx(30);
+            transition: all 0.2s;
+
+            &:active {
+                transform: scale(0.98);
+                background: var(--color-navy-800);
+            }
+        }
+    }
+
+    .add-back {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        margin-bottom: px2rpx(12);
+        padding: px2rpx(12) px2rpx(16);
+        background: var(--color-zinc-100);
+        border-radius: px2rpx(8);
+
+        text {
+            font-size: px2rpx(14);
+            color: var(--color-navy-700);
+            font-weight: 500;
+        }
+
+        .add-btn {
+            color: var(--color-primary);
+            font-weight: 600;
+            text-decoration: underline;
+
+            &:active {
+                opacity: 0.7;
+            }
+        }
+    }
+
+    .proof {
+        margin-top: px2rpx(8);
+        border: px2rpx(1) dashed var(--color-zinc-300);
+        border-radius: px2rpx(8);
+        padding: px2rpx(8);
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        background: var(--color-zinc-50);
+
+        .state {
+            padding: px2rpx(4) px2rpx(12);
+            border-radius: px2rpx(4);
+            font-size: px2rpx(12);
+            font-weight: bold;
+        }
+    }
+
+    .agree {
+        margin: px2rpx(24) 0;
+        display: flex;
+        align-items: flex-start;
+
+        .checkbox {
+            display: flex;
+            align-items: flex-start;
+            gap: px2rpx(8);
+
+            :deep(uni-checkbox .uni-checkbox-input) {
+                border-radius: px2rpx(4);
+                width: px2rpx(18);
+                height: px2rpx(18);
+            }
+
+            text {
+                font-size: px2rpx(13);
+                color: var(--color-zinc-500);
+                line-height: 1.5;
+            }
+        }
+    }
+
+    .step3-attention {
+        // background: var(--color-error-50, #fff1f0);
+        border-radius: px2rpx(12);
+        margin-bottom: px2rpx(20);
+
+        .tips {
+            line-height: 1.8;
+            font-size: px2rpx(12);
+            color: #909399;
+            background-color: #f9f9f9;
+            padding: px2rpx(12);
+            border-radius: px2rpx(4);
+            border-left: px2rpx(2) solid #409eff;
+
+            .title {
+                font-weight: 600;
+                margin-bottom: px2rpx(6);
+                color: #606266;
+            }
+        }
+
+        .attention {
+            font-size: px2rpx(14);
+            //  color: var(--color-error-600, #cf1322);
+            line-height: 1.6;
+        }
+
+        .btn-bottom {
+            margin-top: px2rpx(20);
+            display: flex;
+            justify-content: center;
+
+            .btn {
+                background: var(--color-error-600, #cf1322);
+                color: #fff;
+                padding: px2rpx(10) px2rpx(48);
+                border-radius: px2rpx(24);
+                font-size: px2rpx(15);
+                font-weight: 700;
+                box-shadow: 0 px2rpx(4) px2rpx(10) rgba(207, 19, 34, 0.2);
+                transition: all 0.2s;
+
+                &:active {
+                    transform: scale(0.96);
+                    opacity: 0.8;
+                }
+            }
+        }
+    }
+
+    :deep(.base-info-form) {
+        .uni-row1 {
+            .uni-col {
+                padding: 0 px2rpx(10) !important;
+            }
+
+            .uni-forms-item {
+                min-height: px2rpx(79);
+                margin-bottom: px2rpx(10);
+            }
+
+            .uni-select,
+            .uni-combox,
+            .uni-easyinput__content,
+            .uni-date-editor--x {
+                border: none !important;
+                background-color: var(--color-zinc-100) !important;
+                border-radius: px2rpx(8) !important;
+            }
+
+            .uni-date-x {
+                border: none !important;
+                background-color: rgba(195, 195, 195, 0) !important;
+            }
+
+            .uni-easyinput__content-input {
+                height: px2rpx(44) !important;
+            }
+        }
+    }
+
+    @keyframes rotate {
+        from {
+            transform: rotate(0deg);
+        }
+
+        to {
+            transform: rotate(360deg);
+        }
+    }
+}
 </style>