From 0f5c5f11d13711db618ae2947bf35ed2effba8a2 Mon Sep 17 00:00:00 2001
From: yyb <995253665@qq.com>
Date: 星期五, 17 四月 2026 09:59:58 +0800
Subject: [PATCH] 标识

---
 src/views/productionManagement/productionProcess/New.vue |  244 +++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 207 insertions(+), 37 deletions(-)

diff --git a/src/views/productionManagement/productionProcess/New.vue b/src/views/productionManagement/productionProcess/New.vue
index 4fa2c97..250e229 100644
--- a/src/views/productionManagement/productionProcess/New.vue
+++ b/src/views/productionManagement/productionProcess/New.vue
@@ -3,29 +3,64 @@
     <el-dialog
         v-model="isShow"
         title="鏂板閮ㄤ欢"
-        width="400"
+        width="760"
         @close="closeModal"
     >
       <el-form label-width="140px" :model="formState" label-position="top" ref="formRef">
-        <el-form-item
-            label="閮ㄤ欢锛�"
-            prop="name"
+        <el-row :gutter="16">
+          <el-col :span="12">
+            <el-form-item
+            label="浜у搧鍚嶇О锛�"
+            prop="productId"
             :rules="[
                 {
                 required: true,
-                message: '璇疯緭鍏ラ儴浠�',
+                message: '璇烽�夋嫨浜у搧鍚嶇О',
               },
-              {
-                max: 100,
-                message: '鏈�澶�100涓瓧绗�',
-              }
             ]">
-          <el-input v-model="formState.name" />
-        </el-form-item>
-        <el-form-item label="閮ㄤ欢缂栧彿" prop="no">
-          <el-input v-model="formState.no"  />
-        </el-form-item>
-        <el-form-item
+              <el-tree-select
+            v-model="formState.productId"
+            placeholder="璇烽�夋嫨浜у搧鍚嶇О"
+            clearable
+            filterable
+            check-strictly
+            :data="productCategoryOptions"
+            :render-after-expand="false"
+            style="width: 100%"
+            @change="handleProductChange"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item
+            label="浜у搧瑙勬牸锛�"
+            prop="productModelId"
+            :rules="[
+                {
+                required: true,
+                message: '璇烽�夋嫨浜у搧瑙勬牸',
+              },
+            ]">
+              <el-select v-model="formState.productModelId"
+                     placeholder="璇烽�夋嫨浜у搧瑙勬牸"
+                     clearable
+                     filterable
+                     :disabled="!formState.productId"
+                     style="width: 100%">
+                <el-option v-for="item in modelOptions"
+                       :key="item.id"
+                       :label="item.model"
+                       :value="item.id" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="閮ㄤ欢缂栧彿" prop="no">
+              <el-input v-model="formState.no"  />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item
             label="閮ㄤ欢绫诲瀷"
             prop="type"
             :rules="[
@@ -34,27 +69,60 @@
                 message: '璇烽�夋嫨閮ㄤ欢绫诲瀷',
               }
             ]"
-        >
-          <el-select v-model="formState.type" placeholder="璇烽�夋嫨閮ㄤ欢绫诲瀷">
-            <el-option label="鍔犲伐" :value="1" />
-            <el-option label="鍒澘鍐疯姱鍒朵綔" :value="2" />
-            <el-option label="绠¤矾缁勫" :value="3" />
-            <el-option label="缃愪綋杩炴帴鍙婅皟璇�" :value="4" />
-            <el-option label="娴嬭瘯鎵撳帇" :value="5" />
-            <el-option label="鍏朵粬" :value="6" />
-          </el-select>
-        </el-form-item>
-        <el-form-item label="宸ヨ祫瀹氶" prop="salaryQuota">
-          <el-input v-model="formState.salaryQuota" type="number" :step="0.001">
-            <template #append>鍏�</template>
-          </el-input>
-        </el-form-item>
-        <el-form-item label="鏄惁璐ㄦ" prop="isQuality">
-          <el-switch v-model="formState.isQuality" :active-value="true" inactive-value="false"/>
-        </el-form-item>
-        <el-form-item label="澶囨敞" prop="remark">
-          <el-input v-model="formState.remark" type="textarea" />
-        </el-form-item>
+            >
+              <el-select v-model="formState.type" placeholder="璇烽�夋嫨閮ㄤ欢绫诲瀷">
+                <el-option label="鍔犲伐" :value="1" />
+                <el-option label="鍒澘鍐疯姱鍒朵綔" :value="2" />
+                <el-option label="绠¤矾缁勫" :value="3" />
+                <el-option label="缃愪綋杩炴帴鍙婅皟璇�" :value="4" />
+                <el-option label="娴嬭瘯鎵撳帇" :value="5" />
+                <el-option label="鍏朵粬" :value="6" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item
+            label="璁″垝宸ユ椂(灏忔椂)"
+            prop="salaryQuota"
+            :rules="[
+              { validator: validateNonNegativeSalaryQuota, trigger: ['blur', 'change'] }
+            ]"
+            >
+              <el-input v-model="formState.salaryQuota" type="number" :step="0.001" :min="0">
+                <template #append>灏忔椂</template>
+              </el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="璁″垝浜哄憳" prop="plannerId">
+              <el-select
+            v-model="formState.plannerId"
+            placeholder="璇烽�夋嫨璁″垝浜哄憳"
+            clearable
+            filterable
+            style="width: 100%"
+            @change="handlePlannerChange"
+              >
+                <el-option
+              v-for="item in plannerOptions"
+              :key="item.userId"
+              :label="item.nickName"
+              :value="item.userId"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鏄惁璐ㄦ" prop="isQuality">
+              <el-switch v-model="formState.isQuality" :active-value="true" inactive-value="false"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="澶囨敞" prop="remark">
+              <el-input v-model="formState.remark" type="textarea" />
+            </el-form-item>
+          </el-col>
+        </el-row>
       </el-form>
       <template #footer>
         <div class="dialog-footer">
@@ -67,8 +135,10 @@
 </template>
 
 <script setup>
-import { ref, computed, getCurrentInstance } from "vue";
+import { ref, computed, getCurrentInstance, onMounted } from "vue";
 import {add} from "@/api/productionManagement/productionProcess.js";
+import { modelListPage, productTreeList } from "@/api/basicData/product";
+import { userListNoPageByTenantId } from "@/api/system/user.js";
 
 const props = defineProps({
   visible: {
@@ -82,11 +152,18 @@
 // 鍝嶅簲寮忔暟鎹紙鏇夸唬閫夐」寮忕殑 data锛�
 const formState = ref({
   name: '',
+  productId: undefined,
+  productModelId: undefined,
   type: undefined,
   remark: '',
   salaryQuota:  '',
+  plannerId: undefined,
+  plannerName: '',
   isQuality: false,
 });
+const productCategoryOptions = ref([]);
+const modelOptions = ref([]);
+const plannerOptions = ref([]);
 
 const isShow = computed({
   get() {
@@ -98,6 +175,94 @@
 });
 
 let { proxy } = getCurrentInstance()
+
+const validateNonNegativeSalaryQuota = (rule, value, callback) => {
+  if (value === '' || value === null || value === undefined) {
+    callback(new Error('璇疯緭鍏ヨ鍒掑伐鏃�'));
+    return;
+  }
+  const num = Number(value);
+  if (Number.isNaN(num) || num < 0) {
+    callback(new Error('璁″垝宸ユ椂涓嶈兘灏忎簬0'));
+    return;
+  }
+  callback();
+};
+
+const convertProductTree = list => {
+  return (list || []).map(item => {
+    const children = convertProductTree(item.children || item.childList || []);
+    return {
+      ...item,
+      value: item.id,
+      label: item.name || item.label,
+      children,
+      disabled: children.length > 0,
+    };
+  });
+};
+
+const findNodeById = (nodes, targetId) => {
+  for (const node of nodes || []) {
+    if (String(node.value) === String(targetId)) {
+      return node;
+    }
+    if (node.children && node.children.length > 0) {
+      const found = findNodeById(node.children, targetId);
+      if (found) return found;
+    }
+  }
+  return null;
+};
+
+const getProductCategoryOptions = async () => {
+  try {
+    const res = await productTreeList();
+    const list = Array.isArray(res) ? res : res?.data || [];
+    productCategoryOptions.value = convertProductTree(list);
+  } catch (e) {
+    productCategoryOptions.value = [];
+  }
+};
+
+const getModelOptions = async productId => {
+  if (!productId) {
+    modelOptions.value = [];
+    return;
+  }
+  try {
+    const res = await modelListPage({
+      id: productId,
+      current: 1,
+      size: 999,
+    });
+    const records = res?.records || res?.data?.records || [];
+    modelOptions.value = records;
+  } catch (e) {
+    modelOptions.value = [];
+  }
+};
+
+const getPlannerOptions = async () => {
+  try {
+    const res = await userListNoPageByTenantId();
+    plannerOptions.value = res?.data || [];
+  } catch (e) {
+    plannerOptions.value = [];
+  }
+};
+
+const handlePlannerChange = value => {
+  const selectedUser = plannerOptions.value.find(item => String(item.userId) === String(value));
+  formState.value.plannerName = selectedUser?.nickName || '';
+};
+
+const handleProductChange = async value => {
+  const selectedNode = findNodeById(productCategoryOptions.value, value);
+  formState.value.name = selectedNode?.label || '';
+  formState.value.productModelId = undefined;
+  await getModelOptions(value);
+};
 
 const closeModal = () => {
   isShow.value = false;
@@ -117,6 +282,11 @@
   })
 };
 
+onMounted(() => {
+  getProductCategoryOptions();
+  getPlannerOptions();
+});
+
 defineExpose({
   closeModal,
   handleSubmit,

--
Gitblit v1.9.3