From 66f025c6cc855ca4d565ea05afc3da5e58666dca Mon Sep 17 00:00:00 2001 From: yml Date: Wed, 3 Jun 2026 22:36:22 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=88=91=E7=9A=84=E8=AE=A2?= =?UTF-8?q?=E5=8D=95=E7=95=8C=E9=9D=A2ui?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/views/account/OrdersView.vue | 465 ++++++++++++++++++++-- 1 file changed, 426 insertions(+), 39 deletions(-) diff --git a/frontend/src/views/account/OrdersView.vue b/frontend/src/views/account/OrdersView.vue index 1e074ab..5d7b591 100644 --- a/frontend/src/views/account/OrdersView.vue +++ b/frontend/src/views/account/OrdersView.vue @@ -2,10 +2,12 @@ import { computed, onMounted, ref, watch } from 'vue' import { ElMessage } from 'element-plus' import { useRoute, useRouter } from 'vue-router' +import { CopyDocument, Search } from '@element-plus/icons-vue' import { fetchOrders, type Order } from '@/api/orders' import { useSessionStore } from '@/stores/session' import { orderStatusLabel } from '@/utils/statusLabels' +import { formatDateTime } from '@/utils/time' const loading = ref(false) const orders = ref([]) @@ -13,6 +15,7 @@ const payingOrderId = ref(null) const session = useSessionStore() const route = useRoute() const router = useRouter() +const searchKeyword = ref('') const statusTabs = [ { key: 'all', label: '全部' }, { key: 'pending_payment', label: '待支付' }, @@ -25,8 +28,31 @@ const tabKeys = new Set(statusTabs.map((item) => item.key)) const activeTab = ref(readTab(route.query.tab)) const displayOrders = computed(() => { - if (activeTab.value === 'all') return orders.value - return orders.value.filter((order) => order.status === activeTab.value) + let filtered = orders.value + + if (activeTab.value !== 'all') { + filtered = filtered.filter((order) => order.status === activeTab.value) + } + + if (searchKeyword.value.trim()) { + const keyword = searchKeyword.value.trim().toLowerCase() + filtered = filtered.filter((order) => + order.order_no.toLowerCase().includes(keyword) || + order.title.toLowerCase().includes(keyword) + ) + } + + return filtered +}) + +const tabCounts = computed(() => { + const counts: Record = { all: orders.value.length } + statusTabs.forEach((tab) => { + if (tab.key !== 'all') { + counts[tab.key] = orders.value.filter((order) => order.status === tab.key).length + } + }) + return counts }) onMounted(loadOrders) @@ -77,67 +103,220 @@ function readError(error: unknown, fallback: string) { } function orderRole(order: Order) { - if (order.renter_id === session.userId) return '买家' + if (order.renter_id === session.userId) return '租客' if (order.owner_id === session.userId) return '号主' return '-' } +function isRenter(order: Order) { + return order.renter_id === session.userId +} + +function isOwner(order: Order) { + return order.owner_id === session.userId +} + +function amountLabel(order: Order) { + return isRenter(order) ? '支付金额' : '租金收入' +} + function money(value: unknown) { return Math.round(Number(value || 0)) } + +function shortenOrderNo(orderNo: string) { + if (orderNo.length <= 20) return orderNo + return `${orderNo.slice(0, 12)}...${orderNo.slice(-6)}` +} + +async function copyOrderNo(orderNo: string) { + try { + await navigator.clipboard.writeText(orderNo) + ElMessage.success('订单号已复制') + } catch { + ElMessage.error('复制失败') + } +} + +function getPaymentDeadline(order: Order) { + if (order.status !== 'pending_payment' || !order.created_at) return null + const created = new Date(order.created_at) + const deadline = new Date(created.getTime() + 30 * 60 * 1000) + return deadline +} + +function getCountdownMinutes(order: Order) { + const deadline = getPaymentDeadline(order) + if (!deadline) return 0 + const now = new Date() + const diff = deadline.getTime() - now.getTime() + return Math.max(0, Math.ceil(diff / 60000)) +}