需求更改开发中
This commit is contained in:
326
power_leasing/src/views/account/receiptRecord.vue
Normal file
326
power_leasing/src/views/account/receiptRecord.vue
Normal file
@@ -0,0 +1,326 @@
|
||||
<template>
|
||||
<div class="receipt-page">
|
||||
<div class="card" aria-label="收款记录" tabindex="0">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">收款记录</h3>
|
||||
<!-- <div class="card-actions">
|
||||
<el-date-picker
|
||||
v-model="range"
|
||||
type="datetimerange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
size="small"
|
||||
:clearable="true"
|
||||
@change="handleRangeChange"
|
||||
/>
|
||||
<el-input
|
||||
v-model="keyword"
|
||||
size="small"
|
||||
placeholder="订单号/备注搜索"
|
||||
clearable
|
||||
class="search-input"
|
||||
@keyup.enter.native="fetchList"
|
||||
/>
|
||||
<el-button type="primary" size="small" @click="fetchList">查询</el-button>
|
||||
</div> -->
|
||||
</div>
|
||||
|
||||
<div v-if="loading" class="loading">
|
||||
<i class="el-icon-loading" aria-label="加载中" role="img"></i>
|
||||
加载中...
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<el-table
|
||||
ref="receiptTable"
|
||||
:data="rows"
|
||||
border
|
||||
stripe
|
||||
size="small"
|
||||
style="width: 100%"
|
||||
:row-key="getRowKey"
|
||||
:expand-row-keys="expandedRowKeys"
|
||||
:row-class-name="getRowClassName"
|
||||
@row-click="handleRowClick"
|
||||
@expand-change="handleExpandChange"
|
||||
:header-cell-style="{ textAlign: 'left' }"
|
||||
:cell-style="{ textAlign: 'left' }"
|
||||
>
|
||||
<el-table-column type="expand" width="46">
|
||||
<template #default="scope">
|
||||
<div class="detail-panel">
|
||||
<div class="detail-grid">
|
||||
<div class="detail-item">
|
||||
<span class="detail-label">订单号</span>
|
||||
<span class="detail-value mono">{{ scope.row.orderId || '-' }}</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<span class="detail-label">付款链</span>
|
||||
<span class="detail-value"><span class="badge">{{ formatChain(scope.row.fromChain) || '-' }}</span></span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<span class="detail-label">付款币种</span>
|
||||
<span class="detail-value"><span class="badge badge-blue">{{ String((scope.row.fromSymbol || scope.row.coin) || '') .toUpperCase() }}</span></span>
|
||||
</div>
|
||||
<div class="detail-item detail-item-full">
|
||||
<span class="detail-label">付款地址</span>
|
||||
<span class="detail-value address">
|
||||
<span class="mono-ellipsis" :title="scope.row.fromAddress">{{ scope.row.fromAddress || '-' }}</span>
|
||||
<el-button type="text" size="mini" @click.stop="copy(scope.row.fromAddress)" v-if="scope.row.fromAddress">复制</el-button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="支付时间" min-width="160">
|
||||
<template #default="scope">{{ formatFullTime(scope.row.createTime) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="收款金额(USDT)" min-width="160" align="right">
|
||||
<template #default="scope">
|
||||
<span class="amount-green">+{{ formatTrunc(scope.row.realAmount, 2) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="收款链" min-width="120">
|
||||
<template #default="scope">{{ formatChain(scope.row.toChain) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="收款币种" min-width="100">
|
||||
<template #default="scope">{{ String(scope.row.coin || '').toUpperCase() }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="收款地址" min-width="260">
|
||||
<template #default="scope">
|
||||
<span class="mono-ellipsis" :title="scope.row.toAddress">{{ scope.row.toAddress }}</span>
|
||||
<el-button type="text" size="mini" @click.stop="copy(scope.row.toAddress)">复制</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="交易HASH" min-width="260">
|
||||
<template #default="scope">
|
||||
<span class="mono-ellipsis" :title="scope.row.txHash">{{ scope.row.txHash }}</span>
|
||||
<el-button type="text" size="mini" @click.stop="copy(scope.row.txHash)" v-if="scope.row.txHash">复制</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="支付状态" min-width="120">
|
||||
<template #default="scope">
|
||||
<el-tag :type="getStatusType(scope.row.status)" size="small">{{ getStatusText(scope.row.status) }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态更新时间" min-width="160">
|
||||
<template #default="scope">{{ formatFullTime(scope.row.updateTime) }}</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div v-if="!rows.length" class="empty">
|
||||
<div class="empty-icon">💳</div>
|
||||
<div class="empty-text">暂无收款记录</div>
|
||||
</div>
|
||||
|
||||
<div class="pagination">
|
||||
<el-pagination
|
||||
background
|
||||
layout="prev, pager, next, jumper"
|
||||
:current-page.sync="page"
|
||||
:page-size="pageSize"
|
||||
:total="total"
|
||||
@current-change="fetchList"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { sellerReceiptList } from '../../api/wallet'
|
||||
|
||||
export default {
|
||||
name: 'AccountReceiptRecord',
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
rows: [
|
||||
{
|
||||
orderId: '1234567890',
|
||||
fromChain: 'tron',
|
||||
fromSymbol: 'USDT',
|
||||
fromAddress: 'TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE',
|
||||
toChain: 'tron',
|
||||
coin: 'USDT',
|
||||
toAddress: 'TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE',
|
||||
txHash: 'TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE',
|
||||
status: 2,
|
||||
updateTime: '2024-01-15 14:30:25',
|
||||
realAmount: 100,
|
||||
},
|
||||
{
|
||||
orderId: '1234567890',
|
||||
fromChain: 'tron',
|
||||
fromSymbol: 'USDT',
|
||||
fromAddress: 'TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE',
|
||||
toChain: 'tron',
|
||||
coin: 'USDT',
|
||||
toAddress: 'TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE',
|
||||
txHash: 'TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE',
|
||||
status: 1,
|
||||
updateTime: '2024-01-15 14:30:25',
|
||||
realAmount: 106,
|
||||
}
|
||||
],
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
range: [],
|
||||
keyword: '',
|
||||
expandedRowKeys: []
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.fetchList()
|
||||
// 为示例数据补充唯一行键,避免展开联动
|
||||
this.rows = this.withKeys(this.rows)
|
||||
},
|
||||
methods: {
|
||||
withKeys(list) {
|
||||
const arr = Array.isArray(list) ? list : []
|
||||
return arr.map((it, idx) => ({
|
||||
...it,
|
||||
__rowKey: it && it.__rowKey ? it.__rowKey : `${it && (it.txHash || it.orderId || it.updateTime || '')}_${idx}`
|
||||
}))
|
||||
},
|
||||
getRowKey(row) { return row && row.__rowKey },
|
||||
handleRowClick(row) {
|
||||
const key = this.getRowKey(row)
|
||||
const isOpen = this.expandedRowKeys.includes(key)
|
||||
// 手风琴:只保留当前点击行
|
||||
this.expandedRowKeys = isOpen ? [] : [key]
|
||||
},
|
||||
handleExpandChange(row, expandedRows) {
|
||||
// 由内置展开事件触发时,同步 keys,确保手风琴
|
||||
if (!Array.isArray(expandedRows)) {
|
||||
this.expandedRowKeys = []
|
||||
return
|
||||
}
|
||||
this.expandedRowKeys = expandedRows.length ? [this.getRowKey(expandedRows[expandedRows.length - 1])] : []
|
||||
},
|
||||
getRowClassName() { return 'clickable-row' },
|
||||
/**
|
||||
* 精确裁剪数字到指定位数(不四舍五入)
|
||||
*/
|
||||
formatTrunc(value, decimals = 2) {
|
||||
const num = Number(value)
|
||||
if (!Number.isFinite(num)) return '0'
|
||||
const d = Math.max(0, Number(decimals) || 0)
|
||||
const factor = Math.pow(10, d)
|
||||
const truncated = Math.trunc(num * factor) / factor
|
||||
const str = String(truncated)
|
||||
if (d === 0) return str
|
||||
const [intPart, decPart = ''] = str.split('.')
|
||||
const padded = decPart.padEnd(d, '0')
|
||||
return `${intPart}.${padded}`
|
||||
},
|
||||
formatFullTime(time) {
|
||||
if (!time) return ''
|
||||
try {
|
||||
return `${time.split('T')[0]} ${time.split('T')[1].split('.')[0]}`
|
||||
} catch (e) {
|
||||
console.log(e,"时间");
|
||||
|
||||
return time
|
||||
}
|
||||
|
||||
},
|
||||
formatChain(chain) {
|
||||
const map = { tron: 'Tron (TRC20)', ethereum: 'Ethereum (ERC20)', bsc: 'BSC (BEP20)', polygon: 'Polygon' }
|
||||
return map[chain] || chain || '-'
|
||||
},
|
||||
getStatusType(status) {
|
||||
const map = { 0: 'danger', 1: 'success', 2: 'warning', 3: 'danger' }
|
||||
return map[status] || 'info'
|
||||
},
|
||||
getStatusText(status) {
|
||||
const map = { 0: '支付失败', 1: '支付成功', 2: '待校验', 3: '证书校验失败' }
|
||||
return map[status] || '未知'
|
||||
},
|
||||
copy(text) {
|
||||
if (!text) return
|
||||
try {
|
||||
if (navigator.clipboard && navigator.clipboard.writeText) {
|
||||
navigator.clipboard.writeText(text)
|
||||
this.$message.success('已复制')
|
||||
return
|
||||
}
|
||||
} catch (e) {}
|
||||
const area = document.createElement('textarea')
|
||||
area.value = text
|
||||
document.body.appendChild(area)
|
||||
area.select()
|
||||
try { document.execCommand('copy'); this.$message.success('已复制') } catch (e) {}
|
||||
document.body.removeChild(area)
|
||||
},
|
||||
handleRangeChange() {
|
||||
this.page = 1
|
||||
},
|
||||
async fetchList() {
|
||||
this.loading = true
|
||||
try {
|
||||
const params = {
|
||||
page: this.page,
|
||||
pageSize: this.pageSize,
|
||||
// keyword: this.keyword || undefined,
|
||||
// startTime: Array.isArray(this.range) && this.range[0] ? new Date(this.range[0]).getTime() : undefined,
|
||||
// endTime: Array.isArray(this.range) && this.range[1] ? new Date(this.range[1]).getTime() : undefined
|
||||
}
|
||||
const res = await sellerReceiptList(params)
|
||||
const data = res && (res.data || res)
|
||||
const list = Array.isArray(data && data.rows) ? data.rows : (Array.isArray(data) ? data : [])
|
||||
this.rows = this.withKeys(list)
|
||||
this.total = res.total
|
||||
} catch (e) {
|
||||
this.rows = []
|
||||
this.total = 0
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.receipt-page { padding: 4px; }
|
||||
.card { background: #fff; border: 1px solid #eee; border-radius: 10px; padding: 12px; box-shadow: 0 4px 18px rgba(0,0,0,0.04); }
|
||||
.card-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
|
||||
.card-title { margin: 0; font-size: 18px; font-weight: 700; color: #2c3e50; }
|
||||
.card-actions { display: flex; align-items: center; gap: 8px; }
|
||||
.search-input { width: 220px; }
|
||||
.loading { text-align: center; color: #666; padding: 40px 0; }
|
||||
.empty { text-align: center; color: #999; padding: 40px 0; }
|
||||
.empty-icon { font-size: 48px; margin-bottom: 8px; }
|
||||
.amount-green { color: #16a34a; font-weight: 700; }
|
||||
.amount-red { color: #ef4444; font-weight: 700; }
|
||||
.type-green { color: #16a34a; }
|
||||
.type-red { color: #ef4444; }
|
||||
.pagination { display: flex; justify-content: flex-end; margin-top: 8px; }
|
||||
|
||||
/* 展开详情样式 */
|
||||
.detail-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 24px; padding: 8px 4px; }
|
||||
.detail-item { display: grid; grid-template-columns: 90px 1fr; align-items: center; gap: 8px; }
|
||||
.detail-item-full { grid-column: 1 / -1; }
|
||||
.detail-label { color: #666; font-size: 13px; text-align: right; }
|
||||
.detail-value { color: #333; font-size: 13px; text-align: left; }
|
||||
.detail-value.address { font-family: "Monaco", "Menlo", monospace; word-break: break-all; }
|
||||
|
||||
/* 单行等宽省略 */
|
||||
.mono-ellipsis { font-family: "Monaco", "Menlo", monospace; max-width: 360px; display: inline-block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: middle; }
|
||||
|
||||
/* 可点击行的轻交互提示 */
|
||||
.clickable-row:hover > td { background: #f8fafc !important; cursor: pointer; }
|
||||
|
||||
/* 展开面板视觉优化 */
|
||||
.detail-panel { background: #f9fafb; border: 1px dashed #e5e7eb; border-radius: 8px; padding: 12px; }
|
||||
.mono { font-family: "Monaco", "Menlo", monospace; }
|
||||
.badge { display: inline-block; padding: 2px 8px; border-radius: 12px; background: #eef2ff; color: #3b82f6; font-size: 12px; line-height: 18px; }
|
||||
.badge-blue { background: #eff6ff; color: #2563eb; }
|
||||
</style>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user