From cac302f302084ab310d0e35339f30966a4829a4e Mon Sep 17 00:00:00 2001
From: chenhj <1263187585@qq.com>
Date: 星期五, 23 一月 2026 12:18:28 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_New' into dev_New

---
 src/views/productionManagement/productStructure/Detail/index.vue |  300 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 300 insertions(+), 0 deletions(-)

diff --git a/src/views/productionManagement/productStructure/Detail/index.vue b/src/views/productionManagement/productStructure/Detail/index.vue
new file mode 100644
index 0000000..20a472b
--- /dev/null
+++ b/src/views/productionManagement/productStructure/Detail/index.vue
@@ -0,0 +1,300 @@
+<template>
+  <div class="app-container">
+    <PageHeader content="浜у搧缁撴瀯璇︽儏">
+      <template #right-button>
+        <el-button v-if="dataValue.isEdit && !isOrderPage"
+                   type="primary"
+                   @click="addItem">娣诲姞
+        </el-button>
+        <el-button v-if="!dataValue.isEdit && !isOrderPage"
+                   type="primary"
+                   @click="dataValue.isEdit = true">缂栬緫
+        </el-button>
+        <el-button v-if="dataValue.isEdit && !isOrderPage"
+                   type="primary"
+                   @click="cancelEdit">鍙栨秷
+        </el-button>
+        <el-button v-if="!isOrderPage"
+                   type="primary"
+                   :loading="dataValue.loading"
+                   @click="submit"
+                   :disabled="!dataValue.isEdit">纭
+        </el-button>
+      </template>
+    </PageHeader>
+    <el-table
+        :data="tableData"
+        border
+        :preserve-expanded-content="false"
+        :default-expand-all="true"
+        style="width: 100%"
+    >
+      <el-table-column type="expand">
+        <template #default="props">
+          <el-form ref="form"
+                   :model="dataValue">
+            <el-table :data="dataValue.dataList"
+                      style="width: 100%">
+              <el-table-column prop="productName"
+                               label="浜у搧"/>
+              <el-table-column prop="model"
+                               label="瑙勬牸">
+                <template #default="{ row, $index }">
+                  <el-form-item v-if="dataValue.isEdit"
+                                :prop="`dataList.${$index}.model`"
+                                :rules="[{ required: true, message: '璇烽�夋嫨瑙勬牸', trigger: ['blur','change'] }]"
+                                style="margin: 0">
+                    <el-select v-model="row.model"
+                               placeholder="璇烽�夋嫨瑙勬牸"
+                               clearable
+                               :disabled="!dataValue.isEdit"
+                               style="width: 100%"
+                               @visible-change="(v) => { if (v) openDialog($index) }">
+                      <el-option v-if="row.model"
+                                 :label="row.model"
+                                 :value="row.model" />
+                    </el-select>
+                  </el-form-item>
+                </template>
+              </el-table-column>
+              <el-table-column prop="processId"
+                               label="娑堣�楀伐搴�">
+                <template #default="{ row, $index }">
+                  <el-form-item :prop="`dataList.${$index}.processId`"
+                                :rules="[{ required: true, message: '璇烽�夋嫨娑堣�楀伐搴�', trigger: 'change' }]"
+                                style="margin: 0">
+                    <el-select v-model="row.processId"
+                               placeholder="璇烽�夋嫨"
+                               filterable
+                               clearable
+                               style="width: 100%"
+                               :disabled="!dataValue.isEdit">
+                      <el-option v-for="item in dataValue.processOptions"
+                                 :key="item.id"
+                                 :label="item.name"
+                                 :value="item.id" />
+                    </el-select>
+                  </el-form-item>
+                </template>
+              </el-table-column>
+              <el-table-column prop="unitQuantity"
+                               label="鍗曚綅浜у嚭鎵�闇�鏁伴噺">
+                <template #default="{ row, $index }">
+                  <el-form-item :prop="`dataList.${$index}.unitQuantity`"
+                                :rules="[{ required: true, message: '璇疯緭鍏ュ崟浣嶄骇鍑烘墍闇�鏁伴噺', trigger: ['blur','change'] }]"
+                                style="margin: 0">
+                    <el-input-number v-model="row.unitQuantity"
+                                     :min="0"
+                                     :precision="2"
+                                     :step="1"
+                                     controls-position="right"
+                                     style="width: 100%"
+                                     :disabled="!dataValue.isEdit" />
+                  </el-form-item>
+                </template>
+              </el-table-column>
+              <el-table-column v-if="isOrderPage"
+                               prop="demandedQuantity"
+                               label="闇�姹傛�婚噺">
+                <template #default="{ row, $index }">
+                  <el-form-item :prop="`dataList.${$index}.demandedQuantity`"
+                                :rules="[{ required: true, message: '璇疯緭鍏ラ渶姹傛�婚噺', trigger: ['blur','change'] }]"
+                                style="margin: 0">
+                    <el-input-number v-model="row.demandedQuantity"
+                                     :min="0"
+                                     :precision="2"
+                                     :step="1"
+                                     controls-position="right"
+                                     style="width: 100%"
+                                     :disabled="!dataValue.isEdit" />
+                  </el-form-item>
+                </template>
+              </el-table-column>
+              <el-table-column prop="unit"
+                               label="鍗曚綅">
+                <template #default="{ row, $index }">
+                  <el-form-item :prop="`dataList.${$index}.unit`"
+                                :rules="[{ required: true, message: '璇疯緭鍏ュ崟浣�', trigger: ['blur','change'] }]"
+                                style="margin: 0">
+                    <el-input v-model="row.unit"
+                              placeholder="璇疯緭鍏ュ崟浣�"
+                              clearable
+                              :disabled="!dataValue.isEdit" />
+                  </el-form-item>
+                </template>
+              </el-table-column>
+              <el-table-column label="鎿嶄綔" fixed="right" width="100">
+                <template #default="{ row, $index }">
+                  <el-button v-if="dataValue.isEdit"
+                             type="danger"
+                             text
+                             @click="dataValue.dataList.splice($index, 1)">鍒犻櫎
+                  </el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+          </el-form>
+        </template>
+      </el-table-column>
+      <el-table-column label="BOM缂栧彿" prop="bomNo" />
+      <el-table-column label="浜у搧鍚嶇О" prop="productName" />
+      <el-table-column label="瑙勬牸鍨嬪彿" prop="model" />
+    </el-table>
+
+    <product-select-dialog v-if="dataValue.showProductDialog"
+                           v-model:model-value="dataValue.showProductDialog"
+                           @confirm="handleProduct" />
+  </div>
+</template>
+
+<script setup lang="ts">
+import {
+  computed,
+  defineAsyncComponent,
+  defineComponent,
+  onMounted,
+  reactive,
+  ref,
+} from "vue";
+import { queryList, add } from "@/api/productionManagement/productStructure.js";
+import { listProcessBom } from "@/api/productionManagement/productionOrder.js";
+import { list } from "@/api/productionManagement/productionProcess";
+import { ElMessage } from "element-plus";
+import {useRoute, useRouter} from "vue-router";
+
+defineComponent({
+  name: "StructureEdit",
+});
+
+const ProductSelectDialog = defineAsyncComponent(
+    () => import("@/views/basicData/product/ProductSelectDialog.vue")
+);
+const form = ref();
+
+const route = useRoute()
+const router = useRouter()
+const routeId = computed({
+  get() {
+    return route.query.id;
+  },
+
+  set(val) {
+    emit('update:router', val)
+  }
+});
+
+// 浠庤矾鐢卞弬鏁拌幏鍙栦骇鍝佷俊鎭�
+const routeBomNo = computed(() => route.query.bomNo || '');
+const routeProductName = computed(() => route.query.productName || '');
+const routeProductModelName = computed(() => route.query.productModelName || '');
+const routeOrderId = computed(() => route.query.orderId);
+const pageType = computed(() => route.query.type);
+const isOrderPage = computed(() => pageType.value === 'order' && routeOrderId.value);
+
+const dataValue = reactive({
+  dataList: [],
+  productOptions: [],
+  processOptions: [],
+  showProductDialog: false,
+  currentRowIndex: null,
+  loading: false,
+  isEdit: false,
+});
+
+const tableData = reactive([
+  {
+    productName: "",
+    model: "",
+    bomNo: "",
+  }
+])
+
+const openDialog = index => {
+  dataValue.currentRowIndex = index;
+  dataValue.showProductDialog = true;
+};
+
+const fetchData = async () => {
+  if (isOrderPage.value) {
+    // 璁㈠崟鎯呭喌锛氫娇鐢ㄨ鍗曠殑浜у搧缁撴瀯鎺ュ彛
+    const { data } = await listProcessBom({ orderId: routeOrderId.value });
+    dataValue.dataList = data || [];
+  } else {
+    // 闈炶鍗曟儏鍐碉細浣跨敤鍘熸潵鐨勬帴鍙�
+    const { data } = await queryList(routeId.value);
+    dataValue.dataList = data || [];
+  }
+};
+
+const fetchProcessOptions = async () => {
+  const { data } = await list(routeId.value);
+  dataValue.processOptions = data;
+};
+
+const handleProduct = row => {
+  if (row?.length > 1) {
+    ElMessage.error("鍙兘閫夋嫨涓�涓骇鍝�");
+  }
+  dataValue.dataList[dataValue.currentRowIndex].productName =
+      row[0].productName;
+  dataValue.dataList[dataValue.currentRowIndex].model = row[0].model;
+  dataValue.dataList[dataValue.currentRowIndex].productModelId = row[0].id;
+  dataValue.dataList[dataValue.currentRowIndex].unit = row[0].unit || "";
+  dataValue.showProductDialog = false;
+};
+
+const submit = () => {
+  form.value
+      .validate(valid => {
+        dataValue.loading = true;
+        if (valid) {
+          add({
+            bomId: routeId.value,
+            productStructureList: dataValue.dataList || [],
+          }).then(res => {
+            router.push({
+              path: '/productionManagement/productionManagement/productStructure/index',
+            })
+            ElMessage.success("淇濆瓨鎴愬姛");
+            dataValue.loading = false;
+          });
+        }
+      })
+      .finally(() => {
+        dataValue.loading = false;
+      });
+};
+
+const addItem = () => {
+  dataValue.dataList.push({
+    productName: "",
+    productId: "",
+    model: undefined,
+    productModelId: undefined,
+    processId: "",
+    unitQuantity: 0,
+    demandedQuantity: 0,
+    unit: "",
+  });
+};
+
+const cancelEdit = () => {
+  dataValue.isEdit = false;
+  dataValue.dataList = dataValue.dataList.filter(item => item.id !== undefined);
+};
+
+onMounted(() => {
+  // 浠庤矾鐢卞弬鏁板洖鏄炬暟鎹�
+  tableData[0].productName = routeProductName.value;
+  tableData[0].model = routeProductModelName.value;
+  tableData[0].bomNo = routeBomNo.value;
+  
+  // 璁㈠崟鎯呭喌涓嬬鐢ㄧ紪杈�
+  if (isOrderPage.value) {
+    dataValue.isEdit = false;
+  }
+  
+  fetchData();
+  fetchProcessOptions();
+});
+</script>
\ No newline at end of file

--
Gitblit v1.9.3