├── server ├── .gitignore ├── .stackblitzrc ├── pages │ └── index.html ├── README.md ├── static │ └── style.css ├── package.json ├── index.js └── pages.json ├── web ├── public │ ├── index.html │ ├── fixtures │ │ └── basic-fusion-with-single-component │ │ │ ├── view.css │ │ │ ├── view.js │ │ │ └── meta.js │ ├── mock │ │ └── info.json │ ├── favicon.png │ ├── mock-pages.json │ ├── preview.html │ ├── index.ejs │ └── schema.json ├── .prettierrc.js ├── src │ ├── scenarios │ │ ├── basic-fusion-with-single-component │ │ │ ├── README.md │ │ │ ├── index.ts │ │ │ ├── schema.json │ │ │ └── plugin.tsx │ │ ├── next-pro │ │ │ ├── index.ts │ │ │ ├── schema.json │ │ │ ├── assets.json │ │ │ └── plugin.tsx │ │ ├── antd-pro-with-formily │ │ │ ├── index.ts │ │ │ ├── schema.json │ │ │ ├── assets.json │ │ │ └── plugin.tsx │ │ ├── basic-fusion │ │ │ ├── index.ts │ │ │ ├── schema.json │ │ │ └── plugin.tsx │ │ ├── index │ │ │ └── index.ts │ │ ├── node-extended-actions │ │ │ ├── index.ts │ │ │ ├── schema.json │ │ │ └── plugin.tsx │ │ ├── basic-antd │ │ │ ├── index.ts │ │ │ ├── schema.json │ │ │ ├── assets.json │ │ │ ├── PageManage │ │ │ │ └── index.tsx │ │ │ └── plugin.tsx │ │ ├── basic-formily │ │ │ ├── index.ts │ │ │ ├── assets.json │ │ │ ├── plugin.tsx │ │ │ └── schema.json │ │ └── custom-initialization │ │ │ └── index.tsx │ ├── sample-plugins │ │ ├── logo │ │ │ ├── index.scss │ │ │ └── index.tsx │ │ ├── delete-hidden-transducer │ │ │ └── index.ts │ │ ├── scenario-switcher │ │ │ └── index.tsx │ │ └── set-ref-prop │ │ │ └── index.tsx │ ├── setters │ │ ├── custom-setter.tsx │ │ └── behavior-setter.tsx │ ├── universal │ │ ├── scenarios.json │ │ ├── global.scss │ │ ├── assets.json │ │ ├── plugin.tsx │ │ └── utils.ts │ └── preview.tsx ├── .github │ └── CODEOWNERS ├── scripts │ └── watchdog.js ├── README.md ├── LICENSE ├── build.json ├── .gitignore ├── tsconfig.json ├── build.plugin.js └── package.json └── README.md /server/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /web/public/index.html: -------------------------------------------------------------------------------- 1 | 勿删,删了有奇妙的 bug😄~ -------------------------------------------------------------------------------- /server/.stackblitzrc: -------------------------------------------------------------------------------- 1 | { 2 | "startCommand": "npm start" 3 | } -------------------------------------------------------------------------------- /web/public/fixtures/basic-fusion-with-single-component/view.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/public/mock/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": "Hello AliLowCode!!" 3 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # lowcode-multi-page-demo 2 | LowCodeEngine 阿里低代码引擎多页面示例工程 3 | -------------------------------------------------------------------------------- /server/pages/index.html: -------------------------------------------------------------------------------- 1 | 2 |

Hello Express!

-------------------------------------------------------------------------------- /server/README.md: -------------------------------------------------------------------------------- 1 | # node-dmbz1u 2 | 3 | [Edit on StackBlitz ⚡️](https://stackblitz.com/edit/node-dmbz1u) -------------------------------------------------------------------------------- /web/public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lowcode-engine/lowcode-multi-page-demo/HEAD/web/public/favicon.png -------------------------------------------------------------------------------- /server/static/style.css: -------------------------------------------------------------------------------- 1 | h1 { 2 | font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif; 3 | } 4 | -------------------------------------------------------------------------------- /web/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 100, 3 | tabWidth: 2, 4 | semi: true, 5 | singleQuote: true, 6 | trailingComma: 'all', 7 | }; 8 | -------------------------------------------------------------------------------- /web/src/scenarios/basic-fusion-with-single-component/README.md: -------------------------------------------------------------------------------- 1 | 此场景展示的使用将通过 [低代码工具链](https://www.yuque.com/lce/doc/funcv8) 研发的单包组件,集成到已有的 fusion 基础组件中~ 2 | 3 | > 注:assets.json 中使用的 view.js / view.css / meta.js 均通过物料单包中 `npm run lowcode:build` 产生~ -------------------------------------------------------------------------------- /web/src/sample-plugins/logo/index.scss: -------------------------------------------------------------------------------- 1 | .lowcode-plugin-logo { 2 | .logo { 3 | display: block; 4 | width: 139px; 5 | height: 26px; 6 | cursor: pointer; 7 | background-size: contain; 8 | background-position: center; 9 | background-repeat: no-repeat; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /web/.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # ref: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners 2 | 3 | # These owners will be the default owners for everything in 4 | # the repo. Unless a later match takes precedence 5 | * @leoyuan @JackLian @alvarto @mark-ck -------------------------------------------------------------------------------- /server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-starter", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "nodemon index.js" 7 | }, 8 | "dependencies": { 9 | "body-parser": "^1.20.0", 10 | "cors": "^2.8.5", 11 | "express": "^4.17.1" 12 | }, 13 | "devDependencies": { 14 | "nodemon": "^2.0.19" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /web/src/setters/custom-setter.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; // import classNames from 'classnames'; 2 | 3 | class CustomSetter extends Component { 4 | render() { 5 | const { defaultValue, value, onChange } = this.props; 6 | const { editor } = this.props.field; 7 | 8 | return
hello world
; 9 | } 10 | } 11 | 12 | export default CustomSetter; 13 | -------------------------------------------------------------------------------- /web/public/mock-pages.json: -------------------------------------------------------------------------------- 1 | {"success":true,"content":[{"gmtModified":"2021-03-06 00:40:54","formUuid":"FORM-6X866SC1KM4O4BLF3U7879QB0EMT2Z3TGIWLKW","parentNavUuid":"NAV-SYSTEM-PARENT-UUID","hidden":"n","navUuid":"FORM-6X866SC1KM4O4BLF3U7879QB0EMT2Z3TGIWLKW","navType":"PAGE","isIndex":"n","isNew":"n","gmtCreate":"2021-03-06 00:27:26","title":{"en_US":"页面1","zh_CN":"页面1","type":"i18n"},"relateUuid":"FORM-6X866SC1KM4O4BLF3U7879QB0EMT2Z3TGIWLKW","parentId":0,"listOrder":0,"id":556103}]} -------------------------------------------------------------------------------- /web/scripts/watchdog.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | const fs = require('fs'); 3 | const { join } = require('path'); 4 | 5 | const workingDir = process.cwd(); 6 | 7 | const pkg = JSON.parse(fs.readFileSync(join(workingDir, 'package.json'), 'utf-8')); 8 | if (pkg.private) return; 9 | const { files } = pkg; 10 | files.forEach(file => { 11 | const fileDir = join(workingDir, file); 12 | if (!fs.existsSync(fileDir)) { 13 | throw new Error(`${fileDir} does not exist, plz run build`); 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /web/src/sample-plugins/logo/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './index.scss'; 3 | import { PluginProps } from '@alilc/lowcode-types'; 4 | 5 | export interface IProps { 6 | logo?: string; 7 | href?: string; 8 | } 9 | 10 | const Logo: React.FC = (props): React.ReactElement => { 11 | return ( 12 |
13 | 14 |
15 | ); 16 | }; 17 | 18 | export default Logo; 19 | -------------------------------------------------------------------------------- /web/src/sample-plugins/delete-hidden-transducer/index.ts: -------------------------------------------------------------------------------- 1 | import { ILowCodePluginContext, project } from '@alilc/lowcode-engine'; 2 | import { CompositeObject, TransformStage } from '@alilc/lowcode-types'; 3 | 4 | export const deleteHiddenTransducer = (ctx: ILowCodePluginContext) => { 5 | return { 6 | name: 'deleteHiddenTransducer', 7 | async init() { 8 | project.addPropsTransducer((props: CompositeObject): CompositeObject => { 9 | delete props.hidden; 10 | return props; 11 | }, TransformStage.Save); 12 | }, 13 | }; 14 | } 15 | 16 | deleteHiddenTransducer.pluginName = 'deleteHiddenTransducer'; 17 | -------------------------------------------------------------------------------- /web/src/universal/scenarios.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "index", 4 | "title": "综合场景" 5 | }, 6 | { 7 | "name": "basic-fusion", 8 | "title": "基础 fusion 组件" 9 | }, 10 | { 11 | "name": "basic-fusion-with-single-component", 12 | "title": "基础 fusion 组件 + 单自定义组件" 13 | }, 14 | { 15 | "name": "basic-antd", 16 | "title": "基础 antd 组件" 17 | }, 18 | { 19 | "name": "basic-formily", 20 | "title": "formily 表单" 21 | }, 22 | { 23 | "name": "custom-initialization", 24 | "title": "自定义初始化引擎" 25 | }, 26 | { 27 | "name": "node-extended-actions", 28 | "title": "扩展节点操作项" 29 | }, 30 | { 31 | "name": "next-pro", 32 | "title": "基于next实现的高级表单低代码物料" 33 | }, 34 | { 35 | "name": "antd-pro-with-formily", 36 | "title": "antd 高级组件 + formily 表单组件" 37 | } 38 | ] 39 | -------------------------------------------------------------------------------- /web/README.md: -------------------------------------------------------------------------------- 1 | ## Low-Code Engine Demo 2 | 3 | 本 demo 是一个组合内核、setter、插件、物料的示范工程,因为未经长期生产环境打磨,可能还会有一些各个模块间结合的 bug,希望大家理解~ 4 | 5 | 场景列表: 6 | 7 | - [index](https://lowcode-engine.cn/demo/index.html) 8 | - [basic-fusion](https://lowcode-engine.cn/demo/basic-fusion.html)(此 fusion 的元数据描述是很老的版本,只为了示意描述结构,请勿用于生产环境) 9 | - [basic-antd](https://lowcode-engine.cn/demo/basic-antd.html) 10 | - [formily 表单](https://lowcode-engine.cn/demo/basic-formily.html) 11 | - [basic-fusion-with-single-component](https://lowcode-engine.cn/demo/basic-fusion-with-single-component.html) 12 | - [custom-initialization](https://lowcode-engine.cn/demo/custom-initialization.html) 13 | - [node-extended-actions](https://lowcode-engine.cn/demo/node-extended-actions.html) 14 | - [next-pro](https://lowcode-engine.cn/demo/next-pro.html) 15 | - [antd-pro-with-formily](https://lowcode-engine.cn/demo/antd-pro-with-formily.html) 16 | 17 | 更多参考资料: 18 | 19 | - [马上玩一下](https://lowcode-engine.cn/demo/index.html) 20 | - [低代码引擎官网](http://lowcode-engine.cn) 21 | - [引擎主包](https://github.com/alibaba/lowcode-engine) 22 | -------------------------------------------------------------------------------- /web/src/setters/behavior-setter.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import BehaviorSetter from '@alilc/lowcode-setter-behavior'; 3 | 4 | 5 | const defaultExtraBehaviorActions: any[] = []; 6 | class LocalBehaviorSetter extends React.Component { 7 | render() { 8 | // ignore url && responseFormatter props, use default ones 9 | const { url: propsUrl, responseFormatter: propsFormatter, extraBehaviorActions: propsExtraBehaviorActions = [], ...otherProps } = this.props; 10 | const url = 'https://hn.algolia.com/api/v1/search?query'; 11 | const responseFormatter = (response) => response.hits.map((item) => ({ 12 | label: item.title, 13 | value: item.author 14 | })); 15 | const extraBehaviorActions = propsExtraBehaviorActions.concat(defaultExtraBehaviorActions); 16 | return ( 17 | 23 | ); 24 | } 25 | } 26 | 27 | export default LocalBehaviorSetter; -------------------------------------------------------------------------------- /web/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Alibaba 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /web/build.json: -------------------------------------------------------------------------------- 1 | { 2 | "entry": { 3 | "preview": "./src/preview.tsx" 4 | }, 5 | "vendor": false, 6 | "devServer": { 7 | "hot": false 8 | }, 9 | "publicPath": "/", 10 | "externals": { 11 | "react": "var window.React", 12 | "react-dom": "var window.ReactDOM", 13 | "prop-types": "var window.PropTypes", 14 | "@alifd/next": "var window.Next", 15 | "@alilc/lowcode-engine": "var window.AliLowCodeEngine", 16 | "@alilc/lowcode-editor-core": "var window.AliLowCodeEngine.common.editorCabin", 17 | "@alilc/lowcode-editor-skeleton": "var window.AliLowCodeEngine.common.skeletonCabin", 18 | "@alilc/lowcode-designer": "var window.AliLowCodeEngine.common.designerCabin", 19 | "@alilc/lowcode-engine-ext": "var window.AliLowCodeEngineExt", 20 | "@ali/lowcode-engine": "var window.AliLowCodeEngine", 21 | "moment": "var window.moment", 22 | "lodash": "var window._" 23 | }, 24 | "plugins": [ 25 | [ 26 | "build-plugin-react-app" 27 | ], 28 | [ 29 | "build-plugin-moment-locales", 30 | { 31 | "locales": [ 32 | "zh-cn" 33 | ] 34 | } 35 | ], 36 | "./build.plugin.js" 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /web/public/preview.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 阿里低代码引擎 Demo - 预览页 7 | 8 | 9 | 10 | 11 |
12 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /web/src/universal/global.scss: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: PingFangSC-Regular, Roboto, Helvetica Neue, Helvetica, Tahoma, Arial, PingFang SC-Light, Microsoft YaHei; 3 | font-size: 12px; 4 | * { 5 | box-sizing: border-box; 6 | } 7 | } 8 | 9 | body, #lce-container { 10 | position: fixed; 11 | left: 0; 12 | right: 0; 13 | bottom: 0; 14 | top: 0; 15 | box-sizing: border-box; 16 | padding: 0; 17 | margin: 0; 18 | overflow: hidden; 19 | text-rendering: optimizeLegibility; 20 | -webkit-user-select: none; 21 | -webkit-user-drag: none; 22 | -webkit-text-size-adjust: none; 23 | -webkit-touch-callout: none; 24 | -webkit-font-smoothing: antialiased; 25 | #engine { 26 | width: 100%; 27 | height: 100%; 28 | } 29 | } 30 | 31 | html { 32 | min-width: 1024px; 33 | } 34 | 35 | .save-sample { 36 | width: 80px; 37 | height: 30px; 38 | background-color: #5584FF; 39 | border: none; 40 | outline: none; 41 | border-radius: 4px; 42 | color: white; 43 | cursor: pointer; 44 | } 45 | 46 | .load-assets { 47 | width: 100px; 48 | height: 30px; 49 | background-color: #5584FF; 50 | border: none; 51 | outline: none; 52 | border-radius: 4px; 53 | color: white; 54 | cursor: pointer; 55 | } 56 | -------------------------------------------------------------------------------- /web/src/sample-plugins/scenario-switcher/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | ILowCodePluginContext, 4 | } from '@alilc/lowcode-engine'; 5 | import { Select } from '@alifd/next'; 6 | import scenarios from '../../universal/scenarios.json'; 7 | const { Option } = Select; 8 | 9 | const getCurrentScenarioName = () => { 10 | // return 'index' 11 | const list = location.href.split('/'); 12 | return list[list.length - 1].replace('.html', ''); 13 | } 14 | 15 | function Switcher(props: any) { 16 | return () 26 | } 27 | 28 | export const scenarioSwitcher = (ctx: ILowCodePluginContext) => { 29 | return { 30 | name: 'scenarioSwitcher', 31 | async init() { 32 | const { skeleton } = ctx; 33 | 34 | skeleton.add({ 35 | name: 'scenarioSwitcher', 36 | area: 'topArea', 37 | type: 'Widget', 38 | props: { 39 | align: 'right', 40 | width: 80, 41 | }, 42 | content: Switcher, 43 | }); 44 | }, 45 | }; 46 | }; 47 | scenarioSwitcher.pluginName = 'scenarioSwitcher'; -------------------------------------------------------------------------------- /web/src/scenarios/next-pro/index.ts: -------------------------------------------------------------------------------- 1 | import { init, plugins } from '@alilc/lowcode-engine'; 2 | import registerPlugins from './plugin'; 3 | import { scenarioSwitcher } from '../../sample-plugins/scenario-switcher'; 4 | import '../../universal/global.scss'; 5 | 6 | const preference = new Map(); 7 | preference.set('DataSourcePane', { 8 | importPlugins: [], 9 | dataSourceTypes: [ 10 | { 11 | type: 'fetch', 12 | }, 13 | { 14 | type: 'jsonp', 15 | }, 16 | ], 17 | }); 18 | 19 | (async function main() { 20 | await plugins.register(scenarioSwitcher); 21 | await registerPlugins(); 22 | 23 | init( 24 | document.getElementById('lce-container')!, 25 | { 26 | // designMode: 'live', 27 | // locale: 'zh-CN', 28 | enableCondition: true, 29 | enableCanvasLock: true, 30 | // 默认绑定变量 31 | supportVariableGlobally: true, 32 | // simulatorUrl 在当 engine-core.js 同一个父路径下时是不需要配置的!!! 33 | // 这里因为用的是 alifd cdn,在不同 npm 包,engine-core.js 和 react-simulator-renderer.js 是不同路径 34 | simulatorUrl: [ 35 | 'https://alifd.alicdn.com/npm/@alilc/lowcode-react-simulator-renderer@latest/dist/css/react-simulator-renderer.css', 36 | 'https://alifd.alicdn.com/npm/@alilc/lowcode-react-simulator-renderer@latest/dist/js/react-simulator-renderer.js', 37 | ], 38 | }, 39 | preference, 40 | ); 41 | })(); 42 | -------------------------------------------------------------------------------- /web/src/scenarios/antd-pro-with-formily/index.ts: -------------------------------------------------------------------------------- 1 | import { init, plugins } from '@alilc/lowcode-engine'; 2 | import registerPlugins from './plugin'; 3 | import { scenarioSwitcher } from '../../sample-plugins/scenario-switcher'; 4 | import '../../universal/global.scss'; 5 | import 'antd/dist/antd.css'; 6 | 7 | const preference = new Map(); 8 | preference.set('DataSourcePane', { 9 | importPlugins: [], 10 | dataSourceTypes: [ 11 | { 12 | type: 'fetch', 13 | }, 14 | { 15 | type: 'jsonp', 16 | }, 17 | ], 18 | }); 19 | 20 | (async function main() { 21 | await plugins.register(scenarioSwitcher); 22 | await registerPlugins(); 23 | 24 | init( 25 | document.getElementById('lce-container')!, 26 | { 27 | // designMode: 'live', 28 | // locale: 'zh-CN', 29 | enableCondition: true, 30 | enableCanvasLock: true, 31 | // 默认绑定变量 32 | supportVariableGlobally: true, 33 | // simulatorUrl 在当 engine-core.js 同一个父路径下时是不需要配置的!!! 34 | // 这里因为用的是 alifd cdn,在不同 npm 包,engine-core.js 和 react-simulator-renderer.js 是不同路径 35 | simulatorUrl: [ 36 | 'https://alifd.alicdn.com/npm/@alilc/lowcode-react-simulator-renderer@latest/dist/css/react-simulator-renderer.css', 37 | 'https://alifd.alicdn.com/npm/@alilc/lowcode-react-simulator-renderer@latest/dist/js/react-simulator-renderer.js', 38 | ], 39 | }, 40 | preference, 41 | ); 42 | })(); 43 | -------------------------------------------------------------------------------- /web/src/scenarios/basic-fusion/index.ts: -------------------------------------------------------------------------------- 1 | import { init, plugins } from '@alilc/lowcode-engine'; 2 | import { createFetchHandler } from '@alilc/lowcode-datasource-fetch-handler' 3 | import registerPlugins from './plugin'; 4 | import { scenarioSwitcher } from '../../sample-plugins/scenario-switcher'; 5 | import '../../universal/global.scss'; 6 | 7 | const preference = new Map(); 8 | preference.set('DataSourcePane', { 9 | importPlugins: [], 10 | dataSourceTypes: [ 11 | { 12 | type: 'fetch', 13 | }, 14 | { 15 | type: 'jsonp', 16 | } 17 | ] 18 | }); 19 | 20 | (async function main() { 21 | await plugins.register(scenarioSwitcher); 22 | await registerPlugins(); 23 | 24 | init(document.getElementById('lce-container')!, { 25 | // designMode: 'live', 26 | // locale: 'zh-CN', 27 | enableCondition: true, 28 | enableCanvasLock: true, 29 | // 默认绑定变量 30 | supportVariableGlobally: true, 31 | // simulatorUrl 在当 engine-core.js 同一个父路径下时是不需要配置的!!! 32 | // 这里因为用的是 alifd cdn,在不同 npm 包,engine-core.js 和 react-simulator-renderer.js 是不同路径 33 | simulatorUrl: [ 34 | 'https://alifd.alicdn.com/npm/@alilc/lowcode-react-simulator-renderer@latest/dist/css/react-simulator-renderer.css', 35 | 'https://alifd.alicdn.com/npm/@alilc/lowcode-react-simulator-renderer@latest/dist/js/react-simulator-renderer.js' 36 | ], 37 | requestHandlersMap: { 38 | fetch: createFetchHandler() 39 | } 40 | }, preference); 41 | })(); 42 | -------------------------------------------------------------------------------- /web/src/scenarios/index/index.ts: -------------------------------------------------------------------------------- 1 | import { init, plugins } from '@alilc/lowcode-engine'; 2 | import { createFetchHandler } from '@alilc/lowcode-datasource-fetch-handler' 3 | import registerPlugins from '../../universal/plugin'; 4 | import { scenarioSwitcher } from '../../sample-plugins/scenario-switcher'; 5 | import '../../universal/global.scss'; 6 | 7 | const preference = new Map(); 8 | preference.set('DataSourcePane', { 9 | importPlugins: [], 10 | dataSourceTypes: [ 11 | { 12 | type: 'fetch', 13 | }, 14 | { 15 | type: 'jsonp', 16 | } 17 | ] 18 | }); 19 | 20 | (async function main() { 21 | await plugins.register(scenarioSwitcher); 22 | await registerPlugins(); 23 | 24 | init(document.getElementById('lce-container')!, { 25 | // designMode: 'live', 26 | // locale: 'zh-CN', 27 | enableCondition: true, 28 | enableCanvasLock: true, 29 | // 默认绑定变量 30 | supportVariableGlobally: true, 31 | // simulatorUrl 在当 engine-core.js 同一个父路径下时是不需要配置的!!! 32 | // 这里因为用的是 alifd cdn,在不同 npm 包,engine-core.js 和 react-simulator-renderer.js 是不同路径 33 | simulatorUrl: [ 34 | 'https://alifd.alicdn.com/npm/@alilc/lowcode-react-simulator-renderer@latest/dist/css/react-simulator-renderer.css', 35 | 'https://alifd.alicdn.com/npm/@alilc/lowcode-react-simulator-renderer@latest/dist/js/react-simulator-renderer.js' 36 | ], 37 | requestHandlersMap: { 38 | fetch: createFetchHandler() 39 | } 40 | }, preference); 41 | })(); 42 | -------------------------------------------------------------------------------- /web/src/scenarios/node-extended-actions/index.ts: -------------------------------------------------------------------------------- 1 | import { init, plugins } from '@alilc/lowcode-engine'; 2 | import { createFetchHandler } from '@alilc/lowcode-datasource-fetch-handler' 3 | 4 | import registerPlugins from './plugin'; 5 | import { scenarioSwitcher } from '../../sample-plugins/scenario-switcher'; 6 | import '../../universal/global.scss'; 7 | 8 | const preference = new Map(); 9 | preference.set('DataSourcePane', { 10 | importPlugins: [], 11 | dataSourceTypes: [ 12 | { 13 | type: 'fetch', 14 | }, 15 | { 16 | type: 'jsonp', 17 | } 18 | ] 19 | }); 20 | 21 | (async function main() { 22 | await plugins.register(scenarioSwitcher); 23 | await registerPlugins(); 24 | 25 | init(document.getElementById('lce-container')!, { 26 | // designMode: 'live', 27 | // locale: 'zh-CN', 28 | enableCondition: true, 29 | enableCanvasLock: true, 30 | // 默认绑定变量 31 | supportVariableGlobally: true, 32 | // simulatorUrl 在当 engine-core.js 同一个父路径下时是不需要配置的!!! 33 | // 这里因为用的是 alifd cdn,在不同 npm 包,engine-core.js 和 react-simulator-renderer.js 是不同路径 34 | simulatorUrl: [ 35 | 'https://alifd.alicdn.com/npm/@alilc/lowcode-react-simulator-renderer@latest/dist/css/react-simulator-renderer.css', 36 | 'https://alifd.alicdn.com/npm/@alilc/lowcode-react-simulator-renderer@latest/dist/js/react-simulator-renderer.js' 37 | ], 38 | requestHandlersMap: { 39 | fetch: createFetchHandler() 40 | } 41 | }, preference); 42 | })(); 43 | -------------------------------------------------------------------------------- /web/src/scenarios/basic-fusion-with-single-component/index.ts: -------------------------------------------------------------------------------- 1 | import { init, plugins } from '@alilc/lowcode-engine'; 2 | import { createFetchHandler } from '@alilc/lowcode-datasource-fetch-handler'; 3 | import registerPlugins from './plugin'; 4 | import { scenarioSwitcher } from '../../sample-plugins/scenario-switcher'; 5 | import '../../universal/global.scss'; 6 | 7 | const preference = new Map(); 8 | preference.set('DataSourcePane', { 9 | importPlugins: [], 10 | dataSourceTypes: [ 11 | { 12 | type: 'fetch', 13 | }, 14 | { 15 | type: 'jsonp', 16 | } 17 | ] 18 | }); 19 | 20 | (async function main() { 21 | await plugins.register(scenarioSwitcher); 22 | await registerPlugins(); 23 | 24 | init(document.getElementById('lce-container')!, { 25 | // designMode: 'live', 26 | // locale: 'zh-CN', 27 | enableCondition: true, 28 | enableCanvasLock: true, 29 | // 默认绑定变量 30 | supportVariableGlobally: true, 31 | // simulatorUrl 在当 engine-core.js 同一个父路径下时是不需要配置的!!! 32 | // 这里因为用的是 alifd cdn,在不同 npm 包,engine-core.js 和 react-simulator-renderer.js 是不同路径 33 | simulatorUrl: [ 34 | 'https://alifd.alicdn.com/npm/@alilc/lowcode-react-simulator-renderer@latest/dist/css/react-simulator-renderer.css', 35 | 'https://alifd.alicdn.com/npm/@alilc/lowcode-react-simulator-renderer@latest/dist/js/react-simulator-renderer.js' 36 | ], 37 | requestHandlersMap: { 38 | fetch: createFetchHandler() 39 | } 40 | }, preference); 41 | })(); 42 | -------------------------------------------------------------------------------- /web/src/scenarios/basic-antd/index.ts: -------------------------------------------------------------------------------- 1 | import { init, plugins } from '@alilc/lowcode-engine'; 2 | import { createFetchHandler } from '@alilc/lowcode-datasource-fetch-handler'; 3 | import registerPlugins from './plugin'; 4 | import { scenarioSwitcher } from '../../sample-plugins/scenario-switcher'; 5 | import 'antd/dist/antd.css'; 6 | import '../../universal/global.scss'; 7 | 8 | const preference = new Map(); 9 | preference.set('DataSourcePane', { 10 | importPlugins: [], 11 | dataSourceTypes: [ 12 | { 13 | type: 'fetch', 14 | }, 15 | { 16 | type: 'jsonp', 17 | }, 18 | ], 19 | }); 20 | 21 | (async function main() { 22 | await plugins.register(scenarioSwitcher); 23 | await registerPlugins(); 24 | 25 | init( 26 | document.getElementById('lce-container')!, 27 | { 28 | // designMode: 'live', 29 | // locale: 'zh-CN', 30 | enableCondition: true, 31 | enableCanvasLock: true, 32 | // 默认绑定变量 33 | supportVariableGlobally: true, 34 | // simulatorUrl 在当 engine-core.js 同一个父路径下时是不需要配置的!!! 35 | // 这里因为用的是 alifd cdn,在不同 npm 包,engine-core.js 和 react-simulator-renderer.js 是不同路径 36 | simulatorUrl: [ 37 | 'https://alifd.alicdn.com/npm/@alilc/lowcode-react-simulator-renderer@latest/dist/css/react-simulator-renderer.css', 38 | 'https://alifd.alicdn.com/npm/@alilc/lowcode-react-simulator-renderer@latest/dist/js/react-simulator-renderer.js', 39 | ], 40 | requestHandlersMap: { 41 | fetch: createFetchHandler(), 42 | }, 43 | }, 44 | preference, 45 | ); 46 | })(); 47 | -------------------------------------------------------------------------------- /web/src/scenarios/basic-formily/index.ts: -------------------------------------------------------------------------------- 1 | import { init, plugins } from '@alilc/lowcode-engine'; 2 | import { createFetchHandler } from '@alilc/lowcode-datasource-fetch-handler'; 3 | import registerPlugins from './plugin'; 4 | import { scenarioSwitcher } from '../../sample-plugins/scenario-switcher'; 5 | import { PluginFormily } from '@seada/antd-plugins'; 6 | import 'antd/dist/antd.css'; 7 | import '../../universal/global.scss'; 8 | 9 | const preference = new Map(); 10 | preference.set('DataSourcePane', { 11 | importPlugins: [], 12 | dataSourceTypes: [ 13 | { 14 | type: 'fetch', 15 | }, 16 | { 17 | type: 'jsonp', 18 | }, 19 | ], 20 | }); 21 | 22 | (async function main() { 23 | await plugins.register(scenarioSwitcher); 24 | await registerPlugins(); 25 | await plugins.register(PluginFormily); 26 | 27 | init( 28 | document.getElementById('lce-container')!, 29 | { 30 | // designMode: 'live', 31 | // locale: 'zh-CN', 32 | enableCondition: true, 33 | enableCanvasLock: true, 34 | // 默认绑定变量 35 | supportVariableGlobally: true, 36 | // simulatorUrl 在当 engine-core.js 同一个父路径下时是不需要配置的!!! 37 | // 这里因为用的是 alifd cdn,在不同 npm 包,engine-core.js 和 react-simulator-renderer.js 是不同路径 38 | simulatorUrl: [ 39 | 'https://alifd.alicdn.com/npm/@alilc/lowcode-react-simulator-renderer@latest/dist/css/react-simulator-renderer.css', 40 | 'https://alifd.alicdn.com/npm/@alilc/lowcode-react-simulator-renderer@latest/dist/js/react-simulator-renderer.js', 41 | ], 42 | requestHandlersMap: { 43 | fetch: createFetchHandler(), 44 | }, 45 | }, 46 | preference, 47 | ); 48 | })(); 49 | -------------------------------------------------------------------------------- /web/.gitignore: -------------------------------------------------------------------------------- 1 | # project custom 2 | build 3 | dist 4 | 5 | 6 | # IDE 7 | .vscode 8 | .idea 9 | 10 | # Logs 11 | logs 12 | *.log 13 | npm-debug.log* 14 | yarn-debug.log* 15 | yarn-error.log* 16 | lerna-debug.log* 17 | 18 | # Runtime data 19 | pids 20 | *.pid 21 | *.seed 22 | *.pid.lock 23 | 24 | 25 | # Directory for instrumented libs generated by jscoverage/JSCover 26 | lib-cov 27 | 28 | # Coverage directory used by tools like istanbul 29 | coverage 30 | 31 | # nyc test coverage 32 | .nyc_output 33 | 34 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 35 | .grunt 36 | 37 | # Bower dependency directory (https://bower.io/) 38 | bower_components 39 | 40 | # node-waf configuration 41 | .lock-wscript 42 | 43 | # Compiled binary addons (https://nodejs.org/api/addons.html) 44 | build/Release 45 | lib 46 | 47 | # Dependency directories 48 | node_modules/ 49 | jspm_packages/ 50 | 51 | # TypeScript v1 declaration files 52 | typings/ 53 | 54 | # Optional npm cache directory 55 | .npm 56 | 57 | # Optional eslint cache 58 | .eslintcache 59 | 60 | # Optional REPL history 61 | .node_repl_history 62 | 63 | # Output of 'npm pack' 64 | *.tgz 65 | 66 | # Yarn Integrity file 67 | .yarn-integrity 68 | 69 | # dotenv environment variables file 70 | .env 71 | .env.test 72 | 73 | # parcel-bundler cache (https://parceljs.org/) 74 | .cache 75 | 76 | # next.js build output 77 | .next 78 | 79 | # nuxt.js build output 80 | .nuxt 81 | 82 | # vuepress build output 83 | .vuepress/dist 84 | 85 | # Serverless directories 86 | .serverless/ 87 | 88 | # FuseBox cache 89 | .fusebox/ 90 | 91 | # DynamoDB Local files 92 | .dynamodb/ 93 | 94 | # mac config files 95 | .DS_Store 96 | -------------------------------------------------------------------------------- /web/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "declaration": true, 5 | "lib": ["es2015", "dom"], 6 | // Target latest version of ECMAScript. 7 | "target": "esnext", 8 | // Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. 9 | "module": "esnext", 10 | // Search under node_modules for non-relative imports. 11 | "moduleResolution": "node", 12 | // Process & infer types from .js files. 13 | "allowJs": true, 14 | // Report errors in .js files. 15 | "checkJs": false, 16 | // Don't emit; allow Babel to transform files. 17 | // "noEmit": true, 18 | // Enable strictest settings like strictNullChecks & noImplicitAny. 19 | "strict": true, 20 | // Allow default imports from modules with no default export. This does not affect code emit, just typechecking. 21 | "allowSyntheticDefaultImports": true, 22 | // Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. 23 | "esModuleInterop": true, 24 | // Specify JSX code generation: 'preserve', 'react-native', or 'react'. 25 | "jsx": "preserve", 26 | // Import emit helpers (e.g. __extends, __rest, etc..) from tslib 27 | "importHelpers": true, 28 | // Enables experimental support for ES7 decorators. 29 | "experimentalDecorators": true, 30 | // Generates corresponding .map file. 31 | "sourceMap": true, 32 | // Disallow inconsistently-cased references to the same file. 33 | "forceConsistentCasingInFileNames": true, 34 | // Allow json import 35 | "resolveJsonModule": true, 36 | // skip type checking of declaration files 37 | "skipLibCheck": true, 38 | "outDir": "lib" 39 | }, 40 | "include": [ 41 | "./src/" 42 | ], 43 | "exclude": ["**/test", "**/lib", "**/es", "node_modules"] 44 | } 45 | -------------------------------------------------------------------------------- /web/public/fixtures/basic-fusion-with-single-component/view.js: -------------------------------------------------------------------------------- 1 | !function e(t,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?exports.M220318=n():t.M220318=n()}(window,(function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function t(){return e.default}:function t(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=345)}({3:function(e,t){e.exports=window.React},345:function(e,t,n){e.exports=n(429)},346:function(e,t,n){},429:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return l}));var r={};n.r(r),n.d(r,"default",(function(){return l}));var o=n(3),u=function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var o=0,r=Object.getOwnPropertySymbols(e);o { 32 | plugins.init(preference).then(() => { 33 | setHasPluginInited(true); 34 | }).catch(err => console.error(err)); 35 | }, []); 36 | 37 | return hasPluginInited && ; 38 | } 39 | 40 | config.setConfig({ 41 | // designMode: 'live', 42 | // locale: 'zh-CN', 43 | enableCondition: true, 44 | enableCanvasLock: true, 45 | // 默认绑定变量 46 | supportVariableGlobally: true, 47 | // simulatorUrl 在当 engine-core.js 同一个父路径下时是不需要配置的!!! 48 | // 这里因为用的是 alifd cdn,在不同 npm 包,engine-core.js 和 react-simulator-renderer.js 是不同路径 49 | simulatorUrl: [ 50 | 'https://alifd.alicdn.com/npm/@alilc/lowcode-react-simulator-renderer@latest/dist/css/react-simulator-renderer.css', 51 | 'https://alifd.alicdn.com/npm/@alilc/lowcode-react-simulator-renderer@latest/dist/js/react-simulator-renderer.js' 52 | ], 53 | requestHandlersMap: { 54 | fetch: createFetchHandler() 55 | } 56 | }) 57 | 58 | ReactDOM.render(, document.getElementById('lce-container')!); 59 | })(); 60 | -------------------------------------------------------------------------------- /web/src/sample-plugins/set-ref-prop/index.tsx: -------------------------------------------------------------------------------- 1 | import { TransformedComponentMetadata, FieldConfig } from '@alilc/lowcode-types'; 2 | import { v4 as uuidv4 } from 'uuid'; 3 | import { material } from '@alilc/lowcode-engine'; 4 | 5 | function addonCombine(metadata: TransformedComponentMetadata) { 6 | const { componentName, configure = {} } = metadata; 7 | 8 | const isRoot: boolean = componentName === 'Page' || componentName === 'Component'; 9 | 10 | if (isRoot) { 11 | return metadata; 12 | } 13 | 14 | let advancedGroup: FieldConfig | undefined; 15 | 16 | const refItem: FieldConfig = { 17 | title: { 18 | label: 'refId', 19 | tip: '用于获取组件实例,调用物料内部方法', 20 | icon: '', 21 | }, 22 | name: "ref", 23 | setter: { 24 | componentName: 'StringSetter', 25 | }, 26 | defaultValue: () => { 27 | const uuid = uuidv4().replace('-', '').substring(0, 8); 28 | return `${componentName.toLowerCase()}-${uuid}`; 29 | }, 30 | extraProps: { 31 | display: 'block', 32 | supportVariable: false, 33 | }, 34 | } 35 | 36 | if (!configure.combined) { 37 | configure.combined = [] 38 | } 39 | 40 | advancedGroup = configure.combined?.filter(d => d.name === '#advanced')[0]; 41 | 42 | if (!advancedGroup) { 43 | advancedGroup = { 44 | name: '#advanced', 45 | title: { type: 'i18n', 'zh-CN': '高级', 'en-US': 'Advanced' }, 46 | items: [ 47 | refItem, 48 | ], 49 | }; 50 | 51 | configure.combined.push(advancedGroup); 52 | } 53 | 54 | if (!advancedGroup.items) { 55 | advancedGroup.items = [refItem]; 56 | } 57 | 58 | const advanceItems: FieldConfig[] = advancedGroup.items || []; 59 | 60 | if (!advanceItems || !advanceItems.length || !advanceItems?.filter(d => d.name === 'ref').length) { 61 | advanceItems.push(refItem); 62 | } 63 | 64 | return { 65 | ...metadata, 66 | configure, 67 | }; 68 | } 69 | 70 | export const registerRefProp = () => { 71 | return { 72 | init() { 73 | material.registerMetadataTransducer(addonCombine, 110, 'register-ref-prop') 74 | } 75 | }; 76 | }; 77 | 78 | registerRefProp.pluginName = 'register-ref-prop'; 79 | -------------------------------------------------------------------------------- /web/build.plugin.js: -------------------------------------------------------------------------------- 1 | const { join } = require('path'); 2 | const fs = require('fs-extra'); 3 | const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin'); 4 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 5 | 6 | const scenarioNames = fs.readdirSync(join('./src/scenarios')).filter(name => !name.startsWith('.')); 7 | const { version } = JSON.parse(fs.readFileSync('./package.json', 'utf8')); 8 | 9 | module.exports = ({ onGetWebpackConfig }) => { 10 | onGetWebpackConfig((config) => { 11 | config.resolve.plugin('tsconfigpaths').use(TsconfigPathsPlugin, [ 12 | { 13 | configFile: './tsconfig.json', 14 | }, 15 | ]); 16 | 17 | config.merge({ 18 | node: { 19 | fs: 'empty', 20 | }, 21 | }); 22 | 23 | scenarioNames.forEach(name => { 24 | const hasTsx = fs.existsSync(join(`./src/scenarios/${name}/index.tsx`)); 25 | config.merge({ 26 | entry: { 27 | [name]: hasTsx ? require.resolve(`./src/scenarios/${name}/index.tsx`) : require.resolve(`./src/scenarios/${name}/index.ts`), 28 | }, 29 | }); 30 | config 31 | .plugin(name) 32 | .use(HtmlWebpackPlugin, [ 33 | { 34 | inject: false, 35 | minify: false, 36 | templateParameters: { 37 | scenario: name, 38 | version, 39 | }, 40 | template: require.resolve('./public/index.ejs'), 41 | filename: `${name}.html`, 42 | }, 43 | ]); 44 | }) 45 | 46 | config 47 | .plugin('preview') 48 | .use(HtmlWebpackPlugin, [ 49 | { 50 | inject: false, 51 | templateParameters: { 52 | }, 53 | template: require.resolve('./public/preview.html'), 54 | filename: 'preview.html', 55 | }, 56 | ]); 57 | 58 | config.plugins.delete('hot'); 59 | config.devServer.hot(false); 60 | 61 | config.module // fixes https://github.com/graphql/graphql-js/issues/1272 62 | .rule('mjs$') 63 | .test(/\.mjs$/) 64 | .include 65 | .add(/node_modules/) 66 | .end() 67 | .type('javascript/auto'); 68 | }); 69 | }; 70 | -------------------------------------------------------------------------------- /web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@alilc/lowcode-demo", 3 | "version": "1.0.24", 4 | "description": "Low-Code Engine 低代码搭建引擎 Demo 项目", 5 | "repository": "git@github.com:alibaba/lowcode-demo.git", 6 | "license": "MIT", 7 | "main": "index.js", 8 | "scripts": { 9 | "start": "build-scripts start --disable-reload --port 5556", 10 | "build": "build-scripts build", 11 | "prepublishOnly": "npm run build", 12 | "pub": "node ./scripts/watchdog.js && npm pub" 13 | }, 14 | "files": [ 15 | "build" 16 | ], 17 | "config": {}, 18 | "dependencies": { 19 | "@alilc/lowcode-datasource-fetch-handler": "^1.0.1", 20 | "@alilc/lowcode-plugin-code-editor": "^1.0.3", 21 | "@alilc/lowcode-plugin-code-generator": "^1.0.4", 22 | "@alilc/lowcode-plugin-components-pane": "^1.0.2", 23 | "@alilc/lowcode-plugin-datasource-pane": "^1.0.5", 24 | "@alilc/lowcode-plugin-inject": "^1.0.0", 25 | "@alilc/lowcode-plugin-manual": "^1.0.3", 26 | "@alilc/lowcode-plugin-schema": "^1.0.1", 27 | "@alilc/lowcode-plugin-simulator-select": "^1.0.0", 28 | "@alilc/lowcode-plugin-undo-redo": "^1.0.0", 29 | "@alilc/lowcode-plugin-zh-en": "^1.0.0", 30 | "@alilc/lowcode-react-renderer": "^1.0.0", 31 | "@alilc/lowcode-setter-behavior": "^1.0.0", 32 | "@alilc/lowcode-setter-title": "^1.0.2", 33 | "@alilc/lowcode-utils": "^1.0.13", 34 | "@ant-design/icons": "^4.7.0", 35 | "@formily/antd": "^2.1.9", 36 | "@formily/core": "^2.1.9", 37 | "@formily/react": "^2.1.9", 38 | "@seada/antd-plugins": "0.0.1-rc.3", 39 | "antd": "^4.21.4", 40 | "moment": "^2.29.3", 41 | "regenerator-runtime": "^0.13.9", 42 | "uuid": "^8.3.2" 43 | }, 44 | "devDependencies": { 45 | "@alib/build-scripts": "^0.1.18", 46 | "@alilc/lowcode-engine": "^1.0.0", 47 | "@alilc/lowcode-engine-ext": "^1.0.0", 48 | "@alilc/lowcode-types": "^1.0.0", 49 | "@types/events": "^3.0.0", 50 | "@types/react": "^16.8.3", 51 | "@types/react-dom": "^16.8.2", 52 | "@types/streamsaver": "^2.0.0", 53 | "@types/uuid": "^8.3.4", 54 | "build-plugin-fusion": "^0.1.0", 55 | "build-plugin-moment-locales": "^0.1.0", 56 | "build-plugin-react-app": "^1.1.2", 57 | "fs-extra": "^10.0.1", 58 | "tsconfig-paths-webpack-plugin": "^3.2.0" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /web/src/scenarios/next-pro/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "componentName": "Page", 3 | "id": "node_dockcviv8fo1", 4 | "props": { 5 | "ref": "outerView", 6 | "style": { 7 | "height": "100%" 8 | } 9 | }, 10 | "fileName": "/", 11 | "dataSource": { 12 | "list": [ 13 | { 14 | "type": "fetch", 15 | "isInit": true, 16 | "options": { 17 | "params": {}, 18 | "method": "GET", 19 | "isCors": true, 20 | "timeout": 5000, 21 | "headers": {}, 22 | "uri": "mock/info.json" 23 | }, 24 | "id": "info" 25 | } 26 | ] 27 | }, 28 | "state": { 29 | "text": { 30 | "type": "JSExpression", 31 | "value": "\"outer\"" 32 | }, 33 | "isShowDialog": { 34 | "type": "JSExpression", 35 | "value": "false" 36 | } 37 | }, 38 | "css": "body {\n font-size: 12px;\n}\n\n.button {\n width: 100px;\n color: #ff00ff\n}", 39 | "lifeCycles": { 40 | "componentDidMount": { 41 | "type": "JSFunction", 42 | "value": "function componentDidMount() {\n console.log('did mount');\n}" 43 | }, 44 | "componentWillUnmount": { 45 | "type": "JSFunction", 46 | "value": "function componentWillUnmount() {\n console.log('will unmount');\n}" 47 | } 48 | }, 49 | "methods": { 50 | "testFunc": { 51 | "type": "JSFunction", 52 | "value": "function testFunc() {\n console.log('test func');\n}" 53 | }, 54 | "onClick": { 55 | "type": "JSFunction", 56 | "value": "function onClick() {\n this.setState({\n isShowDialog: true\n });\n}" 57 | }, 58 | "closeDialog": { 59 | "type": "JSFunction", 60 | "value": "function closeDialog() {\n this.setState({\n isShowDialog: false\n });\n}" 61 | } 62 | }, 63 | "originCode": "class LowcodeComponent extends Component {\n state = {\n \"text\": \"outer\",\n \"isShowDialog\": false\n }\n componentDidMount() {\n console.log('did mount');\n }\n componentWillUnmount() {\n console.log('will unmount');\n }\n testFunc() {\n console.log('test func');\n }\n onClick() {\n this.setState({\n isShowDialog: true\n })\n }\n closeDialog() {\n this.setState({\n isShowDialog: false\n })\n }\n}", 64 | "hidden": false, 65 | "title": "", 66 | "isLocked": false, 67 | "condition": true, 68 | "conditionGroup": "" 69 | } -------------------------------------------------------------------------------- /web/src/scenarios/antd-pro-with-formily/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "componentName": "Page", 3 | "id": "node_dockcviv8fo1", 4 | "props": { 5 | "ref": "outerView", 6 | "style": { 7 | "height": "100%" 8 | } 9 | }, 10 | "fileName": "/", 11 | "dataSource": { 12 | "list": [ 13 | { 14 | "type": "fetch", 15 | "isInit": true, 16 | "options": { 17 | "params": {}, 18 | "method": "GET", 19 | "isCors": true, 20 | "timeout": 5000, 21 | "headers": {}, 22 | "uri": "mock/info.json" 23 | }, 24 | "id": "info" 25 | } 26 | ] 27 | }, 28 | "state": { 29 | "text": { 30 | "type": "JSExpression", 31 | "value": "\"outer\"" 32 | }, 33 | "isShowDialog": { 34 | "type": "JSExpression", 35 | "value": "false" 36 | } 37 | }, 38 | "css": "body {\n font-size: 12px;\n}\n\n.button {\n width: 100px;\n color: #ff00ff\n}", 39 | "lifeCycles": { 40 | "componentDidMount": { 41 | "type": "JSFunction", 42 | "value": "function componentDidMount() {\n console.log('did mount');\n}" 43 | }, 44 | "componentWillUnmount": { 45 | "type": "JSFunction", 46 | "value": "function componentWillUnmount() {\n console.log('will unmount');\n}" 47 | } 48 | }, 49 | "methods": { 50 | "testFunc": { 51 | "type": "JSFunction", 52 | "value": "function testFunc() {\n console.log('test func');\n}" 53 | }, 54 | "onClick": { 55 | "type": "JSFunction", 56 | "value": "function onClick() {\n this.setState({\n isShowDialog: true\n });\n}" 57 | }, 58 | "closeDialog": { 59 | "type": "JSFunction", 60 | "value": "function closeDialog() {\n this.setState({\n isShowDialog: false\n });\n}" 61 | } 62 | }, 63 | "originCode": "class LowcodeComponent extends Component {\n state = {\n \"text\": \"outer\",\n \"isShowDialog\": false\n }\n componentDidMount() {\n console.log('did mount');\n }\n componentWillUnmount() {\n console.log('will unmount');\n }\n testFunc() {\n console.log('test func');\n }\n onClick() {\n this.setState({\n isShowDialog: true\n })\n }\n closeDialog() {\n this.setState({\n isShowDialog: false\n })\n }\n}", 64 | "hidden": false, 65 | "title": "", 66 | "isLocked": false, 67 | "condition": true, 68 | "conditionGroup": "" 69 | } -------------------------------------------------------------------------------- /web/src/scenarios/basic-antd/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "componentName": "Page", 3 | "id": "node_dockcviv8fo1", 4 | "props": { 5 | "ref": "outerView", 6 | "style": { 7 | "height": "100%" 8 | } 9 | }, 10 | "fileName": "/", 11 | "dataSource": { 12 | "list": [ 13 | { 14 | "type": "fetch", 15 | "isInit": true, 16 | "options": { 17 | "params": {}, 18 | "method": "GET", 19 | "isCors": true, 20 | "timeout": 5000, 21 | "headers": {}, 22 | "uri": "mock/info.json" 23 | }, 24 | "id": "info", 25 | "shouldFetch": { 26 | "type": "JSFunction", 27 | "value": "function() { \n console.log('should fetch.....');\n return true; \n}" 28 | } 29 | } 30 | ] 31 | }, 32 | "state": { 33 | "text": { 34 | "type": "JSExpression", 35 | "value": "\"outer\"" 36 | }, 37 | "isShowDialog": { 38 | "type": "JSExpression", 39 | "value": "false" 40 | } 41 | }, 42 | "css": "body {\n font-size: 12px;\n}\n\n.button {\n width: 100px;\n color: #ff00ff\n}", 43 | "lifeCycles": { 44 | "componentDidMount": { 45 | "type": "JSFunction", 46 | "value": "function componentDidMount() {\n console.log('did mount');\n}" 47 | }, 48 | "componentWillUnmount": { 49 | "type": "JSFunction", 50 | "value": "function componentWillUnmount() {\n console.log('will unmount');\n}" 51 | } 52 | }, 53 | "methods": { 54 | "testFunc": { 55 | "type": "JSFunction", 56 | "value": "function testFunc() {\n console.log('test func');\n}" 57 | }, 58 | "onClick": { 59 | "type": "JSFunction", 60 | "value": "function onClick() {\n this.setState({\n isShowDialog: true\n });\n}" 61 | }, 62 | "closeDialog": { 63 | "type": "JSFunction", 64 | "value": "function closeDialog() {\n this.setState({\n isShowDialog: false\n });\n}" 65 | } 66 | }, 67 | "originCode": "class LowcodeComponent extends Component {\n state = {\n \"text\": \"outer\",\n \"isShowDialog\": false\n }\n componentDidMount() {\n console.log('did mount');\n }\n componentWillUnmount() {\n console.log('will unmount');\n }\n testFunc() {\n console.log('test func');\n }\n onClick() {\n this.setState({\n isShowDialog: true\n })\n }\n closeDialog() {\n this.setState({\n isShowDialog: false\n })\n }\n}", 68 | "hidden": false, 69 | "title": "", 70 | "isLocked": false, 71 | "condition": true, 72 | "conditionGroup": "" 73 | } -------------------------------------------------------------------------------- /web/src/scenarios/basic-fusion/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "componentName": "Page", 3 | "id": "node_dockcviv8fo1", 4 | "props": { 5 | "ref": "outerView", 6 | "style": { 7 | "height": "100%" 8 | } 9 | }, 10 | "fileName": "/", 11 | "dataSource": { 12 | "list": [ 13 | { 14 | "type": "fetch", 15 | "isInit": true, 16 | "options": { 17 | "params": {}, 18 | "method": "GET", 19 | "isCors": true, 20 | "timeout": 5000, 21 | "headers": {}, 22 | "uri": "mock/info.json" 23 | }, 24 | "id": "info", 25 | "shouldFetch": { 26 | "type": "JSFunction", 27 | "value": "function() { \n console.log('should fetch.....');\n return true; \n}" 28 | } 29 | } 30 | ] 31 | }, 32 | "state": { 33 | "text": { 34 | "type": "JSExpression", 35 | "value": "\"outer\"" 36 | }, 37 | "isShowDialog": { 38 | "type": "JSExpression", 39 | "value": "false" 40 | } 41 | }, 42 | "css": "body {\n font-size: 12px;\n}\n\n.button {\n width: 100px;\n color: #ff00ff\n}", 43 | "lifeCycles": { 44 | "componentDidMount": { 45 | "type": "JSFunction", 46 | "value": "function componentDidMount() {\n console.log('did mount');\n}" 47 | }, 48 | "componentWillUnmount": { 49 | "type": "JSFunction", 50 | "value": "function componentWillUnmount() {\n console.log('will unmount');\n}" 51 | } 52 | }, 53 | "methods": { 54 | "testFunc": { 55 | "type": "JSFunction", 56 | "value": "function testFunc() {\n console.log('test func');\n}" 57 | }, 58 | "onClick": { 59 | "type": "JSFunction", 60 | "value": "function onClick() {\n this.setState({\n isShowDialog: true\n });\n}" 61 | }, 62 | "closeDialog": { 63 | "type": "JSFunction", 64 | "value": "function closeDialog() {\n this.setState({\n isShowDialog: false\n });\n}" 65 | } 66 | }, 67 | "originCode": "class LowcodeComponent extends Component {\n state = {\n \"text\": \"outer\",\n \"isShowDialog\": false\n }\n componentDidMount() {\n console.log('did mount');\n }\n componentWillUnmount() {\n console.log('will unmount');\n }\n testFunc() {\n console.log('test func');\n }\n onClick() {\n this.setState({\n isShowDialog: true\n })\n }\n closeDialog() {\n this.setState({\n isShowDialog: false\n })\n }\n}", 68 | "hidden": false, 69 | "title": "", 70 | "isLocked": false, 71 | "condition": true, 72 | "conditionGroup": "" 73 | } -------------------------------------------------------------------------------- /web/src/scenarios/node-extended-actions/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "componentName": "Page", 3 | "id": "node_dockcviv8fo1", 4 | "props": { 5 | "ref": "outerView", 6 | "style": { 7 | "height": "100%" 8 | } 9 | }, 10 | "fileName": "/", 11 | "dataSource": { 12 | "list": [ 13 | { 14 | "type": "fetch", 15 | "isInit": true, 16 | "options": { 17 | "params": {}, 18 | "method": "GET", 19 | "isCors": true, 20 | "timeout": 5000, 21 | "headers": {}, 22 | "uri": "mock/info.json" 23 | }, 24 | "id": "info", 25 | "shouldFetch": { 26 | "type": "JSFunction", 27 | "value": "function() { \n console.log('should fetch.....');\n return true; \n}" 28 | } 29 | } 30 | ] 31 | }, 32 | "state": { 33 | "text": { 34 | "type": "JSExpression", 35 | "value": "\"outer\"" 36 | }, 37 | "isShowDialog": { 38 | "type": "JSExpression", 39 | "value": "false" 40 | } 41 | }, 42 | "css": "body {\n font-size: 12px;\n}\n\n.button {\n width: 100px;\n color: #ff00ff\n}", 43 | "lifeCycles": { 44 | "componentDidMount": { 45 | "type": "JSFunction", 46 | "value": "function componentDidMount() {\n console.log('did mount');\n}" 47 | }, 48 | "componentWillUnmount": { 49 | "type": "JSFunction", 50 | "value": "function componentWillUnmount() {\n console.log('will unmount');\n}" 51 | } 52 | }, 53 | "methods": { 54 | "testFunc": { 55 | "type": "JSFunction", 56 | "value": "function testFunc() {\n console.log('test func');\n}" 57 | }, 58 | "onClick": { 59 | "type": "JSFunction", 60 | "value": "function onClick() {\n this.setState({\n isShowDialog: true\n });\n}" 61 | }, 62 | "closeDialog": { 63 | "type": "JSFunction", 64 | "value": "function closeDialog() {\n this.setState({\n isShowDialog: false\n });\n}" 65 | } 66 | }, 67 | "originCode": "class LowcodeComponent extends Component {\n state = {\n \"text\": \"outer\",\n \"isShowDialog\": false\n }\n componentDidMount() {\n console.log('did mount');\n }\n componentWillUnmount() {\n console.log('will unmount');\n }\n testFunc() {\n console.log('test func');\n }\n onClick() {\n this.setState({\n isShowDialog: true\n })\n }\n closeDialog() {\n this.setState({\n isShowDialog: false\n })\n }\n}", 68 | "hidden": false, 69 | "title": "", 70 | "isLocked": false, 71 | "condition": true, 72 | "conditionGroup": "" 73 | } -------------------------------------------------------------------------------- /web/src/scenarios/basic-formily/assets.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | { 4 | "package": "moment", 5 | "version": "2.24.0", 6 | "urls": ["https://g.alicdn.com/mylib/moment/2.24.0/min/moment.min.js"], 7 | "library": "moment" 8 | }, 9 | { 10 | "package": "lodash", 11 | "library": "_", 12 | "urls": ["https://g.alicdn.com/platform/c/lodash/4.6.1/lodash.min.js"] 13 | }, 14 | { 15 | "package": "iconfont-icons", 16 | "urls": "//at.alicdn.com/t/font_2369445_ukrtsovd92r.js" 17 | }, 18 | { 19 | "package": "@ant-design/icons", 20 | "version": "4.7.0", 21 | "urls": ["//g.alicdn.com/code/npm/@ali/ant-design-icons-cdn/4.5.0/index.umd.min.js"], 22 | "library": "icons" 23 | }, 24 | { 25 | "package": "antd", 26 | "version": "4.19.5", 27 | "urls": [ 28 | "//g.alicdn.com/code/lib/antd/4.19.4/antd.min.js", 29 | "//g.alicdn.com/code/lib/antd/4.19.4/antd.min.css" 30 | ], 31 | "library": "antd" 32 | }, 33 | { 34 | "title": "fusion组件库", 35 | "package": "@alifd/next", 36 | "version": "1.23.0", 37 | "urls": [ 38 | "https://g.alicdn.com/code/lib/alifd__next/1.23.18/next.min.css", 39 | "https://g.alicdn.com/code/lib/alifd__next/1.23.18/next-with-locales.min.js" 40 | ], 41 | "library": "Next" 42 | }, 43 | { 44 | "package": "@seada/formily-materials", 45 | "version": "0.1.1", 46 | "library": "SeadaFormilyMaterials", 47 | "urls": [ 48 | "https://unpkg.com/@seada/formily-materials@latest/build/lowcode/view.js", 49 | "https://unpkg.com/@seada/formily-materials@latest/build/lowcode/view.css" 50 | ], 51 | "editUrls": [ 52 | "https://unpkg.com/@seada/formily-materials@latest/build/lowcode/view.js", 53 | "https://unpkg.com/@seada/formily-materials@latest/build/lowcode/view.css" 54 | ] 55 | } 56 | ], 57 | "components": [ 58 | { 59 | "exportName": "SeadaFormilyMaterialsMeta", 60 | "npm": { 61 | "package": "@seada/formily-materials", 62 | "version": "0.1.1" 63 | }, 64 | "url": "https://unpkg.com/@seada/formily-materials@latest/build/lowcode/meta.js", 65 | "urls": { 66 | "default": "https://unpkg.com/@seada/formily-materials@latest/build/lowcode/meta.js" 67 | } 68 | } 69 | ], 70 | "sort": { 71 | "groupList": ["精选组件", "原子组件"], 72 | "categoryList": ["通用", "导航", "信息输入", "信息展示", "信息反馈"] 73 | }, 74 | "groupList": ["精选组件", "原子组件"], 75 | "ignoreComponents": {} 76 | } 77 | -------------------------------------------------------------------------------- /web/src/scenarios/basic-fusion-with-single-component/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "componentName": "Page", 3 | "id": "node_dockcviv8fo1", 4 | "props": { 5 | "ref": "outerView", 6 | "style": { 7 | "height": "100%" 8 | } 9 | }, 10 | "fileName": "/", 11 | "dataSource": { 12 | "list": [ 13 | { 14 | "type": "fetch", 15 | "isInit": true, 16 | "options": { 17 | "params": {}, 18 | "method": "GET", 19 | "isCors": true, 20 | "timeout": 5000, 21 | "headers": {}, 22 | "uri": "mock/info.json" 23 | }, 24 | "id": "info", 25 | "shouldFetch": { 26 | "type": "JSFunction", 27 | "value": "function() { \n console.log('should fetch.....');\n return true; \n}" 28 | } 29 | } 30 | ] 31 | }, 32 | "state": { 33 | "text": { 34 | "type": "JSExpression", 35 | "value": "\"outer\"" 36 | }, 37 | "isShowDialog": { 38 | "type": "JSExpression", 39 | "value": "false" 40 | } 41 | }, 42 | "css": "body {\n font-size: 12px;\n}\n\n.button {\n width: 100px;\n color: #ff00ff\n}", 43 | "lifeCycles": { 44 | "componentDidMount": { 45 | "type": "JSFunction", 46 | "value": "function componentDidMount() {\n console.log('did mount');\n}" 47 | }, 48 | "componentWillUnmount": { 49 | "type": "JSFunction", 50 | "value": "function componentWillUnmount() {\n console.log('will unmount');\n}" 51 | } 52 | }, 53 | "methods": { 54 | "testFunc": { 55 | "type": "JSFunction", 56 | "value": "function testFunc() {\n console.log('test func');\n}" 57 | }, 58 | "onClick": { 59 | "type": "JSFunction", 60 | "value": "function onClick() {\n this.setState({\n isShowDialog: true\n });\n}" 61 | }, 62 | "closeDialog": { 63 | "type": "JSFunction", 64 | "value": "function closeDialog() {\n this.setState({\n isShowDialog: false\n });\n}" 65 | } 66 | }, 67 | "originCode": "class LowcodeComponent extends Component {\n state = {\n \"text\": \"outer\",\n \"isShowDialog\": false\n }\n componentDidMount() {\n console.log('did mount');\n }\n componentWillUnmount() {\n console.log('will unmount');\n }\n testFunc() {\n console.log('test func');\n }\n onClick() {\n this.setState({\n isShowDialog: true\n })\n }\n closeDialog() {\n this.setState({\n isShowDialog: false\n })\n }\n}", 68 | "hidden": false, 69 | "title": "", 70 | "isLocked": false, 71 | "condition": true, 72 | "conditionGroup": "" 73 | } -------------------------------------------------------------------------------- /web/src/scenarios/basic-antd/assets.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | { 4 | "package": "moment", 5 | "version": "2.24.0", 6 | "urls": ["https://g.alicdn.com/mylib/moment/2.24.0/min/moment.min.js"], 7 | "library": "moment" 8 | }, 9 | { 10 | "package": "lodash", 11 | "library": "_", 12 | "urls": ["https://g.alicdn.com/platform/c/lodash/4.6.1/lodash.min.js"] 13 | }, 14 | { 15 | "package": "iconfont-icons", 16 | "urls": "//at.alicdn.com/t/font_2369445_ukrtsovd92r.js" 17 | }, 18 | { 19 | "package": "@ant-design/icons", 20 | "version": "4.7.0", 21 | "urls": ["//g.alicdn.com/code/npm/@ali/ant-design-icons-cdn/4.5.0/index.umd.min.js"], 22 | "library": "icons" 23 | }, 24 | { 25 | "package": "antd", 26 | "version": "4.19.5", 27 | "urls": [ 28 | "//g.alicdn.com/code/lib/antd/4.19.4/antd.min.js", 29 | "//g.alicdn.com/code/lib/antd/4.19.4/antd.min.css" 30 | ], 31 | "library": "antd" 32 | }, 33 | { 34 | "title": "fusion组件库", 35 | "package": "@alifd/next", 36 | "version": "1.23.0", 37 | "urls": [ 38 | "https://g.alicdn.com/code/lib/alifd__next/1.23.18/next.min.css", 39 | "https://g.alicdn.com/code/lib/alifd__next/1.23.18/next-with-locales.min.js" 40 | ], 41 | "library": "Next" 42 | }, 43 | { 44 | "package": "@alilc/antd-lowcode-materials", 45 | "version": "1.0.6", 46 | "library": "AntdLowcode", 47 | "urls": [ 48 | "https://alifd.alicdn.com/npm/@alilc/antd-lowcode-materials@1.0.6/build/lowcode/view.js", 49 | "https://alifd.alicdn.com/npm/@alilc/antd-lowcode-materials@1.0.6/build/lowcode/view.css" 50 | ], 51 | "editUrls": [ 52 | "https://alifd.alicdn.com/npm/@alilc/antd-lowcode-materials@1.0.6/build/lowcode/view.js", 53 | "https://alifd.alicdn.com/npm/@alilc/antd-lowcode-materials@1.0.6/build/lowcode/view.css" 54 | ] 55 | } 56 | ], 57 | "components": [ 58 | { 59 | "exportName": "AlilcAntdLowcodeMaterialsMeta", 60 | "npm": { 61 | "package": "@alilc/antd-lowcode-materials", 62 | "version": "1.0.9" 63 | }, 64 | "url": "https://alifd.alicdn.com/npm/@alilc/antd-lowcode-materials@1.0.9/build/lowcode/meta.js", 65 | "urls": { 66 | "default": "https://alifd.alicdn.com/npm/@alilc/antd-lowcode-materials@1.0.9/build/lowcode/meta.js" 67 | } 68 | } 69 | ], 70 | "sort": { 71 | "groupList": ["精选组件", "原子组件"], 72 | "categoryList": ["通用", "导航", "信息输入", "信息展示", "信息反馈"] 73 | }, 74 | "groupList": ["精选组件", "原子组件"], 75 | "ignoreComponents": {} 76 | } 77 | -------------------------------------------------------------------------------- /server/index.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const app = express(); 3 | const port = 3010; 4 | const path = require('path'); 5 | const cors = require('cors'); 6 | const bodyParser = require('body-parser'); 7 | 8 | let pages = require('./pages.json') 9 | 10 | app.use(cors()); 11 | app.use(express.static('static')); 12 | app.use(bodyParser.json()) 13 | 14 | app.get('/', (req, res) => { 15 | res.sendFile(path.resolve('pages/index.html')); 16 | }); 17 | 18 | // 获取页面 19 | app.get('/pages', (req, res) => { 20 | res.json({ 21 | code: 0, 22 | data: pages 23 | }) 24 | }); 25 | 26 | // 新建页面 27 | app.post('/page/:fileName', (req, res) => { 28 | const { fileName = '' } = req.params 29 | if (fileName.length === 0) { 30 | res.json({ 31 | code: -1, 32 | msg: '缺少参数:页面文件名' 33 | }) 34 | return 35 | } 36 | const { pageSchema = {} } = req.body 37 | if (Object.keys(pageSchema).length) { 38 | pages.push(pageSchema) 39 | res.json({ 40 | code: 0, 41 | msg: '新页面创建成功' 42 | }) 43 | } else { 44 | res.json({ 45 | code: -1, 46 | msg: '缺少参数:页面描述 Schema' 47 | }) 48 | } 49 | }); 50 | 51 | // 保存页面 52 | app.put('/page/:fileName', (req, res) => { 53 | const { fileName = '' } = req.params 54 | if (fileName.length === 0) { 55 | res.json({ 56 | code: -1, 57 | msg: '页面保存失败,缺少参数:页面文件名' 58 | }) 59 | return 60 | } 61 | const { pageSchema = {} } = req.body 62 | if (Object.keys(pageSchema).length) { 63 | const index = pages.findIndex(item => item.fileName === pageSchema.fileName) 64 | if (index === -1) { 65 | res.json({ 66 | code: -1, 67 | msg: '页面保存失败,未找到要保存/更新的页面' 68 | }) 69 | return 70 | } 71 | pages.splice(index, 1, pageSchema) 72 | res.json({ 73 | code: 0, 74 | msg: `页面保存成功` 75 | }) 76 | } else { 77 | res.json({ 78 | code: -1, 79 | msg: '缺少参数:页面描述 Schema' 80 | }) 81 | } 82 | }); 83 | 84 | // 删除页面 85 | app.delete('/page/:fileName', (req, res) => { 86 | const { fileName = '' } = req.params 87 | if (fileName.length) { 88 | const index = pages.findIndex(page => page.fileName === fileName) 89 | if (index === -1) { 90 | res.json({ 91 | code: -1, 92 | msg: '未找到要删除的页面' 93 | }) 94 | return 95 | } 96 | pages.splice(index, 1) 97 | res.json({ 98 | code: 0, 99 | msg: '删除成功' 100 | }) 101 | } else { 102 | res.json({ 103 | code: -1, 104 | msg: '缺少参数:页面文件名' 105 | }) 106 | } 107 | }); 108 | 109 | app.listen(port, () => { 110 | console.log(`Example app listening at http://localhost:${port}`); 111 | }); 112 | -------------------------------------------------------------------------------- /web/src/preview.tsx: -------------------------------------------------------------------------------- 1 | import ReactDOM from 'react-dom'; 2 | import React, { useState } from 'react'; 3 | import { Loading } from '@alifd/next'; 4 | import { buildComponents, assetBundle, AssetLevel, AssetLoader } from '@alilc/lowcode-utils'; 5 | import ReactRenderer from '@alilc/lowcode-react-renderer'; 6 | import { injectComponents } from '@alilc/lowcode-plugin-inject'; 7 | import { createFetchHandler } from '@alilc/lowcode-datasource-fetch-handler' 8 | 9 | import { getProjectSchemaFromLocalStorage, getPackagesFromLocalStorage } from './universal/utils'; 10 | 11 | const getScenarioName = function() { 12 | if (location.search) { 13 | return new URLSearchParams(location.search.slice(1)).get('scenarioName') || 'index' 14 | } 15 | return 'index'; 16 | } 17 | 18 | const SamplePreview = () => { 19 | const [data, setData] = useState({}); 20 | 21 | async function init() { 22 | const scenarioName = getScenarioName(); 23 | const packages = getPackagesFromLocalStorage(scenarioName); 24 | const projectSchema = getProjectSchemaFromLocalStorage(scenarioName); 25 | const { componentsMap: componentsMapArray, componentsTree } = projectSchema; 26 | const componentsMap: any = {}; 27 | componentsMapArray.forEach((component: any) => { 28 | componentsMap[component.componentName] = component; 29 | }); 30 | const schema = componentsTree[0]; 31 | 32 | const libraryMap = {}; 33 | const libraryAsset = []; 34 | packages.forEach(({ package: _package, library, urls, renderUrls }) => { 35 | libraryMap[_package] = library; 36 | if (renderUrls) { 37 | libraryAsset.push(renderUrls); 38 | } else if (urls) { 39 | libraryAsset.push(urls); 40 | } 41 | }); 42 | 43 | const vendors = [assetBundle(libraryAsset, AssetLevel.Library)]; 44 | 45 | // TODO asset may cause pollution 46 | const assetLoader = new AssetLoader(); 47 | await assetLoader.load(libraryAsset); 48 | const components = await injectComponents(buildComponents(libraryMap, componentsMap)); 49 | 50 | setData({ 51 | schema, 52 | components, 53 | }); 54 | } 55 | 56 | const { schema, components } = data; 57 | 58 | if (!schema || !components) { 59 | init(); 60 | return ; 61 | } 62 | 63 | return ( 64 |
65 | 75 |
76 | ); 77 | }; 78 | 79 | ReactDOM.render(, document.getElementById('ice-container')); 80 | -------------------------------------------------------------------------------- /web/src/scenarios/next-pro/assets.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | { 4 | "package": "moment", 5 | "version": "2.24.0", 6 | "urls": ["https://g.alicdn.com/mylib/moment/2.24.0/min/moment.min.js"], 7 | "library": "moment" 8 | }, 9 | { 10 | "package": "lodash", 11 | "library": "_", 12 | "urls": ["https://g.alicdn.com/platform/c/lodash/4.6.1/lodash.min.js"] 13 | }, 14 | { 15 | "title": "fusion组件库", 16 | "package": "@alifd/next", 17 | "version": "1.24.18", 18 | "urls": [ 19 | "https://g.alicdn.com/code/lib/alifd__next/1.24.18/next.min.css", 20 | "https://g.alicdn.com/code/lib/alifd__next/1.24.18/next-with-locales.min.js" 21 | ], 22 | "library": "Next" 23 | }, 24 | { 25 | "package": "@dogtiti/next-pro-lowcode-materials", 26 | "version": "0.3.0", 27 | "library": "NextProLowcodeMaterials", 28 | "urls": [ 29 | "https://unpkg.com/@dogtiti/next-pro-lowcode-materials@0.3.0/build/lowcode/render/default/view.js", 30 | "https://unpkg.com/@dogtiti/next-pro-lowcode-materials@0.3.0/build/lowcode/render/default/view.css" 31 | ], 32 | "editUrls": [ 33 | "https://unpkg.com/@dogtiti/next-pro-lowcode-materials@0.3.0/build/lowcode/view.js", 34 | "https://unpkg.com/@dogtiti/next-pro-lowcode-materials@0.3.0/build/lowcode/view.css" 35 | ], 36 | "advancedUrls": { 37 | "default": [ 38 | "https://unpkg.com/@dogtiti/next-pro-lowcode-materials@0.3.0/build/lowcode/render/default/view.js", 39 | "https://unpkg.com/@dogtiti/next-pro-lowcode-materials@0.3.0/build/lowcode/render/default/view.css" 40 | ] 41 | }, 42 | "advancedEditUrls": {} 43 | } 44 | ], 45 | "components": [ 46 | { 47 | "exportName": "DogtitiNextProLowcodeMaterialsMeta", 48 | "npm": { 49 | "package": "@dogtiti/next-pro-lowcode-materials", 50 | "version": "0.3.0" 51 | }, 52 | "url": "https://unpkg.com/@dogtiti/next-pro-lowcode-materials@0.3.0/build/lowcode/meta.js", 53 | "urls": { 54 | "default": "https://unpkg.com/@dogtiti/next-pro-lowcode-materials@0.3.0/build/lowcode/meta.js" 55 | }, 56 | "advancedUrls": { 57 | "default": [ 58 | "https://unpkg.com/@dogtiti/next-pro-lowcode-materials@0.3.0/build/lowcode/meta.js" 59 | ] 60 | } 61 | } 62 | ], 63 | "sort": { 64 | "groupList": ["精选组件", "原子组件"], 65 | "categoryList": [ 66 | "基础元素", 67 | "布局容器类", 68 | "表格类", 69 | "表单详情类", 70 | "帮助类", 71 | "对话框类", 72 | "业务类", 73 | "通用", 74 | "引导", 75 | "信息输入", 76 | "信息展示", 77 | "信息反馈" 78 | ] 79 | }, 80 | "groupList": ["精选组件", "原子组件"], 81 | "ignoreComponents": {} 82 | } 83 | -------------------------------------------------------------------------------- /web/public/index.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 阿里低代码引擎 Demo 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 42 | 43 | 44 | 45 |
46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /web/src/scenarios/antd-pro-with-formily/assets.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | { 4 | "package": "moment", 5 | "version": "2.24.0", 6 | "urls": ["https://g.alicdn.com/mylib/moment/2.24.0/min/moment.min.js"], 7 | "library": "moment" 8 | }, 9 | { 10 | "package": "lodash", 11 | "library": "_", 12 | "urls": ["https://g.alicdn.com/platform/c/lodash/4.6.1/lodash.min.js"] 13 | }, 14 | { 15 | "package": "iconfont-icons", 16 | "urls": "//at.alicdn.com/t/font_2369445_ukrtsovd92r.js" 17 | }, 18 | { 19 | "package": "@ant-design/icons", 20 | "version": "4.7.0", 21 | "urls": [ 22 | "//g.alicdn.com/code/npm/@ali/ant-design-icons-cdn/4.5.0/index.umd.min.js" 23 | ], 24 | "library": "icons" 25 | }, 26 | { 27 | "package": "antd", 28 | "version": "4.19.5", 29 | "urls": [ 30 | "//g.alicdn.com/code/lib/antd/4.19.4/antd.min.js", 31 | "//g.alicdn.com/code/lib/antd/4.19.4/antd.min.css" 32 | ], 33 | "library": "antd" 34 | }, 35 | { 36 | "title": "fusion组件库", 37 | "package": "@alifd/next", 38 | "version": "1.24.18", 39 | "urls": [ 40 | "https://g.alicdn.com/code/lib/alifd__next/1.24.18/next.min.css", 41 | "https://g.alicdn.com/code/lib/alifd__next/1.24.18/next-with-locales.min.js" 42 | ], 43 | "library": "Next" 44 | }, 45 | { 46 | "package": "@alilc/antd-lowcode-materials", 47 | "version": "1.0.6", 48 | "library": "AntdLowcode", 49 | "urls": [ 50 | "https://alifd.alicdn.com/npm/@alilc/antd-lowcode-materials@1.0.6/build/lowcode/view.js", 51 | "https://alifd.alicdn.com/npm/@alilc/antd-lowcode-materials@1.0.6/build/lowcode/view.css" 52 | ], 53 | "editUrls": [ 54 | "https://alifd.alicdn.com/npm/@alilc/antd-lowcode-materials@1.0.6/build/lowcode/view.js", 55 | "https://alifd.alicdn.com/npm/@alilc/antd-lowcode-materials@1.0.6/build/lowcode/view.css" 56 | ] 57 | }, 58 | { 59 | "package": "@seada/antd-materials", 60 | "version": "0.1.1", 61 | "library": "SeadaAntdMaterials", 62 | "urls": [ 63 | "https://unpkg.com/@seada/antd-materials@latest/build/lowcode/view.js", 64 | "https://unpkg.com/@seada/antd-materials@latest/build/lowcode/view.css" 65 | ], 66 | "editUrls": [ 67 | "https://unpkg.com/@seada/antd-materials@latest/build/lowcode/view.js", 68 | "https://unpkg.com/@seada/antd-materials@latest/build/lowcode/view.css" 69 | ] 70 | }, 71 | { 72 | "package": "@seada/formily-materials", 73 | "version": "0.1.1", 74 | "library": "SeadaFormilyMaterials", 75 | "urls": [ 76 | "https://unpkg.com/@seada/formily-materials@latest/build/lowcode/view.js", 77 | "https://unpkg.com/@seada/formily-materials@latest/build/lowcode/view.css" 78 | ], 79 | "editUrls": [ 80 | "https://unpkg.com/@seada/formily-materials@latest/build/lowcode/view.js", 81 | "https://unpkg.com/@seada/formily-materials@latest/build/lowcode/view.css" 82 | ] 83 | } 84 | ], 85 | "components": [ 86 | { 87 | "exportName": "AlilcAntdLowcodeMaterialsMeta", 88 | "npm": { 89 | "package": "@alilc/antd-lowcode-materials", 90 | "version": "1.0.6" 91 | }, 92 | "url": "https://alifd.alicdn.com/npm/@alilc/antd-lowcode-materials@latest/build/lowcode/meta.js", 93 | "urls": { 94 | "default": "https://alifd.alicdn.com/npm/@alilc/antd-lowcode-materials@latest/build/lowcode/meta.js" 95 | } 96 | }, 97 | { 98 | "exportName": "SeadaAntdMaterialsMeta", 99 | "npm": { 100 | "package": "@seada/antd-materials", 101 | "version": "0.1.1" 102 | }, 103 | "url": "https://unpkg.com/@seada/antd-materials@latest/build/lowcode/meta.js", 104 | "urls": { 105 | "default": "https://unpkg.com/@seada/antd-materials@latest/build/lowcode/meta.js" 106 | } 107 | }, 108 | { 109 | "exportName": "SeadaFormilyMaterialsMeta", 110 | "npm": { 111 | "package": "@seada/formily-materials", 112 | "version": "0.1.1" 113 | }, 114 | "url": "https://unpkg.com/@seada/formily-materials@latest/build/lowcode/meta.js", 115 | "urls": { 116 | "default": "https://unpkg.com/@seada/formily-materials@latest/build/lowcode/meta.js" 117 | } 118 | } 119 | ], 120 | "sort": { 121 | "groupList": ["精选组件", "原子组件"], 122 | "categoryList": [ 123 | "基础元素", 124 | "布局容器类", 125 | "表格类", 126 | "表单详情类", 127 | "帮助类", 128 | "对话框类", 129 | "业务类", 130 | "通用", 131 | "引导", 132 | "信息输入", 133 | "信息展示", 134 | "信息反馈" 135 | ] 136 | }, 137 | "groupList": ["精选组件", "原子组件"], 138 | "ignoreComponents": {} 139 | } 140 | -------------------------------------------------------------------------------- /web/src/universal/assets.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | { 4 | "package": "moment", 5 | "version": "2.24.0", 6 | "urls": [ 7 | "https://g.alicdn.com/mylib/moment/2.24.0/min/moment.min.js" 8 | ], 9 | "library": "moment" 10 | }, 11 | { 12 | "package": "lodash", 13 | "library": "_", 14 | "urls": [ 15 | "https://g.alicdn.com/platform/c/lodash/4.6.1/lodash.min.js" 16 | ] 17 | }, 18 | { 19 | "title": "fusion组件库", 20 | "package": "@alifd/next", 21 | "version": "1.24.18", 22 | "urls": [ 23 | "https://g.alicdn.com/code/lib/alifd__next/1.24.18/next.min.css", 24 | "https://g.alicdn.com/code/lib/alifd__next/1.24.18/next-with-locales.min.js" 25 | ], 26 | "library": "Next" 27 | }, 28 | { 29 | "title": "NextTable", 30 | "package": "NextTable", 31 | "version": "1.0.1", 32 | "urls": [ 33 | "https://g.alicdn.com/fusion-platform/pro-table/1.0.1/next-table.js", 34 | "https://g.alicdn.com/fusion-platform/pro-table/1.0.1/next-table.css" 35 | ], 36 | "library": "NextTable" 37 | }, 38 | { 39 | "package": "@alilc/lowcode-materials", 40 | "version": "1.0.2", 41 | "library": "AlilcLowcodeMaterials", 42 | "urls": [ 43 | "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.2/dist/AlilcLowcodeMaterials.js", 44 | "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.2/dist/AlilcLowcodeMaterials.css" 45 | ], 46 | "editUrls": [ 47 | "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.2/build/lowcode/view.js", 48 | "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.2/build/lowcode/view.css" 49 | ] 50 | }, 51 | { 52 | "package": "@alifd/pro-layout", 53 | "version": "1.0.1-beta.6", 54 | "library": "AlifdProLayout", 55 | "urls": [ 56 | "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.6/dist/AlifdProLayout.js", 57 | "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.6/dist/AlifdProLayout.css" 58 | ], 59 | "editUrls": [ 60 | "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.6/build/lowcode/view.js", 61 | "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.6/build/lowcode/view.css" 62 | ] 63 | }, 64 | { 65 | "package": "@alifd/fusion-ui", 66 | "version": "1.0.5", 67 | "library": "AlifdFusionUi", 68 | "urls": [ 69 | "https://alifd.alicdn.com/npm/@alifd/fusion-ui@1.0.5/dist/AlifdFusionUi.js", 70 | "https://alifd.alicdn.com/npm/@alifd/fusion-ui@1.0.5/dist/AlifdFusionUi.css" 71 | ], 72 | "editUrls": [ 73 | "https://alifd.alicdn.com/npm/@alifd/fusion-ui@1.0.5/build/lowcode/view.js", 74 | "https://alifd.alicdn.com/npm/@alifd/fusion-ui@1.0.5/build/lowcode/view.css" 75 | ] 76 | } 77 | ], 78 | "components": [ 79 | { 80 | "exportName": "AlilcLowcodeMaterialsMeta", 81 | "npm": { 82 | "package": "@alilc/lowcode-materials" 83 | }, 84 | "url": "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.2/build/lowcode/meta.js", 85 | "urls": { 86 | "default": "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.2/build/lowcode/meta.js", 87 | "design": "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.2/build/lowcode/meta.design.js" 88 | } 89 | }, 90 | { 91 | "exportName": "AlifdProLayoutMeta", 92 | "npm": { 93 | "package": "@alifd/pro-layout", 94 | "version": "1.0.1-beta.6" 95 | }, 96 | "url": "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.6/build/lowcode/meta.js", 97 | "urls": { 98 | "default": "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.6/build/lowcode/meta.js", 99 | "design": "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.6/build/lowcode/meta.design.js" 100 | } 101 | }, 102 | { 103 | "exportName": "AlifdFusionUiMeta", 104 | "npm": { 105 | "package": "@alifd/fusion-ui" 106 | }, 107 | "url": "https://alifd.alicdn.com/npm/@alifd/fusion-ui@1.0.5/build/lowcode/meta.js", 108 | "urls": { 109 | "default": "https://alifd.alicdn.com/npm/@alifd/fusion-ui@1.0.5/build/lowcode/meta.js", 110 | "design": "https://alifd.alicdn.com/npm/@alifd/fusion-ui@1.0.5/build/lowcode/meta.design.js" 111 | } 112 | } 113 | ], 114 | "sort": { 115 | "groupList": [ 116 | "精选组件", 117 | "原子组件" 118 | ], 119 | "categoryList": [ 120 | "基础元素", 121 | "布局容器类", 122 | "表格类", 123 | "表单详情类", 124 | "帮助类", 125 | "对话框类", 126 | "业务类", 127 | "通用", 128 | "引导", 129 | "信息输入", 130 | "信息展示", 131 | "信息反馈" 132 | ] 133 | }, 134 | "groupList": [ 135 | "精选组件", 136 | "原子组件" 137 | ], 138 | "ignoreComponents": {} 139 | } 140 | -------------------------------------------------------------------------------- /web/public/fixtures/basic-fusion-with-single-component/meta.js: -------------------------------------------------------------------------------- 1 | !function e(t,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?exports.M220318Meta=n():t.M220318Meta=n()}(window,(function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function t(){return e.default}:function t(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){e.exports=n(1)},function(e,t,n){"use strict";n.r(t),n.d(t,"components",(function(){return S})),n.d(t,"componentList",(function(){return O}));var r={componentName:"M220318",title:"M220318",docUrl:"",screenshot:"",devMode:"proCode",npm:{package:"m-220318",version:"0.1.0",exportName:"default",main:"src/index.tsx",destructuring:!1,subName:""},configure:{props:[{title:{label:{type:"i18n","en-US":"title","zh-CN":"title"}},name:"title",setter:{componentName:"StringSetter",isRequired:!0,initialValue:""}},{title:{label:{type:"i18n","en-US":"content","zh-CN":"content"}},name:"content",setter:{componentName:"StringSetter",isRequired:!0,initialValue:""}},{title:{label:{type:"i18n","en-US":"ref","zh-CN":"ref"}},name:"ref",setter:{componentName:"MixedSetter",props:{setters:[{componentName:"FunctionSetter"},{componentName:"ObjectSetter",props:{config:{extraSetter:{componentName:"MixedSetter",isRequired:!1,props:{}}}},isRequired:!1,initialValue:{}}]}}},{title:{label:{type:"i18n","en-US":"key","zh-CN":"key"}},name:"key",setter:{componentName:"MixedSetter",props:{setters:[{componentName:"StringSetter",isRequired:!1,initialValue:""},{componentName:"NumberSetter",isRequired:!1,initialValue:0}]}}}],supports:{style:!0},component:{}}},o=[{title:"M220318",screenshot:"",schema:{componentName:"M220318",props:{}}}],i=Object.assign(Object.assign({},r),{snippets:o});function c(e){return l(e)||p(e)||u(e)||a()}function a(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function u(e,t){if(e){if("string"==typeof e)return s(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?s(e,t):void 0}}function p(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}function l(e){if(Array.isArray(e))return s(e)}function s(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n1&&void 0!==arguments[1]?arguments[1]:"m-220318",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"0.1.0",r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{"@alifd/next":"1.25.23","@alifd/meet":"2.6.3",antd:"4.17.3"};if(!e||!n)return e;var o=e.npm;return o?("object"===d(r)&&r[o.package]?e.npm=m(m({},o),{},{version:r[o.package]}):o.package===t&&(e.npm=m(m({},o),{},{version:n})),e):e}["\u57fa\u7840\u5143\u7d20","\u5e03\u5c40\u5bb9\u5668\u7c7b","\u8868\u683c\u7c7b","\u8868\u5355\u8be6\u60c5\u7c7b","\u5e2e\u52a9\u7c7b","\u5bf9\u8bdd\u6846\u7c7b","\u4e1a\u52a1\u7c7b","\u901a\u7528","\u5f15\u5bfc","\u4fe1\u606f\u8f93\u5165","\u4fe1\u606f\u5c55\u793a","\u4fe1\u606f\u53cd\u9988"].reverse().forEach((function(e,t){b[e]=++t}));var v,S=[];[i].forEach((function(e){Array.isArray(e)?S.push.apply(S,c(e.map((function(e){return h(e)})))):e.components?S.push.apply(S,c(e.components.map((function(e){return h(e)})))):S.push(h(e))}));var O=g(S),j=!0}])})); -------------------------------------------------------------------------------- /web/src/scenarios/basic-formily/plugin.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ILowCodePluginContext, plugins, skeleton, project, setters } from '@alilc/lowcode-engine'; 3 | import AliLowCodeEngineExt from '@alilc/lowcode-engine-ext'; 4 | import { Button } from '@alifd/next'; 5 | import UndoRedoPlugin from '@alilc/lowcode-plugin-undo-redo'; 6 | import ComponentsPane from '@alilc/lowcode-plugin-components-pane'; 7 | import ZhEnPlugin from '@alilc/lowcode-plugin-zh-en'; 8 | import CodeGenPlugin from '@alilc/lowcode-plugin-code-generator'; 9 | import DataSourcePanePlugin from '@alilc/lowcode-plugin-datasource-pane'; 10 | import SchemaPlugin from '@alilc/lowcode-plugin-schema'; 11 | import CodeEditor from '@alilc/lowcode-plugin-code-editor'; 12 | import ManualPlugin from '@alilc/lowcode-plugin-manual'; 13 | import Inject, { injectAssets } from '@alilc/lowcode-plugin-inject'; 14 | import SimulatorResizer from '@alilc/lowcode-plugin-simulator-select'; 15 | 16 | // 注册到引擎 17 | import TitleSetter from '@alilc/lowcode-setter-title'; 18 | import BehaviorSetter from '../../setters/behavior-setter'; 19 | import CustomSetter from '../../setters/custom-setter'; 20 | import Logo from '../../sample-plugins/logo'; 21 | 22 | import { 23 | loadIncrementalAssets, 24 | getPageSchema, 25 | saveSchema, 26 | resetSchema, 27 | preview, 28 | getProjectSchemaFromLocalStorage, 29 | } from '../../universal/utils'; 30 | import assets from './assets.json'; 31 | import schema from './schema.json'; 32 | 33 | export default async function registerPlugins() { 34 | await plugins.register(ManualPlugin); 35 | 36 | await plugins.register(Inject); 37 | 38 | // plugin API 见 https://yuque.antfin.com/ali-lowcode/docs/cdukce 39 | SchemaPlugin.pluginName = 'SchemaPlugin'; 40 | await plugins.register(SchemaPlugin); 41 | 42 | SimulatorResizer.pluginName = 'SimulatorResizer'; 43 | plugins.register(SimulatorResizer); 44 | 45 | const editorInit = (ctx: ILowCodePluginContext) => { 46 | return { 47 | name: 'editor-init', 48 | async init() { 49 | // 修改面包屑组件的分隔符属性setter 50 | // const assets = await ( 51 | // await fetch( 52 | // `https://alifd.alicdn.com/npm/@alilc/lowcode-materials/build/lowcode/assets-prod.json` 53 | // ) 54 | // ).json(); 55 | // 设置物料描述 56 | const { material, project } = ctx; 57 | 58 | material.setAssets(await injectAssets(assets)); 59 | 60 | // 加载 schema 61 | project.openDocument( 62 | getProjectSchemaFromLocalStorage('basic-formily').componentsTree?.[0] || schema, 63 | ); 64 | }, 65 | }; 66 | }; 67 | editorInit.pluginName = 'editorInit'; 68 | await plugins.register(editorInit); 69 | 70 | const builtinPluginRegistry = (ctx: ILowCodePluginContext) => { 71 | return { 72 | name: 'builtin-plugin-registry', 73 | async init() { 74 | const { skeleton } = ctx; 75 | // 注册 logo 面板 76 | skeleton.add({ 77 | area: 'topArea', 78 | type: 'Widget', 79 | name: 'logo', 80 | content: Logo, 81 | contentProps: { 82 | logo: 'https://img.alicdn.com/imgextra/i4/O1CN013w2bmQ25WAIha4Hx9_!!6000000007533-55-tps-137-26.svg', 83 | href: 'https://lowcode-engine.cn', 84 | }, 85 | props: { 86 | align: 'left', 87 | }, 88 | }); 89 | 90 | // 注册组件面板 91 | const componentsPane = skeleton.add({ 92 | area: 'leftArea', 93 | type: 'PanelDock', 94 | name: 'componentsPane', 95 | content: ComponentsPane, 96 | contentProps: {}, 97 | props: { 98 | align: 'top', 99 | icon: 'zujianku', 100 | description: '组件库', 101 | }, 102 | }); 103 | componentsPane?.disable?.(); 104 | project.onSimulatorRendererReady(() => { 105 | componentsPane?.enable?.(); 106 | }); 107 | }, 108 | }; 109 | }; 110 | builtinPluginRegistry.pluginName = 'builtinPluginRegistry'; 111 | await plugins.register(builtinPluginRegistry); 112 | 113 | // 设置内置 setter 和事件绑定、插件绑定面板 114 | const setterRegistry = (ctx: ILowCodePluginContext) => { 115 | const { setterMap, pluginMap } = AliLowCodeEngineExt; 116 | return { 117 | name: 'ext-setters-registry', 118 | async init() { 119 | const { setters, skeleton } = ctx; 120 | // 注册setterMap 121 | setters.registerSetter(setterMap); 122 | // 注册插件 123 | // 注册事件绑定面板 124 | skeleton.add({ 125 | area: 'centerArea', 126 | type: 'Widget', 127 | content: pluginMap.EventBindDialog, 128 | name: 'eventBindDialog', 129 | props: {}, 130 | }); 131 | 132 | // 注册变量绑定面板 133 | skeleton.add({ 134 | area: 'centerArea', 135 | type: 'Widget', 136 | content: pluginMap.VariableBindDialog, 137 | name: 'variableBindDialog', 138 | props: {}, 139 | }); 140 | }, 141 | }; 142 | }; 143 | setterRegistry.pluginName = 'setterRegistry'; 144 | await plugins.register(setterRegistry); 145 | 146 | // 注册回退/前进 147 | await plugins.register(UndoRedoPlugin); 148 | 149 | // 注册中英文切换 150 | await plugins.register(ZhEnPlugin); 151 | 152 | const loadAssetsSample = (ctx: ILowCodePluginContext) => { 153 | return { 154 | name: 'loadAssetsSample', 155 | async init() { 156 | const { skeleton } = ctx; 157 | 158 | skeleton.add({ 159 | name: 'loadAssetsSample', 160 | area: 'topArea', 161 | type: 'Widget', 162 | props: { 163 | align: 'right', 164 | width: 80, 165 | }, 166 | content: , 167 | }); 168 | }, 169 | }; 170 | }; 171 | loadAssetsSample.pluginName = 'loadAssetsSample'; 172 | await plugins.register(loadAssetsSample); 173 | 174 | // 注册保存面板 175 | const saveSample = (ctx: ILowCodePluginContext) => { 176 | return { 177 | name: 'saveSample', 178 | async init() { 179 | const { skeleton, hotkey } = ctx; 180 | 181 | skeleton.add({ 182 | name: 'saveSample', 183 | area: 'topArea', 184 | type: 'Widget', 185 | props: { 186 | align: 'right', 187 | }, 188 | content: , 189 | }); 190 | skeleton.add({ 191 | name: 'resetSchema', 192 | area: 'topArea', 193 | type: 'Widget', 194 | props: { 195 | align: 'right', 196 | }, 197 | content: , 198 | }); 199 | hotkey.bind('command+s', (e) => { 200 | e.preventDefault(); 201 | saveSchema('basic-formily'); 202 | }); 203 | }, 204 | }; 205 | }; 206 | saveSample.pluginName = 'saveSample'; 207 | await plugins.register(saveSample); 208 | 209 | DataSourcePanePlugin.pluginName = 'DataSourcePane'; 210 | await plugins.register(DataSourcePanePlugin); 211 | 212 | CodeEditor.pluginName = 'CodeEditor'; 213 | await plugins.register(CodeEditor); 214 | 215 | // 注册出码插件 216 | CodeGenPlugin.pluginName = 'CodeGenPlugin'; 217 | await plugins.register(CodeGenPlugin); 218 | 219 | const previewSample = (ctx: ILowCodePluginContext) => { 220 | return { 221 | name: 'previewSample', 222 | async init() { 223 | const { skeleton } = ctx; 224 | skeleton.add({ 225 | name: 'previewSample', 226 | area: 'topArea', 227 | type: 'Widget', 228 | props: { 229 | align: 'right', 230 | }, 231 | content: ( 232 | 235 | ), 236 | }); 237 | }, 238 | }; 239 | }; 240 | previewSample.pluginName = 'previewSample'; 241 | await plugins.register(previewSample); 242 | 243 | const customSetter = (ctx: ILowCodePluginContext) => { 244 | return { 245 | name: '___registerCustomSetter___', 246 | async init() { 247 | const { setters } = ctx; 248 | 249 | setters.registerSetter('TitleSetter', TitleSetter); 250 | setters.registerSetter('BehaviorSetter', BehaviorSetter); 251 | setters.registerSetter('CustomSetter', CustomSetter); 252 | }, 253 | }; 254 | }; 255 | customSetter.pluginName = 'customSetter'; 256 | await plugins.register(customSetter); 257 | } 258 | -------------------------------------------------------------------------------- /web/src/scenarios/basic-fusion/plugin.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | ILowCodePluginContext, 4 | plugins, 5 | skeleton, 6 | project, 7 | setters, 8 | } from '@alilc/lowcode-engine'; 9 | import AliLowCodeEngineExt from '@alilc/lowcode-engine-ext'; 10 | import { Button } from '@alifd/next'; 11 | import UndoRedoPlugin from '@alilc/lowcode-plugin-undo-redo'; 12 | import ComponentsPane from '@alilc/lowcode-plugin-components-pane'; 13 | import ZhEnPlugin from '@alilc/lowcode-plugin-zh-en'; 14 | import CodeGenPlugin from '@alilc/lowcode-plugin-code-generator'; 15 | import DataSourcePanePlugin from '@alilc/lowcode-plugin-datasource-pane'; 16 | import SchemaPlugin from '@alilc/lowcode-plugin-schema'; 17 | import CodeEditor from "@alilc/lowcode-plugin-code-editor"; 18 | import ManualPlugin from "@alilc/lowcode-plugin-manual"; 19 | import Inject, { injectAssets } from '@alilc/lowcode-plugin-inject'; 20 | import SimulatorResizer from '@alilc/lowcode-plugin-simulator-select'; 21 | 22 | // 注册到引擎 23 | import TitleSetter from '@alilc/lowcode-setter-title'; 24 | import BehaviorSetter from '../../setters/behavior-setter'; 25 | import CustomSetter from '../../setters/custom-setter'; 26 | import Logo from '../../sample-plugins/logo'; 27 | 28 | import { 29 | loadIncrementalAssets, 30 | getPageSchema, 31 | saveSchema, 32 | resetSchema, 33 | preview, 34 | getProjectSchemaFromLocalStorage, 35 | } from '../../universal/utils'; 36 | import assets from './assets.json'; 37 | import schema from './schema.json'; 38 | 39 | export default async function registerPlugins() { 40 | await plugins.register(ManualPlugin); 41 | 42 | await plugins.register(Inject); 43 | 44 | // plugin API 见 https://lowcode-engine.cn/docV2/ibh9fh 45 | SchemaPlugin.pluginName = 'SchemaPlugin'; 46 | await plugins.register(SchemaPlugin); 47 | 48 | SimulatorResizer.pluginName = 'SimulatorResizer'; 49 | plugins.register(SimulatorResizer); 50 | 51 | const editorInit = (ctx: ILowCodePluginContext) => { 52 | return { 53 | name: 'editor-init', 54 | async init() { 55 | // 修改面包屑组件的分隔符属性setter 56 | // const assets = await ( 57 | // await fetch( 58 | // `https://alifd.alicdn.com/npm/@alilc/lowcode-materials/build/lowcode/assets-prod.json` 59 | // ) 60 | // ).json(); 61 | // 设置物料描述 62 | const { material, project } = ctx; 63 | 64 | material.setAssets(await injectAssets(assets)); 65 | 66 | // 加载 schema 67 | project.openDocument(getProjectSchemaFromLocalStorage('basic-fusion').componentsTree?.[0] || schema); 68 | }, 69 | }; 70 | } 71 | editorInit.pluginName = 'editorInit'; 72 | await plugins.register(editorInit); 73 | 74 | const builtinPluginRegistry = (ctx: ILowCodePluginContext) => { 75 | return { 76 | name: 'builtin-plugin-registry', 77 | async init() { 78 | const { skeleton } = ctx; 79 | // 注册 logo 面板 80 | skeleton.add({ 81 | area: 'topArea', 82 | type: 'Widget', 83 | name: 'logo', 84 | content: Logo, 85 | contentProps: { 86 | logo: 'https://img.alicdn.com/imgextra/i4/O1CN013w2bmQ25WAIha4Hx9_!!6000000007533-55-tps-137-26.svg', 87 | href: 'https://lowcode-engine.cn', 88 | }, 89 | props: { 90 | align: 'left', 91 | }, 92 | }); 93 | 94 | // 注册组件面板 95 | const componentsPane = skeleton.add({ 96 | area: 'leftArea', 97 | type: 'PanelDock', 98 | name: 'componentsPane', 99 | content: ComponentsPane, 100 | contentProps: {}, 101 | props: { 102 | align: 'top', 103 | icon: 'zujianku', 104 | description: '组件库', 105 | }, 106 | }); 107 | componentsPane?.disable?.(); 108 | project.onSimulatorRendererReady(() => { 109 | componentsPane?.enable?.(); 110 | }) 111 | }, 112 | }; 113 | } 114 | builtinPluginRegistry.pluginName = 'builtinPluginRegistry'; 115 | await plugins.register(builtinPluginRegistry); 116 | 117 | // 设置内置 setter 和事件绑定、插件绑定面板 118 | const setterRegistry = (ctx: ILowCodePluginContext) => { 119 | const { setterMap, pluginMap } = AliLowCodeEngineExt; 120 | return { 121 | name: 'ext-setters-registry', 122 | async init() { 123 | const { setters, skeleton } = ctx; 124 | // 注册setterMap 125 | setters.registerSetter(setterMap); 126 | // 注册插件 127 | // 注册事件绑定面板 128 | skeleton.add({ 129 | area: 'centerArea', 130 | type: 'Widget', 131 | content: pluginMap.EventBindDialog, 132 | name: 'eventBindDialog', 133 | props: {}, 134 | }); 135 | 136 | // 注册变量绑定面板 137 | skeleton.add({ 138 | area: 'centerArea', 139 | type: 'Widget', 140 | content: pluginMap.VariableBindDialog, 141 | name: 'variableBindDialog', 142 | props: {}, 143 | }); 144 | }, 145 | }; 146 | } 147 | setterRegistry.pluginName = 'setterRegistry'; 148 | await plugins.register(setterRegistry); 149 | 150 | // 注册回退/前进 151 | await plugins.register(UndoRedoPlugin); 152 | 153 | // 注册中英文切换 154 | await plugins.register(ZhEnPlugin); 155 | 156 | const loadAssetsSample = (ctx: ILowCodePluginContext) => { 157 | return { 158 | name: 'loadAssetsSample', 159 | async init() { 160 | const { skeleton } = ctx; 161 | 162 | skeleton.add({ 163 | name: 'loadAssetsSample', 164 | area: 'topArea', 165 | type: 'Widget', 166 | props: { 167 | align: 'right', 168 | width: 80, 169 | }, 170 | content: ( 171 | 174 | ), 175 | }); 176 | }, 177 | }; 178 | }; 179 | loadAssetsSample.pluginName = 'loadAssetsSample'; 180 | await plugins.register(loadAssetsSample); 181 | 182 | // 注册保存面板 183 | const saveSample = (ctx: ILowCodePluginContext) => { 184 | return { 185 | name: 'saveSample', 186 | async init() { 187 | const { skeleton, hotkey } = ctx; 188 | 189 | skeleton.add({ 190 | name: 'saveSample', 191 | area: 'topArea', 192 | type: 'Widget', 193 | props: { 194 | align: 'right', 195 | }, 196 | content: ( 197 | 200 | ), 201 | }); 202 | skeleton.add({ 203 | name: 'resetSchema', 204 | area: 'topArea', 205 | type: 'Widget', 206 | props: { 207 | align: 'right', 208 | }, 209 | content: ( 210 | 213 | ), 214 | }); 215 | hotkey.bind('command+s', (e) => { 216 | e.preventDefault(); 217 | saveSchema('basic-fusion') 218 | }); 219 | }, 220 | }; 221 | } 222 | saveSample.pluginName = 'saveSample'; 223 | await plugins.register(saveSample); 224 | 225 | DataSourcePanePlugin.pluginName = 'DataSourcePane'; 226 | await plugins.register(DataSourcePanePlugin); 227 | 228 | CodeEditor.pluginName = 'CodeEditor'; 229 | await plugins.register(CodeEditor); 230 | 231 | // 注册出码插件 232 | CodeGenPlugin.pluginName = 'CodeGenPlugin'; 233 | await plugins.register(CodeGenPlugin); 234 | 235 | const previewSample = (ctx: ILowCodePluginContext) => { 236 | return { 237 | name: 'previewSample', 238 | async init() { 239 | const { skeleton } = ctx; 240 | skeleton.add({ 241 | name: 'previewSample', 242 | area: 'topArea', 243 | type: 'Widget', 244 | props: { 245 | align: 'right', 246 | }, 247 | content: ( 248 | 251 | ), 252 | }); 253 | }, 254 | }; 255 | }; 256 | previewSample.pluginName = 'previewSample'; 257 | await plugins.register(previewSample); 258 | 259 | const customSetter = (ctx: ILowCodePluginContext) => { 260 | return { 261 | name: '___registerCustomSetter___', 262 | async init() { 263 | const { setters } = ctx; 264 | 265 | setters.registerSetter('TitleSetter', TitleSetter); 266 | setters.registerSetter('BehaviorSetter', BehaviorSetter); 267 | setters.registerSetter('CustomSetter', CustomSetter); 268 | }, 269 | }; 270 | } 271 | customSetter.pluginName = 'customSetter'; 272 | await plugins.register(customSetter); 273 | }; 274 | -------------------------------------------------------------------------------- /web/src/scenarios/next-pro/plugin.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ILowCodePluginContext, plugins, skeleton, project, setters } from '@alilc/lowcode-engine'; 3 | import AliLowCodeEngineExt from '@alilc/lowcode-engine-ext'; 4 | import { Button } from '@alifd/next'; 5 | import UndoRedoPlugin from '@alilc/lowcode-plugin-undo-redo'; 6 | import ComponentsPane from '@alilc/lowcode-plugin-components-pane'; 7 | import ZhEnPlugin from '@alilc/lowcode-plugin-zh-en'; 8 | import CodeGenPlugin from '@alilc/lowcode-plugin-code-generator'; 9 | import DataSourcePanePlugin from '@alilc/lowcode-plugin-datasource-pane'; 10 | import SchemaPlugin from '@alilc/lowcode-plugin-schema'; 11 | import CodeEditor from '@alilc/lowcode-plugin-code-editor'; 12 | import ManualPlugin from '@alilc/lowcode-plugin-manual'; 13 | import Inject, { injectAssets } from '@alilc/lowcode-plugin-inject'; 14 | import SimulatorResizer from '@alilc/lowcode-plugin-simulator-select'; 15 | 16 | // 注册到引擎 17 | import TitleSetter from '@alilc/lowcode-setter-title'; 18 | import BehaviorSetter from '../../setters/behavior-setter'; 19 | import CustomSetter from '../../setters/custom-setter'; 20 | import Logo from '../../sample-plugins/logo'; 21 | import { registerRefProp } from 'src/sample-plugins/set-ref-prop'; 22 | import { deleteHiddenTransducer } from '../../sample-plugins/delete-hidden-transducer'; 23 | 24 | import { 25 | loadIncrementalAssets, 26 | getPageSchema, 27 | saveSchema, 28 | resetSchema, 29 | preview, 30 | getProjectSchemaFromLocalStorage, 31 | } from '../../universal/utils'; 32 | import assets from './assets.json'; 33 | import schema from './schema.json'; 34 | 35 | export default async function registerPlugins() { 36 | await plugins.register(ManualPlugin); 37 | 38 | await plugins.register(Inject); 39 | 40 | await plugins.register(registerRefProp); 41 | 42 | await plugins.register(deleteHiddenTransducer); 43 | 44 | // plugin API 见 https://lowcode-engine.cn/docV2/ibh9fh 45 | SchemaPlugin.pluginName = 'SchemaPlugin'; 46 | await plugins.register(SchemaPlugin); 47 | 48 | SimulatorResizer.pluginName = 'SimulatorResizer'; 49 | plugins.register(SimulatorResizer); 50 | 51 | const editorInit = (ctx: ILowCodePluginContext) => { 52 | return { 53 | name: 'editor-init', 54 | async init() { 55 | // 修改面包屑组件的分隔符属性setter 56 | // const assets = await ( 57 | // await fetch( 58 | // `https://alifd.alicdn.com/npm/@alilc/lowcode-materials/build/lowcode/assets-prod.json` 59 | // ) 60 | // ).json(); 61 | // 设置物料描述 62 | const { material, project } = ctx; 63 | 64 | material.setAssets(await injectAssets(assets)); 65 | 66 | // 加载 schema 67 | project.openDocument( 68 | getProjectSchemaFromLocalStorage('next-pro').componentsTree?.[0] || schema, 69 | ); 70 | }, 71 | }; 72 | }; 73 | editorInit.pluginName = 'editorInit'; 74 | await plugins.register(editorInit); 75 | 76 | const builtinPluginRegistry = (ctx: ILowCodePluginContext) => { 77 | return { 78 | name: 'builtin-plugin-registry', 79 | async init() { 80 | const { skeleton } = ctx; 81 | // 注册 logo 面板 82 | skeleton.add({ 83 | area: 'topArea', 84 | type: 'Widget', 85 | name: 'logo', 86 | content: Logo, 87 | contentProps: { 88 | logo: 'https://img.alicdn.com/imgextra/i4/O1CN013w2bmQ25WAIha4Hx9_!!6000000007533-55-tps-137-26.svg', 89 | href: 'https://lowcode-engine.cn', 90 | }, 91 | props: { 92 | align: 'left', 93 | }, 94 | }); 95 | 96 | // 注册组件面板 97 | const componentsPane = skeleton.add({ 98 | area: 'leftArea', 99 | type: 'PanelDock', 100 | name: 'componentsPane', 101 | content: ComponentsPane, 102 | contentProps: {}, 103 | props: { 104 | align: 'top', 105 | icon: 'zujianku', 106 | description: '组件库', 107 | }, 108 | }); 109 | componentsPane?.disable?.(); 110 | project.onSimulatorRendererReady(() => { 111 | componentsPane?.enable?.(); 112 | }); 113 | }, 114 | }; 115 | }; 116 | builtinPluginRegistry.pluginName = 'builtinPluginRegistry'; 117 | await plugins.register(builtinPluginRegistry); 118 | 119 | // 设置内置 setter 和事件绑定、插件绑定面板 120 | const setterRegistry = (ctx: ILowCodePluginContext) => { 121 | const { setterMap, pluginMap } = AliLowCodeEngineExt; 122 | return { 123 | name: 'ext-setters-registry', 124 | async init() { 125 | const { setters, skeleton } = ctx; 126 | // 注册setterMap 127 | setters.registerSetter(setterMap); 128 | // 注册插件 129 | // 注册事件绑定面板 130 | skeleton.add({ 131 | area: 'centerArea', 132 | type: 'Widget', 133 | content: pluginMap.EventBindDialog, 134 | name: 'eventBindDialog', 135 | props: {}, 136 | }); 137 | 138 | // 注册变量绑定面板 139 | skeleton.add({ 140 | area: 'centerArea', 141 | type: 'Widget', 142 | content: pluginMap.VariableBindDialog, 143 | name: 'variableBindDialog', 144 | props: {}, 145 | }); 146 | }, 147 | }; 148 | }; 149 | setterRegistry.pluginName = 'setterRegistry'; 150 | await plugins.register(setterRegistry); 151 | 152 | // 注册回退/前进 153 | await plugins.register(UndoRedoPlugin); 154 | 155 | // 注册中英文切换 156 | await plugins.register(ZhEnPlugin); 157 | 158 | const loadAssetsSample = (ctx: ILowCodePluginContext) => { 159 | return { 160 | name: 'loadAssetsSample', 161 | async init() { 162 | const { skeleton } = ctx; 163 | 164 | skeleton.add({ 165 | name: 'loadAssetsSample', 166 | area: 'topArea', 167 | type: 'Widget', 168 | props: { 169 | align: 'right', 170 | width: 80, 171 | }, 172 | content: , 173 | }); 174 | }, 175 | }; 176 | }; 177 | loadAssetsSample.pluginName = 'loadAssetsSample'; 178 | await plugins.register(loadAssetsSample); 179 | 180 | // 注册保存面板 181 | const saveSample = (ctx: ILowCodePluginContext) => { 182 | return { 183 | name: 'saveSample', 184 | async init() { 185 | const { skeleton, hotkey } = ctx; 186 | 187 | skeleton.add({ 188 | name: 'saveSample', 189 | area: 'topArea', 190 | type: 'Widget', 191 | props: { 192 | align: 'right', 193 | }, 194 | content: , 195 | }); 196 | skeleton.add({ 197 | name: 'resetSchema', 198 | area: 'topArea', 199 | type: 'Widget', 200 | props: { 201 | align: 'right', 202 | }, 203 | content: , 204 | }); 205 | hotkey.bind('command+s', (e) => { 206 | e.preventDefault(); 207 | saveSchema('next-pro'); 208 | }); 209 | }, 210 | }; 211 | }; 212 | saveSample.pluginName = 'saveSample'; 213 | await plugins.register(saveSample); 214 | 215 | DataSourcePanePlugin.pluginName = 'DataSourcePane'; 216 | await plugins.register(DataSourcePanePlugin); 217 | 218 | CodeEditor.pluginName = 'CodeEditor'; 219 | await plugins.register(CodeEditor); 220 | 221 | // 注册出码插件 222 | CodeGenPlugin.pluginName = 'CodeGenPlugin'; 223 | await plugins.register(CodeGenPlugin); 224 | 225 | const previewSample = (ctx: ILowCodePluginContext) => { 226 | return { 227 | name: 'previewSample', 228 | async init() { 229 | const { skeleton } = ctx; 230 | skeleton.add({ 231 | name: 'previewSample', 232 | area: 'topArea', 233 | type: 'Widget', 234 | props: { 235 | align: 'right', 236 | }, 237 | content: ( 238 | 241 | ), 242 | }); 243 | }, 244 | }; 245 | }; 246 | previewSample.pluginName = 'previewSample'; 247 | await plugins.register(previewSample); 248 | 249 | const customSetter = (ctx: ILowCodePluginContext) => { 250 | return { 251 | name: '___registerCustomSetter___', 252 | async init() { 253 | const { setters } = ctx; 254 | 255 | setters.registerSetter('TitleSetter', TitleSetter); 256 | setters.registerSetter('BehaviorSetter', BehaviorSetter); 257 | setters.registerSetter('CustomSetter', CustomSetter); 258 | }, 259 | }; 260 | }; 261 | customSetter.pluginName = 'customSetter'; 262 | await plugins.register(customSetter); 263 | } 264 | -------------------------------------------------------------------------------- /web/src/universal/plugin.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | ILowCodePluginContext, 4 | plugins, 5 | skeleton, 6 | project, 7 | setters, 8 | } from '@alilc/lowcode-engine'; 9 | import AliLowCodeEngineExt from '@alilc/lowcode-engine-ext'; 10 | import { Button } from '@alifd/next'; 11 | import UndoRedoPlugin from '@alilc/lowcode-plugin-undo-redo'; 12 | import ComponentsPane from '@alilc/lowcode-plugin-components-pane'; 13 | import ZhEnPlugin from '@alilc/lowcode-plugin-zh-en'; 14 | import CodeGenPlugin from '@alilc/lowcode-plugin-code-generator'; 15 | import DataSourcePanePlugin from '@alilc/lowcode-plugin-datasource-pane'; 16 | import SchemaPlugin from '@alilc/lowcode-plugin-schema'; 17 | import CodeEditor from "@alilc/lowcode-plugin-code-editor"; 18 | import ManualPlugin from "@alilc/lowcode-plugin-manual"; 19 | import Inject, { injectAssets } from '@alilc/lowcode-plugin-inject'; 20 | import SimulatorResizer from '@alilc/lowcode-plugin-simulator-select'; 21 | 22 | // 注册到引擎 23 | import TitleSetter from '@alilc/lowcode-setter-title'; 24 | import BehaviorSetter from '../setters/behavior-setter'; 25 | import CustomSetter from '../setters/custom-setter'; 26 | import Logo from '../sample-plugins/logo'; 27 | import { deleteHiddenTransducer } from '../sample-plugins/delete-hidden-transducer'; 28 | 29 | import { 30 | loadIncrementalAssets, 31 | getPageSchema, 32 | saveSchema, 33 | resetSchema, 34 | preview, 35 | } from './utils'; 36 | import assets from './assets.json' 37 | import { registerRefProp } from 'src/sample-plugins/set-ref-prop'; 38 | 39 | export default async function registerPlugins() { 40 | await plugins.register(ManualPlugin); 41 | 42 | await plugins.register(Inject); 43 | 44 | await plugins.register(registerRefProp); 45 | 46 | await plugins.register(deleteHiddenTransducer); 47 | 48 | // plugin API 见 https://lowcode-engine.cn/docV2/ibh9fh 49 | SchemaPlugin.pluginName = 'SchemaPlugin'; 50 | await plugins.register(SchemaPlugin); 51 | 52 | SimulatorResizer.pluginName = 'SimulatorResizer'; 53 | plugins.register(SimulatorResizer); 54 | 55 | const editorInit = (ctx: ILowCodePluginContext) => { 56 | return { 57 | name: 'editor-init', 58 | async init() { 59 | // 修改面包屑组件的分隔符属性setter 60 | // const assets = await ( 61 | // await fetch( 62 | // `https://alifd.alicdn.com/npm/@alilc/lowcode-materials/build/lowcode/assets-prod.json` 63 | // ) 64 | // ).json(); 65 | // 设置物料描述 66 | const { material, project } = ctx; 67 | 68 | await material.setAssets(await injectAssets(assets)); 69 | 70 | const schema = await getPageSchema(); 71 | 72 | // 加载 schema 73 | project.openDocument(schema); 74 | }, 75 | }; 76 | } 77 | editorInit.pluginName = 'editorInit'; 78 | await plugins.register(editorInit); 79 | 80 | const builtinPluginRegistry = (ctx: ILowCodePluginContext) => { 81 | return { 82 | name: 'builtin-plugin-registry', 83 | async init() { 84 | const { skeleton } = ctx; 85 | // 注册 logo 面板 86 | skeleton.add({ 87 | area: 'topArea', 88 | type: 'Widget', 89 | name: 'logo', 90 | content: Logo, 91 | contentProps: { 92 | logo: 'https://img.alicdn.com/imgextra/i4/O1CN013w2bmQ25WAIha4Hx9_!!6000000007533-55-tps-137-26.svg', 93 | href: 'https://lowcode-engine.cn', 94 | }, 95 | props: { 96 | align: 'left', 97 | }, 98 | }); 99 | 100 | // 注册组件面板 101 | const componentsPane = skeleton.add({ 102 | area: 'leftArea', 103 | type: 'PanelDock', 104 | name: 'componentsPane', 105 | content: ComponentsPane, 106 | contentProps: {}, 107 | props: { 108 | align: 'top', 109 | icon: 'zujianku', 110 | description: '组件库', 111 | }, 112 | }); 113 | componentsPane?.disable?.(); 114 | project.onSimulatorRendererReady(() => { 115 | componentsPane?.enable?.(); 116 | }) 117 | }, 118 | }; 119 | } 120 | builtinPluginRegistry.pluginName = 'builtinPluginRegistry'; 121 | await plugins.register(builtinPluginRegistry); 122 | 123 | // 设置内置 setter 和事件绑定、插件绑定面板 124 | const setterRegistry = (ctx: ILowCodePluginContext) => { 125 | const { setterMap, pluginMap } = AliLowCodeEngineExt; 126 | return { 127 | name: 'ext-setters-registry', 128 | async init() { 129 | const { setters, skeleton } = ctx; 130 | // 注册setterMap 131 | setters.registerSetter(setterMap); 132 | // 注册插件 133 | // 注册事件绑定面板 134 | skeleton.add({ 135 | area: 'centerArea', 136 | type: 'Widget', 137 | content: pluginMap.EventBindDialog, 138 | name: 'eventBindDialog', 139 | props: {}, 140 | }); 141 | 142 | // 注册变量绑定面板 143 | skeleton.add({ 144 | area: 'centerArea', 145 | type: 'Widget', 146 | content: pluginMap.VariableBindDialog, 147 | name: 'variableBindDialog', 148 | props: {}, 149 | }); 150 | }, 151 | }; 152 | } 153 | setterRegistry.pluginName = 'setterRegistry'; 154 | await plugins.register(setterRegistry); 155 | 156 | // 注册回退/前进 157 | await plugins.register(UndoRedoPlugin); 158 | 159 | // 注册中英文切换 160 | await plugins.register(ZhEnPlugin); 161 | 162 | const loadAssetsSample = (ctx: ILowCodePluginContext) => { 163 | return { 164 | name: 'loadAssetsSample', 165 | async init() { 166 | const { skeleton } = ctx; 167 | 168 | skeleton.add({ 169 | name: 'loadAssetsSample', 170 | area: 'topArea', 171 | type: 'Widget', 172 | props: { 173 | align: 'right', 174 | width: 80, 175 | }, 176 | content: ( 177 | 180 | ), 181 | }); 182 | }, 183 | }; 184 | }; 185 | loadAssetsSample.pluginName = 'loadAssetsSample'; 186 | await plugins.register(loadAssetsSample); 187 | 188 | // 注册保存面板 189 | const saveSample = (ctx: ILowCodePluginContext) => { 190 | return { 191 | name: 'saveSample', 192 | async init() { 193 | const { skeleton, hotkey } = ctx; 194 | 195 | skeleton.add({ 196 | name: 'saveSample', 197 | area: 'topArea', 198 | type: 'Widget', 199 | props: { 200 | align: 'right', 201 | }, 202 | content: ( 203 | 206 | ), 207 | }); 208 | skeleton.add({ 209 | name: 'resetSchema', 210 | area: 'topArea', 211 | type: 'Widget', 212 | props: { 213 | align: 'right', 214 | }, 215 | content: ( 216 | 219 | ), 220 | }); 221 | hotkey.bind('command+s', (e) => { 222 | e.preventDefault(); 223 | saveSchema(); 224 | }); 225 | }, 226 | }; 227 | } 228 | saveSample.pluginName = 'saveSample'; 229 | await plugins.register(saveSample); 230 | 231 | DataSourcePanePlugin.pluginName = 'DataSourcePane'; 232 | await plugins.register(DataSourcePanePlugin); 233 | 234 | CodeEditor.pluginName = 'CodeEditor'; 235 | await plugins.register(CodeEditor); 236 | 237 | // 注册出码插件 238 | CodeGenPlugin.pluginName = 'CodeGenPlugin'; 239 | await plugins.register(CodeGenPlugin); 240 | 241 | const previewSample = (ctx: ILowCodePluginContext) => { 242 | return { 243 | name: 'previewSample', 244 | async init() { 245 | const { skeleton } = ctx; 246 | skeleton.add({ 247 | name: 'previewSample', 248 | area: 'topArea', 249 | type: 'Widget', 250 | props: { 251 | align: 'right', 252 | }, 253 | content: ( 254 | 257 | ), 258 | }); 259 | }, 260 | }; 261 | }; 262 | previewSample.pluginName = 'previewSample'; 263 | await plugins.register(previewSample); 264 | 265 | const customSetter = (ctx: ILowCodePluginContext) => { 266 | return { 267 | name: '___registerCustomSetter___', 268 | async init() { 269 | const { setters } = ctx; 270 | 271 | setters.registerSetter('TitleSetter', TitleSetter); 272 | setters.registerSetter('BehaviorSetter', BehaviorSetter); 273 | setters.registerSetter('CustomSetter', CustomSetter); 274 | }, 275 | }; 276 | } 277 | customSetter.pluginName = 'customSetter'; 278 | await plugins.register(customSetter); 279 | }; 280 | -------------------------------------------------------------------------------- /web/src/scenarios/basic-fusion-with-single-component/plugin.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | ILowCodePluginContext, 4 | plugins, 5 | skeleton, 6 | project, 7 | setters, 8 | } from '@alilc/lowcode-engine'; 9 | import AliLowCodeEngineExt from '@alilc/lowcode-engine-ext'; 10 | import { Button } from '@alifd/next'; 11 | import UndoRedoPlugin from '@alilc/lowcode-plugin-undo-redo'; 12 | import ComponentsPane from '@alilc/lowcode-plugin-components-pane'; 13 | import ZhEnPlugin from '@alilc/lowcode-plugin-zh-en'; 14 | import CodeGenPlugin from '@alilc/lowcode-plugin-code-generator'; 15 | import DataSourcePanePlugin from '@alilc/lowcode-plugin-datasource-pane'; 16 | import SchemaPlugin from '@alilc/lowcode-plugin-schema'; 17 | import CodeEditor from "@alilc/lowcode-plugin-code-editor"; 18 | import ManualPlugin from "@alilc/lowcode-plugin-manual"; 19 | import Inject, { injectAssets } from '@alilc/lowcode-plugin-inject'; 20 | import SimulatorResizer from '@alilc/lowcode-plugin-simulator-select'; 21 | 22 | // 注册到引擎 23 | import TitleSetter from '@alilc/lowcode-setter-title'; 24 | import BehaviorSetter from '../../setters/behavior-setter'; 25 | import CustomSetter from '../../setters/custom-setter'; 26 | import Logo from '../../sample-plugins/logo'; 27 | 28 | import { 29 | loadIncrementalAssets, 30 | getPageSchema, 31 | saveSchema, 32 | resetSchema, 33 | preview, 34 | getProjectSchemaFromLocalStorage, 35 | } from '../../universal/utils'; 36 | import assets from './assets.json'; 37 | import schema from './schema.json'; 38 | 39 | export default async function registerPlugins() { 40 | await plugins.register(ManualPlugin); 41 | 42 | await plugins.register(Inject); 43 | 44 | // plugin API 见 https://lowcode-engine.cn/docV2/ibh9fh 45 | SchemaPlugin.pluginName = 'SchemaPlugin'; 46 | await plugins.register(SchemaPlugin); 47 | 48 | SimulatorResizer.pluginName = 'SimulatorResizer'; 49 | plugins.register(SimulatorResizer); 50 | 51 | const editorInit = (ctx: ILowCodePluginContext) => { 52 | return { 53 | name: 'editor-init', 54 | async init() { 55 | // 修改面包屑组件的分隔符属性setter 56 | // const assets = await ( 57 | // await fetch( 58 | // `https://alifd.alicdn.com/npm/@alilc/lowcode-materials/build/lowcode/assets-prod.json` 59 | // ) 60 | // ).json(); 61 | // 设置物料描述 62 | const { material, project } = ctx; 63 | 64 | material.setAssets(await injectAssets(assets)); 65 | 66 | // 加载 schema 67 | project.openDocument(getProjectSchemaFromLocalStorage('basic-fusion-with-single-component').componentsTree?.[0] || schema); 68 | }, 69 | }; 70 | } 71 | editorInit.pluginName = 'editorInit'; 72 | await plugins.register(editorInit); 73 | 74 | const builtinPluginRegistry = (ctx: ILowCodePluginContext) => { 75 | return { 76 | name: 'builtin-plugin-registry', 77 | async init() { 78 | const { skeleton } = ctx; 79 | // 注册 logo 面板 80 | skeleton.add({ 81 | area: 'topArea', 82 | type: 'Widget', 83 | name: 'logo', 84 | content: Logo, 85 | contentProps: { 86 | logo: 'https://img.alicdn.com/imgextra/i4/O1CN013w2bmQ25WAIha4Hx9_!!6000000007533-55-tps-137-26.svg', 87 | href: 'https://lowcode-engine.cn', 88 | }, 89 | props: { 90 | align: 'left', 91 | }, 92 | }); 93 | 94 | // 注册组件面板 95 | const componentsPane = skeleton.add({ 96 | area: 'leftArea', 97 | type: 'PanelDock', 98 | name: 'componentsPane', 99 | content: ComponentsPane, 100 | contentProps: {}, 101 | props: { 102 | align: 'top', 103 | icon: 'zujianku', 104 | description: '组件库', 105 | }, 106 | }); 107 | componentsPane?.disable?.(); 108 | project.onSimulatorRendererReady(() => { 109 | componentsPane?.enable?.(); 110 | }) 111 | }, 112 | }; 113 | } 114 | builtinPluginRegistry.pluginName = 'builtinPluginRegistry'; 115 | await plugins.register(builtinPluginRegistry); 116 | 117 | // 设置内置 setter 和事件绑定、插件绑定面板 118 | const setterRegistry = (ctx: ILowCodePluginContext) => { 119 | const { setterMap, pluginMap } = AliLowCodeEngineExt; 120 | return { 121 | name: 'ext-setters-registry', 122 | async init() { 123 | const { setters, skeleton } = ctx; 124 | // 注册setterMap 125 | setters.registerSetter(setterMap); 126 | // 注册插件 127 | // 注册事件绑定面板 128 | skeleton.add({ 129 | area: 'centerArea', 130 | type: 'Widget', 131 | content: pluginMap.EventBindDialog, 132 | name: 'eventBindDialog', 133 | props: {}, 134 | }); 135 | 136 | // 注册变量绑定面板 137 | skeleton.add({ 138 | area: 'centerArea', 139 | type: 'Widget', 140 | content: pluginMap.VariableBindDialog, 141 | name: 'variableBindDialog', 142 | props: {}, 143 | }); 144 | }, 145 | }; 146 | } 147 | setterRegistry.pluginName = 'setterRegistry'; 148 | await plugins.register(setterRegistry); 149 | 150 | // 注册回退/前进 151 | await plugins.register(UndoRedoPlugin); 152 | 153 | // 注册中英文切换 154 | await plugins.register(ZhEnPlugin); 155 | 156 | const loadAssetsSample = (ctx: ILowCodePluginContext) => { 157 | return { 158 | name: 'loadAssetsSample', 159 | async init() { 160 | const { skeleton } = ctx; 161 | 162 | skeleton.add({ 163 | name: 'loadAssetsSample', 164 | area: 'topArea', 165 | type: 'Widget', 166 | props: { 167 | align: 'right', 168 | width: 80, 169 | }, 170 | content: ( 171 | 174 | ), 175 | }); 176 | }, 177 | }; 178 | }; 179 | loadAssetsSample.pluginName = 'loadAssetsSample'; 180 | await plugins.register(loadAssetsSample); 181 | 182 | // 注册保存面板 183 | const saveSample = (ctx: ILowCodePluginContext) => { 184 | return { 185 | name: 'saveSample', 186 | async init() { 187 | const { skeleton, hotkey } = ctx; 188 | 189 | skeleton.add({ 190 | name: 'saveSample', 191 | area: 'topArea', 192 | type: 'Widget', 193 | props: { 194 | align: 'right', 195 | }, 196 | content: ( 197 | 200 | ), 201 | }); 202 | skeleton.add({ 203 | name: 'resetSchema', 204 | area: 'topArea', 205 | type: 'Widget', 206 | props: { 207 | align: 'right', 208 | }, 209 | content: ( 210 | 213 | ), 214 | }); 215 | hotkey.bind('command+s', (e) => { 216 | e.preventDefault(); 217 | saveSchema('basic-fusion-with-single-component') 218 | }); 219 | }, 220 | }; 221 | } 222 | saveSample.pluginName = 'saveSample'; 223 | await plugins.register(saveSample); 224 | 225 | DataSourcePanePlugin.pluginName = 'DataSourcePane'; 226 | await plugins.register(DataSourcePanePlugin); 227 | 228 | CodeEditor.pluginName = 'CodeEditor'; 229 | await plugins.register(CodeEditor); 230 | 231 | // 注册出码插件 232 | CodeGenPlugin.pluginName = 'CodeGenPlugin'; 233 | await plugins.register(CodeGenPlugin); 234 | 235 | const previewSample = (ctx: ILowCodePluginContext) => { 236 | return { 237 | name: 'previewSample', 238 | async init() { 239 | const { skeleton } = ctx; 240 | skeleton.add({ 241 | name: 'previewSample', 242 | area: 'topArea', 243 | type: 'Widget', 244 | props: { 245 | align: 'right', 246 | }, 247 | content: ( 248 | 251 | ), 252 | }); 253 | }, 254 | }; 255 | }; 256 | previewSample.pluginName = 'previewSample'; 257 | await plugins.register(previewSample); 258 | 259 | const customSetter = (ctx: ILowCodePluginContext) => { 260 | return { 261 | name: '___registerCustomSetter___', 262 | async init() { 263 | const { setters } = ctx; 264 | 265 | setters.registerSetter('TitleSetter', TitleSetter); 266 | setters.registerSetter('BehaviorSetter', BehaviorSetter); 267 | setters.registerSetter('CustomSetter', CustomSetter); 268 | }, 269 | }; 270 | } 271 | customSetter.pluginName = 'customSetter'; 272 | await plugins.register(customSetter); 273 | }; 274 | -------------------------------------------------------------------------------- /web/src/scenarios/antd-pro-with-formily/plugin.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ILowCodePluginContext, plugins, skeleton, project, setters } from '@alilc/lowcode-engine'; 3 | import AliLowCodeEngineExt from '@alilc/lowcode-engine-ext'; 4 | import { Button } from '@alifd/next'; 5 | import UndoRedoPlugin from '@alilc/lowcode-plugin-undo-redo'; 6 | import ComponentsPane from '@alilc/lowcode-plugin-components-pane'; 7 | import ZhEnPlugin from '@alilc/lowcode-plugin-zh-en'; 8 | import CodeGenPlugin from '@alilc/lowcode-plugin-code-generator'; 9 | import DataSourcePanePlugin from '@alilc/lowcode-plugin-datasource-pane'; 10 | import SchemaPlugin from '@alilc/lowcode-plugin-schema'; 11 | import CodeEditor from '@alilc/lowcode-plugin-code-editor'; 12 | import ManualPlugin from '@alilc/lowcode-plugin-manual'; 13 | import Inject, { injectAssets } from '@alilc/lowcode-plugin-inject'; 14 | import SimulatorResizer from '@alilc/lowcode-plugin-simulator-select'; 15 | import { PluginFormily } from '@seada/antd-plugins' 16 | 17 | // 注册到引擎 18 | import TitleSetter from '@alilc/lowcode-setter-title'; 19 | import BehaviorSetter from '../../setters/behavior-setter'; 20 | import CustomSetter from '../../setters/custom-setter'; 21 | import Logo from '../../sample-plugins/logo'; 22 | import { registerRefProp } from 'src/sample-plugins/set-ref-prop'; 23 | import { deleteHiddenTransducer } from '../../sample-plugins/delete-hidden-transducer'; 24 | 25 | import { 26 | loadIncrementalAssets, 27 | getPageSchema, 28 | saveSchema, 29 | resetSchema, 30 | preview, 31 | getProjectSchemaFromLocalStorage, 32 | } from '../../universal/utils'; 33 | import assets from './assets.json'; 34 | import schema from './schema.json'; 35 | 36 | export default async function registerPlugins() { 37 | await plugins.register(ManualPlugin); 38 | 39 | await plugins.register(Inject); 40 | 41 | await plugins.register(registerRefProp); 42 | 43 | await plugins.register(deleteHiddenTransducer); 44 | 45 | await plugins.register(PluginFormily) 46 | 47 | // plugin API 见 https://lowcode-engine.cn/docV2/ibh9fh 48 | SchemaPlugin.pluginName = 'SchemaPlugin'; 49 | await plugins.register(SchemaPlugin); 50 | 51 | SimulatorResizer.pluginName = 'SimulatorResizer'; 52 | plugins.register(SimulatorResizer); 53 | 54 | const editorInit = (ctx: ILowCodePluginContext) => { 55 | return { 56 | name: 'editor-init', 57 | async init() { 58 | // 修改面包屑组件的分隔符属性setter 59 | // const assets = await ( 60 | // await fetch( 61 | // `https://alifd.alicdn.com/npm/@alilc/lowcode-materials/build/lowcode/assets-prod.json` 62 | // ) 63 | // ).json(); 64 | // 设置物料描述 65 | const { material, project } = ctx; 66 | 67 | material.setAssets(await injectAssets(assets)); 68 | 69 | // 加载 schema 70 | project.openDocument( 71 | getProjectSchemaFromLocalStorage('antd-pro-with-formily').componentsTree?.[0] || schema, 72 | ); 73 | }, 74 | }; 75 | }; 76 | editorInit.pluginName = 'editorInit'; 77 | await plugins.register(editorInit); 78 | 79 | const builtinPluginRegistry = (ctx: ILowCodePluginContext) => { 80 | return { 81 | name: 'builtin-plugin-registry', 82 | async init() { 83 | const { skeleton } = ctx; 84 | // 注册 logo 面板 85 | skeleton.add({ 86 | area: 'topArea', 87 | type: 'Widget', 88 | name: 'logo', 89 | content: Logo, 90 | contentProps: { 91 | logo: 'https://img.alicdn.com/imgextra/i4/O1CN013w2bmQ25WAIha4Hx9_!!6000000007533-55-tps-137-26.svg', 92 | href: 'https://lowcode-engine.cn', 93 | }, 94 | props: { 95 | align: 'left', 96 | }, 97 | }); 98 | 99 | // 注册组件面板 100 | const componentsPane = skeleton.add({ 101 | area: 'leftArea', 102 | type: 'PanelDock', 103 | name: 'componentsPane', 104 | content: ComponentsPane, 105 | contentProps: {}, 106 | props: { 107 | align: 'top', 108 | icon: 'zujianku', 109 | description: '组件库', 110 | }, 111 | }); 112 | componentsPane?.disable?.(); 113 | project.onSimulatorRendererReady(() => { 114 | componentsPane?.enable?.(); 115 | }); 116 | }, 117 | }; 118 | }; 119 | builtinPluginRegistry.pluginName = 'builtinPluginRegistry'; 120 | await plugins.register(builtinPluginRegistry); 121 | 122 | // 设置内置 setter 和事件绑定、插件绑定面板 123 | const setterRegistry = (ctx: ILowCodePluginContext) => { 124 | const { setterMap, pluginMap } = AliLowCodeEngineExt; 125 | return { 126 | name: 'ext-setters-registry', 127 | async init() { 128 | const { setters, skeleton } = ctx; 129 | // 注册setterMap 130 | setters.registerSetter(setterMap); 131 | // 注册插件 132 | // 注册事件绑定面板 133 | skeleton.add({ 134 | area: 'centerArea', 135 | type: 'Widget', 136 | content: pluginMap.EventBindDialog, 137 | name: 'eventBindDialog', 138 | props: {}, 139 | }); 140 | 141 | // 注册变量绑定面板 142 | skeleton.add({ 143 | area: 'centerArea', 144 | type: 'Widget', 145 | content: pluginMap.VariableBindDialog, 146 | name: 'variableBindDialog', 147 | props: {}, 148 | }); 149 | }, 150 | }; 151 | }; 152 | setterRegistry.pluginName = 'setterRegistry'; 153 | await plugins.register(setterRegistry); 154 | 155 | // 注册回退/前进 156 | await plugins.register(UndoRedoPlugin); 157 | 158 | // 注册中英文切换 159 | await plugins.register(ZhEnPlugin); 160 | 161 | const loadAssetsSample = (ctx: ILowCodePluginContext) => { 162 | return { 163 | name: 'loadAssetsSample', 164 | async init() { 165 | const { skeleton } = ctx; 166 | 167 | skeleton.add({ 168 | name: 'loadAssetsSample', 169 | area: 'topArea', 170 | type: 'Widget', 171 | props: { 172 | align: 'right', 173 | width: 80, 174 | }, 175 | content: , 176 | }); 177 | }, 178 | }; 179 | }; 180 | loadAssetsSample.pluginName = 'loadAssetsSample'; 181 | await plugins.register(loadAssetsSample); 182 | 183 | // 注册保存面板 184 | const saveSample = (ctx: ILowCodePluginContext) => { 185 | return { 186 | name: 'saveSample', 187 | async init() { 188 | const { skeleton, hotkey } = ctx; 189 | 190 | skeleton.add({ 191 | name: 'saveSample', 192 | area: 'topArea', 193 | type: 'Widget', 194 | props: { 195 | align: 'right', 196 | }, 197 | content: , 198 | }); 199 | skeleton.add({ 200 | name: 'resetSchema', 201 | area: 'topArea', 202 | type: 'Widget', 203 | props: { 204 | align: 'right', 205 | }, 206 | content: , 207 | }); 208 | hotkey.bind('command+s', (e) => { 209 | e.preventDefault(); 210 | saveSchema('next-pro'); 211 | }); 212 | }, 213 | }; 214 | }; 215 | saveSample.pluginName = 'saveSample'; 216 | await plugins.register(saveSample); 217 | 218 | DataSourcePanePlugin.pluginName = 'DataSourcePane'; 219 | await plugins.register(DataSourcePanePlugin); 220 | 221 | CodeEditor.pluginName = 'CodeEditor'; 222 | await plugins.register(CodeEditor); 223 | 224 | // 注册出码插件 225 | CodeGenPlugin.pluginName = 'CodeGenPlugin'; 226 | await plugins.register(CodeGenPlugin); 227 | 228 | const previewSample = (ctx: ILowCodePluginContext) => { 229 | return { 230 | name: 'previewSample', 231 | async init() { 232 | const { skeleton } = ctx; 233 | skeleton.add({ 234 | name: 'previewSample', 235 | area: 'topArea', 236 | type: 'Widget', 237 | props: { 238 | align: 'right', 239 | }, 240 | content: ( 241 | 244 | ), 245 | }); 246 | }, 247 | }; 248 | }; 249 | previewSample.pluginName = 'previewSample'; 250 | await plugins.register(previewSample); 251 | 252 | const customSetter = (ctx: ILowCodePluginContext) => { 253 | return { 254 | name: '___registerCustomSetter___', 255 | async init() { 256 | const { setters } = ctx; 257 | 258 | setters.registerSetter('TitleSetter', TitleSetter); 259 | setters.registerSetter('BehaviorSetter', BehaviorSetter); 260 | setters.registerSetter('CustomSetter', CustomSetter); 261 | }, 262 | }; 263 | }; 264 | customSetter.pluginName = 'customSetter'; 265 | await plugins.register(customSetter); 266 | } 267 | -------------------------------------------------------------------------------- /web/src/scenarios/basic-antd/PageManage/index.tsx: -------------------------------------------------------------------------------- 1 | import { PageSchema, TransformStage } from '@alilc/lowcode-types'; 2 | import { SelectInfo } from 'rc-menu/lib/interface'; 3 | import { useEffect, useState } from 'react'; 4 | import { project } from '@alilc/lowcode-engine'; 5 | import { 6 | Row, 7 | Col, 8 | Form, 9 | Menu, 10 | Input, 11 | Modal, 12 | Space, 13 | Button, 14 | Upload, 15 | Divider, 16 | message 17 | } from 'antd'; 18 | import { UploadChangeParam } from 'antd/lib/upload' 19 | import { FileAddOutlined, ExportOutlined, ImportOutlined, DeleteTwoTone } from '@ant-design/icons' 20 | 21 | let defaultPageSchema: PageSchema = require('../schema.json') 22 | /** 接口请求域名端口前缀,根据服务实际情况调整 */ 23 | const baseUrl = 'http://localhost:3010' 24 | 25 | /** 新建表单字段值 */ 26 | interface ICreateFormFieldsValue { 27 | fileName: string 28 | } 29 | 30 | export default () => { 31 | // 新建表单实例 32 | const [createPageForm] = Form.useForm(); 33 | // 页面列表 34 | const [pages, setPages] = useState([]); 35 | // 当前页面 36 | const [currentPage, setCurrentPage] = useState(''); 37 | // 新建页面弹窗是否可见 38 | const [createPageModalVisible, setPageModalVisible] = useState(false); 39 | 40 | useEffect(() => { 41 | getPages() 42 | .then((pages: PageSchema[]) => { 43 | setCurrentPage(pages[0].fileName) 44 | project.currentDocument && project.removeDocument(project.currentDocument); 45 | project.openDocument(pages[0]) 46 | }) 47 | }, []); 48 | 49 | /** 开启/关闭新建页面弹窗 */ 50 | const openCreatePageModal = () => setPageModalVisible(true); 51 | const closeCreatePageModal = () => setPageModalVisible(false); 52 | 53 | /** 54 | * 获取所有页面 55 | */ 56 | const getPages = () => { 57 | return fetch(`${baseUrl}/pages`, { method: 'GET' }) 58 | .then((res) => res.json()) 59 | .then((resJson: { 60 | code: 0, 61 | data: PageSchema[] 62 | }) => { 63 | setPages(resJson.data); 64 | return resJson.data 65 | }) 66 | }; 67 | 68 | /** 69 | * 通过页面文件名删除指定页面 70 | */ 71 | const deletePageByFileName = (fileName: string) => { 72 | fetch(`${baseUrl}/page/${fileName}`, { method: 'DELETE' }) 73 | .then(res => res.json()) 74 | .then((resJson: { 75 | code: 0 | -1, 76 | msg: string 77 | }) => { 78 | if (resJson.code === 0) { 79 | message.success(resJson.msg) 80 | getPages() 81 | .then((pages: PageSchema[]) => { 82 | setCurrentPage(pages[0].fileName) 83 | project.openDocument(pages[0]) 84 | }) 85 | } else { 86 | message.error(resJson.msg) 87 | } 88 | }) 89 | }; 90 | 91 | /** 新建页面 */ 92 | const createPage = (values: ICreateFormFieldsValue) => { 93 | const { fileName } = values 94 | defaultPageSchema.fileName = fileName 95 | fetch(`${baseUrl}/page/${fileName}`, { 96 | method: 'POST', 97 | body: JSON.stringify({ pageSchema: defaultPageSchema }), 98 | headers: { 'content-type': 'application/json;charset=UTF-8' } 99 | }) 100 | .then((res) => res.json()) 101 | .then((resJson: { code: 0 | -1, msg: string }) => { 102 | if (resJson.code === 0) { 103 | message.success(resJson.msg) 104 | getPages(); 105 | createPageForm.resetFields(); 106 | setPageModalVisible(false); 107 | } else { 108 | message.error(resJson.msg) 109 | } 110 | }) 111 | }; 112 | 113 | /** 导出 */ 114 | const exportAllPageSchema = () => { 115 | const blob = new window.Blob([JSON.stringify(pages)], { 116 | type: 'application/json;charset=UTF-8', 117 | }); 118 | const downloadUrl = URL.createObjectURL(blob); 119 | const downloadLinkDOM = document.createElement('a'); 120 | downloadLinkDOM.href = downloadUrl; 121 | downloadLinkDOM.download = 'schema.json'; 122 | downloadLinkDOM.click(); 123 | URL.revokeObjectURL(downloadUrl); 124 | }; 125 | 126 | /** 导入 */ 127 | const importAllPageSchema = (info: UploadChangeParam) => { 128 | if (info.file.status === 'done') { 129 | const file = info.file.originFileObj; 130 | const fileReader = new FileReader(); 131 | fileReader.readAsText(file!); 132 | fileReader.onload = () => { 133 | // 具体逻辑待补充 134 | // const allPageSchema = JSON.parse(fileReader.result as string); 135 | // let pageId; 136 | // allPageSchema.forEach((item: string[], index: number) => { 137 | // if (index === 0) pageId = item[0].split(':')[0]; 138 | // localStorage.setItem(item[0], item[1]); 139 | // }); 140 | // message.success('导入成功'); 141 | // getPages(); 142 | // setCurrentPage(pageId); 143 | // saveSchema(); 144 | }; 145 | } 146 | }; 147 | 148 | /** 保存页面 */ 149 | const savePage = () => { 150 | const pageSchema = project.currentDocument?.exportSchema(TransformStage.Save) 151 | return fetch(`${baseUrl}/page/${pageSchema?.fileName}`, { 152 | method: 'PUT', 153 | body: JSON.stringify({ pageSchema }), 154 | headers: { 'content-type': 'application/json;charset=UTF-8' } 155 | }) 156 | .then((res) => res.json()) 157 | .then((resJson: { code: 0 | -1, msg: string }) => { 158 | if (resJson.code === 0) { 159 | message.success('上一页面已自动保存') 160 | } else { 161 | message.error(resJson.msg) 162 | return Promise.reject() 163 | } 164 | }) 165 | } 166 | 167 | const handleSelect = async ({ selectedKeys }: SelectInfo) => { 168 | const prevCurrentPage = currentPage 169 | const fileName = selectedKeys[0]; 170 | setCurrentPage(fileName); 171 | // 在线保存 172 | savePage() 173 | .then(() => { 174 | // 使用低代码编辑的页面往往都挺复杂,确保在线保存成功后再切其他页面 175 | const schema = pages.find(item => item.fileName === fileName)!; 176 | project.currentDocument && project.removeDocument(project.currentDocument); 177 | project.openDocument(schema); 178 | // 为了更快地将所点击页面的 schema 渲染到画布上,重新获取所有页面的数据这一操作可以晚点再做 179 | getPages() 180 | }) 181 | .catch(() => { 182 | // 如果在线保存失败,页面菜单高亮项切回前一个页面 183 | setCurrentPage(prevCurrentPage) 184 | }) 185 | }; 186 | 187 | return ( 188 | <> 189 | 190 | 191 | 198 | 199 | 200 | 208 | 209 | 210 | 214 | 221 | 222 | 223 | 224 | 225 | 230 | {pages.length 231 | ? pages.map(page => ( 232 | 233 | 234 | {page.fileName} 235 | 236 | deletePageByFileName(page.fileName)} /> 237 | 238 | 239 | 240 | )) 241 | : null} 242 | 243 | 244 | 250 |
257 | 262 | 263 | 264 | 265 | 266 | 272 | 277 | 278 | 279 | 280 |
281 |
282 | 283 | ); 284 | }; -------------------------------------------------------------------------------- /web/src/scenarios/basic-antd/plugin.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | ILowCodePluginContext, 4 | plugins, 5 | skeleton, 6 | project, 7 | setters, 8 | } from '@alilc/lowcode-engine'; 9 | import AliLowCodeEngineExt from '@alilc/lowcode-engine-ext'; 10 | import { Button } from '@alifd/next'; 11 | import UndoRedoPlugin from '@alilc/lowcode-plugin-undo-redo'; 12 | import ComponentsPane from '@alilc/lowcode-plugin-components-pane'; 13 | import ZhEnPlugin from '@alilc/lowcode-plugin-zh-en'; 14 | import CodeGenPlugin from '@alilc/lowcode-plugin-code-generator'; 15 | import DataSourcePanePlugin from '@alilc/lowcode-plugin-datasource-pane'; 16 | import SchemaPlugin from '@alilc/lowcode-plugin-schema'; 17 | import CodeEditor from "@alilc/lowcode-plugin-code-editor"; 18 | import ManualPlugin from "@alilc/lowcode-plugin-manual"; 19 | import Inject, { injectAssets } from '@alilc/lowcode-plugin-inject'; 20 | import SimulatorResizer from '@alilc/lowcode-plugin-simulator-select'; 21 | 22 | // 注册到引擎 23 | import TitleSetter from '@alilc/lowcode-setter-title'; 24 | import BehaviorSetter from '../../setters/behavior-setter'; 25 | import CustomSetter from '../../setters/custom-setter'; 26 | import Logo from '../../sample-plugins/logo'; 27 | import PageManage from './PageManage' 28 | 29 | import { 30 | loadIncrementalAssets, 31 | getPageSchema, 32 | saveSchema, 33 | resetSchema, 34 | preview, 35 | getProjectSchemaFromLocalStorage, 36 | } from '../../universal/utils'; 37 | import assets from './assets.json'; 38 | import schema from './schema.json'; 39 | 40 | export default async function registerPlugins() { 41 | await plugins.register(ManualPlugin); 42 | 43 | await plugins.register(Inject); 44 | 45 | // plugin API 见 https://lowcode-engine.cn/docV2/ibh9fh 46 | SchemaPlugin.pluginName = 'SchemaPlugin'; 47 | await plugins.register(SchemaPlugin); 48 | 49 | SimulatorResizer.pluginName = 'SimulatorResizer'; 50 | plugins.register(SimulatorResizer); 51 | 52 | const editorInit = (ctx: ILowCodePluginContext) => { 53 | return { 54 | name: 'editor-init', 55 | async init() { 56 | // 修改面包屑组件的分隔符属性setter 57 | // const assets = await ( 58 | // await fetch( 59 | // `https://alifd.alicdn.com/npm/@alilc/lowcode-materials/build/lowcode/assets-prod.json` 60 | // ) 61 | // ).json(); 62 | // 设置物料描述 63 | const { material, project } = ctx; 64 | 65 | material.setAssets(await injectAssets(assets)); 66 | 67 | // 加载 schema 68 | project.openDocument(getProjectSchemaFromLocalStorage('basic-antd').componentsTree?.[0] || schema); 69 | }, 70 | }; 71 | } 72 | editorInit.pluginName = 'editorInit'; 73 | await plugins.register(editorInit); 74 | 75 | const builtinPluginRegistry = (ctx: ILowCodePluginContext) => { 76 | return { 77 | name: 'builtin-plugin-registry', 78 | async init() { 79 | const { skeleton } = ctx; 80 | // 注册 logo 面板 81 | skeleton.add({ 82 | area: 'topArea', 83 | type: 'Widget', 84 | name: 'logo', 85 | content: Logo, 86 | contentProps: { 87 | logo: 'https://img.alicdn.com/imgextra/i4/O1CN013w2bmQ25WAIha4Hx9_!!6000000007533-55-tps-137-26.svg', 88 | href: 'https://lowcode-engine.cn', 89 | }, 90 | props: { 91 | align: 'left', 92 | }, 93 | }); 94 | 95 | // 注册组件面板 96 | const componentsPane = skeleton.add({ 97 | area: 'leftArea', 98 | type: 'PanelDock', 99 | name: 'componentsPane', 100 | content: ComponentsPane, 101 | contentProps: {}, 102 | props: { 103 | align: 'top', 104 | icon: 'zujianku', 105 | description: '组件库', 106 | }, 107 | }); 108 | componentsPane?.disable?.(); 109 | project.onSimulatorRendererReady(() => { 110 | componentsPane?.enable?.(); 111 | }) 112 | skeleton.add({ 113 | index: -1, 114 | area: 'leftArea', 115 | type: 'PanelDock', 116 | name: 'pagesPane', 117 | content: PageManage, 118 | contentProps: {}, 119 | props: { 120 | align: 'top', 121 | icon: 'kaiwenjianjia', 122 | description: '页面管理', 123 | }, 124 | }); 125 | }, 126 | }; 127 | } 128 | builtinPluginRegistry.pluginName = 'builtinPluginRegistry'; 129 | await plugins.register(builtinPluginRegistry); 130 | 131 | // 设置内置 setter 和事件绑定、插件绑定面板 132 | const setterRegistry = (ctx: ILowCodePluginContext) => { 133 | const { setterMap, pluginMap } = AliLowCodeEngineExt; 134 | return { 135 | name: 'ext-setters-registry', 136 | async init() { 137 | const { setters, skeleton } = ctx; 138 | // 注册setterMap 139 | setters.registerSetter(setterMap); 140 | // 注册插件 141 | // 注册事件绑定面板 142 | skeleton.add({ 143 | area: 'centerArea', 144 | type: 'Widget', 145 | content: pluginMap.EventBindDialog, 146 | name: 'eventBindDialog', 147 | props: {}, 148 | }); 149 | 150 | // 注册变量绑定面板 151 | skeleton.add({ 152 | area: 'centerArea', 153 | type: 'Widget', 154 | content: pluginMap.VariableBindDialog, 155 | name: 'variableBindDialog', 156 | props: {}, 157 | }); 158 | }, 159 | }; 160 | } 161 | setterRegistry.pluginName = 'setterRegistry'; 162 | await plugins.register(setterRegistry); 163 | 164 | // 注册回退/前进 165 | await plugins.register(UndoRedoPlugin); 166 | 167 | // 注册中英文切换 168 | await plugins.register(ZhEnPlugin); 169 | 170 | const loadAssetsSample = (ctx: ILowCodePluginContext) => { 171 | return { 172 | name: 'loadAssetsSample', 173 | async init() { 174 | const { skeleton } = ctx; 175 | 176 | skeleton.add({ 177 | name: 'loadAssetsSample', 178 | area: 'topArea', 179 | type: 'Widget', 180 | props: { 181 | align: 'right', 182 | width: 80, 183 | }, 184 | content: ( 185 | 188 | ), 189 | }); 190 | }, 191 | }; 192 | }; 193 | loadAssetsSample.pluginName = 'loadAssetsSample'; 194 | await plugins.register(loadAssetsSample); 195 | 196 | // 注册保存面板 197 | const saveSample = (ctx: ILowCodePluginContext) => { 198 | return { 199 | name: 'saveSample', 200 | async init() { 201 | const { skeleton, hotkey } = ctx; 202 | 203 | skeleton.add({ 204 | name: 'saveSample', 205 | area: 'topArea', 206 | type: 'Widget', 207 | props: { 208 | align: 'right', 209 | }, 210 | content: ( 211 | 214 | ), 215 | }); 216 | skeleton.add({ 217 | name: 'resetSchema', 218 | area: 'topArea', 219 | type: 'Widget', 220 | props: { 221 | align: 'right', 222 | }, 223 | content: ( 224 | 227 | ), 228 | }); 229 | hotkey.bind('command+s', (e) => { 230 | e.preventDefault(); 231 | saveSchema('basic-antd') 232 | }); 233 | }, 234 | }; 235 | } 236 | saveSample.pluginName = 'saveSample'; 237 | await plugins.register(saveSample); 238 | 239 | DataSourcePanePlugin.pluginName = 'DataSourcePane'; 240 | await plugins.register(DataSourcePanePlugin); 241 | 242 | CodeEditor.pluginName = 'CodeEditor'; 243 | await plugins.register(CodeEditor); 244 | 245 | // 注册出码插件 246 | CodeGenPlugin.pluginName = 'CodeGenPlugin'; 247 | await plugins.register(CodeGenPlugin); 248 | 249 | const previewSample = (ctx: ILowCodePluginContext) => { 250 | return { 251 | name: 'previewSample', 252 | async init() { 253 | const { skeleton } = ctx; 254 | skeleton.add({ 255 | name: 'previewSample', 256 | area: 'topArea', 257 | type: 'Widget', 258 | props: { 259 | align: 'right', 260 | }, 261 | content: ( 262 | 265 | ), 266 | }); 267 | }, 268 | }; 269 | }; 270 | previewSample.pluginName = 'previewSample'; 271 | await plugins.register(previewSample); 272 | 273 | const customSetter = (ctx: ILowCodePluginContext) => { 274 | return { 275 | name: '___registerCustomSetter___', 276 | async init() { 277 | const { setters } = ctx; 278 | 279 | setters.registerSetter('TitleSetter', TitleSetter); 280 | setters.registerSetter('BehaviorSetter', BehaviorSetter); 281 | setters.registerSetter('CustomSetter', CustomSetter); 282 | }, 283 | }; 284 | } 285 | customSetter.pluginName = 'customSetter'; 286 | await plugins.register(customSetter); 287 | }; 288 | -------------------------------------------------------------------------------- /web/src/scenarios/node-extended-actions/plugin.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | ILowCodePluginContext, 4 | plugins, 5 | skeleton, 6 | project, 7 | setters, 8 | Node, 9 | } from '@alilc/lowcode-engine'; 10 | import AliLowCodeEngineExt from '@alilc/lowcode-engine-ext'; 11 | import { Icon, Message, Button } from '@alifd/next'; 12 | import UndoRedoPlugin from '@alilc/lowcode-plugin-undo-redo'; 13 | import ComponentsPane from '@alilc/lowcode-plugin-components-pane'; 14 | import ZhEnPlugin from '@alilc/lowcode-plugin-zh-en'; 15 | import CodeGenPlugin from '@alilc/lowcode-plugin-code-generator'; 16 | import DataSourcePanePlugin from '@alilc/lowcode-plugin-datasource-pane'; 17 | import SchemaPlugin from '@alilc/lowcode-plugin-schema'; 18 | import CodeEditor from "@alilc/lowcode-plugin-code-editor"; 19 | import ManualPlugin from "@alilc/lowcode-plugin-manual"; 20 | import Inject, { injectAssets } from '@alilc/lowcode-plugin-inject'; 21 | import SimulatorResizer from '@alilc/lowcode-plugin-simulator-select'; 22 | 23 | // 注册到引擎 24 | import TitleSetter from '@alilc/lowcode-setter-title'; 25 | import BehaviorSetter from '../../setters/behavior-setter'; 26 | import CustomSetter from '../../setters/custom-setter'; 27 | import Logo from '../../sample-plugins/logo'; 28 | 29 | import { 30 | loadIncrementalAssets, 31 | getPageSchema, 32 | saveSchema, 33 | resetSchema, 34 | preview, 35 | getProjectSchemaFromLocalStorage, 36 | } from '../../universal/utils'; 37 | import assets from './assets.json'; 38 | import schema from './schema.json'; 39 | 40 | export default async function registerPlugins() { 41 | 42 | const addHelloAction = (ctx: ILowCodePluginContext) => { 43 | return { 44 | async init() { 45 | const { addBuiltinComponentAction } = ctx.material; 46 | addBuiltinComponentAction({ 47 | name: 'hello', 48 | content: { 49 | icon: , 50 | title: 'hello', 51 | action(node: Node) { 52 | Message.show('Welcome to Low-Code engine'); 53 | }, 54 | }, 55 | condition: (node: Node) => { 56 | return node.componentMeta.componentName === 'NextTable'; 57 | } 58 | }); 59 | } 60 | }; 61 | } 62 | addHelloAction.pluginName = 'addHelloAction'; 63 | await plugins.register(addHelloAction); 64 | 65 | const removeCopyAction = (ctx: ILowCodePluginContext) => { 66 | return { 67 | async init() { 68 | const { removeBuiltinComponentAction } = ctx.material; 69 | removeBuiltinComponentAction('copy'); 70 | } 71 | } 72 | } 73 | removeCopyAction.pluginName = 'removeCopyAction'; 74 | await plugins.register(removeCopyAction); 75 | 76 | await plugins.register(ManualPlugin); 77 | 78 | await plugins.register(Inject); 79 | 80 | // plugin API 见 https://lowcode-engine.cn/docV2/ibh9fh 81 | SchemaPlugin.pluginName = 'SchemaPlugin'; 82 | await plugins.register(SchemaPlugin); 83 | 84 | SimulatorResizer.pluginName = 'SimulatorResizer'; 85 | plugins.register(SimulatorResizer); 86 | 87 | const editorInit = (ctx: ILowCodePluginContext) => { 88 | return { 89 | name: 'editor-init', 90 | async init() { 91 | // 修改面包屑组件的分隔符属性setter 92 | // const assets = await ( 93 | // await fetch( 94 | // `https://alifd.alicdn.com/npm/@alilc/lowcode-materials/build/lowcode/assets-prod.json` 95 | // ) 96 | // ).json(); 97 | // 设置物料描述 98 | const { material, project } = ctx; 99 | 100 | material.setAssets(await injectAssets(assets)); 101 | 102 | // 加载 schema 103 | project.openDocument(getProjectSchemaFromLocalStorage('node-extended-actions').componentsTree?.[0] || schema); 104 | }, 105 | }; 106 | } 107 | editorInit.pluginName = 'editorInit'; 108 | await plugins.register(editorInit); 109 | 110 | const builtinPluginRegistry = (ctx: ILowCodePluginContext) => { 111 | return { 112 | name: 'builtin-plugin-registry', 113 | async init() { 114 | const { skeleton } = ctx; 115 | // 注册 logo 面板 116 | skeleton.add({ 117 | area: 'topArea', 118 | type: 'Widget', 119 | name: 'logo', 120 | content: Logo, 121 | contentProps: { 122 | logo: 'https://img.alicdn.com/imgextra/i4/O1CN013w2bmQ25WAIha4Hx9_!!6000000007533-55-tps-137-26.svg', 123 | href: 'https://lowcode-engine.cn', 124 | }, 125 | props: { 126 | align: 'left', 127 | }, 128 | }); 129 | 130 | // 注册组件面板 131 | const componentsPane = skeleton.add({ 132 | area: 'leftArea', 133 | type: 'PanelDock', 134 | name: 'componentsPane', 135 | content: ComponentsPane, 136 | contentProps: {}, 137 | props: { 138 | align: 'top', 139 | icon: 'zujianku', 140 | description: '组件库', 141 | }, 142 | }); 143 | componentsPane?.disable?.(); 144 | project.onSimulatorRendererReady(() => { 145 | componentsPane?.enable?.(); 146 | }) 147 | }, 148 | }; 149 | } 150 | builtinPluginRegistry.pluginName = 'builtinPluginRegistry'; 151 | await plugins.register(builtinPluginRegistry); 152 | 153 | // 设置内置 setter 和事件绑定、插件绑定面板 154 | const setterRegistry = (ctx: ILowCodePluginContext) => { 155 | const { setterMap, pluginMap } = AliLowCodeEngineExt; 156 | return { 157 | name: 'ext-setters-registry', 158 | async init() { 159 | const { setters, skeleton } = ctx; 160 | // 注册setterMap 161 | setters.registerSetter(setterMap); 162 | // 注册插件 163 | // 注册事件绑定面板 164 | skeleton.add({ 165 | area: 'centerArea', 166 | type: 'Widget', 167 | content: pluginMap.EventBindDialog, 168 | name: 'eventBindDialog', 169 | props: {}, 170 | }); 171 | 172 | // 注册变量绑定面板 173 | skeleton.add({ 174 | area: 'centerArea', 175 | type: 'Widget', 176 | content: pluginMap.VariableBindDialog, 177 | name: 'variableBindDialog', 178 | props: {}, 179 | }); 180 | }, 181 | }; 182 | } 183 | setterRegistry.pluginName = 'setterRegistry'; 184 | await plugins.register(setterRegistry); 185 | 186 | // 注册回退/前进 187 | await plugins.register(UndoRedoPlugin); 188 | 189 | // 注册中英文切换 190 | await plugins.register(ZhEnPlugin); 191 | 192 | const loadAssetsSample = (ctx: ILowCodePluginContext) => { 193 | return { 194 | name: 'loadAssetsSample', 195 | async init() { 196 | const { skeleton } = ctx; 197 | 198 | skeleton.add({ 199 | name: 'loadAssetsSample', 200 | area: 'topArea', 201 | type: 'Widget', 202 | props: { 203 | align: 'right', 204 | width: 80, 205 | }, 206 | content: ( 207 | 210 | ), 211 | }); 212 | }, 213 | }; 214 | }; 215 | loadAssetsSample.pluginName = 'loadAssetsSample'; 216 | await plugins.register(loadAssetsSample); 217 | 218 | // 注册保存面板 219 | const saveSample = (ctx: ILowCodePluginContext) => { 220 | return { 221 | name: 'saveSample', 222 | async init() { 223 | const { skeleton, hotkey } = ctx; 224 | 225 | skeleton.add({ 226 | name: 'saveSample', 227 | area: 'topArea', 228 | type: 'Widget', 229 | props: { 230 | align: 'right', 231 | }, 232 | content: ( 233 | 236 | ), 237 | }); 238 | skeleton.add({ 239 | name: 'resetSchema', 240 | area: 'topArea', 241 | type: 'Widget', 242 | props: { 243 | align: 'right', 244 | }, 245 | content: ( 246 | 249 | ), 250 | }); 251 | hotkey.bind('command+s', (e) => { 252 | e.preventDefault(); 253 | saveSchema('node-extended-actions') 254 | }); 255 | }, 256 | }; 257 | } 258 | saveSample.pluginName = 'saveSample'; 259 | await plugins.register(saveSample); 260 | 261 | DataSourcePanePlugin.pluginName = 'DataSourcePane'; 262 | await plugins.register(DataSourcePanePlugin); 263 | 264 | CodeEditor.pluginName = 'CodeEditor'; 265 | await plugins.register(CodeEditor); 266 | 267 | // 注册出码插件 268 | CodeGenPlugin.pluginName = 'CodeGenPlugin'; 269 | await plugins.register(CodeGenPlugin); 270 | 271 | const previewSample = (ctx: ILowCodePluginContext) => { 272 | return { 273 | name: 'previewSample', 274 | async init() { 275 | const { skeleton } = ctx; 276 | skeleton.add({ 277 | name: 'previewSample', 278 | area: 'topArea', 279 | type: 'Widget', 280 | props: { 281 | align: 'right', 282 | }, 283 | content: ( 284 | 287 | ), 288 | }); 289 | }, 290 | }; 291 | }; 292 | previewSample.pluginName = 'previewSample'; 293 | await plugins.register(previewSample); 294 | 295 | const customSetter = (ctx: ILowCodePluginContext) => { 296 | return { 297 | name: '___registerCustomSetter___', 298 | async init() { 299 | const { setters } = ctx; 300 | 301 | setters.registerSetter('TitleSetter', TitleSetter); 302 | setters.registerSetter('BehaviorSetter', BehaviorSetter); 303 | setters.registerSetter('CustomSetter', CustomSetter); 304 | }, 305 | }; 306 | } 307 | customSetter.pluginName = 'customSetter'; 308 | await plugins.register(customSetter); 309 | }; 310 | -------------------------------------------------------------------------------- /web/src/scenarios/basic-formily/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "componentName": "Page", 3 | "id": "node_dockcviv8fo1", 4 | "props": { 5 | "ref": "outerView", 6 | "style": { 7 | "height": "100%" 8 | } 9 | }, 10 | "fileName": "/", 11 | "dataSource": { 12 | "list": [ 13 | { 14 | "type": "fetch", 15 | "isInit": true, 16 | "options": { 17 | "params": {}, 18 | "method": "GET", 19 | "isCors": true, 20 | "timeout": 5000, 21 | "headers": {}, 22 | "uri": "mock/info.json" 23 | }, 24 | "id": "info", 25 | "shouldFetch": { 26 | "type": "JSFunction", 27 | "value": "function() { \n console.log('should fetch.....');\n return true; \n}" 28 | } 29 | } 30 | ] 31 | }, 32 | "state": { 33 | "text": { 34 | "type": "JSExpression", 35 | "value": "\"outer\"" 36 | }, 37 | "isShowDialog": { 38 | "type": "JSExpression", 39 | "value": "false" 40 | } 41 | }, 42 | "css": "body {\n font-size: 12px;\n}\n\n.button {\n width: 100px;\n color: #ff00ff\n}", 43 | "lifeCycles": { 44 | "componentDidMount": { 45 | "type": "JSFunction", 46 | "value": "function componentDidMount() {\n console.log('did mount');\n}" 47 | }, 48 | "componentWillUnmount": { 49 | "type": "JSFunction", 50 | "value": "function componentWillUnmount() {\n console.log('will unmount');\n}" 51 | } 52 | }, 53 | "methods": { 54 | "testFunc": { 55 | "type": "JSFunction", 56 | "value": "function testFunc() {\n console.log('test func');\n}" 57 | }, 58 | "onClick": { 59 | "type": "JSFunction", 60 | "value": "function onClick() {\n this.setState({\n isShowDialog: true\n });\n}" 61 | }, 62 | "closeDialog": { 63 | "type": "JSFunction", 64 | "value": "function closeDialog() {\n this.setState({\n isShowDialog: false\n });\n}" 65 | } 66 | }, 67 | "originCode": "class LowcodeComponent extends Component {\n state = {\n \"text\": \"outer\",\n \"isShowDialog\": false\n }\n componentDidMount() {\n console.log('did mount');\n }\n componentWillUnmount() {\n console.log('will unmount');\n }\n testFunc() {\n console.log('test func');\n }\n onClick() {\n this.setState({\n isShowDialog: true\n })\n }\n closeDialog() {\n this.setState({\n isShowDialog: false\n })\n }\n}", 68 | "hidden": false, 69 | "title": "", 70 | "isLocked": false, 71 | "condition": true, 72 | "conditionGroup": "", 73 | "children": [ 74 | { 75 | "componentName": "FormilyForm", 76 | "id": "node_ocl4p2e02w1", 77 | "props": { 78 | "componentProps": { 79 | "layout": "vertical" 80 | }, 81 | "__component_name": "FormilyForm", 82 | "ref": "formily_7eeo00gr8pa" 83 | }, 84 | "title": "FormilyForm", 85 | "hidden": false, 86 | "isLocked": false, 87 | "condition": true, 88 | "conditionGroup": "", 89 | "children": [ 90 | { 91 | "componentName": "FormilyInput", 92 | "id": "node_ocl4p2e02w2", 93 | "props": { 94 | "__component_name": "FormilyInput", 95 | "fieldProps": { 96 | "name": "username", 97 | "title": "Input", 98 | "x-validator": [] 99 | }, 100 | "componentProps": { 101 | "x-component-props": {} 102 | }, 103 | "decoratorProps": { 104 | "x-decorator-props": {} 105 | } 106 | }, 107 | "hidden": false, 108 | "title": "", 109 | "isLocked": false, 110 | "condition": true, 111 | "conditionGroup": "" 112 | }, 113 | { 114 | "componentName": "FormilyPassword", 115 | "id": "node_ocl4p2e02w3", 116 | "props": { 117 | "__component_name": "FormilyPassword", 118 | "fieldProps": { 119 | "name": "password", 120 | "title": "Password", 121 | "x-validator": [] 122 | }, 123 | "componentProps": { 124 | "x-component-props": {} 125 | }, 126 | "decoratorProps": { 127 | "x-decorator-props": {} 128 | } 129 | }, 130 | "hidden": false, 131 | "title": "", 132 | "isLocked": false, 133 | "condition": true, 134 | "conditionGroup": "" 135 | }, 136 | { 137 | "componentName": "FormilyNumberPicker", 138 | "id": "node_ocl4p2e02w4", 139 | "props": { 140 | "__component_name": "FormilyNumberPicker", 141 | "fieldProps": { 142 | "name": "age", 143 | "title": "NumberPicker", 144 | "x-validator": [] 145 | }, 146 | "componentProps": { 147 | "x-component-props": {} 148 | }, 149 | "decoratorProps": { 150 | "x-decorator-props": {} 151 | } 152 | }, 153 | "hidden": false, 154 | "title": "", 155 | "isLocked": false, 156 | "condition": true, 157 | "conditionGroup": "" 158 | }, 159 | { 160 | "componentName": "FormilySelect", 161 | "id": "node_ocl4p2e02w5", 162 | "props": { 163 | "__component_name": "FormilySelect", 164 | "fieldProps": { 165 | "name": "habit", 166 | "title": "Select", 167 | "x-validator": [] 168 | }, 169 | "componentProps": { 170 | "x-component-props": {} 171 | }, 172 | "decoratorProps": { 173 | "x-decorator-props": {} 174 | } 175 | }, 176 | "hidden": false, 177 | "title": "", 178 | "isLocked": false, 179 | "condition": true, 180 | "conditionGroup": "" 181 | }, 182 | { 183 | "componentName": "FormilySwitch", 184 | "id": "node_ocl4p2e02w6", 185 | "props": { 186 | "__component_name": "FormilySwitch", 187 | "fieldProps": { 188 | "name": "switch", 189 | "title": "Switch", 190 | "x-validator": [] 191 | }, 192 | "componentProps": { 193 | "x-component-props": {} 194 | }, 195 | "decoratorProps": { 196 | "x-decorator-props": {} 197 | } 198 | }, 199 | "hidden": false, 200 | "title": "", 201 | "isLocked": false, 202 | "condition": true, 203 | "conditionGroup": "" 204 | }, 205 | { 206 | "componentName": "FormilyCheckbox", 207 | "id": "node_ocl4p2e02w7", 208 | "props": { 209 | "__component_name": "FormilyCheckbox", 210 | "fieldProps": { 211 | "name": "gender", 212 | "title": "Checkbox Group", 213 | "enum": [ 214 | { 215 | "label": "选项1", 216 | "value": 1 217 | }, 218 | { 219 | "label": "选项2", 220 | "value": 2 221 | } 222 | ], 223 | "x-validator": [] 224 | }, 225 | "componentProps": { 226 | "x-component-props": {} 227 | }, 228 | "decoratorProps": { 229 | "x-decorator-props": {} 230 | } 231 | }, 232 | "hidden": false, 233 | "title": "", 234 | "isLocked": false, 235 | "condition": true, 236 | "conditionGroup": "" 237 | }, 238 | { 239 | "componentName": "FormilyTextArea", 240 | "id": "node_ocl4p2e02w8", 241 | "props": { 242 | "__component_name": "FormilyTextArea", 243 | "fieldProps": { 244 | "name": "text", 245 | "title": "TextArea", 246 | "x-component": "Input.TextArea", 247 | "x-validator": [] 248 | }, 249 | "componentProps": { 250 | "x-component-props": {} 251 | }, 252 | "decoratorProps": { 253 | "x-decorator-props": {} 254 | } 255 | }, 256 | "hidden": false, 257 | "title": "", 258 | "isLocked": false, 259 | "condition": true, 260 | "conditionGroup": "" 261 | }, 262 | { 263 | "componentName": "FormilyMonacoInput", 264 | "id": "node_ocl4p2e02w9", 265 | "props": { 266 | "__component_name": "FormilyMonacoInput", 267 | "fieldProps": { 268 | "name": "code", 269 | "title": "MonacoInput", 270 | "x-validator": [] 271 | }, 272 | "componentProps": { 273 | "x-component-props": { 274 | "defaultLanguage": "text", 275 | "height": 160, 276 | "readOnly": false, 277 | "theme": "vs-dark", 278 | "options": { 279 | "lineNumbers": "on" 280 | } 281 | } 282 | }, 283 | "decoratorProps": { 284 | "x-decorator-props": {} 285 | } 286 | }, 287 | "hidden": false, 288 | "title": "", 289 | "isLocked": false, 290 | "condition": true, 291 | "conditionGroup": "" 292 | }, 293 | { 294 | "componentName": "FormilyUploadDragger", 295 | "id": "node_ocl4p2e02wa", 296 | "props": { 297 | "__component_name": "FormilyUploadDragger", 298 | "fieldProps": { 299 | "name": "files", 300 | "title": "Drag Upload", 301 | "type": "Array", 302 | "x-validator": [] 303 | }, 304 | "componentProps": { 305 | "x-component-props": { 306 | "textContent": "Click or drag file to this area to upload" 307 | } 308 | }, 309 | "decoratorProps": { 310 | "x-decorator-props": {} 311 | } 312 | }, 313 | "hidden": false, 314 | "title": "", 315 | "isLocked": false, 316 | "condition": true, 317 | "conditionGroup": "" 318 | } 319 | ] 320 | } 321 | ] 322 | } 323 | -------------------------------------------------------------------------------- /web/src/universal/utils.ts: -------------------------------------------------------------------------------- 1 | import { material, project } from '@alilc/lowcode-engine'; 2 | import { filterPackages } from '@alilc/lowcode-plugin-inject' 3 | import { Message, Dialog } from '@alifd/next'; 4 | import { TransformStage } from '@alilc/lowcode-types'; 5 | 6 | export const loadIncrementalAssets = () => { 7 | material?.onChangeAssets(() => { 8 | Message.success('[MCBreadcrumb] 物料加载成功'); 9 | }); 10 | 11 | material.loadIncrementalAssets({ 12 | packages: [ 13 | { 14 | title: 'MCBreadcrumb', 15 | package: 'mc-breadcrumb', 16 | version: '1.0.0', 17 | urls: [ 18 | 'https://unpkg.alibaba-inc.com/mc-breadcrumb@1.0.0/dist/MCBreadcrumb.js', 19 | 'https://unpkg.alibaba-inc.com/mc-breadcrumb@1.0.0/dist/MCBreadcrumb.css', 20 | ], 21 | library: 'MCBreadcrumb', 22 | }, 23 | ], 24 | components: [ 25 | { 26 | componentName: 'MCBreadcrumb', 27 | title: 'MCBreadcrumb', 28 | docUrl: '', 29 | screenshot: '', 30 | npm: { 31 | package: 'mc-breadcrumb', 32 | version: '1.0.0', 33 | exportName: 'MCBreadcrumb', 34 | main: 'lib/index.js', 35 | destructuring: false, 36 | subName: '', 37 | }, 38 | props: [ 39 | { 40 | name: 'prefix', 41 | propType: 'string', 42 | description: '样式类名的品牌前缀', 43 | defaultValue: 'next-', 44 | }, 45 | { 46 | name: 'title', 47 | propType: 'string', 48 | description: '标题', 49 | defaultValue: 'next-', 50 | }, 51 | { 52 | name: 'rtl', 53 | propType: 'bool', 54 | }, 55 | { 56 | name: 'children', 57 | propType: { 58 | type: 'instanceOf', 59 | value: 'node', 60 | }, 61 | description: '面包屑子节点,需传入 Breadcrumb.Item', 62 | }, 63 | { 64 | name: 'maxNode', 65 | propType: { 66 | type: 'oneOfType', 67 | value: [ 68 | 'number', 69 | { 70 | type: 'oneOf', 71 | value: ['auto'], 72 | }, 73 | ], 74 | }, 75 | description: 76 | '面包屑最多显示个数,超出部分会被隐藏, 设置为 auto 会自动根据父元素的宽度适配。', 77 | defaultValue: 100, 78 | }, 79 | { 80 | name: 'separator', 81 | propType: { 82 | type: 'instanceOf', 83 | value: 'node', 84 | }, 85 | description: '分隔符,可以是文本或 Icon', 86 | }, 87 | { 88 | name: 'component', 89 | propType: { 90 | type: 'oneOfType', 91 | value: ['string', 'func'], 92 | }, 93 | description: '设置标签类型', 94 | defaultValue: 'nav', 95 | }, 96 | { 97 | name: 'className', 98 | propType: 'any', 99 | }, 100 | { 101 | name: 'style', 102 | propType: 'object', 103 | }, 104 | ], 105 | configure: { 106 | component: { 107 | isContainer: true, 108 | isModel: true, 109 | rootSelector: 'div.MCBreadcrumb', 110 | }, 111 | }, 112 | }, 113 | ], 114 | 115 | componentList: [ 116 | { 117 | title: '常用', 118 | icon: '', 119 | children: [ 120 | { 121 | componentName: 'MCBreadcrumb', 122 | title: 'MC面包屑', 123 | icon: '', 124 | package: 'mc-breadcrumb', 125 | library: 'MCBreadcrumb', 126 | snippets: [ 127 | { 128 | title: 'MC面包屑', 129 | screenshot: 130 | 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_breadcrumb.png', 131 | schema: { 132 | componentName: 'MCBreadcrumb', 133 | props: { 134 | title: '物料中心', 135 | prefix: 'next-', 136 | maxNode: 100, 137 | }, 138 | }, 139 | }, 140 | ], 141 | }, 142 | ], 143 | }, 144 | ], 145 | }); 146 | }; 147 | 148 | export const preview = (scenarioName: string = 'index') => { 149 | saveSchema(scenarioName); 150 | setTimeout(() => { 151 | const search = location.search ? `${location.search}&scenarioName=${scenarioName}` : `?scenarioName=${scenarioName}`; 152 | window.open(`./preview.html${search}`); 153 | }, 500); 154 | }; 155 | 156 | export const saveSchema = async (scenarioName: string = 'index') => { 157 | setProjectSchemaToLocalStorage(scenarioName); 158 | 159 | await setPackgesToLocalStorage(scenarioName); 160 | // window.localStorage.setItem( 161 | // 'projectSchema', 162 | // JSON.stringify(project.exportSchema(TransformStage.Save)) 163 | // ); 164 | // const packages = await filterPackages(material.getAssets().packages); 165 | // window.localStorage.setItem( 166 | // 'packages', 167 | // JSON.stringify(packages) 168 | // ); 169 | Message.success('成功保存到本地'); 170 | }; 171 | 172 | export const resetSchema = async (scenarioName: string = 'index') => { 173 | try { 174 | await new Promise((resolve, reject) => { 175 | Dialog.confirm({ 176 | content: '确定要重置吗?您所有的修改都将消失!', 177 | onOk: () => { 178 | resolve(); 179 | }, 180 | onCancel: () => { 181 | reject() 182 | }, 183 | }) 184 | }) 185 | } catch(err) { 186 | return 187 | } 188 | 189 | // 除了「综合场景」,其他场景没有默认 schema.json,这里构造空页面 190 | if (scenarioName !== 'index') { 191 | window.localStorage.setItem( 192 | getLSName(scenarioName), 193 | JSON.stringify({ 194 | componentsTree: [{ componentName: 'Page', fileName: 'sample' }], 195 | componentsMap: material.componentsMap, 196 | version: '1.0.0', 197 | i18n: {}, 198 | }) 199 | ); 200 | project.getCurrentDocument()?.importSchema({ componentName: 'Page', fileName: 'sample' }); 201 | project.simulatorHost?.rerender(); 202 | Message.success('成功重置页面'); 203 | return; 204 | } 205 | 206 | let schema; 207 | try { 208 | schema = await request('./schema.json') 209 | } catch(err) { 210 | schema = { 211 | componentName: 'Page', 212 | fileName: 'sample', 213 | } 214 | } 215 | 216 | window.localStorage.setItem( 217 | getLSName('index'), 218 | JSON.stringify({ 219 | componentsTree: [schema], 220 | componentsMap: material.componentsMap, 221 | version: '1.0.0', 222 | i18n: {}, 223 | }) 224 | ); 225 | 226 | project.getCurrentDocument()?.importSchema(schema); 227 | project.simulatorHost?.rerender(); 228 | Message.success('成功重置页面'); 229 | } 230 | 231 | const getLSName = (scenarioName: string, ns: string = 'projectSchema') => `${scenarioName}:${ns}`; 232 | 233 | export const getProjectSchemaFromLocalStorage = (scenarioName: string) => { 234 | if (!scenarioName) { 235 | console.error('scenarioName is required!'); 236 | return; 237 | } 238 | return JSON.parse(window.localStorage.getItem(getLSName(scenarioName)) || '{}'); 239 | } 240 | 241 | const setProjectSchemaToLocalStorage = (scenarioName: string) => { 242 | if (!scenarioName) { 243 | console.error('scenarioName is required!'); 244 | return; 245 | } 246 | window.localStorage.setItem( 247 | getLSName(scenarioName), 248 | JSON.stringify(project.exportSchema(TransformStage.Save)) 249 | ); 250 | } 251 | 252 | const setPackgesToLocalStorage = async (scenarioName: string) => { 253 | if (!scenarioName) { 254 | console.error('scenarioName is required!'); 255 | return; 256 | } 257 | const packages = await filterPackages(material.getAssets().packages); 258 | window.localStorage.setItem( 259 | getLSName(scenarioName, 'packages'), 260 | JSON.stringify(packages), 261 | ); 262 | } 263 | 264 | export const getPackagesFromLocalStorage = (scenarioName: string) => { 265 | if (!scenarioName) { 266 | console.error('scenarioName is required!'); 267 | return; 268 | } 269 | return JSON.parse(window.localStorage.getItem(getLSName(scenarioName, 'packages')) || '{}'); 270 | } 271 | 272 | export const getPageSchema = async (scenarioName: string = 'index') => { 273 | const pageSchema = getProjectSchemaFromLocalStorage(scenarioName).componentsTree?.[0] 274 | 275 | if (pageSchema) { 276 | return pageSchema; 277 | } 278 | 279 | return await request('./schema.json'); 280 | }; 281 | 282 | function request( 283 | dataAPI: string, 284 | method = 'GET', 285 | data?: object | string, 286 | headers?: object, 287 | otherProps?: any, 288 | ): Promise { 289 | return new Promise((resolve, reject): void => { 290 | if (otherProps && otherProps.timeout) { 291 | setTimeout((): void => { 292 | reject(new Error('timeout')); 293 | }, otherProps.timeout); 294 | } 295 | fetch(dataAPI, { 296 | method, 297 | credentials: 'include', 298 | headers, 299 | body: data, 300 | ...otherProps, 301 | }) 302 | .then((response: Response): any => { 303 | switch (response.status) { 304 | case 200: 305 | case 201: 306 | case 202: 307 | return response.json(); 308 | case 204: 309 | if (method === 'DELETE') { 310 | return { 311 | success: true, 312 | }; 313 | } else { 314 | return { 315 | __success: false, 316 | code: response.status, 317 | }; 318 | } 319 | case 400: 320 | case 401: 321 | case 403: 322 | case 404: 323 | case 406: 324 | case 410: 325 | case 422: 326 | case 500: 327 | return response 328 | .json() 329 | .then((res: object): any => { 330 | return { 331 | __success: false, 332 | code: response.status, 333 | data: res, 334 | }; 335 | }) 336 | .catch((): object => { 337 | return { 338 | __success: false, 339 | code: response.status, 340 | }; 341 | }); 342 | default: 343 | return null; 344 | } 345 | }) 346 | .then((json: any): void => { 347 | if (json && json.__success !== false) { 348 | resolve(json); 349 | } else { 350 | delete json.__success; 351 | reject(json); 352 | } 353 | }) 354 | .catch((err: Error): void => { 355 | reject(err); 356 | }); 357 | }); 358 | } -------------------------------------------------------------------------------- /web/public/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "componentName": "Page", 3 | "id": "node_dockcviv8fo1", 4 | "props": { 5 | "ref": "outerView", 6 | "style": { 7 | "height": "100%" 8 | } 9 | }, 10 | "fileName": "/", 11 | "dataSource": { 12 | "list": [ 13 | { 14 | "type": "fetch", 15 | "isInit": true, 16 | "options": { 17 | "params": {}, 18 | "method": "GET", 19 | "isCors": true, 20 | "timeout": 5000, 21 | "headers": {}, 22 | "uri": "mock/info.json" 23 | }, 24 | "id": "info", 25 | "shouldFetch": { 26 | "type": "JSFunction", 27 | "value": "function() { \n console.log('should fetch.....');\n return true; \n}" 28 | } 29 | } 30 | ] 31 | }, 32 | "state": { 33 | "text": { 34 | "type": "JSExpression", 35 | "value": "\"outer\"" 36 | }, 37 | "isShowDialog": { 38 | "type": "JSExpression", 39 | "value": "false" 40 | } 41 | }, 42 | "css": "body {\n font-size: 12px;\n}\n\n.button {\n width: 100px;\n color: #ff00ff\n}", 43 | "lifeCycles": { 44 | "componentDidMount": { 45 | "type": "JSFunction", 46 | "value": "function componentDidMount() {\n console.log('did mount');\n}" 47 | }, 48 | "componentWillUnmount": { 49 | "type": "JSFunction", 50 | "value": "function componentWillUnmount() {\n console.log('will unmount');\n}" 51 | } 52 | }, 53 | "methods": { 54 | "testFunc": { 55 | "type": "JSFunction", 56 | "value": "function testFunc() {\n console.log('test func');\n}" 57 | }, 58 | "onClick": { 59 | "type": "JSFunction", 60 | "value": "function onClick() {\n this.setState({\n isShowDialog: true\n });\n}" 61 | }, 62 | "closeDialog": { 63 | "type": "JSFunction", 64 | "value": "function closeDialog() {\n this.setState({\n isShowDialog: false\n });\n}" 65 | } 66 | }, 67 | "originCode": "class LowcodeComponent extends Component {\n state = {\n \"text\": \"outer\",\n \"isShowDialog\": false\n }\n componentDidMount() {\n console.log('did mount');\n }\n componentWillUnmount() {\n console.log('will unmount');\n }\n testFunc() {\n console.log('test func');\n }\n onClick() {\n this.setState({\n isShowDialog: true\n })\n }\n closeDialog() {\n this.setState({\n isShowDialog: false\n })\n }\n}", 68 | "hidden": false, 69 | "title": "", 70 | "isLocked": false, 71 | "condition": true, 72 | "conditionGroup": "", 73 | "children": [ 74 | { 75 | "componentName": "NextPage", 76 | "id": "node_ockzs2vw431", 77 | "props": { 78 | "headerDivider": true, 79 | "minHeight": "100vh", 80 | "presetNav": true, 81 | "presetAside": true, 82 | "footer": false, 83 | "nav": false, 84 | "aside": false, 85 | "placeholderStyle": { 86 | "gridRowEnd": "span 1", 87 | "gridColumnEnd": "span 12" 88 | }, 89 | "headerProps": { 90 | "background": "surface" 91 | }, 92 | "header": { 93 | "type": "JSSlot", 94 | "value": [ 95 | { 96 | "componentName": "NextPageHeader", 97 | "id": "node_ockzs2vw433", 98 | "props": {}, 99 | "title": "页面头部", 100 | "hidden": false, 101 | "isLocked": false, 102 | "condition": true, 103 | "conditionGroup": "", 104 | "children": [ 105 | { 106 | "componentName": "NextRowColContainer", 107 | "id": "node_ockzs2vw434", 108 | "props": { 109 | "rowGap": 20, 110 | "colGap": 20 111 | }, 112 | "title": "行列容器", 113 | "hidden": false, 114 | "isLocked": false, 115 | "condition": true, 116 | "conditionGroup": "", 117 | "children": [ 118 | { 119 | "componentName": "NextRow", 120 | "id": "node_ockzs2vw435", 121 | "props": {}, 122 | "title": "行", 123 | "hidden": false, 124 | "isLocked": false, 125 | "condition": true, 126 | "conditionGroup": "", 127 | "children": [ 128 | { 129 | "componentName": "NextCol", 130 | "id": "node_ockzs2vw436", 131 | "props": { 132 | "colSpan": 1 133 | }, 134 | "title": "列", 135 | "hidden": false, 136 | "isLocked": false, 137 | "condition": true, 138 | "conditionGroup": "", 139 | "children": [ 140 | { 141 | "componentName": "NextP", 142 | "id": "node_ockzvfoetv17", 143 | "props": { 144 | "wrap": false, 145 | "type": "body2", 146 | "verAlign": "middle", 147 | "textSpacing": true, 148 | "align": "left" 149 | }, 150 | "docId": "dockzvfoetv", 151 | "title": "段落", 152 | "hidden": false, 153 | "isLocked": false, 154 | "condition": true, 155 | "conditionGroup": "", 156 | "children": [ 157 | { 158 | "componentName": "NextText", 159 | "id": "node_ockzvfoetv18", 160 | "props": { 161 | "type": "h5", 162 | "children": { 163 | "type": "JSExpression", 164 | "value": "this.state.info?.info", 165 | "mock": "标题标题" 166 | }, 167 | "mark": false, 168 | "code": false, 169 | "delete": false, 170 | "underline": false, 171 | "strong": false 172 | }, 173 | "docId": "dockzvfoetv", 174 | "hidden": false, 175 | "title": "", 176 | "isLocked": false, 177 | "condition": true, 178 | "conditionGroup": "" 179 | } 180 | ] 181 | } 182 | ] 183 | } 184 | ] 185 | } 186 | ] 187 | } 188 | ] 189 | } 190 | ], 191 | "title": "header" 192 | }, 193 | "isTab": false, 194 | "contentAlignCenter": false, 195 | "contentProps": { 196 | "style": { 197 | "background": "rgba(255,255,255,0)" 198 | } 199 | } 200 | }, 201 | "title": "页面", 202 | "hidden": false, 203 | "isLocked": false, 204 | "condition": true, 205 | "conditionGroup": "", 206 | "children": [ 207 | { 208 | "componentName": "NextBlock", 209 | "id": "node_ockzs2vw437", 210 | "props": { 211 | "placeholderStyle": { 212 | "height": "100%" 213 | }, 214 | "noPadding": false, 215 | "noBorder": false, 216 | "title": "区域标题", 217 | "rowGap": 20, 218 | "colGap": 20, 219 | "background": "surface", 220 | "layoutmode": "O", 221 | "strict": true, 222 | "colSpan": 12, 223 | "rowSpan": 1, 224 | "mode": "transparent", 225 | "childTotalColumns": 12 226 | }, 227 | "title": "区域", 228 | "hidden": false, 229 | "isLocked": false, 230 | "condition": true, 231 | "conditionGroup": "", 232 | "children": [ 233 | { 234 | "componentName": "NextBlockCell", 235 | "id": "node_ockzs2vw438", 236 | "props": { 237 | "colSpan": 12, 238 | "rowSpan": 1, 239 | "mode": "procard", 240 | "isAutoContainer": true, 241 | "title": "区块标题" 242 | }, 243 | "hidden": false, 244 | "title": "", 245 | "isLocked": false, 246 | "condition": true, 247 | "conditionGroup": "", 248 | "children": [ 249 | { 250 | "componentName": "NextRowColContainer", 251 | "id": "node_ockzs2vw439", 252 | "props": { 253 | "rowGap": 20, 254 | "colGap": 20 255 | }, 256 | "title": "行列容器", 257 | "hidden": false, 258 | "isLocked": false, 259 | "condition": true, 260 | "conditionGroup": "", 261 | "children": [ 262 | { 263 | "componentName": "NextRow", 264 | "id": "node_ockzs2vw43a", 265 | "props": {}, 266 | "title": "行", 267 | "hidden": false, 268 | "isLocked": false, 269 | "condition": true, 270 | "conditionGroup": "", 271 | "children": [ 272 | { 273 | "componentName": "NextCol", 274 | "id": "node_ockzs2vw43b", 275 | "props": { 276 | "colSpan": 1 277 | }, 278 | "title": "列", 279 | "hidden": false, 280 | "isLocked": false, 281 | "condition": true, 282 | "conditionGroup": "" 283 | } 284 | ] 285 | } 286 | ] 287 | } 288 | ] 289 | } 290 | ] 291 | } 292 | ] 293 | } 294 | ] 295 | } -------------------------------------------------------------------------------- /server/pages.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "componentName": "Page", 4 | "id": "node_dockcviv8fo1", 5 | "props": { 6 | "ref": "outerView", 7 | "style": { 8 | "height": "100%" 9 | } 10 | }, 11 | "fileName": "one", 12 | "dataSource": { 13 | "list": [ 14 | { 15 | "type": "fetch", 16 | "isInit": true, 17 | "options": { 18 | "params": {}, 19 | "method": "GET", 20 | "isCors": true, 21 | "timeout": 5000, 22 | "headers": {}, 23 | "uri": "mock/info.json" 24 | }, 25 | "id": "info", 26 | "shouldFetch": { 27 | "type": "JSFunction", 28 | "value": "function() { \n console.log('should fetch.....');\n return true; \n}" 29 | } 30 | } 31 | ] 32 | }, 33 | "state": { 34 | "text": { 35 | "type": "JSExpression", 36 | "value": "\"outer\"" 37 | }, 38 | "isShowDialog": { 39 | "type": "JSExpression", 40 | "value": "false" 41 | } 42 | }, 43 | "css": "body {\n font-size: 12px;\n}\n\n.button {\n width: 100px;\n color: #ff00ff\n}", 44 | "lifeCycles": { 45 | "componentDidMount": { 46 | "type": "JSFunction", 47 | "value": "function componentDidMount() {\n console.log('did mount');\n}" 48 | }, 49 | "componentWillUnmount": { 50 | "type": "JSFunction", 51 | "value": "function componentWillUnmount() {\n console.log('will unmount');\n}" 52 | } 53 | }, 54 | "methods": { 55 | "testFunc": { 56 | "type": "JSFunction", 57 | "value": "function testFunc() {\n console.log('test func');\n}" 58 | }, 59 | "onClick": { 60 | "type": "JSFunction", 61 | "value": "function onClick() {\n this.setState({\n isShowDialog: true\n });\n}" 62 | }, 63 | "closeDialog": { 64 | "type": "JSFunction", 65 | "value": "function closeDialog() {\n this.setState({\n isShowDialog: false\n });\n}" 66 | } 67 | }, 68 | "originCode": "class LowcodeComponent extends Component {\n state = {\n \"text\": \"outer\",\n \"isShowDialog\": false\n }\n componentDidMount() {\n console.log('did mount');\n }\n componentWillUnmount() {\n console.log('will unmount');\n }\n testFunc() {\n console.log('test func');\n }\n onClick() {\n this.setState({\n isShowDialog: true\n })\n }\n closeDialog() {\n this.setState({\n isShowDialog: false\n })\n }\n}", 69 | "hidden": false, 70 | "title": "", 71 | "isLocked": false, 72 | "condition": true, 73 | "conditionGroup": "", 74 | "children": [ 75 | { 76 | "componentName": "Button", 77 | "id": "node_ocl6n2awdi7", 78 | "props": { 79 | "type": "danger", 80 | "children": "危险按钮", 81 | "htmlType": "button", 82 | "size": "middle", 83 | "shape": "default", 84 | "icon": { 85 | "type": "JSSlot", 86 | "value": [ 87 | { 88 | "componentName": "Icon", 89 | "id": "node_ocl6n2awdi9", 90 | "props": { 91 | "type": "SmileOutlined", 92 | "size": 20, 93 | "rotate": 0, 94 | "spin": false 95 | }, 96 | "hidden": false, 97 | "title": "", 98 | "isLocked": false, 99 | "condition": true, 100 | "conditionGroup": "" 101 | } 102 | ] 103 | }, 104 | "block": false, 105 | "danger": false, 106 | "ghost": false, 107 | "disabled": false 108 | }, 109 | "hidden": false, 110 | "title": "", 111 | "isLocked": false, 112 | "condition": true, 113 | "conditionGroup": "" 114 | } 115 | ] 116 | }, 117 | { 118 | "componentName": "Page", 119 | "id": "node_dockcviv8fo1", 120 | "props": { 121 | "ref": "outerView", 122 | "style": { 123 | "height": "100%" 124 | } 125 | }, 126 | "fileName": "two", 127 | "dataSource": { 128 | "list": [ 129 | { 130 | "type": "fetch", 131 | "isInit": true, 132 | "options": { 133 | "params": {}, 134 | "method": "GET", 135 | "isCors": true, 136 | "timeout": 5000, 137 | "headers": {}, 138 | "uri": "mock/info.json" 139 | }, 140 | "id": "info", 141 | "shouldFetch": { 142 | "type": "JSFunction", 143 | "value": "function() { \n console.log('should fetch.....');\n return true; \n}" 144 | } 145 | } 146 | ] 147 | }, 148 | "state": { 149 | "text": { 150 | "type": "JSExpression", 151 | "value": "\"outer\"" 152 | }, 153 | "isShowDialog": { 154 | "type": "JSExpression", 155 | "value": "false" 156 | } 157 | }, 158 | "css": "body {\n font-size: 12px;\n}\n\n.button {\n width: 100px;\n color: #ff00ff\n}", 159 | "lifeCycles": { 160 | "componentDidMount": { 161 | "type": "JSFunction", 162 | "value": "function componentDidMount() {\n console.log('did mount');\n}" 163 | }, 164 | "componentWillUnmount": { 165 | "type": "JSFunction", 166 | "value": "function componentWillUnmount() {\n console.log('will unmount');\n}" 167 | } 168 | }, 169 | "methods": { 170 | "testFunc": { 171 | "type": "JSFunction", 172 | "value": "function testFunc() {\n console.log('test func');\n}" 173 | }, 174 | "onClick": { 175 | "type": "JSFunction", 176 | "value": "function onClick() {\n this.setState({\n isShowDialog: true\n });\n}" 177 | }, 178 | "closeDialog": { 179 | "type": "JSFunction", 180 | "value": "function closeDialog() {\n this.setState({\n isShowDialog: false\n });\n}" 181 | } 182 | }, 183 | "originCode": "class LowcodeComponent extends Component {\n state = {\n \"text\": \"outer\",\n \"isShowDialog\": false\n }\n componentDidMount() {\n console.log('did mount');\n }\n componentWillUnmount() {\n console.log('will unmount');\n }\n testFunc() {\n console.log('test func');\n }\n onClick() {\n this.setState({\n isShowDialog: true\n })\n }\n closeDialog() {\n this.setState({\n isShowDialog: false\n })\n }\n}", 184 | "hidden": false, 185 | "title": "", 186 | "isLocked": false, 187 | "condition": true, 188 | "conditionGroup": "", 189 | "children": [ 190 | { 191 | "componentName": "Button", 192 | "id": "node_ocl6n2awdi7", 193 | "props": { 194 | "type": "danger", 195 | "children": "危险按钮", 196 | "htmlType": "button", 197 | "size": "middle", 198 | "shape": "default", 199 | "icon": { 200 | "type": "JSSlot", 201 | "value": [ 202 | { 203 | "componentName": "Icon", 204 | "id": "node_ocl6n2awdi9", 205 | "props": { 206 | "type": "SmileOutlined", 207 | "size": 20, 208 | "rotate": 0, 209 | "spin": false 210 | }, 211 | "hidden": false, 212 | "title": "", 213 | "isLocked": false, 214 | "condition": true, 215 | "conditionGroup": "" 216 | } 217 | ] 218 | }, 219 | "block": false, 220 | "danger": false, 221 | "ghost": false, 222 | "disabled": false 223 | }, 224 | "hidden": false, 225 | "title": "", 226 | "isLocked": false, 227 | "condition": true, 228 | "conditionGroup": "" 229 | }, 230 | { 231 | "componentName": "Button", 232 | "id": "node_ocl6n2awdi4", 233 | "props": { 234 | "type": "default", 235 | "children": "次按钮", 236 | "htmlType": "button", 237 | "size": "middle", 238 | "shape": "default", 239 | "icon": { 240 | "type": "JSSlot", 241 | "value": [ 242 | { 243 | "componentName": "Icon", 244 | "id": "node_ocl6n2awdi6", 245 | "props": { 246 | "type": "SmileOutlined", 247 | "size": 20, 248 | "rotate": 0, 249 | "spin": false 250 | }, 251 | "hidden": false, 252 | "title": "", 253 | "isLocked": false, 254 | "condition": true, 255 | "conditionGroup": "" 256 | } 257 | ] 258 | }, 259 | "block": false, 260 | "danger": false, 261 | "ghost": false, 262 | "disabled": false 263 | }, 264 | "hidden": false, 265 | "title": "", 266 | "isLocked": false, 267 | "condition": true, 268 | "conditionGroup": "" 269 | } 270 | ] 271 | }, 272 | { 273 | "componentName": "Page", 274 | "id": "node_dockcviv8fo1", 275 | "props": { 276 | "ref": "outerView", 277 | "style": { 278 | "height": "100%" 279 | } 280 | }, 281 | "fileName": "three", 282 | "dataSource": { 283 | "list": [ 284 | { 285 | "type": "fetch", 286 | "isInit": true, 287 | "options": { 288 | "params": {}, 289 | "method": "GET", 290 | "isCors": true, 291 | "timeout": 5000, 292 | "headers": {}, 293 | "uri": "mock/info.json" 294 | }, 295 | "id": "info", 296 | "shouldFetch": { 297 | "type": "JSFunction", 298 | "value": "function() { \n console.log('should fetch.....');\n return true; \n}" 299 | } 300 | } 301 | ] 302 | }, 303 | "state": { 304 | "text": { 305 | "type": "JSExpression", 306 | "value": "\"outer\"" 307 | }, 308 | "isShowDialog": { 309 | "type": "JSExpression", 310 | "value": "false" 311 | } 312 | }, 313 | "css": "body {\n font-size: 12px;\n}\n\n.button {\n width: 100px;\n color: #ff00ff\n}", 314 | "lifeCycles": { 315 | "componentDidMount": { 316 | "type": "JSFunction", 317 | "value": "function componentDidMount() {\n console.log('did mount');\n}" 318 | }, 319 | "componentWillUnmount": { 320 | "type": "JSFunction", 321 | "value": "function componentWillUnmount() {\n console.log('will unmount');\n}" 322 | } 323 | }, 324 | "methods": { 325 | "testFunc": { 326 | "type": "JSFunction", 327 | "value": "function testFunc() {\n console.log('test func');\n}" 328 | }, 329 | "onClick": { 330 | "type": "JSFunction", 331 | "value": "function onClick() {\n this.setState({\n isShowDialog: true\n });\n}" 332 | }, 333 | "closeDialog": { 334 | "type": "JSFunction", 335 | "value": "function closeDialog() {\n this.setState({\n isShowDialog: false\n });\n}" 336 | } 337 | }, 338 | "originCode": "class LowcodeComponent extends Component {\n state = {\n \"text\": \"outer\",\n \"isShowDialog\": false\n }\n componentDidMount() {\n console.log('did mount');\n }\n componentWillUnmount() {\n console.log('will unmount');\n }\n testFunc() {\n console.log('test func');\n }\n onClick() {\n this.setState({\n isShowDialog: true\n })\n }\n closeDialog() {\n this.setState({\n isShowDialog: false\n })\n }\n}", 339 | "hidden": false, 340 | "title": "", 341 | "isLocked": false, 342 | "condition": true, 343 | "conditionGroup": "", 344 | "children": [ 345 | { 346 | "componentName": "Button", 347 | "id": "node_ocl6n2awdi7", 348 | "props": { 349 | "type": "danger", 350 | "children": "危险按钮", 351 | "htmlType": "button", 352 | "size": "middle", 353 | "shape": "default", 354 | "icon": { 355 | "type": "JSSlot", 356 | "value": [ 357 | { 358 | "componentName": "Icon", 359 | "id": "node_ocl6n2awdi9", 360 | "props": { 361 | "type": "SmileOutlined", 362 | "size": 20, 363 | "rotate": 0, 364 | "spin": false 365 | }, 366 | "hidden": false, 367 | "title": "", 368 | "isLocked": false, 369 | "condition": true, 370 | "conditionGroup": "" 371 | } 372 | ] 373 | }, 374 | "block": false, 375 | "danger": false, 376 | "ghost": false, 377 | "disabled": false 378 | }, 379 | "hidden": false, 380 | "title": "", 381 | "isLocked": false, 382 | "condition": true, 383 | "conditionGroup": "" 384 | }, 385 | { 386 | "componentName": "Button", 387 | "id": "node_ocl6n2awdi4", 388 | "props": { 389 | "type": "default", 390 | "children": "次按钮", 391 | "htmlType": "button", 392 | "size": "middle", 393 | "shape": "default", 394 | "icon": { 395 | "type": "JSSlot", 396 | "value": [ 397 | { 398 | "componentName": "Icon", 399 | "id": "node_ocl6n2awdi6", 400 | "props": { 401 | "type": "SmileOutlined", 402 | "size": 20, 403 | "rotate": 0, 404 | "spin": false 405 | }, 406 | "hidden": false, 407 | "title": "", 408 | "isLocked": false, 409 | "condition": true, 410 | "conditionGroup": "" 411 | } 412 | ] 413 | }, 414 | "block": false, 415 | "danger": false, 416 | "ghost": false, 417 | "disabled": false 418 | }, 419 | "hidden": false, 420 | "title": "", 421 | "isLocked": false, 422 | "condition": true, 423 | "conditionGroup": "" 424 | }, 425 | { 426 | "componentName": "Button", 427 | "id": "node_ocl6n2awdi1", 428 | "props": { 429 | "type": "primary", 430 | "children": "主按钮", 431 | "htmlType": "button", 432 | "size": "middle", 433 | "shape": "default", 434 | "icon": { 435 | "type": "JSSlot", 436 | "value": [ 437 | { 438 | "componentName": "Icon", 439 | "id": "node_ocl6n2awdi3", 440 | "props": { 441 | "type": "SmileOutlined", 442 | "size": 20, 443 | "rotate": 0, 444 | "spin": false 445 | }, 446 | "hidden": false, 447 | "title": "", 448 | "isLocked": false, 449 | "condition": true, 450 | "conditionGroup": "" 451 | } 452 | ] 453 | }, 454 | "block": false, 455 | "danger": false, 456 | "ghost": false, 457 | "disabled": false 458 | }, 459 | "hidden": false, 460 | "title": "", 461 | "isLocked": false, 462 | "condition": true, 463 | "conditionGroup": "" 464 | } 465 | ] 466 | } 467 | ] --------------------------------------------------------------------------------