From 49c9eff61882f1f7d519397ccfdd90cdd8735cb8 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期二, 04 八月 2026 13:12:21 +0800
Subject: [PATCH] feat(aftersales): 售后工单支持附件上传和显示

---
 src/views/mes/md/item/components/select.vue |  103 ++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 69 insertions(+), 34 deletions(-)

diff --git a/src/views/mes/md/item/components/select.vue b/src/views/mes/md/item/components/select.vue
index d157aff..6a45bdb 100644
--- a/src/views/mes/md/item/components/select.vue
+++ b/src/views/mes/md/item/components/select.vue
@@ -17,7 +17,8 @@
   defineProps<{
     allowClear?: boolean;
     disabled?: boolean;
-    modelValue?: number;
+    modelValue?: number | number[];
+    multiple?: boolean;
     placeholder?: string;
     productIds?: number[];
   }>(),
@@ -25,53 +26,70 @@
     allowClear: true,
     disabled: false,
     modelValue: undefined,
+    multiple: false,
     placeholder: '璇烽�夋嫨浜у搧鐗╂枡',
     productIds: () => [],
   },
 );
 const emit = defineEmits<{
-  change: [item: MesMdItemApi.Item | undefined];
-  'update:modelValue': [value: number | undefined];
+  change: [items: MesMdItemApi.Item | MesMdItemApi.Item[] | undefined];
+  'update:modelValue': [value: number | number[] | undefined];
 }>();
-const attrs = useAttrs(); // 閫忎紶灞炴��
-const dialogRef = ref<InstanceType<typeof MdItemSelectDialog>>(); // 鐗╂枡閫夋嫨寮圭獥
-const hovering = ref(false); // 鏄惁鎮仠
-const selectedItem = ref<MesMdItemApi.Item>(); // 褰撳墠閫変腑鐗╂枡
+const attrs = useAttrs();
+const dialogRef = ref<InstanceType<typeof MdItemSelectDialog>>();
+const hovering = ref(false);
+const selectedItems = ref<MesMdItemApi.Item[]>([]);
 
-const displayLabel = computed(() => selectedItem.value?.name ?? ''); // 閫夋嫨鍣ㄥ睍绀哄悕绉�
+const displayLabel = computed(() => {
+  if (selectedItems.value.length === 0) return '';
+  return selectedItems.value.map(item => item.name ?? '').join('銆�');
+});
 const showClear = computed(
   () =>
     props.allowClear &&
     !props.disabled &&
     hovering.value &&
-    props.modelValue !== null,
+    (props.multiple
+      ? Array.isArray(props.modelValue) && props.modelValue.length > 0
+      : props.modelValue != null),
 );
 
 /** 鏍规嵁鐗╂枡缂栧彿鍥炴樉閫夋嫨鍣� */
-async function resolveItemById(id: number | undefined) {
-  if (!id) {
-    selectedItem.value = undefined;
+async function resolveItemsById(values: number | number[] | undefined) {
+  if (values == null || (Array.isArray(values) && values.length === 0)) {
+    selectedItems.value = [];
     return;
   }
-  if (selectedItem.value?.id === id) {
+  const ids = Array.isArray(values) ? values : [values];
+  // 宸插叏閮ㄥ洖鏄惧垯璺宠繃
+  if (
+    ids.length === selectedItems.value.length &&
+    ids.every((id, i) => selectedItems.value[i]?.id === id)
+  ) {
     return;
   }
-  selectedItem.value = await getItem(id);
+  const items = await Promise.all(ids.map(id => getItem(id)));
+  selectedItems.value = items.filter(Boolean) as MesMdItemApi.Item[];
 }
 
 watch(
   () => props.modelValue,
   (value) => {
-    resolveItemById(value);
+    resolveItemsById(value);
   },
   { immediate: true },
 );
 
 /** 娓呯┖宸查�夌墿鏂� */
 function clearSelected() {
-  selectedItem.value = undefined;
-  emit('update:modelValue', undefined);
-  emit('change', undefined);
+  selectedItems.value = [];
+  if (props.multiple) {
+    emit('update:modelValue', []);
+    emit('change', []);
+  } else {
+    emit('update:modelValue', undefined);
+    emit('change', undefined);
+  }
 }
 
 /** 鎵撳紑鐗╂枡閫夋嫨寮圭獥 */
@@ -85,24 +103,33 @@
     clearSelected();
     return;
   }
-  const selectedIds = (
-    props.modelValue === null ? [] : [props.modelValue]
-  ) as number[];
+  const selectedIds: number[] = props.multiple
+    ? (props.modelValue as number[] | undefined) ?? []
+    : props.modelValue != null
+      ? [props.modelValue as number]
+      : [];
   dialogRef.value?.open(selectedIds, {
-    multiple: false,
+    multiple: props.multiple,
     productIds: props.productIds,
   });
 }
 
 /** 鍥炲~閫変腑鐨勭墿鏂� */
 function handleSelected(rows: MesMdItemApi.Item[]) {
-  const item = rows[0];
-  if (!item) {
-    return;
+  if (props.multiple) {
+    selectedItems.value = rows;
+    const ids = rows.map(r => r.id).filter(Boolean) as number[];
+    emit('update:modelValue', ids);
+    emit('change', rows);
+  } else {
+    const item = rows[0];
+    if (!item) {
+      return;
+    }
+    selectedItems.value = [item];
+    emit('update:modelValue', item.id);
+    emit('change', item);
   }
-  selectedItem.value = item;
-  emit('update:modelValue', item.id);
-  emit('change', item);
 }
 </script>
 
@@ -115,13 +142,21 @@
     @mouseenter="hovering = true"
     @mouseleave="hovering = false"
   >
-    <Tooltip :mouse-enter-delay="0.5" :open="selectedItem ? undefined : false">
+    <Tooltip :mouse-enter-delay="0.5" :open="selectedItems.length > 0 ? undefined : false">
       <template #title>
-        <div v-if="selectedItem" class="leading-6">
-          <div>缂栫爜锛歿{ selectedItem.code || '-' }}</div>
-          <div>鍚嶇О锛歿{ selectedItem.name || '-' }}</div>
-          <div>瑙勬牸锛歿{ selectedItem.specification || '-' }}</div>
-          <div>鍗曚綅锛歿{ selectedItem.unitMeasureName || '-' }}</div>
+        <div v-if="selectedItems.length === 1" class="leading-6">
+          <div>缂栫爜锛歿{ selectedItems[0].code || '-' }}</div>
+          <div>鍚嶇О锛歿{ selectedItems[0].name || '-' }}</div>
+          <div>瑙勬牸锛歿{ selectedItems[0].specification || '-' }}</div>
+          <div>鍗曚綅锛歿{ selectedItems[0].unitMeasureName || '-' }}</div>
+        </div>
+        <div v-else-if="selectedItems.length > 1" class="leading-6">
+          <div v-for="item in selectedItems" :key="item.id" class="mb-2 border-b border-gray-100 pb-1 last:border-b-0 last:pb-0">
+            <div>缂栫爜锛歿{ item.code || '-' }}</div>
+            <div>鍚嶇О锛歿{ item.name || '-' }}</div>
+            <div>瑙勬牸锛歿{ item.specification || '-' }}</div>
+            <div>鍗曚綅锛歿{ item.unitMeasureName || '-' }}</div>
+          </div>
         </div>
       </template>
       <Input

--
Gitblit v1.9.3