feat(fleet): integrate trip management and fee coverage workflows
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import '@/styles/adminDensity.css'
|
||||
import { computed, onMounted, reactive, ref, watch } from 'vue'
|
||||
import { Download, Pencil, PackagePlus } from '@lucide/vue'
|
||||
import { ChevronDown, ChevronUp, Download, Pencil, PackagePlus, SlidersHorizontal } from '@lucide/vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { listAllPlatformWarehouses, type PlatformWarehouseSummaryResource } from '@/modules/warehouses'
|
||||
@@ -143,6 +143,8 @@ const receivingWarehouseForm = reactive({ warehouseId: '', remark: '' })
|
||||
let receivingWarehouseIdempotencyKey = ''
|
||||
let containerOptionRequest = 0
|
||||
const statusTab = ref<'全部' | '待分配' | '柜子'>('全部')
|
||||
const statusTabs = ['全部', '待分配'] as const
|
||||
const showAdvancedFilters = ref(false)
|
||||
const filters = ref<QueryModel>({ orderNo: '', relabelNo: '', orderType: '', warehouse: '', inboundCode: '', lxCode: '', sourceOrderNo: '', containerNo: '', status: '', transferWarehouseCode: '', abnormal: '', detained: '', createdAt: [] })
|
||||
const allFields: QueryField[] = [
|
||||
{ key: 'orderNo', type: 'input', label: '尾程单号', width: 190, placeholder: '请输入尾程单号' },
|
||||
@@ -176,7 +178,9 @@ const allFields: QueryField[] = [
|
||||
]
|
||||
const fields = computed<QueryField[]>(() => statusTab.value === '柜子'
|
||||
? allFields.filter((field) => ['containerNo', 'createdAt'].includes(field.key))
|
||||
: allFields)
|
||||
: showAdvancedFilters.value
|
||||
? allFields
|
||||
: allFields.filter((field) => ['orderNo', 'inboundCode', 'warehouse'].includes(field.key)))
|
||||
const selectedContainer = computed(() => containerOptions.value.find((row) => row.sourceContainerBookingId === selectedContainerBookingId.value))
|
||||
const selectedReceivingWarehouse = computed(() => receivingWarehouseOptions.value.find((row) => (
|
||||
row.warehouseId === receivingWarehouseForm.warehouseId
|
||||
@@ -381,12 +385,35 @@ async function load(model: QueryModel = filters.value) {
|
||||
}
|
||||
|
||||
function search(model: QueryModel) { page.value = 1; void load(model) }
|
||||
function reset(model: QueryModel) { page.value = 1; void load(model) }
|
||||
function reset() {
|
||||
for (const field of allFields) filters.value[field.key] = field.type === 'daterange' ? [] : ''
|
||||
page.value = 1
|
||||
void load()
|
||||
}
|
||||
function changeStatusTab() {
|
||||
selectedRows.value = []
|
||||
page.value = 1
|
||||
void load()
|
||||
}
|
||||
function selectStatusTab(value: typeof statusTabs[number]) {
|
||||
if (statusTab.value === value) return
|
||||
statusTab.value = value
|
||||
changeStatusTab()
|
||||
}
|
||||
function handleStatusTabKeydown(event: KeyboardEvent, index: number) {
|
||||
let nextIndex = index
|
||||
if (event.key === 'ArrowRight') nextIndex = (index + 1) % statusTabs.length
|
||||
else if (event.key === 'ArrowLeft') nextIndex = (index - 1 + statusTabs.length) % statusTabs.length
|
||||
else if (event.key === 'Home') nextIndex = 0
|
||||
else if (event.key === 'End') nextIndex = statusTabs.length - 1
|
||||
else return
|
||||
event.preventDefault()
|
||||
const tab = statusTabs[nextIndex]
|
||||
if (!tab) return
|
||||
selectStatusTab(tab)
|
||||
const buttons = (event.currentTarget as HTMLElement).parentElement?.querySelectorAll<HTMLElement>('[role="tab"]')
|
||||
buttons?.[nextIndex]?.focus()
|
||||
}
|
||||
|
||||
async function openContainerDetail(row: ContainerPlanProgressSummaryDto) {
|
||||
containerDetailOpen.value = true
|
||||
@@ -944,13 +971,22 @@ onMounted(() => { void load() })
|
||||
<template #toolbar-start><h1>尾程订单</h1></template>
|
||||
<template #filters>
|
||||
<section class="last-mile-toolbar integrated-query-group" aria-label="尾程订单状态与筛选">
|
||||
<el-radio-group v-model="statusTab" aria-label="尾程订单状态" @change="changeStatusTab">
|
||||
<el-radio-button value="全部">全部</el-radio-button>
|
||||
<el-radio-button value="待分配">待分配</el-radio-button>
|
||||
<div class="density-status-tabs" role="tablist" aria-label="尾程订单状态">
|
||||
<button v-for="(tab, index) in statusTabs" :key="tab" type="button" role="tab"
|
||||
:aria-selected="statusTab === tab" :tabindex="statusTab === tab ? 0 : -1"
|
||||
:class="{ 'is-active': statusTab === tab }"
|
||||
@click="selectStatusTab(tab)" @keydown="handleStatusTabKeydown($event, index)">{{ tab }}</button>
|
||||
<!-- 柜子工作台入口暂时隐藏,保留现有实现便于后续恢复。 -->
|
||||
<!-- <el-radio-button value="柜子">柜子工作台({{ containerTotal }})</el-radio-button> -->
|
||||
</el-radio-group>
|
||||
<QueryToolbar v-model="filters" :fields="fields" :available-fields="allFields" :loading="loading" ariaLabel="尾程订单筛选" preference-key="overseas-last-mile-orders-query" :search-on-reset="false" @search="search" @reset="reset" />
|
||||
</div>
|
||||
<QueryToolbar id="last-mile-orders-advanced-filters" v-model="filters" :fields="fields" :available-fields="allFields" :loading="loading" ariaLabel="尾程订单筛选" preference-key="overseas-last-mile-orders-query" :search-on-reset="false" @search="search" @reset="reset">
|
||||
<template v-if="statusTab !== '柜子'" #actions>
|
||||
<el-button :aria-expanded="showAdvancedFilters" aria-controls="last-mile-orders-advanced-filters" @click="showAdvancedFilters = !showAdvancedFilters">
|
||||
<SlidersHorizontal :size="16" />{{ showAdvancedFilters ? '收起筛选' : '高级筛选' }}
|
||||
<ChevronUp v-if="showAdvancedFilters" :size="15" /><ChevronDown v-else :size="15" />
|
||||
</el-button>
|
||||
</template>
|
||||
</QueryToolbar>
|
||||
</section>
|
||||
</template>
|
||||
<template #notices><template v-if="loadError">
|
||||
|
||||
Reference in New Issue
Block a user