This commit is contained in:
2026-10-21 13:22:42 +08:00
parent eb0b0f85d1
commit 2333bd8bab
114 changed files with 1766 additions and 526 deletions
@@ -32,7 +32,7 @@ const columns: DataTableColumn[] = [
{ key: 'updatedAt', label: '更新时间', minWidth: 180, slotName: 'time' },
]
</script>
<template><div class="workbench-table"><DataTable :appearance="integrated ? 'integrated' : 'default'" :stripe="false" :results-visible="!failed" preference-key="fleet-capacity-inquiries" column-settings-mode="show" v-model:page="page" v-model:page-size="size" :columns="columns" :data="rows" :total="total" :loading="loading" row-key="bookingNo" empty-text="当前范围暂无意向">
<template><div class="workbench-table"><DataTable :appearance="integrated ? 'integrated' : 'default'" :results-visible="!failed" preference-key="fleet-capacity-inquiries" column-settings-mode="show" v-model:page="page" v-model:page-size="size" :columns="columns" :data="rows" :total="total" :loading="loading" row-key="bookingNo" empty-text="当前范围暂无意向">
<template v-if="$slots['toolbar-start']" #toolbar-start><slot name="toolbar-start" /></template>
<template v-if="$slots.filters" #filters><slot name="filters" /></template>
<template v-if="$slots.notices" #notices><slot name="notices" /></template>
@@ -11,11 +11,11 @@ const emit = defineEmits<{ back: [] }>()
<template>
<AdminPage class="admin-density admin-workbench" spacing="compact">
<DetailPageLayout aria-label="外配业务详情" class="workbench-panel is-flush is-page-surface">
<DetailPageLayout aria-label="外配任务详情" class="workbench-panel is-flush is-page-surface">
<template #header>
<div class="outsourced-business-detail-heading">
<div><strong>外配业务</strong><span class="outsourced-business-reference">{{ dispatchNo || '—' }}</span><span v-if="statusText">{{ statusText }}</span></div>
<div class="density-actions"><slot name="actions" /><el-button class="density-action" @click="emit('back')">返回外配业务</el-button></div>
<div><strong>外配任务</strong><span class="outsourced-business-reference">{{ dispatchNo || '—' }}</span><span v-if="statusText">{{ statusText }}</span></div>
<div class="density-actions"><slot name="actions" /><el-button class="density-action" @click="emit('back')">返回外配任务</el-button></div>
</div>
</template>
<slot name="state" />
@@ -8,7 +8,7 @@ import ListPageLayout from '@/shared/components/ListPageLayout.vue'
<template>
<AdminPage class="admin-density admin-workbench" spacing="compact">
<slot name="statistics" />
<ListPageLayout aria-label="外配业务任务列表">
<ListPageLayout aria-label="外配任务任务列表">
<template v-if="$slots.filters" #toolbar><slot name="filters" /></template>
<template v-if="$slots.state" #state><slot name="state" /></template>
<slot />
@@ -20,7 +20,7 @@ const emit = defineEmits<{ saved: [value: OutsourcedBusinessDetail]; busy: [valu
const auth = useAuthStore(), access = useAccessPreviewStore(), busy = ref(false), pending = ref<OutsourcedBusinessPending | null>(null), error = ref<ApiErrorDetails | null>(null), corrupted = ref(false)
const form = reactive({ currency: '', amount: '', reason: '', arrivals: {} as Record<string,string> })
const active = computed(() => open.value || Boolean(pending.value))
const registration = useUnsavedWorkRegistration({ key: `outsourced-business-operations:${getCurrentInstance()?.uid}`, label: computed(() => '外配业务运营登记'), isOpen: active, model: reactive({ form, pending }), requiredPermission: computed(() => permission.outsourcedBusinessEdit) })
const registration = useUnsavedWorkRegistration({ key: `outsourced-business-operations:${getCurrentInstance()?.uid}`, label: computed(() => '外配任务运营登记'), isOpen: active, model: reactive({ form, pending }), requiredPermission: computed(() => permission.outsourcedBusinessEdit) })
let actor = '', number = '', baseline = ''
const writable = computed(() => !corrupted.value && access.can(permission.outsourcedBusinessEdit) && props.detail?.row.actions.edit.allowed === true)
const locked = computed(() => busy.value || Boolean(pending.value))
@@ -20,7 +20,7 @@ const emit = defineEmits<{ saved: [value: OutsourcedBusinessDetail]; busy: [valu
const auth = useAuthStore(), access = useAccessPreviewStore(), busy = ref(false), error = ref<ApiErrorDetails | null>(null), pending = ref<OutsourcedBusinessPending | null>(null), prepared = ref<OutsourcedBusinessPhoto | null>(null), corrupted = ref(false)
const urls = ref<Partial<Record<OutsourcedBusinessPhotoSlot,string>>>({}), reading = ref<OutsourcedBusinessPhotoSlot | null>(null)
const uploadable = computed(() => !corrupted.value && access.can(permission.outsourcedBusinessUpload) && props.detail?.row.actions.upload.allowed === true)
useUnsavedWorkRegistration({ key: `outsourced-business-photos:${getCurrentInstance()?.uid}`, label: computed(() => '外配业务照片作业'), isOpen: computed(() => open.value || Boolean(pending.value) || Boolean(prepared.value)), model: reactive({ pending, prepared }), requiredPermission: computed(() => permission.outsourcedBusinessUpload) })
useUnsavedWorkRegistration({ key: `outsourced-business-photos:${getCurrentInstance()?.uid}`, label: computed(() => '外配任务照片作业'), isOpen: computed(() => open.value || Boolean(pending.value) || Boolean(prepared.value)), model: reactive({ pending, prepared }), requiredPermission: computed(() => permission.outsourcedBusinessUpload) })
let actor = '', number = '', generation = 0
function savedPhoto(slot: OutsourcedBusinessPhotoSlot) { return props.detail?.photos.find(photo => photo.slot === slot && photo.savedAt) }
function release() { Object.values(urls.value).forEach(url => { if (url) URL.revokeObjectURL(url) }); urls.value = {} }