| | |
| | | <template #left> |
| | | <ElSpace wrap> |
| | | <ElButton v-auth="'add'" @click="showDialog('add')" v-ripple>新增站点</ElButton> |
| | | <ElButton v-auth="'add'" @click="openInitDialog()" v-ripple>站点初始化</ElButton> |
| | | <ElButton |
| | | v-auth="'delete'" |
| | | type="danger" |
| | |
| | | :resolve-area-label="resolveAreaLabel" |
| | | :resolve-container-type-label="resolveContainerTypeLabel" |
| | | /> |
| | | |
| | | <BasStationInitDialog |
| | | v-model:visible="initDialogVisible" |
| | | :initial-data="currentInitData" |
| | | :area-options="areaOptions" |
| | | :container-type-options="containerTypeOptions" |
| | | :use-status-options="useStatusOptions" |
| | | @submit="handleInitSubmit" |
| | | /> |
| | | </ElCard> |
| | | </div> |
| | | </template> |
| | |
| | | } from '@/api/bas-station' |
| | | import BasStationDialog from './modules/bas-station-dialog.vue' |
| | | import BasStationDetailDrawer from './modules/bas-station-detail-drawer.vue' |
| | | import BasStationInitDialog from './modules/bas-station-init-dialog.vue' |
| | | import { createBasStationTableColumns } from './basStationTable.columns' |
| | | import { |
| | | BAS_STATION_REPORT_STYLE, |
| | | BAS_STATION_REPORT_TITLE, |
| | | buildBasStationDialogModel, |
| | | buildBasStationInitModel, |
| | | buildBasStationInitPayloadList, |
| | | buildBasStationPageQueryParams, |
| | | buildBasStationPrintRows, |
| | | buildBasStationReportMeta, |
| | |
| | | const detailDrawerVisible = ref(false) |
| | | const detailLoading = ref(false) |
| | | const detailData = ref({}) |
| | | const initDialogVisible = ref(false) |
| | | const currentInitData = ref(buildBasStationInitModel()) |
| | | let handleDeleteAction = null |
| | | |
| | | const reportTitle = BAS_STATION_REPORT_TITLE |
| | |
| | | } |
| | | }, |
| | | { |
| | | label: '可入', |
| | | key: 'inAble', |
| | | type: 'select', |
| | | props: { |
| | | clearable: true, |
| | | options: getBasStationBooleanOptions() |
| | | } |
| | | }, |
| | | { |
| | | label: '可出', |
| | | key: 'outAble', |
| | | type: 'select', |
| | | props: { |
| | | clearable: true, |
| | | options: getBasStationBooleanOptions() |
| | | } |
| | | }, |
| | | { |
| | | label: '所属库区', |
| | | key: 'area', |
| | | type: 'select', |
| | |
| | | } |
| | | }, |
| | | { |
| | | label: '可跨区库区', |
| | | key: 'crossZoneArea', |
| | | type: 'input', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: '请输入可跨区库区' |
| | | } |
| | | }, |
| | | { |
| | | label: '是否WCS', |
| | | key: 'isWcs', |
| | | type: 'select', |
| | | props: { |
| | | clearable: true, |
| | | options: getBasStationBooleanOptions() |
| | | } |
| | | }, |
| | | { |
| | | label: 'WCS数据', |
| | | key: 'wcsData', |
| | | type: 'input', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: '请输入WCS数据' |
| | | } |
| | | }, |
| | | { |
| | | label: '容器类型', |
| | | key: 'containerType', |
| | | type: 'select', |
| | | props: { |
| | | clearable: true, |
| | | filterable: true, |
| | | options: containerTypeOptions.value |
| | | } |
| | | }, |
| | | { |
| | |
| | | detailDrawerVisible.value = true |
| | | detailLoading.value = true |
| | | try { |
| | | const detail = await guardRequestWithMessage(fetchGetBasStationDetail(row.id), {}, { |
| | | timeoutMessage: '站点详情加载超时,已停止等待' |
| | | }) |
| | | detailData.value = normalizeBasStationDetailRecord(detail, resolveAreaLabel, resolveContainerTypeLabel) |
| | | const detail = await guardRequestWithMessage( |
| | | fetchGetBasStationDetail(row.id), |
| | | {}, |
| | | { |
| | | timeoutMessage: '站点详情加载超时,已停止等待' |
| | | } |
| | | ) |
| | | detailData.value = normalizeBasStationDetailRecord( |
| | | detail, |
| | | resolveAreaLabel, |
| | | resolveContainerTypeLabel |
| | | ) |
| | | } catch (error) { |
| | | detailDrawerVisible.value = false |
| | | detailData.value = {} |
| | |
| | | |
| | | async function openEditDialog(row) { |
| | | try { |
| | | const detail = await guardRequestWithMessage(fetchGetBasStationDetail(row.id), {}, { |
| | | timeoutMessage: '站点详情加载超时,已停止等待' |
| | | }) |
| | | const detail = await guardRequestWithMessage( |
| | | fetchGetBasStationDetail(row.id), |
| | | {}, |
| | | { |
| | | timeoutMessage: '站点详情加载超时,已停止等待' |
| | | } |
| | | ) |
| | | showDialog('edit', detail) |
| | | } catch (error) { |
| | | ElMessage.error(error?.message || '获取站点详情失败') |
| | | } |
| | | } |
| | | |
| | | const { columns, columnChecks, data, loading, pagination, getData, replaceSearchParams, resetSearchParams, handleSizeChange, handleCurrentChange, refreshData, refreshCreate, refreshUpdate, refreshRemove } = |
| | | useTable({ |
| | | core: { |
| | | apiFn: fetchBasStationPage, |
| | | apiParams: buildBasStationPageQueryParams(searchForm.value), |
| | | paginationKey: getBasStationPaginationKey(), |
| | | columnsFactory: () => |
| | | createBasStationTableColumns({ |
| | | handleView: openDetail, |
| | | handleEdit: hasAuth('update') ? openEditDialog : null, |
| | | handleDelete: hasAuth('delete') ? (row) => handleDeleteAction?.(row) : null, |
| | | canEdit: hasAuth('update'), |
| | | canDelete: hasAuth('delete') |
| | | }) |
| | | }, |
| | | transform: { |
| | | dataTransformer: (records) => { |
| | | if (!Array.isArray(records)) { |
| | | return [] |
| | | } |
| | | return records.map((item) => normalizeBasStationListRow(item, resolveAreaLabel, resolveContainerTypeLabel)) |
| | | function createInitRecordFromRow(row) { |
| | | return buildBasStationInitModel({ |
| | | type: row.type ?? 0, |
| | | useStatus: row.useStatus || row.useStatusText || '', |
| | | areaIds: Array.isArray(row.areaIds) |
| | | ? row.areaIds.map((item) => |
| | | typeof item === 'object' ? (item.id ?? item.areaId ?? item.value) : item |
| | | ) |
| | | : [], |
| | | containerTypes: Array.isArray(row.containerTypes) ? [...row.containerTypes] : [], |
| | | inAble: row.inAble ?? 0, |
| | | outAble: row.outAble ?? 0, |
| | | rows: [ |
| | | { |
| | | stationName: row.stationName || '', |
| | | stationId: row.stationId || '' |
| | | } |
| | | } |
| | | ] |
| | | }) |
| | | } |
| | | |
| | | function openInitDialog(record = null) { |
| | | currentInitData.value = record ? createInitRecordFromRow(record) : buildBasStationInitModel() |
| | | initDialogVisible.value = true |
| | | } |
| | | |
| | | const { |
| | | columns, |
| | | columnChecks, |
| | | data, |
| | | loading, |
| | | pagination, |
| | | getData, |
| | | replaceSearchParams, |
| | | resetSearchParams, |
| | | handleSizeChange, |
| | | handleCurrentChange, |
| | | refreshData, |
| | | refreshCreate, |
| | | refreshUpdate, |
| | | refreshRemove |
| | | } = useTable({ |
| | | core: { |
| | | apiFn: fetchBasStationPage, |
| | | apiParams: buildBasStationPageQueryParams(searchForm.value), |
| | | paginationKey: getBasStationPaginationKey(), |
| | | columnsFactory: () => |
| | | createBasStationTableColumns({ |
| | | handleView: openDetail, |
| | | handleCopy: hasAuth('add') ? openInitDialog : null, |
| | | handleEdit: hasAuth('update') ? openEditDialog : null, |
| | | handleDelete: hasAuth('delete') ? (row) => handleDeleteAction?.(row) : null, |
| | | canEdit: hasAuth('update'), |
| | | canDelete: hasAuth('delete') |
| | | }) |
| | | }, |
| | | transform: { |
| | | dataTransformer: (records) => { |
| | | if (!Array.isArray(records)) { |
| | | return [] |
| | | } |
| | | return records.map((item) => |
| | | normalizeBasStationListRow(item, resolveAreaLabel, resolveContainerTypeLabel) |
| | | ) |
| | | } |
| | | } |
| | | }) |
| | | |
| | | const { |
| | | dialogVisible, |
| | |
| | | await fetchBasStationPage({ |
| | | ...reportQueryParams.value, |
| | | current: 1, |
| | | pageSize: Number(pagination.total) > 0 ? Number(pagination.total) : Number(payload?.pageSize) || 20 |
| | | pageSize: |
| | | Number(pagination.total) > 0 ? Number(pagination.total) : Number(payload?.pageSize) || 20 |
| | | }) |
| | | ).records |
| | | } |
| | | |
| | | const { previewVisible, previewRows, previewMeta, handlePreviewVisibleChange, handleExport, handlePrint } = |
| | | usePrintExportPage({ |
| | | downloadFileName: 'bas-station.xlsx', |
| | | requestExport: (payload) => |
| | | fetchExportBasStationReport(payload, { |
| | | headers: { |
| | | Authorization: userStore.accessToken || '' |
| | | } |
| | | }), |
| | | resolvePrintRecords, |
| | | buildPreviewRows: (records) => buildBasStationPrintRows(records, resolveAreaLabel, resolveContainerTypeLabel), |
| | | buildPreviewMeta |
| | | }) |
| | | const { |
| | | previewVisible, |
| | | previewRows, |
| | | previewMeta, |
| | | handlePreviewVisibleChange, |
| | | handleExport, |
| | | handlePrint |
| | | } = usePrintExportPage({ |
| | | downloadFileName: 'bas-station.xlsx', |
| | | requestExport: (payload) => |
| | | fetchExportBasStationReport(payload, { |
| | | headers: { |
| | | Authorization: userStore.accessToken || '' |
| | | } |
| | | }), |
| | | resolvePrintRecords, |
| | | buildPreviewRows: (records) => |
| | | buildBasStationPrintRows(records, resolveAreaLabel, resolveContainerTypeLabel), |
| | | buildPreviewMeta |
| | | }) |
| | | |
| | | const resolvedPreviewMeta = computed(() => |
| | | buildBasStationReportMeta({ |
| | | previewMeta: previewMeta.value, |
| | | count: previewRows.value.length, |
| | | orientation: previewMeta.value?.reportStyle?.orientation || BAS_STATION_REPORT_STYLE.orientation |
| | | orientation: |
| | | previewMeta.value?.reportStyle?.orientation || BAS_STATION_REPORT_STYLE.orientation |
| | | }) |
| | | ) |
| | | |
| | |
| | | function handleReset() { |
| | | Object.assign(searchForm.value, createBasStationSearchState()) |
| | | resetSearchParams() |
| | | } |
| | | |
| | | async function handleInitSubmit(formData) { |
| | | const payloads = buildBasStationInitPayloadList(formData) |
| | | if (!payloads.length) { |
| | | ElMessage.error('请至少填写一组站点编码和站点名称') |
| | | return |
| | | } |
| | | |
| | | let successCount = 0 |
| | | let failCount = 0 |
| | | let firstErrorMessage = '' |
| | | |
| | | for (const payload of payloads) { |
| | | try { |
| | | await fetchSaveBasStation(payload) |
| | | successCount += 1 |
| | | } catch (error) { |
| | | failCount += 1 |
| | | if (!firstErrorMessage) { |
| | | firstErrorMessage = error?.message || `${payload.stationName} 初始化失败` |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (successCount > 0) { |
| | | ElMessage.success( |
| | | failCount > 0 |
| | | ? `成功保存 ${successCount} 条,失败 ${failCount} 条` |
| | | : `成功保存 ${successCount} 条` |
| | | ) |
| | | initDialogVisible.value = false |
| | | currentInitData.value = buildBasStationInitModel() |
| | | await refreshCreate() |
| | | if (failCount > 0 && firstErrorMessage) { |
| | | ElMessage.warning(firstErrorMessage) |
| | | } |
| | | return |
| | | } |
| | | |
| | | ElMessage.error(firstErrorMessage || '站点初始化失败') |
| | | } |
| | | |
| | | async function loadAreaOptions() { |
| | |
| | | { records: [] }, |
| | | { timeoutMessage: '容器类型加载超时,已停止等待' } |
| | | ) |
| | | containerTypeOptions.value = buildBasStationContainerTypeOptions(defaultResponseAdapter(response).records) |
| | | containerTypeOptions.value = buildBasStationContainerTypeOptions( |
| | | defaultResponseAdapter(response).records |
| | | ) |
| | | } |
| | | |
| | | async function loadUseStatusOptions() { |
| | |
| | | { records: [] }, |
| | | { timeoutMessage: '使用状态加载超时,已停止等待' } |
| | | ) |
| | | useStatusOptions.value = buildBasStationUseStatusOptions(defaultResponseAdapter(response).records) |
| | | useStatusOptions.value = buildBasStationUseStatusOptions( |
| | | defaultResponseAdapter(response).records |
| | | ) |
| | | } |
| | | |
| | | onMounted(async () => { |