diff --git a/ui/src/api/admin/auth/external-login.ts b/ui/src/api/admin/auth/external-login.ts index 8600bfcd3aa..0690a49a552 100644 --- a/ui/src/api/admin/auth/external-login.ts +++ b/ui/src/api/admin/auth/external-login.ts @@ -1,7 +1,8 @@ /** 提供 Admin 第三方认证、扫码登录及客户端授权回调接口。 */ import { get } from '../core/request' -import type { ExternalAuthSetting, LoginResponse, QrCodeSource } from './types' +import type { ExternalAuthSetting, QrCodeSource } from '@/api/types' +import type { LoginResponse } from './types' /** 获取外部认证方式的跳转配置。 */ const getExternalAuthSetting = (authType: string) => { diff --git a/ui/src/api/admin/auth/types.ts b/ui/src/api/admin/auth/types.ts index 5ab8bec417d..70fdffa8666 100644 --- a/ui/src/api/admin/auth/types.ts +++ b/ui/src/api/admin/auth/types.ts @@ -1,6 +1,6 @@ /** Admin 认证 API 及其 Store 消费方共同使用的类型。 */ -import type { LoginMethod, QrCodeConfig, WorkspaceItem } from '@/api/types' +import type { WorkspaceItem } from '@/api/types' export interface CurrentUserInfo { email: string @@ -32,24 +32,6 @@ export interface CaptchaResponse { captcha: string } -export interface ExternalAuthConfig { - authEndpoint?: string - clientId?: string - ldpUri?: string - redirectUrl: string - scope?: string - state?: string -} - -export interface ExternalAuthSetting { - config?: ExternalAuthConfig -} - -export interface QrCodeSource { - auth_type: Extract - config: QrCodeConfig -} - export interface BaseProfile { edition: 'CE' | 'EE' | 'PE' license_is_valid: boolean diff --git a/ui/src/api/admin/system/resource-management/application/application.ts b/ui/src/api/admin/system/resource-management/application/application.ts index 2866d4f4624..419385dab43 100644 --- a/ui/src/api/admin/system/resource-management/application/application.ts +++ b/ui/src/api/admin/system/resource-management/application/application.ts @@ -1,6 +1,13 @@ import { del, get, getExportFile, put } from '@/api/admin/core/request' import type { ParamsPage, ResponsePage } from '@/api/admin/core/types' -import type { ApplicationAccessToken, ApplicationAccessTokenPayload, ApplicationDetail, ApplicationFormPayload, Dict } from '@/api/types' +import type { + ApplicationAccessToken, + ApplicationAccessTokenPayload, + ApplicationDetail, + ApplicationDisplaySetting, + ApplicationFormPayload, + Dict, +} from '@/api/types' const prefix = '/system/resource/application' @@ -45,6 +52,9 @@ const getAccessToken = (applicationId: string) => get(`$ const putAccessToken = (applicationId: string, payload: ApplicationAccessTokenPayload) => put(`${prefix}/${applicationId}/access_token`, payload) +/** 获取智能体展示设置,仅许可证有效的专业版、企业版提供;未保存过的字段可能缺失。 */ +const getDisplaySetting = (applicationId: string) => get>(`${prefix}/${applicationId}/setting`) + /** 保存智能体展示设置,沿用 V2 图片与配置的 multipart 协议。 */ const putDisplaySetting = (applicationId: string, payload: FormData) => put(`${prefix}/${applicationId}/setting`, payload) @@ -63,6 +73,7 @@ export default { getApplicationDetail, getAccessToken, putAccessToken, + getDisplaySetting, putDisplaySetting, putApplication, putApplicationPublish, diff --git a/ui/src/api/admin/workspace/application/application.ts b/ui/src/api/admin/workspace/application/application.ts index fce1df2b9eb..5cf6fa39dc6 100644 --- a/ui/src/api/admin/workspace/application/application.ts +++ b/ui/src/api/admin/workspace/application/application.ts @@ -1,6 +1,13 @@ import { del, get, getExportFile, post, put } from '../../core/request' import type { ParamsPage, ResponsePage } from '../../core/types' -import type { ApplicationAccessToken, ApplicationAccessTokenPayload, ApplicationDetail, ApplicationFormPayload, Dict } from '@/api/types' +import type { + ApplicationAccessToken, + ApplicationAccessTokenPayload, + ApplicationDetail, + ApplicationDisplaySetting, + ApplicationFormPayload, + Dict, +} from '@/api/types' import { getWorkspaceId } from '@/utils/resource-context' const getPrefix = () => { @@ -34,6 +41,9 @@ const getAccessToken = (applicationId: string) => get(`$ const putAccessToken = (applicationId: string, payload: ApplicationAccessTokenPayload) => put(`${getPrefix()}/${applicationId}/access_token`, payload) +/** 获取智能体展示设置,仅许可证有效的专业版、企业版提供;未保存过的字段可能缺失。 */ +const getDisplaySetting = (applicationId: string) => get>(`${getPrefix()}/${applicationId}/setting`) + /** 保存智能体展示设置,沿用 V2 图片与配置的 multipart 协议。 */ const putDisplaySetting = (applicationId: string, payload: FormData) => put(`${getPrefix()}/${applicationId}/setting`, payload) @@ -103,6 +113,7 @@ export default { getApplicationDetail, getAccessToken, putAccessToken, + getDisplaySetting, putDisplaySetting, deleteApplication, exportApplication, diff --git a/ui/src/api/chat/auth.ts b/ui/src/api/chat/auth.ts index ed2589ce984..ea77baa88f9 100644 --- a/ui/src/api/chat/auth.ts +++ b/ui/src/api/chat/auth.ts @@ -1,8 +1,8 @@ -/** 提供单应用对话与门户的认证前置配置、匿名认证、登录和登出接口。 */ +/** 提供单应用对话与门户的认证前置配置、匿名认证、账号/第三方/扫码登录和登出接口。 */ import { get, post, promise, request } from './core/request' import type { ApiResponse } from './core/types' -import type { ApplicationAuthProfile, ChatLoginRequest, ChatLoginResponse, PortalAuthProfile } from '@/api/types' +import type { ApplicationAuthProfile, ChatLoginRequest, ChatLoginResponse, ExternalAuthSetting, PortalAuthProfile, QrCodeSource } from '@/api/types' interface ChatCaptchaResponse { captcha: string @@ -43,6 +43,30 @@ const postLogin = (loginRequest: ChatLoginRequest, accessToken?: string, savedTo ) } +/** 使用 LDAP 账号登录;传入 accessToken 时登录到对应应用,否则登录门户。携带本地保存的 token。 */ +const postLdapLogin = (loginRequest: ChatLoginRequest, accessToken?: string, savedToken?: string) => { + return promise( + request.post>(accessToken ? `/auth/ldap/login/${accessToken}` : '/auth/ldap/login', loginRequest, { + headers: getSavedTokenHeaders(savedToken), + }), + ) +} + +/** 获取 CAS、OIDC、OAuth2 等对话用户第三方认证的跳转配置。 */ +const getExternalAuthSetting = (authType: string) => { + return get(`/chat_user/${authType}/detail`) +} + +/** 获取对话用户扫码登录提供商配置。 */ +const getQrCodeSources = () => { + return get('/auth/qr_type/source') +} + +/** 使用钉钉扫码授权码登录;传入 accessToken 时登录到对应应用。 */ +const getDingTalkCallback = (code: string, accessToken?: string) => { + return get('/auth/dingtalk', accessToken ? { code, accessToken } : { code }) +} + /** * 获取应用登录验证码;无需验证码时返回空字符串。 * 后端当前以 `application_id` 查询参数接收 accessToken,且仅支持应用场景。 @@ -56,4 +80,15 @@ const postLogout = () => { return post('/v3/auth/logout') } -export default { getApplicationAuthProfile, getPortalAuthProfile, postAnonymousAuth, postLogin, getCaptcha, postLogout } +export default { + getApplicationAuthProfile, + getPortalAuthProfile, + postAnonymousAuth, + postLogin, + postLdapLogin, + getExternalAuthSetting, + getQrCodeSources, + getDingTalkCallback, + getCaptcha, + postLogout, +} diff --git a/ui/src/api/types/application.ts b/ui/src/api/types/application.ts index cef0bb08296..5cfa36f5003 100644 --- a/ui/src/api/types/application.ts +++ b/ui/src/api/types/application.ts @@ -140,6 +140,8 @@ export interface ApplicationFormPayload { tts_type?: string tts_autoplay?: boolean stt_autosend?: boolean + file_upload_enable?: boolean + file_upload_setting?: Record folder_id?: string workspace_id?: string mcp_enable?: boolean diff --git a/ui/src/api/types/chat-application.ts b/ui/src/api/types/chat-application.ts index 25c7f3cd875..e1a2ca47f75 100644 --- a/ui/src/api/types/chat-application.ts +++ b/ui/src/api/types/chat-application.ts @@ -1,12 +1,50 @@ /** 对话端智能体信息类型。 */ -/** 对话端可见的智能体基础信息,仅声明当前使用的字段。 */ +import type LogicFlow from '@logicflow/core' +import type { ApplicationType } from './application' +import type { Dict } from './common' + +/** + * 对话端可见的智能体信息。门户智能体列表只返回基础字段; + * profile 接口额外返回对话配置(已发布版本)与访问设置,访问设置中的展示项需许可证有效才返回。 + */ export interface ChatApplicationProfile { id: string name: string icon: string - desc?: string + desc?: string | null prologue?: string + type?: ApplicationType + dialogue_number?: number + problem_optimization?: boolean + stt_model_id?: string | null + tts_model_id?: string | null + stt_model_enable?: boolean + tts_model_enable?: boolean + tts_type?: string + tts_autoplay?: boolean + stt_autosend?: boolean + file_upload_enable?: boolean + file_upload_setting?: Dict + /** 仅包含开始节点(base-node),非工作流智能体为 null。 */ + work_flow?: LogicFlow.GraphConfigData | null + show_source?: boolean + show_exec?: boolean + show_share?: boolean + language?: string | null + show_history?: boolean + draggable?: boolean + show_guide?: boolean + avatar?: string + show_avatar?: boolean + float_icon?: string + disclaimer?: boolean + disclaimer_value?: string + custom_theme?: { theme_color?: string; header_font_color?: string } + user_avatar?: string + show_user_avatar?: boolean + float_location?: Dict + chat_background?: string } /** 门户历史对话中单条会话的摘要。 */ diff --git a/ui/src/api/types/login.ts b/ui/src/api/types/login.ts index e6cb574db20..0c14c93cd53 100644 --- a/ui/src/api/types/login.ts +++ b/ui/src/api/types/login.ts @@ -21,6 +21,25 @@ export interface QrCodeConfig { qr_url?: string } +export interface QrCodeSource { + auth_type: QrCodeProvider + config: QrCodeConfig +} + +/** CAS、OIDC、OAuth2 等第三方认证的跳转配置。 */ +export interface ExternalAuthConfig { + authEndpoint?: string + clientId?: string + ldpUri?: string + redirectUrl: string + scope?: string + state?: string +} + +export interface ExternalAuthSetting { + config?: ExternalAuthConfig +} + export interface UpdatePasswordForm { password: string re_password: string diff --git a/ui/src/assets/conversation/load_error.png b/ui/src/assets/conversation/load_error.png new file mode 100644 index 00000000000..695abfd885e Binary files /dev/null and b/ui/src/assets/conversation/load_error.png differ diff --git a/ui/src/constants/CONSTANT_README.md b/ui/src/constants/CONSTANT_README.md index 024d39d4ec1..00dbf753076 100644 --- a/ui/src/constants/CONSTANT_README.md +++ b/ui/src/constants/CONSTANT_README.md @@ -45,3 +45,6 @@ API 枚举值。例如角色类型和登录方式以 `src/api/enums` 为唯一 `file-type.ts` 维护图片、文档、视频和音频的文件扩展名常量,扩展名统一使用大写。 使用方判断文件类型时先将后缀转换为大写,再与对应常量匹配。 + +`application.ts` 的 `APPLICATION_DISPLAY_SETTING_DEFAULT` 维护智能体显示设置默认值,专业版显示设置弹窗的 +初始与恢复默认、调试面板(社区版或接口未返回的字段)共用;常量只读,使用方修改前先深拷贝。 diff --git a/ui/src/constants/application.ts b/ui/src/constants/application.ts new file mode 100644 index 00000000000..2eb3029216a --- /dev/null +++ b/ui/src/constants/application.ts @@ -0,0 +1,24 @@ +/** 智能体共享常量。 */ + +import type { ApplicationDisplaySetting } from '@/api/types' + +/** 显示设置默认值:专业版显示设置弹窗的初始与恢复默认,社区版调试面板也以此展示。使用方按需深拷贝。 */ +export const APPLICATION_DISPLAY_SETTING_DEFAULT: Readonly = { + show_source: false, + show_exec: false, + language: '', + show_history: true, + draggable: true, + show_share: true, + icon: '', + chat_background: '', + avatar: './favicon.ico', + float_icon: '', + user_avatar: './favicon.ico', + disclaimer: false, + disclaimer_value: '「以上内容均由 AI 生成,仅供参考和借鉴」', + custom_theme: { theme_color: '', header_font_color: '#1f2329' }, + float_location: { x: { type: 'right', value: 0 }, y: { type: 'bottom', value: 30 } }, + show_avatar: true, + show_user_avatar: true, +} diff --git a/ui/src/conversation-panel/components/content/items/text.vue b/ui/src/conversation-panel/components/content/items/text.vue index 4a4862158bc..a888a092d8a 100644 --- a/ui/src/conversation-panel/components/content/items/text.vue +++ b/ui/src/conversation-panel/components/content/items/text.vue @@ -1,17 +1,16 @@ diff --git a/ui/src/conversation-panel/components/header/debug/index.vue b/ui/src/conversation-panel/components/header/debug/index.vue index 351da6e6848..a33c4f25daa 100644 --- a/ui/src/conversation-panel/components/header/debug/index.vue +++ b/ui/src/conversation-panel/components/header/debug/index.vue @@ -18,7 +18,6 @@ const debug = useDebugHeaderStore() -

{{ appInfo?.name }}

diff --git a/ui/src/conversation-panel/components/markdown-renderer/EchartsRender.vue b/ui/src/conversation-panel/components/markdown-renderer/EchartsRender.vue new file mode 100644 index 00000000000..d73ff7f77ef --- /dev/null +++ b/ui/src/conversation-panel/components/markdown-renderer/EchartsRender.vue @@ -0,0 +1,161 @@ + + +