Files
frost-mqtt-client/app/src/renderer/src/stores/mqtt.js
T

308 lines
6.8 KiB
JavaScript

import { ref, computed } from 'vue';
// 全局状态(单例)
const servers = ref([]);
const activeServerId = ref(null);
const messages = ref([]);
const publishHistory = ref([]);
const loading = ref(false);
// 清理函数集合
let cleanupFns = [];
function setupListeners() {
// 清理旧监听器
cleanupFns.forEach((fn) => fn());
cleanupFns = [];
cleanupFns.push(
window.api.onStatusChange((data) => {
const srv = servers.value.find((s) => s.id === data.id);
if (srv) {
srv.status = data.status;
if (data.status === 'disconnected') {
srv.topics.forEach((t) => {
t.subscribed = false;
});
}
}
})
);
cleanupFns.push(
window.api.onMessage((data) => {
if (data.serverId === activeServerId.value) {
messages.value.unshift(data.message);
if (messages.value.length > 500) {
messages.value.pop();
}
}
})
);
cleanupFns.push(
window.api.onSubscriptionChange((data) => {
if (data.serverId === activeServerId.value) {
const srv = servers.value.find((s) => s.id === data.serverId);
if (srv) {
const t = srv.topics.find((t) => t.topic === data.topic || t.id === data.topicId);
if (t) {
t.subscribed = data.subscribed;
if (data.topic && data.topic !== t.topic) {
t.topic = data.topic;
}
}
}
}
})
);
}
export function useMqttStore() {
let activeServer = computed(
() => servers.value.find((s) => s.id === activeServerId.value) || null
);
let connectedServers = computed(() => servers.value.filter((s) => s.status === 'connected'));
let totalTopics = computed(() =>
servers.value.reduce((sum, s) => sum + (s.topics?.length || 0), 0)
);
let subscribedTopics = computed(() =>
servers.value.reduce(
(sum, s) => sum + (s.topics?.filter((t) => t.subscribed)?.length || 0),
0
)
);
let totalMessages = computed(() => messages.value.length);
function sortServers() {
servers.value.sort((a, b) => a.name.localeCompare(b.name, 'zh-CN'));
}
// ==================== 初始化 ====================
async function init() {
loading.value = true;
try {
let data = await window.api.getServers();
servers.value = data;
sortServers();
setupListeners();
} catch (e) {
console.error('初始化失败:', e);
} finally {
loading.value = false;
}
}
// ==================== 服务器管理 ====================
function setActiveServer(id) {
activeServerId.value = id;
// 切换时刷新消息
refreshMessages();
refreshPublishHistory();
}
async function addServer(config) {
let server = await window.api.addServer(config);
servers.value.push(server);
sortServers();
if (!activeServerId.value) {
activeServerId.value = server.id;
}
return server;
}
async function updateServer(id, config) {
let result = await window.api.updateServer(id, config);
if (result) {
let idx = servers.value.findIndex((s) => s.id === id);
if (idx !== -1) {
servers.value[idx] = { ...servers.value[idx], ...result };
}
sortServers();
}
return result;
}
async function deleteServer(id) {
await window.api.deleteServer(id);
servers.value = servers.value.filter((s) => s.id !== id);
sortServers();
if (activeServerId.value === id) {
activeServerId.value = servers.value.length > 0 ? servers.value[0].id : null;
}
}
async function exportServers() {
return await window.api.exportServers();
}
async function importServers(serverList) {
let data = await window.api.importServers(serverList);
servers.value = data;
sortServers();
if (servers.value.length > 0 && !activeServerId.value) {
activeServerId.value = servers.value[0].id;
}
return data;
}
async function connectServer(id) {
return await window.api.connect(id);
}
async function disconnectServer(id) {
await window.api.disconnect(id);
}
// ==================== 主题管理 ====================
async function addTopic(serverId, topic, qos) {
let result = await window.api.addTopic(serverId, topic, qos);
if (result) {
let srv = servers.value.find((s) => s.id === serverId);
if (srv) {
srv.topics.push({ topic, qos, subscribed: false });
}
}
return result;
}
async function removeTopic(serverId, topic) {
await window.api.removeTopic(serverId, topic);
let srv = servers.value.find((s) => s.id === serverId);
if (srv) {
srv.topics = srv.topics.filter((t) => t.topic !== topic);
}
}
async function subscribeTopic(serverId, topic) {
return await window.api.subscribe(serverId, topic);
}
async function unsubscribeTopic(serverId, topic) {
return await window.api.unsubscribe(serverId, topic);
}
async function subscribeAllTopics(serverId) {
return await window.api.subscribeAll(serverId);
}
async function updateTopic(serverId, topicId, topic, qos) {
return await window.api.updateTopic(serverId, topicId, topic, qos);
}
// ==================== 消息发布 ====================
async function publishMessage(serverId, topic, payload, opts) {
let result = await window.api.publish(serverId, topic, payload, opts);
if (result && serverId === activeServerId.value) {
refreshPublishHistory();
}
return result;
}
// ==================== 消息管理 ====================
async function refreshMessages() {
if (activeServerId.value) {
messages.value = await window.api.getMessages(activeServerId.value);
}
}
async function refreshPublishHistory() {
if (activeServerId.value) {
publishHistory.value = await window.api.getPublishHistory(activeServerId.value);
}
}
async function clearMessages() {
if (activeServerId.value) {
await window.api.clearMessages(activeServerId.value);
messages.value = [];
}
}
async function clearPublishHistory() {
if (activeServerId.value) {
await window.api.clearPublishHistory(activeServerId.value);
publishHistory.value = [];
}
}
return {
// 状态
servers,
activeServerId,
activeServer,
messages,
publishHistory,
loading,
// 计算属性
connectedServers,
totalTopics,
subscribedTopics,
totalMessages,
// 方法
init,
setActiveServer,
addServer,
updateServer,
deleteServer,
exportServers,
importServers,
connectServer,
disconnectServer,
addTopic,
removeTopic,
subscribeTopic,
unsubscribeTopic,
subscribeAllTopics,
updateTopic,
publishMessage,
refreshMessages,
refreshPublishHistory,
clearMessages,
clearPublishHistory,
};
}