Files
zn-ai/src/stores/channel.ts
DEV_DSW 411f4f3421 feat: Refactor channel management and UI components
- Removed hardcoded channel data from `channel.ts` and replaced it with a dynamic channel dictionary.
- Introduced a new Pinia store `channel.ts` to manage selected and available channels.
- Reworked `AddChannelDialog.vue` to allow users to search and select channels dynamically.
- Updated `TaskCenter.vue` to utilize the new channel store and handle empty channel selections gracefully.
- Enhanced IPC communication for loading and saving selected channels in the configuration.
- Adjusted `runTaskOperationService.ts` to ensure proper handling of channel data.
- Improved styling and structure of UI components for better user experience.
2026-04-16 15:13:30 +08:00

86 lines
2.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { useScriptStore } from '@stores/script'
import { resolveChannel } from '@constant/channel'
import { IPC_EVENTS, CONFIG_KEYS } from '@lib/constants'
import { v4 as uuidv4 } from 'uuid'
export interface ChannelItem {
id: string
channelName: string
channelUrl: string
}
export const useChannelStore = defineStore('channel', () => {
const scriptStore = useScriptStore()
// 用户选中的"一键打开"渠道(持久化到 electron-store
const selectedChannels = ref<ChannelItem[]>([])
// 从脚本 store 动态聚合可用渠道(按 URL 去重)
const availableChannels = computed<ChannelItem[]>(() => {
const map = new Map<string, ChannelItem>()
for (const script of scriptStore.safeScripts) {
if (!script.channel) continue
const resolved = resolveChannel(script.channel)
const url = resolved.url
if (url && !map.has(url)) {
map.set(url, {
id: uuidv4(),
channelName: resolved.name || url,
channelUrl: url,
})
}
}
return Array.from(map.values())
})
const loadSelectedChannels = async () => {
try {
const result = await window.api.invoke(IPC_EVENTS.GET_CONFIG, CONFIG_KEYS.SELECTED_CHANNELS)
if (Array.isArray(result)) {
selectedChannels.value = result
return
}
} catch (err) {
console.error('[channelStore] loadSelectedChannels failed:', err)
}
selectedChannels.value = []
}
const saveSelectedChannels = async () => {
try {
// 深拷贝剥离 Vue Proxy避免 IPC structured clone 失败
const payload = JSON.parse(JSON.stringify(selectedChannels.value))
await window.api.invoke(IPC_EVENTS.SET_CONFIG, CONFIG_KEYS.SELECTED_CHANNELS, payload)
} catch (err) {
console.error('[channelStore] saveSelectedChannels failed:', err)
throw err
}
}
const addSelectedChannel = (item: ChannelItem) => {
if (!selectedChannels.value.some((c) => c.channelUrl === item.channelUrl)) {
selectedChannels.value.push(item)
}
}
const removeSelectedChannel = (id: string) => {
selectedChannels.value = selectedChannels.value.filter((c) => c.id !== id)
}
const setSelectedChannels = (items: ChannelItem[]) => {
selectedChannels.value = items
}
return {
selectedChannels,
availableChannels,
loadSelectedChannels,
saveSelectedChannels,
addSelectedChannel,
removeSelectedChannel,
setSelectedChannels,
}
})