feat: 初始版本,支持配置和连接多个 MQTT 服务器,支持配置订阅的主题列表,支持消息历史记录
This commit is contained in:
@@ -0,0 +1,238 @@
|
||||
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() {
|
||||
const activeServer = computed(
|
||||
() => servers.value.find((s) => s.id === activeServerId.value) || null
|
||||
)
|
||||
|
||||
const connectedServers = computed(() => servers.value.filter((s) => s.status === 'connected'))
|
||||
|
||||
const totalTopics = computed(() =>
|
||||
servers.value.reduce((sum, s) => sum + (s.topics?.length || 0), 0)
|
||||
)
|
||||
|
||||
const subscribedTopics = computed(() =>
|
||||
servers.value.reduce((sum, s) => sum + (s.topics?.filter((t) => t.subscribed)?.length || 0), 0)
|
||||
)
|
||||
|
||||
const totalMessages = computed(() => messages.value.length)
|
||||
|
||||
// ==================== 初始化 ====================
|
||||
async function init() {
|
||||
loading.value = true
|
||||
try {
|
||||
const data = await window.api.getServers()
|
||||
servers.value = data
|
||||
if (data.length > 0 && !activeServerId.value) {
|
||||
activeServerId.value = data[0].id
|
||||
}
|
||||
setupListeners()
|
||||
} catch (e) {
|
||||
console.error('初始化失败:', e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 服务器管理 ====================
|
||||
function setActiveServer(id) {
|
||||
activeServerId.value = id
|
||||
// 切换时刷新消息
|
||||
refreshMessages()
|
||||
refreshPublishHistory()
|
||||
}
|
||||
|
||||
async function addServer(config) {
|
||||
const server = await window.api.addServer(config)
|
||||
servers.value.push(server)
|
||||
if (!activeServerId.value) {
|
||||
activeServerId.value = server.id
|
||||
}
|
||||
return server
|
||||
}
|
||||
|
||||
async function updateServer(id, config) {
|
||||
const result = await window.api.updateServer(id, config)
|
||||
if (result) {
|
||||
const idx = servers.value.findIndex((s) => s.id === id)
|
||||
if (idx !== -1) {
|
||||
servers.value[idx] = { ...servers.value[idx], ...result }
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
async function deleteServer(id) {
|
||||
await window.api.deleteServer(id)
|
||||
servers.value = servers.value.filter((s) => s.id !== id)
|
||||
if (activeServerId.value === id) {
|
||||
activeServerId.value = servers.value.length > 0 ? servers.value[0].id : null
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
const result = await window.api.addTopic(serverId, topic, qos)
|
||||
if (result) {
|
||||
const 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)
|
||||
const 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) {
|
||||
const result = await window.api.publish(serverId, topic, payload, opts)
|
||||
if (result && serverId === activeServerId.value) {
|
||||
refreshPublishHistory()
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// ==================== 消息管理 ====================
|
||||
async function refreshMessages() {
|
||||
if (!activeServerId.value) return
|
||||
messages.value = await window.api.getMessages(activeServerId.value)
|
||||
}
|
||||
|
||||
async function refreshPublishHistory() {
|
||||
if (!activeServerId.value) return
|
||||
publishHistory.value = await window.api.getPublishHistory(activeServerId.value)
|
||||
}
|
||||
|
||||
async function clearMessages() {
|
||||
if (!activeServerId.value) return
|
||||
await window.api.clearMessages(activeServerId.value)
|
||||
messages.value = []
|
||||
}
|
||||
|
||||
async function clearPublishHistory() {
|
||||
if (!activeServerId.value) return
|
||||
await window.api.clearPublishHistory(activeServerId.value)
|
||||
publishHistory.value = []
|
||||
}
|
||||
|
||||
return {
|
||||
// 状态
|
||||
servers,
|
||||
activeServerId,
|
||||
activeServer,
|
||||
messages,
|
||||
publishHistory,
|
||||
loading,
|
||||
// 计算属性
|
||||
connectedServers,
|
||||
totalTopics,
|
||||
subscribedTopics,
|
||||
totalMessages,
|
||||
// 方法
|
||||
init,
|
||||
setActiveServer,
|
||||
addServer,
|
||||
updateServer,
|
||||
deleteServer,
|
||||
connectServer,
|
||||
disconnectServer,
|
||||
addTopic,
|
||||
removeTopic,
|
||||
subscribeTopic,
|
||||
unsubscribeTopic,
|
||||
subscribeAllTopics,
|
||||
updateTopic,
|
||||
publishMessage,
|
||||
refreshMessages,
|
||||
refreshPublishHistory,
|
||||
clearMessages,
|
||||
clearPublishHistory
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user