669 lines
18 KiB
Vue
669 lines
18 KiB
Vue
<template>
|
||
<div class="e-scene-manage">
|
||
<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-button @click="handleQuery" size="mini">刷新</el-button>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<div class="e-alarm-table">
|
||
<el-table
|
||
v-loading="tableLoading"
|
||
:data="tableList"
|
||
:height="total > 0 ? '530px' : '270px'"
|
||
>
|
||
<el-table-column
|
||
type="index"
|
||
label="序号"
|
||
align="center"
|
||
:index="indexFormatter"
|
||
width="80px"
|
||
></el-table-column>
|
||
|
||
<el-table-column
|
||
label="场景名称"
|
||
width="200px"
|
||
align="left"
|
||
prop="sceneName"
|
||
>
|
||
<template slot-scope="scope">
|
||
<span class="lay-table-textarea" :title="scope.row.sceneName">
|
||
{{ scope.row.sceneName }}
|
||
</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
label="场景编码"
|
||
align="left"
|
||
width="200"
|
||
prop="sceneCode"
|
||
>
|
||
<template slot-scope="scope">
|
||
<span class="lay-table-textarea" :title="scope.row.sceneCode">
|
||
{{ scope.row.sceneCode }}
|
||
</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
label="场景模式"
|
||
align="left"
|
||
width="120"
|
||
prop="relation"
|
||
>
|
||
<template slot-scope="scope">
|
||
<span class="lay-table-textarea" :title="scope.row.relation">
|
||
{{ scope.row.relation }}
|
||
</span>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<el-table-column
|
||
label="状态"
|
||
align="center"
|
||
prop="runStatus"
|
||
>
|
||
<template slot-scope="scope">
|
||
<span class="lay-table-textarea">
|
||
{{ scope.row.runStatus ? "启用" : "停止" }}
|
||
</span>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<el-table-column label="创建时间" align="center" width="160px" prop="createTime">
|
||
<template slot-scope="scope">
|
||
<span class="lay-table-textarea" :title="scope.row.createTime">
|
||
{{ scope.row.createTime }}
|
||
</span>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<!-- <el-table-column label="执行设备" align="left" prop="triggerDevices">
|
||
<template slot-scope="scope">
|
||
<span class="lay-table-textarea" :title="scope.row.triggerDevices">
|
||
{{ scope.row.triggerDevices }}
|
||
</span>
|
||
</template>
|
||
</el-table-column> -->
|
||
<el-table-column
|
||
label="操作"
|
||
align="center"
|
||
width="200"
|
||
prop="alarmTime"
|
||
>
|
||
<template slot-scope="scope">
|
||
<el-button
|
||
size="mini"
|
||
type="text"
|
||
icon="el-icon-edit"
|
||
@click="handleUpdate(scope.row)"
|
||
>编辑</el-button
|
||
>
|
||
|
||
<el-button
|
||
size="mini"
|
||
type="text"
|
||
:icon="scope.row.runStatus ? 'el-icon-video-pause' : 'el-icon-video-play'"
|
||
@click="handleChangeStatus(scope.row)"
|
||
>{{ scope.row.runStatus ? '停止' : '启用' }}</el-button
|
||
>
|
||
|
||
<el-button
|
||
size="mini"
|
||
type="text"
|
||
icon="el-icon-delete"
|
||
@click="handleDelete(scope.row)"
|
||
>删除</el-button
|
||
>
|
||
|
||
<!-- <el-button size="mini" type="text" icon="el-icon-search"
|
||
>详情</el-button
|
||
> -->
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<pagination
|
||
v-show="total > 0"
|
||
:total="total"
|
||
:page.sync="page.pageNum"
|
||
:limit.sync="page.pageSize"
|
||
@pagination="getTableList"
|
||
/>
|
||
</div>
|
||
<div class="e-dialog">
|
||
<!-- 添加或修改建筑类型对话框 -->
|
||
<el-dialog
|
||
:title="title"
|
||
:visible="open"
|
||
@close="open = false"
|
||
class="eldialog-wrap"
|
||
width="880px"
|
||
append-to-body
|
||
:close-on-click-modal="false"
|
||
>
|
||
<el-form
|
||
ref="form"
|
||
:model="form"
|
||
style="padding-right: 20px"
|
||
:rules="rules"
|
||
label-width="100px"
|
||
>
|
||
<el-row :gutter="10">
|
||
<el-col :span="12">
|
||
<el-form-item label="场景名称:" prop="sceneName">
|
||
<el-input
|
||
v-model="form.sceneName"
|
||
placeholder="请输入场景名称"
|
||
/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="场景编码:" prop="sceneCode">
|
||
<el-input
|
||
v-model="form.sceneCode"
|
||
placeholder="请输入场景编码"
|
||
/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<!-- <el-col :span="24">
|
||
<el-form-item label="描述" prop="buildingTypeName">
|
||
<el-input
|
||
v-model="form.buildingTypeName"
|
||
placeholder="请输入类型名称"
|
||
/>
|
||
</el-form-item>
|
||
</el-col> -->
|
||
<el-col :span="24">
|
||
<span
|
||
class="e-form-item__label"
|
||
style="
|
||
text-align: right;
|
||
vertical-align: middle;
|
||
font-size: 14px;
|
||
color: #606266;
|
||
width: 80px;
|
||
word-break: break-all;
|
||
font-weight: 600;
|
||
"
|
||
>
|
||
触发器列表:
|
||
</span>
|
||
<div>
|
||
<e-tag-card
|
||
style="margin-top: 5px"
|
||
v-for="(item, idx) in form.triggers"
|
||
:key="item.guid || getGuid()"
|
||
type="info"
|
||
>
|
||
<e-scene-triggers
|
||
slot="body"
|
||
:dataItem="item"
|
||
:sourceId="sourceId"
|
||
@change="
|
||
(v) => {
|
||
form.triggers[idx] = v;
|
||
}
|
||
"
|
||
@handleDel="
|
||
(v) => {
|
||
form.triggers.splice(idx, 1);
|
||
}
|
||
"
|
||
></e-scene-triggers>
|
||
</e-tag-card>
|
||
</div>
|
||
<el-button
|
||
icon="el-icon-plus"
|
||
type="text"
|
||
@click="handleAddTrigger"
|
||
>新增触发器</el-button
|
||
>
|
||
</el-col>
|
||
<el-col :span="24">
|
||
<div>
|
||
<span
|
||
class="e-form-item__label"
|
||
style="
|
||
text-align: right;
|
||
vertical-align: middle;
|
||
font-size: 14px;
|
||
color: #606266;
|
||
width: 80px;
|
||
word-break: break-all;
|
||
font-weight: 600;
|
||
"
|
||
>执行动作:</span
|
||
>
|
||
</div>
|
||
<div>
|
||
<e-tag-card
|
||
style="margin-top: 5px"
|
||
v-for="(item, idx) in form.actions"
|
||
:key="item.guid || getGuid()"
|
||
type="info"
|
||
>
|
||
<e-scene-action
|
||
slot="body"
|
||
:dataItem="item"
|
||
:sourceId="sourceId"
|
||
@change="
|
||
(v) => {
|
||
form.actions[idx] = v;
|
||
}
|
||
"
|
||
@handleDel="
|
||
(v) => {
|
||
form.actions.splice(idx, 1);
|
||
}
|
||
"
|
||
/>
|
||
</e-tag-card>
|
||
</div>
|
||
<el-button
|
||
type="text"
|
||
icon="el-icon-plus"
|
||
@click="handleAddAction"
|
||
>新增动作</el-button
|
||
>
|
||
</el-col>
|
||
</el-row>
|
||
</el-form>
|
||
<div slot="footer" class="dialog-footer">
|
||
<el-button type="primary" size="mini" @click="submitForm"
|
||
>确 定</el-button
|
||
>
|
||
<el-button @click="cancel" size="mini">取 消</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
<script>
|
||
import {
|
||
projectSceneList,
|
||
projectSceneAdd,
|
||
projectSceneUpdate,
|
||
projectSceneDetail,
|
||
projectSceneDelete,
|
||
projectSceneChangeStatus
|
||
} from "@/api/iot/project_new";
|
||
import DialogTemplate from "@/components/DialogTemplate";
|
||
import ESceneTriggers from "./ESceneTriggers/index";
|
||
import ETagCard from "@/components/Cards/ETagCard";
|
||
import ESceneAction from "./ESceneAction/index";
|
||
|
||
export default {
|
||
name: "ESceneManage",
|
||
props: {
|
||
projectInfo: {
|
||
type: Object,
|
||
require: true,
|
||
},
|
||
sourceId: {
|
||
type: [Number, String],
|
||
require: true,
|
||
},
|
||
tempType: {
|
||
type: String,
|
||
require: true,
|
||
},
|
||
isFoldRight: {
|
||
type: Boolean,
|
||
default: () => {
|
||
return false;
|
||
},
|
||
},
|
||
isShrink: {
|
||
type: Boolean,
|
||
default: () => {
|
||
return false;
|
||
},
|
||
},
|
||
},
|
||
components: { DialogTemplate, ESceneTriggers, ETagCard, ESceneAction },
|
||
data() {
|
||
return {
|
||
queryParams: {},
|
||
page: {
|
||
pageNum: 1,
|
||
pageSize: 10,
|
||
orderByColumn: "createTime",
|
||
isAsc: "desc"
|
||
},
|
||
title: "新增场景",
|
||
total: 0,
|
||
tableList: [],
|
||
tableLoading: false,
|
||
open: false,
|
||
// 表单参数
|
||
form: {},
|
||
// 表单校验
|
||
rules: {
|
||
sceneName: [
|
||
{ required: true, message: "场景名称不能为空", trigger: "change" },
|
||
],
|
||
sceneCode: [
|
||
{
|
||
required: true,
|
||
validator: this.chenking_sceneCode,
|
||
trigger: "change",
|
||
},
|
||
],
|
||
},
|
||
};
|
||
},
|
||
watch: {
|
||
isFoldRight() {
|
||
this.$forceUpdate();
|
||
},
|
||
isShrink() {
|
||
this.$forceUpdate();
|
||
},
|
||
sourceId(val) {
|
||
if (val !== null && val !== undefined) {
|
||
this.handleQuery();
|
||
}
|
||
},
|
||
tempType(val) {
|
||
if (val) {
|
||
this.init();
|
||
}
|
||
},
|
||
},
|
||
mounted() {},
|
||
created() {
|
||
this.init();
|
||
},
|
||
methods: {
|
||
chenking_sceneCode(rule, value, callback) {
|
||
const isExp = /^[A-Z a-z 0-9 _ - $]{0,36}$/;
|
||
if (!this.form.sceneCode || this.form.sceneCode.length <= 0) {
|
||
callback(new Error("场景编码不能为空!"));
|
||
} else if (this.form.sceneCode && !isExp.test(this.form.sceneCode)) {
|
||
callback(new Error("格式不正确(数字,英文字母大小写,36个字符)!"));
|
||
} else {
|
||
callback();
|
||
}
|
||
},
|
||
handleAddAction() {
|
||
let obj = {
|
||
orderBy: this.form.actions.length + 1 || 1,
|
||
recordStatus: 0,
|
||
actionId: null,
|
||
sceneId: this.form.recordId || null,
|
||
actionType: "DEVOUTPUT",
|
||
actionAttr: null,
|
||
sceneActionDevices: [],
|
||
sceneActionNotifierContacts: [],
|
||
};
|
||
this.form.actions.push(obj);
|
||
},
|
||
// 获取标记
|
||
handleAddTrigger() {
|
||
let triggersPop = [...this.form.triggers].pop();
|
||
let obj = {
|
||
orderBy: triggersPop ? triggersPop.orderBy + 1 : 1,
|
||
method: "",
|
||
conditions: [],
|
||
intervalVal: "",
|
||
intervalUnit: "SECONDS",
|
||
sceneTriggerDevices: [],
|
||
execScript: "",
|
||
};
|
||
this.form.triggers.push(obj);
|
||
},
|
||
// 验证 触发器 条件
|
||
validateTrigger() {
|
||
if (!this.form.triggers || this.form.triggers.length <= 0) {
|
||
this.msgError("至少有一条触发器!");
|
||
return false;
|
||
}
|
||
var isTrue = true;
|
||
this.form.triggers.forEach((e) => {
|
||
if (!e.method) {
|
||
this.msgError("设备触发__至少选择一种类型!");
|
||
isTrue = false;
|
||
}
|
||
if (
|
||
e.method === "DEVICE" &&
|
||
(!e.conditions || e.conditions.length <= 0)
|
||
) {
|
||
this.msgError("设备触发__至少选择一条设备以及触发条件!");
|
||
isTrue = false;
|
||
}
|
||
});
|
||
return isTrue && this.validateAction();
|
||
},
|
||
// 验证 执行条件
|
||
validateAction() {
|
||
if (!this.form.actions || this.form.actions.length <= 0) {
|
||
this.msgError("至少有一执行条件!");
|
||
return false;
|
||
}
|
||
var isTrue = true;
|
||
this.form.actions.forEach((e) => {
|
||
if (
|
||
e.actionType === "DEVOUTPUT" &&
|
||
e.sceneActionDevices[0] &&
|
||
(!e.sceneActionDevices[0]["cmdKey"] ||
|
||
!e.sceneActionDevices[0]["deviceKey"])
|
||
) {
|
||
this.msgError("执行条件中有条件未选择设备或者分组!");
|
||
isTrue = false;
|
||
}
|
||
if (
|
||
e.actionType === "NOTIFIER" &&
|
||
(!e.sceneActionNotifierContacts[0] ||
|
||
!e.sceneActionNotifierContacts[0]["contactsRelList"])
|
||
) {
|
||
this.msgError("执行条件中有条件未选择联系人!");
|
||
isTrue = false;
|
||
}
|
||
});
|
||
return isTrue;
|
||
},
|
||
submitForm() {
|
||
console.log("submit---", this.form);
|
||
this.$refs["form"].validate((valid) => {
|
||
if (valid && this.validateTrigger()) {
|
||
if (this.form.recordId != null) {
|
||
projectSceneUpdate(
|
||
Object.assign(this.form, {
|
||
projectId: this.sourceId,
|
||
})
|
||
).then((response) => {
|
||
this.msgSuccess("修改成功");
|
||
this.open = false;
|
||
this.handleQuery();
|
||
});
|
||
} else {
|
||
projectSceneAdd(
|
||
Object.assign(this.form, {
|
||
projectId: this.sourceId,
|
||
})
|
||
).then((response) => {
|
||
this.msgSuccess("新增成功");
|
||
this.open = false;
|
||
this.handleQuery();
|
||
});
|
||
}
|
||
}
|
||
});
|
||
},
|
||
indexFormatter(val) {
|
||
return val + 1 + (this.page.pageNum - 1) * this.page.pageSize;
|
||
},
|
||
handleAdd() {
|
||
this.reset();
|
||
this.title = "新增场景";
|
||
this.open = true;
|
||
},
|
||
/** 修改按钮操作 */
|
||
handleUpdate(row) {
|
||
this.reset();
|
||
projectSceneDetail(row.recordId).then((response) => {
|
||
this.form = response.data;
|
||
this.open = true;
|
||
this.title = "编辑场景";
|
||
});
|
||
},
|
||
handleChangeStatus(row) {
|
||
this.$confirm(row.runStatus ? '是否停止场景?' : '是否开启场景?', "提示", {
|
||
confirmButtonText: "确定",
|
||
cancelButtonText: "取消",
|
||
type: "warning",
|
||
})
|
||
.then(function () {
|
||
return projectSceneChangeStatus({
|
||
recordId: row.recordId,
|
||
runStatus: row.runStatus ? false : true
|
||
});
|
||
})
|
||
.then(() => {
|
||
this.handleQuery();
|
||
this.msgSuccess("成功");
|
||
});
|
||
},
|
||
handleDelete(row) {
|
||
const projectIds = row.recordId;
|
||
this.$confirm("是否删除该选项?", "警告", {
|
||
confirmButtonText: "确定",
|
||
cancelButtonText: "取消",
|
||
type: "warning",
|
||
})
|
||
.then(function () {
|
||
return projectSceneDelete(projectIds);
|
||
})
|
||
.then(() => {
|
||
this.handleQuery();
|
||
this.msgSuccess("删除成功");
|
||
});
|
||
},
|
||
// 取消按钮
|
||
cancel() {
|
||
this.open = false;
|
||
this.reset();
|
||
},
|
||
// 表单重置
|
||
reset() {
|
||
this.form = {
|
||
recordId: null,
|
||
recordStatus: 0,
|
||
buildingTypeCode: null,
|
||
buildingTypeName: null,
|
||
triggers: [],
|
||
actions: [],
|
||
};
|
||
this.resetForm("form");
|
||
},
|
||
init() {
|
||
this.handleQuery();
|
||
},
|
||
handleQuery() {
|
||
this.page.pageNum = 1;
|
||
this.getTableList();
|
||
},
|
||
// 查询 表格 数据
|
||
getTableList() {
|
||
this.tableLoading = true;
|
||
let query = JSON.parse(JSON.stringify(this.queryParams));
|
||
projectSceneList(
|
||
Object.assign(
|
||
query,
|
||
{
|
||
projectId: this.sourceId,
|
||
},
|
||
this.page
|
||
)
|
||
).then((res) => {
|
||
this.tableList = res.rows;
|
||
this.tableLoading = false;
|
||
this.total = res.total;
|
||
});
|
||
},
|
||
},
|
||
};
|
||
</script>
|
||
<style lang="scss">
|
||
.e-scene-manage {
|
||
width: 100%;
|
||
height: 100%;
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
.e-alarm-heard {
|
||
width: 100%;
|
||
height: 40px;
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
align-items: center;
|
||
.heard-query {
|
||
width: 50%;
|
||
height: 100%;
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
align-items: center;
|
||
.data-type {
|
||
width: 32px;
|
||
height: 32px;
|
||
background: #f4f5f7;
|
||
border-radius: 50%;
|
||
font-size: 14px;
|
||
font-family: Source Han Sans CN;
|
||
font-weight: 300;
|
||
color: #6b778c;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
margin: 0 5px;
|
||
cursor: default;
|
||
}
|
||
.data-type-selected {
|
||
background: #1890ff;
|
||
color: #f4f5f7;
|
||
}
|
||
.other-query {
|
||
display: flex;
|
||
width: 420px;
|
||
justify-content: space-evenly;
|
||
align-items: center;
|
||
}
|
||
.other-print {
|
||
font-size: 20px;
|
||
}
|
||
.other-print:hover {
|
||
color: #1890ff;
|
||
}
|
||
}
|
||
}
|
||
.e-alarm-echarts {
|
||
width: 100%;
|
||
height: 300px;
|
||
}
|
||
.e-alarm-table {
|
||
width: 100%;
|
||
padding-top: 10px;
|
||
}
|
||
.pagination-container {
|
||
margin-top: 5px;
|
||
height: 35px;
|
||
}
|
||
.e-form-item__label {
|
||
text-align: right;
|
||
vertical-align: middle;
|
||
font-size: 14px;
|
||
color: #606266;
|
||
width: 80px;
|
||
word-break: break-all;
|
||
font-weight: 600;
|
||
}
|
||
}
|
||
</style>
|