Files
hfb_sys/frontend/src/views/account/OrderDetailView.vue
T

157 lines
4.9 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.
<script setup lang="ts">
import { ElMessage } from 'element-plus'
import { computed, onMounted, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import {
cancelOrder,
confirmReceive,
fetchHandoffRecords,
fetchOrder,
submitHandoff,
type HandoffRecord,
type Order,
} from '@/api/orders'
import { useSessionStore } from '@/stores/session'
const route = useRoute()
const router = useRouter()
const session = useSessionStore()
const loading = ref(false)
const cancelling = ref(false)
const handoffing = ref(false)
const confirming = ref(false)
const order = ref<Order | null>(null)
const handoffRecords = ref<HandoffRecord[]>([])
const handoffContent = ref('')
const isOwner = computed(() => order.value?.owner_id === session.userId)
const isRenter = computed(() => order.value?.renter_id === session.userId)
onMounted(loadOrder)
async function loadOrder() {
loading.value = true
try {
order.value = await fetchOrder(String(route.params.id))
handoffRecords.value = await fetchHandoffRecords(String(route.params.id))
} finally {
loading.value = false
}
}
async function handleCancel() {
if (!order.value) return
cancelling.value = true
try {
await cancelOrder(order.value.id)
ElMessage.success('订单已取消,账号已释放')
await router.push('/orders')
} catch (error) {
ElMessage.error(readError(error, '取消失败'))
} finally {
cancelling.value = false
}
}
async function handleSubmitHandoff() {
if (!order.value) return
handoffing.value = true
try {
await submitHandoff(order.value.id, handoffContent.value)
handoffContent.value = ''
ElMessage.success('交接说明已提交')
await loadOrder()
} catch (error) {
ElMessage.error(readError(error, '提交交接失败'))
} finally {
handoffing.value = false
}
}
async function handleConfirmReceive() {
if (!order.value) return
confirming.value = true
try {
await confirmReceive(order.value.id)
ElMessage.success('已确认收号,订单进入租赁中')
await loadOrder()
} catch (error) {
ElMessage.error(readError(error, '确认收号失败'))
} finally {
confirming.value = false
}
}
function readError(error: unknown, fallback: string) {
if (typeof error === 'object' && error && 'response' in error) {
const response = (error as { response?: { data?: { message?: string } } }).response
return response?.data?.message || fallback
}
return fallback
}
</script>
<template>
<section class="page" v-loading="loading">
<div v-if="order" class="page-header">
<p class="eyebrow">{{ order.order_no }}</p>
<h1>订单详情</h1>
<p>{{ order.title }} · {{ order.server_region }} / {{ order.login_platform }}</p>
</div>
<div v-if="order" class="detail-grid">
<div class="metric-card">
<span>状态</span>
<strong>{{ order.status }}</strong>
</div>
<div class="metric-card">
<span>交接</span>
<strong>{{ order.handoff_status }}</strong>
</div>
<div class="metric-card">
<span>租金</span>
<strong>¥{{ order.rent_amount }}</strong>
</div>
<div class="metric-card">
<span>押金</span>
<strong>¥{{ order.deposit_amount }}</strong>
</div>
</div>
<div v-if="order" class="order-panel">
<p>租期:{{ order.rent_hours }} 小时</p>
<p>开始:{{ order.rent_start_at || '未开始' }}</p>
<p>结束:{{ order.rent_end_at || '未设置' }}</p>
<el-button v-if="order.status === 'pending_handoff'" type="danger" :loading="cancelling" @click="handleCancel">
取消订单并释放账号
</el-button>
</div>
<div v-if="order" class="order-panel">
<h2>交接记录</h2>
<el-empty v-if="handoffRecords.length === 0" description="暂无交接记录" />
<div v-for="record in handoffRecords" :key="record.id" class="timeline-item">
<strong>{{ record.type }}</strong>
<p>{{ record.content }}</p>
<span>{{ record.created_at }}</span>
</div>
</div>
<div v-if="order && isOwner && order.status === 'pending_handoff' && order.handoff_status === 'pending_owner'" class="order-panel">
<h2>提交交接说明</h2>
<el-input v-model="handoffContent" type="textarea" :rows="4" placeholder="填写登录方式、注意事项和交接说明" />
<el-button class="panel-action" type="primary" :loading="handoffing" @click="handleSubmitHandoff">提交交接</el-button>
</div>
<div
v-if="order && isRenter && order.status === 'pending_handoff' && order.handoff_status === 'pending_renter_confirm'"
class="order-panel"
>
<h2>确认收号</h2>
<p>确认账号可以正常登录后,订单会进入租赁中并重新计算租期结束时间。</p>
<el-button type="primary" :loading="confirming" @click="handleConfirmReceive">确认已收到账号</el-button>
</div>
</section>
</template>