优化
This commit is contained in:
@@ -16,6 +16,18 @@ function activeCustomer(id: string, tenantName: string, legalName: string | null
|
||||
}
|
||||
|
||||
describe('InboundTaskList measurement scope', () => {
|
||||
it('uses supplied order status tabs in the toolbar and keeps standalone mode titles as fallback', () => {
|
||||
const source = readFileSync(resolve('src/modules/inbounds/components/InboundTaskList.vue'), 'utf8')
|
||||
const toolbar = source.match(/<template #toolbar-start>([\s\S]*?)<\/template>/)?.[1]
|
||||
const filters = source.match(/<template #filters>([\s\S]*?)<\/template>/)?.[1]
|
||||
expect(toolbar).toContain('<slot name="status-tabs"><h1>')
|
||||
expect(toolbar).toContain("title || (isReview ? '测量数据审核' : '订单测量')")
|
||||
expect(toolbar).toContain('</h1></slot>')
|
||||
expect(filters).toContain('<QueryToolbar')
|
||||
expect(filters).not.toContain('name="status-tabs"')
|
||||
expect(source).toContain('<template v-if="isReview && access.can(actionPermission)" #toolbar-actions>')
|
||||
})
|
||||
|
||||
it('supports selecting only pending measurement reviews for batch approval', () => {
|
||||
const source = readFileSync(resolve('src/modules/inbounds/components/InboundTaskList.vue'), 'utf8')
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import '@/styles/adminDensity.css'
|
||||
import '@/styles/adminWorkbench.css'
|
||||
import '../measurement/measurementDensity.css'
|
||||
import { computed, onActivated, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
@@ -341,13 +342,13 @@ onBeforeUnmount(() => { disposed = true; requestSerial += 1; optionsRequestSeria
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AdminPage as="div" class="inbound-task-page admin-density">
|
||||
<AdminPage as="div" class="inbound-task-page admin-density admin-workbench">
|
||||
<ListPageLayout :aria-label="`${taskLabel}待办`">
|
||||
|
||||
|
||||
|
||||
|
||||
<section :aria-busy="loading"><DataTable appearance="integrated" :stripe="false" column-settings-mode="show" :results-visible="!loadError"
|
||||
<section :aria-busy="loading"><div class="workbench-table is-page-surface"><DataTable appearance="integrated" :stripe="false" column-settings-mode="show" :results-visible="!loadError"
|
||||
v-model:page="page"
|
||||
v-model:page-size="pageSize"
|
||||
:data="result.records"
|
||||
@@ -361,9 +362,8 @@ onBeforeUnmount(() => { disposed = true; requestSerial += 1; optionsRequestSeria
|
||||
:aria-label="`${taskLabel}待办列表`"
|
||||
@selection-change="handleReviewSelectionChange"
|
||||
>
|
||||
<template #toolbar-start><h1>{{ title || (isReview ? '测量数据审核' : '订单测量') }}</h1></template>
|
||||
<template #toolbar-start><slot name="status-tabs"><h1>{{ title || (isReview ? '测量数据审核' : '订单测量') }}</h1></slot></template>
|
||||
<template #filters>
|
||||
<slot name="status-tabs" />
|
||||
<QueryToolbar
|
||||
v-model="filters"
|
||||
:ariaLabel="`${taskLabel}待办筛选`"
|
||||
@@ -415,7 +415,7 @@ onBeforeUnmount(() => { disposed = true; requestSerial += 1; optionsRequestSeria
|
||||
<template #actualVolumeCbm="{ row }">{{ formatNumber((row as InboundOrderSummary).actualVolumeCbm) }}</template>
|
||||
<template #measureCompletedAt="{ row }">{{ formatDate((row as InboundOrderSummary).measureCompletedAt) }}</template>
|
||||
<template #empty><el-empty :description="emptyText" /></template>
|
||||
</DataTable></section>
|
||||
</DataTable></div></section>
|
||||
</ListPageLayout>
|
||||
|
||||
<AppDialog
|
||||
@@ -430,7 +430,7 @@ onBeforeUnmount(() => { disposed = true; requestSerial += 1; optionsRequestSeria
|
||||
append-to-body
|
||||
:close-on-click-modal="!reviewNavigationLoading"
|
||||
:close-on-press-escape="!reviewNavigationLoading"
|
||||
class="inbound-task-dialog admin-density-dialog admin-density-workspace inbound-density"
|
||||
class="inbound-task-dialog admin-density-dialog admin-density-workspace inbound-density admin-workbench is-dialog"
|
||||
@closed="clearSelectedInbound"
|
||||
>
|
||||
<el-alert v-if="reviewNavigationError" type="error" :closable="false" show-icon class="review-navigation-error">
|
||||
@@ -487,7 +487,7 @@ onBeforeUnmount(() => { disposed = true; requestSerial += 1; optionsRequestSeria
|
||||
.primary-cell { display: grid; gap: 3px; min-width: 0; }
|
||||
.primary-cell strong, .primary-cell span { overflow-wrap: anywhere; }
|
||||
.inbound-code-cell { display: grid; gap: 3px; min-width: 0; }
|
||||
.primary-cell span, .muted-action { color: var(--cc-muted); font-size: var(--admin-font-caption, 12px); }
|
||||
.primary-cell span, .muted-action { color: var(--workbench-muted); font-size: var(--admin-font-caption, 12px); }
|
||||
@media (max-width: 520px) {
|
||||
.row-actions { align-items: stretch; flex-direction: column; }
|
||||
.row-actions :deep(.el-button) { width: 100%; }
|
||||
|
||||
@@ -4,6 +4,7 @@ import { onBeforeUnmount, ref, watch } from 'vue'
|
||||
import { Printer, RefreshCw } from '@lucide/vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import '@/styles/adminDensity.css'
|
||||
import '@/styles/adminWorkbench.css'
|
||||
import { getApiErrorDetails, type ApiErrorDetails } from '@/shared/api/http'
|
||||
import ApiErrorMeta from '@/shared/components/ApiErrorMeta.vue'
|
||||
import LoadErrorState from '@/shared/components/LoadErrorState.vue'
|
||||
@@ -86,7 +87,7 @@ onBeforeUnmount(() => { disposed = true; requestSerial += 1 })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="dropship-print-panel admin-density" aria-labelledby="dropship-print-title">
|
||||
<section class="dropship-print-panel admin-density admin-workbench" aria-labelledby="dropship-print-title">
|
||||
<header class="print-heading">
|
||||
<div>
|
||||
<h3 id="dropship-print-title">一件代发托盘打印<InlineHelp title="托盘打印说明"><p>测量审核生成托盘码后,在电脑端打印并贴到空托盘,再交由 PDA 扫码组托。</p><p>箱数与 SKU 种类数按整托统计,包含合托的其他入仓码;相同 SKU 编码只计一种,不代表商品件数。</p></InlineHelp></h3>
|
||||
@@ -121,8 +122,8 @@ onBeforeUnmount(() => { disposed = true; requestSerial += 1 })
|
||||
<style scoped>
|
||||
.dropship-print-panel { min-width: 0; }
|
||||
.print-heading { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--admin-space-5); margin-bottom: var(--admin-space-5); }
|
||||
.print-heading h3 { margin: 0; color: var(--cc-text); font-size: var(--admin-font-section); }
|
||||
.print-heading p { margin: var(--admin-space-1) 0 0; color: var(--cc-muted); font-size: var(--admin-font-caption); line-height: 1.5; }
|
||||
.print-heading h3 { margin: 0; color: var(--workbench-text); font-size: var(--admin-font-section); }
|
||||
.print-heading p { margin: var(--admin-space-1) 0 0; color: var(--workbench-muted); font-size: var(--admin-font-caption); line-height: 1.5; }
|
||||
.print-actions { display: flex; flex-shrink: 0; gap: var(--admin-space-2); }
|
||||
.print-actions .el-button { margin-left: 0; }
|
||||
.loading-state { padding: var(--admin-space-5) 0; }
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import '@/styles/adminDensity.css'
|
||||
import '@/styles/adminWorkbench.css'
|
||||
import type { InboundDropshipPallet, InboundFileSummary, InboundInternalNote, InboundPalletLocation, InboundStatusHistory } from './types'
|
||||
import { inboundHistoryActionLabel, inboundProcessStatusLabels, inboundStatusLabel } from '../status'
|
||||
import { downloadDropshipPalletLabel } from './api'
|
||||
@@ -47,7 +49,7 @@ async function printPallet(pallet: InboundDropshipPallet) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="history-panel">
|
||||
<div class="history-panel admin-workbench">
|
||||
<section v-if="shows('dropship')" class="history-section">
|
||||
<div class="section-heading"><h3>一件代发清点与组托结果</h3><span>{{ dropshipPallets.length }} 个托盘</span></div>
|
||||
<el-alert v-if="!canViewDropship" title="当前账号缺少一件代发 PDA 查看权限,无法读取清点组托结果。" type="warning" :closable="false" show-icon />
|
||||
@@ -102,7 +104,7 @@ async function printPallet(pallet: InboundDropshipPallet) {
|
||||
</section>
|
||||
<section v-if="shows('history')" class="history-section">
|
||||
<div class="section-heading"><h3>状态历史</h3><span>{{ statusHistory.length }} 条</span></div>
|
||||
<ol v-if="statusHistory.length" class="timeline"><li v-for="(history, index) in statusHistory" :key="`${history.occurredAt}-${index}`"><span class="timeline-dot" /><div><strong>{{ inboundHistoryActionLabel(history.action) }}</strong><span>{{ inboundStatusLabel(history.fromStatus, inboundProcessStatusLabels) }} → {{ inboundStatusLabel(history.toStatus, inboundProcessStatusLabels) }} · {{ value(history.operatorName || history.operatorId) }}</span><small>{{ date(history.occurredAt) }}<template v-if="history.reason"> · {{ history.reason }}</template></small></div></li></ol>
|
||||
<ol v-if="statusHistory.length" class="timeline"><li v-for="(history, index) in statusHistory" :key="`${history.occurredAt}-${index}`"><span class="timeline-dot" /><div><strong>{{ inboundHistoryActionLabel(history.action) }}</strong><span>{{ inboundStatusLabel(history.fromStatus, inboundProcessStatusLabels) }} → {{ inboundStatusLabel(history.toStatus, inboundProcessStatusLabels) }} · {{ value(history.operatorName) }}</span><small>{{ date(history.occurredAt) }}<template v-if="history.reason"> · {{ history.reason }}</template></small></div></li></ol>
|
||||
<p v-else class="muted-empty">暂无状态历史</p>
|
||||
</section>
|
||||
<section v-if="shows('remark') && publicRemark" class="history-section remark-section"><div class="section-heading"><h3>公开备注</h3></div><p>{{ publicRemark }}</p></section>
|
||||
@@ -111,46 +113,46 @@ async function printPallet(pallet: InboundDropshipPallet) {
|
||||
|
||||
<style scoped>
|
||||
.history-panel { display: grid; gap: 24px; min-width: 0; }
|
||||
.history-section { min-width: 0; padding-top: 16px; border-top: 1px solid var(--cc-border); }
|
||||
.history-section { min-width: 0; padding-top: 16px; border-top: 1px solid var(--workbench-border); }
|
||||
.history-section:first-child { padding-top: 0; border-top: 0; }
|
||||
.section-heading { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
|
||||
.section-heading h3 { margin: 0; color: #172033; font-size: 13px; }
|
||||
.section-heading span { color: var(--cc-muted); font-size: 12px; }
|
||||
.allocation-list, .simple-list { overflow: hidden; border: 1px solid var(--cc-border); border-radius: 6px; background: #fff; }
|
||||
.section-heading span { color: var(--workbench-muted); font-size: 12px; }
|
||||
.allocation-list, .simple-list { overflow: hidden; border: 1px solid var(--workbench-border); border-radius: 6px; background: #fff; }
|
||||
.allocation-row { display: grid; grid-template-columns: 1fr auto minmax(100px, 0.8fr); gap: 12px; align-items: center; padding: 10px 12px; border-bottom: 1px solid #edf0f4; font-size: 12px; }
|
||||
.allocation-row:last-child, .simple-list > div:last-child { border-bottom: 0; }
|
||||
.allocation-row > div, .simple-list > div { min-width: 0; }
|
||||
.allocation-row span, .simple-list span { display: block; margin-top: 3px; color: var(--cc-muted); }
|
||||
.allocation-location { overflow-wrap: anywhere; color: var(--cc-primary); text-align: right; }
|
||||
.allocation-row span, .simple-list span { display: block; margin-top: 3px; color: var(--workbench-muted); }
|
||||
.allocation-location { overflow-wrap: anywhere; color: var(--workbench-primary); text-align: right; }
|
||||
.simple-list > div { padding: 10px 12px; border-bottom: 1px solid #edf0f4; font-size: 12px; }
|
||||
.simple-list strong, .simple-list span { overflow-wrap: anywhere; }
|
||||
.dropship-pallet-list { display: grid; gap: 12px; }
|
||||
.dropship-pallet-card { min-width: 0; overflow: hidden; border: 1px solid var(--cc-border); border-radius: 6px; background: #fff; }
|
||||
.dropship-pallet-card { min-width: 0; overflow: hidden; border: 1px solid var(--workbench-border); border-radius: 6px; background: #fff; }
|
||||
.dropship-pallet-card > header { display: flex; min-height: 42px; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 12px; border-bottom: 1px solid #edf0f4; background: #f8fafc; }
|
||||
.dropship-pallet-card > header > div { display: flex; min-width: 0; align-items: center; gap: 8px; }
|
||||
.dropship-pallet-card > header strong { overflow-wrap: anywhere; color: #172033; font-size: 13px; }
|
||||
.dropship-pallet-summary { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); margin: 0; border-bottom: 1px solid #edf0f4; }
|
||||
.dropship-pallet-summary > div { min-width: 0; padding: 8px 12px; border-right: 1px solid #edf0f4; }
|
||||
.dropship-pallet-summary > div:last-child { border-right: 0; }
|
||||
.dropship-pallet-summary dt { color: var(--cc-muted); font-size: 11px; }
|
||||
.dropship-pallet-summary dd { margin: 3px 0 0; overflow-wrap: anywhere; color: var(--cc-text); font-size: 12px; font-weight: 650; }
|
||||
.dropship-pallet-summary dt { color: var(--workbench-muted); font-size: 11px; }
|
||||
.dropship-pallet-summary dd { margin: 3px 0 0; overflow-wrap: anywhere; color: var(--workbench-text); font-size: 12px; font-weight: 650; }
|
||||
.dropship-item-table { min-width: 680px; }
|
||||
.dropship-pallet-card { overflow-x: auto; }
|
||||
.dropship-item-row { display: grid; grid-template-columns: minmax(140px, 1fr) minmax(180px, 1.2fr) 100px 70px minmax(220px, 1.5fr); min-width: 800px; border-bottom: 1px solid #edf0f4; }
|
||||
.dropship-item-row:last-child { border-bottom: 0; }
|
||||
.dropship-item-row > span { min-width: 0; padding: 8px 12px; overflow-wrap: anywhere; color: var(--cc-text); font-size: 12px; }
|
||||
.dropship-item-row > span { min-width: 0; padding: 8px 12px; overflow-wrap: anywhere; color: var(--workbench-text); font-size: 12px; }
|
||||
.dropship-item-row > span + span { border-left: 1px solid #edf0f4; }
|
||||
.dropship-item-row small { display: block; margin-top: 3px; color: var(--cc-muted); font-size: 11px; }
|
||||
.dropship-item-row small { display: block; margin-top: 3px; color: var(--workbench-muted); font-size: 11px; }
|
||||
.dropship-item-row--header { background: #f8fafc; }
|
||||
.dropship-item-row--header > span { color: var(--cc-muted); font-size: 11px; font-weight: 650; }
|
||||
.muted-empty { margin: 0; padding: 18px 12px; border: 1px dashed var(--cc-border); border-radius: 6px; background: #f8fafc; color: var(--cc-muted); font-size: 12px; text-align: center; }
|
||||
.dropship-item-row--header > span { color: var(--workbench-muted); font-size: 11px; font-weight: 650; }
|
||||
.muted-empty { margin: 0; padding: 18px 12px; border: 1px dashed var(--workbench-border); border-radius: 6px; background: #f8fafc; color: var(--workbench-muted); font-size: 12px; text-align: center; }
|
||||
.timeline { display: grid; gap: 0; margin: 0; padding: 0; list-style: none; }
|
||||
.timeline li { display: grid; grid-template-columns: 16px 1fr; gap: 10px; min-width: 0; padding-bottom: 16px; }
|
||||
.timeline-dot { width: 8px; height: 8px; margin-top: 5px; border: 2px solid var(--cc-primary); border-radius: 50%; background: #fff; box-shadow: 0 0 0 3px color-mix(in srgb, var(--cc-primary) 12%, transparent); }
|
||||
.timeline-dot { width: 8px; height: 8px; margin-top: 5px; border: 2px solid var(--workbench-primary); border-radius: 50%; background: #fff; box-shadow: 0 0 0 3px color-mix(in srgb, var(--workbench-primary) 12%, transparent); }
|
||||
.timeline li > div { min-width: 0; padding-bottom: 12px; border-bottom: 1px solid #edf0f4; }
|
||||
.timeline strong, .timeline span, .timeline small { display: block; overflow-wrap: anywhere; }
|
||||
.timeline span, .timeline small { margin-top: 3px; color: var(--cc-muted); font-size: 12px; line-height: 1.5; }
|
||||
.remark-section p { margin: 0; padding: 12px; border-radius: 6px; background: #f8fafc; color: var(--cc-text); font-size: 13px; line-height: 1.6; white-space: pre-wrap; }
|
||||
.timeline span, .timeline small { margin-top: 3px; color: var(--workbench-muted); font-size: 12px; line-height: 1.5; }
|
||||
.remark-section p { margin: 0; padding: 12px; border-radius: 6px; background: #f8fafc; color: var(--workbench-text); font-size: 13px; line-height: 1.6; white-space: pre-wrap; }
|
||||
@media (max-width: 720px) { .dropship-pallet-summary { grid-template-columns: 1fr; } .dropship-pallet-summary > div { border-right: 0; border-bottom: 1px solid #edf0f4; } .dropship-pallet-summary > div:last-child { border-bottom: 0; } }
|
||||
@media (max-width: 480px) { .allocation-row { grid-template-columns: 1fr auto; } .allocation-location { grid-column: 1 / -1; text-align: left; } }
|
||||
</style>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import '@/styles/adminDensity.css'
|
||||
import '@/styles/adminWorkbench.css'
|
||||
import InlineHelp from '@/shared/components/InlineHelp.vue'
|
||||
import { computed, reactive, ref, watch } from 'vue'
|
||||
import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus'
|
||||
@@ -378,7 +380,7 @@ defineExpose({ reload: loadFee })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="inbound-fee-panel" :aria-busy="loading" aria-labelledby="inbound-fee-title">
|
||||
<section class="inbound-fee-panel admin-workbench" :aria-busy="loading" aria-labelledby="inbound-fee-title">
|
||||
<header class="fee-heading" :class="{ 'fee-heading--compact': compact }">
|
||||
<h3 v-if="compact" id="inbound-fee-title" class="fee-heading-title--compact">头程自动初算 <InlineHelp title="计费说明"><p>测量审核完成后,系统会自动生成初算费用;人工确认后才发布。</p><p>实际重量与体积重量取大后计费,金额以服务端快照为准。</p></InlineHelp></h3>
|
||||
<div v-else class="fee-heading-copy">
|
||||
@@ -437,7 +439,7 @@ defineExpose({ reload: loadFee })
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<AppDialog v-model="trialOpen" title="头程费用试算" width="min(760px, calc(100vw - 28px))" :confirm-loading="trialLoading" confirm-text="开始试算" @confirm="submitTrial">
|
||||
<AppDialog class="admin-workbench is-dialog" v-model="trialOpen" title="头程费用试算" width="min(760px, calc(100vw - 28px))" :confirm-loading="trialLoading" confirm-text="开始试算" @confirm="submitTrial">
|
||||
|
||||
<div class="trial-source-grid">
|
||||
<section><h4>计费重量(单选)<InlineHelp title="试算取值说明"><p>重量和体积各选择一项;默认选择实际测量数据。</p></InlineHelp></h4><el-radio-group v-model="trial.weightSource"><el-radio v-for="item in sourceOptions" :key="`weight-${item.value}`" :value="item.value" :disabled="item.weight <= 0"><span>{{ item.label }}</span><strong>{{ formatNumber(item.weight) }} KG</strong></el-radio></el-radio-group></section>
|
||||
@@ -563,7 +565,7 @@ defineExpose({ reload: loadFee })
|
||||
<OperationErrorToast :details="adjustmentError" />
|
||||
|
||||
<AppDialog
|
||||
v-model="adjustOpen"
|
||||
class="admin-workbench is-dialog" v-model="adjustOpen"
|
||||
title="调整入库费用"
|
||||
width="min(760px, calc(100vw - 28px))"
|
||||
confirm-text="确认调整并生成新版本"
|
||||
@@ -605,15 +607,15 @@ defineExpose({ reload: loadFee })
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.inbound-fee-panel { min-width: 0; color: var(--cc-text); }
|
||||
.inbound-fee-panel { min-width: 0; color: var(--workbench-text); }
|
||||
.fee-heading { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding-bottom: 16px; }
|
||||
.fee-heading--compact { align-items: center; justify-content: space-between; padding: 12px 0 8px; }
|
||||
.fee-heading h3.fee-heading-title--compact { color: #344054; font-size: var(--admin-font-section, 14px); line-height: 1.4; }
|
||||
.fee-heading-copy { display: flex; min-width: 0; align-items: flex-start; gap: 12px; }
|
||||
.fee-heading-icon { display: grid; width: 38px; height: 38px; flex: 0 0 38px; place-items: center; border-radius: 10px; background: #eef4ff; color: var(--cc-primary); }
|
||||
.fee-heading-icon { display: grid; width: 38px; height: 38px; flex: 0 0 38px; place-items: center; border-radius: 10px; background: #eef4ff; color: var(--workbench-primary); }
|
||||
.fee-heading h3, .section-title h4 { margin: 0; }
|
||||
.fee-heading h3 { font-size: 16px; }
|
||||
.fee-heading p, .section-title p { margin: 5px 0 0; color: var(--cc-muted); font-size: 12px; line-height: 1.55; }
|
||||
.fee-heading p, .section-title p { margin: 5px 0 0; color: var(--workbench-muted); font-size: 12px; line-height: 1.55; }
|
||||
.fee-heading-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; }
|
||||
.fee-heading-actions .el-button { margin-left: 0; }
|
||||
.fee-refresh-button .is-spinning { animation: fee-refresh-spin 0.8s linear infinite; }
|
||||
@@ -621,50 +623,50 @@ defineExpose({ reload: loadFee })
|
||||
.fee-refresh-error { margin-bottom: 10px; }
|
||||
.inbound-fee-panel :deep(.el-alert p) { margin: 5px 0 0; line-height: 1.55; }
|
||||
.inbound-fee-panel :deep(.el-alert .el-button) { margin-top: 8px; }
|
||||
.empty-note { margin: 0; color: var(--cc-muted); font-size: 12px; }
|
||||
.fee-content { border-top: 1px solid var(--cc-border); }
|
||||
.fee-summary { display: grid; grid-template-columns: minmax(230px, 1.3fr) repeat(4, minmax(135px, 1fr)); border-top: 1px solid var(--cc-border); border-bottom: 1px solid var(--cc-border); }
|
||||
.empty-note { margin: 0; color: var(--workbench-muted); font-size: 12px; }
|
||||
.fee-content { border-top: 1px solid var(--workbench-border); }
|
||||
.fee-summary { display: grid; grid-template-columns: minmax(230px, 1.3fr) repeat(4, minmax(135px, 1fr)); border-top: 1px solid var(--workbench-border); border-bottom: 1px solid var(--workbench-border); }
|
||||
.fee-total, .fee-summary-item { display: flex; min-width: 0; flex-direction: column; justify-content: center; gap: 3px; padding: 11px 14px; }
|
||||
.fee-summary-item { border-left: 1px solid var(--cc-border); }
|
||||
.fee-summary span, .fee-summary small { color: var(--cc-muted); font-size: 11px; }
|
||||
.fee-summary-item { border-left: 1px solid var(--workbench-border); }
|
||||
.fee-summary span, .fee-summary small { color: var(--workbench-muted); font-size: 11px; }
|
||||
.fee-summary strong { font-size: 18px; line-height: 1.25; overflow-wrap: anywhere; }
|
||||
.fee-total strong { color: #0f5c49; font-size: 21px; letter-spacing: -.01em; }
|
||||
.fee-summary-item strong { font-size: 15px; }
|
||||
.version-status { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
|
||||
@keyframes fee-refresh-spin { to { transform: rotate(360deg); } }
|
||||
.calculation-section, .fee-timeline { padding: 10px 0; border-bottom: 1px solid var(--cc-border); }
|
||||
.calculation-section, .fee-timeline { padding: 10px 0; border-bottom: 1px solid var(--workbench-border); }
|
||||
.section-title { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
|
||||
.calculation-tags { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px; }
|
||||
.section-title h4 { font-size: 14px; }
|
||||
.calculation-flow { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); margin-top: 7px; border-top: 1px solid var(--cc-border); border-bottom: 1px solid var(--cc-border); }
|
||||
.calculation-flow > div { display: flex; min-width: 0; min-height: 46px; flex-direction: row; align-items: center; justify-content: space-between; gap: 8px; padding: 6px 10px; border-right: 1px solid var(--cc-border); }
|
||||
.calculation-flow { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); margin-top: 7px; border-top: 1px solid var(--workbench-border); border-bottom: 1px solid var(--workbench-border); }
|
||||
.calculation-flow > div { display: flex; min-width: 0; min-height: 46px; flex-direction: row; align-items: center; justify-content: space-between; gap: 8px; padding: 6px 10px; border-right: 1px solid var(--workbench-border); }
|
||||
.calculation-flow > div:last-child { border-right: 0; }
|
||||
.calculation-flow span, .calculation-flow small { color: var(--cc-muted); font-size: 11px; }
|
||||
.calculation-flow span, .calculation-flow small { color: var(--workbench-muted); font-size: 11px; }
|
||||
.calculation-flow strong { font-size: 13px; overflow-wrap: anywhere; }
|
||||
.calculation-flow small { display: none; }
|
||||
.calculation-flow .is-chargeable { background: #f7fbfa; }
|
||||
.calculation-flow .is-chargeable strong { color: #087d70; }
|
||||
.amount-equation { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; margin-top: 5px; padding: 4px 0 0; color: #475467; font-size: 12px; }
|
||||
.amount-equation i { color: #98a2b3; font-style: normal; }
|
||||
.amount-equation strong { color: var(--cc-text); font-size: 15px; }
|
||||
.fee-detail-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); border-bottom: 1px solid var(--cc-border); }
|
||||
.amount-equation strong { color: var(--workbench-text); font-size: 15px; }
|
||||
.fee-detail-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); border-bottom: 1px solid var(--workbench-border); }
|
||||
.fee-detail-grid > section { min-width: 0; padding: 22px 20px 22px 0; }
|
||||
.fee-detail-grid > section + section { padding-right: 0; padding-left: 20px; border-left: 1px solid var(--cc-border); }
|
||||
.fee-detail-grid > section + section { padding-right: 0; padding-left: 20px; border-left: 1px solid var(--workbench-border); }
|
||||
.fee-detail-grid dl { margin: 14px 0 0; }
|
||||
.fee-detail-grid dl > div { display: grid; grid-template-columns: 104px minmax(0, 1fr); gap: 12px; padding: 9px 0; border-top: 1px solid #edf0f4; font-size: 12px; }
|
||||
.fee-detail-grid dt { color: var(--cc-muted); }
|
||||
.fee-detail-grid dt { color: var(--workbench-muted); }
|
||||
.fee-detail-grid dd { min-width: 0; margin: 0; font-weight: 600; overflow-wrap: anywhere; }
|
||||
.fee-timeline { border-bottom: 0; }
|
||||
.fee-timeline ol { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0; margin: 18px 0 0; padding: 0; list-style: none; }
|
||||
.fee-timeline li { position: relative; display: flex; min-width: 0; flex-direction: column; gap: 5px; padding: 0 18px 0 20px; }
|
||||
.fee-timeline li::before { position: absolute; top: 4px; left: 0; width: 9px; height: 9px; border-radius: 50%; background: #12b76a; content: ''; }
|
||||
.fee-timeline li::after { position: absolute; top: 8px; right: 0; left: 10px; z-index: -1; height: 1px; background: var(--cc-border); content: ''; }
|
||||
.fee-timeline li::after { position: absolute; top: 8px; right: 0; left: 10px; z-index: -1; height: 1px; background: var(--workbench-border); content: ''; }
|
||||
.fee-timeline li:last-child::after { display: none; }
|
||||
.fee-timeline li.pending::before { background: #98a2b3; }
|
||||
.fee-timeline span { color: var(--cc-muted); font-size: 11px; }
|
||||
.fee-timeline span { color: var(--workbench-muted); font-size: 11px; }
|
||||
.fee-timeline strong { font-size: 12px; overflow-wrap: anywhere; }
|
||||
.fee-advanced { border-top: 1px solid var(--cc-border); }
|
||||
.fee-advanced > summary { padding: 10px 2px; color: var(--cc-primary); font-size: 12px; font-weight: 600; cursor: pointer; }
|
||||
.fee-advanced { border-top: 1px solid var(--workbench-border); }
|
||||
.fee-advanced > summary { padding: 10px 2px; color: var(--workbench-primary); font-size: 12px; font-weight: 600; cursor: pointer; }
|
||||
.fee-advanced:not([open]) > summary { border-bottom: 0; }
|
||||
.fee-advanced .fee-detail-grid > section:only-child { grid-column: 1 / -1; }
|
||||
.adjustment-alert { margin-top: 12px; }
|
||||
@@ -673,12 +675,12 @@ defineExpose({ reload: loadFee })
|
||||
.adjustment-amounts :deep(.el-form-item) { min-width: 0; margin-bottom: 18px; }
|
||||
.adjustment-amounts :deep(.el-form-item__content) { display: grid; grid-template-columns: minmax(0, 1fr) auto; flex-wrap: nowrap; column-gap: 8px; }
|
||||
.adjustment-amounts :deep(.el-input-number) { width: 100%; }
|
||||
.adjustment-unit { min-width: max-content; color: var(--cc-muted); font-size: 12px; white-space: nowrap; }
|
||||
.adjustment-unit { min-width: max-content; color: var(--workbench-muted); font-size: 12px; white-space: nowrap; }
|
||||
.adjustment-total { display: grid; grid-template-columns: auto minmax(150px, 1fr) auto; align-items: baseline; gap: 18px; margin: 0 0 18px; padding: 13px 16px; border-radius: 8px; background: #f8fafc; }
|
||||
.adjustment-total span { color: var(--cc-muted); font-size: 12px; }
|
||||
.adjustment-total span { color: var(--workbench-muted); font-size: 12px; }
|
||||
.adjustment-total strong { justify-self: center; font-size: 18px; white-space: nowrap; }
|
||||
.adjustment-total small { color: var(--cc-muted); font-size: 11px; text-align: right; }
|
||||
.trial-source-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; margin-top: 16px; }.trial-source-grid section { padding: 14px; border: 1px solid var(--cc-border); border-radius: 8px; }.trial-source-grid h4 { margin: 0 0 12px; }.trial-source-grid :deep(.el-radio-group) { display: grid; gap: 10px; }.trial-source-grid :deep(.el-radio) { display: grid; grid-template-columns: minmax(0, 1fr) auto; width: 100%; height: auto; margin: 0; padding: 10px; border: 1px solid var(--cc-border); border-radius: 6px; }.trial-source-grid :deep(.el-radio__label) { display: flex; min-width: 0; justify-content: space-between; gap: 10px; }.trial-source-grid strong { color: var(--cc-text); }
|
||||
.adjustment-total small { color: var(--workbench-muted); font-size: 11px; text-align: right; }
|
||||
.trial-source-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; margin-top: 16px; }.trial-source-grid section { padding: 14px; border: 1px solid var(--workbench-border); border-radius: 8px; }.trial-source-grid h4 { margin: 0 0 12px; }.trial-source-grid :deep(.el-radio-group) { display: grid; gap: 10px; }.trial-source-grid :deep(.el-radio) { display: grid; grid-template-columns: minmax(0, 1fr) auto; width: 100%; height: auto; margin: 0; padding: 10px; border: 1px solid var(--workbench-border); border-radius: 6px; }.trial-source-grid :deep(.el-radio__label) { display: flex; min-width: 0; justify-content: space-between; gap: 10px; }.trial-source-grid strong { color: var(--workbench-text); }
|
||||
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
|
||||
|
||||
@media (max-width: 900px) {
|
||||
@@ -687,7 +689,7 @@ defineExpose({ reload: loadFee })
|
||||
.fee-summary-item:first-of-type { border-left: 0; }
|
||||
.calculation-flow { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
||||
.calculation-flow > div:nth-child(2) { border-right: 0; }
|
||||
.calculation-flow > div:nth-child(-n+2) { border-bottom: 1px solid var(--cc-border); }
|
||||
.calculation-flow > div:nth-child(-n+2) { border-bottom: 1px solid var(--workbench-border); }
|
||||
}
|
||||
|
||||
@media (max-width: 720px) {
|
||||
@@ -695,11 +697,11 @@ defineExpose({ reload: loadFee })
|
||||
.fee-heading-actions { justify-content: flex-start; }
|
||||
.fee-heading-actions .el-button:not(.is-circle) { flex: 1; min-height: 44px; }
|
||||
.fee-summary, .calculation-flow, .fee-detail-grid, .fee-timeline ol { grid-template-columns: 1fr; }
|
||||
.fee-summary-item { border-top: 1px solid var(--cc-border); border-left: 0; }
|
||||
.calculation-flow > div { min-height: 76px; border-right: 0; border-bottom: 1px solid var(--cc-border); }
|
||||
.fee-summary-item { border-top: 1px solid var(--workbench-border); border-left: 0; }
|
||||
.calculation-flow > div { min-height: 76px; border-right: 0; border-bottom: 1px solid var(--workbench-border); }
|
||||
.calculation-flow > div:last-child { border-bottom: 0; }
|
||||
.fee-detail-grid > section, .fee-detail-grid > section + section { padding: 20px 0; border-left: 0; }
|
||||
.fee-detail-grid > section + section { border-top: 1px solid var(--cc-border); }
|
||||
.fee-detail-grid > section + section { border-top: 1px solid var(--workbench-border); }
|
||||
.fee-timeline ol { gap: 16px; }
|
||||
.fee-timeline li { padding-left: 20px; }
|
||||
.fee-timeline li::after { display: none; }
|
||||
|
||||
@@ -13,7 +13,7 @@ describe('InboundMeasurementDialog', () => {
|
||||
it('owns the complete measurement workspace behind one centered dialog', () => {
|
||||
expect(source).toContain("import AppDialog from '@/shared/components/AppDialog.vue'")
|
||||
expect(source).toContain('<AppDialog')
|
||||
expect(source).toContain('class="inbound-measurement-workspace-dialog admin-density-dialog admin-density-workspace inbound-density"')
|
||||
expect(source).toContain('class="inbound-measurement-workspace-dialog admin-density-dialog admin-density-workspace inbound-density admin-workbench is-dialog"')
|
||||
expect(source).toContain('width="min(1560px, calc(100vw - 48px))"')
|
||||
expect(source).toContain('height: 92vh')
|
||||
expect(densitySource).toContain('.admin-density-dialog.el-dialog .el-dialog__header')
|
||||
@@ -24,7 +24,7 @@ describe('InboundMeasurementDialog', () => {
|
||||
expect(source).toContain(':customer-name="customerName"')
|
||||
expect(source).toContain('class="measurement-dialog-weight"')
|
||||
expect(source).not.toContain('class="surface-panel measurement-dialog-weight"')
|
||||
expect(source).toContain('border-bottom: 1px solid var(--cc-border)')
|
||||
expect(source).toContain('border-bottom: 1px solid var(--workbench-border)')
|
||||
expect(source).toContain('@summary-changed="handleWeightSummaryChanged"')
|
||||
expect(source).toContain('measurementPanelRef.value?.updateWeightEvidence(actualGrossWeightKg, actualNetWeightKg, hasConfirmedWeight)')
|
||||
expect(source).toContain('measurementPanelRef?.submissionBlockReason')
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import '@/styles/adminDensity.css'
|
||||
import '@/styles/adminWorkbench.css'
|
||||
import './measurementDensity.css'
|
||||
import { computed, ref } from 'vue'
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
@@ -69,7 +70,7 @@ function handleSubmitted() {
|
||||
<template>
|
||||
<AppDialog
|
||||
:model-value="modelValue"
|
||||
class="inbound-measurement-workspace-dialog admin-density-dialog admin-density-workspace inbound-density"
|
||||
class="inbound-measurement-workspace-dialog admin-density-dialog admin-density-workspace inbound-density admin-workbench is-dialog"
|
||||
:title="title"
|
||||
width="min(1560px, calc(100vw - 48px))"
|
||||
top="4vh"
|
||||
@@ -130,7 +131,7 @@ function handleSubmitted() {
|
||||
|
||||
<style scoped>
|
||||
.measurement-dialog-workspace { display: grid; min-width: 0; }
|
||||
.measurement-dialog-weight { min-width: 0; padding: 0 0 var(--admin-space-6, 16px); border-bottom: 1px solid var(--cc-border); }
|
||||
.measurement-dialog-weight { min-width: 0; padding: 0 0 var(--admin-space-6, 16px); border-bottom: 1px solid var(--workbench-border); }
|
||||
.measurement-dialog-footer { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--admin-space-4, 10px); }
|
||||
.measurement-dialog-footer__hint { margin-right: auto; color: var(--el-color-warning-dark-2); font-size: var(--admin-font-caption, 12px); }
|
||||
.measurement-dialog-footer :deep(.el-button) { margin-left: 0; }
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import '@/styles/adminDensity.css'
|
||||
import '@/styles/adminWorkbench.css'
|
||||
import { computed, onBeforeUnmount, reactive, ref, watch } from 'vue'
|
||||
import { ElMessage, ElMessageBox, type UploadFile } from 'element-plus'
|
||||
import { AlertTriangle, Image, Plus, Save, Send, Upload } from '@lucide/vue'
|
||||
@@ -643,7 +644,7 @@ defineExpose({ saveDraft, submitForReview, updateWeightEvidence, submissionBlock
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="surface-panel measurement-panel" aria-label="入库测量草稿">
|
||||
<section class="surface-panel measurement-panel admin-workbench" aria-label="入库测量草稿">
|
||||
<el-empty v-if="!hasContext" description="请选择所属企业和入库单后维护测量数据" />
|
||||
|
||||
<LoadErrorState
|
||||
@@ -722,7 +723,7 @@ defineExpose({ saveDraft, submitForReview, updateWeightEvidence, submissionBlock
|
||||
<p v-for="warning in measurementDeviationWarnings" :key="warning.key">{{ warning.text }}</p>
|
||||
</el-alert>
|
||||
|
||||
<table class="measurement-comparison" aria-label="客户申报与平台实测对比">
|
||||
<div class="workbench-evidence"><table class="measurement-comparison" aria-label="客户申报与平台实测对比">
|
||||
<thead><tr><th scope="col">指标</th><th scope="col">客户申报</th><th scope="col">平台实测</th><th scope="col">差异(实测 − 申报)</th></tr></thead>
|
||||
<tbody>
|
||||
<tr v-for="metric in comparisonMetrics" :key="metric.label">
|
||||
@@ -734,7 +735,7 @@ defineExpose({ saveDraft, submitForReview, updateWeightEvidence, submissionBlock
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</table></div>
|
||||
<div class="measurement-extra-facts">
|
||||
<span>货物净重 <strong>{{ formatNumber(detail.actualNetWeightKg) }}</strong> kg</span>
|
||||
<span>材积重 <strong>{{ formatNumber(detail.volumeWeightKg) }}</strong> kg</span>
|
||||
@@ -874,7 +875,7 @@ defineExpose({ saveDraft, submitForReview, updateWeightEvidence, submissionBlock
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<AppDialog class="admin-density-dialog" v-model="imagePreviewOpen" :title="detail?.inboundCode ? `当前有效测量图片 · ${detail.inboundCode}` : '当前有效测量图片'" width="min(720px, 92vw)" fullscreenable :show-footer="false" :close-on-click-modal="true" destroy-on-close append-to-body @closed="releaseImagePreview">
|
||||
<AppDialog class="admin-density-dialog admin-workbench is-dialog" v-model="imagePreviewOpen" :title="detail?.inboundCode ? `当前有效测量图片 · ${detail.inboundCode}` : '当前有效测量图片'" width="min(720px, 92vw)" fullscreenable :show-footer="false" :close-on-click-modal="true" destroy-on-close append-to-body @closed="releaseImagePreview">
|
||||
<div class="measurement-image-preview">
|
||||
<el-skeleton v-if="imagePreviewLoading" :rows="5" animated />
|
||||
<LoadErrorState v-else-if="imagePreviewError" title="图片加载失败" :message="imagePreviewError.message" :show-retry="false">
|
||||
@@ -885,12 +886,12 @@ defineExpose({ saveDraft, submitForReview, updateWeightEvidence, submissionBlock
|
||||
</div>
|
||||
</AppDialog>
|
||||
|
||||
<el-dialog class="admin-density-dialog" v-model="manualEntryOpen" :title="detail?.inboundCode ? `手动录入箱规 · ${detail.inboundCode}` : '手动录入箱规'" width="min(1000px, 92vw)" destroy-on-close append-to-body>
|
||||
<el-dialog class="admin-density-dialog admin-workbench is-dialog" v-model="manualEntryOpen" :title="detail?.inboundCode ? `手动录入箱规 · ${detail.inboundCode}` : '手动录入箱规'" width="min(1000px, 92vw)" destroy-on-close append-to-body>
|
||||
<el-alert v-if="manualEntryErrors.length" type="error" :closable="false" show-icon class="manual-entry-alert" title="请修正以下问题">
|
||||
<ul><li v-for="error in manualEntryErrors" :key="error">{{ error }}</li></ul>
|
||||
</el-alert>
|
||||
<el-form class="manual-entry-form" @submit.prevent="submitManualEntry">
|
||||
<table class="density-table density-table--editable manual-entry-table" aria-label="手动录入箱规">
|
||||
<div class="workbench-evidence"><table class="density-table density-table--editable manual-entry-table" aria-label="手动录入箱规">
|
||||
<colgroup><col class="manual-entry-label-column" /><col /><col class="manual-entry-label-column" /><col /></colgroup>
|
||||
<tbody>
|
||||
<tr>
|
||||
@@ -916,7 +917,7 @@ defineExpose({ saveDraft, submitForReview, updateWeightEvidence, submissionBlock
|
||||
</el-upload>
|
||||
</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</table></div>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button :disabled="manualEntrySubmitting" @click="manualEntryOpen = false">取消</el-button>
|
||||
@@ -929,20 +930,20 @@ defineExpose({ saveDraft, submitForReview, updateWeightEvidence, submissionBlock
|
||||
|
||||
<style scoped>
|
||||
.measurement-comparison { width: 100%; border-collapse: collapse; table-layout: fixed; background: var(--admin-surface, #fff); font-size: var(--admin-font-body, 13px); }
|
||||
.measurement-comparison th, .measurement-comparison td { padding: var(--admin-space-3, 8px) var(--admin-space-5, 12px); border: 1px solid var(--cc-border); text-align: left; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
|
||||
.measurement-comparison th, .measurement-comparison td { padding: var(--admin-space-3, 8px) var(--admin-space-5, 12px); border: 1px solid var(--workbench-border); text-align: left; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
|
||||
.measurement-comparison thead th { background: #f8fafc; }
|
||||
.measurement-comparison thead th:nth-child(2) { background: #f7f9ff; color: #465fc4; }
|
||||
.measurement-comparison thead th:nth-child(3) { background: #f4fbf8; color: #18795d; }
|
||||
.measurement-comparison__difference { color: var(--el-color-danger-dark-2); font-weight: 600; }
|
||||
.measurement-extra-facts { display: flex; flex-wrap: wrap; gap: var(--admin-space-3, 8px) var(--admin-space-6, 16px); color: var(--cc-muted); font-size: var(--admin-font-caption, 12px); }
|
||||
.measurement-extra-facts strong { color: var(--cc-text); }
|
||||
.measurement-extra-facts { display: flex; flex-wrap: wrap; gap: var(--admin-space-3, 8px) var(--admin-space-6, 16px); color: var(--workbench-muted); font-size: var(--admin-font-caption, 12px); }
|
||||
.measurement-extra-facts strong { color: var(--workbench-text); }
|
||||
.measurement-panel { overflow: hidden; }
|
||||
.measurement-panel__heading > div:first-child { display: flex; min-width: 0; align-items: flex-start; gap: 11px; }
|
||||
.measurement-panel__icon { display: grid; width: 34px; height: 34px; flex: 0 0 34px; place-items: center; border-radius: 8px; background: #eef4ff; color: var(--cc-primary); }
|
||||
.measurement-panel h2, .measurement-panel h3 { margin: 0; color: var(--cc-text); }
|
||||
.measurement-panel__icon { display: grid; width: 34px; height: 34px; flex: 0 0 34px; place-items: center; border-radius: 8px; background: #eef4ff; color: var(--workbench-primary); }
|
||||
.measurement-panel h2, .measurement-panel h3 { margin: 0; color: var(--workbench-text); }
|
||||
.measurement-panel h2 { font-size: var(--admin-font-title, 16px); }
|
||||
.measurement-panel h3 { font-size: var(--admin-font-section, 14px); }
|
||||
.measurement-panel__heading p, .measurement-section__heading p { margin: var(--admin-space-1, 4px) 0 0; color: var(--cc-muted); font-size: var(--admin-font-caption, 12px); line-height: 1.55; }
|
||||
.measurement-panel__heading p, .measurement-section__heading p { margin: var(--admin-space-1, 4px) 0 0; color: var(--workbench-muted); font-size: var(--admin-font-caption, 12px); line-height: 1.55; }
|
||||
.measurement-panel__actions, .measurement-panel__footer > div { display: flex; flex: 0 0 auto; flex-wrap: wrap; justify-content: flex-end; gap: var(--admin-space-3, 8px); }
|
||||
.measurement-platform-fields { margin-bottom: var(--admin-space-5, 12px); }
|
||||
.measurement-declaration-table { margin-top: var(--admin-space-5, 12px); }
|
||||
@@ -953,22 +954,22 @@ defineExpose({ saveDraft, submitForReview, updateWeightEvidence, submissionBlock
|
||||
.measurement-alert ul { margin: 7px 0 0; padding-left: 18px; font-size: var(--admin-font-caption, 12px); line-height: 1.65; }
|
||||
.measurement-alert .el-button { margin-top: 9px; }
|
||||
.measurement-form fieldset { min-width: 0; margin: 0; padding: 0; border: 0; }
|
||||
.measurement-section { padding: var(--admin-space-6, 16px) 0px; border-top: 1px solid var(--cc-border); }
|
||||
.measurement-section { padding: var(--admin-space-6, 16px) 0px; border-top: 1px solid var(--workbench-border); }
|
||||
.measurement-summary-section { display: grid; gap: var(--admin-space-5, 12px); border-top: 0; }
|
||||
.measurement-summary-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 20px; }
|
||||
.measurement-summary-context { display: flex; min-width: 0; flex-wrap: wrap; align-items: center; gap: var(--admin-space-3, 8px) 20px; }
|
||||
.measurement-summary-header span { color: var(--cc-muted); font-size: var(--admin-font-caption, 11px); }
|
||||
.measurement-summary-header span { color: var(--workbench-muted); font-size: var(--admin-font-caption, 11px); }
|
||||
.measurement-deviation-alert { --el-color-warning: var(--el-color-danger-dark-2); --el-color-warning-dark-2: var(--el-color-danger-dark-2); margin: 0; width: auto; }
|
||||
.measurement-deviation-alert p { margin: 3px 0 0; line-height: 1.55; }
|
||||
.measurement-summary-context p { display: inline-flex; min-width: 0; align-items: baseline; gap: var(--admin-space-2, 6px); margin: 0; overflow-wrap: anywhere; color: var(--cc-text); font-size: var(--admin-font-caption, 12px); font-weight: 600; }
|
||||
.measurement-summary-context p { display: inline-flex; min-width: 0; align-items: baseline; gap: var(--admin-space-2, 6px); margin: 0; overflow-wrap: anywhere; color: var(--workbench-text); font-size: var(--admin-font-caption, 12px); font-weight: 600; }
|
||||
.measurement-summary-status { display: flex; flex: 0 0 auto; align-items: center; gap: 9px; }
|
||||
.measurement-subheading { margin: 0; color: #344054; font-size: var(--admin-font-caption, 12px); font-weight: 700; }
|
||||
.measurement-declaration { padding-top: var(--admin-space-5, 12px); border-top: 1px solid var(--cc-border); }
|
||||
.measurement-declaration { padding-top: var(--admin-space-5, 12px); border-top: 1px solid var(--workbench-border); }
|
||||
.measurement-declaration h4 { margin: 0 0 var(--admin-space-4, 10px); color: #344054; font-size: var(--admin-font-caption, 12px); font-weight: 700; }
|
||||
.measurement-section__heading { display: flex; align-items: flex-start; justify-content: space-between; gap: 18px; margin-bottom: var(--admin-space-6, 16px); }
|
||||
.measurement-section__heading > div { min-width: 0; }
|
||||
.measurement-section-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--admin-space-3, 8px); }.measurement-section-actions :deep(.el-button) { margin-left: 0; }
|
||||
.warehouse-suggestion-form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 var(--admin-space-6, 16px); }.warehouse-suggestion-form :deep(.el-select),.warehouse-suggestion-form :deep(.el-input-number) { width: 100%; }.warehouse-suggestion-form :deep(.el-form-item:last-child) { grid-column: 1 / -1; }.suggestion-preview { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); margin: var(--admin-space-1, 4px) 0 0; border: 1px solid var(--cc-border); border-radius: 6px; }.suggestion-preview div { padding: var(--admin-space-5, 12px); border-right: 1px solid var(--cc-border); }.suggestion-preview div:last-child { border-right: 0; }.suggestion-preview dt { color: var(--cc-muted); font-size: var(--admin-font-caption, 11px); }.suggestion-preview dd { margin: 5px 0 0; color: var(--cc-text); font-size: var(--admin-font-body, 13px); font-weight: 650; }
|
||||
.warehouse-suggestion-form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 var(--admin-space-6, 16px); }.warehouse-suggestion-form :deep(.el-select),.warehouse-suggestion-form :deep(.el-input-number) { width: 100%; }.warehouse-suggestion-form :deep(.el-form-item:last-child) { grid-column: 1 / -1; }.suggestion-preview { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); margin: var(--admin-space-1, 4px) 0 0; border: 1px solid var(--workbench-border); border-radius: 6px; }.suggestion-preview div { padding: var(--admin-space-5, 12px); border-right: 1px solid var(--workbench-border); }.suggestion-preview div:last-child { border-right: 0; }.suggestion-preview dt { color: var(--workbench-muted); font-size: var(--admin-font-caption, 11px); }.suggestion-preview dd { margin: 5px 0 0; color: var(--workbench-text); font-size: var(--admin-font-body, 13px); font-weight: 650; }
|
||||
.measurement-data-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--admin-space-5, 12px); }
|
||||
.measurement-form label { display: flex; min-width: 0; flex-direction: column; gap: 7px; color: #344054; font-size: var(--admin-font-caption, 12px); font-weight: 650; }
|
||||
.measurement-form :deep(.el-input-number), .measurement-form :deep(.el-input) { width: 100%; }
|
||||
@@ -976,7 +977,7 @@ defineExpose({ saveDraft, submitForReview, updateWeightEvidence, submissionBlock
|
||||
.measurement-data-grid :deep(.el-input__wrapper) { border-radius: 3px; }
|
||||
.measurement-readonly-field { display: grid; min-width: 0; align-content: start; gap: 7px; }
|
||||
.measurement-readonly-field span { color: #344054; font-size: var(--admin-font-caption, 12px); font-weight: 600; }
|
||||
.measurement-readonly-field strong { min-height: var(--admin-control-height, 32px); padding: 7px 0; overflow-wrap: anywhere; color: var(--cc-text); font-size: var(--admin-font-body, 13px); line-height: 18px; }
|
||||
.measurement-readonly-field strong { min-height: var(--admin-control-height, 32px); padding: 7px 0; overflow-wrap: anywhere; color: var(--workbench-text); font-size: var(--admin-font-body, 13px); line-height: 18px; }
|
||||
.measurement-image-preview { display: grid; min-height: 240px; place-items: center; }
|
||||
.measurement-image-preview img { display: block; width: auto; max-width: 100%; max-height: 68vh; object-fit: contain; }
|
||||
.manual-entry-alert { margin-bottom: var(--admin-space-6, 16px); }
|
||||
@@ -990,14 +991,14 @@ defineExpose({ saveDraft, submitForReview, updateWeightEvidence, submissionBlock
|
||||
.measurement-table :deep(.el-table__cell) { padding: 7px 0; }
|
||||
.measurement-table :deep(.cell) { line-height: 1.35; }
|
||||
.measurement-table :deep(.measurement-table__row--error > td.el-table__cell) { background: var(--el-color-danger-light-9); }
|
||||
.warehouse-suggestion-table { display: grid; gap: var(--admin-space-4, 10px); margin-top: 18px; }.warehouse-suggestion-table h3 { margin: 0; color: var(--cc-text); font-size: var(--admin-font-section, 14px); }
|
||||
.warehouse-suggestion-table { display: grid; gap: var(--admin-space-4, 10px); margin-top: 18px; }.warehouse-suggestion-table h3 { margin: 0; color: var(--workbench-text); font-size: var(--admin-font-section, 14px); }
|
||||
.measurement-box-code { font-weight: 650; }
|
||||
.measurement-count-editor { width: 104px !important; }
|
||||
.measurement-row-details { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--admin-space-3, 8px) 20px; margin: 0; padding: var(--admin-space-1, 4px) 18px var(--admin-space-3, 8px) 62px; }
|
||||
.measurement-row-details dt { color: var(--cc-muted); font-size: var(--admin-font-caption, 11px); }
|
||||
.measurement-row-details dd { margin: 3px 0 0; overflow-wrap: anywhere; color: var(--cc-text); font-size: var(--admin-font-caption, 12px); font-weight: 600; }
|
||||
.measurement-panel__footer { position: sticky; bottom: 0; z-index: 2; display: flex; align-items: center; justify-content: space-between; gap: var(--admin-space-6, 16px); padding: var(--admin-space-5, 12px) 20px; border-top: 1px solid var(--cc-border); background: var(--admin-surface, #fff); }
|
||||
.measurement-panel__footer > span { display: inline-flex; align-items: center; gap: var(--admin-space-2, 6px); color: var(--cc-muted); font-size: var(--admin-font-caption, 12px); }
|
||||
.measurement-row-details dt { color: var(--workbench-muted); font-size: var(--admin-font-caption, 11px); }
|
||||
.measurement-row-details dd { margin: 3px 0 0; overflow-wrap: anywhere; color: var(--workbench-text); font-size: var(--admin-font-caption, 12px); font-weight: 600; }
|
||||
.measurement-panel__footer { position: sticky; bottom: 0; z-index: 2; display: flex; align-items: center; justify-content: space-between; gap: var(--admin-space-6, 16px); padding: var(--admin-space-5, 12px) 20px; border-top: 1px solid var(--workbench-border); background: var(--admin-surface, #fff); }
|
||||
.measurement-panel__footer > span { display: inline-flex; align-items: center; gap: var(--admin-space-2, 6px); color: var(--workbench-muted); font-size: var(--admin-font-caption, 12px); }
|
||||
.measurement-panel__footer > span:has(svg) { color: #b54708; font-weight: 650; }
|
||||
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; }
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import '@/styles/adminDensity.css'
|
||||
import '@/styles/adminWorkbench.css'
|
||||
import { onBeforeUnmount, ref, watch } from 'vue'
|
||||
import { ImageOff } from '@lucide/vue'
|
||||
import { downloadWeightThumbnail } from '../../weight/api/weightOcr'
|
||||
@@ -55,7 +57,7 @@ onBeforeUnmount(() => {
|
||||
|
||||
<template>
|
||||
<button
|
||||
class="measurement-evidence-thumb"
|
||||
class="measurement-evidence-thumb admin-workbench"
|
||||
type="button"
|
||||
:disabled="!fileId"
|
||||
:aria-label="fileId ? `查看${alt}` : emptyText"
|
||||
@@ -70,10 +72,10 @@ onBeforeUnmount(() => {
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.measurement-evidence-thumb { display: block; width: 100%; min-width: 96px; aspect-ratio: 4 / 3; overflow: hidden; padding: 0; border: 1px solid var(--cc-border); border-radius: 6px; background: #f2f4f7; cursor: zoom-in; }
|
||||
.measurement-evidence-thumb { display: block; width: 100%; min-width: 96px; aspect-ratio: 4 / 3; overflow: hidden; padding: 0; border: 1px solid var(--workbench-border); border-radius: 6px; background: var(--workbench-surface-soft); cursor: zoom-in; }
|
||||
.measurement-evidence-thumb:disabled { cursor: default; }
|
||||
.measurement-evidence-thumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
|
||||
.measurement-evidence-thumb__state { display: grid; width: 100%; height: 100%; place-items: center; align-content: center; gap: 7px; padding: 8px; color: #667085; font-size: 12px; }
|
||||
.measurement-evidence-thumb__state.is-loading { color: #98a2b3; }
|
||||
.measurement-evidence-thumb:focus-visible { outline: 2px solid var(--cc-primary); outline-offset: 2px; }
|
||||
.measurement-evidence-thumb__state { display: grid; width: 100%; height: 100%; place-items: center; align-content: center; gap: 7px; padding: 8px; color: var(--workbench-muted); font-size: 12px; }
|
||||
.measurement-evidence-thumb__state.is-loading { color: var(--workbench-muted); }
|
||||
.measurement-evidence-thumb:focus-visible { outline: 2px solid var(--workbench-primary); outline-offset: 2px; }
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import '@/styles/adminDensity.css'
|
||||
import '@/styles/adminWorkbench.css'
|
||||
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { Check, Pencil, RotateCcw } from '@lucide/vue'
|
||||
@@ -178,7 +179,7 @@ defineExpose({ confirmApprove, enableWeightCorrection, approvalButtonLabel, isPe
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="review-panel admin-density density-dialog-sections" aria-labelledby="measurement-review-title">
|
||||
<section class="review-panel admin-density density-dialog-sections admin-workbench" aria-labelledby="measurement-review-title">
|
||||
<h2 id="measurement-review-title" class="sr-only">测量审核内容</h2>
|
||||
<div class="review-toolbar" aria-label="测量审核操作">
|
||||
<div v-if="showActions" class="review-toolbar__actions">
|
||||
@@ -206,14 +207,14 @@ defineExpose({ confirmApprove, enableWeightCorrection, approvalButtonLabel, isPe
|
||||
|
||||
<section class="review-data density-dialog-section" data-tone="summary" aria-labelledby="review-data-title">
|
||||
<header class="review-section-heading density-dialog-section__title"><h3 id="review-data-title">审核数据总览</h3></header>
|
||||
<table class="review-comparison density-table" aria-label="客户申报与平台实测对比">
|
||||
<div class="workbench-evidence"><table class="review-comparison density-table" aria-label="客户申报与平台实测对比">
|
||||
<thead><tr><th scope="col">指标</th><th scope="col">客户申报</th><th scope="col">平台实测</th><th scope="col">差异(实测 − 申报)</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><th scope="row">箱数</th><td>{{ formatNumber(detail.originalPackageCount, 0) }}</td><td>{{ formatNumber(detail.actualPackageCount, 0) }}</td><td>{{ formatDifference(detail.actualPackageCount, detail.originalPackageCount, 0) }}</td></tr>
|
||||
<tr><th scope="row">毛重(kg)</th><td>{{ formatNumber(detail.originalGrossWeightKg) }}</td><td>{{ formatNumber(detail.actualGrossWeightKg) }}</td><td>{{ formatDifference(detail.actualGrossWeightKg, detail.originalGrossWeightKg, 3, ' kg') }}</td></tr>
|
||||
<tr><th scope="row">体积(m³)</th><td>{{ formatNumber(detail.originalVolumeCbm, 4) }}</td><td>{{ formatNumber(detail.actualVolumeCbm, 4) }}</td><td>{{ formatDifference(detail.actualVolumeCbm, detail.originalVolumeCbm, 4, ' m³') }}</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</table></div>
|
||||
<div class="review-extra-facts"><span>货物净重 <strong>{{ formatNumber(detail.actualNetWeightKg) }}</strong> kg</span><span>体积重 <strong>{{ formatNumber(detail.volumeWeightKg) }}</strong> kg</span></div>
|
||||
</section>
|
||||
|
||||
@@ -293,7 +294,7 @@ defineExpose({ confirmApprove, enableWeightCorrection, approvalButtonLabel, isPe
|
||||
/>
|
||||
</template>
|
||||
|
||||
<AppDialog class="admin-density-dialog" v-model="imagePreviewOpen" :title="imagePreviewTitle" width="min(760px, 92vw)" fullscreenable :show-footer="false" :close-on-click-modal="true" destroy-on-close append-to-body @closed="releaseImagePreview">
|
||||
<AppDialog class="admin-density-dialog admin-workbench is-dialog" v-model="imagePreviewOpen" :title="imagePreviewTitle" width="min(760px, 92vw)" fullscreenable :show-footer="false" :close-on-click-modal="true" destroy-on-close append-to-body @closed="releaseImagePreview">
|
||||
<div class="review-image-preview">
|
||||
<el-skeleton v-if="imagePreviewLoading" :rows="5" animated />
|
||||
<div v-else-if="imagePreviewError" class="review-image-preview__error">
|
||||
@@ -308,22 +309,22 @@ defineExpose({ confirmApprove, enableWeightCorrection, approvalButtonLabel, isPe
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.review-panel { display: grid; gap: var(--admin-space-5, 12px); color: var(--cc-text); }
|
||||
.review-toolbar { display: flex; align-items: center; justify-content: space-between; gap: var(--admin-space-5, 12px); position: sticky; top: 0; z-index: 3; flex-wrap: wrap; padding: var(--admin-space-3, 8px) 0; border-bottom: 1px solid var(--cc-border); background: var(--admin-surface, #fff); }
|
||||
.review-panel { display: grid; gap: var(--admin-space-5, 12px); color: var(--workbench-text); }
|
||||
.review-toolbar { display: flex; align-items: center; justify-content: space-between; gap: var(--admin-space-5, 12px); position: sticky; top: 0; z-index: 3; flex-wrap: wrap; padding: var(--admin-space-3, 8px) 0; border-bottom: 1px solid var(--workbench-border); background: var(--admin-surface, #fff); }
|
||||
.review-toolbar__status, .review-toolbar__actions { display: flex; min-width: 0; align-items: center; flex-wrap: wrap; gap: var(--admin-space-3, 8px); }
|
||||
.review-toolbar__status > span { color: var(--cc-muted); font-size: var(--admin-font-caption, 12px); }
|
||||
.review-toolbar__status > span { color: var(--workbench-muted); font-size: var(--admin-font-caption, 12px); }
|
||||
.review-toolbar__actions { justify-content: flex-end; }
|
||||
.review-toolbar__actions :deep(.el-button) { margin-left: 0; }
|
||||
.review-toolbar__status > .review-toolbar__context { padding-left: var(--admin-space-3, 8px); border-left: 1px solid var(--cc-border); font-size: var(--admin-font-body, 13px); line-height: 1.55; overflow-wrap: anywhere; }
|
||||
.review-toolbar__status > .review-toolbar__context { padding-left: var(--admin-space-3, 8px); border-left: 1px solid var(--workbench-border); font-size: var(--admin-font-body, 13px); line-height: 1.55; overflow-wrap: anywhere; }
|
||||
.review-alert-title { display: inline-flex; align-items: center; gap: var(--admin-space-3, 8px); flex-wrap: wrap; }
|
||||
.review-data, .review-items { min-width: 0; }
|
||||
.review-section-heading { display: flex; align-items: center; justify-content: space-between; gap: var(--admin-space-6, 16px); margin-bottom: var(--admin-space-3, 8px); }
|
||||
.review-section-heading > div { min-width: 0; }
|
||||
.review-section-heading h3 { margin: 0; color: var(--cc-text); font-size: var(--admin-font-section, 14px); line-height: 1.35; }
|
||||
.review-section-heading > span { color: var(--cc-muted); font-size: var(--admin-font-caption, 12px); white-space: nowrap; }
|
||||
.review-section-heading h3 { margin: 0; color: var(--workbench-text); font-size: var(--admin-font-section, 14px); line-height: 1.35; }
|
||||
.review-section-heading > span { color: var(--workbench-muted); font-size: var(--admin-font-caption, 12px); white-space: nowrap; }
|
||||
.review-comparison { table-layout: fixed; }
|
||||
.review-extra-facts { display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--admin-space-5, 12px); margin-top: var(--admin-space-3, 8px); color: var(--cc-muted); font-size: var(--admin-font-caption, 12px); }
|
||||
.review-extra-facts strong { color: var(--cc-text); }
|
||||
.review-extra-facts { display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--admin-space-5, 12px); margin-top: var(--admin-space-3, 8px); color: var(--workbench-muted); font-size: var(--admin-font-caption, 12px); }
|
||||
.review-extra-facts strong { color: var(--workbench-text); }
|
||||
.review-table-scroll { width: 100%; min-width: 0; overflow: hidden; }
|
||||
.review-table { width: 100%; }
|
||||
.review-table :deep(.review-time-cell .cell) { white-space: nowrap; }
|
||||
@@ -336,7 +337,7 @@ defineExpose({ confirmApprove, enableWeightCorrection, approvalButtonLabel, isPe
|
||||
.review-image-preview__error { display: grid; justify-items: center; gap: var(--admin-space-3, 8px); color: var(--el-color-danger); }
|
||||
@media (max-width: 720px) {
|
||||
.review-toolbar { align-items: stretch; flex-direction: column; }
|
||||
.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__status > .review-toolbar__context { width: 100%; padding-top: 8px; padding-left: 0; border-top: 1px solid var(--workbench-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; }
|
||||
.review-section-heading { align-items: stretch; flex-direction: column; }
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import '@/styles/adminDensity.css'
|
||||
import '@/styles/adminWorkbench.css'
|
||||
import { computed, onBeforeUnmount, ref, watch } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import {
|
||||
@@ -493,7 +494,7 @@ defineExpose({ reload: loadWorkspace })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="weight-workspace" aria-labelledby="weight-ocr-title">
|
||||
<section class="weight-workspace admin-workbench" aria-labelledby="weight-ocr-title">
|
||||
<header class="weight-heading">
|
||||
<div>
|
||||
<h3 id="weight-ocr-title"><Scale :size="18" aria-hidden="true" />称重图片</h3>
|
||||
@@ -580,7 +581,7 @@ defineExpose({ reload: loadWorkspace })
|
||||
</div>
|
||||
|
||||
<div v-else-if="tableMode" class="weight-table-wrap">
|
||||
<table class="weight-data-table">
|
||||
<div class="workbench-evidence"><table class="weight-data-table">
|
||||
<thead><tr><th>#</th><th>称重图片</th><th>托盘编码</th><th>托盘类型</th><th>库位</th><th>实测毛重(KG)</th><th>服务端确认毛重(KG)</th><th>托盘皮重(KG)</th><th>货物重量(KG)</th><th>操作</th></tr></thead>
|
||||
<tbody>
|
||||
<tr v-for="(row, index) in rows" :key="row.id">
|
||||
@@ -596,7 +597,7 @@ defineExpose({ reload: loadWorkspace })
|
||||
<td><el-tooltip v-if="canEdit && editable && !reviewMode" content="删除图片" placement="top"><el-button text type="danger" :aria-label="`删除称重图片 ${index + 1}`" :loading="isActionLoading('delete', row.id)" :disabled="Boolean(activeAction)" @click="removeResult(row)"><Trash2 :size="16" /></el-button></el-tooltip><span v-else>—</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</table></div>
|
||||
</div>
|
||||
<div v-else class="weight-grid">
|
||||
<article v-for="(row, index) in rows" :key="row.id" class="weight-card">
|
||||
@@ -647,7 +648,7 @@ defineExpose({ reload: loadWorkspace })
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<AppDialog class="admin-density-dialog"
|
||||
<AppDialog class="admin-density-dialog admin-workbench is-dialog"
|
||||
v-model="previewOpen"
|
||||
:title="workspace?.inboundCode ? `确认称重图片 · ${workspace.inboundCode}` : '确认称重图片'"
|
||||
:loading="previewLoading"
|
||||
@@ -673,7 +674,7 @@ defineExpose({ reload: loadWorkspace })
|
||||
<img v-if="previewUrl" class="weight-preview" :src="previewUrl" alt="当前入库单的称重图片" />
|
||||
<section class="density-dialog-section" data-tone="work">
|
||||
<h3 class="density-dialog-section__title">称重数据</h3>
|
||||
<table class="density-table density-table--editable weight-confirm-table" aria-label="称重关键数据">
|
||||
<div class="workbench-evidence"><table class="density-table density-table--editable weight-confirm-table" aria-label="称重关键数据">
|
||||
<colgroup><col class="weight-confirm-label-column" /><col /></colgroup>
|
||||
<tbody>
|
||||
<tr><th scope="row"><span>托盘类型</span></th><td>{{ previewResult.palletType || '未记录类型' }}</td></tr>
|
||||
@@ -704,7 +705,7 @@ defineExpose({ reload: loadWorkspace })
|
||||
</td></tr>
|
||||
</template>
|
||||
</tbody>
|
||||
</table>
|
||||
</table></div>
|
||||
</section>
|
||||
</div>
|
||||
</AppDialog>
|
||||
@@ -713,40 +714,40 @@ defineExpose({ reload: loadWorkspace })
|
||||
|
||||
<style scoped>
|
||||
.weight-workspace { min-width: 0; color: var(--el-text-color-primary); }
|
||||
.weight-heading { display: flex; align-items: center; justify-content: space-between; gap: 20px; padding-bottom: var(--admin-space-4, 10px); border-bottom: 1px solid var(--cc-border); }
|
||||
.weight-heading { display: flex; align-items: center; justify-content: space-between; gap: 20px; padding-bottom: var(--admin-space-4, 10px); border-bottom: 1px solid var(--workbench-border); }
|
||||
.weight-heading h3 { display: flex; align-items: center; gap: var(--admin-space-3, 8px); margin: 0; font-size: 15px; }
|
||||
.weight-heading h3 svg { color: var(--cc-primary); }
|
||||
.weight-heading h3 svg { color: var(--workbench-primary); }
|
||||
.weight-heading__actions { display: flex; flex: 0 0 auto; align-items: center; flex-wrap: wrap; justify-content: flex-end; gap: var(--admin-space-6, 16px); }
|
||||
.pallet-picker { width: clamp(360px, 36vw, 520px); min-width: 0; }
|
||||
.pallet-picker :deep(.el-select) { width: 100%; }
|
||||
.weight-summary { display: flex; align-items: baseline; gap: var(--admin-space-2, 6px); white-space: nowrap; }
|
||||
.weight-summary-group { display: flex; align-items: center; flex-wrap: wrap; gap: 20px; }
|
||||
.weight-summary span { color: var(--cc-muted); font-size: var(--admin-font-caption, 12px); }
|
||||
.weight-summary span { color: var(--workbench-muted); font-size: var(--admin-font-caption, 12px); }
|
||||
.weight-summary strong { color: #067647; font-size: var(--admin-font-title, 16px); }
|
||||
.visually-hidden-input { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
|
||||
.weight-action-error { margin-bottom: 14px; }
|
||||
.weight-list { min-height: 0; margin-top: 14px; }
|
||||
.weight-empty { display: flex; min-height: 0; align-items: center; gap: var(--admin-space-4, 10px); padding: var(--admin-space-1, 4px) 0 0; color: var(--cc-muted); }
|
||||
.weight-empty { display: flex; min-height: 0; align-items: center; gap: var(--admin-space-4, 10px); padding: var(--admin-space-1, 4px) 0 0; color: var(--workbench-muted); }
|
||||
.weight-empty strong { color: #344054; font-size: var(--admin-font-section, 14px); }
|
||||
.weight-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 14px; }
|
||||
.weight-card { position: relative; min-width: 0; overflow: hidden; border: 1px solid var(--cc-border); border-radius: 6px; background: var(--admin-surface, #fff); }
|
||||
.weight-card { position: relative; min-width: 0; overflow: hidden; border: 1px solid var(--workbench-border); border-radius: 6px; background: var(--admin-surface, #fff); }
|
||||
.weight-card__body { padding: var(--admin-space-5, 12px); text-align: center; }
|
||||
.weight-delete { position: absolute; z-index: 2; top: 8px; right: 8px; width: 30px; height: 30px; padding: 0; border: 1px solid rgb(255 255 255 / 82%); background: rgb(255 255 255 / 92%); box-shadow: 0 1px 3px rgb(16 24 40 / 16%); }
|
||||
.weight-card__value { width: 100%; padding: 0; border: 0; background: transparent; color: inherit; cursor: pointer; text-align: center; }
|
||||
.weight-card__value strong { color: #101828; font-size: 17px; }
|
||||
.weight-card__value:focus-visible { outline: 2px solid var(--cc-primary); outline-offset: 4px; }
|
||||
.weight-card__facts { display: grid; gap: var(--admin-space-2, 6px); margin: var(--admin-space-4, 10px) 0 0; padding-top: var(--admin-space-4, 10px); border-top: 1px solid var(--cc-border); }
|
||||
.weight-card__value:focus-visible { outline: 2px solid var(--workbench-primary); outline-offset: 4px; }
|
||||
.weight-card__facts { display: grid; gap: var(--admin-space-2, 6px); margin: var(--admin-space-4, 10px) 0 0; padding-top: var(--admin-space-4, 10px); border-top: 1px solid var(--workbench-border); }
|
||||
.weight-card__facts div { display: flex; justify-content: space-between; gap: var(--admin-space-3, 8px); font-size: var(--admin-font-caption, 11px); line-height: 1.4; }
|
||||
.weight-card__facts dt { color: var(--cc-muted); }
|
||||
.weight-card__facts dt { color: var(--workbench-muted); }
|
||||
.weight-card__facts dd { min-width: 0; margin: 0; color: #344054; overflow-wrap: anywhere; text-align: right; }
|
||||
.weight-card__correct { width: 100%; margin: var(--admin-space-5, 12px) 0 0; }
|
||||
.weight-table-wrap { overflow-x: auto; border: 1px solid #d7e0ef; border-radius: 8px; background: #fff; }
|
||||
.weight-table-wrap { overflow-x: auto; border: 1px solid var(--workbench-border); border-radius: 8px; background: #fff; }
|
||||
.weight-data-table { width: 100%; min-width: 1180px; border-collapse: separate; border-spacing: 0; table-layout: fixed; font-size: var(--admin-font-caption, 12px); }
|
||||
.weight-data-table th { height: 42px; padding: 0 8px; border-bottom: 1px solid #d5dfee; background: linear-gradient(180deg, #f1f4fc, #e9eef8); color: #405473; font-weight: 700; white-space: nowrap; }
|
||||
.weight-data-table td { height: 76px; padding: 6px 8px; border-top: 1px solid #ebeff5; color: #4b5870; text-align: center; vertical-align: middle; white-space: nowrap; }
|
||||
.weight-data-table th + th, .weight-data-table td + td { border-left: 1px solid #edf0f5; }
|
||||
.weight-data-table tbody tr:nth-child(even) td { background: #f8faff; }
|
||||
.weight-data-table tbody tr:hover td { background: #edf3ff; }
|
||||
.weight-data-table th { height: 42px; padding: 0 8px; border-bottom: 1px solid var(--workbench-border); background: var(--workbench-surface-soft); color: var(--workbench-muted); font-weight: 700; white-space: nowrap; }
|
||||
.weight-data-table td { height: 76px; padding: 6px 8px; border-top: 1px solid var(--workbench-border); color: var(--workbench-text); text-align: center; vertical-align: middle; white-space: nowrap; }
|
||||
.weight-data-table th + th, .weight-data-table td + td { border-left: 1px solid var(--workbench-border); }
|
||||
.weight-data-table tbody tr:nth-child(even) td { background: var(--workbench-surface-soft); }
|
||||
.weight-data-table tbody tr:hover td { background: var(--workbench-accent-soft); }
|
||||
.weight-data-table :deep(.weight-thumb) { width: 90px; height: 60px; margin: auto; border-radius: 8px; }
|
||||
.weight-data-table .weight-gross-value { color: #33425f; font-weight: 750; }
|
||||
.weight-data-table .weight-net-value { color: #16875b; font-weight: 750; }
|
||||
|
||||
Reference in New Issue
Block a user