| | |
| | | <ArtTableHeader v-model:columns="columnChecks" :loading="loading" @refresh="refreshData"> |
| | | <template #left> |
| | | <ElSpace wrap> |
| | | <ElButton v-auth="'add'" @click="showDialog('add')" v-ripple>新增库区</ElButton> |
| | | <ElButton v-auth="'add'" @click="openWarehouseAreasDialog('add')" v-ripple> |
| | | {{ t('common.actions.add') + t('pages.basicInfo.warehouseAreas.entity') }} |
| | | </ElButton> |
| | | <ElButton |
| | | v-auth="'delete'" |
| | | type="danger" |
| | |
| | | @click="handleBatchDelete" |
| | | v-ripple |
| | | > |
| | | 批量删除 |
| | | {{ t('common.actions.batchDelete') }} |
| | | </ElButton> |
| | | <ListExportPrint |
| | | class="inline-flex" |
| | | :preview-visible="previewVisible" |
| | | @update:previewVisible="handlePreviewVisibleChange" |
| | | :report-title="reportTitle" |
| | | :selected-rows="selectedRows" |
| | | :query-params="reportQueryParams" |
| | | :columns="columns" |
| | | :preview-rows="previewRows" |
| | | :preview-meta="resolvedPreviewMeta" |
| | | :total="pagination.total" |
| | | :disabled="loading" |
| | | @export="handleExport" |
| | | @print="handlePrint" |
| | | /> |
| | | </ElSpace> |
| | | </template> |
| | | </ArtTableHeader> |
| | |
| | | <script setup> |
| | | import { computed, onMounted, ref } from 'vue' |
| | | import { ElMessage } from 'element-plus' |
| | | import { useI18n } from 'vue-i18n' |
| | | import ListExportPrint from '@/components/biz/list-export-print/index.vue' |
| | | import { useAuth } from '@/hooks/core/useAuth' |
| | | import { useTable } from '@/hooks/core/useTable' |
| | | import { useTableColumns } from '@/hooks/core/useTableColumns' |
| | | import { useUserStore } from '@/store/modules/user' |
| | | import { useCrudPage } from '@/views/system/common/useCrudPage' |
| | | import { usePrintExportPage } from '@/views/system/common/usePrintExportPage' |
| | | import { defaultResponseAdapter } from '@/utils/table/tableUtils' |
| | | import { guardRequestWithMessage } from '@/utils/sys/requestGuard' |
| | | import { fetchDictDataPage } from '@/api/system-manage' |
| | |
| | | fetchCompanysList, |
| | | fetchDeleteWarehouseAreas, |
| | | fetchWarehouseAreasDetail, |
| | | fetchWarehouseAreasMany, |
| | | fetchWarehouseAreasPage, |
| | | fetchExportWarehouseAreasReport, |
| | | fetchSaveWarehouseAreas, |
| | | fetchUpdateWarehouseAreas, |
| | | fetchWarehouseList |
| | |
| | | import { |
| | | buildWarehouseAreasDialogModel, |
| | | buildWarehouseAreasPageQueryParams, |
| | | buildWarehouseAreasPrintRows, |
| | | buildWarehouseAreasSavePayload, |
| | | buildWarehouseAreasSearchParams, |
| | | createWarehouseAreasSearchState, |
| | | getWarehouseAreasReportTitle, |
| | | getWarehouseAreasPaginationKey, |
| | | WAREHOUSE_AREAS_REPORT_STYLE, |
| | | getWarehouseAreasStatusOptions, |
| | | normalizeWarehouseAreasDetailRecord, |
| | | normalizeWarehouseAreasListRow |
| | |
| | | |
| | | defineOptions({ name: 'WarehouseAreas' }) |
| | | |
| | | const { t } = useI18n() |
| | | const { hasAuth } = useAuth() |
| | | const userStore = useUserStore() |
| | | |
| | | const searchForm = ref(createWarehouseAreasSearchState()) |
| | | const detailDrawerVisible = ref(false) |
| | |
| | | const shipperOptions = ref([]) |
| | | const supplierOptions = ref([]) |
| | | const typeOptions = ref([]) |
| | | const companyOptionsLoaded = ref(false) |
| | | const companyOptionsLoading = ref(null) |
| | | let handleDeleteAction = null |
| | | |
| | | const searchItems = computed(() => [ |
| | | { |
| | | label: '关键字', |
| | | label: t('table.keyword'), |
| | | key: 'condition', |
| | | type: 'input', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: '请输入库区名称/编码/备注' |
| | | placeholder: t('pages.basicInfo.warehouseAreas.search.conditionPlaceholder') |
| | | } |
| | | }, |
| | | { |
| | | label: '仓库', |
| | | label: t('pages.basicInfo.warehouseAreas.table.warehouseName'), |
| | | key: 'warehouseId', |
| | | type: 'select', |
| | | props: { |
| | |
| | | } |
| | | }, |
| | | { |
| | | label: '库区编码', |
| | | label: t('pages.basicInfo.warehouseAreas.table.code'), |
| | | key: 'code', |
| | | type: 'input', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: '请输入库区编码' |
| | | placeholder: t('pages.basicInfo.warehouseAreas.search.codePlaceholder') |
| | | } |
| | | }, |
| | | { |
| | | label: '库区名称', |
| | | label: t('pages.basicInfo.warehouseAreas.table.name'), |
| | | key: 'name', |
| | | type: 'input', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: '请输入库区名称' |
| | | placeholder: t('pages.basicInfo.warehouseAreas.search.namePlaceholder') |
| | | } |
| | | }, |
| | | { |
| | | label: '业务类型', |
| | | label: t('pages.basicInfo.warehouseAreas.table.type'), |
| | | key: 'type', |
| | | type: 'select', |
| | | props: { |
| | |
| | | } |
| | | }, |
| | | { |
| | | label: '状态', |
| | | label: t('table.status'), |
| | | key: 'status', |
| | | type: 'select', |
| | | props: { |
| | | clearable: true, |
| | | options: getWarehouseAreasStatusOptions() |
| | | options: getWarehouseAreasStatusOptions(t) |
| | | } |
| | | } |
| | | ]) |
| | | |
| | | const reportTitle = computed(() => getWarehouseAreasReportTitle(t)) |
| | | const reportQueryParams = computed(() => buildWarehouseAreasSearchParams(searchForm.value)) |
| | | |
| | | async function openDetail(row) { |
| | | detailDrawerVisible.value = true |
| | | detailLoading.value = true |
| | | try { |
| | | const detail = await guardRequestWithMessage(fetchWarehouseAreasDetail(row.id), {}, { |
| | | timeoutMessage: '库区详情加载超时,已停止等待' |
| | | timeoutMessage: t('pages.basicInfo.warehouseAreas.messages.detailTimeout') |
| | | }) |
| | | detailData.value = normalizeWarehouseAreasDetailRecord(detail) |
| | | } catch (error) { |
| | | detailDrawerVisible.value = false |
| | | detailData.value = {} |
| | | ElMessage.error(error?.message || '获取库区详情失败') |
| | | ElMessage.error(error?.message || t('pages.basicInfo.warehouseAreas.messages.detailFailed')) |
| | | } finally { |
| | | detailLoading.value = false |
| | | } |
| | |
| | | |
| | | async function openEditDialog(row) { |
| | | try { |
| | | await ensureCompanyOptions() |
| | | const detail = await guardRequestWithMessage(fetchWarehouseAreasDetail(row.id), {}, { |
| | | timeoutMessage: '库区详情加载超时,已停止等待' |
| | | timeoutMessage: t('pages.basicInfo.warehouseAreas.messages.detailTimeout') |
| | | }) |
| | | showDialog('edit', detail) |
| | | } catch (error) { |
| | | ElMessage.error(error?.message || '获取库区详情失败') |
| | | ElMessage.error(error?.message || t('pages.basicInfo.warehouseAreas.messages.detailFailed')) |
| | | } |
| | | } |
| | | |
| | | async function openWarehouseAreasDialog(type, record) { |
| | | await ensureCompanyOptions() |
| | | showDialog(type, record) |
| | | } |
| | | |
| | | const { columns, columnChecks, data, loading, pagination, getData, replaceSearchParams, resetSearchParams, handleSizeChange, handleCurrentChange, refreshData, refreshCreate, refreshUpdate, refreshRemove } = |
| | |
| | | paginationKey: getWarehouseAreasPaginationKey(), |
| | | columnsFactory: () => |
| | | createWarehouseAreasTableColumns({ |
| | | t, |
| | | handleView: openDetail, |
| | | handleEdit: hasAuth('update') ? openEditDialog : null, |
| | | handleDelete: hasAuth('delete') ? (row) => handleDeleteAction?.(row) : null, |
| | |
| | | saveRequest: fetchSaveWarehouseAreas, |
| | | updateRequest: fetchUpdateWarehouseAreas, |
| | | deleteRequest: fetchDeleteWarehouseAreas, |
| | | entityName: '库区', |
| | | entityName: t('pages.basicInfo.warehouseAreas.entity'), |
| | | resolveRecordLabel: (record) => record?.name || record?.code || record?.id, |
| | | refreshCreate, |
| | | refreshUpdate, |
| | | refreshRemove |
| | | }) |
| | | handleDeleteAction = handleDelete |
| | | |
| | | const buildPreviewMeta = (rows) => { |
| | | const now = new Date() |
| | | return { |
| | | reportDate: now.toLocaleDateString('zh-CN'), |
| | | printedAt: now.toLocaleString('zh-CN', { hour12: false }), |
| | | operator: userStore.getUserInfo?.name || userStore.getUserInfo?.username || '', |
| | | count: rows.length, |
| | | reportTitle: reportTitle.value, |
| | | reportStyle: { ...WAREHOUSE_AREAS_REPORT_STYLE } |
| | | } |
| | | } |
| | | |
| | | const resolvePrintRecords = async (payload) => { |
| | | if (Array.isArray(payload?.ids) && payload.ids.length > 0) { |
| | | return defaultResponseAdapter(await fetchWarehouseAreasMany(payload.ids)).records |
| | | } |
| | | return defaultResponseAdapter( |
| | | await fetchWarehouseAreasPage({ |
| | | ...reportQueryParams.value, |
| | | current: 1, |
| | | pageSize: Number(pagination.total) > 0 ? Number(pagination.total) : Number(payload?.pageSize) || 20 |
| | | }) |
| | | ).records |
| | | } |
| | | |
| | | const { |
| | | previewVisible, |
| | | previewRows, |
| | | previewMeta, |
| | | handlePreviewVisibleChange, |
| | | handleExport, |
| | | handlePrint |
| | | } = usePrintExportPage({ |
| | | downloadFileName: 'warehouse-areas.xlsx', |
| | | requestExport: (payload) => |
| | | fetchExportWarehouseAreasReport(payload, { |
| | | headers: { |
| | | Authorization: userStore.accessToken || '' |
| | | } |
| | | }), |
| | | resolvePrintRecords, |
| | | buildPreviewRows: (records) => buildWarehouseAreasPrintRows(records), |
| | | buildPreviewMeta |
| | | }) |
| | | |
| | | const resolvedPreviewMeta = computed(() => ({ |
| | | ...previewMeta.value, |
| | | reportTitle: reportTitle.value, |
| | | count: previewRows.value.length || previewMeta.value?.count || 0, |
| | | reportStyle: { |
| | | ...WAREHOUSE_AREAS_REPORT_STYLE, |
| | | ...(previewMeta.value?.reportStyle || {}) |
| | | } |
| | | })) |
| | | |
| | | function handleSearch(params) { |
| | | replaceSearchParams(buildWarehouseAreasSearchParams(params)) |
| | |
| | | resetSearchParams() |
| | | } |
| | | |
| | | async function loadWarehouseOptions() { |
| | | const records = await guardRequestWithMessage(fetchWarehouseList(), [], { |
| | | timeoutMessage: '仓库选项加载超时,已停止等待' |
| | | }) |
| | | warehouseOptions.value = defaultResponseAdapter(records).records.map((item) => ({ |
| | | label: item.name || item.code || `仓库 ${item.id}`, |
| | | value: item.id |
| | | })) |
| | | async function ensureCompanyOptions() { |
| | | if (companyOptionsLoaded.value) { |
| | | return |
| | | } |
| | | |
| | | if (companyOptionsLoading.value) { |
| | | await companyOptionsLoading.value |
| | | return |
| | | } |
| | | |
| | | companyOptionsLoading.value = (async () => { |
| | | const records = await guardRequestWithMessage(fetchCompanysList(), [], { |
| | | timeoutMessage: t('pages.basicInfo.warehouseAreas.messages.companyOptionsTimeout') |
| | | }) |
| | | const normalizedRecords = defaultResponseAdapter(records).records |
| | | shipperOptions.value = normalizedRecords |
| | | .filter((item) => item.type === 'shipper') |
| | | .map((item) => ({ |
| | | label: item.name || item.code || `${t('pages.basicInfo.warehouseAreas.table.shipperName')} ${item.id}`, |
| | | value: item.id |
| | | })) |
| | | supplierOptions.value = normalizedRecords |
| | | .filter((item) => item.type === 'supplier') |
| | | .map((item) => ({ |
| | | label: item.name || item.code || `${t('pages.basicInfo.warehouseAreas.table.supplierName')} ${item.id}`, |
| | | value: item.id |
| | | })) |
| | | companyOptionsLoaded.value = true |
| | | })() |
| | | |
| | | try { |
| | | await companyOptionsLoading.value |
| | | } finally { |
| | | companyOptionsLoading.value = null |
| | | } |
| | | } |
| | | |
| | | async function loadCompanyOptions() { |
| | | const records = await guardRequestWithMessage(fetchCompanysList(), [], { |
| | | timeoutMessage: '往来企业选项加载超时,已停止等待' |
| | | async function loadWarehouseOptions() { |
| | | const records = await guardRequestWithMessage(fetchWarehouseList(), [], { |
| | | timeoutMessage: t('pages.basicInfo.warehouseAreas.messages.warehouseOptionsTimeout') |
| | | }) |
| | | const normalizedRecords = defaultResponseAdapter(records).records |
| | | shipperOptions.value = normalizedRecords |
| | | .filter((item) => item.type === 'shipper') |
| | | .map((item) => ({ |
| | | label: item.name || item.code || `货主 ${item.id}`, |
| | | value: item.id |
| | | })) |
| | | supplierOptions.value = normalizedRecords |
| | | .filter((item) => item.type === 'supplier') |
| | | .map((item) => ({ |
| | | label: item.name || item.code || `供应商 ${item.id}`, |
| | | value: item.id |
| | | })) |
| | | warehouseOptions.value = defaultResponseAdapter(records).records.map((item) => ({ |
| | | label: item.name || item.code || `${t('pages.basicInfo.warehouseAreas.table.warehouseName')} ${item.id}`, |
| | | value: item.id |
| | | })) |
| | | } |
| | | |
| | | async function loadTypeOptions() { |
| | |
| | | status: 1 |
| | | }), |
| | | { records: [] }, |
| | | { timeoutMessage: '业务类型加载超时,已停止等待' } |
| | | { timeoutMessage: t('pages.basicInfo.warehouseAreas.messages.typeOptionsTimeout') } |
| | | ) |
| | | typeOptions.value = defaultResponseAdapter(response).records.map((item) => ({ |
| | | label: item.label || item.name || item.value, |
| | |
| | | } |
| | | |
| | | onMounted(async () => { |
| | | await Promise.all([loadWarehouseOptions(), loadCompanyOptions(), loadTypeOptions(), getData()]) |
| | | await Promise.all([loadWarehouseOptions(), loadTypeOptions(), getData()]) |
| | | }) |
| | | </script> |