381 lines
12 KiB
Vue
Raw Permalink Normal View History

2025-07-07 09:21:15 +08:00
<template>
<view class="back" :style="{'backgroundColor': template.bgColor,}">
<image :src="template.bgImg" mode="aspectFill" class="full-screen"></image>
<view class="content">
<view v-for="(item,index) in components" :key="index"
:style="{ 'marginTop':item.setStyle.marginTop+'px','marginBottom':item.setStyle.marginBottom+'px' }">
<view
v-if="item.component !== 'hstoricalDataGauge' && item.component !== 'captionText' && device.thingsModels">
<view v-for="(param,paramindex) in item.setConfig.attributes" :key="paramindex">
<view v-if="item.component === 'textDisplay1'">
<textDisplay1Vue :backColor="item.setStyle.backColor" :nameColor="item.setStyle.nameColor"
:statusColor="item.setStyle.statusColor" :showIcon="item.setStyle.showIcon"
:iconColor="item.setStyle.iconColor" :iconBackColor="item.setStyle.iconBackColor"
:templateName="param.templateName" :value="param" :device="device"
@send-Service="handelSendService" ref="textDisplay1Vue" />
</view>
<view v-if="item.component === 'numDisplay1'">
<numDisplay1Vue :backColor="item.setStyle.backColor" :nameColor="item.setStyle.nameColor"
:numColor="item.setStyle.numColor" :showIcon="item.setStyle.showIcon"
:iconColor="item.setStyle.iconColor" :iconBackColor="item.setStyle.iconBackColor"
:templateName="param.templateName" :value="param" ref="numDisplay1Vue" />
</view>
<view v-if="item.component === 'numControl1'">
<numControl1Vue :backColor="item.setStyle.backColor" :nameColor="item.setStyle.nameColor"
:numColor="item.setStyle.numColor" :showIcon="item.setStyle.showIcon"
:iconColor="item.setStyle.iconColor" :iconBackColor="item.setStyle.iconBackColor"
:templateName="param.templateName" :value="param" :device="device" :unit="param.unit"
@send-Service="handelSendService" ref="numControl1Vue" />
</view>
<view v-if="item.component === 'mulStatusControl1'">
<mulStatusControl1Vue :rowNum="item.setStyle.rowNum" :fontSize="item.setStyle.fontSize"
:figureHeight="item.setStyle.figureHeight" :borderRadius="item.setStyle.borderRadius"
:backColor="item.setStyle.backColor" :nameColor="item.setStyle.nameColor"
:noColor="item.setStyle.noColor" :offColor="item.setStyle.offColor"
:noBackColor="item.setStyle.noBackColor" :offBackColor="item.setStyle.offBackColor"
:templateName="param.templateName" :enumList="param.enumList" :value="param"
:device="device" ref="mulStatusControl1Vue" @send-Service="handelSendService" />
</view>
<view v-if="item.component === 'btnControl1'">
<btnControl1Vue :backColor="item.setStyle.backColor" :nameColor="item.setStyle.nameColor"
:model="item.setStyle.model" :btnColor="item.setStyle.btnColor"
:templateName="param.templateName" :value="param" :device="device" ref="btnControl1Vue"
@send-Service="handelSendService" />
</view>
</view>
</view>
<view v-if="item.component === 'hstoricalDataGauge' && device.thingsModels">
<u-grid :col="item.setStyle.rowNum">
<u-grid-item v-for="(param,paramindex) in item.setConfig.attributes" :key="paramindex">
<hstoricalDataGaugeVue :width="item.setStyle.width" :backColor="item.setStyle.backColor"
:nameColor="item.setStyle.nameColor" :loopColor="item.setStyle.loopColor"
:numColor="item.setStyle.numColor" :templateName="param.templateName" :value="param"
ref="hstoricalDataGaugeVue" />
</u-grid-item>
</u-grid>
</view>
<view v-if="item.component === 'captionText'">
<captionTextVue :name="item.setStyle.name" :description="item.setStyle.description"
:wordSize="item.setStyle.wordSize" :descriptionSize="item.setStyle.descriptionSize"
:wordWeight="item.setStyle.wordWeight" :positions="item.setStyle.positions"
:descriptionWeight="item.setStyle.descriptionWeight" :wordColor="item.setStyle.wordColor"
:descriptionColor="item.setStyle.descriptionColor" :backColor="item.setStyle.backColor"
:wordHeight="item.setStyle.wordHeight" />
</view>
</view>
</view>
</view>
</template>
<script>
import textDisplay1Vue from '../drag/components/textDisplay1.vue';
import numDisplay1Vue from '../drag/components/numDisplay1.vue';
import numControl1Vue from '../drag/components/numControl1.vue';
import mulStatusControl1Vue from '../drag/components/mulStatusControl1.vue';
import btnControl1Vue from '../drag/components/btnControl1.vue';
import hstoricalDataGaugeVue from '../drag/components/hstoricalDataGauge.vue';
import captionTextVue from '../drag/components/captionText.vue';
import {
listThingsModel
} from '@/apis/modules/device.js';
import {
getOrderControl
} from '@/apis/modules/device.js';
import {
serviceInvoke
} from '@/apis/modules/runtime.js';
export default {
name: 'drag',
props: {
drag: {
type: Object,
default: null
},
device: {
type: Object,
default: null
}
},
watch: {
// 兼容小程序
drag: function(newVal, oldVal) {
this.init()
},
device: function(newVal, oldVal) {
if (newVal.deviceName !== '') {
this.deviceInfo = newVal;
this.mqttCallback();
}
}
},
components: {
textDisplay1Vue,
numDisplay1Vue,
numControl1Vue,
mulStatusControl1Vue,
btnControl1Vue,
hstoricalDataGaugeVue,
captionTextVue
},
data() {
return {
components: [],
deviceInfo: {},
isIssue: false,
issueOpations: [], // 下发数据
loading: false,
model: [],
template: {}
};
},
created() {
// 获取设备状态(兼容H5和APP)
if (this.device !== null && Object.keys(this.device).length !== 0) {
this.deviceInfo = this.device;
//this.updateDeviceStatus(this.deviceInfo);
this.mqttCallback();
this.init()
};
},
mounted() {
},
methods: {
/* Mqtt回调处理 */
mqttCallback() {
this.$mqttTool.client.on('message', (topic, message, buffer) => {
let topics = topic.split('/');
let productId = topics[1];
let deviceNum = topics[2];
message = JSON.parse(message.toString());
if (topics[3] == 'status') {
console.log('接收到【设备状态-运行】主题:', topic);
console.log('接收到【设备状态-运行】内容:', message);
// 更新列表中设备的状态
if (this.deviceInfo.serialNumber == deviceNum) {
this.deviceInfo.status = message.status;
this.deviceInfo.isShadow = message.isShadow;
this.deviceInfo.rssi = message.rssi;
}
}
//兼容设备回复
if (topics[4] == 'reply') {
uni.showToast({
icon: 'none',
title: message,
})
}
if (topics[3] == 'property' || topics[3] == 'function' || topic.endsWith(
'ws/service')) {
console.log('接收到【物模型】主题:', topic);
console.log('接收到【物模型】内容:', message);
// 更新列表中设备的属性
if (this.deviceInfo.serialNumber == deviceNum) {
const newValue = new Map();
message.message.forEach(item => {
newValue.set(item.id, item.value);
});
this.components.forEach(item => {
if (item.component !== 'captionText') {
item.setConfig.attributes.forEach(param => {
if (newValue.has(param.identifier)) {
const value = newValue.get(param.identifier)
if (param.datatype === 'integer' || param
.datatype === 'bool' || param.datatype ===
'enum') {
param.value = value !== undefined ? parseInt(
value) :
null;
}
if (param.datatype === 'decimal') {
param.value = value !== undefined ? parseFloat(
value) :
null;
}
if (param.datatype !== 'integer' && param
.datatype !== 'decimal' && param
.datatype !== 'bool' && param.datatype !==
'enum') {
param.value = value
}
// param.value = idToValue.get(param.identifier)
}
})
}
})
console.log("接收后修改值", this.components)
//this.key++
}
}
});
},
//发送指令
async mqttPublish(device, model) {
const command = {};
command[model.identifier] = model.shadow;
const params = {
deviceId: device.deviceId,
modelId: model.modelId
}
//判断是否有权限
const response = await getOrderControl(params);
if (response.code != 200) {
uni.$u.toast(response.msg);
return;
}
const data = {
serialNumber: device.serialNumber,
productId: device.productId,
remoteCommand: command,
identifier: model.identifier,
modelName: model.modelName,
isShadow: device.status != 3,
type: model.type,
}
serviceInvoke(data).then(response => {
if (response.code === 200) {
uni.showToast({
icon: 'none',
title: this.$tt('status.service')
});
}
})
},
handelSendService(value, item) {
const model = this.model.find(param =>
param.identifier === item.identifier
)
model.shadow = value;
this.mqttPublish(this.device, model)
},
// 获取数据采集数据
getValue(component) {
this.$nextTick(() => {
const queryParams = {
deviceId: this.device.deviceId,
pageNum: 1,
pageSize: 999,
};
listThingsModel(queryParams).then((res) => {
if (res.code === 200) {
this.model = res.rows
const idToValue = new Map();
res.rows.forEach(item => {
idToValue.set(item.identifier, item.value);
});
component.forEach(item => {
if (item.component !== "captionText") {
item.setConfig.attributes.forEach(param => {
if (idToValue.has(param.identifier)) {
const value = idToValue.get(param.identifier)
if (param.datatype === 'integer' || param
.datatype === 'bool' || param.datatype ===
'enum') {
param.value = value ? parseInt(value) :
null
}
if (param.datatype === 'decimal') {
param.value = value ? parseFloat(value) :
null
}
if (param.datatype !== 'integer' && param
.datatype !== 'decimal' && param
.datatype !== 'bool' && param.datatype !==
'enum') {
param.value = value
}
// param.value = idToValue.get(param.identifier)
}
})
}
})
component = this.getIcon(component)
this.components = component
}
});
})
},
getIcon(component) {
const iconList = [{
id: 'el-icon-edit',
icon: 'edit-pen',
}, {
id: 'el-icon-s-tools',
icon: 'setting-fill'
}, {
id: "el-icon-view",
icon: 'eye'
}, {
id: 'el-icon-document',
icon: 'file-text'
}, {
id: 'el-icon-menu',
icon: 'grid-fill'
}]
const map = new Map();
iconList.forEach(item => {
map.set(item.id, item.icon);
});
component.forEach(item => {
if (item.component !== "captionText") {
item.setConfig.attributes.forEach(param => {
if (map.has(param.icon)) {
const value = map.get(param.icon)
if (param.icon) {
param.icon = value ? value : param.icon
}
// param.value = idToValue.get(param.identifier)
}
})
}
})
return component
},
init() {
const component = JSON.parse(this.drag.component)
this.template = JSON.parse(this.drag.templateJson)
this.getValue(component)
},
}
}
</script>
<style lang="less">
.back {
width: 100%;
min-height: 1200rpx;
background-size: cover;
position: relative;
.full-screen {
position: absolute;
width: 100%;
height: 100%;
z-index: 0;
}
.content {
position: relative;
z-index: 1;
}
}
</style>