style(admin): unify dialog layouts and dense readonly presentation
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import '@/styles/adminDensity.css'
|
||||
import { computed, onBeforeUnmount, reactive, ref, watch } from 'vue'
|
||||
import { useAccessPreviewStore } from '@/core/access/accessPreview'
|
||||
import AppDialog from '@/shared/components/AppDialog.vue'
|
||||
@@ -13,6 +14,11 @@ const props = defineProps<{ container: {
|
||||
destinationPortCode: string | null; destinationPortName?: string | null
|
||||
estimatedSailingAt: string | null; estimatedPortArrivalAt: string | null
|
||||
} }>()
|
||||
const dialogTitle = computed(() => {
|
||||
const action = props.container.currentPortScheduleId ? '原柜船期与修改历史' : '登记原柜船期'
|
||||
const code = props.container.cabinetNo?.trim() || props.container.containerNo?.trim()
|
||||
return code ? `${action} · ${code}` : action
|
||||
})
|
||||
const emit = defineEmits<{ saved: [] }>()
|
||||
const access = useAccessPreviewStore()
|
||||
const canRead = computed(() => access.can('platform:firstleg:port-schedule:list'))
|
||||
@@ -101,37 +107,48 @@ onBeforeUnmount(() => { generation++ })
|
||||
<span v-if="prerequisite">{{ prerequisite }}</span>
|
||||
<span v-else-if="!canRead">当前账号无船期读取权限。</span>
|
||||
</div>
|
||||
<AppDialog v-model="open" class="admin-density-dialog" :title="container.currentPortScheduleId ? '原柜船期与修改历史' : '登记原柜船期'" :width="container.currentPortScheduleId ? '1000px' : '1120px'" :show-confirm="canWrite" :confirm-disabled="loading || !!prerequisite || (!!container.currentPortScheduleId && !schedule)" :confirm-loading="busy" :confirm-text="pending ? '重试原请求' : '保存船期'" @confirm="save">
|
||||
<div v-loading="loading" class="schedule-body">
|
||||
<p>{{ container.cabinetNo || '—' }} · {{ container.containerNo || '—' }} · 提单 {{ container.billOfLadingNo || '—' }} · {{ container.customerName || '—' }}</p>
|
||||
<AppDialog v-model="open" class="admin-density-dialog" :title="dialogTitle" fullscreenable :width="container.currentPortScheduleId ? '1000px' : '1120px'" :show-confirm="canWrite" :confirm-disabled="loading || !!prerequisite || (!!container.currentPortScheduleId && !schedule)" :confirm-loading="busy" :confirm-text="pending ? '重试原请求' : '保存船期'" @confirm="save">
|
||||
<div v-loading="loading" class="density-dialog-sections">
|
||||
<el-alert v-if="error" :title="error" type="error" :closable="false" />
|
||||
<p v-if="!container.currentPortScheduleId">请登记本柜的船名、航次和预计时间,并按实际信息填写来源及有效期。</p>
|
||||
<el-form label-position="top" class="density-form" :disabled="!canWrite || busy || !!pending || loading">
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="container.currentPortScheduleId ? 12 : 8"><el-form-item label="船名" required><el-input v-model="form.vesselName" maxlength="128" placeholder="请输入船名" /></el-form-item></el-col>
|
||||
<el-col :span="container.currentPortScheduleId ? 12 : 8"><el-form-item label="航次" required><el-input v-model="form.voyageNo" maxlength="64" placeholder="请输入航次" /></el-form-item></el-col>
|
||||
<el-col v-for="key in dates" :key="key" :span="container.currentPortScheduleId ? 12 : 8"><el-form-item :label="dateLabels[key]" required><el-date-picker v-model="form[key]" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" :placeholder="`请选择${dateLabels[key]}`" /></el-form-item></el-col>
|
||||
<template v-if="!container.currentPortScheduleId">
|
||||
<el-col :span="8"><el-form-item label="信息来源(人工登记)" required><el-input v-model="form.sourceName" maxlength="128" placeholder="请输入信息来源" /></el-form-item></el-col>
|
||||
<el-col :span="8"><el-form-item label="来源参考号或链接" required><el-input v-model="form.sourceRef" maxlength="255" placeholder="请输入来源参考号或链接" /></el-form-item></el-col>
|
||||
<el-col v-for="key in extraDates" :key="key" :span="8"><el-form-item :label="dateLabels[key]" :required="!['bookingCutoffAt', 'customsCutoffAt'].includes(key)"><el-date-picker v-model="form[key]" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" :placeholder="`请选择${dateLabels[key]}`" /></el-form-item></el-col>
|
||||
</template>
|
||||
<el-col :span="24"><el-form-item label="修改原因" required><el-input v-model="form.reason" type="textarea" maxlength="1000" placeholder="请说明本次修改原因" /></el-form-item></el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<h3>修改历史</h3>
|
||||
<el-table :data="schedule?.histories || []" empty-text="暂无修改历史">
|
||||
<el-table-column label="修改时间" min-width="170"><template #default="{ row }">{{ time(row.createdAt) }}</template></el-table-column>
|
||||
<el-table-column prop="operatorName" label="修改人" width="125" />
|
||||
<el-table-column prop="reason" label="原因" min-width="150" />
|
||||
<el-table-column label="修改前" min-width="240"><template #default="{ row }">{{ snapshot(row.beforeSnapshot) }}</template></el-table-column>
|
||||
<el-table-column label="修改后" min-width="240"><template #default="{ row }">{{ snapshot(row.afterSnapshot) }}</template></el-table-column>
|
||||
</el-table>
|
||||
<section class="density-dialog-section" data-tone="source">
|
||||
<table class="density-table schedule-context-table" aria-label="原柜船期归属"><tbody>
|
||||
<tr><th>柜次号</th><td>{{ container.cabinetNo || '—' }}</td><th>集装箱号</th><td>{{ container.containerNo || '—' }}</td></tr>
|
||||
<tr><th>提单号</th><td>{{ container.billOfLadingNo || '—' }}</td><th>客户</th><td>{{ container.customerName || '—' }}</td></tr>
|
||||
</tbody></table>
|
||||
</section>
|
||||
<section class="density-dialog-section" data-tone="work">
|
||||
<p v-if="!container.currentPortScheduleId" class="density-dialog-note">请登记本柜的船名、航次和预计时间,并按实际信息填写来源及有效期。</p>
|
||||
<el-form v-if="canWrite" class="density-form" :disabled="busy || !!pending || loading">
|
||||
<table class="density-table density-table--editable schedule-editor-table" aria-label="原柜船期填写"><tbody>
|
||||
<tr><td><el-form-item label="船名" label-position="left" label-width="120px" required><el-input v-model="form.vesselName" maxlength="128" placeholder="请输入船名" /></el-form-item></td><td><el-form-item label="航次" label-position="left" label-width="120px" required><el-input v-model="form.voyageNo" maxlength="64" placeholder="请输入航次" /></el-form-item></td></tr>
|
||||
<tr><td v-for="key in dates" :key="key"><el-form-item :label="dateLabels[key]" label-position="left" label-width="120px" required><el-date-picker v-model="form[key]" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" :placeholder="`请选择${dateLabels[key]}`" /></el-form-item></td></tr>
|
||||
<template v-if="!container.currentPortScheduleId">
|
||||
<tr><td><el-form-item label="信息来源" label-position="left" label-width="120px" required><el-input v-model="form.sourceName" maxlength="128" placeholder="请输入信息来源" /></el-form-item></td><td><el-form-item label="来源参考号或链接" label-position="left" label-width="120px" required><el-input v-model="form.sourceRef" maxlength="255" placeholder="请输入来源参考号或链接" /></el-form-item></td></tr>
|
||||
<tr v-for="(keys, index) in [extraDates.slice(0, 2), extraDates.slice(2, 4), extraDates.slice(4)]" :key="index"><td v-for="key in keys" :key="key" :colspan="keys.length === 1 ? 2 : 1"><el-form-item :label="dateLabels[key]" label-position="left" label-width="120px" :required="!['bookingCutoffAt', 'customsCutoffAt'].includes(key)"><el-date-picker v-model="form[key]" type="datetime" value-format="YYYY-MM-DDTHH:mm:ss" :placeholder="`请选择${dateLabels[key]}`" /></el-form-item></td></tr>
|
||||
</template>
|
||||
<tr><td colspan="2"><el-form-item label="修改原因" label-position="left" label-width="120px" required><el-input v-model="form.reason" type="textarea" maxlength="1000" placeholder="请说明本次修改原因" /></el-form-item></td></tr>
|
||||
</tbody></table>
|
||||
</el-form>
|
||||
<table v-else class="density-table schedule-context-table" aria-label="当前船期只读资料"><tbody>
|
||||
<tr><th>船名</th><td>{{ form.vesselName || '—' }}</td><th>航次</th><td>{{ form.voyageNo || '—' }}</td></tr>
|
||||
<tr><template v-for="key in dates" :key="key"><th>{{ dateLabels[key] }}</th><td>{{ time(form[key]) }}</td></template></tr>
|
||||
</tbody></table>
|
||||
</section>
|
||||
<section class="density-dialog-section" data-tone="source">
|
||||
<h3 class="density-dialog-section__title">修改历史</h3>
|
||||
<el-table :data="schedule?.histories || []" empty-text="暂无修改历史">
|
||||
<el-table-column label="修改时间" min-width="170"><template #default="{ row }">{{ time(row.createdAt) }}</template></el-table-column>
|
||||
<el-table-column prop="operatorName" label="修改人" width="125" show-overflow-tooltip />
|
||||
<el-table-column prop="reason" label="原因" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column label="修改前" min-width="240"><template #default="{ row }">{{ snapshot(row.beforeSnapshot) }}</template></el-table-column>
|
||||
<el-table-column label="修改后" min-width="240"><template #default="{ row }">{{ snapshot(row.afterSnapshot) }}</template></el-table-column>
|
||||
</el-table>
|
||||
</section>
|
||||
</div>
|
||||
</AppDialog>
|
||||
</template>
|
||||
<style scoped>
|
||||
.schedule-actions { display:flex; align-items:center; gap:12px; margin:8px 0; }
|
||||
.schedule-body { max-height:65vh; overflow:auto; padding-inline:8px; }
|
||||
.schedule-body :deep(.el-date-editor) { width:100%; }
|
||||
.schedule-actions { display:flex; align-items:center; gap:var(--admin-space-5); margin:var(--admin-space-3) 0; }
|
||||
.schedule-editor-table, .schedule-context-table { table-layout:fixed; }
|
||||
.schedule-context-table th { width:120px; }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user