From c157e9f19c5a2828d4bae68111ee3764d9535336 Mon Sep 17 00:00:00 2001 From: chilingling <26962197+chilingling@users.noreply.github.com> Date: Thu, 24 Jul 2025 14:15:14 +0800 Subject: [PATCH 001/101] fix: url with blockId will get empty page list (#1542) --- packages/plugins/page/src/PageTree.vue | 9 +++------ packages/plugins/page/src/Tree.vue | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/packages/plugins/page/src/PageTree.vue b/packages/plugins/page/src/PageTree.vue index 1963e337bc..377993aaee 100644 --- a/packages/plugins/page/src/PageTree.vue +++ b/packages/plugins/page/src/PageTree.vue @@ -125,9 +125,12 @@ export default { const { subscribe, unsubscribe } = useMessage() + const refreshPageList = (appId: string) => getPageList(appId) + let subscriber = null onMounted(() => { + refreshPageList(getAppId()) subscriber = subscribe({ topic: 'locationHistoryChanged', callback: (data) => { @@ -147,12 +150,6 @@ export default { } }) - const refreshPageList = async (appId) => { - const pages = await getPageList(appId) - - return pages - } - pageSettingState.updateTreeData = async () => { const pageList = await refreshPageList(getAppId()) return pageList diff --git a/packages/plugins/page/src/Tree.vue b/packages/plugins/page/src/Tree.vue index 75251a000b..d570631af4 100644 --- a/packages/plugins/page/src/Tree.vue +++ b/packages/plugins/page/src/Tree.vue @@ -95,7 +95,7 @@ const useCollapseMap = () => { const { collapseMap, setCollapse, switchCollapse } = useCollapseMap() -interface TreeNode { +export interface TreeNode { id: string | number label: string parentId?: string | number From 021d3c4d3539c13d30e823e9b179176fd07ff5bd Mon Sep 17 00:00:00 2001 From: chilingling <26962197+chilingling@users.noreply.github.com> Date: Thu, 24 Jul 2025 14:22:08 +0800 Subject: [PATCH 002/101] feat: sync page state and global state saving behavior (#1540) --- packages/plugins/state/src/Main.vue | 15 +++++++++++++-- packages/toolbars/save/src/js/index.ts | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/packages/plugins/state/src/Main.vue b/packages/plugins/state/src/Main.vue index b5faa0a8a7..fc39783e4d 100644 --- a/packages/plugins/state/src/Main.vue +++ b/packages/plugins/state/src/Main.vue @@ -230,7 +230,7 @@ export default { if (activeName.value === STATE.CURRENT_STATE) { // 校验 - variableRef.value.validateForm().then(() => { + variableRef.value.validateForm().then(async () => { // 获取数据 const variable = variableRef.value.getFormData() @@ -243,7 +243,17 @@ export default { updateSchema({ state: { ...(schema.state || {}), [name]: variable } }) useHistory().addHistory() - openCommon() + + const isFixed = props.fixedPanels.includes(PLUGIN_NAME.State) + // 如果面板没有固定,临时固定,避免因保存时清空选中状态导致的面板关闭 + if (!isFixed) { + useLayout().changeLeftFixedPanels(PLUGIN_NAME.State) + } + await openCommon() + // 恢复原来固定的状态 + if (!isFixed) { + useLayout().changeLeftFixedPanels(PLUGIN_NAME.State) + } }) } else { storeRef.value.validateForm().then(() => { @@ -276,6 +286,7 @@ export default { updateGlobalState(id, { global_state: storeList }).then((res) => { isPanelShow.value = false useResource().appSchemaState.globalState = res.global_state || [] + useNotify({ message: '保存成功!', type: 'success' }) }) openCommon() }) diff --git a/packages/toolbars/save/src/js/index.ts b/packages/toolbars/save/src/js/index.ts index 1e7f286f31..9434e68915 100644 --- a/packages/toolbars/save/src/js/index.ts +++ b/packages/toolbars/save/src/js/index.ts @@ -173,7 +173,7 @@ export const openCommon = async () => { } */ - saveCommon(state.code).finally(() => { + return saveCommon(state.code).finally(() => { state.disabled = false if (typeof saved === 'function') { From cc45dc96174e9bbc7c286e67bce432a167f058a7 Mon Sep 17 00:00:00 2001 From: chilingling <26962197+chilingling@users.noreply.github.com> Date: Thu, 24 Jul 2025 14:24:14 +0800 Subject: [PATCH 003/101] feat: support hide builtin material from material list (#1537) --- docs/api/frontend-api/material-api.md | 185 +++++++++++------- packages/plugins/materials/index.ts | 3 +- .../materials/src/composable/useMaterial.ts | 26 ++- .../materials/src/meta/component/src/Main.vue | 48 +++-- 4 files changed, 170 insertions(+), 92 deletions(-) diff --git a/docs/api/frontend-api/material-api.md b/docs/api/frontend-api/material-api.md index 162894e7f1..7bb9601372 100644 --- a/docs/api/frontend-api/material-api.md +++ b/docs/api/frontend-api/material-api.md @@ -1,19 +1,21 @@ -# 物料模块API +# 物料模块 API + ## 物料插件元应用 ```js export default { id: 'engine.plugins.materials', // 元应用id title: '物料', // 元应用名称 - type: 'plugins', // 元应用类型 + type: 'plugins', // 元应用类型 icon: 'plugin-icon-materials', // 元应用图标 align: 'top', // 元应用在当前类型下的位置 entry, // 入口文件 layout: MaterialLayout, // 布局文件,可替换布局 options: { defaultTabId: 'engine.plugins.materials.component', // 默认激活的Tab的元应用ID - displayComponentIds: ['engine.plugins.materials.component', 'engine.plugins.materials.block'], // 需要展示的Tab组件ID列表,可以为单个,单个的时候,不展示tab,直接显示该元应用 - basePropertyOptions //基础属性配置 + displayComponentIds: ['engine.plugins.materials.component', 'engine.plugins.materials.block'], // 需要展示的Tab组件ID列表,可以为单个,单个的时候,不展示tab,直接显示该元应用 + basePropertyOptions, //基础属性配置 + hiddenBuiltinMaterials: [] // 隐藏的内置物料组件列表,配置的组件不会在物料面板中显示 }, components: { header: MaterialHeader // 公共组件,可自行提供 @@ -23,17 +25,56 @@ export default { } export { entry, ResourceService, MaterialService } - ``` -### 物料插件元应用暴露出来的API +### 物料插件配置选项详解 + +#### hiddenBuiltinMaterials 配置 + +用于隐藏不需要在物料面板中显示的内置组件,提高物料面板的整洁性和用户体验。 + +**配置示例:** + ```js - apis: { - fetchGroups: fetchGroups // 获取区块分组列表 +// registry.js +export default { + [META_APP.Materials]: { + options: { + hiddenBuiltinMaterials: [ + 'Box', // 盒子容器(普通div 容器) + 'CanvasRowColContainer', // 行列容器 + 'CanvasFlexBox', // 弹性容器 + 'CanvasSection', // 全宽居中容器 + 'Text', // 文本 + 'Icon', // 图标 + 'Img', // 图片 + 'Slot', // 插槽(区块插槽需要) + 'RouterView', // 路由视图(子页面需要,不建议隐藏) + 'RouterLink', // 路由链接 + 'Navigation', // 导航条 + 'NavigationV', // 纵向导航条 + 'Collection' // 数据源容器(数据源功能依赖,不建议隐藏) + ] + } } +} +``` + +**使用场景:** + +- 隐藏不常用的内置组件,简化物料面板 +- 根据项目需求定制显示的组件列表 + +### 物料插件元应用暴露出来的 API + +```js +apis: { + fetchGroups: fetchGroups // 获取区块分组列表 +} ``` ## 物料模块元服务 + ### useResource 元服务 负责全局统一的资源管理,如:国际化、大纲树、工具类、全局状态,全局数据源 @@ -47,7 +88,6 @@ const resState = reactive({ globalState: [] }) - return { resState, // 保存着整个tiny-engine的国际化、大纲树、工具类、全局状态,全局数据源数据 fetchResource, // 进行初始化,获取后端返回的资源信息 @@ -67,7 +107,7 @@ return { ```js const materialState = reactive({ components: [], // 这里存放的是物料插件面板里所有显示的组件 - blocks: [], // 这里存放的是物料插件面板里所有显示的区块 + blocks: [], // 这里存放的是物料插件面板里所有显示的区块 componentsDepsMap: { scripts: [], styles: new Set() }, // 这里存放组件依赖的映射 packages: [] // 物料依赖的包 }) @@ -75,7 +115,7 @@ const materialState = reactive({ **使用示例** -```useMaterial().materialState``` +`useMaterial().materialState` 2. 暴露出来的方法函数详情 @@ -83,37 +123,30 @@ const materialState = reactive({ { // 状态对象 materialState, // 存放着组件、物料侧区块、第三方依赖信息 - - // 初始化和请求方法 - initMaterial, // 物料模块初始化,参数: { isInit = true, appData = {} } - fetchMaterial, // 请求物料并进行处理 - refreshMaterial, // 刷新物料,清空后重新初始化和获取 - - // 物料资源获取方法 - getMaterialsRes, // 获取物料,并返回符合物料协议的bundle.json内容,返回: Promise - getMaterial, // 获取单个物料,参数: (name: string) => Material - getComponentsByGroup, // 根据组名获取指定分组组件,参数: (components: Component[], groupName: string) => Component[] - - // 物料操作方法 - generateNode, // 根据包含{ type, component }的组件信息生成组件schema节点 - setMaterial, // 设置单个物料,参数: (name: string, data: Material) => void - addMaterials, // 添加多个物料,参数: (materials: Material) => void - - // 物料清理方法 - clearMaterials, // 清空所有物料 - clearBlockResources, // 清空区块缓存,以便更新最新版区块 - - getBlockByName, // 通过区块名称获取区块 - getBlockCompileRes, // 获取区块编译结果 - addBlockResources, // 增加区块缓存,参数: (id: string, resource: BlockResource) => void - updateBlockCompileCache, // 更新区块编译缓存 - - // 依赖相关方法 - getCanvasDeps, // 组装画布依赖,包含物料和工具类的依赖 - updateCanvasDeps, // 通知画布更新依赖 - - // 配置相关方法 - getConfigureMap // 获取物料组件的配置信息,返回组件名到配置的映射 + // 初始化和请求方法 + initMaterial, // 物料模块初始化,参数: { isInit = true, appData = {} } + fetchMaterial, // 请求物料并进行处理 + refreshMaterial, // 刷新物料,清空后重新初始化和获取 + // 物料资源获取方法 + getMaterialsRes, // 获取物料,并返回符合物料协议的bundle.json内容,返回: Promise + getMaterial, // 获取单个物料,参数: (name: string) => Material + getComponentsByGroup, // 根据组名获取指定分组组件,参数: (components: Component[], groupName: string) => Component[] + // 物料操作方法 + generateNode, // 根据包含{ type, component }的组件信息生成组件schema节点 + setMaterial, // 设置单个物料,参数: (name: string, data: Material) => void + addMaterials, // 添加多个物料,参数: (materials: Material) => void + // 物料清理方法 + clearMaterials, // 清空所有物料 + clearBlockResources, // 清空区块缓存,以便更新最新版区块 + getBlockByName, // 通过区块名称获取区块 + getBlockCompileRes, // 获取区块编译结果 + addBlockResources, // 增加区块缓存,参数: (id: string, resource: BlockResource) => void + updateBlockCompileCache, // 更新区块编译缓存 + // 依赖相关方法 + getCanvasDeps, // 组装画布依赖,包含物料和工具类的依赖 + updateCanvasDeps, // 通知画布更新依赖 + // 配置相关方法 + getConfigureMap // 获取物料组件的配置信息,返回组件名到配置的映射 } ``` @@ -122,10 +155,10 @@ const materialState = reactive({ ```js // 初始化物料 useMaterial().initMaterial({ isInit: true, appData }) // appData为远程拉取的应用数据 - + // 获取单个物料 const material = useMaterial().getMaterial('ComponentName') - + // 生成组件节点 const node = useMaterial().generateNode({ type: 'component', component: 'Button' }) @@ -133,7 +166,7 @@ const node = useMaterial().generateNode({ type: 'component', component: 'Button' await useMaterial().refreshMaterial() ``` -#### 主要API详解 +#### 主要 API 详解 ##### 初始化和请求相关方法 @@ -171,7 +204,6 @@ refreshMaterial() 使用场景:二开工程中,允许用户上传物料,或者是动态更新物料后,需要刷新物料,此时可以调用该方法。 - ##### 物料资源获取方法 1. `getMaterialsRes`:获取物料资源 @@ -280,42 +312,47 @@ updateCanvasDeps() 使用场景:如果需要画布刷新 script 或者 import-map 的时候,可以调用此方法让画布重新加载。(该方法会调用 getCanvasDeps 方法,获取画布依赖,并通知画布更新依赖) #### 物料类型结构 + 主要的物料类型定义包括: -1. `Material`: 物料包定义,符合物料协议的bundle.json内容 +1. `Material`: 物料包定义,符合物料协议的 bundle.json 内容 + ```ts interface Material { - components: Component[]; // 组件列表 - blocks?: Block[]; // 区块列表 - snippets?: Snippet[]; // 物料分组列表 - packages?: Dependency[]; // 物料依赖的包 + components: Component[] // 组件列表 + blocks?: Block[] // 区块列表 + snippets?: Snippet[] // 物料分组列表 + packages?: Dependency[] // 物料依赖的包 } ``` 2. `Component`: 组件物料定义 + ```ts interface Component { - component: string; // 组件名称 - group: string; // 组件分组 - npm?: { // 组件NPM包信息 - package: string; // 包名 - script?: string; // 脚本路径 - exportName: string; // 导出名称 - css?: string; // 样式路径 - }; - schema?: Schema; // 组件配置信息 + component: string // 组件名称 + group: string // 组件分组 + npm?: { + // 组件NPM包信息 + package: string // 包名 + script?: string // 脚本路径 + exportName: string // 导出名称 + css?: string // 样式路径 + } + schema?: Schema // 组件配置信息 } ``` 3. `Block`: 区块物料定义 + ```ts interface Block { - label: string; // 区块标识 - blockName: string; // 区块名称 - version?: string; // 区块版本 - description?: string; // 区块描述 - screenshot?: string; // 区块截图 - content?: BlockResource; // 区块内容 + label: string // 区块标识 + blockName: string // 区块名称 + version?: string // 区块版本 + description?: string // 区块描述 + screenshot?: string // 区块截图 + content?: BlockResource // 区块内容 } ``` @@ -346,13 +383,13 @@ import { useMaterial, useCanvas } from '@opentiny/tiny-engine' export const addComponent = (componentName) => { const material = useMaterial() const canvas = useCanvas() - + // 生成组件节点 - const schema = material.generateNode({ - type: 'component', - component: componentName + const schema = material.generateNode({ + type: 'component', + component: componentName }) - + // 添加到画布 canvas.canvasApi.value.addComponent(schema) } @@ -365,14 +402,14 @@ import { useMaterial } from '@opentiny/tiny-engine' export const getComponentConfigure = (componentName) => { const material = useMaterial() - + // 获取单个物料信息 const componentInfo = material.getMaterial(componentName) - + // 获取组件配置 const configureMap = material.getConfigureMap() const configure = configureMap[componentName] - + return { componentInfo, configure } } ``` diff --git a/packages/plugins/materials/index.ts b/packages/plugins/materials/index.ts index 4545965562..e660a1615a 100644 --- a/packages/plugins/materials/index.ts +++ b/packages/plugins/materials/index.ts @@ -36,7 +36,8 @@ export default { componentBaseStyle: { className: 'component-base-style', style: 'margin: 8px;' - } + }, + hiddenBuiltinMaterials: [] }, components: { header: MaterialHeader diff --git a/packages/plugins/materials/src/composable/useMaterial.ts b/packages/plugins/materials/src/composable/useMaterial.ts index ae55eb0103..c5fe80f023 100644 --- a/packages/plugins/materials/src/composable/useMaterial.ts +++ b/packages/plugins/materials/src/composable/useMaterial.ts @@ -404,12 +404,34 @@ const getBlockDeps = (dependencies: { scripts?: Dependency[]; styles?: any[] } = } } +/** + * 过滤内置物料,用户配置隐藏的内置物料,不显示在物料面板 + * @param materials 物料 + * @returns 过滤后的物料 + */ +const filterBuiltinMaterials = (materials: Material) => { + const hiddenBuiltinMaterials = getOptions(meta.id).hiddenBuiltinMaterials || [] + + return { + ...materials, + snippets: materials.snippets?.map((item) => { + return { + ...item, + children: item.children?.filter((child) => !hiddenBuiltinMaterials.includes(child.snippetName)) + } + }) + } +} + const initBuiltinMaterial = () => { const { Builtin } = useCanvas().canvasApi.value + const builtinMaterials = filterBuiltinMaterials(Builtin!.data.materials) + const builtinComponentMaterials = filterBuiltinMaterials(BuiltinComponentMaterials) + // 添加画布物料 - addMaterials(Builtin!.data.materials) + addMaterials(builtinMaterials) // 添加builtin-component NPM包物料 - addMaterials(BuiltinComponentMaterials) + addMaterials(builtinComponentMaterials) } const initMaterial = ({ isInit = true, appData = {} }: InitMaterialOptions = {}) => { diff --git a/packages/plugins/materials/src/meta/component/src/Main.vue b/packages/plugins/materials/src/meta/component/src/Main.vue index b0b8e9d11c..272caff338 100644 --- a/packages/plugins/materials/src/meta/component/src/Main.vue +++ b/packages/plugins/materials/src/meta/component/src/Main.vue @@ -36,7 +36,7 @@ diff --git a/packages/plugins/state/src/styles/vars.less b/packages/plugins/state/src/styles/vars.less index 406a1cdd8f..2b9e44f1ac 100644 --- a/packages/plugins/state/src/styles/vars.less +++ b/packages/plugins/state/src/styles/vars.less @@ -29,4 +29,5 @@ --te-state-right-panel-icon-color: var(--te-common-icon-hover); --te-state-right-panel-bg-color: var(--te-common-bg-container); + --te-state-tip-highlight-color: var(--te-common-text-emphasize); } From 38084b931e5b9820b0dbe3498242f8b56c04c411 Mon Sep 17 00:00:00 2001 From: chilingling <26962197+chilingling@users.noreply.github.com> Date: Thu, 24 Jul 2025 15:35:21 +0800 Subject: [PATCH 005/101] fix: importMapUpdateI18nHostVersion (#1556) --- packages/common/js/import-map.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/common/js/import-map.json b/packages/common/js/import-map.json index 0e63e28a18..eb278fcf67 100644 --- a/packages/common/js/import-map.json +++ b/packages/common/js/import-map.json @@ -8,7 +8,7 @@ "@vueuse/core": "${VITE_CDN_DOMAIN}/@vueuse/core${versionDelimiter}9.6.0${fileDelimiter}/index.mjs", "@vueuse/shared": "${VITE_CDN_DOMAIN}/@vueuse/shared${versionDelimiter}9.6.0${fileDelimiter}/index.mjs", "axios": "${VITE_CDN_DOMAIN}/axios${versionDelimiter}1.0.0${fileDelimiter}/dist/esm/axios.js", - "@opentiny/tiny-engine-i18n-host": "${VITE_CDN_DOMAIN}/@opentiny/tiny-engine-i18n-host${versionDelimiter}1${fileDelimiter}/dist/lowcode-design-i18n-host.es.js", + "@opentiny/tiny-engine-i18n-host": "${VITE_CDN_DOMAIN}/@opentiny/tiny-engine-i18n-host${versionDelimiter}^2${fileDelimiter}/dist/lowcode-design-i18n-host.es.js", "@opentiny/tiny-engine-builtin-component": "${VITE_CDN_DOMAIN}/@opentiny/tiny-engine-builtin-component${versionDelimiter}^2.0.0${fileDelimiter}/dist/index.mjs", "vue-demi": "${VITE_CDN_DOMAIN}/vue-demi${versionDelimiter}0.13.11${fileDelimiter}/lib/index.mjs", "pinia": "${VITE_CDN_DOMAIN}/pinia${versionDelimiter}2.0.22${fileDelimiter}/dist/pinia.esm-browser.js", From 806360dd884545ae99f8d7d5b381bd322e5ddfab Mon Sep 17 00:00:00 2001 From: ajaxzheng <894103554@qq.com> Date: Fri, 25 Jul 2025 11:31:15 +0800 Subject: [PATCH 006/101] feat(vite-plugin-meta-comments): optimize the processing of directly executing functions. If the function is directly called, only a synchronous ctx context is generated (#1489) --- .../src/transform.js | 24 ------- .../vite-plugin-meta-comments/src/utils.js | 68 ++++++++++++++++++- .../test/expected/entry.js.output.js | 11 ++- .../test/legacy/code/entry.js | 6 +- .../test/legacy/code/output.js | 11 ++- 5 files changed, 81 insertions(+), 39 deletions(-) diff --git a/packages/build/vite-plugin-meta-comments/src/transform.js b/packages/build/vite-plugin-meta-comments/src/transform.js index 8930ca670f..ef1d136755 100644 --- a/packages/build/vite-plugin-meta-comments/src/transform.js +++ b/packages/build/vite-plugin-meta-comments/src/transform.js @@ -201,33 +201,9 @@ export const transform = (code, id) => { plugins: ['typescript', 'jsx'] }) - const handleCallExpression = (state) => (path) => { - const callee = path.node.callee - const name = callee.name - if (name === state.varName[CALLENTRY]) { - return - } - if (name) { - const bindings = path.scope.bindings - // 判断调用的函数是否来自本文件中的函数表达式,且在同一个函数作用域内 - if ( - callee.type === 'Identifier' && - bindings?.[name] && - bindings?.[name]?.kind !== 'module' && - state.ArrowOrFunctionExpression.includes(name) - ) { - // eslint-disable-next-line no-console - console.warn( - `文件 ${state.fileId} 中函数 ${name} 在声明后直接调用了,可能造成函数覆盖场景报错!整改建议:1、导入后再调用。2、在文件最后调用` - ) - } - } - } - traverse(resultAst, { // 使用特定的类型回调处理、函数表达式、箭头函数、带导出的函数 'ArrowFunctionExpression|FunctionExpression': handleFunctionExpression(state), - CallExpression: handleCallExpression(state), ImportDeclaration: handleImportDeclaration(state), VariableDeclaration: handleVariableDeclaration(state), ExpressionStatement: handleExpressionStatement(state), diff --git a/packages/build/vite-plugin-meta-comments/src/utils.js b/packages/build/vite-plugin-meta-comments/src/utils.js index 7d82cfb0f6..2efcbe61f1 100644 --- a/packages/build/vite-plugin-meta-comments/src/utils.js +++ b/packages/build/vite-plugin-meta-comments/src/utils.js @@ -126,6 +126,56 @@ export const getModuleBindings = (path) => { return moduleBindings } +// 获取当前上下文已经可以使用的scope变量 +export const getValidBindings = ({ path, state, functionName }) => { + const validBindings = {} + const { varDeclartion } = state + let varArr = [] + let parentPath = path.parentPath + let block + while (parentPath) { + const newBlock = parentPath.scope.block + parentPath = parentPath.parentPath + if (newBlock === block) { + continue + } + block = newBlock + varArr = varArr.concat(varDeclartion.get(block)) + } + + const allBindings = path.scope.getAllBindings() + const selfBindings = path.scope.bindings + Object.keys(allBindings).forEach((key) => { + if (selfBindings[key]) { + return + } + const value = allBindings[key] + // 如果是变量定义,并且此时还没有初始化,则过滤掉 + if ((['var', 'const', 'let'].includes(value.kind) && !varArr.includes(key)) || key === functionName) { + return + } + validBindings[key] = value + }) + return validBindings +} + +// 获取当前作用域 body 和变量名 +function getCurrentScopeBodyAndVarId(path) { + // 处理变量声明的函数表达式 (例如: const foo = () => {} 或 const foo = function() {}) + if ( + path.parentPath && + path.parentPath.isVariableDeclarator() && // 检查是否为 const/let/var 的声明符 + path.parentPath.parentPath && + path.parentPath.parentPath.isVariableDeclaration() && // 检查是否为变量声明语句 + path.parentPath.parentPath.parent && + Array.isArray(path.parentPath.parentPath.parent.body) // 确保父节点有函数体数组 + ) { + return path.parentPath.parentPath.parent.body + } + + return null +} + /** * 生成callEntry表达式并包裹当前函数 * @param {Object} params - 参数对象 @@ -136,12 +186,28 @@ export const getModuleBindings = (path) => { */ export const wrapEntryFuncNode = ({ path, functionName = '', varName, state }) => { const asyncVars = getOuterBindings(path) + const body = getCurrentScopeBodyAndVarId(path, functionName) + + // 判断是否为"直接调用" + let isDirectlyCalled = false + if (body) { + isDirectlyCalled = body.some( + (node) => + node.type === 'ExpressionStatement' && + node.expression.type === 'CallExpression' && + node.expression.callee.type === 'Identifier' && + node.expression.callee.name === functionName + ) + } + + // 根据是否为直接调用,选择用 syncVars 还是 asyncVars 组装 ctx const entryParam = getEntryParam({ functionName, - asyncVars, + asyncVars: isDirectlyCalled ? getValidBindings({ path, state, functionName }) : asyncVars, // 直接调用用 syncVars,否则用 asyncVars varName, state }) + const callEntry = varName[CALLENTRY] const entryAst = statement(`${callEntry}(${entryParam})`)() const resultNode = path.node diff --git a/packages/build/vite-plugin-meta-comments/test/expected/entry.js.output.js b/packages/build/vite-plugin-meta-comments/test/expected/entry.js.output.js index ad7eb77822..35971e541e 100644 --- a/packages/build/vite-plugin-meta-comments/test/expected/entry.js.output.js +++ b/packages/build/vite-plugin-meta-comments/test/expected/entry.js.output.js @@ -34,8 +34,8 @@ export const useRenderless = _callEntry(({ aaa, bbb, handleClick, - ccc, sendMessage, + ccc, deepCopy, useRenderless }) @@ -54,8 +54,8 @@ export const useRenderless = _callEntry(({ aaa, bbb, handleClick, - ccc, sendMessage, + ccc, deepCopy, useRenderless }) @@ -80,13 +80,12 @@ export const useRenderless = _callEntry(({ aaa, bbb, handleClick, - ccc, sendMessage, + ccc, deepCopy, useRenderless }) }); - const ccc = 111; const sendMessage = _callEntry(() => { logMessage('自定义是的范德萨'); }, { @@ -101,12 +100,12 @@ export const useRenderless = _callEntry(({ aaa, bbb, handleClick, - ccc, - sendMessage, deepCopy, useRenderless }) }); + sendMessage(); + const ccc = 111; return { state, aa, diff --git a/packages/build/vite-plugin-meta-comments/test/legacy/code/entry.js b/packages/build/vite-plugin-meta-comments/test/legacy/code/entry.js index c96077be9c..c48d2e1e53 100644 --- a/packages/build/vite-plugin-meta-comments/test/legacy/code/entry.js +++ b/packages/build/vite-plugin-meta-comments/test/legacy/code/entry.js @@ -37,12 +37,14 @@ export const useRenderless = ({ props }) => { }) } - const ccc = 111 - const sendMessage = () => { logMessage('自定义是的范德萨') } + sendMessage() + + const ccc = 111 + return { state, aa, diff --git a/packages/build/vite-plugin-meta-comments/test/legacy/code/output.js b/packages/build/vite-plugin-meta-comments/test/legacy/code/output.js index 610fc7ca2c..1c6a900a8e 100644 --- a/packages/build/vite-plugin-meta-comments/test/legacy/code/output.js +++ b/packages/build/vite-plugin-meta-comments/test/legacy/code/output.js @@ -34,8 +34,8 @@ export const useRenderless = _callEntry( aaa, bbb, handleClick, - ccc, sendMessage, + ccc, deepCopy, useRenderless }) @@ -57,8 +57,8 @@ export const useRenderless = _callEntry( aaa, bbb, handleClick, - ccc, sendMessage, + ccc, deepCopy, useRenderless }) @@ -86,14 +86,13 @@ export const useRenderless = _callEntry( aaa, bbb, handleClick, - ccc, sendMessage, + ccc, deepCopy, useRenderless }) } ) - const ccc = 111 const sendMessage = _callEntry( () => { logMessage('自定义是的范德萨') @@ -110,13 +109,13 @@ export const useRenderless = _callEntry( aaa, bbb, handleClick, - ccc, - sendMessage, deepCopy, useRenderless }) } ) + sendMessage() + const ccc = 111 return { state, aa, From 29eae05c9444a9a3df23b9e77b35a3fbaeffc6a7 Mon Sep 17 00:00:00 2001 From: chilingling <26962197+chilingling@users.noreply.github.com> Date: Fri, 25 Jul 2025 11:32:26 +0800 Subject: [PATCH 007/101] feat: upgrade vue-repl (#1459) --- package.json | 2 +- .../build/vite-config/src/default-config.js | 14 +--- packages/design-core/package.json | 4 +- .../src/preview/src/preview/Preview.vue | 34 ++++++---- .../src/preview/src/preview/usePreviewData.ts | 46 ++----------- patches/@vue__repl@2.9.0.patch | 50 -------------- patches/@vue__repl@4.6.1.patch | 65 +++++++++++++++++++ pnpm-workspace.yaml | 9 +-- 8 files changed, 104 insertions(+), 120 deletions(-) delete mode 100644 patches/@vue__repl@2.9.0.patch create mode 100644 patches/@vue__repl@4.6.1.patch diff --git a/package.json b/package.json index 290df88e42..49b9ce1e7c 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ }, "pnpm": { "patchedDependencies": { - "@vue/repl@2.9.0": "patches/@vue__repl@2.9.0.patch" + "@vue/repl@4.6.1": "patches/@vue__repl@4.6.1.patch" }, "overrides": { "rollup": "~4.44.0" diff --git a/packages/build/vite-config/src/default-config.js b/packages/build/vite-config/src/default-config.js index 0c53dcedf4..4c3697682f 100644 --- a/packages/build/vite-config/src/default-config.js +++ b/packages/build/vite-config/src/default-config.js @@ -6,7 +6,6 @@ import vueJsx from '@vitejs/plugin-vue-jsx' import nodeGlobalsPolyfillPluginCjs from '@esbuild-plugins/node-globals-polyfill' import nodeModulesPolyfillPluginCjs from '@esbuild-plugins/node-modules-polyfill' import nodePolyfill from 'rollup-plugin-polyfill-node' -import esbuildCopy from 'esbuild-plugin-copy' import { createSvgIconsPlugin } from 'vite-plugin-svg-icons' import visualizerCjs from 'rollup-plugin-visualizer' import generateComment from '@opentiny/tiny-engine-vite-plugin-meta-comments' @@ -78,22 +77,15 @@ const getDefaultConfig = (engineConfig) => { vueJsx() ], optimizeDeps: { + // 避免 @vue/repl 的 monaco-editor 等依赖被优化掉 + exclude: ['@vue/repl'], esbuildOptions: { plugins: [ nodeGlobalsPolyfillPlugin({ process: true, buffer: true }), - nodeModulesPolyfillPlugin(), - esbuildCopy({ - //@vue/repl monaco编辑器需要 - resolveFrom: 'cwd', - assets: { - from: ['./node_modules/@vue/repl/dist/assets/*'], // worker.js文件以url形式引用不会被esbuild拉起,需要手动复制 - to: ['./node_modules/.vite/assets'] // 开发态,js文件被缓存在.vite/deps,请求相对路径为.vite/assets - }, - watch: true - }) + nodeModulesPolyfillPlugin() ] } }, diff --git a/packages/design-core/package.json b/packages/design-core/package.json index e031982a4d..bbbae2ac43 100644 --- a/packages/design-core/package.json +++ b/packages/design-core/package.json @@ -86,8 +86,7 @@ "@opentiny/tiny-engine-toolbar-view-setting": "workspace:*", "@opentiny/tiny-engine-utils": "workspace:*", "@opentiny/tiny-engine-vite-plugin-meta-comments": "workspace:*", - "@vue/babel-plugin-jsx": "^1.2.5", - "@vue/repl": "^2.9.0", + "@vue/repl": "4.6.1", "@vueuse/core": "^9.6.0", "element-resize-detector": "^1.2.4", "eslint-linter-browserify": "8.57.0", @@ -101,7 +100,6 @@ "devDependencies": { "@esbuild-plugins/node-globals-polyfill": "^0.2.3", "@esbuild-plugins/node-modules-polyfill": "^0.2.2", - "@types/babel__core": "^7.20.5", "@types/node": "^18.0.0", "@vitejs/plugin-vue": "^5.1.2", "@vitejs/plugin-vue-jsx": "^4.0.1", diff --git a/packages/design-core/src/preview/src/preview/Preview.vue b/packages/design-core/src/preview/src/preview/Preview.vue index 435fa8ba4c..74e89caa0c 100644 --- a/packages/design-core/src/preview/src/preview/Preview.vue +++ b/packages/design-core/src/preview/src/preview/Preview.vue @@ -3,7 +3,6 @@ ' - } - - const transformedScript = transformSync(p1, { - babelrc: false, - plugins: [[vueJsx, { pragma: 'h' }]], - sourceMaps: false, - configFile: false - }) - - const res = `' - - return `${res}${endTag}` - }) - - newFiles[panelName] = newPanelValue + newFiles[panelName] = panelValue } // 根据新的参数更新预览 @@ -378,7 +344,7 @@ export const usePreviewData = ({ setFiles, store }: IUsePreviewData) => { // importMap 发生变化才更新 importMap if (JSON.stringify(previewState.importMap) !== JSON.stringify(importMapData)) { - store.setImportMap(importMapData) + setImportMap(importMapData) previewState.importMap = importMapData } @@ -417,12 +383,12 @@ export const usePreviewData = ({ setFiles, store }: IUsePreviewData) => { newFiles['app.js'] = appJsCode - pageCode.map(fixScriptLang).forEach((item) => assignFiles(item, newFiles)) + pageCode.forEach((item) => assignFiles(item, newFiles)) const metaFiles = generateMetaFiles(metaData) Object.assign(newFiles, metaFiles) - setFiles(newFiles) + setFiles(newFiles, 'App.vue') } const loadInitialData = async () => { diff --git a/patches/@vue__repl@2.9.0.patch b/patches/@vue__repl@2.9.0.patch deleted file mode 100644 index 86303479e1..0000000000 --- a/patches/@vue__repl@2.9.0.patch +++ /dev/null @@ -1,50 +0,0 @@ -diff --git a/dist/chunks/MonacoEditor-KSgTEMrh.js b/dist/chunks/MonacoEditor-KSgTEMrh.js -index c9668cbf8c44ba3c816246b746127204839f8349..e893c59a432e53372c18aa2e70d7b7bb9fd666ba 100644 ---- a/dist/chunks/MonacoEditor-KSgTEMrh.js -+++ b/dist/chunks/MonacoEditor-KSgTEMrh.js -@@ -1,5 +1,13 @@ - import { watchEffect, defineComponent, ref, shallowRef, inject, computed, onMounted, nextTick, watch, onBeforeUnmount, openBlock, createElementBlock, createBlock } from 'vue'; - import { c as commonjsGlobal, a as getAugmentedNamespace } from './_commonjsHelpers-9Q-OoQuc.js'; -+function getWorkerURL(url){ -+ if (typeof document !== 'undefined' && document.location && document.location.origin !== url.origin) { -+ return URL.createObjectURL(new Blob([`import '${url.href}'`], { -+ type: 'application/javascript' -+ })) -+ } -+ return url.href; -+} - - /*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. -@@ -170640,7 +170648,7 @@ var languages; - - function WorkerWrapper$1(options) { - return new Worker( -- ""+new URL('../assets/editor.worker-FXpxnIqv.js', import.meta.url).href+"", -+ ""+getWorkerURL(new URL('../assets/editor.worker-FXpxnIqv.js', import.meta.url))+"", - { - type: "module", - name: options?.name -@@ -172020,7 +172028,7 @@ function getOrCreateModel(uri, lang, value) { - - function WorkerWrapper(options) { - return new Worker( -- ""+new URL('../assets/vue.worker-eqEbSb3e.js', import.meta.url).href+"", -+ ""+getWorkerURL(new URL('../assets/vue.worker-eqEbSb3e.js', import.meta.url))+"", - { - type: "module", - name: options?.name -diff --git a/dist/vue-repl.js b/dist/vue-repl.js -index 43bfd22a1a7d6f831e3f85228d809750317c4bfb..d5f5cb335533295c63e4cfa8aaa02770d16babca 100644 ---- a/dist/vue-repl.js -+++ b/dist/vue-repl.js -@@ -528,7 +528,8 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({ - "allow-popups", - "allow-same-origin", - "allow-scripts", -- "allow-top-navigation-by-user-activation" -+ "allow-top-navigation-by-user-activation", -+ "allow-downloads" - ].join(" ") - ); - const importMap = store.getImportMap(); \ No newline at end of file diff --git a/patches/@vue__repl@4.6.1.patch b/patches/@vue__repl@4.6.1.patch new file mode 100644 index 0000000000..7aacd6164a --- /dev/null +++ b/patches/@vue__repl@4.6.1.patch @@ -0,0 +1,65 @@ +diff --git a/dist/monaco-editor.js b/dist/monaco-editor.js +index 5132a3752a80f6bbeb67e7e8d1aff65cdc97ae02..9e67e62c44419aeb752966de75afe11b967597b4 100644 +--- a/dist/monaco-editor.js ++++ b/dist/monaco-editor.js +@@ -3,6 +3,15 @@ import { watchEffect, defineComponent, useTemplateRef, shallowRef, inject, compu + import { d as debounce } from './chunks/utils-BJf_b1Uq.js'; + import { a as injectKeyProps } from './chunks/types-XqLqBVey.js'; + ++function getWorkerURL(url){ ++ if (typeof document !== 'undefined' && document.location && document.location.origin !== url.origin) { ++ return URL.createObjectURL(new Blob([`import '${url.href}'`], { ++ type: 'application/javascript' ++ })) ++ } ++ return url.href; ++} ++ + /*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. +@@ -73583,12 +73592,6 @@ function fuzzyScoreGracefulAggressive(pattern, lowPattern, patternPos, word, low + } + function fuzzyScoreWithPermutations(pattern, lowPattern, patternPos, word, lowWord, wordPos, aggressive, options) { + let top = fuzzyScore(pattern, lowPattern, patternPos, word, lowWord, wordPos, options); +- if (top && false) { +- // when using the original pattern yield a result we` +- // return it unless we are aggressive and try to find +- // a better alignment, e.g. `cno` -> `^co^ns^ole` or `^c^o^nsole`. +- return top; +- } + if (pattern.length >= 3) { + // When the pattern is long enough then try a few (max 7) + // permutations of the pattern to find a better match. The +@@ -178015,7 +178018,7 @@ async function registerProviders(worker, language, getSyncUris, languages) { + + function WorkerWrapper$1(options) { + return new Worker( +- ""+new URL('assets/editor.worker-KaUq7_iC.js', import.meta.url).href+"", ++ ""+getWorkerURL(new URL('assets/editor.worker-KaUq7_iC.js', import.meta.url))+"", + { + type: "module", + name: options?.name +@@ -178034,7 +178037,7 @@ function getOrCreateModel(uri, lang, value) { + + function WorkerWrapper(options) { + return new Worker( +- ""+new URL('assets/vue.worker-Dc6PZdLj.js', import.meta.url).href+"", ++ ""+getWorkerURL(new URL('assets/vue.worker-Dc6PZdLj.js', import.meta.url))+"", + { + type: "module", + name: options?.name +diff --git a/dist/vue-repl.js b/dist/vue-repl.js +index cfb74a062a5661ba5a8105825714c8eb464cbf70..91b4747b22b96899c96612b909dc662d87b890e6 100644 +--- a/dist/vue-repl.js ++++ b/dist/vue-repl.js +@@ -551,7 +551,8 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({ + "allow-popups", + "allow-same-origin", + "allow-scripts", +- "allow-top-navigation-by-user-activation" ++ "allow-top-navigation-by-user-activation", ++ "allow-downloads" + ].join(" ") + ); + const importMap = store.value.getImportMap(); diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 85cf00f469..011288d389 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,7 +1,8 @@ packages: - - 'packages/**' - - 'mockServer' - - 'designer-demo' - # 忽略测试文件夹中的 project、脚手架模板 + - packages/** + - mockServer + - designer-demo - '!packages/**/test/**' - '!packages/**/template/**' +patchedDependencies: + '@vue/repl@4.6.1': patches/@vue__repl@4.6.1.patch From ffa37d7edeb9c5b761760bd823e51a9df2432874 Mon Sep 17 00:00:00 2001 From: lu-yg <128358973+lu-yg@users.noreply.github.com> Date: Thu, 24 Jul 2025 23:30:32 -0700 Subject: [PATCH 008/101] feat: Add material upload script (#1516) --- .env.local | 4 +- docs/api/backend-api/material-center.md | 51 ++++++++++++++++++ docs/solutions/imgs/bundle_upload.png | Bin 0 -> 40022 bytes docs/solutions/imgs/component_create_code.png | Bin 0 -> 164055 bytes docs/solutions/material-sync-solution.md | 23 ++++++-- package.json | 3 +- scripts/uploadMaterials.mjs | 40 ++++++++++++++ 7 files changed, 115 insertions(+), 6 deletions(-) create mode 100644 docs/solutions/imgs/bundle_upload.png create mode 100644 docs/solutions/imgs/component_create_code.png create mode 100644 scripts/uploadMaterials.mjs diff --git a/.env.local b/.env.local index a361a78c8f..93b036e1e4 100644 --- a/.env.local +++ b/.env.local @@ -2,4 +2,6 @@ SQL_HOST=localhost SQL_PORT=3306 SQL_USER=root SQL_PASSWORD=admin -SQL_DATABASE=tiny_engine \ No newline at end of file +SQL_DATABASE=tiny_engine + +backend_url=http://localhost:9090/material-center/api/component/bundle/create \ No newline at end of file diff --git a/docs/api/backend-api/material-center.md b/docs/api/backend-api/material-center.md index 52c0049a22..222bd09b46 100644 --- a/docs/api/backend-api/material-center.md +++ b/docs/api/backend-api/material-center.md @@ -327,3 +327,54 @@ tenant 通过前端配置统一 x-lowcode-org 请求头传递,接口中不用 +## 物料同步接口 + + + +### 基本信息 + +**Path:** /material-center/api/component/bundle/create + +**Method:** POST + +**接口描述:** + +

处理物料同步上传bundle.json文件创建或更新组件

+ + +### 请求参数 + +**Headers** + +| 参数名称 | 参数值 | 是否必须 | 示例 | 备注 | +| ------------ | ---------------- | -------- | ---- | ---- | +| Content-Type | multipart/form-data | 是 | | | + +**路径参数** + +| 参数名称 | 示例 | 备注 | +| -------- | ---- | ------ | +| file | bundle.json | bundle.json文件 | + +**Body** + + + + + + + + +
名称类型是否必须默认值备注其他信息
+ + +### 返回数据 + + + + + + + + +
名称类型是否必须默认值备注其他信息
dataobject非必须
├─ insertNumnumber非必须新增组件数
├─ updateNumnumber非必须更新组件数
\ No newline at end of file diff --git a/docs/solutions/imgs/bundle_upload.png b/docs/solutions/imgs/bundle_upload.png new file mode 100644 index 0000000000000000000000000000000000000000..886b3472d23d731333fc3ed378b037db443bd7f9 GIT binary patch literal 40022 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

#w$SZcjx`r* zCjgnIU;oshtD1g(%flwDON@Qj_P6)rXj!lup0f0&&IYPXUu-}*e>iy?sWO=iJ>4?o7)8e)q+al7#-CZ=`gB#m^I^fxn()d&b-g>hdsM$ zX3`>U9G~^{)IiH}Y`m?&!183RdX^nqx||>rzbC)&{7ln=I?ULv%G4tCVNLX+8<$-y zOBmh-MRIs#!Umn=2%uT;6oWE;V@}kQ(x+_3S7T4)F6PCwXTHbV+NO?|!&@ncQ?S)% zXgjm_V{jhQbYC_!{;|84)T7P{j!9sWf% z+;Ep>PF+88gZ@ptqF`GY=ozKq1~+D?wBM{|sIYq;$xv^6!;O3`q^7?IQ8-^?hQo8K~UrBbLQnG_zfQ zbV4b4ZL;`oDT?43va9C)%S57-F=S57C7Cdo1HG>>Nvii667}P$&uVptn z&}N@aB3+e!>Qbw8qdJIZ&#RC?b#8O-G<)Y%YS)V5J&mSlA{5>wTq5}n);4*xY#mxI z6=7%&Wb|U1;dH06v~Z!^K`C&JZJ%@M_p^h87x_gs!f@LaP0Y;R$f_EM$?_-Hjo(^+ zQH7CLMu-?`D+x{QEKhmWGa-VSHjVelP06YoorEA#%`6S)L0%U*8L(C}Qxmv-NY;jN zBDAT=Byc|)igbzs{Aa}InUl!Lj+N$X0m*vQ-#>cIXkBVY+2&C8&^OyPw>=1oscCJ$ zF`i{FfC6=R<@d=7TtFXjiYaSjYJip}c`Lh7pi$}gSvycVE{GfNsXjSWXVe%pST?ml zFezK06@d7JEf-&YA$tp-dlp zE5Hm2d!jyQFLK|Ut!@JZF=3w^C=eg&*N|Go3P5>K1yW9CRrGy=v*kWJSOD590r>} zhSr_-$BQ`?no`XnhHDliGo>vdRc0^3kI~1#^v;QDm(#q;y^1pxt{vIBVCHHzAG*4p zPZM@FDEY24`8&w%*8LjooT|)&*<7=D3WTGUMgA*U`xajaRfho&e4!kUl6JPX!+D;^ z1w~4ox1f4#QL*zRb~6g5ACv07xc+Jx+!2jWYZuA{M=$nne{xKlLzwh5#EXs=b`%uoaZzURU_^1B-G?(}H@bFG` zM3|vgO@vv!m)PxY=Y%s}^g#`c))folngMiIYtsE|*AvlZsOJHOm4QG6PsW!6h5e2X zBge`a9snQhoGMSE`p)E0~W&&!+GCfqgTBT#<&#Of8lgvl3{?PP|;4o$vH7yDieP2nJO8k*r6zXf=VNE0PuB_A&VE+dF8B?;-u^jSZ<>_2LWy4_G zwuTxw>3JH!7ct<0mT2MW&7;|dhGOnHpqffBGS8*U;gPqw+DPq{3I8L#6jxZR7S5L)c=&4Qpm`#5q$-4aCIkh#2}HH+MC<9~{A2O3QMv zHiJII`jvKRkQ)ifJASUDwN@R1O^yaI1fz8I0)G5(;fYO z$vKWU=!>#>(@NHk(UUKaQ(LuwRo*#5w2u0Httk-CCb{p(L-vlFMm{LcWa z>U{vl$8c{L_}_ndmYnkY{hX~M1=Khm^pcZpH?pMqMmemXwJDHqbL(zy(FOPptFogk zr|OJ`c}$wSai*hg^cD1IZ|7_O+_T_5N|T!QxzfV==#8zcsU{U6VtHrOapc?8r53Nv zWNhKdo)7cD7{PY@=%mUULNxEF_5?1^!%KNq#Pz1VW5@x}Z8TYzGM%~m6ZdRL+0ie{ zX%wx#QPAVYIH$9dC{f&~I4mCIlY83q7BCZCNEqH>q2F&tOHvoYeGSbq@5LObTJseC zlkJUP`iXE`H3MDGwr$gAyK9Octsa!6+)QN+v7Gk21kED6971Qx#Vo(@`V~^bisW~n zWd6`wxtarN%Eaz%en${Inlxodc}GybJ7Hi1#I=p(!g`iK|iuF@UW!a2FET7fcg<2i* zeKZhYPAsoYh6o$d<+~T&gb5;C8`0zy(ETWgqQ8nEJT#8PISS9Rv1KOsO460kDG>0c z{R*}ApHv(b&vBe2U2*`cgdWnD=$Zn<-=LlkvBZV941;c=;cAn=9l+p>)V^?gQeDJ> zmUs%Z88n>L@@;SYS`~c^83^DZFG>d!pQci(P4B+PybDfV**W(|eHeFq zPKmcng#f#I>T($V7KaW`_1=t@71%^d88H`8|I}y_HX_Oa=A7C2cG}~tAnLbD_Sq}g z7ly&Om$#K-OdB{xFY>s1Ok)XX6~s@?vt~^@cRS=F@I=?oGlTc5hO-*fDPsa@aPzCc za`e+R>Lv6u=bo;W034Gg@Tcs71O51A^l?|C*7orJ!6^fD^FN5fe|h--!9e}7X1cHb zg@nC|ItNBYExn&<4{86lyV||?aqipJAnHZ#&9^SKHp6VdH0b(E6iwG(C8QU=3n9L_ zy~mJLkhz_Ls4)4P1P&LGInO)wM>dAX;2;&^{HXe7>m(o@hKu_JTty9v)=~04dUHK% zz-Y~2ezf5;!1e@rYG%qS+aV+Ch3N9pnu@Z|k;3ZSaUK=e9<-@F(*%3GxAHlc>zMBJ zQnp;sPt**AwdccSV2G#Ar@>v|gn3?`*lScf01o?9?pSm?z;(dPAJ@$y(f*m0{S@^5 zkXSlgrbWCB4I}2x$pWpr=4oj!Ff$?9QZeQsr1#vmk$T?dRFV(LG7|sP4v(U+)>EvM zqk_I3Z?NH6B3!o${N0EFIITM!YA|xhN^~{g!d<#@4EcP)rNu&55Pb(+*AM@cA>lTs zlFJ%icgiuOkn@6vSTgHAOnleOSi|vY0Bk7b1zygO7d!!l;x&3mM+xNw6yJp3XwWC( zm2~C;x(;cIv&C_{VUEf7_5G0)Nq`WD!Ppegx8m>GcZ*h$`eArg=CIG@Nrv+kqI{~* zg*B#ur*>#|uW7L}7m$V%uwQdMCBg3> zo;V8X8I{Q6u#)VHzC)V&N@0e``#DvYV1}o`Z!J6=k%$!W&YY^?#%P>b&12eAU>Xm& za;i?Cfmgi*Bi>kGMsA8Xwb%ztgdQ21JCaw}209N8B~7PkD{LUs$V3twaagPx!R}JYtWgxhlaVc*h*4a6DDhU z9OMuMLuS*&sI>C~s2^-)awC3S$T?Nby2W&AbzA*?T$+SQTR#TQeKX~I>h{MwFLjB3 z;X+8}bg`&XqZ3M0ezJ8Rsg_+v@{jFqmJe^xg}rQ3!nA?zzkT}|()5q_ z_~yU0_6In$|9I^`r-tLhPpgy9$2z(jYL9<}T&U!*rD?cZx13BE$fl+QQGGY(5CnsV zO(IRdJ~OU4Sz$LmD?Q5cJ5ooW`%t=4%8r5uj$hlXhB^PO=b3P6Wkki%98hG}l%3>r z3RjABpZxmzWNr2Q?1$Yu9KG$*9@FE&4u5cMRe))q{tN##9K@D`yIP~T*6Kc0sO3IY zE&)ygT}Kn=mo0g2uN_(oS^st)cf17E>Db#WC0k8kg}=0CKk$lm<$+y&yE>j1Ia_yP z%}^}YSBn&)xm2r`S=S~e+?!g&v-hHJsYY#d+F<2m7~YXzesxXuP}PaWfJ%GzoT?9- zjQfafWvBayQdYRo2OiZ^J`-ulP(V0_0 zG3IpL9Khu^+`L(qDH*Q(3@1|LW^uE^Dz4-^s{gw zv>)6Vewy6?nPgama0AX)9w)dJGcVpQHIF4F4fEWxB&dkPFv!wILle0?qUVTEsQ z!kwRM(M>KOYygu6109U`>XnV%!|86o=%$4o9AAKn15hO-)%c`|s6jKzN1~%B{Vz*_CKl$`=azh?ht(DD5(Pv`Ak5>IRr<{ymfc-1a6;BLVufmF; zN=D_YX}+?B9IhW#EN@)mV175bhB%&3U?HJdXK&&ElP_P#`P3RpQDO>4P4xw$Yz8}V zU{n71xJ;dvzT&5}iGVgXesT=ia>iPTGaWCQS^mPZU<5t6R&byePcZ^}V_=8fAI|0K zpG=74C%B1YH`+%Hk$WD&q=ND<8oDNgq*~)wpqhst#*$HI70ChWg zJf`u*%Nu46>1RdWMy-XwuWexL3h+hrjR)+M#+vfe8|RKjR(&t$xL6$?B`SqAblIGp zqsLizz;%5FXimC(M-au{ZbJ5)zYSZjEay*ag15=#Crx48EuG>W2WR6KBr|jho-<; z($Gn{9bds>gBvHK5uRYmisV>< zrCUuqfXqUcZdF1}O{%CI;HqcRigH0-pB+x)1o`f0M0r3&m3kXbC&xi zKHM!hoX2q|;O3-^zi+`FmDfL{6+GfmkWX`t)1sErBfU$10m+dooZ!5#-YkfmEX1w! zJMlb+v286u&Motw3V$V}8M1MvHI2@<(mh`)%O-uT&mZJgx_;Gs!U)O{Dvo~38DI_l z!s|F2p@7KH7Tqwbcz!PV?*bb2@IQ(b{~J0aeHprDcI{ zTM^&(gI^yDH;g%s+UqCY{BhupF_d1&sY(dHS+_rMv!e}wisS(4A+sZ&0P5&7v;XW| zOh}jVN*zD2`gT|UNq8A^pbrYWbrl}2r5f^_p~Tv1%D%wgT@F*F__AMtu26Xq74tOz zY0vWYq*%6;&0lbtm)~USm1r<`>&wy^fo3V_r7?r&z{N3qank?(mZtZlYoi0cor~6R zQBp!_pSad&$@I4;%3`Xd2nw|~UxMBOOe8JCF1{>|6T>e(BL!%tEs|{+ii@TZxuJ`D zW?PAX#e%h_28x%=^+e7by_G|i9<@j$3};JxILJf=OQ``FCw`y>s1U)AD6w~GF#^Bh zs4;;bdAc$T*r9p%iTJfoAx^C`VDPf#fyq1t)MK7m*ZL45ZIKE%RdGW5)mI+dzGho-)dQ;*uDWQLNw#hRKK%EK25WfcInGaNkU1L2kaF zvLbNI5I=nOb`NwMQj#9N&s6M zF$j_Yl*O=U0vOp07DY-30uP%KYGg?vid2jgnnLf3j$>y!<1qdI<-R5F-1Gasd)~P> zGiUF<5^Z~>sY%*9>UT_&H_JUCiKeDmHeZ{oq$w^rd4Yit5*U$q{I#6Xh7~^q!vXq8 zM?MO2V)cx>CIdbO%&Q-^E8a)a(dGo%S@$n{m2YP%l#~q|<_Nt-HF8sk0k{C;2 z%9RlVpOsJjQH86x5GL;I_kH_Yu5zUZ&FL}8m%c$r48%%~;QE`6eSqka7o zTQ3i2bf7I#QR1p(`8kf52qNbS>5A_&{I|@xSdBj90s5?3DNu#c#51pp+APzrVP9av z9Am^(pVrBo1jE^W-rJYC0x%Torz4r;2lQh|7}F9B3hck*v}RpH&ctn7!ClWnB&e+>i^jx8zjim` z;`-`HU+JD|c+YC$uEF*~yQscr7O{;N&#`4GnPBS#aeW}wj6F-ZK4rcaZ%RxUYJ#vr z>8kGZLZ`0u4sY1`j*VqOr+%j0XpIRm5C0pG6*XXXEhsy>~( zx#8Iv5=j>Y{$%`c3<*CY%*G0gs=tj7Jxv2)K(Yg2;5Z*}9}Mcb5BPB)2pn+|@h-J0 z&GuGuo(|aDH^T*do^LeTalsuC4V`PR`0=t1xIj=aKja7hpP={;ih{FUmbgxq^5=|_ z5y;V?iD=jr2I2tLZSd(}r zJ`eBZYMU72+`YiZ!}Dp2gQ{_iJSg1wqPyxu^Va*X<-PO{AVi{Xc>Kw5L-h*2G+ zGkNct5`pT~bIB6hUSccG9biKYL?tPNnt6aTD{7zE?_R+rZb}Ue`;NlIuOWtM8t1ty z1mz)A-DPIVrueDUc+d`V9uXWz)_{_lS1J7^`I@foWYq2j7g~@n+1Nn(5`5F)19R0` z84taVh>>s#vICWrwk5GF+^)ya53_v&7h8g?+mpjxuSzs*V3JExsa=|`(9Dz znpPjFlmQKNT)`AT!EU5j7(m($>Xcy7UGEAI5mp)UPNOQT-l5T+1jK8i#hY znif#{25gIcvBGFVvO+wZRXMg`^I-m#_0A{6QHj{}(xK;^f>SsOFM?5_Y2H15Qi3kq zV<$zYecY{`Kt+y;4C0c(sXPbz9<5(}VcG(|2Sf~Oc~axT{_<>??h%hGK)T^~Ob(hK zMXu0g@P94Jyj?bPTBFOBh-Iv&RfUiTk)THOUGJDJ*=#NWKIMnoRe7J+E`8)5c#EfC R4GqIT@%=Kuy9O7|_y>*^+4led literal 0 HcmV?d00001 diff --git a/docs/solutions/imgs/component_create_code.png b/docs/solutions/imgs/component_create_code.png new file mode 100644 index 0000000000000000000000000000000000000000..d78665185e1f701ebc06bf39ebede573e4fd31d2 GIT binary patch literal 164055 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�%sv<4GDb-pwB0Hcfsvt06@5;hqW4N+$b!1y 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 literal 0 HcmV?d00001 diff --git a/docs/solutions/material-sync-solution.md b/docs/solutions/material-sync-solution.md index 3a7cda1cc4..2e1343eb15 100644 --- a/docs/solutions/material-sync-solution.md +++ b/docs/solutions/material-sync-solution.md @@ -1,10 +1,24 @@ ## 物料同步方案 +### 方案一 (推荐使用) +通过前端脚本上传编辑好的bundle.json文件。 +```shell +pnpm uploadMaterials +``` + +#### 注意事项 +1. bundle.json文件内组件版本version字段为必须字段,缺少的需要补充不然上传接口报错 +2. bundle.json文件内组件版本version与数据库t_component内version不一致时为新增,一致为更新,也可根据自身需求更改相关代码逻辑 +3. .env.local中配置访问后端接口的路径,默认java后端路径 + +![注意事项图](./imgs/component_create_code.png '注意事项图') + +### 方案二 由于当前情况下物料无法通过页面交互维护,提供一个临时方案,由前端托管物料。 在本地运行时提供nodejs脚本维护物料,执行脚本保证mockServer工程和前端工程物料的同步。如果启动了后端服务,还可以连接数据库,保证本地json文件和数据库的一致性。 ![物料同步数据流转图](./imgs/synchronize-materials.png '物料同步数据流转图') -### 拆分脚本 +#### 拆分脚本 ```shell pnpm splitMaterials @@ -13,7 +27,7 @@ pnpm splitMaterials 之前对物料的修改要先从大文件bundle.json中找到对应组件,然后进行修改调试,很容易出现找错组件或难以对比历史的情况。 执行该脚本可以将物料资产包拆分为单个组件或区块,再结合构建的脚本,可以将修改限制在相对较小的文件中,便于维护物料和对比变更。 -### 构建脚本 +#### 构建脚本 ```shell pnpm buildMaterials @@ -26,14 +40,15 @@ pnpm buildMaterials - 连接数据库,初始化组件表,将组件数据写入数据库 - 监听组件文件变化,重新构建物料资产包和应用 mock 数据,新增或更新数据库中组件数据 -### 注意事项 +#### 注意事项 1. 本地还没有执行过拆分脚本的,先执行一次,后续可以不用再执行,只需要对单个组件进行维护 2. 单个组件文件需要遵循物料协议,更新文件后保存即可触发重新构建物料资产包,刷新页面后生效 3. 连接数据库失败,不影响构建本地物料资产包即bundle.json 4. 连接数据库需要的配置项在`.env.local`中 +5. 数据关联关系可能没有入库,如果查询不到新添加的组件,需要手动在数据库表r_material_component、r_material_history_component添加关联关系数据 -### 部署建议 +#### 部署建议 需要将设计器进行部署时,关于物料的部署方案,以下供参考: diff --git a/package.json b/package.json index 49b9ce1e7c..5e101abe25 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,8 @@ "setup": "node ./scripts/setup.js", "splitMaterials": "node ./scripts/splitMaterials.mjs", "buildMaterials": "node ./scripts/buildMaterials.mjs", - "updateTemplate": "node ./scripts/updateTemplate.mjs" + "updateTemplate": "node ./scripts/updateTemplate.mjs", + "uploadMaterials": "node scripts/uploadMaterials.mjs" }, "devDependencies": { "@eslint/js": "^8.57.1", diff --git a/scripts/uploadMaterials.mjs b/scripts/uploadMaterials.mjs new file mode 100644 index 0000000000..9435f87e1d --- /dev/null +++ b/scripts/uploadMaterials.mjs @@ -0,0 +1,40 @@ +import { Buffer } from 'buffer' +import dotenv from 'dotenv' +import fs from 'fs-extra' +import path from 'node:path' +import Logger from './logger.mjs' + +const logger = new Logger('uploadMaterials') + +// 先构造出.env*文件的绝对路径 +const appDirectory = fs.realpathSync(process.cwd()) +const resolveApp = (relativePath) => path.resolve(appDirectory, relativePath) +const pathsDotenv = resolveApp('.env') +dotenv.config({ path: `${pathsDotenv}.local` }) +const { backend_url } = process.env + +const bundlePath = path.join(process.cwd(), '/designer-demo/public/mock/bundle.json') +const bundle = fs.readJSONSync(bundlePath) +const jsonBuffer = Buffer.from(JSON.stringify(bundle)) +const boundary = '----WebKitFormBoundary7MA4YWxkTrZu0gW' +const formHeaders = { + 'Content-Type': `multipart/form-data; boundary=${boundary}`, +} + +let body = `--${boundary}\r\n` +body += 'Content-Disposition: form-data; name="file"; filename="bundle.json"\r\n' +body += 'Content-Type: application/json\r\n\r\n' +body += jsonBuffer.toString() + `\r\n--${boundary}--` + +fetch(backend_url, { + method: 'POST', + headers: formHeaders, + body: body, +}) + .then(response => response.json()) + .then(data => { + logger.success('File uploaded successfully:', data) + }) + .catch(error => { + logger.error('Error uploading file:', error) + }) From 2359c09c46c555dcf2c08763b7985fb561befb7d Mon Sep 17 00:00:00 2001 From: Hexqi Date: Mon, 28 Jul 2025 21:18:03 +0800 Subject: [PATCH 009/101] chore: add breaking change tags base on template (#1562) * chore: add breaking change tags base on template --- .github/auto-labeler.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/auto-labeler.yml b/.github/auto-labeler.yml index 47770e6244..e0ef8c69a2 100644 --- a/.github/auto-labeler.yml +++ b/.github/auto-labeler.yml @@ -10,7 +10,7 @@ labels: sync: true matcher: title: '^.+!:|#breaking' - body: '#breaking' + body: '## Does this PR introduce a breaking change\?\s+- \[[xX]\] *Yes' - label: 'enhancement' sync: true matcher: From 54e0b6206d06ab19dc0f91cdacaf040504dada58 Mon Sep 17 00:00:00 2001 From: Hexqi Date: Tue, 29 Jul 2025 12:01:02 +0800 Subject: [PATCH 010/101] feat(ai-roobt): renew robot ui and add mcp calltool (#1561) * feat: replace ui with tiny-robot * feat: add mcp * feat: add option customCompatibleAIModels * feat: upgrade tinyrobot version and fix ui issue * docs: add ai assistant docs --- .../imgs/ai-assistant-enable-mcp-tools.png | Bin 0 -> 65320 bytes .../imgs/ai-assistant-fullscreen.png | Bin 0 -> 41447 bytes .../imgs/ai-assistant-interface.png | Bin 0 -> 35336 bytes .../ai-assistant-mcp-tools-management.png | Bin 0 -> 20792 bytes .../imgs/ai-assistant-open.png | Bin 0 -> 1662 bytes .../imgs/ai-assistant-prompts.png | Bin 0 -> 20133 bytes .../imgs/ai-assistant-settings.png | Bin 0 -> 8602 bytes .../imgs/ai-assistant-tool-execution1.png | Bin 0 -> 24602 bytes .../imgs/ai-assistant-tool-execution2.png | Bin 0 -> 33806 bytes docs/advanced-features/new-ai-plugin-usage.md | 225 ++++++++ docs/catalog.json | 1 + packages/plugins/robot/index.ts | 1 + packages/plugins/robot/package.json | 9 +- packages/plugins/robot/src/Main.vue | 522 +++++++----------- .../plugins/robot/src/RobotSettingPopover.vue | 3 +- packages/plugins/robot/src/js/robotSetting.ts | 14 +- .../robot/src/mcp/MarkdownRenderer.vue | 58 ++ packages/plugins/robot/src/mcp/McpServer.vue | 179 ++++++ packages/plugins/robot/src/mcp/types.ts | 87 +++ packages/plugins/robot/src/mcp/useMcp.ts | 185 +++++++ packages/plugins/robot/src/mcp/utils.ts | 113 ++++ packages/register/src/constants.ts | 3 +- packages/register/src/service.ts | 2 +- 23 files changed, 1077 insertions(+), 325 deletions(-) create mode 100644 docs/advanced-features/imgs/ai-assistant-enable-mcp-tools.png create mode 100644 docs/advanced-features/imgs/ai-assistant-fullscreen.png create mode 100644 docs/advanced-features/imgs/ai-assistant-interface.png create mode 100644 docs/advanced-features/imgs/ai-assistant-mcp-tools-management.png create mode 100644 docs/advanced-features/imgs/ai-assistant-open.png create mode 100644 docs/advanced-features/imgs/ai-assistant-prompts.png create mode 100644 docs/advanced-features/imgs/ai-assistant-settings.png create mode 100644 docs/advanced-features/imgs/ai-assistant-tool-execution1.png create mode 100644 docs/advanced-features/imgs/ai-assistant-tool-execution2.png create mode 100644 docs/advanced-features/new-ai-plugin-usage.md create mode 100644 packages/plugins/robot/src/mcp/MarkdownRenderer.vue create mode 100644 packages/plugins/robot/src/mcp/McpServer.vue create mode 100644 packages/plugins/robot/src/mcp/types.ts create mode 100644 packages/plugins/robot/src/mcp/useMcp.ts create mode 100644 packages/plugins/robot/src/mcp/utils.ts diff --git a/docs/advanced-features/imgs/ai-assistant-enable-mcp-tools.png b/docs/advanced-features/imgs/ai-assistant-enable-mcp-tools.png new file mode 100644 index 0000000000000000000000000000000000000000..5b99aa1285766134216e513f88c0ac983ab92ed3 GIT binary patch literal 65320 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 ZhaNrjVA(^9!k!-hj1ADpSC?))`VYNyvgiN+ literal 0 HcmV?d00001 diff --git a/docs/advanced-features/imgs/ai-assistant-interface.png b/docs/advanced-features/imgs/ai-assistant-interface.png new file mode 100644 index 0000000000000000000000000000000000000000..ab5b8ab932ee6c974da8ef77b0550add41a0628e GIT binary patch literal 35336 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 literal 0 HcmV?d00001 diff --git a/docs/advanced-features/imgs/ai-assistant-open.png b/docs/advanced-features/imgs/ai-assistant-open.png new file mode 100644 index 0000000000000000000000000000000000000000..7d0169cfaf3f21c61f81353091fa5540cb6e909d GIT binary patch literal 1662 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 literal 0 HcmV?d00001 diff --git a/docs/advanced-features/imgs/ai-assistant-tool-execution1.png b/docs/advanced-features/imgs/ai-assistant-tool-execution1.png new file mode 100644 index 0000000000000000000000000000000000000000..68a9ed28ade4acc83f350db9332926d6dce79578 GIT binary patch literal 24602 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 literal 0 HcmV?d00001 diff --git a/docs/advanced-features/imgs/ai-assistant-tool-execution2.png b/docs/advanced-features/imgs/ai-assistant-tool-execution2.png new file mode 100644 index 0000000000000000000000000000000000000000..d41191b12560652be2c5d0d5dac87c4092741180 GIT binary patch literal 33806 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

PV)o*foAwbotF2)| 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 literal 0 HcmV?d00001 diff --git a/docs/advanced-features/new-ai-plugin-usage.md b/docs/advanced-features/new-ai-plugin-usage.md new file mode 100644 index 0000000000..cf0f532e63 --- /dev/null +++ b/docs/advanced-features/new-ai-plugin-usage.md @@ -0,0 +1,225 @@ +# 新版AI插件使用指南 + +随着TinyEngine低代码平台的不断升级,AI插件也迎来了重大更新。新版AI插件(v2.8以上版本)采用了全新的TinyRobot组件库界面,同时通过使用OpenTiny Next SDK 集成了MCP(Model Context Protocol)工具使用能力,使AI能够调用平台各插件提供的工具能力,实现更强大的自动化操作功能。 + +## 一、功能概览 + +新版AI插件具备以下核心功能: + +1. **全新UI界面**:采用TinyRobot组件库,提供更现代化的聊天体验,支持Markdown语法、支持全屏模式等 +2. **智能对话**:支持与AI进行自然语言交互,完成复杂任务 +3. **Next SDK 与 MCP工具集成**:可以调用平台插件提供的各种工具,如修改属性、修改样式、创建页面等 + +## 二、界面介绍 + +### 2.1 主界面 + +在编辑器界面左下角插件栏,您可以看到 AI 助手的图标。点击图标即可打开主界面对话窗口。 + +![打开AI助手](./imgs/ai-assistant-open.png) + +主界面包含以下元素: +- **欢迎区域**:显示AI助手的欢迎信息 +- **提示项**:快速开始的常用问题示例 +- **对话区域**:显示用户与AI的对话历史 +- **输入区域**:用户输入问题的地方 +- **MC工具按钮**:管理和配置MCP工具的入口 + +![AI插件主界面](./imgs/ai-assistant-interface.png) + +### 2.2 设置 + +点击顶部的设置图标,可以进行以下配置: +- 选择 AI 模型:支持多种大型语言模型 +- 设置 API Token:配置访问 AI 服务所需的认证信息 + +![AI设置面板](./imgs/ai-assistant-settings.png) + +注意:切换 AI 模型会开启新的会话。 + + +### 2.3 MCP工具管理 + +![MCP工具管理](./imgs/ai-assistant-mcp-tools-management.png) + +MCP工具管理面板允许用户: +- 查看启用的MCP服务器 +- 启用/禁用特定的MCP工具 +- 添加新的MCP服务器(即将开放) + +## 三、基础使用流程 + + +### 3.1 设置模型接口 + +1. [可选] 配置自定义的OpenAI兼容格式的大模型接口 + +通过AI插件的`customCompatibleAIModels`选项,支持自定义添加OpenAI兼容格式大模型 + +```javascript +// registry.js +[META_APP.Robot]: { + options: { + customCompatibleAIModels: [ + { label: 'SiliconFlow:DeepSeek-V3', value: 'deepseek-ai/DeepSeek-V3', manufacturer: 'siliconflow' }, + { label: 'Qwen:qwen-max', value: 'qwen-max', manufacturer: 'qwen' }, + ] + } +}, +``` + +2. 配置本地的MCP工具调用使用的AI模型接口Proxy, 方便本地调试,以百炼为例: +```javascript +// vite.config.js +const originProxyConfig = baseConfig.server.proxy +baseConfig.server.proxy = { + '/app-center/api/chat/completions': { + target: 'https://dashscope.aliyuncs.com', + changeOrigin: true, + rewrite: path => path.replace('/app-center/api/', '/compatible-mode/v1/'), + }, + ...originProxyConfig, +} +``` + +### 3.2 打开AI插件 + +点击设计器左下角的AI图标即可打开AI插件对话框 + +### 3.3 配置AI模型 + +首次使用或切换AI模型时,需要进行配置: + +1. 点击右上角设置按钮 +2. 选择合适的AI模型 +3. 输入对应的API Token + +### 3.4 开始对话 + +在输入框中输入问题,按回车或点击发送按钮即可开始对话 + +## 四、MCP工具使用 + +### 4.1 MCP工具概览 + +MCP(Model Connector Protocol)是新版AI插件的核心功能之一。通过MCP,AI可以调用平台中各个插件提供的工具能力,例如: +- 创建新页面 +- 修改组件属性 +- 修改样式设置 +- 查询页面列表 +- 添加国际化内容 + +### 4.2 启用MCP工具 + +1. 点击输入框左侧的"MCP"按钮打开工具管理面板 +2. 查看可用的MCP服务器和工具 +3. 启用需要的工具 + +![启用MCP工具](./imgs/ai-assistant-enable-mcp-tools.png) + +### 4.3 使用MCP工具 + +当启用MCP工具后,AI在对话过程中会自动判断是否需要调用相关工具。例如: + +1. 用户询问:"帮我创建一个用户列表页面" +2. AI识别需要调用"创建页面"工具 +3. 自动执行创建页面操作 +4. 返回操作结果给用户 + +工具调用中(以查询天气Mock工具为例): +![MCP工具调用示例中](./imgs/ai-assistant-tool-execution1.png) +工具调用完成后会返回最终结果,也可以点击展开工具调用参数与结果: +![MCP工具调用示例结果示例](./imgs/ai-assistant-tool-execution2.png) + +## 五、典型使用场景 + +### 5.1 页面搭建场景 (即将开放) + +用户可以通过自然语言描述来生成页面: + +``` +用户:帮我创建一个包含用户信息表单的页面,需要有姓名、邮箱、手机号字段 +AI:好的,我将为您创建一个包含用户信息表单的页面... +[执行创建页面操作] +AI:已完成页面创建,您可以在页面列表中查看新创建的表单页面 +``` + +### 5.2 组件属性修改场景 + +用户可以通过对话修改画布中组件的属性: + +``` +用户:将当前选中按钮的文字改为"提交",颜色改为蓝色 +AI:好的,我将为您修改按钮属性... +[执行修改属性操作] +AI:已完成按钮属性修改 +``` + +### 5.3 样式调整场景 + +用户可以通过自然语言调整组件样式: + +``` +用户:把页面标题的文字大小调整为24px,居中显示 +AI:好的,我将为您调整标题样式... +[执行修改样式操作] +AI:已完成标题样式调整 +``` + +## 六、其他功能 + +### 6.1 会话管理 + +- **新建会话**:点击右上角的"新建会话"按钮可以开始新的对话 + +### 6.2 提示项快速开始 + +界面提供了几个提示项帮助用户快速开始: +- MCP工具使用 +- 页面搭建场景 +- 学习/知识型场景 + +点击任一提示项可以快速发送对应的示例问题。 + +### 6.3 Markdown 支持 + +AI 助手支持 Markdown 格式的消息渲染,可以更好地展示: +- 代码片段 +- 表格 +- 列表 +- 等其他富文本内容 + +### 6.4 全屏模式 + +点击右上角的展开按钮,可以进入全屏模式,获得更大的对话空间。 + +![全屏模式](./imgs/ai-assistant-fullscreen.png) + +## 七、注意事项 + +1. **保存提醒**:在使用AI插件前,请确保当前页面或区块已保存 +2. **网络要求**:使用AI功能需要稳定的网络连接 +3. **API Token**:需要配置有效的API Token才能正常使用AI功能 +4. **MCP工具依赖**:部分MCP工具需要相应的插件支持才能正常工作 + +## 八、故障排除 + +### 8.1 无法连接AI服务 + +- 检查网络连接是否正常 +- 确认API Token是否正确配置 +- 检查AI服务是否正常运行 + +### 8.2 MCP工具无法使用 + +- 确认相关插件是否已安装并启用 +- 检查MCP工具是否已启用 +- 查看控制台是否有错误信息 + +### 8.3 功能异常 + +- 尝试刷新页面 +- 清除浏览器缓存 +- 联系技术支持 + +通过以上介绍,您应该能够熟练使用新版AI插件的各项功能。随着平台的不断发展,AI插件将会支持更多强大的功能,帮助您更高效地进行低代码开发。 diff --git a/docs/catalog.json b/docs/catalog.json index 3066d29117..d2ff885ed9 100644 --- a/docs/catalog.json +++ b/docs/catalog.json @@ -41,6 +41,7 @@ { "title": "循环渲染", "name": "loop-rendering.md" }, { "title": "条件渲染", "name": "conditional-rendering.md" }, { "title": "集成ChatGPT搭建简单页面能力", "name": "integrating-chatgpt-for-simple-pages.md" }, + { "title": "新版AI插件使用", "name": "new-ai-plugin-usage.md" }, { "title": "数据源和Collection—远程字段", "name": "data-source-and-collection-remote-fields.md" }, { "title": "数据源和Collection—mock数据", "name": "data-source-and-collection-mock-data.md" }, { "title": "数据源和Collection—使用数据源", "name": "data-source-and-collection-usage.md" }, diff --git a/packages/plugins/robot/index.ts b/packages/plugins/robot/index.ts index f84692b4e6..e4ce8a93bd 100644 --- a/packages/plugins/robot/index.ts +++ b/packages/plugins/robot/index.ts @@ -13,6 +13,7 @@ import RobotIcon from './src/Main.vue' import metaData from './meta' import './src/styles/vars.less' +import '@opentiny/tiny-robot/dist/style.css' export default { ...metaData, diff --git a/packages/plugins/robot/package.json b/packages/plugins/robot/package.json index 0c2185f383..8ef6b469ef 100644 --- a/packages/plugins/robot/package.json +++ b/packages/plugins/robot/package.json @@ -25,10 +25,17 @@ "license": "MIT", "homepage": "https://opentiny.design/tiny-engine", "dependencies": { - "@opentiny/tiny-engine-meta-register": "workspace:*" + "@opentiny/tiny-engine-meta-register": "workspace:*", + "@opentiny/tiny-robot": "0.3.0-alpha.14", + "@opentiny/tiny-robot-kit": "0.3.0-alpha.14", + "@opentiny/tiny-robot-svgs": "0.3.0-alpha.14", + "dompurify": "^3.0.1", + "highlight.js": "^11.11.1", + "markdown-it": "^14.1.0" }, "devDependencies": { "@opentiny/tiny-engine-vite-plugin-meta-comments": "workspace:*", + "@types/markdown-it": "^14.1.2", "@vitejs/plugin-vue": "^5.1.2", "@vitejs/plugin-vue-jsx": "^4.0.1", "vite": "^5.4.2" diff --git a/packages/plugins/robot/src/Main.vue b/packages/plugins/robot/src/Main.vue index 511909ba80..fb9326ccf2 100644 --- a/packages/plugins/robot/src/Main.vue +++ b/packages/plugins/robot/src/Main.vue @@ -4,19 +4,14 @@ -

@@ -113,26 +73,37 @@ + + diff --git a/packages/plugins/robot/src/mcp/McpServer.vue b/packages/plugins/robot/src/mcp/McpServer.vue new file mode 100644 index 0000000000..28d403a041 --- /dev/null +++ b/packages/plugins/robot/src/mcp/McpServer.vue @@ -0,0 +1,179 @@ + + + + + diff --git a/packages/plugins/robot/src/mcp/types.ts b/packages/plugins/robot/src/mcp/types.ts new file mode 100644 index 0000000000..6304732af3 --- /dev/null +++ b/packages/plugins/robot/src/mcp/types.ts @@ -0,0 +1,87 @@ +import type { BubbleContentItem } from '@opentiny/tiny-robot' + +export interface RequestOptions { + url?: string + model?: string + headers?: Record +} + +export interface RequestTool { + type: 'function' + function: { + name: string + description: string + parameters: { + type: 'object' + required?: string[] + properties: Record< + string, + { + type: string + description: string + [prop: string]: unknown + } + > + } + } +} + +export interface LLMMessage { + role: string + content: string + [prop: string]: unknown +} + +export interface RobotMessage { + role: string + content: string | BubbleContentItem[] + [prop: string]: unknown +} + +export interface LLMRequestBody { + model?: string + stream: boolean + messages: LLMMessage[] + tools?: RequestTool[] +} + +export interface ReponseToolCall { + id: string + function: { + name: string + arguments: string + } +} + +export interface LLMResponse { + choices: Array<{ + message: { + role?: string + content: string + tool_calls?: Array + [prop: string]: unknown + } + }> +} + +export interface McpTool { + name: string + description: string + inputSchema?: { + type: 'object' + properties: Record< + string, + { + type: string + description: string + [prop: string]: unknown + } + > + [prop: string]: unknown + } + [prop: string]: unknown +} + +export interface McpListToolsResponse { + tools: Array +} diff --git a/packages/plugins/robot/src/mcp/useMcp.ts b/packages/plugins/robot/src/mcp/useMcp.ts new file mode 100644 index 0000000000..e88ea9b7af --- /dev/null +++ b/packages/plugins/robot/src/mcp/useMcp.ts @@ -0,0 +1,185 @@ +import { computed, ref } from 'vue' +import type { PluginInfo, PluginTool } from '@opentiny/tiny-robot' +import { getMetaApi, META_SERVICE } from '@opentiny/tiny-engine-meta-register' +import type { McpListToolsResponse, McpTool, RequestTool } from './types' + +const ENGINE_MCP_SERVER: PluginInfo = { + id: 'tiny-engine-mcp-server', + name: 'Tiny Engine MCP 服务器', + icon: 'https://res.hc-cdn.com/lowcode-portal/1.1.80.20250515160330/assets/opentiny-tinyengine-logo-4f8a3801.svg', + description: '使用TinyEngine设计器能力,如添加国际化', + added: true +} + +const MOCK_SERVERS: PluginInfo[] = [ + { + id: 'plugin-1', + name: 'Jira 集成 (Mock)', + icon: 'https://ts3.tc.mm.bing.net/th/id/ODLS.2a97aa8b-50c6-4e00-af97-3b563dfa07f4', + description: 'Jira 任务管理', + enabled: true, + added: false, + tools: [ + { id: 'tool-5', name: '创建任务', description: '创建 Jira 任务', enabled: true }, + { id: 'tool-6', name: '查询任务', description: '查询 Jira 任务', enabled: true } + ] + }, + { + id: 'plugin-2', + name: 'Notion 集成 (Mock)', + icon: 'https://www.notion.so/front-static/favicon.ico', + description: 'Notion 文档管理和协作', + enabled: false, + added: false, + tools: [ + { id: 'tool-7', name: '创建页面', description: '创建 Notion 页面', enabled: false }, + { id: 'tool-8', name: '查询数据库', description: '查询 Notion 数据库', enabled: false } + ] + }, + { + id: 'plugin-3', + name: 'Telegram 机器人 (Mock)', + icon: 'https://telegram.org/favicon.ico', + description: 'Telegram 消息推送和自动化', + enabled: false, + added: false, + tools: [{ id: 'tool-9', name: '发送消息', description: '发送 Telegram 消息', enabled: false }] + } +] + +const mcpServers = ref([ENGINE_MCP_SERVER, ...MOCK_SERVERS]) + +const inUseMcpServers = ref([ + { ...ENGINE_MCP_SERVER, enabled: true, expanded: false, tools: [], toolCount: 0 } +]) + +const updateServerTools = (serverId: string, tools: PluginTool[]) => { + const mcpServer = inUseMcpServers.value.find((item) => item.id === serverId) + if (mcpServer) { + mcpServer.tools = tools + mcpServer.toolCount = tools.length + } +} + +const updateEngineTools = async () => { + const tools: Array<{ name: string; description: string; status: string }> = + (await getMetaApi(META_SERVICE.McpService)?.getToolList?.()) || [] + const engineTools = tools.map((tool) => ({ + id: tool.name, + name: tool.name, + description: tool.description, + enabled: tool.status === 'enabled' + })) + updateServerTools(ENGINE_MCP_SERVER.id, engineTools) +} + +const convertMCPToOpenAITools = (mcpTools: McpTool[]): RequestTool[] => { + return mcpTools.map((tool: McpTool) => ({ + type: 'function', + function: { + name: tool.name, + description: tool.description || '', + parameters: { + type: 'object', + properties: Object.fromEntries( + Object.entries(tool.inputSchema?.properties || {}).map(([key, prop]: [string, any]) => [key, { ...prop }]) + ), + required: tool.inputSchema?.required || [] + } + } + })) as RequestTool[] +} + +const getEngineServer = () => { + return inUseMcpServers.value.find((item) => item.id === ENGINE_MCP_SERVER.id) +} + +const isToolsEnabled = computed(() => getEngineServer()?.tools?.some((tool) => tool.enabled)) + +const updateEngineServerToolStatus = (toolId: string, enabled: boolean) => { + getMetaApi(META_SERVICE.McpService)?.updateTool?.(toolId, { enabled }) +} + +const updateEngineServer = (engineServer: PluginInfo, enabled: boolean) => { + engineServer?.tools?.forEach((tool) => { + tool.enabled = enabled + updateEngineServerToolStatus(tool.id, enabled) + }) +} + +// TODO: 连接MCP Server +const connectMcpServer = (_server: PluginInfo) => {} + +// TODO: 断开连接 +const disconnectMcpServer = (_server: PluginInfo) => {} + +const updateMcpServerStatus = async (server: PluginInfo, added: boolean) => { + if (added) { + const newServer: PluginInfo = { + ...server, + id: server.id || `mcp-server-${Date.now()}`, + enabled: true, + added: true, + expanded: false, + tools: server.tools || [], + toolCount: server.tools?.length || 0 + } + inUseMcpServers.value.push(newServer) + if (server.id === ENGINE_MCP_SERVER.id) { + await updateEngineTools() + updateEngineServer(newServer, added) + } + // TODO: 连接MCP Server + connectMcpServer(newServer) + } else { + const index = inUseMcpServers.value.findIndex((p) => p.id === server.id) + if (index > -1) { + updateEngineServer(inUseMcpServers.value[index], added) + inUseMcpServers.value.splice(index, 1) + // TODO: 断开连接 + disconnectMcpServer(server) + } + } +} + +const updateMcpServerToolStatus = (currentServer: PluginInfo, toolId: string, enabled: boolean) => { + const tool = currentServer.tools?.find((t: PluginTool) => t.id === toolId) + if (tool) { + tool.enabled = enabled + if (currentServer.id === ENGINE_MCP_SERVER.id) { + updateEngineServerToolStatus(toolId, enabled) + } else { + // TODO: 更新MCP Server的Tool状态 + // 获取 tool 实例调用 enableTool 或 disableTool + } + } +} + +const refreshMcpServerTools = () => { + updateEngineTools() +} + +const listTools = async (): Promise => + getMetaApi(META_SERVICE.McpService)?.getMcpClient()?.listTools() + +const callTool = async (toolId: string, args: Record) => + getMetaApi(META_SERVICE.McpService)?.getMcpClient()?.callTool({ name: toolId, arguments: args }) || {} + +const getLLMTools = async () => { + const mcpTools = await listTools() + return convertMCPToOpenAITools(mcpTools?.tools || []) +} + +export default function useMcpServer() { + return { + mcpServers, + inUseMcpServers, + refreshMcpServerTools, + updateMcpServerStatus, + updateMcpServerToolStatus, + listTools, + callTool, + getLLMTools, + isToolsEnabled + } +} diff --git a/packages/plugins/robot/src/mcp/utils.ts b/packages/plugins/robot/src/mcp/utils.ts new file mode 100644 index 0000000000..5ef759a8d2 --- /dev/null +++ b/packages/plugins/robot/src/mcp/utils.ts @@ -0,0 +1,113 @@ +import { toRaw } from 'vue' +import useMcpServer from './useMcp' +import type { LLMMessage, RobotMessage } from './types' +import type { LLMRequestBody, LLMResponse, ReponseToolCall, RequestOptions, RequestTool } from './types' + +let requestOptions: RequestOptions = {} + +const fetchLLM = async (messages: LLMMessage[], tools: RequestTool[], options: RequestOptions = requestOptions) => { + const bodyObj: LLMRequestBody = { + model: options?.model || 'deepseek-chat', + stream: false, + messages: toRaw(messages) + } + if (tools.length > 0) { + bodyObj.tools = toRaw(tools) + } + return fetch(options?.url || '/app-center/api/chat/completions', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + ...options?.headers + }, + body: JSON.stringify(bodyObj) + }) +} + +const parseArgs = (args: string) => { + try { + return JSON.parse(args) + } catch (error) { + return args + } +} + +const handleToolCall = async ( + res: LLMResponse, + tools: RequestTool[], + messages: RobotMessage[], + contextMessages?: RobotMessage[] +) => { + if (messages.length < 1) { + return + } + const currentMessage = messages.at(-1)! + if (typeof currentMessage.content === 'string' || !currentMessage.content) { + currentMessage.content = [] + } + if (res.choices[0].message.content) { + currentMessage.content.push({ + type: 'markdown', + content: res.choices[0].message.content + }) + } + const tool_calls: ReponseToolCall[] | undefined = res.choices[0].message.tool_calls + if (tool_calls && tool_calls.length) { + const historyMessages = contextMessages?.length ? contextMessages : toRaw(messages.slice(0, -1)) + const toolMessages: LLMMessage[] = [...historyMessages, res.choices[0].message] as LLMMessage[] + for (const tool of tool_calls) { + const { name, arguments: args } = tool.function + const parsedArgs = parseArgs(args) + const currentToolMessage = { + type: 'tool', + name, + status: 'running', + content: { + params: parsedArgs + }, + formatPretty: true + } + currentMessage.content.push(currentToolMessage) + const toolCallResult = await useMcpServer().callTool(name, parsedArgs) + toolMessages.push({ + type: 'text', + content: toolCallResult.content, + role: 'tool', + tool_call_id: tool.id + }) + + currentMessage.content.at(-1)!.status = 'success' + currentMessage.content.at(-1)!.content = { + params: parsedArgs, + result: toolCallResult.content + } + } + const newResp = await fetchLLM(toolMessages, tools).then((res) => res.json()) + const hasToolCall = newResp.choices[0].message.tool_calls?.length > 0 + if (hasToolCall) { + await handleToolCall(newResp, tools, messages, toolMessages) + } else { + if (newResp.choices[0].message.content) { + currentMessage.content.push({ + type: 'markdown', + content: newResp.choices[0].message.content + }) + } + } + } +} + +export const sendMcpRequest = async (messages: LLMMessage[], options: RequestOptions = {}) => { + if (messages.length < 1) { + return + } + const tools = await useMcpServer().getLLMTools() + requestOptions = options + const res = await fetchLLM(messages.slice(0, -1), tools, options).then((res) => res.json()) + const hasToolCall = res.choices[0].message.tool_calls?.length > 0 + if (hasToolCall) { + await handleToolCall(res, tools, messages) + } else { + messages.at(-1)!.content = res.choices[0].message.content + } +} diff --git a/packages/register/src/constants.ts b/packages/register/src/constants.ts index d200a3d724..d85e3ff2be 100644 --- a/packages/register/src/constants.ts +++ b/packages/register/src/constants.ts @@ -18,7 +18,8 @@ export const META_SERVICE = { Property: 'engine.service.property', Properties: 'engine.service.properties', ThemeSwitch: 'engine.service.themeSwitch', - Style: 'engine.service.style' + Style: 'engine.service.style', + McpService: 'engine.service.mcpService' } export const META_APP = { diff --git a/packages/register/src/service.ts b/packages/register/src/service.ts index 0161c56652..54b5bcb8b3 100644 --- a/packages/register/src/service.ts +++ b/packages/register/src/service.ts @@ -8,7 +8,7 @@ interface Context { options: K } -interface ServiceOptions { +export interface ServiceOptions { id: string type: 'MetaService' initialState: T From 068a6f35ef684ed6580bbd34ad8f5e099fe19e62 Mon Sep 17 00:00:00 2001 From: zzerX Date: Tue, 29 Jul 2025 19:30:37 +0800 Subject: [PATCH 011/101] feat(Block): implement property selector with two-way binding (#1453) --- packages/plugins/block/src/BlockEventForm.vue | 129 +++++++++++++++++- 1 file changed, 122 insertions(+), 7 deletions(-) diff --git a/packages/plugins/block/src/BlockEventForm.vue b/packages/plugins/block/src/BlockEventForm.vue index 0d98186403..0510f9a968 100644 --- a/packages/plugins/block/src/BlockEventForm.vue +++ b/packages/plugins/block/src/BlockEventForm.vue @@ -1,7 +1,31 @@ @@ -119,6 +123,7 @@ import { } from 'vue' import { Notify, Loading, TinyPopover, TinyDialogBox } from '@opentiny/vue' import { useCanvas, useModal, getMetaApi, META_SERVICE } from '@opentiny/tiny-engine-meta-register' +import { ToolbarBase } from '@opentiny/tiny-engine-common' import { TrContainer, TrWelcome, @@ -154,12 +159,16 @@ import LoadingRenderer from './mcp/LoadingRenderer.vue' import { sendMcpRequest, serializeError } from './mcp/utils' import type { RobotMessage } from './mcp/types' import RobotTypeSelect from './RobotTypeSelect.vue' +import McpIconComponent from './icon-prompt/mcp-icon.vue' +import PageIconComponent from './icon-prompt/page-icon.vue' +import StudyIconComponent from './icon-prompt/study-icon.vue' export default { components: { TinyPopover: TinyPopover as unknown, TinyDialogBox: TinyDialogBox as unknown, RobotSettingPopover, + ToolbarBase, TrContainer, TrWelcome, TrPrompts, @@ -172,6 +181,12 @@ export default { TrBubbleProvider, RobotTypeSelect }, + props: { + options: { + type: Object, + default: () => ({}) + } + }, emits: ['close-chat'], setup() { const { pageState, importSchema, setSaved } = useCanvas() @@ -196,6 +211,7 @@ export default { const MESSAGE_TIP = '已生成新的页面效果,请点击下方按钮应用schema' const aiType = ref(TALK_TYPE) const chatContainerRef = ref(null) + const showTeleport = ref(false) const sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay)) watchEffect(() => { avatarUrl.value = 'img/defaultAvator.png' @@ -252,7 +268,7 @@ export default { return item }) } - if (aiType.value === MCP_TYPE) { + if (useMcpServer().isToolsEnabled && aiType.value === TALK_TYPE) { firstContent = `${getBlockContent()}\n${codeRules}\n${firstMessage.content[0]?.text || ''}` } @@ -333,7 +349,7 @@ export default { // 发送流式请求 const sendStreamRequest = async () => { const requestData = getSendSeesionProcess() - if (useMcpServer().isToolsEnabled && aiType.value === MCP_TYPE) { + if (useMcpServer().isToolsEnabled && aiType.value === TALK_TYPE) { try { requestLoading.value = true await scrollContent() @@ -533,6 +549,9 @@ export default { } onMounted(async () => { + setTimeout(() => { + showTeleport.value = true + }, 1000) const loadingInstance = Loading.service({ text: '初始化中,请稍等...', customClass: 'chat-loading', @@ -606,18 +625,18 @@ export default { { label: 'MCP工具', description: '帮我查询当前的页面列表', - icon: h('span', { style: { fontSize: '18px' } as CSSProperties }, '🔧'), + icon: h(McpIconComponent), badge: 'NEW' }, { label: '页面搭建场景', description: '给当前页面中添加一个问卷调查表单', - icon: h('span', { style: { fontSize: '18px' } as CSSProperties }, '✨') + icon: h(PageIconComponent) }, { label: '学习/知识型场景', description: 'Vue3 和 React 有什么区别?', - icon: h('span', { style: { fontSize: '18px' } as CSSProperties }, '🤔') + icon: h(StudyIconComponent) } ] @@ -796,6 +815,7 @@ export default { TALK_TYPE, MCP_TYPE, BUILD_TYPE, + showTeleport, sendContent, endContent, changeApiKey, @@ -817,6 +837,12 @@ export default { diff --git a/packages/plugins/robot/src/icon-prompt/mcp-icon.vue b/packages/plugins/robot/src/icon-prompt/mcp-icon.vue new file mode 100644 index 0000000000..073d2eb0ac --- /dev/null +++ b/packages/plugins/robot/src/icon-prompt/mcp-icon.vue @@ -0,0 +1,38 @@ + + + diff --git a/packages/plugins/robot/src/icon-prompt/page-icon.vue b/packages/plugins/robot/src/icon-prompt/page-icon.vue new file mode 100644 index 0000000000..ae82278def --- /dev/null +++ b/packages/plugins/robot/src/icon-prompt/page-icon.vue @@ -0,0 +1,39 @@ + + + diff --git a/packages/plugins/robot/src/icon-prompt/study-icon.vue b/packages/plugins/robot/src/icon-prompt/study-icon.vue new file mode 100644 index 0000000000..b851005195 --- /dev/null +++ b/packages/plugins/robot/src/icon-prompt/study-icon.vue @@ -0,0 +1,38 @@ + + + diff --git a/packages/plugins/robot/src/mcp/McpServer.vue b/packages/plugins/robot/src/mcp/McpServer.vue index 0a7e1a3e6c..488e439b7d 100644 --- a/packages/plugins/robot/src/mcp/McpServer.vue +++ b/packages/plugins/robot/src/mcp/McpServer.vue @@ -2,7 +2,6 @@
- MCP
@@ -126,12 +125,13 @@ onMounted(() => { display: flex; align-items: center; justify-content: center; - width: 64px; - height: 28px; + width: 32px; + height: 32px; border: 1px solid rgb(194, 194, 194); border-radius: 999px; cursor: pointer; box-sizing: border-box; + background-color: var(--te-common-bg-container); &:hover { background-color: rgba(0, 0, 0, 0.08); diff --git a/packages/register/src/constants.ts b/packages/register/src/constants.ts index d85e3ff2be..8a0349620a 100644 --- a/packages/register/src/constants.ts +++ b/packages/register/src/constants.ts @@ -33,6 +33,7 @@ export const META_APP = { Media: 'engine.toolbars.media', Collaboration: 'engine.toolbars.collaboration', Clean: 'engine.toolbars.clean', + Robot: 'engine.toolbars.robot', ThemeSwitch: 'engine.toolbars.themeSwitch', Refresh: 'engine.toolbars.refresh', Save: 'engine.toolbars.save', @@ -66,8 +67,6 @@ export const META_APP = { Schema: 'engine.plugins.schema', // 新手帮助/帮助文档 Help: 'engine.plugins.editorhelp', - // AI 插件 - Robot: 'engine.plugins.robot', // 属性设置面板 Props: 'engine.setting.props', // 样式设置面板 From f9ea40c1770adfe6d731d33e16060f163b9e83e6 Mon Sep 17 00:00:00 2001 From: xuanlid <51027603+xuanlid@users.noreply.github.com> Date: Fri, 5 Sep 2025 02:24:05 -0700 Subject: [PATCH 033/101] fix: Modify settings panel icons (#1612) --- packages/design-core/assets/event.svg | 13 +++++++++++++ packages/design-core/assets/property.svg | 13 +++++++++++++ packages/design-core/assets/style.svg | 13 +++++++++++++ packages/settings/events/meta.js | 2 +- packages/settings/props/meta.js | 2 +- packages/settings/styles/meta.js | 2 +- 6 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 packages/design-core/assets/event.svg create mode 100644 packages/design-core/assets/property.svg create mode 100644 packages/design-core/assets/style.svg diff --git a/packages/design-core/assets/event.svg b/packages/design-core/assets/event.svg new file mode 100644 index 0000000000..4b0e465145 --- /dev/null +++ b/packages/design-core/assets/event.svg @@ -0,0 +1,13 @@ + + + Created with Pixso. + + + + + + + + + + diff --git a/packages/design-core/assets/property.svg b/packages/design-core/assets/property.svg new file mode 100644 index 0000000000..e602fc32ce --- /dev/null +++ b/packages/design-core/assets/property.svg @@ -0,0 +1,13 @@ + + + Created with Pixso. + + + + + + + + + + diff --git a/packages/design-core/assets/style.svg b/packages/design-core/assets/style.svg new file mode 100644 index 0000000000..b221fe8740 --- /dev/null +++ b/packages/design-core/assets/style.svg @@ -0,0 +1,13 @@ + + + Created with Pixso. + + + + + + + + + + diff --git a/packages/settings/events/meta.js b/packages/settings/events/meta.js index db03c7d224..3dfb271e83 100644 --- a/packages/settings/events/meta.js +++ b/packages/settings/events/meta.js @@ -3,5 +3,5 @@ export default { title: '高级', type: 'plugins', name: 'event', - icon: 'target' + icon: 'event' } diff --git a/packages/settings/props/meta.js b/packages/settings/props/meta.js index 5b0d95c14f..8f4e70e719 100644 --- a/packages/settings/props/meta.js +++ b/packages/settings/props/meta.js @@ -3,5 +3,5 @@ export default { title: '属性', type: 'plugins', name: 'props', - icon: 'form' + icon: 'property' } diff --git a/packages/settings/styles/meta.js b/packages/settings/styles/meta.js index 0b7c99e0c3..81fcca1c6a 100644 --- a/packages/settings/styles/meta.js +++ b/packages/settings/styles/meta.js @@ -3,5 +3,5 @@ export default { title: '样式', name: 'style', type: 'plugins', - icon: 'display-inline' + icon: 'style' } From da1c7d6b4e451d796a5f541c0f613311a03ff073 Mon Sep 17 00:00:00 2001 From: lichunn <46984087+lichunn@users.noreply.github.com> Date: Fri, 5 Sep 2025 17:54:07 +0800 Subject: [PATCH 034/101] feat: Add AI streaming data real-time rendering (#1614) --- packages/plugins/robot/package.json | 4 +- packages/plugins/robot/src/Main.vue | 89 +++++++++++++------------- packages/plugins/robot/src/js/utils.ts | 16 +++++ 3 files changed, 62 insertions(+), 47 deletions(-) diff --git a/packages/plugins/robot/package.json b/packages/plugins/robot/package.json index ee4721848f..c050b84229 100644 --- a/packages/plugins/robot/package.json +++ b/packages/plugins/robot/package.json @@ -27,6 +27,7 @@ "dependencies": { "@opentiny/tiny-engine-meta-register": "workspace:*", "@opentiny/tiny-engine-common": "workspace:*", + "@opentiny/tiny-engine-utils": "workspace:*", "@opentiny/tiny-robot": "0.3.0-rc.0", "@opentiny/tiny-robot-kit": "0.3.0-rc.0", "@opentiny/tiny-robot-svgs": "0.3.0-rc.0", @@ -34,7 +35,8 @@ "fast-json-patch": "~3.1.1", "dompurify": "^3.0.1", "highlight.js": "^11.11.1", - "markdown-it": "^14.1.0" + "markdown-it": "^14.1.0", + "jsonrepair": "3.13.0" }, "devDependencies": { "@opentiny/tiny-engine-vite-plugin-meta-comments": "workspace:*", diff --git a/packages/plugins/robot/src/Main.vue b/packages/plugins/robot/src/Main.vue index db4a361075..16deb1dbee 100644 --- a/packages/plugins/robot/src/Main.vue +++ b/packages/plugins/robot/src/Main.vue @@ -130,13 +130,13 @@ import { TrPrompts, TrBubbleList, TrSender, - TrFeedback, TrAttachments, TrBubbleProvider } from '@opentiny/tiny-robot' import type { BubbleRoleConfig, PromptProps } from '@opentiny/tiny-robot' import { IconNewSession } from '@opentiny/tiny-robot-svgs' import SchemaRenderer from '@opentiny/tiny-schema-renderer' +import { utils } from '@opentiny/tiny-engine-utils' import RobotSettingPopover from './RobotSettingPopover.vue' import { getBlockContent, @@ -151,7 +151,7 @@ import { } from './js/robotSetting' import { PROMPTS } from './js/prompts' import * as jsonpatch from 'fast-json-patch' -import { chatStream } from './js/utils' +import { chatStream, checkComponentNameExists } from './js/utils' import McpServer from './mcp/McpServer.vue' import useMcpServer from './mcp/useMcp' import MarkdownRenderer from './mcp/MarkdownRenderer.vue' @@ -162,6 +162,7 @@ import RobotTypeSelect from './RobotTypeSelect.vue' import McpIconComponent from './icon-prompt/mcp-icon.vue' import PageIconComponent from './icon-prompt/page-icon.vue' import StudyIconComponent from './icon-prompt/study-icon.vue' +import { jsonrepair } from 'jsonrepair' export default { components: { @@ -208,10 +209,11 @@ export default { const showPreview = ref(false) const singleAttachmentItems = ref([]) const imageUrl = ref('') - const MESSAGE_TIP = '已生成新的页面效果,请点击下方按钮应用schema' + const MESSAGE_TIP = '已生成新的页面效果。' const aiType = ref(TALK_TYPE) const chatContainerRef = ref(null) const showTeleport = ref(false) + const { deepClone, string2Obj, reactiveObj2String: obj2String } = utils const sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay)) watchEffect(() => { avatarUrl.value = 'img/defaultAvator.png' @@ -296,19 +298,20 @@ export default { id }) - const setSchema = () => { + const setSchema = async (schema: any) => { const value = { ...pageState.pageSchema, - ...currentSchema.value, + ...schema, componentName: pageState.pageSchema.componentName } importSchema(value) setSaved(false) showPreview.value = false + await nextTick() } // 处理响应 - const handleResponse = ({ id, chatMessage }: { id: string; chatMessage: any }) => { + const handleResponse = ({ id, chatMessage }: { id: string; chatMessage: any }, currentJson) => { try { if (aiType.value === BUILD_TYPE) { const regex = /```json([\s\S]*?)```/ @@ -317,7 +320,7 @@ export default { if (match && match[1] && JSON.parse(match[1]) && isValidFastJsonPatch(JSON.parse(match[1]))) { const newValue = JSON.parse(match[1]) // 使用 applyPatch 修改 Schema - const result = newValue.reduce(jsonpatch.applyReducer, pageState.pageSchema) + const result = newValue.reduce(jsonpatch.applyReducer, currentJson) sessionProcess.messages.push(getAiRespMessage(JSON.stringify(result, null, 2), chatMessage.role)) sessionProcess.displayMessages.push(getAiDisplayMessage(MESSAGE_TIP, chatMessage.role, result, id)) @@ -385,6 +388,9 @@ export default { let streamContent = '' const chatId = Date.now().toString() + const currentJson = deepClone(pageState.pageSchema) + let lastExecutionTime = 0 + const throttleDelay = 3000 await chatStream( { requestUrl: '/app-center/api/ai/chat', @@ -402,6 +408,24 @@ export default { } streamContent += choice.delta.content messages.value[messages.value.length - 1].content += choice.delta.content + const currentTime = Date.now() + if (currentTime - lastExecutionTime > throttleDelay) { + try { + const repaired = jsonrepair(streamContent) + const parsedJson = JSON.parse(repaired) + const result = parsedJson.reduce((acc, patch) => { + return jsonpatch.applyPatch(acc, [patch], false, false).newDocument + }, currentJson) + const editorValue = string2Obj(obj2String(result)) + + if (editorValue && checkComponentNameExists(result)) { + setSchema(result) + } + } catch (error) { + // error + } + lastExecutionTime = currentTime + } } }, onError: (error) => { @@ -413,14 +437,17 @@ export default { console.error('Stream error:', error) }, onDone: () => { - handleResponse({ - id: chatId, - chatMessage: { - role: 'assistant', - content: streamContent || '没有返回内容', - name: 'AI' - } - }) + handleResponse( + { + id: chatId, + chatMessage: { + role: 'assistant', + content: streamContent || '没有返回内容', + name: 'AI' + } + }, + currentJson + ) } }, { @@ -645,12 +672,6 @@ export default { sendContent(item.description, true) } - const getItemSchema = (item) => { - const targetMessage = messages.value.find((message) => message.id && message.id === item.id) - - return targetMessage - } - // Icon const getSvgIcon = (name: string, style?: CSSProperties) => { return h(resolveComponent('svg-icon'), { name, style: { fontSize: '32px', ...style } }) @@ -658,8 +679,6 @@ export default { const aiAvatar = getSvgIcon('AI') const userAvatar = getSvgIcon('user-head', { color: '#dfe1e6' }) const welcomeIcon = getSvgIcon('AI', { fontSize: '48px' }) - const saveIcon = getSvgIcon('save', { fontSize: '20px' }) - const previewIcon = getSvgIcon('preview', { fontSize: '20px' }) // 处理文件选择事件 const handleSingleFilesSelected = (files: FileList | null, retry = false) => { @@ -742,29 +761,7 @@ export default { avatar: aiAvatar, maxWidth: '90%', contentRenderer: MarkdownRenderer, - customContentField: 'renderContent', - slots: { - footer: ({ bubbleProps }) => { - return h(TrFeedback, { - style: { - display: getItemSchema(bubbleProps)?.schema && aiType.value === BUILD_TYPE ? 'block' : 'none' - }, - actions: [ - { name: 'run', label: '应用', icon: saveIcon }, - { name: 'preview', label: '预览', icon: previewIcon } - ], - onAction(name) { - currentSchema.value = getItemSchema(bubbleProps)?.schema || {} - if (name === 'preview') { - showPreview.value = true - } - if (name === 'run') { - setSchema() - } - } - }) - } - } + customContentField: 'renderContent' }, user: { placement: 'end', avatar: userAvatar, maxWidth: '90%', contentRenderer: MarkdownRenderer }, system: { hidden: true } diff --git a/packages/plugins/robot/src/js/utils.ts b/packages/plugins/robot/src/js/utils.ts index e7d71b86d7..a17eecd0de 100644 --- a/packages/plugins/robot/src/js/utils.ts +++ b/packages/plugins/robot/src/js/utils.ts @@ -26,3 +26,19 @@ export const chatStream = async (requestOpts: any, handler: StreamHandler, heade logger.error('Error in chatStream:', error) } } + +export const checkComponentNameExists = (data: any) => { + if (!data.componentName) { + return false + } + + if (data.children && Array.isArray(data.children)) { + for (const child of data.children) { + if (!checkComponentNameExists(child)) { + return false + } + } + } + + return true +} From ce0767278f0f7ac19febf78a2dc1d79048dc50aa Mon Sep 17 00:00:00 2001 From: chilingling <26962197+chilingling@users.noreply.github.com> Date: Tue, 9 Sep 2025 19:27:37 +0800 Subject: [PATCH 035/101] docs: change to pre wrap to avoid identify as env (#1621) --- docs/extension-capabilities-tutorial/mcpService.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/extension-capabilities-tutorial/mcpService.md b/docs/extension-capabilities-tutorial/mcpService.md index f108b83126..bb54fb0b5e 100644 --- a/docs/extension-capabilities-tutorial/mcpService.md +++ b/docs/extension-capabilities-tutorial/mcpService.md @@ -430,20 +430,22 @@ mcpService.setOptions(remoteConfig) ### 高级配置 -```typescript +
+
 import { getMetaApi } from '@opentiny/tiny-engine-meta-register'
 
 const mcpService = getMetaApi('engine.service.mcp')
 
 const advancedConfig = {
-  proxyUrl: process.env.MCP_PROXY_URL || 'http://localhost:3000/mcp',
-  connectToAgentServer: process.env.NODE_ENV === 'production',
+  proxyUrl: process.env.MCP_PROXY_URL || 'http://localhost:3000/mcp',
+  connectToAgentServer: process.env.NODE_ENV === 'production',
   reconnectAttempts: 5,
   reconnectInterval: 2000
 }
 
 mcpService.setOptions(advancedConfig)
-```
+
+
## 最佳实践 From 3e61fcd06cd3c719936dad91fc8474521ce778b7 Mon Sep 17 00:00:00 2001 From: chilingling <26962197+chilingling@users.noreply.github.com> Date: Wed, 10 Sep 2025 20:40:52 +0800 Subject: [PATCH 036/101] fix: resolve tinyvue type errors (#1623) --- .../common/component/BlockDeployDialog.vue | 7 ++-- packages/common/component/BlockLinkEvent.vue | 5 ++- packages/common/component/BlockLinkField.vue | 5 ++- packages/common/component/ConfigItem.vue | 5 ++- packages/common/component/I18nInput.vue | 3 +- packages/common/component/LifeCycles.vue | 5 ++- packages/common/component/LinkButton.vue | 3 +- packages/common/component/MetaListActions.vue | 3 +- packages/common/component/MetaListItem.vue | 7 ++-- packages/common/component/MetaListItems.vue | 3 +- packages/common/component/MetaPopover.vue | 3 +- packages/common/component/MonacoEditor.vue | 3 +- .../common/component/MultiTypeSelector.vue | 5 ++- packages/common/component/PluginBlockList.vue | 5 ++- packages/common/component/PluginPanel.vue | 3 +- packages/common/component/PluginSetting.vue | 3 +- packages/common/component/SvgButton.vue | 3 +- .../toolbar-built-in/ToolbarBaseButton.vue | 3 +- .../toolbar-built-in/ToolbarBaseIcon.vue | 3 +- .../ButtonGroupConfigurator.vue | 5 ++- .../CheckBoxConfigurator.vue | 5 ++- .../CheckboxGroupConfigurator.vue | 5 ++- .../CodeListConfigurator.vue | 5 ++- .../CollectionConfigurator.vue | 5 ++- .../HtmlAttributesConfigurator.vue | 7 ++-- .../IpSectionConfigurator.vue | 5 ++- .../JsSlotConfigurator.vue | 5 ++- .../radio-configurator/RadioConfigurator.vue | 5 ++- .../SelectConfigurator.vue | 5 ++- .../SelectIconConfigurator.vue | 5 ++- .../slot-configurator/SlotConfigurator.vue | 5 ++- .../VariableConfigurator.vue | 7 ++-- packages/layout/src/DesignPlugins.vue | 7 ++-- packages/layout/src/DesignSettings.vue | 3 +- packages/layout/src/ToolbarCollapse.vue | 3 +- packages/plugins/bridge/src/BridgeSetting.vue | 3 +- .../datasource/src/DataSourceFieldCheck.vue | 3 +- .../src/DataSourceRemoteAutoload.vue | 3 +- .../src/DataSourceRemoteDataAdapter.vue | 3 +- .../src/DataSourceRemoteResultMapping.vue | 3 +- packages/plugins/help/src/HelpIcon.vue | 3 +- packages/plugins/i18n/src/Main.vue | 7 ++-- .../src/meta/block/src/BlockGroup.vue | 5 ++- .../src/meta/block/src/BlockGroupFilters.vue | 5 ++- .../src/meta/block/src/BlockGroupSort.vue | 3 +- packages/plugins/page/src/PageHome.vue | 3 +- packages/plugins/page/src/PageInputOutput.vue | 3 +- .../plugins/robot/src/RobotSettingPopover.vue | 41 ++++++++++++++----- .../plugins/robot/src/RobotTypeSelect.vue | 3 +- packages/plugins/schema/src/Main.vue | 5 ++- .../plugins/state/src/CreateRemoteAPI.vue | 7 ++-- .../state/src/DataSourceRightPanel.vue | 3 +- packages/plugins/state/src/EditorI18nTool.vue | 5 ++- packages/plugins/state/src/Main.vue | 3 +- .../design/src/components/PropertyCanvas.vue | 7 ++-- .../design/src/components/PropertyList.vue | 5 ++- .../design/src/components/SettingPanel.vue | 5 ++- .../events/src/components/AdvanceConfig.vue | 5 ++- .../events/src/components/BindEvents.vue | 7 ++-- .../components/BindEventsDialogContent.vue | 5 ++- .../props/src/components/groups/LifeCycle.vue | 9 ++-- .../src/components/inputs/CheckValue.vue | 5 ++- .../background/BackgroundImageGradient.vue | 5 ++- .../background/BackgroundImageSetting.vue | 5 ++- packages/toolbars/breadcrumb/src/Main.vue | 3 +- packages/toolbars/collaboration/src/Main.vue | 5 ++- packages/toolbars/media/src/Main.vue | 3 +- packages/toolbars/redoundo/src/Main.vue | 3 +- packages/toolbars/save/src/Main.vue | 7 ++-- packages/toolbars/themeSwitch/src/Main.vue | 5 ++- 70 files changed, 222 insertions(+), 132 deletions(-) diff --git a/packages/common/component/BlockDeployDialog.vue b/packages/common/component/BlockDeployDialog.vue index 107f6d4ade..08cd385163 100644 --- a/packages/common/component/BlockDeployDialog.vue +++ b/packages/common/component/BlockDeployDialog.vue @@ -72,6 +72,7 @@ `) @@ -9,6 +9,7 @@ export function initCanvas(importMap = {}, importStyleUrls = []) { '', importStyleUrls.map((styleUrl) => ``).join('\n') ) + .replace('', importScripts.map((script) => ``).join('\n')) .replace('', () => { if (import.meta.env.MODE === 'development') { return `` diff --git a/packages/common/composable/generateCode/index.ts b/packages/common/composable/generateCode/index.ts index bb5105f05b..505a9e1acb 100644 --- a/packages/common/composable/generateCode/index.ts +++ b/packages/common/composable/generateCode/index.ts @@ -1,29 +1,46 @@ -import { - generateApp, - parseRequiredBlocks, - genSFCWithDefaultPlugin, - type IAppSchema -} from '@opentiny/tiny-engine-dsl-vue' +import { generateApp, type IAppSchema } from '@opentiny/tiny-engine-dsl-vue' +import * as dslVue from '@opentiny/tiny-engine-dsl-vue' +import { getMergeMeta } from '@opentiny/tiny-engine-meta-register' import defaultPrettierConfig from '../../js/config-files/prettierrc' // 应用出码默认配置 const defaultOptions = { pluginConfig: { + template: {}, + block: {}, + page: {}, + dataSource: {}, + dependencies: {}, + globalState: {}, + i18n: {}, + router: {}, + utils: {}, formatCode: { // 默认格式化配置 ...defaultPrettierConfig - } + }, + parseSchema: {} } } // 应用出码 const generateAppCode = async (appSchema: IAppSchema, options = {}) => { - const instance = generateApp({ ...defaultOptions, ...options }) + const enableTailwindCSS = getMergeMeta('engine.config')?.enableTailwindCSS + const instance = generateApp({ + ...defaultOptions, + pluginConfig: { + ...defaultOptions.pluginConfig, + template: { ...defaultOptions.pluginConfig.template, enableTailwindCSS } + }, + ...options + }) return instance.generate(appSchema) } // 页面出码 +const { parseRequiredBlocks, genSFCWithDefaultPlugin } = dslVue as any + const generatePageCode = (...args: any[]) => { return genSFCWithDefaultPlugin(...args) } @@ -53,10 +70,14 @@ const getAllNestedBlocksSchema = async (pageSchema: any, fetchBlockSchemaApi: an const schemaList = await Promise.allSettled(promiseList) const extraList: any[] = [] - schemaList.forEach((item: { value: any[]; status: string }) => { - const blockItem = item.value?.[0] + schemaList.forEach((item) => { + if (item.status !== 'fulfilled') { + return + } + + const blockItem = (item.value as any[])?.[0] - if (item.status !== 'fulfilled' || !blockItem) { + if (!blockItem) { return } diff --git a/packages/common/js/import-map.json b/packages/common/js/import-map.json index eb278fcf67..5895d7b983 100644 --- a/packages/common/js/import-map.json +++ b/packages/common/js/import-map.json @@ -17,7 +17,8 @@ "@opentiny/vue-common": "${VITE_CDN_DOMAIN}/@opentiny/vue-runtime${versionDelimiter}~3.20${fileDelimiter}/dist3/tiny-vue-common.mjs", "@opentiny/vue-locale": "${VITE_CDN_DOMAIN}/@opentiny/vue-runtime${versionDelimiter}~3.20${fileDelimiter}/dist3/tiny-vue-locale.mjs", "@opentiny/vue-renderless/": "${VITE_CDN_DOMAIN}/@opentiny/vue-renderless${versionDelimiter}~3.20${fileDelimiter}/", - "echarts": "${VITE_CDN_DOMAIN}/echarts${versionDelimiter}5.4.1${fileDelimiter}/dist/echarts.esm.js" + "echarts": "${VITE_CDN_DOMAIN}/echarts${versionDelimiter}5.4.1${fileDelimiter}/dist/echarts.esm.js", + "@tailwindcss/browser": "${VITE_CDN_DOMAIN}/@tailwindcss/browser${versionDelimiter}^4${fileDelimiter}/dist/index.global.js" }, "importStyles": { "@opentiny/vue-theme": "${VITE_CDN_DOMAIN}/@opentiny/vue-theme${versionDelimiter}~3.20${fileDelimiter}/index.css" diff --git a/packages/configurator/src/basic-tag-configurator/BasicTagConfigurator.vue b/packages/configurator/src/basic-tag-configurator/BasicTagConfigurator.vue new file mode 100644 index 0000000000..7d11dc6837 --- /dev/null +++ b/packages/configurator/src/basic-tag-configurator/BasicTagConfigurator.vue @@ -0,0 +1,317 @@ + + + + + diff --git a/packages/configurator/src/class-configurator/ClassConfigurator.vue b/packages/configurator/src/class-configurator/ClassConfigurator.vue new file mode 100644 index 0000000000..6b0cbc2092 --- /dev/null +++ b/packages/configurator/src/class-configurator/ClassConfigurator.vue @@ -0,0 +1,95 @@ + + + diff --git a/packages/configurator/src/index.ts b/packages/configurator/src/index.ts index ecb870b853..0779781377 100644 --- a/packages/configurator/src/index.ts +++ b/packages/configurator/src/index.ts @@ -29,6 +29,8 @@ import SwitchConfigurator from './switch-configurator/SwitchConfigurator.vue' import TableColumnsConfigurator from './table-columns-configurator/TableColumnsConfigurator.vue' import TabsGroupConfigurator from './tabs-group-configurator/TabsGroupConfigurator.vue' import VariableConfigurator from './variable-configurator/VariableConfigurator.vue' +import BasicTagConfigurator from './basic-tag-configurator/BasicTagConfigurator.vue' +import ClassConfigurator from './class-configurator/ClassConfigurator.vue' import { I18nInput, MetaCodeEditor } from '@opentiny/tiny-engine-common' import './styles/vars.less' @@ -65,6 +67,8 @@ export { TableColumnsConfigurator, TabsGroupConfigurator, VariableConfigurator, + BasicTagConfigurator, + ClassConfigurator, MetaCodeEditor, I18nInput as I18nConfigurator, MetaCodeEditor as CodeConfigurator, diff --git a/packages/design-core/registry.js b/packages/design-core/registry.js index ce278dafc1..a12711d3fc 100644 --- a/packages/design-core/registry.js +++ b/packages/design-core/registry.js @@ -128,7 +128,8 @@ export default { icon: 'dark', oppositeTheme: 'light' } - ] + ], + enableTailwindCSS: true }, layout: __TINY_ENGINE_REMOVED_REGISTRY['engine.layout'] === false ? null : Layout, toolbars: [ diff --git a/packages/design-core/src/preview/src/preview/generate.js b/packages/design-core/src/preview/src/preview/generate.js index 5a3fa46948..61dcd5726a 100644 --- a/packages/design-core/src/preview/src/preview/generate.js +++ b/packages/design-core/src/preview/src/preview/generate.js @@ -150,18 +150,20 @@ const compatibleI18n = (i18n) => { * @param {*} cssList css文件 * @returns */ -export const processAppJsCode = (code, cssList) => { - if (!Array.isArray(cssList) || !cssList.length) { - return code - } - +export const processAppJsCode = (code, cssList, enableTailwindCSS) => { let res = `${code}\n` - cssList.forEach((css) => { - if (!code.includes(`addCss('${css}')`)) { - res += `addCss('${css}')\n` - } - }) + if (Array.isArray(cssList) && cssList.length) { + cssList.forEach((css) => { + if (!code.includes(`addCss('${css}')`)) { + res += `addCss('${css}')\n` + } + }) + } + + if (enableTailwindCSS && !code.includes('@tailwindcss/browser')) { + res += `\nimport('@tailwindcss/browser')\n` + } return res } diff --git a/packages/design-core/src/preview/src/preview/importMap.js b/packages/design-core/src/preview/src/preview/importMap.js index c99c1c117f..27ff506010 100644 --- a/packages/design-core/src/preview/src/preview/importMap.js +++ b/packages/design-core/src/preview/src/preview/importMap.js @@ -14,7 +14,6 @@ import { useEnv } from '@opentiny/tiny-engine-meta-register' import { importMapConfig as importMapJSON } from '@opentiny/tiny-engine-common/js/importMap' const importMap = {} - const opentinyVueVersion = '~3.20' function replacePlaceholder(v) { diff --git a/packages/design-core/src/preview/src/preview/usePreviewData.ts b/packages/design-core/src/preview/src/preview/usePreviewData.ts index 637914c568..c696fe6294 100644 --- a/packages/design-core/src/preview/src/preview/usePreviewData.ts +++ b/packages/design-core/src/preview/src/preview/usePreviewData.ts @@ -392,7 +392,8 @@ export const usePreviewData = ({ setFiles, store, setImportMap }: IUsePreviewDat ] const newFiles = store.getFiles() - const appJsCode = processAppJsCode(newFiles['app.js'], params.styles) + const enableTailwindCSS = getMergeMeta('engine.config')?.enableTailwindCSS + const appJsCode = processAppJsCode(newFiles['app.js'] || '', params.styles, enableTailwindCSS) newFiles['app.js'] = appJsCode diff --git a/packages/design-core/src/preview/src/previewDefaultRegistry.js b/packages/design-core/src/preview/src/previewDefaultRegistry.js index bcb5a04038..d2b67b89e2 100644 --- a/packages/design-core/src/preview/src/previewDefaultRegistry.js +++ b/packages/design-core/src/preview/src/previewDefaultRegistry.js @@ -86,7 +86,8 @@ export default { icon: 'dark', oppositeTheme: 'light' } - ] + ], + enableTailwindCSS: true }, toolbars: [Breadcrumb, Media, Lang] } diff --git a/packages/plugins/materials/src/js/options.ts b/packages/plugins/materials/src/js/options.ts index 87385e7262..5d5896eb7b 100644 --- a/packages/plugins/materials/src/js/options.ts +++ b/packages/plugins/materials/src/js/options.ts @@ -35,7 +35,7 @@ export const basePropertyOptions = { cols: 12, rules: [], widget: { - component: 'InputConfigurator', + component: 'ClassConfigurator', props: {} }, labelPosition: 'left' diff --git a/packages/vue-generator/src/plugins/genTemplatePlugin.js b/packages/vue-generator/src/plugins/genTemplatePlugin.js index 159c331af9..5ce90ba6e9 100644 --- a/packages/vue-generator/src/plugins/genTemplatePlugin.js +++ b/packages/vue-generator/src/plugins/genTemplatePlugin.js @@ -25,12 +25,12 @@ function genTemplatePlugin(options = {}) { } if (typeof template === 'function') { - context.genResult.push(...(template(schema) || [])) + context.genResult.push(...(template(schema, options) || [])) return } if (templateMap[template]) { - context.genResult.push(...templateMap[template](schema)) + context.genResult.push(...templateMap[template](schema, options)) } } } diff --git a/packages/vue-generator/src/templates/vue-template/index.js b/packages/vue-generator/src/templates/vue-template/index.js index 90577077dd..0380e44650 100644 --- a/packages/vue-generator/src/templates/vue-template/index.js +++ b/packages/vue-generator/src/templates/vue-template/index.js @@ -4,7 +4,7 @@ import getPackageJson from './templateFiles/packageJson' import gitIgnoreFile from './templateFiles/.gitignore?raw' import entryHTMLFile from './templateFiles/index.html?raw' import logoImage from './templateFiles/public/favicon.ico' -import mainJSFile from './templateFiles/src/main.js?raw' +import mainJSFile from './templateFiles/src/main.js' import appVueFile from './templateFiles/src/App.vue?raw' import bridgeFile from './templateFiles/src/lowcodeConfig/bridge.js?raw' import dataSourceFile from './templateFiles/src/lowcodeConfig/dataSource.js?raw' @@ -13,6 +13,7 @@ import lowcodeStoreFile from './templateFiles/src/lowcodeConfig/store.js?raw' import axiosFile from './templateFiles/src/http/axios.js?raw' import axiosConfigFile from './templateFiles/src/http/config.js?raw' import httpEntryFile from './templateFiles/src/http/index.js?raw' +import styleCSSFile from './templateFiles/src/style.css?raw' /** * 模板写入动态内容 @@ -79,7 +80,7 @@ const base64ToBlob = (base64Data) => { * get project template * @returns */ -export function generateTemplate(schema) { +export function generateTemplate(schema, options) { const res = [ { fileType: 'md', @@ -91,13 +92,13 @@ export function generateTemplate(schema) { fileType: 'js', fileName: 'vite.config.js', path: '.', - fileContent: genViteConfig(schema) + fileContent: genViteConfig(schema, options) }, { fileType: 'json', fileName: 'package.json', path: '.', - fileContent: getPackageJson(schema) + fileContent: getPackageJson(schema, options) }, { fileName: '.gitignore', @@ -114,7 +115,7 @@ export function generateTemplate(schema) { fileType: 'js', fileName: 'main.js', path: './src', - fileContent: getTemplate(schema, mainJSFile) + fileContent: getTemplate(schema, mainJSFile(options)) }, { fileType: 'vue', @@ -166,6 +167,15 @@ export function generateTemplate(schema) { } ] + if (options?.enableTailwindCSS) { + res.push({ + fileType: 'css', + fileName: 'style.css', + path: './src', + fileContent: styleCSSFile + }) + } + try { const faviconData = base64ToBlob(logoImage) diff --git a/packages/vue-generator/src/templates/vue-template/templateFiles/genViteConfig.js b/packages/vue-generator/src/templates/vue-template/templateFiles/genViteConfig.js index 99dde75cd1..9d92ddcd56 100644 --- a/packages/vue-generator/src/templates/vue-template/templateFiles/genViteConfig.js +++ b/packages/vue-generator/src/templates/vue-template/templateFiles/genViteConfig.js @@ -1,4 +1,4 @@ -export default () => { +export default (schema, options) => { // 避免在构建的时候,被 process. env 替换 const processStr = ['process', 'env'] @@ -7,6 +7,7 @@ export default () => { import path from 'path' import vue from '@vitejs/plugin-vue' import vueJsx from '@vitejs/plugin-vue-jsx' + ${options.enableTailwindCSS ? 'import tailwindcss from "@tailwindcss/vite"' : ''} export default defineConfig({ resolve: { @@ -14,7 +15,7 @@ export default () => { '@': path.resolve(__dirname, 'src') } }, - plugins: [vue(), vueJsx()], + plugins: [vue(), vueJsx(), ${options.enableTailwindCSS ? 'tailwindcss()' : ''}], define: { '${processStr.join('.')}': { ...${processStr.join('.')} } }, diff --git a/packages/vue-generator/src/templates/vue-template/templateFiles/packageJson.js b/packages/vue-generator/src/templates/vue-template/templateFiles/packageJson.js index 09bb44b68e..78d521bb91 100644 --- a/packages/vue-generator/src/templates/vue-template/templateFiles/packageJson.js +++ b/packages/vue-generator/src/templates/vue-template/templateFiles/packageJson.js @@ -1,5 +1,5 @@ // 这里 package.json 格式设置为 js,避免被识别成一个 package -export default (schema) => { +export default (schema, options = {}) => { const packageName = schema?.meta?.name || '@opentiny/tiny-engine-preview-vue' const res = { @@ -31,5 +31,10 @@ export default (schema) => { } } + if (options?.enableTailwindCSS) { + res.dependencies['tailwindcss'] = '^4.1.12' + res.devDependencies['@tailwindcss/vite'] = '^4.1.12' + } + return JSON.stringify(res) } diff --git a/packages/vue-generator/src/templates/vue-template/templateFiles/src/main.js b/packages/vue-generator/src/templates/vue-template/templateFiles/src/main.js index c4574461b3..d9d26cec03 100644 --- a/packages/vue-generator/src/templates/vue-template/templateFiles/src/main.js +++ b/packages/vue-generator/src/templates/vue-template/templateFiles/src/main.js @@ -10,11 +10,17 @@ * */ +export default (options) => { + return ` import { createApp } from 'vue' import router from './router' import { createPinia } from 'pinia' import App from './App.vue' +${options.enableTailwindCSS ? 'import "./style.css"' : ''} + const pinia = createPinia() createApp(App).use(pinia).use(router).mount('#app') + ` +} diff --git a/packages/vue-generator/src/templates/vue-template/templateFiles/src/style.css b/packages/vue-generator/src/templates/vue-template/templateFiles/src/style.css new file mode 100644 index 0000000000..a461c505f1 --- /dev/null +++ b/packages/vue-generator/src/templates/vue-template/templateFiles/src/style.css @@ -0,0 +1 @@ +@import "tailwindcss"; \ No newline at end of file From 746a60dbfafacb5b84859a8ef5bcab1917563403 Mon Sep 17 00:00:00 2001 From: chilingling <26962197+chilingling@users.noreply.github.com> Date: Wed, 17 Sep 2025 07:41:21 +0800 Subject: [PATCH 048/101] chore: update gencode template deps version (#1620) --- .../templates/vue-template/templateFiles/genViteConfig.js | 2 +- .../templates/vue-template/templateFiles/packageJson.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/vue-generator/src/templates/vue-template/templateFiles/genViteConfig.js b/packages/vue-generator/src/templates/vue-template/templateFiles/genViteConfig.js index 9d92ddcd56..4bd5538ad5 100644 --- a/packages/vue-generator/src/templates/vue-template/templateFiles/genViteConfig.js +++ b/packages/vue-generator/src/templates/vue-template/templateFiles/genViteConfig.js @@ -17,7 +17,7 @@ export default (schema, options) => { }, plugins: [vue(), vueJsx(), ${options.enableTailwindCSS ? 'tailwindcss()' : ''}], define: { - '${processStr.join('.')}': { ...${processStr.join('.')} } + '${processStr.join('.')}': { } }, build: { minify: true, diff --git a/packages/vue-generator/src/templates/vue-template/templateFiles/packageJson.js b/packages/vue-generator/src/templates/vue-template/templateFiles/packageJson.js index 78d521bb91..d3fc72c94b 100644 --- a/packages/vue-generator/src/templates/vue-template/templateFiles/packageJson.js +++ b/packages/vue-generator/src/templates/vue-template/templateFiles/packageJson.js @@ -14,10 +14,10 @@ export default (schema, options = {}) => { main: 'dist/index.js', module: 'dist/index.js', dependencies: { - '@opentiny/tiny-engine-i18n-host': '^1.0.0', - '@opentiny/vue': '^3.10.0', - '@opentiny/vue-icon': '^3.10.0', - axios: '^0.21.1', + '@opentiny/tiny-engine-i18n-host': '^2.8.0', + '@opentiny/vue': '^3.20.0', + '@opentiny/vue-icon': '^3.20.0', + axios: '^0.30.1', 'axios-mock-adapter': '^1.19.0', vue: '^3.3.9', 'vue-i18n': '^9.2.0-beta.3', From f5fb03619faf846c609322b96be79f4e860bbf7e Mon Sep 17 00:00:00 2001 From: chilingling <26962197+chilingling@users.noreply.github.com> Date: Wed, 17 Sep 2025 14:50:23 +0800 Subject: [PATCH 049/101] chore: delete webcomponent package (#1583) --- .../src/vite-plugins/devAliasPlugin.js | 1 - packages/webcomponent/README.md | 2 - packages/webcomponent/package.json | 42 --- .../webcomponent/src/defineCustomElement.js | 279 ------------------ packages/webcomponent/src/lib.js | 15 - packages/webcomponent/vite.config.js | 46 --- tsconfig.app.json | 3 +- 7 files changed, 1 insertion(+), 387 deletions(-) delete mode 100644 packages/webcomponent/README.md delete mode 100644 packages/webcomponent/package.json delete mode 100644 packages/webcomponent/src/defineCustomElement.js delete mode 100644 packages/webcomponent/src/lib.js delete mode 100644 packages/webcomponent/vite.config.js diff --git a/packages/build/vite-config/src/vite-plugins/devAliasPlugin.js b/packages/build/vite-config/src/vite-plugins/devAliasPlugin.js index 67783ab22b..2756343cc2 100644 --- a/packages/build/vite-config/src/vite-plugins/devAliasPlugin.js +++ b/packages/build/vite-config/src/vite-plugins/devAliasPlugin.js @@ -54,7 +54,6 @@ const getDevAlias = (useSourceAlias) => { '@opentiny/tiny-engine-canvas/render': path.resolve(basePath, 'packages/canvas/render/index.ts'), '@opentiny/tiny-engine-canvas': path.resolve(basePath, 'packages/canvas/index.ts'), '@opentiny/tiny-engine-utils': path.resolve(basePath, 'packages/utils/src/index.ts'), - '@opentiny/tiny-engine-webcomponent-core': path.resolve(basePath, 'packages/webcomponent/src/lib.js'), '@opentiny/tiny-engine-i18n-host': path.resolve(basePath, 'packages/i18n/src/lib.ts'), '@opentiny/tiny-engine-builtin-component': path.resolve(basePath, 'packages/builtinComponent/index.ts'), '@opentiny/tiny-engine-meta-register': path.resolve(basePath, 'packages/register/src/index.ts'), diff --git a/packages/webcomponent/README.md b/packages/webcomponent/README.md deleted file mode 100644 index 4f6b9df812..0000000000 --- a/packages/webcomponent/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# lowcode-webcomponent - diff --git a/packages/webcomponent/package.json b/packages/webcomponent/package.json deleted file mode 100644 index 07733fe9f5..0000000000 --- a/packages/webcomponent/package.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "name": "@opentiny/tiny-engine-webcomponent-core", - "version": "2.8.0", - "publishConfig": { - "access": "public" - }, - "description": "webcomponent vue core", - "scripts": { - "dev": "vite", - "build": "vite build", - "format": "prettier --write **/*{.vue,.js,.ts,.html,.json}", - "publish:npm": "npm run build && npm publish --verbose" - }, - "files": [ - "dist" - ], - "type": "module", - "main": "dist/tiny-engine-webcomponent-core.umd.js", - "module": "dist/tiny-engine-webcomponent-core.es.js", - "repository": { - "type": "git", - "url": "https://github.com/opentiny/tiny-engine", - "directory": "packages/webcomponent" - }, - "bugs": { - "url": "https://github.com/opentiny/tiny-engine/issues" - }, - "author": "OpenTiny Team", - "license": "MIT", - "homepage": "https://opentiny.design/tiny-engine", - "dependencies": { - "@vue/shared": "^3.3.4" - }, - "devDependencies": { - "@vitejs/plugin-vue": "^5.1.2", - "prettier": "^2.4.0", - "vite": "^5.4.2" - }, - "peerDependencies": { - "vue": "^3.4.15" - } -} diff --git a/packages/webcomponent/src/defineCustomElement.js b/packages/webcomponent/src/defineCustomElement.js deleted file mode 100644 index 1c05933225..0000000000 --- a/packages/webcomponent/src/defineCustomElement.js +++ /dev/null @@ -1,279 +0,0 @@ -/** - * Copyright (c) 2023 - present TinyEngine Authors. - * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd. - * - * Use of this source code is governed by an MIT-style license. - * - * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, - * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR - * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. - * - */ - -import { defineComponent, render, nextTick, createVNode } from 'vue' -import { camelize, hyphenate, toNumber, extend, isArray } from '@vue/shared' - -const BaseLowcodeClass = typeof HTMLElement !== 'undefined' ? HTMLElement : class {} - -class LowcodeVueElement extends BaseLowcodeClass { - constructor(_def, _props = {}) { - super() - this._def = _def - this._props = _props - - /** - * @internal - */ - this._numberProps = null - this._cbConnected = false - this._instance = null - this._resolved = false - - this.attachShadow({ mode: 'open' }) - } - - disconnectedCallback() { - this._cbConnected = false - - nextTick(() => { - if (!this._cbConnected) { - render(null, this.shadowRoot) - this._instance = null - } - }) - } - - connectedCallback() { - this._cbConnected = true - - if (!this._instance) { - this._resolveLowcodeDef() - } - } - - _resolveLowcodeDef() { - if (this._resolved) { - return - } - - this._resolved = true - - const attributes = [...this.attributes] - - attributes.forEach(({ name }) => { - this._setAttr(name) - }) - - new MutationObserver((mutations) => { - for (const m of mutations) { - this._setAttr(m.attributeName) - } - }).observe(this, { attributes: true }) - - const resolve = (def) => { - const { props, styles, links } = def - const hasOptions = props && !isArray(props) - const realProps = hasOptions ? Object.keys(props) : props - const propsKeys = props ? realProps : [] - let numberProps - - if (hasOptions) { - for (const key in this._props) { - if (Object.prototype.hasOwnProperty.call(this._props, key)) { - const opt = props[key] - - if (opt === Number || (opt && opt.type === Number)) { - this._props[key] = toNumber(this._props[key]) - ;(numberProps || (numberProps = Object.create(null)))[key] = true - } - } - } - } - - this._numberProps = numberProps - - for (const key of Object.keys(this)) { - if (key[0] !== '_') { - this._setProp(key, this[key], true, false) - } - } - - for (const key of propsKeys.map(camelize)) { - Object.defineProperty(this, key, { - get() { - return this._getDefProp(key) - }, - set(value) { - this._setProp(key, value) - } - }) - } - - this._addStyles(styles) - this._applyLinks(links) - this._update() - } - - const asyncDef = this._def.__asyncLoader - - if (asyncDef) { - asyncDef().then(resolve) - } else { - resolve(this._def) - } - } - - _setAttr(key) { - let value = this.getAttribute(key) - - if (this._numberProps && this._numberProps[key]) { - value = toNumber(value) - } - - this._setProp(camelize(key), value, false) - } - - /** - * @internal - */ - _getDefProp(key) { - return this._props[key] - } - - _setProp(key, value, shouldReflect = true, shouldUpdate = true) { - if (value !== this._props[key]) { - if (value === 'true') { - value = true - } - if (value === 'false') { - value = false - } - - this._props[key] = value - - if (shouldUpdate && this._instance) { - this._update() - } - - // reflect - if (shouldReflect) { - if (value === true) { - this.setAttribute(hyphenate(key), '') - } else if (typeof value === 'string' || typeof value === 'number') { - this.setAttribute(hyphenate(key), String(value)) - } else if (!value) { - this.removeAttribute(hyphenate(key)) - } - } - } - } - - _setProps(props, shouldReflect = true, shouldUpdate = true) { - let bChange = false - - Object.entries(props).forEach(([key, value]) => { - if (value !== this._props[key]) { - bChange = true - - this._setProp(key, value, shouldReflect, false) - } - }) - - if (bChange && shouldUpdate && this._instance) { - this._update() - } - } - - _update() { - render(this._createLowcodeVNode(), this.shadowRoot) - } - - _createLowcodeVNode() { - const vnode = createVNode(this._def, extend({}, this._props)) - - if (!this._instance) { - // eslint-disable-next-line @typescript-eslint/no-this-alias - const dom = this - - vnode.ce = (instance) => { - this._instance = instance - instance.isCE = true - // HMR - instance.ceReload = (styles) => { - if (this._styles) { - this._styles.forEach((s) => this.shadowRoot.removeChild(s)) - this._styles.length = 0 - } - this._addStyles(styles) - if (!this._def.__asyncLoader) { - this._instance = null - this._update() - } - } - instance.emit = (event, ...args) => { - this.dispatchEvent( - new CustomEvent(event, { - detail: args - }) - ) - } - instance.updateProp = (key, value) => { - dom[key] = value - dom._props[key] = value - instance.attrs[key] = value - } - instance.domProps = dom._props - // eslint-disable-next-line @typescript-eslint/no-this-alias - let parent = this - - while ((parent = parent && (parent.parentNode || parent.host))) { - if (parent instanceof LowcodeVueElement) { - instance.parent = parent._instance - - break - } - } - } - } - return vnode - } - - _addStyles(styles) { - if (styles) { - styles.forEach((css) => { - const s = document.createElement('style') - - s.textContent = css - this.shadowRoot.appendChild(s) - ;(this._styles || (this._styles = [])).push(s) - }) - } - } - - _applyLinks(links) { - const appendStyle = (href) => { - const l = document.createElement('link') - l.href = href - l.rel = 'stylesheet' - this.shadowRoot.appendChild(l) - } - - // 支持在组件中指定样式文件 links - if (links && isArray(links)) { - links.forEach(appendStyle) - } - } -} - -export default function defineCustomElement(options) { - const Component = defineComponent(options) - class LowcodeVueCustomElement extends LowcodeVueElement { - constructor(props) { - super(Component, props) - } - } - - LowcodeVueCustomElement.def = Component - - return LowcodeVueCustomElement -} diff --git a/packages/webcomponent/src/lib.js b/packages/webcomponent/src/lib.js deleted file mode 100644 index 19f1f07b24..0000000000 --- a/packages/webcomponent/src/lib.js +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Copyright (c) 2023 - present TinyEngine Authors. - * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd. - * - * Use of this source code is governed by an MIT-style license. - * - * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, - * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR - * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. - * - */ - -import defineCustomElement from './defineCustomElement' - -export { defineCustomElement } diff --git a/packages/webcomponent/vite.config.js b/packages/webcomponent/vite.config.js deleted file mode 100644 index 370297c61c..0000000000 --- a/packages/webcomponent/vite.config.js +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright (c) 2023 - present TinyEngine Authors. - * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd. - * - * Use of this source code is governed by an MIT-style license. - * - * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, - * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR - * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. - * - */ - -import { defineConfig } from 'vite' -import vue from '@vitejs/plugin-vue' -import path from 'path' - -// https://vitejs.dev/config/ -export default defineConfig({ - plugins: [vue()], - define: {}, - build: { - sourcemap: true, - minify: false, - emptyOutDir: true, - lib: { - entry: path.resolve(__dirname, './src/lib.js'), - name: 'LowcodeDesignWebcomponentCore', - formats: ['es', 'umd'], - fileName: (format) => `tiny-engine-webcomponent-core.${format}.js` - }, - commonjsOptions: { - transformMixedEsModules: true - }, - rollupOptions: { - // 确保外部化处理那些你不想打包进库的依赖 - external: ['vue', 'vue-i18n'], - output: { - // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量 - globals: { - vue: 'Vue', - 'vue-i18n': 'VueI18n' - } - } - } - } -}) diff --git a/tsconfig.app.json b/tsconfig.app.json index 2554b8449f..65003a243b 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -51,8 +51,7 @@ "@opentiny/tiny-engine-toolbar-save": ["packages/toolbars/save/index"], "@opentiny/tiny-engine-toolbar-theme-switch": ["packages/toolbars/themeSwitch/index"], "@opentiny/tiny-engine-toolbar-view-setting": ["packages/toolbars/view-setting/index"], - "@opentiny/tiny-engine-utils": ["packages/utils/src/index"], - "@opentiny/tiny-engine-webcomponent-core": ["packages/webcomponent/src/lib"] + "@opentiny/tiny-engine-utils": ["packages/utils/src/index"] } }, "include": ["packages/**/*"], From 4d8bb53f74e3caea4a2af1372c9ca5bcf3b9d4da Mon Sep 17 00:00:00 2001 From: lichunn <46984087+lichunn@users.noreply.github.com> Date: Wed, 17 Sep 2025 20:22:22 +0800 Subject: [PATCH 050/101] =?UTF-8?q?Feat=EF=BC=9AAdjust=20the=20AI=20buildi?= =?UTF-8?q?ng=20interface=20parameters=20and=20add=20a=20cancel=20function?= =?UTF-8?q?=20(#1633)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat:AI搭建添加撤销 * feat:AI搭建添加撤销 * feat:修改AI搭建参数 --- packages/plugins/robot/src/Main.vue | 26 ++++++++++++++----------- packages/plugins/robot/src/mcp/types.ts | 1 + packages/plugins/robot/src/mcp/utils.ts | 1 + 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/packages/plugins/robot/src/Main.vue b/packages/plugins/robot/src/Main.vue index 16deb1dbee..16d9a720a2 100644 --- a/packages/plugins/robot/src/Main.vue +++ b/packages/plugins/robot/src/Main.vue @@ -122,7 +122,7 @@ import { type Component } from 'vue' import { Notify, Loading, TinyPopover, TinyDialogBox } from '@opentiny/vue' -import { useCanvas, useModal, getMetaApi, META_SERVICE } from '@opentiny/tiny-engine-meta-register' +import { useHistory, useCanvas, useModal, getMetaApi, META_SERVICE } from '@opentiny/tiny-engine-meta-register' import { ToolbarBase } from '@opentiny/tiny-engine-common' import { TrContainer, @@ -321,6 +321,7 @@ export default { const newValue = JSON.parse(match[1]) // 使用 applyPatch 修改 Schema const result = newValue.reduce(jsonpatch.applyReducer, currentJson) + useHistory().addHistory() sessionProcess.messages.push(getAiRespMessage(JSON.stringify(result, null, 2), chatMessage.role)) sessionProcess.displayMessages.push(getAiDisplayMessage(MESSAGE_TIP, chatMessage.role, result, id)) @@ -360,7 +361,8 @@ export default { model: selectedModel.value.model, headers: { Authorization: `Bearer ${selectedModel.value.apiKey || import.meta.env.VITE_API_TOKEN}` - } + }, + baseUrl: selectedModel.value.baseUrl }) } catch (error) { const { renderContent } = messages.value.at(-1)! @@ -382,8 +384,13 @@ export default { } return } else { - if (requestData.foundationModel) { - requestData.foundationModel.stream = true + const params = { + label: requestData.foundationModel?.label, + baseUrl: requestData.foundationModel?.baseUrl, + model: requestData.foundationModel?.model, + apiKey: requestData.foundationModel?.apiKey, + stream: true, + messages: requestData.messages } let streamContent = '' @@ -394,7 +401,7 @@ export default { await chatStream( { requestUrl: '/app-center/api/ai/chat', - requestData: { ...requestData.foundationModel, messages: requestData.messages } + requestData: params }, { onData: (data) => { @@ -617,7 +624,6 @@ export default { activeName: model.activeName, baseUrl: model.baseUrl, model: model.model, - maxTokens: model.maxTokens, apiKey: model.apiKey } singleAttachmentItems.value = [] @@ -712,20 +718,18 @@ export default { // 开始上传 const formData = new FormData() const fileData = retry ? files : files[0] - formData.append('modelName', String(sessionProcess.foundationModel.model)) - formData.append('apiKey', String(sessionProcess.foundationModel.apiKey)) formData.append('file', fileData) try { getMetaApi(META_SERVICE.Http) - .post('/app-center/api/ai/uploadFile', formData, { + .post('/material-center/api/resource/upload', formData, { headers: { 'Content-Type': 'multipart/form-data' } }) .then((res) => { - if (res?.url) { - imageUrl.value = res.url + if (res?.resourceUrl) { + imageUrl.value = res.resourceUrl singleAttachmentItems.value[0].status = 'done' singleAttachmentItems.value[0].isUploading = false singleAttachmentItems.value[0].messageType = 'success' diff --git a/packages/plugins/robot/src/mcp/types.ts b/packages/plugins/robot/src/mcp/types.ts index 3fad7339d0..781523f3e0 100644 --- a/packages/plugins/robot/src/mcp/types.ts +++ b/packages/plugins/robot/src/mcp/types.ts @@ -41,6 +41,7 @@ export interface RobotMessage { } export interface LLMRequestBody { + baseUrl?: string model?: string stream: boolean messages: LLMMessage[] diff --git a/packages/plugins/robot/src/mcp/utils.ts b/packages/plugins/robot/src/mcp/utils.ts index 349313c5c4..02ba2dfde7 100644 --- a/packages/plugins/robot/src/mcp/utils.ts +++ b/packages/plugins/robot/src/mcp/utils.ts @@ -16,6 +16,7 @@ const formatMessages = (messages: LLMMessage[]) => { const fetchLLM = async (messages: LLMMessage[], tools: RequestTool[], options: RequestOptions = requestOptions) => { const bodyObj: LLMRequestBody = { + baseUrl: options.baseUrl, model: options?.model || 'deepseek-chat', stream: false, messages: toRaw(messages) From 01722bce28ea10c87a5039f422a6ff30418f9440 Mon Sep 17 00:00:00 2001 From: betterdancing Date: Thu, 18 Sep 2025 01:51:22 +0800 Subject: [PATCH 051/101] feat: Add Model Components & Model Manage Plugin & Model Use Configurator (#1625) --- docs/api/frontend-api/main-package-api.md | 1 + .../src/vite-plugins/devAliasPlugin.js | 1 + packages/builtinComponent/index.ts | 3 + packages/builtinComponent/package.json | 4 + .../src/components/BaseForm.vue | 242 +++ .../src/components/BasePage.vue | 533 +++++ .../src/components/BaseTable.vue | 269 +++ .../builtinComponent/src/meta/BaseForm.json | 1158 +++++++++++ .../builtinComponent/src/meta/BasePage.json | 1666 +++++++++++++++ .../builtinComponent/src/meta/BaseTable.json | 1792 +++++++++++++++++ packages/builtinComponent/src/meta/index.js | 15 +- .../src/material-function/material-getter.ts | 8 +- packages/configurator/package.json | 2 + .../BindVariableConfigurator.vue | 108 + packages/configurator/src/index.ts | 8 + .../ModelApiConfigurator.vue | 322 +++ .../model-api-configurator/ParamsBindGrid.vue | 58 + .../src/model-common/ModelSelect.vue | 147 ++ .../src/model-common/constants.js | 23 + .../configurator/src/model-common/http.js | 6 + .../configurator/src/model-common/utils.js | 52 + .../src/model-configurator/MetaListItem.vue | 258 +++ .../model-configurator/ModelConfigurator.vue | 513 +++++ .../MetaChildItem.vue | 121 ++ .../operator-group-configurator/MetaList.vue | 21 + .../MetaListItem.vue | 354 ++++ .../OperatorGroupConfigurator.vue | 210 ++ .../assets/plugin-icon-modelmanager.svg | 13 + packages/design-core/package.json | 1 + packages/design-core/re-export.js | 1 + packages/design-core/registry.js | 4 +- packages/layout/src/defaultLayout.js | 3 +- packages/plugins/model-manager/index.ts | 8 + packages/plugins/model-manager/meta.js | 7 + packages/plugins/model-manager/package.json | 47 + packages/plugins/model-manager/src/Main.vue | 250 +++ .../src/components/FieldManager.vue | 356 ++++ .../src/components/ModelBasicForm.vue | 104 + .../src/components/ModelSetting.vue | 213 ++ .../src/composable/useModelManager.js | 28 + .../model-manager/src/styles/vars.less | 21 + packages/plugins/model-manager/vite.config.ts | 39 + packages/register/src/constants.ts | 2 + packages/vue-generator/src/constant/index.js | 21 + tsconfig.app.json | 1 + 45 files changed, 9010 insertions(+), 4 deletions(-) create mode 100644 packages/builtinComponent/src/components/BaseForm.vue create mode 100644 packages/builtinComponent/src/components/BasePage.vue create mode 100644 packages/builtinComponent/src/components/BaseTable.vue create mode 100644 packages/builtinComponent/src/meta/BaseForm.json create mode 100644 packages/builtinComponent/src/meta/BasePage.json create mode 100644 packages/builtinComponent/src/meta/BaseTable.json create mode 100644 packages/configurator/src/bind-variable-configurator/BindVariableConfigurator.vue create mode 100644 packages/configurator/src/model-api-configurator/ModelApiConfigurator.vue create mode 100644 packages/configurator/src/model-api-configurator/ParamsBindGrid.vue create mode 100644 packages/configurator/src/model-common/ModelSelect.vue create mode 100644 packages/configurator/src/model-common/constants.js create mode 100644 packages/configurator/src/model-common/http.js create mode 100644 packages/configurator/src/model-common/utils.js create mode 100644 packages/configurator/src/model-configurator/MetaListItem.vue create mode 100644 packages/configurator/src/model-configurator/ModelConfigurator.vue create mode 100644 packages/configurator/src/operator-group-configurator/MetaChildItem.vue create mode 100644 packages/configurator/src/operator-group-configurator/MetaList.vue create mode 100644 packages/configurator/src/operator-group-configurator/MetaListItem.vue create mode 100644 packages/configurator/src/operator-group-configurator/OperatorGroupConfigurator.vue create mode 100644 packages/design-core/assets/plugin-icon-modelmanager.svg create mode 100644 packages/plugins/model-manager/index.ts create mode 100644 packages/plugins/model-manager/meta.js create mode 100644 packages/plugins/model-manager/package.json create mode 100644 packages/plugins/model-manager/src/Main.vue create mode 100644 packages/plugins/model-manager/src/components/FieldManager.vue create mode 100644 packages/plugins/model-manager/src/components/ModelBasicForm.vue create mode 100644 packages/plugins/model-manager/src/components/ModelSetting.vue create mode 100644 packages/plugins/model-manager/src/composable/useModelManager.js create mode 100644 packages/plugins/model-manager/src/styles/vars.less create mode 100644 packages/plugins/model-manager/vite.config.ts diff --git a/docs/api/frontend-api/main-package-api.md b/docs/api/frontend-api/main-package-api.md index 4f3b42127f..20c62c4aac 100644 --- a/docs/api/frontend-api/main-package-api.md +++ b/docs/api/frontend-api/main-package-api.md @@ -34,6 +34,7 @@ export { default as Bridge } from '@opentiny/tiny-engine-plugin-bridge' export { default as Block, BlockService } from '@opentiny/tiny-engine-plugin-block' export { default as Datasource, DataSourceService } from '@opentiny/tiny-engine-plugin-datasource' export { default as Robot } from '@opentiny/tiny-engine-plugin-robot' +export { default as ModelManager } from '@opentiny/tiny-engine-plugin-model-manager' export { default as Props, PropertiesService, PropertyService } from '@opentiny/tiny-engine-setting-props' export { default as Events } from '@opentiny/tiny-engine-setting-events' export { default as Styles } from '@opentiny/tiny-engine-setting-styles' diff --git a/packages/build/vite-config/src/vite-plugins/devAliasPlugin.js b/packages/build/vite-config/src/vite-plugins/devAliasPlugin.js index 2756343cc2..45e4103788 100644 --- a/packages/build/vite-config/src/vite-plugins/devAliasPlugin.js +++ b/packages/build/vite-config/src/vite-plugins/devAliasPlugin.js @@ -29,6 +29,7 @@ const getDevAlias = (useSourceAlias) => { '@opentiny/tiny-engine-plugin-bridge': path.resolve(basePath, 'packages/plugins/bridge/index.ts'), '@opentiny/tiny-engine-plugin-tutorial': path.resolve(basePath, 'packages/plugins/tutorial/index.ts'), '@opentiny/tiny-engine-plugin-robot': path.resolve(basePath, 'packages/plugins/robot/index.ts'), + '@opentiny/tiny-engine-plugin-model-manager': path.resolve(basePath, 'packages/plugins/model-manager/index.ts'), '@opentiny/tiny-engine-settings-panel': path.resolve(basePath, 'packages/settings/panel/index.ts'), '@opentiny/tiny-engine-setting-events': path.resolve(basePath, 'packages/settings/events/index.ts'), '@opentiny/tiny-engine-setting-props': path.resolve(basePath, 'packages/settings/props/index.ts'), diff --git a/packages/builtinComponent/index.ts b/packages/builtinComponent/index.ts index d9976790dd..86bc80ac8b 100644 --- a/packages/builtinComponent/index.ts +++ b/packages/builtinComponent/index.ts @@ -3,4 +3,7 @@ export { default as CanvasRow } from './src/components/CanvasRow.vue' export { default as CanvasRowColContainer } from './src/components/CanvasRowColContainer.vue' export { default as CanvasFlexBox } from './src/components/CanvasFlexBox.vue' export { default as CanvasSection } from './src/components/CanvasSection.vue' +export { default as FormModel } from './src/components/BaseForm.vue' +export { default as TableModel } from './src/components/BaseTable.vue' +export { default as PageModel } from './src/components/BasePage.vue' export { default as meta } from './src/meta' diff --git a/packages/builtinComponent/package.json b/packages/builtinComponent/package.json index 7b202c7410..d3d61ca334 100644 --- a/packages/builtinComponent/package.json +++ b/packages/builtinComponent/package.json @@ -21,6 +21,7 @@ "preview": "vite preview" }, "dependencies": { + "axios": "^0.28.0", "vite-plugin-css-injected-by-js": "^3.3.1" }, "devDependencies": { @@ -29,6 +30,9 @@ "vite": "^5.4.2" }, "peerDependencies": { + "@opentiny/vue": "^3.20.0", + "@opentiny/vue-icon": "^3.20.0", + "@opentiny/vue-renderless": "^3.20.0", "vue": "^3.4.15" } } diff --git a/packages/builtinComponent/src/components/BaseForm.vue b/packages/builtinComponent/src/components/BaseForm.vue new file mode 100644 index 0000000000..3be724cd3a --- /dev/null +++ b/packages/builtinComponent/src/components/BaseForm.vue @@ -0,0 +1,242 @@ + + + diff --git a/packages/builtinComponent/src/components/BasePage.vue b/packages/builtinComponent/src/components/BasePage.vue new file mode 100644 index 0000000000..9450f0f3fe --- /dev/null +++ b/packages/builtinComponent/src/components/BasePage.vue @@ -0,0 +1,533 @@ + + + diff --git a/packages/builtinComponent/src/components/BaseTable.vue b/packages/builtinComponent/src/components/BaseTable.vue new file mode 100644 index 0000000000..a9bb0e5c84 --- /dev/null +++ b/packages/builtinComponent/src/components/BaseTable.vue @@ -0,0 +1,269 @@ + + + diff --git a/packages/builtinComponent/src/meta/BaseForm.json b/packages/builtinComponent/src/meta/BaseForm.json new file mode 100644 index 0000000000..b32343d0d5 --- /dev/null +++ b/packages/builtinComponent/src/meta/BaseForm.json @@ -0,0 +1,1158 @@ +{ + "component": { + "icon": "form", + "name": { + "zh_CN": "FormModel" + }, + "component": "FormModel", + "schema": { + "properties": [ + { + "label": { + "zh_CN": "选择模型" + }, + "description": { + "zh_CN": "选择模型" + }, + "content": [ + { + "property": "serviceModel", + "label": { + "text": { + "zh_CN": "选择模型" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "bindState": false, + "cols": 12, + "widget": { + "component": "ModelConfigurator", + "props": { + "expand": true + } + }, + "properties": [ + { + "label": { + "zh_CN": "默认分组", + "en_US": "Default Group" + }, + "content": [ + { + "property": "label", + "type": "string", + "label": { + "text": { + "zh_CN": "表单项标签", + "en_US": "Form Item Label" + } + }, + "required": true, + "bindState": false, + "cols": 12, + "widget": { + "component": "I18nConfigurator", + "props": {} + }, + "description": { + "zh_CN": "表单项标签", + "en_US": "Form item's label." + } + }, + { + "property": "prop", + "bindState": false, + "disabled": true, + "label": { + "text": { + "zh_CN": "字段名", + "en_US": "Field Name" + } + }, + "cols": 12, + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "description": { + "zh_CN": "字段名", + "en_US": "Name of the form field." + } + }, + { + "property": "required", + "type": "boolean", + "defaultValue": false, + "label": { + "text": { + "zh_CN": "必填", + "en_US": "Required" + } + }, + "required": false, + "bindState": true, + "cols": 12, + "widget": { + "component": "SwitchConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否必填", + "en_US": "Enable required or not." + } + }, + { + "property": "rules", + "label": { + "text": { + "zh_CN": "校验规则", + "en_US": "Verification Rules" + } + }, + "required": false, + "bindState": true, + "cols": 12, + "widget": { + "component": "CodeConfigurator", + "props": { + "language": "json" + } + }, + "description": { + "zh_CN": "表单项校验", + "en_US": "Verification for form item." + } + }, + { + "property": "component", + "type": "string", + "required": false, + "bindState": true, + "cols": 12, + "label": { + "text": { + "zh_CN": "输入类型", + "en_US": "Input Type" + } + }, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": { + "zh_CN": "输入框", + "en_US": "Input" + }, + "value": "TinyInput" + }, + { + "label": { + "zh_CN": "选择器", + "en_US": "Select" + }, + "value": "TinySelect" + }, + { + "label": { + "zh_CN": "多选框", + "en_US": "Checkbox" + }, + "value": "TinyCheckbox" + }, + { + "label": { + "zh_CN": "单选框", + "en_US": "Radio" + }, + "value": "TinyRadio" + }, + { + "label": { + "zh_CN": "日期选择器", + "en_US": "Date Picker" + }, + "value": "TinyDatePicker" + } + ] + } + }, + "description": { + "zh_CN": "输入类型", + "en_US": "Type of the input." + } + } + ] + }, + { + "componentName": "TinyInput", + "label": { + "zh_CN": "输入框", + "en_US": "Input" + }, + "content": [ + { + "property": "type", + "label": { + "text": { + "zh_CN": "类型" + } + }, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "textarea", + "value": "textarea" + }, + { + "label": "text", + "value": "text" + }, + { + "label": "password", + "value": "password" + } + ] + } + }, + "description": { + "zh_CN": "设置input框的type属性" + }, + "labelPosition": "left" + }, + { + "property": "rows", + "label": { + "text": { + "zh_CN": "行数" + } + }, + "widget": { + "component": "NumberConfigurator", + "props": {} + }, + "description": { + "zh_CN": "输入框行数,只对 type='textarea' 有效" + }, + "labelPosition": "left" + }, + { + "property": "placeholder", + "label": { + "text": { + "zh_CN": "占位文本" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "I18nConfigurator", + "props": {} + }, + "description": { + "zh_CN": "输入框占位文本" + }, + "labelPosition": "left" + }, + { + "property": "clearable", + "type": "boolean", + "defaultValue": false, + "label": { + "text": { + "zh_CN": "清除按钮" + } + }, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否显示清除按钮" + }, + "labelPosition": "left" + }, + { + "property": "disabled", + "type": "boolean", + "defaultValue": false, + "label": { + "text": { + "zh_CN": "禁用" + } + }, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否禁用" + }, + "labelPosition": "left" + } + ] + }, + { + "componentName": "TinySelect", + "label": { + "zh_CN": "选择器", + "en_US": "Select" + }, + "content": [ + { + "property": "placeholder", + "label": { + "text": { + "zh_CN": "占位文本" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "description": { + "zh_CN": "输入框占位文本" + }, + "labelPosition": "left" + }, + { + "property": "clearable", + "type": "boolean", + "defaultValue": false, + "label": { + "text": { + "zh_CN": "清除按钮" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否显示清除按钮" + }, + "labelPosition": "left" + }, + { + "property": "searchable", + "type": "boolean", + "defaultValue": false, + "label": { + "text": { + "zh_CN": "下拉可搜索" + } + }, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "下拉面板是否可搜索" + }, + "labelPosition": "left" + }, + { + "property": "disabled", + "type": "boolean", + "defaultValue": false, + "label": { + "text": { + "zh_CN": "禁用" + } + }, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否禁用" + }, + "labelPosition": "left" + }, + { + "property": "options", + "label": { + "text": { + "zh_CN": "选项数据" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "bindState": true, + "cols": 12, + "widget": { + "component": "CodeConfigurator", + "props": { + "language": "json" + } + }, + "description": { + "zh_CN": "配置 Select 下拉数据项" + }, + "labelPosition": "top" + }, + { + "property": "multiple", + "type": "boolean", + "defaultValue": false, + "label": { + "text": { + "zh_CN": "多选" + } + }, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否允许输入框输入或选择多个项" + }, + "labelPosition": "left" + } + ] + }, + { + "componentName": "TinyDatePicker", + "label": { + "zh_CN": "日期选择器", + "en_US": "DatePicker" + }, + "content": [ + { + "property": "type", + "label": { + "text": { + "zh_CN": "类型" + } + }, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "日期", + "value": "date" + }, + { + "label": "日期时间", + "value": "datetime" + }, + { + "label": "周", + "value": "week" + }, + { + "label": "月份", + "value": "month" + }, + { + "label": "年份", + "value": "year" + } + ] + } + }, + "description": { + "zh_CN": "设置日期框的type属性" + }, + "labelPosition": "left" + }, + { + "property": "placeholder", + "label": { + "text": { + "zh_CN": "占位文本" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "I18nConfigurator", + "props": {} + }, + "description": { + "zh_CN": "输入框占位文本" + }, + "labelPosition": "left" + }, + { + "property": "clearable", + "type": "boolean", + "defaultValue": false, + "label": { + "text": { + "zh_CN": "清除按钮" + } + }, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否显示清除按钮" + }, + "labelPosition": "left" + }, + { + "property": "disabled", + "type": "boolean", + "defaultValue": false, + "label": { + "text": { + "zh_CN": "禁用" + } + }, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否禁用" + }, + "labelPosition": "left" + }, + { + "property": "readonly", + "type": "boolean", + "defaultValue": false, + "label": { + "text": { + "zh_CN": "只读" + } + }, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否只读" + }, + "labelPosition": "left" + }, + { + "property": "format", + "type": "string", + "defaultValue": "", + "label": { + "text": { + "zh_CN": "格式化" + } + }, + "cols": 12, + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否只读" + }, + "labelPosition": "left" + }, + { + "property": "valueFormat", + "type": "string", + "defaultValue": "", + "label": { + "text": { + "zh_CN": "绑定值格式化" + } + }, + "cols": 12, + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "description": { + "zh_CN": "value-format" + }, + "labelPosition": "left" + } + ] + }, + { + "componentName": "TinyRadio", + "label": { + "zh_CN": "单选框", + "en_US": "Radio" + }, + "content": [ + { + "property": "text", + "label": { + "text": { + "zh_CN": "文本内容" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "description": { + "zh_CN": "单选框文本内容" + } + }, + { + "property": "label", + "label": { + "text": { + "zh_CN": "选中值" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "description": { + "zh_CN": "radio 选中时的值" + } + }, + { + "property": "disabled", + "type": "boolean", + "defaultValue": false, + "label": { + "text": { + "zh_CN": "禁用" + } + }, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否禁用" + }, + "labelPosition": "left" + } + ] + }, + { + "componentName": "TinyCheckbox", + "label": { + "zh_CN": "多选框", + "en_US": "Checkbox" + }, + "content": [ + { + "property": "disabled", + "type": "boolean", + "defaultValue": false, + "label": { + "text": { + "zh_CN": "禁用" + } + }, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否禁用" + }, + "labelPosition": "left" + }, + { + "property": "checked", + "type": "boolean", + "defaultValue": false, + "label": { + "text": { + "zh_CN": "勾选" + } + }, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "当前是否勾选" + }, + "labelPosition": "left" + }, + { + "property": "text", + "label": { + "text": { + "zh_CN": "文本" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "description": { + "zh_CN": "复选框的文本" + }, + "labelPosition": "left" + } + ] + }, + { + "componentName": "TinyNumeric", + "label": { + "zh_CN": "数组输入框", + "en_US": "Numeric" + }, + "content": [ + { + "property": "placeholder", + "label": { + "text": { + "zh_CN": "占位文本" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "I18nConfigurator", + "props": {} + }, + "description": { + "zh_CN": "输入框占位文本" + }, + "labelPosition": "left" + }, + { + "property": "allow-empty", + "label": { + "text": { + "zh_CN": "内容可清空" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否内容可清空" + }, + "labelPosition": "left" + }, + { + "property": "disabled", + "label": { + "text": { + "zh_CN": "禁用" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否禁用" + }, + "labelPosition": "left" + }, + { + "property": "size", + "label": { + "text": { + "zh_CN": "尺寸" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "medium", + "value": "medium" + }, + { + "label": "small", + "value": "small" + }, + { + "label": "mini", + "value": "mini" + } + ] + } + }, + "description": { + "zh_CN": "输入框尺寸。该属性的可选值为 medium / small / mini" + }, + "labelPosition": "left" + }, + { + "property": "controls", + "label": { + "text": { + "zh_CN": "加减按钮" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否使用加减按钮" + }, + "labelPosition": "left" + }, + { + "property": "controls-position", + "label": { + "text": { + "zh_CN": "加减按钮位置" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "左右两侧", + "value": "" + }, + { + "label": "只在右侧", + "value": "right" + } + ] + } + }, + "description": { + "zh_CN": "加减按钮位置" + } + }, + { + "property": "precision", + "label": { + "text": { + "zh_CN": "精度" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "NumberConfigurator", + "props": { + "allowEmpty": true + } + }, + "description": { + "zh_CN": "数值精度" + }, + "labelPosition": "left" + }, + { + "property": "step", + "label": { + "text": { + "zh_CN": "步长" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "NumberConfigurator", + "props": { + "allowEmpty": true + } + }, + "description": { + "zh_CN": "步长" + }, + "labelPosition": "left" + } + ] + } + ], + "labelPosition": "top" + }, + { + "property": "modelApis", + "label": { + "text": { + "zh_CN": "绑定模型方法" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "bindState": false, + "cols": 12, + "widget": { + "component": "ModelApiConfigurator", + "props": {} + }, + "labelPosition": "top" + } + ] + }, + { + "label": { + "zh_CN": "基础信息" + }, + "description": { + "zh_CN": "基础信息" + }, + "content": [ + { + "property": "layout", + "label": { + "text": { + "zh_CN": "表单布局", + "en_US": "From Layout" + } + }, + "required": true, + "bindState": false, + "cols": 12, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": { + "zh_CN": "一列布局", + "en_US": "One-column Layout" + }, + "value": 1 + }, + { + "label": { + "zh_CN": "两列布局", + "en_US": "Two-column Layout" + }, + "value": 2 + }, + { + "label": { + "zh_CN": "三列布局", + "en_US": "Three-column Layout" + }, + "value": 3 + } + ] + } + }, + "description": { + "zh_CN": "设置表单布局", + "en_US": "Set the form layout." + } + }, + { + "property": "size", + "label": { + "text": { + "zh_CN": "尺寸" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "medium", + "value": "medium" + }, + { + "label": "small", + "value": "small" + }, + { + "label": "mini", + "value": "mini" + } + ] + } + }, + "description": { + "zh_CN": "输入框尺寸。该属性的可选值为 medium / small / mini" + }, + "labelPosition": "left" + }, + { + "property": "disabled", + "type": "boolean", + "defaultValue": false, + "label": { + "text": { + "zh_CN": "禁用", + "en_US": "Disabled" + } + }, + "required": false, + "bindState": true, + "cols": 12, + "widget": { + "component": "SwitchConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否禁用", + "en_US": "Enable Disabled or not." + } + }, + { + "property": "viewOnly", + "label": { + "text": { + "zh_CN": "只读", + "en_US": "Readonly" + } + }, + "required": false, + "bindState": true, + "cols": 12, + "widget": { + "component": "SwitchConfigurator", + "props": {} + }, + "description": { + "zh_CN": "控制编辑态、查看态", + "en_US": "Control the editing and viewing states." + } + }, + { + "property": "modelValue", + "label": { + "text": { + "zh_CN": "表单数据绑定变量", + "en_US": "Binding Variables For Form Data" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "BindVariableConfigurator", + "props": { + "defaultValue": [] + } + }, + "description": { + "zh_CN": "为表单数据绑定变量", + "en_US": "Binding Variables For Form Data." + } + } + ] + } + ], + "events": { + "onUpdate:modelValue": { + "label": { + "zh_CN": "绑定值改变时触发", + "en_US": "Binding changed Triggered" + }, + "description": { + "zh_CN": "绑定值改变时触发", + "en_US": "Triggered when the value of the binding changes." + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "value", + "type": "array", + "defaultValue": [], + "description": { + "zh_CN": "双向绑定值", + "en_US": "Binding value." + } + } + ], + "returns": {} + } + } + } + }, + "configure": { + "loop": false, + "condition": true, + "isContainer": false, + "isModal": false, + "nestingRule": { + "childWhitelist": [], + "parentWhitelist": "" + } + } + }, + "snippet": { + "name": { + "zh_CN": "表单模型", + "en_US": "FormModel" + }, + "icon": "form", + "screenshot": "", + "snippetName": "FormModel", + "schema": { + "componentName": "FormModel", + "props": {} + } + } +} diff --git a/packages/builtinComponent/src/meta/BasePage.json b/packages/builtinComponent/src/meta/BasePage.json new file mode 100644 index 0000000000..7e095e6f15 --- /dev/null +++ b/packages/builtinComponent/src/meta/BasePage.json @@ -0,0 +1,1666 @@ +{ + "component": { + "icon": "form", + "name": { + "zh_CN": "PageModel" + }, + "component": "PageModel", + "schema": { + "properties": [ + { + "label": { + "zh_CN": "选择模型" + }, + "description": { + "zh_CN": "选择模型" + }, + "content": [ + { + "property": "serviceModel", + "label": { + "text": { + "zh_CN": "选择模型" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "bindState": false, + "cols": 12, + "widget": { + "component": "ModelConfigurator", + "props": { + "expand": true + } + }, + "properties": [ + { + "label": { + "zh_CN": "默认分组", + "en_US": "Default Group" + }, + "content": [ + { + "property": "label", + "type": "string", + "label": { + "text": { + "zh_CN": "表单项标签", + "en_US": "Form Item Label" + } + }, + "required": true, + "bindState": false, + "cols": 12, + "widget": { + "component": "I18nConfigurator", + "props": {} + }, + "description": { + "zh_CN": "表单项标签", + "en_US": "Form item's label." + } + }, + { + "property": "prop", + "bindState": false, + "disabled": true, + "label": { + "text": { + "zh_CN": "字段名", + "en_US": "Field Name" + } + }, + "cols": 12, + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "description": { + "zh_CN": "字段名", + "en_US": "Name of the form field." + } + }, + { + "property": "required", + "type": "boolean", + "defaultValue": false, + "label": { + "text": { + "zh_CN": "必填", + "en_US": "Required" + } + }, + "required": false, + "bindState": true, + "cols": 12, + "widget": { + "component": "SwitchConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否必填", + "en_US": "Enable required or not." + } + }, + { + "property": "rules", + "label": { + "text": { + "zh_CN": "校验规则", + "en_US": "Verification Rules" + } + }, + "required": false, + "bindState": true, + "cols": 12, + "widget": { + "component": "CodeConfigurator", + "props": { + "language": "json" + } + }, + "description": { + "zh_CN": "表单项校验", + "en_US": "Verification for form item." + } + }, + { + "property": "component", + "type": "string", + "required": false, + "bindState": true, + "cols": 12, + "label": { + "text": { + "zh_CN": "输入类型", + "en_US": "Input Type" + } + }, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": { + "zh_CN": "输入框", + "en_US": "Input" + }, + "value": "TinyInput" + }, + { + "label": { + "zh_CN": "选择器", + "en_US": "Select" + }, + "value": "TinySelect" + }, + { + "label": { + "zh_CN": "多选框", + "en_US": "Checkbox" + }, + "value": "TinyCheckbox" + }, + { + "label": { + "zh_CN": "单选框", + "en_US": "Radio" + }, + "value": "TinyRadio" + }, + { + "label": { + "zh_CN": "日期选择器", + "en_US": "Date Picker" + }, + "value": "TinyDatePicker" + } + ] + } + }, + "description": { + "zh_CN": "输入类型", + "en_US": "Type of the input." + } + } + ] + }, + { + "componentName": "TinyInput", + "label": { + "zh_CN": "输入框", + "en_US": "Input" + }, + "content": [ + { + "property": "type", + "label": { + "text": { + "zh_CN": "类型" + } + }, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "textarea", + "value": "textarea" + }, + { + "label": "text", + "value": "text" + }, + { + "label": "password", + "value": "password" + } + ] + } + }, + "description": { + "zh_CN": "设置input框的type属性" + }, + "labelPosition": "left" + }, + { + "property": "rows", + "label": { + "text": { + "zh_CN": "行数" + } + }, + "widget": { + "component": "NumberConfigurator", + "props": {} + }, + "description": { + "zh_CN": "输入框行数,只对 type='textarea' 有效" + }, + "labelPosition": "left" + }, + { + "property": "placeholder", + "label": { + "text": { + "zh_CN": "占位文本" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "I18nConfigurator", + "props": {} + }, + "description": { + "zh_CN": "输入框占位文本" + }, + "labelPosition": "left" + }, + { + "property": "clearable", + "type": "boolean", + "defaultValue": false, + "label": { + "text": { + "zh_CN": "清除按钮" + } + }, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否显示清除按钮" + }, + "labelPosition": "left" + }, + { + "property": "disabled", + "type": "boolean", + "defaultValue": false, + "label": { + "text": { + "zh_CN": "禁用" + } + }, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否禁用" + }, + "labelPosition": "left" + } + ] + }, + { + "componentName": "TinySelect", + "label": { + "zh_CN": "选择器", + "en_US": "Select" + }, + "content": [ + { + "property": "placeholder", + "label": { + "text": { + "zh_CN": "占位文本" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "description": { + "zh_CN": "输入框占位文本" + }, + "labelPosition": "left" + }, + { + "property": "clearable", + "type": "boolean", + "defaultValue": false, + "label": { + "text": { + "zh_CN": "清除按钮" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否显示清除按钮" + }, + "labelPosition": "left" + }, + { + "property": "searchable", + "type": "boolean", + "defaultValue": false, + "label": { + "text": { + "zh_CN": "下拉可搜索" + } + }, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "下拉面板是否可搜索" + }, + "labelPosition": "left" + }, + { + "property": "disabled", + "type": "boolean", + "defaultValue": false, + "label": { + "text": { + "zh_CN": "禁用" + } + }, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否禁用" + }, + "labelPosition": "left" + }, + { + "property": "options", + "label": { + "text": { + "zh_CN": "选项数据" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "bindState": true, + "cols": 12, + "widget": { + "component": "CodeConfigurator", + "props": { + "language": "json" + } + }, + "description": { + "zh_CN": "配置 Select 下拉数据项" + }, + "labelPosition": "top" + }, + { + "property": "multiple", + "type": "boolean", + "defaultValue": false, + "label": { + "text": { + "zh_CN": "多选" + } + }, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否允许输入框输入或选择多个项" + }, + "labelPosition": "left" + } + ] + }, + { + "componentName": "TinyDatePicker", + "label": { + "zh_CN": "日期选择器", + "en_US": "DatePicker" + }, + "content": [ + { + "property": "type", + "label": { + "text": { + "zh_CN": "类型" + } + }, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "日期", + "value": "date" + }, + { + "label": "日期时间", + "value": "datetime" + }, + { + "label": "周", + "value": "week" + }, + { + "label": "月份", + "value": "month" + }, + { + "label": "年份", + "value": "year" + } + ] + } + }, + "description": { + "zh_CN": "设置日期框的type属性" + }, + "labelPosition": "left" + }, + { + "property": "placeholder", + "label": { + "text": { + "zh_CN": "占位文本" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "I18nConfigurator", + "props": {} + }, + "description": { + "zh_CN": "输入框占位文本" + }, + "labelPosition": "left" + }, + { + "property": "clearable", + "type": "boolean", + "defaultValue": false, + "label": { + "text": { + "zh_CN": "清除按钮" + } + }, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否显示清除按钮" + }, + "labelPosition": "left" + }, + { + "property": "disabled", + "type": "boolean", + "defaultValue": false, + "label": { + "text": { + "zh_CN": "禁用" + } + }, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否禁用" + }, + "labelPosition": "left" + }, + { + "property": "readonly", + "type": "boolean", + "defaultValue": false, + "label": { + "text": { + "zh_CN": "只读" + } + }, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否只读" + }, + "labelPosition": "left" + }, + { + "property": "format", + "type": "string", + "defaultValue": "", + "label": { + "text": { + "zh_CN": "格式化" + } + }, + "cols": 12, + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否只读" + }, + "labelPosition": "left" + }, + { + "property": "valueFormat", + "type": "string", + "defaultValue": "", + "label": { + "text": { + "zh_CN": "绑定值格式化" + } + }, + "cols": 12, + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "description": { + "zh_CN": "value-format" + }, + "labelPosition": "left" + } + ] + }, + { + "componentName": "TinyRadio", + "label": { + "zh_CN": "单选框", + "en_US": "Radio" + }, + "content": [ + { + "property": "text", + "label": { + "text": { + "zh_CN": "文本内容" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "description": { + "zh_CN": "单选框文本内容" + } + }, + { + "property": "label", + "label": { + "text": { + "zh_CN": "选中值" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "description": { + "zh_CN": "radio 选中时的值" + } + }, + { + "property": "disabled", + "type": "boolean", + "defaultValue": false, + "label": { + "text": { + "zh_CN": "禁用" + } + }, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否禁用" + }, + "labelPosition": "left" + } + ] + }, + { + "componentName": "TinyCheckbox", + "label": { + "zh_CN": "多选框", + "en_US": "Checkbox" + }, + "content": [ + { + "property": "disabled", + "type": "boolean", + "defaultValue": false, + "label": { + "text": { + "zh_CN": "禁用" + } + }, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否禁用" + }, + "labelPosition": "left" + }, + { + "property": "checked", + "type": "boolean", + "defaultValue": false, + "label": { + "text": { + "zh_CN": "勾选" + } + }, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "当前是否勾选" + }, + "labelPosition": "left" + }, + { + "property": "text", + "label": { + "text": { + "zh_CN": "文本" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "description": { + "zh_CN": "复选框的文本" + }, + "labelPosition": "left" + } + ] + }, + { + "componentName": "TinyNumeric", + "label": { + "zh_CN": "数组输入框", + "en_US": "Numeric" + }, + "content": [ + { + "property": "placeholder", + "label": { + "text": { + "zh_CN": "占位文本" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "I18nConfigurator", + "props": {} + }, + "description": { + "zh_CN": "输入框占位文本" + }, + "labelPosition": "left" + }, + { + "property": "allow-empty", + "label": { + "text": { + "zh_CN": "内容可清空" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否内容可清空" + }, + "labelPosition": "left" + }, + { + "property": "disabled", + "label": { + "text": { + "zh_CN": "禁用" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否禁用" + }, + "labelPosition": "left" + }, + { + "property": "size", + "label": { + "text": { + "zh_CN": "尺寸" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "medium", + "value": "medium" + }, + { + "label": "small", + "value": "small" + }, + { + "label": "mini", + "value": "mini" + } + ] + } + }, + "description": { + "zh_CN": "输入框尺寸。该属性的可选值为 medium / small / mini" + }, + "labelPosition": "left" + }, + { + "property": "controls", + "label": { + "text": { + "zh_CN": "加减按钮" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否使用加减按钮" + }, + "labelPosition": "left" + }, + { + "property": "controls-position", + "label": { + "text": { + "zh_CN": "加减按钮位置" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "左右两侧", + "value": "" + }, + { + "label": "只在右侧", + "value": "right" + } + ] + } + }, + "description": { + "zh_CN": "加减按钮位置" + } + }, + { + "property": "precision", + "label": { + "text": { + "zh_CN": "精度" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "NumberConfigurator", + "props": { + "allowEmpty": true + } + }, + "description": { + "zh_CN": "数值精度" + }, + "labelPosition": "left" + }, + { + "property": "step", + "label": { + "text": { + "zh_CN": "步长" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "NumberConfigurator", + "props": { + "allowEmpty": true + } + }, + "description": { + "zh_CN": "步长" + }, + "labelPosition": "left" + } + ] + } + ], + "labelPosition": "top" + }, + { + "property": "modelApis", + "label": { + "text": { + "zh_CN": "绑定模型方法" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "bindState": false, + "cols": 12, + "widget": { + "component": "ModelApiConfigurator", + "props": {} + }, + "labelPosition": "top" + }, + { + "property": "searchFormData", + "label": { + "text": { + "zh_CN": "搜索表单绑定变量", + "en_US": "Binding Variables For Search Form" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "BindVariableConfigurator" + }, + "description": { + "zh_CN": "为搜索表单绑定变量", + "en_US": "Binding Variables For Search Form." + } + }, + { + "property": "tableData", + "label": { + "text": { + "zh_CN": "表格数据绑定变量", + "en_US": "Binding Variables For Table Data" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "BindVariableConfigurator", + "props": { + "defaultValue": [], + "isValueArray": true + } + }, + "description": { + "zh_CN": "为表格数据绑定变量", + "en_US": "Binding Variables For Search Form." + } + }, + { + "property": "editFormData", + "label": { + "text": { + "zh_CN": "数据表单绑定变量", + "en_US": "Binding Variables For Data Form" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "BindVariableConfigurator" + }, + "description": { + "zh_CN": "为新增数据或编辑数据表单绑定变量", + "en_US": "Binding Variables For Add or Edit Form." + } + } + ] + }, + { + "label": { + "zh_CN": "基础信息" + }, + "description": { + "zh_CN": "基础信息" + }, + "content": [ + { + "property": "layout", + "label": { + "text": { + "zh_CN": "表单布局", + "en_US": "From Layout" + } + }, + "required": true, + "bindState": false, + "cols": 12, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": { + "zh_CN": "一列布局", + "en_US": "One-column Layout" + }, + "value": 1 + }, + { + "label": { + "zh_CN": "两列布局", + "en_US": "Two-column Layout" + }, + "value": 2 + }, + { + "label": { + "zh_CN": "三列布局", + "en_US": "Three-column Layout" + }, + "value": 3 + } + ] + } + }, + "description": { + "zh_CN": "设置表单布局", + "en_US": "Set the form layout." + } + }, + { + "property": "size", + "label": { + "text": { + "zh_CN": "尺寸" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "medium", + "value": "medium" + }, + { + "label": "small", + "value": "small" + }, + { + "label": "mini", + "value": "mini" + } + ] + } + }, + "description": { + "zh_CN": "输入框尺寸。该属性的可选值为 medium / small / mini" + }, + "labelPosition": "left" + } + ] + }, + { + "label": { + "zh_CN": "表格信息" + }, + "description": { + "zh_CN": "表格信息" + }, + "content": [ + { + "property": "selectedEnabled", + "resetProps": true, + "label": { + "text": { + "zh_CN": "启用复选", + "en_US": "enable select data" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "SwitchConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否允许复选框选中数据", + "en_US": "Whether to allow the check box to select data" + }, + "labelPosition": "left" + }, + { + "property": "handleSelectedRows", + "label": { + "text": { + "zh_CN": "处理选中数据方法", + "en_US": "Method of Processing Selected Data" + } + }, + "defaultValue": { + "type": "JSFunction", + "value": "/**\r\n * 获取表格勾选数据方法\r\n * tableSelection - 表格已勾选的数据\r\n */\r\nfunction handleSelectedRows(tableSelection) {\r\n // 处理方法函数体\r\n}" + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CodeConfigurator", + "props": { + "language": "javascript", + "dataType": "JSFunction" + } + }, + "description": { + "zh_CN": "处理选中数据方法", + "en_US": "Method of Processing Selected Data" + }, + "labelPosition": "left" + }, + { + "property": "rowOperationEnabled", + "resetProps": true, + "label": { + "text": { + "zh_CN": "启用行操作", + "en_US": "enable row operation" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "SwitchConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否使用行操作", + "en_US": "Whether to allow the row operation" + }, + "labelPosition": "left" + }, + { + "property": "useIconOperation", + "resetProps": true, + "label": { + "text": { + "zh_CN": "使用图标", + "en_US": "use icon operation" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "SwitchConfigurator", + "props": {} + }, + "description": { + "zh_CN": "行操作是否使用图标", + "en_US": "use Icon Whether to handle the row operation" + }, + "labelPosition": "left" + }, + { + "type": "configList", + "property": "rowOperations", + "label": { + "text": { + "zh_CN": "行操作", + "en_US": "Row Operation" + } + }, + "required": false, + "cols": 12, + "properties": [ + { + "label": { + "zh_CN": "默认分组", + "en_US": "Default Group" + }, + "content": [ + { + "property": "label", + "type": "string", + "label": { + "text": { + "zh_CN": "文本", + "en_US": "Text" + } + }, + "cols": 12, + "widget": { + "component": "I18nConfigurator", + "props": {} + }, + "description": { + "zh_CN": "操作名称", + "en_US": "Operation's name." + } + }, + { + "property": "icon", + "type": "string", + "label": { + "text": { + "zh_CN": "图标", + "en_US": "Icon" + } + }, + "cols": 12, + "widget": { + "component": "InputConfigurator", + "props": { + "placeholder": "请输入图标类名" + } + }, + "description": { + "zh_CN": "图标库地址: https://tinyuidesign.cloudbu.huawei.com/tiny-vue/zh-CN/os-theme/components/icon#list", + "en_US": "Icon Library Address: https://tinyuidesign.cloudbu.huawei.com/tiny-vue/zh-CN/os-theme/components/icon#list" + } + }, + { + "property": "handler", + "label": { + "text": { + "zh_CN": "点击回调事件", + "en_US": "Click Callback Event" + } + }, + "defaultValue": { + "type": "JSFunction", + "value": "function handleRow(row, index, extendApis) {}" + }, + "cols": 12, + "widget": { + "component": "CodeConfigurator", + "props": { + "dataType": "JSFunction" + } + }, + "description": { + "zh_CN": "操作的回调函数", + "en_US": "Callback functions for operations." + } + } + ] + } + ], + "widget": { + "component": "OperatorGroupConfigurator", + "props": { + "type": "object", + "textField": "label", + "language": "json", + "buttonText": "编辑行操作", + "title": "编辑行操作", + "enableVisibleControl": true, + "disableDelete": true, + "expand": true, + "isAbleBatchOperation": true + } + }, + "description": { + "zh_CN": "表格自定义行操作", + "en_US": "Custom operations For table's row." + }, + "labelPosition": "top" + }, + { + "property": "columnMinWidth", + "label": { + "text": { + "zh_CN": "表格列最小宽度", + "en_US": "Minimum Column Width" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "NumberConfigurator", + "props": {} + }, + "description": { + "zh_CN": "表格列最小宽度", + "en_US": "Minimum width of table's column." + } + }, + { + "property": "columnWidth", + "label": { + "text": { + "zh_CN": "表格列宽度", + "en_US": "Column Width" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "NumberConfigurator", + "props": {} + }, + "description": { + "zh_CN": "表格列宽度", + "en_US": "Width of table's column." + } + } + ] + } + ], + "events": { + "onUpdate:modelValue": { + "label": { + "zh_CN": "绑定值改变时触发", + "en_US": "Binding changed Triggered" + }, + "description": { + "zh_CN": "绑定值改变时触发", + "en_US": "Triggered when the value of the binding changes." + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "value", + "type": "array", + "defaultValue": [], + "description": { + "zh_CN": "双向绑定值", + "en_US": "Binding value." + } + } + ], + "returns": {} + } + }, + "onUpdate:searchFormData": { + "label": { + "zh_CN": "绑定值改变时触发", + "en_US": "Binding changed Triggered" + }, + "description": { + "zh_CN": "绑定值改变时触发", + "en_US": "Triggered when the value of the binding changes." + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "value", + "type": "object", + "defaultValue": {}, + "description": { + "zh_CN": "双向绑定值", + "en_US": "Binding value." + } + } + ], + "returns": {} + } + }, + "onUpdate:tableData": { + "label": { + "zh_CN": "绑定值改变时触发", + "en_US": "Binding changed Triggered" + }, + "description": { + "zh_CN": "绑定值改变时触发", + "en_US": "Triggered when the value of the binding changes." + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "value", + "type": "array", + "defaultValue": [], + "description": { + "zh_CN": "双向绑定值", + "en_US": "Binding value." + } + } + ], + "returns": {} + } + }, + "onUpdate:editFormData": { + "label": { + "zh_CN": "绑定值改变时触发", + "en_US": "Binding changed Triggered" + }, + "description": { + "zh_CN": "绑定值改变时触发", + "en_US": "Triggered when the value of the binding changes." + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "value", + "type": "object", + "defaultValue": {}, + "description": { + "zh_CN": "双向绑定值", + "en_US": "Binding value." + } + } + ], + "returns": {} + } + }, + "onFilterChange": { + "label": { + "zh_CN": "筛选条件改变时触发改事件" + }, + "description": { + "zh_CN": "配置 remote-filter 开启服务端过滤,服务端过滤会调用表格 fetch-data 进行查询,filter-change 服务端过滤后触发的事件" + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "table", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": "{$table,filters} 包含 table 实例对象和过滤条件的对象" + } + } + ], + "returns": {} + }, + "defaultValue": "function onClick(e) {}" + }, + "onSortChange": { + "label": { + "zh_CN": "点击列头,执行数据排序前触发的事件" + }, + "description": { + "zh_CN": "配置 remote-filter 开启服务端过滤,服务端过滤会调用表格 fetch-data 进行查询,filter-change 服务端过滤后触发的事件" + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "table", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": "{$table,filters} 包含 table 实例对象和过滤条件的对象" + } + } + ], + "returns": {} + }, + "defaultValue": "function onClick(e) {}" + }, + "onSelectAll": { + "label": { + "zh_CN": "当手动勾选全选时触发的事件" + }, + "description": { + "zh_CN": "只对 type=selection 有效,当手动勾选全选时触发的事件" + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "table", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": " 包含 table 实例对象" + } + }, + { + "name": "checked", + "type": "boolean", + "defaultValue": "", + "description": { + "zh_CN": "勾选状态" + } + }, + { + "name": "selction", + "type": "Array", + "defaultValue": "", + "description": { + "zh_CN": "选中的表格数据数组" + } + } + ], + "returns": {} + }, + "defaultValue": "function onClick(e) {}" + }, + "onSelectChange": { + "label": { + "zh_CN": "手动勾选并且值发生改变时触发的事件" + }, + "description": { + "zh_CN": "只对 type=selection 有效,当手动勾选并且值发生改变时触发的事件" + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "table", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": " table 实例对象" + } + }, + { + "name": "event", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": " 原生 Event" + } + } + ], + "returns": {} + }, + "defaultValue": "function onClick(e) {}" + }, + "onToggleExpandChange": { + "label": { + "zh_CN": "当行展开或收起时会触发该事件" + }, + "description": { + "zh_CN": "当行展开或收起时会触发该事件" + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "table", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": "{$table,row,rowIndex} 包含 table 实例对象和当前行数据的对象" + } + }, + { + "name": "event", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": " 原生 Event" + } + } + ], + "returns": {} + }, + "defaultValue": "function onClick(e) {}" + }, + "onCurrentChange": { + "label": { + "zh_CN": "行点击时触发" + }, + "description": { + "zh_CN": "行点击时触发" + }, + "type": "event", + "functionInfo": { + "params": [], + "returns": {} + }, + "defaultValue": "" + } + } + }, + "configure": { + "loop": false, + "condition": true, + "styles": true, + "isContainer": false, + "isModal": false, + "nestingRule": { + "childWhitelist": [], + "parentWhitelist": "" + } + } + }, + "snippet": { + "name": { + "zh_CN": "页面模型", + "en_US": "PageModel" + }, + "icon": "page", + "screenshot": "", + "snippetName": "PageModel", + "schema": { + "componentName": "PageModel", + "props": { + "rowOperations": { + "value": [ + { + "label": "编辑", + "icon": "IconEdit", + "builtIn": true, + "itemVisible": true + }, + { + "label": "删除", + "icon": "IconDel", + "builtIn": true, + "itemVisible": true + } + ] + } + } + } + } +} diff --git a/packages/builtinComponent/src/meta/BaseTable.json b/packages/builtinComponent/src/meta/BaseTable.json new file mode 100644 index 0000000000..009d9edb37 --- /dev/null +++ b/packages/builtinComponent/src/meta/BaseTable.json @@ -0,0 +1,1792 @@ +{ + "component": { + "icon": "grid", + "name": { + "zh_CN": "TableModel" + }, + "component": "TableModel", + "schema": { + "properties": [ + { + "label": { + "zh_CN": "选择模型" + }, + "description": { + "zh_CN": "选择模型" + }, + "content": [ + { + "property": "serviceModel", + "label": { + "text": { + "zh_CN": "选择模型" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "bindState": false, + "cols": 12, + "widget": { + "component": "ModelConfigurator", + "props": { + "expand": true + } + }, + "properties": [ + { + "label": { + "zh_CN": "默认分组", + "en_US": "Default Group" + }, + "content": [ + { + "property": "label", + "type": "string", + "label": { + "text": { + "zh_CN": "列标题", + "en_US": "Column Title" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "I18nConfigurator", + "props": {} + }, + "description": { + "zh_CN": "列标题", + "en_US": "Column's title." + } + }, + { + "property": "prop", + "type": "string", + "label": { + "text": { + "zh_CN": "列字段", + "en_US": "Column Field" + } + }, + "required": false, + "readOnly": false, + "disabled": true, + "cols": 12, + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "description": { + "zh_CN": "列字段", + "en_US": "Column's field." + } + }, + { + "property": "width", + "type": "string", + "label": { + "text": { + "zh_CN": "列宽", + "en_US": "Column Width" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "NumberConfigurator", + "props": {} + }, + "description": { + "zh_CN": "列宽", + "en_US": "Column's width." + } + }, + { + "property": "minWidth", + "type": "string", + "label": { + "text": { + "zh_CN": "最小列宽", + "en_US": "Minimum Width" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "NumberConfigurator", + "props": {} + }, + "description": { + "zh_CN": "最小列宽", + "en_US": "Minimum width of column." + } + }, + { + "property": "formatter", + "type": "object", + "label": { + "text": { + "zh_CN": "格式化方法", + "en_US": "Formatting Method" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CodeConfigurator", + "props": { + "dataType": "JSFunction" + } + }, + "description": { + "zh_CN": "格式化方法", + "en_US": "Method to format." + } + }, + { + "property": "showOverflowTooltip", + "type": "boolean", + "defaultValue": false, + "label": { + "text": { + "zh_CN": "文本溢出显示tooltip", + "en_US": "Tooltips when Text Overflow" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "SwitchConfigurator", + "props": {} + }, + "description": { + "zh_CN": "文本溢出是否显示tooltip", + "en_US": "Whether to display tooltips when text overflow?" + } + }, + { + "property": "fixed", + "type": "string", + "label": { + "text": { + "zh_CN": "列固定", + "en_US": "Column Fixed" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": { + "zh_CN": "固定左侧", + "en_US": "Fixed Left" + }, + "value": "left" + }, + { + "label": { + "zh_CN": "固定右侧", + "en_US": "Fixed Right" + }, + "value": "right" + } + ] + } + }, + "description": { + "zh_CN": "列固定", + "en_US": "Fixed table column on which side." + } + }, + { + "property": "sortable", + "type": "boolean", + "label": { + "text": { + "zh_CN": "是否排序", + "en_US": "Sortable" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "SwitchConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否排序", + "en_US": "Enable sortable or not." + } + }, + { + "property": "tip", + "type": "boolean", + "label": { + "text": { + "zh_CN": "表头tip", + "en_US": "Table Header Tip" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "SwitchConfigurator", + "props": {} + }, + "description": { + "zh_CN": "表头tip", + "en_US": "Tip of table's header." + } + }, + { + "property": "tipContent", + "type": "string", + "label": { + "text": { + "zh_CN": "表头tip内容", + "en_US": "Header Tip Content" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "description": { + "zh_CN": "表头tip内容", + "en_US": "Content of table header's tip." + } + }, + { + "property": "edit", + "type": "boolean", + "label": { + "text": { + "zh_CN": "是否可编辑", + "en_US": "Editable" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "SwitchConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否可编辑", + "en_US": "Enable editable or not." + } + }, + { + "property": "required", + "type": "boolean", + "label": { + "text": { + "zh_CN": "必填", + "en_US": "Required" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "SwitchConfigurator", + "props": {} + }, + "description": { + "zh_CN": "不可编辑时,默认必填不生效", + "en_US": "When it is not editable, the default requirement for mandatory filling does not take effect." + } + }, + { + "property": "component", + "defaultValue": "TinyInput", + "type": "string", + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "label": { + "text": { + "zh_CN": "控件类型", + "en_US": "Control Type" + } + }, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": { + "zh_CN": "输入框", + "en_US": "Input" + }, + "value": "TinyInput" + }, + { + "label": { + "zh_CN": "选择框", + "en_US": "Select" + }, + "value": "TinySelect" + }, + { + "label": { + "zh_CN": "布尔值", + "en_US": "Boolean" + }, + "value": "TinyRadio" + }, + { + "label": { + "zh_CN": "状态标识", + "en_US": "StatusMarker" + }, + "value": "TinyModelStatus" + }, + { + "label": { + "zh_CN": "日期选择器", + "en_US": "Date Picker" + }, + "value": "TinyDatePicker" + }, + { + "label": { + "zh_CN": "计数器", + "en_US": "Input Number" + }, + "value": "TinyNumeric" + } + ], + "labelZhCN": "表格列配置" + } + }, + "description": { + "zh_CN": "控件类型", + "en_US": "Type of control." + } + } + ] + }, + { + "componentName": "TinyInput", + "label": { + "zh_CN": "输入框", + "en_US": "Input" + }, + "content": [ + { + "property": "type", + "label": { + "text": { + "zh_CN": "类型" + } + }, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "textarea", + "value": "textarea" + }, + { + "label": "text", + "value": "text" + }, + { + "label": "password", + "value": "password" + } + ] + } + }, + "description": { + "zh_CN": "设置input框的type属性" + }, + "labelPosition": "left" + }, + { + "property": "rows", + "label": { + "text": { + "zh_CN": "行数" + } + }, + "widget": { + "component": "NumberConfigurator", + "props": {} + }, + "description": { + "zh_CN": "输入框行数,只对 type='textarea' 有效" + }, + "labelPosition": "left" + }, + { + "property": "placeholder", + "label": { + "text": { + "zh_CN": "占位文本" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "I18nConfigurator", + "props": {} + }, + "description": { + "zh_CN": "输入框占位文本" + }, + "labelPosition": "left" + }, + { + "property": "clearable", + "label": { + "text": { + "zh_CN": "清除按钮" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否显示清除按钮" + }, + "labelPosition": "left" + }, + { + "property": "disabled", + "label": { + "text": { + "zh_CN": "禁用" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否禁用" + }, + "labelPosition": "left" + }, + { + "property": "size", + "label": { + "text": { + "zh_CN": "尺寸" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "medium", + "value": "medium" + }, + { + "label": "small", + "value": "small" + }, + { + "label": "mini", + "value": "mini" + } + ] + } + }, + "description": { + "zh_CN": "输入框尺寸。该属性的可选值为 medium / small / mini" + }, + "labelPosition": "left" + } + ] + }, + { + "componentName": "TinySelect", + "label": { + "zh_CN": "选择器", + "en_US": "Select" + }, + "content": [ + { + "property": "placeholder", + "label": { + "text": { + "zh_CN": "占位文本" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "description": { + "zh_CN": "输入框占位文本" + }, + "labelPosition": "left" + }, + { + "property": "clearable", + "label": { + "text": { + "zh_CN": "清除按钮" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否显示清除按钮" + }, + "labelPosition": "left" + }, + { + "property": "searchable", + "label": { + "text": { + "zh_CN": "下拉可搜索" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "下拉面板是否可搜索" + }, + "labelPosition": "left" + }, + { + "property": "disabled", + "label": { + "text": { + "zh_CN": "禁用" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否禁用" + }, + "labelPosition": "left" + }, + { + "property": "options", + "label": { + "text": { + "zh_CN": "选项数据" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CodeConfigurator", + "props": { + "language": "json" + } + }, + "description": { + "zh_CN": "配置 Select 下拉数据项" + }, + "labelPosition": "top" + }, + { + "property": "multiple", + "label": { + "text": { + "zh_CN": "多选" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否允许输入框输入或选择多个项" + }, + "labelPosition": "left" + } + ] + }, + { + "componentName": "TinyDatePicker", + "label": { + "zh_CN": "日期选择器", + "en_US": "DatePicker" + }, + "content": [ + { + "property": "type", + "label": { + "text": { + "zh_CN": "类型" + } + }, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "日期", + "value": "date" + }, + { + "label": "日期时间", + "value": "datetime" + }, + { + "label": "周", + "value": "week" + }, + { + "label": "月份", + "value": "month" + }, + { + "label": "年份", + "value": "year" + } + ] + } + }, + "description": { + "zh_CN": "设置日期框的type属性" + }, + "labelPosition": "left" + }, + { + "property": "placeholder", + "label": { + "text": { + "zh_CN": "占位文本" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "I18nConfigurator", + "props": {} + }, + "description": { + "zh_CN": "输入框占位文本" + }, + "labelPosition": "left" + }, + { + "property": "clearable", + "label": { + "text": { + "zh_CN": "清除按钮" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否显示清除按钮" + }, + "labelPosition": "left" + }, + { + "property": "disabled", + "label": { + "text": { + "zh_CN": "禁用" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否禁用" + }, + "labelPosition": "left" + }, + { + "property": "readonly", + "label": { + "text": { + "zh_CN": "只读" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否只读" + }, + "labelPosition": "left" + }, + { + "property": "size", + "label": { + "text": { + "zh_CN": "尺寸" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "medium", + "value": "medium" + }, + { + "label": "small", + "value": "small" + }, + { + "label": "mini", + "value": "mini" + } + ] + } + }, + "description": { + "zh_CN": "日期框尺寸。该属性的可选值为 medium / small / mini" + }, + "labelPosition": "left" + }, + { + "property": "format", + "type": "string", + "defaultValue": "", + "label": { + "text": { + "zh_CN": "格式化" + } + }, + "cols": 12, + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否只读" + }, + "labelPosition": "left" + }, + { + "property": "valueFormat", + "type": "string", + "defaultValue": "", + "label": { + "text": { + "zh_CN": "绑定值格式化" + } + }, + "cols": 12, + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "description": { + "zh_CN": "value-format" + }, + "labelPosition": "left" + } + ] + }, + { + "componentName": "TinyRadio", + "label": { + "zh_CN": "单选框", + "en_US": "Radio" + }, + "content": [ + { + "property": "text", + "label": { + "text": { + "zh_CN": "文本内容" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "description": { + "zh_CN": "单选框文本内容" + } + }, + { + "property": "label", + "label": { + "text": { + "zh_CN": "选中值" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "description": { + "zh_CN": "radio 选中时的值" + } + }, + { + "property": "disabled", + "label": { + "text": { + "zh_CN": "禁用" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否禁用" + }, + "labelPosition": "left" + } + ] + }, + { + "componentName": "TinyCheckbox", + "label": { + "zh_CN": "多选框", + "en_US": "Checkbox" + }, + "content": [ + { + "property": "disabled", + "label": { + "text": { + "zh_CN": "禁用" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否禁用" + }, + "labelPosition": "left" + }, + { + "property": "checked", + "label": { + "text": { + "zh_CN": "勾选" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "当前是否勾选" + }, + "labelPosition": "left" + }, + { + "property": "text", + "label": { + "text": { + "zh_CN": "文本" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "description": { + "zh_CN": "复选框的文本" + }, + "labelPosition": "left" + } + ] + }, + { + "componentName": "TinyNumeric", + "label": { + "zh_CN": "数组输入框", + "en_US": "Numeric" + }, + "content": [ + { + "property": "placeholder", + "label": { + "text": { + "zh_CN": "占位文本" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "I18nConfigurator", + "props": {} + }, + "description": { + "zh_CN": "输入框占位文本" + }, + "labelPosition": "left" + }, + { + "property": "allow-empty", + "label": { + "text": { + "zh_CN": "内容可清空" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否内容可清空" + }, + "labelPosition": "left" + }, + { + "property": "disabled", + "label": { + "text": { + "zh_CN": "禁用" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否禁用" + }, + "labelPosition": "left" + }, + { + "property": "size", + "label": { + "text": { + "zh_CN": "尺寸" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "medium", + "value": "medium" + }, + { + "label": "small", + "value": "small" + }, + { + "label": "mini", + "value": "mini" + } + ] + } + }, + "description": { + "zh_CN": "输入框尺寸。该属性的可选值为 medium / small / mini" + }, + "labelPosition": "left" + }, + { + "property": "controls", + "label": { + "text": { + "zh_CN": "加减按钮" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否使用加减按钮" + }, + "labelPosition": "left" + }, + { + "property": "controls-position", + "label": { + "text": { + "zh_CN": "加减按钮位置" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "左右两侧", + "value": "" + }, + { + "label": "只在右侧", + "value": "right" + } + ] + } + }, + "description": { + "zh_CN": "加减按钮位置" + } + }, + { + "property": "precision", + "label": { + "text": { + "zh_CN": "精度" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "NumberConfigurator", + "props": { + "allowEmpty": true + } + }, + "description": { + "zh_CN": "数值精度" + }, + "labelPosition": "left" + }, + { + "property": "step", + "label": { + "text": { + "zh_CN": "步长" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "NumberConfigurator", + "props": { + "allowEmpty": true + } + }, + "description": { + "zh_CN": "步长" + }, + "labelPosition": "left" + } + ] + } + ], + "labelPosition": "top" + }, + { + "property": "modelApis", + "label": { + "text": { + "zh_CN": "绑定模型方法" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "bindState": false, + "cols": 12, + "widget": { + "component": "ModelApiConfigurator", + "props": {} + }, + "labelPosition": "top" + } + ] + }, + { + "label": { + "zh_CN": "基础属性", + "en_US": "Basic Attributes" + }, + "description": { + "zh_CN": "基础属性", + "en_US": "Basic attributes." + }, + "collapse": { + "number": 6, + "text": { + "zh_CN": "显示更多", + "en_US": "Show More" + } + }, + "content": [ + { + "property": "viewOnly", + "label": { + "text": { + "zh_CN": "只读", + "en_US": "Readonly" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "SwitchConfigurator", + "props": {} + }, + "description": { + "zh_CN": "控制编辑态、查看态", + "en_US": "Control the editing and viewing states." + } + }, + { + "property": "selectedEnabled", + "resetProps": true, + "label": { + "text": { + "zh_CN": "启用复选", + "en_US": "enable select data" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "SwitchConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否允许复选框选中数据", + "en_US": "Whether to allow the check box to select data" + }, + "labelPosition": "left" + }, + { + "property": "handleSelectedRows", + "label": { + "text": { + "zh_CN": "处理选中数据方法", + "en_US": "Method of Processing Selected Data" + } + }, + "defaultValue": { + "type": "JSFunction", + "value": "/**\r\n * 获取表格勾选数据方法\r\n * tableSelection - 表格已勾选的数据\r\n */\r\nfunction handleSelectedRows(tableSelection) {\r\n // 处理方法函数体\r\n}" + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CodeConfigurator", + "props": { + "language": "javascript", + "dataType": "JSFunction" + } + }, + "description": { + "zh_CN": "处理选中数据方法", + "en_US": "Method of Processing Selected Data" + }, + "labelPosition": "left" + } + ] + }, + { + "label": { + "zh_CN": "表格数据配置", + "en_US": "Form Data Configuration" + }, + "description": { + "zh_CN": "表格数据配置", + "en_US": "Configuration of form data." + }, + "collapse": { + "number": 6, + "text": { + "zh_CN": "显示更多", + "en_US": "Show More" + } + }, + "content": [ + { + "property": "modelValue", + "label": { + "text": { + "zh_CN": "表格数据绑定变量", + "en_US": "Binding Variables For Table Data" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "BindVariableConfigurator", + "props": { + "defaultValue": [], + "isValueArray": true + } + }, + "description": { + "zh_CN": "为表格数据绑定变量", + "en_US": "Binding Variables For Search Form." + } + } + ] + }, + { + "label": { + "zh_CN": "表格列配置", + "en_US": "Columns Configuration" + }, + "description": { + "zh_CN": "表格列配置", + "en_US": "Configuration for table column." + }, + "collapse": { + "number": 6, + "text": { + "zh_CN": "显示更多", + "en_US": "Show More" + } + }, + "content": [ + { + "property": "rowOperationEnabled", + "resetProps": true, + "label": { + "text": { + "zh_CN": "启用行操作", + "en_US": "enable row operation" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "SwitchConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否使用行操作", + "en_US": "Whether to allow the row operation" + }, + "labelPosition": "left" + }, + { + "property": "useIconOperation", + "resetProps": true, + "label": { + "text": { + "zh_CN": "使用图标", + "en_US": "use icon operation" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "SwitchConfigurator", + "props": {} + }, + "description": { + "zh_CN": "行操作是否使用图标", + "en_US": "use Icon Whether to handle the row operation" + }, + "labelPosition": "left" + }, + { + "type": "configList", + "property": "rowOperations", + "label": { + "text": { + "zh_CN": "行操作", + "en_US": "Row Operation" + } + }, + "required": false, + "cols": 12, + "properties": [ + { + "label": { + "zh_CN": "默认分组", + "en_US": "Default Group" + }, + "content": [ + { + "property": "label", + "type": "string", + "label": { + "text": { + "zh_CN": "文本", + "en_US": "Text" + } + }, + "cols": 12, + "widget": { + "component": "I18nConfigurator", + "props": {} + }, + "description": { + "zh_CN": "操作名称", + "en_US": "Operation's name." + } + }, + { + "property": "icon", + "type": "string", + "label": { + "text": { + "zh_CN": "图标", + "en_US": "Icon" + } + }, + "cols": 12, + "widget": { + "component": "InputConfigurator", + "props": { + "placeholder": "请输入图标类名" + } + }, + "description": { + "zh_CN": "图标库地址: https://tinyuidesign.cloudbu.huawei.com/tiny-vue/zh-CN/os-theme/components/icon#list", + "en_US": "Icon Library Address: https://tinyuidesign.cloudbu.huawei.com/tiny-vue/zh-CN/os-theme/components/icon#list" + } + }, + { + "property": "handler", + "label": { + "text": { + "zh_CN": "点击回调事件", + "en_US": "Click Callback Event" + } + }, + "defaultValue": { + "type": "JSFunction", + "value": "function handleRow(row, index, extendApis) {}" + }, + "cols": 12, + "widget": { + "component": "CodeConfigurator", + "props": { + "dataType": "JSFunction" + } + }, + "description": { + "zh_CN": "操作的回调函数", + "en_US": "Callback functions for operations." + } + } + ] + } + ], + "widget": { + "component": "OperatorGroupConfigurator", + "props": { + "type": "object", + "textField": "label", + "language": "json", + "buttonText": "编辑行操作", + "title": "编辑行操作", + "enableVisibleControl": true, + "disableDelete": true, + "expand": true, + "isAbleBatchOperation": true + } + }, + "description": { + "zh_CN": "表格自定义行操作", + "en_US": "Custom operations For table's row." + }, + "labelPosition": "top" + }, + { + "property": "columnMinWidth", + "label": { + "text": { + "zh_CN": "表格列最小宽度", + "en_US": "Minimum Column Width" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "NumberConfigurator", + "props": {} + }, + "description": { + "zh_CN": "表格列最小宽度", + "en_US": "Minimum width of table's column." + } + }, + { + "property": "columnWidth", + "label": { + "text": { + "zh_CN": "表格列宽度", + "en_US": "Column Width" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "NumberConfigurator", + "props": {} + }, + "description": { + "zh_CN": "表格列宽度", + "en_US": "Width of table's column." + } + } + ] + } + ], + "events": { + "onFilterChange": { + "label": { + "zh_CN": "筛选条件改变时触发改事件" + }, + "description": { + "zh_CN": "配置 remote-filter 开启服务端过滤,服务端过滤会调用表格 fetch-data 进行查询,filter-change 服务端过滤后触发的事件" + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "table", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": "{$table,filters} 包含 table 实例对象和过滤条件的对象" + } + } + ], + "returns": {} + }, + "defaultValue": "function onClick(e) {}" + }, + "onSortChange": { + "label": { + "zh_CN": "点击列头,执行数据排序前触发的事件" + }, + "description": { + "zh_CN": "配置 remote-filter 开启服务端过滤,服务端过滤会调用表格 fetch-data 进行查询,filter-change 服务端过滤后触发的事件" + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "table", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": "{$table,filters} 包含 table 实例对象和过滤条件的对象" + } + } + ], + "returns": {} + }, + "defaultValue": "function onClick(e) {}" + }, + "onSelectAll": { + "label": { + "zh_CN": "当手动勾选全选时触发的事件" + }, + "description": { + "zh_CN": "只对 type=selection 有效,当手动勾选全选时触发的事件" + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "table", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": " 包含 table 实例对象" + } + }, + { + "name": "checked", + "type": "boolean", + "defaultValue": "", + "description": { + "zh_CN": "勾选状态" + } + }, + { + "name": "selction", + "type": "Array", + "defaultValue": "", + "description": { + "zh_CN": "选中的表格数据数组" + } + } + ], + "returns": {} + }, + "defaultValue": "function onClick(e) {}" + }, + "onSelectChange": { + "label": { + "zh_CN": "手动勾选并且值发生改变时触发的事件" + }, + "description": { + "zh_CN": "只对 type=selection 有效,当手动勾选并且值发生改变时触发的事件" + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "table", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": " table 实例对象" + } + }, + { + "name": "event", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": " 原生 Event" + } + } + ], + "returns": {} + }, + "defaultValue": "function onClick(e) {}" + }, + "onToggleExpandChange": { + "label": { + "zh_CN": "当行展开或收起时会触发该事件" + }, + "description": { + "zh_CN": "当行展开或收起时会触发该事件" + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "table", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": "{$table,row,rowIndex} 包含 table 实例对象和当前行数据的对象" + } + }, + { + "name": "event", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": " 原生 Event" + } + } + ], + "returns": {} + }, + "defaultValue": "function onClick(e) {}" + }, + "onCurrentChange": { + "label": { + "zh_CN": "行点击时触发" + }, + "description": { + "zh_CN": "行点击时触发" + }, + "type": "event", + "functionInfo": { + "params": [], + "returns": {} + }, + "defaultValue": "" + } + }, + "shortcuts": { + "properties": ["sortable", "columns"] + }, + "contentMenu": { + "actions": ["create symbol"] + }, + "onBeforeMount": "console.log('table on load'); this.pager = source.pager; this.fetchData = source.fetchData; this.data = source.data ;this.columns = source.columns" + }, + "configure": { + "loop": false, + "condition": true, + "styles": true, + "isContainer": false, + "isModal": false, + "nestingRule": { + "childWhitelist": "", + "parentWhitelist": "" + } + } + }, + "snippet": { + "name": { + "zh_CN": "表格模型", + "en_US": "TableModel" + }, + "icon": "grid", + "screenshot": "", + "snippetName": "TableModel", + "schema": { + "componentName": "TableModel", + "props": { + "editConfig": { + "trigger": "click", + "mode": "cell", + "showStatus": true + }, + "rowOperations": { + "type": "object", + "value": [] + } + } + } + } +} diff --git a/packages/builtinComponent/src/meta/index.js b/packages/builtinComponent/src/meta/index.js index 7521af69aa..e5a1f19fe0 100644 --- a/packages/builtinComponent/src/meta/index.js +++ b/packages/builtinComponent/src/meta/index.js @@ -3,6 +3,9 @@ import CanvasRow from './CanvasRow.json' import CanvasRowColContainer from './CanvasRowColContainer.json' import CanvasFlexBox from './CanvasFlexBox.json' import CanvasSection from './CanvasSection.json' +import BaseForm from './BaseForm.json' +import BaseTable from './BaseTable.json' +import BasePage from './BasePage.json' export default { components: [ @@ -10,7 +13,10 @@ export default { CanvasRow.component, CanvasRowColContainer.component, CanvasFlexBox.component, - CanvasSection.component + CanvasSection.component, + BaseForm.component, + BaseTable.component, + BasePage.component ], snippets: [ { @@ -19,6 +25,13 @@ export default { zh_CN: '布局与容器' }, children: [CanvasRowColContainer.snippet, CanvasFlexBox.snippet, CanvasSection.snippet] + }, + { + group: 'model', + label: { + zh_CN: '模型组件' + }, + children: [BaseForm.snippet, BaseTable.snippet, BasePage.snippet] } ] } diff --git a/packages/canvas/render/src/material-function/material-getter.ts b/packages/canvas/render/src/material-function/material-getter.ts index 95bc1da415..1b5157a9ae 100644 --- a/packages/canvas/render/src/material-function/material-getter.ts +++ b/packages/canvas/render/src/material-function/material-getter.ts @@ -7,7 +7,10 @@ import { CanvasCol, CanvasRowColContainer, CanvasFlexBox, - CanvasSection + CanvasSection, + FormModel, + TableModel, + PageModel } from '@opentiny/tiny-engine-builtin-component' import { CanvasBox, @@ -38,6 +41,9 @@ export const Mapper = { CanvasCol, CanvasRowColContainer, CanvasPlaceholder, + FormModel, + TableModel, + PageModel, RouterView: CanvasRouterView, RouterLink: CanvasRouterLink } diff --git a/packages/configurator/package.json b/packages/configurator/package.json index ce9eba0f34..032e00cfaf 100644 --- a/packages/configurator/package.json +++ b/packages/configurator/package.json @@ -24,11 +24,13 @@ "peerDependencies": { "@opentiny/vue": "^3.20.0", "@opentiny/vue-icon": "^3.20.0", + "@opentiny/vue-renderless": "^3.20.0", "vue": "^3.4.15" }, "dependencies": { "@opentiny/tiny-engine-common": "workspace:*", "@opentiny/tiny-engine-meta-register": "workspace:*", + "@opentiny/tiny-engine-plugin-i18n": "workspace:*", "@opentiny/tiny-engine-utils": "workspace:*", "@vue/shared": "^3.3.4", "monaco-editor": "0.51.0", diff --git a/packages/configurator/src/bind-variable-configurator/BindVariableConfigurator.vue b/packages/configurator/src/bind-variable-configurator/BindVariableConfigurator.vue new file mode 100644 index 0000000000..ccfc805015 --- /dev/null +++ b/packages/configurator/src/bind-variable-configurator/BindVariableConfigurator.vue @@ -0,0 +1,108 @@ + + + + + diff --git a/packages/configurator/src/index.ts b/packages/configurator/src/index.ts index 0779781377..0f78444384 100644 --- a/packages/configurator/src/index.ts +++ b/packages/configurator/src/index.ts @@ -29,6 +29,10 @@ import SwitchConfigurator from './switch-configurator/SwitchConfigurator.vue' import TableColumnsConfigurator from './table-columns-configurator/TableColumnsConfigurator.vue' import TabsGroupConfigurator from './tabs-group-configurator/TabsGroupConfigurator.vue' import VariableConfigurator from './variable-configurator/VariableConfigurator.vue' +import BindVariableConfigurator from './bind-variable-configurator/BindVariableConfigurator.vue' +import ModelConfigurator from './model-configurator/ModelConfigurator.vue' +import ModelApiConfigurator from './model-api-configurator/ModelApiConfigurator.vue' +import OperatorGroupConfigurator from './operator-group-configurator/OperatorGroupConfigurator.vue' import BasicTagConfigurator from './basic-tag-configurator/BasicTagConfigurator.vue' import ClassConfigurator from './class-configurator/ClassConfigurator.vue' @@ -67,6 +71,10 @@ export { TableColumnsConfigurator, TabsGroupConfigurator, VariableConfigurator, + BindVariableConfigurator, + ModelConfigurator, + ModelApiConfigurator, + OperatorGroupConfigurator, BasicTagConfigurator, ClassConfigurator, MetaCodeEditor, diff --git a/packages/configurator/src/model-api-configurator/ModelApiConfigurator.vue b/packages/configurator/src/model-api-configurator/ModelApiConfigurator.vue new file mode 100644 index 0000000000..0a6b59b91d --- /dev/null +++ b/packages/configurator/src/model-api-configurator/ModelApiConfigurator.vue @@ -0,0 +1,322 @@ + + + + diff --git a/packages/configurator/src/model-api-configurator/ParamsBindGrid.vue b/packages/configurator/src/model-api-configurator/ParamsBindGrid.vue new file mode 100644 index 0000000000..90bd238611 --- /dev/null +++ b/packages/configurator/src/model-api-configurator/ParamsBindGrid.vue @@ -0,0 +1,58 @@ + + + + + diff --git a/packages/configurator/src/model-common/ModelSelect.vue b/packages/configurator/src/model-common/ModelSelect.vue new file mode 100644 index 0000000000..8c708b6adb --- /dev/null +++ b/packages/configurator/src/model-common/ModelSelect.vue @@ -0,0 +1,147 @@ + + + + diff --git a/packages/configurator/src/model-common/constants.js b/packages/configurator/src/model-common/constants.js new file mode 100644 index 0000000000..883fd27c2b --- /dev/null +++ b/packages/configurator/src/model-common/constants.js @@ -0,0 +1,23 @@ +export const typeComponentsMap = { + String: { component: 'TinyInput' }, + Boolean: { + component: 'TinySelect', + props: { + options: [ + { + label: '是', + value: true, + }, + { + label: '否', + value: false, + }, + ] + }, + }, + Date: { component: 'TinyDatePicker', props: { format: 'yyyy-MM-dd', valueFormat: 'yyyy-MM-dd' }}, + Number: { component: 'TinyNumeric' }, + Enum: { + component: 'TinySelect' + }, +}; \ No newline at end of file diff --git a/packages/configurator/src/model-common/http.js b/packages/configurator/src/model-common/http.js new file mode 100644 index 0000000000..f1c104b3dd --- /dev/null +++ b/packages/configurator/src/model-common/http.js @@ -0,0 +1,6 @@ +import { getMetaApi, META_SERVICE } from '@opentiny/tiny-engine-meta-register' + +export const getModelList = (currentPage, params) => + getMetaApi(META_SERVICE.Http).get(`/material-center/api/model/list?currentPage=${currentPage}&pageSize=10`, { + params: params || {} + }) diff --git a/packages/configurator/src/model-common/utils.js b/packages/configurator/src/model-common/utils.js new file mode 100644 index 0000000000..7c760f315d --- /dev/null +++ b/packages/configurator/src/model-common/utils.js @@ -0,0 +1,52 @@ +import { getModelList } from './http' +import { typeComponentsMap } from './constants' + +const handleModelParameters = (paramItem) => { + const extension = {} + if (paramItem.type === 'Enum') { + extension.options = JSON.parse(paramItem.options) || [] + } + const item = { + ...paramItem, + ...(typeComponentsMap[paramItem.type]?.props || {}), + ...extension, + originType: paramItem.type, + label: paramItem?.label ?? paramItem.prop, + isModel: paramItem.isModel, + component: typeComponentsMap[paramItem.type]?.component ?? 'TinyInput', + itemVisible: true + } + delete item.type + return item +} + +export const handleSelectedModelParameters = async (model) => { + const parameters = await Promise.all( + (model?.parameters || model).map(async (item) => { + const defaultItem = handleModelParameters(item) + // 如果是关联字段,则查询关联模型数据 + if (item?.isModel) { + const data = await getModelList(1, { id: item.defaultValue }) + return { + ...defaultItem, + defaultValue: (data.records.length > 0 ? data.records[0].parameters : []).map((insideItem) => + handleModelParameters(insideItem) + ) + } + } else { + return defaultItem + } + }) + ) + return model?.parameters + ? { + id: model.id, + name: model.nameCn, + nameEn: model.nameEn, + description: model.description, + version: model.version, + baseUrl: model.modelUrl ?? '', + parameters + } + : parameters +} diff --git a/packages/configurator/src/model-configurator/MetaListItem.vue b/packages/configurator/src/model-configurator/MetaListItem.vue new file mode 100644 index 0000000000..f75803564b --- /dev/null +++ b/packages/configurator/src/model-configurator/MetaListItem.vue @@ -0,0 +1,258 @@ + + + + + diff --git a/packages/configurator/src/model-configurator/ModelConfigurator.vue b/packages/configurator/src/model-configurator/ModelConfigurator.vue new file mode 100644 index 0000000000..49c90fb682 --- /dev/null +++ b/packages/configurator/src/model-configurator/ModelConfigurator.vue @@ -0,0 +1,513 @@ + + + + + diff --git a/packages/configurator/src/operator-group-configurator/MetaChildItem.vue b/packages/configurator/src/operator-group-configurator/MetaChildItem.vue new file mode 100644 index 0000000000..c9a18f1499 --- /dev/null +++ b/packages/configurator/src/operator-group-configurator/MetaChildItem.vue @@ -0,0 +1,121 @@ + + + + + diff --git a/packages/configurator/src/operator-group-configurator/MetaList.vue b/packages/configurator/src/operator-group-configurator/MetaList.vue new file mode 100644 index 0000000000..fefeead3fb --- /dev/null +++ b/packages/configurator/src/operator-group-configurator/MetaList.vue @@ -0,0 +1,21 @@ + + + diff --git a/packages/configurator/src/operator-group-configurator/MetaListItem.vue b/packages/configurator/src/operator-group-configurator/MetaListItem.vue new file mode 100644 index 0000000000..c0396ab153 --- /dev/null +++ b/packages/configurator/src/operator-group-configurator/MetaListItem.vue @@ -0,0 +1,354 @@ + + + + + diff --git a/packages/configurator/src/operator-group-configurator/OperatorGroupConfigurator.vue b/packages/configurator/src/operator-group-configurator/OperatorGroupConfigurator.vue new file mode 100644 index 0000000000..d155d1fb29 --- /dev/null +++ b/packages/configurator/src/operator-group-configurator/OperatorGroupConfigurator.vue @@ -0,0 +1,210 @@ + + + + + diff --git a/packages/design-core/assets/plugin-icon-modelmanager.svg b/packages/design-core/assets/plugin-icon-modelmanager.svg new file mode 100644 index 0000000000..f2c88bcd14 --- /dev/null +++ b/packages/design-core/assets/plugin-icon-modelmanager.svg @@ -0,0 +1,13 @@ + + + Created with Pixso. + + + + + + + + + + diff --git a/packages/design-core/package.json b/packages/design-core/package.json index f524e887db..4e7cc073a5 100644 --- a/packages/design-core/package.json +++ b/packages/design-core/package.json @@ -62,6 +62,7 @@ "@opentiny/tiny-engine-plugin-state": "workspace:*", "@opentiny/tiny-engine-plugin-tree": "workspace:*", "@opentiny/tiny-engine-plugin-tutorial": "workspace:*", + "@opentiny/tiny-engine-plugin-model-manager": "workspace:*", "@opentiny/tiny-engine-setting-design": "workspace:*", "@opentiny/tiny-engine-setting-events": "workspace:*", "@opentiny/tiny-engine-setting-props": "workspace:*", diff --git a/packages/design-core/re-export.js b/packages/design-core/re-export.js index ca1b0e7db8..1d71e340bb 100644 --- a/packages/design-core/re-export.js +++ b/packages/design-core/re-export.js @@ -27,6 +27,7 @@ export { default as Bridge } from '@opentiny/tiny-engine-plugin-bridge' export { default as Block, BlockService } from '@opentiny/tiny-engine-plugin-block' export { default as Datasource, DataSourceService } from '@opentiny/tiny-engine-plugin-datasource' export { default as Robot } from '@opentiny/tiny-engine-plugin-robot' +export { default as ModelManager } from '@opentiny/tiny-engine-plugin-model-manager' export { default as Props, PropertiesService, PropertyService } from '@opentiny/tiny-engine-setting-props' export { default as Events } from '@opentiny/tiny-engine-setting-events' export { default as Styles } from '@opentiny/tiny-engine-setting-styles' diff --git a/packages/design-core/registry.js b/packages/design-core/registry.js index a12711d3fc..147a7095e7 100644 --- a/packages/design-core/registry.js +++ b/packages/design-core/registry.js @@ -40,6 +40,7 @@ import { Block, Datasource, Robot, + ModelManager, Props, Events, Styles, @@ -161,7 +162,8 @@ export default { __TINY_ENGINE_REMOVED_REGISTRY['engine.plugins.state'] === false ? null : State, __TINY_ENGINE_REMOVED_REGISTRY['engine.plugins.schema'] === false ? null : Schema, __TINY_ENGINE_REMOVED_REGISTRY['engine.plugins.editorhelp'] === false ? null : Help, - __TINY_ENGINE_REMOVED_REGISTRY['engine.plugins.robot'] === false ? null : Robot + __TINY_ENGINE_REMOVED_REGISTRY['engine.plugins.robot'] === false ? null : Robot, + __TINY_ENGINE_REMOVED_REGISTRY['engine.plugins.modelmanager'] === false ? null : ModelManager ], settings: [ __TINY_ENGINE_REMOVED_REGISTRY['engine.setting.props'] === false ? null : Props, diff --git a/packages/layout/src/defaultLayout.js b/packages/layout/src/defaultLayout.js index 1c90c1c80c..8d17e1ffd5 100644 --- a/packages/layout/src/defaultLayout.js +++ b/packages/layout/src/defaultLayout.js @@ -12,7 +12,8 @@ export default { META_APP.Bridge, META_APP.I18n, META_APP.Page, - META_APP.State + META_APP.State, + META_APP.ModelManager ], bottom: [META_APP.Schema, META_APP.Help, META_APP.Robot] }, diff --git a/packages/plugins/model-manager/index.ts b/packages/plugins/model-manager/index.ts new file mode 100644 index 0000000000..a20999e2ac --- /dev/null +++ b/packages/plugins/model-manager/index.ts @@ -0,0 +1,8 @@ +import entry from './src/Main.vue' +import metaData from './meta' +import './src/styles/vars.less' + +export default { + ...metaData, + entry +} diff --git a/packages/plugins/model-manager/meta.js b/packages/plugins/model-manager/meta.js new file mode 100644 index 0000000000..7dd4e4c518 --- /dev/null +++ b/packages/plugins/model-manager/meta.js @@ -0,0 +1,7 @@ +export default { + id: 'engine.plugins.modelmanager', + title: '模型管理', + type: 'plugins', + width: 280, + icon: 'plugin-icon-modelmanager' +} diff --git a/packages/plugins/model-manager/package.json b/packages/plugins/model-manager/package.json new file mode 100644 index 0000000000..a2b90a7429 --- /dev/null +++ b/packages/plugins/model-manager/package.json @@ -0,0 +1,47 @@ +{ + "name": "@opentiny/tiny-engine-plugin-model-manager", + "version": "2.8.0", + "publishConfig": { + "access": "public" + }, + "scripts": { + "build": "vite build" + }, + "type": "module", + "main": "dist/index.js", + "module": "dist/index.js", + "files": [ + "dist" + ], + "keywords": [ + "tiny-engine-plugin", + "model-manager" + ], + "repository": { + "type": "git", + "url": "https://github.com/opentiny/tiny-engine", + "directory": "packages/plugins/model-manager" + }, + "bugs": { + "url": "https://github.com/opentiny/tiny-engine/issues" + }, + "author": "OpenTiny Team", + "license": "MIT", + "homepage": "https://opentiny.design/tiny-engine", + "dependencies": { + "@opentiny/tiny-engine-meta-register": "workspace:*", + "@opentiny/tiny-engine-common": "workspace:*" + }, + "devDependencies": { + "@opentiny/tiny-engine-vite-plugin-meta-comments": "workspace:*", + "@vitejs/plugin-vue": "^5.1.2", + "@vitejs/plugin-vue-jsx": "^4.0.1", + "vite": "^5.4.2" + }, + "peerDependencies": { + "@opentiny/vue": "^3.20.0", + "@opentiny/vue-icon": "^3.20.0", + "@opentiny/vue-renderless": "^3.20.0", + "vue": "^3.4.15" + } +} diff --git a/packages/plugins/model-manager/src/Main.vue b/packages/plugins/model-manager/src/Main.vue new file mode 100644 index 0000000000..c0cab6efb0 --- /dev/null +++ b/packages/plugins/model-manager/src/Main.vue @@ -0,0 +1,250 @@ + + + + + diff --git a/packages/plugins/model-manager/src/components/FieldManager.vue b/packages/plugins/model-manager/src/components/FieldManager.vue new file mode 100644 index 0000000000..a9a514b011 --- /dev/null +++ b/packages/plugins/model-manager/src/components/FieldManager.vue @@ -0,0 +1,356 @@ + + + + + diff --git a/packages/plugins/model-manager/src/components/ModelBasicForm.vue b/packages/plugins/model-manager/src/components/ModelBasicForm.vue new file mode 100644 index 0000000000..293d2b175f --- /dev/null +++ b/packages/plugins/model-manager/src/components/ModelBasicForm.vue @@ -0,0 +1,104 @@ + + + + + diff --git a/packages/plugins/model-manager/src/components/ModelSetting.vue b/packages/plugins/model-manager/src/components/ModelSetting.vue new file mode 100644 index 0000000000..758ff8c91f --- /dev/null +++ b/packages/plugins/model-manager/src/components/ModelSetting.vue @@ -0,0 +1,213 @@ + + + diff --git a/packages/plugins/model-manager/src/composable/useModelManager.js b/packages/plugins/model-manager/src/composable/useModelManager.js new file mode 100644 index 0000000000..55f0747a3f --- /dev/null +++ b/packages/plugins/model-manager/src/composable/useModelManager.js @@ -0,0 +1,28 @@ +import { getMetaApi, META_SERVICE } from '@opentiny/tiny-engine-meta-register' + +// 示例API路径,请根据实际后端接口调整 +const modelApi = '/material-center/api/model' + +export function getModelList(params = {}) { + return getMetaApi(META_SERVICE.Http).get(`${modelApi}/list`, { params }) +} + +export function createModel(data) { + return getMetaApi(META_SERVICE.Http).post(`${modelApi}/create`, data) +} + +export function updateModel(id, data) { + return getMetaApi(META_SERVICE.Http).put(`${modelApi}/update/${id}`, data) +} + +export function deleteModel(id) { + return getMetaApi(META_SERVICE.Http).delete(`${modelApi}/delete/${id}`) +} + +export function getModelSql() { + return getMetaApi(META_SERVICE.Http).get(`${modelApi}/table/list`) +} + +export function getModelSqlById(id) { + return getMetaApi(META_SERVICE.Http).get(`${modelApi}/table/${id}`) +} diff --git a/packages/plugins/model-manager/src/styles/vars.less b/packages/plugins/model-manager/src/styles/vars.less new file mode 100644 index 0000000000..3ea5b23c9f --- /dev/null +++ b/packages/plugins/model-manager/src/styles/vars.less @@ -0,0 +1,21 @@ +.plugin-modelmanager { + --te-model-manage-title-text-color: var(--te-common-text-primary); + --te-model-manage-input-bg-color: var(--te-common-bg-default); + --te-model-manage-input-border-color: var(--te-common-border-default); + --te-model-manage-tip-color: var(--te-common-text-primary); + --te-model-manage-tip-text-color: var(--te-common-text-weaken); + --te-model-manage-tip-dim-text-color: var(--te-common-text-primary); + --te-model-manage-tree-text-bg-color: var(--te-common-bg-default); + --te-model-manage-tree-node-bg-color: var(--te-common-bg-default); + --te-model-manage-tree-node-bg-color-hover: var(--te-common-bg-container); + --te-model-manage-text-color: var(--te-common-text-secondary); + --te-model-manage-input-head-text-color: var(--te-common-text-primary); + --te-model-manage-input-or-output-text-color: var(--te-common-text-secondary); + --te-model-manage-life-cycle-alert-text-color: var(--te-common-text-weaken); + --te-model-manage-icon-color: var(--te-common-icon-secondary); + --te-model-manage-draggable-row-bg-color-hover: var(--te-common-bg-container); + --te-model-manage-draggable-text-color: var(--te-common-text-primary); + --te-model-manage-draggable-icon-color: var(--te-common-icon-secondary); + --te-model-manage-draggable-border-color: var(--te-common-border-checked); + --te-model-common-border-color-divider: var(--te-common-border-divider); +} diff --git a/packages/plugins/model-manager/vite.config.ts b/packages/plugins/model-manager/vite.config.ts new file mode 100644 index 0000000000..23b1ee2414 --- /dev/null +++ b/packages/plugins/model-manager/vite.config.ts @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2023 - present TinyEngine Authors. + * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd. + * + * Use of this source code is governed by an MIT-style license. + * + * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, + * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR + * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. + * + */ + +import { defineConfig } from 'vite' +import path from 'path' +import vue from '@vitejs/plugin-vue' +import vueJsx from '@vitejs/plugin-vue-jsx' +import generateComment from '@opentiny/tiny-engine-vite-plugin-meta-comments' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [generateComment(), vue(), vueJsx()], + publicDir: false, + resolve: {}, + build: { + sourcemap: true, + lib: { + entry: path.resolve(__dirname, './index.ts'), + name: 'plugin-model-manager', + fileName: (_format, entryName) => `${entryName}.js`, + formats: ['es'] + }, + rollupOptions: { + output: { + banner: 'import "./style.css"' + }, + external: ['vue', /@opentiny\/tiny-engine.*/, /@opentiny\/vue.*/] + } + } +}) diff --git a/packages/register/src/constants.ts b/packages/register/src/constants.ts index c09be033b9..20a0bd9cce 100644 --- a/packages/register/src/constants.ts +++ b/packages/register/src/constants.ts @@ -68,6 +68,8 @@ export const META_APP = { Schema: 'engine.plugins.schema', // 新手帮助/帮助文档 Help: 'engine.plugins.editorhelp', + // 模型管理插件 + ModelManager: 'engine.plugins.modelmanager', // 属性设置面板 Props: 'engine.setting.props', // 样式设置面板 diff --git a/packages/vue-generator/src/constant/index.js b/packages/vue-generator/src/constant/index.js index e639d92353..e7385d8105 100644 --- a/packages/vue-generator/src/constant/index.js +++ b/packages/vue-generator/src/constant/index.js @@ -2209,6 +2209,27 @@ export const BUILTIN_COMPONENTS_MAP = [ package: '@opentiny/tiny-engine-builtin-component', version: '^2.0.0', destructuring: true + }, + { + componentName: 'FormModel', + exportName: 'FormModel', + package: '@opentiny/tiny-engine-builtin-component', + version: '^2.0.0', + destructuring: true + }, + { + componentName: 'TableModel', + exportName: 'TableModel', + package: '@opentiny/tiny-engine-builtin-component', + version: '^2.0.0', + destructuring: true + }, + { + componentName: 'PageModel', + exportName: 'PageModel', + package: '@opentiny/tiny-engine-builtin-component', + version: '^2.0.0', + destructuring: true } ] diff --git a/tsconfig.app.json b/tsconfig.app.json index 65003a243b..3ab1d0ed93 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -34,6 +34,7 @@ "@opentiny/tiny-engine-plugin-script": ["packages/plugins/script/index"], "@opentiny/tiny-engine-plugin-state": ["packages/plugins/state/index"], "@opentiny/tiny-engine-plugin-tree": ["packages/plugins/tree/index"], + "@opentiny/tiny-engine-plugin-model-manager": ["packages/plugins/model-manager/index"], "@opentiny/tiny-engine-setting-events": ["packages/settings/events/index"], "@opentiny/tiny-engine-setting-props": ["packages/settings/props/index"], "@opentiny/tiny-engine-setting-styles": ["packages/settings/styles/index"], From f45f68606e26a91bd326292be6c395a8119a50a0 Mon Sep 17 00:00:00 2001 From: betterdancing Date: Thu, 18 Sep 2025 02:10:14 +0800 Subject: [PATCH 052/101] feat(preview): support app preview (#1628) --- packages/common/component/ToolbarBase.vue | 7 +- .../toolbar-built-in/ToolbarBaseIcon.vue | 7 +- packages/common/js/preview.js | 2 + .../src/preview/src/preview/http.js | 2 + .../src/preview/src/preview/usePreviewData.ts | 303 +++++++++++++++--- packages/toolbars/preview/src/Main.vue | 30 +- packages/toolbars/preview/vite.config.ts | 3 + .../src/plugins/genI18nPlugin.js | 6 +- .../vue-template/templateFiles/src/App.vue | 2 +- .../templateFiles/src/http/axios.js | 58 ---- .../templateFiles/src/http/index.js | 4 +- .../src/lowcodeConfig/dataSource.js | 6 +- .../src/lowcodeConfig/lowcode.js | 8 +- .../templateFiles/src/lowcodeConfig/store.js | 2 +- .../vue-template/templateFiles/src/main.js | 4 +- 15 files changed, 318 insertions(+), 126 deletions(-) diff --git a/packages/common/component/ToolbarBase.vue b/packages/common/component/ToolbarBase.vue index 88bd69dd22..cd7ea7f704 100644 --- a/packages/common/component/ToolbarBase.vue +++ b/packages/common/component/ToolbarBase.vue @@ -32,6 +32,10 @@ export default { options: { type: Object, default: () => ({}) + }, + trigger: { + type: String, + default: 'hover' } }, emits: ['click-api'], @@ -39,7 +43,8 @@ export default { const state = reactive({ icon: computed(() => props.icon), content: computed(() => props.content), - options: computed(() => props.options) + options: computed(() => props.options), + trigger: computed(() => props.trigger) }) const click = () => { diff --git a/packages/common/component/toolbar-built-in/ToolbarBaseIcon.vue b/packages/common/component/toolbar-built-in/ToolbarBaseIcon.vue index df8630f408..c50a8d1488 100644 --- a/packages/common/component/toolbar-built-in/ToolbarBaseIcon.vue +++ b/packages/common/component/toolbar-built-in/ToolbarBaseIcon.vue @@ -1,11 +1,12 @@ @@ -159,7 +159,7 @@ const getModelLists = async () => { currentPage: 1, pageSize: 500 }) - models.value = data.records + models.value = data.records || [] } // 导出模型的sql const exportModel = async (id) => { diff --git a/packages/plugins/resource/index.ts b/packages/plugins/resource/index.ts new file mode 100644 index 0000000000..d7800acd2b --- /dev/null +++ b/packages/plugins/resource/index.ts @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2023 - present TinyEngine Authors. + * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd. + * + * Use of this source code is governed by an MIT-style license. + * + * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, + * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR + * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. + * + */ + +import entry from './src/Main.vue' +import metaData from './meta' +import './src/styles/vars.less' + +export default { + ...metaData, + entry +} diff --git a/packages/plugins/resource/meta.js b/packages/plugins/resource/meta.js new file mode 100644 index 0000000000..e31c579141 --- /dev/null +++ b/packages/plugins/resource/meta.js @@ -0,0 +1,6 @@ +export default { + id: 'engine.plugins.resource', + title: '资源管理', + type: 'plugins', + icon: 'plugin-icon-resource' +} diff --git a/packages/plugins/resource/package.json b/packages/plugins/resource/package.json new file mode 100644 index 0000000000..c2bc0a12ae --- /dev/null +++ b/packages/plugins/resource/package.json @@ -0,0 +1,43 @@ +{ + "name": "@opentiny/tiny-engine-plugin-resource", + "version": "2.8.0", + "publishConfig": { + "access": "public" + }, + "scripts": { + "build": "vite build" + }, + "type": "module", + "main": "dist/index.js", + "module": "dist/index.js", + "files": [ + "dist" + ], + "repository": { + "type": "git", + "url": "https://github.com/opentiny/tiny-engine", + "directory": "packages/plugins/resource" + }, + "bugs": { + "url": "https://github.com/opentiny/tiny-engine/issues" + }, + "author": "OpenTiny Team", + "license": "MIT", + "homepage": "https://opentiny.design/tiny-engine", + "dependencies": { + "@opentiny/tiny-engine-common": "workspace:*", + "@opentiny/tiny-engine-meta-register": "workspace:*", + "vue-clipboard3": "^2.0.0" + }, + "devDependencies": { + "@opentiny/tiny-engine-vite-plugin-meta-comments": "workspace:*", + "@vitejs/plugin-vue": "^5.1.2", + "@vitejs/plugin-vue-jsx": "^4.0.1", + "vite": "^5.4.2" + }, + "peerDependencies": { + "@opentiny/vue": "^3.20.0", + "@opentiny/vue-icon": "^3.20.0", + "vue": "^3.4.15" + } +} diff --git a/packages/plugins/resource/src/Main.vue b/packages/plugins/resource/src/Main.vue new file mode 100644 index 0000000000..62c1f8d5f0 --- /dev/null +++ b/packages/plugins/resource/src/Main.vue @@ -0,0 +1,184 @@ + + + diff --git a/packages/plugins/resource/src/ResourceList.vue b/packages/plugins/resource/src/ResourceList.vue new file mode 100644 index 0000000000..7fbbf51c44 --- /dev/null +++ b/packages/plugins/resource/src/ResourceList.vue @@ -0,0 +1,627 @@ + + + diff --git a/packages/plugins/resource/src/ResourceSetting.vue b/packages/plugins/resource/src/ResourceSetting.vue new file mode 100644 index 0000000000..04fbc889a3 --- /dev/null +++ b/packages/plugins/resource/src/ResourceSetting.vue @@ -0,0 +1,177 @@ + + + diff --git a/packages/plugins/resource/src/js/http.ts b/packages/plugins/resource/src/js/http.ts new file mode 100644 index 0000000000..f39ad5c49d --- /dev/null +++ b/packages/plugins/resource/src/js/http.ts @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2023 - present TinyEngine Authors. + * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd. + * + * Use of this source code is governed by an MIT-style license. + * + * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, + * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR + * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. + * + */ + +/* metaService: engine.plugins.resource.http */ +import { getMetaApi, getMergeMeta, META_SERVICE } from '@opentiny/tiny-engine-meta-register' + +const baseUrl = '/material-center/api' +// 资源管理 -- 根据分组ID获取资源列表 +export const fetchResourceListByGroupId = (resourceGroupId: number) => + getMetaApi(META_SERVICE.Http).get(`${baseUrl}/resource/find/${resourceGroupId}`) + +// 资源管理 -- 获取资源列表含模糊查询 +export const fetchResourceList = () => getMetaApi(META_SERVICE.Http).get(`${baseUrl}/resource/like`) + +// 资源管理 -- 创建资源 +export const createResource = (params: any) => + getMetaApi(META_SERVICE.Http).post(`${baseUrl}/resource/create`, { + appId: getMetaApi(META_SERVICE.GlobalService).getBaseInfo().id, + platformId: getMergeMeta('engine.config')?.platformId, + ...params + }) + +// 资源管理 -- 批量创建资源 +export const batchCreateResource = (params: any) => + getMetaApi(META_SERVICE.Http).post( + `${baseUrl}/resource/create/batch`, + params.map((item: any) => ({ + appId: getMetaApi(META_SERVICE.GlobalService).getBaseInfo().id, + platformId: getMergeMeta('engine.config')?.platformId, + ...item + })) + ) + +// 资源管理 -- 删除资源 +export const deleteResource = (id: number) => getMetaApi(META_SERVICE.Http).get(`${baseUrl}/resource/delete/${id}`) + +// 资源管理 -- 根据appId查询资源分组列表 +export const fetchResourceGroupByAppId = () => + getMetaApi(META_SERVICE.Http).get( + `${baseUrl}/resource-group/${getMetaApi(META_SERVICE.GlobalService).getBaseInfo().id}` + ) + +// 资源管理 -- 创建资源分组 +export const createResourceGroup = (params: any) => + getMetaApi(META_SERVICE.Http).post(`${baseUrl}/resource-group/create`, { + appId: getMetaApi(META_SERVICE.GlobalService).getBaseInfo().id, + platformId: getMergeMeta('engine.config')?.platformId, + ...params + }) + +// 资源管理 -- 修改资源分组信息-包括删除 +export const updateResourceGroup = (id: number, params: any) => + getMetaApi(META_SERVICE.Http).put(`${baseUrl}/resource-group/update/${id}`, params) diff --git a/packages/plugins/resource/src/styles/vars.less b/packages/plugins/resource/src/styles/vars.less new file mode 100644 index 0000000000..6b50111adb --- /dev/null +++ b/packages/plugins/resource/src/styles/vars.less @@ -0,0 +1,21 @@ +.plugin-resource { + --te-resource-manage-title-text-color: var(--te-common-text-primary); + --te-resource-manage-button-text-color: var(--te-common-text-inverse); + --te-resource-manage-input-bg-color: var(--te-common-bg-default); + --te-resource-manage-input-border-color: var(--te-common-border-default); + --te-resource-manage-tip-color: var(--te-common-text-primary); + --te-resource-manage-tip-text-color: var(--te-common-text-weaken); + --te-resource-manage-tip-dim-text-color: var(--te-common-text-primary); + --te-resource-manage-tree-text-bg-color: var(--te-common-bg-default); + --te-resource-manage-tree-node-bg-color: var(--te-common-bg-default); + --te-resource-manage-tree-node-bg-color-hover: var(--te-common-bg-container); + --te-resource-manage-text-color: var(--te-common-text-secondary); + --te-resource-manage-input-head-text-color: var(--te-common-text-primary); + --te-resource-manage-input-or-output-text-color: var(--te-common-text-secondary); + --te-resource-manage-life-cycle-alert-text-color: var(--te-common-text-weaken); + --te-resource-manage-icon-color: var(--te-common-icon-secondary); + --te-resource-manage-draggable-row-bg-color-hover: var(--te-common-bg-container); + --te-resource-manage-draggable-text-color: var(--te-common-text-primary); + --te-resource-manage-draggable-icon-color: var(--te-common-icon-secondary); + --te-resource-manage-draggable-border-color: var(--te-common-border-checked); +} diff --git a/packages/plugins/resource/vite.config.ts b/packages/plugins/resource/vite.config.ts new file mode 100644 index 0000000000..e34785fe3c --- /dev/null +++ b/packages/plugins/resource/vite.config.ts @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2023 - present TinyEngine Authors. + * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd. + * + * Use of this source code is governed by an MIT-style license. + * + * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, + * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR + * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. + * + */ + +import { defineConfig } from 'vite' +import path from 'path' +import vue from '@vitejs/plugin-vue' +import vueJsx from '@vitejs/plugin-vue-jsx' +import generateComment from '@opentiny/tiny-engine-vite-plugin-meta-comments' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [generateComment(), vue(), vueJsx()], + publicDir: false, + resolve: {}, + build: { + sourcemap: true, + lib: { + entry: path.resolve(__dirname, './index.ts'), + name: 'plugin-resource', + fileName: (_format, entryName) => `${entryName}.js`, + formats: ['es'] + }, + rollupOptions: { + output: { + banner: 'import "./style.css"' + }, + external: ['vue', /@opentiny\/tiny-engine.*/, /@opentiny\/vue.*/] + } + } +}) diff --git a/packages/register/src/constants.ts b/packages/register/src/constants.ts index 20a0bd9cce..6019640633 100644 --- a/packages/register/src/constants.ts +++ b/packages/register/src/constants.ts @@ -66,6 +66,8 @@ export const META_APP = { State: 'engine.plugins.state', // 页面 schema 插件 Schema: 'engine.plugins.schema', + // 资源管理 插件 + Resource: 'engine.plugins.resource', // 新手帮助/帮助文档 Help: 'engine.plugins.editorhelp', // 模型管理插件 From 91adc98bc0b0eea57ed9a3013b7515f5372f576a Mon Sep 17 00:00:00 2001 From: xuanlid <51027603+xuanlid@users.noreply.github.com> Date: Wed, 17 Sep 2025 23:49:39 -0700 Subject: [PATCH 054/101] feat: add static data source (#1619) --- .../canvas/render/src/builtin/CanvasCollection.ts | 2 +- packages/plugins/datasource/src/DataSourceForm.vue | 14 ++++++++------ packages/plugins/datasource/src/DataSourceList.vue | 5 +---- packages/plugins/datasource/src/DataSourceType.vue | 4 ++++ .../templateFiles/src/lowcodeConfig/dataSource.js | 4 +++- .../appdemo01/src/lowcodeConfig/dataSource.js | 4 +++- .../appdemo01/src/lowcodeConfig/dataSource.js | 4 +++- 7 files changed, 23 insertions(+), 14 deletions(-) diff --git a/packages/canvas/render/src/builtin/CanvasCollection.ts b/packages/canvas/render/src/builtin/CanvasCollection.ts index 35aeff5907..a156f88464 100644 --- a/packages/canvas/render/src/builtin/CanvasCollection.ts +++ b/packages/canvas/render/src/builtin/CanvasCollection.ts @@ -183,7 +183,7 @@ return new Promise((resolve, reject) => { this.dataSourceMap.${sourceName}.load().then((res) => { // 如果按照数据源面板的建议格式编写dataHandler // 那么dataSourceMap的res格式应该是:{ code: string, msg: string, data: {items: any[], total: number} } - resolve({ result: res.data.items, page: { total: res.data.total } }); + resolve({ result: res?.data?.items || res?.data, page: { total: res?.data?.total || res?.total || res.data.length } }); }); }); }` diff --git a/packages/plugins/datasource/src/DataSourceForm.vue b/packages/plugins/datasource/src/DataSourceForm.vue index 3037c22b3c..13cc5534a5 100644 --- a/packages/plugins/datasource/src/DataSourceForm.vue +++ b/packages/plugins/datasource/src/DataSourceForm.vue @@ -210,12 +210,14 @@ export default { } const save = async () => { - try { - // await validate() 如果验证不通过会抛出异常,而不是返回 false - await getServiceForm().validate() - } catch (error) { - activeTabChange('remote') - return + if (state.dataSource.data.type === 'remote') { + try { + // await validate() 如果验证不通过会抛出异常,而不是返回 false + await getServiceForm().validate() + } catch (error) { + activeTabChange('remote') + return + } } getDataSourceName().validate(async (valid) => { if (valid) { diff --git a/packages/plugins/datasource/src/DataSourceList.vue b/packages/plugins/datasource/src/DataSourceList.vue index 9501722061..2abd81e2bd 100644 --- a/packages/plugins/datasource/src/DataSourceList.vue +++ b/packages/plugins/datasource/src/DataSourceList.vue @@ -70,10 +70,7 @@ export default { const openDataSourceForm = (item, index) => { activeIndex.value = index fetchDataSourceDetail(item.id).then((data) => { - const editData = { ...data, data: { ...data.data, type: 'remote' } } || { - ...item, - data: { ...item.data, type: 'remote' } - } + const editData = data || item emit('edit', editData) getServiceForm()?.clearValidate() }) diff --git a/packages/plugins/datasource/src/DataSourceType.vue b/packages/plugins/datasource/src/DataSourceType.vue index 270eb2e9a2..c0b0fc3589 100644 --- a/packages/plugins/datasource/src/DataSourceType.vue +++ b/packages/plugins/datasource/src/DataSourceType.vue @@ -44,6 +44,10 @@ export default { { name: '远程数据源', value: 'remote' + }, + { + name: '静态数据源', + value: 'field' } ] diff --git a/packages/vue-generator/src/templates/vue-template/templateFiles/src/lowcodeConfig/dataSource.js b/packages/vue-generator/src/templates/vue-template/templateFiles/src/lowcodeConfig/dataSource.js index 166b549097..1b54f9107c 100644 --- a/packages/vue-generator/src/templates/vue-template/templateFiles/src/lowcodeConfig/dataSource.js +++ b/packages/vue-generator/src/templates/vue-template/templateFiles/src/lowcodeConfig/dataSource.js @@ -25,7 +25,9 @@ const createFn = (fnContent) => { } } -const globalDataHandle = dataSources.dataHandler ? createFn(dataSources.dataHandler.value) : (res) => res +const globalDataHandle = dataSources.dataHandler + ? createFn(dataSources.dataHandler.value) + : (res) => Promise.resolve({ data: res }) const load = (http, options, dataSource, shouldFetch) => (params, customUrl) => { // 如果没有配置远程请求,则直接返回静态数据,返回前可能会有全局数据处理 diff --git a/packages/vue-generator/test/testcases/element-plus-case/expected/appdemo01/src/lowcodeConfig/dataSource.js b/packages/vue-generator/test/testcases/element-plus-case/expected/appdemo01/src/lowcodeConfig/dataSource.js index f82f146bfc..5ac149730c 100644 --- a/packages/vue-generator/test/testcases/element-plus-case/expected/appdemo01/src/lowcodeConfig/dataSource.js +++ b/packages/vue-generator/test/testcases/element-plus-case/expected/appdemo01/src/lowcodeConfig/dataSource.js @@ -25,7 +25,9 @@ const createFn = (fnContent) => { } } -const globalDataHandle = dataSources.dataHandler ? createFn(dataSources.dataHandler.value) : (res) => res +const globalDataHandle = dataSources.dataHandler + ? createFn(dataSources.dataHandler.value) + : Promise.resolve({ data: res }) const load = (http, options, dataSource, shouldFetch) => (params, customUrl) => { // 如果没有配置远程请求,则直接返回静态数据,返回前可能会有全局数据处理 diff --git a/packages/vue-generator/test/testcases/generator/expected/appdemo01/src/lowcodeConfig/dataSource.js b/packages/vue-generator/test/testcases/generator/expected/appdemo01/src/lowcodeConfig/dataSource.js index f82f146bfc..5ac149730c 100644 --- a/packages/vue-generator/test/testcases/generator/expected/appdemo01/src/lowcodeConfig/dataSource.js +++ b/packages/vue-generator/test/testcases/generator/expected/appdemo01/src/lowcodeConfig/dataSource.js @@ -25,7 +25,9 @@ const createFn = (fnContent) => { } } -const globalDataHandle = dataSources.dataHandler ? createFn(dataSources.dataHandler.value) : (res) => res +const globalDataHandle = dataSources.dataHandler + ? createFn(dataSources.dataHandler.value) + : Promise.resolve({ data: res }) const load = (http, options, dataSource, shouldFetch) => (params, customUrl) => { // 如果没有配置远程请求,则直接返回静态数据,返回前可能会有全局数据处理 From 439aea7233cf3c461a10e06145c4c394c217148f Mon Sep 17 00:00:00 2001 From: xuanlid <51027603+xuanlid@users.noreply.github.com> Date: Thu, 18 Sep 2025 01:46:14 -0700 Subject: [PATCH 055/101] feat:Modify the output code of static data source (#1634) --- packages/canvas/render/src/builtin/CanvasCollection.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/canvas/render/src/builtin/CanvasCollection.ts b/packages/canvas/render/src/builtin/CanvasCollection.ts index a156f88464..e4479a7620 100644 --- a/packages/canvas/render/src/builtin/CanvasCollection.ts +++ b/packages/canvas/render/src/builtin/CanvasCollection.ts @@ -183,7 +183,7 @@ return new Promise((resolve, reject) => { this.dataSourceMap.${sourceName}.load().then((res) => { // 如果按照数据源面板的建议格式编写dataHandler // 那么dataSourceMap的res格式应该是:{ code: string, msg: string, data: {items: any[], total: number} } - resolve({ result: res?.data?.items || res?.data, page: { total: res?.data?.total || res?.total || res.data.length } }); + resolve({ result: res?.data?.items || res?.data?.data || res?.data, page: { total: res?.data?.total || res?.data?.data?.length || res?.data?.length } }); }); }); }` From 2f5b7bda2ee393933c4e6f45462d1a8052d1bdd9 Mon Sep 17 00:00:00 2001 From: Hexqi Date: Fri, 19 Sep 2025 14:03:04 +0800 Subject: [PATCH 056/101] fix: format toolcall result (#1637) * fix: format toolcall result --- packages/plugins/robot/src/mcp/utils.ts | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/packages/plugins/robot/src/mcp/utils.ts b/packages/plugins/robot/src/mcp/utils.ts index 02ba2dfde7..aa9fd4887c 100644 --- a/packages/plugins/robot/src/mcp/utils.ts +++ b/packages/plugins/robot/src/mcp/utils.ts @@ -52,6 +52,25 @@ export const serializeError = (err: unknown): string => { } } +const formatToolResult = ( + toolResult: string | { type: 'text'; text: string } | Array<{ type: 'text'; text: string }> +) => { + let result: any = toolResult + if (Array.isArray(result) && result.length === 1) { + result = result[0] + } + + if (typeof result === 'object' && result.type === 'text' && result.text) { + result = result.text + } + + if (typeof result === 'string') { + return result + } + + return JSON.stringify(result) +} + const handleToolCall = async ( res: LLMResponse, tools: RequestTool[], @@ -99,8 +118,7 @@ const handleToolCall = async ( toolCallResult = serializeError(error) } toolMessages.push({ - type: 'text', - content: toolCallResult, + content: formatToolResult(toolCallResult), role: 'tool', tool_call_id: tool.id }) From 898ab86c81f49924a6e9850cd17dbca6b90d4b04 Mon Sep 17 00:00:00 2001 From: betterdancing Date: Fri, 19 Sep 2025 17:12:18 +0800 Subject: [PATCH 057/101] fix(resources): fix resource group validator function (#1638) --- .../plugins/resource/src/ResourceSetting.vue | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/plugins/resource/src/ResourceSetting.vue b/packages/plugins/resource/src/ResourceSetting.vue index 04fbc889a3..a9f73da52e 100644 --- a/packages/plugins/resource/src/ResourceSetting.vue +++ b/packages/plugins/resource/src/ResourceSetting.vue @@ -89,15 +89,13 @@ export default { { min: 1, max: 32, message: '长度在1-32之间', trigger: 'blur' }, { type: 'string', - validator: (value) => { - return new Promise((resolve, reject) => { - const regex = /^[a-zA-Z0-9_\-\u4e00-\u9fa5]+$/i - if (!regex.test(value)) { - reject(new Error('分组名称只能包含中文、英文、数字、下划线、中划线等字符')) - } else { - resolve() - } - }) + validator: (rule, value, callback) => { + const regex = /^[\w\-\u4e00-\u9fa5]+$/ + if (!regex.test(value)) { + callback(new Error('分组名称只能包含中文、英文、数字、下划线、中划线等字符')) + } else { + callback() + } } } ] From 1109de0b7777dfc04bc919c7c30ae27f2e868ec9 Mon Sep 17 00:00:00 2001 From: lichunn <46984087+lichunn@users.noreply.github.com> Date: Tue, 23 Sep 2025 11:24:09 +0800 Subject: [PATCH 058/101] =?UTF-8?q?feat=EF=BC=9AAdd=20and=20complete=20sma?= =?UTF-8?q?ll=20models=20and=20robot=20meta-services=20(#1639)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/advanced-features/new-ai-plugin-usage.md | 4 +- .../ai-plugin-configuration.md | 2 +- packages/plugins/robot/index.ts | 4 +- packages/plugins/robot/src/Main.vue | 98 +++++++++-------- .../plugins/robot/src/RobotSettingPopover.vue | 92 ++++++++-------- .../plugins/robot/src/RobotTypeSelect.vue | 15 ++- packages/plugins/robot/src/js/index.ts | 11 ++ .../src/js/{robotSetting.ts => useRobot.ts} | 101 +++++++++++------- packages/register/src/hooks.ts | 10 +- packages/register/src/types.ts | 2 + 10 files changed, 200 insertions(+), 139 deletions(-) create mode 100644 packages/plugins/robot/src/js/index.ts rename packages/plugins/robot/src/js/{robotSetting.ts => useRobot.ts} (58%) diff --git a/docs/advanced-features/new-ai-plugin-usage.md b/docs/advanced-features/new-ai-plugin-usage.md index 94d57a4875..e4dafb2c2f 100644 --- a/docs/advanced-features/new-ai-plugin-usage.md +++ b/docs/advanced-features/new-ai-plugin-usage.md @@ -65,8 +65,8 @@ MCP工具管理面板允许用户: label: 'DeepSeek', value: 'https://api.deepseek.com/v1', model: [ - { label: 'deepseek-chat', value: 'deepseek-chat', maxTokens: 64000 }, - { label: 'deepseek-reasoner', value: 'deepseek-reasoner', maxTokens: 64000 } + { label: 'deepseek-chat', value: 'deepseek-chat'}, + { label: 'deepseek-reasoner', value: 'deepseek-reasoner'} ] } ] diff --git a/docs/extension-capabilities-tutorial/ai-plugin-configuration.md b/docs/extension-capabilities-tutorial/ai-plugin-configuration.md index 9c4c508ba8..90b91e934d 100644 --- a/docs/extension-capabilities-tutorial/ai-plugin-configuration.md +++ b/docs/extension-capabilities-tutorial/ai-plugin-configuration.md @@ -16,7 +16,7 @@ ### 前端代码改动 -在`tiny-engine/packages/plugins/robot/src/js/robotSetting.js`文件改动如下 +在`tiny-engine/packages/plugins/robot/src/js/useRobot.ts`文件改动如下 ![](./imgs/ai-image23.png) diff --git a/packages/plugins/robot/index.ts b/packages/plugins/robot/index.ts index 25336f8c83..ef4fba0da0 100644 --- a/packages/plugins/robot/index.ts +++ b/packages/plugins/robot/index.ts @@ -14,8 +14,10 @@ import entry from './src/Main.vue' import metaData from './meta' import './src/styles/vars.less' import '@opentiny/tiny-robot/dist/style.css' +import { RobotService } from './src/js/index' export default { ...metaData, - entry + entry, + metas: [RobotService] } diff --git a/packages/plugins/robot/src/Main.vue b/packages/plugins/robot/src/Main.vue index 16d9a720a2..91b92944ac 100644 --- a/packages/plugins/robot/src/Main.vue +++ b/packages/plugins/robot/src/Main.vue @@ -25,7 +25,6 @@ > @@ -72,9 +71,7 @@ placeholder="请输入问题或“/”唤起指令,支持粘贴文档" :clearable="true" :showWordLimit="true" - :allowFiles=" - singleAttachmentItems.length < 1 && VISUAL_MODEL.includes(selectedModel.model) && aiType === BUILD_TYPE - " + :allowFiles="singleAttachmentItems.length < 1 && isVisualModel() && aiType === AI_MODES['Builder']" uploadTooltip="支持上传1张图片" @submit="sendContent(inputContent, false)" @files-selected="handleSingleFilesSelected" @@ -94,7 +91,7 @@ @@ -122,7 +119,14 @@ import { type Component } from 'vue' import { Notify, Loading, TinyPopover, TinyDialogBox } from '@opentiny/vue' -import { useHistory, useCanvas, useModal, getMetaApi, META_SERVICE } from '@opentiny/tiny-engine-meta-register' +import { + useRobot, + useHistory, + useCanvas, + useModal, + getMetaApi, + META_SERVICE +} from '@opentiny/tiny-engine-meta-register' import { ToolbarBase } from '@opentiny/tiny-engine-common' import { TrContainer, @@ -138,17 +142,6 @@ import { IconNewSession } from '@opentiny/tiny-robot-svgs' import SchemaRenderer from '@opentiny/tiny-schema-renderer' import { utils } from '@opentiny/tiny-engine-utils' import RobotSettingPopover from './RobotSettingPopover.vue' -import { - getBlockContent, - initBlockList, - getAIModelOptions, - defaultSelectedModel, - isValidFastJsonPatch, - VISUAL_MODEL, - TALK_TYPE, - MCP_TYPE, - BUILD_TYPE -} from './js/robotSetting' import { PROMPTS } from './js/prompts' import * as jsonpatch from 'fast-json-patch' import { chatStream, checkComponentNameExists } from './js/utils' @@ -190,6 +183,15 @@ export default { }, emits: ['close-chat'], setup() { + const { + getBlockContent, + initBlockList, + getAIModelOptions, + isValidFastJsonPatch, + VISUAL_MODEL, + AI_MODES, + robotSettingState + } = useRobot() const { pageState, importSchema, setSaved } = useCanvas() const AIModelOptions = getAIModelOptions() const robotVisible = ref(false) @@ -201,7 +203,6 @@ export default { const connectedFailed = ref(false) const inputContent = ref('') const inProcesing = ref(false) - const selectedModel = ref(defaultSelectedModel) const { confirm } = useModal() const showPopover = ref(false) const searchContent = ref('') @@ -210,7 +211,7 @@ export default { const singleAttachmentItems = ref([]) const imageUrl = ref('') const MESSAGE_TIP = '已生成新的页面效果。' - const aiType = ref(TALK_TYPE) + const aiType = ref(AI_MODES['Chat']) const chatContainerRef = ref(null) const showTeleport = ref(false) const { deepClone, string2Obj, reactiveObj2String: obj2String } = utils @@ -226,7 +227,7 @@ export default { ? JSON.stringify(sessionProcess) : JSON.stringify({ foundationModel: { - ...selectedModel.value + ...robotSettingState.selectedModel }, messages: [], displayMessages: [], // 专门用来进行展示的消息,非原始消息,仅作为展示但是不作为请求的发送 @@ -260,7 +261,7 @@ export default { const sendProcess = { ...sessionProcess } const firstMessage = sendProcess.messages[0] let firstContent = firstMessage.content - if (aiType.value === BUILD_TYPE) { + if (aiType.value === AI_MODES['Builder']) { firstContent = firstMessage.content.map((item) => { if (item.type === 'text') { item.text = `[指令] ${PROMPTS}\n[知识] ${searchContent.value}\n[当前schema] ${JSON.stringify( @@ -270,7 +271,7 @@ export default { return item }) } - if (useMcpServer().isToolsEnabled && aiType.value === TALK_TYPE) { + if (useMcpServer().isToolsEnabled && aiType.value === AI_MODES['Chat']) { firstContent = `${getBlockContent()}\n${codeRules}\n${firstMessage.content[0]?.text || ''}` } @@ -313,7 +314,7 @@ export default { // 处理响应 const handleResponse = ({ id, chatMessage }: { id: string; chatMessage: any }, currentJson) => { try { - if (aiType.value === BUILD_TYPE) { + if (aiType.value === AI_MODES['Builder']) { const regex = /```json([\s\S]*?)```/ const match = chatMessage?.content.match(regex) @@ -337,7 +338,7 @@ export default { inProcesing.value = false connectedFailed.value = false } - if (aiType.value === TALK_TYPE) { + if (aiType.value === AI_MODES['Chat']) { sessionProcess.messages.push(getAiRespMessage(chatMessage?.content)) sessionProcess.displayMessages.push(getAiRespMessage(chatMessage?.content)) messages.value[messages.value.length - 1].content = chatMessage?.content @@ -353,16 +354,16 @@ export default { // 发送流式请求 const sendStreamRequest = async () => { const requestData = getSendSeesionProcess() - if (useMcpServer().isToolsEnabled && aiType.value === TALK_TYPE) { + if (useMcpServer().isToolsEnabled && aiType.value === AI_MODES['Chat']) { try { requestLoading.value = true await scrollContent() await sendMcpRequest(messages.value, { - model: selectedModel.value.model, + model: robotSettingState.selectedModel.model, headers: { - Authorization: `Bearer ${selectedModel.value.apiKey || import.meta.env.VITE_API_TOKEN}` + Authorization: `Bearer ${robotSettingState.selectedModel.apiKey || import.meta.env.VITE_API_TOKEN}` }, - baseUrl: selectedModel.value.baseUrl + baseUrl: robotSettingState.selectedModel.baseUrl }) } catch (error) { const { renderContent } = messages.value.at(-1)! @@ -458,7 +459,7 @@ export default { } }, { - Authorization: `Bearer ${selectedModel.value.apiKey || import.meta.env.VITE_API_TOKEN}` + Authorization: `Bearer ${robotSettingState.selectedModel.apiKey || import.meta.env.VITE_API_TOKEN}` } ) } @@ -499,7 +500,7 @@ export default { text } ] - if (singleAttachmentItems.value.length > 0 && aiType.value === BUILD_TYPE) { + if (singleAttachmentItems.value.length > 0 && aiType.value === AI_MODES['Builder']) { content.push({ type: 'image_url', image_url: { @@ -529,7 +530,7 @@ export default { if (chatWindowOpened.value === false) { await resizeChatWindow() } - if (!sessionProcess?.messages?.length && aiType.value !== TALK_TYPE) { + if (!sessionProcess?.messages?.length && aiType.value !== AI_MODES['Chat']) { sessionProcess?.messages.push({ role: 'system', content: [ @@ -545,7 +546,7 @@ export default { messages.value.push(message) sessionProcess?.messages.push(getSessionMessage(realContent)) sessionProcess?.displayMessages.push(message) - if (aiType.value === BUILD_TYPE && (!searchContent.value || !sessionProcess.messages?.length)) { + if (aiType.value === AI_MODES['Builder'] && (!searchContent.value || !sessionProcess.messages?.length)) { await search(realContent) } @@ -564,10 +565,10 @@ export default { // 根据localstorage初始化AI大模型 const initCurrentModel = (aiSession) => { - selectedModel.value = { + robotSettingState.selectedModel = { ...JSON.parse(aiSession)?.foundationModel } - aiType.value = JSON.parse(aiSession)?.aiType + aiType.value = JSON.parse(aiSession)?.aiType || aiType.value } const initChat = () => { @@ -614,16 +615,20 @@ export default { } const changeModel = (model) => { - if (selectedModel.value.baseUrl !== model.baseUrl || selectedModel.value !== model.model) { + if ( + robotSettingState.selectedModel.baseUrl !== model.baseUrl || + robotSettingState.selectedModel.model !== model.model + ) { confirm({ title: '切换AI大模型', message: '切换AI大模型将导致当前会话被清空,重新开启新会话,是否继续?', exec() { - selectedModel.value = { + robotSettingState.selectedModel = { label: model.label || model.model, activeName: model.activeName, baseUrl: model.baseUrl, model: model.model, + completeModel: model.completeModel, apiKey: model.apiKey } singleAttachmentItems.value = [] @@ -633,11 +638,11 @@ export default { }) } if ( - selectedModel.value.apiKey !== model.apiKey && - selectedModel.value.baseUrl === model.baseUrl && - selectedModel.value.model === model.model + robotSettingState.selectedModel.apiKey !== model.apiKey && + robotSettingState.selectedModel.baseUrl === model.baseUrl && + robotSettingState.selectedModel.model === model.model ) { - selectedModel.value.apiKey = model.apiKey + robotSettingState.selectedModel.apiKey = model.apiKey changeApiKey() } } @@ -791,6 +796,12 @@ export default { } }) + const isVisualModel = () => { + const platform = AIModelOptions.find((option) => option.value === robotSettingState.selectedModel.baseUrl) + const modelAbility = platform.model.find((item) => item.value === robotSettingState.selectedModel.model) + return modelAbility?.ability?.includes('visual') || false + } + return { chatContainerRef, robotVisible, @@ -800,7 +811,7 @@ export default { inputContent, connectedFailed, AIModelOptions, - selectedModel, + robotSettingState, showPopover, fullscreen, welcomeIcon, @@ -813,9 +824,7 @@ export default { MarkdownRenderer, requestLoading, aiType, - TALK_TYPE, - MCP_TYPE, - BUILD_TYPE, + AI_MODES, showTeleport, sendContent, endContent, @@ -830,6 +839,7 @@ export default { handleSingleFileRemove, handleSingleFileRetry, typeChange, + isVisualModel, contentRenderers, mcpDrawerPosition } diff --git a/packages/plugins/robot/src/RobotSettingPopover.vue b/packages/plugins/robot/src/RobotSettingPopover.vue index bcb3ec32cd..a7ab36b61d 100644 --- a/packages/plugins/robot/src/RobotSettingPopover.vue +++ b/packages/plugins/robot/src/RobotSettingPopover.vue @@ -3,7 +3,13 @@
设置
- + + + + @@ -50,6 +62,13 @@ + + + - - - - @@ -97,7 +103,7 @@ import { TinyTabItem, TinyAlert } from '@opentiny/vue' -import { EXISTING_MODELS, CUSTOMIZE, getAIModelOptions } from './js/robotSetting' +import { useRobot } from '@opentiny/tiny-engine-meta-register' export default { components: { @@ -111,19 +117,12 @@ export default { TinyTabItem, TinyAlert }, - props: { - typeValue: { - type: Object, - default: () => ({}) - } - }, setup(props, { emit }) { + const { EXISTING_MODELS, CUSTOMIZE, getAIModelOptions, robotSettingState } = useRobot() const robotSettingExistForm = ref(null) const robotSettingCustomizeForm = ref(null) const apiKeyTip = 'API Key 是用于身份验证和权限控制的密钥,允许开发者通过API访问云服务商提供的大模型(如通义千问、deepseek等)。' - const maxTokensTip = - '上下文长度表示模型单次响应中最多生成的token数量(包括输入和输出的总和)。若该项不设置,默认为64K。' const AIModelOptions = getAIModelOptions() const state = reactive({ @@ -133,20 +132,23 @@ export default { label: '', baseUrl: '', model: '', - maxTokens: null, + completeModel: '', apiKey: '' }, customizeFormData: { baseUrl: '', model: '', - maxTokens: null, + completeModel: '', apiKey: '' } }) const customizeFormRules = { baseUrl: [{ required: true, message: '必填', trigger: 'blur' }], - model: [{ required: true, message: '必填', trigger: 'blur' }], + apiKey: [{ required: true, message: '必填', trigger: 'blur' }] + } + + const existFormRules = { apiKey: [{ required: true, message: '必填', trigger: 'blur' }] } @@ -159,14 +161,8 @@ export default { const options = AIModelOptions.find((option) => option.value === state.existFormData.baseUrl) state.modelOptions = options?.model state.existFormData.label = options?.label - state.existFormData.model = state.modelOptions[0]?.value - state.existFormData.maxTokens = state.modelOptions[0]?.maxTokens - } - - const changeModel = () => { - state.existFormData.maxTokens = state.modelOptions.find( - (option) => option.value === state.existFormData.model - )?.maxTokens + state.existFormData.model = state.modelOptions[0]?.value || '' + state.existFormData.completeModel = state.modelOptions[0]?.value || '' } const confirm = () => { @@ -178,9 +174,6 @@ export default { } else { formData = { ...state.customizeFormData } form = robotSettingCustomizeForm - if (!formData.maxTokens) { - formData.maxTokens = 64000 - } } form.value.validate((valid) => { @@ -188,6 +181,14 @@ export default { return } + robotSettingState.selectedModel.completeModel = formData.completeModel + localStorage.setItem( + 'AICompleteModel', + JSON.stringify({ + existModel: state.existFormData.completeModel, + customizeModel: state.customizeFormData.completeModel + }) + ) emit('changeType', { activeName: state.activeName, ...formData @@ -197,11 +198,11 @@ export default { } const initFormData = () => { - const initModel = props.typeValue + const smallModel = JSON.parse(localStorage.getItem('AICompleteModel')) || null + const initModel = robotSettingState.selectedModel const data = { baseUrl: initModel.baseUrl, model: initModel.model, - maxTokens: initModel.maxTokens, apiKey: initModel.apiKey } state.activeName = initModel.activeName @@ -209,13 +210,17 @@ export default { if (state.activeName === EXISTING_MODELS) { state.existFormData = { label: initModel.label, + completeModel: smallModel?.existModel ? smallModel.existModel : initModel.completeModel, ...data } const options = AIModelOptions.find((option) => option.value === state.existFormData.baseUrl) state.modelOptions = options?.model } if (state.activeName === CUSTOMIZE) { - state.customizeFormData = data + state.customizeFormData = { ...data } + state.customizeFormData.completeModel = smallModel?.customizeModel + ? smallModel.customizeModel + : initModel.completeModel } } @@ -229,12 +234,11 @@ export default { robotSettingCustomizeForm, state, customizeFormRules, + existFormRules, confirm, closePanel, changeBaseUrl, - changeModel, - apiKeyTip, - maxTokensTip + apiKeyTip } } } diff --git a/packages/plugins/robot/src/RobotTypeSelect.vue b/packages/plugins/robot/src/RobotTypeSelect.vue index 579e1f58c5..58b711c682 100644 --- a/packages/plugins/robot/src/RobotTypeSelect.vue +++ b/packages/plugins/robot/src/RobotTypeSelect.vue @@ -1,7 +1,7 @@