5.27
This commit is contained in:
parent
9911c4d8c5
commit
b4a2661c04
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@ -6,5 +6,8 @@
|
||||
"i18n-ally.localesPaths": ["src/lang"], // 防止找到不路径
|
||||
"i18n-ally.keystyle": "flat",
|
||||
"i18n-ally.sourceLanguage": "en-US", // 源文件
|
||||
"i18n-ally.displayLanguage": "zh-CN" // 显示文件
|
||||
"i18n-ally.displayLanguage": "zh-CN",
|
||||
"[javascript]": {
|
||||
"editor.defaultFormatter": "vscode.typescript-language-features"
|
||||
} // 显示文件
|
||||
}
|
||||
|
@ -127,3 +127,6 @@ Element.Table.props.border = {
|
||||
|
||||
//设置点击所有弹窗的遮罩不会关闭弹窗
|
||||
Element.Dialog.props.closeOnClickModal.default = false;
|
||||
|
||||
|
||||
|
||||
|
1119
src/views/iot/device/.vue
Normal file
1119
src/views/iot/device/.vue
Normal file
File diff suppressed because it is too large
Load Diff
@ -69,7 +69,7 @@
|
||||
<template slot="prepend">Version</template>
|
||||
<template slot="append">{{ form.firmwareType === 1 ?
|
||||
$t('firmware.index.222541-52') : $t('firmware.index.222541-53')
|
||||
}}</template>
|
||||
}}</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<!-- 设备影子 -->
|
||||
@ -187,6 +187,8 @@
|
||||
ref="gatewayRunningStatus" :device="form" @statusEvent="getDeviceStatusData($event)" />
|
||||
<relay v-else-if="form.productName && form.productName.toLowerCase().includes('多路控制器')" ref="relay"
|
||||
:device="form" @statusEvent="getDeviceStatusData($event)" />
|
||||
<gatewaypre v-else-if="form.productName && form.productName.toLowerCase().includes('网关卡预配置')" ref="gatewaypre"
|
||||
:device="form" @statusEvent="getDeviceStatusData($event)" />
|
||||
<running-status v-else ref="runningStatus" :device="form"
|
||||
@statusEvent="getDeviceStatusData($event)" />
|
||||
|
||||
@ -405,7 +407,7 @@
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button class="btns" type="primary" @click="doCopy(2)">{{ $t('device.device-edit.148398-59')
|
||||
}}</el-button>
|
||||
}}</el-button>
|
||||
<el-button @click="closeSummaryDialog">{{ $t('device.device-edit.148398-57') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
@ -450,6 +452,7 @@ import { clientOut } from '@/api/iot/netty';
|
||||
import defaultSettings from '@/settings';
|
||||
import gatewayRunningStatus from './gatewayrunning-status.vue';
|
||||
import relay from './relay.vue'
|
||||
import gatewaypre from './gatewaypre.vue'
|
||||
export default {
|
||||
name: 'DeviceEdit',
|
||||
dicts: ['iot_device_status', 'iot_location_way'],
|
||||
@ -482,7 +485,8 @@ export default {
|
||||
deviceModbusTask,
|
||||
deviceInlineVideo,
|
||||
gatewayRunningStatus,
|
||||
relay
|
||||
relay,
|
||||
gatewaypre
|
||||
},
|
||||
watch: {
|
||||
activeName(val) {
|
||||
|
516
src/views/iot/device/gatewaypre.vue
Normal file
516
src/views/iot/device/gatewaypre.vue
Normal file
@ -0,0 +1,516 @@
|
||||
<template>
|
||||
<div class="professional-control-panel">
|
||||
<!-- 顶部状态栏 -->
|
||||
<div class="status-bar">
|
||||
<div class="status-item">
|
||||
<span class="status-label">当前产品:</span>
|
||||
<el-tag type="info">{{ selectedProductName }}</el-tag>
|
||||
</div>
|
||||
<div class="status-item">
|
||||
<span class="status-label">设备状态:</span>
|
||||
<el-tag :type="statusTagType">{{ statusText }}</el-tag>
|
||||
</div>
|
||||
<div class="status-item">
|
||||
<span class="status-label">信号强度:</span>
|
||||
<el-rate
|
||||
v-model="signalStrength"
|
||||
disabled
|
||||
:colors="['#99A9BF', '#F7BA2A', '#FF9900']"
|
||||
:max="3"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 主控制区 -->
|
||||
<div class="main-control-area">
|
||||
<div class="control-section">
|
||||
<h3 class="section-title">
|
||||
<i class="el-icon-s-platform"></i> 产品选择
|
||||
</h3>
|
||||
<el-select
|
||||
v-model="selectedProduct"
|
||||
placeholder="请选择产品"
|
||||
class="enhanced-select"
|
||||
size="medium"
|
||||
filterable
|
||||
@focus="loadProductList"
|
||||
>
|
||||
<el-option
|
||||
v-for="product in productModels"
|
||||
:key="product.id"
|
||||
:label="`${product.name} (${product.id})`"
|
||||
:value="product.id"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
<div class="control-section">
|
||||
<h3 class="section-title">
|
||||
<i class="el-icon-menu"></i> 功能选择
|
||||
</h3>
|
||||
<div class="page-control-grid">
|
||||
<div
|
||||
v-for="(page, index) in pageList"
|
||||
:key="index"
|
||||
class="page-item"
|
||||
:class="{ 'active': selectedPages[index] }"
|
||||
@click="togglePage(index)"
|
||||
>
|
||||
<div class="page-icon">
|
||||
<i :class="page.icon"></i>
|
||||
</div>
|
||||
<div class="page-name">{{ page.name }}</div>
|
||||
<div class="page-checkmark">
|
||||
<i class="el-icon-check" v-if="selectedPages[index]"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 调试信息(可选) -->
|
||||
<div class="control-section" v-if="showDebugInfo">
|
||||
<h3 class="section-title">
|
||||
<i class="el-icon-document"></i> 控制编码
|
||||
</h3>
|
||||
<div class="binary-preview">
|
||||
<div class="binary-code">
|
||||
<span v-for="(bit, index) in binaryCode" :key="index" class="bit">
|
||||
{{ bit }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="product-code">/{{ selectedProduct }}</div>
|
||||
</div>
|
||||
<div class="full-command">
|
||||
完整指令: <strong>{{ fullCommand }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮区 -->
|
||||
<div class="action-buttons">
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="el-icon-s-promotion"
|
||||
@click="sendControlCommand"
|
||||
class="action-button"
|
||||
:loading="sending"
|
||||
:disabled="!selectedProduct || !deviceInfo.deviceId"
|
||||
>
|
||||
发送指令
|
||||
</el-button>
|
||||
<el-button
|
||||
type="info"
|
||||
icon="el-icon-refresh"
|
||||
@click="resetSettings"
|
||||
class="action-button"
|
||||
>
|
||||
重置选择
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listShortProduct } from '@/api/iot/product';
|
||||
import { getOrderControl } from '@/api/iot/control';
|
||||
import { serviceInvoke, serviceInvokeReply } from '@/api/iot/runstatus';
|
||||
|
||||
export default {
|
||||
name: 'ProfessionalControlPanel',
|
||||
props: {
|
||||
device: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
deviceId: null,
|
||||
productId: null,
|
||||
serialNumber: null,
|
||||
status: null,
|
||||
isShadow: null,
|
||||
protocolCode: null,
|
||||
thingsModels: []
|
||||
})
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectedProduct: '',
|
||||
selectedPages: [0, 0, 0, 0, 0, 0, 0, 0],
|
||||
sending: false,
|
||||
signalStrength: 2,
|
||||
productModels: [],
|
||||
pageList: [
|
||||
{ name: '显示设置', icon: 'el-icon-data-line' },
|
||||
{ name: '声卡设置', icon: 'el-icon-headset' },
|
||||
{ name: '车牌识别', icon: 'el-icon-camera' },
|
||||
{ name: '预警设置', icon: 'el-icon-warning' },
|
||||
{ name: '远程喊话', icon: 'el-icon-microphone' },
|
||||
{ name: '网关设置', icon: 'el-icon-connection' },
|
||||
{ name: '路锥控制', icon: 'el-icon-place' },
|
||||
{ name: '翻转屏', icon: 'el-icon-monitor' }
|
||||
],
|
||||
loadingProducts: false,
|
||||
deviceInfo: {
|
||||
deviceId: null,
|
||||
productId: null,
|
||||
serialNumber: null,
|
||||
status: null,
|
||||
isShadow: null,
|
||||
protocolCode: null,
|
||||
thingsModels: []
|
||||
},
|
||||
showDebugInfo: false // 设置为true可显示调试信息
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
statusTagType() {
|
||||
switch (this.deviceInfo?.status) {
|
||||
case 3: return 'success'; // 在线
|
||||
case 1: return 'warning'; // 离线
|
||||
case 2: return 'danger'; // 异常
|
||||
default: return 'info'; // 未知
|
||||
}
|
||||
},
|
||||
statusText() {
|
||||
switch (this.deviceInfo?.status) {
|
||||
case 3: return '在线';
|
||||
case 1: return '离线';
|
||||
case 2: return '异常';
|
||||
default: return '未知';
|
||||
}
|
||||
},
|
||||
binaryCode() {
|
||||
return this.selectedPages.map(bit => bit ? '1' : '0').join('');
|
||||
},
|
||||
fullCommand() {
|
||||
return `${this.binaryCode}/${this.selectedProduct}`;
|
||||
},
|
||||
selectedProductName() {
|
||||
if (!this.selectedProduct) return '未选择';
|
||||
const product = this.productModels.find(p => p.id === this.selectedProduct);
|
||||
return product ? `${product.name} (${product.id})` : this.selectedProduct;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
device: {
|
||||
handler(newVal) {
|
||||
if (newVal && newVal.deviceId) {
|
||||
this.deviceInfo = {
|
||||
...newVal,
|
||||
thingsModels: newVal.thingsModels || [],
|
||||
// 确保包含所有必要属性
|
||||
deviceId: newVal.deviceId,
|
||||
productId: newVal.productId,
|
||||
serialNumber: newVal.serialNumber,
|
||||
status: newVal.status,
|
||||
isShadow: newVal.isShadow,
|
||||
protocolCode: newVal.protocolCode
|
||||
};
|
||||
|
||||
// 初始化distribute模型的shadow值
|
||||
const distributeModel = this.deviceInfo.thingsModels.find(
|
||||
model => model.id === 'distribute'
|
||||
);
|
||||
if (distributeModel) {
|
||||
distributeModel.shadow = this.fullCommand;
|
||||
}
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadProductList();
|
||||
},
|
||||
methods: {
|
||||
async loadProductList() {
|
||||
if (this.productModels.length > 0 || this.loadingProducts) return;
|
||||
|
||||
this.loadingProducts = true;
|
||||
try {
|
||||
const params = {
|
||||
pageSize: 999,
|
||||
showSenior: true
|
||||
};
|
||||
const res = await listShortProduct(params);
|
||||
if (res.code === 200) {
|
||||
this.productModels = res.data || [];
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取产品列表失败:', error);
|
||||
this.$message.error('获取产品列表失败');
|
||||
} finally {
|
||||
this.loadingProducts = false;
|
||||
}
|
||||
},
|
||||
|
||||
togglePage(index) {
|
||||
this.$set(this.selectedPages, index, this.selectedPages[index] ? 0 : 1);
|
||||
// 更新distribute模型的shadow值
|
||||
this.updateDistributeModel();
|
||||
},
|
||||
|
||||
updateDistributeModel() {
|
||||
const distributeModel = this.deviceInfo.thingsModels.find(
|
||||
model => model.id === 'distribute'
|
||||
);
|
||||
if (distributeModel) {
|
||||
distributeModel.shadow = this.fullCommand;
|
||||
}
|
||||
},
|
||||
|
||||
async sendControlCommand() {
|
||||
if (!this.selectedProduct) {
|
||||
this.$message.warning('请选择产品');
|
||||
return;
|
||||
}
|
||||
if (!this.deviceInfo.deviceId) {
|
||||
this.$message.warning('设备信息未初始化');
|
||||
return;
|
||||
}
|
||||
|
||||
this.sending = true;
|
||||
|
||||
try {
|
||||
const distributeModel = this.deviceInfo.thingsModels.find(
|
||||
model => model.id === 'productpram'
|
||||
);
|
||||
|
||||
if (!distributeModel) {
|
||||
throw new Error('未找到分发控制模型');
|
||||
}
|
||||
|
||||
// 确保shadow值是最新的
|
||||
distributeModel.shadow = this.fullCommand;
|
||||
|
||||
await this.mqttPublish(this.deviceInfo, distributeModel);
|
||||
|
||||
this.$message.success('控制指令发送成功');
|
||||
} catch (error) {
|
||||
console.error('发送控制指令失败:', error);
|
||||
this.$message.error(`控制指令发送失败: ${error.message}`);
|
||||
} finally {
|
||||
this.sending = false;
|
||||
}
|
||||
},
|
||||
|
||||
async mqttPublish(device, model) {
|
||||
try {
|
||||
if (!device || !device.deviceId) {
|
||||
throw new Error('无效的设备信息');
|
||||
}
|
||||
if (!model || !model.id) {
|
||||
throw new Error('无效的模型信息');
|
||||
}
|
||||
|
||||
const command = {};
|
||||
command[model.id] = model.shadow;
|
||||
|
||||
const params = {
|
||||
deviceId: device.deviceId,
|
||||
modelId: model.modelId,
|
||||
};
|
||||
|
||||
const response = await getOrderControl(params);
|
||||
if (response.code != 200) {
|
||||
throw new Error(response.msg || '获取控制指令失败');
|
||||
}
|
||||
|
||||
const data = {
|
||||
serialNumber: device.serialNumber,
|
||||
productId: device.productId,
|
||||
remoteCommand: command,
|
||||
identifier: model.id,
|
||||
modelName: model.name,
|
||||
isShadow: device.status != 3,
|
||||
type: model.type,
|
||||
};
|
||||
|
||||
if (device.status !== 3 && device.isShadow !== 1) {
|
||||
throw new Error('设备不在线且未启用影子模式');
|
||||
}
|
||||
|
||||
if ((device.protocolCode === 'MODBUS-TCP' || device.protocolCode === 'MODBUS-RTU') && device.status === 3) {
|
||||
await serviceInvokeReply(data);
|
||||
} else {
|
||||
await serviceInvoke(data);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('MQTT发布失败:', error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
resetSettings() {
|
||||
this.selectedPages = [0, 0, 0, 0, 0, 0, 0, 0];
|
||||
this.updateDistributeModel();
|
||||
this.$message.info('已重置所有页面选择');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.professional-control-panel {
|
||||
width: 100%;
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
background-color: #f5f7fa;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.status-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20px;
|
||||
padding: 15px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.status-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.status-label {
|
||||
font-weight: bold;
|
||||
margin-right: 10px;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.main-control-area {
|
||||
background-color: #fff;
|
||||
padding: 25px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 20px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.control-section {
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
color: #409EFF;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
padding-bottom: 10px;
|
||||
margin-bottom: 15px;
|
||||
font-size: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.section-title i {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.enhanced-select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.page-control-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.page-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 15px 10px;
|
||||
border-radius: 8px;
|
||||
background-color: #f8f9fa;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
border: 1px solid #ebeef5;
|
||||
}
|
||||
|
||||
.page-item:hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.page-item.active {
|
||||
background-color: #ecf5ff;
|
||||
border-color: #d9ecff;
|
||||
}
|
||||
|
||||
.page-icon {
|
||||
font-size: 24px;
|
||||
margin-bottom: 10px;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.page-name {
|
||||
font-size: 14px;
|
||||
margin-bottom: 8px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.page-checkmark {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
text-align: center;
|
||||
border-radius: 50%;
|
||||
background-color: #f1f1f1;
|
||||
color: #67c23a;
|
||||
}
|
||||
|
||||
.page-item.active .page-checkmark {
|
||||
background-color: #f0f9eb;
|
||||
}
|
||||
|
||||
.binary-preview {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 20px 0;
|
||||
padding: 15px;
|
||||
background-color: #f1f1f1;
|
||||
border-radius: 8px;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.binary-code {
|
||||
font-size: 24px;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
|
||||
.bit {
|
||||
display: inline-block;
|
||||
width: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.product-code {
|
||||
font-size: 24px;
|
||||
margin-left: 10px;
|
||||
color: #409EFF;
|
||||
}
|
||||
|
||||
.full-command {
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
padding: 10px;
|
||||
background-color: #f8f8f8;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.action-button {
|
||||
padding: 12px 30px;
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
@ -21,10 +21,13 @@
|
||||
|
||||
<el-button type="primary" size="mini" :plain="true" @click="viewVersion()">{{
|
||||
$t('device.running-status.866086-44')
|
||||
}}</el-button>
|
||||
}}</el-button>
|
||||
<el-button type="primary" size="mini" :plain="true" @click="sendDataToIframe()">{{
|
||||
$t('device.running-status.866086-44')
|
||||
}}</el-button>
|
||||
}}</el-button>
|
||||
<el-button type="primary" size="mini" :plain="true" @click="sendProductParamOnce()">{{
|
||||
$t('device.running-status.866086-44')
|
||||
}}</el-button>
|
||||
</el-descriptions-item>
|
||||
|
||||
<!-- 设备物模型-->
|
||||
@ -428,17 +431,17 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
<!-- <iframe ref="childFrame" src="https://www.jayjiajun.cn/" width="23%" height="800px"
|
||||
|
||||
|
||||
<iframe ref="childFrame" src="https://iot-xcwl.cn/h5/gateway/index.html#/" width="23%" height="800px"
|
||||
style="border: none;"></iframe>
|
||||
|
||||
|
||||
|
||||
<!-- <iframe ref="childFrame" src="http://localhost:81/" width="23%" height="800px"
|
||||
style="border: none;"></iframe> -->
|
||||
|
||||
|
||||
<iframe ref="childFrame" src="http://localhost:81/" width="23%" height="800px"
|
||||
style="border: none;"></iframe>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</el-row>
|
||||
|
||||
@ -484,17 +487,17 @@
|
||||
$t('device.running-status.866086-12') }}</el-link>
|
||||
</template>
|
||||
<el-descriptions-item :label="$t('device.running-status.866086-13')">{{ firmware.firmwareName
|
||||
}}</el-descriptions-item>
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('device.device-edit.148398-4')">{{ firmware.productName
|
||||
}}</el-descriptions-item>
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('device.device-edit.148398-12')">Version {{ firmware.version
|
||||
}}</el-descriptions-item>
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('device.running-status.866086-16')">
|
||||
<el-link :href="getDownloadUrl(firmware.filePath)" :underline="false" type="primary">{{
|
||||
getDownloadUrl(firmware.filePath) }}</el-link>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('device.running-status.866086-17')">{{ firmware.remark
|
||||
}}</el-descriptions-item>
|
||||
}}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="success" @click="otaUpgrade"
|
||||
@ -621,27 +624,83 @@ export default {
|
||||
this.initData();
|
||||
}
|
||||
// this.mqttCallback();
|
||||
|
||||
// 只在mounted时发送一次productpram数据
|
||||
this.$nextTick(() => {
|
||||
this.waitForIframeLoad();
|
||||
});
|
||||
// 添加消息监听器
|
||||
window.addEventListener('message', (event) => {
|
||||
// 确保消息来源是可信的
|
||||
if (event.origin === 'http://localhost:81') {
|
||||
console.log('收到来自子页面的消息:', event.data);
|
||||
|
||||
// 找到 id 为 distribute 的模型
|
||||
const distributeModel = this.deviceInfo.thingsModels.find(model => model.id === 'distribute');
|
||||
if (distributeModel) {
|
||||
// 更新模型的 shadow 值,直接使用内部数据
|
||||
distributeModel.shadow = event.data.data;
|
||||
// 调用 mqttPublish 下发数据
|
||||
this.mqttPublish(this.deviceInfo, distributeModel);
|
||||
}
|
||||
|
||||
// 找到 id 为 distribute 的模型
|
||||
const distributeModel = this.deviceInfo.thingsModels.find(model => model.id === 'distribute');
|
||||
if (distributeModel) {
|
||||
// 更新模型的 shadow 值,直接使用内部数据
|
||||
distributeModel.shadow = JSON.stringify(event.data.data);
|
||||
console.log('收到来自子页面的消息:', JSON.stringify(event.data.data));
|
||||
|
||||
// 调用 mqttPublish 下发数据
|
||||
this.mqttPublish(this.deviceInfo, distributeModel);
|
||||
}
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 新增方法:等待iframe加载完成
|
||||
waitForIframeLoad() {
|
||||
const maxAttempts = 5; // 最大尝试次数
|
||||
let attempts = 0;
|
||||
|
||||
const checkInterval = setInterval(() => {
|
||||
const iframe = this.$refs.childFrame;
|
||||
|
||||
// 1. 检查iframe是否存在且已加载
|
||||
if (iframe && iframe.contentWindow) {
|
||||
// 2. 可选:检查子页面是否已准备好接收消息(需要子页面配合)
|
||||
// iframe.contentWindow.postMessage({ type: 'ping' }, '*');
|
||||
|
||||
clearInterval(checkInterval);
|
||||
this.sendProductParamOnce();
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. 超过最大尝试次数则停止
|
||||
if (++attempts >= maxAttempts) {
|
||||
clearInterval(checkInterval);
|
||||
console.warn('Iframe not ready after multiple attempts');
|
||||
return;
|
||||
}
|
||||
}, 500); // 每500ms检查一次
|
||||
},
|
||||
|
||||
// 发送productpram数据(保持不变)
|
||||
sendProductParamOnce() {
|
||||
const iframe = this.$refs.childFrame;
|
||||
if (!iframe || !iframe.contentWindow) {
|
||||
console.error('Iframe not ready');
|
||||
return;
|
||||
}
|
||||
|
||||
const productParamModel = this.deviceInfo.thingsModels.find(model => model.id === 'productpram');
|
||||
if (!productParamModel) {
|
||||
console.warn('productpram model not found');
|
||||
return;
|
||||
}
|
||||
|
||||
let paramData = productParamModel.shadow;
|
||||
if (typeof paramData === 'string' && paramData.startsWith('JSON=')) {
|
||||
paramData = paramData.substring(5);
|
||||
}
|
||||
const paramDataString = typeof paramData === 'string' ? paramData : JSON.stringify(paramData);
|
||||
|
||||
iframe.contentWindow.postMessage(
|
||||
paramDataString,
|
||||
'https://iot-xcwl.cn/h5/gateway/index.html#/'
|
||||
);
|
||||
console.log('Initial productpram data sent:', paramDataString);
|
||||
},
|
||||
|
||||
//监听设备状态(设备联动)
|
||||
handleDeviceChange(device) {
|
||||
@ -841,6 +900,7 @@ export default {
|
||||
isShadow: device.status != 3,
|
||||
type: model.type,
|
||||
};
|
||||
// console.log('下发指令:', JSON.stringify(data));
|
||||
//设备在线状态判断
|
||||
if (this.device.status !== 3 && this.device.isShadow !== 1) {
|
||||
if (this.device.status === 1) {
|
||||
@ -1111,22 +1171,27 @@ export default {
|
||||
option && this.monitorChart[i].chart.setOption(option);
|
||||
}
|
||||
},
|
||||
// 向iframe发送数据的方法
|
||||
sendDataToIframe() {
|
||||
const iframe = this.$refs.childFrame;
|
||||
// console.log("thingsmodel",JSON.stringify(this.deviceInfo.thingsModels));
|
||||
if (iframe && iframe.contentWindow) {
|
||||
// 找到 id 为 upload 的模型
|
||||
const uploadModel = this.deviceInfo.thingsModels.find(model => model.id === 'upload');
|
||||
const dataToSend = uploadModel ? { value: uploadModel.shadow } : null;
|
||||
|
||||
// 打印要发送的数据(方便调试)
|
||||
console.log('Sending data to iframe:', JSON.stringify(dataToSend));
|
||||
|
||||
// 发送数据到 iframe
|
||||
iframe.contentWindow.postMessage(dataToSend, 'http://localhost:81/#/');
|
||||
// 保留原有方法(但不再用于productpram)
|
||||
sendDataToIframe() {
|
||||
const iframe = this.$refs.childFrame;
|
||||
if (iframe && iframe.contentWindow) {
|
||||
// 这里只处理upload数据(如果需要)
|
||||
const uploadModel = this.deviceInfo.thingsModels.find(model => model.id === 'upload');
|
||||
if (uploadModel) {
|
||||
let shadowData = uploadModel.shadow;
|
||||
if (typeof shadowData === 'string' && shadowData.startsWith('JSON=')) {
|
||||
shadowData = shadowData.substring(5);
|
||||
}
|
||||
const uploadDataString = typeof shadowData === 'string' ? shadowData : JSON.stringify(shadowData);
|
||||
|
||||
iframe.contentWindow.postMessage(
|
||||
uploadDataString,
|
||||
'https://iot-xcwl.cn/h5/gateway/index.html#/'
|
||||
);
|
||||
console.log('Sent upload data:', uploadDataString);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
Loading…
x
Reference in New Issue
Block a user