From 8a188440894cfd7d155084c453955c36be604c7a Mon Sep 17 00:00:00 2001
From: chenhj <1263187585@qq.com>
Date: 星期五, 26 十二月 2025 09:39:52 +0800
Subject: [PATCH] 产品选项

---
 src/api/basicData/product.js                                      |    8 +
 src/api/productionManagement/productStructure.js                  |   18 ++
 src/api/productionManagement/productionProcess.js                 |    8 +
 src/views/productionManagement/productStructure/StructureEdit.vue |  247 +++++++++++++++++++++++++++++++++++
 src/views/productionManagement/productStructure/index.vue         |  104 ++++++++++++++
 5 files changed, 385 insertions(+), 0 deletions(-)

diff --git a/src/api/basicData/product.js b/src/api/basicData/product.js
index 10f8fd1..3be642d 100644
--- a/src/api/basicData/product.js
+++ b/src/api/basicData/product.js
@@ -56,3 +56,11 @@
         params: query
     })
 }
+
+export function modelPage(query) {
+    return request({
+        url: '/basic/product/pageModel',
+        method: 'get',
+        params: query
+    })
+}
diff --git a/src/api/productionManagement/productStructure.js b/src/api/productionManagement/productStructure.js
new file mode 100644
index 0000000..ce2c31f
--- /dev/null
+++ b/src/api/productionManagement/productStructure.js
@@ -0,0 +1,18 @@
+// 浜у搧缁撴瀯椤甸潰鎺ュ彛
+import request from "@/utils/request";
+
+// 鍒嗛〉鏌ヨ
+export function queryList(id) {
+  return request({
+    url: "/productStructure/" + id,
+    method: "get",
+  });
+}
+
+export function add(data) {
+  return request({
+    url: "/productStructure",
+    method: "post",
+    data: data,
+  });
+}
\ No newline at end of file
diff --git a/src/api/productionManagement/productionProcess.js b/src/api/productionManagement/productionProcess.js
index 28e268a..c5f1f23 100644
--- a/src/api/productionManagement/productionProcess.js
+++ b/src/api/productionManagement/productionProcess.js
@@ -32,4 +32,12 @@
     method: 'put',
     data: data,
   })
+}
+
+// 宸ュ簭鏌ヨ
+export function list() {
+    return request({
+        url: "/productProcess/list",
+        method: "get",
+    });
 }
\ No newline at end of file
diff --git a/src/views/productionManagement/productStructure/StructureEdit.vue b/src/views/productionManagement/productStructure/StructureEdit.vue
new file mode 100644
index 0000000..c202473
--- /dev/null
+++ b/src/views/productionManagement/productStructure/StructureEdit.vue
@@ -0,0 +1,247 @@
+<template>
+  <el-dialog
+      v-model="visible"
+      title="Tips"
+      width="500"
+      :before-close="visible = false"
+  >
+    <el-form
+        ref="form"
+        :model="dataValue"
+        label-width="80px"
+    >
+      <el-table :data="dataValue.dataList" style="width: 100%">
+        <el-table-column prop="productName" label="浜у搧" width="180" />
+        <el-table-column prop="model" label="瑙勬牸" width="180">
+          <template #default="{ row, index }">
+            <el-form-item
+                :prop="`dataList.${index}.model`"
+                :rules="[{ required: true, message: '璇烽�夋嫨瑙勬牸', trigger: ['blur','change'] }]"
+                style="margin: 0"
+            >
+              <el-input
+                  v-model="dataValue.dataList[index].model"
+                  placeholder="璇烽�夋嫨浜у搧"
+                  readonly
+                  @focus="() => {
+              dataValue.currentRowIndex = index
+              showModel = true
+            }"
+              />
+            </el-form-item>
+          </template>
+        </el-table-column>
+
+        <el-table-column prop="processName" label="娑堣�楀伐搴�" width="180">
+          <template #default="{ row, index }">
+            <el-form-item
+                :prop="`dataList.${index}.processId`"
+                :rules="[{ required: true, message: '璇烽�夋嫨娑堣�楀伐搴�', trigger: 'change' }]"
+                style="margin: 0"
+            >
+              <el-select
+                  v-model="dataValue.dataList[index].processId"
+                  placeholder="璇烽�夋嫨"
+                  filterable
+                  clearable
+                  style="width: 100%"
+              >
+                <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="dataValue.dataList[index].unitQuantity"
+                  :min="0"
+                  :precision="2"
+                  :step="1"
+                  controls-position="right"
+                  style="width: 100%"
+              />
+            </el-form-item>
+          </template>
+        </el-table-column>
+
+        <el-table-column 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="dataValue.dataList[index].demandedQuantity"
+                  :min="0"
+                  :precision="2"
+                  :step="1"
+                  controls-position="right"
+                  style="width: 100%"
+              />
+            </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="dataValue.dataList[index].unit"
+                  placeholder="璇疯緭鍏ュ崟浣�"
+                  clearable
+              />
+            </el-form-item>
+          </template>
+        </el-table-column>
+
+        <el-table-column prop="address" label="鐩樻暟锛堢洏锛�">
+          <template #default="{ row, index }">
+            <el-form-item
+                :prop="`dataList.${index}.address`"
+                :rules="[{ required: true, message: '璇疯緭鍏ョ洏鏁�', trigger: ['blur','change'] }]"
+                style="margin: 0"
+            >
+              <el-input-number
+                  v-model="dataValue.dataList[index].address"
+                  :min="0"
+                  :precision="0"
+                  :step="1"
+                  controls-position="right"
+                  style="width: 100%"
+              />
+            </el-form-item>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="鎿嶄綔">
+          <template #default="{ row, index }">
+            <el-button
+                type="danger"
+                icon="el-icon-delete"
+                circle
+                @click="dataValue.dataList.splice(index, 1)"
+            >鍒犻櫎
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-form>
+
+    <product-select-dialog
+        v-if="dataValue.showProductDialog"
+        :model-value="dataValue.showProductDialog"
+        @confirm="handleProduct"/>
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button @click="visible = false">鍙栨秷</el-button>
+        <el-button type="primary" :loading="dataValue.loading" @click="submit">
+          纭
+        </el-button>
+      </div>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup lang="ts">
+import {computed, defineComponent, onMounted, reactive, ref} from "vue";
+import {queryList, add} from '@/api/productionManagement/productStructure.js'
+import {list} from '@/api/productionManagement/productionProcess'
+import {ElMessage} from "element-plus";
+
+
+defineComponent({
+  name: "StructureEdit",
+})
+
+const ProductSelectDialog = () => import('@/views/basicData/product/ProductSelectDialog.vue')
+const from = ref()
+
+
+const props = defineProps({
+  showModel: {
+    type: Boolean,
+    default: false
+  },
+  productModelId: {
+    type: Number,
+    required: true
+  }
+})
+
+const emits = defineEmits(['update:visible'])
+const visible = computed({
+  get() {
+    return props.showModel
+  },
+  set(val) {
+    emits('update:visible', val)
+  }
+})
+
+const dataValue = reactive({
+  dataList: [],
+  productOptions: [],
+  processOptions: [],
+  showProductDialog: false,
+  currentRowIndex: null,
+  loading: false,
+});
+
+const fetchData = async () => {
+  const {data} = await queryList(props.productModelId)
+  dataValue.dataList = data
+}
+
+const fetchProcessOptions = async () => {
+  const {data} = await list(props.productModelId)
+  dataValue.processOptions = data
+}
+
+const handleProduct = (row) => {
+  dataValue.showProductDialog = false
+  dataValue.dataList[dataValue.currentRowIndex].speculativeTradingName = row.productName + '-' + row.model
+  dataValue.dataList[dataValue.currentRowIndex].productModelId = row.id
+}
+
+const submit = () => {
+  from.value.validate(valid => {
+    dataValue.loading = true
+    if (valid) {
+      add({
+        productModelId: props.productModelId,
+        dataList: dataValue.dataList
+      }).then(res => {
+        ElMessage.success('淇濆瓨鎴愬姛')
+        visible.value = false
+        dataValue.loading = false
+      })
+    }
+  }).finally(() => {
+    dataValue.loading = false
+  })
+}
+
+onMounted(() => {
+  fetchData()
+  fetchProcessOptions()
+})
+
+
+</script>
\ No newline at end of file
diff --git a/src/views/productionManagement/productStructure/index.vue b/src/views/productionManagement/productStructure/index.vue
new file mode 100644
index 0000000..44fae1c
--- /dev/null
+++ b/src/views/productionManagement/productStructure/index.vue
@@ -0,0 +1,104 @@
+<template>
+  <div class="app-container">
+    <PIMTable
+        rowKey="id"
+        :column="tableColumn"
+        :tableData="tableData"
+        :page="page"
+        :isSelection="true"
+        @selection-change="handleSelectionChange"
+        :tableLoading="tableLoading"
+        @pagination="pagination"
+    >
+      <template #detail="{row}">
+        <el-button
+            type="primary"
+            text
+            @click="() =>{
+              currentRowId = row.id;
+              showEdit = true;
+            }"
+        >{{ row.productName }}
+        </el-button>
+      </template>
+    </PIMTable>
+    <StructureEdit v-if="showEdit" v-model:show-model="showEdit" :product-model-id="currentRowId"/>
+  </div>
+</template>
+
+<script setup>
+import {ref} from "vue";
+import {
+  modelPage,
+} from "@/api/basicData/product.js";
+
+const StructureEdit = () => import('@/views/productionManagement/productStructure/StructureEdit.vue')
+
+const tableColumn = ref([
+  {
+    label: "浜у搧鍚嶇О",
+    prop: "productName",
+    dataType: 'slot',
+    slot: "detail"
+  },
+  {
+    label: "瑙勬牸鍨嬪彿",
+    prop: "model",
+  },
+  {
+    label: "鍗曚綅",
+    prop: "unit",
+  }
+]);
+const tableData = ref([]);
+const tableLoading = ref(false);
+const showEdit = ref(false);
+const selectedRows = ref([]);
+const currentRowId = ref(0);
+const page = reactive({
+  current: 1,
+  size: 10,
+  total: 0,
+});
+const data = reactive({
+  form: {
+    productName: "",
+  },
+  rules: {
+    productName: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
+  },
+  modelForm: {
+    otherModel: '',
+    model: "",
+    unit: "",
+    speculativeTradingName: [],
+  },
+});
+const {form, rules} = toRefs(data);
+// 琛ㄦ牸閫夋嫨鏁版嵁
+const handleSelectionChange = (selection) => {
+  selectedRows.value = selection;
+};
+
+// 鏌ヨ瑙勬牸鍨嬪彿
+const pagination = (obj) => {
+  page.current = obj.page;
+  page.size = obj.limit;
+  getModelList();
+};
+const getModelList = () => {
+  tableLoading.value = true;
+  modelPage({
+    current: page.current,
+    size: page.size,
+  }).then((res) => {
+    console.log("res", res);
+    tableData.value = res.records;
+    page.total = res.total;
+    tableLoading.value = false;
+  });
+};
+onMounted(() => {
+  getModelList();
+})
+</script>

--
Gitblit v1.9.3