Эх сурвалжийг харах

通道管理:详情处理

vera_min 3 жил өмнө
parent
commit
b8c48651c7

+ 82 - 1
package-lock.json

@@ -26,6 +26,45 @@
         "regenerator-runtime": "^0.13.4"
       }
     },
+    "@codemirror/commands": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.1.0.tgz",
+      "integrity": "sha512-qCj2YqmbBjj0P1iumnlL5lBqZvJPzT+t2UvgjcaXErp5ZvMqFRVgQyrEfdXX6SX5UcvcHKBjXqno+MkUp0aYvQ==",
+      "requires": {
+        "@codemirror/language": "^6.0.0",
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "@lezer/common": "^1.0.0"
+      }
+    },
+    "@codemirror/language": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.2.1.tgz",
+      "integrity": "sha512-MC3svxuvIj0MRpFlGHxLS6vPyIdbTr2KKPEW46kCoCXw2ktb4NTkpkPBI/lSP/FoNXLCBJ0mrnUi1OoZxtpW1Q==",
+      "requires": {
+        "@codemirror/state": "^6.0.0",
+        "@codemirror/view": "^6.0.0",
+        "@lezer/common": "^1.0.0",
+        "@lezer/highlight": "^1.0.0",
+        "@lezer/lr": "^1.0.0",
+        "style-mod": "^4.0.0"
+      }
+    },
+    "@codemirror/state": {
+      "version": "6.1.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.1.1.tgz",
+      "integrity": "sha512-2s+aXsxmAwnR3Rd+JDHPG/1lw0YsA9PEwl7Re88gHJHGfxyfEzKBmsN4rr53RyPIR4lzbbhJX0DCq0WlqlBIRw=="
+    },
+    "@codemirror/view": {
+      "version": "6.2.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.2.2.tgz",
+      "integrity": "sha512-RwtFlBM/+xnv95urH1D8bVsX3KYLZGygGyZG2TZoXW2Q/GMrI+AuUXh7jBE1M38IOX3YnLTlp6RdgCx3Xo2jVA==",
+      "requires": {
+        "@codemirror/state": "^6.0.0",
+        "style-mod": "^4.0.0",
+        "w3c-keyname": "^2.2.4"
+      }
+    },
     "@ctrl/tinycolor": {
       "version": "3.4.1",
       "resolved": "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.4.1.tgz",
@@ -329,6 +368,27 @@
         "@intlify/shared": "9.1.10"
       }
     },
+    "@lezer/common": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.0.1.tgz",
+      "integrity": "sha512-8TR5++Q/F//tpDsLd5zkrvEX5xxeemafEaek7mUp7Y+bI8cKQXdSqhzTOBaOogETcMOVr0pT3BBPXp13477ciw=="
+    },
+    "@lezer/highlight": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.0.0.tgz",
+      "integrity": "sha512-nsCnNtim90UKsB5YxoX65v3GEIw3iCHw9RM2DtdgkiqAbKh9pCdvi8AWNwkYf10Lu6fxNhXPpkpHbW6mihhvJA==",
+      "requires": {
+        "@lezer/common": "^1.0.0"
+      }
+    },
+    "@lezer/lr": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.2.3.tgz",
+      "integrity": "sha512-qpB7rBzH8f6Mzjv2AVZRahcm+2Cf7nbIH++uXbvVOL1yIRvVWQ3HAM/saeBLCyz/togB7LGo76qdJYL1uKQlqA==",
+      "requires": {
+        "@lezer/common": "^1.0.0"
+      }
+    },
     "@nodelib/fs.scandir": {
       "version": "2.1.5",
       "resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -819,7 +879,7 @@
       "dependencies": {
         "react-textarea-autosize": {
           "version": "8.3.3",
-          "resolved": "https://registry.npmmirror.com/react-textarea-autosize/-/react-textarea-autosize-8.3.3.tgz",
+          "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.3.3.tgz",
           "integrity": "sha512-2XlHXK2TDxS6vbQaoPbMOfQ8GK7+irc2fVK6QFIcC8GOnH3zI/v481n+j1L0WaPVvKxwesnY93fEfH++sus2rQ==",
           "requires": {
             "@babel/runtime": "^7.10.2",
@@ -3330,6 +3390,11 @@
       "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
       "dev": true
     },
+    "style-mod": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.0.0.tgz",
+      "integrity": "sha512-OPhtyEjyyN9x3nhPsu76f52yUGXiZcgvsrFVtvTkyGRQJ0XK+GPc6ov1z+lRpbeabka+MYEQxOYRnt5nF30aMw=="
+    },
     "supports-color": {
       "version": "7.2.0",
       "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
@@ -3605,6 +3670,17 @@
         "clipboard": "^2.0.6"
       }
     },
+    "vue-codemirror": {
+      "version": "6.1.1",
+      "resolved": "https://registry.npmjs.org/vue-codemirror/-/vue-codemirror-6.1.1.tgz",
+      "integrity": "sha512-rTAYo44owd282yVxKtJtnOi7ERAcXTeviwoPXjIc6K/IQYUsoDkzPvw/JDFtSP6T7Cz/2g3EHaEyeyaQCKoDMg==",
+      "requires": {
+        "@codemirror/commands": "6.x",
+        "@codemirror/language": "6.x",
+        "@codemirror/state": "6.x",
+        "@codemirror/view": "6.x"
+      }
+    },
     "vue-demi": {
       "version": "0.13.7",
       "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.13.7.tgz",
@@ -3699,6 +3775,11 @@
         "@vue/devtools-api": "^6.0.0-beta.11"
       }
     },
+    "w3c-keyname": {
+      "version": "2.2.6",
+      "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.6.tgz",
+      "integrity": "sha512-f+fciywl1SJEniZHD6H+kUO8gOnwIr7f4ijKA6+ZvJFjeGi1r4PDLl53Ayud9O/rk64RqgoQine0feoeOU0kXg=="
+    },
     "wangeditor": {
       "version": "4.7.15",
       "resolved": "https://registry.npmmirror.com/wangeditor/-/wangeditor-4.7.15.tgz",

+ 1 - 0
package.json

@@ -35,6 +35,7 @@
     "vue": "^3.2.37",
     "vue-baidu-map-3x": "^1.0.18",
     "vue-clipboard3": "^1.0.1",
+    "vue-codemirror": "^6.1.1",
     "vue-grid-layout": "^3.0.0-beta1",
     "vue-i18n": "9.1.10",
     "vue-router": "^4.0.13",

+ 1 - 0
src/api/network/index.ts

@@ -3,4 +3,5 @@ import { get, post, del, put } from '/@/utils/request_network';
 export default {
   getList: (params?: object) => get('/tunnel/list', params),
   deleteItem: (params?: object) => del('/tunnel/delete', params),
+  getDetail: (params?: object) => get('/tunnel/get', params)
 }

+ 109 - 0
src/components/codeEditor/index.vue

@@ -0,0 +1,109 @@
+<template>
+  <div>
+    <textarea ref="editor"></textarea>
+  </div>
+</template>
+<script setup lang="ts">
+// 引入全局实例
+import _CodeMirror from "codemirror/lib/codemirror.js";
+// 核心样式
+import "codemirror/lib/codemirror.css";
+import "codemirror/theme/monokai.css";
+import "codemirror/addon/fold/foldgutter.css";
+import "codemirror/addon/display/fullscreen.css";
+import "codemirror/addon/dialog/dialog.css";
+import "codemirror/addon/search/matchesonscrollbar.css";
+import "codemirror/addon/scroll/simplescrollbars.css";
+import "codemirror/addon/fold/foldcode.js";
+import "codemirror/addon/edit/closetag.js";
+import "codemirror/addon/fold/foldgutter.js";
+import "codemirror/addon/fold/brace-fold.js";
+import "codemirror/addon/fold/xml-fold.js";
+import "codemirror/addon/fold/indent-fold.js";
+import "codemirror/addon/fold/comment-fold.js";
+import "codemirror/addon/edit/closebrackets.js";
+import "codemirror/addon/fold/xml-fold.js";
+import "codemirror/addon/edit/matchtags.js";
+import "codemirror/addon/display/fullscreen.js";
+import "codemirror/addon/dialog/dialog.js";
+import "codemirror/addon/search/searchcursor.js";
+import "codemirror/addon/search/search.js";
+import "codemirror/addon/scroll/annotatescrollbar.js";
+import "codemirror/addon/search/matchesonscrollbar.js";
+import "codemirror/addon/search/jump-to-line.js";
+import "codemirror/addon/scroll/simplescrollbars.js";
+import "codemirror/mode/htmlmixed/htmlmixed.js";
+import "codemirror/mode/javascript/javascript.js";
+import "codemirror/mode/xml/xml.js";
+import "codemirror/mode/css/css.js";
+import { ref, nextTick } from "vue";
+import "codemirror/mode/javascript/javascript.js";
+
+let props = defineProps({
+  mode: {
+    type: String,
+    required: false,
+    default: 'htmlmixed'
+  },
+  content: {
+    type: String,
+    required: false,
+    default: ''
+  }
+})
+
+const editor = ref();
+
+let coder;
+
+nextTick(() => {
+  coder = _CodeMirror.fromTextArea(editor.value, {
+    mode: props.mode, // 不设置的话,默认使用第一个引用
+    // 缩进格式
+    tabSize: 2,
+    // 显示行号
+    lineNumbers: true,
+    lineWrapping: true,
+    theme: "material-ocean",
+    matchTags: { bothTags: true },
+    foldGutter: true,
+    autoCloseTags: true,
+    autoCloseBrackets: true,
+    scrollbarStyle: "simple",
+    extraKeys: {
+      "Alt-F": "findPersistent",
+    },
+    gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter", "breakpoints"]
+  });
+  console.log(props)
+  coder.setValue(props.content);
+});
+
+/**
+ * 对外提供赋值
+ */
+const setValue = (val: string) => {
+  coder.setValue(val);
+};
+
+/**
+ * 设置模式
+ */
+const setMode = (mode: string) => {
+  console.info(mode)
+  coder.setOption("mode", mode);
+}
+
+/**
+ * 对外提供取值
+ */
+const getValue = () => {
+  return coder.getValue();
+};
+
+defineExpose({
+  setValue,
+  getValue,
+  setMode,
+})
+</script>

+ 7 - 3
src/views/network/tunnel/component/list.vue

@@ -17,9 +17,7 @@
             <el-table-column align="center" label="操作" width="200">
                 <template #default="scope">
                     
-                    <router-link :to="'/network/tunnel/detail/' + scope.row.id" class="link-type" style="padding-right: 12px; font-size: 12px;color: #409eff;">
-                        <el-button size="small" type="text">详情</el-button>
-                    </router-link>
+                    <el-button @click="toDetail(scope.row.id)" size="small" type="text">详情</el-button>
                     <el-button size="small" link key="info" type="info" @click="onOpenEditSign(scope.row)">编辑</el-button>
                    
                     <el-popover placement="bottom" :width="160" trigger="click">
@@ -59,6 +57,7 @@
 <script lang="ts">
 import { ref, toRefs, reactive, onMounted, nextTick, computed, watch, defineComponent } from 'vue';
 import { ElMessageBox, ElMessage } from 'element-plus';
+import { useRouter } from 'vue-router';
 
 import api from '/@/api/network';
 
@@ -90,6 +89,7 @@ export default defineComponent({
 		},
     },
     setup(props, { emit }) {
+        const router = useRouter();
         const state = reactive<TableData>({
 			data: [],
             total: 0,
@@ -147,6 +147,9 @@ export default defineComponent({
 				})
 				.catch(() => {});
 		};
+        const toDetail = (id: number) => {
+            router.push(`/network/tunnel/detail/${id}`)
+        };
         // 监听双向绑定 queryForm 的变化
 		watch(
             () => props.queryForm,
@@ -164,6 +167,7 @@ export default defineComponent({
 		});
         return {
             fetchList,
+            toDetail,
             onRowDel,
             onHandleSizeChange,
             onHandleCurrentChange,

+ 81 - 0
src/views/network/tunnel/component/serverDetail.vue

@@ -0,0 +1,81 @@
+<!-- 服务器详情页 -->
+<template>
+	<div class="server-detail-wrap">
+        <div class="server-detail-item-wrap">
+            <div class="label">名称</div>
+            <div class="value">新建服务器</div>
+        </div>
+        <div class="server-detail-item-wrap">
+            <div class="label">类型</div>
+            <div class="value">tcp</div>
+        </div>
+        <div class="server-detail-item-wrap">
+            <div class="label">地址</div>
+            <div class="value">8888</div>
+        </div>
+        <div class="server-detail-item-wrap">
+            <div class="label">状态</div>
+            <div class="value">启动</div>
+        </div>
+         <div class="server-detail-item-wrap">
+            <div class="label">禁用</div>
+            <div class="value">
+                <el-switch size="small" v-model="value1" />
+            </div>
+        </div>
+        <div class="server-detail-item-wrap">
+            <div class="label">创建时间</div>
+            <div class="value">2022-09-02 17:12:10</div>
+        </div>
+    </div>
+</template>
+<script lang="ts">
+import { toRefs, reactive, onMounted, ref, defineComponent } from 'vue';
+import { Delete, Edit, Search, Share, Upload } from '@element-plus/icons-vue';
+
+
+
+interface TableDataState {
+	ids: number,
+    value1: boolean
+}
+export default defineComponent({
+	name: 'serverDetail',
+	props: {
+		data: {
+			type: String,
+			default: 'add'
+		}
+	},
+
+	setup(props, context) {
+		const state = reactive<TableDataState>({
+            ids: 0,
+            value1: true
+		});
+		onMounted(() => {
+		});
+		return {
+			...toRefs(props),
+			...toRefs(state),
+		};
+	}
+});
+</script>
+
+<style lang="scss" scoped>
+.server-detail-wrap {
+    .server-detail-item-wrap {
+        display: flex;
+        justify-content: space-between;
+        padding: 10px;
+        border-left: 1px solid var(--el-border-color-light);
+        border-top: 1px solid var(--el-border-color-light);
+        border-right: 1px solid var(--el-border-color-light);
+    }
+    .server-detail-item-wrap:last-child {
+        border-bottom: 1px solid var(--el-border-color-light);
+    }
+}
+</style>
+

+ 7 - 1
src/views/network/tunnel/component/table.vue

@@ -25,7 +25,7 @@
         </el-table> -->
         <div class="content">
             <!-- <section v-for="(item, index) in data" :key="index"> -->
-            <el-card class="item" shadow="hover" v-for="(item, index) in data" :key="index">
+            <el-card class="item" @click="toDetail(item.id)" shadow="hover" v-for="(item, index) in data" :key="index">
                 <div class="top-inner-wrap">
                     <span>通道:{{item.id}}</span>
                     <span class="more">更多
@@ -67,6 +67,7 @@
 
 <script lang="ts">
 import { ref, toRefs, reactive, onMounted, nextTick, computed, watch, defineComponent } from 'vue';
+import { useRouter } from 'vue-router';
 import api from '/@/api/network';
 
 // 定义接口来定义对象的类型
@@ -96,6 +97,7 @@ export default defineComponent({
 		},
     },
     setup(props, { emit }) {
+        const router = useRouter();
         const state = reactive<TableData>({
 			data: [],
             total: 0,
@@ -133,6 +135,9 @@ export default defineComponent({
 
 
 		};
+        const toDetail = (id: number) => {
+            router.push(`/network/tunnel/detail/${id}`)
+        };
         // 监听双向绑定 queryForm 的变化
 		watch(
             () => props.queryForm,
@@ -149,6 +154,7 @@ export default defineComponent({
 			initTableData();
 		});
         return {
+            toDetail,
             onHandleSizeChange,
             onHandleCurrentChange,
             ...toRefs(state),

+ 97 - 28
src/views/network/tunnel/detail.vue

@@ -1,56 +1,122 @@
 <template>
-	<div class="system-dic-container">
-	 <h1>通道详情</h1>
-	</div>
+	<el-card class="system-dic-container" style="position: relative;">
+		<el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
+			<el-tab-pane label="服务器详情" name="first">
+				<serverDetail />
+			</el-tab-pane>
+			<el-tab-pane label="相关详情" name="second">相关详情</el-tab-pane>
+			<el-tab-pane label="通道" name="third">通道</el-tab-pane>
+		</el-tabs>
+		<div style="position: absolute;right:20px;top: 34px;">
+			<el-icon style="font-size: 16px;"><ele-RefreshRight /></el-icon>
+			<el-icon style="font-size: 16px;margin: 0 6px;"><ele-Operation /></el-icon>
+			<el-icon style="font-size: 16px;"><ele-Edit /></el-icon>
+		</div>
+	  	 <!-- <codeEditor ref="mirrorRef"
+	  :mode="resourceModalPro.mode"
+	  :content="resourceModalPro.content"
+	  >
+	  </codeEditor> -->
+	</el-card>
 </template>
 <script lang="ts">
 import { toRefs, reactive, onMounted, ref, defineComponent } from 'vue';
 import { Delete, Edit, Search, Share, Upload } from '@element-plus/icons-vue';
 import { ElMessageBox, ElMessage, FormInstance } from 'element-plus';
+import type { TabsPaneContext } from 'element-plus'
+import codeEditor from '/@/components/codeEditor/index.vue'
 
+import serverDetail from './component/serverDetail.vue'
 
 import { useRoute } from 'vue-router';
 
-// import api from '/@/api/device';
+import api from '/@/api/network';
 
 interface TableDataState {
 	// ids: number[];
-	title: string,
-	// tableData: {
-	// 	data: [];
-	// 	total: number;
-	// 	loading: boolean;
-	// 	param: {
-	// 		pageNum: number;
-	// 		pageSize: number;
-	// 		name: string;
-	// 		deviceType: string;
-	// 		status: string;
-	// 		dateRange: string[];
-	// 	};
-	// };
+	ids: number,
+	resourceModalPro: {
+		mode: string,
+		content: string,
+		// content: object,
+	}
 }
 export default defineComponent({
 	name: 'tunnelDetail',
-	components: {  },
+	components: { codeEditor, serverDetail },
+	props: {
+		type: {
+			type: String,
+			default: 'add'
+		}
+	},
 
-	setup(prop, context) {
+	setup(props, context) {
 		const route = useRoute();
-		// const editDicRef = ref();
-		// const editAttrRef = ref();
-		// const editFunRef = ref();
-		// const editEventRef = ref();
-		// const editTabRef = ref();
 		const state = reactive<TableDataState>({
-            title: ''
+            ids: 0,
+			resourceModalPro: {
+				mode: '',
+				// content: '{\n "id": 100,\n "name": "vera", \n}'
+				content: ''
+			}
+		});
+		const activeName = ref('first')
+		const getDetail = () => {
+			const id = route.params && route.params.id;
+			api.getDetail({"id": id}).then((res: any) => {
+				console.log(res)
+			})
+		};
+		onMounted(() => {
+			
+			getDetail()
+			let obj = {
+						"id": 1,
+						"name": "新建服务器",
+						"type": "tcp",
+						"addr": "10010",
+						"register": {
+							"regex": "^\\w+$"
+						},
+						"heartbeat": {
+							"enable": false,
+							"timeout": 30,
+							"regex": "^\\w+$"
+						},
+						"protocol": {
+							"name": "ModbusTCP",
+							"options": {}
+						},
+						"devices": [
+							{
+								"station": 1,
+								"product_id": ""
+							}
+						],
+						"disabled": false,
+						"updated": "2022-08-26T15:10:07+08:00",
+						"created": "2022-08-20T18:44:20+08:00",
+						"running": true
+					}
+					var jsonData = JSON.stringify(obj);//data是请求的后台数据
+					state.resourceModalPro.content = JSON.stringify(JSON.parse(jsonData),null,4);
 		});
+		const handleClick = (tab: TabsPaneContext, event: Event) => {
+			console.log(tab, event)
+		}
+
 		return {
 			Edit,
+			activeName,
+			getDetail,
+			handleClick,
 			// editDicRef,
 			// editAttrRef,
 			// editFunRef,
 			// editEventRef,
 			// editTabRef,
+			...toRefs(props),
 			...toRefs(state),
 		};
 	},
@@ -58,7 +124,10 @@ export default defineComponent({
 </script>
 
 <style>
-
+.CodeMirror {
+  width: 100%;
+  height: 600px;
+  font-size: 16px;
+}
 </style>
 
-