feat(fleet): complete exception processing and trip evidence interfaces
This commit is contained in:
@@ -1,19 +1,21 @@
|
||||
import ElementPlus from 'element-plus'
|
||||
import { flushPromises, mount } from '@vue/test-utils'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { createExceptionOrder, listExceptionOrders, resolveExceptionRelation } from '../api/exceptionOrders'
|
||||
import { createExceptionOrder, listExceptionOrders, resolveExceptionRelation, getExceptionDetail } from '../api/exceptionOrders'
|
||||
import ExceptionOrdersView from './ExceptionOrdersView.vue'
|
||||
import { commonPhase5Stubs } from './phase5TestStubs'
|
||||
|
||||
const canPermission = vi.hoisted(() => vi.fn((_code: string) => false))
|
||||
vi.mock('@/core/access/accessPreview', () => ({ useAccessPreviewStore: () => ({ can: canPermission }) }))
|
||||
vi.mock('../api/exceptionOrders', () => ({ listExceptionOrders: vi.fn(), resolveExceptionRelation: vi.fn(), createExceptionOrder: vi.fn() }))
|
||||
vi.mock('../api/exceptionOrders', () => ({ listExceptionOrders: vi.fn(), resolveExceptionRelation: vi.fn(), createExceptionOrder: vi.fn(), getExceptionDetail: vi.fn(), commandException: vi.fn(), uploadExceptionEvidence: vi.fn() }))
|
||||
|
||||
function mountView() { return mount(ExceptionOrdersView, { global: { plugins: [ElementPlus], stubs: commonPhase5Stubs } }) }
|
||||
|
||||
describe('ExceptionOrdersView permissions and creation', () => {
|
||||
beforeEach(() => {
|
||||
canPermission.mockReset().mockReturnValue(false)
|
||||
vi.mocked(getExceptionDetail).mockReset().mockResolvedValue({ order: { id: '19', exceptionNo: 'EXC-1', customerId: '100', customerName: '示例客户',
|
||||
exceptionType: 'DAMAGED', status: 'PROCESSING', reason: '包装破损', handlerName: '1000001', version: 1, allowedActions: ['COMPLETE_EXCEPTION'], exceptionAt: '', updatedAt: '' }, returnSources: [] })
|
||||
vi.mocked(listExceptionOrders).mockReset().mockResolvedValue({ records: [], page: 1, size: 10, total: 0, pages: 0 })
|
||||
vi.mocked(resolveExceptionRelation).mockReset().mockResolvedValue({ inboundOrderId: '9', inboundCode: 'IN-1', lastMileOrderId: '8', lastMileOrderNo: 'LM-1', customerId: '100' })
|
||||
vi.mocked(createExceptionOrder).mockReset().mockResolvedValue({ id: '19', exceptionNo: 'EXC-1', status: 'PENDING' })
|
||||
|
||||
@@ -17,6 +17,7 @@ import { formatOverseasDateTime } from '../lastMilePresentation'
|
||||
import { overseasWarehousePermissions as permission } from '../permissions'
|
||||
import { createExceptionOrder, listExceptionOrders, resolveExceptionRelation, type ExceptionOrderRow, type ExceptionRelation } from '../api/exceptionOrders'
|
||||
import OrderReferenceText from '../components/OrderReferenceText.vue'
|
||||
import ExceptionProcessingPanel from '../components/ExceptionProcessingPanel.vue'
|
||||
|
||||
const rows = ref<ExceptionOrderRow[]>([]); const page = ref(1); const pageSize = ref(10); const total = ref(0); const loading = ref(false); const error = ref<ApiErrorDetails | null>(null)
|
||||
const access = useAccessPreviewStore()
|
||||
@@ -24,7 +25,7 @@ const filters = ref<QueryModel>({ keyword: '', exceptionType: '', status: '' })
|
||||
const fields: QueryField[] = [
|
||||
{ key: 'keyword', type: 'input', label: '关键词', placeholder: '异常单号 / 关联单号 / 客户 / 原因' },
|
||||
{ key: 'exceptionType', type: 'select', label: '异常类型', placeholder: '全部类型', options: [{ label: '退货', value: 'RETURN' }, { label: '拒收', value: 'REJECT' }, { label: '破损', value: 'DAMAGED' }, { label: '其他', value: 'OTHER' }] },
|
||||
{ key: 'status', type: 'select', label: '处理状态', placeholder: '全部状态', options: [{ label: '待处理', value: 'PENDING' }, { label: '处理中', value: 'PROCESSING' }, { label: '已完成', value: 'COMPLETED' }] },
|
||||
{ key: 'status', type: 'select', label: '处理状态', placeholder: '全部状态', options: [{ label: '待处理', value: 'PENDING' }, { label: '处理中', value: 'PROCESSING' }, { label: '已完成', value: 'COMPLETED' }, { label: '已取消', value: 'CANCELLED' }] },
|
||||
]
|
||||
const columns: DataTableColumn[] = [
|
||||
{ key: 'actions', label: '操作', width: 100, fixed: 'left', slotName: 'actions' },
|
||||
@@ -44,7 +45,7 @@ const columns: DataTableColumn[] = [
|
||||
{ key: 'updatedAt', label: '更新时间', minWidth: 170, formatter: (row: ExceptionOrderRow) => formatOverseasDateTime(row.updatedAt) },
|
||||
]
|
||||
const typeLabels: Record<string, string> = { RETURN: '退货', REJECT: '拒收', DAMAGED: '破损', OTHER: '其他' }
|
||||
const statusLabels: Record<string, string> = { PENDING: '待处理', PROCESSING: '处理中', COMPLETED: '已完成' }
|
||||
const statusLabels: Record<string, string> = { PENDING: '待处理', PROCESSING: '处理中', COMPLETED: '已完成', CANCELLED: '已取消' }
|
||||
const detailOpen = ref(false); const detailRow = ref<ExceptionOrderRow | null>(null)
|
||||
function openDetail(row: ExceptionOrderRow) { detailRow.value = row; detailOpen.value = true }
|
||||
function displayHandler(value: unknown) {
|
||||
@@ -108,18 +109,7 @@ onMounted(load)
|
||||
</el-form>
|
||||
</AppDialog>
|
||||
<AppDialog class="admin-density-dialog" v-model="detailOpen" title="异常订单详情" width="min(760px, calc(100vw - 28px))" :show-confirm="false" cancel-text="关闭">
|
||||
<el-descriptions class="density-descriptions" v-if="detailRow" :column="2" border>
|
||||
<el-descriptions-item label="异常订单号">{{ detailRow.exceptionNo }}</el-descriptions-item>
|
||||
<el-descriptions-item label="处理状态">{{ statusLabels[String(detailRow.status)] || detailRow.status }}</el-descriptions-item>
|
||||
<el-descriptions-item label="异常类型">{{ typeLabels[detailRow.exceptionType] || detailRow.exceptionType }}</el-descriptions-item>
|
||||
<el-descriptions-item label="客户">{{ detailRow.customerName || '—' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="海外仓">{{ detailRow.overseasWarehouseName || '—' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="处理人">{{ displayHandler(detailRow.handlerName) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="异常时间">{{ formatOverseasDateTime(detailRow.exceptionAt) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="更新时间">{{ formatOverseasDateTime(detailRow.updatedAt) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="异常原因" :span="2">{{ detailRow.reason || '—' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="处理动作" :span="2">{{ detailRow.handlingAction || '—' }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<ExceptionProcessingPanel v-if="detailRow" :customer-id="detailRow.customerId" :exception-no="detailRow.exceptionNo" :active="detailOpen" @changed="load()" />
|
||||
</AppDialog>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user