| | |
| | | import { MesProBatchStatusEnum } from "@vben/constants"; |
| | | import { downloadFileFromBlobPart } from "@vben/utils"; |
| | | |
| | | import { Button, message } from "ant-design-vue"; |
| | | import { Button, message, Modal, Tag } from "ant-design-vue"; |
| | | |
| | | import { ACTION_ICON, TableAction, useVbenVxeGrid } from "#/adapter/vxe-table"; |
| | | import { |
| | | deleteBatch, |
| | | exportBatchExcel, |
| | | exportBatchQr, |
| | | exportBatchBusinessQr, |
| | | generateBatchBusinessCodes, |
| | | getBatchPage, |
| | | updateBatchStatus, |
| | | } from "#/api/mes/pro/batch"; |
| | | import { IconifyIcon } from "@vben/icons"; |
| | | import { $t } from "#/locales"; |
| | | |
| | | import { useGridColumns, useGridFormSchema } from "./data"; |
| | | import Form from "./modules/form.vue"; |
| | | import PreGenerateModal from "./modules/pre-generate.vue"; |
| | | import QrTraceModal from "../components/qr-trace-modal.vue"; |
| | | import BusinessQrModal from "../components/business-qr.vue"; |
| | | |
| | | const [FormModal, formModalApi] = useVbenModal({ |
| | | connectedComponent: Form, |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | | const [PreGenerateModalApi, preGenerateModalApi] = useVbenModal({ |
| | | connectedComponent: PreGenerateModal, |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | |
| | | }); |
| | | |
| | | /** 刷新表格 */ |
| | | const [BusinessQrViewModal, businessQrApi] = useVbenModal({ connectedComponent: BusinessQrModal, destroyOnClose: true }); |
| | | function handleBusinessQr(row: MesProBatchApi.Batch) { |
| | | businessQrApi.setData({ code: row.businessCode }).open(); |
| | | } |
| | | async function handleGenerateBusiness(row: MesProBatchApi.Batch) { |
| | | if (row.id == null) return; |
| | | const count = await generateBatchBusinessCodes([row.id]); |
| | | message.success(`已补生成 ${count} 份业务码,已有码值保持不变`); handleRefresh(); |
| | | } |
| | | async function handleExportBusiness(row: MesProBatchApi.Batch) { |
| | | if (row.id == null) return; |
| | | const data = await exportBatchBusinessQr(row.id); |
| | | downloadFileFromBlobPart({ fileName: '批次与托盘业务二维码.zip', source: data }); |
| | | } |
| | | |
| | | function handleRefresh() { |
| | | gridApi.query(); |
| | | } |
| | |
| | | qrTraceQueryModalApi.open(); |
| | | } |
| | | |
| | | /** 查看二维码(行内预填码值) */ |
| | | /** 获取批次显示用的码值(正式批次号优先,其次临时批次码) */ |
| | | function getDisplayCode(row: MesProBatchApi.Batch) { |
| | | return row.code || row.tempCode || ""; |
| | | } |
| | | |
| | | /** 查看二维码(行内预填码值,临时批次用临时批次码) */ |
| | | function handleViewQr(row: MesProBatchApi.Batch) { |
| | | qrTraceQueryModalApi.setData({ code: row.code }).open(); |
| | | qrTraceQueryModalApi.setData({ code: getDisplayCode(row) }).open(); |
| | | } |
| | | |
| | | /** 打印整套二维码(批次图 + 全部托盘图 ZIP) */ |
| | | async function handlePrintQrSet(row: MesProBatchApi.Batch) { |
| | | const data = await exportBatchQr(row.id!); |
| | | downloadFileFromBlobPart({ |
| | | fileName: `批次二维码-${row.code}.zip`, |
| | | fileName: `批次二维码-${getDisplayCode(row)}.zip`, |
| | | source: data, |
| | | }); |
| | | } |
| | | |
| | | /** 预生成批次二维码成功:刷新列表并展示生成的临时批次码 */ |
| | | function handlePreGenerateSuccess(result: { id: number; tempCode: string }[]) { |
| | | handleRefresh(); |
| | | Modal.success({ |
| | | title: "预生成临时批次码成功", |
| | | content: result.map((item) => item.tempCode).join("\n"), |
| | | centered: true, |
| | | }); |
| | | } |
| | | |
| | | /** 新增批次 */ |
| | | function handleCreate() { |
| | | formModalApi.setData({ formType: "create" }).open(); |
| | | } |
| | | |
| | | /** 临时批次补录正式信息 */ |
| | | function handleFillInfo(row: MesProBatchApi.Batch) { |
| | | formModalApi.setData({ formType: "fill", id: row.id }).open(); |
| | | } |
| | | |
| | | /** 预生成批次二维码 */ |
| | | function handlePreGenerate() { |
| | | preGenerateModalApi.open(); |
| | | } |
| | | |
| | | /** 查看详情 */ |
| | |
| | | /** 删除批次 */ |
| | | async function handleDelete(row: MesProBatchApi.Batch) { |
| | | await deleteBatch(row.id!); |
| | | message.success($t("ui.actionMessage.deleteSuccess", [row.code])); |
| | | message.success($t("ui.actionMessage.deleteSuccess", [getDisplayCode(row)])); |
| | | handleRefresh(); |
| | | } |
| | | |
| | |
| | | <template> |
| | | <Page auto-content-height> |
| | | <FormModal @success="handleRefresh" /> |
| | | <PreGenerateModalApi @success="handlePreGenerateSuccess" /> |
| | | <QrTraceQueryModal /> |
| | | <BusinessQrViewModal /> |
| | | <Grid table-title="生产批次列表"> |
| | | <template #table-title><span class="text-[1rem] font-bold" style="white-space:nowrap">生产批次列表</span></template> |
| | | <template #toolbar-tools> |
| | | <TableAction :actions="[ |
| | | { |
| | | label: $t('ui.actionTitle.create', ['批次']), |
| | | type: 'primary', |
| | | icon: ACTION_ICON.ADD, |
| | | auth: ['mes:pro-batch:create'], |
| | | onClick: handleCreate, |
| | | }, |
| | | { |
| | | label: '扫码追溯', |
| | | icon: ACTION_ICON.SEARCH, |
| | | auth: ['mes:pro-batch:query'], |
| | | onClick: handleTrace, |
| | | }, |
| | | { |
| | | label: $t('ui.actionTitle.export'), |
| | | type: 'primary', |
| | | icon: ACTION_ICON.DOWNLOAD, |
| | | auth: ['mes:pro-batch:export'], |
| | | onClick: handleExport, |
| | | }, |
| | | ]" /> |
| | | <div class="mes-code-toolbar"> |
| | | <TableAction :actions="[{ label: '预生成二维码', type: 'primary', icon: ACTION_ICON.ADD, auth: ['mes:pro-batch:create'], onClick: handlePreGenerate }, |
| | | { label: '新增批次', auth: ['mes:pro-batch:create'], onClick: handleCreate }, |
| | | { label: '扫码追溯', icon: ACTION_ICON.SEARCH, auth: ['mes:pro-batch:query'], onClick: handleTrace }]" /> |
| | | <TableAction :dropdown-trigger="['click']" :drop-down-actions="[{ label: 'Excel 数据', auth: ['mes:pro-batch:export'], onClick: handleExport }]"> |
| | | <template #more><Button>导出 <IconifyIcon icon="lucide:chevron-down" /></Button></template> |
| | | </TableAction> |
| | | </div> |
| | | </template> |
| | | <template #code="{ row }"> |
| | | <Button type="link" @click="handleDetail(row)"> |
| | | {{ row.code }} |
| | | {{ getDisplayCode(row) }} |
| | | </Button> |
| | | <Tag v-if="!row.code" color="warning">待补录</Tag> |
| | | </template> |
| | | <template #actions="{ row }"> |
| | | <TableAction :actions="[ |
| | | { |
| | | label: '查看二维码', |
| | | label: '追溯二维码', |
| | | type: 'link', |
| | | auth: ['mes:pro-batch:query'], |
| | | onClick: handleViewQr.bind(null, row), |
| | | }, |
| | | { |
| | | label: '补录信息', |
| | | type: 'link', |
| | | icon: ACTION_ICON.EDIT, |
| | | auth: ['mes:pro-batch:update'], |
| | | ifShow: !row.code, |
| | | onClick: handleFillInfo.bind(null, row), |
| | | }, |
| | | { |
| | | label: $t('common.edit'), |
| | |
| | | icon: ACTION_ICON.EDIT, |
| | | auth: ['mes:pro-batch:update'], |
| | | ifShow: |
| | | row.status === MesProBatchStatusEnum.DRAFT || |
| | | row.status === MesProBatchStatusEnum.PRODUCING, |
| | | (row.status === MesProBatchStatusEnum.DRAFT || |
| | | row.status === MesProBatchStatusEnum.PRODUCING) && |
| | | !!row.code, |
| | | onClick: handleEdit.bind(null, row), |
| | | }, |
| | | { |
| | |
| | | row.status === MesProBatchStatusEnum.DRAFT || |
| | | row.status === MesProBatchStatusEnum.CANCELED, |
| | | popConfirm: { |
| | | title: $t('ui.actionMessage.deleteConfirm', [row.code]), |
| | | title: $t('ui.actionMessage.deleteConfirm', [getDisplayCode(row)]), |
| | | confirm: handleDelete.bind(null, row), |
| | | }, |
| | | }, |
| | | ]" |
| | | :drop-down-actions="[ |
| | | { label: '业务二维码', auth: ['mes:pro-batch:query'], ifShow: !!row.businessCode, onClick: () => handleBusinessQr(row) }, |
| | | { label: '补生成业务码', auth: ['mes:pro-batch:create'], ifShow: !row.businessCode && row.status !== MesProBatchStatusEnum.CANCELED, onClick: () => handleGenerateBusiness(row) }, |
| | | { label: '导出整套业务二维码', auth: ['mes:pro-batch:export'], ifShow: row.status !== MesProBatchStatusEnum.CANCELED, onClick: () => handleExportBusiness(row) }, |
| | | { |
| | | label: '开始生产', |
| | | auth: ['mes:pro-batch:update'], |
| | | ifShow: row.status === MesProBatchStatusEnum.DRAFT, |
| | | ifShow: row.status === MesProBatchStatusEnum.DRAFT && !!row.code, |
| | | popConfirm: { |
| | | title: '确认开始生产该批次吗?', |
| | | confirm: () => |
| | |
| | | }, |
| | | }, |
| | | { |
| | | label: '打印整套二维码', |
| | | label: '打印整套追溯二维码', |
| | | auth: ['mes:pro-batch:export'], |
| | | onClick: () => handlePrintQrSet(row), |
| | | }, |
| | |
| | | </Grid> |
| | | </Page> |
| | | </template> |
| | | |
| | | <style scoped> |
| | | .mes-code-toolbar { display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:8px; } |
| | | .mes-code-toolbar :deep(.ant-btn) { white-space:nowrap; } |
| | | .mes-code-toolbar :deep(.ant-btn > .iconify) { display:inline-block;width:14px;height:14px;vertical-align:middle; } |
| | | </style> |