前端测试更新
@@ -5,7 +5,7 @@
|
||||
"author": "kerwincui",
|
||||
"license": "AGPL3.0",
|
||||
"scripts": {
|
||||
"dev": "vue-cli-service serve --open",
|
||||
"dev": "set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --open",
|
||||
"build:prod": "set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build --report",
|
||||
"build:stage": "set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build --mode staging",
|
||||
"preview": "set NODE_OPTIONS=--openssl-legacy-provider && node build/index.js --preview",
|
||||
|
||||
45
vue/public/js/echarts.min.js
vendored
@@ -1 +0,0 @@
|
||||
{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"adcode":710000,"name":"台湾省","center":[121.509062,25.044332],"centroid":[120.971485,23.749452],"childrenNum":0,"level":"province","acroutes":[100000],"parent":{"adcode":100000}},"geometry":{"type":"MultiPolygon","coordinates":[[[[120.443558,22.441245],[120.517584,22.408536],[120.569903,22.361728],[120.640505,22.241347],[120.659209,22.15432],[120.662001,22.066983],[120.651464,22.033165],[120.667691,21.983168],[120.70157,21.927065],[120.743246,21.915569],[120.78155,21.923957],[120.85468,21.883333],[120.87291,21.897387],[120.866482,21.98436],[120.907315,22.033208],[120.904154,22.119757],[120.914955,22.302718],[120.981658,22.528305],[121.015009,22.584168],[121.033292,22.650725],[121.078498,22.669656],[121.170544,22.723133],[121.210481,22.770665],[121.237931,22.836327],[121.324708,22.945666],[121.354687,23.01006],[121.370388,23.084347],[121.409535,23.102669],[121.430294,23.137196],[121.415015,23.195973],[121.440358,23.272096],[121.479558,23.3223],[121.497788,23.419789],[121.521497,23.483198],[121.523078,23.538708],[121.587778,23.76102],[121.621604,23.92075],[121.659381,24.006893],[121.639992,24.064276],[121.643838,24.097713],[121.678085,24.133906],[121.689044,24.174401],[121.809172,24.339055],[121.826717,24.423579],[121.867498,24.478978],[121.885464,24.529677],[121.892524,24.617912],[121.862598,24.671515],[121.837993,24.76015],[121.845053,24.836269],[121.932883,24.938645],[122.012178,25.001469],[121.980776,25.03079],[121.947425,25.031955],[121.917077,25.137908],[121.842155,25.135332],[121.782407,25.160425],[121.750531,25.160716],[121.707327,25.191493],[121.700319,25.226913],[121.655324,25.241859],[121.623026,25.294694],[121.584986,25.308926],[121.535038,25.307515],[121.444415,25.270624],[121.413487,25.238912],[121.371864,25.159885],[121.319281,25.140691],[121.209322,25.127104],[121.133135,25.078728],[121.102102,25.075153],[121.024704,25.040479],[121.009688,24.993649],[120.960899,24.940227],[120.908475,24.852012],[120.892299,24.767526],[120.823753,24.688321],[120.762371,24.658335],[120.688661,24.600678],[120.64277,24.490172],[120.589187,24.432354],[120.546299,24.370413],[120.521009,24.312038],[120.470534,24.24259],[120.451461,24.182691],[120.392029,24.11824],[120.316158,23.984881],[120.278276,23.927798],[120.245768,23.840553],[120.175377,23.807385],[120.102773,23.700981],[120.094817,23.587466],[120.121741,23.504664],[120.107831,23.341264],[120.081434,23.29191],[120.018947,23.073115],[120.029537,23.048623],[120.131382,23.002118],[120.149138,22.896715],[120.200403,22.721101],[120.274272,22.560181],[120.297191,22.531315],[120.443558,22.441245]]],[[[124.542984,25.903911],[124.586346,25.913777],[124.572805,25.93974],[124.541825,25.931031],[124.542984,25.903911]]],[[[123.445286,25.725966],[123.472104,25.713024],[123.508933,25.723237],[123.514834,25.751226],[123.483063,25.768587],[123.444496,25.746514],[123.445286,25.725966]]],[[[119.64597,23.55091],[119.701081,23.550657],[119.678057,23.600041],[119.610089,23.603953],[119.594388,23.577245],[119.566306,23.584732],[119.562565,23.530377],[119.573788,23.505885],[119.609141,23.503864],[119.64597,23.55091]]],[[[123.667207,25.914066],[123.707092,25.916873],[123.678008,25.938667],[123.667207,25.914066]]],[[[119.506031,23.625567],[119.505241,23.575814],[119.472416,23.557136],[119.523207,23.563699],[119.525578,23.624895],[119.506031,23.625567]]],[[[119.49739,23.386683],[119.495125,23.350156],[119.516885,23.349903],[119.49739,23.386683]]],[[[119.557454,23.666474],[119.604083,23.616989],[119.615516,23.660925],[119.586485,23.675974],[119.557454,23.666474]]],[[[121.46823,22.676644],[121.476502,22.64166],[121.513541,22.631833],[121.5147,22.67639],[121.46823,22.676644]]],[[[121.510538,22.087185],[121.507693,22.048523],[121.534089,22.022146],[121.594522,21.995382],[121.604586,22.022699],[121.575028,22.037122],[121.575607,22.084421],[121.510538,22.087185]]],[[[122.097533,25.500168],[122.093581,25.47183],[122.124825,25.475932],[122.097533,25.500168]]],[[[119.421467,23.216684],[119.421309,23.18935],[119.453396,23.217697],[119.421467,23.216684]]],[[[120.355042,22.327259],[120.395454,22.342287],[120.383072,22.355573],[120.355042,22.327259]]]]}}]}
|
||||
@@ -1,168 +0,0 @@
|
||||
|
||||
/*
|
||||
* @LastEditors: Please set LastEditors
|
||||
* @LastEditTime: 2022-04-28 10:25:38
|
||||
*/
|
||||
import axios from 'axios';
|
||||
import UtilVar from "@/config/UtilVar";
|
||||
import router from '@/router'
|
||||
|
||||
let baseUrl = UtilVar.baseUrl
|
||||
const CancelToken = axios.CancelToken;
|
||||
export { baseUrl };
|
||||
// axios.defaults.withCredentials = true;
|
||||
// 添加请求拦截器
|
||||
axios.interceptors.request.use(function (config) {
|
||||
// 在发送请求之前做些什么 传token
|
||||
let token = localStorage.getItem("token");
|
||||
config.headers.common['Content-Type'] = "application/json;charset=utf-8";
|
||||
config.headers.common['token'] = token; //Authorization
|
||||
return config;
|
||||
}, function (error) {
|
||||
// 对请求错误做些什么
|
||||
console.log(error)
|
||||
return Promise.reject(error);
|
||||
});
|
||||
/**
|
||||
* @响应拦截
|
||||
*/
|
||||
axios.interceptors.response.use(response => {
|
||||
|
||||
if (response.status !== 200) {
|
||||
return Promise.reject(response)
|
||||
}
|
||||
/**
|
||||
* @code 登录过期 token验证失败 根据后端调
|
||||
*/
|
||||
if (response.data.code == UtilVar.code) {
|
||||
// router.push("/login")
|
||||
}
|
||||
return response.data
|
||||
}, error => {
|
||||
// console.log('axiosError',error);
|
||||
let err = {
|
||||
success: false,
|
||||
msg: "未知异常,请联系管理员!"
|
||||
}
|
||||
return Promise.reject(err)
|
||||
})
|
||||
|
||||
let configs_ENC = {
|
||||
headers: { 'enc': UtilVar.ENC }
|
||||
}
|
||||
//处理是否加密数据
|
||||
let isEncryptionParam = (params) => {
|
||||
return params
|
||||
|
||||
}
|
||||
export const GET = async (url, params) => {
|
||||
try {
|
||||
params = isEncryptionParam(params)
|
||||
const data = await axios.get(`${baseUrl}${url}`, {
|
||||
params: params,
|
||||
headers: configs_ENC.headers
|
||||
}, configs_ENC);
|
||||
return data;
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
//没有基地址 访问根目录下文件
|
||||
|
||||
export const GETNOBASE = async (url, params) => {
|
||||
try {
|
||||
const data = await axios.get(url, {
|
||||
params: params,
|
||||
});
|
||||
return data;
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
export const POST = async (url, params) => {
|
||||
try {
|
||||
params = isEncryptionParam(params)
|
||||
const data = await axios.post(`${baseUrl}${url}`, params, configs_ENC);
|
||||
return data;
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
export const PUT = async (url, params) => {
|
||||
try {
|
||||
params = isEncryptionParam(params)
|
||||
const data = await axios.put(`${baseUrl}${url}`, params, configs_ENC);
|
||||
return data;
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
export const DELETE = async (url, params) => {
|
||||
// console.log(params)
|
||||
try {
|
||||
params = isEncryptionParam(params)
|
||||
const data = await axios.delete(`${baseUrl}${url}`, { data: params, headers: configs_ENC.headers }, configs_ENC);
|
||||
return data;
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @文件类型提交方法
|
||||
*/
|
||||
let configs = {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
|
||||
}
|
||||
export const FILESubmit = async (url, params, config) => {
|
||||
try {
|
||||
const data = await axios.post(`${baseUrl}${url}`, params, {
|
||||
...configs,
|
||||
cancelToken: new CancelToken(function executor(c) {
|
||||
config.setCancel && config.setCancel(c)
|
||||
}),
|
||||
onUploadProgress: (e) => {
|
||||
if (e.total > 0) {
|
||||
e.percent = e.loaded / e.total * 100;
|
||||
}
|
||||
// console.log(config)
|
||||
config.onProgress && config.onProgress(e)
|
||||
},
|
||||
|
||||
});
|
||||
return data;
|
||||
} catch (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载文档流
|
||||
* @param {config.responseType} 下载文件流根据后端 配置 arraybuffer || blod
|
||||
*/
|
||||
export const FILE = async (config = {}, body, params) => {
|
||||
try {
|
||||
const data = await axios({
|
||||
method: config.method || 'get',
|
||||
url: `${baseUrl}${config.url}`,
|
||||
data: body,
|
||||
params: params,
|
||||
responseType: config.responseType || 'blob',
|
||||
onDownloadProgress: (e) => {
|
||||
// console.log(e,e.currentTarget)
|
||||
// if (e.currentTarget.response.size > 0) {
|
||||
// e.percent = e.loaded / e.currentTarget.response.size * 100;
|
||||
// }
|
||||
// event.srcElement.getResponseHeader('content-length')
|
||||
config.onProgress && config.onProgress(e)
|
||||
},
|
||||
});
|
||||
return data;
|
||||
} catch (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* @Author: daidai
|
||||
* @Date: 2021-12-09 10:47:56
|
||||
* @LastEditors: Please set LastEditors
|
||||
* @LastEditTime: 2022-04-27 16:32:31
|
||||
* @FilePath: \web-pc\src\api\index.js
|
||||
*/
|
||||
|
||||
|
||||
import { currentList,
|
||||
currentPage,
|
||||
currentSave,
|
||||
currentUpdate,
|
||||
currentDelete,
|
||||
currentSelect,
|
||||
currentSelectList,
|
||||
|
||||
currentPOST,
|
||||
currentGET,
|
||||
currentApi
|
||||
|
||||
} from './modules'
|
||||
import {
|
||||
GETNOBASE,
|
||||
GET
|
||||
} from './api'
|
||||
|
||||
|
||||
export {
|
||||
GETNOBASE,
|
||||
GET
|
||||
}
|
||||
|
||||
|
||||
export {
|
||||
currentApi,
|
||||
currentList,
|
||||
currentPage,
|
||||
currentSave,
|
||||
currentUpdate,
|
||||
currentDelete,
|
||||
currentSelect,
|
||||
currentSelectList,
|
||||
currentPOST,
|
||||
currentGET
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* @Author: daidai
|
||||
* @Date: 2021-12-23 11:18:37
|
||||
* @LastEditors: Please set LastEditors
|
||||
* @LastEditTime: 2022-04-28 15:10:45
|
||||
* @FilePath: \web-pc\src\api\modules\index.js
|
||||
*/
|
||||
import * as API from "../api";
|
||||
|
||||
export const paramType ={
|
||||
'big1':"/bigscreen/countUserNum", //用户总览
|
||||
'big2':"/bigscreen/countDeviceNum", //设备总览
|
||||
'big3':"/bigscreen/sbtx", //设备提醒
|
||||
'big4':"/bigscreen/alarmNum", //报警次数
|
||||
'big5':'/bigscreen/ssyj',//实时预警
|
||||
'big6':'/bigscreen/installationPlan',// 安装计划
|
||||
'big7':'/bigscreen/ranking',// 报警排名
|
||||
'big8':'/bigscreen/centermap',// //中间地图
|
||||
|
||||
}
|
||||
/****************** 通用增删改查 ********************* */
|
||||
/**
|
||||
* 通用列表
|
||||
* @param {*} param
|
||||
*/
|
||||
export const currentList = (key,param)=> {
|
||||
return API.GET(paramType[key]+"/list", param)
|
||||
}
|
||||
export const currentPage = (key,param)=> {
|
||||
return API.GET(paramType[key]+"/page", param)
|
||||
}
|
||||
/**
|
||||
* 查询可选择的列表
|
||||
* @param {*} param
|
||||
*/
|
||||
export const currentSelectList= (key,param)=> {
|
||||
return API.GET(paramType[key]+"/selectList", param)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通用新增
|
||||
* @param {*} param
|
||||
*/
|
||||
export const currentSave= (key,param)=> {
|
||||
return API.POST(paramType[key]+"/save", param)
|
||||
}
|
||||
/**
|
||||
* 通用修改
|
||||
* @param {*} param
|
||||
*/
|
||||
export const currentUpdate= (key,param) => {
|
||||
return API.POST(paramType[key]+"/update", param)
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用删除
|
||||
* @param {*} param
|
||||
*/
|
||||
export const currentDelete= (key,param) => {
|
||||
return API.POST(paramType[key]+"/delete", param)
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用获取所有不分页
|
||||
* @param {*} param
|
||||
*/
|
||||
export const currentSelect= (key,param)=> {
|
||||
return API.GET(paramType[key]+"/select", param)
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用GET
|
||||
* @param {*} param
|
||||
*/
|
||||
export const currentGET= (key,param)=> {
|
||||
return API.GET(paramType[key], param)
|
||||
}
|
||||
/**
|
||||
* 通用POST
|
||||
* @param {*} param
|
||||
*/
|
||||
export const currentPOST= (key,param)=> {
|
||||
return API.POST(paramType[key], param)
|
||||
}
|
||||
// 通用接口集合
|
||||
export const currentApi={
|
||||
currentList,
|
||||
currentPage,
|
||||
currentSave,
|
||||
currentUpdate,
|
||||
currentDelete,
|
||||
currentSelect,
|
||||
currentSelectList,
|
||||
currentPOST,
|
||||
currentGET
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询设备告警列表
|
||||
export function listAlert(query) {
|
||||
return request({
|
||||
url: '/iot/alert/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询设备告警详细
|
||||
export function getAlert(alertId) {
|
||||
return request({
|
||||
url: '/iot/alert/' + alertId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增设备告警
|
||||
export function addAlert(data) {
|
||||
return request({
|
||||
url: '/iot/alert',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改设备告警
|
||||
export function updateAlert(data) {
|
||||
return request({
|
||||
url: '/iot/alert',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除设备告警
|
||||
export function delAlert(alertId) {
|
||||
return request({
|
||||
url: '/iot/alert/' + alertId,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询设备告警列表
|
||||
export function listAlertLog(query) {
|
||||
return request({
|
||||
url: '/iot/alertLog/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询设备告警详细
|
||||
export function getAlertLog(alertLogId) {
|
||||
return request({
|
||||
url: '/iot/alertLog/' + alertLogId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增设备告警
|
||||
export function addAlertLog(data) {
|
||||
return request({
|
||||
url: '/iot/alertLog',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改设备告警
|
||||
export function updateAlertLog(data) {
|
||||
return request({
|
||||
url: '/iot/alertLog',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除设备告警
|
||||
export function delAlertLog(alertLogId) {
|
||||
return request({
|
||||
url: '/iot/alertLog/' + alertLogId,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
@@ -1,378 +0,0 @@
|
||||
import axios from 'axios'
|
||||
|
||||
const username = process.env.VUE_APP_EMQX_API_USER_NAME;
|
||||
const password = process.env.VUE_APP_EMQX_API_PASSWORD;
|
||||
|
||||
// 集群下所有客户端列表
|
||||
export function listMqttClient(query) {
|
||||
var url = "/api/v4/clients";
|
||||
return axios({
|
||||
method: 'get',
|
||||
url: url,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 集群下所有订阅信息
|
||||
export function listMqttSubscribe(query) {
|
||||
var url = "/api/v4/subscriptions";
|
||||
return axios({
|
||||
method: 'get',
|
||||
url: url,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 集群下所有主题/路由信息
|
||||
export function listMqttTopic(query) {
|
||||
var url = "/api/v4/routes";
|
||||
return axios({
|
||||
method: 'get',
|
||||
url: url,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 集群下所有插件信息
|
||||
export function listMqttPlugin() {
|
||||
var url = "/api/v4/plugins";
|
||||
return axios({
|
||||
method: 'get',
|
||||
url: url,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 加载指定节点的指定插件
|
||||
export function loadMqttPlugin(node,plugin) {
|
||||
var url = "/api/v4/nodes/"+node+"/plugins/"+plugin+"/load";
|
||||
return axios({
|
||||
method: 'put',
|
||||
url: url,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 卸载指定节点的指定插件
|
||||
export function unloadMqttPlugin(node,plugin) {
|
||||
var url = "/api/v4/nodes/"+node+"/plugins/"+plugin+"/unload";
|
||||
return axios({
|
||||
method: 'put',
|
||||
url: url,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 集群下所有监听器信息
|
||||
export function listMqttListener() {
|
||||
var url = "/api/v4/listeners";
|
||||
return axios({
|
||||
method: 'get',
|
||||
url: url,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 集群下所有统计指标数据
|
||||
export function statisticMqtt() {
|
||||
var url = "/api/v4/metrics";
|
||||
return axios({
|
||||
method: 'get',
|
||||
url: url,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 集群下所有状态数据
|
||||
export function getMqttStats() {
|
||||
var url = "/api/v4/stats";
|
||||
return axios({
|
||||
method: 'get',
|
||||
url: url,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
//断开客户端连接
|
||||
export function eliminateClient(clientId){
|
||||
var url = "/api/v4/clients/"+clientId;
|
||||
return axios({
|
||||
method: 'delete',
|
||||
url: url,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
//查看客户端详情
|
||||
export function getClientDetails(clientId){
|
||||
var url = "/api/v4/clients/"+clientId;
|
||||
return axios({
|
||||
method: 'get',
|
||||
url: url,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
//查看集群下指定客户端的订阅信息
|
||||
export function getSubscriptionsByClientId(clientId){
|
||||
var url = "/api/v4/subscriptions/"+clientId;
|
||||
return axios({
|
||||
method: 'get',
|
||||
url: url,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
//取消该客户端订阅
|
||||
export function unsubscribe(query){
|
||||
var url = "/api/v4/mqtt/unsubscribe";
|
||||
return axios({
|
||||
method: 'post',
|
||||
url: url,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
//添加该客户端订阅
|
||||
export function addSubscribe(query){
|
||||
var url = "/api/v4/mqtt/subscribe";
|
||||
return axios({
|
||||
method: 'post',
|
||||
url: url,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
//获取所有规则引擎的动作
|
||||
export function getRules(ruleid){
|
||||
let url = "";
|
||||
if(typeof(ruleid) == 'undefined' || ruleid == '' ||ruleid == null){
|
||||
url = "/api/v4/rules";
|
||||
}else{
|
||||
url = "/api/v4/rules/"+ruleid;
|
||||
}
|
||||
return axios({
|
||||
method: 'get',
|
||||
url: url,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
//删除规则
|
||||
export function deleteRule(ruleid){
|
||||
var url = "/api/v4/rules/"+ruleid;
|
||||
return axios({
|
||||
method: 'delete',
|
||||
url: url,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
//获取资源列表或详情
|
||||
export function getResources(resourceid){
|
||||
let url = "";
|
||||
if(typeof(resourceid) == 'undefined' || resourceid == '' ||resourceid == null){
|
||||
url = "/api/v4/resources";
|
||||
}else{
|
||||
url = "/api/v4/resources/"+resourceid;
|
||||
}
|
||||
return axios({
|
||||
method: 'get',
|
||||
url: url,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
})
|
||||
}
|
||||
//获取资源状态
|
||||
export function getResourcesStatus(resourceid){
|
||||
let url = "/api/v4/resources/"+resourceid;
|
||||
return axios({
|
||||
method: 'get',
|
||||
url: url,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
//连接资源
|
||||
export function getConnectResource(resourceid){
|
||||
let url = "/api/v4/resources/"+resourceid;
|
||||
return axios({
|
||||
method: 'post',
|
||||
url: url,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
//删除资源
|
||||
export function deleteResource(resourceid){
|
||||
let url = "/api/v4/resources/"+resourceid;
|
||||
return axios({
|
||||
method: 'delete',
|
||||
url: url,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
//获取资源类型
|
||||
export function getResourcesType(){
|
||||
let url = "/api/v4/resource_types";
|
||||
return axios({
|
||||
method: 'get',
|
||||
url: url,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
//资源测试连接
|
||||
export function getResourcesConnect(query){
|
||||
let url = "/api/v4/resources?test=true";
|
||||
return axios({
|
||||
method: 'post',
|
||||
url: url,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: query
|
||||
})
|
||||
}
|
||||
//新增资源
|
||||
export function saveResources(query){
|
||||
let url = "/api/v4/resources";
|
||||
return axios({
|
||||
method: 'post',
|
||||
url: url,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: query
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
//获取规则消息类型
|
||||
export function getRulesEvent(){
|
||||
let url = "/api/v4/rule_events";
|
||||
return axios({
|
||||
method: 'get',
|
||||
url: url,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
//获取响应动作类型
|
||||
export function getActionsEvent(){
|
||||
let url = "/api/v4/actions";
|
||||
return axios({
|
||||
method: 'get',
|
||||
url: url,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
//新增规则引擎
|
||||
export function saveRule(query){
|
||||
let url = "/api/v4/rules";
|
||||
return axios({
|
||||
method: 'post',
|
||||
url: url,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: query
|
||||
})
|
||||
}
|
||||
//测试规则引擎
|
||||
export function testConnectRule(query){
|
||||
let url = "/api/v4/rules?test=true";
|
||||
return axios({
|
||||
method: 'post',
|
||||
url: url,
|
||||
auth: {
|
||||
username: username,
|
||||
password: password
|
||||
},
|
||||
data: query
|
||||
})
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询产品固件列表
|
||||
export function listFirmware(query) {
|
||||
return request({
|
||||
url: '/iot/firmware/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询设备最新固件
|
||||
export function getLatestFirmware(deviceId) {
|
||||
return request({
|
||||
url: '/iot/firmware/getLatest/' + deviceId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 查询产品固件详细
|
||||
export function getFirmware(firmwareId) {
|
||||
return request({
|
||||
url: '/iot/firmware/' + firmwareId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增产品固件
|
||||
export function addFirmware(data) {
|
||||
return request({
|
||||
url: '/iot/firmware',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改产品固件
|
||||
export function updateFirmware(data) {
|
||||
return request({
|
||||
url: '/iot/firmware',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除产品固件
|
||||
export function delFirmware(firmwareId) {
|
||||
return request({
|
||||
url: '/iot/firmware/' + firmwareId,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询场景联动列表
|
||||
export function listScene(query) {
|
||||
return request({
|
||||
url: '/iot/scene/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询场景联动详细
|
||||
export function getScene(sceneId) {
|
||||
return request({
|
||||
url: '/iot/scene/' + sceneId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增场景联动
|
||||
export function addScene(data) {
|
||||
return request({
|
||||
url: '/iot/scene',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改场景联动
|
||||
export function updateScene(data) {
|
||||
return request({
|
||||
url: '/iot/scene',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除场景联动
|
||||
export function delScene(sceneId) {
|
||||
return request({
|
||||
url: '/iot/scene/' + sceneId,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 8.7 KiB |
|
Before Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 7.6 KiB |
|
Before Width: | Height: | Size: 8.5 KiB |
|
Before Width: | Height: | Size: 289 KiB |
|
Before Width: | Height: | Size: 24 KiB |
@@ -1,15 +0,0 @@
|
||||
/*
|
||||
* @Author: daidai
|
||||
* @Date: 2021-12-06 10:58:24
|
||||
* @LastEditors: Please set LastEditors
|
||||
* @LastEditTime: 2022-04-27 16:54:32
|
||||
* @FilePath: \web-pc\src\config\UtilVar.js
|
||||
*/
|
||||
var UtilVar = {
|
||||
ENC: false, //返回结果是否加密
|
||||
baseUrl: `http://locolhost:8888`,
|
||||
code: 401,
|
||||
}
|
||||
|
||||
export default UtilVar
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
/*
|
||||
* @Author: daidai
|
||||
* @Date: 2022-01-11 15:27:31
|
||||
* @LastEditors: Please set LastEditors
|
||||
* @LastEditTime: 2022-04-21 14:32:03
|
||||
* @FilePath: \web-pc\src\directives\filters.js
|
||||
*/
|
||||
export function montionFilter (val) {
|
||||
// console.log(val);
|
||||
return val ? Number(val).toFixed(2) : '--'
|
||||
}
|
||||
@@ -1,233 +0,0 @@
|
||||
import Mock from 'mockjs'
|
||||
//延时200-600毫秒请求到数据
|
||||
Mock.setup({
|
||||
timeout: '200-600'
|
||||
})
|
||||
|
||||
const Random = Mock.Random;
|
||||
// 用户总览
|
||||
function countUserNum() {
|
||||
const a = Mock.mock({
|
||||
success: true,
|
||||
data: {
|
||||
offlineNum:'@integer(1, 100)',
|
||||
lockNum: '@integer(1, 10)',
|
||||
totalNum:218
|
||||
}
|
||||
})
|
||||
a.data.onlineNum=a.data.totalNum-a.data.offlineNum-a.data.lockNum
|
||||
return a
|
||||
}
|
||||
|
||||
// 接口,第一个参数url,第二个参数请求类型,第三个参数响应回调
|
||||
Mock.mock(new RegExp('countUserNum'), 'get', countUserNum)
|
||||
|
||||
// /设备总览
|
||||
|
||||
function countDeviceNum() {
|
||||
const a = Mock.mock({
|
||||
success: true,
|
||||
data: {
|
||||
alarmNum: '@integer(100, 1000)',
|
||||
offlineNum: '@integer(0, 50)',
|
||||
totalNum:698
|
||||
}
|
||||
})
|
||||
a.data.onlineNum=a.data.totalNum-a.data.offlineNum
|
||||
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
Mock.mock(new RegExp('countDeviceNum'), 'get', countDeviceNum)
|
||||
|
||||
// /设备总览
|
||||
|
||||
function sbtx() {
|
||||
const a = Mock.mock({
|
||||
success: true,
|
||||
data: {
|
||||
"list|20": [
|
||||
{
|
||||
provinceName: "@province()",
|
||||
cityName: '@city()',
|
||||
countyName: "@county()",
|
||||
createTime: "@datetime('yyyy-MM-dd HH:mm:ss')",
|
||||
deviceId: "6c512d754bbcd6d7cd86abce0e0cac58",
|
||||
"gatewayno|+1": 10000,
|
||||
"onlineState|1": [0, 1],
|
||||
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
return a
|
||||
}
|
||||
|
||||
Mock.mock(new RegExp('sbtx'), 'get', sbtx)
|
||||
|
||||
|
||||
|
||||
//中间地图
|
||||
|
||||
function centermap(options) {
|
||||
let params = parameteUrl(options.url)
|
||||
if (params.regionCode && params.regionCode != -1) {
|
||||
const a = Mock.mock({
|
||||
success: true,
|
||||
data: {
|
||||
"dataList|30": [
|
||||
{
|
||||
name: "@city()",
|
||||
value: '@integer(1, 1000)'
|
||||
}
|
||||
],
|
||||
regionCode: params.regionCode,//-代表中国
|
||||
}
|
||||
})
|
||||
return a
|
||||
} else {
|
||||
const a = Mock.mock({
|
||||
success: true,
|
||||
data: {
|
||||
"dataList|8": [
|
||||
{
|
||||
name: "@province()",
|
||||
value: '@integer(1, 1000)'
|
||||
}
|
||||
],
|
||||
regionCode: -1,//-代表中国
|
||||
}
|
||||
})
|
||||
return a
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Mock.mock(new RegExp('centermap'), 'get', centermap)
|
||||
|
||||
// 报警次数
|
||||
|
||||
function alarmNum() {
|
||||
const a = Mock.mock({
|
||||
success: true,
|
||||
data: {
|
||||
dateList:['2021-11', '2021-12', '2022-01', '2022-02', '2022-03',"2022-04"],
|
||||
"numList|6":[
|
||||
'@integer(0, 1000)'
|
||||
],
|
||||
"numList2|6":[
|
||||
'@integer(0, 1000)'
|
||||
]
|
||||
}
|
||||
})
|
||||
return a
|
||||
}
|
||||
Mock.mock(new RegExp('alarmNum'), 'get', alarmNum)
|
||||
|
||||
// 实时预警
|
||||
|
||||
function ssyj() {
|
||||
const a = Mock.mock({
|
||||
success: true,
|
||||
data: {
|
||||
"list|40":[{
|
||||
alertdetail: "@csentence(5,10)",
|
||||
"alertname|1": ["水浸告警","各种报警"],
|
||||
alertvalue: "@float(60, 200)",
|
||||
createtime: "2022-04-19 08:38:33",
|
||||
deviceid: null,
|
||||
"gatewayno|+1": 10000,
|
||||
phase: "A1",
|
||||
sbInfo: "@csentence(10,18)",
|
||||
"terminalno|+1": 100,
|
||||
provinceName: "@province()",
|
||||
cityName: '@city()',
|
||||
countyName: "@county()",
|
||||
}],
|
||||
|
||||
}
|
||||
})
|
||||
return a
|
||||
}
|
||||
Mock.mock(new RegExp('ssyj'), 'get', ssyj)
|
||||
//安装计划
|
||||
function installationPlan() {
|
||||
let num= RandomNumBoth(26,32);
|
||||
const a = Mock.mock({
|
||||
["category|"+num]:["@city()"],
|
||||
["barData|"+num]:["@integer(10, 100)"],
|
||||
})
|
||||
let lineData=[],rateData=[];
|
||||
for (let index = 0; index < num; index++) {
|
||||
let lineNum = Mock.mock('@integer(0, 100)')+a.barData[index]
|
||||
lineData.push(lineNum)
|
||||
let rate = a.barData[index] / lineNum;
|
||||
rateData.push((rate*100).toFixed(0))
|
||||
}
|
||||
a.lineData=lineData
|
||||
a.rateData=rateData
|
||||
return {
|
||||
success: true,
|
||||
data:a
|
||||
}
|
||||
}
|
||||
Mock.mock(new RegExp('installationPlan'), 'get', installationPlan)
|
||||
|
||||
|
||||
|
||||
|
||||
//报警排名
|
||||
function ranking() {
|
||||
//多生成几个避免重复 重复会报错
|
||||
let num =Mock.mock({"list|48":[{ value:"@integer(50,1000)",name:"@city()"}]}).list
|
||||
// console.log(num);
|
||||
let newNum =[],numObj={}
|
||||
num.map(item=>{
|
||||
if(!numObj[item.name] && newNum.length<8){
|
||||
numObj[item.name] =true
|
||||
newNum.push(item)
|
||||
}
|
||||
})
|
||||
let arr = newNum.sort((a,b)=>{
|
||||
return b.value-a.value
|
||||
})
|
||||
let a ={
|
||||
success:true,
|
||||
data:arr
|
||||
}
|
||||
return a
|
||||
}
|
||||
Mock.mock(new RegExp('ranking'), 'get', ranking)
|
||||
/**
|
||||
* @description: min ≤ r ≤ max 随机数
|
||||
* @param {*} Min
|
||||
* @param {*} Max
|
||||
* @return {*}
|
||||
*/
|
||||
function RandomNumBoth(Min,Max){
|
||||
var Range = Max - Min;
|
||||
var Rand = Math.random();
|
||||
var num = Min + Math.round(Rand * Range); //四舍五入
|
||||
return num;
|
||||
}
|
||||
/**
|
||||
* @description: 获取路径参数
|
||||
* @param {*} url
|
||||
* @return {*}
|
||||
*/
|
||||
function parameteUrl(url) {
|
||||
var json = {}
|
||||
if (/\?/.test(url)) {
|
||||
var urlString = url.substring(url.indexOf("?") + 1);
|
||||
var urlArray = urlString.split("&");
|
||||
for (var i = 0; i < urlArray.length; i++) {
|
||||
var urlItem = urlArray[i];
|
||||
var item = urlItem.split("=");
|
||||
console.log(item);
|
||||
json[item[0]] = item[1];
|
||||
}
|
||||
return json;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
@@ -1,217 +0,0 @@
|
||||
/*
|
||||
* @Author: daidai
|
||||
* @Date: 2022-03-02 09:51:44
|
||||
* @LastEditors: daidai
|
||||
* @LastEditTime: 2022-03-02 09:51:45
|
||||
* @FilePath: \web-pc\src\pages\big-screen\utils\map\xzqCode.js
|
||||
*/
|
||||
//获取中国行政区 code
|
||||
// AMap.plugin("AMap.DistrictSearch", function () {
|
||||
// var districtSearch = new AMap.DistrictSearch({
|
||||
// // 关键字对应的行政区级别,country表示国家
|
||||
// level: "country",
|
||||
// // 显示下级行政区级数,1表示返回下一级行政区
|
||||
// subdistrict: 1,
|
||||
// });
|
||||
// let xzqCode = {};
|
||||
// // 搜索所有省/直辖市信息
|
||||
// districtSearch.search("中国", function (status, result) {
|
||||
// // console.log(result);
|
||||
// result.districtList[0].districtList.forEach((item) => {
|
||||
// // console.log(item);
|
||||
// xzqCode[item.name] = {
|
||||
// adcode: item.adcode,
|
||||
// level: item.level,
|
||||
// name: item.name,
|
||||
// };
|
||||
// });
|
||||
// });
|
||||
// xzqCode["中国"] = {
|
||||
// adcode: "100000",
|
||||
// level: "country",
|
||||
// name: "中华人民共和国",
|
||||
// };
|
||||
// setTimeout(() => {
|
||||
// console.log(JSON.stringify(xzqCode),);
|
||||
|
||||
// }, 1000);
|
||||
// });
|
||||
|
||||
|
||||
export default {
|
||||
"中国": {
|
||||
"adcode": "100000",
|
||||
"level": "country",
|
||||
"name": "中华人民共和国"
|
||||
},
|
||||
"新疆维吾尔自治区": {
|
||||
"adcode": "650000",
|
||||
"level": "province",
|
||||
"name": "新疆维吾尔自治区"
|
||||
},
|
||||
"湖北省": {
|
||||
"adcode": "420000",
|
||||
"level": "province",
|
||||
"name": "湖北省"
|
||||
},
|
||||
"辽宁省": {
|
||||
"adcode": "210000",
|
||||
"level": "province",
|
||||
"name": "辽宁省"
|
||||
},
|
||||
"广东省": {
|
||||
"adcode": "440000",
|
||||
"level": "province",
|
||||
"name": "广东省"
|
||||
},
|
||||
"内蒙古自治区": {
|
||||
"adcode": "150000",
|
||||
"level": "province",
|
||||
"name": "内蒙古自治区"
|
||||
},
|
||||
"黑龙江省": {
|
||||
"adcode": "230000",
|
||||
"level": "province",
|
||||
"name": "黑龙江省"
|
||||
},
|
||||
"河南省": {
|
||||
"adcode": "410000",
|
||||
"level": "province",
|
||||
"name": "河南省"
|
||||
},
|
||||
"山东省": {
|
||||
"adcode": "370000",
|
||||
"level": "province",
|
||||
"name": "山东省"
|
||||
},
|
||||
"陕西省": {
|
||||
"adcode": "610000",
|
||||
"level": "province",
|
||||
"name": "陕西省"
|
||||
},
|
||||
"贵州省": {
|
||||
"adcode": "520000",
|
||||
"level": "province",
|
||||
"name": "贵州省"
|
||||
},
|
||||
"上海市": {
|
||||
"adcode": "310000",
|
||||
"level": "province",
|
||||
"name": "上海市"
|
||||
},
|
||||
"重庆市": {
|
||||
"adcode": "500000",
|
||||
"level": "province",
|
||||
"name": "重庆市"
|
||||
},
|
||||
"西藏自治区": {
|
||||
"adcode": "540000",
|
||||
"level": "province",
|
||||
"name": "西藏自治区"
|
||||
},
|
||||
"安徽省": {
|
||||
"adcode": "340000",
|
||||
"level": "province",
|
||||
"name": "安徽省"
|
||||
},
|
||||
"福建省": {
|
||||
"adcode": "350000",
|
||||
"level": "province",
|
||||
"name": "福建省"
|
||||
},
|
||||
"湖南省": {
|
||||
"adcode": "430000",
|
||||
"level": "province",
|
||||
"name": "湖南省"
|
||||
},
|
||||
"海南省": {
|
||||
"adcode": "460000",
|
||||
"level": "province",
|
||||
"name": "海南省"
|
||||
},
|
||||
"江苏省": {
|
||||
"adcode": "320000",
|
||||
"level": "province",
|
||||
"name": "江苏省"
|
||||
},
|
||||
"青海省": {
|
||||
"adcode": "630000",
|
||||
"level": "province",
|
||||
"name": "青海省"
|
||||
},
|
||||
"广西壮族自治区": {
|
||||
"adcode": "450000",
|
||||
"level": "province",
|
||||
"name": "广西壮族自治区"
|
||||
},
|
||||
"宁夏回族自治区": {
|
||||
"adcode": "640000",
|
||||
"level": "province",
|
||||
"name": "宁夏回族自治区"
|
||||
},
|
||||
"浙江省": {
|
||||
"adcode": "330000",
|
||||
"level": "province",
|
||||
"name": "浙江省"
|
||||
},
|
||||
"河北省": {
|
||||
"adcode": "130000",
|
||||
"level": "province",
|
||||
"name": "河北省"
|
||||
},
|
||||
"香港特别行政区": {
|
||||
"adcode": "810000",
|
||||
"level": "province",
|
||||
"name": "香港特别行政区"
|
||||
},
|
||||
"台湾省": {
|
||||
"adcode": "710000",
|
||||
"level": "province",
|
||||
"name": "台湾省"
|
||||
},
|
||||
"澳门特别行政区": {
|
||||
"adcode": "820000",
|
||||
"level": "province",
|
||||
"name": "澳门特别行政区"
|
||||
},
|
||||
"甘肃省": {
|
||||
"adcode": "620000",
|
||||
"level": "province",
|
||||
"name": "甘肃省"
|
||||
},
|
||||
"四川省": {
|
||||
"adcode": "510000",
|
||||
"level": "province",
|
||||
"name": "四川省"
|
||||
},
|
||||
"天津市": {
|
||||
"adcode": "120000",
|
||||
"level": "province",
|
||||
"name": "天津市"
|
||||
},
|
||||
"江西省": {
|
||||
"adcode": "360000",
|
||||
"level": "province",
|
||||
"name": "江西省"
|
||||
},
|
||||
"云南省": {
|
||||
"adcode": "530000",
|
||||
"level": "province",
|
||||
"name": "云南省"
|
||||
},
|
||||
"山西省": {
|
||||
"adcode": "140000",
|
||||
"level": "province",
|
||||
"name": "山西省"
|
||||
},
|
||||
"北京市": {
|
||||
"adcode": "110000",
|
||||
"level": "province",
|
||||
"name": "北京市"
|
||||
},
|
||||
"吉林省": {
|
||||
"adcode": "220000",
|
||||
"level": "province",
|
||||
"name": "吉林省"
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||