Files
webs/power_leasing/src/views/account/OrderList.vue

351 lines
15 KiB
Vue
Raw Normal View History

2025-09-26 16:40:38 +08:00
<template>
<div v-loading="payLoading">
<div v-if="!safeItems.length" class="empty">{{ emptyText }}</div>
<el-table v-else :data="safeItems" border :header-cell-style="{ textAlign: 'left' }" :cell-style="{ textAlign: 'left' }">
<el-table-column type="expand" width="46">
<template #default="outer">
<el-table :data="outer.row.orderItemDtoList || []" size="small" border :header-cell-style="{ textAlign: 'left' }" :cell-style="{ textAlign: 'left' }" row-key="productMachineId">
<el-table-column prop="productMachineId" label="机器ID" min-width="120" />
<el-table-column prop="name" label="名称" min-width="160" />
<el-table-column prop="payCoin" label="币种" min-width="100" />
<el-table-column prop="address" label="收款地址" min-width="240" />
<el-table-column prop="leaseTime" label="租赁天数" min-width="100" />
<el-table-column prop="price" label="售价(USDT)" min-width="240">
<template #default="scope">
<span class="value strong">
<el-tooltip
v-if="formatAmount(scope.row.price, scope.row.payCoin || 'USDT').truncated"
:content="formatAmount(scope.row.price, scope.row.payCoin || 'USDT').full"
placement="top"
>
<span>
{{ formatAmount(scope.row.price, scope.row.payCoin || 'USDT').text }}
<i class="el-icon-more amount-more"></i>
</span>
</el-tooltip>
<span v-else>{{ formatAmount(scope.row.price, scope.row.payCoin || 'USDT').text }}</span>
</span>
</template>
</el-table-column>
2025-09-26 16:40:38 +08:00
</el-table>
</template>
</el-table-column>
<el-table-column label="订单号" min-width="220">
<template #default="scope"><span class="value mono">{{ scope.row && scope.row.orderNumber || '—' }}</span></template>
</el-table-column>
<el-table-column label="创建时间" min-width="180">
<template #default="scope">{{ formatDateTime(scope.row && scope.row.createTime) }}</template>
</el-table-column>
<el-table-column label="商品数" min-width="100">
<template #default="scope">{{ Array.isArray(scope.row && scope.row.orderItemDtoList) ? scope.row.orderItemDtoList.length : 0 }}</template>
</el-table-column>
<el-table-column label="总金额(USDT)" min-width="140">
<template #default="scope">
<span class="value strong">
<el-tooltip
v-if="formatAmount(scope.row && scope.row.totalPrice, 'USDT').truncated"
:content="formatAmount(scope.row && scope.row.totalPrice, 'USDT').full"
placement="top"
>
<span>
{{ formatAmount(scope.row && scope.row.totalPrice, 'USDT').text }}
<i class="el-icon-more amount-more"></i>
</span>
</el-tooltip>
<span v-else>{{ formatAmount(scope.row && scope.row.totalPrice, 'USDT').text }}</span>
</span>
</template>
2025-09-26 16:40:38 +08:00
</el-table-column>
2025-10-31 14:09:58 +08:00
<el-table-column min-width="180">
<template #header>
<el-tooltip placement="top" effect="dark">
<div slot="content">
实际支付金额/理论支付金额<br/>
1. 实际支付金额是按照矿机实际算力计算支付金额<br/>
2. 理论支付金额是卖家定义出售价格
</div>
<span style="display:inline-flex;align-items:center;gap:6px;">
<i class="el-icon-question" style="color:#909399;" aria-label="说明" role="img"></i>
已支付金额(USDT)
</span>
</el-tooltip>
</template>
<template #default="scope">
<span class="value strong">
<el-tooltip
v-if="formatAmount(scope.row && scope.row.payAmount, 'USDT').truncated"
:content="formatAmount(scope.row && scope.row.payAmount, 'USDT').full"
placement="top"
>
<span>
{{ formatAmount(scope.row && scope.row.payAmount, 'USDT').text }}
<i class="el-icon-more amount-more"></i>
</span>
</el-tooltip>
<span v-else>{{ formatAmount(scope.row && scope.row.payAmount, 'USDT').text }}</span>
</span>
2025-10-31 14:09:58 +08:00
</template>
2025-09-26 16:40:38 +08:00
</el-table-column>
<el-table-column label="待支付金额(USDT)" min-width="140">
<template #default="scope">
<span class="value strong">
<el-tooltip
v-if="formatAmount(scope.row && scope.row.noPayAmount, 'USDT').truncated"
:content="formatAmount(scope.row && scope.row.noPayAmount, 'USDT').full"
placement="top"
>
<span>
{{ formatAmount(scope.row && scope.row.noPayAmount, 'USDT').text }}
<i class="el-icon-more amount-more"></i>
</span>
</el-tooltip>
<span v-else>{{ formatAmount(scope.row && scope.row.noPayAmount, 'USDT').text }}</span>
</span>
</template>
2025-09-26 16:40:38 +08:00
</el-table-column>
<el-table-column label="操作" min-width="280" fixed="right">
<template #default="scope">
<el-button size="mini" @click="handleGoDetail(scope.row)" style="margin-right:8px;">详情</el-button>
<template v-if="shouldShowActions(scope.row)">
<el-button type="primary" size="mini" @click="handleCheckout(scope.row)">去结算</el-button>
<!-- <el-button type="danger" size="mini" style="margin-left:8px;" @click="handleCancel(scope.row)">取消订单</el-button> -->
</template>
</template>
</el-table-column>
</el-table>
<!-- 修改功能之前 跟购物车弹窗一样
<el-dialog :visible.sync="orderDialog.visible" width="520px" title="请扫码支付">
<div style="text-align:left; margin-bottom:12px; color:#666;">
<div style="margin-bottom:6px;">支付币种<b>{{ orderDialog.coin }}</b></div>
<div style="margin-bottom:6px;">支付金额(USDT)<b class="value strong">{{ orderDialog.amount }}</b></div>
<div style="word-break:break-all;">收款地址<code>{{ orderDialog.address }}</code></div>
</div>
<div style="text-align:left;">
<img v-if="orderDialog.qrContent" :src="orderDialog.qrContent" alt="支付二维码" style="width:240px;height:240px;" />
<div v-else style="color:#666;">未返回支付二维码</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="orderDialog.visible=false">关闭</el-button>
</span>
</el-dialog> -->
<el-dialog :visible.sync="dialogVisible" width="520px" title="请扫码支付">
<div style="text-align:left; margin-bottom:12px; color:#666;">
<div style="margin-bottom:6px;">总金额(USDT)
<b>
<el-tooltip
v-if="formatAmount(paymentDialog.totalPrice, 'USDT').truncated"
:content="formatAmount(paymentDialog.totalPrice, 'USDT').full"
placement="top"
>
<span>
{{ formatAmount(paymentDialog.totalPrice, 'USDT').text }}
<i class="el-icon-more amount-more"></i>
</span>
</el-tooltip>
<span v-else>{{ formatAmount(paymentDialog.totalPrice, 'USDT').text }}</span>
</b>
</div>
2025-10-31 14:09:58 +08:00
<div style="margin-bottom:6px;display:flex;align-items:center;gap:6px;">
<el-tooltip placement="top" effect="dark">
<div slot="content">
实际支付金额/理论支付金额<br/>
1. 实际支付金额是按照矿机实际算力计算支付金额<br/>
2. 理论支付金额是卖家定义出售价格
</div>
<i class="el-icon-question" style="color:#909399;" aria-label="说明" role="img"></i>
</el-tooltip>
<span>已支付金额(USDT)</span>
<b class="value strong">
<el-tooltip
v-if="formatAmount(paymentDialog.payAmount, 'USDT').truncated"
:content="formatAmount(paymentDialog.payAmount, 'USDT').full"
placement="top"
>
<span>
{{ formatAmount(paymentDialog.payAmount, 'USDT').text }}
<i class="el-icon-more amount-more"></i>
</span>
</el-tooltip>
<span v-else>{{ formatAmount(paymentDialog.payAmount, 'USDT').text }}</span>
</b>
</div>
<div style="margin-bottom:6px;">待支付金额(USDT)
<b class="value strong">
<el-tooltip
v-if="formatAmount(paymentDialog.noPayAmount, 'USDT').truncated"
:content="formatAmount(paymentDialog.noPayAmount, 'USDT').full"
placement="top"
>
<span>
{{ formatAmount(paymentDialog.noPayAmount, 'USDT').text }}
<i class="el-icon-more amount-more"></i>
</span>
</el-tooltip>
<span v-else>{{ formatAmount(paymentDialog.noPayAmount, 'USDT').text }}</span>
</b>
2025-10-31 14:09:58 +08:00
</div>
2025-09-26 16:40:38 +08:00
<!-- <div style="word-break:break-all;">收款地址<code>{{ orderDialog.address }}</code></div> -->
</div>
<div style="text-align:center;">
<img v-if="paymentDialog.img" :src="paymentDialog.img" alt="支付二维码" style="width:180px;height:180px;margin-top: 18px;" />
<div v-else style="color:#666;">未返回支付二维码</div>
</div>
<p style="margin-bottom:6px;color:red;text-align:left">注意如果已经支付对应金额不要在重复支付待系统确认后会自动更新订单状态因个人原因重复支付导致无法退款平台不承担任何责任</p>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible=false">关闭</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { addOrders } from '../../api/order'
import { truncateAmountByCoin } from '../../utils/amount'
2025-09-26 16:40:38 +08:00
export default {
name: 'OrderList',
props: {
items: { type: Array, default: () => [] },
emptyText: { type: String, default: '暂无数据' },
showCheckout: { type: Boolean, default: false },
onCancel: { type: Function, default: null }
},
data() {
return {
payLoading: false,
orderDialog: { visible: false, qrContent: '', coin: '', amount: '', address: '' },
dialogVisible: false,
paymentDialog: { totalPrice: "", payAmount: '', noPayAmount: '', img: '', }
}
},
computed: {
safeItems() {
return Array.isArray(this.items) ? this.items : []
}
},
methods: {
formatAmount(value, coin) {
return truncateAmountByCoin(value, coin)
},
2025-09-26 16:40:38 +08:00
buildQrSrc(img) {
if (!img) return ''
try { const s = String(img).trim(); return s.startsWith('data:') ? s : `data:image/png;base64,${s}` } catch (e) { return '' }
},
formatDateTime(value) {
if (!value) return '—'
try { const str = String(value); return str.includes('T') ? str.replace('T', ' ') : str } catch (e) { return String(value) }
},
async handleCheckout(row) {
if (!row) return
try {
this.payLoading = true
this.paymentDialog={
totalPrice: row.totalPrice,
payAmount: row.payAmount,
noPayAmount: row.noPayAmount,
img: row.img
}
if (this.paymentDialog.img) {
this.paymentDialog.img = this.buildQrSrc(this.paymentDialog.img)
this.dialogVisible=true
}else{
this.$message({
message: '未返回支付二维码',
type: 'error',
showClose: true
});
}
// this.dialogVisible=true
// const list = Array.isArray(row.orderItemDtoList) ? row.orderItemDtoList : []
// const payload = list.map(m => {
// const base = {
// leaseTime: Number(m.leaseTime || 1),
// machineId: m.productMachineId != null ? m.productMachineId : (m.machineId != null ? m.machineId : m.id),
// productId: m.productId,
// shopId: m.shopId
// }
// // 尝试从子项或订单行上获取店铺ID并附加
// const sid = m.shopId != null ? m.shopId : (row && (row.shopId != null ? row.shopId : row.shopID))
// return sid != null ? { ...base, shopId: sid } : base
// }).filter(p => p.machineId != null && p.productId != null)
// if (!payload.length) { this.$message.warning('该订单没有可支付的机器项'); return }
// const res = await addOrders(payload)
// if (!res || Number(res.code) !== 200) {
// // 全局拦截器已弹错误,这里只记录并中断,避免重复弹窗
// console.warn('创建支付订单失败:', res)
// return
// }
// const first = Array.isArray(res.data) && res.data.length ? res.data[0] : null
// if (!first || !first.img) { this.$message.error('未返回支付二维码'); return }
// this.orderDialog.coin = first.payCoin || ''
// this.orderDialog.amount = first.amount != null ? String(first.amount) : ''
// this.orderDialog.address = first.payAddress || ''
// this.orderDialog.qrContent = this.buildQrSrc(first.img)
// this.orderDialog.visible = true
} catch (e) {
console.log(e,'创建支付订单失败');
} finally { this.payLoading = false }
},
handleGoDetail(row) {
const id = row && (row.id != null ? row.id : row.orderId)
if (id == null) {
this.$message({
message: '订单ID缺失',
type: 'error',
showClose: true
});
return
}
2025-11-07 16:30:03 +08:00
try { this.$router.push(`/account/order-detail/${id}`) } catch (e) {
2025-09-26 16:40:38 +08:00
this.$message({
message: '无法跳转到详情页',
type: 'error',
showClose: true
})
}
},
handleCancel(row) {
if (!row || !this.onCancel) return
const id = row.id
if (id == null) {
this.$message({
message: '订单ID缺失',
type: 'error',
showClose: true
});
return
}
this.$confirm('确认取消该订单吗?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' })
.then(() => { try { this.onCancel({ orderId: id }) } catch (e) { void 0 } })
.catch(() => { return null })
},
shouldShowActions(row) {
console.log(row,'飞机飞机覅附件s');
if (!this.showCheckout) return false
const s = Number(row && row.status)
console.log(s,'飞机飞机覅附件s');
// 支持在 待支付(0) 与 支付中(6) 部分已支付(10) 三个状态显示按钮
return s === 0 || s === 6 || s === 10
}
}
}
</script>
<style scoped>
.empty { color: #888; padding: 24px; text-align: center; }
.value.mono { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; word-break: break-all; }
.value.strong { font-weight: 700; color: #e74c3c; }
.amount-more { font-size: 12px; color: #94a3b8; margin-left: 4px; }
2025-09-26 16:40:38 +08:00
</style>