liuqiao hai 11 meses
pai
achega
c0454b0af2

+ 109 - 0
package-lock.json

@@ -18,8 +18,11 @@
         "@vue-flow/node-resizer": "^1.4.0",
         "@vue-flow/node-toolbar": "^1.1.0",
         "axios": "^1.5.0",
+        "canvg": "^4.0.2",
         "echarts": "^5.4.3",
         "element-plus": "^2.3.14",
+        "html-to-image": "^1.11.11",
+        "html2canvas": "^1.4.1",
         "jquery": "^3.7.1",
         "js-cookie": "2.2.0",
         "mitt": "^3.0.1",
@@ -2743,6 +2746,11 @@
         "undici-types": "~5.26.4"
       }
     },
+    "node_modules/@types/raf": {
+      "version": "3.4.3",
+      "resolved": "https://registry.npmjs.org/@types/raf/-/raf-3.4.3.tgz",
+      "integrity": "sha512-c4YAvMedbPZ5tEyxzQdMoOhhJ4RD3rngZIdwC2/qDN3d7JpEhB6fiBRKVY1lg5B7Wk+uPBjn5f39j1/2MY1oOw=="
+    },
     "node_modules/@types/semver": {
       "version": "7.5.2",
       "resolved": "https://registry.npmmirror.com/@types/semver/-/semver-7.5.2.tgz",
@@ -3768,6 +3776,14 @@
       "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
       "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
     },
+    "node_modules/base64-arraybuffer": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
+      "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==",
+      "engines": {
+        "node": ">= 0.6.0"
+      }
+    },
     "node_modules/big.js": {
       "version": "5.2.2",
       "resolved": "https://registry.npmmirror.com/big.js/-/big.js-5.2.2.tgz",
@@ -3868,6 +3884,21 @@
       "integrity": "sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==",
       "peer": true
     },
+    "node_modules/canvg": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/canvg/-/canvg-4.0.2.tgz",
+      "integrity": "sha512-/7kIZger/mdFci4KXdtMr+NQB4GU1InkJ4RwSyDBRcvy4BUlg1hD+ZUWo550sWPyWaKZ8purqby6kjf09qVriw==",
+      "dependencies": {
+        "@types/raf": "^3.4.0",
+        "raf": "^3.4.1",
+        "rgbcolor": "^1.0.1",
+        "stackblur-canvas": "^2.0.0",
+        "svg-pathdata": "^6.0.3"
+      },
+      "engines": {
+        "node": ">=12.0.0"
+      }
+    },
     "node_modules/chalk": {
       "version": "4.1.2",
       "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
@@ -3990,6 +4021,14 @@
         "node": ">= 8"
       }
     },
+    "node_modules/css-line-break": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz",
+      "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
+      "dependencies": {
+        "utrie": "^1.0.2"
+      }
+    },
     "node_modules/cssesc": {
       "version": "3.0.0",
       "resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz",
@@ -5327,6 +5366,23 @@
         "he": "bin/he"
       }
     },
+    "node_modules/html-to-image": {
+      "version": "1.11.11",
+      "resolved": "https://registry.npmjs.org/html-to-image/-/html-to-image-1.11.11.tgz",
+      "integrity": "sha512-9gux8QhvjRO/erSnDPv28noDZcPZmYE7e1vFsBLKLlRlKDSqNJYebj6Qz1TGd5lsRV+X+xYyjCKjuZdABinWjA=="
+    },
+    "node_modules/html2canvas": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz",
+      "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
+      "dependencies": {
+        "css-line-break": "^2.1.0",
+        "text-segmentation": "^1.0.3"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
     "node_modules/ignore": {
       "version": "5.2.4",
       "resolved": "https://registry.npmmirror.com/ignore/-/ignore-5.2.4.tgz",
@@ -6188,6 +6244,11 @@
       "integrity": "sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==",
       "dev": true
     },
+    "node_modules/performance-now": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+      "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow=="
+    },
     "node_modules/picocolors": {
       "version": "1.0.0",
       "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz",
@@ -6336,6 +6397,14 @@
       "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
       "dev": true
     },
+    "node_modules/raf": {
+      "version": "3.4.1",
+      "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz",
+      "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==",
+      "dependencies": {
+        "performance-now": "^2.1.0"
+      }
+    },
     "node_modules/randombytes": {
       "version": "2.1.0",
       "resolved": "https://registry.npmmirror.com/randombytes/-/randombytes-2.1.0.tgz",
@@ -6502,6 +6571,14 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/rgbcolor": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/rgbcolor/-/rgbcolor-1.0.1.tgz",
+      "integrity": "sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw==",
+      "engines": {
+        "node": ">= 0.8.15"
+      }
+    },
     "node_modules/rimraf": {
       "version": "3.0.2",
       "resolved": "https://registry.npmmirror.com/rimraf/-/rimraf-3.0.2.tgz",
@@ -6801,6 +6878,14 @@
       "resolved": "https://registry.npmmirror.com/sprintf-js/-/sprintf-js-1.0.3.tgz",
       "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="
     },
+    "node_modules/stackblur-canvas": {
+      "version": "2.7.0",
+      "resolved": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-2.7.0.tgz",
+      "integrity": "sha512-yf7OENo23AGJhBriGx0QivY5JP6Y1HbrrDI6WLt6C5auYZXlQrheoY8hD4ibekFKz1HOfE48Ww8kMWMnJD/zcQ==",
+      "engines": {
+        "node": ">=0.1.14"
+      }
+    },
     "node_modules/stream-browserify": {
       "version": "3.0.0",
       "resolved": "https://registry.npmmirror.com/stream-browserify/-/stream-browserify-3.0.0.tgz",
@@ -6913,6 +6998,14 @@
         "node": ">= 0.4"
       }
     },
+    "node_modules/svg-pathdata": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npmjs.org/svg-pathdata/-/svg-pathdata-6.0.3.tgz",
+      "integrity": "sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==",
+      "engines": {
+        "node": ">=12.0.0"
+      }
+    },
     "node_modules/tapable": {
       "version": "2.2.1",
       "resolved": "https://registry.npmmirror.com/tapable/-/tapable-2.2.1.tgz",
@@ -6970,6 +7063,14 @@
         }
       }
     },
+    "node_modules/text-segmentation": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz",
+      "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
+      "dependencies": {
+        "utrie": "^1.0.2"
+      }
+    },
     "node_modules/text-table": {
       "version": "0.2.0",
       "resolved": "https://registry.npmmirror.com/text-table/-/text-table-0.2.0.tgz",
@@ -7312,6 +7413,14 @@
       "resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz",
       "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
     },
+    "node_modules/utrie": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz",
+      "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
+      "dependencies": {
+        "base64-arraybuffer": "^1.0.2"
+      }
+    },
     "node_modules/v-scale-screen": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/v-scale-screen/-/v-scale-screen-2.2.0.tgz",

+ 3 - 0
package.json

@@ -21,8 +21,11 @@
     "@vue-flow/node-resizer": "^1.4.0",
     "@vue-flow/node-toolbar": "^1.1.0",
     "axios": "^1.5.0",
+    "canvg": "^4.0.2",
     "echarts": "^5.4.3",
     "element-plus": "^2.3.14",
+    "html-to-image": "^1.11.11",
+    "html2canvas": "^1.4.1",
     "jquery": "^3.7.1",
     "js-cookie": "2.2.0",
     "mitt": "^3.0.1",

BIN=BIN
src/assets/flowimg/xuek10.png


BIN=BIN
src/assets/flowimg/xuek11.png


BIN=BIN
src/assets/flowimg/xuek12.png


BIN=BIN
src/assets/img/xuek10.png


BIN=BIN
src/assets/img/xuek11.png


BIN=BIN
src/assets/img/xuek12.png


+ 5 - 0
src/router/index.js

@@ -18,6 +18,11 @@ const router = createRouter({
               name: '首页',
               component: () => import('@/views/home/newfile.vue'),
             },
+            {
+              path: '/home/querylist',
+              name: '打开',
+              component: () => import('@/views/home/querylist.vue'),
+            },
             {
               path: '/home/savefile',
               name: 'savefile',

+ 14 - 14
src/views/home.vue

@@ -815,16 +815,16 @@
                   @click="activeIndex = index">{{ tab }}</span>
                 </div>
                 <div>
-                  <li
+                  <!-- <li
                     class="exloadbox"
                     v-show="elodingfalse"
                   >
                     <span>正在求解中</span>
                     <i class="el-icon-loading"></i>
-                  </li>
-                  <li>
+                  </li> -->
+                  <!-- <li>
                     <span >清空</span>
-                  </li>
+                  </li> -->
                   <li>
                     <span @click="footerShows('foot')">&#9650;&#9660;</span>
                   </li>
@@ -845,7 +845,7 @@
                   @click="activeIndex2 = index">{{ tab }}</li>
                 </ul>
                 <div  class="footer-content">
-                <div class="eldesign" v-if="activeIndex2==0">
+                <div class="eldesign classtable" v-if="activeIndex2==0">
                  <el-table :data="designtable" border style="width: 100%">
                   <el-table-column type="index" label="编号"  width="70" />
                   <el-table-column prop="name" label="变量名称">
@@ -881,7 +881,7 @@
                 </el-table>
                 
                 </div>
-                <div class="elconstraint" v-if="activeIndex2==1">
+                <div class="elconstraint classtable" v-if="activeIndex2==1">
                   <el-table :data="tableData" stripe style="width: 100%">
                   <el-table-column type="index" label="编号"  width="100" />
                   <el-table-column prop="data" label="约束类型" >
@@ -918,7 +918,7 @@
                     </el-table>
                 
                 </div>
-                <div class="eloptimize" v-if="activeIndex2==2">
+                <div class="eloptimize classtable" v-if="activeIndex2==2">
                   <el-table :data="eloptimize" stripe style="width: 100%">
                   <el-table-column type="index" label="编号"  width="70" />
                   <el-table-column prop="qi" label="启用" width="70">
@@ -1708,27 +1708,27 @@ box-shadow: 0px 2px 2px 0px #2267B1;
 border-radius: 0px 0px 0px 0px;
 border: 1px solid #2267B1;
 }
-.el-table td.el-table__cell div .el-input__wrapper{
+.classtable .el-table td.el-table__cell div .el-input__wrapper{
   box-shadow: none !important;
   padding: 0;
 }
-.el-table .el-table__cell{
+.classtable .el-table .el-table__cell{
   padding: 0;
 }
 .gooterpading{
   border: 1px solid #2267B1;
 }
-.el-table th .cell{
+.classtable .el-table th .cell{
   background:#D8D8D8;
 }
-.el-table .cell{
+.classtable .el-table .cell{
   font-size: 12px;
 }
-.el-table td.el-table__cell div{
+.classtable .el-table td.el-table__cell div{
   height: 24px;
     overflow: hidden;
 }
-.el-table td.el-table__cell, .el-table th.el-table__cell.is-leaf,.eldesign{
-  border: 1px solid #000000;
+.classtable .el-table td.el-table__cell, .el-table th.el-table__cell.is-leaf,.eldesign{
+  /* border: 1px solid #000000; */
 }
   </style>

+ 46 - 15
src/views/home/newfile.vue

@@ -3,16 +3,10 @@
     <div class="demo-collapse">
     <el-collapse  class="custom-collapse" v-model="activeNames" @change="handleChange">
       <el-collapse-item title="新建工程" name="1">
-        <!-- <template #title>
-            <el-icon class="el-icon "><CaretRight /></el-icon>
-            新建工程
-          </template> -->
-        <div class="collapse-list">
-            <router-link to="/home">
-            <div class="list">
+        <div class="collapse-list" >
+            <div class="list" @click="newclick()">
                 <el-image :src="s0" fit="contain" ></el-image>
             </div>
-        </router-link>
         </div>
     
       </el-collapse-item>
@@ -25,30 +19,63 @@
             </div>
    
         </div>
- 
       </el-collapse-item>
-   
-  
     </el-collapse>
   </div>
+  <el-dialog v-model="eldialog"  align-center    :append-to-body="true" width="400" class="dialog_class">
 
-  <div>
-  </div>
+ <template #header="{ titleId, titleClass }">
+    <div class="my-header ">
+        <!-- <el-image :src="icon" fit="contain"></el-image> -->
+        <h4 :id="titleId" :class="titleClass">新建</h4>
+
+    </div>
+</template>
+<div>
+  <el-form-item label="名称:" >
+        <el-input v-model="newfile.name" class="w-50 m-2" placeholder="请输入" />
+    </el-form-item>
+    <el-form-item label="描述:">
+        <el-input v-model="newfile.description" class="w-50 m-2" placeholder="请输入" />
+    </el-form-item>
+</div>
+    <template #footer>
+      <span class="dialog-footer">
+        <el-button @click="eldialog = false">取消</el-button>
+        <el-button type="primary" @click="saveclick();"
+          >确认</el-button
+        >
+      </span>
+    </template>
+
+</el-dialog>
 </template>
 <script setup>
 import { ref, onMounted, reactive, } from "vue";
 import {CaretRight } from "@element-plus/icons-vue";
-import { RouterView, RouterLink } from "vue-router"
+import { RouterView, RouterLink,useRouter } from "vue-router"
 import { request, uploadFile } from "@/utils/request";
 import { ElMessage, ElButton, ElDialog, ElSelect } from 'element-plus'
 import s0 from "@/assets/img/s0.png";
 import open2 from "@/assets/img/open2.png";
 import open3 from "@/assets/img/open3.png";
+let router = useRouter();
+let eldialog=ref(false);
+const activeNames = ref(['1','2']);
+let newfile=ref({
+  name:'',
+  description:'',
+});
 
-const activeNames = ref(['1','2'])
 const handleChange = (val) => {
   console.log(val)
+
+}
+const newclick = () => {
+  eldialog.value=true;
+
 }
+
 let collapselist = ref([
   {img:open2},{img:open3},
  
@@ -56,6 +83,10 @@ let collapselist = ref([
 const openclick=()=>{
    // router.replace({ path: key })
 }
+const saveclick=()=>{
+  router.push({ path: "/home" ,query:{name:1 ,vlaobj:JSON.stringify(newfile.value)}});
+  eldialog.value = false;
+}
 </script>
 <style lang="scss" scoped>
 .collapse-list{

+ 181 - 0
src/views/home/querylist.vue

@@ -0,0 +1,181 @@
+<template>
+    <!-- 打开查询 -->
+    <h3 class="opt_tltie"></h3>
+    <div>
+        <div  class="input ">
+            <div  class="text el-input">
+                <input type="text" autocomplete="off" placeholder="请输入项目名称"
+                v-model="gd.searchtag"
+                    class="el-input__inner"></div>
+                    <!-- <button  type="button"
+                class="el-button el-button--primary" style="border-radius: 0px;" @click="searchclick()">
+                <i class="el-icon-search"></i><span>搜索</span></button> -->
+                <el-button type="primary"  class="el-button el-button--primary" style="border-radius: 0px;" @click="searchclick()" :icon="Search">搜索</el-button>
+        </div>
+        <el-table :data="tableData" :max-height="tableHeight"   @row-click="handlerow($event)"
+            :header-cell-style="{ 'background': 'rgba(13, 22, 57, 0) ' }">
+            <el-table-column prop="image" label="图片" >
+            <template #default="scope">
+                <el-image :src="scope.row.image" fit="contain"></el-image>      
+         </template>
+                        </el-table-column>
+            <el-table-column prop="name" label="名称" />
+            <el-table-column prop="remark" label="描述" />
+            <el-table-column prop="createtime" label="创建时间" />
+            <el-table-column prop="updatetime" label="更新时间" />
+            <el-table-column label="操作"  width="100">
+                          <template #default="scope">
+                            <el-button
+                              size="small"
+                              type="danger"
+                              @click="handdelete(scope.$index, scope.row)"
+                              >删除</el-button
+                            >
+                          </template>
+                        </el-table-column>
+        </el-table>
+        <div class="demo-pagination-block pagination" style="margin-top: 20px;">
+            <el-pagination v-model:current-page="gd.currentPage4" v-model:page-size="gd.pageSize4" small background
+                layout="prev, total,pager, next, jumpe," :total="parseInt(gd.total)" class="mt-4"
+                @current-change="handleCurrentChange2" />
+        </div>
+    </div>
+</template>
+<script setup>
+import { ref, onMounted, reactive, } from "vue";
+import { RouterView, RouterLink,useRouter } from "vue-router"
+import { request, uploadFile } from "@/utils/request";
+import { ElMessage, ElButton, ElDialog, ElSelect } from 'element-plus'
+import { Calendar, Search } from "@element-plus/icons-vue";
+import * as echarts from 'echarts'
+let tableData = ref([]);
+let router = useRouter();
+let gd = ref({
+    total: 1,
+    currentPage4: 1,
+    pageSize4:5,
+    searchtag: ''
+})
+let tableHeight=(600);
+onMounted(() => {
+    getsensor();
+});
+// 查询
+const getsensor = () => {
+    const params = {
+        transCode: 'MDO0001',
+        count: gd.value.pageSize4,
+        page: gd.value.currentPage4,
+        searchtag: gd.value.searchtag,
+
+    }
+    request(params)
+        .then((res) => {
+            console.log(res);
+            gd.value.total = res.total;
+            tableData.value=res.rows;
+        })
+        .catch((err) => {
+            ElMessage.error(err.returnMsg)
+        })
+}
+//搜索
+const searchclick = () => {
+    getsensor();
+}
+//删除
+const handdelete=(e,row)=>{
+    console.log(row)
+console.log(row.pid)
+const params = {
+        transCode: 'MDO0003',
+        pid:row.pid,
+    }
+    request(params)
+        .then((res) => {
+            getsensor();
+            ElMessage({
+                  message: res.returnMsg,
+                  type: 'success',
+              })
+        })
+        .catch((err) => {
+            ElMessage.error(err.returnMsg)
+        })
+}
+//分页查询
+const handleCurrentChange2=(val)=>{
+    getsensor();
+}
+//点击列表
+const handlerow=(val)=>{
+    router.push({ path: "/home",query:{id:'2'}});
+console.log(val);
+sessionStorage.setItem("objlist",JSON.stringify(val));
+}
+</script>
+<style lang="scss" scoped>
+ .input {
+    width: 25%;
+    display: flex;
+    min-width: 200px;
+    -webkit-box-sizing: border-box;
+    -webkit-transition: .5s linear;
+    transition: .5s linear;
+    position: relative;
+    box-sizing: border-box;
+    overflow: hidden;
+    color: #fff; 
+    border: 1px solid #dcdfe6;
+}
+.input .text {
+    -webkit-box-flex: 1;
+    -ms-flex: 1;
+    flex: 1;
+}
+.el-input__inner {
+    -webkit-appearance: none;
+    background-color: #fff;
+    background-image: none;
+    border-radius: 4px;
+    border: 1px solid #dcdfe6;
+    -webkit-box-sizing: border-box;
+    box-sizing: border-box;
+    color: #606266;
+    display: inline-block;
+    height: 40px;
+    border: none;
+    line-height: 40px;
+    outline: 0;
+    padding: 0 15px;
+    -webkit-transition: border-color .2s cubic-bezier(.645,.045,.355,1);
+    transition: border-color .2s cubic-bezier(.645,.045,.355,1);
+    width: 100%;
+}
+.input  .el-button {
+    display: inline-block;
+    line-height: 1;
+    white-space: nowrap;
+    height: 40px;
+    cursor: pointer;
+    background: #fff;
+    border:none;
+    border-left: 1px solid #dcdfe6;
+    color: #606266;
+    -webkit-appearance: none;
+    text-align: center;
+    -webkit-box-sizing: border-box;
+    box-sizing: border-box;
+    outline: 0;
+    margin: 0;
+    -webkit-transition: .1s;
+    transition: .1s;
+    font-weight: 500;
+    padding: 12px 20px;
+    font-size: 14px;
+    border-radius: 4px;
+}
+
+
+</style>
+

+ 12 - 8
src/views/openpage.vue

@@ -17,18 +17,15 @@
                     fit="contain"
                 ></el-image>
             </div>
-             <el-menu-item  index="/home/newfile">新建</el-menu-item>
-          <el-menu-item  >打开</el-menu-item>
-            <el-menu-item   index="/home/baocuo" >保存</el-menu-item>
+            <el-menu-item  index="/home/newfile">新建</el-menu-item>
+           <el-menu-item   index="/home/querylist" >打开</el-menu-item>
+          <el-menu-item    index="/home/savefile" >保存</el-menu-item>
           <el-menu-item  >另存</el-menu-item>
           <el-menu-item   >选择</el-menu-item>
         </el-menu>
       </div>
       <section class="user-main ">
-       
-        <!-- <transition name="fade-transform" mode="out-in"> -->
         <router-view > </router-view>
-        <!-- </transition> -->
       </section>
     </div>
   </div>
@@ -54,8 +51,11 @@ const activeIndex=computed(()=>{
      return  path
   })
  function Select(key) {
-    console.log(router)
-    router.replace({ path: key })
+  router.replace({ path: key })
+    if(key=='/home/querylist'){
+      console.log(11111)
+    }
+
     }
 </script>
 <style lang="scss" scoped>
@@ -119,5 +119,9 @@ const activeIndex=computed(()=>{
     width: 100%;
     height: 100%;
 }
+.user-slider .el-menu-item.is-active{
+  color: #000;
+    background: #ecf5ff;
+}
 </style>
 

+ 4 - 6
src/views/vuetree/Sidebar.vue

@@ -142,22 +142,20 @@ const datatree = ref([
 </script>
 
 <template>
-<div class="left_main">
+<div class="left_main">       
 
 <div class="left_main_content el-treeicon">
   <el-tree :data="datatree"  class="custom-tree"  default-expand-all  :props="defaultProps" @node-click="handleNodeClick"  >
     <template #default="{ node, data }">
-          <div   @dragstart="onDragStart($event, 'default',data.id)">
+          <div   @dragstart="onDragStart($event, 'default',data.id)"  :draggable="true" >
             <img :src="data.img" class="custom-image" />
-            <span class="custom-text">
-              {{ node.label }}
-            </span>
+            <span class="custom-text"> {{ node.label }}  </span>
           </div>
         </template>
   </el-tree>
  <el-tree :data="datatree1"  class="custom-tree1" default-expand-all  :props="defaultProps" @node-click="handleNodeClick">
     <template #default="{ node, data }">
-          <div  @dragstart="onDragStart($event, 'default',data.id)">
+          <div  @dragstart="onDragStart($event, 'default',data.id)" :draggable="true" >
             <img :src="getImgPath(data.img)" class="custom-image" />
             <span class="custom-text">
               {{ node.label }} 

+ 117 - 40
src/views/vuetree/index.vue

@@ -4,7 +4,7 @@
     :default-viewport="{ zoom: 1.5 }" :min-zoom="0.2" :max-zoom="4" @drop="onDrop"
     @contextmenu.prevent="onContextMenu" @node-contextmenu="logEvent('contextmenu', $event)" 
     @dragover="onDragOver" @dragleave="onDragLeave" @edge-click="onEdgeClick" @node-click="onNodeClick">
-    <template #node-default="props">
+    <template  #node-default="props">
       <!-- <template  #node-process="props">   //  @contextmenu.prevent="onContextMenu"  -->
       <eltree :node="props" />
     </template>
@@ -18,6 +18,7 @@
         <button class="remove" @click="removeEdge(event)">删除线</button>
         <!-- <button class="remove" @click="getnodes()">获取所有数据</button> -->
       </div>
+     
     </Panel>
     <Controls position="top-left">
       <ControlButton title="Reset Transform" @click="resetTransform">
@@ -33,7 +34,7 @@
         <Icon v-else name="moon" />
       </ControlButton>
 
-      <ControlButton title="Log `toObject`" @click="logToObject">
+      <ControlButton title="Log `toObject`" @click="logToObject1">
         <Icon name="log" />
       </ControlButton>
     </Controls>
@@ -41,7 +42,7 @@
   </VueFlow>
   <div class="dnd-flow">
 
-    <div id="contextMenu" @click="deleteItemConfirm">删除</div>
+    <!-- <div id="contextMenu" @click="deleteItemConfirm">删除</div> -->
 
 
   </div>
@@ -49,7 +50,9 @@
 <script setup>
 import { ref, markRaw } from 'vue'
 import { VueFlow, useVueFlow, MarkerType } from '@vue-flow/core'
+import { ElMessage, ElButton, ElDialog, ElSelect } from 'element-plus'
 import { useRoute } from 'vue-router';
+import { request, uploadFile } from "@/utils/request";
 import { Background } from '@vue-flow/background'
 import { ControlButton, Controls } from '@vue-flow/controls'
 import { initialEdges, initialNodes } from './modeljs.js'
@@ -57,21 +60,25 @@ import { MiniMap } from '@vue-flow/minimap'
 import "./main.css";//重置样式
 import DropzoneBackground from './DropzoneBackground.vue'
 import eltree from './eltree.vue'
-import useDragAndDrop from './useDnD'
+import useDragAndDrop from './useDnD';
 import f11 from '@/assets/img/f11.png'
+import html2canvas from 'html2canvas';
 import Icon from './Icon.vue'
+
 const dark = ref(false)
 const route = useRoute();
 const { onInit, onNodeDragStop, onNodeContextMenu, onConnect, addEdges, setViewport, toObject } = useVueFlow()
 let vueFlowRef = ref();
 let emit = defineEmits(['optimizerfalse']);
+let mergedObj=ref();
 const props = defineProps({
 
   optimizer: {
     type: Boolean,
   },
 })
-
+let newroter=ref();
+let vueflowimg=ref('');
 const shopShow = ref(false);
 let noid = ref([]);
 let Edgeid = ref();
@@ -105,36 +112,36 @@ function logEvent(name, event) {
   console.log(2222)
 }
 function onContextMenu(event) {
-  if (noid.value !== null) {
-    if (noid.value.id) {
-      console.log(noid.value.position.y);
-      console.log(noid.value.position.x);
-      document.getElementById('contextMenu').style.top = noid.value.position.y + 100 + 'px';
-      document.getElementById('contextMenu').style.left = noid.value.position.x + 270 + 'px';
-      document.getElementById('contextMenu').style.display = 'block';
-      event.preventDefault();
-      //shopShow.value=true;
-      // document.getElementById('contextMenu').style.display = 'none';
-    }
-  }
+//   if (noid.value !== null) {
+//     if (noid.value.id) {
+//       console.log(noid.value.position.y);
+//       console.log(noid.value.position.x);
+//       document.getElementById('contextMenu').style.top = noid.value.position.y + 100 + 'px';
+//       document.getElementById('contextMenu').style.left = noid.value.position.x + 270 + 'px';
+//       document.getElementById('contextMenu').style.display = 'block';
+//       event.preventDefault();
+//       //shopShow.value=true;
+//       // document.getElementById('contextMenu').style.display = 'none';
+//     }
+//   }
 
 }
 //点击左键右键内容消失
-document.addEventListener('click', function (e) {
-  if (e.button === 0) { // 0 是左键
-    document.getElementById('contextMenu').style.display = 'none';
-    //   shopShow.value=false;
-  }
-});
+// document.addEventListener('click', function (e) {
+//   if (e.button === 0) { // 0 是左键
+//     document.getElementById('contextMenu').style.display = 'none';
+//     //   shopShow.value=false;
+//   }
+// });
 //删除
-const deleteItemConfirm = () => {
-  if (noid.value.id) {
-    vueFlowRef.value.removeNodes(noid.value.id);
-    noid.value = null;
-    document.getElementById('contextMenu').style.display = 'none';
-  }
+// const deleteItemConfirm = () => {
+//   if (noid.value.id) {
+//     vueFlowRef.value.removeNodes(noid.value.id);
+//     noid.value = null;
+//     document.getElementById('contextMenu').style.display = 'none';
+//   }
 
-}
+// }
 onInit((vueFlowInstance) => {
   vueFlowInstance.fitView()
 })
@@ -167,10 +174,58 @@ function removeNode(id) {
   id = noid.value.id
   vueFlowRef.value.removeNodes(noid.value.id);
 }
-function logToObject() {
-  console.log(toObject())
-}
+async  function logToObject1() {
+  let obj = { nodes: toObject().nodes,edges:toObject().edges };
+  mergedObj.value=JSON.stringify(obj);
+  try {
+    console.log(vueFlowRef.value)
+        const container = vueFlowRef.value.$el;
+        const canvas = await html2canvas(container);
+        const img = canvas.toDataURL('image/png');
+ 
+        // 创建一个图片元素并设置src属性为转换后的图片数据
+        const image = new Image();
+        image.src = img;
+       vueflowimg.value=img
+       if(vueflowimg.value!=''){
+        console.log("进入了")
+        addflow();
+       }
+        // 添加到DOM中或者做其他操作
+      } catch (error) {
+        console.error('转换出错:', error);
+      }
+  // console.log(toObject())
+  // if (!vueFlowRef.value) {
+  //   console.warn('VueFlow element not found');
+  //   return;
+  // }
 
+  // capture(vueFlowRef.value, { shouldDownload: true });
+}
+//添加接口
+const addflow = () => {
+    const params = {
+        transCode: 'MDO0002',
+        pid: '',
+        name: newroter.value.name,
+        remark:newroter.value.description,
+        image:vueflowimg.value,
+        isshare:'1',
+        flow:mergedObj.value 
+    }
+    request(params)
+        .then((res) => {
+            console.log(res);
+            ElMessage({
+                  message: res.returnMsg,
+                  type: 'success',
+              })
+        })
+        .catch((err) => {
+            ElMessage.error(err.returnMsg)
+        })
+}
 /**
  * Resets the current viewport transformation (zoom & pan)
  */
@@ -188,13 +243,21 @@ onMounted(() => {
 });
 // 获取链接
 const getroter=()=>{
-  console.log(11111)
-  console.log(route.query);
-  if(route.query.id=='0'){
-    console.log(route.query);
-    nodes.value=initialNodes;
-    edges.value=initialEdges;
-  }
+
+ if(route.query.id=='2'){
+  let objlist=JSON.parse(sessionStorage.getItem("objlist"));
+  let nodesflow=JSON.parse(objlist.flow)
+      nodes.value=nodesflow.nodes;
+      edges.value=nodesflow.edges;
+ }else if(route.query.id='1'&&route.query!={}){
+  newroter.value=JSON.parse(route.query.vlaobj);
+  
+ }
+  // if(route.query.id=='0'){
+  //   console.log(route.query);
+  //   nodes.value=initialNodes;
+  //   edges.value=initialEdges;
+  // }
 }
 </script>
 
@@ -240,4 +303,18 @@ panel {
   border: none;
   background-color: rgba(0,0,0,0);
 }
+.node-content {
+  cursor: move;  /* 更改鼠标光标表示可拖动 */
+}
+.vue-flow__node {
+  cursor: move;
+}
+
+/* 禁用文本选中效果 */
+.left_main * {
+  -webkit-user-select: none; /* Safari */
+  -moz-user-select: none; /* Firefox */
+  -ms-user-select: none; /* IE10+/Edge */
+  user-select: none; /* Standard syntax */
+}
 </style>

+ 26 - 0
src/views/vuetree/types.ts

@@ -0,0 +1,26 @@
+import type { Options as HTMLToImageOptions } from 'html-to-image/es/types';
+import type { Ref } from 'vue';
+
+export type ImageType = 'jpeg' | 'png';
+
+export interface UseScreenshotOptions extends HTMLToImageOptions {
+  type?: ImageType;
+  fileName?: string;
+  shouldDownload?: boolean;
+  fetchRequestInit?: RequestInit;
+}
+
+export type CaptureScreenshot = (
+  el: HTMLElement,
+  options?: UseScreenshotOptions
+) => Promise<string>;
+
+export type Download = (fileName: string) => void;
+
+export interface UseScreenshot {
+  // returns the data url of the screenshot
+  capture: CaptureScreenshot;
+  download: Download;
+  dataUrl: Ref<string>;
+  error: Ref;
+}

+ 10 - 0
src/views/vuetree/useDnD.js

@@ -14,6 +14,9 @@ import xuek6 from '@/assets/flowimg/xuek6.png'
 import xuek7 from '@/assets/flowimg/xuek7.png'
 import xuek8 from '@/assets/flowimg/xuek8.png'
 import xuek9 from '@/assets/flowimg/xuek9.png'
+import xuek10 from '@/assets/flowimg/xuek10.png'
+import xuek11 from '@/assets/flowimg/xuek11.png'
+import xuek12 from '@/assets/flowimg/xuek12.png'
 let nid = 0;
 let id=0
 let datas={}
@@ -52,6 +55,12 @@ function imagefun(){
       return datas = {label:'Python', image:xuek8}
     }else if(nid=='3-9'){
       return datas = {label:'AirfoilAero', image:xuek9}
+    }else if(nid=='4-1'){
+      return datas = {label:'进化优化器', image:xuek10}
+    }else if(nid=='4-2'){
+      return datas = {label:'代理优化器', image:xuek11}
+    }else if(nid=='4-3'){
+      return datas = {label:'梯度优化器', image:xuek12}
     }
     else{
       return null;
@@ -82,6 +91,7 @@ export default function useDragAndDrop() {
   })
 
   function onDragStart(event, type,id) {
+    console.log(event);
     nid=id;
     if (event.dataTransfer) {
       event.dataTransfer.setData('application/vueflow', type)

+ 85 - 0
src/views/vuetree/useScreenshot.ts

@@ -0,0 +1,85 @@
+import { toJpeg as ElToJpg, toPng as ElToPng } from 'html-to-image';
+import { ref } from 'vue';
+import type { Options as HTMLToImageOptions } from 'html-to-image/es/types';
+import type { ImageType, UseScreenshot, UseScreenshotOptions } from './types';
+
+export function useScreenshot(): UseScreenshot {
+  const dataUrl = ref<string>('');
+  const imgType = ref<ImageType>('png');
+  const error = ref();
+
+  async function capture(el: HTMLElement, options: UseScreenshotOptions = {}) {
+    let data;
+
+    const fileName = options.fileName ?? `vue-flow-screenshot-${Date.now()}`;
+
+    switch (options.type) {
+      case 'jpeg':
+        data = await toJpeg(el, options);
+        break;
+      case 'png':
+        data = await toPng(el, options);
+        break;
+      default:
+        data = await toPng(el, options);
+        break;
+    }
+
+    // immediately download the image if shouldDownload is true
+    if (options.shouldDownload && fileName !== '') {
+      download(fileName);
+    }
+
+    return data;
+  }
+
+  function toJpeg(
+    el: HTMLElement,
+    options: HTMLToImageOptions = { quality: 0.95 }
+  ) {
+    error.value = null;
+
+    return ElToJpg(el, options)
+      .then((data) => {
+        dataUrl.value = data;
+        imgType.value = 'jpeg';
+        return data;
+      })
+      .catch((error) => {
+        error.value = error;
+        throw new Error(error);
+      });
+  }
+
+  function toPng(
+    el: HTMLElement,
+    options: HTMLToImageOptions = { quality: 0.95 }
+  ) {
+    error.value = null;
+
+    return ElToPng(el, options)
+      .then((data) => {
+        dataUrl.value = data;
+        imgType.value = 'png';
+        return data;
+      })
+      .catch((error) => {
+        error.value = error;
+        throw new Error(error);
+      });
+  }
+
+  function download(fileName: string) {
+    const link = document.createElement('a');
+    link.download = `${fileName}.${imgType.value}`;
+    link.href = dataUrl.value;
+    link.click();
+  }
+
+  return {
+    capture,
+    download,
+    dataUrl,
+    error,
+  };
+}

+ 1 - 1
vite.config.ts

@@ -46,7 +46,7 @@ export default defineConfig(({ mode }) => {
         server: {
             proxy: {
                 '/api': {
-                    target: 'http://192.168.0.131:8187/TransServlet',//配置文件获取地址
+                    target: 'http://192.168.0.131:8188/TransServlet',//配置文件获取地址
                     secure: false, //接受使用https
                     changeOrigin: true, //允许跨域
                     ws: false, //使用websocket