Browse Source

组态设计器增加右键菜单,框架界面新增监视页面结构

WXW 4 years ago
parent
commit
002ea0c1aa
15 changed files with 4525 additions and 3309 deletions
  1. 3 0
      .env.dev
  2. 3 0
      .env.prod
  3. 3 0
      .env.test
  4. 3 0
      .env.uat
  5. 20 0
      .gitignore
  6. 4236 3223
      package-lock.json
  7. 7 5
      package.json
  8. 7 0
      src/main.js
  9. 37 37
      src/request/http.js
  10. 17 14
      src/router/index.js
  11. 30 0
      src/static/json/pathsunmmery.json
  12. 27 2
      src/views/Home.vue
  13. 27 15
      src/views/xDesigner/viewer.vue
  14. 97 12
      src/views/xDesigner/xdesigner.vue
  15. 8 1
      vue.config.js

+ 3 - 0
.env.dev

@@ -0,0 +1,3 @@
+NODE_ENV='development'
+VUE_APP_CURRENTMODE='dev'
+VUE_APP_BASEURL='http://****/api/'

+ 3 - 0
.env.prod

@@ -0,0 +1,3 @@
+NODE_ENV='production'
+VUE_APP_CURRENTMODE='prod'
+VUE_APP_BASEURL='http://****/api/'

+ 3 - 0
.env.test

@@ -0,0 +1,3 @@
+NODE_ENV='production'
+VUE_APP_CURRENTMODE='test'
+VUE_APP_BASEURL='http://****/api/'

+ 3 - 0
.env.uat

@@ -0,0 +1,3 @@
+NODE_ENV='production'
+VUE_APP_CURRENTMODE='uat'
+VUE_APP_BASEURL='http://****/api/'

+ 20 - 0
.gitignore

@@ -0,0 +1,20 @@
+.DS_Store
+node_modules
+
+# local env files
+.env.local
+.env.*.local
+
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?

File diff suppressed because it is too large
+ 4236 - 3223
package-lock.json


+ 7 - 5
package.json

@@ -31,18 +31,20 @@
     "open": "^7.0.0",
     "shebang-command": "^2.0.0",
     "string.prototype.padstart": "^3.0.0",
+    "v-contextmenu": "^2.9.0",
     "vue": "^2.6.10",
     "vue-router": "^3.1.3",
+    "vue-runtime-helpers": "^1.1.2",
     "vuex": "^3.0.1",
     "wrappy": "^1.0.2",
     "yallist": "^4.0.0"
   },
   "devDependencies": {
-    "@vue/cli-plugin-babel": "^4.0.0",
-    "@vue/cli-plugin-router": "^4.0.0",
-    "@vue/cli-plugin-vuex": "^4.0.0",
-    "@vue/cli-service": "^4.0.0",
-    "vue-template-compiler": "^2.6.10"
+    "@vue/cli-plugin-babel": "^4.5.3",
+    "@vue/cli-plugin-router": "^4.5.3",
+    "@vue/cli-plugin-vuex": "^4.5.3",
+    "@vue/cli-service": "^4.5.3",
+    "vue-template-compiler": "^2.6.11"
   },
   "postcss": {
     "plugins": {

+ 7 - 0
src/main.js

@@ -31,6 +31,13 @@ Vue.prototype.$config = Config //配置信息
 console.log('NODE_ENV:', process.env.NODE_ENV)
 Vue.config.productionTip = false
 
+
+// 右键菜单-----
+import contentmenu from 'v-contextmenu'
+import 'v-contextmenu/dist/index.css'
+Vue.use(contentmenu)
+// 右键菜单-------
+
 new Vue({
     router,
     store,

+ 37 - 37
src/request/http.js

@@ -98,42 +98,42 @@ let errorHandle = (status, other) => {
 }
 
 //响应拦截器
-instance.interceptors.response.use(
-    //请求成功
-    res => {
-        if (res.status === 200) {
-            //Promise.resolve(value)方法返回一个以给定值解析后的Promise 对象。
-            return Promise.resolve(res)
-        } else {
-            console.log("响应拦截器失败")
-            //Promise.reject(reason)方法返回一个带有拒绝原因reason参数的Promise对象。
-            return Promise.reject(res)
-        }
-    },
-    //请求失败
-    error => {
-        //return Promise.reject(error)
-        const { response } = error
-        if (response) {
-            //请求已发出,但是不在2xx的范围    ------错误处理、token过期等
-            errorHandle(response.status, response.data.message)
-            return Promise.reject(response)
-        } else {
-            Message({
-                message: '网络异常,即将前往登录页',
-                type: 'error'
-            })
-            setTimeout(() => {
-                //跳转到登录
-                toLogin()
-            }, 5000)
-            // 处理断网的情况
-            // eg:请求超时或断网时,更新state的network状态
-            // network状态在app.vue中控制着一个全局的断网提示组件的显示隐藏
-            // 关于断网组件中的刷新重新获取数据,会在断网组件中说明
-            //store.commit('changeNetwork', false)
-        }
-    }
-)
+// instance.interceptors.response.use(
+//     //请求成功
+//     res => {
+//         if (res.status === 200) {
+//             //Promise.resolve(value)方法返回一个以给定值解析后的Promise 对象。
+//             return Promise.resolve(res)
+//         } else {
+//             console.log("响应拦截器失败")
+//             //Promise.reject(reason)方法返回一个带有拒绝原因reason参数的Promise对象。
+//             return Promise.reject(res)
+//         }
+//     },
+//     //请求失败
+//     error => {
+//         //return Promise.reject(error)
+//         const { response } = error
+//         if (response) {
+//             //请求已发出,但是不在2xx的范围    ------错误处理、token过期等
+//             errorHandle(response.status, response.data.message)
+//             return Promise.reject(response)
+//         } else {
+//             Message({
+//                 message: '网络异常,即将前往登录页',
+//                 type: 'error'
+//             })
+//             setTimeout(() => {
+//                 //跳转到登录
+//                 toLogin()
+//             }, 5000)
+//             // 处理断网的情况
+//             // eg:请求超时或断网时,更新state的network状态
+//             // network状态在app.vue中控制着一个全局的断网提示组件的显示隐藏
+//             // 关于断网组件中的刷新重新获取数据,会在断网组件中说明
+//             //store.commit('changeNetwork', false)
+//         }
+//     }
+// )
 
 export default instance

+ 17 - 14
src/router/index.js

@@ -66,7 +66,7 @@ const routes = [
         iconCls: "fa el-icon-s-data",
         hidden: false,
         meta: {
-            title: "框架简介",
+            title: "监视",
             keepAlive: false,
             level: 0
         },
@@ -81,9 +81,23 @@ const routes = [
                     keepAlive: false,
                     level: 0
                 }
-            }
+            },
         ]
     },
+
+    //         {
+    //             hidden: true,
+    //             path: '/Viewer/:path',
+    //             name: 'Viewer',
+    //             meta: {
+    //                 title: "Viewer",
+    //                 keepAlive: false,
+    //                 level: 0 //判断是否缓存 0为不缓存 1为缓存 2为详情页
+    //             },
+    //             component: () => import("../views/xDesigner/viewer.vue")
+    //         },
+    //     ]
+    // },
     {
         path: "/home",
         component: Home,
@@ -184,17 +198,6 @@ const routes = [
             level: 0 //判断是否缓存 0为不缓存 1为缓存 2为详情页
         },
         component: () => import("../views/xDesigner/xdesigner.vue")
-    }, 
-    {
-        hidden: true,
-        path: '/Viewer',
-        name: 'Viewer',
-        meta: {
-            title: "Viewer",
-            keepAlive: false,
-            level: 0 //判断是否缓存 0为不缓存 1为缓存 2为详情页
-        },
-        component: () => import("../views/xDesigner/viewer.vue")
     },
 ]
 
@@ -204,7 +207,7 @@ const router = new VueRouter({
     routes
 });
 
-//全局路由守卫、路由拦截
+// 全局路由守卫、路由拦截
 // router.beforeEach((to, from, next) => {
 //     const isLogin = localStorage.token ? true : false;
 //     if (to.path === "/login" || to.path === "/forgotPassword") {

+ 30 - 0
src/static/json/pathsunmmery.json

@@ -0,0 +1,30 @@
+[
+    {
+        "name": "预处理系统",
+        "path": "/yuchuli",
+        "page": [
+            {
+                "name": "沉淀系统",
+                "path": "/chengdian.json"
+            },
+            {
+                "name": "污泥处理系统",
+                "path": "/wunichulixitong.json"
+            }
+        ]
+    },
+    {
+        "name": "GE干燥系统",
+        "path": "/geganzao",
+        "page": [
+            {
+                "name": "末端干燥-废水系统",
+                "path": "/moduanganzao.json"
+            },
+            {
+                "name": "末端干燥-双流体雾化系统",
+                "path": "/moduanshuangliutiwuhua.json"
+            }
+        ]
+    }
+]

+ 27 - 2
src/views/Home.vue

@@ -11,6 +11,22 @@
           element-loading-spinner="el-icon-loading"
           element-loading-background="#304156"
         >
+          <el-submenu index="1">
+            <template slot="title">监视</template>
+            <el-submenu
+              :index="'1_'+pathIndex"
+              v-for="(pathObj, pathIndex) in pathsummury"
+              :key="pathObj.name+pathIndex"
+            >
+              <template slot="title">{{pathObj.name}}</template>
+              <label v-for="(pageitem, pageindex) in pathObj.page" :key="pageindex">
+                <el-menu-item
+                  :index="'1_'+pathIndex+'_'+pageindex"
+                  @click="toViewer(pathObj.path+pageitem.path)"
+                >{{pageitem.name}}</el-menu-item>
+              </label>
+            </el-submenu>
+          </el-submenu>
           <!-- $router.options.routes到时候可以从后台动态获取菜单 -->
           <template v-for="(item, index) in $router.options.routes">
             <template>
@@ -42,7 +58,7 @@
             </template>
           </template>
           <router-link target="_blank" to="/AppDesign">
-            <div class="el-submenu__title zt" style="color:#fff;" to="/home">组态</div>
+            <div class="el-submenu__title zt" style="color:#fff;">组态</div>
           </router-link>
         </el-menu>
       </el-aside>
@@ -82,12 +98,14 @@
 <script>
 import AdminHeader from '@/components/AdminHeader'
 import NavMenu from '@/components/NavMenu'
+import pathsummery from '../static/json/pathsunmmery.json'
 export default {
   name: 'home',
   data()
   {
     return {
-      levelList: null//路由列表
+      levelList: null,//路由列表,
+      pathsummury: pathsummery
     }
   },
   created()
@@ -105,6 +123,13 @@ export default {
     this.getBreadcrumb()
   },
   methods: {
+    toViewer(path)
+    {
+      console.log(path)
+      this.$router.push({
+        path: '/Viewer/' + path,
+      })
+    },
     /**
      * 生成面包屑的方法
      */

+ 27 - 15
src/views/xDesigner/viewer.vue

@@ -1,5 +1,6 @@
 <template>
-  <div class="mainpage" id="rootElement" ref="rootElement"></div>
+<div class="mainpage" id="rootElement" ref="rootElement"></div>
+  
 </template>
 
  <script>
@@ -35,6 +36,9 @@ export default {
   },
 
   methods: {
+    con(){
+      console.log(this.$route.params.path)
+    },
     init()
     {
       window.scrollTo(0, 0);
@@ -80,20 +84,22 @@ export default {
     open()
     {
 
-      // console.log("this.$route.query");
-      // console.log(this.$route.query);
-      // if (!this.$route.query.id) {
-      //   return
-      // }
-      // else {
-      //   let path = this.$route.query.id;
-      //   console.log(path);
-      //   network.getJsonFile(this.$axios, path);
-      //   }
-      // let s=JSON.stringify(example);
-      // console.log(s)
+      console.log("this.$route.query");
+      console.log(this.$route.query);
+      if (!this.$route.query.id) {
+        return
+      }
+      else {
+        let path = this.$route.query.id;
+        console.log(path);
+        network.getJsonFile(this.$axios, path);
+      }
+
+
+      let s = JSON.stringify(example);
+      console.log(s)
 
-      // this.canvas.open(s);
+      this.canvas.open(s);
 
 
       // if (data && data.id) {
@@ -156,4 +162,10 @@ export default {
 
   }
 }
- </script> 
+ </script> 
+ <style lang="css" scoped>
+ .mainpage{
+   height: 100%;
+   width:100%;
+ }
+ </style>

+ 97 - 12
src/views/xDesigner/xdesigner.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="mainpage">
+  <div :class="['mainpage', theme]" v-contextmenu:contextmenu>
     <el-container>
       <el-header>
         <Header v-if="canvas" :canvasdata="canvas.data" @onMessage="onMessage" @onMenu="onMenu" />
@@ -42,6 +42,24 @@
         </div>
       </el-main>
     </el-container>
+    <v-contextmenu ref="contextmenu" :theme="theme">
+      <v-contextmenu-item @click="OnTop">置顶</v-contextmenu-item>
+      <v-contextmenu-item @click="OnBottom">置底</v-contextmenu-item>
+      <v-contextmenu-item divider></v-contextmenu-item>
+      <v-contextmenu-item @click="OnCombine" v-if="nodes && nodes.pens && (nodes.pens.length > 1)">组合</v-contextmenu-item>
+      <v-contextmenu-item @click="OnUncombine" v-if="nodes && nodes.pen && nodes.pen.children">取消组合</v-contextmenu-item>
+      <v-contextmenu-item @click="OnPenLock">{{ penLocked ? '解锁' : '锁定' }}</v-contextmenu-item>
+      <v-contextmenu-item divider></v-contextmenu-item>
+      <v-contextmenu-item @click="OnDelete">删除</v-contextmenu-item>
+      <v-contextmenu-item divider></v-contextmenu-item>
+      <v-contextmenu-item @click="OnUndo">撤销 Ctrl+Z</v-contextmenu-item>
+      <v-contextmenu-item @click="OnRedo">重做 Ctrl+Shift+Z</v-contextmenu-item>
+      <v-contextmenu-item divider></v-contextmenu-item>
+      <v-contextmenu-item @click="OnCut">剪切 Ctrl+X</v-contextmenu-item>
+      <v-contextmenu-item @click="OnCopy">复制 Ctrl+C</v-contextmenu-item>
+      <v-contextmenu-item @click="OnPaste">粘贴 Ctrl+V</v-contextmenu-item>
+      <v-contextmenu-item divider></v-contextmenu-item>
+    </v-contextmenu>
   </div>
 </template>
 
@@ -97,8 +115,6 @@ i {
   width: 246px;
   overflow-y: auto;
 }
-
-
 </style>
 <script>
 
@@ -117,6 +133,9 @@ export default {
   components: {
     Header, Pens, Nodepropertys, Filepropertys
   },
+  props: {
+    theme: String,
+  },
   data()
   {
     return {
@@ -143,6 +162,7 @@ export default {
         pens: []
       },
       isSelected: false,
+      penLocked: false,
       cpPresetColors: [
         '#1890ff',
         '#096dd9',
@@ -209,6 +229,10 @@ export default {
     // }
   },
   methods: {
+    handleSubmenuShow(vm, placement)
+    {
+      console.log(vm, placement)
+    },
     init()
     {
       window.scrollTo(0, 0);
@@ -231,8 +255,6 @@ export default {
     },
     onMenu(docmd, value)
     {
-      console.log(docmd)
-      console.log(value)
       switch (docmd) {
         case "new":
           { this.OnNew(); } break;
@@ -369,7 +391,7 @@ export default {
             } break;
           default:
             {
-              console.log('onMessage_____Default:', event, value);
+              //console.log('onMessage_____Default:', event, value);
             } break;
         }
         console.log('onMessage:', event, value);
@@ -394,7 +416,7 @@ export default {
 
     onUpdateProps(node)
     {
-      console.log("canvas.updateProps(node)");
+      //console.log("canvas.updateProps(node)");
       // 如果是node属性改变,需要传入node,重新计算node相关属性值
       // 如果是line属性改变,无需传参
       canvas.updateProps(node)
@@ -505,23 +527,23 @@ export default {
       evt.initEvent('click', true, true)
       a.dispatchEvent(evt)
     },
-    OnUndo(data)
+    OnUndo()
     {
       this.canvas.undo()
     },
-    OnRedo(data)
+    OnRedo()
     {
       this.canvas.redo()
     },
-    OnCopy(data)
+    OnCopy()
     {
       this.canvas.copy()
     },
-    OnCut(data)
+    OnCut()
     {
       this.canvas.cut()
     },
-    OnPaste(data)
+    OnPaste()
     {
       this.canvas.paste()
     },
@@ -543,6 +565,69 @@ export default {
         }
       }
     },
+    OnTop()
+    {
+      if (!this.nodes) {
+        return;
+      }
+      if (this.nodes.pen) {
+        this.canvas.top(this.nodes.pen);
+      }
+      if (this.nodes.pens) {
+        for (const item of this.nodes.pens) {
+          this.canvas.top(item);
+        }
+      }
+      this.canvas.render();
+    },
+    OnBottom()
+    {
+      if (!this.nodes) {
+        return;
+      }
+      if (this.nodes.pen) {
+        this.canvas.bottom(this.nodes.pen);
+      }
+      if (this.nodes.pens) {
+        for (const item of this.nodes.pens) {
+          this.canvas.bottom(item);
+        }
+      }
+      this.canvas.render();
+    },
+    OnCombine(stand = false)
+    {
+      if (!this.nodes || !this.nodes.pens || this.nodes.pens.length < 2) {
+        return;
+      }
+      this.canvas.combine(this.nodes.pens, stand);
+    },
+
+    OnUncombine()
+    {
+      if (!this.nodes || !this.nodes.pen || this.nodes.pen.type) {
+        return;
+      }
+      this.canvas.uncombine(this.nodes.pen);
+      this.canvas.render();
+    }
+    ,//penLocked
+    OnPenLock()
+    {
+      this.penLocked = !this.penLocked;
+      if (this.nodes.pen) {
+        this.canvas.lockPens([this.nodes.pen], this.penLocked ? 1 : 0);
+      }
+      if (this.nodes.pens) {
+        this.canvas.lockPens(this.nodes.pens, this.penLocked ? 1 : 0);
+      }
+      this.canvas.render(true);
+    },
+    OnDelete()
+    {
+      this.canvas.delete();
+    },
+
     destroyed()
     {
       canvas.destroy()

+ 8 - 1
vue.config.js

@@ -39,7 +39,14 @@ module.exports = {
 				pathRewrite: {
 					"^/api": ""
 				}
-			}
+			},
+			'/restfull': {
+                target: "http://192.168.0.238:8033",//"http://172.168.1.8:8075", // 报警服务
+                changeOrigin: true, // 在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样服务端和服务端进行数据的交互就不会有跨域问题
+                pathRewrite: {  // 路径重写,
+                    '^/restfull': ''  // 替换target中的请求地址,也就是说以后你在请求http://api.douban.com/v2/XXXXX这个地址的时候直接写成/api即可。
+                }
+            },
 		}
 	},