Files
webs/power_leasing/src/views/account/orders.vue
2026-01-23 17:00:06 +08:00

133 lines
5.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="orders-page">
<h2 class="title">订单列表</h2>
<el-tabs v-model="active" @tab-click="handleTabClick">
<el-tab-pane label="订单进行中" name="7">
<order-list :items="orders[7]" :show-checkout="true" :show-end-time="false" :on-cancel="handleCancelOrder" empty-text="暂无进行中的订单" />
</el-tab-pane>
<el-tab-pane label="订单已完成" name="8">
<order-list :items="orders[8]" :show-checkout="false" :show-end-time="true" empty-text="暂无已完成的订单" />
</el-tab-pane>
<el-tab-pane label="订单生成失败" name="11">
<div class="order-fail-reason">失败原因无法连接矿池导致生成订单失败</div>
<order-list :items="orders[11]" :show-checkout="false" :show-end-time="false" empty-text="暂无订单生成失败记录" />
</el-tab-pane>
<!-- <el-tab-pane label="余额不足,订单已取消" name="9">
<order-list :items="orders[9]" :show-checkout="false" empty-text="暂无因余额不足取消的订单" />
</el-tab-pane> -->
</el-tabs>
</div>
</template>
<script>
/**
* 订单列表页(个人中心)
* - 使用标签页按状态展示订单
* - 列表项可展开以显示 orderItemDtoList机器列表
* - 通过 getOrdersByStatus(status) 拉取,兼容 { data: { rows: [] } } 或 { rows: [] }
*/
import { getOrdersByStatus, cancelOrder } from '../../api/order'
import OrderList from './OrderList.vue'
// 使用外部 SFC 组件,避免 runtime-only 构建下的模板编译警告
export default {
name: 'AccountOrders',
components: { OrderList },
data() {
return {
active: '7', // 默认值改为 '7'(订单进行中)
orders: { 7: [], 8: [], 9: [], 11: [] },
loading: false
}
},
created() {
// 优先从 URL 参数获取状态,其次从 localStorage 获取,最后使用默认值
const urlStatus = this.$route && this.$route.query && this.$route.query.status ? String(this.$route.query.status) : null
const savedStatus = localStorage.getItem('orderListActiveTab')
const initial = urlStatus || savedStatus || '7'
this.active = initial
this.fetchOrders(initial)
},
methods: {
async fetchCancelOrder(params) {
const res = await cancelOrder(params)
if (res && Number(res.code) === 200) {
this.$message({
message: '取消订单成功',
type: 'success',
showClose: true
})
this.fetchOrders(this.active)
} else {
this.$message({
message: (res && res.msg) || '取消失败',
type: 'error',
showClose: true
})
}
},
handleCancelOrder({ orderId }) {
if (!orderId) return
this.fetchCancelOrder({ orderId })
},
handleTabClick(tab) {
const name = tab && tab.name ? String(tab.name) : this.active
// 保存用户选择的标签页状态到 localStorage
try {
localStorage.setItem('orderListActiveTab', name)
} catch (e) {
console.warn('保存标签页状态失败:', e)
}
this.fetchOrders(name)
},
async fetchOrders(status) {
const key = String(status)
try {
this.loading = true
const res = await getOrdersByStatus({ status: Number(status) })
const payload = (res && res.data) != null ? res.data : res
const list = Array.isArray(payload)
? payload
: (Array.isArray(payload && payload.rows) ? payload.rows : [])
this.$set(this.orders, key, list)
} catch (e) {
console.log(e,'获取订单失败');
} finally {
this.loading = false
}
}
}
}
</script>
<style scoped>
.orders-page { padding: 12px; }
.title { margin: 0 0 12px 0; font-weight: 600; color: #2c3e50; }
.empty { color: #888; padding: 24px; text-align: center; }
.order-fail-reason { margin: 8px 0 12px; color: #f56c6c; font-size: 13px; }
.order-list { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.order-card { border: 1px solid #eee; border-radius: 8px; padding: 0; background: #fff; overflow: hidden; }
.order-header { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 12px; padding: 12px; cursor: pointer; position: relative; }
.order-header:focus { outline: 2px solid #409eff; outline-offset: -2px; }
.order-header.is-open { background: #fafafa; }
.header-row { display: flex; gap: 8px; line-height: 1.8; align-items: center; }
.chevron { position: absolute; right: 12px; top: 12px; width: 10px; height: 10px; border-right: 2px solid #666; border-bottom: 2px solid #666; transform: rotate(-45deg); transition: transform 0.2s ease; }
.chevron.chevron-open { transform: rotate(45deg); }
.order-details { border-top: 1px solid #eee; padding: 12px; }
.machine-list { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.machine-card { border: 1px dashed #e2e2e2; border-radius: 6px; padding: 10px; background: #fff; }
.row { display: flex; gap: 8px; line-height: 1.8; }
.label { color: #666; }
.value { color: #333; }
.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; }
@media (max-width: 960px) {
.order-list { grid-template-columns: 1fr; }
.order-header { grid-template-columns: 1fr; }
.machine-list { grid-template-columns: 1fr; }
}
</style>