| | |
| | | <ElCard class="wh-mat-page__sidebar-card"> |
| | | <div class="mb-3 flex items-center justify-between gap-3"> |
| | | <div> |
| | | <div class="text-base font-medium text-[var(--art-text-primary)]">物料分组</div> |
| | | <div class="text-base font-medium text-[var(--art-text-primary)]">{{ t('pages.basicInfo.whMat.title') }}</div> |
| | | <div class="text-xs text-[var(--art-text-secondary)]"> |
| | | {{ selectedGroupLabel }} |
| | | </div> |
| | | </div> |
| | | <ElButton text @click="handleResetGroup">全部</ElButton> |
| | | <ElButton text @click="handleResetGroup">{{ t('common.actions.viewAll') }}</ElButton> |
| | | </div> |
| | | |
| | | <div class="mb-3 flex items-center gap-2"> |
| | | <ElInput |
| | | v-model.trim="groupSearch" |
| | | clearable |
| | | placeholder="搜索物料分组" |
| | | :placeholder="t('pages.basicInfo.whMat.search.groupKeywordPlaceholder')" |
| | | @clear="handleGroupSearch" |
| | | @keyup.enter="handleGroupSearch" |
| | | /> |
| | | <ElButton @click="handleGroupSearch">搜索</ElButton> |
| | | <ElButton @click="handleGroupSearch">{{ t('common.actions.search') }}</ElButton> |
| | | </div> |
| | | |
| | | <ElScrollbar class="wh-mat-page__tree-scroll pr-1"> |
| | | <div v-if="groupTreeLoading" class="py-6"> |
| | | <ElSkeleton :rows="10" animated /> |
| | | </div> |
| | | <ElEmpty v-else-if="!groupTreeData.length" description="暂无物料分组" /> |
| | | <ElEmpty v-else-if="!groupTreeData.length" :description="t('pages.basicInfo.whMat.messages.emptyGroups')" /> |
| | | <ElTree |
| | | v-else |
| | | :data="groupTreeData" |
| | |
| | | > |
| | | <template #default="{ data }"> |
| | | <div class="flex items-center gap-2"> |
| | | <span class="font-medium">{{ data.name || '--' }}</span> |
| | | <span class="text-xs text-[var(--art-text-secondary)]">{{ data.code || '--' }}</span> |
| | | <span class="font-medium">{{ data.name || t('common.placeholder.empty') }}</span> |
| | | <span class="text-xs text-[var(--art-text-secondary)]">{{ data.code || t('common.placeholder.empty') }}</span> |
| | | </div> |
| | | </template> |
| | | </ElTree> |
| | |
| | | <script setup> |
| | | import { ElMessage } from 'element-plus' |
| | | import { computed, onMounted, reactive, ref } from 'vue' |
| | | import { useI18n } from 'vue-i18n' |
| | | import ArtButtonTable from '@/components/core/forms/art-button-table/index.vue' |
| | | import { useTableColumns } from '@/hooks/core/useTableColumns' |
| | | import { guardRequestWithMessage } from '@/utils/sys/requestGuard' |
| | |
| | | } from './whMatPage.helpers' |
| | | |
| | | defineOptions({ name: 'WhMat' }) |
| | | const { t } = useI18n() |
| | | |
| | | const loading = ref(false) |
| | | const groupTreeLoading = ref(false) |
| | |
| | | |
| | | const searchItems = computed(() => [ |
| | | { |
| | | label: '关键字', |
| | | label: t('pages.basicInfo.whMat.search.condition'), |
| | | key: 'condition', |
| | | type: 'input', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: '请输入物料编码/物料名称' |
| | | placeholder: t('pages.basicInfo.whMat.search.conditionPlaceholder') |
| | | } |
| | | }, |
| | | { |
| | | label: '物料编码', |
| | | label: t('pages.basicInfo.whMat.search.code'), |
| | | key: 'code', |
| | | type: 'input', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: '请输入物料编码' |
| | | placeholder: t('pages.basicInfo.whMat.search.codePlaceholder') |
| | | } |
| | | }, |
| | | { |
| | | label: '物料名称', |
| | | label: t('pages.basicInfo.whMat.search.name'), |
| | | key: 'name', |
| | | type: 'input', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: '请输入物料名称' |
| | | placeholder: t('pages.basicInfo.whMat.search.namePlaceholder') |
| | | } |
| | | }, |
| | | { |
| | | label: '规格', |
| | | label: t('pages.basicInfo.whMat.search.spec'), |
| | | key: 'spec', |
| | | type: 'input', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: '请输入规格' |
| | | placeholder: t('pages.basicInfo.whMat.search.specPlaceholder') |
| | | } |
| | | }, |
| | | { |
| | | label: '条码', |
| | | label: t('pages.basicInfo.whMat.search.barcode'), |
| | | key: 'barcode', |
| | | type: 'input', |
| | | props: { |
| | | clearable: true, |
| | | placeholder: '请输入条码' |
| | | placeholder: t('pages.basicInfo.whMat.search.barcodePlaceholder') |
| | | } |
| | | } |
| | | ]) |
| | | |
| | | const { columnChecks, columns } = useTableColumns(() => |
| | | createWhMatTableColumns({ |
| | | t, |
| | | handleViewDetail: openDetailDrawer |
| | | }) |
| | | ) |
| | | |
| | | const selectedGroupLabel = computed(() => { |
| | | if (!selectedGroupId.value) { |
| | | return '全部物料' |
| | | return t('pages.basicInfo.whMat.labels.allMaterials') |
| | | } |
| | | const found = findGroupNode(groupTreeData.value, selectedGroupId.value) |
| | | return found ? getWhMatTreeNodeLabel(found) : '全部物料' |
| | | return found ? getWhMatTreeNodeLabel(found) : t('pages.basicInfo.whMat.labels.allMaterials') |
| | | }) |
| | | |
| | | function findGroupNode(nodes, targetId) { |
| | |
| | | const records = await guardRequestWithMessage( |
| | | fetchMatnrGroupTree(buildMatnrGroupTreeQueryParams({ condition: groupSearch.value })), |
| | | [], |
| | | { timeoutMessage: '物料分组加载超时,已停止等待' } |
| | | { timeoutMessage: t('pages.basicInfo.whMat.messages.groupTimeout') } |
| | | ) |
| | | const normalizedTree = normalizeMatnrGroupTreeRows(Array.isArray(records) ? records : []) |
| | | const normalizedTree = normalizeMatnrGroupTreeRows(Array.isArray(records) ? records : [], t) |
| | | groupTreeData.value = normalizedTree |
| | | if (selectedGroupId.value && !findGroupNode(normalizedTree, selectedGroupId.value)) { |
| | | selectedGroupId.value = null |
| | | } |
| | | } catch (error) { |
| | | groupTreeData.value = [] |
| | | ElMessage.error(error?.message || '物料分组加载失败') |
| | | ElMessage.error(error?.message || t('pages.basicInfo.whMat.messages.groupLoadFailed')) |
| | | } finally { |
| | | groupTreeLoading.value = false |
| | | } |
| | |
| | | current: pagination.current, |
| | | size: pagination.size |
| | | }, |
| | | { timeoutMessage: '物料列表加载超时,已停止等待' } |
| | | { timeoutMessage: t('pages.basicInfo.whMat.messages.listTimeout') } |
| | | ) |
| | | tableData.value = Array.isArray(response?.records) |
| | | ? response.records.map((record) => normalizeMatnrRow(record)) |
| | | ? response.records.map((record) => normalizeMatnrRow(record, t)) |
| | | : [] |
| | | updatePaginationState(pagination, response, pagination.current, pagination.size) |
| | | } catch (error) { |
| | | tableData.value = [] |
| | | ElMessage.error(error?.message || '物料列表加载失败') |
| | | ElMessage.error(error?.message || t('pages.basicInfo.whMat.messages.listLoadFailed')) |
| | | } finally { |
| | | loading.value = false |
| | | } |
| | |
| | | try { |
| | | detailData.value = normalizeMatnrDetail( |
| | | await guardRequestWithMessage(fetchMatnrDetail(row.id), {}, { |
| | | timeoutMessage: '物料详情加载超时,已停止等待' |
| | | }) |
| | | timeoutMessage: t('pages.basicInfo.whMat.messages.detailTimeout') |
| | | }), |
| | | t |
| | | ) |
| | | } catch (error) { |
| | | detailDrawerVisible.value = false |
| | | detailData.value = {} |
| | | ElMessage.error(error?.message || '获取物料详情失败') |
| | | ElMessage.error(error?.message || t('pages.basicInfo.whMat.messages.detailLoadFailed')) |
| | | } finally { |
| | | detailLoading.value = false |
| | | } |