cauto 2 years ago
parent
commit
44db55df5c

+ 12 - 0
public/menu.json

@@ -21,8 +21,20 @@
         {
           "key": "2.2",
           "icon": "AppleOutlined",
+          "title": "PING配置",
+          "path": "/pingconfig"
+        },
+        {
+          "key": "2.3",
+          "icon": "AppleOutlined",
           "title": "定时管理",
           "path": "/task"
+        },
+        {
+          "key": "2.4",
+          "icon": "AppleOutlined",
+          "title": "服务器配置",
+          "path": "/nodeconfig"
         }
       ]
     }

+ 23 - 2
src/App.vue

@@ -2,12 +2,30 @@
   <router-view></router-view>
 </template>
 <script lang="ts">
+// This starter template is using Vue 3 <script setup> SFCs
+// Check out https://vuejs.org/api/sfc-script-setup.html#script-setup
+import Sider from '/@/components/sider.vue'
+import {
+  UserOutlined,
+  VideoCameraOutlined,
+  UploadOutlined,
+  MenuUnfoldOutlined,
+  MenuFoldOutlined,
+} from '@ant-design/icons-vue';
 import { defineComponent, ref } from 'vue';
 export default defineComponent({
-
+  components: {
+    UserOutlined,
+    VideoCameraOutlined,
+    UploadOutlined,
+    MenuUnfoldOutlined,
+    MenuFoldOutlined,
+    Sider
+  },
   setup() {
     return {
-
+      selectedKeys: ref<string[]>(['1']),
+      collapsed: ref<boolean>(false)
     };
   },
 });
@@ -22,5 +40,8 @@ export default defineComponent({
   min-height: 100%;
 }
 
+.loginout {
+  float:right;
+}
 
 </style>

+ 20 - 0
src/apis/node.ts

@@ -2,6 +2,8 @@
 import httprequest from "/@/request/index";
 import {INodeList, NodeAddParam, NodeinfoParam, NodeItme, NodeItmeData, TaskNode} from "/@/model/node"
 import {LoginRet} from "/@/model/login";
+import {PingConfig} from "/@/model/pingconfig";
+import NodeConfigData = namespace.NodeConfigData;
 
 
 // 用户登录
@@ -56,4 +58,22 @@ export const loginReqUse = (params : any) => {
 //登录退出
 export const loginOutReqUse = (params : any) => {
     return httprequest.post<any>("api/v1/auth/loginout",params)
+}
+
+
+
+//获取PING配置
+export const pingConfigReqUse = (params : any) => {
+    return httprequest.get<PingConfig>("api/v1/ping/config/get",params)
+}
+
+
+//获取PING配置
+export const pingConfigEditReqUse = (params : any) => {
+    return httprequest.post<any>("api/v1/ping/config/edit",params)
+}
+
+//获取全部nodeconfig配置
+export const nodeConfigGetALLReqUse = (params : any) => {
+    return httprequest.get<NodeConfigData>("api/v1/node/config/all",params)
 }

+ 45 - 0
src/components/SubMenu.vue

@@ -0,0 +1,45 @@
+<template>
+  <a-sub-menu :key="menuInfo.path">
+<!--    <template #icon>    <component :is="$antIcons[item.icon]" /> </template>-->
+    <template #title>{{ menuInfo.title }}</template>
+    <template v-for="item in menuInfo.children" :key="item.path">
+      <template v-if="!item.children">
+        <a-menu-item :key="item.path" @click="menuItemClick(item)">
+          <template #icon>
+            <component :is="$antIcons[item.icon]" />
+          </template>
+          {{ item.title }}
+        </a-menu-item>
+      </template>
+      <template v-else>
+        <sub-menu
+            :key="item.path"
+            :menu-info="item"
+            @menuItemClick="menuItemClick(item)"
+        ></sub-menu>
+      </template>
+    </template>
+  </a-sub-menu>
+</template>
+
+<script lang="ts" setup name="SubMenu">
+
+interface MenuInfo {
+  key: string;
+  title: string;
+  path?: string;
+  icon?: string;
+  children?: MenuInfo[];
+}
+
+defineProps<{
+  menuInfo: MenuInfo;
+}>();
+
+const emit = defineEmits(['menuItemClick']);
+
+const menuItemClick = (item: MenuInfo) => {
+  emit('menuItemClick', item);
+};
+</script>
+

+ 70 - 52
src/components/sider.vue

@@ -1,56 +1,74 @@
 <template>
-  <a-menu
-      v-model:openKeys="openKeys"
-      v-model:selectedKeys="selectedKeys"
-      mode="inline"
-      theme="dark"
-  >
-    <div v-for="item in menuList">
-      <a-menu-item v-if="!item.children" :key="item.key">
-        <router-link :to="item.path">
-          <component :is="$antIcons[item.icon]" />
-          <span>{{ item.title }}</span>
-        </router-link>
-      </a-menu-item>
-      <submenu v-else :key="item.key" :menu-info="item" />
-    </div>
-  </a-menu>
+  <a-layout-sider v-model:collapsed="collapsed" collapsible>
+    <a-menu
+        :selectedKeys="selectedKeys"
+        @update:selectedKeys="updateSelectedKeys"
+        theme="dark"
+        mode="inline"
+        :openKeys="openKeys"
+        @update:openKeys="updateOpenKeys"
+    >
+      <template v-for="item in menuList" :key="item.path">
+        <template v-if="!item.children">
+          <a-menu-item :key="item.path" @click="menuItemClick(item)">
+            <template #icon>
+              <component :is="$antIcons[item.icon]" />
+            </template>
+            {{ item.title }}
+          </a-menu-item>
+        </template>
+        <template v-else>
+          <sub-menu
+              :key="item.path"
+              :menu-info="item"
+              @menuItemClick="menuItemClick"
+          ></sub-menu>
+        </template>
+      </template>
+    </a-menu>
+  </a-layout-sider>
 </template>
-<script lang="ts">
-import { Menu, } from 'ant-design-vue';
-import {defineComponent, onMounted, reactive, ref, toRefs} from "vue";
-import axios from "axios";
-import submenu from '/@/components/submenu.vue'
-export default defineComponent({
-
-  components: {
-    submenu,
-    Menu
-  },
-  setup() {
-      const status = reactive({
-        menuList: [],
-      })
-
-      const getData = () => {
-        axios.get('/menu.json').then(res => {
-          status.menuList = res.data.menuItems
-        })
-      }
-
-      onMounted(()=>{
-        getData()
-      })
-
-      return {
-        ...toRefs(status),
-        selectedKeys: ref(['2']),
-        openKeys : ref(['2.1']),
-      }
-  }
-})
-</script>
 
-<style scoped>
+<script lang="ts" setup>
+import SubMenu from '/@/components/SubMenu.vue';
+
+import { SettingOutlined } from '@ant-design/icons-vue';
+
+interface MenuInfo {
+  key: string;
+  title: string;
+  path?: string;
+  icon?: string;
+  children?: MenuInfo[];
+}
+
+interface Props {
+  menuList: Array<MenuInfo>;
+  selectedKeys: string[];
+  openKeys: string[];
+  collapsed?: boolean;
+}
+
+withDefaults(defineProps<Props>(), {
+  collapsed: false
+});
+
+const emit = defineEmits([
+  'menuItemClick',
+  'update:selectedKeys',
+  'update:openKeys'
+]);
+
+const updateSelectedKeys = (...res: string[][]) => {
+  emit('update:selectedKeys', ...res);
+};
+
+const updateOpenKeys = (...res: string[][]) => {
+  emit('update:openKeys', ...res);
+};
+
+const menuItemClick = (item: MenuInfo) => {
+  emit('menuItemClick', item);
+};
+</script>
 
-</style>

+ 0 - 36
src/components/submenu.vue

@@ -1,36 +0,0 @@
-<template >
-  <a-sub-menu :key="menuInfo.key" :title="menuInfo.title" >
-<!--    <span slot="title">-->
-<!--      <a-icon type="mail" /><span>-->
-<!--    </span>-->
-    <div v-for="item in menuInfo.children" :key="item">
-       
-      <a-menu-item v-if="!item.children" :key="item.key">
-        <router-link :to="item.path">
-          <component :is="$antIcons[item.icon]" />
-          <span>{{ item.title }}</span>
-        </router-link>
-      </a-menu-item>
-      
-      <submenu v-else :key="item.key" :menu-info="item" />
-    </div>
-  </a-sub-menu>
-
-</template>
-<script lang="ts">
-// import { ComponentInternalInstance, getCurrentInstance } from 'vue';
-// const { proxy } = getCurrentInstance() as ComponentInternalInstance
-import {defineComponent} from "vue";
-export default defineComponent({
-  props: ["menuInfo"],
-  setup(){
-    return {
-      
-    }
-  }
-})
-</script>
-
-<style scoped>
-
-</style>

+ 7 - 0
src/model/menu.ts

@@ -0,0 +1,7 @@
+export interface MenuInfo {
+    key: string;
+    title: string;
+    path?: string;
+    icon?: string;
+    children?: MenuInfo[];
+}

+ 41 - 0
src/model/nodeconfig.ts

@@ -0,0 +1,41 @@
+declare module namespace {
+
+    export interface Node {
+        Id: number;
+        Name: string;
+        Host: string;
+    }
+
+    export interface NodeConfig {
+        Id: number;
+        Serverid: number;
+        Sshcommand: string;
+        Sshpassword: string;
+        Sshusername: string;
+    }
+
+    export interface NodeConfigItem {
+        Node: Node;
+        NodeConfig: NodeConfig[];
+    }
+
+    export interface NodeConfigData {
+        NodeConfigItem: NodeConfigItem[];
+    }
+
+
+
+    export interface NodeConfigInfo {
+        Id: number;
+        Name: string;
+        Host: string;
+        Sshcommand: string;
+        Sshpassword: string;
+        Sshusername: string;
+    }
+
+
+
+
+}
+

+ 10 - 0
src/model/pingconfig.ts

@@ -0,0 +1,10 @@
+export interface PingConfigItem{
+    nodeDie: number
+    nodeCount: number
+    nodeLoos: number
+    pingTime: number
+    pingName: string
+}
+export interface PingConfig {
+    PingConfig: PingConfigItem
+}

+ 1 - 1
src/request/index.ts

@@ -58,7 +58,7 @@ class RequestHttp {
 				return {
 					...config,
 					headers: {
-						'x-access-token': token, // 请求头中携带token信息
+						'Authorization': "Bearer " + token, // 请求头中携带token信息
 					}
 				}
 			},

+ 74 - 40
src/router/index.ts

@@ -2,41 +2,57 @@ import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
 import HelloWorld from '/@/components/HelloWorld.vue'
 import Home from '/@/view/index/index.vue'
 import Node from '/@/view/node/index.vue'
+import NodeConfig from '/@/view/node/nodeconfig.vue'
 import Task from '/@/view/task/index.vue'
 import Login from '/@/view/login/login.vue'
 import Main from "/@/view/main.vue";
+import PingConfig from "/@/view/config/index.vue";
 
 const routes: Array<RouteRecordRaw> = [
 
     {
         path: '/',
         name: 'index',
-        redirect: Login
-    },
-    {
-        path: '/main',
-        name: 'main',
         component: Main
     },
-    {
-        path: '/home',
-        name: 'home',
-        component: Home
-    },
-    {
-        path:'/node',
-        name: 'node',
-        component:Node
-    },
-    {
-        path:'/task',
-        name: 'task',
-        component:Task
-    },
     {
         path:'/login',
         name: 'login',
         component:Login
+    },
+
+    {
+        path: '/main',
+        name: 'main',
+        component: Main,
+        redirect: '/home',
+        children: [
+            {
+                path: '/home',
+                name: 'home',
+                component: Home
+            },
+            {
+                path:'/node',
+                name: 'node',
+                component:Node
+            },
+            {
+                path:'/pingconfig',
+                name: 'pingconfig',
+                component: PingConfig
+            },
+            {
+                path:'/task',
+                name: 'task',
+                component:Task
+            },
+            {
+                path:'/nodeconfig',
+                name: 'nodeconfig',
+                component:NodeConfig
+            }
+        ]
     }
 ]
 const router = createRouter({ history: createWebHashHistory(), routes })
@@ -45,28 +61,46 @@ export default router
 
 router.beforeEach((to, from, next) => {
     // 获取 token
-    const token = localStorage.getItem('token')
-    // 如果有token
-    if (token !== null && token !== '') {
-        // 带有token访问登录页面跳转至主页
-        if (to.path === '/login') {
-            console.log('token1')
-            next({ name: 'Vue_messageDemo' })
-        } else {
-            // 带有token访问其他页面允许跳转
-            next()
-        }
+
+    if (to.path == '/login'){
+        next()
     } else {
-        // 没有token
-        // 没有token访问登录页面允许
-        if (to.path === '/login') {
-            next()
+        const token = localStorage.getItem('token')
+        if (token !== null && token !== '') {
+            if (to.path === '/')
+            {
+                next('/main')
+            }
+            else {
+                next()
+            }
         } else {
-            // 没有token访问其他页面跳转至登录页面
-            next({
-                path: '/login',
-                query: { redirect: to.fullPath }
-            })
+            next('/login')
         }
     }
+
+
+    // // 如果有token
+    // if (token !== null && token !== '') {
+    //     // 带有token访问登录页面跳转至主页
+    //     if (to.path === '/main') {
+    //         console.log(token)
+    //         next()
+    //     } else {
+    //         // 带有token访问其他页面允许跳转
+    //         next()
+    //     }
+    // } else {
+    //     // 没有token
+    //     // 没有token访问登录页面允许
+    //     if (to.path === '/login') {
+    //         next()
+    //     } else {
+    //         // 没有token访问其他页面跳转至登录页面
+    //         next({
+    //             path: '/login',
+    //             query: { redirect: to.fullPath }
+    //         })
+    //     }
+    // }
 })

+ 1 - 1
src/style.css

@@ -4,7 +4,7 @@ body,#app {
   height: 100vh;
   margin: 0;
   padding: 0;
-  background: red;
+  background: white;
 }
 /* :root {
   font-family: Inter, Avenir, Helvetica, Arial, sans-serif;

+ 205 - 0
src/view/config/index.vue

@@ -0,0 +1,205 @@
+<template>
+
+  <!-- 添加点击对话框 -->
+  <a-modal v-model:visible="Visible" title="Title" @ok="handleOk">
+
+    <a-form
+        ref="formRef"
+        :model="formState"
+    >
+      <a-form-item ref="pingName" name="pingName">
+        <label>pingName:</label>
+        <a-input v-model:value="formState.pingName" />
+      </a-form-item>
+
+      <a-form-item ref="nodeCount" name="nodeCount">
+        <label>nodeCount:</label>
+        <a-input v-model:value="formState.nodeCount" />
+      </a-form-item>
+
+      <a-form-item ref="nodeDie" name="nodeDie">
+        <label>nodeDie:</label>
+        <a-input v-model:value="formState.nodeDie" placeholder="" />
+      </a-form-item>
+
+      <a-form-item ref="nodeLoos" name="nodeLoos">
+        <label>nodeLoos:</label>
+        <a-input v-model:value="formState.nodeLoos" placeholder=""/>
+      </a-form-item>
+
+      <a-form-item ref="pingTime" name="pingTime">
+        <label>pingTime:</label>
+        <a-input v-model:value="formState.pingTime" placeholder=""/>
+      </a-form-item>
+      <a-form-item :wrapper-col="{ span: 14, offset: 4 }">
+
+        <a-button  type="primary" @click="onSubmit(true)">编辑</a-button>
+
+      </a-form-item>
+    </a-form>
+  </a-modal>
+
+
+
+  <!-- 加载节点信息 -->
+  <a-table  :columns="columns" :data-source="datalist" rowKey="id" :style="{ height: '100%', borderRight: 0 }">
+    <template v-slot:bodyCell="{column , record}">
+      <template v-if="column.dataIndex === 'delete'">
+        <a-popconfirm
+            v-if="datalist.length"
+            title="是否删除这条记录"
+            @confirm="onDeleteNode(record)"
+        >
+          <a>删除</a>
+        </a-popconfirm>
+      </template>
+
+      <template v-if="column.dataIndex === 'edit'">
+        <a @click="onEditNode(record)">编辑</a>
+      </template>
+
+    </template>
+
+
+
+
+  </a-table>
+</template>
+
+<script lang="ts">
+import {defineComponent, onMounted, reactive, ref, toRaw, toRefs} from "vue";
+import {pingConfigEditReqUse, pingConfigReqUse} from "/@/apis/node";
+import {INode} from "/@/model/node";
+import {PingConfig, PingConfigItem} from "/@/model/pingconfig";
+
+export default defineComponent({
+  name: "config",
+  setup() {
+
+    const formRef = ref()
+
+
+    const columns = [
+      {
+        title: 'pingName',
+        name: 'pingName',
+        dataIndex: 'pingName',
+        key: 'pingName',
+      },
+      {
+        title: 'nodeCount',
+        name: 'nodeCount',
+        dataIndex: 'nodeCount',
+        key: 'nodeCount',
+      },
+      {
+        title: 'nodeDie',
+        name: 'nodeDie',
+        dataIndex: 'nodeDie',
+        key: 'nodeDie',
+      },
+      {
+        title: 'nodeLoos',
+        dataIndex: 'nodeLoos',
+        key: 'nodeLoos',
+      },
+
+      {
+        title: 'pingTime',
+        dataIndex: 'pingTime',
+        key: 'pingTime',
+      },
+      {
+        title: '删除',
+        key: 'delete',
+        dataIndex: 'delete',
+        // slots: { customRender: 'delete' },
+      },
+      {
+        title: '编辑',
+        key: 'edit',
+        dataIndex: 'edit',
+        // slots: { customRender: 'edit' },
+      },
+    ];
+
+    const formState = reactive({
+      pingName: "",
+      pingTime: "",
+      nodeLoos: "",
+      nodeDie: "",
+      nodeCount: "",
+    })
+
+
+    const state = reactive({
+       datalist: [] as PingConfigItem[],
+      Visible: false,
+    })
+
+    const getPingConfig = ()=>{
+      state.datalist = []
+      pingConfigReqUse(null).then(r =>{
+
+        state.datalist.push(r.data.PingConfig)
+        console.log(state.datalist);
+      })
+    }
+
+    const handleOk = () =>{
+      state.Visible = false
+    }
+
+    const onDeleteNode = (record)=>{
+
+    }
+
+    const onEditNode = (record)=>{
+      formState.pingName = record.pingName
+      formState.nodeDie = record.nodeDie
+      formState.nodeCount = record.nodeCount
+      formState.nodeLoos = record.nodeLoos
+      formState.pingTime = record.pingTime
+      state.Visible = true
+    }
+
+    const onSubmit = ( b ) =>{
+      const data = {
+        "nodedie": toRaw(formState).nodeDie,
+        "nodecount": toRaw(formState).nodeCount,
+        "nodeloos":  toRaw(formState).nodeLoos,
+        "pingtime":  toRaw(formState).pingTime,
+        "pingname":  toRaw(formState).pingName,
+      };
+      pingConfigEditReqUse(data).then(r =>
+        state.Visible = false
+      )
+
+      getPingConfig()
+    }
+
+    onMounted(  () =>{
+      getPingConfig()
+    })
+
+
+
+    return {
+      handleOk,
+      onSubmit,
+      formRef,
+      formState,
+      ...toRefs(state),
+      onDeleteNode,
+      onEditNode,
+      columns,
+    }
+  }
+})
+
+
+</script>
+
+<style scoped>
+
+</style>

+ 23 - 11
src/view/login/login.vue

@@ -1,16 +1,16 @@
 <template>
   <div class="login-container">
     <h2 class="login-title">登陆页面</h2>
-    <a-form ref="form" :model="form" class="login-form">
+    <a-form ref="formRef" :model="formState" class="login-form">
       <h2 class="title">用户登录 LOGIN</h2>
       <a-form-item>
-        <a-input v-model="form.username">
-          <a-icon slot="prefix" type="user" />
+        <a-input v-model:value="formState.username">
+<!--          <a-icon slot="prefix" type="user" />-->
         </a-input>
       </a-form-item>
       <a-form-item>
-        <a-input-password v-model="form.password">
-          <a-icon slot="prefix" type="unlock" />
+        <a-input-password v-model:value="formState.password">
+<!--          <a-icon slot="prefix" type="unlock" />-->
         </a-input-password>
       </a-form-item>
       <a-form-item>
@@ -21,29 +21,41 @@
 </template>
 
 <script lang="ts">
-import {defineComponent, reactive} from "vue";
+import {defineComponent, reactive, ref, toRaw} from "vue";
 import {loginReqUse} from "/@/apis/node.js";
+import router from "/@/router";
 
 export default defineComponent({
   name: "login",
   setup(){
-      const form = reactive({
+
+    const formRef = ref()
+
+
+      const formState = reactive({
         username : "",
         password : "",
       })
 
       const onLogin = ()=>{
+        // localStorage.setItem("token","111")
+        // router.push('main')
+        // console.log(toRaw(formState).username)
+        // console.log(toRaw(formState).password);
         loginReqUse({
-          "username" : "",
-          "password" : ""
+          "username" : toRaw(formState).username,
+          "password" : toRaw(formState).password
         }).then(r => {
-          console.log(r.data.Token);
+          //console.log(r.data.Token);
+          localStorage.setItem("token",r.data.Token)
+          router.push("main")
         })
       }
 
       return {
         onLogin,
-        form
+        formRef,
+        formState
       }
   }
 

+ 76 - 7
src/view/main.vue

@@ -2,10 +2,14 @@
   <a-layout>
 
 
-    <a-layout-sider v-model:collapsed="collapsed" :trigger="null" collapsible    mode="inline">
-      <Sider />
+    <Sider
+        :menuList="menuList"
+        v-model:openKeys="openKeys"
+        v-model:selectedKeys="selectedKeys"
+        @menuItemClick="menuItemClick"
+        @update:selectedKeys="updateselectedKeys"
+    ></Sider>
 
-    </a-layout-sider>
     <a-layout>
       <a-layout-header style="background: #fff; padding: 10px">
         <menu-unfold-outlined
@@ -14,6 +18,11 @@
             @click="() => (collapsed = !collapsed)"
         />
         <menu-fold-outlined v-else class="trigger" @click="() => (collapsed = !collapsed)" />
+
+        <span class="loginout" >
+          <a @click="onLoginOut()"> 退出</a>
+        </span>
+
       </a-layout-header>
 
       <a-layout-content
@@ -35,7 +44,18 @@ import {
   MenuUnfoldOutlined,
   MenuFoldOutlined,
 } from '@ant-design/icons-vue';
-import { defineComponent, ref } from 'vue';
+import {defineComponent, onMounted, reactive, ref, toRefs} from 'vue';
+import router from "/@/router";
+import axios from "axios";
+import {loginOutReqUse, loginReqUse} from "/@/apis/node";
+
+interface MenuItem {
+  key: string;
+  title: string;
+  path?: string;
+  icon?: string;
+  children?: MenuItem[];
+}
 export default defineComponent({
   components: {
     UserOutlined,
@@ -43,12 +63,56 @@ export default defineComponent({
     UploadOutlined,
     MenuUnfoldOutlined,
     MenuFoldOutlined,
-    Sider
+    Sider,
   },
   setup() {
+
+    const status = reactive({
+      menuList: [] as MenuItem[],
+    })
+
+    const getData = () => {
+      axios.get('/menu.json').then(res => {
+        status.menuList = res.data.menuItems
+        console.log("获取菜单");
+        console.log(status.menuList);
+      })
+    }
+    const onLoginOut = () => {
+      loginOutReqUse(null).then(r => {
+        const token = localStorage.getItem('token')
+        if (token != null && token != ''){
+          localStorage.removeItem('token')
+          router.replace('/')
+        }
+      })
+    }
+    const openKeys = ref<string[]>(['/node','/task']);
+
+    const selectedKeys = ref<string[]>(['/nodeMage']);
+
+    const title = ref<string>('');
+
+    const menuItemClick = (item: MenuItem) => {
+      title.value = item.title;
+      router.push(item.path)
+    };
+
+    const updateselectedKeys = () => {
+      return openKeys
+    }
+
+    onMounted(()=>{
+      getData()
+    })
     return {
-      selectedKeys: ref<string[]>(['1']),
-      collapsed: ref<boolean>(false)
+      onLoginOut,
+      selectedKeys,
+      collapsed: ref<boolean>(false),
+      openKeys,
+      updateselectedKeys,
+      menuItemClick,
+      ...toRefs(status),
     };
   },
 });
@@ -63,5 +127,10 @@ export default defineComponent({
   min-height: 100%;
 }
 
+.loginout {
+  display: block;
+  float:right;
+  margin-right: 20px;
+}
 
 </style>

+ 408 - 0
src/view/node/nodeconfig.vue

@@ -0,0 +1,408 @@
+<template>
+  <a-space>
+    <a-button type="primary" class="role_btn role_add" @click="showAddNode">添加节点</a-button>
+<!--    <a-button type="primary" class="role_btn role_add" @click="onDeleteALlNode">删除节点</a-button>-->
+<!--    <a-button type="primary" class="role_btn role_add" @click="onEditNode">编辑节点</a-button>-->
+  </a-space>
+
+  <!-- 添加点击对话框 -->
+  <a-modal v-model:visible="Visible" title="Title" @ok="handleOk">
+
+    <a-form
+        ref="formRef"
+        :model="formState"
+        :rules="rules"
+        :label-col="labelCol"
+        :wrapper-col="wrapperCol"
+    >
+      <a-form-item ref="name" name="name">
+        <label>name:</label>
+        <a-input v-model:value="formState.name" />
+      </a-form-item>
+
+      <a-form-item ref="host" name="host">
+        <label>host:</label>
+        <a-input v-model:value="formState.host" />
+      </a-form-item>
+
+      <a-form-item ref="port" name="port">
+        <label>port:</label>
+        <a-input v-model:value="formState.port" placeholder="输入服务器端口" />
+      </a-form-item>
+
+      <a-form-item ref="url" name="url">
+        <label>url:</label>
+        <a-input v-model:value="formState.url" placeholder="输入切换地址url"/>
+      </a-form-item>
+      <a-form-item ref="urlstatus" name="urlstatus">
+        <label>urlstatus:</label>
+        <a-input v-model:value="formState.urlstatus" placeholder="输入状态"/>
+      </a-form-item
+      >
+      <a-form-item>
+        <label>ping类型:</label>
+        <a-select v-model:value="formState.pingType" placeholder="选择ping类型">
+          <a-select-option :value=0>icmp</a-select-option>
+          <a-select-option :value=1>tcpping</a-select-option>
+        </a-select>
+      </a-form-item>
+
+<!--      <template #footer>-->
+<!--        <a-button key="back" @click="cancel">关闭</a-button>-->
+<!--        <a-button key="back" @click="resetForm">Reset</a-button>-->
+<!--        <a-button key="submit" type="primary" @click="onSubmit">Submit</a-button>-->
+<!--      </template>-->
+      <a-form-item :wrapper-col="{ span: 14, offset: 4 }">
+
+        <a-button v-if="formState.isedit === false" type="primary" @click="onSubmit(true)">编辑</a-button>
+        <a-button v-else type="primary" @click="onSubmit(false)">Create</a-button>
+
+        <a-button style="margin-left: 10px" @click="resetForm">Reset</a-button>
+      </a-form-item>
+    </a-form>
+  </a-modal>
+
+    <!-- 加载节点信息 -->
+  <a-table :row-selection="rowSelection" :columns="columns" :data-source="datalist" rowKey="id" :style="{ height: '100%', borderRight: 0 }">
+      <template v-slot:bodyCell="{column , record}">
+        <template v-if="column.dataIndex === 'delete'">
+          <a-popconfirm
+              v-if="datalist.length"
+              title="是否删除这条记录"
+              @confirm="onDeleteNode(record)"
+          >
+            <a>删除</a>
+          </a-popconfirm>
+        </template>
+
+        <template v-if="column.dataIndex === 'edit'">
+          <a @click="onEditNode(record)">编辑</a>
+          <!--          <a-popconfirm-->
+          <!--              v-if="datalist.length"-->
+          <!--              title="编辑"-->
+          <!--              @confirm="onDeleteNode(record)"-->
+          <!--          >-->
+          <!--              <a>Delete</a>-->
+          <!--          </a-popconfirm>-->
+        </template>
+
+      </template>
+
+
+
+
+  </a-table>
+</template>
+
+<script lang="ts">
+import {
+  computed,
+  defineComponent,
+  getCurrentInstance,
+  inject,
+  onMounted,
+  reactive,
+  ref,
+  toRaw,
+  toRefs,
+  unref
+} from "vue";
+import {INode, NodeAddParam, NodeStatus} from "/@/model/node";
+import {delNodeReqUse, editNodeReqUse, nodeAddReqUse, nodeConfigGetALLReqUse, nodeReqUse} from "/@/apis/node";
+import { ColumnProps } from "ant-design-vue/lib/table";
+import {it} from "node:test";
+import {message} from "ant-design-vue";
+import router from "/@/router";
+import NodeConfigInfo = namespace.NodeConfigInfo;
+type Key = ColumnProps['key'];
+export default defineComponent({
+  name:"node",
+  components:{
+
+  },
+  data(){
+    return {
+      labelCol: {
+        span: 4,
+      },
+      wrapperCol: {
+        span: 14,
+      },
+
+    }
+  },
+  mounted() {
+
+  },
+  setup() {
+    const formRef = ref()
+   // const reload: any = inject('reload')
+    //const reload = inject("reload");
+    const columns = [
+      {
+        title: 'Id',
+        name: 'Id',
+        dataIndex: 'id',
+        key: 'id',
+      },
+      {
+        title: '服务器名称',
+        name: 'Name',
+        dataIndex: 'Name',
+        key: 'Name',
+      },
+      {
+        title: '服务器IP',
+        dataIndex: 'Host',
+        key: 'Host',
+      },
+      {
+        title: '服务器命令',
+        dataIndex: 'Sshcommand',
+        key: 'Sshcommand',
+      },
+      {
+        title: '服务器密码',
+        key: 'Sshpassword',
+        dataIndex: 'Sshpassword',
+      },
+      {
+        title: '服务器名称',
+        key: 'Sshusername',
+        dataIndex:'Sshusername',
+      },
+      {
+        title: '删除',
+        key: 'delete',
+        dataIndex: 'delete',
+        // slots: { customRender: 'delete' },
+      },
+      {
+        title: '编辑',
+        key: 'edit',
+        dataIndex: 'edit',
+        // slots: { customRender: 'edit' },
+      },
+    ];
+    let ids = ""
+    const state = reactive({
+      datalist : [] as NodeConfigInfo[],
+      selectedTableRow: [] as INode[],
+      loading : false,
+      Visible : false,
+      code: false,
+    })
+
+    const rowSelection = {
+      onChange: (selectedRowKeys: Key[], selectedRows) => {
+        //第一个参数控制选不选中,第二个参数是选中列表的数据的集合
+        state.selectedTableRow = selectedRows
+        console.log(state.selectedTableRow);
+      },
+      getCheckboxProps: (record) => ({
+        disabled: record.releaseState === "ONLINE", //控制禁用那个按钮
+        releaseState: record.releaseState,
+      }),
+    };
+
+    const getNodeList = async () => {
+      let data = <NodeConfigInfo>{}
+      const node_list = await nodeConfigGetALLReqUse(null)
+      for (let dataKey in node_list.data.NodeConfigItem) {
+        data.Id = node_list.data.NodeConfigItem[dataKey].Node.Id
+        data.Name = node_list.data.NodeConfigItem[dataKey].Node.Name
+        data.Host = node_list.data.NodeConfigItem[dataKey].Node.Host
+        if (node_list.data.NodeConfigItem[dataKey].NodeConfig != null)
+        {
+          for (let nodeConfig of node_list.data.NodeConfigItem[dataKey].NodeConfig) {
+            data.Sshpassword = nodeConfig.Sshpassword;
+            data.Sshcommand = nodeConfig.Sshcommand;
+            data.Sshusername = nodeConfig.Sshusername;
+          }
+          state.datalist.push(data)
+        }
+      }
+
+      console.log(state.datalist);
+
+    }
+
+    const addNodeList = async (data) => {
+
+      let ret = await nodeAddReqUse(data)
+
+      if (ret.code == 0)
+      {
+        console.log(state.Visible);
+        state.Visible = false
+        await getNodeList()
+      }
+      else {
+        console.log(state.Visible);
+        state.Visible = true
+
+      }
+
+    }
+
+    const editNode = async (data) => {
+      let ret =  await  editNodeReqUse(data)
+      if (ret.code == 0)
+      {
+        console.log(state.Visible);
+        state.Visible = false
+        await getNodeList()
+      }
+      else {
+        console.log(state.Visible);
+        state.Visible = true
+
+      }
+
+    }
+
+
+    const delNodeById = async (data) => {
+
+      let ret = await delNodeReqUse(data)
+      if (ret.code == 0)
+      {
+        console.log(state.Visible);
+        state.Visible = false
+        await getNodeList()
+      }
+      else {
+        console.log(state.Visible);
+        state.Visible = true
+
+      }
+
+    }
+
+    onMounted(  () =>{
+       getNodeList()
+    })
+
+    const formState = reactive({
+        id: 0,
+        name: "",
+        host: "",
+        port: 22,
+        url:  "",
+        pingType: undefined,
+        isedit : false,
+        urlstatus: 0,
+        urlcount:0,
+        urlret: "",
+    })
+
+
+    const rules = {
+      name: [
+        { required: true, message: "输入服务器名称", trigger: "blur" },
+        { min: 1, max: 100, message: "Length should be 3 to 5", trigger: "blur" }
+      ],
+      host: [
+        { required: true, message: "输入服务器IP", trigger: "blur" },
+        { min: 1, max: 100, message: "Length should be 3 to 5", trigger: "blur" }
+      ]
+    }
+    const resetForm = () => {
+      formRef.value.resetFields();
+    };
+
+    const onSubmit = (isedit) =>{
+      const reqdata = {
+        "id"   : toRaw(formState).id,
+        "name" : toRaw(formState).name,
+        "host" : toRaw(formState).host,
+        "port" : toRaw(formState).port,
+        "url"  : toRaw(formState).url,
+        "pingType": toRaw(formState).pingType,
+        "urlstatus": toRaw(formState).urlstatus,
+      }
+      if (isedit){
+        editNode(reqdata)
+      } else {
+        addNodeList(reqdata)
+      }
+    }
+
+    const onEditNode = (record) => {
+      formState.id = record.id
+      formState.name = record.name
+      formState.host = record.host
+      formState.port = record.port
+      formState.url = record.url
+      formState.pingType = record.pingType
+      formState.urlstatus = record.urlstatus
+      formState.isedit = false
+      state.Visible = true
+
+    }
+
+    const  showAddNode = () => {
+      formState.name = ""
+      formState.host = ""
+      formState.port = 22
+      formState.url = ""
+      formState.pingType = undefined
+      formState.urlstatus = 0
+      formState.isedit = true
+      state.Visible = true;
+    }
+    const handleOk= () =>{
+
+      //addNodeList(data.value)
+      state.Visible = false
+    }
+    // 对话框的中的取消按钮
+    const cancel = () => {
+      state.loading = false
+      state.Visible = false
+    }
+
+    const { datalist ,selectedTableRow,loading,Visible } =  toRefs(state)
+
+    const onDeleteALlNode = () => {
+      const idsTmp = []
+      selectedTableRow.value.forEach(item => idsTmp.push(item.id))
+      ids = idsTmp.join(",")
+      console.log(ids);
+    }
+
+    const onDeleteNode = ( record )=>{
+      console.log(record.id);
+      delNodeById({
+        "id" : record.id
+      })
+    }
+
+
+    return{
+
+      onDeleteALlNode,
+      showAddNode,
+      handleOk,
+      cancel,
+      onEditNode,
+      onDeleteNode,
+      rowSelection,
+      resetForm,
+      onSubmit,
+      datalist,
+      selectedTableRow,
+      formRef,
+      formState,
+      rules,
+      columns,
+      loading,
+      Visible,
+    }
+  }
+})
+</script>
+
+<style lang="less" scoped>
+
+</style>