This commit is contained in:
2026-08-06 13:56:04 +08:00
parent 6736893128
commit a813426588
35 changed files with 2822 additions and 489 deletions
@@ -2,7 +2,6 @@
import { computed, onMounted, reactive, ref, watch } from 'vue'
import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus'
import { Eye, MapPin, MoreHorizontal, Pencil, Plus, Power, Trash2 } from '@lucide/vue'
import { listPlatformTenants, type PlatformTenantResource } from '@/modules/iam'
import { useAccessPreviewStore } from '@/core/access/accessPreview'
import { useUnsavedWorkRegistration } from '@/core/unsaved-work/useUnsavedWorkRegistration'
import { getApiErrorDetails, type ApiErrorDetails } from '@/shared/api/http'
@@ -43,9 +42,6 @@ type AppliedLocationFilters = {
}
const access = useAccessPreviewStore()
const customers = ref<PlatformTenantResource[]>([])
const customerLoading = ref(false)
const customerError = ref<ApiErrorDetails | null>(null)
const warehouses = ref<PlatformWarehouseResource[]>([])
const warehouseLoading = ref(false)
const warehouseError = ref<ApiErrorDetails | null>(null)
@@ -82,7 +78,7 @@ const queryFields = computed<QueryField[]>(() => [
},
options: warehouses.value.map((warehouse) => ({
value: String(warehouse.id),
label: `${warehouse.warehouseName}(${warehouse.warehouseCode}) · ${customerLabel(warehouse.tenantId)}`,
label: `${warehouse.warehouseName}(${warehouse.warehouseCode})`,
})),
},
{ key: 'zoneCode', type: 'input', width: 210, placeholder: '库区编码', props: { maxlength: 50, 'aria-label': '库区编码' } },
@@ -232,32 +228,13 @@ function recordScope(row: PlatformLocationResource) {
return { customerId: apiId(String(row.tenantId)), warehouseId: apiId(String(row.warehouseId)) }
}
function customerLabel(customerId: number | string) {
const customer = customers.value.find((item) => String(item.id) === String(customerId))
return customer ? `${customer.tenantName}(${customer.tenantCode || customer.id})` : String(customerId)
}
async function loadCustomers() {
customerLoading.value = true
customerError.value = null
try {
const result = await listPlatformTenants({ page: 1, size: 200 })
customers.value = result.records
} catch (error) {
customers.value = []
customerError.value = getApiErrorDetails(error, '所属企业列表加载失败,请稍后重试')
} finally {
customerLoading.value = false
}
}
async function loadWarehouses() {
const sequence = ++warehouseLoadSequence
warehouseLoading.value = true
warehouseError.value = null
warehouses.value = []
try {
const result = await listPlatformWarehouses(undefined, 1, 200)
const result = await listPlatformWarehouses(1, 200)
if (sequence !== warehouseLoadSequence) return
warehouses.value = result.records
} catch (error) {
@@ -482,7 +459,6 @@ watch(() => form.warehouseId, (warehouseId) => {
})
onMounted(() => {
void loadCustomers()
void loadWarehouses()
void loadLocations()
})
@@ -497,12 +473,6 @@ onMounted(() => {
@search="applyFilters"
/>
<el-alert v-if="customerError" type="warning" :closable="false" show-icon class="state-alert">
<template #title>所属企业列表加载失败</template>
<p>{{ customerError.message }}</p>
<ApiErrorMeta :details="customerError" />
<el-button size="small" @click="loadCustomers">重新加载所属企业</el-button>
</el-alert>
<el-alert v-if="warehouseError" type="error" :closable="false" show-icon class="state-alert">
<template #title>仓库列表加载失败</template>
<p>{{ warehouseError.message }}</p>
@@ -637,7 +607,7 @@ onMounted(() => {
<el-tag :type="statusMeta[detail.location.status].type">{{ statusMeta[detail.location.status].label }}</el-tag>
</section>
<el-descriptions :column="2" border class="detail-descriptions">
<el-descriptions-item label="所属企业">{{ customerLabel(detail.location.tenantId) }}</el-descriptions-item>
<el-descriptions-item label="资源作用域">平台公共资源</el-descriptions-item>
<el-descriptions-item label="所属仓库">{{ detail.warehouseName }}({{ detail.warehouseCode }})</el-descriptions-item>
<el-descriptions-item label="库位编码">{{ detail.location.locationCode }}</el-descriptions-item>
<el-descriptions-item label="库位名称">{{ detail.location.locationName || '—' }}</el-descriptions-item>
@@ -677,21 +647,21 @@ onMounted(() => {
>
<div v-if="drawerMode === 'edit'" class="editor-scope">
<MapPin :size="18" />
<div><strong>{{ detail?.warehouseName || selectedWarehouse?.warehouseName }}({{ detail?.warehouseCode || selectedWarehouse?.warehouseCode }})</strong><span>所属企业:{{ customerLabel(form.customerId) }} · 保存后不可跨仓移动</span></div>
<div><strong>{{ detail?.warehouseName || selectedWarehouse?.warehouseName }}({{ detail?.warehouseCode || selectedWarehouse?.warehouseCode }})</strong><span>平台公共资源 · 保存后不可跨仓移动</span></div>
</div>
<el-form-item v-if="drawerMode === 'create'" label="所属仓库" prop="warehouseId" required>
<el-select v-model="form.warehouseId" filterable placeholder="请选择所属仓库" :loading="warehouseLoading">
<el-option
v-for="warehouse in warehouses"
:key="String(warehouse.id)"
:label="`${warehouse.warehouseName}(${warehouse.warehouseCode}) · ${customerLabel(warehouse.tenantId)}`"
:label="`${warehouse.warehouseName}(${warehouse.warehouseCode})`"
:value="String(warehouse.id)"
/>
</el-select>
</el-form-item>
<section class="form-section">
<h3>库位标识</h3>
<p class="section-description">库位编码在当前企业和仓库内唯一;编辑后不能移动到其他仓库。</p>
<p class="section-description">库位编码在当前仓库内唯一;编辑后不能移动到其他仓库。</p>
<div class="form-grid two-cols">
<el-form-item label="库位编码" prop="locationCode" required>
<el-input v-model.trim="form.locationCode" maxlength="50" placeholder="例如 A1-01" />