Kaynağa Gözat

feat:币种,所属区块链筛选

ljc 1 ay önce
ebeveyn
işleme
41b7316a43

+ 2 - 2
.env.development

@@ -1,6 +1,6 @@
 # 与 gypsy-crm-frontend-admin 开发环境默认 Host 对齐,可按环境修改
 # VITE_API_HOST82=https://ad.44a5c8109e4.com
-#VITE_API_HOST82=http://103.158.191.66:9300
-VITE_API_HOST82=http://192.168.0.25:9300
+VITE_API_HOST82=http://103.158.191.66:9300
+#VITE_API_HOST82=http://192.168.0.25:9300
 #VITE_API_HOST82=http://192.168.0.22:9300
 VITE_API_HOST80=https://secure.44a5c8109e4.com

+ 1 - 0
src/locales/en-US.ts

@@ -69,5 +69,6 @@ export default {
     colFee: 'Network fee',
     colFeeUnit: 'Fee asset',
     colTxId: 'Transaction hash',
+    Unit: 'Unit',
   },
 }

+ 1 - 0
src/locales/zh-CN.ts

@@ -65,5 +65,6 @@ export default {
     colFee: '区块链手续费',
     colFeeUnit: '手续费币种',
     colTxId: '链上交易哈希',
+    Unit: '币种',
   },
 }

+ 4 - 0
src/service/vault.ts

@@ -16,6 +16,8 @@ export interface FetchVaultTransactionsBody {
   recipientAddress?: string | null
   startTime?: string | null
   endTime?: string | null
+  blockchain?: string | null
+  unit?: string | null
   /** 页码,从 1 开始 */
   page?: {
     current?: number
@@ -36,6 +38,8 @@ function buildVaultTransactionsPayload(body: FetchVaultTransactionsBody): Record
     payload.recipientAddress = body.recipientAddress
   if (body.startTime != null) payload.startTime = body.startTime
   if (body.endTime != null) payload.endTime = body.endTime
+  if (body.blockchain != null && String(body.blockchain).trim() !== '') payload.blockchain = body.blockchain
+  if (body.unit != null && String(body.unit).trim() !== '') payload.unit = body.unit
   if (body.page != null) payload.page = body.page
   return payload
 }

+ 100 - 76
src/views/Vault/vaultList.vue

@@ -1,12 +1,12 @@
 <script setup lang="ts">
-import { computed, h, onMounted, reactive, ref, watch } from 'vue'
-import type { DataTableColumns } from 'naive-ui'
-import { ApiCode } from '@/config'
-import { exportVaultTransactions, fetchVaultTransactions } from '@/service/vault'
-import { useVaultStore } from '@/store/vault'
-import type { VaultTransactionItem } from '@/types/vault'
-
-const { t } = useI18n()
+import {computed, h, onMounted, reactive, ref, watch} from 'vue'
+import type {DataTableColumns} from 'naive-ui'
+import {ApiCode} from '@/config'
+import {exportVaultTransactions, fetchVaultTransactions} from '@/service/vault'
+import {useVaultStore} from '@/store/vault'
+import type {VaultTransactionItem} from '@/types/vault'
+
+const {t} = useI18n()
 const message = useMessage()
 const vault = useVaultStore()
 
@@ -39,14 +39,29 @@ const filters = reactive<{
   senderAddress: string | null
   recipientAddress: string | null
   timeRange: [number, number] | null
+  blockchain: string | null
+  unit: string | null
 }>({
   senderLabel: null,
   recipientLabel: null,
   senderAddress: null,
   recipientAddress: null,
   timeRange: null,
+  blockchain: null,
+  unit: null,
 })
 
+const blockchainOptions = computed(() => [
+  {label: 'ethereum', value: 'ethereum'},
+  {label: 'tron', value: 'tron'},
+])
+
+const unitOptions = computed(() => [
+  {label: 'TRX', value: 'TRX'},
+  {label: 'USDT', value: 'USDT'},
+  {label: 'USDC', value: 'USDC'},
+])
+
 function formatDash(v: unknown): string {
   if (v == null || v === '') return '—'
   return String(v)
@@ -86,7 +101,7 @@ function formatTimestamp(v: string | number | undefined): string {
 
 /** 各列 width 之和,供 scroll-x 使用,保证超出视口时可横向滚动看全列 */
 const VAULT_TX_COL_WIDTHS = [
-  120, 186, 200, 160,/* 120,*/ 96, 140, 200, 160, /*120,*/ 96, 140, 120, 112, 128, 96, 260,
+  120, 200, 160,/* 120,*/ 96, 140, 200, 160, /*120,*/ 96, 140, 112, 128, 96, 120, 186, 260,
 ] as const
 
 const tableScrollX = VAULT_TX_COL_WIDTHS.reduce((a, w) => a + w, 0) + 120
@@ -94,23 +109,14 @@ const tableScrollX = VAULT_TX_COL_WIDTHS.reduce((a, w) => a + w, 0) + 120
 /** 表头与单元格均居中(titleAlign / align: center) */
 const columns = computed<DataTableColumns<VaultTransactionItem>>(() => [
   {
-    title: () => t('vaultTx.colStatus'),
-    key: 'status',
+    title: () => t('vaultTx.colBlockchain'),
+    key: 'blockchain',
     width: 120,
     titleAlign: 'center',
     align: 'center',
-    ellipsis: { tooltip: true },
+    ellipsis: {tooltip: true},
     render: (row) =>
-      h('span', { class: 'vault-tx__cell-text vault-tx__cell-status' }, formatDash(row.status)),
-  },
-  {
-    title: () => t('vaultTx.colCreated'),
-    key: 'createdTimestamp',
-    width: 186,
-    titleAlign: 'center',
-    align: 'center',
-    render: (row) =>
-      h('span', { class: 'vault-tx__cell-text vault-tx__cell-mono' }, formatTimestamp(row.createdTimestamp)),
+      h('span', {class: 'vault-tx__cell-text'}, formatDash(row.blockchain)),
   },
   {
     title: () => t('vaultTx.colSenderAddr'),
@@ -118,9 +124,9 @@ const columns = computed<DataTableColumns<VaultTransactionItem>>(() => [
     width: 200,
     titleAlign: 'center',
     align: 'center',
-    ellipsis: { tooltip: true },
+    ellipsis: {tooltip: true},
     render: (row) =>
-      h('span', { class: 'vault-tx__cell-text vault-tx__cell-mono' }, formatDash(row.senderAddress)),
+      h('span', {class: 'vault-tx__cell-text vault-tx__cell-mono'}, formatDash(row.senderAddress)),
   },
   {
     title: () => t('vaultTx.colSenderLabel'),
@@ -128,8 +134,8 @@ const columns = computed<DataTableColumns<VaultTransactionItem>>(() => [
     width: 160,
     titleAlign: 'center',
     align: 'center',
-    ellipsis: { tooltip: true },
-    render: (row) => h('span', { class: 'vault-tx__cell-text' }, formatDash(row.senderLabel)),
+    ellipsis: {tooltip: true},
+    render: (row) => h('span', {class: 'vault-tx__cell-text'}, formatDash(row.senderLabel)),
   },
   // {
   //   title: () => t('vaultTx.colSenderInternal'),
@@ -146,9 +152,9 @@ const columns = computed<DataTableColumns<VaultTransactionItem>>(() => [
     width: 96,
     titleAlign: 'center',
     align: 'center',
-    ellipsis: { tooltip: true },
+    ellipsis: {tooltip: true},
     render: (row) =>
-      h('span', { class: 'vault-tx__cell-text vault-tx__cell-unit' }, formatDash(row.senderAmountUnit)),
+      h('span', {class: 'vault-tx__cell-text vault-tx__cell-unit'}, formatDash(row.senderAmountUnit)),
   },
   {
     title: () => t('vaultTx.colSenderAmount'),
@@ -157,7 +163,7 @@ const columns = computed<DataTableColumns<VaultTransactionItem>>(() => [
     titleAlign: 'center',
     align: 'center',
     render: (row) =>
-      h('span', { class: 'vault-tx__cell-num' }, formatAmount(row.senderAmount)),
+      h('span', {class: 'vault-tx__cell-num'}, formatAmount(row.senderAmount)),
   },
   {
     title: () => t('vaultTx.colRecipientAddr'),
@@ -165,9 +171,9 @@ const columns = computed<DataTableColumns<VaultTransactionItem>>(() => [
     width: 200,
     titleAlign: 'center',
     align: 'center',
-    ellipsis: { tooltip: true },
+    ellipsis: {tooltip: true},
     render: (row) =>
-      h('span', { class: 'vault-tx__cell-text vault-tx__cell-mono' }, formatDash(row.recipientAddress)),
+      h('span', {class: 'vault-tx__cell-text vault-tx__cell-mono'}, formatDash(row.recipientAddress)),
   },
   {
     title: () => t('vaultTx.colRecipientLabel'),
@@ -175,8 +181,8 @@ const columns = computed<DataTableColumns<VaultTransactionItem>>(() => [
     width: 160,
     titleAlign: 'center',
     align: 'center',
-    ellipsis: { tooltip: true },
-    render: (row) => h('span', { class: 'vault-tx__cell-text' }, formatDash(row.recipientLabel)),
+    ellipsis: {tooltip: true},
+    render: (row) => h('span', {class: 'vault-tx__cell-text'}, formatDash(row.recipientLabel)),
   },
   // {
   //   title: () => t('vaultTx.colRecipientInternal'),
@@ -193,9 +199,9 @@ const columns = computed<DataTableColumns<VaultTransactionItem>>(() => [
     width: 96,
     titleAlign: 'center',
     align: 'center',
-    ellipsis: { tooltip: true },
+    ellipsis: {tooltip: true},
     render: (row) =>
-      h('span', { class: 'vault-tx__cell-text vault-tx__cell-unit' }, formatDash(row.recipientAmountUnit)),
+      h('span', {class: 'vault-tx__cell-text vault-tx__cell-unit'}, formatDash(row.recipientAmountUnit)),
   },
   {
     title: () => t('vaultTx.colRecipientAmount'),
@@ -204,17 +210,7 @@ const columns = computed<DataTableColumns<VaultTransactionItem>>(() => [
     titleAlign: 'center',
     align: 'center',
     render: (row) =>
-      h('span', { class: 'vault-tx__cell-num' }, formatAmount(row.recipientAmount)),
-  },
-  {
-    title: () => t('vaultTx.colBlockchain'),
-    key: 'blockchain',
-    width: 120,
-    titleAlign: 'center',
-    align: 'center',
-    ellipsis: { tooltip: true },
-    render: (row) =>
-      h('span', { class: 'vault-tx__cell-text' }, formatDash(row.blockchain)),
+      h('span', {class: 'vault-tx__cell-num'}, formatAmount(row.recipientAmount)),
   },
   // {
   //   title: () => t('vaultTx.colBlockHeight'),
@@ -232,7 +228,7 @@ const columns = computed<DataTableColumns<VaultTransactionItem>>(() => [
     titleAlign: 'center',
     align: 'center',
     render: (row) =>
-      h('span', { class: 'vault-tx__cell-num' }, formatAmount(row.feeAmount)),
+      h('span', {class: 'vault-tx__cell-num'}, formatAmount(row.feeAmount)),
   },
   {
     title: () => t('vaultTx.colFeeUnit'),
@@ -240,9 +236,28 @@ const columns = computed<DataTableColumns<VaultTransactionItem>>(() => [
     width: 96,
     titleAlign: 'center',
     align: 'center',
-    ellipsis: { tooltip: true },
+    ellipsis: {tooltip: true},
+    render: (row) =>
+      h('span', {class: 'vault-tx__cell-text vault-tx__cell-unit'}, formatDash(row.feeAmountUnit)),
+  },
+  {
+    title: () => t('vaultTx.colStatus'),
+    key: 'status',
+    width: 120,
+    titleAlign: 'center',
+    align: 'center',
+    ellipsis: {tooltip: true},
     render: (row) =>
-      h('span', { class: 'vault-tx__cell-text vault-tx__cell-unit' }, formatDash(row.feeAmountUnit)),
+      h('span', {class: 'vault-tx__cell-text vault-tx__cell-status'}, formatDash(row.status)),
+  },
+  {
+    title: () => t('vaultTx.colCreated'),
+    key: 'createdTimestamp',
+    width: 186,
+    titleAlign: 'center',
+    align: 'center',
+    render: (row) =>
+      h('span', {class: 'vault-tx__cell-text vault-tx__cell-mono'}, formatTimestamp(row.createdTimestamp)),
   },
   {
     title: () => t('vaultTx.colTxId'),
@@ -250,10 +265,10 @@ const columns = computed<DataTableColumns<VaultTransactionItem>>(() => [
     width: 260,
     titleAlign: 'center',
     align: 'center',
-    ellipsis: { tooltip: true },
+    ellipsis: {tooltip: true},
     render: (row) => {
       const txid = row.transactionId?.trim()
-      if (!txid) return h('span', { class: 'vault-tx__cell-text vault-tx__cell-mono' }, '—')
+      if (!txid) return h('span', {class: 'vault-tx__cell-text vault-tx__cell-mono'}, '—')
       const unit = row.blockchain?.trim()
       const baseUrl = unit === 'ethereum' ? ETH_TX_BASE_URL : TRON_TX_BASE_URL
       return h(
@@ -298,8 +313,8 @@ async function load(): Promise<void> {
       recipientAddress: filters.recipientAddress,
       startTime,
       endTime,
-      // senderIsVaultAddress: filters.senderIsVaultAddress,
-      // recipientIsVaultAddress: filters.recipientIsVaultAddress,
+      blockchain: filters.blockchain,
+      unit: filters.unit,
       page: {
         current: pagination.page,
         row: pagination.pageSize
@@ -331,7 +346,15 @@ watch(
 )
 
 watch(
-  () => [filters.senderLabel, filters.recipientLabel, filters.senderAddress, filters.recipientAddress, filters.timeRange],
+  () => [
+    filters.senderLabel,
+    filters.recipientLabel,
+    filters.senderAddress,
+    filters.recipientAddress,
+    filters.timeRange,
+    filters.blockchain,
+    filters.unit,
+  ],
   () => {
     pagination.page = 1
     void load()
@@ -376,8 +399,8 @@ async function onExport(): Promise<void> {
       recipientAddress: filters.recipientAddress,
       startTime,
       endTime,
-      // senderIsVaultAddress: filters.senderIsVaultAddress,
-      // recipientIsVaultAddress: filters.recipientIsVaultAddress,
+      blockchain: filters.blockchain,
+      unit: filters.unit,
       page: {
         current: pagination.page,
         row: pagination.pageSize,
@@ -403,8 +426,8 @@ function onResetFilters(): void {
   filters.senderAddress = null
   filters.recipientAddress = null
   filters.timeRange = null
-  // filters.senderIsVaultAddress = null
-  // filters.recipientIsVaultAddress = null
+  filters.blockchain = null
+  filters.unit = null
 }
 </script>
 
@@ -423,14 +446,28 @@ function onResetFilters(): void {
           </div>
         </div> -->
       </template>
-
+      
       <n-spin :show="loading" class="vault-panel__spin">
         <div v-if="vault.currentVaultId == null" class="vault-panel__empty-wrap">
-          <n-empty size="large" :description="t('vaultTx.selectVaultHint')" />
+          <n-empty size="large" :description="t('vaultTx.selectVaultHint')"/>
         </div>
         <div v-else class="vault-panel__body">
           <div class="vault-panel__toolbar">
             <div class="vault-panel__filters">
+              <n-select
+                v-model:value="filters.blockchain"
+                :options="blockchainOptions"
+                :placeholder="t('vaultTx.colBlockchain')"
+                clearable
+                style="width: 180px"
+              />
+              <n-select
+                v-model:value="filters.unit"
+                :options="unitOptions"
+                :placeholder="t('vaultTx.Unit')"
+                clearable
+                style="width: 180px"
+              />
               <n-input
                 v-model:value="filters.senderLabel"
                 :placeholder="t('vaultTx.colSenderLabel')"
@@ -463,20 +500,6 @@ function onResetFilters(): void {
                 :end-placeholder="t('vaultTx.filterEndTime')"
                 style="width: 420px"
               />
-<!--              <n-select-->
-<!--                v-model:value="filters.senderIsVaultAddress"-->
-<!--                :options="boolFilterOptions"-->
-<!--                :placeholder="t('vaultTx.colSenderInternal')"-->
-<!--                clearable-->
-<!--                style="width: 200px"-->
-<!--              />-->
-<!--              <n-select-->
-<!--                v-model:value="filters.recipientIsVaultAddress"-->
-<!--                :options="boolFilterOptions"-->
-<!--                :placeholder="t('vaultTx.colRecipientInternal')"-->
-<!--                clearable-->
-<!--                style="width: 200px"-->
-<!--              />-->
               <n-button tertiary @click="onResetFilters">{{ t('vaultTx.filterReset') }}</n-button>
             </div>
             <n-button class="vault-panel__export" type="primary" secondary :loading="exporting" @click="onExport">
@@ -500,7 +523,7 @@ function onResetFilters(): void {
             />
           </div>
           <!-- 仅占位:让白卡片铺满剩余高度,表格本身不纵向拉伸 -->
-          <div class="vault-panel__tail-spacer" aria-hidden="true" />
+          <div class="vault-panel__tail-spacer" aria-hidden="true"/>
         </div>
       </n-spin>
     </n-card>
@@ -647,7 +670,8 @@ function onResetFilters(): void {
   gap: 10px;
   min-width: 0;
 }
-.vault-panel__export{
+
+.vault-panel__export {
   align-self: flex-start;
 }