This commit is contained in:
2026-08-18 11:41:14 +08:00
parent 114d5bacc7
commit f9ae2d94cb
8 changed files with 46 additions and 27 deletions
@@ -16,6 +16,9 @@ const props = defineProps<{
/** @deprecated 仅用于兼容尚未完成 customerId 映射的上层集成。 */
tenantId?: string
inboundId: string
customerName?: string | null
channelName?: string | null
channelCode?: string | null
}>()
const emit = defineEmits<{ changed: [] }>()
@@ -36,6 +39,8 @@ const customerId = computed(() => props.customerId || props.tenantId || '')
const isPending = computed(() => detail.value?.measureReviewStatus === 'PENDING' && detail.value?.processStatus === 'MEASURE_PENDING')
const isRejected = computed(() => detail.value?.measureReviewStatus === 'REJECTED' && detail.value?.processStatus === 'MEASURE_REJECTED')
const reviewStatusLabel = computed(() => inboundStatusLabel(detail.value?.measureReviewStatus, inboundReviewStatusLabels, '未提交'))
const displayCustomerName = computed(() => detail.value?.companyName?.trim() || props.customerName?.trim() || '客户未命名')
const displayChannelName = computed(() => detail.value?.channelName?.trim() || detail.value?.channelCode?.trim() || props.channelName?.trim() || props.channelCode?.trim() || '渠道未填写')
function formatDate(value: string | null | undefined) {
return value ? value.replace('T', ' ') : '—'
@@ -135,20 +140,18 @@ defineExpose({ confirmApprove, isPending, canReview, actionLoading })
<section class="review-panel" aria-labelledby="measurement-review-title">
<h2 id="measurement-review-title" class="sr-only">测量审核内容</h2>
<div class="review-toolbar" aria-label="测量审核操作">
<div class="review-toolbar__main">
<div class="review-toolbar__status">
<StatusBadge v-if="detail" :status="reviewStatusLabel" />
<span v-if="isPending">通过后进入待分柜</span>
<span v-else-if="isRejected">历史记录为审核驳回,仅供查看</span>
<span v-else>当前记录不可审核</span>
</div>
<div class="review-toolbar__actions">
<el-button v-if="isPending && canReview" type="primary" plain @click="correctionMode = true"><Pencil :size="16" />修改重量</el-button>
<el-button v-if="isPending && canReview" type="primary" :loading="actionLoading === 'approve'" @click="confirmApprove"><Check :size="16" />通过并进入待分柜</el-button>
<el-button :loading="loading || historyLoading" aria-label="刷新审核数据" @click="reload"><RotateCcw :size="16" />刷新</el-button>
</div>
<div class="review-toolbar__status">
<StatusBadge v-if="detail" :status="reviewStatusLabel" />
<span v-if="isPending">通过后进入待分柜</span>
<span v-else-if="isRejected">历史记录为审核驳回,仅供查看</span>
<span v-else>当前记录不可审核</span>
<span v-if="detail" class="review-toolbar__context">客户:{{ displayCustomerName }} · 渠道:{{ displayChannelName }}</span>
</div>
<div class="review-toolbar__actions">
<el-button v-if="isPending && canReview" type="primary" plain @click="correctionMode = true"><Pencil :size="16" />修改重量</el-button>
<el-button v-if="isPending && canReview" type="primary" :loading="actionLoading === 'approve'" @click="confirmApprove"><Check :size="16" />通过并进入待分柜</el-button>
<el-button :loading="loading || historyLoading" aria-label="刷新审核数据" @click="reload"><RotateCcw :size="16" />刷新</el-button>
</div>
<p v-if="detail" class="review-toolbar__context">客户:{{ detail.companyName || '客户未命名' }} · 渠道:{{ detail.channelName || detail.channelCode || '渠道未填写' }}</p>
</div>
<el-alert v-if="loadError" type="error" :closable="false" show-icon role="alert">
@@ -187,13 +190,12 @@ defineExpose({ confirmApprove, isPending, canReview, actionLoading })
<style scoped>
.review-panel { display: grid; gap: 16px; color: var(--cc-text); }
.review-toolbar { position: sticky; z-index: 4; top: 0; display: grid; gap: 10px; margin: -20px -24px 0; padding: 14px 24px 12px; border-bottom: 1px solid var(--cc-border); background: #fff; box-shadow: 0 4px 12px rgb(16 24 40 / 6%); }
.review-toolbar__main { display: flex; min-width: 0; align-items: center; justify-content: space-between; gap: 14px; }
.review-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 14px; margin: -20px -24px 0; padding: 14px 24px; border-bottom: 1px solid var(--cc-border); background: #fff; }
.review-toolbar__status, .review-toolbar__actions { display: flex; min-width: 0; align-items: center; flex-wrap: wrap; gap: 8px; }
.review-toolbar__status > span { color: var(--cc-muted); font-size: 12px; }
.review-toolbar__actions { justify-content: flex-end; }
.review-toolbar__actions :deep(.el-button) { margin-left: 0; }
.review-toolbar__context { margin: 0; padding-top: 10px; border-top: 1px solid var(--cc-border); color: var(--cc-muted); font-size: 13px; line-height: 1.55; overflow-wrap: anywhere; }
.review-toolbar__status > .review-toolbar__context { padding-left: 8px; border-left: 1px solid var(--cc-border); font-size: 13px; line-height: 1.55; overflow-wrap: anywhere; }
.review-alert-title { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.review-history { border-top: 1px solid var(--cc-border); border-bottom: 0; }
.review-history :deep(.el-collapse-item__header) { height: 42px; color: var(--cc-muted); font-size: 12px; }
@@ -209,8 +211,8 @@ defineExpose({ confirmApprove, isPending, canReview, actionLoading })
.history-content time, .history-content > span { color: var(--cc-muted); font-size: 11px; }
.history-content p { margin: 5px 0 4px; color: var(--cc-text); font-size: 13px; overflow-wrap: anywhere; }
@media (max-width: 720px) {
.review-toolbar { margin: -14px -14px 0; padding: 12px 14px; }
.review-toolbar__main { align-items: stretch; flex-direction: column; }
.review-toolbar { align-items: stretch; flex-direction: column; margin: -14px -14px 0; padding: 12px 14px; }
.review-toolbar__status > .review-toolbar__context { width: 100%; padding-top: 8px; padding-left: 0; border-top: 1px solid var(--cc-border); border-left: 0; }
.review-toolbar__actions { display: grid; width: 100%; grid-template-columns: 1fr; justify-content: stretch; }
.review-toolbar__actions :deep(.el-button) { width: 100%; min-height: 44px; }
}