|
|
@@ -0,0 +1,372 @@
|
|
|
+<template>
|
|
|
+ <div id="CardDetail" class="InfoBox">
|
|
|
+ <!-- 银行卡基础信息 -->
|
|
|
+ <div class="info">
|
|
|
+ <el-card class="card card-info" shadow="hover">
|
|
|
+ <div class="card-icon">
|
|
|
+ <div>
|
|
|
+ <img class="icon-visa" src="@/assets/image/card/icon-visa.png" />
|
|
|
+ </div>
|
|
|
+ <!-- 可能会有图标 -->
|
|
|
+ <div class="icon-type">{{ detail.type }}</div>
|
|
|
+ </div>
|
|
|
+ <div class="card-number">
|
|
|
+ {{ detail.cardNumber }}
|
|
|
+ <span>
|
|
|
+ <el-icon class="cur-p ml5" @click="copy(detail.cardNumber)"><Document /></el-icon>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ <div class="card-other-info">
|
|
|
+ <div>
|
|
|
+ <div class="other-title">{{ t('card.Detail.thru') }}</div>
|
|
|
+ <div class="other-info">{{ detail.expireDate }}</div>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <div class="other-title">CVV</div>
|
|
|
+ <div class="other-info">
|
|
|
+ <span v-if="detail.expireDate" class="cvv" @click="getQueryCvv()">
|
|
|
+ ***
|
|
|
+ <el-icon><View /></el-icon>
|
|
|
+ <i class="el-icon-view" />
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="card-user-name">{{ `${detail.firstName} ${detail.lastName}` }}</div>
|
|
|
+ </div>
|
|
|
+ <div class="card-type">
|
|
|
+ <i
|
|
|
+ v-if="detail.freezeType == 1 && detail.freezeStatus != 'success'"
|
|
|
+ class="el-icon-lock state_yellow"
|
|
|
+ style="margin-right: 5px"
|
|
|
+ />
|
|
|
+ <i v-else class="el-icon-unlock state_blue" style="margin-right: 5px" />
|
|
|
+ <template v-if="detail.freezeType == 1">
|
|
|
+ <!-- 正常 -->
|
|
|
+ <span v-if="detail.freezeStatus == 'success'" class="state_blue">
|
|
|
+ {{ t('Ucard.VirtualCard.t7') }}
|
|
|
+ </span>
|
|
|
+ <!-- 解冻失败 -->
|
|
|
+ <span v-else-if="detail.freezeStatus == 'fail'" class="state_yellow">
|
|
|
+ {{ t('card.Btn.b19') }}
|
|
|
+ </span>
|
|
|
+ <!-- 解冻处理中 -->
|
|
|
+ <span v-else class="state_yellow">
|
|
|
+ {{ t('card.Btn.b21') }}
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <!-- 冻结 -->
|
|
|
+ <span v-if="detail.freezeStatus == 'success'" class="state_yellow">
|
|
|
+ {{ t('Ucard.VirtualCard.t8') }}
|
|
|
+ </span>
|
|
|
+ <!-- 解冻失败 -->
|
|
|
+ <span v-else-if="detail.freezeStatus == 'fail'" class="state_yellow">
|
|
|
+ {{ t('card.Btn.b20') }}
|
|
|
+ </span>
|
|
|
+ <!-- 冻结处理中 -->
|
|
|
+ <span v-else class="state_yellow">
|
|
|
+ {{ t('card.Btn.b22') }}
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ <el-card class="card base-info" shadow="hover">
|
|
|
+ <div class="card-base-title">
|
|
|
+ <div class="title">{{ t('Ucard.PaymentTransfer.item6') }}</div>
|
|
|
+ <div class="card-tag">
|
|
|
+ <div v-if="detail.status === 'unactivate'" class="state crm_state_gray">
|
|
|
+ {{ t('Ucard.VirtualCard.t9') }}
|
|
|
+ </div>
|
|
|
+ <div v-else-if="detail.status === 'success'" class="state crm_state_blue">
|
|
|
+ {{ t('Ucard.VirtualCard.t6') }}
|
|
|
+ </div>
|
|
|
+ <div v-else-if="detail.status === 'fail'" class="state crm_state_gray">
|
|
|
+ {{ t('Ucard.VirtualCard.t10') }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="card-base-info">
|
|
|
+ <div class="money flex1">
|
|
|
+ <div class="money-title">
|
|
|
+ <div>{{ t('Documentary.console.item15') }}</div>
|
|
|
+ <span>
|
|
|
+ <i
|
|
|
+ class="iconfont iconshuaxin1 icon-refresh"
|
|
|
+ style="font-weight: bold; font-size: 20px"
|
|
|
+ @click="getMoney"
|
|
|
+ ></i>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ <div class="money-num">$ {{ NumberDecimal(canUseMoney) }}</div>
|
|
|
+ </div>
|
|
|
+ <div class="info1 flex1">
|
|
|
+ <div class="info-box">
|
|
|
+ <div class="info-title">
|
|
|
+ {{ t('card.Detail.cardUserName') }}
|
|
|
+ </div>
|
|
|
+ <div class="info-text mr10">
|
|
|
+ {{ detail.firstName }}
|
|
|
+ <span>
|
|
|
+ <el-icon class="cur-p ml5" @click="copy(detail.firstName)">
|
|
|
+ <CopyDocument />
|
|
|
+ </el-icon>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ <div class="info-text">
|
|
|
+ {{ detail.lastName }}
|
|
|
+ <span>
|
|
|
+ <el-icon class="cur-p ml5" @click="copy(detail.lastName)">
|
|
|
+ <CopyDocument />
|
|
|
+ </el-icon>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="info-box">
|
|
|
+ <div class="info-title">
|
|
|
+ {{ t('card.Detail.address') }}
|
|
|
+ </div>
|
|
|
+ <div class="info-text">
|
|
|
+ {{ detail.realAddress }}
|
|
|
+ <span>
|
|
|
+ <el-icon class="cur-p ml5" @click="copy(detail.realAddress)">
|
|
|
+ <CopyDocument />
|
|
|
+ </el-icon>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="info1 flex1">
|
|
|
+ <div class="info-box">
|
|
|
+ <div class="info-title">
|
|
|
+ {{ t('card.Detail.email') }}
|
|
|
+ </div>
|
|
|
+ <div class="info-text">
|
|
|
+ {{ detail.email }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="info-box">
|
|
|
+ <div class="info-title">
|
|
|
+ {{ t('card.Detail.phone') }}
|
|
|
+ </div>
|
|
|
+ <div class="info-text">
|
|
|
+ {{ `${detail.areaCode} ${detail.mobile}` }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- cvv弹窗 -->
|
|
|
+ <el-dialog v-model="dialogCheckCvv" title="CVV" center class="dialog_header_w">
|
|
|
+ <div class="dia-content">
|
|
|
+ <el-form
|
|
|
+ :rules="rules"
|
|
|
+ :model="cvvForm"
|
|
|
+ label-width="130px"
|
|
|
+ label-position="right"
|
|
|
+ class="business-edit-form"
|
|
|
+ >
|
|
|
+ <el-form-item prop="gaCode" :label="t('getCode.R-GoogleSecretKey')">
|
|
|
+ <el-input
|
|
|
+ v-model="cvvForm.gaCode"
|
|
|
+ size="small"
|
|
|
+ :placeholder="t('Placeholder.Input')"
|
|
|
+ ></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item v-if="cvvForm.cvv" prop="cvv" label="CVV">
|
|
|
+ <el-input
|
|
|
+ v-model="cvvForm.cvv"
|
|
|
+ size="small"
|
|
|
+ :placeholder="t('Placeholder.Input')"
|
|
|
+ ></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </div>
|
|
|
+ <template #footer>
|
|
|
+ <div class="dialog-footer">
|
|
|
+ <el-button @click="cancel1">{{ t('Btn.Cancel') }}</el-button>
|
|
|
+ <el-button v-if="!cvvForm.cvv" type="primary" @click="queryCvv()">
|
|
|
+ {{ t('Btn.Confirm') }}
|
|
|
+ </el-button>
|
|
|
+ <el-button v-if="cvvForm.cvv" type="primary" @click="copyCvv()">
|
|
|
+ {{ t('Label.Copy') }}
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+ <div style="padding: 0 20px; margin-top: 20px">
|
|
|
+ <el-card class="financial-tab-card" shadow="hover">
|
|
|
+ <div class="tab-content">
|
|
|
+ <el-tabs v-model="activeTab" type="card" @tab-click="handleTabClick">
|
|
|
+ <el-tab-pane v-for="tab in tabs" :key="tab.name" :label="tab.label" :name="tab.name">
|
|
|
+ <component
|
|
|
+ :is="tab.component"
|
|
|
+ v-if="activeTab === tab.name && detail.cardNumber"
|
|
|
+ :card-number="detail.cardNumber"
|
|
|
+ />
|
|
|
+ </el-tab-pane>
|
|
|
+ </el-tabs>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+ import { ref, reactive, computed, onMounted, inject, defineAsyncComponent } from 'vue'
|
|
|
+ import { useI18n } from 'vue-i18n'
|
|
|
+ import { useRoute } from 'vue-router'
|
|
|
+ import { ElMessage } from 'element-plus'
|
|
|
+ import Service from '@/service/ucard'
|
|
|
+ import Config from '@/config/index'
|
|
|
+ import { copyText } from '@/utils/utils'
|
|
|
+ import { CopyDocument, Document, View } from '@element-plus/icons-vue'
|
|
|
+ import { NumberDecimal } from '@/utils/filter'
|
|
|
+
|
|
|
+ const { Code } = Config
|
|
|
+ const { t } = useI18n()
|
|
|
+ const route = useRoute()
|
|
|
+ const Session = inject('session')
|
|
|
+ const pigeon = inject('pigeon')
|
|
|
+
|
|
|
+ // 响应式数据
|
|
|
+ const detail = ref({})
|
|
|
+ const activeTab = ref('Recharge')
|
|
|
+ const dialogCheckCvv = ref(false)
|
|
|
+ const canUseMoney = ref('')
|
|
|
+ const cvvForm = reactive({
|
|
|
+ gaCode: undefined,
|
|
|
+ cvv: undefined,
|
|
|
+ id: undefined,
|
|
|
+ })
|
|
|
+
|
|
|
+ // 计算属性
|
|
|
+ const display = computed(() => {
|
|
|
+ return JSON.parse(Session.Get('display', true))
|
|
|
+ })
|
|
|
+
|
|
|
+ const user = computed(() => {
|
|
|
+ return JSON.parse(Session.Get('user', true))
|
|
|
+ })
|
|
|
+
|
|
|
+ const rules = computed(() => ({
|
|
|
+ gaCode: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: t('vaildate.input.empty'),
|
|
|
+ trigger: 'blur',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ }))
|
|
|
+
|
|
|
+ const tabs = computed(() => [
|
|
|
+ {
|
|
|
+ name: 'Recharge',
|
|
|
+ label: t('card.tab7'),
|
|
|
+ component: defineAsyncComponent(() =>
|
|
|
+ import('@/views/card/components/CardDetailRecharge/index.vue')
|
|
|
+ ),
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'Transaction',
|
|
|
+ label: t('card.Detail.tab1'),
|
|
|
+ component: defineAsyncComponent(() =>
|
|
|
+ import('@/views/card/components/CardDetailTransactions/index.vue')
|
|
|
+ ),
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'Withdraw',
|
|
|
+ label: t('card.Detail.tab3'),
|
|
|
+ component: defineAsyncComponent(() =>
|
|
|
+ import('@/views/card/components/CardDetailWithdraw/index.vue')
|
|
|
+ ),
|
|
|
+ },
|
|
|
+ ])
|
|
|
+
|
|
|
+ // 方法
|
|
|
+ const cancel1 = () => {
|
|
|
+ dialogCheckCvv.value = false
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取银行卡详情
|
|
|
+ const getDetailByCardNumber = async (cardNumber) => {
|
|
|
+ const res = await Service.getCardDetails({ cardNumber })
|
|
|
+ if (res.code == Code.StatusOK) {
|
|
|
+ const { data } = res
|
|
|
+ detail.value = {
|
|
|
+ realAddress:
|
|
|
+ Session.Get('lang') == 'cn'
|
|
|
+ ? `${data.countryCnName} ${data.addressCn}`
|
|
|
+ : `${data.countryEnName} ${data.address}`,
|
|
|
+ ...data,
|
|
|
+ }
|
|
|
+ getMoney()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const getMoney = async () => {
|
|
|
+ if (!detail.value.uniqueId || !detail.value.cardNo) return
|
|
|
+
|
|
|
+ const params = { uniqueId: detail.value.uniqueId, cardNo: detail.value.cardNo }
|
|
|
+ const res = await Service.ucardBalance(params)
|
|
|
+ if (res.code == Code.StatusOK) {
|
|
|
+ canUseMoney.value = res.data.amount
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const getQueryCvv = () => {
|
|
|
+ dialogCheckCvv.value = true
|
|
|
+ Object.assign(cvvForm, {
|
|
|
+ gaCode: undefined,
|
|
|
+ cvv: undefined,
|
|
|
+ id: detail.value.id,
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询cvv
|
|
|
+ const queryCvv = async () => {
|
|
|
+ const res = await Service.queryCvv({ ...cvvForm })
|
|
|
+ if (res.code == Code.StatusOK) {
|
|
|
+ cvvForm.cvv = res.data
|
|
|
+ } else {
|
|
|
+ ElMessage.error(res.msg)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const copyCvv = () => {
|
|
|
+ copy(cvvForm.cvv)
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleTabClick = (e) => {
|
|
|
+ console.log(e, 12)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 复制到剪切板
|
|
|
+ const copy = (str) => {
|
|
|
+ copyText(str)
|
|
|
+ ElMessage.success(t('Dashboard.Profile.CopySuccess'))
|
|
|
+ }
|
|
|
+
|
|
|
+ // 生命周期
|
|
|
+ onMounted(() => {
|
|
|
+ // 如果是页面形式,自动根据路由参数加载详情
|
|
|
+ if (route?.params?.cardNumber) {
|
|
|
+ getDetailByCardNumber(route.params.cardNumber)
|
|
|
+ }
|
|
|
+ })
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+ @import 'index.scss';
|
|
|
+</style>
|
|
|
+<style lang="scss">
|
|
|
+ #CardDetail.InfoBox {
|
|
|
+ .dialog_header_w {
|
|
|
+ .crm_search_down {
|
|
|
+ width: 400px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+</style>
|