From 1e1e5f612f252d66b0d0386cf52873bb1f3f7d7b Mon Sep 17 00:00:00 2001 From: haoxuan <haoxuan> Date: 星期五, 01 九月 2023 16:10:37 +0800 Subject: [PATCH] 系统维护+系统监控器+调试工具的app 增加 --- public/images/app-mid/productionSign.png | 0 public/images/desktop/header-icon/SmartAI-新.png | 0 public/images/app-mid/debuggTool.png | 0 src/pages/vindicate/index/App.vue | 617 ++++++++++++++++ src/pages/vindicate/index/main.ts | 16 src/pages/desktop/index/components/ToolsEntry.vue | 3 src/pages/systemMonitor/index/main.ts | 16 src/pages/systemMonitor/index/App.vue | 853 ++++++++++++++++++++++ src/pages/systemMonitor/api/api.ts | 22 public/apps.json | 74 + src/pages/debuggTool/index/App.vue | 617 ++++++++++++++++ src/pages/debuggTool/index/main.ts | 16 12 files changed, 2,231 insertions(+), 3 deletions(-) diff --git a/public/apps.json b/public/apps.json index b066097..64f07a2 100644 --- a/public/apps.json +++ b/public/apps.json @@ -93,17 +93,85 @@ "isUpgrade": false, "progressMsg": "" }, - + { + "id": "ee64fe23-7631-4ef9-9aca-ea09673693be", + "name": "绯荤粺缁存姢", + "package": "vindicate", + "type": "2", + "url": "/view/vindicate/", + "title": "绯荤粺缁存姢", + "width": 760, + "height": 534, + "iconBlob": "", + "icon": "../../images/app-mid/vindicate.png", + "version": "1.0.0", + "create_time": "2020-10-09 14:00:11", + "create_by": "", + "update_time": "", + "update_by": "", + "isDelete": 0, + "isDefault": true, + "remoteVersion": "", + "installed": true, + "isUpgrade": false, + "progressMsg": "" + }, { "id": "fa5674ee-70cf-4e22-8a06-c17429fb777", - "name": "鐢熶骇绠$悊鐪嬫澘", + "name": "鐢熶骇浠诲姟", "package": "shuohuangMonitorAnalyze", "type": "1", "url": "http://192.168.20.125:8080", - "title": "鐢熶骇绠$悊鐪嬫澘", + "title": "鐢熶骇浠诲姟", + "width": 0, + "height": 0, + "iconBlob": "", + "icon": "../../images/app-mid/productionSign.png", + "version": "1.0.0", + "create_time": "2020-10-09 14:00:08", + "create_by": "", + "update_time": "", + "update_by": "", + "isDelete": 0, + "isDefault": false, + "remoteVersion": "", + "installed": true, + "isUpgrade": false, + "progressMsg": "" + }, + { + "id": "fa5674ee-70cf-4e22-8a06-c17429fb777", + "name": "璋冭瘯宸ュ叿", + "package": "debuggTool", + "type": "2", + "url": "/view/debuggTool/", + "title": "璋冭瘯宸ュ叿", "width": 1500, "height": 750, "iconBlob": "", + "icon": "../../images/app-mid/debuggTool.png", + "version": "1.0.0", + "create_time": "2020-10-09 14:00:08", + "create_by": "", + "update_time": "", + "update_by": "", + "isDelete": 0, + "isDefault": false, + "remoteVersion": "", + "installed": true, + "isUpgrade": false, + "progressMsg": "" + }, + { + "id": "fa5674ee-70cf-4e22-8a06-c171292b777", + "name": "绯荤粺鐩戞帶", + "package": "systemMonitor", + "type": "2", + "url": "/view/systemMonitor/", + "title": "绯荤粺鐩戞帶", + "width": 1220, + "height": 800, + "iconBlob": "", "icon": "../../images/app-mid/visual.png", "version": "1.0.0", "create_time": "2020-10-09 14:00:08", diff --git a/public/images/app-mid/debuggTool.png b/public/images/app-mid/debuggTool.png new file mode 100644 index 0000000..3e3957a --- /dev/null +++ b/public/images/app-mid/debuggTool.png Binary files differ diff --git a/public/images/app-mid/productionSign.png b/public/images/app-mid/productionSign.png new file mode 100644 index 0000000..8bd7c19 --- /dev/null +++ b/public/images/app-mid/productionSign.png Binary files differ diff --git "a/public/images/desktop/header-icon/SmartAI-\346\226\260.png" "b/public/images/desktop/header-icon/SmartAI-\346\226\260.png" index a5546cc..f865095 100644 --- "a/public/images/desktop/header-icon/SmartAI-\346\226\260.png" +++ "b/public/images/desktop/header-icon/SmartAI-\346\226\260.png" Binary files differ diff --git a/src/pages/debuggTool/index/App.vue b/src/pages/debuggTool/index/App.vue new file mode 100644 index 0000000..7f0e417 --- /dev/null +++ b/src/pages/debuggTool/index/App.vue @@ -0,0 +1,617 @@ +<template> + <div class="s-system-manage"> + <el-tabs + id="systemMaintenance" + v-model="activeName" + v-loading="loading" + :element-loading-text="loadingText" + > + <el-tab-pane label="璁惧缁存姢" name="device" v-if="isShow('vindicate:device')"> + <div class="s-system-maintenance"> + <div class="box-card"> + <div class="ui-top-view"> + <div class="ui-top-title">閲嶅惎</div> + </div> + <el-divider></el-divider> + + <div class="box-card-content"> + <el-button type="primary" size="small" style="width:80px" @click="reboot">閲嶅惎</el-button> + + <b class="card-text">閲嶅惎鑺傜偣</b> + + <el-row style="margin-top:20px"> + <el-col> + <vue-cron :expression="rebootCron" @update="setRebootCron" /> + </el-col> + </el-row> + </div> + </div> + <!-- + <div class="box-card"> + <div class="ui-top-view"> + <div class="ui-top-title">鎭㈠榛樿鍊�</div> + </div> + <el-divider></el-divider> + + <div class="box-card-content"> + <el-row> + <el-col :span="1"> + <el-button type="primary" size="small">绠�鍗曟仮澶�</el-button> + </el-col> + <el-col :span="23"> + <b class="card-text">绠�鍗曟仮澶嶈澶囧弬鏁�</b> + </el-col> + </el-row> + <el-row style="margin-top:20px"> + <el-col :span="1"> + <el-button type="primary" size="small">瀹屽叏鎭㈠</el-button> + </el-col> + <el-col :span="23"> + <b class="card-text">瀹屽叏鎭㈠璁惧鍙傛暟鍒板嚭鍘傝缃�</b> + </el-col> + </el-row> + </div> + </div> + + <div class="box-card"> + <div class="ui-top-view"> + <div class="ui-top-title">鍙傛暟瀵煎叆瀵煎嚭</div> + </div> + <el-divider></el-divider> + + <div class="box-card-content"> + <el-row :gutter="4"> + <el-col :span="1"> + <el-button type="info" size="small" style="width:80px">瀵煎叆</el-button> + </el-col> + <el-col :span="3" style="padding-left:30px"> + <el-input placeholder="涓婁紶鍙傛暟鏂囦欢" size="small" :readonly="true"> + <el-upload slot="suffix" action="https://jsonplaceholder.typicode.com/posts/"> + <el-button + type="text" + icon="el-icon-upload2" + size="small" + style="font-size:18px; color:#0088ff" + ></el-button> + </el-upload> + </el-input> + </el-col> + </el-row> + <el-row style="margin-top:20px"> + <el-col :span="1"> + <el-button type="primary" size="small">璁惧鍙傛暟</el-button> + </el-col> + <el-col :span="23"> + <b class="card-text">鍙傛暟瀵煎嚭</b> + </el-col> + </el-row> + </div> + </div> + --> + <div class="box-card"> + <div class="ui-top-view"> + <div class="ui-top-title">鍗囩骇</div> + </div> + </div> + <el-divider></el-divider> + <div class="box-card-content"> + <el-row :gutter="4"> + <el-col :span="12"> + <file-uploader + single + uploadPlaceholder="涓婁紶鍗囩骇鏂囦欢" + url="/data/api-v/sysset/patchUpdate" + @complete="onFileUpload" + @file-added="onFileAdded" + /> + </el-col> + <el-col :span="2"> + <el-button + type="primary" + size="small" + style="width:80px" + @click="upgrade" + :disabled="!fileAdded" + :loading="upgrading" + >鍗囩骇</el-button> + </el-col> + <el-col :span="16" class="upload-msg"> + <span v-html="patchUpdateStatus"></span> + </el-col> + </el-row> + </div> + </div> + </el-tab-pane> + <el-tab-pane label="鏁版嵁搴撶淮鎶�" name="dbvdc" v-if="isShow('vindicate:db')"> + <div class="box"> + <p class="title"> + <label>鏁版嵁娓呯悊</label> + </p> + <div class="range"> + <div class="left"> + <p>閫夋嫨鏁版嵁鑼冨洿锛�</p> + </div> + <div class="middle"> + <el-date-picker + v-model="dataRange" + type="daterange" + range-separator="鑷�" + start-placeholder="寮�濮嬫棩鏈�" + end-placeholder="缁撴潫鏃ユ湡" + style="height:38px" + :picker-options="pickerOptions" + ></el-date-picker> + </div> + <div class="right"> + <el-button @click="deleteData" style="height:38px;background:#ff0000;color:white">鍒犻櫎鏁版嵁</el-button> + </div> + </div> + <div class="tip"> + <i class="iconfont icontishi-zhuyi"></i> + <p class="zhuyi">璇锋敞鎰忥紝鎸変互涓婃棩鏈熻寖鍥村垹闄ょ殑鏁版嵁涓嶅彲鎭㈠锛岀珛鍗崇敓鏁堬紝璇疯皑鎱庢搷浣�</p> + </div> + </div> + </el-tab-pane> + </el-tabs> + </div> +</template> + +<script> +import { rebootServer, getDevInfo, getRebootTask, setRebootTask, fileUpload, doUpgrade, deleteDate } from "@/api/system" +import VueCron from "@/components/subComponents/VueCron" +import FileUploader from "@/components/subComponents/FileUpload/index" + +export default { + components: { + VueCron, + FileUploader + }, + data() { + return { + timer: null, + buttonAuthority: sessionStorage.getItem("buttonAuthoritys") || [], + rebootCron: "", + activeName: "device", + restartValue: "涓嶉噸鍚�", + restartTimeValue: new Date(2019, 9, 10, 18, 40), + loading: false, + loadingText: '', + probeSum: 0, + patchUpdateStatus: "", + dataRange: [ + this.$moment().format("YYYY-MM-DD HH:mm:ss"), + this.$moment().format("YYYY-MM-DD HH:mm:ss") + ], + fileUploadUrl: fileUpload, + patchFile: {}, + pickerOptions: { + disabledDate(time) { + var day = new Date() + day.setTime(day.getTime() - 24 * 60 * 60 * 1000) + return time.getTime() > day; + }, + }, + upgrading: false, + fileAdded: false, + }; + }, + mounted() { + this.getRebootCron() + if (!this.isShow('vindicate:device')) { + this.activeName = "dbvdc" + } + }, + computed: { + isAdmin() { + if ( + sessionStorage.getItem('userInfo') && + sessionStorage.getItem('userInfo') !== '' + ) { + let loginName = JSON.parse(sessionStorage.getItem('userInfo')).username + return ( + loginName === 'superadmin' || loginName === 'basic' + ) + } + return false; + } + }, + methods: { + isShow(authority) { + if (this.isAdmin) { + return true + } else if ( + this.buttonAuthority.indexOf(',' + authority + ',') > -1 + ) { + return true + } else { + return false + } + }, + format(array) { + return [ + this.$moment(array[0]).format("YYYY-MM-DD"), + this.$moment(array[1]).format("YYYY-MM-DD") + ]; + }, + getRebootCron() { + getRebootTask().then(rsp => { + this.rebootCron = rsp.data + }) + }, + setRebootCron(value) { + this.rebootCron = value + setRebootTask({ task: value }).then(rsp => { + if (rsp && rsp.success) { + this.$notify({ + type: "success", + message: "閰嶇疆鎴愬姛" + }) + } + }).catch(err => { + this.$notify({ + type: "error", + message: "閰嶇疆澶辫触" + }) + }) + }, + reboot() { + this.$confirm('纭畾瑕侀噸鍚鑺傜偣鍚�?', { + center: true, + cancelButtonClass: 'comfirm-class-cancle', + confirmButtonClass: 'comfirm-class-sure' + }).then(() => { + this.loading = true; + this.loadingText = "鏅鸿兘璁$畻鑺傜偣姝e湪閲嶅惎锛岃鑰愬績绛夊緟..." + 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) + } + }) + }) + }, + deleteData() { + var timeRange = this.format(this.dataRange); + var showStartTime = timeRange[0] + var showEndTime = timeRange[1] + console.log("鏃堕棿锛�", showStartTime, showEndTime) + this.$confirm("鎻愮ず锛�" + showStartTime + " 鑷� " + showEndTime + " 浜х敓鐨勫叏閮ㄦ暟鎹皢琚垹闄わ紝姝ゆ搷浣滅珛鍗崇敓鏁堬紝涓嶅彲鎭㈠锛屾槸鍚﹀垹闄わ紵", { + center: true, + cancelButtonClass: "comfirm-class-cancle", + confirmButtonClass: "comfirm-class-sure" + }).then(() => { + this.loading = true + this.loadingText = "姝e湪鍒犻櫎鏁版嵁锛岃绋嶅�欙紒" + var param = { + startTime: showStartTime, + endTime: showEndTime + } + deleteDate(param).then(resp => { + if (resp.success) { + this.$message({ + type: "success", + message: "鍒犻櫎鏁版嵁鎴愬姛" + }) + this.loading = false + } + }).catch(err => { + this.$message({ + type: "error", + message: "鍒犻櫎鏁版嵁澶辫触锛�" + }) + this.loading = false + }) + + }).catch(() => { + console.log("鍙栨秷浜嗭紒") + }) + }, + reLogin() { + this.$router.push("/") + }, + probeServer(callback) { + this.probeSum++; + let _this = this + if (this.probeSum > 60) { + this.$confirm('杩炴帴鏈嶅姟鍣ㄥけ璐�, 璇峰埛鏂伴〉闈㈡垨鑱旂郴绠$悊鍛�', '澶辫触', { + type: 'error', + cancelButtonClass: 'comfirm-class-cancle', + confirmButtonClass: 'comfirm-class-sure' + }).then(() => { + // _this.$router.push("/") + callback() + }) + return + } + + this.timer = setTimeout(() => { + getDevInfo().then(() => { + // _this.$router.push("/") + callback() + }).catch(err => { + _this.probeServer(callback) + }) + }, 10000) + }, + 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">姝e湪鍗囩骇...</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() + }) + } + } +}; +</script> +<style lang="scss"> +.s-system-manage { + width: 100% !important; + min-width: 759px; + box-sizing: border-box; + padding: 10px; + // background-color: #e9ebf2; + background-color: #fff; + .s-system-manage-breadcrumb { + height: 5%; + box-sizing: border-box; + border: 1px solid #e4e7ed; + box-shadow: #e4e7ed 0px 0px 9px inset; + box-shadow: #e4e7ed 0px 0px 9px inset; + border-radius: 5px; + } + + .el-tabs--border-card { + border: 0px solid #dcdfe6; + -webkit-box-shadow: none; + box-shadow: none; + .el-tabs__header { + border: 0px solid #dcdfe6; + .el-tabs__item { + padding: 5px 50px; + height: 50px; + font-family: PingFangSC-Regular; + font-size: 15px; + color: #222222; + text-align: center; + border: 0px solid transparent; + } + .el-tabs__item:nth-child(2) { + padding-left: 50px !important; + } + .el-tabs__item:last-child { + padding-right: 50px !important; + } + .el-tabs__item.is-active { + color: #3d68e1; + font-weight: bold; + // border-right-color: #fff; + // border-left-color: #fff; + } + .el-tabs__item:not(.is-disabled):hover { + color: #3d68e1; + } + } + } + .el-tabs__content { + height: calc(100% - 64px); + width: calc(100% - 20px); + box-sizing: border-box; + overflow-y: auto; + padding: 10px 40px !important; + .el-tab-pane { + width: 100%; + .s-title { + text-align: left; + padding: 15px 0px; + font-size: 16px; + } + } + } + + .s-table { + border: 1px solid #e8e8e9; + margin-top: 40px; + } + + .ui-top-title { + padding-bottom: 10px; + /* border-bottom: 1px solid #ebebeb; */ + position: relative; + text-align: left; + padding-left: 15px; + font-size: 16px; + font-weight: bold; + } + + .ui-top-title:before { + content: " "; + border-left: 4px solid #f53d3d; + display: inline-block; + height: 16px; + position: absolute; + top: 50%; + left: 0; + margin-top: -13px; + } + + .el-button--text { + color: #3d68e1; + text-decoration: underline; + } +} +.s-system-maintenance { + width: 100%; + height: 100%; + .el-button--primary { + color: #ffffff; + background-color: #3d68e1; + border-color: #3d68e1; + } + .el-button--primary.is-disabled, + .el-button--primary.is-disabled:hover, + .el-button--primary.is-disabled:focus, + .el-button--primary.is-disabled:active { + color: #ffffff; + background-color: #9eb4f0; + border-color: #9eb4f0; + } + .box-card { + text-align: left; + height: auto; + margin: 10px 0px; + .box-card-content { + padding-bottom: 40px; + .card-text { + padding: 0 30px; + line-height: 32px; + } + } + } + + .upload-icon { + font-size: 18px; + color: #0088ff; + } + .upload-msg { + padding-left: 10px; + text-align: left; + span { + line-height: 32px; + font-size: 13px; + } + } +} +.box { + width: 50%; + min-width: 700px; + height: 270px; + border: 1px solid #eee; + .title { + font-size: 20px; + font-weight: bold; + text-align: left; + padding: 20px; + border-bottom: 1px solid #eee; + } + .range { + width: 100%; + padding-top: 30px; + height: 38px; + .left { + width: 120px; + float: left; + text-align: right; + font-size: 14px; + p { + height: 38px; + line-height: 38px; + margin: 0; + } + } + .middle { + width: 50%; + min-width: 400px; + height: 38px; + float: left; + } + .right { + width: 20%; + height: 38px; + float: left; + } + } + .tip { + width: 100%; + padding: 30px 0px 0px 30px; + height: 34px; + + .zhuyi { + font-size: 14px; + height: 34px; + line-height: 34px; + margin-left: 20px; + float: left; + } + i { + font-size: 32px; + color: #e99038; + float: left; + } + } +} +#systemMaintenance { + .el-tabs__header { + border: 0px solid #dcdfe6; + .el-tabs__item { + padding: 5px 50px; + height: 50px; + font-family: PingFangSC-Regular; + font-size: 14px; + color: #222222; + text-align: center; + border: 0px solid transparent; + } + .el-tabs__item:nth-child(2) { + padding-left: 50px; + } + .el-tabs__item:last-child { + padding-right: 50px; + } + .el-tabs__item.is-active { + color: #ff7733; + font-weight: bold; + // border-right-color: #fff; + // border-left-color: #fff; + } + .el-tabs__item:not(.is-disabled):hover { + color: #ff7733; + } + } + .el-tabs__active-bar { + background-color: #ff7733; + } + .el-tabs__content { + padding-left: 15px !important; + } +} +</style> diff --git a/src/pages/debuggTool/index/main.ts b/src/pages/debuggTool/index/main.ts new file mode 100644 index 0000000..b5ea667 --- /dev/null +++ b/src/pages/debuggTool/index/main.ts @@ -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) +}) \ No newline at end of file diff --git a/src/pages/desktop/index/components/ToolsEntry.vue b/src/pages/desktop/index/components/ToolsEntry.vue index 63730ea..4e9b703 100644 --- a/src/pages/desktop/index/components/ToolsEntry.vue +++ b/src/pages/desktop/index/components/ToolsEntry.vue @@ -190,6 +190,9 @@ if (dock.type === "1") { window.open(dock.url); } else if (dock.type === "2" && !dock.isOpen) { + if(dock.url== "/view/debuggTool/"){ + return true; + } this.$store.dispatch("desktop/addFrame", { id: dock.id, icon: dock.src, diff --git a/src/pages/systemMonitor/api/api.ts b/src/pages/systemMonitor/api/api.ts new file mode 100644 index 0000000..abba575 --- /dev/null +++ b/src/pages/systemMonitor/api/api.ts @@ -0,0 +1,22 @@ +import request from "@/scripts/httpRequest"; + +export const showSystemStates = () => { + return request({ + url: "/data/api-z/system/showSystemStates", + method: "get" + }); +}; + +export const showService = () => { + return request({ + url: "/data/api-z/system/showService", + method: "get" + }); +}; + +export const showProcesses = () => { + return request({ + url: "/data/api-z/system/showProcesses", + method: "get" + }); +}; diff --git a/src/pages/systemMonitor/index/App.vue b/src/pages/systemMonitor/index/App.vue new file mode 100644 index 0000000..88437be --- /dev/null +++ b/src/pages/systemMonitor/index/App.vue @@ -0,0 +1,853 @@ +<template> + <div class="s-system-monitor"> + <el-tabs id="systemMonitor" v-model="activeName"> + <el-tab-pane label="鍗曞厓" name="proc"> + <div class="form-title"> + <b>绠楁硶鍗曞厓</b> + (姝e湪杩涜{{algoProcessData.length}}涓畻娉曞崟鍏�) + <el-table :data="algoProcessData" style="width: 100%"> + <el-table-column prop="desc" label="鍚嶇О" width="180"></el-table-column> + <el-table-column label="CPU" width="180"> + <template slot-scope="scope"> + <span>{{ scope.row.cpu.toFixed(2)}} %</span> + </template> + </el-table-column> + <el-table-column label="鍐呭瓨"> + <template slot-scope="scope"> + <span>{{ scope.row.mem.toFixed(2)}} %</span> + </template> + </el-table-column> + <el-table-column prop="disk" label="纭洏"></el-table-column> + <el-table-column label="绠楀姏"> + <template slot-scope="scope"> + <span>{{ scope.row.gpu}} M</span> + </template> + </el-table-column> + <el-table-column prop="net" label="缃戠粶"></el-table-column> + </el-table> + </div> + + <div class="form-title" style="margin-top:20px"> + <b>搴旂敤鍗曞厓</b> + (姝e湪杩涜{{appProcessData.length}}涓簲鐢ㄥ崟鍏�) + <el-table :data="appProcessData" style="width: 100%"> + <el-table-column prop="desc" label="鍚嶇О" width="180"></el-table-column> + <el-table-column prop="cpu" label="CPU" width="180"></el-table-column> + <el-table-column prop="mem" label="鍐呭瓨"></el-table-column> + <el-table-column prop="disk" label="纭洏"></el-table-column> + <el-table-column prop="gpu" label="绠楀姏"></el-table-column> + <el-table-column prop="net" label="缃戠粶"></el-table-column> + </el-table> + </div> + </el-tab-pane> + + <el-tab-pane label="鎬ц兘" name="top"> + <div class="column-left" ref="left"> + <div class="resize-bar"> + <div + :class="['ax_default', activeChartItem == 'cpu' ?'selected': '']" + @click="setActiveChartItem('cpu')" + > + <div class="ax_default_pic color-cpu"></div> + <div class="ax_default_text">CPU</div> + <div class="ax_default_subtext">{{cpuUsedPercent}}%</div> + </div> + + <div + :class="['ax_default', activeChartItem == 'mem' ?'selected': '']" + @click="setActiveChartItem('mem')" + > + <div class="ax_default_pic color-mem"></div> + <div class="ax_default_text">鍐呭瓨</div> + <div class="ax_default_subtext">{{memUsedPercent}}%</div> + </div> + + <div + :class="['ax_default', activeChartItem == 'gpu' ?'selected': '']" + @click="setActiveChartItem('gpu')" + > + <div class="ax_default_pic color-gpu"></div> + <div class="ax_default_text">绠楀姏</div> + <div class="ax_default_subtext">{{gpuUsedPercent}}%</div> + </div> + + <div + :class="['ax_default', activeChartItem == 'net' ?'selected': '']" + @click="setActiveChartItem('net')" + > + <div class="ax_default_pic color-net"></div> + <div class="ax_default_text">缃戠粶</div> + <div class="ax_default_subtext">{{netSend | byteConver}} / {{netRecive | byteConver}}</div> + </div> + + <div + v-for="(v, k) in disks" + :key="k" + :class="['ax_default', activeChartItem == ('disk|' + k) ?'selected': '']" + @click="setActiveChartItem('disk|'+k)" + > + <div class="ax_default_pic color-disk"></div> + <div class="ax_default_text">纾佺洏 {{k}}</div> + <div class="ax_default_subtext">{{v.info.total | byteConver}}</div> + </div> + </div> + + <div class="resize-line"></div> + </div> + + <div class="column-right"> + <div class="max-val">{{yAxisMaxVal}}</div> + <div ref="graphs" class="graphs-chart"></div> + + <div v-show="activeChartItem == 'cpu'"> + <div class="ax_default_label"> + <b>鍗犵敤鐜�</b> + <p>{{cpuUsedPercent}}%</p> + </div> + <div class="ax_default_label"> + <b>涓婚</b> + <p>{{cpuMaxRate}}Ghz</p> + </div> + <div class="ax_default_label"> + <b>鎻掓Ы</b> + <p>{{cpuCount}}</p> + </div> + <div class="ax_default_label"> + <b>鍐呮牳</b> + <p>{{cpuCore}}</p> + </div> + </div> + + <div v-show="activeChartItem == 'mem'"> + <div class="ax_default_label"> + <b>浣跨敤涓�</b> + <p>{{memUsed}}G</p> + </div> + <div class="ax_default_label"> + <b>宸茬紦瀛�</b> + <p>{{memCache}}G</p> + </div> + <div class="ax_default_label"> + <b>鍙敤</b> + <p>{{memFree}}G</p> + </div> + </div> + + <div v-show="activeChartItem == 'net'"> + <div class="ax_default_label"> + <b>鎺ユ敹</b> + <p>{{netRecive |byteConver}}</p> + </div> + <div class="ax_default_label"> + <b>鍙戦��</b> + <p>{{netSend |byteConver}}</p> + </div> + <div class="ax_default_label"> + <b>IP鍦板潃</b> + <p>{{ipAddr}}</p> + </div> + <div class="ax_default_label" style="margin-left: 19px;"> + <b>MAC鍦板潃</b> + <p>{{macAddr}}</p> + </div> + </div> + + <div v-show="isDisk"> + <div class="ax_default_label"> + <b>瀹归噺</b> + <p>{{activeDisk.total |byteConver}}</p> + </div> + <div class="ax_default_label"> + <b>宸茬敤</b> + <p>{{activeDisk.used |byteConver}}</p> + </div> + <div class="ax_default_label"> + <b>鍙敤</b> + <p>{{activeDisk.free |byteConver}}</p> + </div> + <div class="ax_default_label"> + <b>璇诲彇閫熷害</b> + <p>{{ioRead | byteConver}}</p> + </div> + <div class="ax_default_label"> + <b>鍐欏叆閫熷害</b> + <p>{{ioWrite | byteConver}}</p> + </div> + </div> + </div> + </el-tab-pane> + + <el-tab-pane label="鏈嶅姟" name="service"> + <el-table :data="vasystemServicesData"> + <el-table-column label="鍚嶇О" show-overflow-tooltip> + <template slot-scope="scope"> + <span>{{ scope.row.name}}</span> + </template> + </el-table-column> + <el-table-column label="鐘舵��" prop="status"> + <template slot-scope="scope"> + <span>{{ scope.row.pid == 0 ? "鏈惎鍔�" : "宸插惎鍔�" }}</span> + </template> + </el-table-column> + <el-table-column label="鎻忚堪" prop="desc"></el-table-column> + </el-table> + </el-tab-pane> + </el-tabs> + </div> +</template> + +<script> +import echarts from "echarts"; +import { showSystemStates, showService, showProcesses } from "../api/api" + +export default { + components: { + }, + computed: { + isDisk() { + return this.activeChartItem.indexOf("disk") == 0 + }, + isAdmin() { + if ( + sessionStorage.getItem('userInfo') && + sessionStorage.getItem('userInfo') !== '' + ) { + let loginName = JSON.parse(sessionStorage.getItem('userInfo')).username + return ( + loginName === 'superadmin' || loginName === 'basic' + ) + } + return false; + } + }, + filters: { + byteConver(limit) { + var size = ""; + if (limit < 1024) { //濡傛灉灏忎簬0.1KB杞寲鎴怋 + size = limit + "B"; + } else if (limit < 1024 * 1024) {//濡傛灉灏忎簬0.1MB杞寲鎴怟B + size = (limit / 1024).toFixed(2) + "KB"; + } else if (limit < 1024 * 1024 * 1024) { //濡傛灉灏忎簬0.1GB杞寲鎴怣B + size = (limit / (1024 * 1024)).toFixed(2) + "MB"; + } else if (limit < 1024 * 1024 * 1024 * 1024) { //鍏朵粬杞寲鎴怗B + size = (limit / (1024 * 1024 * 1024)).toFixed(2) + "GB"; + } else { + size = (limit / (1024 * 1024 * 1024 * 1024)).toFixed(2) + "TB"; + } + + var sizestr = size + ""; + var len = sizestr.indexOf("\."); + var dec = sizestr.substr(len + 1, 2); + if (dec == "00") {//褰撳皬鏁扮偣鍚庝负00鏃� 鍘绘帀灏忔暟閮ㄥ垎 + return sizestr.substring(0, len) + sizestr.substr(len + 3, 2); + } + + return sizestr; + } + }, + data() { + return { + activeName: "proc", + activeChartItem: "cpu", + yAxisMaxVal: "100%", + algoProcessData: [], + appProcessData: [], + vasystemServicesData: [], + eChartsObj: {}, + eChartsBaseOpt: { + title: { + top: 10, + }, + animation: false, + grid: { + show: true, + left: '1%', + right: '4%', + bottom: '3%', + containLabel: true, + borderWidth: 2, + borderColor: '#000' + }, + xAxis: { + type: "category", + boundaryGap: false, + data: Array.from({ length: 60 }, () => 0), + // show: false, + axisLabel: { + show: false + }, + axisTick: { + show: false + }, + splitLine: { + show: true, + interval: 5, + lineStyle: { + width: 1, + type: 'solid' + } + } + }, + yAxis: { + type: 'value', + // show: false, + axisLine: { + show: false + }, + axisLabel: { + show: false + }, + axisTick: { + show: false + } + }, + series: [ + { + type: 'line', + symbol: 'none', + data: Array.from({ length: 60 }, () => 0), + // smooth: true, + itemStyle: {}, + areaStyle: {} + } + ] + }, + cpuUtilizations: Array.from({ length: 60 }, () => 0), + memUtilizations: Array.from({ length: 60 }, () => 0), + gpuUtilizations: Array.from({ length: 60 }, () => 0), + diskIOWriteCount: Array.from({ length: 60 }, () => 0), + diskIOReadCount: Array.from({ length: 60 }, () => 0), + netReciveCount: Array.from({ length: 60 }, () => 0), + netSendCount: Array.from({ length: 60 }, () => 0), + cpuModel: "", + cpuUsedPercent: 0, + cpuMaxRate: 0, + cpuCount: 0, + cpuCore: 0, + memTotal: 0, + memUsed: 0, + memFree: 0, + memCache: 0, + memUsedPercent: 0, + netSend: 0, + netRecive: 0, + ipAddr: "", + macAddr: "", + gpuUsedPercent: 0, + disks: {}, + activeDisk: {}, + ioRead: 0, + ioWrite: 0 + }; + }, + mounted() { + this.dataCollection(); + this.initChart(); + }, + methods: { + // 寰幆閲囬泦鎵�鏈夋暟鎹� + dataCollection() { + this.serviceCollect(); + this.procCollect(); + setTimeout(() => { + this.dataCollection(); + }, 5000) + }, + serviceCollect() { + showService().then(rsp => { + if (rsp && rsp.success) { + rsp.data.sort(function (obj1, obj2) { + var val1 = obj1.name + var val2 = obj2.name + if (val1 < val2) { + return -1 + } else if (val1 > val2) { + return 1 + } else { + return 0 + } + }) + this.vasystemServicesData = rsp.data; + } + }).catch(() => { }) + + }, + procCollect() { + showProcesses().then(rsp => { + if (rsp && rsp.success) { + if (rsp.data.algos) + this.algoProcessData = rsp.data.algos; + + if (rsp.data.apps) + this.appProcessData = rsp.data.apps; + } + + }).catch(() => { }) + }, + getSystemState() { + showSystemStates().then(rsp => { + if (rsp && rsp.success) { + // 澶勭悊cpu + this.cpuUtilizations = this.cpuUtilizations.slice(1); + this.cpuUtilizations.push(rsp.data.cpu.toFixed(2)); + this.cpuUsedPercent = this.cpuUtilizations[59]; + if (rsp.data.cpu_info) { + this.cpuMaxRate = (rsp.data.cpu_info[0].mhz / 1024).toFixed(2); + this.cpuModel = rsp.data.cpu_info[0].modelName; + this.cpuCore = Number(rsp.data.cpu_info[rsp.data.cpu_info.length - 1].coreId) + 1; + this.cpuCount = (rsp.data.cpu_info.length / this.cpuCore).toFixed(0); + } + + // 鍐呭瓨 + this.memUtilizations = this.memUtilizations.slice(1); + this.memUtilizations.push(rsp.data.mem.usedPercent.toFixed(2)); + this.memTotal = (rsp.data.mem.total / 1024 / 1024 / 1000).toFixed(0); + this.memUsed = (rsp.data.mem.used / 1024 / 1024 / 1000).toFixed(2); + this.memFree = (rsp.data.mem.free / 1024 / 1024 / 1000).toFixed(2); + this.memCache = ((rsp.data.mem.cached + rsp.data.mem.buffers) / 1024 / 1024 / 1000).toFixed(2); + this.memUsedPercent = rsp.data.mem.usedPercent.toFixed(2); + + // 绠楀姏 + this.gpuUtilizations = this.gpuUtilizations.slice(1); + this.gpuUtilizations.push(rsp.data.gpu.toFixed(2)); + this.gpuUsedPercent = this.gpuUtilizations[59]; + + // 缃戠粶 + this.netReciveCount = this.netReciveCount.slice(1); + this.netReciveCount.push(rsp.data.net.bytesRecv); + this.netSendCount = this.netSendCount.slice(1); + this.netSendCount.push(rsp.data.net.bytesSent); + + this.netRecive = this.netReciveCount[59]; + this.netSend = this.netSendCount[59]; + this.macAddr = rsp.data.net.mac; + if (rsp.data.net.addr.length) { + this.ipAddr = rsp.data.net.addr[0].addr; + } + + // 纾佺洏 + rsp.data.disk.sort(function (obj1, obj2) { + var val1 = obj1.name; + var val2 = obj2.name; + if (val1 < val2) { + return -1; + } else if (val1 > val2) { + return 1; + } else { + return 0; + } + }) + + rsp.data.disk.forEach(d => { + if (d.name in this.disks) { + this.disks[d.name].readBytes = this.disks[d.name].readBytes.slice(1); + this.disks[d.name].readBytes.push(d.readBytes); + this.disks[d.name].writeBytes = this.disks[d.name].writeBytes.slice(1); + this.disks[d.name].writeBytes.push(d.writeBytes); + } else { + this.disks[d.name] = {}; + this.disks[d.name]["info"] = d.info; + this.disks[d.name]["readBytes"] = Array.from({ length: 60 }, () => 0); + this.disks[d.name]["writeBytes"] = Array.from({ length: 60 }, () => 0); + } + }); + + // this.disks = rsp.data.disk; + } + + + this.setChartData(); + setTimeout(() => { + this.getSystemState(); + }, 1000) + }) + }, + isShow(authority) { + if (this.isAdmin) { + return true + } else if ( + this.buttonAuthority.indexOf(',' + authority + ',') > -1 + ) { + return true + } else { + return false + } + }, + format(array) { + return [ + this.$moment(array[0]).format("YYYY-MM-DD"), + this.$moment(array[1]).format("YYYY-MM-DD") + ]; + }, + setActiveChartItem(item) { + this.activeChartItem = item; + this.eChartsObj.clear(); + this.setChartData(); + }, + initChart() { + this.eChartsObj = echarts.init(this.$refs.graphs); + this.getSystemState(); + }, + setChartData() { + let option = JSON.parse(JSON.stringify(this.eChartsBaseOpt)); + switch (this.activeChartItem) { + case 'cpu': + this.yAxisMaxVal = this.cpuModel; + option.title.text = "CPU"; + option.title.subtext = "%鍗犵敤鐜�"; + option.yAxis.max = 100; + option.yAxis.min = 0; + option.grid.borderColor = "#8aadd0"; + option.series[0].itemStyle.color = "#8aadd0"; + option.series[0].areaStyle.color = "#a8d4ff"; + option.series[0].data = this.cpuUtilizations; + + break; + case 'mem': + this.yAxisMaxVal = this.memTotal + "G"; + option.title.text = "鍐呭瓨"; + option.title.subtext = "鍐呭瓨浣跨敤閲�"; + option.yAxis.max = 100; + option.yAxis.min = 0; + option.grid.borderColor = "#ff9900"; + option.series[0].itemStyle.color = "#ff9900"; + option.series[0].areaStyle.color = "#f7bb88"; + option.series[0].data = this.memUtilizations; + break; + case 'gpu': + this.yAxisMaxVal = "100%"; + option.title.text = "绠楀姏"; + option.title.subtext = "%浣跨敤鐜�"; + option.yAxis.max = 100; + option.yAxis.min = 0; + option.grid.borderColor = "#bc84d8"; + option.series[0].itemStyle.color = "#bc84d8"; + option.series[0].areaStyle.color = "#de9dff"; + option.series[0].data = this.gpuUtilizations; + break; + case 'net': + this.yAxisMaxVal = ""; + option.title.text = "缃戠粶"; + option.title.subtext = "缃戠粶璐熻浇"; + option.grid.borderColor = "#4696da"; + option.series[0].itemStyle.color = "#ffa16a"; + option.series[0].areaStyle.color = "#d68658"; + option.series[0].data = this.netReciveCount; + option.series.push({ + type: 'line', + symbol: 'none', + data: this.netSendCount, + // smooth: true, + itemStyle: { + color: "#4696da" + }, + areaStyle: { + color: "#4eacfd" + } + }) + break; + default: + if (this.activeChartItem.indexOf("disk|") == 0) { + let dev = this.activeChartItem.split("|")[1]; + + this.yAxisMaxVal = ""; + option.title.text = "纾佺洏"; + option.title.subtext = "纾佺洏浼犺緭閫熺巼"; + option.grid.borderColor = "#33cc66"; + option.series[0].itemStyle.color = "#4696da"; + option.series[0].areaStyle.color = "#4eacfd"; + option.series[0].data = this.disks[dev].readBytes; + option.series.push({ + type: 'line', + symbol: 'none', + data: this.disks[dev].writeBytes, + // smooth: true, + itemStyle: { + color: "#33ff66" + }, + areaStyle: { + color: "#33cc66" + } + }) + + this.activeDisk = this.disks[dev].info; + this.ioRead = this.disks[dev].readBytes[59]; + this.ioWrite = this.disks[dev].writeBytes[59]; + } + break; + } + + this.eChartsObj.setOption(option); + } + + } +}; +</script> +<style lang="scss"> +.s-system-monitor { + width: 100% !important; + min-width: 759px; + box-sizing: border-box; + padding: 10px; + // background-color: #e9ebf2; + background-color: #fff; + .form-title { + text-align: left; + font-size: 14px; + } + + .graphs-chart { + height: 500px; + width: 900px; + margin-left: 15px; + // border: 1px solid rgb(69, 69, 172); + } + + .column-left { + background-color: #fff; + position: relative; + float: left; + } + + .column-right { + //overflow: hidden; + overflow-y: hidden; + overflow-x: auto; + } + + .max-val { + position: absolute; + right: 4%; + top: 8%; + } + + .resize-bar { + width: 238px; + height: 610px; + } + + /* 鎷栨嫿绾� */ + .resize-line { + position: absolute; + right: 0; + top: 0; + bottom: 0; + border-right: 1px solid #efefef; + border-left: 1px solid #e0e0e0; + pointer-events: none; + } + + .ax_default { + width: 207px; + height: 45px; + padding: 10px; + font-size: 15px; + margin: 5px; + cursor: pointer; + } + + .selected { + background: inherit; + background-color: #cde8ff; + border: none; + border-radius: 8px; + } + + .ax_default_pic { + position: absolute; + border-width: 0px; + width: 66px; + height: 45px; + box-sizing: border-box; + border: 1px solid rgba(255, 153, 0, 1); + background-repeat: no-repeat; + background-position: bottom; + } + + .color-cpu { + border-color: #8aadd0; + background-image: url("/images/systemMonitor/cpu.png"); + } + + .color-mem { + border-color: #ff9900; + background-image: url("/images/systemMonitor/mem.png"); + } + + .color-gpu { + border-color: #bc84d8; + background-image: url("/images/systemMonitor/gpu.png"); + } + + .color-net { + border-color: #4696da; + background-image: url("/images/systemMonitor/net.png"); + } + + .color-disk { + border-color: #33cc66; + background-image: url("/images/systemMonitor/disk.png"); + } + + .ax_default_text { + position: relative; + text-align: left; + margin-left: 72px; + } + + .ax_default_subtext { + font-size: 13px; + margin-left: 72px; + line-height: 35px; + color: #4e4d4d; + text-align: left; + } + + .ax_default_label { + width: 120px; + font-size: 15px; + display: inline-block; + float: left; + + b { + font-family: "鎬濇簮榛戜綋"; + font-weight: 400; + font-style: normal; + color: #a1a1a1; + } + + p { + margin-top: 5px; + } + } + .ax_label_flex { + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + } + .s-system-monitor-breadcrumb { + height: 5%; + box-sizing: border-box; + border: 1px solid #e4e7ed; + box-shadow: #e4e7ed 0px 0px 9px inset; + border-radius: 5px; + } + + .el-tabs--border-card { + border: 0px solid #dcdfe6; + -webkit-box-shadow: none; + box-shadow: none; + .el-tabs__header { + border: 0px solid #dcdfe6; + .el-tabs__item { + padding: 5px 50px; + height: 50px; + font-family: PingFangSC-Regular; + font-size: 15px; + color: #222222; + text-align: center; + border: 0px solid transparent; + } + .el-tabs__item:nth-child(2) { + padding-left: 50px !important; + } + .el-tabs__item:last-child { + padding-right: 50px !important; + } + .el-tabs__item.is-active { + color: #3d68e1; + font-weight: bold; + // border-right-color: #fff; + // border-left-color: #fff; + } + .el-tabs__item:not(.is-disabled):hover { + color: #3d68e1; + } + } + } + + .el-tabs__content { + height: calc(100% - 64px); + width: calc(100% - 20px); + box-sizing: border-box; + overflow-y: auto; + padding: 10px 10px !important; + .el-tab-pane { + width: 100%; + .s-title { + text-align: left; + padding: 15px 0px; + font-size: 16px; + } + } + } + + .s-table { + border: 1px solid #e8e8e9; + margin-top: 40px; + } + + .ui-top-title { + padding-bottom: 10px; + /* border-bottom: 1px solid #ebebeb; */ + position: relative; + text-align: left; + padding-left: 15px; + font-size: 16px; + font-weight: bold; + } + + .ui-top-title:before { + content: " "; + border-left: 4px solid #f53d3d; + display: inline-block; + height: 16px; + position: absolute; + top: 50%; + left: 0; + margin-top: -13px; + } + + .el-button--text { + color: #3d68e1; + text-decoration: underline; + } +} + +#systemMonitor { + .el-tabs__header { + border: 0px solid #dcdfe6; + .el-tabs__item { + padding: 5px 50px; + height: 50px; + font-family: PingFangSC-Regular; + font-size: 14px; + color: #222222; + text-align: center; + border: 0px solid transparent; + } + .el-tabs__item:nth-child(2) { + padding-left: 50px; + } + .el-tabs__item:last-child { + padding-right: 50px; + } + .el-tabs__item.is-active { + color: #ff7733; + font-weight: bold; + // border-right-color: #fff; + // border-left-color: #fff; + } + .el-tabs__item:not(.is-disabled):hover { + color: #ff7733; + } + } + .el-tabs__active-bar { + background-color: #ff7733; + } + .el-tabs__content { + padding-left: 15px !important; + } +} +</style> diff --git a/src/pages/systemMonitor/index/main.ts b/src/pages/systemMonitor/index/main.ts new file mode 100644 index 0000000..b5ea667 --- /dev/null +++ b/src/pages/systemMonitor/index/main.ts @@ -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) +}) \ No newline at end of file diff --git a/src/pages/vindicate/index/App.vue b/src/pages/vindicate/index/App.vue new file mode 100644 index 0000000..7f0e417 --- /dev/null +++ b/src/pages/vindicate/index/App.vue @@ -0,0 +1,617 @@ +<template> + <div class="s-system-manage"> + <el-tabs + id="systemMaintenance" + v-model="activeName" + v-loading="loading" + :element-loading-text="loadingText" + > + <el-tab-pane label="璁惧缁存姢" name="device" v-if="isShow('vindicate:device')"> + <div class="s-system-maintenance"> + <div class="box-card"> + <div class="ui-top-view"> + <div class="ui-top-title">閲嶅惎</div> + </div> + <el-divider></el-divider> + + <div class="box-card-content"> + <el-button type="primary" size="small" style="width:80px" @click="reboot">閲嶅惎</el-button> + + <b class="card-text">閲嶅惎鑺傜偣</b> + + <el-row style="margin-top:20px"> + <el-col> + <vue-cron :expression="rebootCron" @update="setRebootCron" /> + </el-col> + </el-row> + </div> + </div> + <!-- + <div class="box-card"> + <div class="ui-top-view"> + <div class="ui-top-title">鎭㈠榛樿鍊�</div> + </div> + <el-divider></el-divider> + + <div class="box-card-content"> + <el-row> + <el-col :span="1"> + <el-button type="primary" size="small">绠�鍗曟仮澶�</el-button> + </el-col> + <el-col :span="23"> + <b class="card-text">绠�鍗曟仮澶嶈澶囧弬鏁�</b> + </el-col> + </el-row> + <el-row style="margin-top:20px"> + <el-col :span="1"> + <el-button type="primary" size="small">瀹屽叏鎭㈠</el-button> + </el-col> + <el-col :span="23"> + <b class="card-text">瀹屽叏鎭㈠璁惧鍙傛暟鍒板嚭鍘傝缃�</b> + </el-col> + </el-row> + </div> + </div> + + <div class="box-card"> + <div class="ui-top-view"> + <div class="ui-top-title">鍙傛暟瀵煎叆瀵煎嚭</div> + </div> + <el-divider></el-divider> + + <div class="box-card-content"> + <el-row :gutter="4"> + <el-col :span="1"> + <el-button type="info" size="small" style="width:80px">瀵煎叆</el-button> + </el-col> + <el-col :span="3" style="padding-left:30px"> + <el-input placeholder="涓婁紶鍙傛暟鏂囦欢" size="small" :readonly="true"> + <el-upload slot="suffix" action="https://jsonplaceholder.typicode.com/posts/"> + <el-button + type="text" + icon="el-icon-upload2" + size="small" + style="font-size:18px; color:#0088ff" + ></el-button> + </el-upload> + </el-input> + </el-col> + </el-row> + <el-row style="margin-top:20px"> + <el-col :span="1"> + <el-button type="primary" size="small">璁惧鍙傛暟</el-button> + </el-col> + <el-col :span="23"> + <b class="card-text">鍙傛暟瀵煎嚭</b> + </el-col> + </el-row> + </div> + </div> + --> + <div class="box-card"> + <div class="ui-top-view"> + <div class="ui-top-title">鍗囩骇</div> + </div> + </div> + <el-divider></el-divider> + <div class="box-card-content"> + <el-row :gutter="4"> + <el-col :span="12"> + <file-uploader + single + uploadPlaceholder="涓婁紶鍗囩骇鏂囦欢" + url="/data/api-v/sysset/patchUpdate" + @complete="onFileUpload" + @file-added="onFileAdded" + /> + </el-col> + <el-col :span="2"> + <el-button + type="primary" + size="small" + style="width:80px" + @click="upgrade" + :disabled="!fileAdded" + :loading="upgrading" + >鍗囩骇</el-button> + </el-col> + <el-col :span="16" class="upload-msg"> + <span v-html="patchUpdateStatus"></span> + </el-col> + </el-row> + </div> + </div> + </el-tab-pane> + <el-tab-pane label="鏁版嵁搴撶淮鎶�" name="dbvdc" v-if="isShow('vindicate:db')"> + <div class="box"> + <p class="title"> + <label>鏁版嵁娓呯悊</label> + </p> + <div class="range"> + <div class="left"> + <p>閫夋嫨鏁版嵁鑼冨洿锛�</p> + </div> + <div class="middle"> + <el-date-picker + v-model="dataRange" + type="daterange" + range-separator="鑷�" + start-placeholder="寮�濮嬫棩鏈�" + end-placeholder="缁撴潫鏃ユ湡" + style="height:38px" + :picker-options="pickerOptions" + ></el-date-picker> + </div> + <div class="right"> + <el-button @click="deleteData" style="height:38px;background:#ff0000;color:white">鍒犻櫎鏁版嵁</el-button> + </div> + </div> + <div class="tip"> + <i class="iconfont icontishi-zhuyi"></i> + <p class="zhuyi">璇锋敞鎰忥紝鎸変互涓婃棩鏈熻寖鍥村垹闄ょ殑鏁版嵁涓嶅彲鎭㈠锛岀珛鍗崇敓鏁堬紝璇疯皑鎱庢搷浣�</p> + </div> + </div> + </el-tab-pane> + </el-tabs> + </div> +</template> + +<script> +import { rebootServer, getDevInfo, getRebootTask, setRebootTask, fileUpload, doUpgrade, deleteDate } from "@/api/system" +import VueCron from "@/components/subComponents/VueCron" +import FileUploader from "@/components/subComponents/FileUpload/index" + +export default { + components: { + VueCron, + FileUploader + }, + data() { + return { + timer: null, + buttonAuthority: sessionStorage.getItem("buttonAuthoritys") || [], + rebootCron: "", + activeName: "device", + restartValue: "涓嶉噸鍚�", + restartTimeValue: new Date(2019, 9, 10, 18, 40), + loading: false, + loadingText: '', + probeSum: 0, + patchUpdateStatus: "", + dataRange: [ + this.$moment().format("YYYY-MM-DD HH:mm:ss"), + this.$moment().format("YYYY-MM-DD HH:mm:ss") + ], + fileUploadUrl: fileUpload, + patchFile: {}, + pickerOptions: { + disabledDate(time) { + var day = new Date() + day.setTime(day.getTime() - 24 * 60 * 60 * 1000) + return time.getTime() > day; + }, + }, + upgrading: false, + fileAdded: false, + }; + }, + mounted() { + this.getRebootCron() + if (!this.isShow('vindicate:device')) { + this.activeName = "dbvdc" + } + }, + computed: { + isAdmin() { + if ( + sessionStorage.getItem('userInfo') && + sessionStorage.getItem('userInfo') !== '' + ) { + let loginName = JSON.parse(sessionStorage.getItem('userInfo')).username + return ( + loginName === 'superadmin' || loginName === 'basic' + ) + } + return false; + } + }, + methods: { + isShow(authority) { + if (this.isAdmin) { + return true + } else if ( + this.buttonAuthority.indexOf(',' + authority + ',') > -1 + ) { + return true + } else { + return false + } + }, + format(array) { + return [ + this.$moment(array[0]).format("YYYY-MM-DD"), + this.$moment(array[1]).format("YYYY-MM-DD") + ]; + }, + getRebootCron() { + getRebootTask().then(rsp => { + this.rebootCron = rsp.data + }) + }, + setRebootCron(value) { + this.rebootCron = value + setRebootTask({ task: value }).then(rsp => { + if (rsp && rsp.success) { + this.$notify({ + type: "success", + message: "閰嶇疆鎴愬姛" + }) + } + }).catch(err => { + this.$notify({ + type: "error", + message: "閰嶇疆澶辫触" + }) + }) + }, + reboot() { + this.$confirm('纭畾瑕侀噸鍚鑺傜偣鍚�?', { + center: true, + cancelButtonClass: 'comfirm-class-cancle', + confirmButtonClass: 'comfirm-class-sure' + }).then(() => { + this.loading = true; + this.loadingText = "鏅鸿兘璁$畻鑺傜偣姝e湪閲嶅惎锛岃鑰愬績绛夊緟..." + 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) + } + }) + }) + }, + deleteData() { + var timeRange = this.format(this.dataRange); + var showStartTime = timeRange[0] + var showEndTime = timeRange[1] + console.log("鏃堕棿锛�", showStartTime, showEndTime) + this.$confirm("鎻愮ず锛�" + showStartTime + " 鑷� " + showEndTime + " 浜х敓鐨勫叏閮ㄦ暟鎹皢琚垹闄わ紝姝ゆ搷浣滅珛鍗崇敓鏁堬紝涓嶅彲鎭㈠锛屾槸鍚﹀垹闄わ紵", { + center: true, + cancelButtonClass: "comfirm-class-cancle", + confirmButtonClass: "comfirm-class-sure" + }).then(() => { + this.loading = true + this.loadingText = "姝e湪鍒犻櫎鏁版嵁锛岃绋嶅�欙紒" + var param = { + startTime: showStartTime, + endTime: showEndTime + } + deleteDate(param).then(resp => { + if (resp.success) { + this.$message({ + type: "success", + message: "鍒犻櫎鏁版嵁鎴愬姛" + }) + this.loading = false + } + }).catch(err => { + this.$message({ + type: "error", + message: "鍒犻櫎鏁版嵁澶辫触锛�" + }) + this.loading = false + }) + + }).catch(() => { + console.log("鍙栨秷浜嗭紒") + }) + }, + reLogin() { + this.$router.push("/") + }, + probeServer(callback) { + this.probeSum++; + let _this = this + if (this.probeSum > 60) { + this.$confirm('杩炴帴鏈嶅姟鍣ㄥけ璐�, 璇峰埛鏂伴〉闈㈡垨鑱旂郴绠$悊鍛�', '澶辫触', { + type: 'error', + cancelButtonClass: 'comfirm-class-cancle', + confirmButtonClass: 'comfirm-class-sure' + }).then(() => { + // _this.$router.push("/") + callback() + }) + return + } + + this.timer = setTimeout(() => { + getDevInfo().then(() => { + // _this.$router.push("/") + callback() + }).catch(err => { + _this.probeServer(callback) + }) + }, 10000) + }, + 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">姝e湪鍗囩骇...</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() + }) + } + } +}; +</script> +<style lang="scss"> +.s-system-manage { + width: 100% !important; + min-width: 759px; + box-sizing: border-box; + padding: 10px; + // background-color: #e9ebf2; + background-color: #fff; + .s-system-manage-breadcrumb { + height: 5%; + box-sizing: border-box; + border: 1px solid #e4e7ed; + box-shadow: #e4e7ed 0px 0px 9px inset; + box-shadow: #e4e7ed 0px 0px 9px inset; + border-radius: 5px; + } + + .el-tabs--border-card { + border: 0px solid #dcdfe6; + -webkit-box-shadow: none; + box-shadow: none; + .el-tabs__header { + border: 0px solid #dcdfe6; + .el-tabs__item { + padding: 5px 50px; + height: 50px; + font-family: PingFangSC-Regular; + font-size: 15px; + color: #222222; + text-align: center; + border: 0px solid transparent; + } + .el-tabs__item:nth-child(2) { + padding-left: 50px !important; + } + .el-tabs__item:last-child { + padding-right: 50px !important; + } + .el-tabs__item.is-active { + color: #3d68e1; + font-weight: bold; + // border-right-color: #fff; + // border-left-color: #fff; + } + .el-tabs__item:not(.is-disabled):hover { + color: #3d68e1; + } + } + } + .el-tabs__content { + height: calc(100% - 64px); + width: calc(100% - 20px); + box-sizing: border-box; + overflow-y: auto; + padding: 10px 40px !important; + .el-tab-pane { + width: 100%; + .s-title { + text-align: left; + padding: 15px 0px; + font-size: 16px; + } + } + } + + .s-table { + border: 1px solid #e8e8e9; + margin-top: 40px; + } + + .ui-top-title { + padding-bottom: 10px; + /* border-bottom: 1px solid #ebebeb; */ + position: relative; + text-align: left; + padding-left: 15px; + font-size: 16px; + font-weight: bold; + } + + .ui-top-title:before { + content: " "; + border-left: 4px solid #f53d3d; + display: inline-block; + height: 16px; + position: absolute; + top: 50%; + left: 0; + margin-top: -13px; + } + + .el-button--text { + color: #3d68e1; + text-decoration: underline; + } +} +.s-system-maintenance { + width: 100%; + height: 100%; + .el-button--primary { + color: #ffffff; + background-color: #3d68e1; + border-color: #3d68e1; + } + .el-button--primary.is-disabled, + .el-button--primary.is-disabled:hover, + .el-button--primary.is-disabled:focus, + .el-button--primary.is-disabled:active { + color: #ffffff; + background-color: #9eb4f0; + border-color: #9eb4f0; + } + .box-card { + text-align: left; + height: auto; + margin: 10px 0px; + .box-card-content { + padding-bottom: 40px; + .card-text { + padding: 0 30px; + line-height: 32px; + } + } + } + + .upload-icon { + font-size: 18px; + color: #0088ff; + } + .upload-msg { + padding-left: 10px; + text-align: left; + span { + line-height: 32px; + font-size: 13px; + } + } +} +.box { + width: 50%; + min-width: 700px; + height: 270px; + border: 1px solid #eee; + .title { + font-size: 20px; + font-weight: bold; + text-align: left; + padding: 20px; + border-bottom: 1px solid #eee; + } + .range { + width: 100%; + padding-top: 30px; + height: 38px; + .left { + width: 120px; + float: left; + text-align: right; + font-size: 14px; + p { + height: 38px; + line-height: 38px; + margin: 0; + } + } + .middle { + width: 50%; + min-width: 400px; + height: 38px; + float: left; + } + .right { + width: 20%; + height: 38px; + float: left; + } + } + .tip { + width: 100%; + padding: 30px 0px 0px 30px; + height: 34px; + + .zhuyi { + font-size: 14px; + height: 34px; + line-height: 34px; + margin-left: 20px; + float: left; + } + i { + font-size: 32px; + color: #e99038; + float: left; + } + } +} +#systemMaintenance { + .el-tabs__header { + border: 0px solid #dcdfe6; + .el-tabs__item { + padding: 5px 50px; + height: 50px; + font-family: PingFangSC-Regular; + font-size: 14px; + color: #222222; + text-align: center; + border: 0px solid transparent; + } + .el-tabs__item:nth-child(2) { + padding-left: 50px; + } + .el-tabs__item:last-child { + padding-right: 50px; + } + .el-tabs__item.is-active { + color: #ff7733; + font-weight: bold; + // border-right-color: #fff; + // border-left-color: #fff; + } + .el-tabs__item:not(.is-disabled):hover { + color: #ff7733; + } + } + .el-tabs__active-bar { + background-color: #ff7733; + } + .el-tabs__content { + padding-left: 15px !important; + } +} +</style> diff --git a/src/pages/vindicate/index/main.ts b/src/pages/vindicate/index/main.ts new file mode 100644 index 0000000..b5ea667 --- /dev/null +++ b/src/pages/vindicate/index/main.ts @@ -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) +}) \ No newline at end of file -- Gitblit v1.8.0