From 577edb4400290865acb07f8342f7ee0c1055aa70 Mon Sep 17 00:00:00 2001 From: zhangzengfei <zhangzengfei@iotlink.com> Date: 星期三, 29 七月 2020 10:39:56 +0800 Subject: [PATCH] appp:添加算力管理 --- src/pages/analysisPower/index/mixins.ts | 13 src/components/subComponents/SystemInfo.vue | 204 ++++++++++++ package.json | 6 src/pages/analysisPower/index/main.ts | 20 + src/pages/desktop/index/mock/userData.json | 54 +- src/pages/analysisPower/index/App.vue | 608 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 876 insertions(+), 29 deletions(-) diff --git a/package.json b/package.json index d3e822c..793a32b 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "@hscmap/vue-window": "^2.4.2", "axios": "^0.19.2", "d3-force": "^2.0.1", - "element-ui": "^2.4.6", + "echarts": "^4.8.0", + "element-ui": "^2.13.2", "less-loader": "^6.2.0", "pug": "^3.0.0", "pug-plain-loader": "^1.0.0", @@ -22,6 +23,7 @@ "stylus-loader": "^3.0.2", "vue": "^2.6.11", "vue-awesome-swiper": "^3.1.3", + "vue-js-toggle-button": "^1.3.3", "vue-qrcode-component": "^2.1.1", "vuex": "^3.5.1" }, @@ -75,4 +77,4 @@ "keywords": [], "author": "", "license": "ISC" -} +} \ No newline at end of file diff --git a/src/components/subComponents/SystemInfo.vue b/src/components/subComponents/SystemInfo.vue new file mode 100644 index 0000000..5dd0915 --- /dev/null +++ b/src/components/subComponents/SystemInfo.vue @@ -0,0 +1,204 @@ +<template> + <div :class="showClass"> + <div class="card-box" :style="`width:${borderWidth}`"> + <ul> + <li style="max-width:30px;" v-if="ShowLocalVedio"> + <div class="total-box"> + <div style="width:100%;margin-top:28px;"> + <div class="top-text"> + <em>{{"鎬荤畻鍔�"}}</em> + </div> + <div class="mid-text"> + <em>{{` ${PollData.channelTotal}`}}</em> + </div> + </div> + </div> + </li> + <li style="max-width:120px" v-if="showRealPoll"> + <DataStackCard + style="width:95%" + title="瀹炴椂绠楀姏" + fourTip="鏁呴殰瀵艰嚧鏈鐞�" + fourIcon="iconicon-test21" + :total="`${PollData.RealTimeValidCount}璺痐" + :ValidCount="`${PollData.RealTimeSum}璺痐" + :InValidCount="`${PollData.RealTimeInvalid}璺痐" + :RunningCount="`${PollData.RealTimeRun}璺痐" + :NoDeal="`${PollData.RealTimeNoDeal}璺痐" + /> + </li> + <li style="max-width:120px" v-if="showRealPoll"> + <DataStackCard + title="杞绠楀姏" + fourTip="绛夊緟杞澶勭悊" + fourIcon="iconicon-test2" + style="width:95%" + :total="`${PollData.PollValidCount}璺痐" + :ValidCount="`${PollData.PollSum}璺痐" + :InValidCount="`${PollData.PollInvalid}璺痐" + :RunningCount="`${PollData.PollRun}璺痐" + :NoDeal="`${PollData.PollNoDeal}璺痐" + /> + </li> + <li style="max-width:120px" v-if="ShowLocalVedio"> + <!-- <local-vedio-card + title="鏈湴绠楀姏" + style="width:95%" + :total="`${PollData.localVideo}閫氶亾`" + :success="`${PollData.PollRun}璺痐" + :warning="`${PollData.PollInvalid}璺痐" + />--> + <DataStackCard + title="鏁版嵁鏍堢畻鍔�" + style="width:95%" + fourTip="鏈煡鍘熷洜瀵艰嚧鏈鐞�" + fourIcon="iconicon-test5" + :total="`${PollData.stackChannelCount}璺痐" + :ValidCount="`${PollData.stackTotal}璺痐" + :InValidCount="`${PollData.stackInvalidCount}璺痐" + :RunningCount="`${PollData.stackRunningCount}璺痐" + :NoDeal="`${PollData.stackNoDeal}璺痐" + ></DataStackCard> + </li> + </ul> + </div> + <!-- <div :class="marginTop" :style="`width:${liquidWidth};`"> + <ul> + <li> + <liquid-fill-chart title="鍐呭瓨" :value="PollData.MemUsedPercent" :size="75" /> + </li> + <li> + <liquid-fill-chart title="绠楀姏" :value="PollData.GpuUsedPercent" :size="75" /> + </li> + <li> + <liquid-fill-chart title="CPU" :value="PollData.CpuUsedPercent" :size="75" /> + </li> + </ul> + </div>--> + <div class="eCharts-box" :style="`width:${liquidWidth}`"> + <eChartsBar ref="cpuMeneryCharts" :xAxisData="PollData.barCharts"></eChartsBar> + </div> + </div> +</template> + +<script> +import DataStackCard from "@/components/subComponents/DataStackCard" +import eChartsBar from '@/components/subComponents/eChartsBar' + +export default { + name: "SystemInfo", + components: { + DataStackCard, + eChartsBar, + }, + props: { + showTask: { + type: Boolean, + default: false + }, + showClass: { + type: String, + default: 'sysinfo-box flex-box' + }, + ShowLocalVedio: { + type: Boolean, + default: false + }, + showRealPoll: { + type: Boolean, + default: true + }, + marginTop: { + type: String, + default: 'ma' + }, + borderWidth: { + type: String, + default: '70%' + }, + liquidWidth: { + type: String, + default: '30%' + } + }, + methods: { + initCpuCharts() { + this.$forceUpdate(); + } + }, +} +</script> +<style lang="scss"> +.sysinfo-box { + height: 100%; + .card-box { + width: 50%; + @media screen and (min-width: 1280px) and (max-width: 1440px) { + width: 65%; + } + @media screen and (max-width: 1279px) { + width: 70%; + } + .total-box { + height: 120px; + width: 100%; + display: inline-block; + margin: 10px 5px; + background: #ffffff; + border: 1px solid #e2e2e2; + box-shadow: 0 5px 12px 0 rgba(0, 0, 0, 0.07); + border-radius: 4px; + cursor: pointer; + .top-text { + line-height: 30px; + font-family: PingFangSC-Medium; + font-size: 14px; + color: #222222; + } + .mid-text { + margin-bottom: 18px; + font-family: PingFangSC-Medium; + font-size: 18px; + color: #ff7733; + } + .bottom-text { + position: relative; + top: 3px; + left: 1px; + color: #666666; + font-size: 13px; + } + em { + font-weight: 700; + } + } + } + .eCharts-box { + width: 50%; + height: 100%; + margin-left: 5px; + @media screen and (min-width: 1280px) and (max-width: 1440px) { + width: 35%; + } + @media screen and (max-width: 1279px) { + width: 30%; + } + } + .chart-box { + float: left; + width: 50%; + margin-top: 20px; + margin-left: 20px; + } + ul { + list-style: none; + display: table; + width: 100%; + li { + display: table-cell; + text-align: center; + vertical-align: top; + } + } +} +</style> \ No newline at end of file diff --git a/src/pages/analysisPower/index/App.vue b/src/pages/analysisPower/index/App.vue new file mode 100644 index 0000000..ed19b56 --- /dev/null +++ b/src/pages/analysisPower/index/App.vue @@ -0,0 +1,608 @@ +<template> + <div class="s-poll-setting"> + <div class="top" v-show="!strethTable"> + <div class="percentBall"> + <sysinfo + ref="sysInfo" + v-if="showSysInfo" + :ShowLocalVedio="true" + showTask + showClass="sysinfo-box flex-row-left" + /> + </div> + + <div class="barGraph"> + <div id="barSimple"></div> + </div> + </div> + + <div class="bottom"> + <div style="width: 100%;height: 10px;background-color: #E9EBF2;"></div> + <div class="content"> + <div class="toolBar"> + <el-input + size="small" + style="width: 180px;" + placeholder="璇疯緭鍏ユ悳绱㈠唴瀹�" + prefix-icon="el-icon-search" + clearable + v-model="PollData.SearchName" + ></el-input> + <el-button + size="small" + type="primary" + style="margin-left: 20px; margin-right: 50px;" + @click="pollSeach" + >鎼滅储</el-button> + <div class="tip"> + <span> + 杞鏃堕棿 : + <b>{{PollData.Config.poll_period}}</b>鍒嗛挓 + </span> + <span> + 杞鍛ㄦ湡 : + <b>{{pollCycle}}</b>鍒嗛挓 + </span> + <span> + 杞寮�鍏� : + <b>{{PollData.Enabled | switchText}}</b> + </span> + </div> + <span :class="stretchStyle" @click="strethTable = !strethTable"></span> + + <el-button size="small" type="primary" style="float:right" @click="openDrawer">璁剧疆</el-button> + </div> + + <el-table + :header-cell-style="{background:'#F8F8F8', color: '#222222'}" + :data="PollData.CameraList" + height="93%" + border + > + <el-table-column label="搴忓彿" type="index" align="center" width="100px"></el-table-column> + <el-table-column label="鎽勫儚鏈哄悕绉�" align="center" show-overflow-tooltip sortable> + <template slot-scope="scope"> + <span + :style="scope.row.is_running ? `color:#3d68e1` : '' " + >{{scope.row.alias !== '' ? scope.row.alias: scope.row.name}}</span> + </template> + </el-table-column> + <el-table-column label="鎽勫儚鏈哄湴鍧�" prop="addr" align="center" show-overflow-tooltip sortable></el-table-column> + <el-table-column label="鎽勫儚鏈篒P" prop="ip" align="center" width="130px" sortable></el-table-column> + <el-table-column label="鎽勫儚鏈虹被鍨�" align="center" width="110px" sortable> + <template slot-scope="scope"> + <span>{{scope.row.run_type | cameraType}}</span> + </template> + </el-table-column> + <el-table-column label="鎵ц绠楁硶" align="center" show-overflow-tooltip sortable> + <template slot-scope="scope"> + <span v-if="scope.row.run_type === -1 ">-</span> + <span v-else>{{scope.row.tasks | taskList}}</span> + </template> + </el-table-column> + <el-table-column label="杩愯璁惧" align="center" width="160px"> + <template slot-scope="scope"> + <span v-if="scope.row.run_type === -1 ">-</span> + <span v-else>{{scope.row.runServerName}}</span> + </template> + </el-table-column> + <el-table-column label="鐘舵��" align="center" show-overflow-tooltip sortable width="100px"> + <template slot-scope="scope"> + <span v-if="scope.row.status === -1 ">-</span> + <span v-else-if="scope.row.status === 2">{{"澶勭悊涓�"}}</span> + <span v-else-if="scope.row.status === 1">{{"绛夊緟澶勭悊"}}</span> + <span v-else-if="scope.row.status === 0">{{"瑙勫垯涓嶅叏"}}</span> + </template> + </el-table-column> + <el-table-column label="瀹炴椂/杞" align="center" width="100px"> + <template slot-scope="scope"> + <span v-if="scope.row.run_type === -1 ">-</span> + <toggle-button + v-else + :value="scope.row.run_type === 1" + :width="60" + :labels="{checked: '瀹炴椂', unchecked: '杞'}" + :color="{checked: '#4D88FF', unchecked: '#FF7733', disabled: '#CCCCCC'}" + :sync="true" + @change="pollSwitch(scope.row)" + /> + </template> + </el-table-column> + </el-table> + </div> + </div> + + <!-- 璁剧疆寮圭獥 --> + <el-drawer + title="绠楀姏璁剧疆" + :visible.sync="drawer" + direction="rtl" + size="350px" + custom-class="e-drawer" + :before-close="closeDrawer" + > + <div class="dawer_details"> + <span>鎬荤畻鍔� {{formData.totalChanle}} 閫氶亾</span> + <span style="margin-left:20px">瀹炴椂绠楀姏 {{formData.realTime}} 閫氶亾</span> + </div> + <div class="e-drawer_rate"> + <div class="rate"> + <label>杞鏃堕棿</label> + <el-input-number + size="small" + style="width: 60px;margin-left:25px" + v-model.number="formData.pollPeriod" + :controls="false" + :min="0" + :max="60 * 24 * 1" + ></el-input-number> + <span>鍒嗛挓</span> + + <label>杞寮�鍏�</label> + <el-switch style="margin-left: 10px;" v-model="formData.pollEnable"></el-switch> + </div> + <div class="rate"> + <label>杞绠楀姏</label> + <el-input-number + style="margin-left:25px;width:90px" + size="small" + v-model="formData.polling" + @change="changePoll" + controls-position="right" + :min="0" + :max="maxPoll" + ></el-input-number> + </div> + <div class="rate"> + <label>鏁版嵁鏍堢畻鍔�</label> + <el-input-number + style="margin-left:11px;width:90px" + size="small" + v-model="formData.dataStack" + @change="changeStack" + controls-position="right" + :min="0" + :max="maxDataStack" + ></el-input-number> + </div> + + <el-button + size="small" + type="primary" + style="margin:10px 10px 0px 200px" + @click="saveSetting" + >淇濆瓨</el-button> + <el-button size="small" type="info" style="color:black" @click="closeDrawer">鍙栨秷</el-button> + </div> + </el-drawer> + </div> +</template> + +<script> +import echarts from "echarts"; +import { changeRunType, updatePollEnable, updatePollPeriod, updateChannelCount } from "@/api/pollConfig"; + +import Sysinfo from "@/components/subComponents/SystemInfo" +// import SliderVedio from '@/components/camera/slider-vedio' +// import eChartsBar from '@/components/subComponents/eChartsBar' +export default { + name: "PollSeting", + components: { + Sysinfo, + // SliderVedio, + // eChartsBar + }, + filters: { + cameraType(type) { + return type === -1 ? "鐩戞帶鎽勫儚鏈�" : "AI鎽勫儚鏈�"; + }, + taskList(tasks) { + return tasks.filter(task => { + return task.hasRule; + }).map(task => { + return task.taskname + }).join(',') + }, + switchText(type) { + return type ? "宸插紑鍚�" : "鏈紑鍚�"; + } + }, + computed: { + maxPoll() { + return this.formData.totalChanle - this.formData.realTime; + }, + maxDataStack() { + return this.formData.totalChanle - this.formData.realTime; + }, + stretchStyle() { + let arry = ["iconfont", "stretch-btn"]; + arry.push(this.strethTable ? "iconzhankai" : "iconshouqi") + return arry; + }, + pollCycle() { + let sumPollingCamera = 0; + this.PollData.CameraList.forEach(cam => { + if (cam.run_type === 0) { + sumPollingCamera++ + } + }) + + return sumPollingCamera * this.PollData.Config.poll_period + } + }, + data() { + return { + switchValue: true, + search: "", + timeout: null, + taskName: [], + dataList: [], + barChart: {}, + localDataChannel: 2, + showSysInfo: false, + drawer: false, + formData: {}, + strethTable: false + }; + }, + mounted() { + this.PollData.init(); + this.statistic(); + this.barChart = echarts.init(document.getElementById("barSimple")); + this.initLineChart(); + }, + beforeDestroy() { + clearTimeout(this.timeout); + }, + methods: { + openDrawer() { + this.initFormData(); + this.drawer = true; + }, + closeDrawer() { + this.drawer = false; + this.initFormData(); + }, + initFormData() { + this.formData = { + totalChanle: this.PollData.channelTotal, + realTime: this.PollData.RealTimeSum, + pollEnable: this.PollData.Enabled, + pollPeriod: this.PollData.Config.poll_period, + polling: this.PollData.PollChannelTotal, + dataStack: this.PollData.localVideo, + } + }, + pollSeach() { + this.PollData.fetchPollList(); + }, + pollEnable() { + updatePollEnable({ enable: this.PollData.Enabled }).then(rsp => { + this.$notify({ + type: "success", + message: "淇敼鎴愬姛" + }); + // this.PollData.fetchPollConfig() + }) + }, + updateDelayTime() { + updatePollPeriod({ period: this.PollData.Config.poll_period }).then(rsp => { + if (rsp && rsp.success) { + this.$notify({ + type: 'success', + message: '杞鏃堕棿淇敼鎴愬姛锛�' + }) + } else { + this.$notify({ + type: 'error', + message: '杞鏃堕棿淇敼澶辫触锛�' + }) + } + }) + }, + statistic() { + this.PollData.statistics(); + let _this = this; + _this.timeout = setTimeout(() => { + _this.statistic(); + }, 10 * 1000); + }, + pollSwitch(row) { + changeRunType({ camera_ids: [row.id], run_type: row.run_type ^ 1 }).then( + rsp => { + if (rsp && rsp.success) { + this.$notify({ + type: "success", + message: "閰嶇疆鎴愬姛" + }); + + row.run_type = row.run_type ^ 1 + + } else { + this.$notify({ + type: "error", + message: "閰嶇疆澶辫触" + }); + } + + // this.PollData.fetchPollList(); + } + ); + }, + initLineChart() { + // console.log(this.barChart,'initLineChart') + // this.$refs.sysInfo.initCpuCharts(); + let optionBar = { + color: ["#3D68E1"], + tooltip: { + trigger: "axis", + axisPointer: { + // 鍧愭爣杞存寚绀哄櫒锛屽潗鏍囪酱瑙﹀彂鏈夋晥 + type: "shadow" // 榛樿涓虹洿绾匡紝鍙�変负锛�'line' | 'shadow' + } + }, + grid: { + top: 40, + // bottom: '45%', + left: 0, + containLabel: true + }, + + xAxis: [ + { + type: "category", + data: this.taskName, + axisTick: { + // alignWithLabel: true + }, + axisLine: { + show: false + }, + nameLocation: 'start', + axisTick: { + show: false + }, + axisLabel: { + rotate: 45, + formatter: function (value, index) { + let name = "" + if (value.length > 2) { + name = value.substring(0, 2) + '...' + } else { + name = value + } + let text = [`{a|${name}}`] + return text + }, + rich: { + a: { + fontSize: 10, + with: 30 + } + } + } + } + ], + yAxis: [ + { + type: "value", + show: true, + axisLine: { + show: false + }, + splitLine: { + lineStyle: { + type: "dotted", + color: ['#f1f1f1'] + } + }, + axisTick: { + show: false + } + } + ], + series: [ + { + name: "鏁伴噺", + type: "bar", + barWidth: "30%", + data: this.dataList + } + ] + }; + this.showSysInfo = true + this.barChart.setOption(optionBar); + this.barChart.resize() + this.$nextTick(() => { + this.barChart.resize() + }) + }, + + //婊戝潡鏁版嵁鏇存柊鍥炶皟 + changeSlider(val) { + // console.log(val, '婊戝潡鍊煎彉鍔�') + let fileChannelCount = val[val.length - 1] - val[val.length - 2] + let pollChannelCount = val[val.length - 2] - val[val.length - 3] + this.PollData.updateChannelCount(fileChannelCount, pollChannelCount) + }, + + async saveSetting() { + let rsp = await updatePollEnable({ enable: this.formData.pollEnable }) + if (!rsp || !rsp.success) { + this.formData.pollEnable = !this.formData.pollEnable + this.$notify({ + type: "error", + message: "杞寮�鍏冲垏鎹㈠け璐ワ紒" + }); + return + } + + rsp = await updatePollPeriod({ period: this.formData.pollPeriod }) + if (!rsp || !rsp.success) { + this.$notify({ + type: "error", + message: "杞鏃堕棿淇敼澶辫触锛�" + }); + return + } + rsp = await updateChannelCount({ videoChannelCount: this.formData.dataStack, pollChannelCount: this.formData.polling }) + if (!rsp || !rsp.success) { + this.$notify({ + type: "error", + message: "绠楀姏閰嶇疆澶辫触锛�" + }); + return + } else { + this.$notify({ + type: "success", + message: "閰嶇疆淇濆瓨鎴愬姛" + }); + } + this.PollData.statisticTaskInfo() + this.PollData.fetchPollConfig() + }, + + //鐩戝惉杞绠楀姏 + changePoll(newVal, oldVal) { + if (newVal > oldVal) { + this.formData.dataStack-- + } + if (newVal < oldVal) { + this.formData.dataStack++ + } + // console.log("this.formData.dataStack:"+this.formData.dataStack) + }, + //鐩戝惉鏁版嵁鏍堢畻鍔� + changeStack(newVal, oldVal) { + if (newVal > oldVal) { + this.formData.polling-- + } + if (newVal < oldVal) { + this.formData.polling++ + } + // console.log("this.formData.polling:"+this.formData.polling) + } + } +}; +</script> +<style lang="scss"> +.s-poll-setting { + width: 100%; + height: 100%; + font-size: 14px; + position: relative; + .top { + width: 100%; + height: 190px; + // border-bottom: 1px solid #ccc; + .progressBar { + width: 26%; + } + .percentBall { + width: 80%; + height: 82%; + float: left; + // @media screen and (min-width: 1280px) and (max-width: 1440px) { + // width: 75%; + // } + // @media screen and (max-width: 1280px) { + // width: 80%; + // } + } + .barGraph { + width: 20%; + height: 100%; + float: right; + // @media screen and (min-width: 1280px) and (max-width: 1440px) { + // width: 25%; + // } + // @media screen and (max-width: 1280px) { + // width: 20%; + // } + #barSimple { + width: 100%; + height: 250px; + margin-top: -30px; + } + } + .point { + text-align: right; + margin-left: 64px; + b { + display: inline-block; + width: 9px; + height: 9px; + border-radius: 50%; + background-color: #f53d3d; + } + } + } + .bottom { + width: calc(100% + 76px); + height: 100%; + // height: calc(100% - 220px); + position: absolute; + // top: 220px; + left: -38px; + .tip { + display: inline-block; + font-family: PingFangSC-Medium; + font-size: 14px; + span { + margin: 0px 10px; + } + } + .content { + padding: 20px 38px 38px 38px; + box-sizing: border-box; + width: 100%; + height: 100%; + .toolBar { + width: 100%; + height: 42px; + text-align: left; + margin-bottom: 15px; + } + .el-table { + border: 1px solid #e0e0e0; + } + } + + .stretch-btn { + float: right; + margin-left: 10px; + line-height: 35px; + cursor: pointer; + } + } +} + +.e-drawer { + // margin-top: 150px; + + font-family: PingFangSC-Medium; + font-size: 14px; + .dawer_details { + text-align: left; + margin-left: 70px; + margin-top: 30px; + } + .e-drawer_rate { + width: 100%; + margin-top: 15px; + .rate { + width: 100%; + text-align: left; + margin-top: 15px; + margin-left: 50px; + } + label { + margin-left: 20px; + } + } + + .el-drawer__header { + margin-bottom: 0px; + } +} +</style> diff --git a/src/pages/analysisPower/index/main.ts b/src/pages/analysisPower/index/main.ts new file mode 100644 index 0000000..fdbeeda --- /dev/null +++ b/src/pages/analysisPower/index/main.ts @@ -0,0 +1,20 @@ +import Vue from 'vue' +import ElementUI from 'element-ui' +import 'element-ui/lib/theme-chalk/index.css'; +import "@/assets/css/element-variables.scss"; +import "../../../assets/icons/alibaba/iconfont.css"; +import "../../../assets/icons/basic/iconfont.css"; +import "../../../assets/icons/iconfont.css"; +import "../../../assets/icons/symbol.js"; + +import App from './App.vue' +import ToggleButton from 'vue-js-toggle-button'; +import Mixin from "./mixins"; + +Vue.use(ElementUI) +Vue.use(ToggleButton) +Vue.mixin(Mixin); +new Vue({ + el: '#app', + render: h => h(App) +}) diff --git a/src/pages/analysisPower/index/mixins.ts b/src/pages/analysisPower/index/mixins.ts new file mode 100644 index 0000000..9c6bb20 --- /dev/null +++ b/src/pages/analysisPower/index/mixins.ts @@ -0,0 +1,13 @@ +import DataPool from "@/Pool/PollData" + +/* eslint-disable */ +const onlyDataPool = new DataPool + +const mixin = { + data() { + return { + PollData: onlyDataPool + }; + }, +}; +export default mixin; \ No newline at end of file diff --git a/src/pages/desktop/index/mock/userData.json b/src/pages/desktop/index/mock/userData.json index f6e7281..a08717b 100644 --- a/src/pages/desktop/index/mock/userData.json +++ b/src/pages/desktop/index/mock/userData.json @@ -4,12 +4,36 @@ "data": { "docks": [ { + "id": "5", + "src": "../../images/app-mid/GB-config.png", + "alt": "GB28281閰嶇疆", + "type": "2", + "url": "/view/gb28181", + "name": "GB28281閰嶇疆" + }, + { + "id": "12", + "src": "../../images/app-mid/monitor.png", + "alt": "瀹炴椂鐩戞帶-鍦ㄧ嚎鎾斁", + "type": "2", + "url": "/view/cameraVideo", + "name": "瀹炴椂鐩戞帶-鍦ㄧ嚎鎾斁" + }, + { + "id": "9", + "src": "../../images/app-mid/algorithm-manage.png", + "alt": "绠楁硶绠$悊", + "type": "2", + "url": "/view/algorithmManage", + "name": "绠楁硶绠$悊" + }, + { "id": "1", "src": "../../images/app-mid/camera-access.png", "alt": "camera-access", "type": "2", "url": "/view/camera", - "name":"鎽勫儚鏈烘帴鍏�" + "name": "鎽勫儚鏈烘帴鍏�" }, { "id": "2", @@ -17,7 +41,7 @@ "alt": "datastack-config", "type": "2", "url": "/view/datastack", - "name":"鏁版嵁鏍堥厤缃�" + "name": "鏁版嵁鏍堥厤缃�" }, { "id": "3", @@ -34,14 +58,6 @@ "type": "2", "url": "/view/datapush", "name": "鏁版嵁鎺ㄩ��" - }, - { - "id": "5", - "src": "../../images/app-mid/GB-config.png", - "alt": "GB28281閰嶇疆", - "type": "2", - "url": "/view/gb28181", - "name": "GB28281閰嶇疆" }, { "id": "6", @@ -68,14 +84,6 @@ "name": "杞绠$悊" }, { - "id": "9", - "src": "../../images/app-mid/algorithm-manage.png", - "alt": "绠楁硶绠$悊", - "type": "2", - "url": "/view/algorithmManage", - "name": "绠楁硶绠$悊" - }, - { "id": "10", "src": "../../images/app-mid/algorithm-store.png", "alt": "绠楁硶鍟嗗煄", @@ -88,16 +96,8 @@ "src": "../../images/app-mid/hashrate-manage.png", "alt": "绠楀姏绠$悊", "type": "2", - "url": "/view/hashrateManage", + "url": "/view/analysisPower", "name": "绠楀姏绠$悊" - }, - { - "id": "12", - "src": "../../images/app-mid/monitor.png", - "alt": "瀹炴椂鐩戞帶-鍦ㄧ嚎鎾斁", - "type": "2", - "url": "/view/monitor", - "name": "瀹炴椂鐩戞帶-鍦ㄧ嚎鎾斁" }, { "id": "13", -- Gitblit v1.8.0