| | |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesWmSnApi } from '#/api/mes/wm/sn'; |
| | | |
| | | import { ref } from 'vue'; |
| | | |
| | | import { Page, useVbenModal } from '@vben/common-ui'; |
| | | import { downloadFileFromBlobPart } from '@vben/utils'; |
| | | |
| | | import { message } from 'ant-design-vue'; |
| | | import { message, Tabs, Tag } from 'ant-design-vue'; |
| | | |
| | | import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; |
| | | import { |
| | |
| | | exportSnDetailExcel, |
| | | exportSnGroupExcel, |
| | | getSnGroupPage, |
| | | getSnInStockPage, |
| | | } from '#/api/mes/wm/sn'; |
| | | import { $t } from '#/locales'; |
| | | |
| | | import { useGridColumns, useGridFormSchema } from './data'; |
| | | import { |
| | | useGridColumns, |
| | | useGridFormSchema, |
| | | useInStockGridColumns, |
| | | useInStockGridFormSchema, |
| | | } from './data'; |
| | | import { |
| | | formatWmLocation, |
| | | getWmLocationMaps, |
| | | type WmLocationMaps, |
| | | } from './location-maps'; |
| | | import Detail from './modules/detail.vue'; |
| | | import Form from './modules/form.vue'; |
| | | import InStockModal from './modules/in-stock-modal.vue'; |
| | | import OutStockModal from './modules/out-stock-modal.vue'; |
| | | import SnDetailModal from './modules/sn-detail-modal.vue'; |
| | | |
| | | const activeKey = ref('group'); |
| | | |
| | | const [FormModal, formModalApi] = useVbenModal({ |
| | | connectedComponent: Form, |
| | |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | | /** 刷新表格 */ |
| | | const [InStockModalRef, inStockModalApi] = useVbenModal({ |
| | | connectedComponent: InStockModal, |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | | const [OutStockModalRef, outStockModalApi] = useVbenModal({ |
| | | connectedComponent: OutStockModal, |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | | const snDetailModalRef = ref<InstanceType<typeof SnDetailModal>>(); |
| | | |
| | | /** 刷新当前页签 */ |
| | | function handleRefresh() { |
| | | gridApi.query(); |
| | | if (activeKey.value === 'group') { |
| | | gridApi.query(); |
| | | } else { |
| | | inStockGridApi.query(); |
| | | } |
| | | } |
| | | |
| | | /** 生成 SN 码 */ |
| | |
| | | } |
| | | } |
| | | |
| | | /** 入库登记 */ |
| | | function handleInStock() { |
| | | inStockModalApi.open(); |
| | | } |
| | | |
| | | /** 出库核销 */ |
| | | function handleOutStock() { |
| | | outStockModalApi.open(); |
| | | } |
| | | |
| | | /** 查看单件详情 */ |
| | | function handleSnDetail(row: MesWmSnApi.Sn) { |
| | | snDetailModalRef.value?.open(row.code); |
| | | } |
| | | |
| | | /** 在库单件列表位置名称映射(懒加载,首次访问时初始化) */ |
| | | const locationMapsRef = ref<Awaited<ReturnType<typeof getWmLocationMaps>>>(); |
| | | const EMPTY_MAPS: WmLocationMaps = { |
| | | warehouseNameMap: {}, |
| | | locationNameMap: {}, |
| | | areaNameMap: {}, |
| | | }; |
| | | async function ensureLocationMaps() { |
| | | if (!locationMapsRef.value) { |
| | | locationMapsRef.value = await getWmLocationMaps(); |
| | | } |
| | | } |
| | | |
| | | const [Grid, gridApi] = useVbenVxeGrid({ |
| | | formOptions: { |
| | | schema: useGridFormSchema(), |
| | |
| | | }, |
| | | } as VxeTableGridOptions<MesWmSnApi.SnGroup>, |
| | | }); |
| | | |
| | | const [InStockGrid, inStockGridApi] = useVbenVxeGrid({ |
| | | formOptions: { |
| | | schema: useInStockGridFormSchema(), |
| | | }, |
| | | gridOptions: { |
| | | columns: useInStockGridColumns(), |
| | | height: 'auto', |
| | | keepSource: true, |
| | | proxyConfig: { |
| | | ajax: { |
| | | query: async ({ page }, formValues) => { |
| | | return await getSnInStockPage({ |
| | | pageNo: page.currentPage, |
| | | pageSize: page.pageSize, |
| | | ...formValues, |
| | | }); |
| | | }, |
| | | }, |
| | | }, |
| | | rowConfig: { |
| | | keyField: 'id', |
| | | isHover: true, |
| | | }, |
| | | toolbarConfig: { |
| | | refresh: true, |
| | | search: true, |
| | | }, |
| | | } as VxeTableGridOptions<MesWmSnApi.Sn>, |
| | | }); |
| | | |
| | | // 首次挂载时预热位置名称映射,供列表展示 |
| | | void ensureLocationMaps(); |
| | | </script> |
| | | |
| | | <template> |
| | | <Page auto-content-height><FormModal @success="handleRefresh" /> |
| | | <Page auto-content-height> |
| | | <FormModal @success="handleRefresh" /> |
| | | <DetailModal /> |
| | | <InStockModalRef @success="handleRefresh" /> |
| | | <OutStockModalRef @success="handleRefresh" /> |
| | | <SnDetailModal ref="snDetailModalRef" /> |
| | | |
| | | <Grid table-title="SN 码列表"> |
| | | <template #toolbar-tools> |
| | | <TableAction |
| | | :actions="[ |
| | | { |
| | | label: '生成 SN 码', |
| | | type: 'primary', |
| | | icon: ACTION_ICON.ADD, |
| | | auth: ['mes:wm-sn:create'], |
| | | onClick: handleCreate, |
| | | }, |
| | | { |
| | | label: $t('ui.actionTitle.export'), |
| | | type: 'primary', |
| | | icon: ACTION_ICON.DOWNLOAD, |
| | | auth: ['mes:wm-sn:export'], |
| | | onClick: handleExport, |
| | | }, |
| | | ]" |
| | | /> |
| | | </template> |
| | | <template #count="{ row }"> |
| | | <TableAction |
| | | :actions="[ |
| | | { |
| | | label: `${row.count ?? 0}`, |
| | | type: 'link', |
| | | auth: ['mes:wm-sn:query'], |
| | | onClick: handleDetail.bind(null, row), |
| | | }, |
| | | ]" |
| | | /> |
| | | </template> |
| | | <template #actions="{ row }"> |
| | | <TableAction |
| | | :actions="[ |
| | | { |
| | | label: '查看明细', |
| | | type: 'link', |
| | | auth: ['mes:wm-sn:query'], |
| | | onClick: handleDetail.bind(null, row), |
| | | }, |
| | | { |
| | | label: '导出明细', |
| | | type: 'link', |
| | | auth: ['mes:wm-sn:export'], |
| | | onClick: handleExportDetail.bind(null, row), |
| | | }, |
| | | { |
| | | label: $t('common.delete'), |
| | | type: 'link', |
| | | danger: true, |
| | | auth: ['mes:wm-sn:delete'], |
| | | popConfirm: { |
| | | title: $t('ui.actionMessage.deleteConfirm', [ |
| | | row.batchCode || row.itemName, |
| | | ]), |
| | | confirm: handleDelete.bind(null, row), |
| | | }, |
| | | }, |
| | | ]" |
| | | /> |
| | | </template> |
| | | </Grid> |
| | | <Tabs v-model:active-key="activeKey" class="px-4 pt-1" type="card"> |
| | | <Tabs.TabPane key="group" tab="SN 码分组"> |
| | | <Grid table-title="SN 码列表"> |
| | | <template #toolbar-tools> |
| | | <TableAction |
| | | :actions="[ |
| | | { |
| | | label: '生成 SN 码', |
| | | type: 'primary', |
| | | icon: ACTION_ICON.ADD, |
| | | auth: ['mes:wm-sn:create'], |
| | | onClick: handleCreate, |
| | | }, |
| | | { |
| | | label: $t('ui.actionTitle.export'), |
| | | type: 'primary', |
| | | icon: ACTION_ICON.DOWNLOAD, |
| | | auth: ['mes:wm-sn:export'], |
| | | onClick: handleExport, |
| | | }, |
| | | ]" |
| | | /> |
| | | </template> |
| | | <template #count="{ row }"> |
| | | <TableAction |
| | | :actions="[ |
| | | { |
| | | label: `${row.count ?? 0}`, |
| | | type: 'link', |
| | | auth: ['mes:wm-sn:query'], |
| | | onClick: handleDetail.bind(null, row), |
| | | }, |
| | | ]" |
| | | /> |
| | | </template> |
| | | <template #actions="{ row }"> |
| | | <TableAction |
| | | :actions="[ |
| | | { |
| | | label: '查看明细', |
| | | type: 'link', |
| | | auth: ['mes:wm-sn:query'], |
| | | onClick: handleDetail.bind(null, row), |
| | | }, |
| | | { |
| | | label: '导出明细', |
| | | type: 'link', |
| | | auth: ['mes:wm-sn:export'], |
| | | onClick: handleExportDetail.bind(null, row), |
| | | }, |
| | | { |
| | | label: $t('common.delete'), |
| | | type: 'link', |
| | | danger: true, |
| | | auth: ['mes:wm-sn:delete'], |
| | | popConfirm: { |
| | | title: $t('ui.actionMessage.deleteConfirm', [ |
| | | row.batchCode || row.itemName, |
| | | ]), |
| | | confirm: handleDelete.bind(null, row), |
| | | }, |
| | | }, |
| | | ]" |
| | | /> |
| | | </template> |
| | | </Grid> |
| | | </Tabs.TabPane> |
| | | <Tabs.TabPane key="in-stock" tab="在库单件"> |
| | | <InStockGrid table-title="SN 单件状态列表"> |
| | | <template #toolbar-tools> |
| | | <TableAction |
| | | :actions="[ |
| | | { |
| | | label: '入库登记', |
| | | type: 'primary', |
| | | icon: ACTION_ICON.ADD, |
| | | auth: ['mes:wm-sn:update'], |
| | | onClick: handleInStock, |
| | | }, |
| | | { |
| | | label: '出库核销', |
| | | type: 'primary', |
| | | danger: true, |
| | | icon: ACTION_ICON.DELETE, |
| | | auth: ['mes:wm-sn:update'], |
| | | onClick: handleOutStock, |
| | | }, |
| | | ]" |
| | | /> |
| | | </template> |
| | | <template #status="{ row }"> |
| | | <Tag :color="row.status === 1 ? 'green' : 'orange'"> |
| | | {{ row.status === 1 ? '在库' : '已出库' }} |
| | | </Tag> |
| | | </template> |
| | | <template #locations="{ row }"> |
| | | <span v-if="row.status === 1"> |
| | | {{ |
| | | formatWmLocation( |
| | | locationMapsRef ?? EMPTY_MAPS, |
| | | row.warehouseId, |
| | | row.locationId, |
| | | row.areaId, |
| | | ) |
| | | }} |
| | | </span> |
| | | <span v-else>-</span> |
| | | </template> |
| | | <template #actions="{ row }"> |
| | | <TableAction |
| | | :actions="[ |
| | | { |
| | | label: '详情', |
| | | type: 'link', |
| | | auth: ['mes:wm-sn:query'], |
| | | onClick: handleSnDetail.bind(null, row), |
| | | }, |
| | | ]" |
| | | /> |
| | | </template> |
| | | </InStockGrid> |
| | | </Tabs.TabPane> |
| | | </Tabs> |
| | | </Page> |
| | | </template> |
| | | </template> |