From 6738e8f5a78431e41fed28e6b795e70c2396070a Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期四, 03 九月 2026 17:27:23 +0800
Subject: [PATCH] refactor(mes): 优化工艺路线配置与工单表单功能

---
 src/views/mes/md/item/components/product-bom-select-dialog.vue |  182 ++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 152 insertions(+), 30 deletions(-)

diff --git a/src/views/mes/md/item/components/product-bom-select-dialog.vue b/src/views/mes/md/item/components/product-bom-select-dialog.vue
index 9718d32..64eeccb 100644
--- a/src/views/mes/md/item/components/product-bom-select-dialog.vue
+++ b/src/views/mes/md/item/components/product-bom-select-dialog.vue
@@ -13,26 +13,115 @@
 
 defineOptions({ name: 'MdProductBomSelectDialog' });
 
+const props = withDefaults(
+  defineProps<{
+    multiple?: boolean;
+  }>(),
+  {
+    multiple: false,
+  },
+);
+
 const emit = defineEmits<{
-  selected: [row: MesMdProductBomApi.ProductBom];
+  selected: [rows: MesMdProductBomApi.ProductBom[]];
 }>();
 
 const open = ref(false); // 寮圭獥鏄惁鎵撳紑
 const list = ref<MesMdProductBomApi.ProductBom[]>([]); // BOM 瀛愮墿鏂欏垪琛�
-const selectedRow = ref<MesMdProductBomApi.ProductBom>(); // 褰撳墠閫変腑鐨� BOM 琛�
+const selectedRows = ref<MesMdProductBomApi.ProductBom[]>([]); // 宸查�� BOM 琛岋紙鍗曢�夋椂鏈�澶氫竴琛岋級
+const preSelectedIds = ref<number[]>([]); // 棰勯�� BOM 鐗╂枡缂栧彿
+
+/** 鑾峰彇澶氶�夎褰曪紝鍖呭惈 VXE reserve 璁板綍 */
+function getMultipleSelectedRows() {
+  const selectedMap = new Map<number, MesMdProductBomApi.ProductBom>();
+  const records = [
+    ...(gridApi.grid.getCheckboxReserveRecords?.() ?? []),
+    ...(gridApi.grid.getCheckboxRecords?.() ?? []),
+  ] as MesMdProductBomApi.ProductBom[];
+  records.forEach((row) => {
+    if (row.bomItemId != null) {
+      selectedMap.set(row.bomItemId, row);
+    }
+  });
+  return [...selectedMap.values()];
+}
+
+/** 澶勭悊鍕鹃�夊彉鍖� */
+function handleCheckboxSelectChange() {
+  selectedRows.value = getMultipleSelectedRows();
+}
+
+/** 涓婂懆鍗曞嚮琛岀棔杩癸紝鐢ㄤ簬鍚炴帀鍙屽嚮瑙﹀彂鐨勭浜屾 click */
+let lastClick = { bomItemId: undefined as number | undefined, time: 0 };
+
+/** 鍗曞嚮琛岋細澶氶�夊垏鎹㈠嬀閫夛紱鍗曢�夌敱 radioConfig.trigger='row' 澶勭悊 */
+async function handleCellClick({
+  row,
+  column,
+}: {
+  row: MesMdProductBomApi.ProductBom;
+  column?: { type?: string };
+}) {
+  // 鐐瑰嚮鍕鹃��/鍗曢�夊垪鑷韩鐢辨帶浠跺鐞嗭紝閬垮厤浜屾鍒囨崲
+  if (column?.type === 'checkbox' || column?.type === 'radio') {
+    return;
+  }
+  if (!props.multiple) {
+    return;
+  }
+  const now = Date.now();
+  if (lastClick.bomItemId === row.bomItemId && now - lastClick.time < 300) {
+    lastClick.time = 0;
+    return;
+  }
+  lastClick = { bomItemId: row.bomItemId, time: now };
+  const selected = gridApi.grid.isCheckedByCheckboxRow(row);
+  await gridApi.grid.setCheckboxRow(row, !selected);
+  selectedRows.value = getMultipleSelectedRows();
+}
+
+/** 澶勭悊琛屽弻鍑� */
+async function handleCellDblclick({
+  row,
+}: {
+  row: MesMdProductBomApi.ProductBom;
+}) {
+  if (props.multiple) {
+    return; // 澶氶�夌敱鍗曞嚮 cellClick 鍒囨崲锛屽弻鍑讳笉鍐嶉噸澶嶅鐞�
+  }
+  selectedRows.value = [row];
+  gridApi.grid.setRadioRow(row);
+  handleConfirm();
+}
+
+/** 澶勭悊鍗曢�夊彉鍖� */
+function handleRadioChange(row: MesMdProductBomApi.ProductBom) {
+  selectedRows.value = [row];
+}
+
+/** 褰撳墠閫夋嫨鍒楃被鍨� */
+function getSelectColumn() {
+  return {
+    type: props.multiple ? 'checkbox' : 'radio',
+    width: 55,
+    align: 'center',
+  } as const;
+}
 
 const [Grid, gridApi] = useVbenVxeGrid({
   gridOptions: {
     border: true,
-    columns: [
-      { type: 'radio', width: 55, align: 'center' },
-      ...(useProductBomGridColumns(true) || []),
-    ],
+    columns: [getSelectColumn(), ...(useProductBomGridColumns(true) || [])],
     data: list.value,
     height: 500,
     keepSource: true,
     pagerConfig: {
       enabled: false,
+    },
+    checkboxConfig: {
+      highlight: true,
+      range: true,
+      reserve: true,
     },
     radioConfig: {
       highlight: true,
@@ -48,35 +137,62 @@
     },
   } as VxeTableGridOptions<MesMdProductBomApi.ProductBom>,
   gridEvents: {
-    cellDblclick: ({ row }: { row: MesMdProductBomApi.ProductBom }) => {
-      selectedRow.value = row;
-      gridApi.grid.setRadioRow(row);
-      handleConfirm();
-    },
+    cellClick: handleCellClick,
+    cellDblclick: handleCellDblclick,
+    checkboxChange: handleCheckboxSelectChange,
+    checkboxAll: handleCheckboxSelectChange,
     radioChange: ({ row }: { row: MesMdProductBomApi.ProductBom }) => {
-      selectedRow.value = row;
+      handleRadioChange(row);
     },
   },
 });
 
-/** 鎵撳紑 BOM 鐗╂枡閫夋嫨寮圭獥 */
-async function openModal(itemId: number, selectedBomItemId?: number) {
+/** 鍥炴樉棰勯�� BOM 鐗╂枡锛堟暟鎹竴娆℃�у姞杞斤紝鏃犲垎椤碉紝鐩存帴鍕鹃�夊嵆鍙級 */
+async function applyPreSelection() {
+  if (preSelectedIds.value.length === 0) {
+    return;
+  }
+  for (const row of list.value) {
+    if (
+      row.bomItemId === undefined ||
+      row.bomItemId === null ||
+      !preSelectedIds.value.includes(row.bomItemId)
+    ) {
+      continue;
+    }
+    if (props.multiple) {
+      await gridApi.grid.setCheckboxRow(row, true);
+    } else {
+      await gridApi.grid.setRadioRow(row);
+      selectedRows.value = [row];
+      return;
+    }
+  }
+  if (props.multiple) {
+    selectedRows.value = getMultipleSelectedRows();
+  }
+}
+
+/** 鎵撳紑 BOM 鐗╂枡閫夋嫨寮圭獥锛坰electedBomItemIds 鍗曢�変紶鍗曚釜缂栧彿锛屽閫変紶缂栧彿鏁扮粍锛� */
+async function openModal(itemId: number, selectedBomItemIds?: number | number[]) {
   open.value = true;
-  selectedRow.value = undefined;
+  preSelectedIds.value = (
+    Array.isArray(selectedBomItemIds)
+      ? selectedBomItemIds
+      : selectedBomItemIds === undefined || selectedBomItemIds === null
+        ? []
+        : [selectedBomItemIds]
+  ).filter((id): id is number => id != null);
+  selectedRows.value = [];
   gridApi.setLoading(true);
   try {
     list.value = await getProductBomListByItemId(itemId);
-    gridApi.setGridOptions({ data: list.value });
+    gridApi.setGridOptions({
+      data: list.value,
+      columns: [getSelectColumn(), ...(useProductBomGridColumns(true) || [])],
+    });
     await nextTick();
-    if (selectedBomItemId !== null) {
-      const match = list.value.find(
-        (row) => row.bomItemId === selectedBomItemId,
-      );
-      if (match) {
-        selectedRow.value = match;
-        gridApi.grid.setRadioRow(match);
-      }
-    }
+    await applyPreSelection();
   } finally {
     gridApi.setLoading(false);
   }
@@ -85,17 +201,23 @@
 /** 鍏抽棴 BOM 鐗╂枡閫夋嫨寮圭獥 */
 async function closeModal() {
   open.value = false;
-  selectedRow.value = undefined;
+  selectedRows.value = [];
+  preSelectedIds.value = [];
+  await gridApi.grid.clearCheckboxRow();
+  await gridApi.grid.clearCheckboxReserve();
   await gridApi.grid.clearRadioRow();
 }
 
 /** 纭閫夋嫨 BOM 鐗╂枡 */
 function handleConfirm() {
-  if (!selectedRow.value) {
-    message.warning('璇烽�夋嫨涓�鏉℃暟鎹�');
+  const rows = props.multiple
+    ? getMultipleSelectedRows()
+    : selectedRows.value.slice(0, 1);
+  if (rows.length === 0) {
+    message.warning(props.multiple ? '璇疯嚦灏戦�夋嫨涓�鏉℃暟鎹�' : '璇烽�夋嫨涓�鏉℃暟鎹�');
     return;
   }
-  emit('selected', selectedRow.value);
+  emit('selected', rows);
   open.value = false;
 }
 
@@ -113,4 +235,4 @@
   >
     <Grid table-title="BOM 瀛愮墿鏂欏垪琛�" />
   </Modal>
-</template>
+</template>
\ No newline at end of file

--
Gitblit v1.9.3