cauto 2 years ago
parent
commit
d5c55902f7
8 changed files with 288 additions and 12 deletions
  1. 3 3
      public/menu.json
  2. 30 3
      src/apis/node.ts
  3. 2 2
      src/components/sider.vue
  4. 13 0
      src/model/node.ts
  5. 8 2
      src/router/index.ts
  6. 115 0
      src/utils/storage.ts
  7. 27 2
      src/view/node/index.vue
  8. 90 0
      src/view/task/index.vue

+ 3 - 3
public/menu.json

@@ -21,10 +21,10 @@
         {
           "key": "3",
           "icon": "AppleOutlined",
-          "title": "其他",
-          "path": "/node/oth"
+          "title": "定时管理",
+          "path": "/task"
         }
       ]
     }
   ]
-}
+}

+ 30 - 3
src/apis/node.ts

@@ -1,6 +1,6 @@
 
 import httprequest from "/@/request/index";
-import {INodeList, NodeAddParam, NodeinfoParam} from "/@/model/node"
+import {INodeList, NodeAddParam, NodeinfoParam, TaskNode} from "/@/model/node"
 
 
 // 用户登录
@@ -9,7 +9,34 @@ export const nodeReqUse = (params: NodeinfoParam) => {
     return httprequest.get<INodeList>('api/api/v1/node/all', params);
 }
 
-
+// 添加节点
 export const nodeAddReqUse = (params : any) => {
     return httprequest.post<any>("api/api/v1/node/add",params)
-}
+}
+
+// 删除节点
+export const delNodeReqUse = (params : any) => {
+    return httprequest.post<any>("api/api/v1/node/del",params)
+}
+
+
+// 编辑节点
+export const editNodeReqUse = (params : any) => {
+    return httprequest.post<any>("api/api/v1/node/edit",params)
+}
+
+
+// 开启Ping任务
+export const startNodeReqUse = (params : any) => {
+    return httprequest.post<TaskNode>("api/api/v1/node/start",params)
+}
+
+// 停止任务
+export const stopNodeReqUse = (params : any) => {
+    return httprequest.post<any>("api/api/v1/node/stop",params)
+}
+
+// 查看任务状态
+export const taskNodeReqUse = (params : any) => {
+    return httprequest.get<TaskNode>("api/api/v1/node/task",params)
+}

+ 2 - 2
src/components/sider.vue

@@ -33,7 +33,7 @@ export default defineComponent({
   },
   data() {
     return {
-      collapsed: false,
+      collapsed: true,
       menuList: [],
     }
   },
@@ -54,4 +54,4 @@ export default defineComponent({
 
 <style scoped>
 
-</style>
+</style>

+ 13 - 0
src/model/node.ts

@@ -26,4 +26,17 @@ export interface INode {
   createAt: string;
   pingType: number;
   urlStatus: number;
+  nodeMs : number;
+}
+
+
+export interface RetEntry {
+  name: string;
+  time: string;
+}
+
+export interface TaskNode {
+  retEntry: RetEntry[];
+  retCronCount: number;
+  status: number;
 }

+ 8 - 2
src/router/index.ts

@@ -2,17 +2,23 @@ import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
 import HelloWorld from '/@/components/HelloWorld.vue'
 import Index from '/@/view/index/index.vue'
 import Node from '/@/view/node/index.vue'
+import Task from '/@/view/task/index.vue'
 
 const routes: Array<RouteRecordRaw> = [
     {
-     path: '/', 
+     path: '/',
      name: 'index',
-      component: Index 
+      component: Index
     },
     {
         path:'/node',
         name: 'node',
         component:Node
+    },
+    {
+        path:'/task',
+        name: 'task',
+        component:Task
     }
 ]
 const router = createRouter({ history: createWebHashHistory(), routes })

+ 115 - 0
src/utils/storage.ts

@@ -0,0 +1,115 @@
+/**
+ * 为什么不支持加密存储?
+ * 1.单一职责,只负责存储,不管存储什么样的数据。
+ * 2.加密需要引入库,会增加代码大小和复杂度,但这不是必要的。
+ * 3.加密功能,完全可以另外封装一个方法,将数据加密后再行存储,而不是耦合到存储方法中!
+ */
+
+/** */
+interface IConfig<T> {
+    key: string;
+    value: T;
+    isLocalStorage?: boolean;
+    maxAge?: number;
+    prefix?: string;
+}
+
+/**
+ * 默认前缀
+ */
+const PREFIX = 'v3-';
+
+/**
+ * 本地/会话存储,支持设置过期时间
+ * @param config
+ * @param config.key 键
+ * @param config.value 值
+ * @param [config.isLocalStorage] 是否本地存储,默认本地存储
+ * @param [config.maxAge] 多少秒后过期
+ * @param [config.prefix] 前缀,不传入将使用设置的默认前缀
+ * @returns
+ */
+export const setStorage = <T = any>({
+                                        key,
+                                        value,
+                                        isLocalStorage = true,
+                                        maxAge,
+                                        prefix = PREFIX
+                                    }: IConfig<T>) => {
+    const storage = { data: value, expire: 0 };
+
+    if (maxAge) {
+        storage.expire = Date.now() + maxAge * 1000;
+    }
+
+    try {
+        const value = JSON.stringify(storage);
+        const name = `${prefix}${key}`;
+
+        if (isLocalStorage) {
+            localStorage.setItem(name, value);
+            return;
+        }
+
+        sessionStorage.setItem(name, value);
+    } catch (ex) {
+        console.error(ex);
+    }
+};
+
+/**
+ * 取出本地/会话存储中未过期的数据,已过期、未找到返回null
+ * @param key
+ * @param isLocalStorage
+ * @param prefix 前缀,不传则采用设置的默认前缀
+ * @returns
+ */
+export const getStorage = <T = any>(
+    key: string,
+    isLocalStorage: boolean = true,
+    prefix: string = PREFIX
+): T | null => {
+    const name = `${prefix}${key}`;
+    const storage = isLocalStorage
+        ? localStorage.getItem(name)
+        : sessionStorage.getItem(name);
+
+    if (storage === null) {
+        console.error(`not found ${name}`);
+        return null;
+    }
+
+    try {
+        const value: { data: T; expire: number } = JSON.parse(storage);
+        if (value.expire && value.expire <= Date.now()) {
+            console.error(`${name}: data expired!`);
+            return null;
+        }
+
+        return value.data;
+    } catch(e) {
+        console.error(e);
+        return null;
+    }
+};
+
+/**
+ * 删除本地/会话存储中的对应数据
+ * @param key
+ * @param isLocalStorage
+ * @param prefix 前缀,不传则采用设置的默认前缀
+ * @returns
+ */
+export const removeStorage = (
+    key: string,
+    isLocalStorage: boolean = true,
+    prefix: string = PREFIX
+) => {
+    const name = `${prefix}${key}`;
+
+    if (isLocalStorage) {
+        localStorage.removeItem(name);
+    } else {
+        sessionStorage.removeItem(name);
+    }
+};

+ 27 - 2
src/view/node/index.vue

@@ -94,7 +94,7 @@ import {
   unref
 } from "vue";
 import {INode, NodeAddParam} from "/@/model/node";
-import {nodeAddReqUse, nodeReqUse} from "/@/apis/node";
+import {delNodeReqUse, nodeAddReqUse, nodeReqUse} from "/@/apis/node";
 import { ColumnProps } from "ant-design-vue/lib/table";
 import {it} from "node:test";
 import {message} from "ant-design-vue";
@@ -124,7 +124,6 @@ export default defineComponent({
     const formRef = ref()
     const reload: any = inject('reload')
     //const reload = inject("reload");
-
     const columns = [
       {
         title: 'Id',
@@ -173,6 +172,11 @@ export default defineComponent({
         key: 'urlStatus',
         dataIndex: 'urlStatus',
       },
+      {
+        title: 'nodeMs',
+        key: 'nodeMs',
+        dataIndex: 'nodeMs',
+      },
       {
         title: 'Delete',
         key: 'delete',
@@ -231,6 +235,24 @@ export default defineComponent({
 
     }
 
+
+    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()
     })
@@ -313,6 +335,9 @@ export default defineComponent({
 
     const onDeleteNode = ( record )=>{
       console.log(record.id);
+      delNodeById({
+        "id" : record.id
+      })
     }
 
 

+ 90 - 0
src/view/task/index.vue

@@ -0,0 +1,90 @@
+<template>
+
+  <a-input-group size="large">
+    <div>
+      <a-space>
+        <a-input v-model:value="startTime" placeholder="输入定时时间(60)秒" style="width: 200px" />
+        <a-button type="primary" class="role_btn role_add" @click="onStartPing">开启PING任务</a-button>
+        <a-button type="primary" class="role_btn role_add" @click="onTaskPing">查看任务</a-button>
+      </a-space>
+    </div>
+    <div>
+      <a-space>
+        <a-button type="primary" class="role_btn role_add" @click="onDeletePing">停止任务</a-button>
+        <a-select v-model:value="removeTask" placeholder="不移除">
+          <a-select-option  :value=0>不移除</a-select-option>
+          <a-select-option :value=1>移除</a-select-option>
+        </a-select>
+      </a-space>
+    </div>
+    <div style="margin-top: 10px">
+      <a-textarea v-model:value="data" :disabled="true"  style="height: 500px" />
+    </div>
+  </a-input-group>
+
+</template>
+
+<script lang="ts">
+
+import {defineComponent, reactive, ref, toRefs} from "vue";
+import {startNodeReqUse, stopNodeReqUse, taskNodeReqUse} from "/@/apis/node";
+import {TaskNode} from "/@/model/node";
+
+interface Value {
+  value?: string;
+  label?: string;
+}
+
+export default defineComponent ({
+  name: "task",
+  setup() {
+
+    const provinceData = ['Zhejiang', 'Jiangsu'];
+
+    const status = reactive({
+      data : undefined,
+      startTime : 60,
+      removeTask: 0,
+    })
+
+    const onStartPing = () =>{
+        startNodeReqUse({
+          "startTime" : 60
+        }).then(r =>
+            status.data = JSON.stringify(r.data)
+        )
+    }
+    const onDeletePing = () =>{
+      stopNodeReqUse({
+        "remove" : status.removeTask
+      }).then(r =>
+          status.data = JSON.stringify(r.data)
+      )
+      //console.log(status.removeTask);
+    }
+    const onTaskPing = () =>{
+      taskNodeReqUse({
+        "startTime" : 60
+      }).then(r =>
+          status.data = JSON.stringify(r.data)
+      )
+
+      status.data = "aaaaa"
+    }
+    return {
+      onStartPing,
+      onDeletePing,
+      onTaskPing,
+      ...toRefs(status),
+    }
+  }
+
+})
+</script>
+
+<style lang="less" scoped>
+//.components-input-demo-size .ant-input {
+//  width: 200px;
+//  margin: 0 8px 8px 0;
+//}
+</style>