优化
This commit is contained in:
@@ -1,8 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, reactive, ref, watch } from 'vue'
|
||||
import { ElMessage, ElMessageBox, type UploadFile } from 'element-plus'
|
||||
import { ChevronDown, Download, FileSpreadsheet, MapPin, Pencil, Plus, Power, Upload, Warehouse as WarehouseIcon } from '@lucide/vue'
|
||||
import { ChevronDown, Download, FileSpreadsheet, FileUp, MapPin, Pencil, Plus, Power, Save, Warehouse as WarehouseIcon } from '@lucide/vue'
|
||||
import AdminPage from '@/shared/components/AdminPage.vue'
|
||||
import AppDrawer from '@/shared/components/AppDrawer.vue'
|
||||
import DataTable, { type DataTableColumn } from '@/shared/components/DataTable.vue'
|
||||
import FormSection from '@/shared/components/FormSection.vue'
|
||||
import ListPageLayout from '@/shared/components/ListPageLayout.vue'
|
||||
import LoadErrorState from '@/shared/components/LoadErrorState.vue'
|
||||
import QueryToolbar, { type QueryField, type QueryModel } from '@/shared/components/QueryToolbar.vue'
|
||||
import { useUnsavedWorkRegistration } from '@/core/unsaved-work/useUnsavedWorkRegistration'
|
||||
import { getApiErrorDetails, type ApiErrorDetails } from '@/shared/api/http'
|
||||
@@ -253,8 +258,7 @@ const loadErrorDescription = computed(() => {
|
||||
loadError.value.requestId ? `requestId ${loadError.value.requestId}` : '',
|
||||
loadError.value.traceId ? `traceId ${loadError.value.traceId}` : '',
|
||||
].filter(Boolean)
|
||||
const retained = loaded.value ? '当前仍显示最近一次成功加载的数据。' : ''
|
||||
return [loadError.value.message, references.join(' · '), retained].filter(Boolean).join(' ')
|
||||
return [loadError.value.message, references.join(' · ')].filter(Boolean).join(' ')
|
||||
})
|
||||
|
||||
watch(
|
||||
@@ -665,16 +669,22 @@ onMounted(() => void loadWarehouses())
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="business-page">
|
||||
<el-alert v-if="loadError" type="error" :closable="false" show-icon class="state-alert">
|
||||
<template #title>仓库数据加载失败</template>
|
||||
<p>{{ loadErrorDescription }}</p>
|
||||
<el-button size="small" @click="loadWarehouses()">重新查询</el-button>
|
||||
</el-alert>
|
||||
<AdminPage as="div">
|
||||
<ListPageLayout aria-label="仓库列表页面">
|
||||
<template #toolbar>
|
||||
<QueryToolbar v-model="filters" class="surface-panel" ariaLabel="仓库筛选" :fields="queryFields" preference-key="warehouses-query" @search="queryWarehouses" />
|
||||
</template>
|
||||
<template v-if="loadError" #state>
|
||||
<LoadErrorState
|
||||
title="仓库数据加载失败"
|
||||
:message="loadErrorDescription"
|
||||
:loading="loading"
|
||||
retry-text="重新查询"
|
||||
@retry="loadWarehouses"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<QueryToolbar v-model="filters" class="surface-panel" ariaLabel="仓库筛选" :fields="queryFields" preference-key="warehouses-query" @search="queryWarehouses" />
|
||||
|
||||
<section class="surface-panel table-panel" aria-live="polite">
|
||||
<section v-if="!loadError" class="surface-panel table-panel" aria-live="polite">
|
||||
<DataTable
|
||||
v-model:page="page"
|
||||
v-model:page-size="pageSize"
|
||||
@@ -688,10 +698,9 @@ onMounted(() => void loadWarehouses())
|
||||
aria-label="公共仓库列表"
|
||||
:empty-text="loaded ? '暂无符合筛选条件的仓库' : '仓库数据暂不可用,请重新加载'"
|
||||
>
|
||||
<template #toolbar-start><div><h2>公共仓库</h2><p>国内收货仓、FBA 地址和海外仓统一维护 · 共 {{ total }} 个</p></div></template>
|
||||
<template #toolbar-actions>
|
||||
<div v-if="access.can('platform:warehouse:create')" class="warehouse-primary-actions">
|
||||
<el-button :disabled="!warehouseReady" @click="openImport"><Upload :size="16" />导入仓库</el-button>
|
||||
<el-button :disabled="!warehouseReady" @click="openImport"><FileUp :size="16" />导入仓库</el-button>
|
||||
<el-dropdown trigger="click" :disabled="!warehouseReady" @command="openCreate($event as WarehouseType)">
|
||||
<el-button type="primary" :disabled="!warehouseReady"><Plus :size="16" />新增仓库<ChevronDown :size="15" /></el-button>
|
||||
<template #dropdown><el-dropdown-menu><el-dropdown-item command="FBA"><FileSpreadsheet :size="15" />新增 FBA 地址</el-dropdown-item><el-dropdown-item command="DOMESTIC"><WarehouseIcon :size="15" />新增国内仓</el-dropdown-item><el-dropdown-item command="OVERSEAS"><MapPin :size="15" />新增海外仓</el-dropdown-item></el-dropdown-menu></template>
|
||||
@@ -721,12 +730,12 @@ onMounted(() => void loadWarehouses())
|
||||
<template #status="{ row }"><el-tag :type="(row as WarehouseRow).status === 'ACTIVE' ? 'success' : 'info'" effect="light">{{ (row as WarehouseRow).status === 'ACTIVE' ? '启用' : '停用' }}</el-tag></template>
|
||||
<template #pagination-left="{ total: tableTotal }">共 {{ tableTotal }} 个公共仓库</template>
|
||||
</DataTable>
|
||||
</section>
|
||||
</section>
|
||||
</ListPageLayout>
|
||||
|
||||
<el-drawer v-model="editorOpen" :title="editorLabel" size="620px" class="business-drawer editor-drawer" :close-on-click-modal="false">
|
||||
<AppDrawer v-model="editorOpen" :title="editorLabel" size="min(620px, 94vw)" class="editor-drawer" :close-on-click-modal="false" :confirm-loading="saving" :show-confirm="false">
|
||||
<el-form :model="form" label-position="top" class="drawer-form" :disabled="saving">
|
||||
<div class="form-section">
|
||||
<h3>基础信息</h3>
|
||||
<FormSection title="基础信息">
|
||||
<div class="form-grid two-cols">
|
||||
<el-form-item v-if="isFbaCreate" label="FBA 编码" required :class="{ 'has-field-error': formErrors.code }"><el-input v-model="form.code" maxlength="50" placeholder="例如 LAX9" @input="form.code = String($event).toUpperCase(); clearFieldError('code')" /><p v-if="formErrors.code" class="field-error" role="alert">{{ formErrors.code }}</p></el-form-item>
|
||||
<el-form-item v-if="isFbaCreate" label="国家或地区" required>
|
||||
@@ -749,10 +758,9 @@ onMounted(() => void loadWarehouses())
|
||||
</el-form-item>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</FormSection>
|
||||
|
||||
<div class="form-section">
|
||||
<h3>地址信息</h3>
|
||||
<FormSection title="地址信息">
|
||||
<div class="form-grid two-cols">
|
||||
<el-form-item :label="addressRegionLabel" :required="isFbaCreate || usesUsStateSelect" :class="{ 'has-field-error': formErrors.province }">
|
||||
<el-select v-if="usesUsStateSelect" v-model="form.province" filterable :placeholder="regionPlaceholder" @change="onRegionChange"><el-option v-for="state in usStateOptions" :key="state.value" :label="state.label" :value="state.value" /></el-select>
|
||||
@@ -763,28 +771,26 @@ onMounted(() => void loadWarehouses())
|
||||
<el-form-item label="邮编" :required="isFbaCreate" :class="{ 'has-field-error': formErrors.postalCode }"><el-input v-model="form.postalCode" maxlength="20" :placeholder="isDomesticForm ? '例如 322000' : '例如 90802'" @input="clearFieldError('postalCode')" /><p v-if="formErrors.postalCode" class="field-error" role="alert">{{ formErrors.postalCode }}</p></el-form-item>
|
||||
</div>
|
||||
<el-form-item label="详细地址" required :class="{ 'has-field-error': formErrors.address }"><el-input v-model="form.address" maxlength="255" type="textarea" :rows="3" :placeholder="addressPlaceholder" @input="clearFieldError('address')" /><p v-if="formErrors.address" class="field-error" role="alert">{{ formErrors.address }}</p></el-form-item>
|
||||
</div>
|
||||
</FormSection>
|
||||
|
||||
<section v-if="!isFbaCreate" class="form-section">
|
||||
<h3>编码与状态</h3>
|
||||
<FormSection v-if="!isFbaCreate" title="编码与状态">
|
||||
<div class="form-grid two-cols compact-grid">
|
||||
<el-form-item label="仓库编码" :class="{ 'has-field-error': formErrors.code }"><el-input v-model="form.code" maxlength="50" placeholder="系统自动生成" @input="form.code = String($event).toUpperCase(); clearFieldError('code')" /><p v-if="formErrors.code" class="field-error" role="alert">{{ formErrors.code }}</p></el-form-item>
|
||||
<el-form-item label="状态"><el-radio-group v-model="form.status" class="warehouse-status-toggle"><el-radio-button value="ACTIVE">启用</el-radio-button><el-radio-button value="INACTIVE">停用</el-radio-button></el-radio-group></el-form-item>
|
||||
</div>
|
||||
</section>
|
||||
</FormSection>
|
||||
|
||||
<section v-if="!isFbaCreate" class="form-section">
|
||||
<h3>联系信息</h3>
|
||||
<FormSection v-if="!isFbaCreate" title="联系信息">
|
||||
<div class="form-grid two-cols compact-grid">
|
||||
<el-form-item label="联系人"><el-input v-model="form.contactName" maxlength="64" placeholder="选填" /></el-form-item>
|
||||
<el-form-item label="联系电话"><el-input v-model="form.contactPhone" maxlength="32" placeholder="选填" /></el-form-item>
|
||||
<el-form-item label="收货时间"><el-input v-model="form.businessHours" maxlength="500" placeholder="例如 周一至周六 08:30-18:00" /></el-form-item>
|
||||
</div>
|
||||
<el-form-item label="备注"><el-input v-model="form.remark" maxlength="500" type="textarea" :rows="3" show-word-limit placeholder="选填" /></el-form-item>
|
||||
</section>
|
||||
</FormSection>
|
||||
</el-form>
|
||||
<template #footer><div class="drawer-footer"><el-button :disabled="saving" @click="editorOpen = false">取消</el-button><el-button type="primary" :loading="saving" @click="saveWarehouse">{{ editorMode === 'EDIT' ? '保存修改' : '确认新增' }}</el-button></div></template>
|
||||
</el-drawer>
|
||||
<template #footer><div class="drawer-footer"><el-button :disabled="saving" @click="editorOpen = false">取消</el-button><el-button type="primary" :loading="saving" @click="saveWarehouse"><Save :size="16" />{{ editorMode === 'EDIT' ? '保存修改' : '确认新增' }}</el-button></div></template>
|
||||
</AppDrawer>
|
||||
|
||||
<el-dialog v-model="importOpen" title="导入公共仓库" width="min(760px, calc(100vw - 32px))" :close-on-click-modal="!importing" :close-on-press-escape="!importing">
|
||||
<div class="import-content">
|
||||
@@ -796,7 +802,7 @@ onMounted(() => void loadWarehouses())
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<el-upload accept=".xlsx" :auto-upload="false" :limit="1" :on-change="selectImportFile" :on-remove="removeImportFile">
|
||||
<el-button><Upload :size="16" />选择 XLSX 文件</el-button>
|
||||
<el-button><FileUp :size="16" />选择 XLSX 文件</el-button>
|
||||
<template #tip><div class="el-upload__tip">最多 5MB、1000 行;请使用标准模板,FBA 名称可不填并默认使用编码。</div></template>
|
||||
</el-upload>
|
||||
<div v-if="importResult" class="import-result" role="status">
|
||||
@@ -814,9 +820,9 @@ onMounted(() => void loadWarehouses())
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer><el-button :disabled="importing" @click="importOpen = false">关闭</el-button><el-button :loading="importing" :disabled="!importFile" @click="runImport(true)">预检文件</el-button><el-button type="primary" :loading="importing" :disabled="!canCommitImport" @click="runImport(false)">确认导入</el-button></template>
|
||||
<template #footer><el-button :disabled="importing" @click="importOpen = false">关闭</el-button><el-button :loading="importing" :disabled="!importFile" @click="runImport(true)">预检文件</el-button><el-button type="primary" :loading="importing" :disabled="!canCommitImport" @click="runImport(false)"><FileUp :size="16" />确认导入</el-button></template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</AdminPage>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
Reference in New Issue
Block a user