From 6a415a072a98d64d2f95d16eef73b6d7270b8d56 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期六, 30 五月 2026 15:14:25 +0800
Subject: [PATCH] 新疆马铃薯 1.首页问题:挪新系统ui,需要确认一下页面数据完整。 2.协同办公:挪新系统 3.营销管理:客户往来取消回款金额字段,改为点击左侧客户时显示与该客户的所有订单信息,以及发货情况。销售可以选好对应的采购订单方便质量追溯。 4.采购管理:供应商往来同上逻辑,显示是否收货,也加上采购退货和采购报表功能。 5.采购加上设备备件选项,设备备件入库到备件库存。设备,仓储不足时做采购提醒。 6.仓储物流:得区分成品库和原料库(不存在半成品,成品只有一个产品,很好确认),原材料需要有批号,采集原料库需要做好仓库字段,让他们可以区分哪个仓库,然后把数采设备信息做一个实时的显示。总库存显示好当前存在的批次信息。 7.质量:只有不通过才需要填写对应的数据信息。在外侧做好选择通过不通过。过程,出厂检验无法对应到生产订单,那就对应到销售订单。 8.决策分析:基础数据分析和进销存分析,质量数据分析需要重新设计

---
 src/views/basicData/product/ProductSelectDialog.vue |  187 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 187 insertions(+), 0 deletions(-)

diff --git a/src/views/basicData/product/ProductSelectDialog.vue b/src/views/basicData/product/ProductSelectDialog.vue
new file mode 100644
index 0000000..ad27baa
--- /dev/null
+++ b/src/views/basicData/product/ProductSelectDialog.vue
@@ -0,0 +1,187 @@
+<template>
+  <el-dialog v-model="visible" title="閫夋嫨浜у搧" width="900px" destroy-on-close :close-on-click-modal="false">
+    <el-form :inline="true" :model="query" class="mb-2">
+      <el-form-item label="浜у搧鍚嶇О">
+        <el-input v-model="query.productName" placeholder="杈撳叆浜у搧鍚嶇О" clearable @keyup.enter="onSearch" />
+      </el-form-item>
+
+      <el-form-item label="浜у搧鍨嬪彿">
+        <el-input v-model="query.model" placeholder="杈撳叆浜у搧鍨嬪彿" clearable @keyup.enter="onSearch" />
+      </el-form-item>
+
+      <el-form-item>
+        <el-button type="primary" @click="onSearch">鎼滅储</el-button>
+        <el-button @click="onReset">閲嶇疆</el-button>
+      </el-form-item>
+    </el-form>
+
+    <!-- 鍒楄〃 -->
+    <el-table ref="tableRef" v-loading="loading" :data="tableData" height="420" highlight-current-row row-key="id"
+      @selection-change="handleSelectionChange" @select="handleSelect">
+      <el-table-column type="selection" width="55" />
+      <el-table-column type="index" label="搴忓彿" width="60" />
+      <el-table-column prop="productName" label="浜у搧鍚嶇О" min-width="160" />
+      <el-table-column prop="model" label="浜у搧鍨嬪彿" min-width="200" />
+      <el-table-column prop="unit" label="鍗曚綅" min-width="160" />
+    </el-table>
+
+    <div class="mt-3 flex justify-end">
+      <el-pagination background layout="total, sizes, prev, pager, next, jumper" :total="total"
+        v-model:page-size="page.pageSize" v-model:current-page="page.pageNum" :page-sizes="[10, 20, 50, 100]"
+        @size-change="onPageChange" @current-change="onPageChange" />
+    </div>
+
+    <template #footer>
+      <el-button type="primary" :disabled="multipleSelection.length === 0" @click="onConfirm">
+        纭畾
+      </el-button>
+			<el-button @click="close()">鍙栨秷</el-button>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup lang="ts">
+import { computed, onMounted, reactive, ref, watch, nextTick } from "vue";
+import { ElMessage } from "element-plus";
+import { productModelList, productModelListByUrl } from '@/api/basicData/productModel'
+
+export type ProductRow = {
+  id: number;
+  productName: string;
+  model: string;
+  unit?: string;
+};
+
+const props = defineProps<{
+  modelValue: boolean;
+  single?: boolean; // 鏄惁鍙兘閫夋嫨涓�涓紝榛樿false锛堝彲閫夋嫨澶氫釜锛�
+  topProductParentId?: number; // 涓�绾т骇鍝乮d
+  requestUrl?: string; // 鑷畾涔夋煡璇㈡帴鍙�
+}>();
+
+const emit = defineEmits(['update:modelValue', 'confirm']);
+
+const visible = computed({
+  get: () => props.modelValue,
+  set: (v) => emit("update:modelValue", v),
+});
+
+const query = reactive({
+  productName: "",
+  model: "",
+});
+
+const page = reactive({
+  pageNum: 1,
+  pageSize: 10,
+});
+
+const loading = ref(false);
+const tableData = ref<ProductRow[]>([]);
+const total = ref(0);
+const multipleSelection = ref<ProductRow[]>([]);
+const tableRef = ref();
+
+function close() {
+  visible.value = false;
+}
+
+const handleSelectionChange = (val: ProductRow[]) => {
+  if (props.single && val.length > 1) {
+    // 濡傛灉闄愬埗涓哄崟涓�夋嫨锛屽彧淇濈暀鏈�鍚庝竴涓�変腑鐨�
+    const lastSelected = val[val.length - 1];
+    multipleSelection.value = [lastSelected];
+    // 娓呯┖琛ㄦ牸閫変腑鐘舵�侊紝鐒跺悗閲嶆柊閫変腑鏈�鍚庝竴涓�
+    nextTick(() => {
+      if (tableRef.value) {
+        tableRef.value.clearSelection();
+        tableRef.value.toggleRowSelection(lastSelected, true);
+      }
+    });
+  } else {
+    multipleSelection.value = val;
+  }
+}
+
+// 澶勭悊鍗曚釜閫夋嫨
+const handleSelect = (selection: ProductRow[], row: ProductRow) => {
+  if (props.single) {
+    // 濡傛灉闄愬埗涓哄崟涓紝娓呯┖鍏朵粬閫夋嫨锛屽彧淇濈暀褰撳墠琛�
+    if (selection.includes(row)) {
+      // 閫変腑褰撳墠琛屾椂锛屾竻绌哄叾浠栭�変腑
+      multipleSelection.value = [row];
+      nextTick(() => {
+        if (tableRef.value) {
+          tableData.value.forEach((item) => {
+            if (item.id !== row.id) {
+              tableRef.value.toggleRowSelection(item, false);
+            }
+          });
+        }
+      });
+    }
+  }
+}
+
+function onSearch() {
+  page.pageNum = 1;
+  loadData();
+}
+
+function onReset() {
+  query.productName = "";
+  query.model = "";
+  page.pageNum = 1;
+  loadData();
+}
+
+function onPageChange() {
+  loadData();
+}
+
+function onConfirm() {
+  if (multipleSelection.value.length === 0) {
+    ElMessage.warning("璇烽�夋嫨涓�鏉′骇鍝�");
+    return;
+  }
+  if (props.single && multipleSelection.value.length > 1) {
+    ElMessage.warning("鍙兘閫夋嫨涓�涓骇鍝�");
+    return;
+  }
+  emit("confirm", props.single ? [multipleSelection.value[0]] : multipleSelection.value);
+  close();
+}
+
+async function loadData() {
+  loading.value = true;
+  try {
+    multipleSelection.value = []; // 缈婚〉/鎼滅储鍚庢竻绌洪�夋嫨鏇寸鍚堥鏈�
+    const params = {
+      productName: query.productName.trim(),
+      model: query.model.trim(),
+      current: page.pageNum,
+      size: page.pageSize,
+      topProductParentId: props.topProductParentId,
+    };
+    const res: any = props.requestUrl
+      ? await productModelListByUrl(props.requestUrl, params)
+      : await productModelList(params);
+    const records = res?.records || res?.data?.records || res?.data || [];
+    tableData.value = Array.isArray(records) ? records : [];
+    total.value = Number(res?.total ?? res?.data?.total ?? tableData.value.length);
+  } finally {
+    loading.value = false;
+  }
+}
+
+// 鐩戝惉寮圭獥鎵撳紑锛岄噸缃�夋嫨
+watch(() => props.modelValue, (visible) => {
+  if (visible) {
+    multipleSelection.value = [];
+  }
+});
+
+onMounted(() => {
+  loadData()
+})
+</script>

--
Gitblit v1.9.3