Răsfoiți Sursa

612属性弹窗

tangjunhao 3 luni în urmă
părinte
comite
5cf45204d0

+ 491 - 71
src/views/model/vueflow/aside/asideData.vue

@@ -11,7 +11,6 @@
         <el-tab-pane label="数据" name="data" style="height: 100%">
           <Splitpanes horizontal>
             <Pane min-size="20" size="50" max-size="80">
-              <!-- <div>shang</div> -->
               <el-table :data="comdata" border class="datatable">
                 <el-table-column type="index" width="40" label="" />
                 <el-table-column prop="name" label="属性"> </el-table-column>
@@ -85,24 +84,117 @@
       </el-tabs>
     </el-main>
 
-    <!-- 用于数据按钮键值对 -->
+    <!-- 用于数据按钮table -->
     <el-dialog
       v-model="paneTabledialog"
       align-center
       :append-to-body="true"
-      width="500"
+      width="700"
       class="dialog_class"
       draggable
     >
       <template #header="{ titleId, titleClass }">
         <div class="my-header">
           <!-- <el-image :src="icon" fit="contain"></el-image> -->
-          <h4 :id="titleId" :class="titleClass">{{ $t("dialog.new") }}</h4>
+          <h4 :id="titleId" :class="titleClass">{{ dialogname }}</h4>
         </div>
       </template>
-      <el-table :data="tableData" border style="width: 100%">
-        <el-table-colum prop="name" label="属性"></el-table-colum>
-        <el-table-colum prop="" label="值"></el-table-colum>
+      <el-row :gutter="10" style="margin-bottom: 10px">
+        <el-col :span="4"> </el-col>
+        <el-col :span="5"> </el-col>
+        <el-col :span="5">
+          <el-button class="btnwidth100" @click="handleAddRow">添加</el-button>
+        </el-col>
+        <el-col :span="5">
+          <el-button class="btnwidth100" @click="handleDeleteSelected"
+            >删除</el-button
+          >
+        </el-col>
+        <el-col :span="5">
+          <el-button class="btnwidth100" @click="handleInsertSelected"
+            >插入</el-button
+          >
+        </el-col>
+      </el-row>
+      <!-- <el-row :gutter="10" style="margin-bottom: 10px">
+        <el-col :span="4"> </el-col>
+        <el-col :span="5">
+          <el-button class="btnwidth100" @click="handleAddRow">添加</el-button>
+        </el-col>
+        <el-col :span="5">
+          <el-button class="btnwidth100" @click="handleDeleteSelected"
+            >删除</el-button
+          >
+        </el-col>
+        <el-col :span="5">
+          <el-button class="btnwidth100" @click="handleInsertSelected"
+            >插入</el-button
+          >
+        </el-col>
+        <el-col :span="5">
+          <el-button class="btnwidth100">修正</el-button>
+        </el-col>
+      </el-row> -->
+      <el-table
+        :data="tableData"
+        border
+        height="300"
+        style="width: 100%"
+        @row-click="handleRowClick"
+        highlight-current-row
+        ref="tableRef"
+      >
+        <el-table-column type="index" width="40"></el-table-column>
+        <el-table-column
+          v-for="col in tableColumns"
+          :key="col.code"
+          :label="col.name"
+          :min-width="200"
+        >
+          <template #header>
+            <div class="unitheader">
+              <div>{{ col.name }}</div>
+              <div style="width: 50%; min-width: 100px">
+                <el-select
+                  v-if="col.unit !== '无'"
+                  v-model="col.unit"
+                  size="small"
+                  @change="(val) => handleUnitChange(col, val)"
+                >
+                  <el-option
+                    v-for="opt in col.unitoptions"
+                    :key="opt.val"
+                    :label="opt.tag"
+                    :value="opt.val"
+                  />
+                </el-select>
+              </div>
+            </div>
+          </template>
+
+          <template #default="{ row }">
+            <el-select
+              v-if="col.valueType === 1"
+              v-model="row[col.code].value"
+              class="full-width-select"
+            >
+              <el-option
+                v-for="option in row[col.code].options"
+                :key="option.val"
+                :label="option.tag"
+                :value="option.val"
+              >
+              </el-option>
+            </el-select>
+            <el-input
+              v-else-if="col.valueType === 2"
+              v-model="row[col.code].value"
+              class="full-width-input"
+            />
+            <el-button v-else-if="col.valueType === 3"></el-button>
+            <div v-else>{{ col.valueDef }}</div>
+          </template>
+        </el-table-column>
       </el-table>
 
       <template #footer>
@@ -110,14 +202,14 @@
           <el-button @click="paneTabledialog = false">{{
             $t("dialog.cancel")
           }}</el-button>
-          <el-button type="primary">
+          <el-button type="primary" @click="saveTabelDialog()">
             {{ $t("dialog.ok") }}
           </el-button>
         </span>
       </template>
     </el-dialog>
 
-    <!-- 用于数据按钮table -->
+    <!-- 用于数据按钮键值对 -->
     <el-dialog
       v-model="paneKVdialog"
       align-center
@@ -129,18 +221,22 @@
       <template #header="{ titleId, titleClass }">
         <div class="my-header">
           <!-- <el-image :src="icon" fit="contain"></el-image> -->
-          <h4 :id="titleId" :class="titleClass">{{ $t("dialog.new") }}</h4>
+          <h4 :id="titleId" :class="titleClass">{{ dialogname }}</h4>
         </div>
       </template>
-      <el-table :data="tableData" border style="width: 100%">
-        <!-- 动态列 -->
-        <el-table-column
-          v-for="col in tableColumns"
-          :key="col.code"
-          :prop="col.code"
-          :label="col.name"
-          :min-width="100"
-        />
+      <el-table
+        :data="tableKVData"
+        border
+        height="300"
+        style="width: 100%"
+      >
+        <el-table-column type="index" label="编号" width="60"></el-table-column>
+        <el-table-column prop="property" label="属性"></el-table-column>
+        <el-table-column prop="value" label="值">
+          <template #default="{ row }">
+            <el-input v-model="row.value" class="full-width-input"></el-input>
+          </template>
+        </el-table-column>
       </el-table>
 
       <template #footer>
@@ -148,7 +244,7 @@
           <el-button @click="paneKVdialog = false">{{
             $t("dialog.cancel")
           }}</el-button>
-          <el-button type="primary">
+          <el-button type="primary" @click="saveKVTabelDialog">
             {{ $t("dialog.ok") }}
           </el-button>
         </span>
@@ -177,47 +273,58 @@ const titlename = ref()
 const comdata = ref()
 const paneTabledialog = ref(false)
 const paneKVdialog = ref(false)
+const dialogname = ref("")
 
 // data表格按钮点击弹窗表格
 const tableColumns = ref([])
 const tableData = ref([])
+let pcaId = ref("") //项目组件的属性id
+
+const tableKVData = ref([])
 
 const closePanel = () => {
   emit("close")
 }
 
-const getcomdata = (pcId) => {
+const getcomdata = async (pcId) => {
+  // 改为 async 函数
   const params = {
     transCode: "ES0009",
     pcId: pcId
   }
 
-  request(params)
-    .then((res) => {
-      titlename.value = `${res.name}${res.idCode}${res.ser}`
-      comdata.value = res.rows
-      console.log("comdata.value", comdata.value)
-
-      comdata.value.forEach((item) => {
-        if (item.pcaId) {
-          // 若为下拉类型,则获取选项
-          if (item.valueType === 1) {
-            getlistopt(item, "value")
-          } else {
-          }
+  try {
+    const res = await request(params) // 使用 await 等待请求完成
+    titlename.value = `${res.name}${res.idCode}${res.ser}`
+    comdata.value = res.rows
+    console.log("comdata.value", comdata.value)
 
-          if (item.unitType !== "无") {
-            getlistopt(item, "unit")
-          } else {
-            item.unit = "无"
-          }
-        }
-      })
-    })
-    .catch((err) => {
-      console.error(err)
-      ElMessage.error("初始化失败")
-    })
+    // 使用 for...of 循环以便使用 await
+    for (const item of comdata.value) {
+      if (!item.pcaId) continue
+
+      // 并行处理 value 和 unit 的初始化
+      const promises = []
+
+      if (item.valueType === 1) {
+        promises.push(getlistopt(item, "value"))
+      }
+
+      if (item.unitType !== "无") {
+        promises.push(getlistopt(item, "unit"))
+      } else {
+        item.unit = "无"
+      }
+
+      // 等待当前 item 的所有初始化完成
+      await Promise.all(promises)
+    }
+
+    console.log("所有数据初始化完成")
+  } catch (err) {
+    console.error("初始化失败:", err)
+    ElMessage.error("初始化失败")
+  }
 }
 
 const getbtnvalue = (pcaId, dataType) => {
@@ -225,21 +332,100 @@ const getbtnvalue = (pcaId, dataType) => {
     transCode: "ES0010",
     pcaId: pcaId
   }
+
   request(params)
-    .then((res) => {
-      console.log(`值获取成功 [${pcaId}]:`, res)
+    .then(async (res) => {
       if (dataType === 1) {
+        // 遍历 headers,初始化单位值
+        for (const header of res.headers) {
+          if (header.unitType !== "无") {
+            // 调用 getlistopt 获取单位选项并设置默认值
+            await getlistopt(header, "unit")
+          } else {
+            // 如果不需要单位,直接设置为"无"
+            header.unit = "无"
+            header.unitoptions = [] // 保持选项列表为空
+          }
+        }
+
+        // 设置表格列
         tableColumns.value = res.headers || []
-        tableData.value = res.datas || []
-      } else {
+
+        // 将 datas 按行号(pcadgId)分组,每行是一个对象
+        const rowMap = new Map()
+
+        res.datas?.forEach(async (item) => {
+          // 添加 async
+          const rowId = item.pcadgId
+          if (!rowMap.has(rowId)) {
+            rowMap.set(rowId, { pcadgId: rowId })
+          }
+
+          const header = res.headers.find((h) => h.cdvId === item.cdvId)
+          if (header) {
+            const row = rowMap.get(rowId)
+
+            // 如果是下拉类型,调用 getlistopt 获取选项
+            if (header.valueType === 1) {
+              await getlistopt(header, "value") // 获取选项并设置默认值
+              // 使用从 getlistopt 获取的 value(如果 item.value 为空)
+              row[header.code] = {
+                value: item.value || header.value, // 优先使用 item.value
+                unit: item.unit,
+                options: header.options, // 添加 options 到行数据
+                pcadgId: item.pcadgId,
+                pcadId: item.pcadId,
+                cdvId: item.cdvId
+              }
+            } else {
+              // 非下拉类型保持原样
+              row[header.code] = {
+                value: item.value,
+                unit: item.unit,
+                pcadgId: item.pcadgId,
+                pcadId: item.pcadId,
+                cdvId: item.cdvId
+              }
+            }
+          }
+        })
+
+        tableData.value = Array.from(rowMap.values())
+        console.log("tableData.value", tableData.value)
+      } else if (dataType === 2) {
+        // 处理属性-值对形式
+        const kvData = []
+        // 记录行号
+        let rowCount = 0;
+
+        res.headers?.forEach((header) => {
+          // 找到对应的数据项
+          const dataItem = res.datas?.find(
+            (item) => item.cdvId === header.cdvId
+          )
+          rowCount++;
+
+          kvData.push({
+            cdvId: header.cdvId,
+            property: header.name, // 属性名称
+            value: dataItem ? dataItem.value : "",
+            pcadgId: dataItem ? dataItem.pcadgId : "",
+            pcadId: rowCount,
+            unit: dataItem ? dataItem.unit : "无"
+          })
+        })
+
+        tableKVData.value = kvData
+        // console.log("tableKVData.value", tableKVData.value)
       }
     })
     .catch((err) => {
+      console.error('err',err)
       ElMessage.error("值初始化失败")
     })
 }
 
-const getlistopt = (item, gettype) => {
+const getlistopt = async (item, gettype) => {
   let params = {}
   if (gettype === "value") {
     params = {
@@ -252,33 +438,45 @@ const getlistopt = (item, gettype) => {
       type: item.unitType
     }
   }
-  request(params)
-    .then((res) => {
-      console.log("选项获取成功", res)
 
-      if (gettype === "value") {
-        if (item.value === undefined || item.value === null) {
-          item.value = res.rows?.[0]?.val ?? ""
-        }
-        item.options = res.rows || []
-      } else {
-        if (item.unit === undefined || item.unit === null) {
-          item.unit = res.rows?.[0]?.val ?? ""
-        }
-        item.unitoptions = res.rows || []
+  try {
+    const res = await request(params)
+    // console.log("选项获取成功", res)
+
+    if (gettype === "value") {
+      if (
+        item.value === undefined ||
+        item.value === null ||
+        item.value === ""
+      ) {
+        item.value = res.rows?.[0]?.val ?? ""
       }
-    })
-    .catch((err) => {
-      console.error("err", err)
-      ElMessage.error("选项初始化失败")
-    })
+      item.options = res.rows || []
+    } else if (gettype === "unit") {
+      if (item.unit === undefined || item.unit === null || item.unit === "") {
+        item.unit = res.rows?.[0]?.val ?? ""
+      }
+      item.unitoptions = res.rows || []
+    }
+  } catch (err) {
+    console.error("err", err)
+    ElMessage.error("选项初始化失败")
+  }
 }
 
 const handleClick = (row) => {
-  paneTabledialog.value = true
-  const pcaId = row.pcaId
+  dialogname.value = row.name
+
+  pcaId = row.pcaId
   const dataType = row.dataType
   getbtnvalue(pcaId, dataType)
+
+  if (dataType === 1) {
+    paneTabledialog.value = true
+    // console.log("tableColumns:", tableColumns.value)
+  } else if (dataType === 2) {
+    paneKVdialog.value = true
+  }
 }
 
 const savecomvalue = () => {
@@ -307,6 +505,214 @@ const savecomvalue = () => {
     })
 }
 
+//
+// 关于表格弹窗的操作
+//
+const tableRef = ref(null) // 表格引用
+const currentRow = ref(null) // 当前选中行
+
+// 创建新行的辅助函数
+const createNewRow = () => {
+  const rowIndex = tableData.value.length + 1
+  const newRow = {}
+  tableColumns.value.forEach((col) => {
+    newRow[col.code] = {
+      value: col.valueType === 1 ? col.options?.[0]?.val || "" : "",
+      unit: col.unit || "无",
+      options: col.valueType === 1 ? col.options : [],
+      pcadgId: rowIndex,
+      pcadId: "",
+      cdvId: col.cdvId
+    }
+  })
+  return newRow
+}
+
+const handleAddRow = () => {
+  const newRow = createNewRow()
+  tableData.value.push(newRow)
+  // 选中新添加的行
+  nextTick(() => {
+    currentRow.value = newRow
+    tableRef.value?.setCurrentRow(newRow)
+  })
+}
+
+// 处理行点击
+const handleRowClick = (row) => {
+  currentRow.value = row
+  // 高亮显示选中行
+  tableRef.value?.setCurrentRow(row)
+}
+
+// 删除选中行
+const handleDeleteSelected = () => {
+  if (!currentRow.value) {
+    ElMessage.warning("请先点击选择要删除的行")
+    return
+  }
+
+  const index = tableData.value.findIndex((row) => row === currentRow.value)
+  if (index !== -1) {
+    tableData.value.splice(index, 1)
+
+    // 更新后续行的 pcadgId
+    for (let i = index; i < tableData.value.length; i++) {
+      const newPcadgId = i + 1 // 行号从1开始
+
+      // 更新行中每个列的 pcadgId
+      tableColumns.value.forEach((col) => {
+        if (
+          tableData.value[i][col.code] &&
+          typeof tableData.value[i][col.code] === "object"
+        ) {
+          tableData.value[i][col.code].pcadgId = newPcadgId
+        }
+      })
+    }
+
+    // 删除后自动选中上一行或下一行(如果还有行)
+    if (tableData.value.length > 0) {
+      const newIndex = Math.min(index, tableData.value.length - 1)
+      currentRow.value = tableData.value[newIndex]
+      nextTick(() => {
+        tableRef.value?.setCurrentRow(currentRow.value)
+      })
+    } else {
+      currentRow.value = null
+    }
+  }
+}
+
+// 在选中行下方插入新行
+const handleInsertSelected = () => {
+  if (!currentRow.value && tableData.value.length > 0) {
+    ElMessage.warning("请先点击选择要插入的位置")
+    return
+  }
+
+  const index = currentRow.value
+    ? tableData.value.findIndex((row) => row === currentRow.value)
+    : -1
+
+  // 创建新行时使用正确的行号(插入位置+1)
+  const newRow = createNewRow()
+
+  // 插入新行
+  tableData.value.splice(index + 1, 0, newRow)
+
+  // 更新所有后续行的行号,包括该行
+  for (let i = index + 1; i < tableData.value.length; i++) {
+    const currentRowPcadgId = i + 1
+
+    // 更新行中每个列的 pcadgId
+    tableColumns.value.forEach((col) => {
+      if (tableData.value[i][col.code]) {
+        tableData.value[i][col.code].pcadgId = currentRowPcadgId
+      }
+    })
+  }
+
+  // 选中新插入的行
+  nextTick(() => {
+    currentRow.value = newRow
+    tableRef.value?.setCurrentRow(newRow)
+  })
+}
+
+const handleUnitChange = (column, newUnit) => {
+  // 更新表头的单位值
+  column.unit = newUnit
+
+  // 更新该列所有行的单位值
+  tableData.value.forEach((row) => {
+    if (row[column.code]) {
+      row[column.code].unit = newUnit
+    }
+  })
+}
+
+// 保存
+const saveTabelDialog = () => {
+  // 检查表格数据是否为空
+  if (!tableData.value || tableData.value.length === 0) {
+    ElMessage.warning("请设置正确的数据");
+    return;
+  }
+  console.log("表格数据:", tableData.value)
+  // 收集所有行数据
+  const formattedData = tableData.value.map((row) => {
+    // 收集当前行的所有字段数据
+    const rowFields = tableColumns.value.map((col) => {
+      const cellData = row[col.code]
+      if (!cellData) return ""
+
+      // 组装 cdvId-pcadgId-pcadId-value-unit 格式
+      return [
+        cellData.cdvId || "", // cdvId
+        cellData.pcadgId || "", // pcadgId (行号)
+        cellData.pcadId || "", // pcadId
+        cellData.value || "", // value
+        cellData.unit || "" // unit
+      ].join(",") // 字段间用逗号分隔
+    })
+
+    return rowFields.join(";") // 行内字段用分号分隔
+  })
+
+  // 最终数据用分号分隔各行
+  const result = formattedData.join(";")
+
+  // console.log("格式化后的表格数据:", result);
+
+  const params = {
+    transCode: "ES0011",
+    pcaId: pcaId,
+    pcadvals: result
+  }
+  request(params)
+    .then((res) => {
+      paneTabledialog.value = false
+      ElMessage.success("保存成功")
+    })
+    .catch((err) => {
+      console.error("err", err)
+      ElMessage.error("保存失败")
+    })
+}
+
+
+// 
+// 关于KV表格弹窗的操作
+//
+const saveKVTabelDialog = () => {
+  // 检查表格数据是否为空
+  if (!tableKVData.value || tableKVData.value.length === 0) {
+    ElMessage.warning("请设置正确的数据");
+    return;
+  }
+  console.log('表格数据:',tableKVData.value)
+  const result = tableKVData.value.map((item)=>{
+    return [item.cdvId, item.pcadgId, item.pcadId, item.value, item.unit].join(',')
+  }).join(";");
+  // console.log('格式化后的字符串:', result);
+  const params = {
+    transCode: "ES0011",
+    pcaId: pcaId,
+    pcadvals: result
+  }
+  request(params)
+    .then((res) => {
+      paneKVdialog.value = false
+      ElMessage.success("保存成功")
+    })
+    .catch((err) => {
+      console.error("err", err)
+      ElMessage.error("保存失败")
+    })
+}
+
+
 defineExpose({
   getcomdata
 })
@@ -330,4 +736,18 @@ defineExpose({
   align-items: center;
   padding: 10px 20px;
 }
+
+.unitheader {
+  width: 100%;
+  display: flex;
+  gap: 10px;
+}
+
+.unitheader :deep(.el-select__wrapper) {
+  width: 100%;
+}
+
+.btnwidth100 {
+  width: 100%;
+}
 </style>

+ 1 - 1
src/views/model/vueflow/pointonlynode.vue

@@ -23,7 +23,7 @@ const props = defineProps({
 <style scoped>
 .icons img{
     width: 8px;
-    margin-bottom: 5px;
+    margin-bottom: 7px;
 
 }
 .icons span{