feat(iot): 新增设备功能调用模块
- 添加功能列表和事件列表的 vuex state管理 - 实现功能调用的简化模式和高级模式 - 增加功能调用结果的展示和记录 - 优化设备信息展示界面,支持功能和事件的显示 - 新增 Monaco 编辑器组件用于 JSON 数据编辑
This commit is contained in:
parent
bae4c40a65
commit
c1ab37bfc1
|
@ -64,6 +64,8 @@
|
|||
"jsbarcode": "^3.11.6",
|
||||
"jsencrypt": "3.0.0-rc.1",
|
||||
"moment": "^2.29.4",
|
||||
"monaco-editor": "0.24.0",
|
||||
"monaco-editor-webpack-plugin": "3.1.0",
|
||||
"nprogress": "0.2.0",
|
||||
"qrcodejs2": "^0.0.2",
|
||||
"quill": "1.3.7",
|
||||
|
|
|
@ -18,6 +18,7 @@ const getters = {
|
|||
attributeList: state => state.attribute.attributeList,
|
||||
groupList: state => state.attribute.groupList,
|
||||
functionList: state => state.attribute.functionList,
|
||||
eventList: state => state.attribute.eventList,
|
||||
attributeInfo: state => state.permission.attribute
|
||||
}
|
||||
export default getters
|
||||
|
|
|
@ -6,6 +6,7 @@ const attribute = {
|
|||
attributeList: [],
|
||||
groupList: [],
|
||||
functionList: [],
|
||||
eventList: [],
|
||||
},
|
||||
|
||||
mutations: {
|
||||
|
@ -66,6 +67,25 @@ const attribute = {
|
|||
GET_FUNCTION_LIST: (state) => {
|
||||
return state.functionList
|
||||
},
|
||||
//功能
|
||||
SET_EVENT_LIST: (state, list) => {
|
||||
state.eventList = list
|
||||
},
|
||||
PUSH_EVENT: (state, item) => {
|
||||
state.eventList.push(item)
|
||||
},
|
||||
UPDATE_EVENT: (state, {item, idx}) => {
|
||||
state.eventList[idx] = item
|
||||
},
|
||||
DELETE_EVENT: (state, idx) => {
|
||||
state.eventList.splice(idx,1);
|
||||
},
|
||||
GET_EVENT_ITEM: (state, idx) => {
|
||||
return state.eventList[idx]
|
||||
},
|
||||
GET_EVENT_LIST: (state) => {
|
||||
return state.eventList
|
||||
},
|
||||
},
|
||||
|
||||
actions: {
|
||||
|
@ -85,6 +105,11 @@ const attribute = {
|
|||
resolve(state.functionList)
|
||||
})
|
||||
},
|
||||
GetEventList({state}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
resolve(state.eventList)
|
||||
})
|
||||
},
|
||||
setAttribute({ commit, state }, data){
|
||||
commit('SET_ATTRIBUTE_LIST', data)
|
||||
},
|
||||
|
@ -93,6 +118,7 @@ const attribute = {
|
|||
commit('SET_ATTRIBUTE_LIST', data.attrList)
|
||||
commit('SET_GROUP_LIST', data.groupList)
|
||||
commit('SET_FUNCTION_LIST', data.functionList)
|
||||
commit('SET_EVENT_LIST', data.eventList)
|
||||
console.log('res:', state, data)
|
||||
},
|
||||
// 新增 属性
|
||||
|
@ -107,6 +133,10 @@ const attribute = {
|
|||
AddFunction({ commit, state }, data) {
|
||||
commit('PUSH_FUNCTION', data)
|
||||
},
|
||||
// 新增 功能
|
||||
AddEvent({ commit, state }, data) {
|
||||
commit('PUSH_EVENT', data)
|
||||
},
|
||||
// 获取 属性 单个信息
|
||||
GetAttributeItem({ commit, state }, idx) {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
@ -119,6 +149,18 @@ const attribute = {
|
|||
resolve(state.groupList[idx])
|
||||
})
|
||||
},
|
||||
// 获取 功能 单个信息
|
||||
GetFunctionItem({ commit, state }, idx) {
|
||||
return new Promise((resolve, reject) => {
|
||||
resolve(state.functionList[idx])
|
||||
})
|
||||
},
|
||||
// 获取 功能 单个信息
|
||||
GetEventItem({ commit, state }, idx) {
|
||||
return new Promise((resolve, reject) => {
|
||||
resolve(state.eventList[idx])
|
||||
})
|
||||
},
|
||||
// 修改 属性
|
||||
EditAttribute({ commit, state }, param) {
|
||||
commit('UPDATE_ATTRIBUTE', param)
|
||||
|
@ -131,6 +173,10 @@ const attribute = {
|
|||
EditFunction({ commit, state }, param) {
|
||||
commit('UPDATE_FUNCTION', param)
|
||||
},
|
||||
// 修改 事件
|
||||
EditEvent({ commit, state }, param) {
|
||||
commit('UPDATE_EVENT', param)
|
||||
},
|
||||
// 删除分组 删除分组 判断分组是否有属性,有属性就不能删除
|
||||
DeleteGroup({ commit, state }, idx) {
|
||||
let groupItem = state.groupList[idx];
|
||||
|
@ -153,7 +199,10 @@ const attribute = {
|
|||
DeleteFunction({ commit, state }, idx) {
|
||||
commit('DELETE_FUNCTION', idx)
|
||||
},
|
||||
|
||||
// 删除事件
|
||||
DeleteEvent({ commit, state }, idx) {
|
||||
commit('DELETE_EVENT', idx)
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
<!--
|
||||
my-monaco-editor:
|
||||
基于monaco-editor封装的vue组件,支持尺寸、配置的响应式
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div :style="{height, width}" class="my-monaco-editor"></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as monaco from 'monaco-editor'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
options: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
}
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: '300px'
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: '100%'
|
||||
},
|
||||
code: {
|
||||
type: [String,Object],
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// defaultOptions: {
|
||||
// value: this.code, // 编辑器的值
|
||||
// language: 'json', //语言
|
||||
// theme: 'vs-dark', // 编辑器主题:vs, hc-black, or vs-dark
|
||||
// automaticLayout: true,
|
||||
// tabSize: 2,
|
||||
// scrollBeyondLastLine: false,
|
||||
// formatOnPaste: true,
|
||||
// }
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
standaloneEditorConstructionOptions() {
|
||||
return Object.assign(this.defaultOptions, this.options)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
createMonacoEditor() {
|
||||
const finalOptions = Object.assign(
|
||||
{
|
||||
value: this.code,
|
||||
language: 'json',
|
||||
theme: 'vs-dark',
|
||||
automaticLayout: true,
|
||||
tabSize: 2,
|
||||
scrollBeyondLastLine: false,
|
||||
formatOnPaste: true
|
||||
},
|
||||
this.options
|
||||
);
|
||||
|
||||
this.monacoEditor = monaco.editor.create(this.$el, finalOptions);
|
||||
|
||||
this.monacoEditor.onDidChangeModelContent(event => {
|
||||
this.$emit('update:code', this.monacoEditor.getValue())
|
||||
});
|
||||
},
|
||||
reSize() {
|
||||
this.$nextTick(() => {
|
||||
this.monacoEditor.layout()
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.createMonacoEditor()
|
||||
},
|
||||
watch: {
|
||||
height() {
|
||||
this.reSize()
|
||||
},
|
||||
width() {
|
||||
this.reSize()
|
||||
},
|
||||
options: {
|
||||
handler() {
|
||||
this.$nextTick(() => {
|
||||
this.monacoEditor.updateOptions(this.standaloneEditorConstructionOptions)
|
||||
})
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
code(newVal) {
|
||||
if (this.monacoEditor && newVal !== this.monacoEditor.getValue()) {
|
||||
this.monacoEditor.setValue(newVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
</style>
|
|
@ -14,9 +14,259 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="functionList.length > 0" class="model-function-list">
|
||||
<div class="function-container">
|
||||
<!-- 左侧功能列表 -->
|
||||
<div :span="4" class="function-tabs">
|
||||
<el-tabs
|
||||
v-model="activeFunction"
|
||||
style="min-height: 200px;width: 150px;height: 100%"
|
||||
tab-position="left"
|
||||
@tab-click="handleFunctionSelect"
|
||||
>
|
||||
<el-tab-pane
|
||||
v-for="(item, index) in functionList"
|
||||
:key="index"
|
||||
:label="item.name"
|
||||
:name="item.id"
|
||||
></el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
|
||||
<!-- 中间参数区域 -->
|
||||
<div :span="14" class="function-params">
|
||||
<div class="params-header">
|
||||
<el-radio-group v-model="functionMode" size="small">
|
||||
<el-radio-button label="simple">精简模式</el-radio-button>
|
||||
<el-radio-button label="advanced">高级模式</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
|
||||
|
||||
<div v-if="currentFunction" class="params-content">
|
||||
<div v-if="functionMode === 'simple'" >
|
||||
<el-form
|
||||
:ref="'form_' + currentFunction.id"
|
||||
:model="formData[currentFunction.id]"
|
||||
>
|
||||
<el-table :data="getSimpleTableData()" style="width: 100%">
|
||||
<el-table-column
|
||||
label="参数名称"
|
||||
prop="name"
|
||||
width="180"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
label="输入类型"
|
||||
prop="type"
|
||||
width="180"
|
||||
></el-table-column>
|
||||
<el-table-column label="值">
|
||||
<template slot-scope="scope">
|
||||
<el-form-item
|
||||
:prop="scope.row.id"
|
||||
:required="scope.row.expands.required"
|
||||
>
|
||||
<!-- 整数类型 -->
|
||||
<el-input-number
|
||||
v-if="
|
||||
['int', 'long'].includes(scope.row.valueType.type)
|
||||
"
|
||||
v-model="formData[currentFunction.id][scope.row.id]"
|
||||
:placeholder="'请输入' + scope.row.name"
|
||||
size="small"
|
||||
></el-input-number>
|
||||
|
||||
<!-- 浮点数类型 -->
|
||||
<el-input-number
|
||||
v-else-if="
|
||||
['float', 'double'].includes(scope.row.valueType.type)
|
||||
"
|
||||
v-model="formData[currentFunction.id][scope.row.id]"
|
||||
:placeholder="'请输入' + scope.row.name"
|
||||
:precision="scope.row.valueType.type==='float'?1:2"
|
||||
size="small"
|
||||
></el-input-number>
|
||||
|
||||
<!-- 字符串类型 -->
|
||||
<el-input
|
||||
v-else-if="scope.row.valueType.type === 'string'"
|
||||
v-model="formData[currentFunction.id][scope.row.id]"
|
||||
:placeholder="'请输入' + scope.row.name"
|
||||
size="small"
|
||||
style="width: 100%"
|
||||
></el-input>
|
||||
|
||||
<!-- 布尔类型 -->
|
||||
<el-switch
|
||||
v-else-if="scope.row.valueType.type === 'boolean'"
|
||||
v-model="formData[currentFunction.id][scope.row.id]"
|
||||
></el-switch>
|
||||
|
||||
<!-- <!– 日期类型 –>-->
|
||||
<!-- <el-date-picker-->
|
||||
<!-- v-else-if="scope.row.valueType.type === 'date'"-->
|
||||
<!-- v-model="formData[currentFunction.id][scope.row.id]"-->
|
||||
<!-- :placeholder="'请选择' + scope.row.name"-->
|
||||
<!-- size="small"-->
|
||||
<!-- style="width: 100%"-->
|
||||
<!-- type="datetime"-->
|
||||
<!-- ></el-date-picker>-->
|
||||
|
||||
<!-- 枚举类型 -->
|
||||
<el-select
|
||||
v-else-if="scope.row.valueType.type === 'enum'"
|
||||
v-model="formData[currentFunction.id][scope.row.id]"
|
||||
:placeholder="'请选择' + scope.row.name"
|
||||
size="small"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="(option, optionIndex) in scope.row.valueType
|
||||
.elements"
|
||||
:key="optionIndex"
|
||||
:label="option.text"
|
||||
:value="option.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
|
||||
<!-- 数组类型 -->
|
||||
<!-- <div-->
|
||||
<!-- v-else-if="scope.row.valueType.type === 'array'"-->
|
||||
<!-- class="array-input"-->
|
||||
<!-- >-->
|
||||
<!-- <el-tag-->
|
||||
<!-- v-for="(tag, tagIndex) in formData[-->
|
||||
<!-- currentFunction.id-->
|
||||
<!-- ][scope.row.id]"-->
|
||||
<!-- :key="tagIndex"-->
|
||||
<!-- closable-->
|
||||
<!-- size="small"-->
|
||||
<!-- @close="-->
|
||||
<!-- handleArrayItemRemove(-->
|
||||
<!-- currentFunction.id,-->
|
||||
<!-- scope.row.id,-->
|
||||
<!-- tagIndex-->
|
||||
<!-- )-->
|
||||
<!-- "-->
|
||||
<!-- >-->
|
||||
<!-- {{ tag }}-->
|
||||
<!-- </el-tag>-->
|
||||
<!-- <el-input-->
|
||||
<!-- v-if="inputVisible[currentFunction.id + scope.row.id]"-->
|
||||
<!-- v-model="-->
|
||||
<!-- inputValue[currentFunction.id + scope.row.id]-->
|
||||
<!-- "-->
|
||||
<!-- class="array-input-new"-->
|
||||
<!-- size="small"-->
|
||||
<!-- @blur="-->
|
||||
<!-- handleArrayItemConfirm(-->
|
||||
<!-- currentFunction.id,-->
|
||||
<!-- scope.row.id-->
|
||||
<!-- )-->
|
||||
<!-- "-->
|
||||
<!-- @keyup.enter.native="-->
|
||||
<!-- handleArrayItemConfirm(-->
|
||||
<!-- currentFunction.id,-->
|
||||
<!-- scope.row.id-->
|
||||
<!-- )-->
|
||||
<!-- "-->
|
||||
<!-- ></el-input>-->
|
||||
<!-- <el-button-->
|
||||
<!-- v-else-->
|
||||
<!-- size="small"-->
|
||||
<!-- @click="-->
|
||||
<!-- showArrayInput(currentFunction.id, scope.row.id)-->
|
||||
<!-- "-->
|
||||
<!-- >+ 添加</el-button-->
|
||||
<!-- >-->
|
||||
<!-- </div>-->
|
||||
|
||||
<!-- <!– 对象类型 –>-->
|
||||
<!-- <el-button-->
|
||||
<!-- v-else-if="scope.row.valueType.type === 'object'"-->
|
||||
<!-- size="small"-->
|
||||
<!-- @click="-->
|
||||
<!-- showJsonEditor(currentFunction.id, scope.row.id)-->
|
||||
<!-- "-->
|
||||
<!-- >编辑对象</el-button-->
|
||||
<!-- >-->
|
||||
<el-input
|
||||
v-else-if="scope.row.valueType.type === 'object'"
|
||||
v-model="formData[currentFunction.id][scope.row.id]"
|
||||
:placeholder="'请输入' + scope.row.name"
|
||||
size="small"
|
||||
style="width: 100%"
|
||||
>
|
||||
<template slot="append">
|
||||
<i class="el-icon-edit-outline" style="cursor: pointer" @click="showJsonEditor(currentFunction.id,scope.row.id)"></i>
|
||||
</template>
|
||||
</el-input>
|
||||
|
||||
<!-- 默认输入框 -->
|
||||
<el-input
|
||||
v-else
|
||||
v-model="formData[currentFunction.id][scope.row.id]"
|
||||
:placeholder="'请输入' + scope.row.name"
|
||||
size="small"
|
||||
style="width: 100%"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="btn-box">
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="submitFunction(currentFunction,'simple')"
|
||||
>执行</el-button
|
||||
>
|
||||
<el-button @click="resetForm()"
|
||||
>重置</el-button
|
||||
>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
<div v-else class="advanced-mode">
|
||||
<div class="editor-container">
|
||||
<my-monaco-editor :code.sync="monacoValue" :options="options" height="360px" ></my-monaco-editor>
|
||||
</div>
|
||||
<div class="btn-box">
|
||||
<el-button type="primary" @click="submitFunction(currentFunction,'advanced')">执行</el-button>
|
||||
<el-button @click="initFormData('advanced')">重置</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧执行结果区域 -->
|
||||
<div :span="6" class="function-result">
|
||||
<div class="result-header">执行结果:</div>
|
||||
<div ref="resultContent" class="result-content">
|
||||
<div
|
||||
v-for="(item, index) in executionResults"
|
||||
:key="index"
|
||||
class="result-item"
|
||||
>
|
||||
<!-- <div class="result-function">{{ item.functionName }}</div>-->
|
||||
<!-- <div-->
|
||||
<!-- :class="item.success ? 'success' : 'error'"-->
|
||||
<!-- class="result-status"-->
|
||||
<!-- >-->
|
||||
<!-- {{ item.success ? "成功" : "失败" }}-->
|
||||
<!-- </div>-->
|
||||
<div class="result-data">{{ item.data }}</div>
|
||||
<div class="result-time">{{ item.time }}</div>
|
||||
</div>
|
||||
<!-- <div v-if="executionResults.length === 0" class="no-result">-->
|
||||
<!-- <div>暂无执行结果</div>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else style="padding: 100px;text-align: center">
|
||||
<i class="el-icon-s-order" style="font-size: 50px;color: #999"></i>
|
||||
<div style="color: #909399;margin-top: 10px">暂无数据</div>
|
||||
<div style="color: #909399;margin-top: 10px">暂无功能</div>
|
||||
</div>
|
||||
|
||||
<el-dialog :visible.sync="open" title="卡管理" width="700px">
|
||||
|
@ -42,18 +292,25 @@
|
|||
>添加卡号</el-button
|
||||
>
|
||||
</div>
|
||||
<el-table v-loading="loading" :data="tableData" height="500" style="width: 100%">
|
||||
<el-table-column
|
||||
type="index"
|
||||
width="70">
|
||||
</el-table-column>
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="tableData"
|
||||
height="500"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column type="index" width="70"> </el-table-column>
|
||||
<el-table-column align="center" label="卡号" prop="cardNumber">
|
||||
</el-table-column>
|
||||
<!-- <el-table-column align="center" label="卡号(16进制)" prop="name">-->
|
||||
<!-- </el-table-column>-->
|
||||
<!-- <el-table-column align="center" label="卡号(16进制)" prop="name">-->
|
||||
<!-- </el-table-column>-->
|
||||
<el-table-column align="center" label="操作" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="small" type="danger" @click="delCardNumber(scope.row.cardNumber)">删除</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
type="danger"
|
||||
@click="delCardNumber(scope.row.cardNumber)"
|
||||
>删除</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
@ -64,6 +321,15 @@
|
|||
>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<!-- JSON编辑器弹窗 -->
|
||||
<el-dialog :visible.sync="jsonEditorVisible" title="编辑对象" width="600px">
|
||||
<my-monaco-editor :code.sync="jsonEditorValue" :options="options" height="360px" ></my-monaco-editor>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="jsonEditorVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="confirmJsonEdit">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
|
@ -72,21 +338,29 @@ import DialogTemplate from "@/components/DialogTemplate";
|
|||
import DeviceAlarmConfig from "@/views/profile/DeviceAlarmConfig/DeviceAlarmConfig";
|
||||
import DeviceTimingConfig from "@/views/profile/DeviceTimingConfig/DeviceTimingConfig";
|
||||
import { addCard, delCard, getCard, setCardQuery } from "@/api/iot/cardNumber";
|
||||
import MyMonacoEditor from '@/views/components/my-monaco-editor'
|
||||
// import JsonEditor from "@/components/JsonEditor";
|
||||
// import { callFunction } from "@/api/iot/function";
|
||||
|
||||
export default {
|
||||
name: "functionWrap",
|
||||
props: ["deviceInfo"],
|
||||
components: { DialogTemplate, DeviceAlarmConfig, DeviceTimingConfig },
|
||||
components: { DialogTemplate, DeviceAlarmConfig, DeviceTimingConfig, MyMonacoEditor },
|
||||
data() {
|
||||
const validatorNull = (rule, value, callback) => {
|
||||
callback();
|
||||
};
|
||||
return {
|
||||
monacoValue: 'ok',
|
||||
options: {},
|
||||
height: '100px',
|
||||
width: '500px',
|
||||
updateState: false,
|
||||
prodtreeOptions: [],
|
||||
modelList: [],
|
||||
showProdSecret: false,
|
||||
showDevicePassword: false,
|
||||
loading:false,
|
||||
loading: false,
|
||||
temp: {
|
||||
deviceName: "",
|
||||
deviceId: undefined
|
||||
|
@ -106,60 +380,424 @@ export default {
|
|||
title: "",
|
||||
open: false,
|
||||
newCardNumber: "",
|
||||
tableData: []
|
||||
tableData: [],
|
||||
functionList: [],
|
||||
functionMode: "simple", // 功能模式:simple-精简模式,advanced-高级模式
|
||||
formData: {}, // 存储所有功能的表单数据
|
||||
inputVisible: {}, // 控制数组输入框的显示
|
||||
inputValue: {}, // 数组输入框的值
|
||||
jsonEditorVisible: false, // JSON编辑器弹窗
|
||||
jsonEditorValue: {}, // JSON编辑器的值
|
||||
currentJsonField: {
|
||||
// 当前正在编辑的JSON字段
|
||||
functionId: "",
|
||||
inputId: ""
|
||||
},
|
||||
activeFunction: "", // 当前选中的功能ID
|
||||
currentFunction: null, // 当前选中的功能对象
|
||||
executionResults: [] // 执行结果列表
|
||||
};
|
||||
},
|
||||
created() {
|
||||
if(this.deviceInfo.deviceId){
|
||||
this.init();
|
||||
if (this.deviceInfo.deviceId) {
|
||||
this.getProdFunctionList();
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
deviceInfo: function(val) {
|
||||
if (val.deviceId) {
|
||||
// 清空之前的数据
|
||||
this.formData = {};
|
||||
this.executionResults = [];
|
||||
this.activeFunction = "";
|
||||
this.currentFunction = null;
|
||||
this.monacoValue = "{}";
|
||||
this.getProdFunctionList();
|
||||
}
|
||||
},
|
||||
functionMode(newVal) {
|
||||
if (newVal === 'advanced') {
|
||||
// 切换到高级模式时,更新编辑器内容
|
||||
this.updateAdvancedModeCode();
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
init(){
|
||||
console.log("this.d eviceInfo",this.deviceInfo)
|
||||
let params = {
|
||||
data: {params:{}},
|
||||
deviceId: this.deviceInfo.deviceId
|
||||
};
|
||||
setCardQuery(params).then(response => {
|
||||
// if(response?.code == 200){
|
||||
// let data = response?.data ||[];
|
||||
// this.tableData = data.map(item=>{
|
||||
// return {
|
||||
// cardNumber: item,
|
||||
// // name: item.cardNumber.toString(16).toUpperCase()
|
||||
// }
|
||||
// })
|
||||
// }else{
|
||||
// this.tableData = []
|
||||
// 获取精简模式表格数据
|
||||
getSimpleTableData() {
|
||||
if (!this.currentFunction || !this.currentFunction.inputs) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return this.currentFunction.inputs.map(input => {
|
||||
// 获取类型显示名称
|
||||
let typeName = "";
|
||||
// switch (input.valueType.type) {
|
||||
// case "int":
|
||||
// typeName = "整数";
|
||||
// break;
|
||||
// case "long":
|
||||
// typeName = "长整数";
|
||||
// break;
|
||||
// case "float":
|
||||
// typeName = "浮点数";
|
||||
// break;
|
||||
// case "double":
|
||||
// typeName = "双精度浮点数";
|
||||
// break;
|
||||
// case "string":
|
||||
// typeName = "字符串";
|
||||
// break;
|
||||
// case "boolean":
|
||||
// typeName = "布尔值";
|
||||
// break;
|
||||
// case "date":
|
||||
// typeName = "日期时间";
|
||||
// break;
|
||||
// case "enum":
|
||||
// typeName = "枚举";
|
||||
// break;
|
||||
// case "array":
|
||||
// typeName = "数组";
|
||||
// break;
|
||||
// case "object":
|
||||
// typeName = "对象";
|
||||
// break;
|
||||
// default:
|
||||
// typeName = input.valueType.type;
|
||||
// }
|
||||
// this.loading = false;
|
||||
})
|
||||
|
||||
return {
|
||||
...input,
|
||||
type: input.valueType.type
|
||||
};
|
||||
});
|
||||
},
|
||||
getProdFunctionList() {
|
||||
// 重置数据
|
||||
this.functionList = [];
|
||||
this.formData = {};
|
||||
this.executionResults = [];
|
||||
|
||||
let functionList = [];
|
||||
try {
|
||||
let json = JSON.parse(this.deviceInfo.prodJson);
|
||||
functionList = json.functions || [];
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
console.log("this.deviceInfo", this.deviceInfo);
|
||||
this.functionList = functionList || [];
|
||||
|
||||
// 初始化表单数据
|
||||
this.initFormData();
|
||||
// 默认选中第一个功能
|
||||
if (this.functionList.length > 0) {
|
||||
this.activeFunction = this.functionList[0].id;
|
||||
this.currentFunction = this.functionList[0];
|
||||
// 更新高级模式编辑器内容
|
||||
if (this.functionMode === 'advanced') {
|
||||
this.updateAdvancedModeCode();
|
||||
}
|
||||
} else {
|
||||
this.activeFunction = "";
|
||||
this.currentFunction = null;
|
||||
this.monacoValue = "{}";
|
||||
}
|
||||
},
|
||||
// 处理功能选择
|
||||
handleFunctionSelect(e) {
|
||||
console.log(e._props.name);
|
||||
this.functionMode = "simple";
|
||||
this.activeFunction = e._props.name;
|
||||
this.currentFunction = this.functionList.find(
|
||||
item => item.id === e._props.name
|
||||
);
|
||||
// 如果是高级模式,更新编辑器内容
|
||||
if (this.functionMode === 'advanced') {
|
||||
this.updateAdvancedModeCode();
|
||||
}
|
||||
},
|
||||
|
||||
// 初始化表单数据
|
||||
initFormData(type) {
|
||||
let formData = {};
|
||||
this.functionList.forEach(item => {
|
||||
this.formData[item.id] = {};
|
||||
formData[item.id] = {};
|
||||
item.inputs.forEach(input => {
|
||||
// 根据不同类型设置默认值
|
||||
if (['int', 'long'].includes(input.valueType.type)) {
|
||||
formData[item.id][input.id] = 0;
|
||||
} else if (['float'].includes(input.valueType.type)) {
|
||||
formData[item.id][input.id] = 0.0;
|
||||
} else if (['double'].includes(input.valueType.type)) {
|
||||
formData[item.id][input.id] = 0.00;
|
||||
} else if (input.valueType.type === 'boolean') {
|
||||
formData[item.id][input.id] = false;
|
||||
} else if (input.valueType.type === 'date') {
|
||||
formData[item.id][input.id] = new Date();
|
||||
} else if (input.valueType.type === 'enum' && input.valueType.elements && input.valueType.elements.length > 0) {
|
||||
formData[item.id][input.id] = input.valueType.elements[0].value;
|
||||
} else if (input.valueType.type === 'array') {
|
||||
formData[item.id][input.id] = [];
|
||||
} else if (input.valueType.type === 'object') {
|
||||
formData[item.id][input.id] = '{}';
|
||||
} else {
|
||||
formData[item.id][input.id] = '';
|
||||
}
|
||||
});
|
||||
});
|
||||
if(type==='advanced'){
|
||||
let monacoValue= JSON.stringify(formData[this.currentFunction.id], null, 2);
|
||||
this.$nextTick(() => {
|
||||
this.$set(this, 'monacoValue', monacoValue);
|
||||
})
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.$set(this, 'formData', formData);
|
||||
})
|
||||
|
||||
},
|
||||
|
||||
// 提交功能
|
||||
submitFunction(item,type) {
|
||||
if(type==='simple'){
|
||||
this.$refs["form_" + item.id].validate(valid => {
|
||||
if (valid) {
|
||||
this.loading = true;
|
||||
|
||||
// 处理表单数据,确保对象类型正确解析
|
||||
const processedData = {};
|
||||
|
||||
// 复制表单数据
|
||||
for (const key in this.formData[item.id]) {
|
||||
const value = this.formData[item.id][key];
|
||||
|
||||
// 查找对应的输入定义
|
||||
const inputDef = item.inputs.find(input => input.id === key);
|
||||
|
||||
// 如果是对象类型且值是字符串,尝试解析为对象
|
||||
if (inputDef && inputDef.valueType.type === 'object' && typeof value === 'string') {
|
||||
try {
|
||||
processedData[key] = JSON.parse(value);
|
||||
} catch (error) {
|
||||
processedData[key] = {};
|
||||
console.error('解析对象失败:', error);
|
||||
}
|
||||
} else {
|
||||
processedData[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
// 模拟API调用
|
||||
setTimeout(() => {
|
||||
this.loading = false;
|
||||
|
||||
// 添加执行结果
|
||||
const result = {
|
||||
time: new Date().toLocaleString(),
|
||||
functionName: item.name,
|
||||
success: Math.random() > 0.2, // 模拟成功/失败
|
||||
data: JSON.stringify(processedData, null, 2)
|
||||
};
|
||||
|
||||
this.executionResults.unshift(result);
|
||||
|
||||
// 控制结果列表最大数量
|
||||
if (this.executionResults.length > 20) {
|
||||
this.executionResults.pop();
|
||||
}
|
||||
|
||||
// 显示执行结果提示
|
||||
if (result.success) {
|
||||
this.$message.success("功能执行成功");
|
||||
} else {
|
||||
this.$message.error("功能执行失败");
|
||||
}
|
||||
|
||||
// 滚动到顶部
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.resultContent) {
|
||||
this.$refs.resultContent.scrollTop = 0;
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
}else{
|
||||
this.loading = true;
|
||||
// 模拟API调用
|
||||
setTimeout(() => {
|
||||
this.loading = false;
|
||||
|
||||
// 添加执行结果
|
||||
const result = {
|
||||
time: new Date().toLocaleString(),
|
||||
functionName: item.name,
|
||||
success: Math.random() > 0.2, // 模拟成功/失败
|
||||
data: this.monacoValue
|
||||
};
|
||||
|
||||
this.executionResults.unshift(result);
|
||||
|
||||
// 控制结果列表最大数量
|
||||
if (this.executionResults.length > 20) {
|
||||
this.executionResults.pop();
|
||||
}
|
||||
|
||||
// 显示执行结果提示
|
||||
if (result.success) {
|
||||
this.$message.success("功能执行成功");
|
||||
} else {
|
||||
this.$message.error("功能执行失败");
|
||||
}
|
||||
|
||||
// 滚动到顶部
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.resultContent) {
|
||||
this.$refs.resultContent.scrollTop = 0;
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
// 重置表单
|
||||
resetForm() {
|
||||
this.initFormData();
|
||||
},
|
||||
|
||||
// 更新高级模式编辑器的内容
|
||||
updateAdvancedModeCode() {
|
||||
if (this.currentFunction && this.formData[this.currentFunction.id]) {
|
||||
// 处理表单数据,确保对象类型正确解析
|
||||
const processedData = {};
|
||||
|
||||
// 复制表单数据
|
||||
for (const key in this.formData[this.currentFunction.id]) {
|
||||
const value = this.formData[this.currentFunction.id][key];
|
||||
|
||||
// 查找对应的输入定义
|
||||
const inputDef = this.currentFunction.inputs.find(input => input.id === key);
|
||||
|
||||
// 如果是对象类型且值是字符串,尝试解析为对象
|
||||
if (inputDef && inputDef.valueType.type === 'object' && typeof value === 'string') {
|
||||
try {
|
||||
processedData[key] = JSON.parse(value);
|
||||
} catch (error) {
|
||||
processedData[key] = {};
|
||||
console.error('解析对象失败:', error);
|
||||
}
|
||||
} else {
|
||||
processedData[key] = value;
|
||||
}
|
||||
}
|
||||
this.monacoValue = JSON.stringify(processedData, null, 2);
|
||||
}
|
||||
},
|
||||
|
||||
// 显示数组输入框
|
||||
showArrayInput(functionId, inputId) {
|
||||
this.inputVisible[functionId + inputId] = true;
|
||||
this.inputValue[functionId + inputId] = "";
|
||||
this.$nextTick(_ => {
|
||||
this.$refs.saveTagInput.$refs.input.focus();
|
||||
});
|
||||
},
|
||||
|
||||
// 处理数组项移除
|
||||
handleArrayItemRemove(functionId, inputId, index) {
|
||||
this.formData[functionId][inputId].splice(index, 1);
|
||||
},
|
||||
|
||||
// 处理数组项确认
|
||||
handleArrayItemConfirm(functionId, inputId) {
|
||||
const inputKey = functionId + inputId;
|
||||
const inputValue = this.inputValue[inputKey];
|
||||
if (inputValue) {
|
||||
this.formData[functionId][inputId].push(inputValue);
|
||||
}
|
||||
this.inputVisible[inputKey] = false;
|
||||
this.inputValue[inputKey] = "";
|
||||
},
|
||||
|
||||
// 显示JSON编辑器
|
||||
showJsonEditor(functionId, inputId) {
|
||||
this.currentJsonField = {
|
||||
functionId,
|
||||
inputId
|
||||
};
|
||||
// 获取当前值
|
||||
let currentValue = this.formData[functionId][inputId];
|
||||
|
||||
// 尝试解析JSON字符串
|
||||
try {
|
||||
// 如果当前值是字符串,尝试解析为JSON对象
|
||||
if (typeof currentValue === 'string') {
|
||||
const parsedValue = JSON.parse(currentValue);
|
||||
// 格式化JSON
|
||||
this.jsonEditorValue = JSON.stringify(parsedValue, null, 2);
|
||||
} else {
|
||||
// 如果已经是对象,直接格式化
|
||||
this.jsonEditorValue = JSON.stringify(currentValue, null, 2);
|
||||
}
|
||||
} catch (error) {
|
||||
// 如果解析失败,使用空对象
|
||||
this.jsonEditorValue = '{}';
|
||||
this.$message.warning('当前值不是有效的JSON,已重置为空对象');
|
||||
}
|
||||
this.jsonEditorVisible = true;
|
||||
},
|
||||
|
||||
// 确认JSON编辑
|
||||
confirmJsonEdit() {
|
||||
try {
|
||||
// 尝试解析编辑器中的JSON
|
||||
const parsedValue = JSON.parse(this.jsonEditorValue);
|
||||
|
||||
// 更新表单数据
|
||||
this.$set(
|
||||
this.formData[this.currentJsonField.functionId],
|
||||
this.currentJsonField.inputId,
|
||||
this.jsonEditorValue
|
||||
);
|
||||
|
||||
// 关闭弹窗
|
||||
this.jsonEditorVisible = false;
|
||||
this.$message.success('对象编辑成功');
|
||||
} catch (error) {
|
||||
this.$message.error('JSON格式错误,请检查输入');
|
||||
}
|
||||
},
|
||||
|
||||
getCardNumberList() {
|
||||
this.loading = true;
|
||||
let params = {
|
||||
data: {params:{}},
|
||||
data: { params: {} },
|
||||
deviceId: this.deviceInfo.deviceId
|
||||
};
|
||||
getCard(params).then(response => {
|
||||
console.log("获取卡号列表", response);
|
||||
if(response?.code == 200){
|
||||
let data = response?.data ||[];
|
||||
this.tableData = data.map(item=>{
|
||||
return {
|
||||
cardNumber: item,
|
||||
// name: item.cardNumber.toString(16).toUpperCase()
|
||||
}
|
||||
})
|
||||
}else{
|
||||
this.tableData = []
|
||||
}
|
||||
this.loading = false;
|
||||
}).catch(e => {
|
||||
this.tableData = []
|
||||
this.loading = false;
|
||||
});
|
||||
getCard(params)
|
||||
.then(response => {
|
||||
console.log("获取卡号列表", response);
|
||||
if (response?.code == 200) {
|
||||
let data = response?.data || [];
|
||||
this.tableData = data.map(item => {
|
||||
return {
|
||||
cardNumber: item
|
||||
// name: item.cardNumber.toString(16).toUpperCase()
|
||||
};
|
||||
});
|
||||
} else {
|
||||
this.tableData = [];
|
||||
}
|
||||
this.loading = false;
|
||||
})
|
||||
.catch(e => {
|
||||
this.tableData = [];
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
openLock() {
|
||||
console.log("开锁");
|
||||
|
@ -168,20 +806,20 @@ export default {
|
|||
cancelButtonText: "取消",
|
||||
inputPattern: /^[a-z A-z 0-9 $.]+/,
|
||||
inputType: "password",
|
||||
inputErrorMessage: "登录密码不能为空",
|
||||
inputErrorMessage: "登录密码不能为空"
|
||||
}).then(({ value }) => {
|
||||
let params = {
|
||||
data: {
|
||||
// cmd: "set_switch",
|
||||
params: {
|
||||
switch: 0,
|
||||
},
|
||||
switch: 0
|
||||
}
|
||||
},
|
||||
deviceId: this.deviceInfo.deviceId,
|
||||
verifyKey: value,
|
||||
verifyKey: value
|
||||
};
|
||||
setSwitchControl(params).then((res) => {
|
||||
if(res.code==200){
|
||||
setSwitchControl(params).then(res => {
|
||||
if (res.code == 200) {
|
||||
this.msgSuccess("开锁成功");
|
||||
}
|
||||
});
|
||||
|
@ -196,12 +834,12 @@ export default {
|
|||
addCardNumber() {
|
||||
console.log("新增卡", this.newCardNumber);
|
||||
let params = {
|
||||
data: {params:{card:this.newCardNumber}},
|
||||
data: { params: { card: this.newCardNumber } },
|
||||
deviceId: this.deviceInfo.deviceId
|
||||
};
|
||||
addCard(params).then(response => {
|
||||
console.log("添加卡号", response);
|
||||
if(response?.code == 200){
|
||||
if (response?.code == 200) {
|
||||
this.msgSuccess("添加成功");
|
||||
this.getCardNumberList();
|
||||
}
|
||||
|
@ -210,21 +848,21 @@ export default {
|
|||
delCardNumber(cardNumber) {
|
||||
console.log("删除卡", cardNumber);
|
||||
let params = {
|
||||
data: {params:{card:cardNumber}},
|
||||
data: { params: { card: cardNumber } },
|
||||
deviceId: this.deviceInfo.deviceId
|
||||
};
|
||||
delCard(params).then(response => {
|
||||
if(response?.code == 200){
|
||||
if (response?.code == 200) {
|
||||
this.msgSuccess("删除成功");
|
||||
this.getCardNumberList();
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
<style lang="scss" scoped>
|
||||
.function-list-box {
|
||||
.function-list {
|
||||
.function-item {
|
||||
|
@ -239,9 +877,126 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
.model-function-list {
|
||||
.function-container {
|
||||
display: flex;
|
||||
.function-tabs {
|
||||
width: 130px;
|
||||
/* 调整标签栏样式 */
|
||||
::v-deep .is-left.el-tabs__header {
|
||||
width: 130px;
|
||||
}
|
||||
|
||||
::v-deep .el-tabs--left .el-tabs__item {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
padding: 0 20px;
|
||||
}
|
||||
}
|
||||
.function-params {
|
||||
flex: 5;
|
||||
padding: 0 20px;
|
||||
.params-header {
|
||||
text-align: left;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
::v-deep .el-form-item{
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.btn-box{
|
||||
margin-top: 10px;
|
||||
text-align: right;
|
||||
}
|
||||
.advanced-mode {
|
||||
height: 100%;
|
||||
|
||||
.editor-container {
|
||||
width: 100%;
|
||||
min-height: 300px;
|
||||
border: 1px solid #dcdfe6;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.btn-box {
|
||||
margin-top: 15px;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
.function-result {
|
||||
flex: 3;
|
||||
padding: 0 20px;
|
||||
.result-header{
|
||||
font-size: 13px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
.result-content{
|
||||
height: calc(100% - 30px);
|
||||
max-height: 50vh;
|
||||
overflow-y: auto;
|
||||
border: 1px solid #999;
|
||||
border-radius: 5px;
|
||||
padding: 10px;
|
||||
.result-item{
|
||||
margin-bottom: 10px;
|
||||
.result-time{
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.function-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
|
||||
.function-title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.function-content {
|
||||
.function-item {
|
||||
display: flex;
|
||||
padding: 15px;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.function-item-label {
|
||||
width: 150px;
|
||||
font-weight: bold;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.function-item-main {
|
||||
flex: 1;
|
||||
|
||||
.array-input {
|
||||
.el-tag {
|
||||
margin-right: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.array-input-new {
|
||||
width: 100px;
|
||||
margin-right: 10px;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.eldaialog-wrap {
|
||||
.el-dialog__header {
|
||||
|
||||
}
|
||||
.el-radio {
|
||||
width: 90px;
|
||||
|
|
|
@ -232,7 +232,7 @@
|
|||
<el-input
|
||||
v-if="form.protocolType === 'OFFICIAL'"
|
||||
v-model="form.prodKey"
|
||||
:disabled="form.modelId || form.modelId === 0"
|
||||
:disabled="form.modelId !== undefined && form.modelId !== null && form.modelId !== ''"
|
||||
placeholder="请填写产品PK"
|
||||
></el-input>
|
||||
<el-input
|
||||
|
@ -1069,6 +1069,7 @@ export default {
|
|||
});
|
||||
groupList.sort((a, b) => a.sort - b.sort);
|
||||
}
|
||||
|
||||
let functionList = [];
|
||||
if (
|
||||
this.$store.getters.functionList &&
|
||||
|
@ -1077,10 +1078,18 @@ export default {
|
|||
functionList = this.$store.getters.functionList;
|
||||
}
|
||||
|
||||
let eventList = [];
|
||||
if (
|
||||
this.$store.getters.eventList &&
|
||||
this.$store.getters.eventList.length > 0
|
||||
) {
|
||||
eventList = this.$store.getters.eventList;
|
||||
}
|
||||
|
||||
this.form.prodJson = JSON.stringify({
|
||||
properties:attrList,
|
||||
functions:functionList,
|
||||
events:[]
|
||||
events:eventList
|
||||
}) || null;
|
||||
this.form.remark = JSON.stringify(groupList) || null;
|
||||
}
|
||||
|
|
|
@ -2,14 +2,27 @@
|
|||
<div class="device-run-starts-wrap">
|
||||
<div class="cmd-list">
|
||||
<div class="cmd-title-wrap">
|
||||
<svg-icon
|
||||
icon-class="A_product1"
|
||||
style="margin-right: 2px; height: 20px; width: 20px"
|
||||
/>分组名称:
|
||||
<span class="cmd-title">全部</span>
|
||||
<!-- <svg-icon-->
|
||||
<!-- icon-class="A_product1"-->
|
||||
<!-- style="margin-right: 2px; height: 20px; width: 20px"-->
|
||||
<!-- />-->
|
||||
分组名称:
|
||||
<el-select v-model="activeCmd" placeholder="请选择" @change="changeCmd">
|
||||
<el-option
|
||||
v-for="item in cmdList"
|
||||
:key="item.cmdKey"
|
||||
:label="item.cmdName"
|
||||
:value="item.cmdKey"
|
||||
>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<div v-if="filterProdObj.properties.length <= 0" style="width:100%; padding: 100px;text-align: center">
|
||||
<i class="el-icon-s-order" style="font-size: 50px;color: #999"></i>
|
||||
<div style="color: #909399;margin-top: 10px">暂无数据</div>
|
||||
</div>
|
||||
<div
|
||||
v-for="(item, indexs) in prodObj.properties"
|
||||
v-for="(item, indexs) in filterProdObj.properties"
|
||||
:key="indexs"
|
||||
class="param-item2"
|
||||
>
|
||||
|
@ -20,13 +33,13 @@
|
|||
<div class="value-info">
|
||||
<div class="value-wrap">
|
||||
<span
|
||||
v-if="item.dataFormatType =='ENUM'"
|
||||
v-if="item.dataFormatType == 'ENUM'"
|
||||
class="val-span"
|
||||
v-text="item.dataFormatObj[item.lastValue]||item.lastValue"
|
||||
v-text="item.dataFormatObj[item.lastValue] || item.lastValue"
|
||||
>
|
||||
</span>
|
||||
<span
|
||||
v-else-if="item.dataFormatType =='TIME'"
|
||||
v-else-if="item.dataFormatType == 'TIME'"
|
||||
class="val-span"
|
||||
v-text="formatTime(item.lastValue)"
|
||||
>
|
||||
|
@ -51,8 +64,10 @@
|
|||
></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<el-dialog
|
||||
:close-on-click-modal="false"
|
||||
:visible.sync="dialogShow"
|
||||
|
@ -82,7 +97,7 @@
|
|||
import { getDeviceFunList, getDeviceCmdList } from "@/api/iot/device";
|
||||
import { iotWebSocketBaseUrl } from "@/config/env";
|
||||
import RunStateTable from "./table";
|
||||
import moment from 'moment';
|
||||
import moment from "moment";
|
||||
export default {
|
||||
name: "RunStartsWrap",
|
||||
props: ["prodId", "sourceId", "deviceInfo", "wsUrl", "realTimeData"],
|
||||
|
@ -91,7 +106,12 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
cmdList: [],
|
||||
cmdList: [
|
||||
{
|
||||
cmdKey: "",
|
||||
cmdName: "全部"
|
||||
}
|
||||
],
|
||||
cmdObject: {},
|
||||
stompClient: null,
|
||||
deviceKey: "",
|
||||
|
@ -99,10 +119,15 @@ export default {
|
|||
dialogData: {},
|
||||
dialogShow: false,
|
||||
firstWsMassage: true,
|
||||
prodObj:{
|
||||
properties:[],
|
||||
events:[],
|
||||
}
|
||||
prodObj: {
|
||||
properties: [],
|
||||
events: []
|
||||
},
|
||||
filterProdObj: {
|
||||
properties: [],
|
||||
events: []
|
||||
},
|
||||
activeCmd: ""
|
||||
};
|
||||
},
|
||||
created() {
|
||||
|
@ -112,25 +137,40 @@ export default {
|
|||
// this.connection();
|
||||
},
|
||||
methods: {
|
||||
getProdObj(){
|
||||
changeCmd(e) {
|
||||
if (e != "") {
|
||||
const filterObj =
|
||||
this.prodObj.properties.filter(item => item.cmdKey === e) || [];
|
||||
this.$nextTick(() => {
|
||||
this.$set(this.filterProdObj, "properties", filterObj);
|
||||
});
|
||||
} else {
|
||||
this.$nextTick(() => {
|
||||
this.$set(this.filterProdObj, "properties", this.prodObj.properties);
|
||||
});
|
||||
}
|
||||
},
|
||||
getProdObj() {
|
||||
let prodJson = {
|
||||
properties: [],
|
||||
events: []
|
||||
}
|
||||
};
|
||||
try {
|
||||
prodJson = JSON.parse(this.deviceInfo.prodJson);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
if(prodJson.properties){
|
||||
if (prodJson.properties) {
|
||||
let list = prodJson.properties.filter(item => item.show === true) || [];
|
||||
let properties = list.map(item => {
|
||||
if (item.dataFormat) {
|
||||
let dataFormat = item.dataFormat;
|
||||
item.dataFormatType = dataFormat.type;
|
||||
if (dataFormat.list && dataFormat.type === 'ENUM') {
|
||||
if (dataFormat.list && dataFormat.type === "ENUM") {
|
||||
try {
|
||||
item.dataFormatObj = JSON.parse(dataFormat.list.replace(/\\/g, ''));
|
||||
item.dataFormatObj = JSON.parse(
|
||||
dataFormat.list.replace(/\\/g, "")
|
||||
);
|
||||
} catch (e) {
|
||||
item.dataFormatObj = {};
|
||||
}
|
||||
|
@ -138,23 +178,23 @@ export default {
|
|||
}
|
||||
return item;
|
||||
});
|
||||
console.log("properties",properties)
|
||||
this.$nextTick(()=>{
|
||||
this.$set(this.prodObj,'properties',properties)
|
||||
})
|
||||
}else{
|
||||
this.prodObj.properties=[];
|
||||
this.prodObj.properties = properties;
|
||||
this.$nextTick(() => {
|
||||
this.$set(this.filterProdObj, "properties", properties);
|
||||
});
|
||||
} else {
|
||||
this.prodObj.properties = [];
|
||||
}
|
||||
this.prodObj.events=prodJson.events || [];
|
||||
this.prodObj.events = prodJson.events || [];
|
||||
},
|
||||
formatTime(date){
|
||||
formatTime(date) {
|
||||
// 检查时间戳长度
|
||||
if (date && date.toString().length === 10) {
|
||||
// 10 位时间戳
|
||||
return moment(date * 1000).format('YYYY-MM-DD HH:mm:ss');
|
||||
return moment(date * 1000).format("YYYY-MM-DD HH:mm:ss");
|
||||
} else if (date && date.toString().length === 13) {
|
||||
// 13 位时间戳
|
||||
return moment(date).format('YYYY-MM-DD HH:mm:ss');
|
||||
return moment(date).format("YYYY-MM-DD HH:mm:ss");
|
||||
} else {
|
||||
return date;
|
||||
}
|
||||
|
@ -192,18 +232,18 @@ export default {
|
|||
this.stompClient.onclose = this.socket_onclose;
|
||||
},
|
||||
socket_onmsg(evt) {
|
||||
console.log("evt.data",evt.data)
|
||||
console.log("evt.data", evt.data);
|
||||
this.setListData(evt.data);
|
||||
},
|
||||
setListData(data) {
|
||||
// this.recursionSet(this.cmdList, JSON.parse(data));
|
||||
this.recursionSet('', JSON.parse(data));
|
||||
this.recursionSet("", JSON.parse(data));
|
||||
this.firstWsMassage = false;
|
||||
this.$forceUpdate();
|
||||
},
|
||||
recursionSet(list, result) {
|
||||
if(result.type === "properties"){
|
||||
if(result.tags.device_key === this.deviceInfo.deviceKey){
|
||||
if (result.type === "properties") {
|
||||
if (result.tags.device_key === this.deviceInfo.deviceKey) {
|
||||
this.prodObj.properties = this.prodObj.properties.map(item => ({
|
||||
...item,
|
||||
...(item.funKey in result.properties && {
|
||||
|
@ -211,6 +251,15 @@ export default {
|
|||
lastTime: result.properties.timestamp
|
||||
})
|
||||
}));
|
||||
this.filterProdObj.properties = this.filterProdObj.properties.map(
|
||||
item => ({
|
||||
...item,
|
||||
...(item.funKey in result.properties && {
|
||||
lastValue: result.properties[item.funKey],
|
||||
lastTime: result.properties.timestamp
|
||||
})
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -274,9 +323,11 @@ export default {
|
|||
if (item.dataFormat) {
|
||||
let dataFormat = JSON.parse(item.dataFormat);
|
||||
item.dataFormatType = dataFormat.type;
|
||||
if (dataFormat.list && dataFormat.type === 'ENUM') {
|
||||
if (dataFormat.list && dataFormat.type === "ENUM") {
|
||||
try {
|
||||
item.dataFormatObj = JSON.parse(dataFormat.list.replace(/\\/g, ''));
|
||||
item.dataFormatObj = JSON.parse(
|
||||
dataFormat.list.replace(/\\/g, "")
|
||||
);
|
||||
} catch (e) {
|
||||
item.dataFormatObj = {};
|
||||
}
|
||||
|
@ -307,7 +358,15 @@ export default {
|
|||
cmdType: "1"
|
||||
};
|
||||
getDeviceCmdList(params).then(response => {
|
||||
this.cmdList = response.data;
|
||||
if (response.data && response.data.length > 0) {
|
||||
this.cmdList = [
|
||||
{
|
||||
cmdKey: "",
|
||||
cmdName: "全部"
|
||||
},
|
||||
...response.data
|
||||
];
|
||||
}
|
||||
});
|
||||
},
|
||||
closeWebscoket() {
|
||||
|
@ -320,14 +379,16 @@ export default {
|
|||
},
|
||||
async processAllRequests(data) {
|
||||
try {
|
||||
await Promise.all(data.map(async (row, index) => {
|
||||
await this.forGetParams(row, index);
|
||||
}));
|
||||
await Promise.all(
|
||||
data.map(async (row, index) => {
|
||||
await this.forGetParams(row, index);
|
||||
})
|
||||
);
|
||||
this.connection();
|
||||
} catch (error) {
|
||||
console.error('Error processing all requests:', error);
|
||||
console.error("Error processing all requests:", error);
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
destroyed() {
|
||||
this.closeWebscoket();
|
||||
|
@ -370,16 +431,16 @@ export default {
|
|||
flex-wrap: wrap;
|
||||
cursor: default;
|
||||
padding: 10px;
|
||||
&:first-child{
|
||||
&:first-child {
|
||||
padding-top: 0;
|
||||
}
|
||||
.cmd-title-wrap {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
// border-bottom: 1px solid #bdb7b7;
|
||||
height: 35px;
|
||||
font-size: 16px;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
.cmd-title {
|
||||
font-size: 14px;
|
||||
color: #a9a6a6;
|
||||
|
|
|
@ -357,7 +357,6 @@ export default {
|
|||
}, 50)
|
||||
},
|
||||
setList(list) {
|
||||
debugger
|
||||
this.loading = true
|
||||
this.functionList = []
|
||||
setTimeout(() => {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<template>
|
||||
<div class="attribute-form-view">
|
||||
<el-dialog
|
||||
:close-on-click-modal="false"
|
||||
:modal="false"
|
||||
:title="title"
|
||||
:visible.sync="visible"
|
||||
|
@ -83,6 +84,7 @@
|
|||
</el-dialog>
|
||||
<!-- 输入参数弹窗 -->
|
||||
<el-dialog
|
||||
:close-on-click-modal="false"
|
||||
:visible.sync="inputParamOpen"
|
||||
append-to-body
|
||||
class="params-eldialog"
|
||||
|
@ -126,9 +128,8 @@
|
|||
v-model="scope.row.value"
|
||||
:class="{ 'is-error': scope.row.value }"
|
||||
placeholder="请输入值"
|
||||
@blur="validateEnumItem(scope.row, 'value', scope.$index)"
|
||||
></el-input>
|
||||
<div v-if="scope.row.value" class="el-form-item__error">值不能为空</div>
|
||||
<div v-if="scope.row.value===''" class="el-form-item__error">值不能为空</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="描述" prop="text">
|
||||
|
@ -137,9 +138,8 @@
|
|||
v-model="scope.row.text"
|
||||
:class="{ 'is-error': scope.row.text }"
|
||||
placeholder="请输入描述"
|
||||
@blur="validateEnumItem(scope.row, 'text', scope.$index)"
|
||||
></el-input>
|
||||
<div v-if="scope.row.text" class="el-form-item__error">描述不能为空</div>
|
||||
<div v-if="scope.row.text===''" class="el-form-item__error">描述不能为空</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="操作" width="80">
|
||||
|
@ -317,7 +317,7 @@ export default {
|
|||
id: '',
|
||||
name: '',
|
||||
expands: {},
|
||||
async: false,
|
||||
async: true,
|
||||
inputs: [],
|
||||
output: {}
|
||||
};
|
||||
|
@ -336,7 +336,7 @@ export default {
|
|||
id: '',
|
||||
name: '',
|
||||
expands: {},
|
||||
async: false,
|
||||
async: true,
|
||||
inputs: [],
|
||||
output: {}
|
||||
};
|
||||
|
@ -433,20 +433,11 @@ export default {
|
|||
|
||||
// 添加一个新的枚举项
|
||||
const newEnumItem = JSON.parse(JSON.stringify(defaultenumForm));
|
||||
newEnumItem.value = false;
|
||||
newEnumItem.text = false;
|
||||
newEnumItem.value = '';
|
||||
newEnumItem.text = '';
|
||||
this.inputFormObj.form.valueType.elements.push(newEnumItem);
|
||||
},
|
||||
|
||||
validateEnumItem(item, field, index) {
|
||||
if (field === 'value') {
|
||||
item.value = !item.value;
|
||||
} else if (field === 'text') {
|
||||
item.text = !item.text;
|
||||
}
|
||||
return !item.value && !item.text;
|
||||
},
|
||||
|
||||
// 修改提交方法,增加枚举项验证
|
||||
submitInputForm() {
|
||||
// 验证表单
|
||||
|
@ -465,9 +456,9 @@ export default {
|
|||
let hasError = false;
|
||||
for (let i = 0; i < this.inputFormObj.form.valueType.elements.length; i++) {
|
||||
const item = this.inputFormObj.form.valueType.elements[i];
|
||||
item.value = !item.value;
|
||||
item.text = !item.text;
|
||||
if (item.value || item.text) {
|
||||
let value = !item.value;
|
||||
let text = !item.text;
|
||||
if (value || text) {
|
||||
hasError = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -198,21 +198,27 @@ export default {
|
|||
handleInitData() {
|
||||
let arttributeList = [],
|
||||
groupList = [],
|
||||
functionList = [];
|
||||
functionList = [],
|
||||
eventList = [];
|
||||
|
||||
try {
|
||||
let json = JSON.parse(this.arttributeList);
|
||||
if(json.properties){
|
||||
arttributeList = json.properties;
|
||||
groupList = JSON.parse(this.groupList);
|
||||
functionList = json.functions;
|
||||
eventList = json.events;
|
||||
}else{
|
||||
arttributeList = json;
|
||||
groupList = JSON.parse(this.groupList);
|
||||
functionList = json.functions;
|
||||
eventList = json.events;
|
||||
}
|
||||
} catch (error) {
|
||||
arttributeList = [];
|
||||
groupList = [];
|
||||
functionList = [];
|
||||
eventList = [];
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
|
@ -221,7 +227,8 @@ export default {
|
|||
this.$store.dispatch("InitAttributeAndGroup", {
|
||||
attrList: arttributeList,
|
||||
groupList: groupList,
|
||||
functionList:functionList
|
||||
functionList:functionList,
|
||||
eventList:eventList
|
||||
});
|
||||
},
|
||||
},
|
||||
|
|
|
@ -3,6 +3,7 @@ const path = require('path')
|
|||
const defaultSettings = require('./src/settings.js')
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||
const CompressionWebpackPlugin = require('compression-webpack-plugin');
|
||||
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin')
|
||||
|
||||
function resolve(dir) {
|
||||
return path.join(__dirname, dir)
|
||||
|
@ -55,6 +56,7 @@ module.exports = {
|
|||
{ from: 'node_modules/@liveqing/liveplayer/dist/component/liveplayer.swf'},
|
||||
{ from: 'node_modules/@liveqing/liveplayer/dist/component/liveplayer-lib.min.js', to: 'cdn/js/liveplayer/'},
|
||||
]),
|
||||
new MonacoWebpackPlugin()
|
||||
],
|
||||
name: name,
|
||||
resolve: {
|
||||
|
@ -93,7 +95,7 @@ module.exports = {
|
|||
}]);
|
||||
|
||||
config
|
||||
.when(process.env.NODE_ENV !== 'development'&&process.env.NODE_ENV !== 'drgy'&&process.env.NODE_ENV !== 'dr',
|
||||
.when(process.env.NODE_ENV !== 'development'&&process.env.NODE_ENV !== 'drgyprod'&&process.env.NODE_ENV !== 'dr',
|
||||
config => {
|
||||
config
|
||||
.plugin('ScriptExtHtmlWebpackPlugin')
|
||||
|
|
Loading…
Reference in New Issue