smart-power-ui/src/views/profile/DeviceDetailsView/deviceSelectNav.vue

846 lines
24 KiB
Vue

<template>
<div class="device-select-nav">
<div class="layout-select-wrap" v-if="childDeviceList.length > 0">
<el-button
plain
size="mini"
:disabled="tSelectLabelList.length <= 0"
@click="handleChildStatus('true')"
>合闸</el-button
>
<el-button
plain
size="mini"
:disabled="tSelectLabelList.length <= 0"
@click="handleChildStatus('false')"
>分闸</el-button
>
<el-button plain size="mini" @click="handleAllStatus('true')"
>一键合闸</el-button
>
<el-button plain size="mini" @click="handleAllStatus('false')"
>一键分闸</el-button
>
<el-button plain size="mini" @click="handleAllSelect()"
>{{ childDeviceList.length > tSelectList.length ? '全选' : '取消' }}</el-button
>
<span class="title-span">已选择设备:</span>
<span v-if="tSelectLabelList.length <= 0">当前未选择设备</span>
<el-tag
style="margin: 5px 5px 5px 0px"
v-for="(item, idx) in tSelectLabelList"
:key="idx"
closable
@close="selectDevClose(item)"
>
{{ item }}
</el-tag>
</div>
<div class="layout-select-wrap" v-else>
<span class="title-span">当前没有可用于分闸合闸设备~</span>
</div>
<div class="layout-device-list">
<el-card
:body-style="{ padding: '0px', width: '220px' }"
:style="
deviceInfo.deviceId === checkobxDeviceId
? 'border: 1px solid #1890ff; margin: 5px; width: 220px; flex-shrink: 0;'
: ' margin: 5px; width: 220px; flex-shrink: 0;'
"
>
<div class="nav-p-dev">
<div
style="
height: 25px;
width: 100%;
display: flex;
justify-content: flex-end;
padding-right: 10px;
padding-top: 5px;
"
>
<!-- <div
style="width: 60px; display: flex; justify-content: center"
v-if="deviceInfo.stype === 'LAN' || deviceInfo.stype === 'lan'"
>
<i
:class="`iconfont ${statusFormat(deviceInfo.stype)}`"
style="color: black; font-size: 20px"
></i>
</div> -->
<div style="width: 60px; display: flex; justify-content: center">
<!-- <i
:class="`iconfont ${statusFormat(deviceInfo.stype)}`"
style="color: black; font-size: 20px"
v-if="deviceInfo.stype === 'WIFI' || deviceInfo.stype === 'wifi'"
></i> -->
<i
:class="signalType(deviceInfo.stype)"
style="color: black; font-size: 20px"
></i>
<signal-intensity
v-if="deviceInfo.stype !== 'LAN' && deviceInfo.stype !== 'lan'"
:intensityNumber="deviceInfo.signal"
></signal-intensity>
</div>
<i
v-if="deviceInfo.deviceId === checkobxDeviceId"
class="el-icon-s-claim"
style="font-size: 25px; color: #1890ff"
></i>
</div>
<div class="dev-info">
<span class="dev-info-title" :title="deviceInfo.deviceName">{{
deviceInfo.deviceName
}}</span>
<div class="dev-info-state">
<el-tag type="success" v-if="deviceInfo.deviceState === 'ONLINE'"
>在线</el-tag
>
<el-tag
type="danger"
v-else-if="deviceInfo.deviceState === 'OFFLINE'"
>离线</el-tag
>
<el-tag
type="danger"
v-else-if="deviceInfo.deviceState === 'OUTLINE'"
>脱线</el-tag
>
<el-tag
type="info"
v-else-if="deviceInfo.deviceState === 'UNACTIVE'"
>未激活</el-tag
>
<el-button
type="primary"
size="mini"
@click="viewDeviceChange(deviceInfo.deviceId)"
>查看</el-button
>
</div>
</div>
</div>
</el-card>
<el-card
:body-style="{ padding: '0px', width: '220px' }"
:style="
item.deviceId === checkobxDeviceId
? 'border: 1px solid #1890ff; margin: 5px; width: 220px; flex-shrink: 0;'
: ' margin: 5px; width: 220px; flex-shrink: 0;'
"
v-for="item in childDeviceList"
:key="item.deviceId"
>
<div class="nav-c-dev">
<div
style="
height: 25px;
width: 100%;
display: flex;
justify-content: flex-end;
padding-right: 10px;
padding-top: 5px;
"
>
<div
@click="handleCheckbox(item)"
:style="item.deviceId === checkobxDeviceId ? 'right: 159px;' : ''"
:class="
tSelectList.indexOf(item.deviceId) >= 0
? 'checkbox-i selected-c'
: 'checkbox-i'
"
>
<i
v-show="tSelectList.indexOf(item.deviceId) >= 0"
class="el-icon-check"
></i>
</div>
<!-- <div style="
width: 60px;
display: flex;
justify-content: center;
">
<i :class="signalType(item.stype)" style="color: black; font-size: 20px;" ></i>
<signal-intensity :intensityNumber="item.signal" ></signal-intensity>
</div> -->
<i
v-if="item.deviceId === checkobxDeviceId"
class="el-icon-s-claim"
style="font-size: 25px; color: #1890ff"
></i>
</div>
<div class="dev-info">
<span class="dev-info-title" :title="item.deviceName">{{
item.deviceName
}}</span>
<div
class="dev-info-state"
v-show="item.deviceId !== checkobxDeviceId"
>
<el-tag type="success" v-if="item.deviceState === 'ONLINE'"
>在线</el-tag
>
<el-tag type="danger" v-else-if="item.deviceState === 'OFFLINE'"
>离线</el-tag
>
<el-tag type="danger" v-else-if="item.deviceState === 'OUTLINE'"
>脱线</el-tag
>
<el-tag type="info" v-else-if="item.deviceState === 'UNACTIVE'"
>未激活</el-tag
>
<el-button
type="primary"
size="mini"
@click="viewDeviceChange(item.deviceId)"
>查看</el-button
>
</div>
<div
class="dev-info-state"
v-show="item.deviceId === checkobxDeviceId"
>
<el-switch
size="mini"
v-model="item.switch"
active-text="开启"
disabled
inactive-text="关闭"
active-value="1"
inactive-value="0"
active-color="#13ce66"
inactive-color="#dcdfe6"
class="switch-wrap"
>
</el-switch>
<el-button
size="mini"
v-if="item.switch === '1'"
:disabled="item.deviceId !== checkobxDeviceId"
@click="submitChildStatus('false', item)"
type="success"
>关闭</el-button
>
<el-button
size="mini"
v-else
:disabled="item.deviceId !== checkobxDeviceId"
@click="submitChildStatus('true', item)"
type="danger"
>开启</el-button
>
<el-button
type="primary"
size="mini"
@click="viewDeviceChange(item.deviceId)"
>查看</el-button
>
</div>
</div>
</div>
</el-card>
</div>
<e-web-socket
:wsServiceUrl="wsStatusService"
:closeSleepTime="10000"
@message="wsMessage($event)"
></e-web-socket>
</div>
</template>
<script>
import { listChildrenDevice, setSwitchControl } from "@/api/iot/device";
import {
iotWebSocketBaseUrl,
devLiveWebSocketBaseUrl,
webSocketProjectGatewayUrl,
} from "@/config/env";
import SignalIntensity from "./signalIntensity";
import EWebSocket from "@/components/EWebSocket/src/basic/index";
import objectAssign from "object-assign";
export default {
name: "DeviceSelectNav",
components: {
SignalIntensity,
EWebSocket,
},
props: {
deviceInfo: {
type: Object,
default: () => {
return {};
},
},
wsDeviceInfo: {
type: Object,
default: () => {
return {};
},
},
},
data() {
return {
checkobxDeviceId: "",
childDeviceList: [],
stompClient: null,
socket_flag: true,
setTimeOut_flag: null,
timingPingWs_flag: null,
tSelectList: [],
tSelectLabelList: [],
iotSignalType: [],
// wsDeviceInfo: null?,
wsStatusService: "",
};
},
created() {
this.checkobxDeviceId = this.deviceInfo.deviceId || null;
this.getDicts("iot_signal_type").then((response) => {
this.iotSignalType = response.data;
});
},
watch: {
wsDeviceInfo: {
handler: function () {
this.timingPingWs(this.wsDeviceInfo);
if (this.deviceInfo.deviceId !== this.wsDeviceInfo.deviceId) {
for (let i = 0; i < this.childDeviceList.length; i++) {
if (
this.childDeviceList[i]["deviceId"] ===
this.wsDeviceInfo["deviceId"]
) {
this.childDeviceList[i]["switch"] =
this.wsDeviceInfoswitch?.switch.toString();
this.$forceUpdate();
break;
}
}
// this.timingPingWs(this.wsDeviceInfo);
// 更换设备 开启ws
this.connection();
} else {
this.connection();
}
},
deep: true,
},
deviceInfo: {
handler: function () {
this.checkobxDeviceId = this.deviceInfo.deviceId || null;
this.getList();
},
deep: true,
},
},
methods: {
// 开启 设备状态ws
handleOpenDevStatusService(str) {
console.log("handleOpenDevStatusService", str);
this.wsStatusService = `${webSocketProjectGatewayUrl}/${this.getGuid()}/${
this.deviceInfo.deviceKey
},${str}`;
},
wsMessage(e) {
if (e['deviceState']) {
this.handleDeviceInfo(e);
}
},
// 处理 socket 数据返回 赋值问题
handleDeviceInfo(param) {
if (param.deviceKey === this.deviceInfo.deviceKey) {
this.deviceInfo = Object.assign(this.deviceInfo, param);
} else {
if (this.childDeviceList && this.childDeviceList.length > 0) {
this.childDeviceList = this.childDeviceList.map((v) => {
if (v["deviceKey"] === param["deviceKey"]) {
return Object.assign(v, param);
} else {
return v;
}
});
}
}
},
handleAllStatus(type) {
if (this.childDeviceList.length > 0) {
this.childDeviceList.forEach((v) => {
if (this.tSelectList.indexOf(v.deviceId) < 0) {
this.tSelectList.push(v.deviceId);
this.tSelectLabelList.push(v.deviceName);
}
});
this.handleChildStatus(type);
}
},
handleAllSelect() {
if (this.childDeviceList.length > 0) {
if (this.tSelectList.length >= this.childDeviceList.length) {
this.tSelectList = [];
this.tSelectLabelList = [];
} else {
this.childDeviceList.forEach((v) => {
if (this.tSelectList.indexOf(v.deviceId) < 0) {
this.tSelectList.push(v.deviceId);
this.tSelectLabelList.push(v.deviceName);
}
});
}
}
},
// 点击子设备 线路开关
handleChildStatus(type) {
this.$prompt("请输入登录密码", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
inputPattern: /^[a-z A-z 0-9 $.]+/,
inputType: "password",
inputErrorMessage: "登录密码不能为空",
}).then(({ value }) => {
let params = {
data: {
cmd: "set_switch",
params: {
switch: 1,
},
},
deviceId: "",
verifyKey: value,
};
switch (type) {
case "true":
params.data.params.switch = 1;
params.deviceId = this.tSelectList.toString();
break;
case "false":
params.data.params.switch = 0;
params.deviceId = this.tSelectList.toString();
break;
}
setSwitchControl(params).then((res) => {
this.msgSuccess("修改成功");
});
});
},
selectDevClose(e) {
console.log(e);
this.tSelectList.splice(this.tSelectLabelList.indexOf(e), 1);
this.tSelectLabelList.splice(this.tSelectLabelList.indexOf(e), 1);
},
handleCheckbox(e) {
if (this.tSelectList.indexOf(e.deviceId) >= 0) {
// delete e
this.tSelectList.splice(this.tSelectList.indexOf(e.deviceId), 1);
this.tSelectLabelList.splice(
this.tSelectLabelList.indexOf(e.deviceName),
1
);
} else {
this.tSelectLabelList.push(e.deviceName);
this.tSelectList.push(e.deviceId);
}
},
signalType(val) {
if (val) {
return "iconfont " + this.statusFormat(val);
}
return "iconfont " + this.statusFormat("0");
// switch (val) {
// case "5G":
// return "iconfont " + this.statusFormat(val);
// case "4G":
// return "iconfont " + this.statusFormat(val);
// case "3G":
// return "iconfont " + this.statusFormat(val);
// case "2G":
// return "iconfont " + this.statusFormat(val);
// default:
// return "iconfont " + this.statusFormat(0);
// }
},
// 字典状态字典翻译 描述
statusFormat(value) {
return this.selectDictDesc(this.iotSignalType, value);
},
// ws 获取子设备 状态
connection() {
if (this.stompClient) {
return;
}
if (!this.wsDeviceInfo) {
return;
}
if (!devLiveWebSocketBaseUrl) {
return;
}
let headers = {
clientid: this.wsDeviceInfo.wsClientId,
username: this.wsDeviceInfo.wsUsername,
sign: this.wsDeviceInfo.wsSign,
};
// console.log("connection:--");
this.stompClient = new WebSocket(
`${devLiveWebSocketBaseUrl}${headers.clientid}/${headers.username}/${headers.sign}`
);
this.socket_flag = true;
this.stompClient.onopen = this.socket_open;
this.stompClient.onmessage = this.socket_onmsg;
this.stompClient.onclose = this.socket_onclose;
},
socket_open(evt) {
console.log("ws-open:", evt);
},
socket_onmsg(evt) {
this.handlerWsMsgData(JSON.parse(evt.data));
},
handlerWsMsgData(evt) {
// console.log("msg:", evt);
this.$emit("wsRealTImeMsg", JSON.stringify(evt));
if (this.deviceInfo.deviceId !== this.wsDeviceInfo.deviceId) {
for (let i = 0; i < this.childDeviceList.length; i++) {
if (this.childDeviceList[i]["deviceKey"] === evt["devId"]) {
this.childDeviceList[i]["switch"] = evt["params"]["switch"]
? evt["params"]["switch"].toString()
: "0";
this.$forceUpdate();
break;
}
}
} else {
this.deviceInfo["stype"] = evt["params"]["stype"]
? evt["params"]["stype"].toString()
: "0";
this.deviceInfo["signal"] = evt["params"]["signal"]
? evt["params"]["signal"].toString()
: "0";
}
},
socket_onclose(e) {
// console.log("socket_onclose:--", e, this.stompClient);
this.stompClient = null;
if (this.socket_flag) {
this.socket_flag = false;
let this_ = this;
this_.setTimeOut_flag = setTimeout(function () {
this_.socket_flag = true;
this_.connection();
}, 10000);
}
},
// 销毁事件
closeWebscoket() {
// console.log(this.stompClient);
this.socket_flag = false;
if (this.stompClient) {
console.log("we-close---");
this.stompClient.close();
}
this.stompClient = null;
clearInterval(this.timingPingWs_flag);
clearTimeout(this.setTimeOut_flag);
},
// 定时 ping ws
timingPingWs(row) {
this.extenSubmit(row);
const _this = this;
this.timingPingWs_flag = setInterval(function () {
_this.extenSubmit(row);
}, 110000);
},
extenSubmit(row) {
let params = {
data: {
cmd: "set_live_time",
params: {
ltime: 15, // 上报间隔(0.1秒)
dtime: 1200, //上报时长(0.1秒)
},
},
deviceId: row.deviceId,
};
setSwitchControl(params).then((res) => {
console.log(res);
// this.msgSuccess("成功");
});
},
// 点击子设备 线路开关
submitChildStatus(type, row) {
this.$prompt("请输入登录密码", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
inputPattern: /^[a-z A-z 0-9 $.]+/,
inputType: "password",
inputErrorMessage: "登录密码不能为空",
}).then(({ value }) => {
let params = {
data: {
cmd: "set_switch",
params: {
switch: type === "true" ? 1 : 0,
},
},
deviceId: row.deviceId,
verifyKey: value,
};
setSwitchControl(params).then((res) => {
// console.log(res);
this.msgSuccess("修改成功");
});
});
},
// 勾选设备
viewDeviceChange(id) {
if (this.checkobxDeviceId !== id) {
this.checkobxDeviceId = id;
// 销毁当前ws
this.closeWebscoket();
this.$emit("changeEvent", { val: id });
}
},
/** 查询设备列表 */
getList() {
listChildrenDevice({
parentId: this.deviceInfo.deviceId,
pageNum: 1,
pageSize: 999999,
}).then((response) => {
this.childDeviceList = response.rows;
var childDeviceIds = [...response.rows].map((v) => {
return v.deviceKey;
});
this.handleOpenDevStatusService(childDeviceIds.toString());
});
},
},
destroyed() {
this.closeWebscoket();
},
};
</script>
<style lang="scss">
.device-select-nav {
min-height: 180px;
width: 100%;
display: flex;
overflow-y: auto;
background-color: #e4eaf3;
flex-wrap: wrap;
align-items: flex-start;
.layout-select-wrap {
width: 100%;
min-height: 40px;
display: flex;
flex-wrap: wrap;
align-items: center;
padding-left: 5px;
border: 1px solid #1890ff;
margin: 10px 5px;
border-radius: 5px;
background-color: #1890ff17;
margin-bottom: 5px;
.title-span {
margin-left: 10px;
}
}
.layout-device-list {
width: 100%;
display: flex;
height: 130px;
overflow: auto;
}
.nav-p-dev {
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
-webkit-box-pack: end;
-ms-flex-pack: end;
justify-content: flex-end;
// padding-top: 10px;
flex-shrink: 0;
.dev-info {
padding: 10px;
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
width: 100%;
.dev-info-title {
display: block;
width: 100%;
text-overflow: ellipsis;
height: 30px;
font-size: 18px;
line-height: 30px;
white-space: nowrap;
display: inline-block;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
}
.dev-info-state {
width: 100%;
height: 50px;
justify-content: center;
display: flex;
align-items: center;
font-size: 16px;
justify-content: space-between;
/* switch按钮样式 */
.switch-wrap .el-switch__label {
position: absolute;
display: none;
color: #fff !important;
}
/*打开时文字位置设置*/
.switch-wrap .el-switch__label--right {
z-index: 1;
}
/* 调整打开时文字的显示位子 */
.switch-wrap .el-switch__label--right span {
margin-left: 10px;
}
/*关闭时文字位置设置*/
.switch-wrap .el-switch__label--left {
z-index: 1;
}
/* 调整关闭时文字的显示位子 */
.switch-wrap .el-switch__label--left span {
margin-left: 20px;
}
/*显示文字*/
.switch-wrap .el-switch__label.is-active {
display: block;
}
/* 调整按钮的宽度 */
.switch-wrap.el-switch .el-switch__core,
.el-switch .el-switch__label {
width: 60px !important;
margin: 0;
}
}
}
}
.nav-c-dev {
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
-webkit-box-pack: end;
-ms-flex-pack: end;
justify-content: flex-end;
// padding-top: 10px;
flex-shrink: 0;
.checkbox-i {
width: 20px;
border: 1px solid #1890ff;
height: 20px;
border-radius: 3px;
position: relative;
right: 184px;
font-size: 17px;
display: flex;
align-items: center;
}
.selected-c {
background: #1890ff;
color: #fff;
border-color: #fff;
}
.dev-info {
padding: 10px;
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
width: 100%;
.dev-info-title {
display: block;
width: 100%;
text-overflow: ellipsis;
height: 30px;
font-size: 18px;
line-height: 30px;
white-space: nowrap;
display: inline-block;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
}
.dev-info-state {
width: 100%;
height: 50px;
justify-content: center;
display: flex;
align-items: center;
font-size: 16px;
justify-content: space-between;
/* switch按钮样式 */
.switch-wrap .el-switch__label {
position: absolute;
display: none;
color: #fff !important;
}
/*打开时文字位置设置*/
.switch-wrap .el-switch__label--right {
z-index: 1;
}
/* 调整打开时文字的显示位子 */
.switch-wrap .el-switch__label--right span {
margin-left: 10px;
}
/*关闭时文字位置设置*/
.switch-wrap .el-switch__label--left {
z-index: 1;
}
/* 调整关闭时文字的显示位子 */
.switch-wrap .el-switch__label--left span {
margin-left: 20px;
}
/*显示文字*/
.switch-wrap .el-switch__label.is-active {
display: block;
}
/* 调整按钮的宽度 */
.switch-wrap.el-switch .el-switch__core,
.el-switch .el-switch__label {
width: 60px !important;
margin: 0;
}
}
}
}
}
.layout-device-list::-webkit-scrollbar {
/*滚动条整体样式*/
width: 8px; /*高宽分别对应横竖滚动条的尺寸*/
height: 5px;
}
.layout-device-list::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
border-radius: 10px;
// box-shadow: inset 0 0 5px #c4c4c4;
background: #929292a6;
}
.layout-device-list::-webkit-scrollbar-track {
/*滚动条里面轨道*/
// -webkit-box-shadow:
box-shadow: inset 0 0 5px #f6f6f6;
border-radius: 10px;
background: #ffffff;
}
</style>