Explorar el Código

feature: 补充钱包地址页面

ljc hace 5 meses
padre
commit
a27fdb5efc

+ 9 - 0
src/service/ucard.ts

@@ -1,6 +1,7 @@
 import Service from '../lib/service.js'
 import axios from 'axios'
 import Config from '../config'
+import { withLoading } from '@/utils/requestLoading'
 
 class UCardService extends Service {
   constructor() {
@@ -371,6 +372,14 @@ class UCardService extends Service {
   async getCard3DSTransactionPage(params = {}) {
     return await this.post('/wasabi/card/3ds/transaction/page', params)
   }
+  // 钱包地址列表
+  async getDepositAddressPage(params = {}) {
+    return await this.post('/ucard/wallet/address/page', params)
+  }
+  // 重置钱包地址
+  async restDepositAddress(params = {}) {
+    return await withLoading(() => this.post('/ucard/wallet/address/reset', params))
+  }
 }
 
 export default new UCardService()

+ 34 - 0
src/utils/requestLoading.ts

@@ -0,0 +1,34 @@
+// 封装全局请求 loading 控制
+
+import { ElLoading } from 'element-plus'
+
+let loadingInstance = null
+
+export function showLoading(text = '') {
+  if (!loadingInstance) {
+    loadingInstance = ElLoading.service({
+      lock: true,
+      text,
+      spinner: 'el-icon-loading',
+      background: 'rgba(43, 48, 67, 0.65)',
+    })
+  }
+}
+
+export function hideLoading() {
+  if (loadingInstance) {
+    loadingInstance.close()
+    loadingInstance = null
+  }
+}
+
+// 通用封装:包装一个异步函数,自动显示/隐藏 loading
+export async function withLoading(fn, text = '') {
+  showLoading(text)
+  try {
+    const res = await fn()
+    return res
+  } finally {
+    hideLoading()
+  }
+}

+ 334 - 3
src/views/card/CardDepositAddress/index.vue

@@ -1,5 +1,336 @@
-<script setup lang="ts"></script>
+<template>
+  <div
+    id="card_DepositAddress"
+    v-loading="pictLoading"
+    class="view"
+    element-loading-background="rgba(43, 48, 67, 0.65)"
+    element-loading-spinner="el-icon-loading"
+  >
+    <div class="crm_search">
+      <el-form ref="formRef" :model="search" label-width="">
+        <el-row>
+          <el-col :span="24" :md="24" :lg="24">
+            <el-form-item>
+              <el-select
+                v-model="search.tag"
+                class="crm_search_down crm-border-radius-no"
+                :placeholder="t('Placeholder.Choose')"
+              >
+                <el-option
+                  v-for="tag in tagOptions"
+                  :key="tag.value"
+                  :label="t(tag.label)"
+                  :value="tag.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+            <el-form-item style="margin-right: 10px">
+              <el-input
+                v-if="search.tag === 1"
+                v-model.trim="search.cId"
+                class="crm-border-left-no crm-border-radius-no"
+                clearable
+                :placeholder="t('Placeholder.Input')"
+                @keyup.enter="toSearch"
+              ></el-input>
+              <el-input
+                v-if="search.tag === 2"
+                v-model.trim="search.mobile"
+                class="crm-border-left-no crm-border-radius-no"
+                clearable
+                :placeholder="t('Placeholder.Input')"
+                @keyup.enter="toSearch"
+              ></el-input>
+              <el-input
+                v-if="search.tag === 3"
+                v-model.trim="search.email"
+                class="crm-border-left-no crm-border-radius-no"
+                clearable
+                :placeholder="t('Placeholder.Input')"
+                @keyup.enter="toSearch"
+              ></el-input>
+            </el-form-item>
+            <el-form-item>
+              <el-select
+                v-model="search.isReset"
+                class="crm-border-radius-no"
+                clearable
+                :placeholder="t('Ucard.DepositAddress.s1')"
+                @change="toSearch"
+              >
+                <el-option
+                  v-for="(value, key) in restStatus"
+                  :key="key"
+                  :label="t(value)"
+                  :value="key"
+                />
+              </el-select>
+            </el-form-item>
+            <el-form-item>
+              <el-button
+                class="crm-border-radius-no crm-border-left-no"
+                :icon="Search"
+                @click="toSearch"
+              ></el-button>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </div>
+    <el-table :data="tableData" stripe style="width: 100%">
+      <el-table-column prop="" align="left" :label="t('Label.CidAccount')">
+        <template #default="scope">
+          <span>{{ scope.row.cId || '--' }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="name" align="left" :label="t('Label.Name')">
+        <template #default="scope">
+          <span v-if="scope.row.firstName">
+            {{ scope.row.firstName + ' ' }}
+          </span>
+          <span v-if="scope.row.middle">{{ scope.row.middle + ' ' }}</span>
+          <span v-if="scope.row.lastName">{{ scope.row.lastName }}</span>
+          <span v-if="!scope.row.firstName && !scope.row.lastName && !scope.row.middle">{{
+            '--'
+          }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="mobile" align="left" :label="t('Label.Mobile')">
+        <template #default="scope"> {{ scope.row.areaCode }} {{ scope.row.mobile }} </template>
+      </el-table-column>
+      <el-table-column prop="email" align="left" :label="t('Label.Email')">
+        <template #default="scope">
+          {{ scope.row.email || '--' }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="blockchain" align="left" :label="t('Ucard.Blockchain.pageT2')">
+        <template #default="scope">
+          {{ scope.row.blockchain || '--' }}
+        </template>
+      </el-table-column>
+      <!--			<el-table-column prop="country" align="left" :label="t('Ucard.DepositAddress.p1')">-->
+      <!--				<template #default="scope">-->
+      <!--					{{ scope.row.country || "&#45;&#45;" }}-->
+      <!--				</template>-->
+      <!--			</el-table-column>-->
+      <el-table-column prop="address" align="left" :label="t('Ucard.DepositAddress.p2')">
+        <template #default="scope">
+          {{ scope.row.address || '--' }}
+        </template>
+      </el-table-column>
+      <el-table-column
+        prop="linkAddressRequestId"
+        align="left"
+        :label="t('Ucard.DepositAddress.p3')"
+      >
+        <template #default="scope">
+          {{ scope.row.linkAddressRequestId || '--' }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="isReset" align="left" :label="t('Ucard.DepositAddress.s1')">
+        <template #default="scope">
+          {{ t(restStatus[scope.row.isReset ? 1 : 0]) || '--' }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="ctrl" align="center" :label="t('Label.Action')">
+        <template #default="scope">
+          <el-dropdown
+            v-if="display['R-Card-Deposit-Address-Rest']?.show && !scope.row.isReset"
+            trigger="click"
+            @command="handleCommand"
+          >
+            <span class="el-dropdown-link crm-cursor">
+              <el-icon style="font-weight: bold; font-size: 20px">
+                <MoreFilled />
+              </el-icon>
+            </span>
+            <el-dropdown-menu>
+              <el-dropdown-item :command="{ type: 'rest', row: scope.row }">
+                <el-icon><Refresh /></el-icon>
+                <span>{{ t('R-Card-Deposit-Address-Rest') }}</span>
+              </el-dropdown-item>
+            </el-dropdown-menu>
+          </el-dropdown>
+        </template>
+      </el-table-column>
+    </el-table>
+    <PagePagination
+      :pager-info="pagerInfo"
+      @current-change="handleCurrentChange"
+      @size-change="handleSizeChange"
+    />
+  </div>
+</template>
 
-<template>1</template>
+<script setup>
+  import { ref, computed, onMounted, watch, inject } from 'vue'
+  import { Search, MoreFilled, Refresh } from '@element-plus/icons-vue'
+  import Service from '@/service/ucard'
+  import Config from '@/config/index'
+  import { restStatus } from '@/enum/enum.ts'
+  import PagePagination from '@/components/pagePagination/index.vue'
+  import { useI18n } from 'vue-i18n'
+  import { ElMessageBox } from 'element-plus'
 
-<style scoped lang="scss"></style>
+  const { t } = useI18n()
+  const Session = inject('session')
+  const pigeon = inject('pigeon')
+
+  const { Code } = Config
+
+  // 标签选项
+  const tagOptions = [
+    { value: 1, label: 'Label.CidAccount' },
+    { value: 2, label: 'Ucard.KycAuth.item2' },
+    { value: 3, label: 'Ucard.KycAuth.item3' },
+  ]
+
+  const pictLoading = ref(false)
+  const tableData = ref([])
+  const formRef = ref(null)
+  const search = ref({
+    tag: 1,
+    cId: '',
+    email: '',
+    mobile: '',
+    isReset: '',
+  })
+  const pagerInfo = ref({
+    row: 10,
+    current: 1,
+    pageTotal: 0,
+    rowTotal: 0,
+  })
+
+  // 权限控制
+  const display = computed(() => {
+    return JSON.parse(Session.Get('display', true))
+  })
+
+  // 获取列表数据
+  const searchFunc = async () => {
+    pictLoading.value = true
+
+    if (!display.value['R-Card-Deposit-Address-Page']?.show) {
+      pigeon.warning(t('Msg.NotDisplay'))
+      pictLoading.value = false
+      return
+    }
+
+    try {
+      const res = await Service.getDepositAddressPage({
+        ...search.value,
+        page: {
+          current: pagerInfo.value.current,
+          row: pagerInfo.value.row,
+        },
+      })
+
+      if (res.code == Code.StatusOK) {
+        tableData.value = res.data
+        if (res.page != null) {
+          pagerInfo.value.rowTotal = res.page.rowTotal
+          pagerInfo.value.pageTotal = res.page.pageTotal
+        } else {
+          pagerInfo.value.rowTotal = 0
+        }
+        pigeon.success(t('Msg.SearchSuccess'))
+      } else {
+        pigeon.error(res.msg)
+      }
+    } catch (error) {
+      console.error('Search error:', error)
+    } finally {
+      pictLoading.value = false
+    }
+  }
+
+  // 搜索
+  const toSearch = () => {
+    pagerInfo.value.current = 1
+    searchFunc()
+  }
+
+  // 分页处理
+  const handleSizeChange = (val) => {
+    pagerInfo.value.row = val
+    searchFunc()
+  }
+
+  const handleCurrentChange = (val) => {
+    pagerInfo.value.current = val
+    searchFunc()
+  }
+
+  // 重置地址
+  const restAddress = async (row) => {
+    ElMessageBox.confirm(t('Ucard.DepositAddress.t1'), t('Msg.SystemPrompt'), {
+      confirmButtonText: t('Btn.Confirm'),
+      cancelButtonText: t('Btn.Cancel'),
+      type: 'warning',
+    })
+      .then(async () => {
+        try {
+          const res = await Service.restDepositAddress({ id: row.id, isReset: true })
+          if (res.code == Code.StatusOK) {
+            pigeon.success(t('Msg.Success'))
+            searchFunc()
+          } else {
+            pigeon.error(res.msg)
+          }
+        } catch (error) {
+          console.error(error)
+        }
+      })
+      .catch(() => {
+        // 用户取消操作
+      })
+  }
+
+  // 处理下拉菜单命令
+  const handleCommand = (command) => {
+    if (command.type === 'rest') {
+      restAddress(command.row)
+    }
+  }
+
+  onMounted(() => {
+    searchFunc()
+  })
+
+  // 监听标签变化
+  watch(
+    () => search.value.tag,
+    () => {
+      search.value.cId = ''
+      search.value.email = ''
+      search.value.mobile = ''
+    }
+  )
+</script>
+
+<style scoped lang="scss">
+  #card_DepositAddress {
+    .crm_search {
+      .search_action_btn {
+        .delete {
+          background-color: #a1a1a1;
+        }
+
+        .delete.active {
+          background-color: #368fec;
+        }
+      }
+    }
+  }
+</style>
+
+<style lang="scss">
+  #card_DepositAddress {
+    .dialog_header_w {
+      .crm_search_down {
+        width: 400px;
+      }
+    }
+  }
+</style>

+ 1 - 0
src/views/card/CardTransactions/index.vue

@@ -258,6 +258,7 @@
   const { Code } = Config
   const { t } = useI18n()
   const Session = inject('session')
+  const pigeon = inject('pigeon')
   const router = useRouter()
 
   // 响应式数据

+ 0 - 2
src/views/home2/Home.vue

@@ -253,11 +253,9 @@
   const initDisplay = () => {
     let display = {}
     const userData = safeGetUser(session)
-    console.log(userData.display, '2')
     if (userData && userData.display) {
       userData.display.forEach((item) => {
         item.children?.forEach((item1) => {
-          console.log(item1)
           item1.children = item1.btns ? Object.values(item1.btns) : []
           item1?.children.forEach((item2) => {
             display[item2.code] = item2