tangjunhao vor 3 Monaten
Ursprung
Commit
8a7d26fa39

+ 49 - 0
src/style/index.css

@@ -245,4 +245,53 @@ img{
 
 .el-collapse-item__header:focus {
   outline: none;
+}
+
+.default-theme.splitpanes .splitpanes__pane{
+  background-color: transparent !important;
+}
+
+
+/* 取消所有表格中 el-input 的边框 */
+.el-table .el-input__wrapper {
+  box-shadow: none !important;
+  border: none !important;
+}
+
+.el-table td.el-table__cell div ,.el-table th.el-table__cell div{
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+/* 让输入框填满整个单元格 */
+.full-width-input .el-input__wrapper {
+  width: 100%;
+  height: 100%;
+  box-shadow: none !important; /* 去掉默认阴影边框 */
+  border: none !important;
+  padding: 0; /* 去掉内边距 */
+  border-radius: 0; /* 去掉圆角 */
+}
+
+/* 调整单元格内边距,使输入框贴合 */
+.el-table .cell {
+  padding: 0 !important;
+}
+
+/* 确保输入框高度和单元格一致 */
+.el-table td {
+  padding: 0 !important;
+}
+
+/* 让输入框文本居中 */
+.full-width-input .el-input__inner {
+  text-align: center !important;
+}
+
+.el-table td.el-table__cell div .el-select__wrapper{
+  width: 100%;
+}
+.el-table td.el-table__cell div .el-button{
+  width: 100%;
 }

+ 291 - 0
src/views/model/vueflow/aside/asideData.vue

@@ -0,0 +1,291 @@
+<template>
+  <el-container style="height: 100%">
+    <el-header class="panel-header">
+      <p>管网预览</p>
+      <el-button style="border: none" @click="closePanel">
+        <el-icon><Close /></el-icon>
+      </el-button>
+    </el-header>
+    <el-main>
+      <el-tabs v-model="activename" style="height: 100%">
+        <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>
+                <el-table-column prop="val" label="值">
+                  <template #default="{ row }">
+                    <el-select
+                      v-if="row.valueType === 1"
+                      v-model="row.val"
+                      placeholder="请选择"
+                      class="full-width-select"
+                    >
+                      <el-option
+                        v-for="option in row.options"
+                        :key="option.val"
+                        :label="option.tag"
+                        :value="option.val"
+                      >
+                      </el-option>
+                    </el-select>
+                    <el-input
+                      v-else-if="row.valueType === 2"
+                      v-model="row.val"
+                      class="full-width-input"
+                    />
+                    <el-button
+                      v-else-if="row.valueType === 3"
+                      @click="handleClick(row)"
+                    ></el-button>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="unit" label="单位" width="100">
+                  <template #default="{ row }">
+                    <el-select
+                      v-if="row.unitType !== '无'"
+                      v-model="row.unit"
+                      placeholder="请选择"
+                      class="full-width-select"
+                    >
+                      <el-option
+                        v-for="option in row.unitoptions"
+                        :key="option.val"
+                        :label="option.tag"
+                        :value="option.val"
+                      >
+                      </el-option>
+                    </el-select>
+                    <div v-else>{{ row.unitType }}</div>
+                  </template>
+                </el-table-column>
+              </el-table>
+            </Pane>
+            <Pane min-size="20" size="50" max-size="80">
+              <!-- <div>xia</div> -->
+            </Pane>
+          </Splitpanes>
+        </el-tab-pane>
+        <el-tab-pane label="模拟数据" name="simulatedata" style="height: 100%">
+          <Splitpanes horizontal>
+            <Pane min-size="20" size="50" max-size="80">
+              <div>shang</div>
+            </Pane>
+            <Pane min-size="20" size="50" max-size="80">
+              <div>xia</div>
+            </Pane>
+          </Splitpanes>
+        </el-tab-pane>
+      </el-tabs>
+    </el-main>
+    
+    <!-- 用于数据按钮table -->
+    <el-dialog
+      v-model="paneTabledialog"
+      align-center
+      :append-to-body="true"
+      width="500"
+      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>
+        </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-table>
+      
+      <template #footer>
+        <span class="lastbtn">
+          <el-button @click="paneTabledialog = false">{{
+            $t("dialog.cancel")
+          }}</el-button>
+          <el-button type="primary" >
+            {{ $t("dialog.ok") }}
+          </el-button>
+        </span>
+      </template>
+    </el-dialog>
+
+    <!-- 用于数据按钮键值对 -->
+    <el-dialog
+      v-model="paneKVdialog"
+      align-center
+      :append-to-body="true"
+      width="500"
+      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>
+        </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>
+      
+      <template #footer>
+        <span class="lastbtn">
+          <el-button @click="paneKVdialog = false">{{
+            $t("dialog.cancel")
+          }}</el-button>
+          <el-button type="primary" >
+            {{ $t("dialog.ok") }}
+          </el-button>
+        </span>
+      </template>
+    </el-dialog>
+
+  </el-container>
+</template>
+<script setup>
+import { Splitpanes, Pane } from "splitpanes"
+import "splitpanes/dist/splitpanes.css"
+import { Close } from "@element-plus/icons-vue"
+import { request } from "@/utils/request"
+import {
+  ElMessage,
+  ElButton,
+  ElDialog,
+  ElSelect,
+  ElMessageBox
+} from "element-plus"
+
+const activename = ref("data")
+
+const emit = defineEmits(["close"])
+
+const comdata = ref()
+const paneTabledialog = ref(false)
+const paneKVdialog = ref(false)
+
+// data表格按钮点击弹窗表格
+const tableColumns = ref([]);
+const tableData = ref([]);
+
+const closePanel = () => {
+  emit("close")
+}
+
+const getcomdata = (pcId) => {
+  const params = {
+    transCode: "ES0009",
+    pcId: pcId
+  }
+
+  request(params)
+    .then((res) => {
+      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 {
+          }
+
+          if (item.unitType !== "无") {
+            getlistopt(item, "unit")
+          }
+        }
+      })
+    })
+    .catch((err) => {
+      console.error(err)
+      ElMessage.error("初始化失败")
+    })
+}
+
+const getbtnvalue = (pcaId,dataType) => {
+  const params = {
+    transCode: "ES0010",
+    pcaId: pcaId
+  }
+  request(params)
+    .then((res) => {
+      console.log(`值获取成功 [${pcaId}]:`, res)
+      if(dataType === 1){
+        tableColumns.value = res.headers || [];
+        tableData.value = res.datas || [];
+      }
+      else {
+
+      }
+    })
+    .catch((err) => {
+      ElMessage.error("值初始化失败")
+    })
+}
+
+const getlistopt = (item, gettype) => {
+  let params = {}
+  if (gettype === "value") {
+    params = {
+      transCode: "BES001",
+      type: item.valueDef
+    }
+  } else {
+    params = {
+      transCode: "BES001",
+      type: item.unitType
+    }
+  }
+  request(params)
+    .then((res) => {
+      console.log("选项获取成功", res)
+
+      if (gettype === "value") {
+        item.val = res.rows[0].val
+        item.options = res.rows || []
+      } else {
+        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;
+  const dataType = row.dataType;
+  getbtnvalue(pcaId,dataType)
+}
+
+defineExpose({
+  getcomdata
+})
+</script>
+<style scoped>
+.panel-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.datatable {
+  width: 100%;
+  max-height: 300px;
+  overflow: auto;
+}
+</style>

+ 1 - 4
src/views/model/vueflow/defaultnode.vue

@@ -7,9 +7,6 @@ const props = defineProps({
     required: true,
   },
 })
-const nodeData = toRef(props.node, 'data') // 保留响应式引用
-
-const idCodeser = computed(() => nodeData.value?.idCodeser || '')
 onMounted(() => {
 });
 </script>
@@ -18,7 +15,7 @@ onMounted(() => {
   <div v-if="props.node.data!=null">
     <div class="custom-node icons  " :id="`node-${node.id}`"  >
       <img :src="props.node.data.image"/>
-      <span>{{idCodeser }}</span>
+      <span>{{props.node.data.idCodeser }}</span>
     </div>
   <Handle id="target-a" type="source" :position="Position.Right"  />
   <Handle id="target-c" type="source" :position="Position.Top"  /> 

+ 43 - 6
src/views/model/vueflow/index.vue

@@ -1,4 +1,6 @@
 <template>
+  <splitpanes class="default-theme">
+    <pane min-size="50" size="100" max-size="100">
   <VueFlow ref="vueFlowRef" v-model:nodes="nodes" v-model:edges="edges"  :class="{ dark }"
     class="basic-flow" 
     :default-viewport="{ zoom: 1.5 }" :min-zoom="0.2" :max-zoom="2.5" @drop="customOnDrop"
@@ -15,8 +17,7 @@
       <PointOnlyNode :node="props" :key="props.data.idCodeser || props.id"/>
     </template>
 
-    <Background pattern-color="#aaa" :gap="16" 
-    />
+    <Background pattern-color="#aaa" :gap="16" />
 
     <Controls position="top-left">
       <ControlButton title="重置" @click="resetTransform">
@@ -45,6 +46,11 @@
     </Controls>
     
   </VueFlow>
+    </pane>
+    <pane v-if="showPanel" min-size="20" :size=30 max-size="50" class="flow-panel">
+      <asideData ref="asideDataref" @close="closePanel"/>
+    </pane>
+  </splitpanes>
 </template>
 
 <script setup>
@@ -57,6 +63,7 @@ import {
   Histogram,
   DeleteFilled,
   Crop,
+  Close,
 } from '@element-plus/icons-vue'
 
 import { request, uploadFile } from "@/utils/request";
@@ -70,6 +77,9 @@ import changebak from './changebak.vue'
 import { useProjectStore } from '@/store/project'
 import emitter from "@/utils/emitter";
 import { onMounted } from 'vue';
+import { Splitpanes, Pane } from 'splitpanes'
+import 'splitpanes/dist/splitpanes.css'
+import asideData from './aside/asideData.vue';
 
 const { onInit, onNodeDragStop, onConnect, addEdges, setViewport, toObject,addNodes,updateEdgeData,onConnectStart,updateNode,updateNodeInternals} = useVueFlow()
 
@@ -99,6 +109,8 @@ let midNodeCounter = 0;//储存中间节点的序号
 const projectStore = useProjectStore()
 let pid = computed(() => projectStore.pid || '')
 
+const showPanel = ref(false)
+const asideDataref = ref()
 
 // 旧数据存储
 let prevNodes = [...nodes.value];
@@ -342,6 +354,16 @@ const onNodeClick = (event) => {
 
 const onNodeDoubleClick = (event) => {
   console.log('节点被双击:', event);
+  
+  showPanel.value = true;
+  const pcId = event.node.data.pcId;
+  nextTick(() => {
+    console.log("diaoy",pcId)
+      if (asideDataref.value) {
+        asideDataref.value.getcomdata(pcId);
+      }
+    });
+  
 };
 
 const onEdgeDoubleClick = (event) => {
@@ -488,10 +510,6 @@ onConnect(async (connection) => {
       const {pcId: npcId ,ser ,idCode} = await createCom3(pid.value);
 
       const pointNode = nodes.value.find(n => n.id === pointNodeId);
-      // if (pointNode) {
-      //   pointNode.data.pcId = npcId; // 写入 data
-      //   pointNode.data.idCodeser = `${idCode}${ser}`;
-      // }
       updateNode(pointNodeId, (node) => ({
         ...node,
         data: {
@@ -639,6 +657,14 @@ onMounted(() => {
 });
 
 
+const closePanel = () => {
+  setTimeout(() => {
+    showPanel.value = false
+  }, 100) // 延迟 100ms 销毁组件,避免 Splitpanes 销毁错误
+}
+
+
+
 </script>
 
 <style scoped>
@@ -714,4 +740,15 @@ onMounted(() => {
   display: flex;
 }
 
+</style>
+
+<!-- 用于侧栏pane -->
+<style scoped>
+.flow-panel {
+  font-size:14px;
+}
+
+
+
+
 </style>

+ 0 - 7
src/views/model/vueflow/useDnD.js

@@ -188,9 +188,6 @@ export default function useDragAndDrop() {
     try {
       // 等待 createComponent 完成再继续执行
       const { pcId, ser, idCode } = await createComponent(pid, nid)
-
-      // 更新前检查节点
-      console.log('更新前的节点:', findNode(nodeId))
       updateNode(nodeId, (node) => ({
         ...node,
         data: {
@@ -200,10 +197,6 @@ export default function useDragAndDrop() {
         }
       }))
       updateNodeInternals(nodeId);
-      // 更新后检查节点
-      nextTick(() => {
-        console.log('更新后的节点:', findNode(nodeId))
-      })
     } catch (err) {
       console.error("添加组件失败:", err.message)
       ElMessage.error("添加组件失败")