From ef2334b75891f1e64ae2054157ba777c7f138a0f Mon Sep 17 00:00:00 2001 From: xuncha <1658671838@qq.com> Date: Sat, 25 Apr 2026 14:33:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=AE=A2=E9=98=85=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- electron/main/api/pullDiscovery.ts | 2 +- .../Settings/API/DataSourceAddModal.vue | 95 +++++++++++++++++-- src/i18n/locales/en-US/settings.json | 5 + src/i18n/locales/ja-JP/settings.json | 5 + src/i18n/locales/zh-CN/settings.json | 5 + src/i18n/locales/zh-TW/settings.json | 5 + 6 files changed, 110 insertions(+), 7 deletions(-) diff --git a/electron/main/api/pullDiscovery.ts b/electron/main/api/pullDiscovery.ts index a35bc49d..5f676d95 100644 --- a/electron/main/api/pullDiscovery.ts +++ b/electron/main/api/pullDiscovery.ts @@ -22,7 +22,7 @@ export interface RemoteSession { */ export function fetchRemoteSessions(baseUrl: string, token?: string): Promise { return new Promise((resolve, reject) => { - const url = normalizeBaseUrl(baseUrl) + '/sessions?format=chatlab' + const url = normalizeBaseUrl(baseUrl) + '/sessions?format=chatlab&limit=10000' const request = net.request(url) if (token) { diff --git a/src/components/common/Settings/API/DataSourceAddModal.vue b/src/components/common/Settings/API/DataSourceAddModal.vue index 3c1009e2..22ae7ff3 100644 --- a/src/components/common/Settings/API/DataSourceAddModal.vue +++ b/src/components/common/Settings/API/DataSourceAddModal.vue @@ -32,6 +32,11 @@ const selectedSessionIds = ref>(new Set()) const discovering = ref(false) const discoveryError = ref('') +type SessionTypeSelection = 'private' | 'group' | 'other' +type SessionTypeFilter = 'all' | SessionTypeSelection + +const activeSessionTypeFilter = ref('all') + watch( () => props.open, async (val) => { @@ -49,6 +54,7 @@ watch( remoteSessions.value = [] selectedSessionIds.value = new Set() discoveryError.value = '' + activeSessionTypeFilter.value = 'all' if (isManageMode.value) { await discoverSessions() } @@ -57,17 +63,71 @@ watch( { immediate: true } ) -const availableSessions = computed(() => remoteSessions.value.filter((s) => !props.subscribedRemoteIds?.has(s.id))) +const visibleRemoteSessions = computed(() => { + if (activeSessionTypeFilter.value === 'all') return remoteSessions.value + return remoteSessions.value.filter((session) => getSessionTypeSelection(session) === activeSessionTypeFilter.value) +}) -const allSelected = computed( - () => availableSessions.value.length > 0 && selectedSessionIds.value.size === availableSessions.value.length +const visibleAvailableSessions = computed(() => + visibleRemoteSessions.value.filter((s) => !props.subscribedRemoteIds?.has(s.id)) ) +const allSelected = computed( + () => + visibleAvailableSessions.value.length > 0 && + visibleAvailableSessions.value.every((session) => selectedSessionIds.value.has(session.id)) +) + +const sessionTypeSelectionOptions = computed(() => + ( + [ + { value: 'all', label: t('settings.api.dataSources.discovery.typeAll') }, + { value: 'private', label: t('settings.api.dataSources.discovery.typePrivate') }, + { value: 'group', label: t('settings.api.dataSources.discovery.typeGroup') }, + { value: 'other', label: t('settings.api.dataSources.discovery.typeOther') }, + ] as Array<{ value: SessionTypeFilter; label: string }> + ).map((option) => ({ + ...option, + count: + option.value === 'all' + ? remoteSessions.value.length + : remoteSessions.value.filter((session) => getSessionTypeSelection(session) === option.value).length, + })) +) + +function getSessionTypeSelection(session: RemoteSession): SessionTypeSelection { + const rawType = String(session.type || '') + .trim() + .toLowerCase() + const id = String(session.id || '') + .trim() + .toLowerCase() + if (rawType === 'group' || id.endsWith('@chatroom')) return 'group' + if ( + rawType === 'channel' || + rawType === 'official' || + rawType === 'other' || + id.startsWith('gh_') || + id.includes('@openim') || + (id.startsWith('weixin') && id !== 'weixin') + ) { + return 'other' + } + return 'private' +} + +function setSessionTypeFilter(type: SessionTypeFilter) { + activeSessionTypeFilter.value = type +} + function toggleSelectAll() { + const visibleIds = visibleAvailableSessions.value.map((s) => s.id) if (allSelected.value) { - selectedSessionIds.value = new Set() + const next = new Set(selectedSessionIds.value) + for (const id of visibleIds) next.delete(id) + selectedSessionIds.value = next } else { - selectedSessionIds.value = new Set(availableSessions.value.map((s) => s.id)) + selectedSessionIds.value = new Set([...selectedSessionIds.value, ...visibleIds]) } } @@ -89,6 +149,7 @@ async function discoverSessions() { discoveryError.value = '' remoteSessions.value = [] selectedSessionIds.value = new Set() + activeSessionTypeFilter.value = 'all' try { remoteSessions.value = await store.fetchRemoteSessions(formData.value.baseUrl, formData.value.token) } catch (err: any) { @@ -226,9 +287,31 @@ function formatMessageCount(count?: number): string { }} +
+ + {{ t('settings.api.dataSources.discovery.selectByType') }} + +
+ +
+