diff --git a/ui/src/assets/iconfont.js b/ui/src/assets/iconfont.js
index 9384323d861..a90129fc01b 100644
--- a/ui/src/assets/iconfont.js
+++ b/ui/src/assets/iconfont.js
@@ -1 +1 @@
-window._iconfont_svg_string_5200172='',(h=>{var a=(l=(l=document.getElementsByTagName("script"))[l.length-1]).getAttribute("data-injectcss"),l=l.getAttribute("data-disable-injectsvg");if(!l){var o,v,t,i,c,d=function(a,l){l.parentNode.insertBefore(a,l)};if(a&&!h.__iconfont__svg__cssinject__){h.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(a){console&&console.log(a)}}o=function(){var a,l=document.createElement("div");l.innerHTML=h._iconfont_svg_string_5200172,(l=l.getElementsByTagName("svg")[0])&&(l.setAttribute("aria-hidden","true"),l.style.position="absolute",l.style.width=0,l.style.height=0,l.style.overflow="hidden",l=l,(a=document.body).firstChild?d(l,a.firstChild):a.appendChild(l))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(o,0):(v=function(){document.removeEventListener("DOMContentLoaded",v,!1),o()},document.addEventListener("DOMContentLoaded",v,!1)):document.attachEvent&&(t=o,i=h.document,c=!1,e(),i.onreadystatechange=function(){"complete"==i.readyState&&(i.onreadystatechange=null,m())})}function m(){c||(c=!0,t())}function e(){try{i.documentElement.doScroll("left")}catch(a){return void setTimeout(e,50)}m()}})(window);
\ No newline at end of file
+window._iconfont_svg_string_5200172='',(h=>{var a=(l=(l=document.getElementsByTagName("script"))[l.length-1]).getAttribute("data-injectcss"),l=l.getAttribute("data-disable-injectsvg");if(!l){var o,v,t,i,c,d=function(a,l){l.parentNode.insertBefore(a,l)};if(a&&!h.__iconfont__svg__cssinject__){h.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(a){console&&console.log(a)}}o=function(){var a,l=document.createElement("div");l.innerHTML=h._iconfont_svg_string_5200172,(l=l.getElementsByTagName("svg")[0])&&(l.setAttribute("aria-hidden","true"),l.style.position="absolute",l.style.width=0,l.style.height=0,l.style.overflow="hidden",l=l,(a=document.body).firstChild?d(l,a.firstChild):a.appendChild(l))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(o,0):(v=function(){document.removeEventListener("DOMContentLoaded",v,!1),o()},document.addEventListener("DOMContentLoaded",v,!1)):document.attachEvent&&(t=o,i=h.document,c=!1,e(),i.onreadystatechange=function(){"complete"==i.readyState&&(i.onreadystatechange=null,m())})}function m(){c||(c=!0,t())}function e(){try{i.documentElement.doScroll("left")}catch(a){return void setTimeout(e,50)}m()}})(window);
\ No newline at end of file
diff --git a/ui/src/components.d.ts b/ui/src/components.d.ts
index 479856cc62f..8c06ac46455 100644
--- a/ui/src/components.d.ts
+++ b/ui/src/components.d.ts
@@ -37,11 +37,11 @@ declare module 'vue' {
MkListItem: typeof import('./components/global/mk-list-item/index.vue')['default']
MkMediaPreview: typeof import('./components/global/mk-media-preview/index.vue')['default']
MkQuickCreate: typeof import('./components/global/mk-table/MkQuickCreate.vue')['default']
+ MkResourceCard: typeof import('./components/global/mk-resource-card/index.vue')['default']
+ MkResourceCardAction: typeof import('./components/global/mk-resource-card/MkResourceCardAction.vue')['default']
+ MkResourceCardActionDropdown: typeof import('./components/global/mk-resource-card/MkResourceCardActionDropdown.vue')['default']
MkSearchInput: typeof import('./components/global/mk-search-input/index.vue')['default']
MkSlider: typeof import('./components/global/mk-slider/index.vue')['default']
- MkSourceCard: typeof import('./components/global/mk-source-card/index.vue')['default']
- MkSourceCardAction: typeof import('./components/global/mk-source-card/MkSourceCardAction.vue')['default']
- MkSourceCardActionDropdown: typeof import('./components/global/mk-source-card/MkSourceCardActionDropdown.vue')['default']
MkStatusLabel: typeof import('./components/global/mk-status-label/index.vue')['default']
MkTable: typeof import('./components/global/mk-table/index.vue')['default']
MkTableFilter: typeof import('./components/global/mk-table/mk-table-filter/index.vue')['default']
@@ -89,11 +89,11 @@ declare global {
const MkListItem: typeof import('./components/global/mk-list-item/index.vue')['default']
const MkMediaPreview: typeof import('./components/global/mk-media-preview/index.vue')['default']
const MkQuickCreate: typeof import('./components/global/mk-table/MkQuickCreate.vue')['default']
+ const MkResourceCard: typeof import('./components/global/mk-resource-card/index.vue')['default']
+ const MkResourceCardAction: typeof import('./components/global/mk-resource-card/MkResourceCardAction.vue')['default']
+ const MkResourceCardActionDropdown: typeof import('./components/global/mk-resource-card/MkResourceCardActionDropdown.vue')['default']
const MkSearchInput: typeof import('./components/global/mk-search-input/index.vue')['default']
const MkSlider: typeof import('./components/global/mk-slider/index.vue')['default']
- const MkSourceCard: typeof import('./components/global/mk-source-card/index.vue')['default']
- const MkSourceCardAction: typeof import('./components/global/mk-source-card/MkSourceCardAction.vue')['default']
- const MkSourceCardActionDropdown: typeof import('./components/global/mk-source-card/MkSourceCardActionDropdown.vue')['default']
const MkStatusLabel: typeof import('./components/global/mk-status-label/index.vue')['default']
const MkTable: typeof import('./components/global/mk-table/index.vue')['default']
const MkTableFilter: typeof import('./components/global/mk-table/mk-table-filter/index.vue')['default']
diff --git a/ui/src/components/COMPONENT_README.md b/ui/src/components/COMPONENT_README.md
index 5eab41a004f..90ec99fe9e4 100644
--- a/ui/src/components/COMPONENT_README.md
+++ b/ui/src/components/COMPONENT_README.md
@@ -234,6 +234,7 @@ Element Plus 的 `v-infinite-scroll`。组件通过 `v-model` 管理已经加载
数据驱动时传 `row`,`labelField` 默认 `name`,`index` 默认 0;默认插槽提供 `{ row, index, active }`。
`action`、`action-dropdown` 提供 `{ row, index }`,有可渲染下拉项时优先下拉,否则显示普通操作。
下拉插槽直接放 `MkDropdownItem`,组件提供 More 触发器并隔离行点击;空菜单不显示入口。
+操作区在选中时常显,未选中时悬停或内部聚焦显示。
### MkSearchInput
@@ -404,7 +405,7 @@ Dialog、Drawer、Popover、嵌套区域等其他大、小表格均禁止开启
`size` 沿用 Element Plus Tag 的尺寸类型,统一作用于首个标签、`+N` 和浮层内标签;
传入 `size="small"` 显示小尺寸标签,不传时沿用 Element Plus 的默认尺寸继承行为。
-### MkSourceCard
+### MkResourceCard
等高资源卡片,`title` 必填,`nick_name`、`create_time` 提供创建信息;
`icon`、`title`(透出 `{ title }`)、`subtitle`、`tag` 插槽可覆盖头部,默认插槽放详情。
diff --git a/ui/src/components/business/select-application-dialog/index.vue b/ui/src/components/business/select-application-dialog/index.vue
index 08e9a3353b1..4cac7f6b424 100644
--- a/ui/src/components/business/select-application-dialog/index.vue
+++ b/ui/src/components/business/select-application-dialog/index.vue
@@ -151,10 +151,10 @@ defineExpose({ open })
-
+
{{ application.desc || '-' }}
-
+
diff --git a/ui/src/components/business/select-tool-dialog/index.vue b/ui/src/components/business/select-tool-dialog/index.vue
index 6ff7acdc0e8..08514b5d3e2 100644
--- a/ui/src/components/business/select-tool-dialog/index.vue
+++ b/ui/src/components/business/select-tool-dialog/index.vue
@@ -155,10 +155,10 @@ defineExpose({ open })
-
+
{{ tool.desc || '-' }}
-
+
diff --git a/ui/src/components/global/mk-list-item/index.vue b/ui/src/components/global/mk-list-item/index.vue
index a4de4c2b98f..d5ff0270b2d 100644
--- a/ui/src/components/global/mk-list-item/index.vue
+++ b/ui/src/components/global/mk-list-item/index.vue
@@ -36,10 +36,11 @@ const hasActionDropdown = computed(() => hasRenderableSlotContent(slots['action-
{{ itemLabel }}
-
+
diff --git a/ui/src/components/global/mk-source-card/MkSourceCardAction.vue b/ui/src/components/global/mk-resource-card/MkResourceCardAction.vue
similarity index 82%
rename from ui/src/components/global/mk-source-card/MkSourceCardAction.vue
rename to ui/src/components/global/mk-resource-card/MkResourceCardAction.vue
index c2c9e199d0c..b47fab52079 100644
--- a/ui/src/components/global/mk-source-card/MkSourceCardAction.vue
+++ b/ui/src/components/global/mk-resource-card/MkResourceCardAction.vue
@@ -1,5 +1,5 @@
diff --git a/ui/src/components/global/mk-source-card/MkSourceCardActionDropdown.vue b/ui/src/components/global/mk-resource-card/MkResourceCardActionDropdown.vue
similarity index 92%
rename from ui/src/components/global/mk-source-card/MkSourceCardActionDropdown.vue
rename to ui/src/components/global/mk-resource-card/MkResourceCardActionDropdown.vue
index 39dec4daa9c..8ce91090cc0 100644
--- a/ui/src/components/global/mk-source-card/MkSourceCardActionDropdown.vue
+++ b/ui/src/components/global/mk-resource-card/MkResourceCardActionDropdown.vue
@@ -2,7 +2,7 @@
import { computed, useSlots } from 'vue'
import { hasRenderableSlotContent } from '@/utils/vnode'
-defineOptions({ name: 'MkSourceCardActionDropdown' })
+defineOptions({ name: 'MkResourceCardActionDropdown' })
defineSlots<{ default: () => unknown }>()
diff --git a/ui/src/components/global/mk-source-card/index.vue b/ui/src/components/global/mk-resource-card/index.vue
similarity index 84%
rename from ui/src/components/global/mk-source-card/index.vue
rename to ui/src/components/global/mk-resource-card/index.vue
index c88e2ade722..152c1f9d5b4 100644
--- a/ui/src/components/global/mk-source-card/index.vue
+++ b/ui/src/components/global/mk-resource-card/index.vue
@@ -2,8 +2,8 @@
import { computed, h, type FunctionalComponent } from 'vue'
import { dateFormat } from '@/utils/time'
import { hasRenderableSlotContent } from '@/utils/vnode'
-import MkSourceCardAction from './MkSourceCardAction.vue'
-import MkSourceCardActionDropdown from './MkSourceCardActionDropdown.vue'
+import MkResourceCardAction from './MkResourceCardAction.vue'
+import MkResourceCardActionDropdown from './MkResourceCardActionDropdown.vue'
/**
@@ -27,7 +27,7 @@ import MkSourceCardActionDropdown from './MkSourceCardActionDropdown.vue'
*
*
*/
-defineOptions({ name: 'MkSourceCard' })
+defineOptions({ name: 'MkResourceCard' })
const props = withDefaults(
defineProps<{
@@ -45,15 +45,17 @@ const emit = defineEmits<{ selected: [selected: boolean] }>()
const slots = defineSlots<{
default?: () => unknown
- footer?: (props: { Action: FunctionalComponent; ActionDropdown: typeof MkSourceCardActionDropdown }) => unknown
+ footer?: (props: { Action: FunctionalComponent; ActionDropdown: typeof MkResourceCardActionDropdown }) => unknown
icon?: () => unknown
subtitle?: () => unknown
tag?: () => unknown
title?: (props: { title: string }) => unknown
}>()
-const SourceCardAction: FunctionalComponent = (_, { slots }) => (props.selectable ? null : h(MkSourceCardAction, null, slots))
-const hasFooter = computed(() => hasRenderableSlotContent(slots.footer?.({ Action: SourceCardAction, ActionDropdown: MkSourceCardActionDropdown })))
+const ResourceCardAction: FunctionalComponent = (_, { slots }) => (props.selectable ? null : h(MkResourceCardAction, null, slots))
+const hasFooter = computed(() =>
+ hasRenderableSlotContent(slots.footer?.({ Action: ResourceCardAction, ActionDropdown: MkResourceCardActionDropdown })),
+)
function handleSelect() {
if (props.selectable) emit('selected', !props.selected)
@@ -70,7 +72,7 @@ function handleSelectedChange(selected: boolean | string | number) {
:role="props.selectable ? 'checkbox' : undefined"
:tabindex="props.selectable ? 0 : undefined"
:shadow="props.disabled ? 'never' : 'hover'"
- class="mk-source-card group relative"
+ class="mk-resource-card group relative"
body-class="flex-column h-full"
@click="handleSelect"
>
@@ -108,13 +110,13 @@ function handleSelectedChange(selected: boolean | string | number) {
+
diff --git a/ui/src/conversation-panel/index.scss b/ui/src/conversation-panel/index.scss
index 4758ced54c8..a010387ab98 100644
--- a/ui/src/conversation-panel/index.scss
+++ b/ui/src/conversation-panel/index.scss
@@ -127,5 +127,11 @@
width: fit-content;
}
-.mk-conversation-message-footer {
+/* 门户 */
+.portal {
+ .mk-conversation-side-panel {
+ &.left {
+ background: var(--mk-N100);
+ }
+ }
}
diff --git a/ui/src/conversation-panel/left-sidebar/conversation-list/index.vue b/ui/src/conversation-panel/left-sidebar/conversation-list/index.vue
index ca97dd89485..f7d752db136 100644
--- a/ui/src/conversation-panel/left-sidebar/conversation-list/index.vue
+++ b/ui/src/conversation-panel/left-sidebar/conversation-list/index.vue
@@ -49,18 +49,17 @@ const conversationTime = (conversation: Conversation) => relativeTimeFormat(conv
暂无历史记录
-
-
+
+
{{ conversation.abstract || '新对话' }}
-
-
+
+
{{ conversationTime(conversation) }}
diff --git a/ui/src/conversation-panel/left-sidebar/portal-conversation-list/SelectApplicationDrawer.vue b/ui/src/conversation-panel/left-sidebar/portal-conversation-list/SelectApplicationDrawer.vue
index efe17dc6472..31d1ea8100e 100644
--- a/ui/src/conversation-panel/left-sidebar/portal-conversation-list/SelectApplicationDrawer.vue
+++ b/ui/src/conversation-panel/left-sidebar/portal-conversation-list/SelectApplicationDrawer.vue
@@ -45,23 +45,17 @@ defineExpose({ open })
-
+
-
-
选择智能体
-
-
+
-
+
@@ -63,8 +63,8 @@ const handleDeleteConversation = (group: PortalApplicationGroup, conversation: C
-
- 全部智能体
+
+ 智能体
@@ -87,48 +87,77 @@ const handleDeleteConversation = (group: PortalApplicationGroup, conversation: C
暂无历史记录
-
-
-
- {{ group.name }}
-
-
-
-
-
-
-
-
-
-
- {{ conversation.abstract || '新对话' }}
-
-
-
-
- {{ conversationTime(conversation) }}
-
-
-
-
-
-
- 删除
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+ {{ conversation.abstract || '新对话' }}
+
+
+
+
+ {{ conversationTime(conversation) }}
+
+
+
+
+
+
+ 删除
+
+
+
+
+
diff --git a/ui/src/conversation-panel/main/portal-application-panel/index.vue b/ui/src/conversation-panel/main/portal-application-panel/index.vue
index 028b50a8597..b4dfa5334b9 100644
--- a/ui/src/conversation-panel/main/portal-application-panel/index.vue
+++ b/ui/src/conversation-panel/main/portal-application-panel/index.vue
@@ -22,7 +22,7 @@ onMounted(() => {
-
+
@@ -31,26 +31,21 @@ onMounted(() => {
-
-
-
-
-
-
+
-
全部智能体
+
智能体
-
+
-
+
diff --git a/ui/src/conversation-panel/view/portal/index.ts b/ui/src/conversation-panel/view/portal/index.ts
index b9fa1875c3e..c15c41c57f2 100644
--- a/ui/src/conversation-panel/view/portal/index.ts
+++ b/ui/src/conversation-panel/view/portal/index.ts
@@ -25,9 +25,7 @@ function usePortalChatRouting(): ChatConversationRouting {
// 门户首页与全部智能体页没有智能体,不同步会话地址
if (!applicationId) return
void router.replace(
- chatId
- ? { name: 'portal-application-chat', params: { applicationId, chatId } }
- : { name: 'portal-application', params: { applicationId } },
+ chatId ? { name: 'portal-application-chat', params: { applicationId, chatId } } : { name: 'portal-application', params: { applicationId } },
)
},
}
@@ -74,13 +72,5 @@ export function createPortalConversation(options: PortalConversationOptions): Po
bundle.list.conversations.value = [...(findGroup(applicationId)?.conversations ?? [])]
})
- // 门户首页(/portal)未指定智能体:分组加载后进入第一个智能体的新建对话;没有可用智能体时保持空状态
- watch(portalList.applicationGroups, (applicationGroups) => {
- const firstApplication = applicationGroups[0]
- if (route.name === 'portal-home' && firstApplication) {
- void router.replace({ name: 'portal-application', params: { applicationId: firstApplication.id } })
- }
- })
-
return { ...bundle, portalList }
}
diff --git a/ui/src/conversation-panel/view/portal/index.vue b/ui/src/conversation-panel/view/portal/index.vue
index 2fd6366a84e..4fc1cc375ac 100644
--- a/ui/src/conversation-panel/view/portal/index.vue
+++ b/ui/src/conversation-panel/view/portal/index.vue
@@ -78,6 +78,7 @@ watch([() => bundle.list.currentChatId.value, () => bundle.list.composerResetSig
:left-mode="leftMode"
:right-mode="rightMode"
@mask-click="closeDrawers"
+ class="portal"
>
diff --git a/ui/src/layout/LayoutHeader.vue b/ui/src/layout/LayoutHeader.vue
index bd273201b2f..e5c9727f270 100644
--- a/ui/src/layout/LayoutHeader.vue
+++ b/ui/src/layout/LayoutHeader.vue
@@ -10,11 +10,12 @@ import type { LayoutMode } from './types'
import { Compare, hasPermission, Role, RoleConstants } from '@/permission/core'
import { getWorkspaceId } from '@/utils/resource-context'
import { useStore } from '@/stores'
+import { CHAT_API_BASE_PATH } from '@/api/constants'
const router = useRouter()
const props = withDefaults(defineProps<{ mode?: LayoutMode; preview?: boolean }>(), { mode: 'workspace', preview: false })
-const { user } = useStore()
+const { user, auth } = useStore()
// 命中 "X" / "X:..." / "X:w:..."(系统模式下没有 workspaceId,仍能匹配 EXTENDS_*)
function hasRolePrefix(name: string) {
@@ -61,6 +62,13 @@ function switchMode() {
const workspaceId = localStorage.getItem('workspaceId') || user.userInfo?.workspace_list?.[0]?.id || 'default'
router.push({ name: 'workspace-home', params: { workspaceId } })
}
+
+const portalAccessUrl = new URL(`${CHAT_API_BASE_PATH.replace(/\/api$/, '')}/portal`, window.location.origin).href
+
+function toUrl(url?: string) {
+ if (!url) return
+ window.open(url, '_blank')
+}
@@ -76,7 +84,16 @@ function switchMode() {
-
+
+
+
+
+ 门户
+
+
+
+
+
升级
diff --git a/ui/src/router/ROUTE_README.md b/ui/src/router/ROUTE_README.md
index 8807e9f03fd..34cae91e50a 100644
--- a/ui/src/router/ROUTE_README.md
+++ b/ui/src/router/ROUTE_README.md
@@ -106,8 +106,9 @@ Chat 使用独立入口 `src/chat.ts` 和独立 Router,不要把 Chat 路由
`portal-login`(`/portal/login`)、`portal-application-list`(`/portal/applications`,全部智能体)、
`portal-application`(`/portal/a/:applicationId`,新建对话)、
`portal-application-chat`(`/portal/a/:applicationId/c/:chatId`),
-`portal-home`、`portal-application-list`、`portal-application`、`portal-application-chat` 共用门户对话页 `views/portal/index.vue`,
-访问 `portal-home` 时由页面在分组加载后进入第一个智能体的新建对话。`portal-login` 与 `chat-login` 共用 `views/chat/login/index.vue`,页面按 Store
+`portal-home` 重定向到 `portal-application-list`(`/portal/applications`),默认展示全部智能体。
+`portal-application-list`、`portal-application`、`portal-application-chat` 共用门户对话页 `views/portal/index.vue`。
+`portal-login` 与 `chat-login` 共用 `views/chat/login/index.vue`,页面按 Store
当前认证场景显示门户或应用名称,并使用对应场景登录。不要把门户页面放到 `/login` 等一级路径,否则会与 `/:accessToken/` 冲突。
单应用对话路由以 `/:accessToken/` 开头,兼容 v2 对话地址:`chat-home`(`/:accessToken/`)、
diff --git a/ui/src/router/chat/routes.ts b/ui/src/router/chat/routes.ts
index 3a927c0444c..1b245d6436a 100644
--- a/ui/src/router/chat/routes.ts
+++ b/ui/src/router/chat/routes.ts
@@ -1,68 +1,67 @@
import type { RouteRecordRaw } from 'vue-router'
const portalRoutes: RouteRecordRaw[] = [
- {
- path: '/portal',
- name: 'portal-home',
- component: () => import('@/views/portal/index.vue'),
- meta: { title: '门户', portal: true }
- },
- {
- path: '/portal/login',
- name: 'portal-login',
- component: () => import('@/views/chat/login/index.vue'),
- meta: { title: '登录', portal: true }
- },
- {
- path: '/portal/applications',
- name: 'portal-application-list',
- component: () => import('@/views/portal/index.vue'),
- meta: { title: '全部智能体', portal: true }
- },
- {
- path: '/portal/a/:applicationId',
- name: 'portal-application',
- component: () => import('@/views/portal/index.vue'),
- meta: { title: '对话', portal: true }
- },
- {
- path: '/portal/a/:applicationId/c/:chatId',
- name: 'portal-application-chat',
- component: () => import('@/views/portal/index.vue'),
- meta: { title: '对话', portal: true }
- }
+ {
+ path: '/portal',
+ name: 'portal-home',
+ redirect: { name: 'portal-application-list' },
+ meta: { title: '门户', portal: true },
+ },
+ {
+ path: '/portal/login',
+ name: 'portal-login',
+ component: () => import('@/views/chat/login/index.vue'),
+ meta: { title: '登录', portal: true },
+ },
+ {
+ path: '/portal/applications',
+ name: 'portal-application-list',
+ component: () => import('@/views/portal/index.vue'),
+ meta: { title: '全部智能体', portal: true },
+ },
+ {
+ path: '/portal/a/:applicationId',
+ name: 'portal-application',
+ component: () => import('@/views/portal/index.vue'),
+ meta: { title: '对话', portal: true },
+ },
+ {
+ path: '/portal/a/:applicationId/c/:chatId',
+ name: 'portal-application-chat',
+ component: () => import('@/views/portal/index.vue'),
+ meta: { title: '对话', portal: true },
+ },
]
-
const applicationRoutes: RouteRecordRaw[] = [
- {
- path: '/:accessToken/login',
- name: 'chat-login',
- component: () => import('@/views/chat/login/index.vue'),
- meta: { title: '登录' }
- },
- {
- path: '/:accessToken/',
- name: 'chat-home',
- component: () => import('@/views/chat/index.vue'),
- meta: { title: '应用对话' }
- },
- {
- path: '/:accessToken/c/:chatId',
- name: 'chat-home-detail',
- component: () => import('@/views/chat/index.vue'),
- meta: { title: '对话' }
- }
+ {
+ path: '/:accessToken/login',
+ name: 'chat-login',
+ component: () => import('@/views/chat/login/index.vue'),
+ meta: { title: '登录' },
+ },
+ {
+ path: '/:accessToken/',
+ name: 'chat-home',
+ component: () => import('@/views/chat/index.vue'),
+ meta: { title: '应用对话' },
+ },
+ {
+ path: '/:accessToken/c/:chatId',
+ name: 'chat-home-detail',
+ component: () => import('@/views/chat/index.vue'),
+ meta: { title: '对话' },
+ },
]
export const chatRoutes: RouteRecordRaw[] = [
- { path: '/', redirect: { name: 'portal-home' } },
- ...portalRoutes,
- ...applicationRoutes,
- {
- path: '/:pathMatch(.*)*',
- name: 'chat-not-found',
- component: () => import('@/views/chat/error/index.vue'),
- meta: { title: '页面不存在' }
- }
+ { path: '/', redirect: { name: 'portal-home' } },
+ ...portalRoutes,
+ ...applicationRoutes,
+ {
+ path: '/:pathMatch(.*)*',
+ name: 'chat-not-found',
+ component: () => import('@/views/chat/error/index.vue'),
+ meta: { title: '页面不存在' },
+ },
]
diff --git a/ui/src/styles/STYLE_README.md b/ui/src/styles/STYLE_README.md
index edd148a583d..db89e53ccdd 100644
--- a/ui/src/styles/STYLE_README.md
+++ b/ui/src/styles/STYLE_README.md
@@ -213,7 +213,7 @@ CSS 自定义属性同样按变量名排序。嵌套选择器、伪类和媒体
段落卡片使用 `app.scss` 中的 `mk-paragraph-card`,普通模式悬停背景为 N100;多选模式添加
`selectable`,未选中卡片悬停为主题色边框、白色背景。已选卡片添加 `active`,沿用
-`MkSourceCard` 的主题色边框和 10% 主题色背景,选中背景在悬停时保留。
+`MkResourceCard` 的主题色边框和 10% 主题色背景,选中背景在悬停时保留。
禁用样式添加 `disabled`,标题、Markdown 正文和辅助文字使用 N400 浅灰色;此类只改变展示,
悬停时背景和边框不变色,保留选中和操作交互,实际禁用行为由使用方控制。
diff --git a/ui/src/views/VIEW_README.md b/ui/src/views/VIEW_README.md
index 640ae5c07f5..84db908ebbe 100644
--- a/ui/src/views/VIEW_README.md
+++ b/ui/src/views/VIEW_README.md
@@ -203,7 +203,7 @@ System 资源管理或 System 共享 Knowledge API 的 `postKnowledgeHitTest`;
桌面 Enter 提交,Ctrl/Shift/Alt/Meta + Enter 换行,输入法组合期间不提交;移动端 Enter 换行,文本上限 100000 字符。
输入区通过 `ImageUploadCard` 展示图片进度、失败重试和删除,不提供点击预览。上传中或存在失败图片时禁测试,
失败图片可直接重新上传或移除。移除与卸载释放本地预览并取消未完成上传。
-测试期间冻结参数与输入;结果使用 `MkSourceCard` 展示分段、得分、文档名称及命中图片,Markdown 只读。
+测试期间冻结参数与输入;结果使用 `MkResourceCard` 展示分段、得分、文档名称及命中图片,Markdown 只读。
点击结果卡片按需挂载 `ParagraphDialog`,按命中分段的知识库和文档 ID 加载详情,关闭动画后卸载;保存正文后同步当前结果,保留检索得分。
“本次查询”展示成功请求的文本与图片快照,图片位于文本上方,缩略图自动换行并支持预览,不使用横向滚动。
初始与无命中分别展示空态;请求失败由请求层提示,保留输入与已有结果供重试。
@@ -486,5 +486,5 @@ View 负责路由、资源与模式、图加载、保存/发布/调试编排
会话装配在 conversation-panel,列表 Store 不感知 Router;门户复用 chat 装配,保留各智能体最近会话分组。
账户菜单位于 `conversation-panel/left-sidebar/account-menu/index.vue`,单应用与门户共用;直接调用 Chat API 的 `postLogout()`,成功后清理当前认证场景并重新导航,由守卫处理后续认证。
同目录的 `UserPwdDialog.vue` 修改当前对话用户密码,`ApiKeyDialog.vue` 展示门户地址及用户唯一 API Key,支持复制完整密钥和重新生成;密钥在界面中仅显示末四位。
- 没有当前智能体时不查询其信息/会话、禁用输入,分组加载后选首个;无可用智能体显示空态。
+ 门户首页默认进入全部智能体列表,不自动选择智能体;没有当前智能体时不查询其信息/会话、禁用输入,无可用智能体显示空态。
全部智能体与选择抽屉复用卡片,抽屉每次打开重新查询,搜索状态独立。
diff --git a/ui/src/views/application-detail/overview/index.vue b/ui/src/views/application-detail/overview/index.vue
index a59f9e9ae43..3e06e633708 100644
--- a/ui/src/views/application-detail/overview/index.vue
+++ b/ui/src/views/application-detail/overview/index.vue
@@ -41,8 +41,13 @@ const chatBasePath = CHAT_API_BASE_PATH.replace(/\/api$/, '')
const apiDocUrl = new URL(`${CHAT_API_BASE_PATH}-doc/`, window.location.origin).href
-// TODO:分享链接还有问题
-const shareUrl = computed(() => (accessToken.value ? `${window.location.origin}${chatBasePath}/${accessToken.value}` : ''))
+// TODO:访问链接还有问题
+const accessUrl = computed(() => (accessToken.value ? `${window.location.origin}${chatBasePath}/${accessToken.value}` : ''))
+
+function toUrl(url?: string) {
+ if (!url) return
+ window.open(url, '_blank')
+}
function handleChangeWebAccess() {
if (loading.value) return false
@@ -126,11 +131,11 @@ onMounted(() => {
链接
-
+
-
+
@@ -142,13 +147,13 @@ onMounted(() => {
-
-
+
+
去对话
-
+
diff --git a/ui/src/views/application-detail/setting/components/ButtonLongTermSetting.vue b/ui/src/views/application-detail/setting/components/ButtonLongTermSetting.vue
index c74c61efa98..f82cda0724c 100644
--- a/ui/src/views/application-detail/setting/components/ButtonLongTermSetting.vue
+++ b/ui/src/views/application-detail/setting/components/ButtonLongTermSetting.vue
@@ -186,7 +186,7 @@ function submit() {
-
-
+
diff --git a/ui/src/views/application/application-card/ApplicationCard.vue b/ui/src/views/application/application-card/ApplicationCard.vue
index 4211ca9b59c..b8ad7b562a2 100644
--- a/ui/src/views/application/application-card/ApplicationCard.vue
+++ b/ui/src/views/application/application-card/ApplicationCard.vue
@@ -17,7 +17,7 @@ function handleOpen() {
-
-
+
diff --git a/ui/src/views/application/create-application/AdvancedCreateDialog.vue b/ui/src/views/application/create-application/AdvancedCreateDialog.vue
index 9be12d38947..1a0cb62870d 100644
--- a/ui/src/views/application/create-application/AdvancedCreateDialog.vue
+++ b/ui/src/views/application/create-application/AdvancedCreateDialog.vue
@@ -150,7 +150,7 @@ defineExpose({ open })
-
将从知识库中检索到的知识作为已知信息,回答用户提出的问题。
-
+
diff --git a/ui/src/views/knowledge-detail/hit-test/index.vue b/ui/src/views/knowledge-detail/hit-test/index.vue
index a46e6e4aa15..04263eb8456 100644
--- a/ui/src/views/knowledge-detail/hit-test/index.vue
+++ b/ui/src/views/knowledge-detail/hit-test/index.vue
@@ -199,7 +199,7 @@ function testKnowledge(query: Required
-
+
{{ `#${paragraphIndex + 1}` }}
@@ -231,7 +231,7 @@ function testKnowledge(query: Required{{ paragraph.document_name }}
-
+
diff --git a/ui/src/views/knowledge/create-knowledge/components/DocumentStrategyForm.vue b/ui/src/views/knowledge/create-knowledge/components/DocumentStrategyForm.vue
index e336f2d33c5..9023107681d 100644
--- a/ui/src/views/knowledge/create-knowledge/components/DocumentStrategyForm.vue
+++ b/ui/src/views/knowledge/create-knowledge/components/DocumentStrategyForm.vue
@@ -135,7 +135,7 @@ defineExpose({ validate, getStrategy, setStrategy })
-
-
+
图片处理
diff --git a/ui/src/views/knowledge/knowledge-card/KnowledgeCard.vue b/ui/src/views/knowledge/knowledge-card/KnowledgeCard.vue
index 1cbc0b44ca5..9df4055b3d2 100644
--- a/ui/src/views/knowledge/knowledge-card/KnowledgeCard.vue
+++ b/ui/src/views/knowledge/knowledge-card/KnowledgeCard.vue
@@ -21,7 +21,7 @@ function handleOpen() {
-
-
+
diff --git a/ui/src/views/model/model-card/ModelCard.vue b/ui/src/views/model/model-card/ModelCard.vue
index 7d6ce358c28..af2e8946beb 100644
--- a/ui/src/views/model/model-card/ModelCard.vue
+++ b/ui/src/views/model/model-card/ModelCard.vue
@@ -33,7 +33,7 @@ const errMessage = computed(() => {
-
+
@@ -75,5 +75,5 @@ const errMessage = computed(() => {
-
+
diff --git a/ui/src/views/system/chat-management/portal-setting/components/PortalPreview.vue b/ui/src/views/system/chat-management/portal-setting/components/PortalPreview.vue
index f71818dcdad..a26179b181e 100644
--- a/ui/src/views/system/chat-management/portal-setting/components/PortalPreview.vue
+++ b/ui/src/views/system/chat-management/portal-setting/components/PortalPreview.vue
@@ -10,11 +10,11 @@ defineProps<{ name: string; logo: string | null }>()
{{ name }}
-
+
-
全部智能体
+ 智能体
-
+
新建对话
diff --git a/ui/src/views/system/chat-management/portal-setting/index.vue b/ui/src/views/system/chat-management/portal-setting/index.vue
index cbf8d351359..04eebaf7b65 100644
--- a/ui/src/views/system/chat-management/portal-setting/index.vue
+++ b/ui/src/views/system/chat-management/portal-setting/index.vue
@@ -1,6 +1,7 @@
-
-
+
diff --git a/ui/src/views/tool/tool-store/component/ToolStoreCard.vue b/ui/src/views/tool/tool-store/component/ToolStoreCard.vue
index bab48083e0c..04e4834815a 100644
--- a/ui/src/views/tool/tool-store/component/ToolStoreCard.vue
+++ b/ui/src/views/tool/tool-store/component/ToolStoreCard.vue
@@ -39,7 +39,7 @@ function handleApply(tool = props.tool) {
-
+
@@ -69,7 +69,7 @@ function handleApply(tool = props.tool) {
-
+
diff --git a/ui/src/views/trigger/execution-record/ExecutionDetailDrawer.vue b/ui/src/views/trigger/execution-record/ExecutionDetailDrawer.vue
index c4c3dd8ec13..513c2564f70 100644
--- a/ui/src/views/trigger/execution-record/ExecutionDetailDrawer.vue
+++ b/ui/src/views/trigger/execution-record/ExecutionDetailDrawer.vue
@@ -23,7 +23,15 @@ const detail = ref
()
const isTool = computed(() => props.record.source_type === RESOURCE_TYPE.TOOL)
const triggerFailed = computed(() => detail.value?.state === STATE_TYPES.TRIGGER_ERROR)
const runTime = computed(() => detail.value?.run_time ?? props.record.run_time)
-const nodeDetails = computed(() => Object.values((isTool.value ? detail.value?.meta?.details : detail.value?.details) ?? {}))
+const nodeDetails = computed(() => {
+ const executionDetails = Object.fromEntries(Object.entries(detail.value?.details ?? {}))
+ if (!isTool.value) return Object.values(executionDetails)
+
+ return Object.values({
+ ...executionDetails,
+ tool_call: { ...executionDetails.tool_call, name: 'ssss' },
+ })
+})
function loadDetail() {
loading.value = true
diff --git a/ui/src/views/trigger/trigger-form/TriggerFormDrawer.vue b/ui/src/views/trigger/trigger-form/TriggerFormDrawer.vue
index b8bdb94272e..37d28764f1c 100644
--- a/ui/src/views/trigger/trigger-form/TriggerFormDrawer.vue
+++ b/ui/src/views/trigger/trigger-form/TriggerFormDrawer.vue
@@ -317,7 +317,7 @@ defineExpose({ open })
-
-
+
diff --git a/ui/src/views/workflow/components/template-store/components/TemplateCard.vue b/ui/src/views/workflow/components/template-store/components/TemplateCard.vue
index 46aa897220b..22faa01719a 100644
--- a/ui/src/views/workflow/components/template-store/components/TemplateCard.vue
+++ b/ui/src/views/workflow/components/template-store/components/TemplateCard.vue
@@ -30,7 +30,7 @@ function handleUseTemplate() {
-
+
@@ -53,7 +53,7 @@ function handleUseTemplate() {
-
+
-
-
+
diff --git a/ui/src/workflow-canvas/nodes/reranker-node/details/index.vue b/ui/src/workflow-canvas/nodes/reranker-node/details/index.vue
index 83c8be1d7f3..c48e3205b82 100644
--- a/ui/src/workflow-canvas/nodes/reranker-node/details/index.vue
+++ b/ui/src/workflow-canvas/nodes/reranker-node/details/index.vue
@@ -28,7 +28,7 @@ defineProps<{
重排内容
-
+
{{ `#${Number(paragraphIndex) + 1}` }}
@@ -72,7 +72,7 @@ defineProps<{
{{ paragraph.metadata?.knowledge_name || '-' }}
-
+
-
@@ -82,7 +82,7 @@ defineProps<{
重排结果
-
+
{{ `#${Number(paragraphIndex) + 1}` }}
@@ -126,7 +126,7 @@ defineProps<{
{{ paragraph.metadata?.knowledge_name || '-' }}
-
+
-
diff --git a/ui/src/workflow-canvas/nodes/search-knowledge-node/details/index.vue b/ui/src/workflow-canvas/nodes/search-knowledge-node/details/index.vue
index b1889952d5a..35f5d20c635 100644
--- a/ui/src/workflow-canvas/nodes/search-knowledge-node/details/index.vue
+++ b/ui/src/workflow-canvas/nodes/search-knowledge-node/details/index.vue
@@ -57,7 +57,7 @@ function getParagraphImageUrl(paragraph: SearchParagraph) {
检索结果
-
+
{{ `#${paragraphIndex + 1}` }}
@@ -111,7 +111,7 @@ function getParagraphImageUrl(paragraph: SearchParagraph) {
{{ paragraph.knowledge_name || '-' }}
-
+
-