liu
2026-09-07 a7dc7b230fcc6abc6ee5a7bfadb90789b03d2ca8
src/views/mes/md/item/components/select-dialog.vue
@@ -5,7 +5,7 @@
  import { nextTick, ref } from "vue";
  import { CommonStatusEnum } from "../../../../../packages/constants/src";
  import { CommonStatusEnum } from "@vben/constants";
  import { Card, message, Modal } from "ant-design-vue";
@@ -26,6 +26,7 @@
  const selectedRows = ref<MesMdItemApi.Item[]>([]); // 已选物料列表
  const selectedItemTypeId = ref<number>(); // 当前筛选分类编号
  const preSelectedIds = ref<number[]>([]); // 预选物料编号列表
  const productIds = ref<number[]>([]); // 限定可选的物料编号列表(为空则不限制)
  const typeTreeRef = ref<InstanceType<typeof MdItemTypeTree>>(); // 物料分类树
  /** 获取当前表格数据 */
@@ -66,11 +67,38 @@
    selectedRows.value = getMultipleSelectedRows();
  }
  /** 上次单击行痕迹,用于吞掉双击触发的第二次 click,避免"选了又取消" */
  let lastClick = { rowId: undefined as number | undefined, time: 0 };
  /** 单击行:多选直接切换勾选;单选由 radioConfig.trigger='row' 处理 */
  async function handleCellClick({
    row,
    column,
  }: {
    row: MesMdItemApi.Item;
    column?: { type?: string };
  }) {
    // 点击勾选列自身由 checkbox 控件处理,避免二次切换
    if (column?.type === "checkbox") {
      return;
    }
    if (!multiple.value) {
      return;
    }
    const rowId = row.id;
    const now = Date.now();
    if (lastClick.rowId === rowId && now - lastClick.time < 300) {
      lastClick.time = 0;
      return;
    }
    lastClick = { rowId, time: now };
    await toggleMultipleRow(row);
  }
  /** 处理行双击 */
  async function handleCellDblclick({ row }: { row: MesMdItemApi.Item }) {
    if (multiple.value) {
      await toggleMultipleRow(row);
      return;
      return; // 多选由单击 cellClick 切换,双击不再重复处理
    }
    selectedRows.value = [row];
    await gridApi.grid.setRadioRow(row);
@@ -83,18 +111,20 @@
    gridApi.query();
  }
  /** 回显预选物料 */
  /** 回显预选物料:当前页直接勾选,跨页预选注册为 reserve,翻页后自动回显 */
  async function applyPreSelection() {
    if (preSelectedIds.value.length === 0) {
      return;
    }
    const rows = getTableRows();
    const currentIds = new Set(
      rows.filter((row) => row.id != null).map((row) => row.id),
    );
    for (const row of rows) {
      if (
        row.id === undefined ||
        row.id === null ||
        !preSelectedIds.value.includes(row.id)
      ) {
      if (row.id === undefined || row.id === null) {
        continue;
      }
      if (!preSelectedIds.value.includes(row.id)) {
        continue;
      }
      if (multiple.value) {
@@ -106,6 +136,21 @@
      }
    }
    if (multiple.value) {
      // 拉取不在当前页的预选物料完整数据,注册为 checkbox reserve(翻页后自动勾选)
      const missingIds = preSelectedIds.value.filter(
        (id) => !currentIds.has(id),
      );
      if (missingIds.length > 0) {
        const result = await getItemPage({
          pageNo: 1,
          pageSize: 200,
          ids: missingIds.join(","),
        } as never);
        const fullRows = result?.list as MesMdItemApi.Item[] | undefined;
        if (fullRows && fullRows.length > 0) {
          await gridApi.grid.setCheckboxReserve(fullRows, true);
        }
      }
      selectedRows.value = getMultipleSelectedRows();
    }
  }
@@ -130,13 +175,21 @@
      proxyConfig: {
        ajax: {
          query: async ({ page }, formValues) => {
            return await getItemPage({
            const params: Record<string, unknown> = {
              pageNo: page.currentPage,
              pageSize: page.pageSize,
              ...formValues,
              itemTypeId: selectedItemTypeId.value,
              status: CommonStatusEnum.ENABLE,
            });
            };
            // 限定可选物料范围
            if (productIds.value.length > 0) {
              // 后端分页每页条数上限为 200,白名单场景一次拉取尽量多的可选物料
              params.pageSize = 200;
              params.ids = productIds.value.join(',');
            }
            const result = await getItemPage(params as never);
            return result;
          },
        },
      },
@@ -150,6 +203,7 @@
      },
    } as VxeTableGridOptions<MesMdItemApi.Item>,
    gridEvents: {
      cellClick: handleCellClick,
      cellDblclick: handleCellDblclick,
      checkboxAll: handleCheckboxSelectChange,
      checkboxChange: handleCheckboxSelectChange,
@@ -173,11 +227,12 @@
  /** 打开物料选择弹窗 */
  async function openModal(
    selectedIds?: number[],
    options?: { multiple?: boolean }
    options?: { multiple?: boolean; productIds?: number[] }
  ) {
    open.value = true;
    multiple.value = options?.multiple ?? true;
    preSelectedIds.value = selectedIds || [];
    productIds.value = options?.productIds || [];
    await nextTick();
    gridApi.setGridOptions({
      columns: useItemSelectGridColumns(multiple.value),