heyujie
2022-01-26 4aa13af3c74cf57d70bad9c4bc53b2c26e04fb5d
集群管理搜索集群
11个文件已修改
931 ■■■■ 已修改文件
src/api/clusterManage.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/system.ts 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/desktop/index/components/Desktop.vue 292 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/settings/views/clusterManagement.vue 80 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/settings/views/deviceInfo.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/systemSettings/components/ClusterManagement.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/vindicate/index/App.vue 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/vindicate/views/backUp.vue 225 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/vindicate/views/restartSettings.vue 256 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/vindicate/views/sysInfo.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/vindicate/views/updateSettings.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/clusterManage.ts
@@ -76,7 +76,6 @@
  })
};
// 退出集群
export const leave = (query: any) => {
  return request({
    url: "/data/api-v/cluster/leave",
src/api/system.ts
@@ -440,6 +440,8 @@
    data: qs.stringify(query)
  })
}
//
export const uploadKey = (data: any) => {
  return request({
    url: "/version/authorization/upload",
@@ -447,3 +449,56 @@
    data
  })
}
export const getBakConfig = () => {
  return request({
    url: "/version/autoBak/config",
    method: "get"
  })
}
export const getSmsCode = (query: any) => {
  return request({
    url: "/version/auth/shop/smsCode",
    method: "get",
    params: query,
  })
}
export const loginShopInSmart = (data: any) => {
  return request({
    url: "/version/auth/shop/login",
    method: "post",
    data: qs.stringify(data)
  })
}
export const setBakConfig = (data: any) => {
  return request({
    url: "/version/autoBak/saveConf",
    method: "post",
    data
  })
}
export const backupRN = (data: any) => {
  return request({
    url: "/version/autoBak/backupRN",
    method: "post",
    data
  })
}
export const recoverBackup = (data: any) => {
  return request({
    url: "/version/autoBak/recover",
    method: "post",
    data: qs.stringify(data)
  })
}
export const getBackupList = () => {
  return request({
    url: "/version/autoBak/list",
    method: "get"
  })
}
src/pages/desktop/index/components/Desktop.vue
@@ -14,9 +14,7 @@
      <span v-if="!snExpire" class="text"
        >试用版尚未激活,仅支持部分功能使用,如需使用全部功能,请尽快激活系统。</span
      >
      <span v-else class="text"
        >SmartAIOS 试用期已到期,请您尽快激活系统</span
      >
      <span v-else class="text">SmartAIOS 试用期已到期,请您尽快激活系统</span>
      <span class="go-to" @click="gotoActive">前往激活</span>
      <span class="icon iconfont" @click="showFreeVersion = false"
        >&#xe61b;</span
@@ -31,17 +29,79 @@
      :close-on-click-modal="false"
      :close-on-press-escape="false"
    >
      <el-dialog
        width="30%"
        title="账户激活"
        :visible.sync="innerVisible"
        append-to-body
        class="inner-login-dialog"
      >
        <div class="info">
          请输入你在SmartAI商城账户的手机号并完成验证码校验,实现系统激活!
        </div>
        <div class="login-content">
          <el-form
            :model="phone"
            status-icon
            :rules="phoneCodeRule"
            :validate-on-rule-change="false"
            ref="phoneLogin"
            class="demo-ruleForm"
          >
            <el-form-item prop="phoneNum" style="margin-top: 20px">
              <el-input
                v-model="phone.phoneNum"
                style="width: 380px"
                placeholder="请输入手机号"
              >
                <i slot="prefix" class="el-icon-mobile-phone"></i>
              </el-input>
            </el-form-item>
            <el-form-item prop="verifyCode">
              <el-input
                @keyup.enter.native="phoneLogin"
                v-model="phone.verifyCode"
                autocomplete="off"
                style="width: 254px"
                placeholder="请输入验证码"
              >
                <i slot="prefix" class="el-icon-message"></i>
              </el-input>
              <el-button
                class="code-btn"
                style="margin-left: 15px"
                :disabled="codeDisabled"
                @click="getCode"
                >{{ codeMsg }}</el-button
              >
            </el-form-item>
          </el-form>
        </div>
        <span slot="footer" class="dialog-footer">
          <el-button @click="activeDialog = false">取消</el-button>
          <el-button type="primary" @click="loginShop">确定</el-button>
        </span>
      </el-dialog>
      <div class="ver"><span class="ver-text">版本:</span>{{ version }}</div>
      <div class="ver">
        <span class="ver-text">状态:</span>{{ versionState }}
      </div>
      <el-divider></el-divider>
      <div class="info">
        如果还没有产品密钥,你可以使用手机扫码或前往此链接
        <a href="http://apps.smartai.com" target="_blank"
        如果您已连接到Internet并且已购买产品密钥,可以尝试验证SmartAI商城账户激活系统。
        <div>
          <el-button type="primary" @click="innerVisible = true">
            账户激活
          </el-button>
        </div>
      </div>
      <div class="info">
        如果您未连接Internet或激活失败,可尝试离线激活,使用手机扫码购买产品或验证SmartAI商城账户激活系统。
        <!-- <a href="http://apps.smartai.com" target="_blank"
          >http://apps.smartai.com</a
        >
        购买。
        如果还没有产品密钥,你可以使用手机扫码或前往此链接
        购买。 -->
      </div>
      <img class="qr-code-img" src="/version/offline/qrcode" />
      <el-divider></el-divider>
@@ -73,7 +133,66 @@
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button v-if="!snExpire" @click="activeDialog = false">继续试用</el-button>
        <el-button v-if="!snExpire" @click="activeDialog = false"
          >继续试用</el-button
        >
        <el-button v-else @click="quit">退出登录</el-button>
        <el-button type="primary" @click="activateVersion">激活</el-button>
      </span>
    </el-dialog>
    <el-dialog
      title="我的订单"
      :visible.sync="innerDialog"
      width="750px"
      :show-close="false"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      custom-class="my-order"
    >
      <div class="tip">
        <i class="el-icon-info"></i>
        <span> 请检查订单信息,确认无误后再激活系统。 </span>
      </div>
      <div class="order-list">
        <div class="order-card">
          <div class="head">
            <el-checkbox v-model="checked">
              <span>订单ID:{{ 22322323423 }}</span>
            </el-checkbox>
            <span>¥{{ 111 }} 元</span>
          </div>
          <div class="desc">
            <div>系统版本:{{ 22322323423 }}</div>
            <div>通道数量:{{ 22322323423 }}</div>
            <div>摄像机数量:{{ 22322323423 }}</div>
            <div>服务时长:{{ 22322323423 }}</div>
          </div>
        </div>
        <div class="order-card">
          <div class="head">
            <el-checkbox v-model="checked">
              <span>订单ID:{{ 31423233423 }}</span>
            </el-checkbox>
            <span>¥{{ 111 }} 元</span>
          </div>
          <div class="desc">
            <div>系统版本:{{ 22322323423 }}</div>
            <div>通道数量:{{ 22322323423 }}</div>
            <div>摄像机数量:{{ 22322323423 }}</div>
            <div>服务时长:{{ 22322323423 }}</div>
          </div>
        </div>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button v-if="!snExpire" @click="activeDialog = false"
          >取消激活</el-button
        >
        <el-button v-else @click="quit">退出登录</el-button>
        <el-button type="primary" @click="activateVersion">激活</el-button>
      </span>
@@ -84,11 +203,14 @@
<script>
import DFrame from "./DFrame";
import Safari from "./Safari";
import { isPhone } from "../../../../scripts/validate.ts";
import {
  getActiveQrCode,
  getSN,
  activateVersion,
  uploadKey,
  getSmsCode,
  loginShopInSmart,
} from "@/api/system";
export default {
  name: "Desktop",
@@ -100,24 +222,87 @@
    return {
      showFreeVersion: false,
      activeDialog: false,
      countdown: 60,innerDialog: false,
      version: "SmartAI试用版",
      codeMsg: "获取验证码",
      versionState: "尚未激活",
      secrectKey: "",
      snExpire: false
      codeDisabled: false,
      innerVisible: false,
      snExpire: false,
      timer: null,
      phone: {
        phoneNum: "",
        verifyCode: "",
      },
      phoneCodeRule: {
        phoneNum: [{ validator: isPhone, trigger: "change" }],
        verifyCode: [
          { required: true, message: "请输入验证码", trigger: "change" },
        ],
      },
    };
  },
  mounted() {
  created() {
    this.validateSn();
  },
  methods: {
    quit(){
      this.$emit("quit")
    quit() {
      this.$emit("quit");
    },
    validateSn() {
      getSN().then((res) => {
        this.snExpire = res.data.expire;
        this.showFreeVersion = res.data.sn == "" || res.data.expire;
      });
    },
    getValidStr() {
      if (this.countdown > 0 && this.countdown <= 60) {
        this.countdown--;
        if (this.countdown !== 0) {
          this.codeMsg = "重新发送(" + this.countdown + ")";
        } else {
          clearInterval(this.timer);
          this.codeMsg = "获取验证码";
          this.countdown = 60;
          this.timer = null;
          this.codeDisabled = false;
        }
      }
    },
    loginShop(){
      loginShopInSmart({
        phoneNum:this.phone.phoneNum,
        verifyCode
      })
    },
    // 获取验证码
    getCode() {
      // 验证码60秒倒计时
      var pattern = /^1[345789]\d{9}$/;
      if (this.phone.phoneNum == "") {
        this.$refs['phoneLogin'].fields[0].validateMessage = "请输入手机号";
        this.$refs['phoneLogin'].fields[0].validateState = "error";
        return;
      }
      if (!pattern.test(this.phone.phoneNum)) {
        this.$refs['phoneLogin'].fields[0].validateMessage = "手机号码格式有误";
        this.$refs['phoneLogin'].fields[0].validateState = "error";
        return;
      }
      if (!this.timer) {
        this.codeDisabled = true;
        this.getValidStr();
        this.timer = setInterval(this.getValidStr, 1000);
        getSmsCode({ phoneNum: this.phone.phoneNum })
          .then((res) => {
            this.gotCode = true;
          })
          .catch((err) => {
            this.$refs['phoneLogin'].fields[0].validateMessage = err.data.msg;
            this.$refs['phoneLogin'].fields[0].validateState = "error";
          });
      }
    },
    activateVersion() {
      if (this.secrectKey.trim() == "") {
@@ -126,7 +311,7 @@
      }
      activateVersion({ code: this.secrectKey.trim() })
        .then((res) => {
          debugger
          debugger;
          if (res.code == 200) {
            this.$notify.success("激活成功");
            this.validateSn();
@@ -227,6 +412,89 @@
    font-size: 15px;
  }
}
.inner-login-dialog {
  .info {
    padding: 0 30px;
  }
  .el-dialog__body {
    text-align: left;
  }
}
.login-content {
  box-sizing: border-box;
  padding: 0 30px;
  .el-input__inner {
    -webkit-appearance: none;
    background-color: #ffffff;
    background-image: none;
    border-radius: 4px;
    border: 1px solid #dcdfe6;
    box-sizing: border-box;
    color: #606266;
    display: inline-block;
    font-size: 16px;
    border-radius: 5px;
    height: 40px;
    line-height: 40px;
    outline: none;
    padding: 0 15px;
    transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
    width: 100%;
  }
}
.el-dialog.my-order {
  .tip {
    width: auto;
    height: 40px;
    background: rgb(145, 213, 255, 0.2);
    box-sizing: border-box;
    border: 1px rgb(145, 213, 255) solid;
    display: flex;
    padding: 0 10px;
    border-radius: 5px;
    align-items: center;
    i {
      margin-right: 5px;
      font-size: 16px;
      color: rgb(24, 144, 255);
    }
    span {
      font-size: 14px;
    }
  }
  .order-list {
    margin: 20px 0;
    .order-card {
      height: 150px;
      background: #fff;
      margin-bottom: 15px;
      border-radius: 8px;
      box-shadow: 0px 0px 4px rgb(0 0 0 / 25%);
      .head {
        height: 40px;
        line-height: 40px;
        text-align: left;
        box-sizing: border-box;
        padding: 0 20px;
        border-bottom: 1px rgba(242, 242, 242, 1) solid;
        font-size: 14px;
        display: flex;
        justify-content: space-between;
      }
      .desc {
        display: flex;
        flex-direction: column;
        justify-content: space-evenly;
        height: 110px;
        text-align: left;
        box-sizing: border-box;
        padding: 0 20px;
      }
    }
  }
}
.warn-tag {
  width: 640px;
  text-align: left;
src/pages/settings/views/clusterManagement.vue
@@ -93,7 +93,11 @@
    </div>
    <!-- !showCurCluster || !isHasColony -->
    <div class="cluster-content" v-if="!showCurCluster || !isHasColony">
      <div class="cluster-center" ref="left" v-if="!showCurCluster || !isHasColony">
      <div
        class="cluster-center"
        ref="left"
        v-if="!showCurCluster || !isHasColony"
      >
        <div
          class="menu-item"
          :class="activePage == i ? 'menu-item-active' : ''"
@@ -158,15 +162,14 @@
            :rules="joinExistRules"
            ref="joinForm"
            class="join-form"
            v-loading="joinLoading"
          >
            <el-form-item  prop="clusterid">
            <el-form-item prop="clusterid">
              <div class="p-title">集群ID</div>
              <el-input v-model="joinForm.clusterid" size="small"></el-input>
            </el-form-item>
            <el-form-item  prop="clusterip">
            <el-form-item prop="clusterip">
              <div class="p-title">IP地址</div>
              <el-input
                v-model="joinForm.clusterip"
@@ -175,7 +178,7 @@
                autocomplete="new-password"
              ></el-input>
            </el-form-item>
            <el-form-item  prop="clusterpwd">
            <el-form-item prop="clusterpwd">
              <div class="p-title">集群密码</div>
              <el-input
                v-model="joinForm.clusterpwd"
@@ -202,9 +205,20 @@
              </el-input>
            </el-form-item>
          </el-form>
           <div class="btns">
        <div class="ok" @click="join('joinForm')">加入集群</div>
      </div>
          <div class="clu-list">
            <div
              class="clu-item"
              v-for="(item, index) in members"
              :key="index"
              @click="pickNode(index)"
            >
              <i class="iconfont">&#xe727;</i>
              {{ item.Address }}
            </div>
          </div>
          <div class="btns">
            <div class="ok" @click="join('joinForm')">加入集群</div>
          </div>
        </div>
      </div>
    </div>
@@ -224,7 +238,7 @@
  joinCluster,
} from "@/api/clusterManage";
// import cloudNode from "../components/CloudNode";
import NetNode from '../components/NetNode'
import NetNode from "../components/NetNode";
import ipInput from "../components/IPInput";
import { isIPv4 } from "@/scripts/validate";
@@ -256,6 +270,7 @@
      activePage: 0,
      inputIp: "",
      serverIp: "",
      pickedNodeI: null,
      members: [],
      virtualIp: "192.168.1.188",
      searchDis: false,
@@ -287,20 +302,20 @@
        clustername: [
          { required: true, message: "请输入集群名称", trigger: "blur" },
        ],
        clusterpwd: [{ validator: checkPwd, trigger: "blur" }],
        clusterpwd: [{ validator: checkPwd, required: true }],
        virtualIp: [{ required: true, validator: isIPv4, trigger: "change" }],
      },
      joinExistRules: {
        clusterid: [{ validator: checkID, trigger: "blur" }],
        clusterip: [{ validator: isIPv4, trigger: "blur" }],
        clusterpwd: [{ validator: checkPwd, trigger: "blur" }],
        clusterpwd: [{ validator: checkPwd, required: true }],
      },
    };
  },
  components: {
    // cloudNode,
    NetNode,
    ipInput
    ipInput,
  },
  mounted() {
    this.findCluster();
@@ -312,6 +327,9 @@
    clearInterval(this.intervalTimer);
  },
  methods: {
    pickNode(index) {
      // this.pickedNodeI=index
    },
    async createCluster(json) {
      let res = await createSerfCluster(json);
      this.$notify({
@@ -357,21 +375,20 @@
      });
    },
    join(formName) {
      debugger
      let _this = this;
      this.$refs[formName].validate((valid) => {
      debugger
        if (valid) {
      debugger
          _this.joinLoading = true;
          let nodeIps = _this.members.map((i) => {
            return i.Address;
          });
          // let nodeIps = _this.members.map((i) => {
          //   return i.Address;
          // });
          debugger;
          let data = {
            clusterId: _this.joinForm.clusterid,
            password: _this.joinForm.clusterpwd,
            nodeIps: [_this.joinForm.clusterip],
          };
          debugger;
          _this
            .joinCluster(data)
            .then(() => {
@@ -625,7 +642,7 @@
}
.cluster-guanli {
  margin: 0 auto;
width: 760px;
  width: 760px;
  padding: 0 10px;
  .btns {
    margin-top: 30px !important;
@@ -644,6 +661,7 @@
      margin-top: 0;
    }
  }
  .cloud {
    width: 100%;
    display: flex;
@@ -781,7 +799,27 @@
      > .el-form-item__label:before {
      display: none;
    }
    .clu-list {
      background: #f2f2f7;
      border-radius: 8px;
      margin-top: 20px;
      .clu-item {
        border-radius: 8px;
        height: 40px;
        // cursor: pointer;
        line-height: 40px;
        text-align: left;
        padding: 0 20px;
        font-size: 14px;
        .iconfont {
          margin-right: 8px;
        }
      }
      // .clu-item:hover {
      //   background: var(--colorCard);
      //   color: #fff;
      // }
    }
    .el-form-item__content {
      line-height: 48px;
      display: flex;
@@ -813,7 +851,7 @@
      left: 20px;
    }
    .el-form-item {
    margin-bottom: 10px;
      margin-bottom: 10px;
      .el-input__inner {
        background-color: #ffffff;
        border: 2px solid transparent;
src/pages/settings/views/deviceInfo.vue
@@ -54,7 +54,7 @@
</template>
<script>
import { saveAlarmConfig, getDevInfo } from "@/api/system";
import { getDevInfo } from "@/api/system";
import { uploadSound, getSoundList, deleteSound } from "@/api/event";
export default {
src/pages/systemSettings/components/ClusterManagement.vue
@@ -511,7 +511,6 @@
    async search(json) {
      let res = await search(json);
      if (res && res.success) {
        console.log(res, "搜索集群");
        this.searchNum = res.data;
      }
      this.searchDis = true;
src/pages/vindicate/index/App.vue
@@ -26,13 +26,13 @@
      style="width: 100%"
      ref="view_0"
    ></updateSettings>
    <!-- <back-up v-if="activePage == 3" style="width: 100%"></back-up> -->
    <back-up v-if="activePage == 3" style="width: 100%"></back-up>
    <restartSettings
      v-if="activePage == 2"
      style="width: 100%"
      ref="view_2"
    ></restartSettings>
    <sysInfo v-if="activePage == 3" style="width: 100%" ref="view_3"></sysInfo>
    <sysInfo v-if="activePage == 4" style="width: 100%" ref="view_3"></sysInfo>
  </div>
  <div
@@ -99,7 +99,7 @@
import { getUrlKey } from "@/api/utils";
import systemClean from "../views/systemClean";
import updateSettings from "../views/updateSettings";
// import BackUp from "../views/backUp";
import BackUp from "../views/backUp";
import restartSettings from "../views/restartSettings";
import sysInfo from "../views/sysInfo";
export default {
@@ -107,7 +107,7 @@
  components: {
    systemClean,
    updateSettings,
    //   BackUp,
      BackUp,
    restartSettings,
    sysInfo,
  },
@@ -126,6 +126,7 @@
          img_white: "/images/vindicate/系统清理-白.png",
          img_welcome: "/images/vindicate/系统清理.png",
        },
        {
          name: "重启设置",
          img_black: "/images/vindicate/重启设置-黑.png",
@@ -133,6 +134,12 @@
          img_welcome: "/images/vindicate/重启设置.png",
        },
        {
          name: "备份还原",
          img_black: "/images/vindicate/系统清理-黑.png",
          img_white: "/images/vindicate/系统清理-白.png",
          img_welcome: "/images/vindicate/系统清理.png",
        },
        {
          name: "系统信息",
          img_black: "/images/vindicate/系统信息-黑.png",
          img_white: "/images/vindicate/系统信息-白.png",
src/pages/vindicate/views/backUp.vue
@@ -2,14 +2,18 @@
  <div class="all">
    <div class="backup-content">
      <div class="backup-center" ref="left">
        <div class="menu-item" @click="openRight(i)"  v-for="(item, i) in tabList"  :class="activePage == i ? 'menu-item-active' : ''"
          :key="i">
        <div
          class="menu-item"
          @click="openRight(i)"
          v-for="(item, i) in tabList"
          :class="activePage == i ? 'menu-item-active' : ''"
          :key="i"
        >
          <div class="con">
            <span class="icon iconfont">{{ item.icon }}</span>
            <span class="menu-text">{{ item.name }}</span>
          </div>
        </div>
      </div>
      <div class="backup-right">
        <div class="auto" v-if="activePage == 0">
@@ -24,14 +28,18 @@
          </div>
          <div class="bar">
            <div class="name">备份目录</div>
            <input type="file" id="file_input" webkitdirectory directory />
            <!-- <input type="file" id="file_input" webkitdirectory directory /> -->
            <el-input
              v-model="dir"
              :placeholder="'请输入备份目录'"
              size="small"
            ></el-input>
          </div>
          <div class="bar">
            <div class="name">备份间隔 / 天</div>
            <el-input
              v-model="interval"
              v-model.number="interval"
              :placeholder="'请输入天数'"
              @change="handleChange"
              size="small"
            ></el-input>
            <!-- :controls="false" -->
@@ -39,9 +47,8 @@
          <div class="bar">
            <div class="name">备份数据保存时间 / 天</div>
            <el-input
              v-model="lifeSpan"
              v-model.number="lifeSpan"
              placeholder="请输入天数"
              @change="handleChange"
              size="small"
            ></el-input>
          </div>
@@ -51,6 +58,10 @@
              >立即备份</el-button
            >
          </div>
          <el-button class="save-btn" type="primary" @click="saveBakConfig"
            >保存</el-button
          >
        </div>
        <div class="recover" v-if="activePage == 1">
          <div class="title">显示备份的文件范围:{{ 5 }}</div>
@@ -62,9 +73,9 @@
          </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>
            <span class="time">{{ item }}</span>
            <span class="time">{{ item }}</span>
            <span class="operation" @click="recoverFile(item)">恢复</span>
          </div>
        </div>
      </div>
@@ -73,70 +84,121 @@
</template>
<script>
import {
  getBakConfig,
  setBakConfig,
  backupRN,
  getBackupList,
  recoverBackup,
} from "@/api/system";
export default {
  mounted() {},
  created() {
    this.getBakConfig();
    this.getBakFileList();
  },
  data() {
    return {
       tabList: [
      tabList: [
        { name: "自动备份设置", icon: "\ue6f2" },
        { name: "从备份中恢复", icon: "\ue6db" },
      ],
      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" },
      ],
      warnSpn: "\ue71c",
      fileList: [],
      activePage: 0,
      interval: "",
      lifeSpan: "",
      options: [
        {
          value: "选项1",
          label: "手动",
        },
        {
          value: "选项2",
          label: "自动",
        },
      ],
      isBackUp: true,
      interval: null,
      lifeSpan: null,
      dir: "",
      isBackUp: false,
    };
  },
  methods: {
    getBakFileList() {
      getBackupList().then((res) => {
        this.fileList = res.data;
      });
    },
    getBakConfig() {
      getBakConfig().then((res) => {
        this.isBackUp = res.data.enable;
        this.lifeSpan = res.data.saveDays;
        this.interval = res.data.period;
        this.dir = res.data.dir;
      });
    },
    openRight(i) {
      this.activePage = i;
    },
    handleChange() {},
    backUpNow() {
      this.$confirm("您是否确认立即备份所有应用的配置数据?", "立即备份", {
      const h = this.$createElement;
      const icon = this.$msgbox({
        title: "",
        message: h(
          "div",
          {
            style:
              "display: flex;  flex-direction: column; justify-content: center; align-items: center;",
          },
          [
            h("span", { class: "icon iconfont warn-icon" }, `${this.warnSpn}`),
            h("span", { class: "warn-title" }, "立即备份"),
            h(
              "span",
              { class: "warn-dec" },
              "确认立即备份所有应用的配置数据?"
            ),
          ]
        ),
        showCancelButton: true,
        confirmButtonText: "确定",
        cancelButtonText: "取消",
      }).then(() => {
        this.$message({
          type: "success",
          message: "备份成功",
        });
        backupRN({
          enable: this.isBackUp,
          dir: this.dir,
          period: this.interval,
          saveDays: this.lifeSpan,
        })
          .then((res) => {
            if (res.code == 200) {
              this.$notify.success(res.msg);
            } else {
              this.$notify.error(res.msg);
            }
          })
          .catch((err) => {
            this.$notify.error(err.msg);
          });
      });
      //  .then((resp) => {
      //         if (resp.success) {
      //           this.$message({
      //             type: "success",
      //             message: "删除数据成功",
      //           });
      //           this.loading = false;
      //         }
      //       })
      //       .catch((err) => {
      //         this.$message({
      //           type: "error",
      //           message: "删除数据失败!",
      //         });
      //         this.loading = false;
      //       });
    },
    recoverFile(bakDir) {
      recoverBackup({bakDir}).then((res) => {
        debugger
        res.data
      })
    },
    saveBakConfig() {
      setBakConfig({
        enable: this.isBackUp,
        dir: this.dir,
        period: this.interval,
        saveDays: this.lifeSpan,
      })
        .then((res) => {
          if (res.code == 200) {
            this.$notify.success(res.msg);
            this.getBakConfig();
          } else {
            this.$notify.error(res.msg);
          }
        })
        .catch((err) => {
          this.$notify.error(err.msg);
        });
    },
    switchChange(val) {
      console.log(val);
      this.saveBakConfig();
    },
  },
};
@@ -144,7 +206,7 @@
<style lang="scss">
.all {
  width: 100%;
  background-color: #FBFAFF;
  background-color: #fbfaff;
}
.backup-content {
@@ -154,44 +216,55 @@
  flex: 1;
  flex-basis: auto;
  box-sizing: border-box;
  border-top:2px solid #E1E0E6 ;
  border-left:2px solid #E1E0E6 ;
  border-top: 4px solid rgb(242, 242, 247);
  border-left: 4px solid rgb(242, 242, 247);
  .backup-center {
    height: 100%;
    width: 280px;
    width: 300px;
    overflow: auto;
    box-sizing: border-box;
    flex-shrink: 0;
    padding: 10px;
    border-right: 5px solid #f8f8f8;
    padding: 9px 10px 0 10px;
    border-right: 4px solid rgb(242, 242, 247);
    .menu-item {
      background-color: #f8f8f8;
      height: 50px;
      margin-bottom: 10px;
      height: 56px;
      margin-bottom: 4px;
      border-radius: 8px;
      line-height: 50px;
      line-height: 56px;
      box-sizing: border-box;
      font-size: 14px;
      cursor: pointer;
      padding: 0 20px;
      padding: 0 15px;
      display: flex;
      justify-content: space-between;
      .con {
        .iconfont {
          font-size: 20px;
          line-height: 32px;
          width: 32px;
          height: 26px;
          margin-right: 10px;
          color: #333;
        }
        .menu-text {
          font-size: 15px;
          font-size: 16px;
          font-weight: 700;
        }
      }
    }
    .menu-item-active {
      color: #fff;
      background-color: var(--colorCard);
      background-color: var(--colorCard) !important;
      .iconfont {
        color: #fff !important;
      }
      .menu-text {
        color: #fff;
      }
    }
    .menu-item:hover {
      color: #fff;
      background-color: var(--colorCard);
      background-color: #f2f2f7;
    }
  }
  .backup-right {
@@ -200,7 +273,6 @@
    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)
@@ -303,7 +375,7 @@
          text-align: left;
        }
        .operation {
          color: rgba(26, 115, 232, 1);
          color: var(--colorCard);
          cursor: pointer;
          width: 10%;
          text-align: right;
@@ -311,15 +383,12 @@
      }
    }
    .save-btn {
      background-color: #3d68e1;
      width: 240px;
      width: 251px;
      height: 40px;
      margin: 0 auto;
      border-radius: 10px;
      color: #fff;
      line-height: 40px;
      font-size: 14px;
      margin-top: 20px;
      margin-top: 80px;
      background: var(--colorCard) !important;
      border: 1px solid var(--colorCard) !important;
      border-radius: 25px;
    }
  }
}
src/pages/vindicate/views/restartSettings.vue
@@ -1,9 +1,10 @@
<template>
  <div class="restart"
   v-loading="loading"
   :element-loading-text="loadingText"
   element-loading-spinner="restart-loading"
   element-loading-background="rgba(0, 0, 0, 0.35)"
  <div
    class="restart"
    v-loading="loading"
    :element-loading-text="loadingText"
    element-loading-spinner="restart-loading"
    element-loading-background="rgba(0, 0, 0, 0.35)"
  >
    <div class="restart-set">
      <div class="t">重启设置</div>
@@ -111,8 +112,8 @@
      timer: null,
      probeSum: 0,
      cronText: "",
      loading:false,
      loadingText:"智能计算节点正在重启,请耐心等待......",
      loading: false,
      loadingText: "智能计算节点正在重启,请耐心等待......",
      cronValueObj: {
        min: "*",
        hour: "*",
@@ -201,7 +202,7 @@
    },
    restart() {
      const h = this.$createElement;
      const icon = this.$msgbox( {
      const icon = this.$msgbox({
        title: "",
        message: h(
          "div",
@@ -220,7 +221,7 @@
        cancelButtonText: "取消",
      }).then(() => {
        this.loading = true;
        this.loadingText = "智能计算节点正在重启,请耐心等待..."
        this.loadingText = "智能计算节点正在重启,请耐心等待...";
        rebootServer()
          .then((rsp) => {
            this.probeServer(this.reLogin);
@@ -338,7 +339,7 @@
<style lang="scss">
.all {
  width: 100%;
  background-color: #FBFAFF;
  background-color: #fbfaff;
}
.restart {
  margin: 0 auto;
@@ -351,18 +352,18 @@
  border-left: 4px solid #f2f2f7;
  .t {
    height: 48px;
    background: #F2F2F7;
    background: #f2f2f7;
    box-sizing: border-box;
    text-align: left;
    width: 100%;
    padding: 10px 20px;
    line-height: 32px;
    border-radius:8px ;
    border-radius: 8px;
  }
  .bar {
    height: 50px;
    width: 100%;
    background: #F2F2F7;
    background: #f2f2f7;
    min-width: 300px;
    display: flex;
    justify-content: space-between;
@@ -373,16 +374,16 @@
    margin-top: 4px;
    margin-bottom: 4px;
    .reset-btn {
     width: 150px;
     height: 32px;
     border-radius: 20px;
     background: rgba(78, 148, 255, 0.1) !important;
     border: 1px solid var(--colorCard);
     color: #333333;
     font-weight: bold;
     font-size: 14px;
      width: 150px;
      height: 32px;
      border-radius: 20px;
      background: rgba(78, 148, 255, 0.1) !important;
      border: 1px solid var(--colorCard);
      color: #333333;
      font-weight: bold;
      font-size: 14px;
    }
    .name {
      min-width: 150px;
      text-align: left;
@@ -404,32 +405,30 @@
    .el-date-editor.el-input__inner {
      width: 100%;
    }
  }
  .el-select {
      width: 509px;
      height: 32px;
      input {
         background: #FBFAFF !important;
         border-radius: 20px !important;
         text-align: center;
      }
    width: 509px;
    height: 32px;
    input {
      background: #fbfaff !important;
      border-radius: 20px !important;
      text-align: center;
    }
  }
  .el-date-editor {
    width: 509px;
    height: 32px;
      input {
         background: #FBFAFF !important;
         border-radius: 20px !important;
         text-align: center;
      }
    input {
      background: #fbfaff !important;
      border-radius: 20px !important;
      text-align: center;
    }
      .el-input__prefix {
        left: 215px !important;
      }
    .el-input__prefix {
      left: 215px !important;
    }
  }
  .save-btn {
    width: 251px;
@@ -442,105 +441,104 @@
}
.restartTimePicker {
    width: 509px !important;
    background-color: #FBFAFF !important;
    margin-top:8px !important;
   /*  .popper__arrow::after {
  width: 509px !important;
  background-color: #fbfaff !important;
  margin-top: 8px !important;
  /*  .popper__arrow::after {
    display: none !important;
  } */
  }
}
</style>
<style lang="scss">
.warn-icon {
    color: #fe6d68;
    font-size: 40px;
    margin-top: 11px;
  color: #fe6d68;
  font-size: 40px;
  margin-top: 11px;
}
.warn-title {
  font-weight: bold;
  font-size: 16px;
  margin: 6px;
  line-height: 22px;
}
.warn-dec {
  font-weight: bold;
  font-size: 14px;
  color: #828282;
  line-height: 20px;
}
.el-message-box__headerbtn {
  top: 12px;
}
.el-message-box__headerbtn .el-message-box__close {
  color: #333333;
  font-weight: bold;
}
.el-message-box__btns {
  display: flex;
  justify-content: center;
  margin-top: 20px;
  .el-button:focus,
  .el-button:hover {
    background-color: none;
    border: none;
  }
  .warn-title {
    font-weight: bold;
    font-size: 16px;
    margin: 6px;
    line-height: 22px;
  }
  .warn-dec {
    font-weight: bold;
    font-size: 14px;
    color: #828282;
    line-height: 20px;
  }
   .el-message-box__headerbtn {
    top: 12px;
  }
  .el-message-box__headerbtn .el-message-box__close {
    color: #333333;
    font-weight: bold;
  }
  .el-message-box__btns {
    display: flex;
    justify-content: center;
    margin-top: 20px;
    .el-button:focus,
    .el-button:hover {
      background-color: none;
      border: none;
  button {
    width: 175px;
    height: 40px;
    border-radius: 25px;
    span {
      font-size: 16px;
      font-weight: 700;
    }
    button {
      width: 175px;
      height: 40px;
      border-radius: 25px;
      span {
        font-size: 16px;
        font-weight: 700;
      }
      &:hover {
        border: 1px solid var(--colorCard) !important;
      }
    }
    button:first-child {
      background-color: #e0e0e0;
      span {
        color: #333333;
      }
    }
    button:last-child {
      background-color: var(--colorCard) !important;
    &:hover {
      border: 1px solid var(--colorCard) !important;
      span {
         color: #fff;
      }
    }
   }
   .restart  .el-loading-mask .el-loading-spinner {
     top: 40%;
   }
 .restart  .el-loading-mask .el-loading-spinner .el-loading-text {
     font-size: 16px;
     font-weight: bold;
     color: #FFFFFF;
     margin-top:20px ;
   }
  .restart .el-loading-mask .restart-loading {
    background-image: url("/images/desktop/safari.png");
    display: block;
    width: 50px;
    height: 50px;
    margin-bottom:20px ;
    background-size:50px ;
    margin: 0 auto;
    animation: rotate 6s linear infinite;
  }
  button:first-child {
    background-color: #e0e0e0;
    span {
      color: #333333;
    }
  }
  button:last-child {
    background-color: var(--colorCard) !important;
    border: 1px solid var(--colorCard) !important;
    span {
      color: #fff;
    }
  }
}
@keyframes rotate{
    0%{
        transform: rotateZ(0deg);/*从0度开始*/
    }
    100%{
        transform: rotateZ(360deg);/*360度结束*/
    }
.restart .el-loading-mask .el-loading-spinner {
  top: 40%;
}
.restart .el-loading-mask .el-loading-spinner .el-loading-text {
  font-size: 16px;
  font-weight: bold;
  color: #ffffff;
  margin-top: 20px;
}
.restart .el-loading-mask .restart-loading {
  background-image: url("/images/desktop/safari.png");
  display: block;
  width: 50px;
  height: 50px;
  margin-bottom: 20px;
  background-size: 50px;
  margin: 0 auto;
  animation: rotate 6s linear infinite;
}
@keyframes rotate {
  0% {
    transform: rotateZ(0deg); /*从0度开始*/
  }
  100% {
    transform: rotateZ(360deg); /*360度结束*/
  }
}
</style>
src/pages/vindicate/views/sysInfo.vue
@@ -125,7 +125,6 @@
          this.expireTime = res.data.expireTime;
          this.serializedNumber = res.data.sn;
          this.q = res.data.q;
          debugger
        }
      });
    },
@@ -174,7 +173,6 @@
        a.download = "key.txt";
        a.click();
        window.URL.revokeObjectURL(url);
          debugger
        this.refreshSn();
        window.parent.postMessage({ msg: "checkSN" }, "*");
        this.$notify.success("导出成功");
src/pages/vindicate/views/updateSettings.vue
@@ -182,7 +182,6 @@
<script>
import {
  getDevInfo,
  doUpgrade,
  checkNewVersion,
  upgradeNewVersion,
  uploadUpgradePkg,
@@ -390,7 +389,6 @@
    flex-shrink: 0;
    padding: 9px 10px 0 10px;
    border-right: 4px solid rgb(242, 242, 247);
    .menu-item {
      height: 56px;
      margin-bottom: 4px;