| | |
| | | }) |
| | | }; |
| | | |
| | | // 退出集群 |
| | | export const leave = (query: any) => { |
| | | return request({ |
| | | url: "/data/api-v/cluster/leave", |
| | |
| | | data: qs.stringify(query) |
| | | }) |
| | | } |
| | | |
| | | // |
| | | export const uploadKey = (data: any) => { |
| | | return request({ |
| | | url: "/version/authorization/upload", |
| | |
| | | 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" |
| | | }) |
| | | } |
| | | |
| | |
| | | <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" |
| | | ></span |
| | |
| | | :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> |
| | |
| | | </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> |
| | |
| | | <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", |
| | |
| | | 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() == "") { |
| | |
| | | } |
| | | activateVersion({ code: this.secrectKey.trim() }) |
| | | .then((res) => { |
| | | debugger |
| | | debugger; |
| | | if (res.code == 200) { |
| | | this.$notify.success("激活成功"); |
| | | this.validateSn(); |
| | |
| | | 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; |
| | |
| | | </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' : ''"
|
| | |
| | | :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"
|
| | |
| | | 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"
|
| | |
| | | </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"></i>
|
| | | {{ item.Address }}
|
| | | </div>
|
| | | </div>
|
| | | <div class="btns">
|
| | | <div class="ok" @click="join('joinForm')">加入集群</div>
|
| | | </div>
|
| | | </div>
|
| | | </div>
|
| | | </div>
|
| | |
| | | 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";
|
| | |
|
| | |
| | | activePage: 0,
|
| | | inputIp: "",
|
| | | serverIp: "",
|
| | | pickedNodeI: null,
|
| | | members: [],
|
| | | virtualIp: "192.168.1.188",
|
| | | searchDis: false,
|
| | |
| | | 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();
|
| | |
| | | clearInterval(this.intervalTimer);
|
| | | },
|
| | | methods: {
|
| | | pickNode(index) {
|
| | | // this.pickedNodeI=index
|
| | | },
|
| | | async createCluster(json) {
|
| | | let res = await createSerfCluster(json);
|
| | | this.$notify({
|
| | |
| | | });
|
| | | },
|
| | | 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(() => {
|
| | |
| | | }
|
| | | .cluster-guanli {
|
| | | margin: 0 auto;
|
| | | width: 760px; |
| | | width: 760px;
|
| | | padding: 0 10px;
|
| | | .btns {
|
| | | margin-top: 30px !important;
|
| | |
| | | margin-top: 0;
|
| | | }
|
| | | }
|
| | |
|
| | | .cloud {
|
| | | width: 100%;
|
| | | display: flex;
|
| | |
| | | > .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;
|
| | |
| | | left: 20px;
|
| | | }
|
| | | .el-form-item {
|
| | | margin-bottom: 10px;
|
| | | margin-bottom: 10px;
|
| | | .el-input__inner {
|
| | | background-color: #ffffff;
|
| | | border: 2px solid transparent;
|
| | |
| | | </template>
|
| | |
|
| | | <script>
|
| | | import { saveAlarmConfig, getDevInfo } from "@/api/system";
|
| | | import { getDevInfo } from "@/api/system";
|
| | | import { uploadSound, getSoundList, deleteSound } from "@/api/event";
|
| | |
|
| | | export default {
|
| | |
| | | async search(json) { |
| | | let res = await search(json); |
| | | if (res && res.success) { |
| | | console.log(res, "搜索集群"); |
| | | this.searchNum = res.data; |
| | | } |
| | | this.searchDis = true; |
| | |
| | | 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 |
| | |
| | | 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 { |
| | |
| | | components: { |
| | | systemClean, |
| | | updateSettings, |
| | | // BackUp, |
| | | BackUp, |
| | | restartSettings, |
| | | sysInfo, |
| | | }, |
| | |
| | | img_white: "/images/vindicate/系统清理-白.png", |
| | | img_welcome: "/images/vindicate/系统清理.png", |
| | | }, |
| | | |
| | | { |
| | | name: "重启设置", |
| | | img_black: "/images/vindicate/重启设置-黑.png", |
| | |
| | | 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", |
| | |
| | | <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">
|
| | |
| | | </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" -->
|
| | |
| | | <div class="bar">
|
| | | <div class="name">备份数据保存时间 / 天</div>
|
| | | <el-input
|
| | | v-model="lifeSpan"
|
| | | v-model.number="lifeSpan"
|
| | | placeholder="请输入天数"
|
| | | @change="handleChange"
|
| | | size="small"
|
| | | ></el-input>
|
| | | </div>
|
| | |
| | | >立即备份</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>
|
| | |
| | | </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>
|
| | |
| | | </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();
|
| | | },
|
| | | },
|
| | | };
|
| | |
| | | <style lang="scss">
|
| | | .all {
|
| | | width: 100%;
|
| | | background-color: #FBFAFF;
|
| | | background-color: #fbfaff;
|
| | | }
|
| | |
|
| | | .backup-content {
|
| | |
| | | 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 {
|
| | |
| | | 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)
|
| | |
| | | text-align: left;
|
| | | }
|
| | | .operation {
|
| | | color: rgba(26, 115, 232, 1);
|
| | | color: var(--colorCard);
|
| | | cursor: pointer;
|
| | | width: 10%;
|
| | | text-align: right;
|
| | |
| | | }
|
| | | }
|
| | | .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;
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | <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>
|
| | |
| | | timer: null,
|
| | | probeSum: 0,
|
| | | cronText: "",
|
| | | loading:false,
|
| | | loadingText:"智能计算节点正在重启,请耐心等待......",
|
| | | loading: false,
|
| | | loadingText: "智能计算节点正在重启,请耐心等待......",
|
| | | cronValueObj: {
|
| | | min: "*",
|
| | | hour: "*",
|
| | |
| | | },
|
| | | restart() {
|
| | | const h = this.$createElement;
|
| | | const icon = this.$msgbox( {
|
| | | const icon = this.$msgbox({
|
| | | title: "",
|
| | | message: h(
|
| | | "div",
|
| | |
| | | cancelButtonText: "取消",
|
| | | }).then(() => {
|
| | | this.loading = true;
|
| | | this.loadingText = "智能计算节点正在重启,请耐心等待..."
|
| | | this.loadingText = "智能计算节点正在重启,请耐心等待...";
|
| | | rebootServer()
|
| | | .then((rsp) => {
|
| | | this.probeServer(this.reLogin);
|
| | |
| | | <style lang="scss">
|
| | | .all {
|
| | | width: 100%;
|
| | | background-color: #FBFAFF;
|
| | | background-color: #fbfaff;
|
| | | }
|
| | | .restart {
|
| | | margin: 0 auto;
|
| | |
| | | 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;
|
| | |
| | | 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;
|
| | |
| | | .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;
|
| | |
| | | }
|
| | |
|
| | | .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>
|
| | |
| | | this.expireTime = res.data.expireTime;
|
| | | this.serializedNumber = res.data.sn;
|
| | | this.q = res.data.q;
|
| | | debugger
|
| | | }
|
| | | });
|
| | | },
|
| | |
| | | a.download = "key.txt";
|
| | | a.click();
|
| | | window.URL.revokeObjectURL(url);
|
| | | debugger
|
| | | this.refreshSn();
|
| | | window.parent.postMessage({ msg: "checkSN" }, "*");
|
| | | this.$notify.success("导出成功");
|
| | |
| | | <script>
|
| | | import {
|
| | | getDevInfo,
|
| | | doUpgrade,
|
| | | checkNewVersion,
|
| | | upgradeNewVersion,
|
| | | uploadUpgradePkg,
|
| | |
| | | flex-shrink: 0;
|
| | | padding: 9px 10px 0 10px;
|
| | | border-right: 4px solid rgb(242, 242, 247);
|
| | |
|
| | | .menu-item {
|
| | | height: 56px;
|
| | | margin-bottom: 4px;
|