heyujie
2021-05-24 eb9378ccee13fd280144fa0ba2066c9bcdb6c406
日志中心
8个文件已添加
2个文件已修改
2234 ■■■■■ 已修改文件
public/apps.json 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/logCenter/components/CloudNode.vue 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/logCenter/components/switchBar.vue 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/logCenter/index/App.vue 607 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/logCenter/index/main.ts 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/logCenter/views/eventPushLog.vue 478 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/logCenter/views/operationLog.vue 202 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/logCenter/views/pollingLog.vue 384 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/logCenter/views/systemLog.vue 326 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
vue.config.js 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/apps.json
@@ -163,6 +163,29 @@
      "progressMsg": ""
    },
    {
      "id": "850b5e86-dbcf-40f2-8511-745a4d06ec85",
      "name": "日志管理(新版)",
      "package": "logCenter",
      "type": "2",
      "url": "/view/logCenter/",
      "title": "日志管理(新版)",
      "width": 1200,
      "height": 600,
      "iconBlob": "",
      "icon": "../../images/app-mid/log-manage.png",
      "version": "1.0.0",
      "create_time": "2020-10-09 14:00:09",
      "create_by": "",
      "update_time": "",
      "update_by": "",
      "isDelete": 0,
      "isDefault": true,
      "remoteVersion": "",
      "installed": true,
      "isUpgrade": false,
      "progressMsg": ""
    },
    {
      "id": "5a5e0610-0a62-4de3-8021-2c6652c29ebf",
      "name": "系统设置",
      "package": "settings",
src/pages/logCenter/components/CloudNode.vue
New file
@@ -0,0 +1,149 @@
<template>
  <div class="cloud">
    <div class="inner">
      <div class="rect">
        <serfDiagram
          ref="inside-nodes"
          :members="insideNodes"
          :agent="agentName"
          :sizeX="insideSizeX"
          :sizeY="insideSizeY"
          :startX="insideStartX"
          :isShowHover="true"
          class="inside-nodes"
        ></serfDiagram>
      </div>
    </div>
    <div class="outer" v-if="outsideNodes.length">
      <serfDiagram
        ref="outer-nodes"
        :members="outsideNodes"
        :agent="agentName"
        :sizeX="280"
        :sizeY="370"
        :startX="60"
        class="outer-nodes"
      ></serfDiagram>
    </div>
  </div>
</template>
<script>
import SerfDiagram from "@/components/serfDiagram";
export default {
  name: "cloudNode",
  props: {
    nodes: Array,
  },
  components: {
    SerfDiagram,
  },
  data() {
    return {
      agentName: "",
      nodeIcons: [],
      //insideNodes: [],
      BaseWidth: 150,
      BaseHeight: 70,
      minWidth: 0,
      minHeight: 0,
    };
  },
  mounted() {
    console.log(this.nodes);
    //this.getInsideNodes();
  },
  methods: {
    getRandom(index) {
      if (index % 2 == 0) {
        return Math.random() * 20;
      } else {
        return Math.random() * 50;
      }
    },
    getInsideNodes() {
      let arr = this.nodes.filter(
        (item) => item.hardwareType == "01" || item.hardwareType == "02"
      );
      let len = arr.length;
      let lefts = [];
      let tops = [];
      this.insideNodes = arr.map((item, index) => {
        lefts.push((20 - len) * (index + 1) + this.getRandom(index));
        tops.push(30 * (index + 1));
        return {
          l: 10 + this.getRandom(index),
          t: 30 * (index + 1),
          nodeName: item.nodeName,
          id: item.id,
          workType: item.workType,
        };
      });
      this.minWidth = Math.max(...lefts) - Math.min(...lefts);
      this.minHeight = Math.max(...tops) - Math.min(...tops);
      console.log("w,h", this.minWidth, this.minHeight);
    },
  },
  computed: {
    cloudPic() {
      return "/images/settings/cloud.png";
    },
    insideNodes() {
      return this.nodes.filter(
        (item) => item.hardwareType == "01" || item.hardwareType == "02"
      );
    },
    insideSizeX() {
      return 160 + 200 * 0.2 * this.insideNodes.length <= 400
        ? 160 + 200 * 0.2 * this.insideNodes.length
        : 400;
    },
    insideSizeY() {
      return 140 + 200 * 0.2 * this.insideNodes.length <= 380
        ? 140 + 200 * 0.2 * this.insideNodes.length
        : 380;
    },
    insideStartX() {
      return this.insideSizeX / 3;
    },
    outsideNodes() {
      return this.nodes.filter((item) => item.hardwareType == "03");
    },
  },
};
</script>
<style lang="scss">
.cloud {
  width: 100%;
  display: flex;
  .inner {
    background: url("/images/settings/easy-cloud.png") no-repeat;
    background-size: 100%;
    margin-top: -55px;
    margin-left: 55px;
    .rect {
      position: relative;
      margin: 130px 100px 70px;
      .node {
        position: absolute;
        .node-icon {
          width: 40px;
          height: 40px;
        }
        .node-name {
          font-size: 14px;
          color: #333;
        }
      }
    }
  }
  .outer {
    width: 40%;
    position: relative;
    text-align: left;
    .node {
      position: absolute;
    }
  }
}
</style>
src/pages/logCenter/components/switchBar.vue
New file
@@ -0,0 +1,42 @@
<template>
  <div class="switch-bar">
    <div class="name">{{ barName }}</div>
    <el-switch
      v-model="value"
      active-color="rgba(61, 104, 225, 1)"
      @change="switchChange"
    >
    </el-switch>
  </div>
</template>
<script>
export default {
  data() {
    return {
      // value: false,
    };
  },
  props: ["barName","value"],
  methods: {
    switchChange(val) {
      this.$emit("switchChange",val);
    },
  },
};
</script>
<style lang="scss">
.switch-bar {
  display: flex;
  align-items: center;
  height: 50px;
  padding: 0 25px;
  background-color: rgba(248, 248, 248, 1);
  justify-content: space-between;
  border-radius: 12px;
  margin-bottom: 10px;
  .name {
    font-size: 14px;
  }
}
</style>
src/pages/logCenter/index/App.vue
New file
@@ -0,0 +1,607 @@
<template>
  <div class="container">
    <div class="container-left">
      <div
        class="left-card"
        v-for="(item, index) in menuArr"
        :key="index"
        @click="openMenu(item, index)"
      >
        <span class="icon iconfont">&#xe646;</span>
        <span class="card-text">{{ item.name }}</span>
      </div>
    </div>
    <operationLog
      v-if="activePage == '操作日志'"
      style="width: 100%"
    ></operationLog>
    <systemLog
      v-if="activePage == '系统日志'"
      style="width: 100%"
    ></systemLog>
    <pollingLog v-if="activePage == '轮询日志'" style="width: 100%"></pollingLog>
    <eventPushLog
      v-if="activePage == '事件推送日志'"
      style="width: 100%"
    ></eventPushLog>
  </div>
</template>
<script>
import operationLog from "../views/operationLog";
import systemLog from "../views/systemLog";
import pollingLog from "../views/pollingLog";
import eventPushLog from "../views/eventPushLog";
export default {
  name: "settings",
  components: {
    operationLog,
    systemLog,
    pollingLog,
    eventPushLog,
  },
  data() {
    return {
      menuArr: [
        { name: "操作日志" },
        { name: "系统日志" },
        { name: "轮询日志" },
        { name: "事件推送日志" },
      ],
      activePage: "操作日志",
      activeIndex: 0,
    };
  },
  mounted() {
    const s = document.getElementsByClassName("left-card")[0];
    s.style.backgroundColor = "rgba(61, 104, 225, 1)";
    s.style.color = "#fff";
  },
  methods: {
    openMenu(item, i) {
      const old = document.getElementsByClassName("left-card")[
        this.activeIndex
      ];
      old.style.backgroundColor = "initial";
      old.style.color = "rgba(81, 81, 81, 1)";
      this.activePage = item.name;
      this.activeIndex = i;
      const s = document.getElementsByClassName("left-card")[i];
      s.style.backgroundColor = "rgba(61, 104, 225, 1)";
      s.style.color = "#fff";
    },
  },
};
</script>
<style lang="scss">
.container {
  height: 100%;
  display: flex;
  flex-direction: row;
  flex: 1;
  flex-basis: auto;
  box-sizing: border-box;
  .container-left {
    height: 100%;
    width: 210px;
    overflow: auto;
    box-sizing: border-box;
    flex-shrink: 0;
    padding: 10px;
    border-right: 5px solid rgba(248, 248, 248, 1);
    box-sizing: border-box;
    .left-card {
      height: 55px;
      cursor: pointer;
      border-radius: 12px;
      margin-bottom: 10px;
      display: flex;
      align-items: center;
      .iconfont {
        margin-left: 25px;
        margin-right: 10px;
        font-size: 24px;
      }
      .card-text {
        font-size: 16px;
      }
    }
    .left-card:hover {
      background-color: rgba(61, 104, 225, 1);
      color: #fff;
    }
  }
  .container-center {
    height: 100%;
    width: 280px;
    overflow: auto;
    flex-shrink: 0;
    padding: 10px;
    border-right: 5px solid rgba(248, 248, 248, 1);
    box-sizing: border-box;
    .account-left {
      .add-account {
        color: rgba(61, 104, 225, 1);
        margin-top: 50px;
        .iconfont {
          cursor: pointer;
          font-size: 32px;
        }
      }
      .account-card {
        height: 50px;
        background-color: rgba(248, 248, 248, 1);
        margin-bottom: 10px;
        display: flex;
        align-items: center;
        padding: 0 20px;
        box-sizing: border-box;
        border-radius: 10px;
        cursor: pointer;
        .touxiang {
          height: 35px;
          width: 35px;
          background-color: bisque;
          border-radius: 17.5px;
        }
        .user-name {
          margin-left: 10px;
          font-size: 14px;
        }
      }
    }
    .datetime-left {
      .time-card {
        height: 105px;
        background-color: rgba(248, 248, 248, 1);
        margin-bottom: 30px;
        border-radius: 10px;
        .head {
          height: 30px;
          line-height: 30px;
          text-align: left;
          box-sizing: border-box;
          padding: 0 10px;
          font-size: 14px;
          .icon {
            margin-right: 5px;
            color: rgba(61, 104, 225, 1);
          }
        }
        .time-main {
          height: 42px;
          line-height: 42px;
          font-family: Consolas;
          font-size: 36px;
        }
        .date-bot {
          height: 25px;
          font-size: 14px;
          line-height: 25px;
          color: #868686;
          display: flex;
          justify-content: space-evenly;
        }
      }
      .line {
        display: flex;
        align-items: center;
        height: 50px;
        padding: 0 25px;
        background-color: rgba(248, 248, 248, 1);
        justify-content: space-between;
        border-radius: 12px;
        margin-bottom: 10px;
        .name {
          font-size: 14px;
        }
      }
    }
  }
  .container-right {
    flex: 1;
    flex-basis: auto;
    overflow: auto;
    box-sizing: border-box;
    position: relative;
    padding: 20px 40px;
    .account-right {
      .account-content {
        .content-top {
          height: 120px;
          width: 350px;
          margin: 0 auto;
          display: flex;
          align-items: center;
          justify-content: center;
          margin-bottom: 20px;
          .touxiang-big {
            width: 100px;
            height: 100px;
            background-color: bisque;
            border-radius: 50px;
          }
          .user-desc {
            height: 100px;
            display: flex;
            flex-direction: column;
            align-items: baseline;
            min-width: 200px;
            .username {
              margin: 5px 15px;
              height: 30px;
              line-height: 30px;
              width: 90px;
              text-align: left;
              font-size: 15px;
              display: flex;
              align-items: center;
            }
            .nickname {
              margin: 5px 15px;
              font-size: 14px;
              .input-nick {
                width: 50px;
                margin-right: 5px;
              }
              .iconfont {
                font-size: 14px;
                margin-left: 5px;
              }
            }
          }
        }
        .list-btn {
          display: flex;
          flex-direction: column;
          align-items: center;
          .item-btn {
            width: 500px;
            height: 45px;
            background-color: #f0f0f0;
            margin-bottom: 15px;
            border-radius: 10px;
            line-height: 45px;
            font-size: 15px;
            cursor: pointer;
          }
          .item-btn:hover {
            color: rgba(255, 153, 102, 1);
          }
        }
      }
      .title {
        height: 30px;
        line-height: 30px;
        /* background-color: aliceblue; */
        margin-bottom: 10px;
        font-size: 16px;
        font-weight: 600;
      }
      .change-pw {
        .p-title {
          text-align: left;
          font-size: 15px;
          margin-top: 5px;
        }
      }
      .el-form-item {
        margin-bottom: 0;
        .el-input__inner {
          background-color: rgba(240, 240, 240, 1);
          border: none;
          border-radius: 12px;
          height: 45px;
          padding: 0 20px;
          font-size: 15px;
        }
        .el-input__clear {
          color: dimgray;
          font-size: 17px;
          line-height: 45px;
        }
        .el-input__suffix {
          right: 1px;
          top: -0.5px;
          width: 45px;
          // background-color: rgba(61, 104, 225, 1);
          /* color: white; */
          border-radius: 12px;
        }
      }
      .permission {
        .line {
          display: flex;
          align-items: center;
          height: 50px;
          padding: 0 25px;
          background-color: rgba(248, 248, 248, 1);
          justify-content: space-between;
          border-radius: 12px;
          margin-bottom: 10px;
          .name {
            font-size: 14px;
          }
        }
      }
      .add-account-page {
        // background-color: lightcyan;
        // padding: 10px 50px;
        .upload-group {
          height: 120px;
          width: 350px;
          margin: 0 auto;
          overflow: hidden;
          .upload-jpg {
            height: 50px;
            width: 50px;
            float: left;
            margin: 0 10px;
            background-color: antiquewhite;
            margin-bottom: 20px;
            border-radius: 25px;
          }
        }
        .fill-group {
          .p-title {
            text-align: left;
          }
        }
      }
    }
    .datetime-right {
      .el-form-item.is-required:not(.is-no-asterisk)
        > .el-form-item__label:before,
      .el-form-item.is-required:not(.is-no-asterisk)
        .el-form-item__label-wrap
        > .el-form-item__label:before {
        display: none;
      }
      .el-form-item {
        margin-bottom: 10px;
        height: 50px;
        background: #f8f8f8;
        padding: 4px 20px;
        -webkit-box-sizing: border-box;
        box-sizing: border-box;
        border-radius: 10px;
        .el-form-item__label {
          text-align: left;
          line-height: 42px;
        }
      }
      .el-form-item__content {
        line-height: 40px;
        position: relative;
        font-size: 14px;
      }
      .ip-input-container {
        max-width: none !important;
      }
      .ntp-time {
        .right {
          display: flex;
          align-items: baseline;
          .el-input-number--small {
            width: 100%;
          }
          .el-button--text {
            margin-left: 10px;
            text-decoration: underline;
          }
        }
        .ntp-bar {
          height: 40px;
          background-color: rgba(248, 248, 248, 1);
          display: flex;
          align-items: center;
          justify-content: space-between;
          padding: 0 10px;
          border-radius: 10px;
          margin-bottom: 10px;
          .title {
            min-width: 70px;
          }
          .input-area {
            width: 450px;
            height: 30px;
            background-color: rgba(240, 240, 240, 1);
            border-radius: 10px;
            line-height: 30px;
            font-size: 14px;
          }
        }
        .int-bar {
          height: 40px;
          background-color: rgba(248, 248, 248, 1);
          display: flex;
          align-items: center;
          justify-content: space-between;
          padding: 0 10px;
          border-radius: 10px;
          margin-bottom: 10px;
          .title {
            min-width: 130px;
          }
          .right {
            width: 450px;
            display: flex;
            align-items: center;
            height: 30px;
            .input-area {
              // width: 410px;
              background-color: rgba(240, 240, 240, 1);
              border-radius: 10px;
              line-height: 30px;
              width: -webkit-fill-available;
              font-size: 14px;
            }
            .test {
              width: 40px;
            }
          }
        }
      }
      .manual-time {
        .clock-wrap {
          height: 75px;
          background-color: #f8f8f8;
          display: flex;
          justify-content: center;
          align-items: center;
          margin-bottom: 10px;
          border-radius: 10px;
          .clock {
            display: flex;
            align-items: center;
            height: 90px;
            justify-content: space-evenly;
            .iconfont {
              cursor: pointer;
              color: rgba(134, 134, 134, 1);
            }
            .iconfont:hover {
              background-color: gainsboro;
            }
            .hour {
              background-color: rgba(240, 240, 240, 1);
              display: flex;
              align-items: center;
              width: 100px;
              height: 50px;
              justify-content: space-evenly;
              border-radius: 10px;
            }
            .dnum {
              width: 40px;
              height: 40px;
              line-height: 40px;
              font-size: 34px;
              font-family: Consolas;
              display: flex;
              align-items: center;
              .input-box {
                width: inherit;
                border: none;
                border-radius: 5px;
                height: 35px;
                font-size: 28px;
                text-align: center;
              }
              .input-box:focus {
                outline: none;
              }
            }
            .control {
              width: 20px;
              .fanzhuan {
                display: inline-block;
                -moz-transform: scaleY(-1);
                -webkit-transform: scaleY(-1);
                -o-transform: scaleY(-1);
                transform: scaleY(-1);
              }
            }
            .sep {
              font-family: Consolas;
              width: 40px;
              font-size: 34px;
              height: 40px;
              line-height: 40px;
            }
            .mins {
              background-color: #f0f0f0;
              display: flex;
              align-items: center;
              width: 110px;
              height: 50px;
              justify-content: space-evenly;
              border-radius: 10px;
            }
          }
        }
        .adjust-bar {
          display: flex;
          justify-content: space-between;
          align-items: center;
          margin-bottom: 10px;
          border-radius: 10px;
          height: 50px;
          background-color: rgba(248, 248, 248, 1);
          .middle {
            font-size: 14px;
          }
          .input-box {
            width: 80px;
            border: none;
            border-radius: 5px;
            height: 25px;
            font-size: 18px;
            text-align: center;
          }
          .input-box:focus {
            outline: none;
          }
          .minus {
            width: 50px;
            height: 50px;
            background-color: #f0f0f0;
            font-size: 35px;
            border-radius: 10px;
            cursor: pointer;
            line-height: 50px;
            color: rgba(134, 134, 134, 1);
          }
          .plus {
            width: 50px;
            height: 50px;
            cursor: pointer;
            background-color: #f0f0f0;
            font-size: 35px;
            border-radius: 10px;
            line-height: 50px;
            color: rgba(134, 134, 134, 1);
          }
        }
      }
    }
    .btns {
      display: flex;
      justify-content: space-between;
      margin-top: 20px;
      .cancel {
        height: 40px;
        width: 48%;
        cursor: pointer;
        border-radius: 8px;
        background-color: rgba(240, 240, 240, 1);
        line-height: 40px;
        font-size: 14px;
      }
      .ok {
        height: 40px;
        width: 48%;
        cursor: pointer;
        border-radius: 8px;
        background-color: rgba(61, 104, 225, 1);
        color: #fff;
        line-height: 40px;
        font-size: 14px;
      }
    }
  }
}
</style>
src/pages/logCenter/index/main.ts
New file
@@ -0,0 +1,16 @@
import Vue from 'vue';
import App from './App.vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import "@/assets/css/element-variables.scss";
import moment from 'moment';
Vue.use(ElementUI)
Vue.prototype.$moment = moment;
new Vue({
  el: '#app',
  render: h => h(App)
})
src/pages/logCenter/views/eventPushLog.vue
New file
@@ -0,0 +1,478 @@
<template>
  <div class="all">
    <div class="cluster-content">
      <div class="cluster-center" ref="left">
        <div class="menu-item" @click="openRight(0)">
          <div class="con">
            <span class="icon iconfont">&#xe646;</span>
            <span class="menu-text">系统更新</span>
          </div>
        </div>
        <div class="menu-item" @click="openRight(1)">
          <div class="con">
            <span class="icon iconfont">&#xe646;</span>
            <span class="menu-text">更新设置</span>
          </div>
        </div>
      </div>
      <div class="cluster-right">
        <div class="net-set" v-if="activePage == 0">
          <el-radio-group v-model="radio2" size="medium">
            <el-radio-button label="检查更新"></el-radio-button>
            <el-radio-button label="上传更新"></el-radio-button>
          </el-radio-group>
          <div class="update-center" v-if="radio2 == '检查更新'">
            <div class="spin-bg"></div>
            <div class="line"></div>
            <div class="desc">{{ "检查到最新版本:1.0.2" }}</div>
            <el-button type="primary" size="small">更新</el-button>
          </div>
          <div class="upload-center" v-if="radio2 == '上传更新'">
            <!-- uploadPlaceholder="上传升级文件" -->
            <div class="top">
              <div class="up-text">上传更新文件</div>
              <fileUploader
                single
                url="/data/api-v/sysset/patchUpdate"
                @complete="onFileUpload"
                @file-added="onFileAdded"
              />
              <el-button
                type="primary"
                size="small"
                style="width: 80px"
                @click="upgrade"
                :disabled="!fileAdded"
                :loading="upgrading"
                >升级</el-button
              >
            </div>
            <div class="update-center">
              <div class="spin-bg"></div>
              <div class="line"></div>
              <div class="desc">{{ "检查到最新版本:1.0.2" }}</div>
              <el-button type="primary" size="small">更新</el-button>
            </div>
            <!-- <span v-html="patchUpdateStatus"></span> -->
          </div>
          <div class="cur-version">当前版本:{{ "1.0.1" }}</div>
        </div>
        <div class="wifi" v-if="activePage == 1">
          <div class="content">
            <div class="title">系统更新设置</div>
            <div class="bar">
              <div class="name">自动清理软件包缓存</div>
              <el-switch
                v-model="sys_auto_clear"
                active-color="rgba(61, 104, 225, 1)"
                @change="switchChange('sys_auto_clear')"
              >
              </el-switch>
            </div>
            <div class="bar">
              <div class="name">更新提醒</div>
              <el-switch
                v-model="sys_remind"
                active-color="rgba(61, 104, 225, 1)"
                @change="switchChange('sys_remind')"
              >
              </el-switch>
            </div>
            <div class="bar" v-if="sys_remind">
              <div class="name">自动下载更新</div>
              <el-switch
                v-model="sys_auto_download"
                active-color="rgba(61, 104, 225, 1)"
                @change="switchChange('sys_auto_download')"
              >
              </el-switch>
            </div>
          </div>
          <div class="content">
            <div class="title">应用/算法更新设置</div>
            <div class="bar">
              <div class="name">自动清理软件包缓存</div>
              <el-switch
                v-model="app_auto_clear"
                active-color="rgba(61, 104, 225, 1)"
                @change="switchChange('app_auto_clear')"
              >
              </el-switch>
            </div>
            <div class="bar">
              <div class="name">更新提醒</div>
              <el-switch
                v-model="app_remind"
                active-color="rgba(61, 104, 225, 1)"
                @change="switchChange('app_remind')"
              >
              </el-switch>
            </div>
            <div class="bar" v-if="app_remind">
              <div class="name">自动下载更新</div>
              <el-switch
                v-model="app_auto_download"
                active-color="rgba(61, 104, 225, 1)"
                @change="switchChange('app_auto_download')"
              >
              </el-switch>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import { getDevInfo, fileUpload, doUpgrade } from "@/api/system";
import FileUploader from "@/components/subComponents/FileUpload/index";
export default {
  components: {
    FileUploader,
  },
  data() {
    return {
      wifiList: [{ name: "无线网络1" }, { name: "无线网络2" }],
      radio2: "检查更新",
      activePage: 0,
      patchUpdateStatus: "",
      probeSum: 0,
      sys_auto_clear: false,
      sys_remind: false,
      sys_auto_download: false,
      app_auto_clear: false,
      app_remind: false,
      app_auto_download: false,
      timer: null,
      patchFile: {},
      fileAdded: false,
      upgrading: false,
    };
  },
  mounted() {},
  methods: {
    onFileUpload(file) {
      this.patchUpdateStatus = `<span style="color:green">上传成功, 点击升级按钮开始升级</span>`;
      this.patchFile = { ...file };
      this.fileAdded = true;
    },
    onFileAdded() {
      this.patchUpdateStatus = "";
    },
    upgrade() {
      this.upgrading = true;
      this.patchUpdateStatus = `<span style="color:red">正在升级...</span>`;
      doUpgrade(this.patchFile)
        .then((rsp) => {
          this.upgrading = false;
          if (rsp && rsp.success) {
            clearTimeout(this.timer);
            this.doneUpgrade();
          }
        })
        .catch((err) => {
          if (err.code) {
            this.upgrading = false;
            this.patchUpdateStatus = `<span style="color:red">${err.data}</span>`;
            clearTimeout(this.timer);
          } else {
            this.probeServer(this.doneUpgrade);
          }
        });
    },
    doneUpgrade() {
      this.upgrading = false;
      this.patchUpdateStatus = `<span style="color:green">升级成功</span>`;
      let _this = this;
      this.$confirm("升级成功, 请重新登录系统", "成功", {
        type: "success",
        cancelButtonClass: "comfirm-class-cancle",
        confirmButtonClass: "comfirm-class-sure",
      }).then(() => {
        _this.reLogin();
      });
    },
    reLogin() {
      this.$router.push("/");
    },
    probeServer(cb) {
      this.probeSum++;
      let _this = this;
      if (this.probeSum > 60) {
        this.$confirm("连接服务器失败, 请刷新页面或联系管理员", "失败", {
          type: "error",
          cancelButtonClass: "comfirm-class-cancle",
          confirmButtonClass: "comfirm-class-sure",
        }).then(() => {
          cb();
        });
        return;
      }
      this.timer = setTimeout(() => {
        getDevInfo()
          .then(() => {
            cb();
          })
          .catch((err) => {
            _this.probeServer(cb);
          });
      }, 10000);
    },
    openRight(typ) {
      const es = document.getElementsByClassName("menu-item");
      es[this.activePage].style.backgroundColor = "#f8f8f8";
      es[this.activePage].style.color = "rgba(54, 54, 54, 1)";
      es[typ].style.backgroundColor = "rgba(61, 104, 225, 1)";
      es[typ].style.color = "#fff";
      this.activePage = typ;
    },
    switchChange(typ) {
      console.log(this[typ]);
    },
  },
};
</script>
<style lang="scss">
.all {
  width: 100%;
}
.cluster-content {
  height: 100%;
  display: flex;
  flex-direction: row;
  flex: 1;
  flex-basis: auto;
  box-sizing: border-box;
  .cluster-center {
    height: 100%;
    width: 280px;
    overflow: auto;
    box-sizing: border-box;
    flex-shrink: 0;
    padding: 10px;
    border-right: 5px solid #f8f8f8;
    // background-color: lavender;
    .menu-item {
      background-color: #f8f8f8;
      height: 50px;
      margin-bottom: 10px;
      border-radius: 8px;
      line-height: 50px;
      box-sizing: border-box;
      font-size: 14px;
      cursor: pointer;
      padding: 0 20px;
      display: flex;
      justify-content: space-between;
      .con {
        .iconfont {
          margin-right: 10px;
        }
        .menu-text {
          font-size: 15px;
        }
      }
    }
  }
  .cluster-right {
    flex: 1;
    flex-basis: auto;
    overflow: auto;
    box-sizing: border-box;
    position: relative;
    padding: 20px 40px;
    .el-form-item.is-required:not(.is-no-asterisk)
      > .el-form-item__label:before,
    .el-form-item.is-required:not(.is-no-asterisk)
      .el-form-item__label-wrap
      > .el-form-item__label:before {
      display: none;
    }
    .el-select {
      width: 100%;
    }
    .el-form-item {
      margin-bottom: 10px;
      height: 50px;
      background: #f8f8f8;
      padding: 4px 20px;
      -webkit-box-sizing: border-box;
      box-sizing: border-box;
      border-radius: 10px;
      .el-form-item__label {
        text-align: left;
        line-height: 42px;
      }
    }
    .el-form-item__content {
      line-height: 40px;
      position: relative;
      font-size: 14px;
    }
    .ip-input-container {
      max-width: none !important;
    }
    .net-set {
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      height: 95%;
      // .el-radio-button__inner {
      //   // color: #333333;
      //   border: none;
      // }
      .update-center {
        height: 160px;
        .spin-bg {
          width: 70px;
          height: 70px;
          background: rgba(230, 230, 230, 1);
          margin: 0 auto;
          border-radius: 35px;
        }
        .line {
          width: 180px;
          height: 5px;
          background: #e6e6e6;
          border-radius: 5px;
          margin: 5px auto;
        }
        .desc {
          height: 20px;
          line-height: 20px;
          font-size: 14px;
          color: rgba(161, 161, 161, 1);
          margin-bottom: 10px;
        }
        .el-button {
          width: 120px;
        }
        .el-button--small {
          font-size: 14px;
        }
      }
      .upload-center {
        height: 340px;
        // margin: 0 auto;
         .update-center {
        height: 160px;
        .spin-bg {
          width: 70px;
          height: 70px;
          background: rgba(230, 230, 230, 1);
          margin: 0 auto;
          border-radius: 35px;
        }
        .line {
          width: 180px;
          height: 5px;
          background: #e6e6e6;
          border-radius: 5px;
          margin: 5px auto;
        }
        .desc {
          height: 20px;
          line-height: 20px;
          font-size: 14px;
          color: rgba(161, 161, 161, 1);
          margin-bottom: 10px;
        }
        .el-button {
          width: 120px;
        }
        .el-button--small {
          font-size: 14px;
        }
      }
        .top {
          display: flex;
          justify-content: space-evenly;
          align-items: center;
          background: rgba(248, 248, 248, 1);
          box-sizing: border-box;
          padding: 8px 10px;
          border-radius: 8px;
          .el-input--small .el-input__inner {
            border: none;
          }
          .uploader-btn {
            padding: 6px 8px;
            .el-icon-upload2 {
              font-size: 21px;
              font-weight: 600;
            }
          }
        }
        .up-text {
          height: 32px;
          line-height: 32px;
          font-size: 14px;
          min-width: 105px;
          margin-right: 5px;
        }
        .file-uploader {
          width: 100%;
          margin-right: 20px;
          min-width: 150px;
        }
      }
      .cur-version {
        font-size: 14px;
      }
    }
    .wifi {
      .content {
        margin-bottom: 20px;
      }
      .bar {
        display: flex;
        align-items: center;
        height: 50px;
        padding: 0 25px;
        background-color: #f8f8f8;
        justify-content: space-between;
        border-radius: 12px;
        margin-bottom: 10px;
        .name {
          font-size: 15px;
        }
      }
      .title {
        text-align: left;
        padding: 10px;
        font-size: 16px;
      }
    }
    .save-btn {
      background-color: #3d68e1;
      width: 240px;
      height: 40px;
      margin: 0 auto;
      border-radius: 10px;
      color: #fff;
      line-height: 40px;
      font-size: 14px;
      margin-top: 20px;
    }
  }
}
</style>
src/pages/logCenter/views/operationLog.vue
New file
@@ -0,0 +1,202 @@
<template>
  <div class="op-log" v-loading="loading" :element-loading-text="loadingText">
    <div class="top">
      <div class="first">
        <div class="time-option">
          <div class="title">周期:</div>
          <div class="opts">
            <div class="opt" tabindex="1">今日</div>
            <div class="opt" tabindex="2">近三天</div>
            <div class="opt" tabindex="3">近七天</div>
            <div class="opt" tabindex="4">近一个月</div>
            <div class="opt" tabindex="5">近六个月</div>
          </div>
        </div>
        <div class="search">
          <el-input
            placeholder="搜索"
            v-model="input3"
            size="small"
            class="input-with-select"
          >
            <el-button slot="append" icon="el-icon-search"></el-button>
          </el-input>
        </div>
      </div>
      <div class="second">
        <div class="bar">
          <div class="name">操作模块:</div>
          <el-select v-model="value" placeholder="请选择"
            size="small"
          >
            <el-option
              v-for="item in options"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            >
            </el-option>
          </el-select>
        </div>
         <div class="bar">
          <div class="name">操作模块:</div>
          <el-select v-model="value" placeholder="请选择"
            size="small"
          >
            <el-option
              v-for="item in options"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            >
            </el-option>
          </el-select>
        </div>
         <div class="bar">
          <div class="name">操作模块:</div>
          <el-select v-model="value" placeholder="请选择"
            size="small"
          >
            <el-option
              v-for="item in options"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            >
            </el-option>
          </el-select>
        </div>
      </div>
    </div>
    <div class="table">faefws</div>
  </div>
</template>
<script>
import { deleteDate } from "@/api/system";
export default {
  data() {
    return {
      loading: false,
      loadingText: "",
      input3: "",
      options: [
        {
          value: "选项1",
          label: "黄金糕",
        },
        {
          value: "选项2",
          label: "双皮奶",
        },
        {
          value: "选项3",
          label: "蚵仔煎",
        },
        {
          value: "选项4",
          label: "龙须面",
        },
        {
          value: "选项5",
          label: "北京烤鸭",
        },
      ],
      value: "",
    };
  },
  mounted() {},
  methods: {
    format(array) {
      return [
        this.$moment(array[0]).format("YYYY-MM-DD"),
        this.$moment(array[1]).format("YYYY-MM-DD"),
      ];
    },
  },
};
</script>
<style lang="scss">
.op-log {
  margin: 0 auto;
  padding: 10px 8px 10px 5px;
  background-color: rgba(248, 248, 248, 1);
  width: 100%;
  display: flex;
  flex-direction: column;
  .top {
    height: 100px;
    background: #fff;
    border-radius: 5px;
    .first {
      display: flex;
      justify-content: space-between;
      height: 45px;
      padding: 0 20px;
      .time-option {
        display: flex;
        justify-content: space-between;
        align-items: center;
        // padding-left: 20px;
        .title {
          margin-right: 20px;
        }
        .opts {
          display: flex;
          justify-content: space-between;
          .opt {
            width: fit-content;
            height: 32px;
            padding: 0 15px;
            // background: aquamarine;
            border-radius: 4px;
            cursor: pointer;
            margin-right: 20px;
            line-height: 32px;
            font-size: 14px;
          }
          .opt:hover {
            background-color: rgba(61, 104, 225, 1);
            color: #fff;
          }
          .opt:focus {
            color: #fff;
            background-color: rgba(61, 104, 225, 1);
          }
        }
      }
      .search {
        display: flex;
        align-items: center;
      }
    }
    .second {
          display: flex;
      .bar {
        display: flex;
        align-items: baseline;
        background: aliceblue;
        width: fit-content;
        padding-left: 20px;
        .name{
          margin-right: 5px;
        }
      }
    }
  }
  .table {
    margin-top: 10px;
    background: #fff;
    height: 100%;
    border-radius: 5px;
  }
}
</style>
src/pages/logCenter/views/pollingLog.vue
New file
@@ -0,0 +1,384 @@
<template>
  <div class="restart">
    <div class="restart-set">
      <div class="t">重启设置</div>
      <div class="bar">
        <div class="name">重启节点</div>
        <el-button
          class="reset-btn"
          type="primary"
          size="small"
          @click="restart"
          >重启</el-button
        >
      </div>
    </div>
    <div class="restart-set">
      <div class="t">定时重启</div>
      <div class="bar">
        <div class="name">重启周期</div>
        <el-select
          v-model="every"
          placeholder="关闭"
          size="small"
          @change="changeEvery"
        >
          <el-option
            v-for="item in options"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          >
          </el-option>
        </el-select>
      </div>
      <div class="bar" v-if="every == 'monthly'">
        <div class="name">重启日期</div>
        <el-select
          v-model="cronValueObj.day"
          placeholder="请选择"
          size="small"
          @change="updateExpression"
        >
          <el-option
            v-for="item in days"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          ></el-option>
        </el-select>
      </div>
      <div class="bar" v-if="every == 'weekly'">
        <div class="name">重启日期</div>
        <el-select
          v-model="cronValueObj.week"
          placeholder="请选择"
          size="small"
          @change="updateExpression"
        >
          <el-option label="星期一" value="1"></el-option>
          <el-option label="星期二" value="2"></el-option>
          <el-option label="星期三" value="3"></el-option>
          <el-option label="星期四" value="4"></el-option>
          <el-option label="星期五" value="5"></el-option>
          <el-option label="星期六" value="6"></el-option>
          <el-option label="星期日" value="7"></el-option>
        </el-select>
      </div>
      <div class="bar" v-if="every != 'close'">
        <div class="name">重启时间</div>
        <el-time-picker
          v-model="time"
          :picker-options="{ selectableRange: '00:00:00 - 23:59:59' }"
          value-format="HH:mm"
          format="HH:mm"
          placeholder="任意时间点"
          size="small"
          @change="updateExpression"
        ></el-time-picker>
      </div>
    </div>
    <el-button class="save-btn" type="primary" @click="save">保存</el-button>
  </div>
</template>
<script>
import {
  rebootServer,
  getDevInfo,
  getRebootTask,
  setRebootTask,
  fileUpload,
  doUpgrade,
  deleteDate,
} from "@/api/system";
export default {
  data() {
    return {
      time: "",
      saveBtn: false,
      timer: null,
      probeSum: 0,
      cronText: "",
      cronValueObj: {
        min: "*",
        hour: "*",
        day: "*",
        month: "*",
        week: "*",
      },
      options: [
        {
          value: "close",
          label: "关闭",
        },
        {
          value: "daily",
          label: "每日",
        },
        {
          value: "weekly",
          label: "每周",
        },
        {
          value: "monthly",
          label: "每月",
        },
      ],
      every: "close",
      rebootCron: "",
    };
  },
  computed: {
    days: () => {
      let arr = [];
      for (let i = 1; i < 32; i++) {
        arr.push({
          label: i + "日",
          value: i + "",
        });
      }
      return arr;
    },
  },
  components: {},
  mounted() {
    this.getRebootCron();
  },
  beforeDestroy() {},
  methods: {
    resolveExp() {
      // "准备反解析", this.expression;
      if (this.rebootCron.length) {
        let arr = this.rebootCron.split(" ");
        if (arr.length >= 5) {
          //6 位以上是合法表达式
          this.cronValueObj.min = arr[0];
          this.cronValueObj.hour = arr[1];
          this.cronValueObj.day = arr[2];
          this.cronValueObj.month = "*";
          this.cronValueObj.week = arr[4];
        }
        if (this.cronValueObj.week != "*") {
          this.every = "weekly";
        } else if (this.cronValueObj.day != "*") {
          this.every = "monthly";
        } else {
          this.every = "daily";
        }
        this.time = this.cronValueObj.hour + ":" + this.cronValueObj.min;
      } else {
        //没有传入的表达式 则还原
        this.clearCron();
      }
    },
    clearCron() {
      this.cronValueObj.min = "*";
      this.cronValueObj.hour = "*";
      this.cronValueObj.day = "*";
      this.cronValueObj.month = "*";
      this.cronValueObj.week = "*";
    },
    getRebootCron() {
      getRebootTask().then((rsp) => {
        this.rebootCron = rsp.data;
      });
    },
    reLogin() {
      this.$router.push("/");
    },
    restart() {
      this.$confirm("确定要重启该节点吗?", {
        center: true,
        cancelButtonClass: "comfirm-class-cancle",
        confirmButtonClass: "comfirm-class-sure",
      }).then(() => {
        // this.loading = true;
        // this.loadingText = "智能计算节点正在重启,请耐心等待..."
        rebootServer()
          .then((rsp) => {
            this.probeServer(this.reLogin);
          })
          .catch((err) => {
            if (err.status == 400) {
              // this.loading = false;
              this.$notify({
                type: "error",
                message: "重启计算节点失败",
              });
            } else {
              this.probeServer(this.reLogin);
            }
          });
      });
    },
    probeServer(cb) {
      this.probeSum++;
      let _this = this;
      if (this.probeSum > 60) {
        this.$confirm("连接服务器失败, 请刷新页面或联系管理员", "失败", {
          type: "error",
          cancelButtonClass: "comfirm-class-cancle",
          confirmButtonClass: "comfirm-class-sure",
        }).then(() => {
          cb();
        });
        return;
      }
      this.timer = setTimeout(() => {
        getDevInfo()
          .then(() => {
            cb();
          })
          .catch((err) => {
            _this.probeServer(cb);
          });
      }, 10000);
    },
    save() {
      this.rebootCron = this.cronText;
      setRebootTask({ task: this.cronText })
        .then((rsp) => {
          if (rsp && rsp.success) {
            this.$notify({
              type: "success",
              message: "配置成功",
            });
          }
        })
        .catch((err) => {
          this.$notify({
            type: "error",
            message: "配置失败",
          });
        });
    },
    changeEvery() {
      this.saveBtn = true;
      if (this.every === "close") {
        this.cronText = "";
        return;
      }
      if (this.every === "monthly") {
        this.cronValueObj.week = "*";
        this.cronValueObj.day = "1";
        if (!this.time.length) {
          this.time = "00:00";
        }
      }
      if (this.every === "weekly") {
        this.cronValueObj.day = "*";
        this.cronValueObj.week = "1";
        if (!this.time.length) {
          this.time = "00:00";
        }
      }
      if (this.every === "daily") {
        this.cronValueObj.day = "*";
        this.cronValueObj.week = "*";
      }
      this.updateExpression();
    },
    updateExpression() {
      this.saveBtn = true;
      if (this.time.length) {
        let arr = this.time.split(":");
        this.cronValueObj.hour = arr[0];
        this.cronValueObj.min = arr[1];
      }
      this.crontabValueString();
    },
    crontabValueString() {
      let obj = this.cronValueObj;
      this.cronText =
        obj.min +
        " " +
        obj.hour +
        " " +
        obj.day +
        " " +
        obj.month +
        " " +
        obj.week;
    },
  },
  watch: {
    rebootCron() {
      this.resolveExp();
    },
  },
};
</script>
<style lang="scss">
.all {
  width: 100%;
}
.restart {
  margin: 0 auto;
  padding: 20px;
  .t {
    box-sizing: border-box;
    text-align: left;
    width: 70%;
    margin: 0 auto;
    padding: 10px;
    font-size: 16px;
  }
  .bar {
    height: 50px;
    width: 70%;
    background: rgba(248, 248, 248, 1);
    margin: 0 auto;
    min-width: 300px;
    display: flex;
    justify-content: space-between;
    box-sizing: border-box;
    padding: 0 20px;
    align-items: center;
    border-radius: 10px;
    margin-bottom: 10px;
    .reset-btn {
      width: 70px;
      height: 32px;
      border-radius: 5px;
    }
    .el-select {
      width: 100%;
    }
    .name {
      min-width: 150px;
      text-align: left;
      font-size: 14px;
    }
    .el-input__inner::placeholder {
      color: rgba(107, 107, 107, 1);
    }
    .el-input--small .el-input__inner {
      height: 32px;
      line-height: 32px;
      border: none;
      background: rgba(240, 240, 240, 1);
    }
    .el-select .el-input .el-select__caret {
      color: rgba(138, 138, 138, 1);
      font-size: 15px;
    }
    .el-date-editor.el-input,
    .el-date-editor.el-input__inner {
      width: 100%;
    }
  }
  .save-btn {
    width: 260px;
    margin-top: 50px;
  }
}
</style>
src/pages/logCenter/views/systemLog.vue
New file
@@ -0,0 +1,326 @@
<template>
  <div class="all">
    <div class="backup-content">
      <div class="backup-center" ref="left">
        <div class="menu-item" @click="openRight(0)">
          <div class="con">
            <span class="icon iconfont">&#xe646;</span>
            <span class="menu-text">自动备份设置</span>
          </div>
        </div>
        <div class="menu-item" @click="openRight(1)">
          <div class="con">
            <span class="icon iconfont">&#xe646;</span>
            <span class="menu-text">从备份中恢复</span>
          </div>
        </div>
      </div>
      <div class="backup-right">
        <div class="auto" v-if="activePage == 0">
          <div class="bar">
            <div class="name">自动备份</div>
            <el-switch
              v-model="isBackUp"
              active-color="rgba(61, 104, 225, 1)"
              @change="switchChange"
            >
            </el-switch>
          </div>
          <div class="bar">
            <div class="name">备份目录</div>
            <input type="file" id="file_input" webkitdirectory directory />
          </div>
          <div class="bar">
            <div class="name">备份间隔 / 天</div>
            <el-input
              v-model="interval"
              :placeholder="'请输入天数'"
              @change="handleChange"
              size="small"
            ></el-input>
            <!-- :controls="false" -->
          </div>
          <div class="bar">
            <div class="name">备份数据保存时间 / 天</div>
            <el-input
              v-model="lifeSpan"
              placeholder="请输入天数"
              @change="handleChange"
              size="small"
            ></el-input>
          </div>
          <div class="bar">
            <div class="name">自动备份</div>
            <el-button type="primary" size="small" @click="backUpNow"
              >立即备份</el-button
            >
          </div>
        </div>
        <div class="recover" v-if="activePage == 1">
          <div class="title">显示备份的文件范围:{{ 5 }}</div>
          <div class="table-head">
            <span class="line1">自动备份时间</span>
            <span class="line1">备份文件名称</span>
            <span class="line2">操作</span>
          </div>
          <div class="bar" v-for="(item, i) in fileList" :key="i">
            <span class="time">{{ item.time }}</span>
            <span class="time">{{ item.name }}</span>
            <span class="operation">恢复</span>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  mounted() {},
  data() {
    return {
      langList: [
        { name: "简体中文" },
        { name: "英文" },
        { name: "繁体中文(香港)" },
      ],
      fileList: [
        { time: "2010-10-02 12:30:09", name: "文件1" },
        { time: "2010-10-02 12:30:09", name: "文件12121212121" },
        { time: "2010-10-02", name: "文件2211" },
        { time: "2011", name: "备份文件2" },
      ],
      activePage: 0,
      interval: "",
      lifeSpan: "",
      options: [
        {
          value: "选项1",
          label: "手动",
        },
        {
          value: "选项2",
          label: "自动",
        },
      ],
      isBackUp: true,
    };
  },
  methods: {
    openRight(typ) {
      const es = document.getElementsByClassName("menu-item");
      es[this.activePage].style.backgroundColor = "#f8f8f8";
      es[this.activePage].style.color = "rgba(54, 54, 54, 1)";
      es[typ].style.backgroundColor = "rgba(61, 104, 225, 1)";
      es[typ].style.color = "#fff";
      this.activePage = typ;
    },
    handleChange() {},
    backUpNow() {
      this.$confirm("您是否确认立即备份所有应用的配置数据?", "立即备份", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
      }).then(() => {
        this.$message({
          type: "success",
          message: "备份成功",
        });
      });
      //  .then((resp) => {
      //         if (resp.success) {
      //           this.$message({
      //             type: "success",
      //             message: "删除数据成功",
      //           });
      //           this.loading = false;
      //         }
      //       })
      //       .catch((err) => {
      //         this.$message({
      //           type: "error",
      //           message: "删除数据失败!",
      //         });
      //         this.loading = false;
      //       });
    },
    switchChange(val) {
      console.log(val);
    },
  },
};
</script>
<style lang="scss">
.all {
  width: 100%;
}
.backup-content {
  height: 100%;
  display: flex;
  flex-direction: row;
  flex: 1;
  flex-basis: auto;
  box-sizing: border-box;
  .backup-center {
    height: 100%;
    width: 280px;
    overflow: auto;
    box-sizing: border-box;
    flex-shrink: 0;
    padding: 10px;
    border-right: 5px solid #f8f8f8;
    .menu-item {
      background-color: #f8f8f8;
      height: 50px;
      margin-bottom: 10px;
      border-radius: 8px;
      line-height: 50px;
      box-sizing: border-box;
      font-size: 14px;
      cursor: pointer;
      padding: 0 20px;
      display: flex;
      justify-content: space-between;
      .con {
        .iconfont {
          margin-right: 10px;
        }
        .menu-text {
          font-size: 15px;
        }
      }
    }
  }
  .backup-right {
    flex: 1;
    flex-basis: auto;
    overflow: auto;
    box-sizing: border-box;
    position: relative;
    padding: 20px 40px;
    .el-form-item.is-required:not(.is-no-asterisk)
      > .el-form-item__label:before,
    .el-form-item.is-required:not(.is-no-asterisk)
      .el-form-item__label-wrap
      > .el-form-item__label:before {
      display: none;
    }
    .el-select {
      width: 100%;
    }
    .el-form-item {
      margin-bottom: 10px;
      height: 50px;
      background: #f8f8f8;
      padding: 4px 20px;
      -webkit-box-sizing: border-box;
      box-sizing: border-box;
      border-radius: 10px;
      .el-form-item__label {
        text-align: left;
        line-height: 42px;
      }
    }
    .el-form-item__content {
      line-height: 40px;
      position: relative;
      font-size: 14px;
    }
    .ip-input-container {
      max-width: none !important;
    }
    .auto {
      .bar {
        display: flex;
        align-items: center;
        height: 50px;
        padding: 0 25px;
        background-color: #f8f8f8;
        justify-content: space-between;
        border-radius: 12px;
        margin-bottom: 10px;
        .name {
          font-size: 15px;
          text-align: left;
          min-width: 180px;
        }
        .el-input {
          width: 100%;
          .el-input {
            height: auto;
          }
          .el-input__inner {
            border: none;
            border-radius: 8px;
            background-color: rgba(240, 240, 240, 1);
            text-align: left;
          }
        }
      }
    }
    .recover {
      .title {
        font-size: 13px;
        color: #868686;
        text-align: left;
        padding: 0 10px;
        margin-bottom: 10px;
      }
      .table-head {
        height: 30px;
        line-height: 30px;
        display: flex;
        // justify-content: space-between;
        box-sizing: border-box;
        font-size: 15px;
        padding: 0 10px;
        margin-bottom: 5px;
        .line1 {
          flex: 4;
          text-align: left;
        }
        .line2 {
          flex: 1;
          text-align: right;
        }
      }
      .bar {
        height: 40px;
        background-color: rgba(248, 248, 248, 1);
        display: flex;
        box-sizing: border-box;
        padding: 0 10px;
        align-items: center;
        border-radius: 8px;
        color: #797979;
        font-size: 14px;
        margin-bottom: 10px;
        .time {
          width: 45%;
          text-align: left;
        }
        .operation {
          color: rgba(26, 115, 232, 1);
          cursor: pointer;
          width: 10%;
          text-align: right;
        }
      }
    }
    .save-btn {
      background-color: #3d68e1;
      width: 240px;
      height: 40px;
      margin: 0 auto;
      border-radius: 10px;
      color: #fff;
      line-height: 40px;
      font-size: 14px;
      margin-top: 20px;
    }
  }
}
</style>
vue.config.js
@@ -41,7 +41,10 @@
})
// const serverUrl = "http://58.118.225.79:41243" // 羊五
const serverUrl = "http://192.168.20.106:7009"
const serverUrl = "http://192.168.20.106:8000"
module.exports = {
  pages,
@@ -88,7 +91,7 @@
      },
      "/data/api-v/app/findAllApp": {
        // target: '/',
        target: 'http://localhost:8080/',
        target: 'http://localhost:8081/',
        changeOrigin: true,
        pathRewrite: {
          '^/data/api-v/app/findAllApp': 'apps.json'