| | |
| | | gutter: { required: false, default: 12 }, |
| | | isExpand: { required: false, default: false }, |
| | | labelPosition: { required: false, default: 'right' }, |
| | | labelWidth: { required: false, default: '70px' }, |
| | | labelWidth: { required: false, default: '100px' }, |
| | | showExpand: { required: false, default: true }, |
| | | defaultExpanded: { required: false, default: false }, |
| | | buttonLeftLimit: { required: false, default: 2 }, |
| | |
| | | .art-search-bar { |
| | | padding: 15px 20px 0; |
| | | |
| | | :deep(.el-form-item__label) { |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | .action-column { |
| | | flex: 1; |
| | | max-width: 100%; |
| | |
| | | @click="reload" |
| | | /> |
| | | |
| | | <!-- 快速入口 --> |
| | | <ArtFastEnter v-if="shouldShowFastEnter && width >= headerBarFastEnterMinWidth"> |
| | | <ArtIconButton icon="ri:function-line" class="ml-3" /> |
| | | </ArtFastEnter> |
| | | |
| | | <!-- 面包屑 --> |
| | | <ArtBreadcrumb |
| | | v-if="(shouldShowBreadcrumb && isLeftMenu) || (shouldShowBreadcrumb && isDualMenu)" |
| | |
| | | </template> |
| | | </ElDropdown> |
| | | |
| | | <!-- 通知按钮 --> |
| | | <ArtIconButton |
| | | v-if="shouldShowNotification" |
| | | icon="ri:notification-2-line" |
| | | class="notice-button relative" |
| | | @click="visibleNotice" |
| | | > |
| | | <div class="absolute top-2 right-2 size-1.5 !bg-danger rounded-full"></div> |
| | | </ArtIconButton> |
| | | |
| | | <!-- 聊天按钮 --> |
| | | <ArtIconButton |
| | | v-if="shouldShowChat" |
| | |
| | | |
| | | <!-- 设置按钮 --> |
| | | <div v-if="shouldShowSettings"> |
| | | <ElPopover :visible="showSettingGuide" placement="bottom-start" :width="190" :offset="0"> |
| | | <template #reference> |
| | | <div class="flex-cc"> |
| | | <ArtIconButton icon="ri:settings-line" class="setting-btn" @click="openSetting" /> |
| | | </div> |
| | | </template> |
| | | <template #default> |
| | | <p |
| | | >{{ $t('topBar.guide.title') |
| | | }}<span :style="{ color: systemThemeColor }"> {{ $t('topBar.guide.theme') }} </span |
| | | >、 <span :style="{ color: systemThemeColor }"> {{ $t('topBar.guide.menu') }} </span |
| | | >{{ $t('topBar.guide.description') }} |
| | | </p> |
| | | </template> |
| | | </ElPopover> |
| | | <div class="flex-cc"> |
| | | <ArtIconButton icon="ri:settings-line" class="setting-btn" @click="openSetting" /> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 主题切换按钮 --> |
| | |
| | | |
| | | <!-- 标签页 --> |
| | | <ArtWorkTab /> |
| | | |
| | | <!-- 通知 --> |
| | | <ArtNotification v-model:value="showNotice" ref="notice" /> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | const { |
| | | shouldShowMenuButton, |
| | | shouldShowRefreshButton, |
| | | shouldShowFastEnter, |
| | | shouldShowBreadcrumb, |
| | | shouldShowGlobalSearch, |
| | | shouldShowFullscreen, |
| | | shouldShowNotification, |
| | | shouldShowChat, |
| | | shouldShowLanguage, |
| | | shouldShowSettings, |
| | | shouldShowThemeToggle, |
| | | fastEnterMinWidth: headerBarFastEnterMinWidth |
| | | } = useHeaderBar() |
| | | const { menuOpen, systemThemeColor, showSettingGuide, menuType, isDark, tabStyle } = |
| | | storeToRefs(settingStore) |
| | | const { menuOpen, showSettingGuide, menuType, isDark, tabStyle } = storeToRefs(settingStore) |
| | | const { language } = storeToRefs(userStore) |
| | | const { menuList } = storeToRefs(menuStore) |
| | | const showNotice = ref(false) |
| | | const notice = ref(null) |
| | | const isLeftMenu = computed(() => menuType.value === MenuTypeEnum.LEFT) |
| | | const isDualMenu = computed(() => menuType.value === MenuTypeEnum.DUAL_MENU) |
| | | const isTopMenu = computed(() => menuType.value === MenuTypeEnum.TOP) |
| | |
| | | const { isFullscreen, toggle: toggleFullscreen } = useFullscreen() |
| | | onMounted(() => { |
| | | initLanguage() |
| | | document.addEventListener('click', bodyCloseNotice) |
| | | }) |
| | | onUnmounted(() => { |
| | | document.removeEventListener('click', bodyCloseNotice) |
| | | }) |
| | | const toggleFullScreen = () => { |
| | | toggleFullscreen() |
| | |
| | | } |
| | | const openSearchDialog = () => { |
| | | mittBus.emit('openSearchDialog') |
| | | } |
| | | const bodyCloseNotice = (e) => { |
| | | if (!showNotice.value) return |
| | | const target = e.target |
| | | const isNoticeButton = target.closest('.notice-button') |
| | | const isNoticePanel = target.closest('.art-notification-panel') |
| | | if (!isNoticeButton && !isNoticePanel) { |
| | | showNotice.value = false |
| | | } |
| | | } |
| | | const visibleNotice = () => { |
| | | showNotice.value = !showNotice.value |
| | | } |
| | | const openChat = () => { |
| | | mittBus.emit('openChat') |
| | |
| | | "sessionList": "Sessions", |
| | | "searchPlaceholder": "Search session titles", |
| | | "noSessions": "No history sessions", |
| | | "sessionTitle": "Session %{id}", |
| | | "sessionTitle": "Session {id}", |
| | | "pinAction": "Pin session", |
| | | "unpinAction": "Unpin session", |
| | | "renameAction": "Rename session", |
| | |
| | | "toolStatusRunning": "Running", |
| | | "collapseDetail": "Hide Details", |
| | | "viewDetail": "View Details", |
| | | "toolInput": "Input: %{value}", |
| | | "toolOutput": "Output summary: %{value}", |
| | | "toolError": "Error: %{value}", |
| | | "toolInput": "Input: {value}", |
| | | "toolOutput": "Output summary: {value}", |
| | | "toolError": "Error: {value}", |
| | | "hasSummary": "Summary", |
| | | "noSummary": "No Summary", |
| | | "hasFacts": "Facts", |
| | |
| | | "send": "Send", |
| | | "renameDialogTitle": "Rename Session", |
| | | "sessionTitleField": "Session Title", |
| | | "requestMetric": "Req: %{value}", |
| | | "sessionMetric": "Session: %{id}", |
| | | "promptMetric": "Prompt: %{value}", |
| | | "modelMetric": "Model: %{value}", |
| | | "requestMetric": "Req: {value}", |
| | | "sessionMetric": "Session: {id}", |
| | | "promptMetric": "Prompt: {value}", |
| | | "modelMetric": "Model: {value}", |
| | | "promptLabel": "Prompt", |
| | | "modelLabel": "Model", |
| | | "modelSelectorLabel": "Chat Model", |
| | | "modelSelectorHint": "Switching only affects subsequent replies in this session and does not change the global default model.", |
| | | "modelSwitchFailed": "Failed to switch the chat model", |
| | | "defaultModelSuffix": "(Default)", |
| | | "mcpMetric": "MCP: %{value}", |
| | | "historyMetric": "History: %{value}", |
| | | "mcpMetric": "MCP: {value}", |
| | | "historyMetric": "History: {value}", |
| | | "mcpLabel": "MCP", |
| | | "historyLabel": "History", |
| | | "recentMetric": "Recent: %{value}", |
| | | "elapsedMetric": "Elapsed: %{value} ms", |
| | | "firstTokenMetric": "First token: %{value} ms", |
| | | "tokenMetric": "Tokens: prompt %{prompt} / completion %{completion} / total %{total}" |
| | | "recentMetric": "Recent: {value}", |
| | | "elapsedMetric": "Elapsed: {value} ms", |
| | | "firstTokenMetric": "First token: {value} ms", |
| | | "tokenMetric": "Tokens: prompt {prompt} / completion {completion} / total {total}" |
| | | } |
| | | }, |
| | | "table": { |
| | |
| | | "sessionList": "会话列表", |
| | | "searchPlaceholder": "搜索会话标题", |
| | | "noSessions": "暂无历史会话", |
| | | "sessionTitle": "会话 %{id}", |
| | | "sessionTitle": "会话 {id}", |
| | | "pinAction": "置顶会话", |
| | | "unpinAction": "取消置顶", |
| | | "renameAction": "重命名会话", |
| | |
| | | "toolStatusRunning": "执行中", |
| | | "collapseDetail": "收起详情", |
| | | "viewDetail": "查看详情", |
| | | "toolInput": "入参: %{value}", |
| | | "toolOutput": "结果摘要: %{value}", |
| | | "toolError": "错误: %{value}", |
| | | "toolInput": "入参: {value}", |
| | | "toolOutput": "结果摘要: {value}", |
| | | "toolError": "错误: {value}", |
| | | "hasSummary": "有摘要", |
| | | "noSummary": "无摘要", |
| | | "hasFacts": "有事实", |
| | |
| | | "send": "发送", |
| | | "renameDialogTitle": "重命名会话", |
| | | "sessionTitleField": "会话标题", |
| | | "requestMetric": "Req: %{value}", |
| | | "sessionMetric": "Session: %{id}", |
| | | "promptMetric": "Prompt: %{value}", |
| | | "modelMetric": "Model: %{value}", |
| | | "requestMetric": "Req: {value}", |
| | | "sessionMetric": "Session: {id}", |
| | | "promptMetric": "Prompt: {value}", |
| | | "modelMetric": "Model: {value}", |
| | | "promptLabel": "Prompt", |
| | | "modelLabel": "Model", |
| | | "modelSelectorLabel": "对话模型", |
| | | "modelSelectorHint": "切换后仅影响当前会话后续回复,不会改动全局默认模型。", |
| | | "modelSwitchFailed": "切换对话模型失败", |
| | | "defaultModelSuffix": "(默认)", |
| | | "mcpMetric": "MCP: %{value}", |
| | | "historyMetric": "History: %{value}", |
| | | "mcpMetric": "MCP: {value}", |
| | | "historyMetric": "History: {value}", |
| | | "mcpLabel": "MCP", |
| | | "historyLabel": "History", |
| | | "recentMetric": "Recent: %{value}", |
| | | "elapsedMetric": "耗时: %{value} ms", |
| | | "firstTokenMetric": "首包: %{value} ms", |
| | | "tokenMetric": "Tokens: prompt %{prompt} / completion %{completion} / total %{total}" |
| | | "recentMetric": "Recent: {value}", |
| | | "elapsedMetric": "耗时: {value} ms", |
| | | "firstTokenMetric": "首包: {value} ms", |
| | | "tokenMetric": "Tokens: prompt {prompt} / completion {completion} / total {total}" |
| | | } |
| | | }, |
| | | "table": { |
| | |
| | | GeoComponent, |
| | | VisualMapComponent |
| | | } from 'echarts/components' |
| | | import { LegacyGridContainLabel } from 'echarts/features' |
| | | import { CanvasRenderer } from 'echarts/renderers' |
| | | echarts.use([ |
| | | // 图表类型 |
| | |
| | | BrushComponent, |
| | | GeoComponent, |
| | | VisualMapComponent, |
| | | LegacyGridContainLabel, |
| | | // 渲染器 |
| | | CanvasRenderer |
| | | ]) |
| | |
| | | redirect: WORKBENCH_PATH, |
| | | meta: { |
| | | title: 'menus.dashboard.title', |
| | | icon: 'ri:home-smile-2-line' |
| | | icon: 'ri:home-smile-2-line', |
| | | staticRoute: true |
| | | }, |
| | | children: [ |
| | | { |
| | |
| | | title: 'menus.dashboard.console', |
| | | icon: 'ri:home-smile-2-line', |
| | | keepAlive: false, |
| | | fixedTab: true |
| | | fixedTab: true, |
| | | staticRoute: true |
| | | } |
| | | } |
| | | ] |
| | |
| | | (this.router.getRoutes?.() || []).map((route) => route?.path).filter(Boolean) |
| | | ) |
| | | menuList.forEach((route) => { |
| | | if (route?.meta?.staticRoute) { |
| | | return |
| | | } |
| | | |
| | | const routeConfig = this.transformer.transform(route) |
| | | const routePath = routeConfig?.path |
| | | |
| | |
| | | import { dashboardRoutes } from './dashboard' |
| | | import { systemRoutes } from './system' |
| | | import { resultRoutes } from './result' |
| | | import { exceptionRoutes } from './exception' |
| | | |
| | | const routeModules = [ |
| | | dashboardRoutes, |
| | | systemRoutes, |
| | | resultRoutes, |
| | | exceptionRoutes |
| | |
| | | async executeUpgrade(storedVersion, legacyStorage) { |
| | | try { |
| | | if (!upgradeLogList.value.length) { |
| | | console.warn('[Upgrade] 升级日志列表为空') |
| | | this.setStoredVersion(StorageConfig.CURRENT_VERSION) |
| | | return |
| | | } |
| | | const requireReLogin = this.shouldRequireReLogin(storedVersion) |