|
|
|
@@ -2,7 +2,7 @@
|
|
|
|
|
import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue'
|
|
|
|
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
|
|
|
import type { FormInstance, FormRules } from 'element-plus'
|
|
|
|
|
import { ArrowLeft, Eye, FilePenLine, PackageCheck } from '@lucide/vue'
|
|
|
|
|
import { ArrowLeft, CircleX, Eye, FilePenLine, MoreHorizontal, PackageCheck } from '@lucide/vue'
|
|
|
|
|
import { useRoute, useRouter } from 'vue-router'
|
|
|
|
|
import {
|
|
|
|
|
acceptPlatformFirstLegOrder,
|
|
|
|
@@ -90,7 +90,7 @@ const queryFields = computed<QueryField[]>(() => [
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
const orderColumns: DataTableColumn[] = [
|
|
|
|
|
{ key: 'actions', label: '操作', minWidth: 200, fixed: 'left', slotName: 'actions' },
|
|
|
|
|
{ key: 'actions', label: '操作', minWidth: 224, fixed: 'left', slotName: 'actions' },
|
|
|
|
|
{ key: 'orderInfo', label: '订单信息', minWidth: 210, slotName: 'orderInfo' },
|
|
|
|
|
{ key: 'customer', label: '客户', minWidth: 190, showOverflowTooltip: true, slotName: 'customer' },
|
|
|
|
|
{ key: 'transport', label: '运输方案', minWidth: 180, slotName: 'transport' },
|
|
|
|
@@ -179,6 +179,20 @@ function canCancel(order: PlatformFirstLegOrderResource) {
|
|
|
|
|
return can('platform:order:cancel') && ['DRAFT', 'SUBMITTED', 'APPROVED', 'ACCEPTED', 'REJECTED'].includes(order.status)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function canMaintainExpress(order: PlatformFirstLegOrderResource) {
|
|
|
|
|
return can('platform:order:fulfillment') && !['DRAFT', 'REJECTED', 'CANCELLED'].includes(order.status)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function hasSecondaryActions(order: PlatformFirstLegOrderResource) {
|
|
|
|
|
return canCancel(order) || canMaintainExpress(order) || can('platform:order:note')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function runSecondaryAction(command: string | number | object, order: PlatformFirstLegOrderResource) {
|
|
|
|
|
if (command === 'express') openExpress(order)
|
|
|
|
|
if (command === 'note') openNote(order)
|
|
|
|
|
if (command === 'cancel') void cancelOrder(order)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function actionLabel(order: PlatformFirstLegOrderResource) {
|
|
|
|
|
if (order.status === 'SUBMITTED' && can('platform:order:approve')) return '审核通过'
|
|
|
|
|
if (order.status === 'APPROVED' && can('platform:order:accept')) return '受理订单'
|
|
|
|
@@ -505,7 +519,22 @@ onMounted(() => void loadTenants())
|
|
|
|
|
empty-text="当前没有符合条件的头程订单"
|
|
|
|
|
row-key="id"
|
|
|
|
|
>
|
|
|
|
|
<template #actions="{ row }"><div class="table-actions"><el-button link type="primary" @click="openDetail(row as PlatformFirstLegOrderResource)"><Eye :size="15" />详情</el-button><el-button v-if="actionLabel(row as PlatformFirstLegOrderResource)" link type="success" :loading="actionLoadingId === String((row as PlatformFirstLegOrderResource).id)" @click="runLifecycleAction(row as PlatformFirstLegOrderResource)">{{ actionLabel(row as PlatformFirstLegOrderResource) }}</el-button><el-button v-if="canCancel(row as PlatformFirstLegOrderResource)" link type="danger" :loading="actionLoadingId === String((row as PlatformFirstLegOrderResource).id)" @click="cancelOrder(row as PlatformFirstLegOrderResource)">取消</el-button><el-button v-if="can('platform:order:fulfillment') && !['DRAFT', 'REJECTED', 'CANCELLED'].includes((row as PlatformFirstLegOrderResource).status)" link type="primary" @click="openExpress(row as PlatformFirstLegOrderResource)"><PackageCheck :size="15" />快递</el-button><el-button v-if="can('platform:order:note')" link type="primary" @click="openNote(row as PlatformFirstLegOrderResource)"><FilePenLine :size="15" />备注</el-button></div></template>
|
|
|
|
|
<template #actions="{ row }">
|
|
|
|
|
<div class="table-actions order-row-actions">
|
|
|
|
|
<el-button link type="primary" :disabled="actionLoadingId === String((row as PlatformFirstLegOrderResource).id)" @click="openDetail(row as PlatformFirstLegOrderResource)"><Eye :size="15" />详情</el-button>
|
|
|
|
|
<el-button v-if="actionLabel(row as PlatformFirstLegOrderResource)" link type="success" :loading="actionLoadingId === String((row as PlatformFirstLegOrderResource).id)" @click="runLifecycleAction(row as PlatformFirstLegOrderResource)">{{ actionLabel(row as PlatformFirstLegOrderResource) }}</el-button>
|
|
|
|
|
<el-dropdown v-if="hasSecondaryActions(row as PlatformFirstLegOrderResource)" trigger="click" popper-class="first-leg-action-menu" :disabled="actionLoadingId === String((row as PlatformFirstLegOrderResource).id)" @command="runSecondaryAction($event, row as PlatformFirstLegOrderResource)">
|
|
|
|
|
<el-button link type="primary" aria-label="更多订单操作"><MoreHorizontal :size="17" />更多</el-button>
|
|
|
|
|
<template #dropdown>
|
|
|
|
|
<el-dropdown-menu>
|
|
|
|
|
<el-dropdown-item v-if="canMaintainExpress(row as PlatformFirstLegOrderResource)" command="express"><PackageCheck :size="15" />维护快递</el-dropdown-item>
|
|
|
|
|
<el-dropdown-item v-if="can('platform:order:note')" command="note"><FilePenLine :size="15" />内部备注</el-dropdown-item>
|
|
|
|
|
<el-dropdown-item v-if="canCancel(row as PlatformFirstLegOrderResource)" command="cancel" divided><CircleX :size="15" />取消订单</el-dropdown-item>
|
|
|
|
|
</el-dropdown-menu>
|
|
|
|
|
</template>
|
|
|
|
|
</el-dropdown>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<template #orderInfo="{ row }"><div class="primary-cell"><strong>{{ (row as PlatformFirstLegOrderResource).orderNo || '-' }}</strong><span>{{ (row as PlatformFirstLegOrderResource).referenceId || '无客户参考号' }} · {{ formattedDate((row as PlatformFirstLegOrderResource).createdAt) }}</span></div></template>
|
|
|
|
|
<template #customer="{ row }"><div class="primary-cell"><strong>{{ tenantName((row as PlatformFirstLegOrderResource).tenantId) }}</strong><span>{{ (row as PlatformFirstLegOrderResource).customerName }} · {{ (row as PlatformFirstLegOrderResource).tenantId }}</span></div></template>
|
|
|
|
|
<template #transport="{ row }"><div class="primary-cell"><strong>{{ transportLabel(row as PlatformFirstLegOrderResource) }}</strong><span>{{ (row as PlatformFirstLegOrderResource).channelName || '未填写渠道' }}</span></div></template>
|
|
|
|
@@ -538,6 +567,9 @@ onMounted(() => void loadTenants())
|
|
|
|
|
.detail-page-header p { margin: 5px 0 0; color: var(--cc-muted); font-size: 12px; line-height: 1.5; }
|
|
|
|
|
.detail-table-scroll { overflow-x: auto; }
|
|
|
|
|
.party-grid p { margin: 4px 0 0; color: var(--cc-muted); font-size: 12px; line-height: 1.6; overflow-wrap: anywhere; }
|
|
|
|
|
.order-row-actions { gap: 8px; white-space: nowrap; }
|
|
|
|
|
.order-row-actions :deep(.el-button + .el-button) { margin-left: 0; }
|
|
|
|
|
:global(.first-leg-action-menu .el-dropdown-menu__item) { min-height: 44px; gap: 8px; }
|
|
|
|
|
|
|
|
|
|
@media (max-width: 720px) {
|
|
|
|
|
.detail-page-header { align-items: flex-start; flex-direction: column; padding: 16px; }
|
|
|
|
|