206 lines
4.0 KiB
Vue
206 lines
4.0 KiB
Vue
<script setup lang="ts">
|
|
import type { HandoffRecord } from '@/features/orders/api/orders'
|
|
import { formatHandoffRecordType } from '@/features/orders/composables/useOrderSnapshot'
|
|
import { formatDateTime } from '@/shared/utils/time'
|
|
|
|
const props = withDefaults(
|
|
defineProps<{
|
|
variant?: 'desktop' | 'mobile'
|
|
records: HandoffRecord[]
|
|
listingCode: string
|
|
}>(),
|
|
{ variant: 'desktop' }
|
|
)
|
|
</script>
|
|
|
|
<template>
|
|
<section v-if="props.variant === 'mobile'" class="card-section">
|
|
<h3 class="section-title">交接日志 · 商品编号 {{ props.listingCode }}</h3>
|
|
<van-empty v-if="props.records.length === 0" image="search" description="暂无交接日志记录" />
|
|
<div v-else class="log-timeline">
|
|
<div v-for="record in props.records" :key="record.id" class="log-item">
|
|
<div class="log-dot"></div>
|
|
<div class="log-content-wrap">
|
|
<strong class="log-type">{{ formatHandoffRecordType(record.type) }}</strong>
|
|
<p class="log-desc">{{ record.content }}</p>
|
|
<span class="log-time">{{ formatDateTime(record.created_at) }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<div v-else class="timeline-section">
|
|
<div class="section-header">
|
|
<h2>交接记录</h2>
|
|
<span>商品编号 {{ props.listingCode }}</span>
|
|
</div>
|
|
<div class="timeline-card">
|
|
<div v-if="props.records.length === 0" class="empty-log">暂无交接记录</div>
|
|
<div v-else class="compact-timeline">
|
|
<div v-for="record in props.records" :key="record.id" class="timeline-row">
|
|
<span class="timeline-dot"></span>
|
|
<span class="timeline-time">{{ formatDateTime(record.created_at) }}</span>
|
|
<strong class="timeline-title">{{ formatHandoffRecordType(record.type) }}</strong>
|
|
<p class="timeline-body">{{ record.content }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.timeline-section {
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.section-header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.section-header h2 {
|
|
font-size: 18px;
|
|
font-weight: 700;
|
|
color: #1f2937;
|
|
margin: 0;
|
|
}
|
|
|
|
.timeline-card {
|
|
padding: 12px;
|
|
background: #ffffff;
|
|
border: 1px solid #e5e7eb;
|
|
border-radius: 8px;
|
|
}
|
|
|
|
.empty-log {
|
|
padding: 14px;
|
|
color: #8a94a6;
|
|
font-size: 13px;
|
|
text-align: center;
|
|
}
|
|
|
|
.compact-timeline {
|
|
display: grid;
|
|
gap: 8px;
|
|
}
|
|
|
|
.timeline-row {
|
|
position: relative;
|
|
display: grid;
|
|
grid-template-columns: 150px 92px minmax(0, 1fr);
|
|
gap: 10px;
|
|
align-items: start;
|
|
padding: 10px 12px 10px 22px;
|
|
border: 1px solid #eef1f5;
|
|
border-radius: 6px;
|
|
background: #fbfcfe;
|
|
}
|
|
|
|
.timeline-dot {
|
|
position: absolute;
|
|
left: 10px;
|
|
top: 15px;
|
|
width: 7px;
|
|
height: 7px;
|
|
border-radius: 50%;
|
|
background: #ff6a00;
|
|
}
|
|
|
|
.timeline-time {
|
|
color: #8a94a6;
|
|
font-size: 12px;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.timeline-title {
|
|
font-size: 13px;
|
|
font-weight: 600;
|
|
color: #1f2937;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.timeline-body {
|
|
margin: 0;
|
|
font-size: 13px;
|
|
color: #64748b;
|
|
line-height: 1.55;
|
|
white-space: pre-wrap;
|
|
word-break: break-word;
|
|
}
|
|
|
|
.card-section {
|
|
margin: 12px 12px 0;
|
|
padding: 14px;
|
|
background: #ffffff;
|
|
border-radius: 8px;
|
|
}
|
|
|
|
.section-title {
|
|
font-size: 15px;
|
|
font-weight: 800;
|
|
color: #182232;
|
|
margin: 0 0 12px;
|
|
}
|
|
|
|
.log-timeline {
|
|
position: relative;
|
|
padding-left: 18px;
|
|
}
|
|
|
|
.log-timeline::after {
|
|
content: '';
|
|
position: absolute;
|
|
left: 5px;
|
|
top: 4px;
|
|
bottom: 4px;
|
|
width: 1px;
|
|
background: #e2e8f0;
|
|
}
|
|
|
|
.log-item {
|
|
position: relative;
|
|
padding-bottom: 16px;
|
|
}
|
|
|
|
.log-item:last-child {
|
|
padding-bottom: 0;
|
|
}
|
|
|
|
.log-dot {
|
|
position: absolute;
|
|
left: -18px;
|
|
top: 4px;
|
|
z-index: 1;
|
|
width: 11px;
|
|
height: 11px;
|
|
border: 2px solid #ffffff;
|
|
border-radius: 50%;
|
|
background: #ff6a00;
|
|
}
|
|
|
|
.log-content-wrap {
|
|
display: grid;
|
|
gap: 4px;
|
|
}
|
|
|
|
.log-type {
|
|
color: #182232;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.log-desc {
|
|
margin: 0;
|
|
color: #5f6f86;
|
|
font-size: 13px;
|
|
line-height: 1.55;
|
|
white-space: pre-wrap;
|
|
}
|
|
|
|
.log-time {
|
|
color: #a0aec0;
|
|
font-size: 11px;
|
|
}
|
|
</style>
|