diff --git a/ui/AGENTS.md b/ui/AGENTS.md index c1a40bee3fe..dab2290ed2d 100644 --- a/ui/AGENTS.md +++ b/ui/AGENTS.md @@ -68,17 +68,20 @@ ui/ │ ├── constants/ # Cross-feature constants grouped by domain │ │ └── CONSTANT_README.md # Shared constant placement and naming rules │ ├── layout/ # Shared application shells, headers, sidebars, types, and helpers -│ ├── locales/ # Reserved for internationalization messages and locale setup +│ ├── permission/ # Permission policies, business permission methods, and Admin $perm plugin │ ├── workflow-canvas/ # LogicFlow canvas and workflow domain components │ │ ├── component/ # Reusable workflow canvas UI │ │ ├── config/ # Maintainable node data, menus, mappings, and constants │ │ ├── core/ # Stable canvas behavior and shared node infrastructure +│ │ ├── details/ # Node execution detail dispatch and shared presentation │ │ ├── icons/ # Workflow node icons +│ │ ├── node-menu/ # Basic, tool, and application node selection menus │ │ ├── nodes/ # Workflow node definitions and components │ │ ├── plugins/ # Canvas-local plugins +│ │ ├── store/ # Resource API adapters, query caching, and request deduplication │ │ ├── WORKFLOW_README.md # Canvas boundaries and maintenance rules │ │ ├── types.ts # Workflow canvas protocol types -│ │ └── index.vue # MkWorkflow canvas entry +│ │ └── index.vue # WorkflowCanvas canvas entry │ ├── router/ # Vue Router routes and router instance │ │ └── ROUTE_README.md # Routing conventions and rules │ ├── stores/ # Shared Pinia instance and state stores @@ -95,16 +98,27 @@ ui/ │ ├── views/ # Route-level page components grouped by feature │ │ ├── VIEW_README.md # Page responsibilities and feature-local code rules │ │ ├── home/ # Workspace home page +│ │ ├── application/ # Application list and creation +│ │ ├── application-detail/ # Application overview and settings +│ │ ├── knowledge/ # Knowledge base list and cards +│ │ ├── knowledge-detail/ # Knowledge base and document details +│ │ ├── model/ # Model list, creation, and settings +│ │ ├── tool/ # Tool list, forms, and tool store +│ │ ├── trigger/ # Workspace trigger list │ │ ├── system/ # System-management pages -│ │ ├── login/ # Reserved for admin login pages -│ │ ├── chat/ # Chat-side pages, including user login +│ │ ├── login/ # Admin login, account recovery, and login modes +│ │ ├── chat/ # Chat entry placeholder page +│ │ ├── error/ # Not-found page +│ │ ├── details-demo/ # Temporary execution-detail preview page │ │ └── workflow/ # Full-screen workflow route pages ├── vite.config.ts # Vite entries, plugins, aliases, proxy, and build output ├── tsconfig*.json # TypeScript configuration └── package.json # Dependencies and npm scripts ``` -Directories marked as reserved may be empty while their feature is being introduced. Add files to the matching feature directory instead of creating parallel top-level structures. +Internationalization is not yet integrated; `src/locales/` has not been created. Chat currently has a +placeholder route page and a reserved independent API directory. Add files to the matching feature +directory instead of creating parallel top-level structures. Structural responsibilities: @@ -113,7 +127,7 @@ Structural responsibilities: - Put reusable application chrome in `layout/`, not in individual route views. - Keep LogicFlow initialization, node registration, and canvas behavior inside `workflow-canvas/`. Every page rendering this canvas belongs in `views/workflow/`; those Views own the page header, - route and page-level actions around `MkWorkflow`. + route and page-level actions around `WorkflowCanvas`. - Put server communication in `api/`, isolate Admin and Chat request systems, and group business APIs by domain and resource according to `src/api/API_README.md`. - Put backend fixed-value enums in `api/enums/` and import them through `@/api/enums`; keep @@ -149,7 +163,8 @@ Important variables: - `VITE_APP_PORT`: local dev server port - `VITE_APP_TITLE`: HTML title - `VITE_ENTRY`: HTML entry file -- `VITE_API_TARGET`: optional backend proxy target, defaults to `http://127.0.0.1:8080` +- `VITE_API_TARGET`: optional backend proxy target; currently defaults to `http://47.120.55.164:38080` + through `defaultBackendTarget` in `vite.config.ts`. Override it locally for a different backend. Build output mirrors the v2 layout: @@ -169,10 +184,14 @@ npm run chat # chat dev server npm run build # default admin build with type-check npm run build-chat # chat build with type-check npm run type-check -npm run lint npm run format ``` +Node.js must satisfy `^22.18.0 || >=24.12.0` as declared in `package.json`. +Admin and Chat use ports 3000 and 3001 respectively, with `strictPort` enabled. +`npm run lint` currently delegates to `lint:*`, but no matching scripts are defined. Use +`npx eslint ` for targeted linting until those scripts are configured. + ## Vite Configuration Main config: `vite.config.ts`. diff --git a/ui/README.md b/ui/README.md index 80619bb296b..920cb8d572f 100644 --- a/ui/README.md +++ b/ui/README.md @@ -1,48 +1,99 @@ -# ui +# MaxKB v3 前端 -This template should help get you started developing with Vue 3 in Vite. +MaxKB 企业级 AI 智能体平台的前端工程,使用 Vue 3.5、TypeScript 6、Vite 8、Element Plus、 +Tailwind CSS 4、Pinia 3 和 Vue Router 5,工作流画布基于 LogicFlow。 -## Recommended IDE Setup +项目采用 Admin 和 Chat 双入口。Admin 包含登录、工作空间资源、系统管理和工作流编辑等功能; +Chat 已配置独立入口与路由,当前 `ChatView.vue` 仍为空白占位页,`src/api/chat/` 的独立请求体系尚未实现。 -[VS Code](https://code.visualstudio.com/) + [Vue (Official)](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur). +## 本地开发 -## Recommended Browser Setup +Node.js 版本要求为 `^22.18.0 || >=24.12.0`,以 `package.json` 的 `engines` 为准。 +以下命令均在 `ui/` 目录执行: -- Chromium-based browsers (Chrome, Edge, Brave, etc.): - - [Vue.js devtools](https://chromewebstore.google.com/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd) - - [Turn on Custom Object Formatter in Chrome DevTools](http://bit.ly/object-formatters) -- Firefox: - - [Vue.js devtools](https://addons.mozilla.org/en-US/firefox/addon/vue-js-devtools/) - - [Turn on Custom Object Formatter in Firefox DevTools](https://fxdx.dev/firefox-devtools-custom-object-formatters/) - -## Type Support for `.vue` Imports in TS - -TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types. - -## Customize configuration - -See [Vite Configuration Reference](https://vite.dev/config/). - -## Project Setup - -```sh +```bash npm install +npm run dev ``` -### Compile and Hot-Reload for Development +Admin 默认访问地址为 `http://localhost:3000/admin/`。在另一个终端运行 `npm run chat`, +可通过 `http://localhost:3001/chat/` 访问 Chat 入口。开发服务器启用 `strictPort`,端口被占用时不会自动换端口。 -```sh -npm run dev -``` +### 后端代理与环境变量 -### Type-Check, Compile and Minify for Production +公共及 Admin 默认配置在 `env/.env`,Chat 模式通过 `env/.env.chat` 覆盖入口、路径和端口。 +本地覆盖可放在 `env/.env.local`,Chat 专属覆盖可放在 `env/.env.chat.local`。 -```sh -npm run build -``` +| 变量 | Admin 默认值 | Chat 默认值 | 用途 | +| ----------------- | ------------ | ----------- | -------------------------- | +| `VITE_APP_NAME` | `admin` | `chat` | 应用名称 | +| `VITE_BASE_PATH` | `/admin/` | `/chat/` | 路由基础路径与构建输出目录 | +| `VITE_APP_PORT` | `3000` | `3001` | 开发服务端口 | +| `VITE_APP_TITLE` | `MaxKB` | `MaxKB` | HTML 标题 | +| `VITE_ENTRY` | `admin.html` | `chat.html` | HTML 入口 | +| `VITE_API_TARGET` | 未设置 | 未设置 | 覆盖开发代理的后端地址 | -### Lint with [ESLint](https://eslint.org/) +当前未设置 `VITE_API_TARGET` 时,使用 `vite.config.ts` 中的 `defaultBackendTarget`, +值为 `http://47.120.55.164:38080`。连接本地后端时,在 `env/.env.local` 中配置: -```sh -npm run lint +```dotenv +VITE_API_TARGET=http://127.0.0.1:8080 ``` + +开发代理覆盖 `/admin/api`、`/chat/api`、`/doc`、`/schema`、`/static` 和当前应用基础路径下的 +OSS 文件接口。前端业务接口需要可用的后端服务。 + +## 构建与检查 + +| 命令 | 作用 | +| -------------------------------- | ------------------------------- | +| `npm run dev` | 启动 Admin 开发服务 | +| `npm run chat` | 启动 Chat 开发服务 | +| `npm run build` | 类型检查并构建 Admin | +| `npm run build-chat` | 类型检查并构建 Chat | +| `npm run build-only` | 仅构建 Admin | +| `npm run build-only-chat` | 仅构建 Chat | +| `npm run type-check` | 使用 `vue-tsc --build` 检查类型 | +| `npm run preview` | 预览 Admin 构建产物 | +| `npm run preview -- --mode chat` | 预览 Chat 构建产物 | +| `npm run format` | 使用 Prettier 格式化 `src/` | + +`npm run lint` 当前仅配置了 `run-s "lint:*"`,但尚未定义任何 `lint:*` 子脚本,不能作为已执行 +ESLint 检查的依据。需要检查代码时,可运行 `npx eslint <待检查的文件或目录>`。 + +默认构建分别输出 `dist/admin/index.html` 和 `dist/chat/index.html`,HTML 由构建插件统一重命名。 +静态资源使用相对路径(`base: './'`);部署时仍需为 History 路由配置对应入口回退, +并由部署服务转发 API 和文件请求。Vite 的开发代理不会随静态构建产物部署。 + +## 代码目录 + +| 目录或文件 | 职责 | +| ------------------------------- | ---------------------------------------------------- | +| `src/main.ts` / `src/chat.ts` | Admin / Chat 启动入口 | +| `src/api/` | 请求基础设施、业务 API、后端枚举与共享类型 | +| `src/components/` | 全局 Mk 组件、跨页面业务组件及其他共享组件 | +| `src/layout/` | 应用头部、侧栏与资源详情布局 | +| `src/views/` | 登录、工作空间、系统管理、资源详情和工作流等路由页面 | +| `src/workflow-canvas/` | 画布内核、节点配置、节点实现、执行详情与资源查询缓存 | +| `src/router/` | Admin / Chat 独立路由 | +| `src/permission/` | 权限策略、分业务权限方法与 Admin `$perm` 插件 | +| `src/stores/` | 共享 Pinia 实例及认证、用户、主题状态 | +| `src/styles/` | 主题变量、Tailwind、Element Plus 集成与全局样式 | +| `src/constants/` / `src/utils/` | 跨功能常量与工具函数 | +| `src/assets/` / `public/` | 源码导入资源 / 保留原始路径的静态资源 | + +## 开发约定与文档 + +修改前先阅读 [AGENTS.md](AGENTS.md),再阅读涉及领域的规则文档: + +- [样式](src/styles/STYLE_README.md) +- [组件](src/components/COMPONENT_README.md) +- [路由](src/router/ROUTE_README.md) +- [API](src/api/API_README.md) +- [页面](src/views/VIEW_README.md) +- [工作流画布](src/workflow-canvas/WORKFLOW_README.md) +- [常量](src/constants/CONSTANT_README.md) +- [工具函数](src/utils/UTILS_README.md) + +详细规则由各领域 README 维护;目录、公共接口或使用约定变化时同步对应文档。 +`src/components.d.ts` 由组件自动注册插件生成,不手动编辑。 diff --git a/ui/src/api/admin/core/request.ts b/ui/src/api/admin/core/request.ts index 683a0497233..5fbcfbb6f54 100644 --- a/ui/src/api/admin/core/request.ts +++ b/ui/src/api/admin/core/request.ts @@ -256,36 +256,20 @@ export function post(url: string, data?: TData, pa } /** 发送 POST 请求并返回可逐块读取的原始响应。 */ -export async function postStream(url: string, data?: TData, config: StreamRequestConfig = {}) { +export function postStream(base: string, path: string, data?: unknown) { const { auth, user } = useStore() - const headers = new Headers({ 'Content-Type': 'application/json' }) - if (auth.token) headers.set('Authorization', `Bearer ${auth.token}`) - if (user.language) headers.set('Accept-Language', user.language) - - const baseUrl = String(request.defaults.baseURL ?? '').replace(/\/+$/, '') - const response = await fetch(`${baseUrl}/${url.replace(/^\/+/, '')}`, { - body: JSON.stringify(data ?? {}), - headers, + const headers: Record = { 'Content-Type': 'application/json' } + if (auth.token) { + headers['Authorization'] = `Bearer ${auth.token}` + } + if (user.language) { + headers['Accept-Language'] = user.language + } + return fetch(`${base}${path.startsWith('/') ? path : `/${path}`}`, { method: 'POST', - signal: config.signal, + headers, + body: data === undefined ? undefined : JSON.stringify(data), }) - - if (response.ok) return response - - const errorMessage = (await getFetchErrorMessage(response)) || response.statusText - if (response.status === 401) { - auth.clearToken() - void router.push({ name: 'login' }) - } else if (response.status === 403) { - MsgError(errorMessage || 'No permission to access') - } else if (response.status === 404) { - void router.replace({ name: 'not-found', params: { pathMatch: ['404'] } }) - } else { - MsgError(errorMessage) - } - const error = new Error(errorMessage) - error.name = 'StreamRequestError' - throw error } /** 发送 PUT 请求。 */ diff --git a/ui/src/assets/file-type/file-audio-icon.svg b/ui/src/assets/file-type/file-audio-icon.svg new file mode 100644 index 00000000000..13f1f72160a --- /dev/null +++ b/ui/src/assets/file-type/file-audio-icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/ui/src/assets/file-type/file-document-icon.svg b/ui/src/assets/file-type/file-document-icon.svg new file mode 100644 index 00000000000..86ac2d3f174 --- /dev/null +++ b/ui/src/assets/file-type/file-document-icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/ui/src/assets/file-type/file-image-icon.svg b/ui/src/assets/file-type/file-image-icon.svg new file mode 100644 index 00000000000..4511c36f5d8 --- /dev/null +++ b/ui/src/assets/file-type/file-image-icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/ui/src/assets/file-type/file-video-icon.svg b/ui/src/assets/file-type/file-video-icon.svg new file mode 100644 index 00000000000..cdfe18190ab --- /dev/null +++ b/ui/src/assets/file-type/file-video-icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/ui/src/assets/workflow/icon_loop.svg b/ui/src/assets/workflow/icon_loop.svg new file mode 100644 index 00000000000..4577fec7866 --- /dev/null +++ b/ui/src/assets/workflow/icon_loop.svg @@ -0,0 +1,3 @@ + + + diff --git a/ui/src/assets/workflow/icon_loop_break.svg b/ui/src/assets/workflow/icon_loop_break.svg new file mode 100644 index 00000000000..2346b19ba9e --- /dev/null +++ b/ui/src/assets/workflow/icon_loop_break.svg @@ -0,0 +1,3 @@ + + + diff --git a/ui/src/components/COMPONENT_README.md b/ui/src/components/COMPONENT_README.md index af3afa8f426..3477b394b86 100644 --- a/ui/src/components/COMPONENT_README.md +++ b/ui/src/components/COMPONENT_README.md @@ -102,6 +102,8 @@ src/components/ │ │ └── mk-table-more-dropdown.vue # 表格操作列 More 下拉菜单 │ └── mk-tag-group/ │ └── index.vue # 标签折叠和剩余标签浮层 +├── mk-card-checkbox/ +│ └── index.vue # 卡片式布尔选择,手动导入 ├── mk-date-range/ │ ├── index.vue # 日期预设与自定义日期区间组合筛选器,手动导入 │ └── types.ts # 日期筛选结果类型 @@ -294,7 +296,7 @@ Dialog 外壳仅在首次打开时挂载;默认在关闭动画结束、触发 ... @@ -313,7 +315,7 @@ Escape 关闭;这些默认行为可以通过同名 Props 覆盖。Element Plus ... @@ -710,6 +712,29 @@ Dialog、Drawer、Popover、嵌套区域等其他大、小表格均禁止开启 ## 手动导入组件 +### MkCardCheckbox + +卡片式复选组件,手动导入 `@/components/mk-card-checkbox/index.vue`,不参与全局注册。 +通过布尔 `v-model` 管理选中状态,`label` 必填并作为复选框的无障碍名称;`disabled` 禁止切换。 +默认插槽放置图标、标题、描述等内容。卡片统一维护悬停阴影、选中边框及右侧复选框, +点击卡片或复选框均更新一次 `v-model` 并触发 `change(checked)`;复选框保留原生键盘操作。 +插槽中的输入框、按钮等独立交互区域使用 `@click.stop`,避免操作时切换卡片。 +其余卡片属性和样式通过 `$attrs` 透传到 `el-card`。 +知识库、工具(含 Skills)、智能体选择弹窗,以及动态表单配置器的添加知识库列表统一使用 +该组件。集合选择通过 `:model-value` 与 `@update:model-value` 接入原有业务选择逻辑, +保留筛选、跨目录选择和已选快照;不要同时监听 `change` 重复更新同一集合。 + +```vue + + + +
文档
+

TXT、PDF、DOCX

+
+``` + ### LogoFull、LogoIcon `LogoFull` 展示带产品名称的完整 Logo,`LogoIcon` 展示不带产品名称的图形 Logo,使用时分别从 diff --git a/ui/src/components/business/select-application-dialog/index.vue b/ui/src/components/business/select-application-dialog/index.vue index 97024fe991a..c682458df9c 100644 --- a/ui/src/components/business/select-application-dialog/index.vue +++ b/ui/src/components/business/select-application-dialog/index.vue @@ -6,6 +6,7 @@ import type { FolderItem, ApplicationDetail } from '@/api/types' import { RESOURCE_TYPE } from '@/api/enums' import { FOLDER_ENTRIES } from '@/constants/folder' import FolderTree from '@/components/business/folder-tree/index.vue' +import MkCardCheckbox from '@/components/mk-card-checkbox/index.vue' import MkSourceCard from '@/components/mk-source-card/index.vue' defineOptions({ name: 'SelectApplicationDialog' }) @@ -130,26 +131,16 @@ defineExpose({ open })