739 lines
20 KiB
Vue
739 lines
20 KiB
Vue
<template>
|
||
<div class="e-scene-manage">
|
||
<div v-show="!isLoggingViewShow" style="width: 100%">
|
||
<el-row :gutter="10" class="mb8">
|
||
<el-col :span="1.5">
|
||
<el-button
|
||
v-hasPermi="['project:scene:add']"
|
||
icon="el-icon-plus"
|
||
plain
|
||
size="mini"
|
||
type="primary"
|
||
@click="handleAdd"
|
||
>新增</el-button
|
||
>
|
||
<el-button size="mini" @click="handleQuery">刷新</el-button>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<div class="e-alarm-table">
|
||
<el-table
|
||
v-loading="tableLoading"
|
||
:data="tableList"
|
||
:height="total > 0 ? '470px' : '510px'"
|
||
>
|
||
<el-table-column
|
||
:index="indexFormatter"
|
||
align="center"
|
||
label="序号"
|
||
type="index"
|
||
width="80px"
|
||
></el-table-column>
|
||
|
||
<el-table-column
|
||
align="left"
|
||
label="场景名称"
|
||
prop="sceneName"
|
||
width="200px"
|
||
>
|
||
<template slot-scope="scope">
|
||
<span :title="scope.row.sceneName" class="lay-table-textarea">
|
||
{{ scope.row.sceneName }}
|
||
</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
align="left"
|
||
label="场景编码"
|
||
prop="sceneCode"
|
||
width="200"
|
||
>
|
||
<template slot-scope="scope">
|
||
<span :title="scope.row.sceneCode" class="lay-table-textarea">
|
||
{{ scope.row.sceneCode }}
|
||
</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
align="left"
|
||
label="场景模式"
|
||
prop="relation"
|
||
width="120"
|
||
>
|
||
<template slot-scope="scope">
|
||
<span :title="scope.row.relation" class="lay-table-textarea">
|
||
{{ scope.row.relation }}
|
||
</span>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<el-table-column align="center" label="状态" prop="runStatus">
|
||
<template slot-scope="scope">
|
||
<span class="lay-table-textarea">
|
||
{{ scope.row.runStatus == "0" ? "启用" : "停止" }}
|
||
</span>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<el-table-column
|
||
align="center"
|
||
label="创建时间"
|
||
prop="createTime"
|
||
width="160px"
|
||
>
|
||
<template slot-scope="scope">
|
||
<span :title="scope.row.createTime" class="lay-table-textarea">
|
||
{{ scope.row.createTime }}
|
||
</span>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<el-table-column
|
||
align="center"
|
||
label="操作"
|
||
prop="alarmTime"
|
||
width="300"
|
||
>
|
||
<template slot-scope="scope">
|
||
<el-button
|
||
v-hasPermi="['project:scene:edit']"
|
||
icon="el-icon-edit"
|
||
size="mini"
|
||
type="text"
|
||
@click="handleUpdate(scope.row)"
|
||
>编辑</el-button
|
||
>
|
||
|
||
<el-button
|
||
v-hasPermi="['project:scene:remove']"
|
||
icon="el-icon-delete"
|
||
size="mini"
|
||
type="text"
|
||
@click="handleDelete(scope.row)"
|
||
>删除</el-button
|
||
>
|
||
|
||
<el-button
|
||
v-hasPermi="['project:scene:status']"
|
||
:icon="
|
||
scope.row.runStatus == '0'
|
||
? 'el-icon-open'
|
||
: 'el-icon-turn-off'
|
||
"
|
||
size="mini"
|
||
type="text"
|
||
@click="handleChangeStatus(scope.row)"
|
||
>{{ scope.row.runStatus == "0" ? "停止" : "启用" }}</el-button
|
||
>
|
||
|
||
<el-button
|
||
v-hasPermi="['project:scene:run']"
|
||
icon="el-icon-video-play"
|
||
size="mini"
|
||
type="text"
|
||
@click="handleSingleRun(scope.row)"
|
||
>执行</el-button
|
||
>
|
||
|
||
<el-button
|
||
icon="el-icon-takeaway-box"
|
||
size="mini"
|
||
type="text"
|
||
@click="handleLoggingView(scope.row)"
|
||
>指令历史</el-button
|
||
>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<pagination
|
||
v-show="total > 0"
|
||
:limit.sync="page.pageSize"
|
||
:page.sync="page.pageNum"
|
||
:total="total"
|
||
@pagination="getTableList"
|
||
/>
|
||
</div>
|
||
<div class="e-dialog">
|
||
<!-- 添加或修改建筑类型对话框 -->
|
||
<dialog-template
|
||
:title="title"
|
||
:visible="open"
|
||
width="880px"
|
||
@close="open = false"
|
||
>
|
||
<el-form
|
||
ref="form"
|
||
slot="dialog-center"
|
||
:model="form"
|
||
:rules="rules"
|
||
label-width="100px"
|
||
style="padding-right: 20px"
|
||
>
|
||
<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
|
||
v-for="(item, idx) in form.triggers"
|
||
:key="item.guid "
|
||
style="margin-top: 5px"
|
||
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
|
||
v-for="(item, idx) in form.actions"
|
||
:key="item.guid "
|
||
style="margin-top: 5px"
|
||
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
|
||
icon="el-icon-plus"
|
||
type="text"
|
||
@click="handleAddAction"
|
||
>新增动作</el-button
|
||
>
|
||
</el-col>
|
||
</el-row>
|
||
</el-form>
|
||
<div slot="dialog-footer" class="dialog-footer">
|
||
<el-button size="mini" type="primary" @click="submitForm"
|
||
>确 定</el-button
|
||
>
|
||
<el-button size="mini" @click="cancel">取 消</el-button>
|
||
</div>
|
||
</dialog-template>
|
||
</div>
|
||
</div>
|
||
<e-logging
|
||
v-if="isLoggingViewShow"
|
||
:sceneInfo="loggingSourceObject"
|
||
:sourceId="loggingSourceId"
|
||
@handleLinkToHome="
|
||
() => {
|
||
isLoggingViewShow = false;
|
||
}
|
||
"
|
||
></e-logging>
|
||
</div>
|
||
</template>
|
||
<script>
|
||
import {
|
||
projectSceneList,
|
||
projectSceneAdd,
|
||
projectSceneUpdate,
|
||
projectSceneDetail,
|
||
projectSceneDelete,
|
||
projectSceneChangeStatus,
|
||
projectSceneSingleRun,
|
||
} 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";
|
||
import ELogging from "./ELogging";
|
||
|
||
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,
|
||
ELogging,
|
||
},
|
||
data() {
|
||
return {
|
||
queryParams: {},
|
||
isLoggingViewShow: false,
|
||
loggingSourceId: null,
|
||
loggingSourceObject: {},
|
||
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 = {
|
||
guid: this.getGuid(),
|
||
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 = {
|
||
guid: this.getGuid(),
|
||
orderBy: triggersPop ? triggersPop.orderBy + 1 : 1,
|
||
method: "",
|
||
conditions: [],
|
||
intervalVal: "60",
|
||
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") {
|
||
let arr = e.sceneActionNotifierContacts.filter((v) => {
|
||
if ((!v["contactsRelList"]) || v["contactsRelList"].length <= 0) {
|
||
return v;
|
||
}
|
||
});
|
||
if (arr && arr.length > 0) {
|
||
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 == "0" ? "是否停止场景?" : "是否开启场景?",
|
||
"提示",
|
||
{
|
||
confirmButtonText: "确定",
|
||
cancelButtonText: "取消",
|
||
type: "warning",
|
||
}
|
||
)
|
||
.then(function () {
|
||
return projectSceneChangeStatus({
|
||
recordId: row.recordId,
|
||
runStatus: row.runStatus == "0" ? "1" : "0",
|
||
});
|
||
})
|
||
.then(() => {
|
||
this.handleQuery();
|
||
this.msgSuccess("成功");
|
||
});
|
||
},
|
||
handleLoggingView(row) {
|
||
this.loggingSourceId = row.recordId;
|
||
this.loggingSourceObject = row;
|
||
this.isLoggingViewShow = true;
|
||
},
|
||
/**
|
||
* 场景 执行一次 方法
|
||
* @param {*} row
|
||
*/
|
||
handleSingleRun(row) {
|
||
this.$confirm("是否确认执行一次此场景?", "提示", {
|
||
confirmButtonText: "确定",
|
||
cancelButtonText: "取消",
|
||
type: "warning",
|
||
})
|
||
.then(function () {
|
||
return projectSceneSingleRun(row.recordId);
|
||
})
|
||
.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;
|
||
width: calc(100% - 300px);
|
||
.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>
|