|
@@ -63,7 +63,7 @@
|
|
|
<span class="section-count">{{ pendingOrders.length }}</span>
|
|
<span class="section-count">{{ pendingOrders.length }}</span>
|
|
|
</h3>
|
|
</h3>
|
|
|
<div class="order-list">
|
|
<div class="order-list">
|
|
|
- <div v-for="order in pendingOrders" :key="order.id" class="order-row order-row-pending">
|
|
|
|
|
|
|
+ <div v-for="order in pendingOrders" :key="order.id" class="order-row order-row-pending" @click="openDetail(order)">
|
|
|
<div class="order-room">
|
|
<div class="order-room">
|
|
|
{{ order.roomNo || '--' }}
|
|
{{ order.roomNo || '--' }}
|
|
|
</div>
|
|
</div>
|
|
@@ -79,7 +79,7 @@
|
|
|
<span class="order-amount">¥{{ order.totalAmount }}</span>
|
|
<span class="order-amount">¥{{ order.totalAmount }}</span>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
- <div class="order-actions">
|
|
|
|
|
|
|
+ <div class="order-actions" @click.stop>
|
|
|
<NButton size="small" type="success" @click="handleAccept(order)">
|
|
<NButton size="small" type="success" @click="handleAccept(order)">
|
|
|
接单
|
|
接单
|
|
|
</NButton>
|
|
</NButton>
|
|
@@ -99,7 +99,7 @@
|
|
|
<span class="section-count">{{ inProgressOrders.length }}</span>
|
|
<span class="section-count">{{ inProgressOrders.length }}</span>
|
|
|
</h3>
|
|
</h3>
|
|
|
<div class="order-list">
|
|
<div class="order-list">
|
|
|
- <div v-for="order in inProgressOrders" :key="order.id" class="order-row">
|
|
|
|
|
|
|
+ <div v-for="order in inProgressOrders" :key="order.id" class="order-row" @click="openDetail(order)">
|
|
|
<div class="order-room">
|
|
<div class="order-room">
|
|
|
{{ order.roomNo || '--' }}
|
|
{{ order.roomNo || '--' }}
|
|
|
</div>
|
|
</div>
|
|
@@ -117,17 +117,8 @@
|
|
|
<span class="order-amount">¥{{ order.totalAmount }}</span>
|
|
<span class="order-amount">¥{{ order.totalAmount }}</span>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
- <div class="order-actions">
|
|
|
|
|
- <template v-if="order.status === 2">
|
|
|
|
|
- <NButton size="small" type="primary" @click="handlePrepare(order)">
|
|
|
|
|
- 备餐
|
|
|
|
|
- </NButton>
|
|
|
|
|
- </template>
|
|
|
|
|
- <template v-if="order.status === 3">
|
|
|
|
|
- <NButton size="small" type="success" @click="handleReady(order)">
|
|
|
|
|
- 出餐
|
|
|
|
|
- </NButton>
|
|
|
|
|
- </template>
|
|
|
|
|
|
|
+ <div class="order-actions" @click.stop>
|
|
|
|
|
+ <!-- 前厅只有出餐后的配送/完成操作,备餐/出餐归厨房端 -->
|
|
|
<template v-if="order.status === 4">
|
|
<template v-if="order.status === 4">
|
|
|
<NButton size="small" type="primary" @click="handleDeliver(order)">
|
|
<NButton size="small" type="primary" @click="handleDeliver(order)">
|
|
|
配送
|
|
配送
|
|
@@ -151,7 +142,7 @@
|
|
|
<span class="section-count">{{ rejectedOrders.length }}</span>
|
|
<span class="section-count">{{ rejectedOrders.length }}</span>
|
|
|
</h3>
|
|
</h3>
|
|
|
<div class="order-list">
|
|
<div class="order-list">
|
|
|
- <div v-for="order in rejectedOrders" :key="order.id" class="order-row order-row-rejected">
|
|
|
|
|
|
|
+ <div v-for="order in rejectedOrders" :key="order.id" class="order-row order-row-rejected" @click="openDetail(order)">
|
|
|
<div class="order-room">
|
|
<div class="order-room">
|
|
|
{{ order.roomNo || '--' }}
|
|
{{ order.roomNo || '--' }}
|
|
|
</div>
|
|
</div>
|
|
@@ -227,6 +218,7 @@
|
|
|
:key="order.id"
|
|
:key="order.id"
|
|
|
class="kanban-card"
|
|
class="kanban-card"
|
|
|
:style="{ borderTopColor: col.color }"
|
|
:style="{ borderTopColor: col.color }"
|
|
|
|
|
+ @click="openDetail(order)"
|
|
|
>
|
|
>
|
|
|
<div class="kc-top flex items-center justify-between">
|
|
<div class="kc-top flex items-center justify-between">
|
|
|
<span class="kc-room">{{ order.roomNo || '--' }}</span>
|
|
<span class="kc-room">{{ order.roomNo || '--' }}</span>
|
|
@@ -245,7 +237,8 @@
|
|
|
<div v-if="col.key === 'rejected' && order.rejectReason" class="kc-reject-reason text-xs mt-1 text-gray-400">
|
|
<div v-if="col.key === 'rejected' && order.rejectReason" class="kc-reject-reason text-xs mt-1 text-gray-400">
|
|
|
拒单原因:{{ order.rejectReason }}
|
|
拒单原因:{{ order.rejectReason }}
|
|
|
</div>
|
|
</div>
|
|
|
- <div class="kc-actions">
|
|
|
|
|
|
|
+ <div class="kc-actions" @click.stop>
|
|
|
|
|
+ <!-- 前厅只有接单/拒单 + 出餐后的配送/完成,备餐/出餐归厨房端 -->
|
|
|
<template v-if="col.key === 'pending'">
|
|
<template v-if="col.key === 'pending'">
|
|
|
<NButton size="tiny" type="success" @click="handleAccept(order)">
|
|
<NButton size="tiny" type="success" @click="handleAccept(order)">
|
|
|
接单
|
|
接单
|
|
@@ -254,16 +247,6 @@
|
|
|
拒单
|
|
拒单
|
|
|
</NButton>
|
|
</NButton>
|
|
|
</template>
|
|
</template>
|
|
|
- <template v-if="col.key === 'preparing' && order.status === 2">
|
|
|
|
|
- <NButton size="tiny" type="primary" @click="handlePrepare(order)">
|
|
|
|
|
- 备餐
|
|
|
|
|
- </NButton>
|
|
|
|
|
- </template>
|
|
|
|
|
- <template v-if="col.key === 'preparing' && order.status === 3">
|
|
|
|
|
- <NButton size="tiny" type="success" @click="handleReady(order)">
|
|
|
|
|
- 出餐
|
|
|
|
|
- </NButton>
|
|
|
|
|
- </template>
|
|
|
|
|
<template v-if="col.key === 'ready'">
|
|
<template v-if="col.key === 'ready'">
|
|
|
<NButton size="tiny" type="primary" @click="handleDeliver(order)">
|
|
<NButton size="tiny" type="primary" @click="handleDeliver(order)">
|
|
|
配送
|
|
配送
|
|
@@ -435,6 +418,153 @@
|
|
|
:rows="3"
|
|
:rows="3"
|
|
|
/>
|
|
/>
|
|
|
</NModal>
|
|
</NModal>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- ==================== 订单详情弹窗 ==================== -->
|
|
|
|
|
+ <NModal
|
|
|
|
|
+ v-model:show="showDetail"
|
|
|
|
|
+ preset="card"
|
|
|
|
|
+ :title="null"
|
|
|
|
|
+ style="width: 720px; max-width: 95vw;"
|
|
|
|
|
+ :bordered="false"
|
|
|
|
|
+ :segmented="{ content: true }"
|
|
|
|
|
+ class="order-detail-modal"
|
|
|
|
|
+ >
|
|
|
|
|
+ <div v-if="detailOrder" class="receipt-full">
|
|
|
|
|
+ <!-- 顶部标题栏 -->
|
|
|
|
|
+ <div class="receipt-header-bar mb-6 rounded-t-lg p-4 flex items-center justify-between">
|
|
|
|
|
+ <div class="flex items-center gap-3">
|
|
|
|
|
+ <i class="i-mdi:arrow-left text-xl cursor-pointer hover:text-white/80" @click="showDetail = false" />
|
|
|
|
|
+ <span class="text-white text-base font-semibold">订单详情</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <DictTag dict-type="hotel_order_status" :value="String(detailOrder.status)" />
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 房间号区域 -->
|
|
|
|
|
+ <div class="room-hero-section text-center mb-6">
|
|
|
|
|
+ <div class="room-icon-wrapper inline-flex items-center justify-center w-16 h-16 rounded-full bg-blue-100 mb-3">
|
|
|
|
|
+ <i class="i-mdi:home-city text-3xl text-blue-600" />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="room-number text-5xl font-bold text-gray-800 mb-2">
|
|
|
|
|
+ {{ detailOrder.roomNo || '--' }}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="room-meta text-sm text-gray-500">
|
|
|
|
|
+ {{ detailOrder.orderNo }} · {{ formatDetailTime(detailOrder.createTime) }}下单
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 小票主体(虚线边框) -->
|
|
|
|
|
+ <div class="receipt-body mb-6 rounded-lg border-2 border-dashed border-gray-300 p-6 bg-white">
|
|
|
|
|
+ <!-- 小票头部 -->
|
|
|
|
|
+ <div class="receipt-title text-center mb-4 pb-4 border-b border-dashed border-gray-300">
|
|
|
|
|
+ <div class="text-lg font-bold text-gray-800 mb-1">璞石酒店 · 前台联</div>
|
|
|
|
|
+ <div class="text-sm text-gray-500">{{ detailOrder.orderNo }}</div>
|
|
|
|
|
+ <div class="text-xs text-gray-400 mt-1">{{ formatDateTime(detailOrder.createTime) }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 桌号与备注 -->
|
|
|
|
|
+ <div class="receipt-info mb-4 pb-4 border-b border-dashed border-gray-300">
|
|
|
|
|
+ <div class="flex items-center gap-2 mb-2">
|
|
|
|
|
+ <span class="text-sm text-gray-600">桌号:</span>
|
|
|
|
|
+ <span class="text-base font-semibold text-gray-800">{{ detailOrder.roomNo }}</span>
|
|
|
|
|
+ <span class="text-sm text-gray-600 ml-2">{{ detailOrder.roomType || '' }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div v-if="detailOrder.contactName" class="flex items-center gap-2 mb-2">
|
|
|
|
|
+ <span class="text-sm text-gray-600">联系人:</span>
|
|
|
|
|
+ <span class="text-sm text-gray-700">{{ detailOrder.contactName }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="flex items-center gap-2">
|
|
|
|
|
+ <span class="text-sm text-gray-600">备注:</span>
|
|
|
|
|
+ <span class="text-sm text-gray-700">{{ detailOrder.note || '无' }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 菜品明细 -->
|
|
|
|
|
+ <div class="receipt-items mb-4 pb-4 border-b border-dashed border-gray-300">
|
|
|
|
|
+ <div v-for="(item, idx) in (detailOrder.items || [])" :key="item.id" class="receipt-item-row mb-3 last:mb-0">
|
|
|
|
|
+ <div class="item-header flex justify-between items-start mb-1">
|
|
|
|
|
+ <div class="flex-1">
|
|
|
|
|
+ <span class="item-index text-sm text-gray-500 mr-2">[{{ idx + 1 }}]</span>
|
|
|
|
|
+ <span class="item-name text-base font-medium text-gray-800">{{ item.dishName }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <span class="item-price text-right font-semibold text-gray-800 whitespace-nowrap ml-3">
|
|
|
|
|
+ ¥{{ item.subtotal || '0.00' }}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div v-if="item.specDesc || item.additionsDesc" class="item-details text-xs text-gray-500 ml-6">
|
|
|
|
|
+ <span v-if="item.specDesc">{{ item.specDesc }}</span>
|
|
|
|
|
+ <span v-if="item.specDesc && item.additionsDesc"> / </span>
|
|
|
|
|
+ <span v-if="item.additionsDesc">{{ item.additionsDesc }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div v-if="item.note" class="item-note text-xs text-orange-600 ml-6 mt-1">
|
|
|
|
|
+ 备注: {{ item.note }}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 合计 -->
|
|
|
|
|
+ <div class="receipt-total text-right text-lg font-bold text-gray-800">
|
|
|
|
|
+ 合计:¥{{ detailOrder.totalAmount || '0.00' }}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 底部操作按钮(前厅视角) -->
|
|
|
|
|
+ <div class="receipt-actions">
|
|
|
|
|
+ <NButton
|
|
|
|
|
+ v-if="detailOrder.status === 1"
|
|
|
|
|
+ type="success"
|
|
|
|
|
+ block
|
|
|
|
|
+ size="large"
|
|
|
|
|
+ class="action-btn-primary"
|
|
|
|
|
+ @click="handleAcceptFromDetail"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template #icon><i class="i-mdi:check-circle" /></template>
|
|
|
|
|
+ 接单
|
|
|
|
|
+ </NButton>
|
|
|
|
|
+ <NButton
|
|
|
|
|
+ v-if="detailOrder.status === 1"
|
|
|
|
|
+ type="error"
|
|
|
|
|
+ block
|
|
|
|
|
+ size="large"
|
|
|
|
|
+ class="mt-3"
|
|
|
|
|
+ @click="handleRejectFromDetail"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template #icon><i class="i-mdi:close-circle" /></template>
|
|
|
|
|
+ 拒单
|
|
|
|
|
+ </NButton>
|
|
|
|
|
+ <NButton
|
|
|
|
|
+ v-if="detailOrder.status === 4"
|
|
|
|
|
+ type="primary"
|
|
|
|
|
+ block
|
|
|
|
|
+ size="large"
|
|
|
|
|
+ class="action-btn-primary"
|
|
|
|
|
+ @click="handleDeliverFromDetail"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template #icon><i class="i-mdi:truck-delivery" /></template>
|
|
|
|
|
+ 开始配送
|
|
|
|
|
+ </NButton>
|
|
|
|
|
+ <NButton
|
|
|
|
|
+ v-if="detailOrder.status === 5"
|
|
|
|
|
+ type="success"
|
|
|
|
|
+ block
|
|
|
|
|
+ size="large"
|
|
|
|
|
+ class="action-btn-primary"
|
|
|
|
|
+ @click="handleCompleteFromDetail"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template #icon><i class="i-mdi:flag-checkered" /></template>
|
|
|
|
|
+ 完成配送
|
|
|
|
|
+ </NButton>
|
|
|
|
|
+ <div v-if="detailOrder.status >= 2 && detailOrder.status <= 3" class="status-hint text-center text-sm text-gray-400 py-3">
|
|
|
|
|
+ <i class="i-mdi:chef-hat mr-1" />订单正在厨房制作中,请稍候
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div v-if="detailOrder.status === 6" class="status-hint text-center text-sm text-green-600 py-3">
|
|
|
|
|
+ <i class="i-mdi:check-circle mr-1" />订单已完成
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div v-if="detailOrder.status === 7" class="status-hint text-center text-sm text-gray-400 py-3">
|
|
|
|
|
+ <i class="i-mdi:close-circle mr-1" />订单已拒单
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </NModal>
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
@@ -1088,6 +1218,106 @@ function handleComplete(order) {
|
|
|
},
|
|
},
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+// ==================== 订单详情弹窗 ====================
|
|
|
|
|
+const showDetail = ref(false)
|
|
|
|
|
+const detailOrder = ref(null)
|
|
|
|
|
+
|
|
|
|
|
+function openDetail(order) {
|
|
|
|
|
+ detailOrder.value = order
|
|
|
|
|
+ showDetail.value = true
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function formatDetailTime(dateStr) {
|
|
|
|
|
+ if (!dateStr) return '--'
|
|
|
|
|
+ const d = new Date(dateStr)
|
|
|
|
|
+ return `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function formatDateTime(dateStr) {
|
|
|
|
|
+ if (!dateStr) return '--'
|
|
|
|
|
+ const d = new Date(dateStr)
|
|
|
|
|
+ const hh = String(d.getHours()).padStart(2, '0')
|
|
|
|
|
+ const mm = String(d.getMinutes()).padStart(2, '0')
|
|
|
|
|
+ const ss = String(d.getSeconds()).padStart(2, '0')
|
|
|
|
|
+ return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')} ${hh}:${mm}:${ss}`
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function handleAcceptFromDetail() {
|
|
|
|
|
+ if (!detailOrder.value) return
|
|
|
|
|
+ const order = detailOrder.value
|
|
|
|
|
+ dialog.warning({
|
|
|
|
|
+ title: '确认接单',
|
|
|
|
|
+ content: `确认接受订单 ${order.orderNo} 吗?`,
|
|
|
|
|
+ positiveText: '确认接单',
|
|
|
|
|
+ negativeText: '取消',
|
|
|
|
|
+ async onPositiveClick() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ await acceptOrder(order.id)
|
|
|
|
|
+ message.success('接单成功')
|
|
|
|
|
+ showDetail.value = false
|
|
|
|
|
+ refreshAll()
|
|
|
|
|
+ }
|
|
|
|
|
+ catch (err) {
|
|
|
|
|
+ message.error('接单失败')
|
|
|
|
|
+ console.error('[餐厅订单] 接单失败:', err)
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function handleRejectFromDetail() {
|
|
|
|
|
+ if (!detailOrder.value) return
|
|
|
|
|
+ rejectOrderId = detailOrder.value.id
|
|
|
|
|
+ reasonText.value = ''
|
|
|
|
|
+ reasonVisible.value = true
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function handleDeliverFromDetail() {
|
|
|
|
|
+ if (!detailOrder.value) return
|
|
|
|
|
+ const order = detailOrder.value
|
|
|
|
|
+ dialog.warning({
|
|
|
|
|
+ title: '开始配送',
|
|
|
|
|
+ content: `确认开始配送订单 ${order.orderNo}?`,
|
|
|
|
|
+ positiveText: '确认配送',
|
|
|
|
|
+ negativeText: '取消',
|
|
|
|
|
+ async onPositiveClick() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ await deliverOrder(order.id)
|
|
|
|
|
+ message.success('已开始配送')
|
|
|
|
|
+ showDetail.value = false
|
|
|
|
|
+ refreshAll()
|
|
|
|
|
+ }
|
|
|
|
|
+ catch (err) {
|
|
|
|
|
+ message.error('操作失败')
|
|
|
|
|
+ console.error('[餐厅订单] 配送失败:', err)
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function handleCompleteFromDetail() {
|
|
|
|
|
+ if (!detailOrder.value) return
|
|
|
|
|
+ const order = detailOrder.value
|
|
|
|
|
+ dialog.warning({
|
|
|
|
|
+ title: '完成配送',
|
|
|
|
|
+ content: `确认订单 ${order.orderNo} 配送完成?`,
|
|
|
|
|
+ positiveText: '确认完成',
|
|
|
|
|
+ negativeText: '取消',
|
|
|
|
|
+ async onPositiveClick() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ await completeOrder(order.id)
|
|
|
|
|
+ message.success('订单已完成')
|
|
|
|
|
+ showDetail.value = false
|
|
|
|
|
+ refreshAll()
|
|
|
|
|
+ }
|
|
|
|
|
+ catch (err) {
|
|
|
|
|
+ message.error('操作失败')
|
|
|
|
|
+ console.error('[餐厅订单] 完成失败:', err)
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped>
|
|
<style scoped>
|
|
@@ -1514,4 +1744,109 @@ function handleComplete(order) {
|
|
|
color: #999;
|
|
color: #999;
|
|
|
margin-top: 2px;
|
|
margin-top: 2px;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+/* ==================== 小票详情弹窗 ==================== */
|
|
|
|
|
+.order-detail-modal :deep(.n-card__content) {
|
|
|
|
|
+ padding: 0 !important;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.receipt-full {
|
|
|
|
|
+ background: #f5f7fa;
|
|
|
|
|
+ min-height: 500px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.receipt-header-bar {
|
|
|
|
|
+ background: linear-gradient(135deg, #1a6b8c 0%, #0d526e);
|
|
|
|
|
+ color: white;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.room-hero-section {
|
|
|
|
|
+ padding-top: 12px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.room-icon-wrapper {
|
|
|
|
|
+ box-shadow: 0 4px 12px rgba(32, 128, 240, 0.15);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.room-number {
|
|
|
|
|
+ letter-spacing: 2px;
|
|
|
|
|
+ text-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.receipt-body {
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.receipt-title {
|
|
|
|
|
+ font-family: 'Microsoft YaHei', sans-serif;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.receipt-info {
|
|
|
|
|
+ line-height: 1.8;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.receipt-item-row {
|
|
|
|
|
+ padding-bottom: 12px;
|
|
|
|
|
+ margin-bottom: 12px;
|
|
|
|
|
+ border-bottom: 1px dashed #e5e7eb;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.receipt-item-row:last-child {
|
|
|
|
|
+ border-bottom: none;
|
|
|
|
|
+ margin-bottom: 0;
|
|
|
|
|
+ padding-bottom: 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.item-index {
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ color: #f0a020;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.item-name {
|
|
|
|
|
+ font-size: 15px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.item-price {
|
|
|
|
|
+ font-size: 15px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.item-details {
|
|
|
|
|
+ line-height: 1.6;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.item-note {
|
|
|
|
|
+ line-height: 1.6;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.receipt-total {
|
|
|
|
|
+ padding-top: 16px;
|
|
|
|
|
+ border-top: 2px solid #e5e7eb;
|
|
|
|
|
+ font-size: 18px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.receipt-actions {
|
|
|
|
|
+ margin-top: 8px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.action-btn-primary {
|
|
|
|
|
+ height: 52px;
|
|
|
|
|
+ font-size: 16px;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ border-radius: 12px;
|
|
|
|
|
+ transition: all 0.3s ease;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.action-btn-primary:hover {
|
|
|
|
|
+ transform: translateY(-2px);
|
|
|
|
|
+ box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.action-btn-primary:active {
|
|
|
|
|
+ transform: translateY(0);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.status-hint {
|
|
|
|
|
+ padding: 12px 0;
|
|
|
|
|
+}
|
|
|
</style>
|
|
</style>
|