zhou zhou
14 小时以前 0d93ec4c10d146ffe287e7f4430ee66ad5832a17
rsf-design/src/views/basic-info/bas-station/index.vue
@@ -13,6 +13,7 @@
        <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"
@@ -68,6 +69,15 @@
        :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>
@@ -96,11 +106,14 @@
  } 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,
@@ -129,6 +142,8 @@
  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
@@ -207,6 +222,24 @@
      }
    },
    {
      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',
@@ -226,12 +259,40 @@
      }
    },
    {
      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
      }
    },
    {
@@ -301,10 +362,18 @@
    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 = {}
@@ -316,39 +385,86 @@
  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,
@@ -394,30 +510,39 @@
      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
    })
  )
@@ -429,6 +554,47 @@
  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() {
@@ -449,7 +615,9 @@
      { records: [] },
      { timeoutMessage: '容器类型加载超时,已停止等待' }
    )
    containerTypeOptions.value = buildBasStationContainerTypeOptions(defaultResponseAdapter(response).records)
    containerTypeOptions.value = buildBasStationContainerTypeOptions(
      defaultResponseAdapter(response).records
    )
  }
  async function loadUseStatusOptions() {
@@ -463,7 +631,9 @@
      { records: [] },
      { timeoutMessage: '使用状态加载超时,已停止等待' }
    )
    useStatusOptions.value = buildBasStationUseStatusOptions(defaultResponseAdapter(response).records)
    useStatusOptions.value = buildBasStationUseStatusOptions(
      defaultResponseAdapter(response).records
    )
  }
  onMounted(async () => {