|
1 | 1 | <script setup lang='ts'> |
2 | 2 | import type { MessageReactive, UploadFileInfo } from 'naive-ui' |
3 | 3 | import html2canvas from 'html2canvas' |
| 4 | +import { h } from 'vue' |
4 | 5 | import { |
5 | 6 | fetchChatAPIProcessSSE, |
6 | 7 | fetchChatResponseoHistory, |
@@ -983,8 +984,61 @@ const footerClass = computed(() => { |
983 | 984 | return classes |
984 | 985 | }) |
985 | 986 |
|
| 987 | +// Check if it's an external chat site (format: external:name:url) |
| 988 | +function isExternalModel(value: string): boolean { |
| 989 | + return value.startsWith('external:') |
| 990 | +} |
| 991 | +
|
| 992 | +// Extract URL from external chat site value |
| 993 | +function getExternalModelUrl(value: string): string | null { |
| 994 | + if (!isExternalModel(value)) |
| 995 | + return null |
| 996 | + const parts = value.split(':') |
| 997 | + if (parts.length >= 3) |
| 998 | + return parts.slice(2).join(':') // Handle URLs that may contain : symbol |
| 999 | + return null |
| 1000 | +} |
| 1001 | +
|
| 1002 | +const chatModelOptions = computed(() => { |
| 1003 | + const baseModels = authStore.session?.chatModels ?? [] |
| 1004 | + const externalSites = authStore.session?.externalChatSites ?? [] |
| 1005 | +
|
| 1006 | + // Convert external chat sites to model options format |
| 1007 | + const externalOptions = externalSites.map(site => ({ |
| 1008 | + label: site.name, |
| 1009 | + key: `external:${site.name}`, |
| 1010 | + value: `external:${site.name}:${site.url}`, |
| 1011 | + })) |
| 1012 | +
|
| 1013 | + return [...baseModels, ...externalOptions] |
| 1014 | +}) |
| 1015 | +
|
| 1016 | +function renderChatModelLabel(option: { label: string, value: string }, _selected: boolean) { |
| 1017 | + if (isExternalModel(option.value)) { |
| 1018 | + return h('span', { style: { display: 'flex', alignItems: 'center', gap: '6px' } }, [ |
| 1019 | + option.label, |
| 1020 | + h(SvgIcon, { |
| 1021 | + icon: 'ri:external-link-line', |
| 1022 | + style: { fontSize: '14px', color: 'var(--n-text-color-secondary)' }, |
| 1023 | + }), |
| 1024 | + ]) |
| 1025 | + } |
| 1026 | + return option.label |
| 1027 | +} |
| 1028 | +
|
986 | 1029 | async function handleSyncChatModel(chatModel: string) { |
987 | | - // 保存切换前的模型和 toolsEnabled 状态 |
| 1030 | + // Check if it's an external chat site, open in new tab if so |
| 1031 | + if (isExternalModel(chatModel)) { |
| 1032 | + const url = getExternalModelUrl(chatModel) |
| 1033 | + if (url) { |
| 1034 | + const w = window.open(url, '_blank', 'noopener,noreferrer') |
| 1035 | + if (w) |
| 1036 | + w.opener = null |
| 1037 | + } |
| 1038 | + return |
| 1039 | + } |
| 1040 | +
|
| 1041 | + // Save previous model and toolsEnabled state before switching |
988 | 1042 | const previousModel = currentChatRoom.value?.chatModel |
989 | 1043 | const previousToolsEnabled = currentChatRoom.value?.toolsEnabled ?? false |
990 | 1044 |
|
@@ -1334,8 +1388,9 @@ onUnmounted(() => { |
1334 | 1388 | <NSelect |
1335 | 1389 | style="width: 250px" |
1336 | 1390 | :value="currentChatRoom?.chatModel" |
1337 | | - :options="authStore.session?.chatModels" |
| 1391 | + :options="chatModelOptions" |
1338 | 1392 | :disabled="!!authStore.session?.auth && !authStore.token && !authStore.session?.authProxyEnabled" |
| 1393 | + :render-label="renderChatModelLabel" |
1339 | 1394 | @update:value="handleSyncChatModel" |
1340 | 1395 | /> |
1341 | 1396 | <HoverButton |
|
0 commit comments