<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"
|
:style="{
|
height: strethTable ? 'calc(100% - 30px)' : 'calc(100% - 220px)',
|
}"
|
>
|
<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" v-if="isShowPolling === 'show'">
|
<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"
|
v-if="showSetting && isShowPolling === 'show'"
|
>设置</el-button
|
>
|
</div>
|
|
<el-table
|
:header-cell-style="{ background: '#F8F8F8', color: '#222222' }"
|
height="93%"
|
:data="PollData.CameraList"
|
border
|
:cell-style="cellStyle"
|
>
|
<el-table-column
|
label="序号"
|
type="index"
|
align="center"
|
width="60px"
|
></el-table-column>
|
<el-table-column
|
label="摄像机名称"
|
align="center"
|
show-overflow-tooltip
|
>
|
<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="摄像机IP"
|
prop="ip"
|
align="center"
|
width="130px"
|
sortable
|
:sort-method="ipSortMethod"
|
></el-table-column>
|
<el-table-column label="摄像机类型" align="center" width="120px">
|
<template slot-scope="scope">
|
<span>{{ scope.row.run_type | cameraType }}</span>
|
</template>
|
</el-table-column>
|
<el-table-column
|
label="执行算法"
|
align="center"
|
show-overflow-tooltip
|
>
|
<template slot-scope="scope">
|
<span v-if="scope.row.run_type === -1">-</span>
|
<span v-else-if="scope.row.tasks != null">{{
|
scope.row.tasks | taskList
|
}}</span>
|
<span v-else>-</span>
|
</template>
|
</el-table-column>
|
<el-table-column
|
label="运行设备"
|
align="center"
|
width="160px"
|
sortable
|
>
|
<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
|
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"
|
v-if="isShowPolling === 'show'"
|
>
|
<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="450px"
|
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="1"
|
: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";
|
export default {
|
name: "PollSeting",
|
components: {
|
Sysinfo,
|
},
|
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() {
|
if (this.PollData.PollValidCount === 0 || !this.PollData.PollValidCount) {
|
return 0;
|
}
|
let sumPollingCamera = 0;
|
this.PollData.CameraList.forEach((cam) => {
|
if (cam.run_type === 0) {
|
sumPollingCamera++;
|
}
|
});
|
// 所有轮询的摄像机总数 * 轮询时间 / 轮询算力 - 1
|
let ret =
|
(sumPollingCamera * this.PollData.Config.poll_period) /
|
this.PollData.PollValidCount -
|
1;
|
if (String(ret).indexOf(".") > 0) {
|
ret = ret.toFixed(1);
|
}
|
|
return ret < 0 ? 0 : ret;
|
},
|
isAdmin() {
|
if (
|
sessionStorage.getItem("userInfo") &&
|
sessionStorage.getItem("userInfo") !== ""
|
) {
|
let loginName = JSON.parse(sessionStorage.getItem("userInfo")).username;
|
return loginName === "superadmin" || loginName === "basic";
|
}
|
|
return false;
|
},
|
showSetting() {
|
return (
|
this.isAdmin || this.buttonAuthority.indexOf("analysisPower:set") > -1
|
);
|
},
|
},
|
data() {
|
return {
|
search: "",
|
timeout: null,
|
taskName: [],
|
dataList: [],
|
barChart: {},
|
showSysInfo: false,
|
drawer: false,
|
formData: {},
|
strethTable: false,
|
buttonAuthority: sessionStorage.getItem("buttonAuthoritys") || [],
|
isShowPolling: sessionStorage.getItem("isShowPolling"),
|
};
|
},
|
mounted() {
|
this.PollData.init();
|
this.statistic();
|
this.barChart = echarts.init(document.getElementById("barSimple"));
|
this.initLineChart();
|
},
|
beforeDestroy() {
|
clearTimeout(this.timeout);
|
},
|
methods: {
|
ipSortMethod(a, b) {
|
if (
|
Number(a.ip.substr(a.ip.lastIndexOf(".") + 1)) <
|
Number(b.ip.substr(b.ip.lastIndexOf(".") + 1))
|
) {
|
return -1;
|
}
|
if (
|
Number(a.ip.substr(a.ip.lastIndexOf(".") + 1)) >
|
Number(b.ip.substr(b.ip.lastIndexOf(".") + 1))
|
) {
|
return 1;
|
}
|
return 0;
|
},
|
openDrawer() {
|
this.initFormData();
|
this.drawer = true;
|
},
|
closeDrawer() {
|
this.drawer = false;
|
this.initFormData();
|
},
|
initFormData() {
|
this.formData = {
|
totalChanle: this.PollData.channelTotal,
|
//realTime: this.PollData.RealTimeSum,
|
realTime: this.PollData.RealTimeValidCount,
|
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)
|
},
|
cellStyle(obj) {
|
if (
|
obj.column.label == "摄像机名称" ||
|
obj.column.label == "摄像机地址"
|
) {
|
return "text-align:left;padding-left:8px;";
|
}
|
},
|
},
|
};
|
</script>
|
<style lang="scss">
|
.s-poll-setting {
|
width: 100%;
|
height: 100%;
|
min-width: 1609px;
|
font-size: 14px;
|
position: relative;
|
.top {
|
width: 100%;
|
height: 190px;
|
min-width: 1609px;
|
display: flex;
|
.sysinfo-box .eCharts-box {
|
width: 36%;
|
}
|
.progressBar {
|
width: 26%;
|
}
|
.percentBall {
|
width: 84%;
|
height: 82%;
|
//float: left;
|
padding-left: 30px;
|
box-sizing: border-box;
|
}
|
.barGraph {
|
width: 16%;
|
height: 100%;
|
//float: right;
|
#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 {
|
.tip {
|
display: inline-block;
|
font-family: PingFangSC-Medium;
|
font-size: 14px;
|
span {
|
margin: 0px 10px;
|
}
|
}
|
.content {
|
padding: 20px 30px 30px;
|
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;
|
&:focus {
|
outline: none;
|
}
|
.el-dialog__close {
|
&:focus {
|
outline: none !important;
|
}
|
}
|
.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 {
|
border-bottom: 2px solid #eee;
|
padding-bottom: 10px;
|
font-size: 16px;
|
margin-bottom: 0px;
|
span {
|
border: none !important;
|
border-image-width: 0 !important;
|
&:focus {
|
outline: none;
|
}
|
}
|
}
|
}
|
</style>
|