mirror of
https://gitee.com/beecue/fastbee.git
synced 2025-12-17 16:36:03 +08:00
前端测试更新
This commit is contained in:
@@ -1,43 +0,0 @@
|
||||
<template>
|
||||
<div class='kong'>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
|
||||
};
|
||||
},
|
||||
props:{
|
||||
data:{
|
||||
type:Array,
|
||||
default:()=>[]
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
methods: {
|
||||
init(){
|
||||
},
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
beforeDestroy() {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='scss' scoped>
|
||||
.kong{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -1,30 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
created(){
|
||||
|
||||
},
|
||||
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
|
||||
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang='scss' scoped>
|
||||
|
||||
|
||||
</style>
|
||||
@@ -1,266 +0,0 @@
|
||||
<template>
|
||||
<div style="padding:6px;">
|
||||
<el-card v-show="showSearch" style="margin-bottom:6px;">
|
||||
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px" style="margin-bottom:-20px;">
|
||||
<el-form-item label="告警名称" prop="alertName">
|
||||
<el-input v-model="queryParams.alertName" placeholder="请输入告警名称" clearable size="small" @keyup.enter.native="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="告警级别" prop="alertLevel">
|
||||
<el-select v-model="queryParams.alertLevel" placeholder="请选择告警级别" clearable size="small">
|
||||
<el-option v-for="dict in dict.type.iot_alert_level" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="处理状态" prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="请选择处理状态" clearable size="small">
|
||||
<el-option v-for="dict in dict.type.iot_process_status" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</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-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card style="padding-bottom:100px;">
|
||||
<el-table v-loading="loading" :data="alertLogList" @selection-change="handleSelectionChange" border>
|
||||
<el-table-column label="告警名称" align="center" prop="alertName" />
|
||||
<el-table-column label="告警级别" align="center" prop="alertLevel">
|
||||
<template slot-scope="scope">
|
||||
<dict-tag :options="dict.type.iot_alert_level" :value="scope.row.alertLevel" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="处理状态" align="center" prop="status">
|
||||
<template slot-scope="scope">
|
||||
<dict-tag :options="dict.type.iot_process_status" :value="scope.row.status" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="产品ID" align="center" prop="productId" />
|
||||
<el-table-column label="产品名称" align="center" prop="productName" />
|
||||
<el-table-column label="设备ID" align="center" prop="deviceId" />
|
||||
<el-table-column label="设备名称" align="center" prop="deviceName" />
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="处理结果" align="center" prop="remark" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['iot:alertLog:edit']">处理</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
|
||||
|
||||
<!-- 添加或修改设备告警对话框 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="处理结果" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" rows="8" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
listAlertLog,
|
||||
getAlertLog,
|
||||
delAlertLog,
|
||||
addAlertLog,
|
||||
updateAlertLog
|
||||
} from "@/api/iot/alertLog";
|
||||
|
||||
export default {
|
||||
name: "AlertLog",
|
||||
dicts: ['iot_alert_level', 'iot_process_status'],
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 选中数组
|
||||
ids: [],
|
||||
// 非单个禁用
|
||||
single: true,
|
||||
// 非多个禁用
|
||||
multiple: true,
|
||||
// 显示搜索条件
|
||||
showSearch: true,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 设备告警表格数据
|
||||
alertLogList: [],
|
||||
// 弹出层标题
|
||||
title: "",
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
alertName: null,
|
||||
alertLevel: null,
|
||||
status: null,
|
||||
productId: null,
|
||||
productName: null,
|
||||
deviceId: null,
|
||||
deviceName: null,
|
||||
},
|
||||
// 表单参数
|
||||
form: {},
|
||||
// 表单校验
|
||||
rules: {
|
||||
alertName: [{
|
||||
required: true,
|
||||
message: "告警名称不能为空",
|
||||
trigger: "blur"
|
||||
}],
|
||||
alertLevel: [{
|
||||
required: true,
|
||||
message: "告警级别不能为空",
|
||||
trigger: "change"
|
||||
}],
|
||||
status: [{
|
||||
required: true,
|
||||
message: "处理状态(0=不需要处理,1=未处理,2=已处理)不能为空",
|
||||
trigger: "change"
|
||||
}],
|
||||
productId: [{
|
||||
required: true,
|
||||
message: "产品ID不能为空",
|
||||
trigger: "blur"
|
||||
}],
|
||||
productName: [{
|
||||
required: true,
|
||||
message: "产品名称不能为空",
|
||||
trigger: "blur"
|
||||
}],
|
||||
deviceId: [{
|
||||
required: true,
|
||||
message: "设备ID不能为空",
|
||||
trigger: "blur"
|
||||
}],
|
||||
deviceName: [{
|
||||
required: true,
|
||||
message: "设备名称不能为空",
|
||||
trigger: "blur"
|
||||
}],
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
/** 查询设备告警列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listAlertLog(this.queryParams).then(response => {
|
||||
this.alertLogList = response.rows;
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
this.open = false;
|
||||
this.reset();
|
||||
},
|
||||
// 表单重置
|
||||
reset() {
|
||||
this.form = {
|
||||
alertLogId: null,
|
||||
alertName: null,
|
||||
alertLevel: null,
|
||||
status: null,
|
||||
productId: null,
|
||||
productName: null,
|
||||
deviceId: null,
|
||||
deviceName: null,
|
||||
createBy: null,
|
||||
createTime: null,
|
||||
updateBy: null,
|
||||
updateTime: null,
|
||||
remark: null
|
||||
};
|
||||
this.resetForm("form");
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm("queryForm");
|
||||
this.handleQuery();
|
||||
},
|
||||
// 多选框选中数据
|
||||
handleSelectionChange(selection) {
|
||||
this.ids = selection.map(item => item.alertLogId)
|
||||
this.single = selection.length !== 1
|
||||
this.multiple = !selection.length
|
||||
},
|
||||
/** 新增按钮操作 */
|
||||
handleAdd() {
|
||||
this.reset();
|
||||
this.open = true;
|
||||
this.title = "添加设备告警";
|
||||
},
|
||||
/** 修改按钮操作 */
|
||||
handleUpdate(row) {
|
||||
this.reset();
|
||||
const alertLogId = row.alertLogId || this.ids
|
||||
getAlertLog(alertLogId).then(response => {
|
||||
this.form = response.data;
|
||||
this.open = true;
|
||||
this.title = "修改设备告警";
|
||||
});
|
||||
},
|
||||
/** 提交按钮 */
|
||||
submitForm() {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
if (this.form.alertLogId != null) {
|
||||
updateAlertLog(this.form).then(response => {
|
||||
this.$modal.msgSuccess("修改成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
});
|
||||
} else {
|
||||
addAlertLog(this.form).then(response => {
|
||||
this.$modal.msgSuccess("新增成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
handleDelete(row) {
|
||||
const alertLogIds = row.alertLogId || this.ids;
|
||||
this.$modal.confirm('是否确认删除设备告警编号为"' + alertLogIds + '"的数据项?').then(function () {
|
||||
return delAlertLog(alertLogIds);
|
||||
}).then(() => {
|
||||
this.getList();
|
||||
this.$modal.msgSuccess("删除成功");
|
||||
}).catch(() => {});
|
||||
},
|
||||
/** 导出按钮操作 */
|
||||
handleExport() {
|
||||
this.download('iot/alertLog/export', {
|
||||
...this.queryParams
|
||||
}, `alertLog_${new Date().getTime()}.xlsx`)
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -178,6 +178,12 @@
|
||||
<device-monitor ref="deviceMonitor" :device="form" />
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane name="deviceStastic" :disabled="form.deviceId == 0"
|
||||
v-if="form.deviceType !== 3 && hasShrarePerm('statistic')">
|
||||
<span slot="label">监测统计</span>
|
||||
<device-statistic ref="deviceStatistic" :device="form" />
|
||||
</el-tab-pane>
|
||||
|
||||
<!-- 用于设置间距 -->
|
||||
<el-tab-pane disabled>
|
||||
<span slot="label">
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
<template>
|
||||
<span></span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import mqtt from 'mqtt'
|
||||
import {
|
||||
getToken
|
||||
} from "@/utils/auth";
|
||||
|
||||
export default {
|
||||
name: "mqttClient",
|
||||
props: {
|
||||
publish: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
subscribes: {
|
||||
type: Array,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
// 获取到父组件传递的值
|
||||
publish: function (val, oldVal) {
|
||||
this.mqttPublish(val.topic, val.message, val.name);
|
||||
},
|
||||
subscribes: function (val, oldVal) {
|
||||
this.connectMqtt(val);
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
/** 连接Mqtt */
|
||||
connectMqtt(subscribeTopics) {
|
||||
let randomClientId = 'web-' + Math.random().toString(16).substr(2);
|
||||
let options = {
|
||||
username: "wumei-smart",
|
||||
password: getToken(),
|
||||
cleanSession: false,
|
||||
keepAlive: 30,
|
||||
clientId: randomClientId,
|
||||
connectTimeout: 10000
|
||||
}
|
||||
// 配置Mqtt地址
|
||||
// let url = "ws://" + window.location.hostname + ":8083/mqtt";
|
||||
console.log("mqtt地址:", process.env.VUE_APP_EMQX_SERVER_URL);
|
||||
this.client = mqtt.connect(process.env.VUE_APP_EMQX_SERVER_URL, options);
|
||||
this.client.on("connect", (e) => {
|
||||
console.log("客户端:" + randomClientId + ",成功连接服务器:", e);
|
||||
// 订阅主题
|
||||
if (subscribeTopics != '' && subscribeTopics.length > 0) {
|
||||
this.client.subscribe(subscribeTopics, {
|
||||
qos: 1
|
||||
}, (err) => {
|
||||
if (!err) {
|
||||
console.log("订阅成功");
|
||||
console.log(subscribeTopics.join(", "));
|
||||
} else {
|
||||
console.log('消息订阅失败!')
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
// 重新连接
|
||||
this.reconnectMqtt()
|
||||
// 是否已经断开连接
|
||||
this.mqttError()
|
||||
// 监听获取信息
|
||||
this.mqttSubscribe()
|
||||
},
|
||||
|
||||
/** 发布消息 */
|
||||
mqttPublish(topic, message, name) {
|
||||
if (!this.client.connected) {
|
||||
console.log('客户端未连接')
|
||||
this.$modal.notifyError("Mqtt客户端未连接");
|
||||
return
|
||||
}
|
||||
this.client.publish(topic, message, {
|
||||
qos: 1
|
||||
}, (err) => {
|
||||
if (!err) {
|
||||
console.log('成功发布主题:' + topic)
|
||||
console.log('主题内容:' + message);
|
||||
if (topic.indexOf('offline') > 0) {
|
||||
this.$modal.notify("[ " + name + " ] 影子指令发送成功");
|
||||
} else {
|
||||
this.$modal.notifySuccess("[ " + name + " ] 指令发送成功");
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
/** 监听Mqtt消息 */
|
||||
mqttSubscribe() {
|
||||
this.client.on("message", (topic, message) => {
|
||||
console.log('收到来自', topic, '的信息', message.toString())
|
||||
// 传递信息到父组件
|
||||
let data = {};
|
||||
data.topic = topic;
|
||||
data.message = JSON.parse(message.toString());
|
||||
this.$emit('callbackEvent', data);
|
||||
});
|
||||
},
|
||||
/** 监听服务器是否连接失败 */
|
||||
mqttError() {
|
||||
this.client.on('error', (error) => {
|
||||
console.log('连接失败:', error)
|
||||
this.$modal.notifyError("Mqtt客户端连接失败");
|
||||
this.client.end();
|
||||
})
|
||||
},
|
||||
/** 取消订阅 */
|
||||
unsubscribeMqtt() {
|
||||
this.client.unsubscribe(this.mtopic, (error) => {
|
||||
console.log('主题为' + this.mtopic + '取消订阅成功', error)
|
||||
})
|
||||
},
|
||||
/** 断开连接 */
|
||||
unconnectMqtt() {
|
||||
this.client.end()
|
||||
this.client = null
|
||||
console.log('服务器已断开连接!');
|
||||
this.$modal.notifyError("Mqtt服务器已断开连接!");
|
||||
},
|
||||
/** 监听服务器重新连接 */
|
||||
reconnectMqtt() {
|
||||
this.client.on('reconnect', (error) => {
|
||||
console.log('正在重连:', error)
|
||||
});
|
||||
},
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,327 +0,0 @@
|
||||
<template>
|
||||
<div style="padding: 6px">
|
||||
<el-card v-show="showSearch" style="margin-bottom: 6px">
|
||||
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px" style="margin-bottom: -20px">
|
||||
<el-form-item label="客户端" prop="clientid">
|
||||
<el-input v-model="queryParams.clientid" placeholder="请输入客户端ID" clearable size="small" @keyup.enter.native="handleQuery" />
|
||||
</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-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card style="padding-bottom: 100px">
|
||||
<el-table v-loading="loading" :data="clientList">
|
||||
<el-table-column label="客户端ID" align="left" header-align="center" prop="clientid">
|
||||
<template slot-scope="scope">
|
||||
<el-link :underline="false" type="primary" @click.native="handleOpen(scope.row)">{{ scope.row.clientid }}</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="节点" align="center" prop="node" width="120" />
|
||||
<el-table-column label="IP地址" align="center" prop="ip_address" />
|
||||
<el-table-column label="类型" align="center" prop="type">
|
||||
<template slot-scope="scope">
|
||||
<el-tag type="danger" v-if="scope.row.clientid.indexOf('server') == 0">服务端</el-tag>
|
||||
<el-tag type="success" v-else-if="scope.row.clientid.indexOf('web') == 0">Web端</el-tag>
|
||||
<el-tag type="warning" v-else-if="scope.row.clientid.indexOf('phone') == 0">移动端</el-tag>
|
||||
<el-tag type="info" v-else-if="scope.row.clientid.indexOf('test') == 0">测试端</el-tag>
|
||||
<el-tag type="primary" v-else>设备端</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="连接状态" align="center" prop="connected">
|
||||
<template slot-scope="scope">
|
||||
<el-tag type="success" v-if="scope.row.connected">已连接</el-tag>
|
||||
<el-tag type="info" v-else>已断开</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="心跳(秒)" align="center" prop="keepalive" width="100" />
|
||||
<el-table-column label="会话过期间隔" align="center" prop="expiry_interval" width="100" />
|
||||
<el-table-column label="当前订阅数量" align="center" prop="subscriptions_cnt" width="100" />
|
||||
<el-table-column label="连接时间" align="center" prop="connected_at" />
|
||||
<el-table-column label="会话创建时间" align="center" prop="created_at" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="150">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="small" type="danger" v-if="scope.row.connected" style="padding: 5px" v-hasPermi="['iot:emqx:remove']" @click="handleDelete(scope.row)">
|
||||
<svg-icon icon-class="disconnect" /> 断开连接
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams._page" :limit.sync="queryParams._limit" @pagination="getList" />
|
||||
|
||||
<!-- MQTT客户端详细 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
|
||||
<el-tabs v-model="activeName" tab-position="top" style="padding: 10px">
|
||||
<el-tab-pane name="basic">
|
||||
<span slot="label">基本信息</span>
|
||||
<el-descriptions class="margin-top" :column="2" border size="medium">
|
||||
<el-descriptions-item label="节点">{{form.node }}</el-descriptions-item>
|
||||
<el-descriptions-item label="客户端ID">{{form.clientid}}</el-descriptions-item>
|
||||
<el-descriptions-item label="清除Session">{{form.clean_start}}</el-descriptions-item>
|
||||
<el-descriptions-item label="会话过期间隔(秒)">{{form.expiry_interval}}</el-descriptions-item>
|
||||
<el-descriptions-item label="用户名">{{form.username}}</el-descriptions-item>
|
||||
<el-descriptions-item label="协议类型">{{form.proto_ver}}</el-descriptions-item>
|
||||
<el-descriptions-item label="会话创建时间">{{form.created_at}}</el-descriptions-item>
|
||||
<el-descriptions-item label="订阅数量">{{ form.subscriptions_cnt }}/{{form.max_subscriptions}}</el-descriptions-item>
|
||||
<el-descriptions-item label="IP地址">{{form.ip_address}}</el-descriptions-item>
|
||||
<el-descriptions-item label="端口">{{form.port}}</el-descriptions-item>
|
||||
<el-descriptions-item label="最大订阅数量">{{form.max_subscriptions}}</el-descriptions-item>
|
||||
<el-descriptions-item label="飞行窗口">{{ form.inflight }}/{{ form.max_inflight }}</el-descriptions-item>
|
||||
<el-descriptions-item label="心跳(秒)">{{form.keepalive}}</el-descriptions-item>
|
||||
<el-descriptions-item label="是否为桥接">{{form.is_bridge}}</el-descriptions-item>
|
||||
<el-descriptions-item label="最大飞行窗口">{{form.max_inflight}}</el-descriptions-item>
|
||||
<el-descriptions-item label="消息队列">{{ form.mqueue_len }}/{{ form.max_mqueue }}</el-descriptions-item>
|
||||
<el-descriptions-item label="连接时间">{{form.connected_at}}</el-descriptions-item>
|
||||
<el-descriptions-item label="连接状态">
|
||||
<div v-if="form.connected == true" style="color: green">
|
||||
已连接
|
||||
</div>
|
||||
<div v-else-if="form.connected == false" style="color: red">
|
||||
已断开
|
||||
</div>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="最大消息队列">{{form.max_mqueue}}</el-descriptions-item>
|
||||
<el-descriptions-item label="未确认的PUBREC数据包计数">{{form.awaiting_rel}}</el-descriptions-item>
|
||||
<el-descriptions-item label="Zone">{{form.zone}}</el-descriptions-item>
|
||||
<el-descriptions-item label="最大未确认的PUBREC数据包计数">{{form.max_awaiting_rel}}</el-descriptions-item>
|
||||
<el-descriptions-item label="接收的TCP报文数量">{{form.recv_cnt}}</el-descriptions-item>
|
||||
<el-descriptions-item label="接收的PUBLISH报文数量">{{form.recv_msg}}</el-descriptions-item>
|
||||
<el-descriptions-item label="接收的字节数量">{{form.recv_oct}}</el-descriptions-item>
|
||||
<el-descriptions-item label="接收的MQTT报文数量">{{form.recv_pkt}}</el-descriptions-item>
|
||||
<el-descriptions-item label="发送的TCP报文数量">{{form.send_cnt}}</el-descriptions-item>
|
||||
<el-descriptions-item label="发送的PUBLISH报文数量">{{form.send_msg}}</el-descriptions-item>
|
||||
<el-descriptions-item label="发送的字节数量">{{form.send_oct}}</el-descriptions-item>
|
||||
<el-descriptions-item label="发送的MQTT报文数量">{{form.send_pkt}}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane name="subscribe">
|
||||
<span slot="label">订阅列表</span>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="el-icon-refresh" size="mini" @click="handleRefresh" v-hasPermi="['iot:emqx:query']">刷新</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="el-icon-plus" size="mini" :disabled="single" @click="handleAdd" v-hasPermi="['iot:emqx:add']">添加订阅</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-table v-loading="loadSubscribeing" :data="subscribeList">
|
||||
<el-table-column label="主题" align="center" prop="topic" />
|
||||
<el-table-column label="QoS" align="center" prop="qos" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="150">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="small" type="danger" style="padding: 5px" v-hasPermi="['iot:emqx:remove']" @click="handleUnsubscribe(scope.row)">
|
||||
<svg-icon icon-class="disconnect" /> 取消订阅
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-dialog>
|
||||
</el-card>
|
||||
|
||||
<!-- 添加或修改订阅对话框 -->
|
||||
<el-dialog title="添加订阅" :visible.sync="subscribeOpen" width="800px" append-to-body>
|
||||
<el-form ref="subscribeForm" :model="subscribeForm" :rules="rules" label-width="60px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="主题" prop="topic">
|
||||
<el-input v-model="subscribeForm.topic" placeholder="请输入主题" />
|
||||
</el-form-item>
|
||||
<el-form-item label="Qos" prop="qos">
|
||||
<el-select v-model="subscribeForm.qos" placeholder="请选择消息类型">
|
||||
<el-option key="0" label="0" value="0"></el-option>
|
||||
<el-option key="1" label="1" value="1"></el-option>
|
||||
<el-option key="2" label="2" value="2"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">添 加 订 阅</el-button>
|
||||
<el-button @click="cancelSubscribe">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
listMqttClient,
|
||||
eliminateClient,
|
||||
getClientDetails,
|
||||
getSubscriptionsByClientId,
|
||||
unsubscribe,
|
||||
addSubscribe,
|
||||
} from "@/api/iot/emqx";
|
||||
|
||||
export default {
|
||||
name: "Category",
|
||||
data() {
|
||||
return {
|
||||
// 非单个禁用
|
||||
single: true,
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
loadSubscribeing: true,
|
||||
// 显示搜索条件
|
||||
showSearch: true,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 产品分类表格数据
|
||||
clientList: [],
|
||||
// 弹出层标题
|
||||
title: "",
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 是否显示添加订阅弹出层
|
||||
subscribeOpen: false,
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
_limit: 10,
|
||||
_page: 1,
|
||||
clientid:null,
|
||||
},
|
||||
// 表单参数
|
||||
form: {},
|
||||
// 选中选项卡
|
||||
activeName: "basic",
|
||||
//订阅列表数据
|
||||
subscribeList: [],
|
||||
//订阅数据
|
||||
subscribe: {
|
||||
topic: "",
|
||||
clientid: "",
|
||||
},
|
||||
//添加订阅表单参数
|
||||
subscribeForm: {
|
||||
qos: "0",
|
||||
},
|
||||
//客户端ID
|
||||
clientid: "",
|
||||
// 表单校验
|
||||
rules: {
|
||||
topic: [{
|
||||
required: true,
|
||||
message: "主题不能为空",
|
||||
trigger: "blur",
|
||||
}, ],
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
/** 查询客户端列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listMqttClient(this.queryParams).then((response) => {
|
||||
this.clientList = response.data.data;
|
||||
this.total = response.data.meta.count;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
/** 查询客户端订阅列表 */
|
||||
getSubscribeList(clientid) {
|
||||
this.clientid = clientid;
|
||||
this.loadSubscribeing = true;
|
||||
getSubscriptionsByClientId(clientid).then((res) => {
|
||||
this.subscribeList = res.data.data;
|
||||
this.loadSubscribeing = false;
|
||||
});
|
||||
},
|
||||
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
this.open = false;
|
||||
this.reset();
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm("queryForm");
|
||||
this.handleQuery();
|
||||
},
|
||||
/** 断开客户端连接 */
|
||||
handleDelete(row) {
|
||||
const clientid = row.clientid;
|
||||
this.$modal
|
||||
.confirm('是否确认删除MQTT客户端编号为"' + clientid + '"的数据项?')
|
||||
.then(function () {
|
||||
return eliminateClient(clientid);
|
||||
})
|
||||
.then(() => {
|
||||
this.getList();
|
||||
this.$modal.msgSuccess("删除成功");
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
//取消主题订阅
|
||||
handleUnsubscribe(row) {
|
||||
const clientid = row.clientid;
|
||||
const topic = row.topic;
|
||||
this.$modal
|
||||
.confirm('是否确认取消订阅主题为"' + topic + '"的数据项?')
|
||||
.then(function () {
|
||||
const param = {};
|
||||
param.topic = topic;
|
||||
param.clientid = clientid;
|
||||
return unsubscribe(param);
|
||||
})
|
||||
.then(() => {
|
||||
this.getSubscribeList(clientid);
|
||||
this.$modal.msgSuccess("取消订阅成功");
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
//查看客户端详情
|
||||
handleOpen(row) {
|
||||
const clientid = row.clientid;
|
||||
this.getSubscribeList(clientid);
|
||||
getClientDetails(clientid).then((response) => {
|
||||
this.form = response.data.data[0];
|
||||
this.open = true;
|
||||
this.title = "详情";
|
||||
});
|
||||
},
|
||||
//刷新订阅列表
|
||||
handleRefresh() {
|
||||
this.getSubscribeList(this.clientid);
|
||||
},
|
||||
//添加订阅
|
||||
handleAdd() {
|
||||
this.subscribeOpen = true;
|
||||
},
|
||||
//提交添加订阅表单
|
||||
submitForm() {
|
||||
this.subscribeForm.clientid = this.clientid;
|
||||
console.log(this.subscribeForm);
|
||||
this.$refs["subscribeForm"].validate((valid) => {
|
||||
if (valid) {
|
||||
addSubscribe(this.subscribeForm).then((response) => {
|
||||
this.$modal.msgSuccess("新增订阅成功");
|
||||
this.subscribeOpen = false;
|
||||
this.getSubscribeList(this.clientid);
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
cancelSubscribe() {
|
||||
this.subscribeOpen = false;
|
||||
this.resetForm("subscribeForm");
|
||||
//刷新列表
|
||||
this.getSubscribeList(this.clientid);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -1,80 +0,0 @@
|
||||
<template>
|
||||
<div style="padding:6px;">
|
||||
<el-card style="padding-bottom:100px;">
|
||||
<el-table v-loading="loading" :data="listenerList">
|
||||
<el-table-column label="协议" align="center" prop="protocol" />
|
||||
<el-table-column label="监听地址" align="center" prop="listen_on" />
|
||||
<el-table-column label="最大连接数" align="center" prop="max_conns" />
|
||||
<el-table-column label="当前连接数" align="center" prop="current_conns"/>
|
||||
<el-table-column label="连接成功数" align="center" prop="acceptors" />
|
||||
<el-table-column label="账号错误数" align="center" prop="shutdown_count.bad_username_or_password" />
|
||||
<el-table-column label="功能错误数" align="center" prop="shutdown_count.function_clause" />
|
||||
<el-table-column label="SSL关闭数" align="center" prop="shutdown_count.ssl_closed" />
|
||||
</el-table>
|
||||
|
||||
<!-- 添加或修改产品分类对话框 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
||||
<el-form ref="form" :model="form" label-width="80px">
|
||||
<el-form-item label="分类名称" prop="categoryName">
|
||||
<el-input v-model="form.categoryName" placeholder="请输入产品分类名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="显示顺序" prop="orderNum">
|
||||
<el-input v-model="form.orderNum" placeholder="请输入显示顺序" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="cancel">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import{listMqttListener} from "@/api/iot/emqx"
|
||||
|
||||
|
||||
export default {
|
||||
name: "Category",
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 显示搜索条件
|
||||
showSearch: true,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 列表
|
||||
listenerList: [],
|
||||
// 弹出层标题
|
||||
title: "",
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 表单参数
|
||||
form: {},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
|
||||
},
|
||||
methods: {
|
||||
/** 查询客户端列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listMqttListener().then(response => {
|
||||
this.listenerList=response.data.data[0].listeners;
|
||||
console.log(response);
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
this.open = false;
|
||||
this.reset();
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,137 +0,0 @@
|
||||
<template>
|
||||
<div style="padding:6px;">
|
||||
<el-card style="padding-bottom:100px;">
|
||||
<el-table v-loading="loading" :data="pluginList">
|
||||
<el-table-column label="插件名称" align="center" prop="name" width="300" />
|
||||
<el-table-column label="版本" align="center" prop="version" width="100" />
|
||||
<el-table-column label="类型" align="center" prop="type" width="120" />
|
||||
<el-table-column label="状态" align="center" prop="active" width="150">
|
||||
<template slot-scope="scope">
|
||||
<el-tag type="success" v-if="scope.row.active">运行中</el-tag>
|
||||
<el-tag type="info" v-else>已停止</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="描述" align="left" prop="description" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="150">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="small" type="success" style="padding:5px;" @click="loadMqttPlugin(scope.row.name)" v-if="!scope.row.active" v-hasPermi="['iot:emqx:edit']">
|
||||
<svg-icon icon-class="start" /> 启动
|
||||
</el-button>
|
||||
<el-button size="small" type="danger" style="padding:5px;"
|
||||
@click="unloadMqttPlugin(scope.row.name)"
|
||||
v-hasPermi="['iot:emqx:edit']"
|
||||
v-if="scope.row.active"
|
||||
:disabled="scope.row.name=='emqx_auth_http' || scope.row.name=='emqx_web_hook' || scope.row.name=='emqx_rule_engine' || scope.row.name=='emqx_management'">
|
||||
<svg-icon icon-class="stop" /> 停止
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 添加或修改产品分类对话框 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
||||
<el-form ref="form" :model="form" label-width="80px">
|
||||
<el-form-item label="分类名称" prop="categoryName">
|
||||
<el-input v-model="form.categoryName" placeholder="请输入产品分类名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="显示顺序" prop="orderNum">
|
||||
<el-input v-model="form.orderNum" placeholder="请输入显示顺序" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="cancel">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
listMqttPlugin,
|
||||
loadMqttPlugin,
|
||||
unloadMqttPlugin
|
||||
} from "@/api/iot/emqx"
|
||||
|
||||
export default {
|
||||
name: "Category",
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 显示搜索条件
|
||||
showSearch: true,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 列表
|
||||
pluginList: [],
|
||||
// 节点名称
|
||||
node: "",
|
||||
// 弹出层标题
|
||||
title: "",
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 表单参数
|
||||
form: {},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
|
||||
},
|
||||
methods: {
|
||||
/** 查询客户端列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listMqttPlugin().then(response => {
|
||||
this.pluginList = response.data.data[0].plugins;
|
||||
this.node = response.data.data[0].node;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
/** 启用插件*/
|
||||
loadMqttPlugin(plugin) {
|
||||
this.$confirm('是否启用插件:' + plugin + ' ?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
loadMqttPlugin(this.node, plugin).then(response => {
|
||||
if (response.data.code == 0) {
|
||||
this.getList();
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '成功启用插件!'
|
||||
});
|
||||
}
|
||||
})
|
||||
}).catch(() => {});
|
||||
},
|
||||
/** 卸载插件*/
|
||||
unloadMqttPlugin(plugin) {
|
||||
this.$confirm('是否停止插件:' + plugin + ' ?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
unloadMqttPlugin(this.node, plugin).then(response => {
|
||||
if (response.data.code == 0) {
|
||||
this.getList();
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '成功停止插件!'
|
||||
});
|
||||
}
|
||||
})
|
||||
}).catch(() => {});
|
||||
},
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
this.open = false;
|
||||
this.reset();
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,860 +0,0 @@
|
||||
<template>
|
||||
<div style="padding: 6px">
|
||||
<el-card style="padding-bottom: 100px">
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="el-icon-refresh" size="mini" @click="getList" v-hasPermi="['iot:emqx:query']">刷新</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="addResource" v-hasPermi="['iot:emqx:add']">新增</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-table v-loading="loading" :data="resourceList">
|
||||
<el-table-column label="ID" align="center" header-align="center" prop="id">
|
||||
<template slot-scope="scope">
|
||||
<el-link :underline="false" type="primary" @click="handleQuery(scope.row)">{{ scope.row.id }}</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="资源类型" align="center" prop="type" />
|
||||
<el-table-column label="备注" align="center" prop="description" />
|
||||
<el-table-column label="操作" align="center" width="200">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="small" type="text" icon="el-icon-connection" style="padding: 5px" v-hasPermi="['iot:emqx:edit']" @click="checkStatus(scope.row)">状态
|
||||
</el-button>
|
||||
<el-button size="small" type="text" icon="el-icon-delete" style="padding: 5px" v-hasPermi="['iot:emqx:remove']" @click="handleDelete(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<!-- 资源详细 -->
|
||||
<el-dialog title="资源详细" :visible.sync="openView" width="800px" append-to-body>
|
||||
<el-form ref="form" :model="form" label-width="180px" size="mini">
|
||||
<el-card style="padding-bottom: 10px">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>基础信息</span>
|
||||
</div>
|
||||
<el-row>
|
||||
<el-col :span="20">
|
||||
<el-form-item label="ID:">{{ form.id }}</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="20">
|
||||
<el-form-item label="资源类型:">{{ form.type }}</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="20">
|
||||
<el-form-item label="备注:">{{ form.description }}</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
<el-card style="padding-bottom: 10px; margin-top: 10px">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>配置信息</span>
|
||||
</div>
|
||||
<el-row>
|
||||
<el-col :span="20">
|
||||
<el-form-item label="reconnect_interval:">{{ form.config.reconnect_interval}}</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="20">
|
||||
<el-form-item label="pool_size:">{{ form.config.pool_size }}</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="20">
|
||||
<el-form-item label="mountpoint:">{{ form.config.mountpoint}}</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="20">
|
||||
<el-form-item label="disk_cache:">{{ form.config.disk_cache }}</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="20">
|
||||
<el-form-item label="batch_size:">{{ form.config.batch_size }}</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="20">
|
||||
<el-form-item label="address:">{{ form.config.address}}</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="openView = false" type="success">确 认</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 测试重连 -->
|
||||
<el-dialog title="检测状态" :visible.sync="openStatusView" width="600px" append-to-body>
|
||||
<el-form ref="statusForm" :model="statusForm" label-width="180px" size="mini" v-if="statusForm.status[0]">
|
||||
{{ statusForm.status[0].node }}
|
||||
<el-tag type="success" v-if="statusForm.status[0].is_alive == true" style="margin-left: 10px">可用</el-tag>
|
||||
<el-tag type="danger" v-if="statusForm.status[0].is_alive == false" style="margin-left: 10px">不可用</el-tag>
|
||||
<el-button size="small" type="primary" icon="el-icon-connection" style="padding: 5px; margin-left: 10px" v-hasPermi="['iot:emqx:edit']" @click="checkNode(statusForm.id)">重新连接
|
||||
</el-button>
|
||||
</el-form>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 添加资源 -->
|
||||
<el-dialog title="资源管理" :visible.sync="openAddView" width="800px" append-to-body :before-close="cancel">
|
||||
<el-form ref="addResourceForm" :model="addResourceForm" label-width="180px" :rules="rule">
|
||||
<el-card style="padding-bottom: 10px">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>择取资源类型</span>
|
||||
</div>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="资源类型" prop="resource.title">
|
||||
<el-select v-model="addResourceForm.resource.title" @change="selectTitle" placeholder="请选择资源类型">
|
||||
<el-option v-for="(resource, index) in addResourceForm.resource" :key="index" :label="resource.title.zh" :value="resource.name"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item>
|
||||
<el-button type="success" @click="testConnect('addResourceForm')">测试连接</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</el-form>
|
||||
<el-form ref="EMQXForm" :model="EMQXForm" label-width="180px" :rules="ruleEMQX">
|
||||
<el-card style="padding-bottom: 10px; margin-top: 10px" v-if="EMQXForm.params" v-show="openEMQXView">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>具体信息</span>
|
||||
</div>
|
||||
|
||||
<el-row>
|
||||
<el-col :span="10">
|
||||
<el-form-item prop="params.address.default">
|
||||
<span slot="label">
|
||||
<el-tooltip :content="EMQXForm.params.address.description.zh" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
EMQ X节点名称:
|
||||
</span>
|
||||
<el-input v-model="EMQXForm.params.address.default" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="params.pool_size.default">
|
||||
<span slot="label">
|
||||
<el-tooltip :content="EMQXForm.params.pool_size.description.zh" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
连接池大小:
|
||||
</span>
|
||||
<el-input v-model="EMQXForm.params.pool_size.default" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-form-item prop="params.mountpoint.default">
|
||||
<span slot="label">
|
||||
<el-tooltip :content="EMQXForm.params.mountpoint.description.zh" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
桥接挂载点:
|
||||
</span>
|
||||
<el-input v-model="EMQXForm.params.mountpoint.default" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="EMQreconnect_interval">
|
||||
<span slot="label">
|
||||
<el-tooltip :content="EMQXForm.params.reconnect_interval.description.zh" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
重连间隔:
|
||||
</span>
|
||||
<el-input v-model="EMQXForm.params.reconnect_interval.default" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-form-item prop="EMQbatch_size">
|
||||
<span slot="label">
|
||||
<el-tooltip :content="EMQXForm.params.batch_size.description.zh" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
批处理大小:
|
||||
</span>
|
||||
<el-input v-model="EMQXForm.params.batch_size.default" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注:">
|
||||
<el-input v-model="EMQXForm.description" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-form-item prop="EMQdisk_cache">
|
||||
<span slot="label">
|
||||
<el-tooltip :content="EMQXForm.params.disk_cache.description.zh" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
磁盘缓存:
|
||||
</span>
|
||||
<el-select v-model="EMQXForm.params.disk_cache.default">
|
||||
<el-option v-for="(enums, index) in EMQXForm.params.disk_cache.enum" :key="index" :label="enums" :value="enums"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</el-form>
|
||||
<el-form ref="MQTTForm" :model="MQTTForm" label-width="180px" :rules="ruleMQTT">
|
||||
<el-card style="padding-bottom: 10px; margin-top: 10px" v-if="MQTTForm.params" v-show="openMQTTView">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>具体信息</span>
|
||||
</div>
|
||||
<el-row>
|
||||
<el-col :span="10">
|
||||
<el-form-item prop="params.address.default">
|
||||
<span slot="label">
|
||||
<el-tooltip :content="MQTTForm.params.address.description.zh" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
远程broker地址:
|
||||
</span>
|
||||
<el-input v-model="MQTTForm.params.address.default" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<span slot="label">
|
||||
<el-tooltip :content="MQTTForm.params.disk_cache.description.zh" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
磁盘缓存:
|
||||
</span>
|
||||
<el-select v-model="MQTTForm.params.disk_cache.default">
|
||||
<el-option v-for="(enums, index) in MQTTForm.params.disk_cache.enum" :key="index" :label="enums" :value="enums"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-form-item>
|
||||
<span slot="label">
|
||||
<el-tooltip :content="MQTTForm.params.proto_ver.description.zh" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
协议版本:
|
||||
</span>
|
||||
<el-select v-model="MQTTForm.params.proto_ver.default">
|
||||
<el-option v-for="(enums, index) in MQTTForm.params.proto_ver.enum" :key="index" :label="enums" :value="enums"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<span slot="label">
|
||||
<el-tooltip :content="MQTTForm.params.clientid.description.zh" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
客户端ID:
|
||||
</span>
|
||||
<el-input v-model="MQTTForm.params.clientid.default" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-form-item>
|
||||
<span slot="label">
|
||||
<el-tooltip :content="MQTTForm.params.username.description.zh" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
用户名:
|
||||
</span>
|
||||
<el-input v-model="MQTTForm.params.username.default" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="params.mountpoint.default">
|
||||
<span slot="label">
|
||||
<el-tooltip :content="MQTTForm.params.mountpoint.description.zh" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
桥接挂载点:
|
||||
</span>
|
||||
<el-input v-model="MQTTForm.params.mountpoint.default" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-form-item>
|
||||
<span slot="label">
|
||||
<el-tooltip :content="MQTTForm.params.password.description.zh" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
密码:
|
||||
</span>
|
||||
<el-input v-model="MQTTForm.params.password.default" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="params.keepalive.default">
|
||||
<span slot="label">
|
||||
<el-tooltip :content="MQTTForm.params.keepalive.description.zh" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
心跳间隔:
|
||||
</span>
|
||||
<el-input v-model="MQTTForm.params.keepalive.default" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="10">
|
||||
<el-form-item>
|
||||
<span slot="label">
|
||||
<el-tooltip :content="MQTTForm.params.reconnect_interval.description.zh" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
重连间隔:
|
||||
</span>
|
||||
<el-input v-model="MQTTForm.params.reconnect_interval.default" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<span slot="label">
|
||||
<el-tooltip :content="MQTTForm.params.bridge_mode.description.zh" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
桥接模式:
|
||||
</span>
|
||||
<el-select v-model="MQTTForm.params.bridge_mode.default">
|
||||
<el-option key="false" label="false" value="false"></el-option>
|
||||
<el-option key="true" label="true" value="true"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="10">
|
||||
<el-form-item>
|
||||
<span slot="label">
|
||||
<el-tooltip :content="MQTTForm.params.retry_interval.description.zh" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
重传间隔:
|
||||
</span>
|
||||
<el-input v-model="MQTTForm.params.retry_interval.default" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="params.ssl.default">
|
||||
<span slot="label">
|
||||
<el-tooltip :content="MQTTForm.params.ssl.description.zh" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
Bridge SSL:
|
||||
</span>
|
||||
<el-select v-model="MQTTForm.params.ssl.default">
|
||||
<el-option v-for="(enums, index) in MQTTForm.params.ssl.enum" :key="index" :label="enums" :value="enums"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="10">
|
||||
<el-form-item>
|
||||
<span slot="label">
|
||||
<el-tooltip :content="MQTTForm.params.cacertfile.description.zh" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
CA证书:
|
||||
</span>
|
||||
<el-input v-model="MQTTForm.params.cacertfile.default" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<span slot="label">
|
||||
<el-tooltip :content="MQTTForm.params.keyfile.description.zh" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
SSL 密钥文件:
|
||||
</span>
|
||||
<el-input v-model="MQTTForm.params.keyfile.default" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="10">
|
||||
<el-form-item>
|
||||
<span slot="label">
|
||||
<el-tooltip :content="MQTTForm.params.certfile.description.zh" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
SSL 客户端证书:
|
||||
</span>
|
||||
<el-input v-model="MQTTForm.params.certfile.default" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<span slot="label">
|
||||
<el-tooltip :content="MQTTForm.params.ciphers.description.zh" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
SSL 加密算法 :
|
||||
</span>
|
||||
<el-input v-model="MQTTForm.params.ciphers.default" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-form-item label="备注:">
|
||||
<el-input v-model="MQTTForm.description" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</el-form>
|
||||
<el-form ref="WebHookForm" :model="WebHookForm" label-width="180px" :rules="ruleWebHook">
|
||||
<el-card style="padding-bottom: 10px; margin-top: 10px" v-if="WebHookForm.params" v-show="openWebView">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>具体信息</span>
|
||||
</div>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="params.url.default">
|
||||
<span slot="label">
|
||||
<el-tooltip :content="WebHookForm.params.url.description.zh" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
请求 URL:
|
||||
</span>
|
||||
<el-input v-model="WebHookForm.params.url.default" placeholder="http://" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="请求方法:">
|
||||
<span slot="label">
|
||||
<el-tooltip :content="WebHookForm.params.method.description.zh" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
请求方法:
|
||||
</span>
|
||||
<el-select v-model="WebHookForm.params.method.default">
|
||||
<el-option v-for="(enums, index) in WebHookForm.params.method.enum" :key="index" :label="enums" :value="enums"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="20">
|
||||
<el-form-item label="请求头:" prop="ket_value">
|
||||
<el-row v-for="(item, index) in ket_value" :key="index" style="margin-bottom: 10px">
|
||||
<el-col :span="8">
|
||||
<el-input v-model="item.key" placeholder="键" />
|
||||
</el-col>
|
||||
<el-col :span="12" :offset="1">
|
||||
<el-input v-model="item.value" placeholder="值" />
|
||||
</el-col>
|
||||
<el-col :span="2" :offset="1" v-if="index != 0"><a style="color: #f56c6c" @click="removeHeaderItem(index)">删除</a></el-col>
|
||||
</el-row>
|
||||
<div>
|
||||
+
|
||||
<a style="color: #409eff" @click="addHeader()">添加请求头</a>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="备注:">
|
||||
<el-input v-model="WebHookForm.description" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
<el-button type="success" @click="saveResource('EMQXForm')" v-if="openEMQXView" :loading="showloading">新建</el-button>
|
||||
<el-button type="success" @click="saveResource('MQTTForm')" v-if="openMQTTView" :loading="showloading">新建</el-button>
|
||||
<el-button type="success" @click="saveResource('WebHookForm')" v-if="openWebView" :loading="showloading">新建</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getResources,
|
||||
getResourcesStatus,
|
||||
getConnectResource,
|
||||
deleteResource,
|
||||
getResourcesType,
|
||||
getResourcesConnect,
|
||||
saveResources,
|
||||
} from "@/api/iot/emqx";
|
||||
|
||||
export default {
|
||||
name: "Resource",
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 新建按钮等待效果
|
||||
showloading: false,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 规则表格数据
|
||||
resourceList: [],
|
||||
// 弹出层标题
|
||||
title: "",
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 是否显示详细弹出层
|
||||
openView: false,
|
||||
// 是否显示检测状态弹出层
|
||||
openStatusView: false,
|
||||
// 是否显示添加资源弹出层
|
||||
openAddView: false,
|
||||
// 是否显示EMQX Bridge弹出层
|
||||
openEMQXView: false,
|
||||
// 是否显示MQTT Bridge弹出层
|
||||
openMQTTView: false,
|
||||
// 是否显示WebHook弹出层
|
||||
openWebView: false,
|
||||
//表单数据
|
||||
form: {
|
||||
config: {},
|
||||
},
|
||||
statusForm: {
|
||||
status: [],
|
||||
},
|
||||
//添加资源表单数据
|
||||
addResourceForm: {
|
||||
resource: [],
|
||||
type: "",
|
||||
},
|
||||
//添加EMQX资源表单数据
|
||||
EMQXForm: {
|
||||
description: "",
|
||||
},
|
||||
//添加MQTT资源表单数据
|
||||
MQTTForm: {
|
||||
description: "",
|
||||
},
|
||||
//添加WebHook资源表单数据
|
||||
WebHookForm: {
|
||||
description: "",
|
||||
},
|
||||
ket_value: [],
|
||||
//添加资源表单数据
|
||||
emqxParam: {
|
||||
description: "",
|
||||
name: "",
|
||||
type: "",
|
||||
config: {},
|
||||
},
|
||||
ruleEMQX: {
|
||||
params: {
|
||||
address: {
|
||||
default: [{
|
||||
required: true,
|
||||
message: "请输入EMQ X节点名称",
|
||||
trigger: "blur",
|
||||
}, ],
|
||||
},
|
||||
pool_size: {
|
||||
default: [{
|
||||
required: true,
|
||||
message: "请输入连接池大小",
|
||||
trigger: "blur",
|
||||
}, ],
|
||||
},
|
||||
mountpoint: {
|
||||
default: [{
|
||||
required: true,
|
||||
message: "请输入桥接挂载点",
|
||||
trigger: "blur",
|
||||
}, ],
|
||||
},
|
||||
},
|
||||
},
|
||||
ruleMQTT: {
|
||||
params: {
|
||||
address: {
|
||||
default: [{
|
||||
required: true,
|
||||
message: "请输入远程 broker 地址",
|
||||
trigger: "blur",
|
||||
}, ],
|
||||
},
|
||||
mountpoint: {
|
||||
default: [{
|
||||
required: true,
|
||||
message: "请输入桥接挂载点",
|
||||
trigger: "blur",
|
||||
}, ],
|
||||
},
|
||||
ssl: {
|
||||
default: [{
|
||||
required: true,
|
||||
message: "请选择Bridge SSL",
|
||||
trigger: "change",
|
||||
}, ],
|
||||
},
|
||||
keepalive: {
|
||||
default: [{
|
||||
required: true,
|
||||
message: "请输入心跳间隔",
|
||||
trigger: "blur",
|
||||
}, ],
|
||||
},
|
||||
},
|
||||
},
|
||||
ruleWebHook: {
|
||||
params: {
|
||||
url: {
|
||||
default: [{
|
||||
required: true,
|
||||
message: "请输入请求 URL",
|
||||
trigger: "blur",
|
||||
}, ],
|
||||
},
|
||||
},
|
||||
},
|
||||
rule: {
|
||||
resource: {
|
||||
title: [{
|
||||
required: true,
|
||||
message: "请选择资源类型",
|
||||
trigger: "change"
|
||||
}, ],
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
/** 查询规则列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
getResources("").then((response) => {
|
||||
this.resourceList = response.data.data;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
/** 查看按钮操作 */
|
||||
handleQuery(row) {
|
||||
this.form = row;
|
||||
this.openView = true;
|
||||
},
|
||||
/** 状态按钮操作 */
|
||||
checkStatus(row) {
|
||||
let resourceId = row.id;
|
||||
getResourcesStatus(resourceId).then((response) => {
|
||||
this.statusForm = response.data.data;
|
||||
this.openStatusView = true;
|
||||
});
|
||||
},
|
||||
//删除按钮操作
|
||||
handleDelete(row) {
|
||||
let resourceId = row.id;
|
||||
this.$modal
|
||||
.confirm('是否确认删除ID为"' + resourceId + '"的规则引擎?')
|
||||
.then(function () {
|
||||
return deleteResource(resourceId);
|
||||
})
|
||||
.then(() => {
|
||||
this.getList();
|
||||
this.$modal.msgSuccess("删除资源成功");
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
/** 重新连接资源按钮操作 */
|
||||
checkNode(resourceId) {
|
||||
getConnectResource(resourceId).then((response) => {
|
||||
let code = response.data.code;
|
||||
if (code !== 0) {
|
||||
this.$modal.msgError(response.data.message);
|
||||
} else {
|
||||
this.$modal.msgSuccess("连接资源成功");
|
||||
}
|
||||
});
|
||||
},
|
||||
/** 跳转添加资源页面 */
|
||||
addResource() {
|
||||
getResourcesType().then((res) => {
|
||||
this.addResourceForm.resource = res.data.data;
|
||||
this.EMQXForm.params = res.data.data[0].params;
|
||||
this.MQTTForm.params = res.data.data[1].params;
|
||||
this.WebHookForm.params = res.data.data[2].params;
|
||||
this.openAddView = true;
|
||||
});
|
||||
},
|
||||
|
||||
/** 选择资源类型 */
|
||||
selectTitle(val) {
|
||||
this.addResourceForm.type = val;
|
||||
if ("bridge_rpc" === val) {
|
||||
this.openEMQXView = true;
|
||||
this.openMQTTView = false;
|
||||
this.openWebView = false;
|
||||
} else if ("bridge_mqtt" === val) {
|
||||
this.openEMQXView = false;
|
||||
this.openMQTTView = true;
|
||||
this.openWebView = false;
|
||||
} else if ("web_hook" === val) {
|
||||
this.openEMQXView = false;
|
||||
this.openMQTTView = false;
|
||||
this.openWebView = true;
|
||||
}
|
||||
},
|
||||
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
//初始化
|
||||
this.openEMQXView = false;
|
||||
this.openMQTTView = false;
|
||||
this.openWebView = false;
|
||||
this.openAddView = false;
|
||||
this.EMQXForm = {};
|
||||
this.MQTTForm = {};
|
||||
this.WebHookForm = {};
|
||||
this.addResourceForm.resource = [];
|
||||
this.addResourceForm.description = "";
|
||||
this.$refs['addResourceForm'].resetFields();
|
||||
},
|
||||
|
||||
//测试连接
|
||||
testConnect(formName) {
|
||||
this.$refs[formName].validate((valid) => {
|
||||
if (valid) {
|
||||
this.insertOrTestResourceUtils('test');
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
/** 添加请求头 */
|
||||
addHeader() {
|
||||
this.ket_value.push({
|
||||
key: "",
|
||||
value: "",
|
||||
});
|
||||
},
|
||||
/** 删除请求头 */
|
||||
removeHeaderItem(index) {
|
||||
this.ket_value.splice(index, 1);
|
||||
},
|
||||
|
||||
//新建资源
|
||||
saveResource(formName) {
|
||||
this.showloading = true;
|
||||
//校验表单
|
||||
this.$refs[formName].validate((valid) => {
|
||||
if (valid) {
|
||||
this.insertOrTestResourceUtils('save');
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
// 新增资源或者测试连接公共方法
|
||||
insertOrTestResourceUtils(type) {
|
||||
this.emqxParam.type = this.addResourceForm.type;
|
||||
//判断选择的资源类型
|
||||
if ("bridge_rpc" === this.addResourceForm.type) {
|
||||
this.emqxParam.description = this.EMQXForm.description;
|
||||
this.emqxParam.config.address = this.EMQXForm.params.address.default;
|
||||
this.emqxParam.config.batch_size =
|
||||
this.EMQXForm.params.batch_size.default;
|
||||
this.emqxParam.config.disk_cache =
|
||||
this.EMQXForm.params.disk_cache.default;
|
||||
this.emqxParam.config.mountpoint =
|
||||
this.EMQXForm.params.mountpoint.default;
|
||||
this.emqxParam.config.pool_size =
|
||||
this.EMQXForm.params.pool_size.default;
|
||||
this.emqxParam.config.reconnect_interval =
|
||||
this.EMQXForm.params.reconnect_interval.default;
|
||||
if ("test" == type) {
|
||||
getResourcesConnect(this.emqxParam).then((res) => {
|
||||
let code = res.data.code;
|
||||
if (0 == code) {
|
||||
this.$modal.msgSuccess("连接成功");
|
||||
} else {
|
||||
this.$modal.msgError(res.data.message);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
saveResources(this.emqxParam).then((res) => {
|
||||
this.showloading = false;
|
||||
let code = res.data.code;
|
||||
if (0 == code) {
|
||||
this.$modal.msgSuccess("添加资源成功");
|
||||
this.getList();
|
||||
this.cancel();
|
||||
} else {
|
||||
this.$modal.msgError(res.data.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if ("bridge_mqtt" === this.addResourceForm.type) {
|
||||
this.emqxParam.description = this.MQTTForm.description;
|
||||
this.emqxParam.config.address = this.MQTTForm.params.address.default;
|
||||
this.emqxParam.config.bridge_mode =
|
||||
this.MQTTForm.params.bridge_mode.default;
|
||||
this.emqxParam.config.cacertfile =
|
||||
this.MQTTForm.params.cacertfile.default;
|
||||
this.emqxParam.config.certfile = this.MQTTForm.params.certfile.default;
|
||||
this.emqxParam.config.ciphers = this.MQTTForm.params.ciphers.default;
|
||||
this.emqxParam.config.clientid = this.MQTTForm.params.clientid.default;
|
||||
this.emqxParam.config.disk_cache =
|
||||
this.MQTTForm.params.disk_cache.default;
|
||||
this.emqxParam.config.keepalive =
|
||||
this.MQTTForm.params.keepalive.default;
|
||||
this.emqxParam.config.keyfile = this.MQTTForm.params.keyfile.default;
|
||||
this.emqxParam.config.mountpoint =
|
||||
this.MQTTForm.params.mountpoint.default;
|
||||
this.emqxParam.config.password = this.MQTTForm.params.password.default;
|
||||
this.emqxParam.config.proto_ver =
|
||||
this.MQTTForm.params.proto_ver.default;
|
||||
this.emqxParam.config.reconnect_interval =
|
||||
this.MQTTForm.params.reconnect_interval.default;
|
||||
this.emqxParam.config.retry_interval =
|
||||
this.MQTTForm.params.retry_interval.default;
|
||||
this.emqxParam.config.ssl = this.MQTTForm.params.ssl.default;
|
||||
this.emqxParam.config.username = this.MQTTForm.params.username.default;
|
||||
if ("test" == type) {
|
||||
getResourcesConnect(this.emqxParam).then((res) => {
|
||||
let code = res.data.code;
|
||||
if (0 == code) {
|
||||
this.$modal.msgSuccess("连接成功");
|
||||
} else {
|
||||
this.$modal.msgError(res.data.message);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
saveResources(this.emqxParam).then((res) => {
|
||||
this.showloading = false;
|
||||
let code = res.data.code;
|
||||
if (0 == code) {
|
||||
this.$modal.msgSuccess("添加资源成功");
|
||||
this.getList();
|
||||
this.cancel();
|
||||
} else {
|
||||
this.$modal.msgError(res.data.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if ("web_hook" === this.addResourceForm.type) {
|
||||
this.emqxParam.description = this.WebHookForm.description;
|
||||
this.emqxParam.config.url = this.WebHookForm.params.url.default;
|
||||
this.emqxParam.config.method = this.WebHookForm.params.method.default;
|
||||
|
||||
//解析数据转换成后端需要的数据格式
|
||||
let headers = {};
|
||||
this.ket_value.forEach((item) => {
|
||||
headers[item.key] = item.value;
|
||||
});
|
||||
this.emqxParam.config.headers = headers;
|
||||
if ("test" == type) {
|
||||
getResourcesConnect(this.emqxParam).then((res) => {
|
||||
let code = res.data.code;
|
||||
if (0 == code) {
|
||||
this.$modal.msgSuccess("连接成功");
|
||||
} else {
|
||||
this.$modal.msgError(res.data.message);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
saveResources(this.emqxParam).then((res) => {
|
||||
this.showloading = false;
|
||||
let code = res.data.code;
|
||||
if (0 == code) {
|
||||
this.$modal.msgSuccess("添加资源成功");
|
||||
this.getList();
|
||||
this.cancel();
|
||||
} else {
|
||||
this.$modal.msgError(res.data.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -1,770 +0,0 @@
|
||||
<template>
|
||||
<div style="padding: 6px">
|
||||
<el-card style="padding-bottom: 100px">
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="el-icon-refresh" size="mini" @click="getList" v-hasPermi="['iot:emqx:query']">刷新</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="getAddRules" v-hasPermi="['iot:emqx:add']">新增</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-table v-loading="loading" :data="rulesList">
|
||||
<el-table-column label="ID" align="center" header-align="center" prop="id" width="150">
|
||||
<template slot-scope="scope">
|
||||
<el-link :underline="false" type="primary" @click="handleQuery(scope.row)">{{scope.row.id }}</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="主题" align="center" prop="for">
|
||||
<template slot-scope="scope">
|
||||
<p v-for="(topic, index) in scope.row.for" :key="index">
|
||||
<el-tag type="warning">{{ topic }}</el-tag>
|
||||
</p>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="SQL" align="center" prop="rawsql" />
|
||||
<el-table-column label="响应动作" align="center" prop="actions" width="250">
|
||||
<template slot-scope="scope">
|
||||
<p v-for="(action, index) in scope.row.actions" :key="index">
|
||||
<el-tag type="success">{{ action.name }}</el-tag>
|
||||
</p>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="已命中" align="center" prop="matched" width="100">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.metrics[0].matched }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="small" type="danger" icon="el-icon-delete" style="padding: 5px" v-hasPermi="['iot:emqx:remove']" @click="handleDelete(scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<!-- 规则引擎详细 -->
|
||||
<el-dialog title="规则引擎详细" :visible.sync="openView" width="800px" append-to-body>
|
||||
<el-form ref="form" :model="form" label-width="120px" size="mini">
|
||||
<el-card style="padding-bottom: 10px">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>基本信息</span>
|
||||
</div>
|
||||
<el-row>
|
||||
<el-col :span="20">
|
||||
<el-form-item label="主题:">
|
||||
<el-tag type="success" v-for="(topic, index) in form.for" :key="index">{{ topic }}</el-tag>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="20">
|
||||
<el-form-item label="备注:">{{ form.description }}</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="20">
|
||||
<el-form-item label="规则SQL:">{{ form.rawsql }}</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
<el-card style="padding-bottom: 10px; margin-top: 10px">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>度量指标</span>
|
||||
</div>
|
||||
<el-table :data="form.metrics">
|
||||
<el-table-column label="节点" align="center" prop="node" />
|
||||
<el-table-column label="已命中" align="center" prop="matched" />
|
||||
<el-table-column label="命中速度" align="center" prop="speed" />
|
||||
<el-table-column label="最大命中速度" align="center" prop="speed_max" />
|
||||
<el-table-column label="5分钟平均速度" align="center" prop="speed_last5m" />
|
||||
</el-table>
|
||||
</el-card>
|
||||
<el-card style="padding-bottom: 10px; margin-top: 10px">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>响应动作</span>
|
||||
</div>
|
||||
<el-table :data="form.actions">
|
||||
<el-table-column label="类型" align="center" prop="name" />
|
||||
<el-table-column label="参数" align="center" prop="params">
|
||||
<template slot-scope="scope">
|
||||
{{scope.row.params}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="度量指标" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-tag type="success">{{ scope.row.metrics[0].node }}</el-tag><br />
|
||||
合计: 成功:<el-tag type="success">{{ scope.row.metrics[0].success }}</el-tag>
|
||||
失败:<el-tag type="danger">{{ scope.row.metrics[0].failed }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="openView = false">关 闭</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 添加规则引擎 -->
|
||||
<el-dialog title="添加规则引擎" :visible.sync="openAddView" width="1000px" append-to-body :before-close="cancel">
|
||||
<el-card style="margin-bottom:10px;">
|
||||
<div slot="header" class="clearfix">
|
||||
<span style="font-size:16px;font-weight:bold;">条件</span>
|
||||
<span style="font-size:12px;margin-left:12px;">使用 SQL 定义规则条件与数据处理方式</span>
|
||||
</div>
|
||||
<el-form ref="form" :model="form" label-width="90px">
|
||||
<el-row :gutter="30">
|
||||
<el-col :span="13">
|
||||
<el-form-item prop="sql_example">
|
||||
<span slot="label"> 规则 SQL: </span>
|
||||
<CodeMirrorEditor :value="form.sql_example" myMode="text/x-mysql" height="400" style="border:1px solid #ddd;" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="sql_example">
|
||||
<span slot="label"> 备注: </span>
|
||||
<el-input v-model="form.note" placeholder="e.g.消息转发到WebHook" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="SQLtest">
|
||||
<span slot="label">
|
||||
SQL测试:
|
||||
</span>
|
||||
<el-switch v-model="form.SQLtest" active-text="" inactive-text="" :active-value="true" :inactive-value="false" active-color="#13ce66">
|
||||
</el-switch>
|
||||
<span style="font-size:12px;margin-left:10px;">自定义模拟数据进行 SQL 命令测试,仅用于测试功能</span>
|
||||
</el-form-item>
|
||||
|
||||
</el-col>
|
||||
<el-col :span="11">
|
||||
<div class="sql-tips">
|
||||
<div>编写 SQL 进行条件过滤与数据处理</div>
|
||||
<div class="doc-wrapper">
|
||||
<p>
|
||||
EMQ X
|
||||
在消息发布、事件触发时将触发规则引擎,满足触发条件的规则将执行各自的
|
||||
SQL 语句筛选并处理消息和事件的上下文信息。
|
||||
</p>
|
||||
<p>
|
||||
规则引擎借助响应动作可将特定主题的消息处理结果存储到数据库,发送到
|
||||
HTTP Server,转发到消息队列 Kafka 或
|
||||
RabbitMQ,重新发布到新的主题甚至是另一个 Broker
|
||||
集群中,每个规则可以配置多个响应动作。
|
||||
</p>
|
||||
<p>
|
||||
1. 选择发布到 't/#' 主题的消息,并筛选出全部字段:
|
||||
</p>
|
||||
<div class="code">
|
||||
<code>SELECT * FROM "t/#"</code>
|
||||
</div>
|
||||
<p>
|
||||
2. 选择发布到 't/a' 主题的消息,并从 JSON
|
||||
格式的消息内容中筛选出 "x" 字段:
|
||||
</p>
|
||||
<div class="code">
|
||||
<code>SELECT payload.x as x FROM "t/a"</code>
|
||||
</div>
|
||||
<p>
|
||||
规则引擎使用 $events/ 开头的虚拟主题(事件主题)处理
|
||||
EMQ X
|
||||
内置事件,内置事件提供更精细的消息控制和客户端动作处理能力,可用在
|
||||
QoS 1 QoS 2 的消息抵达记录、设备上下线记录等业务中。
|
||||
</p>
|
||||
<p>
|
||||
1. 选择客户端连接事件,筛选 Username 为 'emqx'
|
||||
的设备并获取连接信息:
|
||||
</p>
|
||||
<div class="code">
|
||||
<code>SELECT clientid, connected_at FROM
|
||||
"$events/client_connected" WHERE username =
|
||||
'emqx'</code>
|
||||
</div>
|
||||
<p>规则引擎和 SQL 语句的详细教程参见 EMQ X 文档。</p>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row v-if="form.SQLtest" style="background-color:#f8f8f8;margin:-20px;">
|
||||
<el-col :span="13">
|
||||
<el-form-item prop="test_columns.username" v-if="form.test_columns">
|
||||
<span slot="label"> username </span>
|
||||
<el-input v-model="form.test_columns.username" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="test_columns.topic" v-if="form.test_columns">
|
||||
<span slot="label"> topic</span>
|
||||
<el-input v-model="form.test_columns.topic" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="test_columns.payload" v-if="form.test_columns">
|
||||
<span slot="label"> payload</span>
|
||||
<CodeMirrorEditor :value="form.test_columns.payload" myMode="application/json" height="150" style="border:1px solid #ddd;" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="11">
|
||||
<el-form-item prop="test_columns.clientid" v-if="form.test_columns">
|
||||
<span slot="label"> clientid </span>
|
||||
<el-input v-model="form.test_columns.clientid" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="test_columns.qos" v-if="form.test_columns">
|
||||
<span slot="label"> qos </span>
|
||||
<el-input v-model="form.test_columns.qos" />
|
||||
</el-form-item>
|
||||
<el-form-item v-if="form.test_columns">
|
||||
<span slot="label"> 测试结果: </span>
|
||||
<el-input type="textarea" v-model="content" :rows="4"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="form.test_columns">
|
||||
<el-button @click="testConnect" type="success" size="mini" style="width:100px;">测 试</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card style="padding-bottom: 10px">
|
||||
<div slot="header" class="clearfix">
|
||||
<div slot="header" class="clearfix">
|
||||
<span style="font-size:16px;font-weight:bold;">响应动作</span>
|
||||
<span style="font-size:12px;margin-left:12px;">处理命中规则的消息</span>
|
||||
</div>
|
||||
</div>
|
||||
<el-table ref="singleTable" :data="actions" highlight-current-row>
|
||||
<el-table-column property="name" label="类型"> </el-table-column>
|
||||
<el-table-column property="param" label="参数">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.param }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" type="danger" @click="deleteAction(scope.$index)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div style="margin-top: 20px">
|
||||
<el-button @click="addActionPage()">添加</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
<el-button type="success" @click="saveRule" :loading="addRuleLoading">新建</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 添加响应动作 -->
|
||||
<el-dialog title="响应动作" :visible.sync="openAddActionView" width="600px" append-to-body :before-close="cancelAction">
|
||||
<el-form ref="actionForm" :model="actionForm" label-width="180px" v-if="actionForm.actions" :rules="ruleActions">
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item prop="actions.title">
|
||||
<span slot="label">
|
||||
动作:
|
||||
<el-tooltip :content="prompt" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<el-select v-model="actionForm.actions.title" @change="selectTitle" placeholder="请选择">
|
||||
<el-option v-for="(action, index) in actionForm.actions" :key="index" :label="action.title.zh" :value="action.name"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<el-form ref="republishForm" :model="republishForm" label-width="180px" v-if="republishForm.params" v-show="republishView" :rules="ruleRepublish">
|
||||
<el-row>
|
||||
<el-col :span="20">
|
||||
<el-form-item prop="params.target_topic.default">
|
||||
<span slot="label">
|
||||
目的主题:
|
||||
<el-tooltip :content="republishForm.params.target_topic.description.zh" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<el-input v-model="republishForm.params.target_topic.default" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="params.target_qos.default">
|
||||
<span slot="label">
|
||||
目的 QoS:
|
||||
<el-tooltip :content="republishForm.params.target_qos.description.zh" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<el-input v-model="republishForm.params.target_qos.default" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="params.payload_tmpl.default">
|
||||
<span slot="label">
|
||||
消息内容模板:
|
||||
<el-tooltip :content="republishForm.params.payload_tmpl.description.zh" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<textarea style="width: 300px; height: 120px" v-model="republishForm.params.payload_tmpl.default"></textarea>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<el-form ref="data_to_mqtt_broker_Form" :model="data_to_mqtt_broker_Form" label-width="180px" v-if="data_to_mqtt_broker_Form.params" v-show="data_to_mqtt_broker_View" :rules="rule_data_to_mqtt_broker">
|
||||
<el-row>
|
||||
<el-col :span="20">
|
||||
<el-form-item prop="resourceId">
|
||||
<span slot="label"> 关联资源: </span>
|
||||
<el-select v-model="data_to_mqtt_broker_Form.resourceId" placeholder="请选择">
|
||||
<el-option v-for="(
|
||||
resource, index
|
||||
) in data_to_mqtt_broker_Form.resources" :key="index" :label="resource.id" :value="resource.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item prop="params.payload_tmpl.default" v-if="data_to_mqtt_broker_Form.params.payload_tmpl">
|
||||
<span slot="label">
|
||||
消息内容模板:
|
||||
<el-tooltip :content="
|
||||
data_to_mqtt_broker_Form.params.payload_tmpl.description.zh
|
||||
" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<textarea style="width: 300px; height: 120px" v-model="data_to_mqtt_broker_Form.params.payload_tmpl.default"></textarea>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<el-form ref="data_to_webserver_Form" :model="data_to_webserver_Form" label-width="180px" v-if="data_to_webserver_Form.params" v-show="data_to_webserver_View" :rules="rule_data_to_webserver">
|
||||
<el-row>
|
||||
<el-col :span="20">
|
||||
<el-form-item prop="resourceId">
|
||||
<span slot="label"> 关联资源: </span>
|
||||
<el-select v-model="data_to_webserver_Form.resourceId" placeholder="请选择">
|
||||
<el-option v-for="(resource, index) in data_to_webserver_Form.resources" :key="index" :label="resource.id" :value="resource.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item prop="params.payload_tmpl.default" v-if="data_to_webserver_Form.params.payload_tmpl">
|
||||
<span slot="label">
|
||||
消息内容模板:
|
||||
<el-tooltip :content="
|
||||
data_to_webserver_Form.params.payload_tmpl.description.zh
|
||||
" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<textarea style="width: 300px; height: 120px" v-model="data_to_webserver_Form.params.payload_tmpl.default"></textarea>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="cancelAction">取 消</el-button>
|
||||
<el-button type="success" @click="saveAction('republishForm')" v-if="republishView" :loading="showloading">新建</el-button>
|
||||
<el-button type="success" @click="saveAction('data_to_mqtt_broker_Form')" v-if="data_to_mqtt_broker_View" :loading="showloading">新建</el-button>
|
||||
<el-button type="success" @click="saveAction('data_to_webserver_Form')" v-if="data_to_webserver_View" :loading="showloading">新建</el-button>
|
||||
<el-button type="success" @click="saveAction('do_nothing_Form')" v-if="do_nothing_View" :loading="showloading">新建</el-button>
|
||||
<el-button type="success" @click="saveAction('inspectForm')" v-if="inspectView" :loading="showloading">新建</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getRules,
|
||||
deleteRule,
|
||||
getRulesEvent,
|
||||
getActionsEvent,
|
||||
getResources,
|
||||
saveRule,
|
||||
testConnectRule,
|
||||
} from "@/api/iot/emqx";
|
||||
import CodeMirrorEditor from "@/components/Codemirror/index";
|
||||
export default {
|
||||
name: "Rules",
|
||||
components: {
|
||||
CodeMirrorEditor,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
//遮罩层
|
||||
showloading: false,
|
||||
// 遮罩层
|
||||
addRuleLoading: false,
|
||||
// 显示搜索条件
|
||||
showSearch: true,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 规则表格数据
|
||||
rulesList: [],
|
||||
// 弹出层标题
|
||||
title: "",
|
||||
// 是否显示详细弹出层
|
||||
openView: false,
|
||||
// 是否显示添加规则弹出层
|
||||
openAddView: false,
|
||||
// 是否显示添加响应动作弹出层
|
||||
openAddActionView: false,
|
||||
//是否显示消息重新发布表单参数
|
||||
republishView: false,
|
||||
//是否显示桥接数据到 MQTT Broker表单参数
|
||||
data_to_mqtt_broker_View: false,
|
||||
//是否显示发送数据到 Web 服务表单参数
|
||||
data_to_webserver_View: false,
|
||||
//是否显示空动作 (调试)表单按钮
|
||||
do_nothing_View: false,
|
||||
//是否显示检查 (调试)表单按钮
|
||||
inspectView: false,
|
||||
// 添加规则表单参数
|
||||
form: {
|
||||
note: "",
|
||||
SQLtest: false,
|
||||
},
|
||||
//测试结果
|
||||
content: "",
|
||||
// 响应动作列表
|
||||
actions: [],
|
||||
//响应动作列表表单参数
|
||||
actionForm: {
|
||||
actions: [],
|
||||
},
|
||||
//动作的提示语
|
||||
prompt: "动作类型",
|
||||
// 响应动作规则
|
||||
ruleActions: {
|
||||
actions: {
|
||||
title: [{
|
||||
required: true,
|
||||
message: "请选择动作类型",
|
||||
trigger: "change"
|
||||
}, ],
|
||||
},
|
||||
},
|
||||
ruleRepublish: {
|
||||
params: {
|
||||
target_topic: {
|
||||
default: [{
|
||||
required: true,
|
||||
message: "请输入目的主题",
|
||||
trigger: "blur"
|
||||
}, ],
|
||||
},
|
||||
target_qos: {
|
||||
default: [{
|
||||
required: true,
|
||||
message: "请输入目的 QoS",
|
||||
trigger: "blur"
|
||||
}, ],
|
||||
},
|
||||
payload_tmpl: {
|
||||
default: [{
|
||||
required: true,
|
||||
message: "请输入消息内容模板",
|
||||
trigger: "blur",
|
||||
}, ],
|
||||
},
|
||||
},
|
||||
},
|
||||
rule_data_to_mqtt_broker: {
|
||||
resourceId: [{
|
||||
required: true,
|
||||
message: "请关联资源类型",
|
||||
trigger: "blur"
|
||||
}, ],
|
||||
},
|
||||
rule_data_to_webserver: {
|
||||
resourceId: [{
|
||||
required: true,
|
||||
message: "请关联资源类型",
|
||||
trigger: "change"
|
||||
}, ],
|
||||
},
|
||||
//空动作 (调试)表单参数
|
||||
do_nothing_Form: {},
|
||||
//检查 (调试)表单参数
|
||||
inspectForm: {},
|
||||
//消息重新发布表单参数
|
||||
republishForm: {},
|
||||
//桥接数据到 MQTT Broker表单参数
|
||||
data_to_mqtt_broker_Form: {
|
||||
resources: [],
|
||||
resourceId: "",
|
||||
},
|
||||
//发送数据到 Web 服务表单参数
|
||||
data_to_webserver_Form: {
|
||||
resources: [],
|
||||
resourceId: "",
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
/** 查询规则列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
getRules("").then((response) => {
|
||||
this.rulesList = response.data.data;
|
||||
// this.total = response.data.meta.count;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
//初始化
|
||||
this.openAddView = false;
|
||||
this.actions = [];
|
||||
this.$refs["form"].resetFields();
|
||||
},
|
||||
//关闭动作页面
|
||||
cancelAction() {
|
||||
//初始化所有数据
|
||||
this.do_nothing_View = false;
|
||||
this.republishView = false;
|
||||
this.data_to_mqtt_broker_View = false;
|
||||
this.data_to_webserver_View = false;
|
||||
this.inspectView = false;
|
||||
this.openAddActionView = false;
|
||||
|
||||
this.do_nothing_Form = {};
|
||||
this.inspectForm = {};
|
||||
this.republishForm = {};
|
||||
this.data_to_mqtt_broker_Form.resources = [];
|
||||
this.data_to_mqtt_broker_Form.resourceId = "";
|
||||
this.data_to_mqtt_broker_Form = {};
|
||||
this.data_to_webserver_Form.resources = [];
|
||||
this.data_to_webserver_Form.resourceId = "";
|
||||
this.data_to_webserver_Form = {};
|
||||
|
||||
this.actionForm.actions = [];
|
||||
|
||||
this.$refs["actionForm"].resetFields();
|
||||
},
|
||||
/** 查看按钮操作 */
|
||||
handleQuery(row) {
|
||||
let ruleId = row.id;
|
||||
getRules(ruleId).then((response) => {
|
||||
this.form = response.data.data;
|
||||
this.openView = true;
|
||||
});
|
||||
},
|
||||
//删除规则
|
||||
handleDelete(row) {
|
||||
debugger;
|
||||
let ruleId = row.id;
|
||||
this.$modal
|
||||
.confirm('是否确认删除ID为"' + ruleId + '"的规则引擎?')
|
||||
.then(function () {
|
||||
return deleteRule(ruleId);
|
||||
})
|
||||
.then(() => {
|
||||
this.getList();
|
||||
this.$modal.msgSuccess("删除规则引擎成功");
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
//跳转到添加规则引擎页面
|
||||
getAddRules() {
|
||||
getRulesEvent().then((res) => {
|
||||
this.form = res.data.data[0];
|
||||
this.openAddView = true;
|
||||
});
|
||||
},
|
||||
//添加响应动作
|
||||
addActionPage() {
|
||||
getActionsEvent().then((res) => {
|
||||
//赋值
|
||||
this.actionForm.actions = res.data.data;
|
||||
this.do_nothing_Form = res.data.data[0];
|
||||
//检查 (调试)表单参数
|
||||
this.inspectForm = res.data.data[2];
|
||||
//消息重新发布表单参数
|
||||
this.republishForm = res.data.data[1];
|
||||
//桥接数据到 MQTT Broker表单参数
|
||||
this.data_to_mqtt_broker_Form = res.data.data[3];
|
||||
//发送数据到 Web 服务表单参数
|
||||
this.data_to_webserver_Form = res.data.data[4];
|
||||
this.openAddActionView = true;
|
||||
});
|
||||
},
|
||||
/** 选择响应动作类型 */
|
||||
selectTitle(val) {
|
||||
if ("do_nothing" === val) {
|
||||
this.data_to_webserver_View = false;
|
||||
this.data_to_mqtt_broker_View = false;
|
||||
this.republishView = false;
|
||||
this.inspectView = false;
|
||||
this.do_nothing_View = true;
|
||||
this.prompt = this.actionForm.actions[0].description.zh;
|
||||
} else if ("republish" === val) {
|
||||
this.data_to_webserver_View = false;
|
||||
this.data_to_mqtt_broker_View = false;
|
||||
this.do_nothing_View = false;
|
||||
this.inspectView = false;
|
||||
this.republishView = true;
|
||||
this.prompt = this.actionForm.actions[1].description.zh;
|
||||
} else if ("inspect" === val) {
|
||||
this.data_to_webserver_View = false;
|
||||
this.data_to_mqtt_broker_View = false;
|
||||
this.do_nothing_View = false;
|
||||
this.republishView = false;
|
||||
this.inspectView = true;
|
||||
this.prompt = this.actionForm.actions[2].description.zh;
|
||||
} else if ("data_to_mqtt_broker" === val) {
|
||||
getResources("").then((res) => {
|
||||
this.data_to_mqtt_broker_Form.resources = res.data.data;
|
||||
this.prompt = this.actionForm.actions[3].description.zh;
|
||||
|
||||
this.data_to_webserver_View = false;
|
||||
this.do_nothing_View = false;
|
||||
this.republishView = false;
|
||||
this.inspectView = false;
|
||||
this.data_to_mqtt_broker_View = true;
|
||||
});
|
||||
} else if ("data_to_webserver" === val) {
|
||||
getResources("").then((res) => {
|
||||
this.data_to_webserver_Form.resources = res.data.data;
|
||||
this.prompt = this.actionForm.actions[4].description.zh;
|
||||
|
||||
this.data_to_mqtt_broker_View = false;
|
||||
this.do_nothing_View = false;
|
||||
this.republishView = false;
|
||||
this.inspectView = false;
|
||||
this.data_to_webserver_View = true;
|
||||
});
|
||||
}
|
||||
},
|
||||
//添加响应动作
|
||||
saveAction(formName) {
|
||||
const action = {};
|
||||
const param = {};
|
||||
if ("do_nothing_Form" === formName) {
|
||||
action.name = this.do_nothing_Form.name;
|
||||
action.params = {};
|
||||
this.actions.push(action);
|
||||
this.cancelAction();
|
||||
} else if ("republishForm" === formName) {
|
||||
//校验表单
|
||||
this.$refs[formName].validate((valid) => {
|
||||
if (valid) {
|
||||
param.payload_tmpl = this.republishForm.params.payload_tmpl.default;
|
||||
param.target_topic = this.republishForm.params.target_topic.default;
|
||||
param.target_qos = this.republishForm.params.target_qos.default;
|
||||
action.name = this.republishForm.name;
|
||||
action.params = param;
|
||||
this.actions.push(action);
|
||||
this.cancelAction();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
} else if ("inspectForm" === formName) {
|
||||
action.name = this.inspectForm.name;
|
||||
action.params = {};
|
||||
this.actions.push(action);
|
||||
this.cancelAction();
|
||||
} else if ("data_to_mqtt_broker_Form" === formName) {
|
||||
//校验表单
|
||||
this.$refs[formName].validate((valid) => {
|
||||
if (valid) {
|
||||
param.$resource = this.data_to_mqtt_broker_Form.resourceId;
|
||||
if (this.data_to_mqtt_broker_Form.params.payload_tmpl != null) {
|
||||
param.payload_tmpl =
|
||||
this.data_to_mqtt_broker_Form.params.payload_tmpl.default;
|
||||
}
|
||||
action.params = param;
|
||||
action.name = this.data_to_mqtt_broker_Form.name;
|
||||
this.actions.push(action);
|
||||
this.cancelAction();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
} else if ("data_to_webserver_Form" === formName) {
|
||||
//校验表单
|
||||
this.$refs[formName].validate((valid) => {
|
||||
if (valid) {
|
||||
param.$resource = this.data_to_webserver_Form.resourceId;
|
||||
if (this.data_to_webserver_Form.params.payload_tmpl != null) {
|
||||
param.payload_tmpl =
|
||||
this.data_to_webserver_Form.params.payload_tmpl.default;
|
||||
}
|
||||
action.params = param;
|
||||
action.name = this.data_to_webserver_Form.name;
|
||||
this.actions.push(action);
|
||||
this.cancelAction();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
//删除动作参数
|
||||
deleteAction(index) {
|
||||
this.actions.splice(index, 1);
|
||||
},
|
||||
//添加规则引擎
|
||||
saveRule() {
|
||||
this.addRuleLoading = true;
|
||||
this.insertOrTestRule("insert");
|
||||
},
|
||||
testConnect() {
|
||||
this.insertOrTestRule("test");
|
||||
},
|
||||
|
||||
//公共方法
|
||||
insertOrTestRule(type) {
|
||||
//将需要的参数进行赋值
|
||||
const ruleParam = {
|
||||
ctx: {}
|
||||
};
|
||||
ruleParam.description = this.form.note;
|
||||
ruleParam.rawsql = this.form.sql_example;
|
||||
ruleParam.actions = this.actions;
|
||||
ruleParam.ctx.clientid = this.form.test_columns.clientid;
|
||||
ruleParam.ctx.payload = this.form.test_columns.payload;
|
||||
ruleParam.ctx.qos = this.form.test_columns.qos;
|
||||
ruleParam.ctx.topic = this.form.test_columns.topic;
|
||||
ruleParam.ctx.username = this.form.test_columns.username;
|
||||
ruleParam.ctx.clientid = this.form.test_columns.clientid;
|
||||
if ("test" === type) {
|
||||
testConnectRule(ruleParam).then((res) => {
|
||||
const code = res.data.code;
|
||||
if (0 === code) {
|
||||
this.content = JSON.stringify(res.data.data);
|
||||
} else {
|
||||
this.$modal.msgError(res.data.message);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
saveRule(ruleParam).then((res) => {
|
||||
const code = res.data.code;
|
||||
if (0 === code) {
|
||||
this.$modal.msgSuccess("添加规则引擎成功");
|
||||
this.cancel();
|
||||
this.getList();
|
||||
} else {
|
||||
this.$modal.msgError(res.data.message);
|
||||
}
|
||||
this.addRuleLoading = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.sql-tips {
|
||||
border: 4px dashed #d8d8d8;
|
||||
color: #71737d;
|
||||
font-size: 12px;
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
height: 510px;
|
||||
overflow: hidden;
|
||||
margin-right: -10px;
|
||||
}
|
||||
|
||||
.code {
|
||||
line-height: 1.4;
|
||||
padding: 6px;
|
||||
border-radius: 4px;
|
||||
background-color: hsla(0, 0%, 87%, 0.8);
|
||||
}
|
||||
</style>
|
||||
@@ -1,123 +0,0 @@
|
||||
<template>
|
||||
<div style="padding:6px;">
|
||||
<el-card v-show="showSearch" style="margin-bottom:6px;">
|
||||
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px" style="margin-bottom:-20px;">
|
||||
<el-form-item label="客户端" prop="categoryName">
|
||||
<el-input v-model="queryParams.categoryName" placeholder="请输入客户端ID" clearable size="small" @keyup.enter.native="handleQuery" />
|
||||
</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-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card style="padding-bottom:100px;">
|
||||
<el-table v-loading="loading" :data="subscribeList">
|
||||
<el-table-column label="类型" align="center" prop="type" width="150">
|
||||
<template slot-scope="scope">
|
||||
<el-tag type="danger" v-if="scope.row.clientid.indexOf('server')==0">服务端</el-tag>
|
||||
<el-tag type="success" v-else-if="scope.row.clientid.indexOf('web')==0">Web端</el-tag>
|
||||
<el-tag type="warning" v-else-if="scope.row.clientid.indexOf('phone')==0">移动端</el-tag>
|
||||
<el-tag type="info" v-else-if="scope.row.clientid.indexOf('test')==0">测试端</el-tag>
|
||||
<el-tag type="primary" v-else>设备端</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="主题" align="left" header-align="center" prop="topic">
|
||||
<template slot-scope="scope">
|
||||
<span style="font-weight:bold">{{scope.row.topic}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="客户端ID" align="center" header-align="center" prop="clientid">
|
||||
<template slot-scope="scope">
|
||||
<el-link :underline="false">{{scope.row.clientid}}</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="Qos" align="center" prop="qos" width="100" />
|
||||
<el-table-column label="节点" align="center" prop="node" />
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams._page" :limit.sync="queryParams._limit" @pagination="getList" />
|
||||
|
||||
<!-- 添加或修改产品分类对话框 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
||||
<el-form ref="form" :model="form" label-width="80px">
|
||||
<el-form-item label="分类名称" prop="categoryName">
|
||||
<el-input v-model="form.categoryName" placeholder="请输入产品分类名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="显示顺序" prop="orderNum">
|
||||
<el-input v-model="form.orderNum" placeholder="请输入显示顺序" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="cancel">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
listMqttSubscribe
|
||||
} from "@/api/iot/emqx"
|
||||
|
||||
export default {
|
||||
name: "Category",
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 显示搜索条件
|
||||
showSearch: true,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 列表
|
||||
subscribeList: [],
|
||||
// 弹出层标题
|
||||
title: "",
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
_limit: 10,
|
||||
_page: 1,
|
||||
},
|
||||
// 表单参数
|
||||
form: {},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
|
||||
},
|
||||
methods: {
|
||||
/** 查询客户端列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listMqttSubscribe(this.queryParams).then(response => {
|
||||
this.subscribeList = response.data.data;
|
||||
this.total = response.data.meta.count;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
this.open = false;
|
||||
this.reset();
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm("queryForm");
|
||||
this.handleQuery();
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,103 +0,0 @@
|
||||
<template>
|
||||
<div style="padding:6px;">
|
||||
<el-card v-show="showSearch" style="margin-bottom:6px;">
|
||||
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px" style="margin-bottom:-20px;">
|
||||
<el-form-item label="主题" prop="categoryName">
|
||||
<el-input v-model="queryParams.categoryName" placeholder="请输入主题" clearable size="small" @keyup.enter.native="handleQuery" />
|
||||
</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-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card style="padding-bottom:100px;">
|
||||
<el-table v-loading="loading" :data="topicList">
|
||||
<el-table-column label="节点" align="center" prop="node" width="300"/>
|
||||
<el-table-column label="主题" align="left" prop="topic" />
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams._page" :limit.sync="queryParams._limit" @pagination="getList" />
|
||||
|
||||
<!-- 添加或修改产品分类对话框 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
||||
<el-form ref="form" :model="form" label-width="80px">
|
||||
<el-form-item label="分类名称" prop="categoryName">
|
||||
<el-input v-model="form.categoryName" placeholder="请输入产品分类名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="显示顺序" prop="orderNum">
|
||||
<el-input v-model="form.orderNum" placeholder="请输入显示顺序" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="cancel">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import{listMqttTopic} from "@/api/iot/emqx"
|
||||
|
||||
|
||||
export default {
|
||||
name: "Category",
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 显示搜索条件
|
||||
showSearch: true,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 列表
|
||||
topicList: [],
|
||||
// 弹出层标题
|
||||
title: "",
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
_limit: 10,
|
||||
_page: 1,
|
||||
},
|
||||
// 表单参数
|
||||
form: {},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
|
||||
},
|
||||
methods: {
|
||||
/** 查询客户端列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listMqttTopic(this.queryParams).then(response => {
|
||||
this.topicList=response.data.data;
|
||||
this.total=response.data.meta.count;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
this.open = false;
|
||||
this.reset();
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm("queryForm");
|
||||
this.handleQuery();
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,364 +0,0 @@
|
||||
<template>
|
||||
<div style="padding:6px;">
|
||||
<el-card v-show="showSearch" style="margin-bottom:6px;">
|
||||
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px" style="margin-bottom:-20px;">
|
||||
<el-form-item label="固件名称" prop="firmwareName">
|
||||
<el-input v-model="queryParams.firmwareName" placeholder="请输入固件名称" clearable size="small" @keyup.enter.native="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="产品名称" prop="productName">
|
||||
<el-input v-model="queryParams.productName" placeholder="请输入产品名称" clearable size="small" @keyup.enter.native="handleQuery" />
|
||||
</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-form-item>
|
||||
<!-- <el-form-item style="float:right;">
|
||||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['iot:firmware:add']">新增</el-button>
|
||||
</el-form-item> -->
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card style="padding-bottom:100px;">
|
||||
<el-table v-loading="loading" :data="firmwareList" @selection-change="handleSelectionChange">
|
||||
<el-table-column label="固件名称" align="center" prop="firmwareName" />
|
||||
<el-table-column label="固件版本" align="center" prop="version" width="120">
|
||||
<template slot-scope="scope">
|
||||
<span>Version </span> {{scope.row.version}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" align="center" prop="isLatest" width="80">
|
||||
<template slot-scope="scope">
|
||||
<el-tag type="success" v-if="scope.row.isLatest==1">最新</el-tag>
|
||||
<el-tag type="info" v-else>默认</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="100">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="产品名称" align="center" prop="productName">
|
||||
<template slot-scope="scope">
|
||||
<el-link :underline="false" type="primary" @click="handleViewProduct(scope.row.productId)">{{scope.row.productName}}</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="下载地址" align="center" prop="filePath" min-width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-link :href="getDownloadUrl(scope.row.filePath)" :underline="false" type="success">{{getDownloadUrl(scope.row.filePath)}}</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="固件描述" align="center" prop="remark" min-width="200" />
|
||||
<!-- <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="small" type="primary" style="padding:5px;" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['iot:firmware:edit']">修改</el-button>
|
||||
<el-button size="small" type="danger" style="padding:5px;" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['iot:firmware:remove']">删除</el-button>
|
||||
</template>
|
||||
</el-table-column> -->
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
|
||||
<!-- 添加或修改产品固件对话框 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="固件名称" prop="firmwareName">
|
||||
<el-input v-model="form.firmwareName" placeholder="请输入固件名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="所属产品" prop="productId">
|
||||
<el-select v-model="form.productId" placeholder="请选择产品" @change="selectProduct">
|
||||
<el-option v-for="product in productShortList" :key="product.id" :label="product.name" :value="product.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="固件版本" prop="version">
|
||||
<el-input v-model="form.version" placeholder="请输入固件版本" type="number" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="固件上传" prop="filePath">
|
||||
<fileUpload ref="file-upload" :value="form.filePath" :limit="1" :fileSize="10" :fileType='["bin", "zip", "pdf"]' @input="getFilePath($event)"></fileUpload>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import fileUpload from '../../../components/FileUpload/index'
|
||||
import {
|
||||
listShortProduct
|
||||
} from "@/api/iot/product"
|
||||
import {
|
||||
listFirmware,
|
||||
getFirmware,
|
||||
delFirmware,
|
||||
addFirmware,
|
||||
updateFirmware
|
||||
} from "@/api/iot/firmware";
|
||||
import {
|
||||
getToken
|
||||
} from "@/utils/auth";
|
||||
|
||||
export default {
|
||||
name: "Firmware",
|
||||
dicts: ["iot_yes_no"],
|
||||
components: {
|
||||
fileUpload
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 选中数组
|
||||
ids: [],
|
||||
// 非单个禁用
|
||||
single: true,
|
||||
// 非多个禁用
|
||||
multiple: true,
|
||||
// 显示搜索条件
|
||||
showSearch: true,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 产品固件表格数据
|
||||
firmwareList: [],
|
||||
// 产品简短列表
|
||||
productShortList: [],
|
||||
// 弹出层标题
|
||||
title: "",
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
firmwareName: null,
|
||||
productName: null,
|
||||
tenantName: null,
|
||||
isSys: null,
|
||||
},
|
||||
// 表单参数
|
||||
form: {
|
||||
version: 1.0
|
||||
},
|
||||
// 表单校验
|
||||
rules: {
|
||||
firmwareName: [{
|
||||
required: true,
|
||||
message: "固件名称不能为空",
|
||||
trigger: "blur"
|
||||
}],
|
||||
productId: [{
|
||||
required: true,
|
||||
message: "产品ID不能为空",
|
||||
trigger: "blur"
|
||||
}],
|
||||
productName: [{
|
||||
required: true,
|
||||
message: "产品名称不能为空",
|
||||
trigger: "blur"
|
||||
}],
|
||||
version: [{
|
||||
required: true,
|
||||
message: "固件版本不能为空",
|
||||
trigger: "blur"
|
||||
}],
|
||||
filePath: [{
|
||||
required: true,
|
||||
message: "文件路径不能为空",
|
||||
trigger: "blur"
|
||||
}],
|
||||
},
|
||||
// 上传参数
|
||||
upload: {
|
||||
// 是否禁用上传
|
||||
isUploading: false,
|
||||
// 设置上传的请求头部
|
||||
headers: {
|
||||
Authorization: "Bearer " + getToken()
|
||||
},
|
||||
// 上传的地址
|
||||
url: process.env.VUE_APP_BASE_API + "/iot/tool/upload",
|
||||
// 上传的文件列表
|
||||
fileList: []
|
||||
},
|
||||
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
this.getProductShortList();
|
||||
},
|
||||
methods: {
|
||||
/** 查看产品按钮操作 */
|
||||
handleViewProduct(productId) {
|
||||
this.$router.push({
|
||||
path: '/iot/product-edit',
|
||||
query: {
|
||||
t: Date.now(),
|
||||
productId: productId,
|
||||
}
|
||||
});
|
||||
},
|
||||
// 获取下载路径前缀
|
||||
getDownloadUrl(path) {
|
||||
return window.location.origin + process.env.VUE_APP_BASE_API + path;
|
||||
},
|
||||
/** 查询产品固件列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listFirmware(this.queryParams).then(response => {
|
||||
this.firmwareList = response.rows;
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
/** 查询产品简短列表 */
|
||||
getProductShortList() {
|
||||
listShortProduct().then(response => {
|
||||
this.productShortList = response.data;
|
||||
});
|
||||
},
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
this.open = false;
|
||||
this.reset();
|
||||
},
|
||||
// 表单重置
|
||||
reset() {
|
||||
this.form = {
|
||||
firmwareId: null,
|
||||
firmwareName: null,
|
||||
productId: null,
|
||||
productName: null,
|
||||
tenantId: null,
|
||||
tenantName: null,
|
||||
isSys: null,
|
||||
version: 1.0,
|
||||
filePath: null,
|
||||
delFlag: null,
|
||||
createBy: null,
|
||||
createTime: null,
|
||||
updateBy: null,
|
||||
updateTime: null,
|
||||
remark: null
|
||||
};
|
||||
this.resetForm("form");
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm("queryForm");
|
||||
this.handleQuery();
|
||||
},
|
||||
// 多选框选中数据
|
||||
handleSelectionChange(selection) {
|
||||
this.ids = selection.map(item => item.firmwareId)
|
||||
this.single = selection.length !== 1
|
||||
this.multiple = !selection.length
|
||||
},
|
||||
/** 新增按钮操作 */
|
||||
handleAdd() {
|
||||
this.reset();
|
||||
this.open = true;
|
||||
this.title = "添加产品固件";
|
||||
this.upload.fileList = [];
|
||||
},
|
||||
/** 修改按钮操作 */
|
||||
handleUpdate(row) {
|
||||
this.reset();
|
||||
const firmwareId = row.firmwareId || this.ids
|
||||
getFirmware(firmwareId).then(response => {
|
||||
this.form = response.data;
|
||||
this.open = true;
|
||||
this.title = "修改产品固件";
|
||||
this.upload.fileList = [{
|
||||
name: this.form.firmwareName,
|
||||
url: this.form.filePath
|
||||
}];
|
||||
});
|
||||
|
||||
},
|
||||
/** 提交按钮 */
|
||||
submitForm() {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
if (this.form.firmwareId != null) {
|
||||
updateFirmware(this.form).then(response => {
|
||||
this.$modal.msgSuccess("修改成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
});
|
||||
} else {
|
||||
addFirmware(this.form).then(response => {
|
||||
this.$modal.msgSuccess("新增成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
handleDelete(row) {
|
||||
const firmwareIds = row.firmwareId || this.ids;
|
||||
this.$modal.confirm('是否确认删除产品固件编号为"' + firmwareIds + '"的数据项?').then(function () {
|
||||
return delFirmware(firmwareIds);
|
||||
}).then(() => {
|
||||
this.getList();
|
||||
this.$modal.msgSuccess("删除成功");
|
||||
}).catch(() => {});
|
||||
},
|
||||
/** 导出按钮操作 */
|
||||
handleExport() {
|
||||
this.download('iot/firmware/export', {
|
||||
...this.queryParams
|
||||
}, `firmware_${new Date().getTime()}.xlsx`)
|
||||
},
|
||||
/** 选择产品 */
|
||||
selectProduct(val) {
|
||||
for (var i = 0; i < this.productShortList.length; i++) {
|
||||
if (this.productShortList[i].id == val) {
|
||||
this.form.productName = this.productShortList[i].name;
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
// 获取文件路径
|
||||
getFilePath(data) {
|
||||
console.log(data);
|
||||
this.form.filePath = data;
|
||||
},
|
||||
|
||||
// 文件提交处理
|
||||
submitUpload() {
|
||||
this.$refs.upload.submit();
|
||||
},
|
||||
// 文件上传中处理
|
||||
handleFileUploadProgress(event, file, fileList) {
|
||||
this.upload.isUploading = true;
|
||||
},
|
||||
// 文件上传成功处理
|
||||
handleFileSuccess(response, file, fileList) {
|
||||
this.upload.isUploading = false;
|
||||
this.form.filePath = response.url;
|
||||
this.$modal.msgSuccess(response.msg);
|
||||
},
|
||||
// 文件下载处理
|
||||
handleDownload(row) {
|
||||
window.open(process.env.VUE_APP_BASE_API + row.filePath);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
};
|
||||
</script>
|
||||
@@ -1,636 +0,0 @@
|
||||
<template>
|
||||
<div style="padding-left:20px;">
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['iot:alert:add']">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="el-icon-refresh" size="mini" @click="getList">刷新</el-button>
|
||||
</el-col>
|
||||
<el-tag type="danger" style="margin-left:15px;">该功能暂不可用,后面版本发布</el-tag>
|
||||
</el-row>
|
||||
|
||||
<el-table v-loading="loading" :data="alertList" @selection-change="handleSelectionChange" border size="mini">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="告警ID" align="center" prop="alertId" />
|
||||
<el-table-column label="告警名称" align="center" prop="alertName" />
|
||||
<el-table-column label="状态" align="center" prop="status">
|
||||
<template slot-scope="scope">
|
||||
<el-tag type="success" v-if="scope.row.status==1">启动</el-tag>
|
||||
<el-tag type="danger" v-if="scope.row.status==2">暂停</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="告警级别" align="center" prop="alertLevel">
|
||||
<template slot-scope="scope">
|
||||
<dict-tag :options="dict.type.iot_alert_level" :value="scope.row.alertLevel" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="触发器" align="center" prop="triggers" />
|
||||
<el-table-column label="执行动作" align="center" prop="actions" />
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="备注" align="center" prop="remark" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['iot:alert:edit']">修改</el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['iot:alert:remove']">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
|
||||
|
||||
<!-- 添加或修改设备告警对话框 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
|
||||
<div class="el-divider el-divider--horizontal" style="margin-top: -25px;"></div>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||||
<el-row :gutter="50">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="告警名称" prop="alertName">
|
||||
<el-input v-model="form.alertName" placeholder="请输入告警名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="告警级别" prop="alertLevel">
|
||||
<el-select v-model="form.alertLevel" placeholder="请选择告警级别" style="width:100%;">
|
||||
<el-option v-for="dict in dict.type.iot_alert_level" :key="dict.value" :label="dict.label" :value="parseInt(dict.value)"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="告警状态">
|
||||
<el-switch v-model="form.status" :active-value="1" :inactive-value="0" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" rows="6" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-divider></el-divider>
|
||||
<el-form-item label="触发器" prop="griggers">
|
||||
<el-select v-model="form.condition" placeholder="请选择" size="small" style="margin-bottom:10px;">
|
||||
<el-option v-for="item in triggerConditions" :key="item.value" :label="item.label" :value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
<div v-for="(item,index) in form.triggers" :key="index" style="margin-bottom:15px;border:1px solid #ddd;padding:10px;">
|
||||
<el-row>
|
||||
<el-col :span="4">
|
||||
<el-select v-model="item.source" placeholder="请选择" size="small" @change="changeTriggerSource">
|
||||
<el-option v-for="subItem in triggerSource" :key="subItem.value" :label="subItem.label" :value="subItem.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="16" :offset="1" v-if="item.source==2">
|
||||
<el-time-picker v-model="timerTimeValue" size="small" value-format="HH:mm" placeholder="选择执行时间" @change="timeChange" :disabled="item.isAdvance==1"></el-time-picker>
|
||||
</el-col>
|
||||
<el-col :span="2" :offset="item.source==1?17:1" v-if="index!=0"><a style="color:#F56C6C" @click="removeTriggerItem(index)">删除</a></el-col>
|
||||
</el-row>
|
||||
|
||||
<!--定时-->
|
||||
<el-row v-if="item.source==2">
|
||||
<el-col :span="24">
|
||||
<el-row style="margin-bottom:5px;">
|
||||
<el-col :span="4">
|
||||
<el-select v-model="timerWeekRepeatValue" placeholder="请选择" @change="repeatChange" size="small" :disabled="item.isAdvance==1">
|
||||
<el-option v-for="item in timerWeekRepeats" :key="item.value" :label="item.label" :value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="15" :offset="1" v-if="timerWeekRepeatValue==3">
|
||||
<el-select v-model="timerWeekValue" placeholder="请选择" multiple style="width:485px" @change="weekChange" size="small" :disabled="item.isAdvance==1">
|
||||
<el-option v-for="item in timerWeeks" :key="item.value" :label="item.label" :value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-row>
|
||||
<el-col :span="18">
|
||||
<el-input v-model="item.cronExpression" placeholder="cron执行表达式" :disabled="item.isAdvance==0" size="small">
|
||||
<template slot="append">
|
||||
<el-button type="primary" @click="handleShowCron(item,index)" :disabled="item.isAdvance==0">
|
||||
生成表达式
|
||||
<i class="el-icon-time el-icon--right"></i>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-col>
|
||||
<el-col :span="4" :offset="1">
|
||||
<el-checkbox v-model="item.isAdvance" :true-label="1" :false-label="0" @change="customerCronChange">自定义表达式</el-checkbox>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!--设备-->
|
||||
<el-row>
|
||||
<el-col :span="4">
|
||||
<el-select v-model="item.modelType" placeholder="请选择" size="small">
|
||||
<el-option v-for="subItem in modelTypes" :key="subItem.value" :label="subItem.label" :value="subItem.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="4" :offset="1">
|
||||
<el-select v-model="item.modelType" placeholder="请选择" size="small">
|
||||
<el-option v-for="subItem in modelTypes" :key="subItem.value" :label="subItem.label" :value="subItem.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="5" :offset="1">
|
||||
<el-select v-model="item.operator" placeholder="请选择操作符" size="small">
|
||||
<el-option key="=" label="等于(=)" value="=" />
|
||||
<el-option key="!=" label="不等于(!=)" value="!=" />
|
||||
<el-option key=">" label="大于(>)" value=">" />
|
||||
<el-option key="<" label="小于(<)" value="<" />
|
||||
<el-option key=">=" label="大于等于(>=)" value=">=" />
|
||||
<el-option key="<=" label="小于等于(<=)" value="<=" />
|
||||
<el-option key="contain" label="包含(contain)" value="contain" />
|
||||
<el-option key="notcontain" label="不包含(not contain)" value="notcontain" />
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="5" :offset="1">
|
||||
<el-input v-model="item.value" placeholder="值" size="small" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div>+ <a style="color:#409EFF" @click="addTriggerItem()">添加触发器</a></div>
|
||||
</el-form-item>
|
||||
|
||||
<el-divider></el-divider>
|
||||
<el-form-item label="执行动作">
|
||||
<el-row v-for="(item,index) in form.actions" :key="index" style="margin-bottom:10px;">
|
||||
<el-col :span="4">
|
||||
<el-select v-model="item.modelType" placeholder="请选择">
|
||||
<el-option v-for="subItem in modelTypes" :key="subItem.value" :label="subItem.label" :value="subItem.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="4" :offset="1">
|
||||
<el-select v-model="item.modelType" placeholder="请选择">
|
||||
<el-option v-for="subItem in modelTypes" :key="subItem.value" :label="subItem.label" :value="subItem.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="11" :offset="1">
|
||||
<el-input v-model="item.value" placeholder="值" />
|
||||
</el-col>
|
||||
<el-col :span="2" :offset="1" v-if="index!=0"><a style="color:#F56C6C" @click="removeActionItem(index)">删除</a></el-col>
|
||||
</el-row>
|
||||
<div>+ <a style="color:#409EFF" @click="addActionItem()">添加执行动作</a></div>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm" disabled>确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog title="Cron表达式生成器" :visible.sync="openCron" append-to-body destroy-on-close class="scrollbar">
|
||||
<crontab @hide="openCron=false" @fill="crontabFill" :expression="expression" style="padding-bottom:80px;"></crontab>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
listAlert,
|
||||
getAlert,
|
||||
delAlert,
|
||||
addAlert,
|
||||
updateAlert
|
||||
} from "@/api/iot/alert";
|
||||
import {
|
||||
cacheJsonThingsModel
|
||||
} from "@/api/iot/model";
|
||||
import Crontab from '@/components/Crontab'
|
||||
export default {
|
||||
name: "device-alert",
|
||||
dicts: ['iot_alert_level', 'sys_job_status'],
|
||||
components: {
|
||||
Crontab
|
||||
},
|
||||
props: {
|
||||
product: {
|
||||
type: Object,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
// 获取到父组件传递的productId后,刷新列表
|
||||
product: function (newVal, oldVal) {
|
||||
this.productInfo = newVal;
|
||||
if (this.productInfo && this.productInfo.productId != 0) {
|
||||
this.queryParams.productId = this.productInfo.productId;
|
||||
this.getList();
|
||||
// 获取缓存的Json物模型
|
||||
cacheJsonThingsModel(newVal.productId).then(response => {
|
||||
this.thingsModel = JSON.parse(response.data);
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 物模型JSON
|
||||
thingsModel: {},
|
||||
// 遮罩层
|
||||
loading: false,
|
||||
// 选中数组
|
||||
ids: [],
|
||||
// 非单个禁用
|
||||
single: true,
|
||||
// 非多个禁用
|
||||
multiple: true,
|
||||
// 显示搜索条件
|
||||
showSearch: true,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 设备告警表格数据
|
||||
alertList: [],
|
||||
// 弹出层标题
|
||||
title: "",
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 是否显示Cron表达式弹出层
|
||||
openCron: false,
|
||||
// 传入的表达式
|
||||
expression: "",
|
||||
// 触发器的索引,用于接收传入的表达式
|
||||
triggerIndex: 0,
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
alertName: null,
|
||||
alertLevel: null,
|
||||
productId: null,
|
||||
productName: null,
|
||||
},
|
||||
// 周
|
||||
timerWeekRepeats: [{
|
||||
value: '1',
|
||||
label: '每天'
|
||||
}, {
|
||||
value: '2',
|
||||
label: '仅此一次'
|
||||
}, {
|
||||
value: '3',
|
||||
label: '指定'
|
||||
}],
|
||||
timerWeekRepeatValue: "1",
|
||||
|
||||
timerWeeks: [{
|
||||
value: 1,
|
||||
label: '周一'
|
||||
}, {
|
||||
value: 2,
|
||||
label: '周二'
|
||||
}, {
|
||||
value: 3,
|
||||
label: '周三'
|
||||
}, {
|
||||
value: 4,
|
||||
label: '周四'
|
||||
}, {
|
||||
value: 5,
|
||||
label: '周五'
|
||||
}, {
|
||||
value: 6,
|
||||
label: '周六'
|
||||
}, {
|
||||
value: 7,
|
||||
label: '周日'
|
||||
}],
|
||||
timerWeekValue: [1, 2, 3, 4, 5, 6, 7],
|
||||
// 时间
|
||||
timerTimeValue: '',
|
||||
// 触发器源 1=设备,2=定时,3=告警输出
|
||||
triggerSource: [{
|
||||
value: 1,
|
||||
label: '设备'
|
||||
}, {
|
||||
value: 2,
|
||||
label: '定时'
|
||||
}],
|
||||
// 执行动作源
|
||||
actionSource: [{
|
||||
value: 1,
|
||||
label: '设备'
|
||||
}, {
|
||||
value: 3,
|
||||
label: '告警输出'
|
||||
}],
|
||||
// 物模型类别
|
||||
modelTypes: [{
|
||||
value: 1,
|
||||
label: '属性'
|
||||
}, {
|
||||
value: 2,
|
||||
label: '功能'
|
||||
}],
|
||||
// 触发器条件
|
||||
triggerConditions: [{
|
||||
value: "all",
|
||||
label: '满足所有条件'
|
||||
}, {
|
||||
value: "any",
|
||||
label: '满足任一条件'
|
||||
}],
|
||||
// 告警状态
|
||||
alertType: [{
|
||||
value: 1,
|
||||
label: '启动'
|
||||
}, {
|
||||
value: 2,
|
||||
label: '停止'
|
||||
}],
|
||||
// 表单参数
|
||||
form: {
|
||||
condition: "all", // 触发器条件
|
||||
triggers: [],
|
||||
actions: []
|
||||
},
|
||||
// 产品
|
||||
productInfo: {},
|
||||
// 表单校验
|
||||
rules: {
|
||||
alertName: [{
|
||||
required: true,
|
||||
message: "告警名称不能为空",
|
||||
trigger: "blur"
|
||||
}],
|
||||
alertLevel: [{
|
||||
required: true,
|
||||
message: "告警级别不能为空",
|
||||
trigger: "change"
|
||||
}],
|
||||
productId: [{
|
||||
required: true,
|
||||
message: "产品ID不能为空",
|
||||
trigger: "blur"
|
||||
}],
|
||||
productName: [{
|
||||
required: true,
|
||||
message: "产品名称不能为空",
|
||||
trigger: "blur"
|
||||
}],
|
||||
triggers: [{
|
||||
required: true,
|
||||
message: "触发器不能为空",
|
||||
trigger: "blur"
|
||||
}],
|
||||
actions: [{
|
||||
required: true,
|
||||
message: "执行动作不能为空",
|
||||
trigger: "blur"
|
||||
}],
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
// this.getList();
|
||||
},
|
||||
methods: {
|
||||
/** 查询设备告警列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listAlert(this.queryParams).then(response => {
|
||||
this.alertList = response.rows;
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
this.open = false;
|
||||
this.reset();
|
||||
},
|
||||
// 表单重置
|
||||
reset() {
|
||||
this.form = {
|
||||
alertId: null,
|
||||
alertName: null,
|
||||
alertLevel: null,
|
||||
productId: null,
|
||||
productName: null,
|
||||
createBy: null,
|
||||
createTime: null,
|
||||
updateBy: null,
|
||||
updateTime: null,
|
||||
remark: null,
|
||||
status: 1,
|
||||
condition: "all", // 触发器条件
|
||||
triggers: [{
|
||||
id: "",
|
||||
name: "",
|
||||
value: "",
|
||||
deviceId: 0,
|
||||
deviceName: "请选择一个设备",
|
||||
source: 1, //1=设备,2=定时,3=告警输出
|
||||
modelType: 1, // 1=属性,2=功能
|
||||
jobId: 0,
|
||||
cronExpression: "",
|
||||
isAdvance: 0
|
||||
}],
|
||||
actions: [{
|
||||
id: "",
|
||||
name: "",
|
||||
value: "",
|
||||
deviceId: 0,
|
||||
deviceName: "请选择一个设备",
|
||||
source: 1, //1=设备,2=定时,3=告警输出
|
||||
modelType: 1, // 1=属性,2=功能
|
||||
}]
|
||||
};
|
||||
this.resetForm("form");
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm("queryForm");
|
||||
this.handleQuery();
|
||||
},
|
||||
// 多选框选中数据
|
||||
handleSelectionChange(selection) {
|
||||
this.ids = selection.map(item => item.alertId)
|
||||
this.single = selection.length !== 1
|
||||
this.multiple = !selection.length
|
||||
},
|
||||
/** 新增按钮操作 */
|
||||
handleAdd() {
|
||||
this.reset();
|
||||
this.open = true;
|
||||
this.title = "添加自定义告警";
|
||||
},
|
||||
/** 修改按钮操作 */
|
||||
handleUpdate(row) {
|
||||
this.reset();
|
||||
const alertId = row.alertId || this.ids
|
||||
getAlert(alertId).then(response => {
|
||||
this.form = response.data;
|
||||
this.open = true;
|
||||
this.title = "修改设备告警";
|
||||
});
|
||||
},
|
||||
/** 提交按钮 */
|
||||
submitForm() {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
if (this.form.alertId != null) {
|
||||
updateAlert(this.form).then(response => {
|
||||
this.$modal.msgSuccess("修改成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
});
|
||||
} else {
|
||||
addAlert(this.form).then(response => {
|
||||
this.$modal.msgSuccess("新增成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
handleDelete(row) {
|
||||
const alertIds = row.alertId || this.ids;
|
||||
this.$modal.confirm('是否确认删除设备告警编号为"' + alertIds + '"的数据项?').then(function () {
|
||||
return delAlert(alertIds);
|
||||
}).then(() => {
|
||||
this.getList();
|
||||
this.$modal.msgSuccess("删除成功");
|
||||
}).catch(() => {});
|
||||
},
|
||||
/** 导出按钮操作 */
|
||||
handleExport() {
|
||||
this.download('iot/alert/export', {
|
||||
...this.queryParams
|
||||
}, `alert_${new Date().getTime()}.xlsx`)
|
||||
},
|
||||
/** 添加动作 */
|
||||
addActionItem() {
|
||||
this.form.actions.push({
|
||||
id: "",
|
||||
name: "",
|
||||
value: ""
|
||||
})
|
||||
},
|
||||
/** 删除动作 */
|
||||
removeActionItem(index) {
|
||||
this.form.actions.splice(index, 1);
|
||||
},
|
||||
/** 触发器源改变事件 **/
|
||||
changeTriggerSource() {
|
||||
this.setTriggerSource();
|
||||
},
|
||||
/** 设置触发器源 **/
|
||||
setTriggerSource() {
|
||||
// 触发器智能包含一个定时
|
||||
let hasTimer = false;
|
||||
for (let i = 0; i < this.form.triggers.length; i++) {
|
||||
if (this.form.triggers[i].source == 2) {
|
||||
hasTimer = true;
|
||||
}
|
||||
}
|
||||
if (hasTimer) {
|
||||
this.triggerSource = [{
|
||||
value: 1,
|
||||
label: '设备'
|
||||
}];
|
||||
} else {
|
||||
//定时
|
||||
this.triggerSource = [{
|
||||
value: 1,
|
||||
label: '设备'
|
||||
}, {
|
||||
value: 2,
|
||||
label: '定时'
|
||||
}];
|
||||
|
||||
}
|
||||
},
|
||||
/** 添加触发器 */
|
||||
addTriggerItem() {
|
||||
this.setTriggerSource();
|
||||
this.form.triggers.push({
|
||||
id: "",
|
||||
name: "",
|
||||
value: "",
|
||||
deviceId: 0,
|
||||
deviceName: "请选择一个设备",
|
||||
source: 1, //1=设备,2=定时,3=告警输出
|
||||
modelType: 1, // 1=属性,2=功能
|
||||
jobId: 0,
|
||||
cronExpression: "",
|
||||
isAdvance: 0
|
||||
})
|
||||
|
||||
},
|
||||
/** 删除触发器 */
|
||||
removeTriggerItem(index) {
|
||||
this.form.triggers.splice(index, 1);
|
||||
this.setTriggerSource();
|
||||
},
|
||||
/** cron表达式按钮操作 */
|
||||
handleShowCron(item, index) {
|
||||
this.expression = item.cronExpression;
|
||||
this.triggerIndex = index;
|
||||
this.openCron = true;
|
||||
},
|
||||
/** 确定后回传值 */
|
||||
crontabFill(value) {
|
||||
this.form.triggers[this.triggerIndex].cronExpression = value;
|
||||
},
|
||||
/** 修改重复事件 **/
|
||||
repeatChange(data) {
|
||||
if (this.timerWeekRepeatValue == 1) {
|
||||
// 每天
|
||||
this.timerWeekValue = [1, 2, 3, 4, 5, 6, 7];
|
||||
this.form.repeat = 1;
|
||||
} else if (this.timerWeekRepeatValue == 2) {
|
||||
// 仅此一次
|
||||
this.timerWeekValue = [];
|
||||
this.form.isRepeat = 0;
|
||||
} else {
|
||||
// 指定
|
||||
this.form.isRepeat = 1;
|
||||
}
|
||||
this.gentCronExpression();
|
||||
},
|
||||
/** 星期改变事件 **/
|
||||
weekChange(data) {
|
||||
this.gentCronExpression();
|
||||
},
|
||||
/** 时间改变事件 **/
|
||||
timeChange(data) {
|
||||
this.gentCronExpression();
|
||||
},
|
||||
/**自定义cron表达式选项改变事件 */
|
||||
customerCronChange(data) {
|
||||
this.gentCronExpression();
|
||||
},
|
||||
/** 生成cron表达式**/
|
||||
gentCronExpression() {
|
||||
if (this.timerTimeValue == "") {
|
||||
this.$modal.alertError("执行时间不能为空");
|
||||
}
|
||||
let minute = this.timerTimeValue.substring(0, 2);
|
||||
let hour = this.timerTimeValue.substring(3);
|
||||
let week = "*";
|
||||
if (this.timerWeekValue.length > 0) {
|
||||
week = this.timerWeekValue;
|
||||
}
|
||||
this.form.triggers[this.triggerIndex].cronExpression = "0 " + minute + " " + hour + " ? * " + week;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,322 +0,0 @@
|
||||
<template>
|
||||
<div style="padding-left:20px;">
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['iot:firmware:add']">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="el-icon-refresh" size="mini" @click="getList">刷新</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-table v-loading="loading" :data="firmwareList" @selection-change="handleSelectionChange" size="small">
|
||||
<el-table-column label="固件名称" align="center" prop="firmwareName" />
|
||||
<el-table-column label="固件版本" align="center" prop="version" width="120">
|
||||
<template slot-scope="scope">
|
||||
<span>Version </span> {{scope.row.version}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" align="center" prop="isLatest" width="80">
|
||||
<template slot-scope="scope">
|
||||
<el-tag type="success" v-if="scope.row.isLatest==1">最新</el-tag>
|
||||
<el-tag type="info" v-else>默认</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="100">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="下载地址" align="center" prop="filePath" min-width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-link :href="getDownloadUrl(scope.row.filePath)" :underline="false" type="success">{{getDownloadUrl(scope.row.filePath)}}</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="固件描述" align="center" prop="remark" min-width="200" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="small" type="primary" style="padding:5px;" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['iot:firmware:edit']">修改</el-button>
|
||||
<el-button size="small" type="danger" style="padding:5px;" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['iot:firmware:remove']">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 添加或修改产品固件对话框 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="固件名称" prop="firmwareName">
|
||||
<el-input v-model="form.firmwareName" placeholder="请输入固件名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="固件版本" prop="version">
|
||||
<el-input v-model="form.version" placeholder="请输入固件版本" type="number" step="0.1" />
|
||||
</el-form-item>
|
||||
<el-form-item label="最新固件" prop="isLatest">
|
||||
<el-switch v-model="form.isLatest" active-text="" inactive-text="" :active-value="1" :inactive-value="0">
|
||||
</el-switch>
|
||||
<el-link type="info" :underline="false" style="font-size:12px;margin-left:15px;">提示:产品中只能有一个最新固件</el-link>
|
||||
</el-form-item>
|
||||
<el-form-item label="固件上传" prop="filePath">
|
||||
<fileUpload ref="file-upload" :value="form.filePath" :limit="1" :fileSize="10" :fileType='["bin", "zip", "pdf"]' @input="getFilePath($event)"></fileUpload>
|
||||
</el-form-item>
|
||||
<el-form-item label="固件描述" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" rows="4" placeholder="请输入固件信息" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import fileUpload from '../../../components/FileUpload/index'
|
||||
import {
|
||||
listFirmware,
|
||||
getFirmware,
|
||||
delFirmware,
|
||||
addFirmware,
|
||||
updateFirmware
|
||||
} from "@/api/iot/firmware";
|
||||
import {
|
||||
getToken
|
||||
} from "@/utils/auth";
|
||||
|
||||
export default {
|
||||
name: "product-firmware",
|
||||
dicts: ["iot_yes_no"],
|
||||
components: {
|
||||
fileUpload
|
||||
},
|
||||
props: {
|
||||
product: {
|
||||
type: Object,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
// 获取到父组件传递的productId后,刷新列表
|
||||
product: function (newVal, oldVal) {
|
||||
this.productInfo = newVal;
|
||||
if (this.productInfo && this.productInfo.productId != 0) {
|
||||
this.queryParams.productId = this.productInfo.productId;
|
||||
this.form.productId = this.productInfo.productId;
|
||||
this.form.productName = this.productInfo.productName;
|
||||
this.getList();
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 选中数组
|
||||
ids: [],
|
||||
// 非单个禁用
|
||||
single: true,
|
||||
// 非多个禁用
|
||||
multiple: true,
|
||||
// 显示搜索条件
|
||||
showSearch: true,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 产品固件表格数据
|
||||
firmwareList: [],
|
||||
// 弹出层标题
|
||||
title: "",
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 100,
|
||||
firmwareName: null,
|
||||
productName: null,
|
||||
productId: 0,
|
||||
isSys: null,
|
||||
},
|
||||
// 产品
|
||||
productInfo: {},
|
||||
// 表单参数
|
||||
form: {
|
||||
version: 1.0
|
||||
},
|
||||
// 表单校验
|
||||
rules: {
|
||||
firmwareName: [{
|
||||
required: true,
|
||||
message: "固件名称不能为空",
|
||||
trigger: "blur"
|
||||
}],
|
||||
version: [{
|
||||
required: true,
|
||||
message: "固件版本不能为空",
|
||||
trigger: "blur"
|
||||
}],
|
||||
filePath: [{
|
||||
required: true,
|
||||
message: "文件路径不能为空",
|
||||
trigger: "blur"
|
||||
}],
|
||||
},
|
||||
// 上传参数
|
||||
upload: {
|
||||
// 是否禁用上传
|
||||
isUploading: false,
|
||||
// 设置上传的请求头部
|
||||
headers: {
|
||||
Authorization: "Bearer " + getToken()
|
||||
},
|
||||
// 上传的地址
|
||||
url: process.env.VUE_APP_BASE_API + "/iot/tool/upload",
|
||||
// 上传的文件列表
|
||||
fileList: []
|
||||
},
|
||||
|
||||
};
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
getDownloadUrl(path) {
|
||||
return window.location.origin + process.env.VUE_APP_BASE_API + path;
|
||||
},
|
||||
/** 查询产品固件列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listFirmware(this.queryParams).then(response => {
|
||||
this.firmwareList = response.rows;
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
this.open = false;
|
||||
this.reset();
|
||||
},
|
||||
// 表单重置
|
||||
reset() {
|
||||
this.form = {
|
||||
firmwareId: null,
|
||||
firmwareName: null,
|
||||
tenantId: null,
|
||||
tenantName: null,
|
||||
productId: this.form.productId,
|
||||
productName: this.form.productName,
|
||||
isSys: null,
|
||||
isLatest: 0,
|
||||
version: 1.0,
|
||||
filePath: null,
|
||||
delFlag: null,
|
||||
createBy: null,
|
||||
createTime: null,
|
||||
updateBy: null,
|
||||
updateTime: null,
|
||||
remark: null
|
||||
};
|
||||
this.resetForm("form");
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm("queryForm");
|
||||
this.handleQuery();
|
||||
},
|
||||
// 多选框选中数据
|
||||
handleSelectionChange(selection) {
|
||||
this.ids = selection.map(item => item.firmwareId)
|
||||
this.single = selection.length !== 1
|
||||
this.multiple = !selection.length
|
||||
},
|
||||
/** 新增按钮操作 */
|
||||
handleAdd() {
|
||||
this.reset();
|
||||
this.open = true;
|
||||
this.title = "添加产品固件";
|
||||
this.upload.fileList = [];
|
||||
},
|
||||
/** 修改按钮操作 */
|
||||
handleUpdate(row) {
|
||||
this.reset();
|
||||
const firmwareId = row.firmwareId || this.ids
|
||||
getFirmware(firmwareId).then(response => {
|
||||
this.form = response.data;
|
||||
this.open = true;
|
||||
this.title = "修改产品固件";
|
||||
this.upload.fileList = [{
|
||||
name: this.form.firmwareName,
|
||||
url: this.form.filePath
|
||||
}];
|
||||
});
|
||||
|
||||
},
|
||||
/** 提交按钮 */
|
||||
submitForm() {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
if (this.form.firmwareId != null) {
|
||||
updateFirmware(this.form).then(response => {
|
||||
this.$modal.msgSuccess("修改成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
});
|
||||
} else {
|
||||
addFirmware(this.form).then(response => {
|
||||
this.$modal.msgSuccess("新增成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
handleDelete(row) {
|
||||
const firmwareIds = row.firmwareId || this.ids;
|
||||
this.$modal.confirm('是否确认删除产品固件编号为"' + firmwareIds + '"的数据项?').then(function () {
|
||||
return delFirmware(firmwareIds);
|
||||
}).then(() => {
|
||||
this.getList();
|
||||
this.$modal.msgSuccess("删除成功");
|
||||
}).catch(() => {});
|
||||
},
|
||||
/** 导出按钮操作 */
|
||||
handleExport() {
|
||||
this.download('iot/firmware/export', {
|
||||
...this.queryParams
|
||||
}, `firmware_${new Date().getTime()}.xlsx`)
|
||||
},
|
||||
// 获取文件路径
|
||||
getFilePath(data) {
|
||||
this.form.filePath = data;
|
||||
},
|
||||
|
||||
// 文件提交处理
|
||||
submitUpload() {
|
||||
this.$refs.upload.submit();
|
||||
},
|
||||
// 文件上传中处理
|
||||
handleFileUploadProgress(event, file, fileList) {
|
||||
this.upload.isUploading = true;
|
||||
},
|
||||
// 文件上传成功处理
|
||||
handleFileSuccess(response, file, fileList) {
|
||||
this.upload.isUploading = false;
|
||||
this.form.filePath = response.url;
|
||||
this.$modal.msgSuccess(response.msg);
|
||||
},
|
||||
// 文件下载处理
|
||||
handleDownload(row) {
|
||||
window.open(process.env.VUE_APP_BASE_API + row.filePath);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
};
|
||||
</script>
|
||||
@@ -1,624 +0,0 @@
|
||||
<template>
|
||||
<div style="padding:6px;">
|
||||
|
||||
<el-card v-show="showSearch" style="margin-bottom:6px;">
|
||||
<div style="height:50px; color:#F56C6C;margin-left:20px;">该功能下个版本发布</div>
|
||||
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px" style="margin-bottom:-20px;">
|
||||
<el-form-item label="场景名称" prop="sceneName">
|
||||
<el-input v-model="queryParams.sceneName" placeholder="请输入场景名称" clearable size="small" @keyup.enter.native="handleQuery" />
|
||||
</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-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card style="padding-bottom:100px;">
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['iot:scene:add']">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate" v-hasPermi="['iot:scene:edit']">修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="el-icon-delete" size="mini" disabled @click="handleDelete" v-hasPermi="['iot:scene:remove']">删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" v-hasPermi="['iot:scene:export']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<el-table v-loading="loading" :data="sceneList" @selection-change="handleSelectionChange" border>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="场景名称" align="center" prop="sceneName" />
|
||||
<el-table-column label="用户ID" align="center" prop="userId" />
|
||||
<el-table-column label="用户名称" align="center" prop="userName" />
|
||||
<el-table-column label="触发器" align="center" prop="triggers" />
|
||||
<el-table-column label="执行动作" align="center" prop="actions" />
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="备注" align="center" prop="remark" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['iot:scene:edit']">修改</el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['iot:scene:remove']" disabled>删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
|
||||
|
||||
<!-- 添加或修改场景联动对话框 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||||
<el-row>
|
||||
<el-col :span="16">
|
||||
<el-form-item label="场景名称" prop="sceneName">
|
||||
<el-input v-model="form.sceneName" placeholder="请输入场景名称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="触发器" prop="griggers">
|
||||
<el-select v-model="form.condition" placeholder="请选择" size="small" style="margin-bottom:10px;">
|
||||
<el-option v-for="item in triggerConditions" :key="item.value" :label="item.label" :value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
<div v-for="(item,index) in form.triggers" :key="index" style="margin-bottom:15px;border:1px solid #ddd;padding:10px;">
|
||||
<el-row>
|
||||
<el-col :span="4">
|
||||
<el-select v-model="item.source" placeholder="请选择" size="small" @change="changeTriggerSource">
|
||||
<el-option v-for="subItem in triggerSource" :key="subItem.value" :label="subItem.label" :value="subItem.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="16" :offset="1" v-if="item.source==1">
|
||||
<el-link :underline="false">请选择一个设备<i class="el-icon-edit el-icon--right"></i></el-link>
|
||||
</el-col>
|
||||
<el-col :span="16" :offset="1" v-if="item.source==2">
|
||||
<el-time-picker v-model="timerTimeValue" size="small" value-format="HH:mm" placeholder="选择执行时间" @change="timeChange" :disabled="item.isAdvance==1"></el-time-picker>
|
||||
</el-col>
|
||||
<el-col :span="2" :offset="1" v-if="index!=0"><a style="color:#F56C6C" @click="removeTriggerItem(index)">删除</a></el-col>
|
||||
</el-row>
|
||||
<!--设备-->
|
||||
<el-row v-if="item.source==1">
|
||||
<el-col :span="4">
|
||||
<el-select v-model="item.modelType" placeholder="请选择" size="small">
|
||||
<el-option v-for="subItem in modelTypes" :key="subItem.value" :label="subItem.label" :value="subItem.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="4" :offset="1">
|
||||
<el-select v-model="item.modelType" placeholder="请选择" size="small">
|
||||
<el-option v-for="subItem in modelTypes" :key="subItem.value" :label="subItem.label" :value="subItem.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="5" :offset="1">
|
||||
<el-select v-model="item.operator" placeholder="请选择操作符" size="small">
|
||||
<el-option key="=" label="等于(=)" value="=" />
|
||||
<el-option key="!=" label="不等于(!=)" value="!=" />
|
||||
<el-option key=">" label="大于(>)" value=">" />
|
||||
<el-option key="<" label="小于(<)" value="<" />
|
||||
<el-option key=">=" label="大于等于(>=)" value=">=" />
|
||||
<el-option key="<=" label="小于等于(<=)" value="<=" />
|
||||
<el-option key="contain" label="包含(contain)" value="contain" />
|
||||
<el-option key="notcontain" label="不包含(not contain)" value="notcontain" />
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="5" :offset="1">
|
||||
<el-input v-model="item.value" placeholder="值" size="small" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!--定时-->
|
||||
<el-row v-if="item.source==2">
|
||||
<el-col :span="24">
|
||||
<el-row style="margin-bottom:5px;">
|
||||
<el-col :span="4">
|
||||
<el-select v-model="timerWeekRepeatValue" placeholder="请选择" @change="repeatChange" size="small" :disabled="item.isAdvance==1">
|
||||
<el-option v-for="item in timerWeekRepeats" :key="item.value" :label="item.label" :value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="15" :offset="1" v-if="timerWeekRepeatValue==3">
|
||||
<el-select v-model="timerWeekValue" placeholder="请选择" multiple style="width:485px" @change="weekChange" size="small" :disabled="item.isAdvance==1">
|
||||
<el-option v-for="item in timerWeeks" :key="item.value" :label="item.label" :value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-row>
|
||||
<el-col :span="18">
|
||||
<el-input v-model="item.cronExpression" placeholder="cron执行表达式" :disabled="item.isAdvance==0" size="small">
|
||||
<template slot="append">
|
||||
<el-button type="primary" @click="handleShowCron(item,index)" :disabled="item.isAdvance==0">
|
||||
生成表达式
|
||||
<i class="el-icon-time el-icon--right"></i>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-col>
|
||||
<el-col :span="4" :offset="1">
|
||||
<el-checkbox v-model="item.isAdvance" :true-label="1" :false-label="0" @change="customerCronChange">自定义表达式</el-checkbox>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div>+ <a style="color:#409EFF" @click="addTriggerItem()">添加触发器</a></div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="执行动作">
|
||||
<div v-for="(item,index) in form.actions" :key="index" style="margin-bottom:15px;border:1px solid #ddd;padding:10px;">
|
||||
<el-row>
|
||||
<el-col :span="4">
|
||||
<el-select v-model="item.source" placeholder="请选择" size="small">
|
||||
<el-option v-for="subItem in actionSource" :key="subItem.value" :label="subItem.label" :value="subItem.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="10" :offset="1" v-if="item.source==1">
|
||||
<el-link :underline="false">请选择一个设备<i class="el-icon-edit el-icon--right"></i></el-link>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!---设备-->
|
||||
<el-row v-if="item.source==1">
|
||||
<el-col :span="4">
|
||||
<el-select v-model="item.modelType" placeholder="请选择" size="small">
|
||||
<el-option v-for="subItem in modelTypes" :key="subItem.value" :label="subItem.label" :value="subItem.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="4" :offset="1">
|
||||
<el-select v-model="item.modelType" placeholder="请选择" size="small">
|
||||
<el-option v-for="subItem in modelTypes" :key="subItem.value" :label="subItem.label" :value="subItem.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="11" :offset="1">
|
||||
<el-input v-model="item.value" placeholder="值" size="small" />
|
||||
</el-col>
|
||||
<el-col :span="2" :offset="1" v-if="index!=0"><a style="color:#F56C6C" @click="removeActionItem(index)">删除</a></el-col>
|
||||
</el-row>
|
||||
<!--告警输出-->
|
||||
<el-row v-if="item.source==3">
|
||||
<el-col :span="4">
|
||||
<el-select v-model="item.alertLevel" placeholder="告警级别" size="small">
|
||||
<el-option v-for="dict in dict.type.iot_alert_level" :key="dict.value" :label="dict.label" :value="parseInt(dict.value)"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="16" :offset="1">
|
||||
<el-input v-model="item.alertName" placeholder="请输入告警名称" size="small" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div>+ <a style="color:#409EFF" @click="addActionItem()">添加执行动作</a></div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm" disabled>确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog title="Cron表达式生成器" :visible.sync="openCron" append-to-body destroy-on-close class="scrollbar">
|
||||
<crontab @hide="openCron=false" @fill="crontabFill" :expression="expression" style="padding-bottom:80px;"></crontab>
|
||||
</el-dialog>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
listScene,
|
||||
getScene,
|
||||
delScene,
|
||||
addScene,
|
||||
updateScene
|
||||
} from "@/api/iot/scene";
|
||||
import Crontab from '@/components/Crontab'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Crontab
|
||||
},
|
||||
name: "Scene",
|
||||
dicts: ['iot_alert_level'],
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 选中数组
|
||||
ids: [],
|
||||
// 非单个禁用
|
||||
single: true,
|
||||
// 非多个禁用
|
||||
multiple: true,
|
||||
// 显示搜索条件
|
||||
showSearch: true,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 场景联动表格数据
|
||||
sceneList: [],
|
||||
// 弹出层标题
|
||||
title: "",
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 是否显示Cron表达式弹出层
|
||||
openCron: false,
|
||||
// 传入的表达式
|
||||
expression: "",
|
||||
// 触发器的索引,用于接收传入的表达式
|
||||
triggerIndex:0,
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
sceneName: null,
|
||||
userId: null,
|
||||
userName: null,
|
||||
},
|
||||
// 周
|
||||
timerWeekRepeats: [{
|
||||
value: '1',
|
||||
label: '每天'
|
||||
}, {
|
||||
value: '2',
|
||||
label: '仅此一次'
|
||||
}, {
|
||||
value: '3',
|
||||
label: '指定'
|
||||
}],
|
||||
timerWeekRepeatValue: "1",
|
||||
|
||||
timerWeeks: [{
|
||||
value: 1,
|
||||
label: '周一'
|
||||
}, {
|
||||
value: 2,
|
||||
label: '周二'
|
||||
}, {
|
||||
value: 3,
|
||||
label: '周三'
|
||||
}, {
|
||||
value: 4,
|
||||
label: '周四'
|
||||
}, {
|
||||
value: 5,
|
||||
label: '周五'
|
||||
}, {
|
||||
value: 6,
|
||||
label: '周六'
|
||||
}, {
|
||||
value: 7,
|
||||
label: '周日'
|
||||
}],
|
||||
timerWeekValue: [1, 2, 3, 4, 5, 6, 7],
|
||||
// 时间
|
||||
timerTimeValue: '',
|
||||
// 触发器源 1=设备,2=定时,3=告警输出
|
||||
triggerSource: [{
|
||||
value: 1,
|
||||
label: '设备'
|
||||
}, {
|
||||
value: 2,
|
||||
label: '定时'
|
||||
}],
|
||||
// 执行动作源
|
||||
actionSource: [{
|
||||
value: 1,
|
||||
label: '设备'
|
||||
}, {
|
||||
value: 3,
|
||||
label: '告警输出'
|
||||
}],
|
||||
// 物模型类别
|
||||
modelTypes: [{
|
||||
value: 1,
|
||||
label: '属性'
|
||||
}, {
|
||||
value: 2,
|
||||
label: '功能'
|
||||
}],
|
||||
// 触发器条件
|
||||
triggerConditions: [{
|
||||
value: "all",
|
||||
label: '满足所有条件'
|
||||
}, {
|
||||
value: "any",
|
||||
label: '满足任一条件'
|
||||
}],
|
||||
// 表单参数
|
||||
form: {
|
||||
condition: "all", // 触发器条件
|
||||
triggers: [],
|
||||
actions: []
|
||||
},
|
||||
// 表单校验
|
||||
rules: {
|
||||
sceneName: [{
|
||||
required: true,
|
||||
message: "场景名称不能为空",
|
||||
trigger: "blur"
|
||||
}],
|
||||
userId: [{
|
||||
required: true,
|
||||
message: "用户ID不能为空",
|
||||
trigger: "blur"
|
||||
}],
|
||||
userName: [{
|
||||
required: true,
|
||||
message: "用户名称不能为空",
|
||||
trigger: "blur"
|
||||
}],
|
||||
triggers: [{
|
||||
required: true,
|
||||
message: "触发器不能为空",
|
||||
trigger: "blur"
|
||||
}],
|
||||
actions: [{
|
||||
required: true,
|
||||
message: "执行动作不能为空",
|
||||
trigger: "blur"
|
||||
}],
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
/** 查询场景联动列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listScene(this.queryParams).then(response => {
|
||||
this.sceneList = response.rows;
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
this.open = false;
|
||||
this.reset();
|
||||
},
|
||||
// 表单重置
|
||||
reset() {
|
||||
this.form = {
|
||||
sceneId: null,
|
||||
sceneName: null,
|
||||
userId: null,
|
||||
userName: null,
|
||||
createBy: null,
|
||||
createTime: null,
|
||||
updateBy: null,
|
||||
updateTime: null,
|
||||
remark: null,
|
||||
condition: "all", // 触发器条件
|
||||
triggers: [{
|
||||
id: "",
|
||||
name: "",
|
||||
value: "",
|
||||
deviceId: 0,
|
||||
deviceName: "请选择一个设备",
|
||||
source: 1, //1=设备,2=定时,3=告警输出
|
||||
modelType: 1, // 1=属性,2=功能
|
||||
jobId: 0,
|
||||
cronExpression: "",
|
||||
isAdvance: 0
|
||||
}],
|
||||
actions: [{
|
||||
id: "",
|
||||
name: "",
|
||||
value: "",
|
||||
deviceId: 0,
|
||||
deviceName: "请选择一个设备",
|
||||
source: 1, //1=设备,2=定时,3=告警输出
|
||||
modelType: 1, // 1=属性,2=功能
|
||||
}]
|
||||
};
|
||||
this.resetForm("form");
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm("queryForm");
|
||||
this.handleQuery();
|
||||
},
|
||||
// 多选框选中数据
|
||||
handleSelectionChange(selection) {
|
||||
this.ids = selection.map(item => item.sceneId)
|
||||
this.single = selection.length !== 1
|
||||
this.multiple = !selection.length
|
||||
},
|
||||
/** 新增按钮操作 */
|
||||
handleAdd() {
|
||||
this.reset();
|
||||
this.open = true;
|
||||
this.title = "添加场景联动";
|
||||
},
|
||||
/** 修改按钮操作 */
|
||||
handleUpdate(row) {
|
||||
this.reset();
|
||||
const sceneId = row.sceneId || this.ids
|
||||
getScene(sceneId).then(response => {
|
||||
this.form = response.data;
|
||||
this.open = true;
|
||||
this.title = "修改场景联动";
|
||||
});
|
||||
},
|
||||
/** 提交按钮 */
|
||||
submitForm() {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
if (this.form.sceneId != null) {
|
||||
updateScene(this.form).then(response => {
|
||||
this.$modal.msgSuccess("修改成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
});
|
||||
} else {
|
||||
addScene(this.form).then(response => {
|
||||
this.$modal.msgSuccess("新增成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
handleDelete(row) {
|
||||
const sceneIds = row.sceneId || this.ids;
|
||||
this.$modal.confirm('是否确认删除场景联动编号为"' + sceneIds + '"的数据项?').then(function () {
|
||||
return delScene(sceneIds);
|
||||
}).then(() => {
|
||||
this.getList();
|
||||
this.$modal.msgSuccess("删除成功");
|
||||
}).catch(() => {});
|
||||
},
|
||||
/** 导出按钮操作 */
|
||||
handleExport() {
|
||||
this.download('iot/scene/export', {
|
||||
...this.queryParams
|
||||
}, `scene_${new Date().getTime()}.xlsx`)
|
||||
},
|
||||
/** 添加动作 */
|
||||
addActionItem() {
|
||||
this.form.actions.push({
|
||||
id: "",
|
||||
name: "",
|
||||
value: ""
|
||||
})
|
||||
},
|
||||
/** 删除动作 */
|
||||
removeActionItem(index) {
|
||||
this.form.actions.splice(index, 1);
|
||||
},
|
||||
/** 触发器源改变事件 **/
|
||||
changeTriggerSource(data) {
|
||||
this.setTriggerSource();
|
||||
},
|
||||
/** 设置触发器源 **/
|
||||
setTriggerSource() {
|
||||
// 触发器智能包含一个定时
|
||||
let hasTimer = false;
|
||||
for (let i = 0; i < this.form.triggers.length; i++) {
|
||||
if (this.form.triggers[i].source == 2) {
|
||||
hasTimer = true;
|
||||
this.triggerIndex=i;
|
||||
}
|
||||
}
|
||||
if (hasTimer) {
|
||||
this.triggerSource = [{
|
||||
value: 1,
|
||||
label: '设备'
|
||||
}];
|
||||
} else {
|
||||
//定时
|
||||
this.triggerSource = [{
|
||||
value: 1,
|
||||
label: '设备'
|
||||
}, {
|
||||
value: 2,
|
||||
label: '定时'
|
||||
}];
|
||||
|
||||
}
|
||||
},
|
||||
/** 添加触发器 */
|
||||
addTriggerItem() {
|
||||
this.setTriggerSource();
|
||||
this.form.triggers.push({
|
||||
id: "",
|
||||
name: "",
|
||||
value: "",
|
||||
deviceId: 0,
|
||||
deviceName: "请选择一个设备",
|
||||
source: 1, //1=设备,2=定时,3=告警输出
|
||||
modelType: 1, // 1=属性,2=功能
|
||||
jobId: 0,
|
||||
cronExpression: "",
|
||||
isAdvance: 0
|
||||
})
|
||||
|
||||
},
|
||||
/** 删除触发器 */
|
||||
removeTriggerItem(index) {
|
||||
this.form.triggers.splice(index, 1);
|
||||
this.setTriggerSource();
|
||||
},
|
||||
/** cron表达式按钮操作 */
|
||||
handleShowCron(item,index) {
|
||||
this.expression=item.cronExpression;
|
||||
this.triggerIndex=index;
|
||||
this.openCron = true;
|
||||
},
|
||||
/** 确定后回传值 */
|
||||
crontabFill(value) {
|
||||
this.form.triggers[this.triggerIndex].cronExpression = value;
|
||||
},
|
||||
/** 修改重复事件 **/
|
||||
repeatChange(data) {
|
||||
if (this.timerWeekRepeatValue == 1) {
|
||||
// 每天
|
||||
this.timerWeekValue = [1, 2, 3, 4, 5, 6, 7];
|
||||
this.form.isRepeat = 1;
|
||||
} else if (this.timerWeekRepeatValue == 2) {
|
||||
// 仅此一次
|
||||
this.timerWeekValue = [];
|
||||
this.form.isRepeat = 0;
|
||||
} else {
|
||||
// 指定
|
||||
this.form.isRepeat = 1;
|
||||
}
|
||||
this.gentCronExpression();
|
||||
},
|
||||
/** 星期改变事件 **/
|
||||
weekChange(data) {
|
||||
this.gentCronExpression();
|
||||
},
|
||||
/** 时间改变事件 **/
|
||||
timeChange(data) {
|
||||
this.gentCronExpression();
|
||||
},
|
||||
/**自定义cron表达式选项改变事件 */
|
||||
customerCronChange(data){
|
||||
this.gentCronExpression();
|
||||
},
|
||||
/** 生成cron表达式**/
|
||||
gentCronExpression() {
|
||||
if (this.timerTimeValue == "") {
|
||||
this.$modal.alertError("执行时间不能为空");
|
||||
}
|
||||
let minute = this.timerTimeValue.substring(0, 2);
|
||||
let hour = this.timerTimeValue.substring(3);
|
||||
let week = "*";
|
||||
if (this.timerWeekValue.length > 0) {
|
||||
week = this.timerWeekValue;
|
||||
}
|
||||
this.form.triggers[this.triggerIndex].cronExpression = "0 " + minute + " " + hour + " ? * " + week;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
Reference in New Issue
Block a user