liu
3 天以前 ee7ac8df8bce38add1f75baf876b49de94b9e00a
src/views/mes/pro/batch/index.vue
@@ -6,24 +6,34 @@
  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,
  });
@@ -33,6 +43,21 @@
  });
  /** 刷新表格 */
  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();
  }
@@ -42,23 +67,48 @@
    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();
  }
  /** 查看详情 */
@@ -74,7 +124,7 @@
  /** 删除批次 */
  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();
  }
@@ -129,44 +179,42 @@
<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'),
@@ -174,8 +222,9 @@
              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),
            },
            {
@@ -188,16 +237,19 @@
                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: () =>
@@ -227,7 +279,7 @@
              },
            },
            {
              label: '打印整套二维码',
              label: '打印整套追溯二维码',
              auth: ['mes:pro-batch:export'],
              onClick: () => handlePrintQrSet(row),
            },
@@ -236,3 +288,9 @@
    </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>