Merge branch 'release/test' of http://8.163.30.128:10082/html/admin-web into release/test

This commit is contained in:
2026-08-11 11:59:39 +08:00
47 changed files with 1193 additions and 236 deletions
@@ -1,5 +1,6 @@
<script setup lang="ts">
import { computed, onMounted, reactive, ref, watch } from 'vue'
import { useRoute } from 'vue-router'
import { ElMessage, type FormInstance, type FormRules } from 'element-plus'
import { Eye, Pencil } from '@lucide/vue'
import { useAccessPreviewStore } from '@/core/access/accessPreview'
@@ -28,6 +29,7 @@ import {
} from '../api/platformLoadingLists'
const props = defineProps<{ mode: LoadingListMode }>()
const route = useRoute()
const access = useAccessPreviewStore()
const rows = ref<LoadingListSummary[]>([])
const loading = ref(false)
@@ -47,6 +49,7 @@ const editSaving = ref(false)
const editError = ref<ApiErrorDetails | null>(null)
const editFormRef = ref<FormInstance>()
const editForm = reactive({ containerNo: '', voyageNo: '', operationReason: '' })
const handledDeepLink = ref('')
const isPreload = computed(() => props.mode === 'preload')
const title = computed(() => isPreload.value ? '预装清单' : '装柜清单')
@@ -111,6 +114,10 @@ function statusLabel(status?: string | null) {
return ({ WAIT_LOADING: '待装柜', EDITING: '预装柜中', LOADING: '拣货中', COMPLETED: '装柜完成' } as Record<string, string>)[status || ''] || status || '—'
}
function queryId(value: unknown) {
return typeof value === 'string' && /^[1-9]\d*$/.test(value) ? value : ''
}
function toQuery(): LoadingListQuery {
const range = Array.isArray(query.createdRange) ? query.createdRange.map(String) : []
return {
@@ -131,6 +138,7 @@ async function load() {
const result = isPreload.value ? await listPreloadPlans(request) : await listConfirmedLoadingLists(request)
rows.value = result.records
total.value = result.total
await openDeepLinkedDetail()
} catch (cause) {
error.value = getApiErrorDetails(cause, `${title.value}加载失败,请稍后重试`)
} finally {
@@ -138,6 +146,30 @@ async function load() {
}
}
async function openDeepLinkedDetail() {
const planId = queryId(route.query.planId)
const warehouseId = queryId(route.query.warehouseId)
if (!planId || !warehouseId || !canView.value) return
const key = `${props.mode}:${planId}:${warehouseId}`
if (handledDeepLink.value === key) return
handledDeepLink.value = key
selectedPlanId.value = planId
selectedWarehouseId.value = warehouseId
detail.value = null
detailError.value = null
detailOpen.value = true
await loadDetail()
const expectedStatus = isPreload.value ? 'LOADING' : 'COMPLETED'
const loadedDetail = detail.value as LoadingDetail | null
if (loadedDetail && loadedDetail.summary.status !== expectedStatus) {
detail.value = null
detailError.value = {
code: 'MODE_STATUS_MISMATCH',
message: `该计划不属于当前${title.value}状态,请从对应清单入口查看。`,
}
}
}
function search() {
if (page.value !== 1) page.value = 1
else void load()
@@ -145,7 +177,15 @@ function search() {
async function loadDetail() {
if (!selectedPlanId.value || !selectedWarehouseId.value || !canView.value) return
if (!canView.value) return
if (!selectedPlanId.value || !selectedWarehouseId.value) {
detail.value = null
detailError.value = {
message: '该清单缺少所属仓库信息,无法安全查询详情,请联系管理员核对数据。',
code: 'MISSING_WAREHOUSE_CONTEXT',
}
return
}
detailLoading.value = true
detailError.value = null
try {
@@ -208,13 +248,23 @@ async function saveTransport() {
ElMessage.success('运输信息已更新')
await load()
} catch (cause) {
editError.value = getApiErrorDetails(cause, '运输信息保存失败,请刷新详情后重试')
const details = getApiErrorDetails(cause, '运输信息保存失败,请刷新详情后重试')
if (details.code === 'A0409' || /版本|并发|已被其他人修改/.test(details.message)) {
await loadDetail()
editError.value = {
...details,
message: '运输信息已被其他人修改,系统已刷新最新版本;当前输入已保留,请核对后重新保存。',
}
} else {
editError.value = details
}
} finally {
editSaving.value = false
}
}
watch([page, pageSize], () => void load())
watch(() => [route.query.planId, route.query.warehouseId], () => void openDeepLinkedDetail())
onMounted(() => {
void load()
})