423 lines
14 KiB
Vue
423 lines
14 KiB
Vue
<template>
|
||
<div class="page-container">
|
||
<Header :title="currentTitle"></Header>
|
||
<van-pull-refresh v-model="loading" success-text="刷新成功" @refresh="onRefresh">
|
||
<div class="content">
|
||
<!-- gateway -->
|
||
<div class="item">
|
||
<van-cell-group inset>
|
||
<div class="header">
|
||
<p class="title">网关卡</p>
|
||
<p :class="getStatusClass(gatewaystatus)" class="state">{{ gatewaystatus }}</p>
|
||
</div>
|
||
<van-divider :style="{ color: 'black' }" />
|
||
<van-field label="版本号:" :model-value="gatwayVision" readonly />
|
||
<van-field label="编译时间:" :model-value="gatewayTime" readonly />
|
||
</van-cell-group>
|
||
</div>
|
||
<!-- LED Screen -->
|
||
<div class="item">
|
||
<van-cell-group inset>
|
||
<div class="header">
|
||
<p class="title">双色LED屏驱动板</p>
|
||
<p :class="getStatusClass(ledStatus)" class="state">{{ ledStatus }}</p>
|
||
</div>
|
||
<van-divider :style="{ color: 'black' }" />
|
||
<van-field label="版本号:" :model-value="ledVision" readonly />
|
||
<van-field label="编译时间:" :model-value="ledTime" readonly />
|
||
</van-cell-group>
|
||
</div>
|
||
|
||
<!-- Car Recognition -->
|
||
<div class="item">
|
||
<van-cell-group inset>
|
||
<div class="header">
|
||
<p class="title">摄像头控制卡</p>
|
||
<p :class="getStatusClass(carStatus)" class="state">{{ carStatus }}</p>
|
||
</div>
|
||
<van-divider :style="{ color: 'black' }" />
|
||
<van-field label="版本号:" :model-value="carVision" readonly />
|
||
<van-field label="编译时间:" :model-value="carTime" readonly />
|
||
</van-cell-group>
|
||
</div>
|
||
|
||
<!-- 4G Sound Card -->
|
||
<div class="item">
|
||
<van-cell-group inset>
|
||
<div class="header">
|
||
<p class="title">音频控制卡</p>
|
||
<p :class="getStatusClass(g4Status)" class="state">{{ g4Status }}</p>
|
||
</div>
|
||
<van-divider :style="{ color: 'black' }" />
|
||
<van-field label="版本号:" :model-value="g4Vision" readonly />
|
||
<van-field label="编译时间:" :model-value="g4Time" readonly />
|
||
</van-cell-group>
|
||
</div>
|
||
|
||
<!-- LoRa -->
|
||
<div class="item">
|
||
<van-cell-group inset>
|
||
<div class="header">
|
||
<p class="title">LoRa预警板</p>
|
||
<p :class="getStatusClass(loraStatus)" class="state">{{ loraStatus }}</p>
|
||
</div>
|
||
<van-divider :style="{ color: 'black' }" />
|
||
<van-field label="版本号:" :model-value="loraVision" readonly />
|
||
<van-field label="编译时间:" :model-value="loraTime" readonly />
|
||
</van-cell-group>
|
||
</div>
|
||
</div>
|
||
</van-pull-refresh>
|
||
<Footer></Footer>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { ref, onMounted, onBeforeUnmount } from 'vue';
|
||
import Header from "../../components/Header.vue";
|
||
import Footer from "../../components/Footer.vue";
|
||
import axios from 'axios';
|
||
// import * as mqtt from 'mqtt/dist/mqtt.min';
|
||
import '@vant/touch-emulator';
|
||
export default {
|
||
components: {
|
||
Header,
|
||
Footer
|
||
},
|
||
|
||
setup() {
|
||
const currentTitle = ref('系统信息');
|
||
const loading = ref(false);
|
||
|
||
// 定义绑定字段
|
||
const gatwayVision = ref('');
|
||
const gatewayTime = ref('');
|
||
const gatewaystatus = ref('离线');
|
||
|
||
|
||
const ledVision = ref('');
|
||
const ledTime = ref('');
|
||
const ledStatus = ref('离线');
|
||
const carVision = ref('');
|
||
const carTime = ref('');
|
||
const carStatus = ref('离线');
|
||
const g4Vision = ref('');
|
||
const g4Time = ref('');
|
||
const g4Status = ref('离线');
|
||
const loraTime = ref('');
|
||
const loraVision = ref('');
|
||
const loraStatus = ref('离线');
|
||
let jsonId = ref(1);
|
||
let data; // 将 data 定义在函数外部,使其可以在函数外部访问
|
||
|
||
// 检查环境是否为本地
|
||
const isLocal = window.location.hostname === '192.168.4.1';
|
||
// const MQTT_send = (send_string) => {
|
||
// console.log(" 向父页面发送消息:", JSON.stringify(send_string));
|
||
// // 使用 postMessage 发送数据给父页面
|
||
// window.parent.postMessage(
|
||
// {
|
||
// data: send_string
|
||
// },
|
||
// '*' // 目标 origin,生产环境应替换为具体的父页面域名
|
||
// );
|
||
// };
|
||
|
||
// const MQTT_send = (send_string) => {
|
||
// console.log("向父页面发送消息:", JSON.stringify(send_string));
|
||
|
||
// // 统一的消息发送方法,兼容各平台
|
||
// if (typeof uni !== 'undefined' && uni.postMessage) {
|
||
// // 小程序/APP环境下使用uni.postMessage
|
||
// uni.postMessage({
|
||
// data: {
|
||
// type: 'mqtt_data',
|
||
// payload: send_string,
|
||
// timestamp: Date.now()
|
||
// }
|
||
// });
|
||
// } else {
|
||
// // H5环境下使用window.parent.postMessage
|
||
// window.parent.postMessage(
|
||
// {
|
||
// data: send_string
|
||
// },
|
||
// '*' // 目标 origin,生产环境应替换为具体的父页面域名
|
||
// );
|
||
// }
|
||
// };
|
||
|
||
const MQTT_send = (send_string) => {
|
||
console.log("向父页面发送消息:", JSON.stringify(send_string));
|
||
|
||
// 统一使用uni.postMessage方法发送消息
|
||
uni.postMessage({
|
||
data: {
|
||
type: 'mqtt_data',
|
||
payload: send_string,
|
||
timestamp: Date.now()
|
||
}
|
||
});
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
const handleMQTTMessage = (string) => {
|
||
// console.log("MQTT 接收:" + string);
|
||
const data = JSON.parse(string);
|
||
// console.log("MQTT 接收:", JSON.stringify(data, null, 2)); // 格式化打印 JSON 对象
|
||
|
||
return new Promise((resolve, reject) => {
|
||
try {
|
||
if (data.led_protocol && data.led_protocol.info) {
|
||
const info = data.led_protocol.info;
|
||
ledVision.value = info.versions;
|
||
ledTime.value = info.compile_time;
|
||
ledStatus.value = '在线';
|
||
resolve(data);
|
||
} else if (data.LPR_card && data.LPR_card.info) {
|
||
const info = data.LPR_card.info;
|
||
carVision.value = info.versions;
|
||
carTime.value = info.compile_time;
|
||
carStatus.value = '在线';
|
||
resolve(data);
|
||
} else if (data.sound_card && data.sound_card.info) {
|
||
const info = data.sound_card.info;
|
||
g4Vision.value = info.versions;
|
||
g4Time.value = info.compile_time;
|
||
g4Status.value = '在线';
|
||
resolve(data);
|
||
} else if (data.LoRa_card && data.LoRa_card.info) {
|
||
const info = data.LoRa_card.info;
|
||
loraVision.value = info.versions;
|
||
loraTime.value = info.compile_time;
|
||
loraStatus.value = '在线';
|
||
resolve(data);
|
||
} else if (data.gateway && data.gateway.info) {
|
||
const info = data.gateway.info;
|
||
gatwayVision.value = info.versions;
|
||
gatewayTime.value = info.compile_time;
|
||
gatewaystatus.value = '在线';
|
||
resolve(data);
|
||
} else {
|
||
resolve(data);
|
||
}
|
||
} catch (error) {
|
||
reject(error);
|
||
}
|
||
});
|
||
};
|
||
|
||
|
||
|
||
|
||
// 发送请求的函数
|
||
const sendRequest = async (requestData, requestType) => {
|
||
return new Promise((resolve, reject) => {
|
||
const timeout = setTimeout(() => {
|
||
console.warn('请求超时,跳过该请求');
|
||
resolve({ skipped: true });
|
||
}, 5000); // 设置超时时间为5秒
|
||
|
||
if (requestType === 'mqtt') {
|
||
MQTT_send(requestData);
|
||
// 不需要在这里再添加事件监听器,使用全局的 handleMessage 即可
|
||
} else if (requestType === 'axios') {
|
||
axios.post('/communication', requestData, {
|
||
headers: {
|
||
"content-type": "application/json"
|
||
},
|
||
})
|
||
.then(response => {
|
||
clearTimeout(timeout); // 在收到响应后清除超时
|
||
const data = response.data;
|
||
console.log('收到 Axios 响应:', data);
|
||
if (data.led_protocol && data.led_protocol.info) {
|
||
const info = data.led_protocol.info;
|
||
ledVision.value = info.versions;
|
||
ledTime.value = info.compile_time;
|
||
ledStatus.value = '在线';
|
||
resolve(data);
|
||
} else if (data.LPR_card && data.LPR_card.info) {
|
||
const info = data.LPR_card.info;
|
||
carVision.value = info.versions;
|
||
carTime.value = info.compile_time;
|
||
carStatus.value = '在线';
|
||
resolve(data);
|
||
} else if (data.sound_card && data.sound_card.info) {
|
||
const info = data.sound_card.info;
|
||
g4Vision.value = info.versions;
|
||
g4Time.value = info.compile_time;
|
||
g4Status.value = '在线';
|
||
resolve(data);
|
||
} else if (data.LoRa_card && data.LoRa_card.info) {
|
||
const info = data.LoRa_card.info;
|
||
loraVision.value = info.versions;
|
||
loraTime.value = info.compile_time;
|
||
loraStatus.value = '在线';
|
||
resolve(data);
|
||
} else if (data.gateway && data.gateway.info) {
|
||
const info = data.gateway.info;
|
||
gatwayVision.value = info.versions;
|
||
gatewayTime.value = info.compile_time;
|
||
gatewaystatus.value = '在线';
|
||
resolve(data);
|
||
|
||
} else {
|
||
resolve(data);
|
||
}
|
||
})
|
||
.catch(error => {
|
||
clearTimeout(timeout); // 在捕获错误后清除超时
|
||
if (error.response && error.response.status === 500) {
|
||
console.error('收到 500 错误码,跳过该请求');
|
||
resolve({ skipped: true });
|
||
} else {
|
||
console.error('Axios 请求错误:', error);
|
||
reject(error);
|
||
}
|
||
});
|
||
}
|
||
});
|
||
};
|
||
|
||
|
||
// MQTT 接收函数
|
||
const MQTT_recv = (string) => {
|
||
// console.log("MQTT 接收的json:" + string);
|
||
// 先解析一次字符串化的 JSON
|
||
const parsedString = JSON.parse(string);
|
||
// 如果解析后的结果仍然是字符串,需要再次解析
|
||
const data = typeof parsedString === 'string' ? JSON.parse(parsedString) : parsedString;
|
||
// console.log("MQTTRECV 接收的json:" + JSON.stringify(data));
|
||
handleMQTTMessage(JSON.stringify(data));
|
||
};
|
||
// 下拉刷新事件处理函数
|
||
const onRefresh = async () => {
|
||
loading.value = true; // 开始刷新时设置 loading 为 true
|
||
|
||
const requests = [
|
||
{ type: isLocal ? 'axios' : 'mqtt', data: { "JSON_id": jsonId.value++, "board_id": 1, "gateway": { "get_info": 1 } } },
|
||
{ type: isLocal ? 'axios' : 'mqtt', data: { "JSON_id": jsonId.value++, "board_id": 102, "led_protocol": { "get_info": 1 } } },
|
||
{ type: isLocal ? 'axios' : 'mqtt', data: { "JSON_id": jsonId.value++, "board_id": 104, "LPR_card": { "get_info": 1 } } },
|
||
{ type: isLocal ? 'axios' : 'mqtt', data: { "JSON_id": jsonId.value++, "board_id": 103, "sound_card": { "get_info": 1 } } },
|
||
{ type: isLocal ? 'axios' : 'mqtt', data: { "JSON_id": jsonId.value++, "board_id": 105, "LoRa_card": { "get_info": 1 } } },
|
||
];
|
||
|
||
for (const request of requests) {
|
||
await sendRequest(request.data, request.type);
|
||
}
|
||
|
||
loading.value = false; // 完成所有请求后停止 loading
|
||
|
||
// 如果没有收到某个设备的信息,设置其状态为离线
|
||
if (!ledVision.value) ledStatus.value = '离线';
|
||
if (!carVision.value) carStatus.value = '离线';
|
||
if (!g4Vision.value) g4Status.value = '离线';
|
||
if (!loraVision.value) loraStatus.value = '离线';
|
||
if (!gatwayVision.value) gatewaystatus.value = '离线';
|
||
};
|
||
|
||
|
||
// 在组件挂载时建立 MQTT 连接
|
||
onMounted(() => {
|
||
console.log(isLocal);
|
||
const messageHandler = function (event) {
|
||
console.log("111接受的原始数据", JSON.stringify(event.data))
|
||
if (event.data) {
|
||
MQTT_recv(JSON.stringify(event.data)); // 保持与原 MQTT_recv 兼容
|
||
}
|
||
};
|
||
window.addEventListener('message', messageHandler);
|
||
// onRefresh();
|
||
|
||
// 在组件卸载时移除事件监听器
|
||
onBeforeUnmount(() => {
|
||
window.removeEventListener('message', messageHandler);
|
||
console.log('移除事件监听器');
|
||
|
||
});
|
||
});
|
||
|
||
onBeforeUnmount(() => {
|
||
});
|
||
|
||
// 获取状态对应的类
|
||
const getStatusClass = (status) => {
|
||
return status === '在线' ? 'state online' : 'state offline';
|
||
};
|
||
|
||
return {
|
||
currentTitle,
|
||
loading,
|
||
onRefresh,
|
||
ledVision,
|
||
ledTime,
|
||
carVision,
|
||
carTime,
|
||
g4Vision,
|
||
g4Time,
|
||
loraTime,
|
||
loraVision,
|
||
ledStatus,
|
||
g4Status,
|
||
carStatus,
|
||
loraStatus,
|
||
getStatusClass,
|
||
gatwayVision,
|
||
gatewayTime,
|
||
gatewaystatus,
|
||
MQTT_send,
|
||
MQTT_recv,
|
||
handleMQTTMessage,
|
||
};
|
||
}
|
||
};
|
||
</script>
|
||
<style scoped>
|
||
.page-container {
|
||
display: flex;
|
||
flex-direction: column;
|
||
min-height: 100vh;
|
||
position: relative;
|
||
}
|
||
|
||
.state {
|
||
text-align: right;
|
||
font-size: 20px;
|
||
}
|
||
|
||
.online {
|
||
color: green;
|
||
}
|
||
|
||
.offline {
|
||
color: gray;
|
||
|
||
}
|
||
|
||
.content {
|
||
flex: 1;
|
||
overflow-y: auto;
|
||
padding: 20px;
|
||
border-radius: 20px !important;
|
||
margin-top: 80px;
|
||
margin-bottom: 100px;
|
||
min-height: 100vh;
|
||
}
|
||
|
||
.item {
|
||
border: 2px solid #0668fc;
|
||
border-radius: 10px;
|
||
margin-top: 20px;
|
||
display: flex;
|
||
}
|
||
|
||
.title {
|
||
text-align: center;
|
||
font-size: 30px;
|
||
}
|
||
</style>
|