提交: 网关 关联子设备 取消关联等操作,修复部分问题

This commit is contained in:
23688nl 2022-05-06 17:41:52 +08:00
parent fb6c0b941e
commit 258c210687
13 changed files with 832 additions and 251 deletions

41
public/wxok.html Normal file
View File

@ -0,0 +1,41 @@
<html>
<head>
</head>
<body>
<div style="
width: 100%;
height: 100%;
background: #e8e8e8;
display: flex;
justify-content: center;
align-items: center;">
<div style="
height: 260px;
width: 100%;
display: flex;
flex-wrap: wrap;
justify-content: center;
color: #67c23a;
font-size: 10vw;">
<span
style="
display: block;
width: 100px;
height: 100px;
background: #67c23a;
border-radius: 50%;
text-align: center;
line-height: 1;
color: #fff;
">√</span>
<span
style="
display: block;
width: 100%;
text-align: center;
height: 130px;
">绑定成功</span>
</div>
</div>
</body>
</html>

View File

@ -124,3 +124,30 @@ export function setSwitchControl(data) {
data: data
});
}
// 获取未绑定设备列表
export function listNoParent(query) {
return request({
url: "/iot/device/no-parent",
method: "get",
params: query
});
}
// 绑定子设备
export function relationChild(data) {
return request({
url: "/iot/device/bind",
method: "put",
data: data
});
}
// 绑定子设备
export function disassociateChild(data) {
return request({
url: "/iot/device/unBind/",
method: "put",
data: data
});
}

View File

@ -0,0 +1,53 @@
.loading-next {
width: 100%;
height: 100%;
background: #00000038;
}
.loading-next .loading-next-box {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.loading-next .loading-next-box-warp {
width: 80px;
height: 80px;
}
.loading-next .loading-next-box-warp .loading-next-box-item {
width: 33.333333%;
height: 33.333333%;
background: #1890ff;
float: left;
animation: loading-next-animation 1.2s infinite ease;
border-radius: 1px;
}
.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(7) {
animation-delay: 0s;
}
.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(4),
.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(8) {
animation-delay: 0.1s;
}
.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(1),
.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(5),
.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(9) {
animation-delay: 0.2s;
}
.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(2),
.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(6) {
animation-delay: 0.3s;
}
.loading-next .loading-next-box-warp .loading-next-box-item:nth-child(3) {
animation-delay: 0.4s;
}
@keyframes loading-next-animation {
0%,
70%,
100% {
transform: scale3D(1, 1, 1);
}
35% {
transform: scale3D(0, 0, 1);
}
}

View File

@ -1,5 +1,5 @@
<template>
<div>
<div class="comp-select-table-box">
<el-row :gutter="20">
<!--用户数据-->
<el-col v-if="queryOption.disable === false" :span="20" :xs="24">
@ -7,9 +7,15 @@
:model="params"
ref="queryForm"
:inline="queryOption.inline"
:label-width="queryOption.labelWidth ? queryOption.labelWidth : '100px'"
:label-width="
queryOption.labelWidth ? queryOption.labelWidth : '100px'
"
>
<el-form-item v-for="item in queryOption.queryChilds" :key="item.key" :label="item.label">
<el-form-item
v-for="item in queryOption.queryChilds"
:key="item.key"
:label="item.label"
>
<el-input
v-if="!item.type || item.type === 'input'"
v-model="params[item.key]"
@ -38,14 +44,42 @@
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button
type="primary"
icon="el-icon-search"
size="mini"
@click="handleQuery"
>搜索</el-button
>
<!-- <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> -->
</el-form-item>
</el-form>
</el-col>
<el-col :span="24" style="padding: 0">
<div class="layout-select-view">
<span class="title-span">已选中</span>
<span
class="empty-text"
v-if="!multipleSelection || multipleSelection.length <= 0"
>未选择任何数据~</span
>
<el-tag
v-else
v-for="item in multipleSelection"
:key="item[tableOption.rowKey]"
effect="plain"
class="item-tag"
closable
@close="handleClose(item)"
>
{{ item[tableOption.rowLabel] }}
</el-tag>
</div>
</el-col>
<el-table
ref="selectTabel"
ref="multipleTable"
v-loading="tableOption.loading"
:data="dataList"
class="select-table"
@ -55,18 +89,22 @@
highlight-current-row
:tree-props="tableOption.treeProps"
:row-key="tableOption.rowKey"
@row-click="row_clicks"
@row-dblclick="rowDblclick"
@selection-change="handleSelectionChange"
@select="handleClickSelect"
@select-all="handleSelectAll"
>
<el-table-column type="index" label="序号" align="center" :index="indexFormatter" width="80px"></el-table-column>
<el-table-column
v-if="tableOption.selection === true"
type="selection"
width="50"
align="center"
/>
<el-table-column
type="index"
label="序号"
align="center"
:index="indexFormatter"
width="80px"
></el-table-column>
<el-table-column
v-for="(item, index) in tableOption.childs"
@ -77,7 +115,7 @@
:label="item.label"
:prop="item.prop"
>
<template slot-scope="scope" v-if="item.tempType !== '' ">
<template slot-scope="scope" v-if="item.tempType !== ''">
<el-switch
v-if="item.tempType === 'switch'"
v-model="scope.row[item.prop]"
@ -86,21 +124,24 @@
:disable="item.option.disable"
></el-switch>
<span v-else-if="item.tempType === 'span'">{{scope.row[item.prop]}}</span>
<span v-else-if="item.tempType === 'span'">{{
scope.row[item.prop]
}}</span>
<svg-icon v-else-if="item.tempType === 'icon'" :icon-class="scope.row[item.prop]" />
<svg-icon
v-else-if="item.tempType === 'icon'"
:icon-class="scope.row[item.prop]"
/>
<span
v-else-if="item.tempType === 'time'"
>{{ parseTime(new Date(scope.row[item.prop])) }}</span>
<span v-else-if="item.tempType === 'time'">{{
parseTime(new Date(scope.row[item.prop]))
}}</span>
<span
v-else-if="item.tempType === 'text1'"
v-html="scope.row[item.prop] === '0' ? '正常':'禁用'"
v-html="scope.row[item.prop] === '0' ? '正常' : '禁用'"
></span>
</template>
</el-table-column>
</el-table>
@ -120,7 +161,7 @@ export default {
props: {
otherOption: {
type: Object,
default: {}
default: {},
},
queryOption: {
type: Object,
@ -131,7 +172,7 @@ export default {
page: {
pageSize: 10,
pageNum: 1,
total: 100
total: 100,
},
inline: true,
queryChilds: [
@ -143,11 +184,11 @@ export default {
type: "input",
key: "userName",
size: "small",
value: ""
}
]
value: "",
},
],
};
}
},
},
tableOption: {
type: Object,
@ -156,8 +197,9 @@ export default {
loading: false,
treeProps: "{ children: 'children', hasChildren: 'hasChildren'}",
rowKey: "deptId",
rowLabel: 'deviceName',
selection: true,
maxHeight: "45vh",
maxHeight: "46vh",
childs: [
{
style: "",
@ -167,7 +209,7 @@ export default {
align: "center",
width: "50",
"show-overflow-tooltip": false,
tempType: ""
tempType: "",
},
{
style: "",
@ -181,25 +223,25 @@ export default {
option: {
"active-value": "0",
"inactive-value": "1",
disable: false
}
}
disable: false,
},
},
],
tableList: {
type: Array
}
type: Array,
},
};
}
},
},
tableList: {
type: Array
type: Array,
},
option: {
type: Object,
default: () => {
return {};
}
}
},
},
},
data() {
return {
@ -209,7 +251,8 @@ export default {
multiple: "",
params: {},
multipleSelection: [],
optionTrue: true
multipleCurrentPage: [],
optionTrue: true,
};
},
updated() {
@ -219,23 +262,60 @@ export default {
}
},
methods: {
indexFormatter(val) {
return val + 1 + ((this.queryOption.page.pageNum - 1) * this.queryOption.page.pageSize);
handleClose(row) {
this.multipleSelection = this.multipleSelection.filter(
(v) => v[this.tableOption.rowKey] !== row[this.tableOption.rowKey]
);
this.$refs.multipleTable.clearSelection();
this.handleUpdateTableSelect();
},
//
handleSelectionChange(selection) {
this.$emit("returnEvent", {
value: selection,
type: "select",
otherOption: this.otherOption
getEventData() {
return this.multipleSelection;
},
indexFormatter(val) {
return (
val +
1 +
(this.queryOption.page.pageNum - 1) * this.queryOption.page.pageSize
);
},
//
handleClickSelect(selection, row) {
let idxArr = [];
this.multipleSelection.map((v, idx) => {
if (v[this.tableOption.rowKey] === row[this.tableOption.rowKey]) {
idxArr.push(idx);
}
});
if (idxArr && idxArr.length > 0) {
let list = this.multipleSelection.filter((n, i) => !idxArr.includes(i));
this.multipleSelection = [...list];
} else {
this.multipleSelection.push(row);
}
},
//
handleSelectAll(selection) {
console.log(selection);
if (selection.length > 0) {
this.multipleCurrentPage = [...selection];
selection.map((row) => {
this.multipleSelection = this.multipleSelection.filter(
(v) => v[this.tableOption.rowKey] !== row[this.tableOption.rowKey]
);
});
this.multipleSelection = this.multipleSelection.concat(selection);
} else {
this.multipleCurrentPage.map((row) => {
this.multipleSelection = this.multipleSelection.filter(
(v) => v[this.tableOption.rowKey] !== row[this.tableOption.rowKey]
);
});
}
},
/** 搜索按钮操作 */
handleQuery() {
// debugger
// this.queryOption.page.pageNum = 1;
// this.queryOption.params = this.params
this.optionTrue = false
this.optionTrue = false;
this.getList(this.queryOption.page, this.queryOption.params);
},
handleQuery2() {
@ -253,30 +333,22 @@ export default {
this.$emit("parentGetList", {
page: page,
param: params,
otherOption: this.otherOption
otherOption: this.otherOption,
});
},
rowDblclick(row) {
if (this.tableOption.selection) {
return
}
this.$emit("returnEvent", {
value: row,
type: "dblclick",
otherOption: this.otherOption
});
},
row_clicks(row) {
if (this.tableOption.selection) {
this.$refs.selectTabel.toggleRowSelection(row)
} else {
this.$emit("returnEvent", {
value: row,
type: "click",
otherOption: this.otherOption
//
handleUpdateTableSelect() {
this.multipleCurrentPage = [];
this.dataList.forEach((v) => {
this.multipleSelection.forEach((row) => {
if (v[this.tableOption.rowKey] === row[this.tableOption.rowKey]) {
this.multipleCurrentPage.push(v);
this.$refs.multipleTable.toggleRowSelection(v, true);
}
});
}
}
});
this.tableOption.loading = false;
},
},
created() {
this.params = this.queryOption.params;
@ -285,19 +357,52 @@ export default {
watch: {
tableList(value) {
this.dataList = value;
this.tableOption.loading = false;
setTimeout(this.handleUpdateTableSelect, 250);
},
multipleSelection(val) {
console.log(val)
}
}
console.log(val);
},
},
};
</script>
<style lang="scss">
.select-table {
.el-table--striped .el-table__body tr.el-table__row--striped.current-row td,
.el-table__body tr.current-row > td {
background-color: #ffec8b;
.comp-select-table-box {
.select-table {
.el-table--striped .el-table__body tr.el-table__row--striped.current-row td,
.el-table__body tr.current-row > td {
background-color: #ffec8b;
}
}
.layout-select-view {
width: 100%;
min-height: 50px;
border: 1px solid #198efc;
background-color: #46a6ff5e;
color: #3d3f41;
font-size: 16px;
margin-bottom: 10px;
border-radius: 5px;
padding: 5px;
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
.title-span {
display: block;
width: 70px;
height: 30px;
line-height: 40px;
text-align: right;
}
.empty-text {
display: block;
width: 200px;
height: 30px;
line-height: 40px;
text-align: left;
}
.item-tag {
margin: 5px;
}
}
}
</style>

View File

@ -4,6 +4,7 @@ import { Message } from 'element-ui'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import { getToken } from '@/utils/auth'
import { NextLoading } from '@/utils/loading';
NProgress.configure({ showSpinner: false })
@ -11,6 +12,7 @@ const whiteList = ['/login', '/auth-redirect', '/bind', '/register']
router.beforeEach((to, from, next) => {
NProgress.start()
// if (!window.nextLoading) NextLoading.start()
if (getToken()) {
/* has token*/
if (to.path === '/login') {
@ -51,4 +53,5 @@ router.beforeEach((to, from, next) => {
router.afterEach(() => {
NProgress.done()
// NextLoading.done();
})

46
src/utils/loading.js Normal file
View File

@ -0,0 +1,46 @@
import Vue from 'vue';
import '@/assets/styles/loading.scss';
/**
* 页面全局 Loading
* @method start 创建 loading
* @method done 移除 loading
*/
export const NextLoading = {
// 创建 loading
start: () => {
const bodys = document.body;
const div = document.createElement('div');
document.body.style.overflow = 'hidden'
div.setAttribute('class', 'loading-next');
const htmls = `
<div class="loading-next-box">
<div class="loading-next-box-warp">
<div class="loading-next-box-item"></div>
<div class="loading-next-box-item"></div>
<div class="loading-next-box-item"></div>
<div class="loading-next-box-item"></div>
<div class="loading-next-box-item"></div>
<div class="loading-next-box-item"></div>
<div class="loading-next-box-item"></div>
<div class="loading-next-box-item"></div>
<div class="loading-next-box-item"></div>
</div>
</div>
`;
div.innerHTML = htmls;
bodys.insertBefore(div, bodys.childNodes[0]);
window.nextLoading = true;
},
// 移除 loading
done:(_this) => {
Vue.nextTick(() => {
window.nextLoading = false;
document.body.style.overflow = ''
const el = document.querySelector('.loading-next');
el?.parentNode?.removeChild(el);
})
},
}

View File

@ -83,6 +83,7 @@ import MapWrap from "./profile/mapWrap";
import MapWrapPersonal from "./profile/personalCenter";
import { iotWebSocketAlarmBaseUrl } from "@/config/env";
import Cookies from "js-cookie";
import { NextLoading } from '@/utils/loading';
import { getWarningAnalysis, homeCount, appProjectList } from "@/api/app";
export default {
@ -133,21 +134,21 @@ export default {
});
},
watch: {
$route(to, from) {
if (from.fullPath === "/index") {
document.getElementById("con_lf_top_div").style.background = "#fff";
document.getElementById("con_lf_top_div").style.height =
"calc(100vh - 84px)";
document.getElementById("con_lf_top_div").style.minHeight =
"calc(100vh - 84px)";
} else if (to.fullPath === "/index") {
document.getElementById("con_lf_top_div").style.background = "#010e45";
document.getElementById("con_lf_top_div").style.height =
"calc(100vh - 84px)";
document.getElementById("con_lf_top_div").style.minHeight =
"calc(100vh - 84px)";
}
},
// $route(to, from) {
// if (from.fullPath === "/index") {
// document.getElementById("con_lf_top_div").style.background = "#fff";
// document.getElementById("con_lf_top_div").style.height =
// "calc(100vh - 84px)";
// document.getElementById("con_lf_top_div").style.minHeight =
// "calc(100vh - 84px)";
// } else if (to.fullPath === "/index") {
// document.getElementById("con_lf_top_div").style.background = "#010e45";
// document.getElementById("con_lf_top_div").style.height =
// "calc(100vh - 84px)";
// document.getElementById("con_lf_top_div").style.minHeight =
// "calc(100vh - 84px)";
// }
// },
},
created() {
document.getElementById("app").style.background = "#010e45";

View File

@ -828,7 +828,7 @@ export default {
/** 删除按钮操作 */
handleDelete(row) {
const deviceIds = row.deviceId || this.ids;
this.$confirm("是否删除该选项?", "警告", {
this.$confirm("删除设备将会删除设备相关数据,请谨慎操作,是否继续?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"

View File

@ -231,12 +231,14 @@
<el-form-item label="产品PK" prop="prodKey">
<el-input
v-if="form.protocolType === 'OFFICIAL'"
:disabled="form.vendorId || vendorId === 0"
placeholder="请填写产品PK"
v-model="form.prodKey"
></el-input>
<el-input
v-else
v-model="form.prodKey"
:disabled="form.vendorId || vendorId === 0"
placeholder="点击选择产品"
@focus="openProductTableSelectDialog()"
/>

View File

@ -236,7 +236,7 @@ import { addTrigger, updateTrigger, getTrigger } from "@/api/iot/trigger";
import { listAlarmType } from "@/api/alarm/alarmType";
import { listContacts } from "@/api/iot/contacts";
import ConditionTemp from "@/views/profile/DeviceTrigger/profile/conditionTemp";
import SelectTableWrap from "@/components/SelectTable/indexbox";
import SelectTableWrap from "@/components/SelectTable/index";
import DeviceParamWrap from "@/views/profile/DeviceTrigger/profile/deviceParam";
const relationOptions = {

View File

@ -18,39 +18,88 @@
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
<el-button
type="primary"
icon="el-icon-search"
size="mini"
@click="handleQuery"
>搜索</el-button
>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
>重置</el-button
>
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增</el-button
>
<el-button
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleRelation"
>关联设备</el-button
>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<!-- <el-row :gutter="10" class="mb8">
<el-col :span="1.5">
</el-col>
<right-toolbar
:showSearch.sync="showSearch"
@queryTable="getList"
></right-toolbar>
</el-row> -->
<el-table v-loading="loading" :data="deviceList">
<el-table-column type="index" label="序号" align="center" :index="indexFormatter" width="80px"></el-table-column>
<el-table-column
type="index"
label="序号"
align="center"
:index="indexFormatter"
width="80px"
></el-table-column>
<el-table-column label="设备名称" align="left" prop="deviceName" />
<el-table-column label="所属型号" align="left" prop="modelName" />
<el-table-column label="设备key" align="left" prop="deviceKey" />
<el-table-column label="设备类型" align="left" width="120px" prop="deviceTypeName" />
<el-table-column label="设备状态" align="center" width="120" prop="deviceStatus">
<el-table-column
label="设备类型"
align="left"
width="120px"
prop="deviceTypeName"
/>
<el-table-column
label="设备状态"
align="center"
width="120"
prop="deviceStatus"
>
<template slot-scope="scope">
<el-tag type="success" v-if="scope.row.deviceState === 'ONLINE'">在线</el-tag>
<el-tag type="danger" v-else-if="scope.row.deviceState === 'OFFLINE'">离线</el-tag>
<el-tag type="danger" v-else-if="scope.row.deviceState === 'OUTLINE'">脱线</el-tag>
<el-tag type="info" v-else-if="scope.row.deviceState === 'UNACTIVE'">未激活</el-tag>
<el-tag type="success" v-if="scope.row.deviceState === 'ONLINE'"
>在线</el-tag
>
<el-tag type="danger" v-else-if="scope.row.deviceState === 'OFFLINE'"
>离线</el-tag
>
<el-tag type="danger" v-else-if="scope.row.deviceState === 'OUTLINE'"
>脱线</el-tag
>
<el-tag type="info" v-else-if="scope.row.deviceState === 'UNACTIVE'"
>未激活</el-tag
>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" width="160px" prop="createTime" />
<el-table-column
label="创建时间"
align="center"
width="160px"
prop="createTime"
/>
<el-table-column
label="操作"
align="center"
@ -61,22 +110,25 @@
<el-button
size="mini"
type="text"
icon="el-icon-search"
@click="handleDetails(scope.row)"
>详情</el-button>
icon="el-icon-error"
@click="handleDisassociate(scope.row)"
>取消关联</el-button
>
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
>修改</el-button>
>修改</el-button
>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['iot:device:remove']"
>删除</el-button>
>删除</el-button
>
</template>
</el-table-column>
</el-table>
@ -89,9 +141,14 @@
@pagination="getList"
/>
<!-- 添加或修改设备对话框 -->
<el-dialog class="eldialog-wrap" :close-on-click-modal="false" :title="title" :visible.sync="open" width="500px">
<el-dialog
class="eldialog-wrap"
:close-on-click-modal="false"
:title="title"
:visible.sync="open"
width="500px"
>
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-form-item label="所属型号:" prop="modelId">
<el-input
@ -105,7 +162,7 @@
<el-select
disabled
v-model="form.deviceType"
style="width: 100%;"
style="width: 100%"
placeholder="请选择设备类型"
clearable
>
@ -130,13 +187,17 @@
</el-form-item>
<el-form-item label="设备KEY" prop="deviceKey">
<el-input :disabled="title === '修改子设备'" v-model="form.deviceKey" placeholder="请输入设备KEY" />
<el-input
:disabled="title === '修改子设备'"
v-model="form.deviceKey"
placeholder="请输入设备KEY"
/>
</el-form-item>
<el-form-item label="线路类型:" prop="lineType">
<el-select
v-model="form.lineType"
style="width: 100%;"
style="width: 100%"
placeholder="请选择线路类型"
clearable
>
@ -150,19 +211,22 @@
</el-form-item>
<el-form-item label="参数设置:">
<span style="color: red; font-size: 12px;">*注意锁定即参数不可修改未锁则可以修改</span>
<span style="color: red; font-size: 12px"
>*注意锁定即参数不可修改未锁则可以修改</span
>
<div class="form-params-wrap">
<param-wrap ref="paramWrap" typeKeys="" v-if="open"></param-wrap>
</div>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" @click="submitForm"> </el-button>
<el-button size="mini" type="primary" @click="submitForm"
> </el-button
>
<el-button size="mini" @click="open = false"> </el-button>
</div>
</el-dialog>
<el-dialog
title="选择"
:visible.sync="selectTableShow"
@ -182,11 +246,54 @@
/>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" @click="resuleClick"> </el-button>
<el-button size="mini" @click="() =>{selectTableShow = false}"> </el-button>
<el-button size="mini" type="primary" @click="resuleClick"
> </el-button
>
<el-button
size="mini"
@click="
() => {
selectTableShow = false;
}
"
> </el-button
>
</div>
</el-dialog>
<el-dialog
:title="title"
:visible.sync="selectTableBoxShow"
width="75%"
top="10vh"
class="select-table-dialog"
:close-on-click-modal="false"
>
<select-table-box
ref="selectTableBox_dev"
v-if="selectTableBoxShow"
:tableOption="tableSelectOption.tableOpt"
:queryOption="tableSelectOption.queryOpt"
:tableList="tableSelectOption.tableList"
@parentGetList="childTableList($event)"
:otherOption="tableSelectOption.otherOption"
/>
<div slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" @click="relationSubmit"
> </el-button
>
<el-button
size="mini"
@click="
() => {
selectTableBoxShow = false;
}
"
> </el-button
>
</div>
</el-dialog>
</div>
</template>
<script>
@ -196,26 +303,32 @@ import {
addDevice,
updateDevice,
listDeviceTypeList,
getDevice
getDevice,
listNoParent,
relationChild,
disassociateChild
} from "@/api/iot/device";
import { listModel, getModel } from "@/api/iot/model";
import SelectTableWrap from "@/components/SelectTable/index";
import SelectTableBox from "@/components/SelectTable/checkbox"
import ParamWrap from "@/components/ParamWrap/deviceParam";
const lineTypeOpt = {
MAIN:'总路',
BRANCH: '支路'
}
MAIN: "总路",
BRANCH: "支路",
};
export default {
name: '',
props: ['sourceId', 'pDevcieInfo'],
name: "",
props: ["sourceId", "pDevcieInfo"],
components: {
SelectTableWrap,
ParamWrap
ParamWrap,
SelectTableBox
},
data() {
return {
lineTypeOpt,
selectTableShow: false,
selectTableBoxShow: false,
tableSelectOption: {},
selectResult: {},
//
@ -229,10 +342,10 @@ export default {
deviceStatus: null,
deviceKey: null,
deviceType: null,
parentId: ''
parentId: "",
},
open: false,
title: '',
title: "",
showSearch: true,
//
deviceList: [],
@ -241,36 +354,59 @@ export default {
//
rules: {
modelId: [
{ required: true, message: "所属型号不能为空", trigger: "blur" }
{ required: true, message: "所属型号不能为空", trigger: "blur" },
],
deviceType: [
{ required: true, message: "设备类型不能为空", trigger: "blur" }
{ required: true, message: "设备类型不能为空", trigger: "blur" },
],
parentId: [
{ required: true, message: "父设备不能为空", trigger: "blur" }
{ required: true, message: "父设备不能为空", trigger: "blur" },
],
deviceName: [
{ required: true, message: "设备名称不能为空", trigger: "blur" }
{ required: true, message: "设备名称不能为空", trigger: "blur" },
],
lineType: [
{ required: true, message: "线路类型不能为空", trigger: "blur" }
lineType: [
{ required: true, message: "线路类型不能为空", trigger: "blur" },
],
deviceKey: [
{
required: true,
validator: this.chenking_deviceKey,
trigger: "blur"
}
]
trigger: "blur",
},
],
},
deviceTypeList: []
}
deviceTypeList: [],
relationForm: {},
};
},
created() {
this.getDeviceTypeList();
this.getList()
this.getList();
},
methods: {
relationSubmit() {
console.log(this.$refs.selectTableBox_dev.getEventData())
let list = this.$refs.selectTableBox_dev.getEventData() || [];
if (list.length > 0) {
let strArr = []
list.map(v => {
strArr.push(v.deviceId)
})
this.relationForm.childIds = strArr
this.handleSubmit()
} else {
this.$message.error('绑定子设必须要选择一条以上设备信息哦!');
}
},
handleSubmit() {
relationChild(this.relationForm).then((response) => {
this.msgSuccess("子设备绑定操作成功!");
this.selectTableBoxShow = false;
this.getList();
this.$emit("EventUpload");
});
},
chenking_deviceKey(rule, value, callback) {
const isExp = /^[A-Z a-z 0-9 _ - $]{0,36}$/;
if (this.form.deviceKey && !isExp.test(this.form.deviceKey)) {
@ -279,6 +415,15 @@ export default {
callback();
}
},
//
childTableList(data) {
listNoParent(Object.assign(data.page, data.param, { selected: 1 })).then(
response => {
this.tableSelectOption.tableList = response.rows;
this.tableSelectOption.queryOpt.page.total = Number(response.total);
}
);
},
//
childGetList(data) {
this.modelChildList(data);
@ -303,13 +448,13 @@ export default {
},
// id
getModelInfoById(modelId) {
getModel(modelId).then(res => {
getModel(modelId).then((res) => {
this.$refs.paramWrap.setList(res.data.paramList || []);
});
},
modelChildList(data) {
listModel(Object.assign(data.page, data.param, { selected: 1 })).then(
response => {
(response) => {
this.tableSelectOption.tableList = response.rows;
this.tableSelectOption.queryOpt.page.total = Number(response.total);
}
@ -317,12 +462,12 @@ export default {
},
//
resuleClick() {
this.form.modelId = this.selectResult.modelId;
this.form.prodKey = this.selectResult.prodKey;
this.form.modelName = this.selectResult.modelName;
this.form.deviceType = this.selectResult.deviceType;
// this.deviceTypeChange(this.form.deviceType);
this.getModelInfoById(this.selectResult.modelId);
this.form.modelId = this.selectResult.modelId;
this.form.prodKey = this.selectResult.prodKey;
this.form.modelName = this.selectResult.modelName;
this.form.deviceType = this.selectResult.deviceType;
// this.deviceTypeChange(this.form.deviceType);
this.getModelInfoById(this.selectResult.modelId);
this.selectTableShow = false;
},
//
@ -330,7 +475,7 @@ export default {
this.selectResult = {};
this.tableSelectOption = {
otherOption: {
tableType: "model"
tableType: "model",
},
queryOpt: {
disable: false,
@ -338,13 +483,13 @@ export default {
params: {
modelName: "",
modelCode: "",
deviceType: 'MINIATURE_BREAKER',
protocolType: ''
deviceType: "MINIATURE_BREAKER",
protocolType: "",
},
page: {
pageSize: 10,
pageNum: 1,
total: 0
total: 0,
},
inline: true,
queryChilds: [
@ -356,7 +501,7 @@ export default {
type: "input",
key: "modelName",
size: "small",
value: ""
value: "",
},
{
style: "",
@ -367,25 +512,25 @@ export default {
key: "protocolType",
size: "small",
value: "",
options: [
options: [
{
key: 'IOTOS',
key: "IOTOS",
label: "iot平台",
value: 'IOTOS'
value: "IOTOS",
},
{
key: 'ONENET',
key: "ONENET",
label: "ONENET",
value: 'ONENET'
}
value: "ONENET",
},
],
optionKey: {
key: 'key',
key: "key",
label: "label",
value: 'value'
}
}
]
value: "value",
},
},
],
},
tableOpt: {
loading: false,
@ -401,7 +546,7 @@ export default {
align: "left",
width: "200",
"show-overflow-tooltip": false,
tempType: "span"
tempType: "span",
},
{
style: "",
@ -411,7 +556,7 @@ export default {
align: "left",
width: "200",
"show-overflow-tooltip": false,
tempType: "span"
tempType: "span",
},
{
style: "",
@ -421,7 +566,7 @@ export default {
align: "left",
width: "120",
"show-overflow-tooltip": false,
tempType: "span"
tempType: "span",
},
{
style: "",
@ -431,7 +576,7 @@ export default {
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span"
tempType: "span",
},
{
style: "",
@ -441,6 +586,95 @@ export default {
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span",
},
],
tableList: {
type: Array,
},
},
tableList: [],
};
this.selectTableShow = true;
},
//
openTableSelectDialog() {
this.selectResult = {};
this.tableSelectOption = {
otherOption: {
tableType: "device"
},
queryOpt: {
disable: false,
labelWidth: "68px",
params: {
deviceName: "",
deviceType: "MINIATURE_BREAKER",
},
page: {
pageSize: 10,
pageNum: 1,
total: 0
},
inline: true,
queryChilds: [
{
style: "",
placeholder: "设备名称",
clearable: true,
label: "设备名称",
type: "input",
key: "deviceName",
size: "small",
value: ""
}
]
},
tableOpt: {
loading: false,
rowKey: "deviceId",
selection: true,
maxHeight: "50vh",
rowLabel: 'deviceName',
childs: [
{
style: "",
label: "所属型号",
type: "",
prop: "modelName",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span"
},
{
style: "",
label: "设备名称",
type: "",
prop: "deviceName",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span"
},
{
style: "",
label: "设备Key",
type: "",
prop: "deviceKey",
align: "left",
width: "",
"show-overflow-tooltip": false,
tempType: "span"
},
{
style: "",
label: "创建时间",
type: "time",
prop: "createTime",
align: "center",
width: "160",
"show-overflow-tooltip": false,
tempType: "span"
}
],
@ -450,11 +684,11 @@ export default {
},
tableList: []
};
this.selectTableShow = true;
this.selectTableBoxShow = true;
},
//
getDeviceTypeList() {
listDeviceTypeList().then(response => {
listDeviceTypeList().then((response) => {
this.deviceTypeList = response.data;
});
},
@ -464,11 +698,20 @@ export default {
this.open = true;
this.title = "添加子设备";
},
/** 关联子设备 */
handleRelation() {
this.relationForm = {
childIds: "",
devId: this.sourceId,
};
this.title = `关联子设备`
this.openTableSelectDialog()
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const _this = this;
getDevice(row.deviceId).then(response => {
getDevice(row.deviceId).then((response) => {
_this.form = response.data;
_this.open = true;
_this.title = "修改子设备";
@ -478,13 +721,15 @@ export default {
});
},
indexFormatter(val) {
return val + 1 + ((this.queryParams.pageNum - 1) * this.queryParams.pageSize);
return (
val + 1 + (this.queryParams.pageNum - 1) * this.queryParams.pageSize
);
},
/** 查询设备列表 */
getList() {
this.loading = true;
this.queryParams.parentId = this.sourceId
listDevice(this.queryParams).then(response => {
this.queryParams.parentId = this.sourceId;
listDevice(this.queryParams).then((response) => {
this.deviceList = response.rows;
this.total = response.total;
this.loading = false;
@ -502,63 +747,82 @@ export default {
},
handleDetails(row) {
if (row.deviceId) {
this.$emit('toChildEvent', { deviceId: row.deviceId })
this.$emit("toChildEvent", { deviceId: row.deviceId });
}
},
/** 取消关联 */
handleDisassociate(row) {
this.$confirm("是否确认取消父子设备关联?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(function () {
return disassociateChild( { childIds: [row.deviceId] });
})
.then(() => {
this.getList();
this.msgSuccess("取消成功");
this.$emit("EventUpload");
});
},
/** 删除按钮操作 */
handleDelete(row) {
this.$confirm("是否删除该选项?", "警告", {
this.$confirm(" 删除设备将会删除设备相关数据,请谨慎操作,是否继续?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
type: "warning",
})
.then(function() {
.then(function () {
return delDevice(row.deviceId);
})
.then(() => {
this.getList();
this.msgSuccess("删除成功");
this.$emit('EventUpload')
this.$emit("EventUpload");
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
this.$refs["form"].validate((valid) => {
if (valid) {
this.form.paramList = this.$refs.paramWrap.getResult();
this.form.lineType = this.form.deviceType === 'MINIATURE_BREAKER' ? this.form.lineType : undefined;
this.form.lineType =
this.form.deviceType === "MINIATURE_BREAKER"
? this.form.lineType
: undefined;
if (this.form.deviceId != null) {
updateDevice(this.form).then(response => {
updateDevice(this.form).then((response) => {
this.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addDevice(this.form).then(response => {
addDevice(this.form).then((response) => {
this.msgSuccess("新增成功");
this.open = false;
this.getList();
this.$emit('EventUpload')
this.$emit("EventUpload");
});
}
}
});
},
//
//
reset() {
this.form = {
modelId: null,
modelName: "",
parentName: this.pDevcieInfo.deviceName,
parentId: this.pDevcieInfo.deviceId,
deviceName: '',
deviceType: 'MINIATURE_BREAKER',
deviceName: "",
deviceType: "MINIATURE_BREAKER",
paramList: [],
deviceKey: "",
lineType: ''
lineType: "",
};
this.resetForm("form");
},
},
}
};
</script>

View File

@ -1,17 +1,27 @@
<template>
<div class="condition-temp">
<div class="top-info">
<span style="margin: 0px 8px;">关系:</span>
<el-select v-model="info.relationType" style="width: 150px;" size="small" placeholder="请选择">
<el-option v-for="(lable, val) in relationOptions" :label="lable" :value="val" :key="val"></el-option>
<span style="margin: 0px 8px">关系:</span>
<el-select
v-model="info.relationType"
style="width: 150px"
size="small"
placeholder="请选择"
>
<el-option
v-for="(lable, val) in relationOptions"
:label="lable"
:value="val"
:key="val"
></el-option>
</el-select>
<span style="margin: 0px 8px;">类型:</span>
<span style="margin: 0px 8px">类型:</span>
<el-select
v-model="info.funKey"
placeholder="请选择"
@change="propertChangeFu"
style="width: 150px;"
size="small"
style="width: 150px"
size="small"
>
<el-option
v-for="opt in propertyList"
@ -20,47 +30,76 @@
:key="opt.funKey"
></el-option>
</el-select>
<span style="margin: 0px 8px;"> 条件:</span>
<span style="margin: 0px 8px"> 条件:</span>
<el-select
v-model="info.conditionType"
placeholder="请选择"
size="small"
style="width: 150px;"
size="small"
style="width: 150px"
@change="changeTriggerCondFu(info.conditionType)"
>
>
<el-option
v-for="(proVal, proName) in trigCondEnumOptions"
:label="proVal"
:value="proName"
:key="proVal"
>{{ proVal }}</el-option>
>{{ proVal }}</el-option
>
</el-select>
<el-button size="small" type="danger" style="margin-left: 5px;" plain @click="delItemFun">删除此数据</el-button>
<el-button
size="small"
type="danger"
style="margin-left: 5px"
plain
@click="delItemFun"
>删除此数据</el-button
>
</div>
<div class="val-info">
<div style="padding-top: 10px;">
<div style="padding-top: 10px">
<div
v-show="info.conditionType !== 'GTB'"
style="float: left; margin-right: 20px; margin-bottom: 8px; padding-left: 10px;"
style="
float: left;
margin-right: 20px;
margin-bottom: 8px;
padding-left: 10px;
"
>
&#12288;&#160;&#160;A:
<el-input-number
<!-- <el-input-number
v-model="info.value1"
placeholder="A"
controls-position="right"
style="width: 220px;margin-left: 5px;"
></el-input-number>
></el-input-number> -->
<el-input
v-model="info.value1"
placeholder="A"
style="width: 220px; margin-left: 5px"
></el-input>
</div>
<div v-show="info.conditionType === 'GTB' || info.conditionType === 'GTA_AND_LTB' || info.conditionType === 'LTA_OR_GTB'" style="float: left; margin-left: 5px;">
<div
v-show="
info.conditionType === 'GTB' ||
info.conditionType === 'GTA_AND_LTB' ||
info.conditionType === 'LTA_OR_GTB'
"
style="float: left; margin-left: 5px"
>
&#12288;&#160;&#160;B:
<el-input-number
<!-- <el-input-number
v-model="info.value2"
placeholder="B"
controls-position="right"
style="width: 220px;margin-left: 5px; "
></el-input-number>
></el-input-number> -->
<el-input
v-model="info.value2"
placeholder="B"
style="width: 220px; margin-left: 5px"
></el-input>
</div>
</div>
</div>
@ -70,36 +109,36 @@
<script>
const relationOptions = {
AND: "并且",
OR: "或者"
OR: "或者",
};
const trigCondEnumOptions = {
LTA: "数值低于A",
GTB: "数值高于B",
GTA_AND_LTB: "数值介于AB之间",
LTA_OR_GTB: "数值高于B低于A",
EQA: "数值等于A"
EQA: "数值等于A",
};
export default {
name: "ConditionTemp",
props: ["info", "propertyList", 'tempIndex'],
props: ["info", "propertyList", "tempIndex"],
data() {
return {
relationOptions,
trigCondEnumOptions,
triggerMinInput: false,
triggerMaxInput: false
trigCondEnumOptions,
triggerMinInput: false,
triggerMaxInput: false,
};
},
created() {
this.triggerCondFu()
},
this.triggerCondFu();
},
methods: {
delItemFun() {
this.$emit('EventDel', this.tempIndex)
},
delItemFun() {
this.$emit("EventDel", this.tempIndex);
},
propertChangeFu(val) {
this.propertyList.forEach(v => {
if (v.funKey === val) {
this.propertyList.forEach((v) => {
if (v.funKey === val) {
// this.info.funDataType = v.funDataType;
this.info.funId = v.funId;
this.info.funName = v.funName;
@ -125,24 +164,24 @@ export default {
if (val === "EQA") {
this.triggerMinInput = true;
}
}
}
},
},
};
</script>
<style lang="scss">
.condition-temp {
width: calc(100% + 80px);
position: relative;
left: -80px;
border: 1px solid #c6c6c6;
padding: 5px;
height: 110px;
overflow: auto;
margin-top: 10px;
.top-info {
border-bottom: 1px dotted #898788;
padding-bottom: 5px;
}
width: calc(100% + 80px);
position: relative;
left: -80px;
border: 1px solid #c6c6c6;
padding: 5px;
height: 110px;
overflow: auto;
margin-top: 10px;
.top-info {
border-bottom: 1px dotted #898788;
padding-bottom: 5px;
}
}
</style>

View File

@ -179,7 +179,7 @@
v-show="temp.hasCtl"
ref="paramsWrap"
:disabled="false"
v-for="(item,index) in relationList"
v-for="(item) in relationList"
:tempIndex="item.guid"
:deleteButtonD="false"
:key="item.guid"
@ -240,7 +240,7 @@ import { addTrigger, updateTrigger, getTrigger } from "@/api/iot/trigger";
import { listAlarmType } from "@/api/alarm/alarmType";
import { listContacts } from "@/api/iot/contacts";
import ConditionTemp from "./conditionTemp";
import SelectTableWrap from "@/components/SelectTable/indexbox";
import SelectTableWrap from "@/components/SelectTable/index";
import DeviceParamWrap from "./deviceParam";
const relationOptions = {