├── server ├── README.md ├── src │ ├── controller │ │ ├── public │ │ │ └── readme.md │ │ └── api │ │ │ ├── base.ts │ │ │ └── department.ts │ ├── library │ │ ├── event │ │ │ └── index.ts │ │ ├── email │ │ │ └── index.ts │ │ ├── utils │ │ │ └── modules │ │ │ │ └── network.ts │ │ └── mysql │ │ │ └── index.ts │ ├── public │ │ ├── favicon.ico │ │ └── index.html │ ├── config │ │ ├── superAdmin.ts │ │ ├── login.ts │ │ ├── _prod.ts │ │ ├── log.ts │ │ ├── env.ts │ │ ├── email.ts │ │ ├── redis.ts │ │ ├── mysql_env.ts │ │ ├── mysql.ts │ │ └── app.ts │ ├── model │ │ ├── validator.ts │ │ ├── base.ts │ │ └── department.ts │ ├── middleware │ │ ├── multi-form.ts │ │ ├── login.ts │ │ └── errorHandler.ts │ └── task.ts ├── typings.d.ts ├── .prettierrc └── copy_static_assets.js ├── plugin ├── src │ ├── components │ │ ├── Field │ │ │ ├── components │ │ │ │ ├── Alert │ │ │ │ │ ├── index.less │ │ │ │ │ ├── __editor__ │ │ │ │ │ │ ├── additableProperties.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── interface.d.ts │ │ │ │ │ ├── index.md │ │ │ │ │ └── demo │ │ │ │ │ │ └── basic.md │ │ │ │ ├── Steps │ │ │ │ │ ├── index.less │ │ │ │ │ ├── __editor__ │ │ │ │ │ │ ├── additableProperties.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── interface.d.ts │ │ │ │ │ ├── demo │ │ │ │ │ │ ├── basic.md │ │ │ │ │ │ └── description.md │ │ │ │ │ └── index.md │ │ │ │ ├── Input │ │ │ │ │ ├── index.tsx │ │ │ │ │ ├── __editor__ │ │ │ │ │ │ ├── additableProperties.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── properties.ts │ │ │ │ │ ├── demo │ │ │ │ │ │ └── basic.md │ │ │ │ │ └── index.md │ │ │ │ ├── Text │ │ │ │ │ ├── index.less │ │ │ │ │ ├── __editor__ │ │ │ │ │ │ ├── additableProperties.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── properties.ts │ │ │ │ │ ├── interface.d.ts │ │ │ │ │ └── index.md │ │ │ │ ├── InputNumber │ │ │ │ │ ├── index.tsx │ │ │ │ │ ├── __editor__ │ │ │ │ │ │ ├── additableProperties.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── properties.ts │ │ │ │ │ ├── demo │ │ │ │ │ │ └── basic.md │ │ │ │ │ └── index.md │ │ │ │ ├── Checkbox │ │ │ │ │ ├── ModalAddOption │ │ │ │ │ │ ├── index.less │ │ │ │ │ │ └── interface.d.ts │ │ │ │ │ ├── __editor__ │ │ │ │ │ │ ├── additableProperties.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── interface.d.ts │ │ │ │ ├── JsonEditor │ │ │ │ │ ├── index.less │ │ │ │ │ ├── __editor__ │ │ │ │ │ │ ├── additableProperties.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── properties.ts │ │ │ │ │ ├── interface.d.ts │ │ │ │ │ └── index.md │ │ │ │ ├── PickerDate │ │ │ │ │ ├── index.less │ │ │ │ │ ├── __editor__ │ │ │ │ │ │ ├── additableProperties.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── interface.d.ts │ │ │ │ ├── Divider │ │ │ │ │ ├── __editor__ │ │ │ │ │ │ ├── additableProperties.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── properties.ts │ │ │ │ │ ├── interface.d.ts │ │ │ │ │ ├── index.md │ │ │ │ │ ├── index.tsx │ │ │ │ │ ├── demo │ │ │ │ │ │ └── basic.md │ │ │ │ │ └── __tests__ │ │ │ │ │ │ └── index.test.tsx │ │ │ │ ├── Radio │ │ │ │ │ ├── __editor__ │ │ │ │ │ │ ├── additableProperties.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── interface.d.ts │ │ │ │ │ └── demo │ │ │ │ │ │ └── basic.md │ │ │ │ ├── Select │ │ │ │ │ ├── __editor__ │ │ │ │ │ │ ├── additableProperties.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── interface.d.ts │ │ │ │ ├── Upload │ │ │ │ │ ├── __editor__ │ │ │ │ │ │ ├── additableProperties.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── index.less │ │ │ │ │ └── utils.ts │ │ │ │ ├── PickerMonth │ │ │ │ │ ├── __editor__ │ │ │ │ │ │ ├── additableProperties.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── interface.d.ts │ │ │ │ ├── PickerRange │ │ │ │ │ ├── __editor__ │ │ │ │ │ │ ├── additableProperties.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── interface.d.ts │ │ │ │ ├── PickerTime │ │ │ │ │ ├── __editor__ │ │ │ │ │ │ ├── additableProperties.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── interface.d.ts │ │ │ │ ├── PickerWeek │ │ │ │ │ ├── __editor__ │ │ │ │ │ │ ├── additableProperties.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── interface.d.ts │ │ │ │ ├── SelectTree │ │ │ │ │ └── __editor__ │ │ │ │ │ │ ├── additableProperties.ts │ │ │ │ │ │ └── index.ts │ │ │ │ ├── SelectTrees │ │ │ │ │ └── __editor__ │ │ │ │ │ │ ├── additableProperties.ts │ │ │ │ │ │ └── index.ts │ │ │ │ ├── TableEditor │ │ │ │ │ ├── __editor__ │ │ │ │ │ │ ├── additableProperties.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── index.less │ │ │ │ ├── InputPassword │ │ │ │ │ └── __editor__ │ │ │ │ │ │ ├── additableProperties.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── properties.ts │ │ │ │ ├── InputTextarea │ │ │ │ │ └── __editor__ │ │ │ │ │ │ ├── additableProperties.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── properties.ts │ │ │ │ ├── PickerDateTime │ │ │ │ │ ├── __editor__ │ │ │ │ │ │ ├── additableProperties.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── index.tsx │ │ │ │ ├── SelectCascade │ │ │ │ │ ├── __editor__ │ │ │ │ │ │ ├── additableProperties.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── interface.d.ts │ │ │ │ ├── SelectMultiple │ │ │ │ │ ├── __editor__ │ │ │ │ │ │ ├── additableProperties.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── demo │ │ │ │ │ │ └── basic.md │ │ │ │ └── _EditableTable │ │ │ │ │ ├── context.ts │ │ │ │ │ ├── EditableCell │ │ │ │ │ └── interface.d.ts │ │ │ │ │ └── interface.ts │ │ │ ├── index.less │ │ │ ├── interface.d.ts │ │ │ ├── types │ │ │ │ └── baseProperty.ts │ │ │ └── rules.ts │ │ ├── Card │ │ │ ├── index.less │ │ │ ├── __editor__ │ │ │ │ ├── defaultConfig.ts │ │ │ │ ├── index.ts │ │ │ │ └── properties.ts │ │ │ ├── components │ │ │ │ └── Primary │ │ │ │ │ ├── interface.d.ts │ │ │ │ │ └── index.tsx │ │ │ ├── _index.md_ │ │ │ └── interface.d.ts │ │ ├── ModalForm │ │ │ ├── index.less │ │ │ ├── __editor__ │ │ │ │ ├── index.ts │ │ │ │ ├── additableProperties.ts │ │ │ │ └── defaultConfig.ts │ │ │ ├── demo │ │ │ │ └── basic.md │ │ │ └── interface.d.ts │ │ ├── BChart │ │ │ ├── index.less │ │ │ ├── __editor__ │ │ │ │ ├── additableProperties.ts │ │ │ │ ├── properties.ts │ │ │ │ └── index.ts │ │ │ ├── ChartPie │ │ │ │ └── index.md │ │ │ ├── ChartBar │ │ │ │ └── index.md │ │ │ ├── ChartLine │ │ │ │ └── index.md │ │ │ └── shapes.ts │ │ ├── Button │ │ │ ├── __editor__ │ │ │ │ ├── additableProperties.ts │ │ │ │ ├── defaultConfig.ts │ │ │ │ └── index.ts │ │ │ ├── interface.d.ts │ │ │ └── index.md │ │ ├── Divider │ │ │ ├── __editor__ │ │ │ │ ├── additableProperties.ts │ │ │ │ ├── defaultConfig.ts │ │ │ │ ├── index.ts │ │ │ │ └── properties.ts │ │ │ ├── interface.d.ts │ │ │ ├── index.md │ │ │ ├── demo │ │ │ │ └── basic.md │ │ │ ├── index.tsx │ │ │ └── __tests__ │ │ │ │ └── index.test.tsx │ │ ├── Container │ │ │ ├── interface.d.ts │ │ │ ├── index.tsx │ │ │ └── __editor__ │ │ │ │ ├── defaultConfig.ts │ │ │ │ ├── properties.ts │ │ │ │ └── index.ts │ │ ├── List │ │ │ ├── components │ │ │ │ ├── Column │ │ │ │ │ └── __editor__ │ │ │ │ │ │ ├── additableProperties.ts │ │ │ │ │ │ └── index.ts │ │ │ │ ├── ActionColumn │ │ │ │ │ └── __editor__ │ │ │ │ │ │ ├── additableProperties.ts │ │ │ │ │ │ └── index.ts │ │ │ │ └── ActionColumn2 │ │ │ │ │ └── __editor__ │ │ │ │ │ ├── additableProperties.ts │ │ │ │ │ └── index.ts │ │ │ ├── index.less │ │ │ ├── __editor__ │ │ │ │ ├── index.ts │ │ │ │ ├── additableProperties │ │ │ │ │ ├── extra │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── default_value.ts │ │ │ │ │ ├── sections │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── columns │ │ │ │ │ │ └── index.ts │ │ │ │ └── defaultConfig.ts │ │ │ └── interface.d.ts │ │ ├── Exception │ │ │ ├── 403.tsx │ │ │ ├── 404.tsx │ │ │ ├── 500.tsx │ │ │ ├── interface.d.ts │ │ │ └── typeConfig.ts │ │ ├── Form │ │ │ ├── index.less │ │ │ ├── __editor__ │ │ │ │ ├── index.ts │ │ │ │ └── additableProperties │ │ │ │ │ ├── extra │ │ │ │ │ ├── index.ts │ │ │ │ │ └── default_value.ts │ │ │ │ │ └── index.ts │ │ │ └── demo │ │ │ │ ├── buttons.md │ │ │ │ ├── alias.md │ │ │ │ ├── edit.md │ │ │ │ └── transform.md │ │ ├── Steps │ │ │ ├── index.less │ │ │ ├── __editor__ │ │ │ │ ├── index.ts │ │ │ │ └── defaultConfig.ts │ │ │ ├── interface.d.ts │ │ │ ├── index._md │ │ │ └── demo │ │ │ │ ├── container.md │ │ │ │ └── basic.md │ │ ├── Tabs │ │ │ ├── __editor__ │ │ │ │ └── index.ts │ │ │ ├── interface.d.ts │ │ │ └── index.md │ │ └── HtmlFragment │ │ │ └── index.tsx │ ├── utils │ │ ├── events.ts │ │ └── __tests__ │ │ │ ├── valid.test.ts │ │ │ └── event.test.ts │ ├── templates │ │ └── custom │ │ │ └── empty.ts │ ├── types │ │ └── index.d.ts │ └── index.ts ├── site │ ├── theme │ │ ├── style │ │ │ ├── index.jsx │ │ │ ├── themes │ │ │ │ └── index.less │ │ │ ├── v2-compatible-reset.jsx │ │ │ ├── index.less │ │ │ ├── core │ │ │ │ ├── index.less │ │ │ │ ├── iconfont.less │ │ │ │ ├── motion │ │ │ │ │ ├── fade.less │ │ │ │ │ └── swing.less │ │ │ │ └── motion.less │ │ │ ├── mixins │ │ │ │ ├── size.less │ │ │ │ ├── clearfix.less │ │ │ │ ├── index.less │ │ │ │ ├── reset.less │ │ │ │ ├── operation-unit.less │ │ │ │ └── compatibility.less │ │ │ └── v2-compatible-reset.less │ │ ├── static │ │ │ ├── favicon.ico │ │ │ ├── style.js │ │ │ ├── theme.less │ │ │ ├── nprogress.less │ │ │ ├── docsearch.less │ │ │ ├── new-version-info-modal.less │ │ │ ├── index.less │ │ │ ├── not-found.less │ │ │ └── motion.less │ │ └── template │ │ │ ├── BrowserFrame.jsx │ │ │ ├── AppShell.jsx │ │ │ ├── Color │ │ │ ├── ColorPatterns.jsx │ │ │ └── ColorBlock.jsx │ │ │ ├── FormattedMessage │ │ │ └── index.jsx │ │ │ ├── Content │ │ │ ├── PrevAndNext.jsx │ │ │ ├── ErrorBoundary.js │ │ │ └── EditButton.jsx │ │ │ ├── Redirect.jsx │ │ │ ├── Layout │ │ │ └── SentryBoundary.jsx │ │ │ ├── NotFound.jsx │ │ │ ├── Home │ │ │ └── util.jsx │ │ │ └── IconDisplay │ │ │ └── CopyableIcon.jsx │ ├── utils │ │ └── index.js │ ├── favicon.ico │ ├── docs │ │ └── editor │ │ │ ├── _04-json-actions.md_ │ │ │ ├── changeLog.md │ │ │ ├── 03-page-publish.md │ │ │ ├── 02-scenarios.md │ │ │ ├── 03-page-debug.md │ │ │ ├── 06-senior-formdata.md │ │ │ ├── 03-page-build.md │ │ │ ├── 05-json-syntax.md │ │ │ ├── 03-project-whitelist.md │ │ │ └── 01-introduce.md │ ├── hetu.ts │ └── template.html ├── __mocks__ │ ├── axios.ts │ └── moment.ts ├── gulpfile.js │ ├── index.js │ ├── copy-types.js │ └── copy-docs.js ├── test │ ├── utils │ │ └── index.ts │ └── setup.ts ├── .eslintignore ├── .gitignore ├── .babelrc └── README.md ├── client ├── src │ ├── routes │ │ ├── Admin │ │ │ ├── Login │ │ │ │ └── index.less │ │ │ ├── Register │ │ │ │ └── index.less │ │ │ ├── ModifyPassword │ │ │ │ └── index.less │ │ │ ├── Layout │ │ │ │ ├── index.less │ │ │ │ └── index.tsx │ │ │ └── Card │ │ │ │ ├── index.tsx │ │ │ │ └── index.less │ │ ├── GuiEditor │ │ │ ├── components │ │ │ │ ├── Header │ │ │ │ │ ├── ThePublishModal │ │ │ │ │ │ ├── index.module.less │ │ │ │ │ │ └── interface.d.ts │ │ │ │ │ └── interface.d.ts │ │ │ │ ├── SiderRight │ │ │ │ │ ├── FormEditor │ │ │ │ │ │ ├── compontent │ │ │ │ │ │ │ ├── readme.md │ │ │ │ │ │ │ ├── FormItem │ │ │ │ │ │ │ │ └── index.less │ │ │ │ │ │ │ └── input │ │ │ │ │ │ │ │ └── index.less │ │ │ │ │ │ └── interface.d.ts │ │ │ │ │ ├── JSONEditor │ │ │ │ │ │ ├── index.module.less │ │ │ │ │ │ └── interface.d.ts │ │ │ │ │ ├── interface.ts │ │ │ │ │ └── index.module.less │ │ │ │ ├── Content │ │ │ │ │ ├── index.less │ │ │ │ │ └── interface.d.ts │ │ │ │ ├── Stage │ │ │ │ │ ├── index.module.less │ │ │ │ │ ├── interface.d.ts │ │ │ │ │ ├── HoverOverlay │ │ │ │ │ │ ├── DropTargetWrapper │ │ │ │ │ │ │ └── interface.d.ts │ │ │ │ │ │ ├── index.module.less │ │ │ │ │ │ └── interface.d.ts │ │ │ │ │ └── SelectedOverlay │ │ │ │ │ │ └── interface.d.ts │ │ │ │ └── SiderLeft │ │ │ │ │ └── interface.d.ts │ │ │ ├── interface.ts │ │ │ └── index.less │ │ ├── Home │ │ │ ├── Layout │ │ │ │ ├── index.ts │ │ │ │ ├── Blank │ │ │ │ │ └── index.tsx │ │ │ │ └── Basic │ │ │ │ │ ├── Header │ │ │ │ │ └── interface.d.ts │ │ │ │ │ ├── index.module.less │ │ │ │ │ ├── interface.d.ts │ │ │ │ │ └── SiderMenu │ │ │ │ │ └── interface.d.ts │ │ │ ├── ModalClone │ │ │ │ └── interface.d.ts │ │ │ ├── interface.d.ts │ │ │ └── index.less │ │ ├── Exception │ │ │ ├── 403.tsx │ │ │ ├── 404.tsx │ │ │ └── 500.tsx │ │ ├── Preview │ │ │ └── index.tsx │ │ └── Templates │ │ │ ├── index.less │ │ │ ├── interface.d.ts │ │ │ └── components │ │ │ └── Card │ │ │ └── interface.d.ts │ ├── utils │ │ ├── events.ts │ │ ├── apis.ts │ │ └── valid.ts │ ├── favicon.ico │ ├── assets │ │ ├── ke.ico │ │ ├── head.png │ │ ├── logo.png │ │ └── button-add.png │ ├── components │ │ ├── Iframe │ │ │ ├── index.less │ │ │ └── interface.d.ts │ │ ├── JsonEditor │ │ │ ├── index.less │ │ │ ├── interface.d.ts │ │ │ └── Controled.d.ts │ │ ├── Exception │ │ │ ├── 404.tsx │ │ │ ├── 500.tsx │ │ │ ├── 403.tsx │ │ │ └── typeConfig.ts │ │ ├── _utils │ │ │ └── pathTools.ts │ │ └── HtmlFragment │ │ │ └── index.tsx │ ├── constant │ │ ├── state.ts │ │ ├── submodule.ts │ │ └── env.ts │ ├── apis │ │ ├── index.ts │ │ └── user.ts │ └── types │ │ ├── components │ │ ├── interfaceBaseCompontentProps.ts │ │ └── editConfig.ts │ │ └── models │ │ ├── connect.d.ts │ │ └── guiEditor.d.ts ├── public │ ├── favicon.ico │ └── index.html ├── .prettierrc ├── .eslintrc ├── jsconfig.json ├── scripts │ └── utils.js ├── tsconfig.json ├── .jest.js ├── config │ └── setupProxy.js ├── .babelrc ├── README.md └── typings.d.ts ├── .prettierrc ├── CHANGELOG.md ├── scripts ├── online_client.sh ├── online_plugin.sh ├── util.sh ├── online_server.sh └── online_docs.sh └── .gitignore /server/README.md: -------------------------------------------------------------------------------- 1 | # node 2 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Alert/index.less: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Steps/index.less: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /server/src/controller/public/readme.md: -------------------------------------------------------------------------------- 1 | ## 供第三方使用的接口 2 | -------------------------------------------------------------------------------- /server/typings.d.ts: -------------------------------------------------------------------------------- 1 | declare module '@adonisjs/ace' 2 | -------------------------------------------------------------------------------- /plugin/site/theme/style/index.jsx: -------------------------------------------------------------------------------- 1 | import './index.less'; 2 | -------------------------------------------------------------------------------- /client/src/routes/Admin/Login/index.less: -------------------------------------------------------------------------------- 1 | .login-container {} 2 | -------------------------------------------------------------------------------- /client/src/routes/Admin/Register/index.less: -------------------------------------------------------------------------------- 1 | .register-container {} 2 | -------------------------------------------------------------------------------- /plugin/site/theme/style/themes/index.less: -------------------------------------------------------------------------------- 1 | @import './default.less'; 2 | -------------------------------------------------------------------------------- /client/src/routes/Admin/ModifyPassword/index.less: -------------------------------------------------------------------------------- 1 | .modify-password-container {} 2 | -------------------------------------------------------------------------------- /client/src/routes/GuiEditor/components/Header/ThePublishModal/index.module.less: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /plugin/site/utils/index.js: -------------------------------------------------------------------------------- 1 | export const FormattedMessage = () => { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /plugin/site/theme/style/v2-compatible-reset.jsx: -------------------------------------------------------------------------------- 1 | import './v2-compatible-reset.less'; 2 | -------------------------------------------------------------------------------- /client/src/utils/events.ts: -------------------------------------------------------------------------------- 1 | import mitt from 'mitt' 2 | 3 | export const emitter = mitt() 4 | -------------------------------------------------------------------------------- /plugin/site/theme/style/index.less: -------------------------------------------------------------------------------- 1 | @import './themes/index'; 2 | @import './core/index'; 3 | -------------------------------------------------------------------------------- /server/src/library/event/index.ts: -------------------------------------------------------------------------------- 1 | import mitt from 'mitt' 2 | 3 | export default mitt() 4 | -------------------------------------------------------------------------------- /client/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LianjiaTech/hetu/HEAD/client/src/favicon.ico -------------------------------------------------------------------------------- /plugin/site/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LianjiaTech/hetu/HEAD/plugin/site/favicon.ico -------------------------------------------------------------------------------- /client/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LianjiaTech/hetu/HEAD/client/public/favicon.ico -------------------------------------------------------------------------------- /client/src/assets/ke.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LianjiaTech/hetu/HEAD/client/src/assets/ke.ico -------------------------------------------------------------------------------- /client/src/routes/GuiEditor/components/SiderRight/FormEditor/compontent/readme.md: -------------------------------------------------------------------------------- 1 | 该文件夹中存放为可视化编辑器专门订制的组件 -------------------------------------------------------------------------------- /plugin/__mocks__/axios.ts: -------------------------------------------------------------------------------- 1 | import mockAxios from 'jest-mock-axios' 2 | 3 | export default mockAxios 4 | -------------------------------------------------------------------------------- /client/src/assets/head.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LianjiaTech/hetu/HEAD/client/src/assets/head.png -------------------------------------------------------------------------------- /client/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LianjiaTech/hetu/HEAD/client/src/assets/logo.png -------------------------------------------------------------------------------- /server/src/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LianjiaTech/hetu/HEAD/server/src/public/favicon.ico -------------------------------------------------------------------------------- /client/src/assets/button-add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LianjiaTech/hetu/HEAD/client/src/assets/button-add.png -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Input/index.tsx: -------------------------------------------------------------------------------- 1 | import { Input } from 'antd' 2 | 3 | export default Input 4 | -------------------------------------------------------------------------------- /plugin/src/components/Card/index.less: -------------------------------------------------------------------------------- 1 | .ht-card-extra-button + .ht-card-extra-button { 2 | margin-left: 8px; 3 | } 4 | -------------------------------------------------------------------------------- /plugin/src/components/ModalForm/index.less: -------------------------------------------------------------------------------- 1 | .ht-modal-trigger-btn+.ht-modal-trigger-btn { 2 | margin-left: 8px; 3 | } 4 | -------------------------------------------------------------------------------- /plugin/site/theme/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LianjiaTech/hetu/HEAD/plugin/site/theme/static/favicon.ico -------------------------------------------------------------------------------- /client/src/routes/Home/Layout/index.ts: -------------------------------------------------------------------------------- 1 | export { default as Basic } from './Basic' 2 | export { default as Blank } from './Blank' 3 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Text/index.less: -------------------------------------------------------------------------------- 1 | .ht-text-jsonEditor { 2 | border: none; 3 | padding: 10px 2px; 4 | } 5 | -------------------------------------------------------------------------------- /plugin/site/theme/style/core/index.less: -------------------------------------------------------------------------------- 1 | @import '../mixins/index'; 2 | @import 'base'; 3 | @import 'iconfont'; 4 | @import 'motion'; 5 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/InputNumber/index.tsx: -------------------------------------------------------------------------------- 1 | import { InputNumber } from 'antd' 2 | 3 | export default InputNumber 4 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 240, 3 | "tabWidth": 2, 4 | "semi": false, 5 | "singleQuote": true, 6 | "trailingComma": "all" 7 | } 8 | -------------------------------------------------------------------------------- /plugin/src/components/BChart/index.less: -------------------------------------------------------------------------------- 1 | .ht-bchart-title { 2 | font-size: 16px; 3 | letter-spacing: 5px; 4 | text-align: center; 5 | } 6 | -------------------------------------------------------------------------------- /client/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 240, 3 | "tabWidth": 2, 4 | "semi": false, 5 | "singleQuote": true, 6 | "trailingComma": "all" 7 | } 8 | -------------------------------------------------------------------------------- /plugin/src/utils/events.ts: -------------------------------------------------------------------------------- 1 | import mitt from 'mitt' 2 | 3 | export let EventHandlerMap = {} 4 | 5 | export const emitter = mitt(EventHandlerMap) 6 | -------------------------------------------------------------------------------- /server/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120, 3 | "tabWidth": 2, 4 | "semi": false, 5 | "singleQuote": true, 6 | "trailingComma": "all" 7 | } 8 | -------------------------------------------------------------------------------- /client/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "parserOptions": { 4 | "ecmaFeatures": { 5 | "legacyDecorators": true 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /client/src/components/Iframe/index.less: -------------------------------------------------------------------------------- 1 | .base-iframe { 2 | display: block; 3 | width: 100%; 4 | height: 100%; 5 | overflow: hidden; 6 | border: 0; 7 | } 8 | -------------------------------------------------------------------------------- /plugin/site/docs/editor/_04-json-actions.md_: -------------------------------------------------------------------------------- 1 | --- 2 | category: 底层概念 3 | order: 3 4 | title: actions 5 | subtitle: actions 6 | --- 7 | 8 | ...待完善 9 | 10 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Checkbox/ModalAddOption/index.less: -------------------------------------------------------------------------------- 1 | .ht-add-option-modal { 2 | .ht-form-container { 3 | margin-top: 12px; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /plugin/site/theme/static/style.js: -------------------------------------------------------------------------------- 1 | import 'rc-drawer/assets/index.css' 2 | import 'docsearch.js/dist/cdn/docsearch.css' 3 | import './index.less' 4 | import 'hetu.css' 5 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/JsonEditor/index.less: -------------------------------------------------------------------------------- 1 | .ht-json-editor { 2 | padding: 10px 2px; 3 | border: 1px solid #d9d9d9; 4 | border-radius: 4px; 5 | } 6 | -------------------------------------------------------------------------------- /server/src/controller/api/base.ts: -------------------------------------------------------------------------------- 1 | import Base from '~/src/controller/proxy/base' 2 | 3 | class BaseController extends Base {} 4 | 5 | export default BaseController 6 | -------------------------------------------------------------------------------- /client/src/components/JsonEditor/index.less: -------------------------------------------------------------------------------- 1 | .ht-json-editor { 2 | padding: 10px 2px; 3 | border: 1px solid #d9d9d9; 4 | border-radius: 4px; 5 | height: 100%; 6 | } 7 | -------------------------------------------------------------------------------- /plugin/site/theme/template/BrowserFrame.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default ({ children }) =>
{children}
; 4 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/PickerDate/index.less: -------------------------------------------------------------------------------- 1 | .ht-calendar-picker, 2 | .ht-time-picker { 3 | width: 100% !important; 4 | min-width: auto !important; 5 | } 6 | -------------------------------------------------------------------------------- /plugin/site/theme/static/theme.less: -------------------------------------------------------------------------------- 1 | @site-heading-color: #0d1a26; 2 | @site-text-color: #314659; 3 | @site-text-color-secondary: #697b8c; 4 | @site-border-color-split: #ebedf0; 5 | -------------------------------------------------------------------------------- /plugin/src/components/BChart/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /plugin/src/components/Button/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /plugin/src/components/Divider/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /plugin/__mocks__/moment.ts: -------------------------------------------------------------------------------- 1 | const moment = jest.requireActual('moment') 2 | 3 | moment.prototype.valueOf = jest.fn().mockImplementation(() => 1578278494065) 4 | 5 | export default moment 6 | -------------------------------------------------------------------------------- /plugin/src/components/Card/__editor__/defaultConfig.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | type: 'HtCard', 3 | props: { 4 | title: '页面标题', 5 | extra: [], 6 | }, 7 | children: [], 8 | } 9 | -------------------------------------------------------------------------------- /plugin/src/components/Container/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { BaseProps, JsonSchema } from '~/types' 2 | 3 | export interface Container extends BaseProps { 4 | style: JsonSchema.DynamicObject 5 | } 6 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Alert/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Divider/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Input/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/InputNumber/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | const config: Editor.AdditableProperties = {} 3 | 4 | export default config 5 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Radio/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Select/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Steps/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Text/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Upload/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /plugin/src/components/List/components/Column/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /client/src/routes/GuiEditor/components/Content/index.less: -------------------------------------------------------------------------------- 1 | .the-gui-content { 2 | position: relative; 3 | width: 100%; 4 | height: 100%; 5 | overflow: hidden; 6 | background-color: #fff; 7 | } 8 | -------------------------------------------------------------------------------- /plugin/gulpfile.js/index.js: -------------------------------------------------------------------------------- 1 | const copyTypes = require('./copy-types').default 2 | const copyDocs = require('./copy-docs').default 3 | 4 | exports.copyTypes = copyTypes 5 | exports.copyDocs = copyDocs 6 | -------------------------------------------------------------------------------- /plugin/src/components/Container/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default (props: any) => { 4 | const { children, ...rest } = props 5 | return
{children}
6 | } 7 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Checkbox/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/JsonEditor/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/PickerDate/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/PickerMonth/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/PickerRange/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/PickerTime/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/PickerWeek/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/SelectTree/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/SelectTrees/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/TableEditor/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /plugin/src/components/List/components/ActionColumn/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /plugin/src/components/List/components/ActionColumn2/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /client/src/components/Exception/404.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Exception from './' 3 | 4 | export default () => ( 5 | 6 | ) 7 | -------------------------------------------------------------------------------- /plugin/gulpfile.js/copy-types.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp') 2 | 3 | function copyTypes(cb) { 4 | gulp.src('src/**/*.d.ts').pipe(gulp.dest('dist')) 5 | cb() 6 | } 7 | 8 | exports.default = copyTypes 9 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/InputPassword/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/InputTextarea/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/PickerDateTime/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/SelectCascade/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/SelectMultiple/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.AdditableProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /client/src/constant/state.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 导出State中会用到的常量 3 | */ 4 | class State { 5 | static InsertItemAt_Before = 'before' 6 | static InsertItemAt_After = 'after' 7 | } 8 | 9 | export default State 10 | -------------------------------------------------------------------------------- /plugin/site/theme/style/mixins/size.less: -------------------------------------------------------------------------------- 1 | // Sizing shortcuts 2 | 3 | .size(@width; @height) { 4 | width: @width; 5 | height: @height; 6 | } 7 | 8 | .square(@size) { 9 | .size(@size; @size); 10 | } 11 | -------------------------------------------------------------------------------- /plugin/src/components/BChart/__editor__/properties.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-template-curly-in-string */ 2 | import { Editor } from '~/types' 3 | let config: Editor.BaseProperties = {} 4 | 5 | export default config 6 | -------------------------------------------------------------------------------- /plugin/test/utils/index.ts: -------------------------------------------------------------------------------- 1 | export function sleep(timeout?: number) { 2 | jest.useRealTimers() 3 | return new Promise(resolve => { 4 | setTimeout(() => { 5 | resolve() 6 | }, timeout) 7 | }) 8 | } 9 | -------------------------------------------------------------------------------- /server/src/config/superAdmin.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 超级管理员项目配置 3 | */ 4 | 5 | export default { 6 | // 唯一标志 7 | projectCode: 'admin', 8 | name: '河图管理后台', 9 | description: "河图超级管理员", 10 | home: '/', 11 | } 12 | -------------------------------------------------------------------------------- /client/src/routes/Exception/403.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Exception from '~/components/Exception' 3 | 4 | export default () => ( 5 | 6 | ) 7 | -------------------------------------------------------------------------------- /client/src/routes/Exception/404.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Exception from '~/components/Exception' 3 | 4 | export default () => ( 5 | 6 | ) 7 | -------------------------------------------------------------------------------- /client/src/routes/Exception/500.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Exception from '~/components/Exception' 3 | 4 | export default () => ( 5 | 6 | ) 7 | -------------------------------------------------------------------------------- /plugin/src/components/Container/__editor__/defaultConfig.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | type: 'HtGuiContainer', 3 | props: { 4 | style: { 5 | padding: '8px', 6 | }, 7 | }, 8 | children: [], 9 | } 10 | -------------------------------------------------------------------------------- /plugin/src/components/Divider/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { DividerProps } from 'antd/lib/divider' 2 | import { BaseProps } from '~/types' 3 | 4 | export interface Props extends BaseProps, DividerProps { 5 | title: string 6 | } 7 | -------------------------------------------------------------------------------- /plugin/.eslintignore: -------------------------------------------------------------------------------- 1 | // .eslintignore 此文件是告诉eslint忽略哪些文件的 2 | build/** 3 | config/** 4 | public/** 5 | scripts/** 6 | .eslintrc.js 7 | jest.config.js 8 | tsdx.config.js 9 | gulpfile.js/** 10 | site/** 11 | .vscode/** 12 | -------------------------------------------------------------------------------- /plugin/src/components/Card/components/Primary/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { BaseProps } from '~/types' 2 | 3 | export interface Props extends BaseProps { 4 | title: string 5 | subtitle: string 6 | extra?: React.ReactNode[] 7 | } 8 | -------------------------------------------------------------------------------- /plugin/src/components/Exception/403.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Exception from '~/components/Exception' 3 | 4 | export default () => ( 5 | 6 | ) 7 | -------------------------------------------------------------------------------- /plugin/src/components/Exception/404.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Exception from '~/components/Exception' 3 | 4 | export default () => ( 5 | 6 | ) 7 | -------------------------------------------------------------------------------- /plugin/src/components/Exception/500.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Exception from '~/components/Exception' 3 | 4 | export default () => ( 5 | 6 | ) 7 | -------------------------------------------------------------------------------- /client/src/components/Exception/500.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Exception from './' 3 | 4 | export default () => ( 5 | 9 | ) 10 | -------------------------------------------------------------------------------- /client/src/utils/apis.ts: -------------------------------------------------------------------------------- 1 | export function transformPath(path: string) { 2 | if (window.__POWERED_BY_QIANKUN__) { 3 | let map = store.get('hetu-pageconfigs-map') 4 | path = _.get(map, path, path) 5 | } 6 | return path 7 | } 8 | -------------------------------------------------------------------------------- /plugin/site/theme/template/AppShell.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Empty component for app shell 3 | * See https://github.com/NekR/offline-plugin/blob/master/docs/app-shell.md 4 | */ 5 | import React from 'react'; 6 | 7 | export default () =>
; 8 | -------------------------------------------------------------------------------- /client/src/apis/index.ts: -------------------------------------------------------------------------------- 1 | import Admin from './admin' 2 | import Page from './page' 3 | import Project from './project' 4 | import User from './user' 5 | 6 | export default { 7 | Admin, 8 | Page, 9 | Project, 10 | User, 11 | } 12 | -------------------------------------------------------------------------------- /plugin/src/components/Divider/__editor__/defaultConfig.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | type: 'HtDivider', 3 | props: { 4 | type: 'horizontal', 5 | title: '分割线', 6 | orientation: 'center', 7 | }, 8 | children: [], 9 | } 10 | -------------------------------------------------------------------------------- /plugin/src/components/Divider/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | category: Components 3 | type: 布局 4 | title: Divider 5 | subtitle: 分割线 6 | cols: 1 7 | --- 8 | 9 | 区隔内容的分割线。 10 | 11 | ## 何时使用 12 | 13 | - 对不同章节的文本段落进行分割。 14 | - 对行内文字/链接进行分割,例如表格的操作列。 15 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Divider/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { DividerProps } from 'antd/lib/divider' 2 | import { BaseProps } from '~/types' 3 | 4 | export interface Props extends BaseProps, DividerProps { 5 | title: string 6 | } 7 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Text/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { BaseProps } from '~/types' 2 | 3 | export interface Props extends BaseProps { 4 | value: any 5 | defaultValue: any 6 | jsonFormat?: boolean 7 | isWrap?: boolean 8 | } 9 | -------------------------------------------------------------------------------- /plugin/src/components/Form/index.less: -------------------------------------------------------------------------------- 1 | .ht-form-container { 2 | padding: 16px; 3 | 4 | .ht-form-btn+.ht-form-btn { 5 | margin-left: 12px; 6 | } 7 | 8 | .ht-form-item-no-colon::after { 9 | content: " "; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /client/src/components/Iframe/interface.d.ts: -------------------------------------------------------------------------------- 1 | export interface Props { 2 | src: string 3 | onLoad: (event: React.SyntheticEvent) => void 4 | getRef: (v: any) => void 5 | onKeydown: (e: KeyboardEvent) => void 6 | } 7 | -------------------------------------------------------------------------------- /plugin/src/components/Button/__editor__/defaultConfig.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | type: 'HtButton', 3 | props: { 4 | type: 'link', 5 | text: '跳转页面', 6 | href: '/', 7 | useH5Href: false, 8 | }, 9 | children: [], 10 | } 11 | -------------------------------------------------------------------------------- /plugin/src/components/List/index.less: -------------------------------------------------------------------------------- 1 | .ht-list-container { 2 | position: relative; 3 | padding: 16px; 4 | 5 | .ht-form-container { 6 | padding: 0; 7 | 8 | .ht-form-item { 9 | margin-bottom: 10px 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /client/src/routes/GuiEditor/components/SiderRight/FormEditor/compontent/FormItem/index.less: -------------------------------------------------------------------------------- 1 | .the-gui-form-item { 2 | .the-context-menu { 3 | background-color: #fff; 4 | } 5 | 6 | .the-menu-item { 7 | cursor: pointer; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /client/src/routes/GuiEditor/components/SiderRight/JSONEditor/index.module.less: -------------------------------------------------------------------------------- 1 | .the-guiEditor-wrap { 2 | flex: 1; 3 | overflow: auto; 4 | } 5 | 6 | .the-guiEditor { 7 | padding-top: 0; 8 | font-size: 15px; 9 | overflow-y: auto; 10 | } 11 | -------------------------------------------------------------------------------- /client/src/routes/GuiEditor/components/Stage/index.module.less: -------------------------------------------------------------------------------- 1 | .the-stage-wrap { 2 | position: absolute; 3 | top: 0; 4 | left: 0; 5 | right: 0; 6 | height: 100%; 7 | cursor: pointer; 8 | background-color: rgba(0, 0, 0, 0.05); 9 | } 10 | -------------------------------------------------------------------------------- /plugin/src/components/Field/index.less: -------------------------------------------------------------------------------- 1 | .field_pure_text { 2 | b { 3 | display: inline-block; 4 | width: 200px; 5 | text-align: right; 6 | font-weight: normal; 7 | margin-right: 12px; 8 | margin-bottom: 10px; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/PickerTime/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { BaseProps } from '~/types' 2 | 3 | export interface HtTimePickerProps extends BaseProps { 4 | value: string 5 | defaultValue?: string 6 | onChange: (v: string) => void 7 | format?: string 8 | } 9 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/PickerWeek/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { BaseProps } from '~/types' 2 | 3 | export interface HtWeekPickerProps extends BaseProps { 4 | value: string 5 | defaultValue?: string 6 | onChange: (v: string) => void 7 | format?: string 8 | } 9 | -------------------------------------------------------------------------------- /client/src/constant/submodule.ts: -------------------------------------------------------------------------------- 1 | // 从页面配置中获取当前环境变量 2 | let env = window.ENV 3 | 4 | const config = { 5 | dev: `hetu-plugin`, 6 | test: `hetu-plugin`, 7 | prod: `hetu-plugin`, 8 | } 9 | 10 | export function getDefaultSubmodule() { 11 | return config[env] 12 | } 13 | -------------------------------------------------------------------------------- /plugin/.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | .DS_Store 3 | node_modules 4 | .cache 5 | .rts2_cache_cjs 6 | .rts2_cache_esm 7 | .rts2_cache_umd 8 | dist 9 | lib 10 | site/_site 11 | site/components 12 | _site 13 | coverage 14 | 15 | .history 16 | .idea 17 | 18 | /package-lock.json 19 | 20 | -------------------------------------------------------------------------------- /client/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "./src", 4 | "paths": { 5 | "~/*": ["*"] 6 | }, 7 | "experimentalDecorators": true // Enables experimental support for ES7 decorators. 8 | }, 9 | "exclude": ["node_modules", "dist"] 10 | } 11 | -------------------------------------------------------------------------------- /plugin/site/theme/style/mixins/clearfix.less: -------------------------------------------------------------------------------- 1 | // mixins for clearfix 2 | // ------------------------ 3 | .clearfix() { 4 | zoom: 1; 5 | &::before, 6 | &::after { 7 | display: table; 8 | content: ''; 9 | } 10 | &::after { 11 | clear: both; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /plugin/site/theme/style/mixins/index.less: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------------------------------- 3 | @import 'size'; 4 | @import 'compatibility'; 5 | @import 'clearfix'; 6 | @import 'iconfont'; 7 | @import 'motion'; 8 | @import 'reset'; 9 | @import 'operation-unit'; 10 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/PickerDate/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { BaseProps } from '~/types' 2 | 3 | export interface HtDatePickerProps extends BaseProps { 4 | value: string 5 | defaultValue?: string 6 | onChange: (v: string) => void 7 | format?: string | string[] 8 | } 9 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/PickerMonth/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { BaseProps } from '~/types' 2 | 3 | export interface HtMonthPickerProps extends BaseProps { 4 | value: string 5 | defaultValue?: string 6 | onChange: (v: string) => void 7 | format?: string | string[] 8 | } 9 | -------------------------------------------------------------------------------- /plugin/src/components/Exception/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { JsonSchema } from '~/types' 2 | 3 | export interface HtExceptionProps { 4 | type: '403' | '404' | '500' 5 | title?: string 6 | desc?: string 7 | img?: string 8 | actions?: any 9 | style?: JsonSchema.DynamicObject 10 | } 11 | -------------------------------------------------------------------------------- /client/src/constant/env.ts: -------------------------------------------------------------------------------- 1 | const ENV_DEV = 'dev' 2 | const ENV_TEST = 'test' 3 | const ENV_PROD = 'prod' 4 | 5 | // 从页面配置中获取当前环境变量 6 | let env = window.ENV 7 | 8 | class ENV { 9 | static current = env 10 | static envList = [ENV_DEV, ENV_TEST, ENV_PROD] 11 | } 12 | 13 | export default ENV 14 | -------------------------------------------------------------------------------- /client/src/routes/GuiEditor/interface.ts: -------------------------------------------------------------------------------- 1 | import { ConnectProps } from '~/types/models/connect' 2 | import { IPageConfig } from '~/types/models/global' 3 | 4 | export interface TheGuiEditorProps extends ConnectProps { 5 | projectDetail: dynamicObject 6 | pageConfig: IPageConfig 7 | isLockIframe: boolean 8 | } 9 | -------------------------------------------------------------------------------- /client/scripts/utils.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs-extra') 2 | const paths = require('../config/paths') 3 | 4 | exports.copyPublicFolder = function copyPublicFolder() { 5 | fs.copySync(paths.appPublic, paths.appBuild, { 6 | dereference: true, 7 | filter: (file) => file !== paths.appHtml, 8 | }) 9 | } 10 | -------------------------------------------------------------------------------- /plugin/src/components/Steps/index.less: -------------------------------------------------------------------------------- 1 | .steps-content { 2 | margin-top: 16px; 3 | border: 1px dashed #e9e9e9; 4 | border-radius: 6px; 5 | background-color: #fafafa; 6 | min-height: 200px; 7 | } 8 | 9 | .steps-action { 10 | margin-top: 24px; 11 | display: flex; 12 | justify-content: space-between; 13 | } -------------------------------------------------------------------------------- /plugin/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [], 3 | "plugins": [ 4 | [ 5 | "module-resolver", 6 | { 7 | "root": "./", 8 | "alias": { 9 | "~": "./src", 10 | "@test": "./test", 11 | "*": ["src/*", "node_modules/*"] 12 | } 13 | } 14 | ] 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /plugin/src/components/BChart/ChartPie/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | category: Components 3 | type: 图表 4 | title: Pie 5 | subtitle: 饼图 6 | cols: 1 7 | order: 3 8 | --- 9 | 10 | 通用图表组件, 属性与[bizCharts](https://bizcharts.net/products/bizCharts)保持一致. 11 | 以下例子来源于[bizCharts demo](https://bizcharts.net/products/bizCharts/demo), 河图将其转换为 JSON 格式。 12 | -------------------------------------------------------------------------------- /plugin/src/components/BChart/ChartBar/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | category: Components 3 | type: 图表 4 | title: Bar 5 | subtitle: 柱状图 6 | cols: 1 7 | order: 0 8 | --- 9 | 10 | 11 | 通用图表组件, 属性与[bizCharts](https://bizcharts.net/products/bizCharts)保持一致. 12 | 以下例子来源于[bizCharts demo](https://bizcharts.net/products/bizCharts/demo), 河图将其转换为 JSON 格式。 13 | -------------------------------------------------------------------------------- /plugin/src/components/Container/__editor__/properties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | const config: Editor.BaseProperties = { 4 | style: { 5 | title: '布局样式', 6 | type: 'json', 7 | height: 100, 8 | defaultValue: { 9 | padding: '8px', 10 | }, 11 | }, 12 | } 13 | 14 | export default config 15 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Divider/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | category: Components 3 | type: Field 表单项 4 | title: Divider 分割线 5 | cols: 1 6 | order: 42 7 | --- 8 | 9 | [河图演示地址](http://139.155.239.172:9536/guiedit?route=%2Fproject%2Fhetu_demo%2Fhetu%2Fdemo%2FDivider) 10 | 11 | 分割线。 12 | 13 | ## 何时使用 14 | 15 | - 当表单项较多时, 用分割线 16 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/_EditableTable/context.ts: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { FormComponentProps } from 'antd/es/form' 3 | 4 | type Context = FormComponentProps 5 | 6 | const defaultContext: any = {} 7 | 8 | const context = React.createContext(defaultContext) 9 | 10 | export default context 11 | -------------------------------------------------------------------------------- /server/src/model/validator.ts: -------------------------------------------------------------------------------- 1 | export default class MValidator { 2 | static checkRequiredFields(requiredFields: string[], target: {[key:string]:any}) { 3 | for (let fieldKey of requiredFields) { 4 | if (target[fieldKey] === undefined) { 5 | throw new Error(`缺少参数${fieldKey}`) 6 | } 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /plugin/site/theme/static/nprogress.less: -------------------------------------------------------------------------------- 1 | #nprogress { 2 | .bar { 3 | background: @primary-color; 4 | } 5 | 6 | .peg { 7 | box-shadow: 0 0 10px @primary-color, 0 0 5px @primary-color; 8 | } 9 | 10 | .spinner-icon { 11 | border-top-color: @primary-color; 12 | border-left-color: @primary-color; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /plugin/src/components/BChart/ChartLine/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | category: Components 3 | type: 图表 4 | title: Line 5 | subtitle: 折线图 6 | cols: 1 7 | order: 2 8 | --- 9 | 10 | 11 | 通用图表组件, 属性与[bizCharts](https://bizcharts.net/products/bizCharts)保持一致. 12 | 以下例子来源于[bizCharts demo](https://bizcharts.net/products/bizCharts/demo), 河图将其转换为 JSON 格式。 13 | -------------------------------------------------------------------------------- /plugin/src/templates/custom/empty.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | route: '/project/template/empty/1', 3 | title: '自定义组件', 4 | local: {}, 5 | remote: {}, 6 | elementConfig: { 7 | type: 'HtGuiContainer', 8 | props: { 9 | style: { 10 | padding: '8px', 11 | }, 12 | }, 13 | children: [], 14 | }, 15 | } 16 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) 4 | 5 | ## 关于发版 6 | 7 | 版本格式(参照[语义化版本](https://semver.org/lang/zh-CN/)):主版本号.次版本号.修订号,版本号递增规则如下: 8 | 9 | - 主版本号:当做了不兼容的 API 修改, 10 | - 次版本号:当做了向下兼容的功能性新增, 11 | - 修订号:当做了向下兼容的问题修正。 12 | 13 | ## [1.0.0] 2020-09-27 14 | 15 | ### 河图开源 16 | -------------------------------------------------------------------------------- /client/src/routes/GuiEditor/components/SiderRight/FormEditor/compontent/input/index.less: -------------------------------------------------------------------------------- 1 | .FormInput-div { 2 | display: flex; 3 | 4 | label.ht-checkbox-wrapper { 5 | padding-left: 14px; 6 | } 7 | 8 | // textarea 9 | textarea.ht-input { 10 | padding: 4px 11px; 11 | line-height: 20px; 12 | transition: none; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /plugin/site/docs/editor/changeLog.md: -------------------------------------------------------------------------------- 1 | --- 2 | category: 关于河图 3 | order: 0 4 | title: 更新日志 5 | toc: false 6 | timeline: true 7 | --- 8 | 9 | #### 发布周期 10 | 11 | - 修订版本号:每周二会进行日常 bugfix 更新。(如果有紧急的 bugfix,则任何时候都可发布) 12 | - 次版本号:每月发布一个带有新特性的向下兼容的版本。 13 | - 主版本号:含有破坏性更新和新特性,不在发布周期内。 14 | 15 | --- 16 | 17 | ## 1.0.0 18 | `2020-09-27` 19 | 20 | - 河图开源啦 21 | -------------------------------------------------------------------------------- /client/src/routes/Preview/index.tsx: -------------------------------------------------------------------------------- 1 | import queryString from 'query-string' 2 | 3 | export default function PagePreview(props: any): null { 4 | const { history } = props 5 | const { route, draftId } = queryString.parse(window.location.search) 6 | 7 | const url = `${route}?draftId=${draftId}` 8 | 9 | history.replace(url) 10 | return null 11 | } 12 | -------------------------------------------------------------------------------- /server/copy_static_assets.js: -------------------------------------------------------------------------------- 1 | const shell = require('shelljs') 2 | 3 | console.log('开始复制静态资源') 4 | 5 | shell.mkdir('-p', 'dist/public/') 6 | shell.cp('-Rf', 'src/public/*', 'dist/public/') 7 | if (shell.test('-f', 'src/system_config.ini')) { 8 | shell.cp('-Rf', 'src/system_config.ini', 'dist/system_config.ini') 9 | } 10 | 11 | console.log('静态资源复制完毕') 12 | -------------------------------------------------------------------------------- /plugin/src/components/BChart/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: [], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /server/src/config/login.ts: -------------------------------------------------------------------------------- 1 | import prodConfig from '~/src/config/_prod' 2 | import env from '~/src/config/env' 3 | import _ from 'lodash' 4 | 5 | const dev = { 6 | token_name: 'hetu_token', 7 | token_name_secure: 'hetu_token_secure', 8 | max_age: 86400 * 1000, 9 | } 10 | 11 | export default { 12 | dev, 13 | test: dev, 14 | prod: dev, 15 | }[env] 16 | -------------------------------------------------------------------------------- /client/src/components/_utils/pathTools.ts: -------------------------------------------------------------------------------- 1 | // /userinfo/2144/id => ['/userinfo','/useinfo/2144,'/userindo/2144/id'] 2 | export function urlToList(url: string): string[] { 3 | if (url === '/') return ['/'] 4 | const urllist = url.split('/').filter((i) => i) 5 | return urllist.map((urlItem, index) => { 6 | return `/${urllist.slice(0, index + 1).join('/')}` 7 | }) 8 | } 9 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Alert/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { BaseProps } from '~/types' 2 | 3 | type AlertType = 'success' | 'info' | 'warning' | 'error' 4 | 5 | export interface Props extends BaseProps { 6 | message: string 7 | description?: string 8 | banner?: boolean 9 | closable?: boolean 10 | showIcon?: boolean 11 | alertType?: AlertType 12 | } 13 | -------------------------------------------------------------------------------- /plugin/src/components/Button/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['move', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Button/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { ButtonProps } from 'antd/es/button' 2 | import { BaseProps } from '~/types' 3 | 4 | export interface HtButtonComponentProps extends ButtonProps, BaseProps { 5 | to?: string 6 | href?: string 7 | text: string 8 | className?: string 9 | 10 | // 使用h5原生跳转 11 | useH5Href?: true 12 | linkTarget?: boolean 13 | } 14 | -------------------------------------------------------------------------------- /plugin/src/components/Card/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['delete', 'move'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Steps/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['move', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Tabs/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['add', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /client/src/components/JsonEditor/interface.d.ts: -------------------------------------------------------------------------------- 1 | type valueType = string | undefined | null 2 | export interface JsonEditorProps { 3 | defaultValue?: valueType 4 | value?: valueType 5 | disabled?: boolean 6 | onChange?: (v: string) => void 7 | height?: number 8 | } 9 | 10 | export interface JsonEditorState { 11 | isEditorVisible: boolean 12 | height: number 13 | } 14 | -------------------------------------------------------------------------------- /client/src/routes/Admin/Layout/index.less: -------------------------------------------------------------------------------- 1 | .login-layout-container { 2 | position: fixed; 3 | z-index: 100; 4 | width: 100vw; 5 | height: 100vh; 6 | background-color: #f9fcff; 7 | 8 | .ht-form-explain { 9 | position: absolute; 10 | margin-top: 1px; 11 | margin-bottom: 1px; 12 | } 13 | 14 | .ht-form-item { 15 | margin-bottom: 28px; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /plugin/src/components/Container/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | additableProperties, 7 | selectedButtons: ['move', 'delete'], 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Divider/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['move', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/ModalForm/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['delete', 'move'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/site/hetu.ts: -------------------------------------------------------------------------------- 1 | import { store } from '@ice/stark-data' 2 | 3 | // 模拟在乾坤中 4 | // @ts-ignore 5 | window.__POWERED_BY_QIANKUN__ = true 6 | 7 | store.set('hetu-request-config', { 8 | baseURL: 'http://mockjs.docway.net/mock/1XhtOi6ISFV', 9 | headers: { 10 | 'X-Requested-With': 'XMLHttpRequest', 11 | // 用于校验登录状态的token 12 | 'X-Custom-Session': 'site', 13 | }, 14 | }) 15 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/PickerRange/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { BaseProps } from '~/types' 2 | 3 | export type HtRangePickerValue = string[] 4 | export interface HtRangePickerProps extends BaseProps { 5 | value: HtRangePickerValue 6 | defaultValue?: HtRangePickerValue 7 | onChange: (v: HtRangePickerValue) => void 8 | format?: string 9 | showTime?: boolean 10 | } 11 | -------------------------------------------------------------------------------- /plugin/site/theme/style/mixins/reset.less: -------------------------------------------------------------------------------- 1 | @import '../themes/index'; 2 | 3 | .reset-component() { 4 | box-sizing: border-box; 5 | margin: 0; 6 | padding: 0; 7 | color: @text-color; 8 | font-size: @font-size-base; 9 | font-variant: @font-variant-base; 10 | line-height: @line-height-base; 11 | list-style: none; 12 | font-feature-settings: @font-feature-settings-base; 13 | } 14 | -------------------------------------------------------------------------------- /plugin/site/theme/template/Color/ColorPatterns.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { generate } from '@ant-design/colors'; 3 | import ColorBlock from './ColorBlock'; 4 | 5 | export default function ColorPatterns({ color }) { 6 | return generate(color).map((colorString, i) => ( 7 | // eslint-disable-line 8 | )); 9 | } 10 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Text/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['move', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/List/components/ActionColumn/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/List/components/ActionColumn2/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Alert/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['move', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Checkbox/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['move', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Divider/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['move', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Input/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['move', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Radio/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['move', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Select/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['move', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Steps/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['move', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Upload/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['move', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Form/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['add', 'delete'], 7 | additableProperties: additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/List/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['add', 'delete'], 7 | additableProperties: additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/List/components/Column/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['move', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Steps/__editor__/defaultConfig.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | type: 'HtSteps', 3 | props: { 4 | current: 0, 5 | direction: 'horizontal', 6 | steps: [ 7 | { 8 | title: 'title1', 9 | }, 10 | { 11 | title: 'title2', 12 | }, 13 | { 14 | title: 'title3', 15 | }, 16 | ], 17 | }, 18 | children: [], 19 | } 20 | -------------------------------------------------------------------------------- /client/src/routes/Home/Layout/Blank/index.tsx: -------------------------------------------------------------------------------- 1 | import React, { Fragment, Component } from 'react' 2 | 3 | export default class LayoutBlank extends Component { 4 | static displayName = 'LayoutBlank' 5 | 6 | static propTypes = {} 7 | 8 | static defaultProps = {} 9 | 10 | render() { 11 | const { children } = this.props 12 | 13 | return {children} 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /plugin/site/theme/style/mixins/operation-unit.less: -------------------------------------------------------------------------------- 1 | @import '../../style/themes/default'; 2 | 3 | .operation-unit() { 4 | color: @link-color; 5 | text-decoration: none; 6 | outline: none; 7 | cursor: pointer; 8 | transition: color 0.3s; 9 | 10 | &:focus, 11 | &:hover { 12 | color: @link-hover-color; 13 | } 14 | 15 | &:active { 16 | color: @link-active-color; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/InputNumber/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['move', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/InputPassword/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['move', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/InputTextarea/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['move', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/JsonEditor/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['move', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/PickerDate/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['move', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/PickerDateTime/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['move', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/PickerMonth/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['move', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/PickerRange/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['move', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/PickerTime/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['move', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/PickerWeek/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['move', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/SelectCascade/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['move', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/SelectMultiple/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['move', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/SelectTree/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['move', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/SelectTrees/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['move', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/TableEditor/__editor__/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import additableProperties from './additableProperties' 3 | import properties from './properties' 4 | 5 | const config: Editor.ComponentEditConfig = { 6 | selectedButtons: ['move', 'delete'], 7 | additableProperties, 8 | guiProperties: properties, 9 | } 10 | 11 | export default config 12 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/SelectMultiple/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import HtSelect from '../Select' 3 | import { HtSelectProps } from '../Select/interface' 4 | 5 | export default class HtSelectMultiple extends React.Component { 6 | static displayName = 'HtSelectMultiple' 7 | 8 | render() { 9 | return 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /client/src/routes/Admin/Card/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import './index.less' 4 | 5 | export default class LoginLayout extends React.Component { 6 | 7 | render() { 8 | const { children } = this.props 9 | return ( 10 |
11 |
河 图
12 | {children} 13 |
14 | ) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /plugin/src/components/ModalForm/__editor__/additableProperties.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-template-curly-in-string */ 2 | import { Editor } from '~/types' 3 | import fieldOptions from '~/components/Form/__editor__/additableProperties/fields' 4 | 5 | const config: Editor.AdditableProperties = { 6 | fields: { 7 | title: '表单项', 8 | optionGroups: fieldOptions, 9 | }, 10 | } 11 | 12 | export default config 13 | -------------------------------------------------------------------------------- /client/src/routes/Templates/index.less: -------------------------------------------------------------------------------- 1 | .page-templates { 2 | display: flex; 3 | flex-direction: column; 4 | min-height: 100vh; 5 | color: #fff; 6 | background-color: #f2f2f2; 7 | } 8 | 9 | .page-templates-content { 10 | display: flex; 11 | flex: 1; 12 | flex-wrap: wrap; 13 | align-content: flex-start; 14 | padding:0 20px; 15 | } 16 | 17 | .page-templates-tabs { 18 | padding: 40px 30px 10px; 19 | } 20 | -------------------------------------------------------------------------------- /plugin/src/components/Divider/demo/basic.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 0 3 | title: 分割线 4 | --- 5 | 6 | ```jsx 7 | import Hetu from 'hetu' 8 | 9 | const elementConfig = { 10 | type: 'HtDivider', 11 | props: { 12 | type: 'horizontal', 13 | title: '分割线', 14 | orientation: 'center', 15 | }, 16 | children: [], 17 | } 18 | 19 | ReactDOM.render(, mountNode) 20 | ``` 21 | -------------------------------------------------------------------------------- /server/src/config/_prod.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs' 2 | import ini from 'ini' 3 | import path from 'path' 4 | 5 | const relativePath = `../../../system_config.ini` 6 | const filePath = path.resolve(__dirname, relativePath) 7 | 8 | const config: { [key: string]: any } = {} 9 | 10 | if (fs.existsSync(filePath)) { 11 | Object.assign(config, ini.parse(fs.readFileSync(filePath, 'utf-8'))) 12 | } 13 | 14 | export default config 15 | -------------------------------------------------------------------------------- /plugin/site/theme/template/FormattedMessage/index.jsx: -------------------------------------------------------------------------------- 1 | import znCNMap from '@/theme/zh-CN' 2 | import { get } from 'lodash/object' 3 | import React, { Fragment } from 'react' 4 | 5 | export default class FormattedMessage extends React.Component { 6 | render() { 7 | const { id } = this.props 8 | 9 | const messages = get(znCNMap, 'messages') 10 | 11 | return {messages[`${id}`]} 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /client/src/routes/GuiEditor/components/SiderRight/JSONEditor/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { ConnectProps, ConnectState } from '~/types/models/connect' 2 | import { activeTab } from '~/types/models/guiEditor' 3 | 4 | export { ConnectState } 5 | export default interface JSONEditorProps extends ConnectProps { 6 | pageConfig: any 7 | projectId: number 8 | pageId: number 9 | dataPageConfigPath: string 10 | activeTab: activeTab 11 | } 12 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/_EditableTable/EditableCell/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { BaseProps, JsonSchema } from '~/types/index' 2 | 3 | export interface HtEditableCellProps 4 | extends BaseProps { 5 | record: T 6 | handleSave: (v: T) => void 7 | dataIndex: string 8 | title: string 9 | type: string 10 | index: number 11 | editable: boolean 12 | onClick: (e: any) => void 13 | } 14 | -------------------------------------------------------------------------------- /plugin/src/components/Form/__editor__/additableProperties/extra/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import map from './default_value' 3 | 4 | const options: Editor.AdditablePropertiesOption[] = [ 5 | { 6 | label: '页面跳转', 7 | icon: 'border', 8 | value: map.HtButton, 9 | }, 10 | { 11 | label: '弹框', 12 | icon: 'alert', 13 | value: map.HtModalForm, 14 | }, 15 | ] 16 | 17 | export default options 18 | -------------------------------------------------------------------------------- /plugin/src/components/List/__editor__/additableProperties/extra/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import map from './default_value' 3 | 4 | const options: Editor.AdditablePropertiesOption[] = [ 5 | { 6 | label: '页面跳转', 7 | icon: 'border', 8 | value: map.HtButton, 9 | }, 10 | { 11 | label: '弹框', 12 | icon: 'alert', 13 | value: map.HtModalForm, 14 | }, 15 | ] 16 | 17 | export default options 18 | -------------------------------------------------------------------------------- /client/src/components/HtmlFragment/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | interface IProps { 4 | block?: boolean 5 | __html: string 6 | } 7 | 8 | export default class HtHtml extends React.Component { 9 | render() { 10 | const { __html, block } = this.props 11 | 12 | const C: keyof JSX.IntrinsicElements = block ? 'div' : 'span' 13 | 14 | return 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /client/src/routes/Home/Layout/Basic/Header/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { IUserInfo, IProjectDetail } from '~/types/models/global' 2 | import { FormComponentProps } from 'antd/es/form' 3 | import { ConnectProps, ConnectState } from '~/types/models/connect' 4 | export { IUserInfo, ConnectState } 5 | 6 | export interface TheHeaderProps extends FormComponentProps, ConnectProps { 7 | userInfo: IUserInfo 8 | projectDetail: IProjectDetail 9 | } 10 | -------------------------------------------------------------------------------- /plugin/src/components/HtmlFragment/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | interface IProps { 4 | block?: boolean 5 | __html: string 6 | } 7 | 8 | export default class HtHtml extends React.Component { 9 | render() { 10 | const { __html, block } = this.props 11 | 12 | const C: keyof JSX.IntrinsicElements = block ? 'div' : 'span' 13 | 14 | return 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /client/src/routes/Admin/Layout/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import LoginCard from '../Card' 3 | import './index.less' 4 | 5 | export default class LoginLayout extends React.Component { 6 | 7 | render() { 8 | const { children } = this.props 9 | return ( 10 |
11 | 12 | {children} 13 | 14 |
15 | ) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /client/src/routes/Home/Layout/Basic/index.module.less: -------------------------------------------------------------------------------- 1 | .the-tabs { 2 | :global { 3 | .ht-tabs-nav-wrap { 4 | background-color: #f0f2f5; 5 | } 6 | 7 | .ht-tabs-bar { 8 | margin-bottom: 0; 9 | } 10 | } 11 | } 12 | .base_footer { 13 | padding: 15px 16px; 14 | text-align: center; 15 | } 16 | 17 | .copyright { 18 | color: #999; 19 | &:hover { 20 | color: #1890ff; 21 | cursor: pointer; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /plugin/src/components/List/__editor__/additableProperties/sections/index.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import map from './default_value' 3 | 4 | const options: Editor.AdditablePropertiesOption[] = [ 5 | { 6 | label: '批量下载', 7 | icon: 'cloud-download', 8 | value: map.HtButton, 9 | }, 10 | { 11 | label: '批量编辑', 12 | icon: 'form', 13 | value: map.HtModalForm, 14 | }, 15 | ] 16 | 17 | export default options 18 | -------------------------------------------------------------------------------- /plugin/src/components/Steps/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { BaseProps } from '~/types' 2 | 3 | export type HtStepValue = undefined | number 4 | 5 | export interface Props extends BaseProps { 6 | alias: string 7 | current: HtStepValue 8 | direction: 'horizontal' | 'vertical' 9 | steps: { 10 | title: string 11 | description?: string | React.ReactNode 12 | }[] 13 | showButton: boolean 14 | onChange: (current: HtStepValue) => void 15 | } 16 | -------------------------------------------------------------------------------- /client/src/apis/user.ts: -------------------------------------------------------------------------------- 1 | import _ from 'lodash' 2 | import request from '~/utils/request' 3 | 4 | export default class User { 5 | /** 6 | * 获取用户信息 7 | */ 8 | static async getAsyncUserInfo() { 9 | return request.get('/api/hetu/info').then((res) => { 10 | if (_.isPlainObject(_.get(res, 'data'))) { 11 | return Promise.resolve(res.data) 12 | } 13 | return Promise.reject('getAsyncUserInfo 返回值格式错误') 14 | }) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /client/src/components/JsonEditor/Controled.d.ts: -------------------------------------------------------------------------------- 1 | type valueType = string | undefined | null 2 | export interface JsonEditorProps { 3 | defaultValue?: valueType 4 | value?: valueType 5 | disabled?: boolean 6 | height?: number 7 | 8 | onChange?: (v: string) => void 9 | getRef: (c: any) => void 10 | } 11 | 12 | export interface JsonEditorState { 13 | codeStr?: string 14 | code?: any 15 | isEditorVisible: boolean 16 | height: number 17 | } 18 | -------------------------------------------------------------------------------- /client/src/types/components/interfaceBaseCompontentProps.ts: -------------------------------------------------------------------------------- 1 | interface InterfaceBaseCompontentProps { 2 | /** 3 | * 组件名 4 | * 示例:data-component-type="BaseFormItemText" 5 | */ 6 | ['data-component-type']: string 7 | /** 8 | * 组件在props中的相对路径 9 | * 示例: data-pageconfig-path="elementConfig.props.content.children[0].children[0].children[3]" 10 | */ 11 | ['data-pageconfig-path']: string 12 | } 13 | export default InterfaceBaseCompontentProps 14 | -------------------------------------------------------------------------------- /plugin/src/components/Card/__editor__/properties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | 3 | let a: Editor.BaseProperties = { 4 | title: { 5 | title: '卡片标题', 6 | type: 'string', 7 | defaultValue: '卡片标题', 8 | }, 9 | bordered: { 10 | title: '是否有边框', 11 | type: 'bool', 12 | defaultValue: true, 13 | }, 14 | extra: { 15 | title: '右上角按钮', 16 | type: 'json', 17 | height: 400, 18 | }, 19 | } 20 | 21 | export default a 22 | -------------------------------------------------------------------------------- /client/src/components/Exception/403.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Button } from 'antd' 3 | import Exception from './' 4 | 5 | export default class Exception403 extends React.Component { 6 | 7 | goHome = () => { 8 | window.location.href = '/' 9 | } 10 | 11 | render() { 12 | return 返回} /> 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /client/src/routes/Home/Layout/Basic/interface.d.ts: -------------------------------------------------------------------------------- 1 | import * as H from 'history' 2 | import { IPaneItem, IUserInfo, IProjectDetail } from '~/types/models/global' 3 | 4 | export interface LayoutBasicProps { 5 | history: H.History 6 | userInfo: IUserInfo 7 | projectDetail: IProjectDetail 8 | activePanekey: string 9 | panes: IPaneItem[] 10 | onChange: (activePanekey: string, panes: IPaneItem[]) => void 11 | } 12 | 13 | export interface LayoutBasicState {} 14 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/JsonEditor/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { BaseProps } from '~/types' 2 | 3 | type valueType = string | undefined | null 4 | export interface JsonEditorProps extends BaseProps { 5 | defaultValue: valueType 6 | value: valueType 7 | disabled: boolean 8 | onChange: (v: string) => void 9 | height?: number 10 | } 11 | 12 | // eslint-disable-next-line @typescript-eslint/no-empty-interface 13 | export interface JsonEditorState {} 14 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/InputPassword/__editor__/properties.ts: -------------------------------------------------------------------------------- 1 | import _ from 'lodash' 2 | import BaseProperty from '~/components/Field/types/baseProperty' 3 | import { Editor } from '~/types' 4 | 5 | let a: Editor.BaseProperties = { 6 | ..._.omit(BaseProperty, ['required', 'disabled']), 7 | maxLength: { 8 | title: '最大长度', 9 | type: 'number', 10 | }, 11 | ..._.pick(BaseProperty, ['required', 'disabled']), 12 | } 13 | 14 | export default a 15 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Steps/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { BaseProps } from '~/types' 2 | 3 | export type HtStepValue = undefined | number 4 | 5 | export interface Props extends BaseProps { 6 | current: HtStepValue 7 | value: HtStepValue 8 | initial: number 9 | direction: 'horizontal' | 'vertical' 10 | steps: { 11 | title: string 12 | description?: string | React.ReactNode 13 | }[] 14 | onChange: (current: HtStepValue) => void 15 | } 16 | -------------------------------------------------------------------------------- /server/src/config/log.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * === app config === 3 | * 项目应用的配置 4 | * 5 | */ 6 | import env from '~/src/config/env' 7 | import path from 'path' 8 | import _ from 'lodash' 9 | 10 | let absoluteLogPath = path.resolve(__dirname, '../logs') 11 | 12 | const logPathMap = { 13 | dev: './logs', 14 | test: absoluteLogPath, 15 | test2: absoluteLogPath, 16 | test3: absoluteLogPath, 17 | prod: absoluteLogPath, 18 | } 19 | 20 | export default logPathMap[env] 21 | -------------------------------------------------------------------------------- /plugin/src/components/ModalForm/__editor__/defaultConfig.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | type: 'HtModalForm', 3 | props: { 4 | url: '/mock/api/update', 5 | fields: [ 6 | { 7 | field: 'name', 8 | title: '姓名', 9 | }, 10 | { 11 | field: 'age', 12 | title: '年龄', 13 | type: 'InputNumber', 14 | }, 15 | ], 16 | title: '弹框表单', 17 | triggerButtonText: '点我', 18 | buttonType: 'primary', 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /client/src/routes/Home/ModalClone/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { FormComponentProps } from 'antd/es/form' 2 | import { IProjectDetail, IPageConfig } from '~/types/models/global' 3 | 4 | export interface TheCloneModalProps extends FormComponentProps { 5 | visible: boolean 6 | pageConfig: IPageConfig 7 | projectDetail: IProjectDetail 8 | 9 | onChange: (visible: boolean) => void 10 | } 11 | 12 | export interface TheCloneModalState { 13 | projectList: IProjectDetail[] 14 | } 15 | -------------------------------------------------------------------------------- /server/src/config/env.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * === env config === 3 | * 环境配置 4 | * 5 | * created at: Thu Nov 30 2017 17:35:34 GMT+0800 (CST) 6 | */ 7 | 8 | // 环境变量值=> 9 | // development 10 | // testing 11 | // production 12 | let env: 'dev' | 'test' | 'prod' = 'test' 13 | switch (process.env.NODE_ENV) { 14 | case 'dev': 15 | case 'test': 16 | case 'prod': 17 | env = process.env.NODE_ENV 18 | break 19 | default: 20 | env = 'test' 21 | } 22 | 23 | export default env 24 | -------------------------------------------------------------------------------- /client/src/routes/Admin/Card/index.less: -------------------------------------------------------------------------------- 1 | .login-card-container { 2 | width: 500px; 3 | position: absolute; 4 | left: 50%; 5 | top: 50%; 6 | transform: translate(-50%, -50%); 7 | padding: 50px; 8 | background-color: #fff; 9 | box-shadow: 0 1px 3px rgba(19, 26, 92, .06), 0 6px 30px rgba(19, 26, 92, .12); 10 | border-radius: 4px; 11 | } 12 | 13 | .login-card-title { 14 | font-size: 40px; 15 | line-height: 1.5; 16 | text-align: center; 17 | margin-bottom: 30px; 18 | } 19 | -------------------------------------------------------------------------------- /plugin/site/theme/static/docsearch.less: -------------------------------------------------------------------------------- 1 | .algolia-autocomplete { 2 | .ds-dropdown-menu { 3 | border: none; 4 | box-shadow: @box-shadow-base; 5 | 6 | [class^='ds-dataset-'] { 7 | border: none; 8 | } 9 | 10 | &::before { 11 | display: none; 12 | } 13 | } 14 | 15 | .algolia-docsearch-suggestion--title { 16 | color: @site-text-color; 17 | } 18 | 19 | .algolia-docsearch-suggestion--highlight { 20 | color: @primary-color; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /plugin/site/theme/style/core/iconfont.less: -------------------------------------------------------------------------------- 1 | @import '../themes/index'; 2 | @import '../mixins/iconfont'; 3 | 4 | .@{iconfont-css-prefix} { 5 | .iconfont-mixin(); 6 | 7 | &[tabindex] { 8 | cursor: pointer; 9 | } 10 | } 11 | 12 | .@{iconfont-css-prefix}-spin::before { 13 | display: inline-block; 14 | animation: loadingCircle 1s infinite linear; 15 | } 16 | .@{iconfont-css-prefix}-spin { 17 | display: inline-block; 18 | animation: loadingCircle 1s infinite linear; 19 | } 20 | -------------------------------------------------------------------------------- /plugin/src/components/Form/__editor__/additableProperties/index.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-template-curly-in-string */ 2 | import { Editor } from '~/types' 3 | import extraOptions from './extra' 4 | import fieldOptions from './fields' 5 | 6 | const config: Editor.AdditableProperties = { 7 | extra: { 8 | title: '右上角按钮', 9 | options: extraOptions, 10 | }, 11 | fields: { 12 | title: '表单项', 13 | optionGroups: fieldOptions, 14 | }, 15 | } 16 | 17 | export default config 18 | -------------------------------------------------------------------------------- /plugin/src/types/index.d.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from './editor' 2 | import { JsonSchema } from './jsonSchema' 3 | 4 | export { JsonSchema, Editor } 5 | 6 | /** 7 | * hetu组件通用Props 8 | */ 9 | export interface BaseProps { 10 | pagestate: JsonSchema.Pagestate 11 | id?: string 12 | className?: string 13 | style?: any 14 | 'v-if'?: boolean 15 | // 属性在pageconfig中的路径 16 | 'data-pageconfig-path'?: string 17 | // 组件类型, 例如 HtList、HtForm 18 | 'data-component-type'?: string 19 | } 20 | -------------------------------------------------------------------------------- /client/src/routes/GuiEditor/components/Header/ThePublishModal/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { ConnectProps, ConnectState } from '~/types/models/connect' 2 | import { activeTab } from '~/types/models/guiEditor' 3 | 4 | import { FormComponentProps } from 'antd/es/form' 5 | 6 | export { ConnectState } 7 | 8 | export interface Props extends ConnectProps, FormComponentProps { 9 | projectId: number 10 | pageId: number 11 | draftId: number 12 | 13 | visible: boolean 14 | 15 | onClose: () => void 16 | } 17 | -------------------------------------------------------------------------------- /plugin/site/theme/template/Content/PrevAndNext.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default ({ prev, next }) => ( 4 |
5 | {prev 6 | ? React.cloneElement(prev.props.children || prev.children[0], { 7 | className: 'prev-page', 8 | }) 9 | : null} 10 | {next 11 | ? React.cloneElement(next.props.children || next.children[0], { 12 | className: 'next-page', 13 | }) 14 | : null} 15 |
16 | ); 17 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/InputNumber/demo/basic.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 0 3 | title: 基本使用 4 | --- 5 | 6 | 7 | ```jsx 8 | import Hetu from 'hetu' 9 | 10 | const elementConfig = { 11 | type: 'HtForm', 12 | props: { 13 | url: '/', 14 | buttons: [], 15 | fields: [ 16 | { 17 | field: 'age', 18 | title: '年龄', 19 | type: 'InputNumber' 20 | }, 21 | ], 22 | }, 23 | children: [], 24 | } 25 | 26 | ReactDOM.render(, mountNode) 27 | ``` 28 | -------------------------------------------------------------------------------- /plugin/src/components/Divider/index.tsx: -------------------------------------------------------------------------------- 1 | import { Divider } from 'antd' 2 | import React, { Component } from 'react' 3 | import { Props } from './interface' 4 | 5 | export default class HtDivider extends Component { 6 | // static displayName = 'HtDivider' 7 | 8 | static defaultProps = { 9 | dashed: false, 10 | orientation: 'left', 11 | type: 'horizontal', 12 | } 13 | 14 | render() { 15 | const { title, pagestate, ...rest } = this.props 16 | return {title} 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/JsonEditor/__editor__/properties.ts: -------------------------------------------------------------------------------- 1 | import _ from 'lodash' 2 | import BaseProperty from '~/components/Field/types/baseProperty' 3 | import { Editor } from '~/types' 4 | 5 | const config: Editor.BaseProperties = { 6 | ..._.omit(BaseProperty, ['placeholder', 'required', 'disabled']), 7 | height: { 8 | title: '高度', 9 | type: 'number', 10 | defaultValue: 60, 11 | }, 12 | required: BaseProperty.required, 13 | disabled: BaseProperty.disabled, 14 | } 15 | 16 | export default config 17 | -------------------------------------------------------------------------------- /plugin/test/setup.ts: -------------------------------------------------------------------------------- 1 | import Enzyme from 'enzyme' 2 | import Adapter from 'enzyme-adapter-react-16' 3 | import 'mobx-react/batchingForReactDom' 4 | 5 | jest.useFakeTimers() 6 | jest.setTimeout(10000) 7 | 8 | // @ts-ignore 9 | delete global.window.location 10 | // @ts-ignore 11 | global.window.location = { 12 | reload: jest.fn(), 13 | replace: jest.fn(), 14 | assign: jest.fn(), 15 | } 16 | 17 | global.Promise = jest.requireActual('promise') 18 | 19 | Enzyme.configure({ adapter: new Adapter() }) 20 | 21 | export default Enzyme 22 | -------------------------------------------------------------------------------- /plugin/src/components/Card/_index.md_: -------------------------------------------------------------------------------- 1 | --- 2 | category: Components 3 | type: 业务组件 4 | title: Card 5 | subtitle: 卡片 6 | cols: 1 7 | order: 0 8 | --- 9 | 10 | ## 何时使用 11 | 12 | 包裹 `List、Form`等页面的容器。 13 | 14 | ## API 15 | 16 | ### Card 17 | 18 | | 参数 | 说明 | 类型 | 默认值 | 19 | | ----- | -------------------- | ------------------- | -------- | 20 | | extra | 卡片右上角的操作区域 | Array<ReactNode> | - | 21 | | title | 卡片标题 | string\|ReactNode | 页面标题 | 22 | | bordered | 是否有边框 | boolean | true | 23 | -------------------------------------------------------------------------------- /plugin/src/components/Field/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { WrappedFormUtils } from 'antd/es/form/Form' 2 | import { BaseProps, JsonSchema } from '~/types' 3 | export { FormItemProps } from 'antd/es/form/FormItem' 4 | 5 | /** 6 | * field 7 | */ 8 | export interface FormField { 9 | field: string 10 | title: string 11 | } 12 | 13 | export interface HtFieldProps 14 | extends BaseProps, 15 | JsonSchema.HtFieldBaseProps { 16 | form: WrappedFormUtils 17 | onChange?: (v: T) => void 18 | otherProps?: JsonSchema.DynamicObject 19 | } 20 | -------------------------------------------------------------------------------- /plugin/site/theme/style/mixins/compatibility.less: -------------------------------------------------------------------------------- 1 | // Compatibility for browsers. 2 | 3 | // Placeholder text 4 | .placeholder(@color: @input-placeholder-color) { 5 | // Firefox 6 | &::-moz-placeholder { 7 | color: @color; 8 | opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526 9 | } 10 | // Internet Explorer 10+ 11 | &:-ms-input-placeholder { 12 | color: @color; 13 | } 14 | // Safari and Chrome 15 | &::-webkit-input-placeholder { 16 | color: @color; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Text/__editor__/properties.ts: -------------------------------------------------------------------------------- 1 | import _ from 'lodash' 2 | import BaseProperty from '~/components/Field/types/baseProperty' 3 | 4 | import { Editor, JsonSchema } from '~/types' 5 | 6 | export const defaultValueMap = {} 7 | 8 | export default (_formData: JsonSchema.DynamicObject): Editor.BaseProperties => { 9 | return { 10 | ..._.omit(BaseProperty, [ 11 | 'placeholder', 12 | 'required', 13 | 'disabled', 14 | 'onChangeRequests', 15 | 'setFieldValues', 16 | ]), 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /client/src/routes/Templates/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { FormComponentProps } from 'antd/es/form' 2 | import { ConnectProps, ConnectState } from '~/types/models/connect' 3 | 4 | export interface PageTemplatesProps extends FormComponentProps, ConnectProps { 5 | visible: boolean 6 | onChange: (visible: boolean) => void 7 | pageConfig: dynamicObject 8 | projectList: dynamicObject[] 9 | } 10 | 11 | export type activeTabKeyType = 'all' 12 | 13 | export interface PageTemplatesState { 14 | activeTabKey: activeTabKeyType 15 | templateData: any[] 16 | } 17 | -------------------------------------------------------------------------------- /client/src/types/models/connect.d.ts: -------------------------------------------------------------------------------- 1 | import { AnyAction } from 'redux'; 2 | import { globalState } from './global' 3 | import { editorState } from './editor.d' 4 | import { guiEditorState } from './guiEditor.d' 5 | 6 | export interface ConnectState { 7 | global: globalState 8 | editor: editorState 9 | guiEditor: guiEditorState 10 | } 11 | 12 | export interface Action { 13 | type: any; 14 | } 15 | 16 | export type Dispatch = (action: AnyAction) => Promise | any; 17 | 18 | export interface ConnectProps { 19 | dispatch?: Dispatch; 20 | } 21 | -------------------------------------------------------------------------------- /plugin/site/theme/template/Redirect.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const redirect = { 4 | '/': '/docs/editor/01-introduce', 5 | } 6 | 7 | export default class Redirect extends React.Component { 8 | componentDidMount() { 9 | const { location } = this.props 10 | const pathname = `/${location.pathname}` 11 | Object.keys(redirect).forEach((from) => { 12 | if (pathname.indexOf(from) === 0) { 13 | window.location.href = redirect[from] 14 | } 15 | }) 16 | } 17 | 18 | render() { 19 | return
20 | } 21 | } 22 | -------------------------------------------------------------------------------- /server/src/config/email.ts: -------------------------------------------------------------------------------- 1 | import _ from 'lodash' 2 | import prodConfig from '~/src/config/_prod' 3 | import env from './env' 4 | 5 | const { host, port, user, pass } = _.get(prodConfig, 'email') 6 | 7 | const dev = { 8 | from: user, 9 | host, 10 | port, 11 | user, 12 | pass, 13 | } 14 | 15 | const test = dev 16 | const test1 = dev 17 | const test2 = dev 18 | const test3 = dev 19 | const prod = dev 20 | 21 | const config = { 22 | dev, 23 | test, 24 | test1, 25 | test2, 26 | test3, 27 | prod, 28 | } 29 | 30 | export default config[env] 31 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/InputTextarea/__editor__/properties.ts: -------------------------------------------------------------------------------- 1 | import _ from 'lodash' 2 | import BaseProperty from '~/components/Field/types/baseProperty' 3 | import { Editor } from '~/types' 4 | 5 | let a: Editor.BaseProperties = { 6 | ..._.omit(BaseProperty, ['required', 'disabled']), 7 | rows: { 8 | title: '默认行数', 9 | type: 'number', 10 | defaultValue: 2, 11 | }, 12 | maxLength: { 13 | title: '最大长度', 14 | type: 'number', 15 | }, 16 | ..._.pick(BaseProperty, ['required', 'disabled']), 17 | } 18 | 19 | export default a 20 | -------------------------------------------------------------------------------- /client/src/routes/GuiEditor/components/SiderLeft/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { ConnectProps } from '~/types/models/connect' 2 | import { IPageConfig, IElementConfig } from '~/types/models/global' 3 | import { selectedComponentData, activeTab } from '~/types/models/guiEditor' 4 | 5 | type Option = any 6 | export { IPageConfig, selectedComponentData, Option, IElementConfig } 7 | 8 | export interface TheSiderLeftProps extends ConnectProps { 9 | pageConfig: IPageConfig 10 | activeTab: activeTab 11 | isLockIframe: boolean 12 | selectedComponentData: selectedComponentData 13 | } 14 | -------------------------------------------------------------------------------- /client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "noImplicitAny": true, 5 | "removeComments": true, 6 | "preserveConstEnums": true, 7 | "sourceMap": true, 8 | "baseUrl": "./src", 9 | "paths": { 10 | "*": [ 11 | "typings", 12 | "node_modules" 13 | ], 14 | "~/*": [ 15 | "*" 16 | ] 17 | }, 18 | "experimentalDecorators": true, 19 | "jsx": "react", 20 | "esModuleInterop": true 21 | }, 22 | "exclude": [ 23 | "node_modules", 24 | "dist" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /plugin/site/theme/static/new-version-info-modal.less: -------------------------------------------------------------------------------- 1 | @import '../style/themes/default.less'; 2 | 3 | .new-version-info-modal { 4 | img { 5 | position: absolute; 6 | top: 36px; 7 | left: 34px; 8 | width: 100px; 9 | } 10 | p { 11 | margin-top: 1em; 12 | } 13 | .anticon { 14 | display: none; 15 | } 16 | .@{ant-prefix}-confirm-body { 17 | .@{ant-prefix}-confirm-title { 18 | font-size: 18px; 19 | } 20 | 21 | margin-left: 120px; 22 | .@{ant-prefix}-confirm-content { 23 | margin-left: 0; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /plugin/src/components/Card/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { BaseProps } from '~/types' 2 | 3 | export type CardType = 'default' | 'primary' | 'plain' 4 | 5 | interface RenderParams { 6 | Extra?: React.ReactNode 7 | } 8 | 9 | export interface HtCardProps extends BaseProps { 10 | title?: string 11 | description?: string 12 | extra?: React.ReactNode[] 13 | bordered?: boolean 14 | // 是否渲染为Card 15 | isCard?: boolean 16 | /** 17 | * 为了支持更多到卡片类型, 添加一个cardType属性, 原有到isCard属性继续兼容 18 | */ 19 | cardType?: CardType 20 | render?: (v: RenderParams) => React.ReactNode 21 | } 22 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Checkbox/ModalAddOption/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { FormComponentProps } from 'antd/es/form' 2 | import { WrappedFormUtils } from 'antd/es/form/Form' 3 | import { ExtraOption } from '../interface' 4 | 5 | export type form = WrappedFormUtils 6 | 7 | export interface ModalAddOptionProps extends FormComponentProps { 8 | visible: boolean 9 | onOpen: () => void 10 | onOk: (formData: ExtraOption) => void 11 | onCancel: () => void 12 | options: ExtraOption[] 13 | width?: number 14 | title?: string 15 | isPlainOption?: boolean 16 | } 17 | -------------------------------------------------------------------------------- /scripts/online_client.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source ./scripts/util.sh 4 | 5 | ENV=$1 6 | 7 | if [ ! -n "$ENV" ]; then 8 | ENV="test" 9 | fi 10 | 11 | echo "开始打包client, 打包环境为 $ENV" 12 | 13 | rm -rf ./dist/client 14 | rm -rf ./client/dist 15 | mkdir -p dist/client 16 | 17 | echo "install deps" 18 | cd ./client 19 | yarn 20 | echo "build source" 21 | yarn build 22 | echo "build success" 23 | cd .. 24 | 25 | cp -R -f client/dist/* dist/client/ 26 | echo "build end" 27 | 28 | echo "push source" 29 | scp -r dist/client/* $ACCOUNT:/data/www/hetu-client 30 | echo "push success" 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | logs/ 2 | npm-debug.log 3 | yarn-error.log 4 | node_modules/ 5 | coverage/ 6 | .idea/ 7 | run/ 8 | .DS_Store 9 | *.sw* 10 | *.un~ 11 | dist/* 12 | mochawesome-report/ 13 | 14 | # 屏蔽编译ts后生成的js/js.map文件 15 | server/app/**/*.js 16 | server/app/**/*.js.map 17 | server/src/**/*.js 18 | server/src/**/*.js.map 19 | server/dist/**/*.js 20 | server/dist/**/*.js.map 21 | 22 | # 忽略编译出来的静态文件 23 | server/app/public/ 24 | # 自带的index.html会在线上打包时被覆盖掉, 所以没有问题 25 | server/dist 26 | client/dist 27 | 28 | client/.env.local 29 | .history 30 | .vscode 31 | 32 | # 系统配置文件 33 | system_config.ini 34 | -------------------------------------------------------------------------------- /client/src/routes/GuiEditor/index.less: -------------------------------------------------------------------------------- 1 | .page-guiEditor-layout { 2 | background-color: #262626; 3 | color: #fff; 4 | font-size: 14px; 5 | width: 100%; 6 | } 7 | 8 | .page-guiEditor { 9 | width: 100vw; 10 | height: 100vh; 11 | 12 | .ht-layout-header, 13 | .ht-layout-sider, 14 | .ht-layout-content { 15 | background-color: transparent; 16 | } 17 | } 18 | 19 | a.is-disabled { 20 | cursor: not-allowed; 21 | color: hsla(0, 0%, 100%, 0.7); 22 | 23 | &:focus, 24 | &:hover, 25 | &:active, 26 | &:visited { 27 | color: hsla(0, 0%, 100%, 0.7); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /plugin/src/components/Divider/__editor__/properties.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types/index' 2 | import baseProperty from '~/components/Field/types/baseProperty' 3 | import _ from 'lodash' 4 | 5 | const config: Editor.BaseProperties = { 6 | title: { 7 | title: '标题', 8 | type: 'string', 9 | }, 10 | orientation: { 11 | title: '标题位置', 12 | type: 'enum', 13 | enumList: ['left', 'center', 'right'], 14 | enumDescriptionList: ['左', '中', '右'], 15 | defaultValue: 'left', 16 | }, 17 | ..._.pick(baseProperty, ['colProps']), 18 | } 19 | 20 | export default config 21 | -------------------------------------------------------------------------------- /scripts/online_plugin.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source ./scripts/util.sh 4 | 5 | ENV=$1 6 | 7 | if [ ! -n "$ENV" ]; then 8 | ENV="test" 9 | fi 10 | 11 | echo "开始打包plugin, 打包环境为 $ENV" 12 | 13 | rm -rf ./dist/plugin 14 | rm -rf ./plugin/dist 15 | mkdir -p dist/plugin 16 | 17 | echo "install deps" 18 | cd ./plugin 19 | yarn 20 | echo "build source" 21 | yarn build:umd 22 | 23 | echo "build success" 24 | cd .. 25 | 26 | cp -R -f plugin/dist/* dist/plugin/ 27 | echo "build end" 28 | 29 | echo "push source" 30 | scp -r dist/plugin/* $ACCOUNT:/data/www/hetu-plugin 31 | echo "push success" 32 | -------------------------------------------------------------------------------- /plugin/site/docs/editor/03-page-publish.md: -------------------------------------------------------------------------------- 1 | --- 2 | category: 详细教程 3 | order: 5 4 | title: 五.发布上线 5 | --- 6 | 7 | 为了保证数据来源的唯一性, 只允许在测试环境编辑页面配置。 8 | 9 | ## 上线流程 10 | 11 | ![](https://user-gold-cdn.xitu.io/2019/8/16/16c987c63e601ece?w=701&h=382&f=png&s=38177) 12 | 13 | ### 1. 测试环境 14 | 15 | - 选中准备上线的页面(确保测试环境已发布) 16 | - 批量下载 17 | ![](https://user-gold-cdn.xitu.io/2019/8/16/16c98689f8690325?w=1049&h=591&f=png&s=68440) 18 | 19 | ### 2. 线上环境 20 | 21 | - 导入页面配置 22 | - 根据页面状态, 选择刚刚导入的页面 23 | - 批量发布 24 | ![](https://user-gold-cdn.xitu.io/2019/8/16/16c986b931aba956?w=1050&h=591&f=png&s=80397) 25 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Divider/__editor__/properties.ts: -------------------------------------------------------------------------------- 1 | import _ from 'lodash' 2 | import baseProperty from '~/components/Field/types/baseProperty' 3 | import { Editor } from '~/types' 4 | const config: Editor.BaseProperties = { 5 | title: { 6 | title: '标题', 7 | type: 'string', 8 | }, 9 | orientation: { 10 | title: '标题位置', 11 | type: 'enum', 12 | enumList: ['left', 'center', 'right'], 13 | enumDescriptionList: ['左', '中', '右'], 14 | defaultValue: 'left', 15 | }, 16 | ..._.pick(baseProperty, 'colProps'), 17 | } 18 | 19 | export default config 20 | -------------------------------------------------------------------------------- /plugin/src/components/Form/demo/buttons.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 3 3 | title: 三种按钮 4 | --- 5 | 6 | 提供三种基本的按钮 提交:`submit reset back jumpTo`, 同时也支持自定义按钮。 7 | 8 | ```jsx 9 | import Hetu from 'hetu' 10 | 11 | const elementConfig = { 12 | type: 'HtForm', 13 | props: { 14 | url: '/api/list/download?ids=123', 15 | fields: [ 16 | { 17 | field: 'name', 18 | title: '姓名', 19 | }, 20 | ], 21 | buttons: ['reset', 'submit', 'back', 'download'], 22 | }, 23 | children: [], 24 | } 25 | 26 | ReactDOM.render(, mountNode) 27 | ``` 28 | -------------------------------------------------------------------------------- /server/src/config/redis.ts: -------------------------------------------------------------------------------- 1 | import prodConfig from '~/src/config/_prod' 2 | import env from '~/src/config/env' 3 | import _ from 'lodash' 4 | 5 | const { host, port, db, password } = _.get(prodConfig, 'redis') 6 | 7 | interface RedisConfig { 8 | host: string 9 | port: number 10 | db: number 11 | password?: string 12 | retry_delay: number 13 | } 14 | 15 | const dev: RedisConfig = { 16 | host, 17 | port, 18 | db, 19 | password, 20 | retry_delay: 1000, 21 | } 22 | 23 | const config = { 24 | dev, 25 | test: dev, 26 | prod: dev, 27 | } 28 | 29 | export default config[env] 30 | -------------------------------------------------------------------------------- /client/src/components/Exception/typeConfig.ts: -------------------------------------------------------------------------------- 1 | const config = { 2 | 403: { 3 | img: '//file.ljcdn.com/hetu-cdn/1557744577067.6889e8c80d32a4cc7574e70150594320.png', 4 | title: '403', 5 | desc: '抱歉,你无权访问该页面', 6 | }, 7 | 404: { 8 | img: '//file.ljcdn.com/hetu-cdn/1557744599553.bc5795db2c6ff54b41b645cc261006f2.png', 9 | title: '404', 10 | desc: '抱歉,你访问的页面不存在', 11 | }, 12 | 500: { 13 | img: '//file.ljcdn.com/hetu-cdn/1557744613778.be1105502172e686c980856fe5b939ed.png', 14 | title: '500', 15 | desc: '抱歉,服务器出错了', 16 | }, 17 | } 18 | 19 | export default config 20 | -------------------------------------------------------------------------------- /client/src/routes/GuiEditor/components/SiderRight/interface.ts: -------------------------------------------------------------------------------- 1 | import { IPageConfig } from '~/types/models/global' 2 | import { ConnectProps, ConnectState } from '~/types/models/connect' 3 | import { activeTab, selectedComponentData } from '~/types/models/guiEditor' 4 | 5 | export { ConnectState, selectedComponentData } 6 | 7 | export interface Props extends ConnectProps { 8 | projectId: number 9 | pageId: number 10 | activeTab: activeTab 11 | isLockIframe: boolean 12 | pageConfig: IPageConfig 13 | selectedComponentData: selectedComponentData 14 | } 15 | 16 | export interface State {} 17 | -------------------------------------------------------------------------------- /plugin/gulpfile.js/copy-docs.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp') 2 | const chalk = require('chalk') 3 | const del = require('del') 4 | 5 | async function cleanDocs(cb) { 6 | await del(['site/components/**/*']) 7 | cb() 8 | } 9 | 10 | function copyDocs(cb) { 11 | gulp 12 | .src('src/components/**/*.md') 13 | .pipe(gulp.dest('site/components')) 14 | cb() 15 | } 16 | 17 | if (process.argv.indexOf('-w') !== -1) { 18 | console.log(chalk.blue('正在监听文件变化')) 19 | gulp.watch('src/components/**/*.md', { delay: 1000 }, copyDocs) 20 | } 21 | 22 | exports.default = gulp.series(cleanDocs, copyDocs) 23 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/InputNumber/__editor__/properties.ts: -------------------------------------------------------------------------------- 1 | import _ from 'lodash' 2 | import BaseProperty from '~/components/Field/types/baseProperty' 3 | import { Editor } from '~/types' 4 | let a: Editor.BaseProperties = { 5 | ..._.omit(BaseProperty, ['required', 'disabled']), 6 | defaultValue: { 7 | title: '默认值', 8 | type: 'number', 9 | }, 10 | min: { 11 | title: '最小值', 12 | type: 'number', 13 | }, 14 | max: { 15 | title: '最大值', 16 | type: 'number', 17 | }, 18 | ..._.pick(BaseProperty, ['required', 'disabled']), 19 | } 20 | 21 | export default a 22 | -------------------------------------------------------------------------------- /server/src/config/mysql_env.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * === mysql env config === 3 | * 默认和env相同, 只有当主动传入NODE_MYSQL_ENV参数时, 才会使用NODE_MYSQL_ENV中的值替代env 4 | * 5 | * 通过分离数据库环境配置, 以支持在测试环境中使用线上数据+测试环境接口进行访问 6 | * 7 | * created at: Thu Nov 30 2017 17:35:34 GMT+0800 (CST) 8 | */ 9 | 10 | import env from '~/src/config/env' 11 | let mysql_env: 'dev' | 'test' | 'prod' = env 12 | switch (process.env.NODE_MYSQL_ENV) { 13 | case 'dev': 14 | case 'test': 15 | case 'prod': 16 | mysql_env = process.env.NODE_MYSQL_ENV 17 | break 18 | default: 19 | mysql_env = env 20 | } 21 | 22 | export default mysql_env 23 | -------------------------------------------------------------------------------- /plugin/site/docs/editor/02-scenarios.md: -------------------------------------------------------------------------------- 1 | --- 2 | category: 接入必看 3 | order: 0 4 | title: 使用场景 5 | --- 6 | 7 | - PC端、后台管理系统 8 | - 数据增、删、改、查页面 9 | - 图表展示页面 10 | 11 | ## 支持的页面模版 12 | 13 | 目前支持 `列表页`、`表单页`、`图表`、`多标签页` 等模版。 14 | 15 | ### 搜索+列表展示 16 | 17 | ![搜索+列表展示](https://user-gold-cdn.xitu.io/2019/6/3/16b1c406089692a0?w=1363&h=761&f=png&s=117988) 18 | 19 | ### 表单编辑 20 | 21 | 页面由`表单项+按钮`构成 22 | ![](https://user-gold-cdn.xitu.io/2019/6/3/16b1c4b17271a680?w=1364&h=763&f=png&s=52742) 23 | 24 | ### 图形化展示 25 | 26 | ![](https://user-gold-cdn.xitu.io/2019/11/13/16e6462123dd77df?w=2214&h=990&f=png&s=120008) 27 | 28 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/PickerDateTime/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { observer } from 'mobx-react' 3 | 4 | import PickerDate from '~/components/Field/components/PickerDate' 5 | import { HtDatePickerProps } from '~/components/Field/components/PickerDate/interface' 6 | 7 | @observer 8 | class PickerDateTime extends React.Component { 9 | static defaultProps = { 10 | format: 'YYYY-MM-DD HH:mm:ss', 11 | showToday: true, 12 | } 13 | 14 | render() { 15 | return 16 | } 17 | } 18 | 19 | export default PickerDateTime 20 | -------------------------------------------------------------------------------- /server/src/config/mysql.ts: -------------------------------------------------------------------------------- 1 | // mysql 配置。 mysql 使用参见 https://dev.mysql.com/doc/refman/8.0/en/ 2 | import prodConfig from '~/src/config/_prod' 3 | import mysql_env from '~/src/config/mysql_env' 4 | import _ from 'lodash' 5 | 6 | const { host, port, user, password, database } = _.get(prodConfig, 'mysql') 7 | 8 | // 开发环境配置 9 | const dev = { 10 | // host 11 | host, 12 | // 端口号 13 | port, 14 | // 用户名 15 | user, 16 | // 密码 17 | password, 18 | // 数据库名 19 | database, 20 | } 21 | 22 | let config = { 23 | dev, 24 | test: dev, 25 | prod: dev, 26 | } 27 | 28 | export default config[mysql_env] 29 | -------------------------------------------------------------------------------- /scripts/util.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ConfigFile="./system_config.ini" 4 | 5 | function ReadINIfile() 6 | { 7 | Key=$1 8 | Section=$2 9 | ReadINI=`awk -F '=' '/\['$Section'\]/{a=1}a==1&&$1~/'$Key'/{gsub(/ /,"",$2);print $2;exit}' $ConfigFile` 10 | echo "$ReadINI" 11 | } 12 | 13 | for key in "ssh_user" "ssh_ip" 14 | do 15 | val=`ReadINIfile "$key" "ssh"` 16 | if [ -z "$val" ]; then 17 | echo "[ssh] $key 配置不存在" 18 | exit 1 19 | fi 20 | done 21 | 22 | USER=`ReadINIfile "ssh_user" "ssh"` 23 | IP=`ReadINIfile "ssh_ip" "ssh"` 24 | 25 | ACCOUNT=$USER"@"$IP 26 | 27 | echo "ssh账号为"$ACCOUNT 28 | 29 | 30 | -------------------------------------------------------------------------------- /client/src/routes/Home/interface.d.ts: -------------------------------------------------------------------------------- 1 | import * as H from 'history' 2 | import { IPageConfig, IPaneItem, IUserInfo, IProjectDetail } from '~/types/models/global' 3 | 4 | export { IProjectDetail } 5 | 6 | export interface PageHomeProps { 7 | history: H.History 8 | } 9 | 10 | export interface PageHomeState { 11 | isCloneModalVisible: boolean 12 | isPageInit: boolean 13 | isLocalPage: boolean 14 | errorMessage?: string 15 | 16 | pageConfig?: IPageConfig 17 | projectDetail?: IProjectDetail 18 | userInfo?: IUserInfo 19 | 20 | activePanekey?: string 21 | panes: IPaneItem[] 22 | uniqueKey: string 23 | } 24 | -------------------------------------------------------------------------------- /plugin/README.md: -------------------------------------------------------------------------------- 1 | 河图组件库 2 | 3 | ## 本地开发 4 | ``` 5 | # 进入plugin目录 6 | cd ./plugin 7 | 8 | # 安装依赖 9 | yarn 10 | 11 | # 打包输出esm模块 12 | yarn build 13 | 14 | # 安装文档依赖 15 | cd ./site & yarn 16 | 17 | # 启动文档服务 18 | yarn start 19 | ``` 20 | 21 | ## 编辑器调试 22 | ``` 23 | 打包输出umd模块 24 | yarn build:umd 25 | 26 | # 启动静态服务, 27 | yarn start:dist 28 | ``` 29 | 30 | 打开 [河图页面](http://139.155.239.172:9536), 同时打开Chrome调试工具面板, 在`Local Storage`中设置 31 | > `hetu-cdn-public` 为`http://127.0.0.1:8888` 32 | 33 | 刷新页面, 查看`network`面板, 看到已经加载了本地资源 34 | ![](https://user-gold-cdn.xitu.io/2020/5/14/17212a5ba3e0be89?w=2184&h=678&f=png&s=210751) 35 | -------------------------------------------------------------------------------- /plugin/src/index.ts: -------------------------------------------------------------------------------- 1 | // fix: Input.Password ConfigProvider prefixCls not work 2 | import 'antd/lib/input/style/index.css' 3 | // https://github.com/ant-design/ant-design/issues/15260 4 | import 'antd/lib/button/style/index.css' 5 | import 'antd/lib/message/style/index.css' 6 | import 'antd/lib/modal/style/index.css' 7 | import 'antd/lib/notification/style/index.css' 8 | import 'regenerator-runtime/runtime' 9 | 10 | export * from './components/editorConfigs' 11 | export * from './components/index' 12 | export * from './templates' 13 | export { Hetu as default } from './Hetu' 14 | export { customRequest } from './utils/request' 15 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Divider/index.tsx: -------------------------------------------------------------------------------- 1 | import { Divider } from 'antd' 2 | import { observer } from 'mobx-react' 3 | import React, { Component } from 'react' 4 | import { Props } from './interface' 5 | 6 | export class HtDivider extends Component { 7 | static displayName = 'HtDivider' 8 | 9 | static defaultProps = { 10 | dashed: false, 11 | orientation: 'left', 12 | type: 'horizontal', 13 | } 14 | 15 | render() { 16 | const { title, pagestate, ...rest } = this.props 17 | return {title} 18 | } 19 | } 20 | 21 | export default observer(HtDivider) 22 | -------------------------------------------------------------------------------- /plugin/site/docs/editor/03-page-debug.md: -------------------------------------------------------------------------------- 1 | --- 2 | category: 详细教程 3 | order: 4 4 | title: 四.异常处理 5 | --- 6 | 7 | 配置页面过程中, 经常遇到页面白屏或者菊花 loading, 90%的可能是接口错误, 可按照如下步骤排查错误。 8 | 9 | ##  接口异常 10 | 11 | ### 1. 检查网络请求 12 | 13 | 鼠标右键, 点击检查 14 | 然后依次打开`Network XHR`面板, 查看接口响应状态码是否异常. `2xx 3xx`通常表示成功,`4xx 5xx`通常表示异常。 15 | ![](https://user-gold-cdn.xitu.io/2019/7/4/16bbb09224fb005e?w=918&h=302&f=png&s=64690) 16 | 17 | ### 2. 查看错误详情 18 | 19 | > 河图对错误请求进行了处理, 会返回详情的错误信息。 20 | > ![](https://user-gold-cdn.xitu.io/2020/3/20/170f75330c67821a?w=2734&h=978&f=png&s=256037) 21 | 22 | ## 接口正常, 页面异常 23 | 24 | - 1. 检查 [接口格式](/docs/editor/02-request) 25 | -------------------------------------------------------------------------------- /plugin/site/theme/style/core/motion/fade.less: -------------------------------------------------------------------------------- 1 | .fade-motion(@className, @keyframeName) { 2 | .make-motion(@className, @keyframeName); 3 | .@{className}-enter, 4 | .@{className}-appear { 5 | opacity: 0; 6 | animation-timing-function: linear; 7 | } 8 | .@{className}-leave { 9 | animation-timing-function: linear; 10 | } 11 | } 12 | 13 | .fade-motion(fade, antFade); 14 | 15 | @keyframes antFadeIn { 16 | 0% { 17 | opacity: 0; 18 | } 19 | 100% { 20 | opacity: 1; 21 | } 22 | } 23 | 24 | @keyframes antFadeOut { 25 | 0% { 26 | opacity: 1; 27 | } 28 | 100% { 29 | opacity: 0; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /plugin/site/theme/template/Layout/SentryBoundary.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | export default class SentryBoundary extends Component { 4 | state = { error: null }; 5 | 6 | componentDidCatch(error, errorInfo) { 7 | this.setState({ error }); 8 | } 9 | 10 | render() { 11 | const { children } = this.props; 12 | const { error } = this.state; 13 | if (error) { 14 | // render fallback UI 15 | return Sentry.showReportDialog()}>Report feedback; 16 | } 17 | // when there's not an error, render children untouched 18 | return children; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /client/src/routes/Templates/components/Card/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { FormComponentProps } from 'antd/es/form' 2 | import { ConnectProps, ConnectState } from '~/types/models/connect' 3 | 4 | export interface templateData { 5 | id: '/project/template/list/1' 6 | desc: '搜索+列表' 7 | imgUrl: string 8 | config: any 9 | } 10 | 11 | export interface TheCardProps extends FormComponentProps, ConnectProps { 12 | data: templateData 13 | projectDetail: dynamicObject 14 | } 15 | 16 | export interface TheCardState { 17 | isHover: boolean 18 | isModalVisible: boolean 19 | templateData: dynamicObject 20 | isTempModalVisible: boolean 21 | } 22 | -------------------------------------------------------------------------------- /plugin/src/components/Exception/typeConfig.ts: -------------------------------------------------------------------------------- 1 | const config = { 2 | 403: { 3 | img: 4 | 'http://file.ljcdn.com/hetu-cdn/1557744577067.6889e8c80d32a4cc7574e70150594320.png', 5 | title: '403', 6 | desc: '抱歉,你无权访问该页面', 7 | }, 8 | 404: { 9 | img: 10 | 'http://file.ljcdn.com/hetu-cdn/1557744599553.bc5795db2c6ff54b41b645cc261006f2.png', 11 | title: '404', 12 | desc: '抱歉,你访问的页面不存在', 13 | }, 14 | 500: { 15 | img: 16 | 'http://file.ljcdn.com/hetu-cdn/1557744613778.be1105502172e686c980856fe5b939ed.png', 17 | title: '500', 18 | desc: '抱歉,服务器出错了', 19 | }, 20 | } 21 | 22 | export default config 23 | -------------------------------------------------------------------------------- /plugin/site/docs/editor/06-senior-formdata.md: -------------------------------------------------------------------------------- 1 | --- 2 | category: 高级用法 3 | order: 0 4 | title: 获取表单值 5 | --- 6 | 7 | 表单的值, 可通过以下别名获取。 8 | 9 | ## 何时使用 10 | - 多个表单相互联动 11 | 12 | ### 表单值别名 13 | > 可通过控制台输入`window.$$pagestate`查看 14 | 15 | - `$$HtList` 搜索表单 16 | - `$$HtModalForm` 右上角弹框表单 17 | - `$$HtFormResponse` 搜索接口返回值 18 | - `$$tableRowModalFormData` 当前行数据, 用于列数据编辑 19 | - `$$tableSelectionRowKeys` 批量选中的id 20 | 21 | ![](https://user-gold-cdn.xitu.io/2020/3/20/170f6d51b56c429d?w=2210&h=1298&f=png&s=314286) 22 | 23 | - `$$HtForm` 24 | - `$$HtFormResponse` 25 | ![](https://user-gold-cdn.xitu.io/2020/3/20/170f6dab25d4ac58?w=2224&h=1022&f=png&s=91150) 26 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/JsonEditor/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | category: Components 3 | type: Field 表单项 4 | title: JsonEditor json编辑器 5 | cols: 1 6 | order: 16 7 | --- 8 | 9 | [河图演示地址](http://139.155.239.172:9536/guiedit?route=%2Fproject%2Fhetu_demo%2Fhetu%2Fdemo%2FJsonEditor) 10 | 11 | 适用于编辑数据类型不确定的动态数据。 12 | 13 | ## API 14 | 15 | ### Input 16 | 17 | | 参数 | 说明 | 类型 | 默认值 | 18 | | ------------ | ---------- | ------- | ------ | 19 | | defaultValue |  默认值 | string | - | 20 | | value |  默认值 | string | - | 21 | | height | 输入框高度 | number | 100 | 22 | | disabled | 禁用 | boolean | false | 23 | -------------------------------------------------------------------------------- /plugin/site/theme/template/Content/ErrorBoundary.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Alert } from 'antd' 3 | 4 | export default class ErrorBoundary extends React.Component { 5 | state = { 6 | error: null, 7 | } 8 | 9 | componentDidCatch(error, info) { 10 | this.setState({ error, info }) 11 | } 12 | 13 | render() { 14 | const { children } = this.props 15 | const { error, info } = this.state 16 | if (error) { 17 | // You can render any custom fallback UI 18 | return 19 | } 20 | return children || null 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /plugin/src/components/ModalForm/demo/basic.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 0 3 | title: 基本用法 4 | --- 5 | 6 | ```jsx 7 | import Hetu from 'hetu' 8 | 9 | const elementConfig = { 10 | type: 'HtModalForm', 11 | props: { 12 | url: '/api/form/update', 13 | fields: [ 14 | { 15 | field: 'name', 16 | title: '姓名', 17 | }, 18 | { 19 | field: 'age', 20 | title: '年龄', 21 | type: 'InputNumber', 22 | }, 23 | ], 24 | title: '弹框表单', 25 | triggerButtonText: '点我', 26 | buttonType: 'primary', 27 | }, 28 | } 29 | 30 | ReactDOM.render(, mountNode) 31 | ``` 32 | -------------------------------------------------------------------------------- /plugin/site/theme/style/core/motion.less: -------------------------------------------------------------------------------- 1 | @import '../style/themes/default.less'; 2 | @import '../mixins/motion'; 3 | @import 'motion/fade'; 4 | @import 'motion/move'; 5 | @import 'motion/other'; 6 | @import 'motion/slide'; 7 | @import 'motion/swing'; 8 | @import 'motion/zoom'; 9 | 10 | // For common/openAnimation 11 | .@{ant-prefix}-motion-collapse-legacy { 12 | overflow: hidden; 13 | &-active { 14 | transition: height 0.15s @ease-in-out, opacity 0.15s @ease-in-out !important; 15 | } 16 | } 17 | 18 | .@{ant-prefix}-motion-collapse { 19 | overflow: hidden; 20 | transition: height 0.15s @ease-in-out, opacity 0.15s @ease-in-out !important; 21 | } 22 | -------------------------------------------------------------------------------- /client/src/routes/Home/Layout/Basic/SiderMenu/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { RouteComponentProps } from 'react-router' 2 | import { IUserInfo, IProjectDetail } from '~/types/models/global' 3 | import * as H from 'history' 4 | 5 | export interface menuItem { 6 | path: string 7 | icon: string 8 | key: string 9 | name?: string 10 | hideInMenu?: boolean 11 | target?: string 12 | children?: menuItem[] 13 | } 14 | 15 | export interface TheSiderMenuProps { 16 | history: H.History 17 | projectDetail: IProjectDetail 18 | } 19 | 20 | export interface TheSiderMenuState { 21 | flatMenuKeys?: string[] 22 | openKeys?: string[] 23 | collapsed: boolean 24 | } 25 | -------------------------------------------------------------------------------- /client/src/utils/valid.ts: -------------------------------------------------------------------------------- 1 | import { isString, isArray, isPlainObject } from 'lodash' 2 | 3 | /** 4 | * 验证是否为一个组件配置 5 | * @param {any} v 6 | * @returns {Boolean} 7 | */ 8 | export function isElementConfig(v: any): boolean { 9 | if (v === null) return true 10 | 11 | if (!isPlainObject(v)) return false 12 | 13 | const { type, props } = v 14 | 15 | if (isString(type) && isPlainObject(props)) { 16 | return true 17 | } 18 | } 19 | 20 | export function isPageConfig(v: any): boolean { 21 | if (!isPlainObject(v)) return false 22 | 23 | const { elementConfig } = v 24 | if (!isElementConfig(elementConfig)) return false 25 | 26 | return true 27 | } 28 | -------------------------------------------------------------------------------- /plugin/src/components/Field/types/baseProperty.ts: -------------------------------------------------------------------------------- 1 | import { Editor } from '~/types' 2 | import { 3 | colProps, 4 | defaultValue, 5 | disabled, 6 | extra, 7 | field, 8 | onChangeRequests, 9 | placeholder, 10 | required, 11 | setFieldValues, 12 | title, 13 | triggerOnChanges, 14 | visible, 15 | } from './commonPropsDefine' 16 | 17 | const baseProperty: Editor.BaseProperties = { 18 | field, 19 | title, 20 | placeholder, 21 | extra, 22 | defaultValue, 23 | required, 24 | disabled, 25 | 'v-if': visible, 26 | colProps, 27 | onChangeRequests, 28 | setFieldValues, 29 | triggerOnChanges, 30 | } 31 | 32 | export default baseProperty 33 | -------------------------------------------------------------------------------- /plugin/src/components/Tabs/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { TabsPosition, TabsType } from 'antd/es/tabs' 2 | import { HtCardProps } from '~/components/Card/interface' 3 | import { BaseProps } from '~/types' 4 | 5 | export interface Tab { 6 | title: string 7 | value: string 8 | disabled?: boolean 9 | // 显示当前第几个子节点, 为空时, 显示全部 10 | showIndexs: number[] 11 | } 12 | 13 | export interface ListComponentProps extends BaseProps, HtCardProps { 14 | defaultActiveKey?: string 15 | tabsType?: TabsType 16 | tabsPosition?: TabsPosition 17 | tabBarStyle?: object 18 | tabs: Tab[] 19 | content: React.ReactNode[] 20 | } 21 | 22 | // export interface ListComponentState {} 23 | -------------------------------------------------------------------------------- /server/src/middleware/multi-form.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response, NextFunction } from 'express' 2 | import { Middleware, ExpressMiddlewareInterface } from 'routing-controllers' 3 | // @ts-ignore 4 | import multipart from 'connect-multiparty' 5 | 6 | const multipartMiddleware = multipart() 7 | 8 | /** 9 | * 通用文件上传中间件 10 | */ 11 | @Middleware({ type: 'before' }) 12 | class multiFormMiddleware implements ExpressMiddlewareInterface { 13 | async use(req: Request, res: Response, next: NextFunction) { 14 | if (req.path !== '/api/upload') { 15 | return multipartMiddleware(req, res, next) 16 | } 17 | next() 18 | } 19 | } 20 | 21 | export default multiFormMiddleware 22 | -------------------------------------------------------------------------------- /plugin/site/theme/template/Content/EditButton.jsx: -------------------------------------------------------------------------------- 1 | import { Icon, Tooltip } from 'antd'; 2 | import React from 'react'; 3 | 4 | const branchUrl = 'http://github.com/LianjiaTech/hetu/tree/master'; 5 | 6 | export default function EditButton({ title, filename }) { 7 | let href = `${branchUrl}/site/${filename}` 8 | if (/^components\//.test(filename)) { 9 | href = `${branchUrl}/src/${filename}` 10 | } 11 | return ( 12 | 13 | 19 | 20 | 21 | 22 | ); 23 | } 24 | -------------------------------------------------------------------------------- /plugin/src/components/Card/components/Primary/index.tsx: -------------------------------------------------------------------------------- 1 | import { Alert } from 'antd' 2 | import React from 'react' 3 | import { Props } from './interface' 4 | 5 | export default class CardPrimary extends React.Component { 6 | static displayName = 'CardPrimary' 7 | 8 | static defaultProps = {} 9 | 10 | state = {} 11 | 12 | renderHeader = () => { 13 | const { title, subtitle } = this.props 14 | return 15 | } 16 | 17 | render() { 18 | const { children } = this.props 19 | return ( 20 |
21 | {this.renderHeader()} 22 | {children} 23 |
24 | ) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /plugin/site/theme/static/index.less: -------------------------------------------------------------------------------- 1 | @import '../style/v2-compatible-reset.less'; 2 | @import '../style/themes/default.less'; 3 | @import './common'; 4 | @import './header'; 5 | @import './footer'; 6 | @import './home'; 7 | @import './page-nav'; 8 | @import './markdown'; 9 | @import './resource'; 10 | @import './preview-img'; 11 | @import './toc'; 12 | @import './not-found'; 13 | @import './highlight'; 14 | @import './demo'; 15 | @import './colors'; 16 | @import './icons'; 17 | @import './mock-browser'; 18 | @import './new-version-info-modal'; 19 | @import './motion'; 20 | @import './responsive'; 21 | @import './theme'; 22 | @import './docsearch'; 23 | @import './nprogress'; 24 | @import './santa'; 25 | -------------------------------------------------------------------------------- /server/src/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 河图 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /plugin/site/theme/template/NotFound.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from 'bisheng/router'; 3 | import * as utils from './utils'; 4 | 5 | export default function NotFound({ location }) { 6 | return ( 7 |
8 |
9 |

404

10 |

11 | 你要找的页面不存在 12 | 13 | 返回首页 14 | 15 |

16 |
17 | 18 | 19 | 20 | 21 | 22 |
23 | {{ content | safe }} 24 |
25 | {% for jsFile in manifest["js"] %} 28 | {% endfor %} 29 | 30 | 31 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Radio/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { RadioChangeEvent } from 'antd/lib/radio' 2 | import { ExtraOption } from '../Checkbox/interface' 3 | import { BaseProps, JsonSchema } from '~/types' 4 | 5 | export { ExtraOption } 6 | 7 | export type HtRadioValue = string | number | boolean 8 | 9 | export interface HtRadioProps extends BaseProps { 10 | defaultValue?: HtRadioValue 11 | value: HtRadioValue 12 | onChange: (v: RadioChangeEvent) => void 13 | disabled?: boolean 14 | name?: string 15 | buttonStyle?: 'outline' | 'solid' 16 | labelField?: string 17 | valueField?: string 18 | optionsSourceType?: JsonSchema.OptionsSourceType 19 | options?: JsonSchema.HtFieldOption[] 20 | optionsDependencies?: JsonSchema.HtFieldOption[] 21 | // 是否允许动态添加选项 22 | canAddOption?: boolean 23 | } 24 | 25 | export interface HtRadioState { 26 | isModalVisible: boolean 27 | // 用户自己添加的options 28 | extraOptions: ExtraOption[] 29 | } 30 | -------------------------------------------------------------------------------- /client/src/types/components/editConfig.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 属性规范 3 | */ 4 | type InterfaceProperty = { 5 | type: 6 | | 'enum' // 枚举类型 7 | | 'object' // 对象 8 | | 'array' // 普通数组 9 | | 'arrayOf' // 对象数组 10 | | 'string' // 字符串 11 | | 'image' // 图片 12 | | 'number' // 数字 13 | | 'color' // 颜色选择器 14 | | 'richtext' // 富文本 15 | | 'bool' // 布尔值 16 | | 'date' // 日期 17 | | 'url' // url 18 | 19 | /** 20 | * 属性名称 21 | */ 22 | title: string 23 | /** 24 | * 属性描述, 作为问号出现在属性左侧, 用于提示用户该属性的含义 25 | */ 26 | desc?: string 27 | /** 28 | * 文档地址 29 | */ 30 | doc?: string 31 | /** 32 | * 默认值, 只有基础类型会有默认值 33 | */ 34 | defaultValue?: string | number | boolean 35 | properties?: { 36 | [datakey: string]: InterfaceProperty 37 | } 38 | } 39 | 40 | type TypeEditConfig = { 41 | [propKey: string]: InterfaceProperty 42 | } 43 | export default TypeEditConfig 44 | 45 | export { InterfaceProperty, TypeEditConfig } 46 | -------------------------------------------------------------------------------- /server/src/library/mysql/index.ts: -------------------------------------------------------------------------------- 1 | import sqlconfig from '~/src/config/mysql' 2 | import knex from 'knex' 3 | 4 | const Knex = knex({ 5 | client: 'mysql', 6 | connection: { 7 | host: sqlconfig.host, 8 | // @ts-ignore 9 | port: sqlconfig.port, 10 | database: sqlconfig.database, 11 | user: sqlconfig.user, 12 | password: sqlconfig.password, 13 | }, 14 | debug: false, 15 | pool: { 16 | max: 10, 17 | min: 0, 18 | // 由于存在资源池, 导致句柄不被释放, 程序不能退出 19 | // 因此将最小句柄数设为0, 每100ms检查一次是否有超过120ms未被使用的资源 20 | // 以便句柄的及时回收 21 | // free resouces are destroyed after this many milliseconds 22 | idleTimeoutMillis: 100, 23 | // how often to check for idle resources to destroy 24 | reapIntervalMillis: 150, 25 | }, 26 | acquireConnectionTimeout: 60000, 27 | //@ts-ignore 28 | log: { 29 | error(message: string) { 30 | console.error(`数据库操作异常 => ${message}`) 31 | }, 32 | }, 33 | }) 34 | 35 | export default Knex 36 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Radio/demo/basic.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 0 3 | title: 基本使用 4 | --- 5 | 6 | - `defaultValue` 设置默认值 7 | - `options` 下拉框选项 8 | - `canAddOption` 允许动态添加选项 9 | 10 | ```jsx 11 | import Hetu from 'hetu' 12 | 13 | const elementConfig = { 14 | type: 'HtForm', 15 | props: { 16 | url: '/', 17 | buttons: [], 18 | fields: [ 19 | { 20 | field: 'sex', 21 | title: '性别', 22 | type: 'Radio', 23 | canAddOption: true, 24 | options: ['男', '女'], 25 | }, 26 | { 27 | field: 'sex', 28 | title: '是否禁用', 29 | type: 'Radio', 30 | options: [ 31 | { 32 | label: '是', 33 | value: 1, 34 | }, 35 | { 36 | label: '否', 37 | value: 0, 38 | }, 39 | ], 40 | }, 41 | ], 42 | }, 43 | children: [], 44 | } 45 | 46 | ReactDOM.render(, mountNode) 47 | ``` 48 | -------------------------------------------------------------------------------- /plugin/src/components/Steps/demo/container.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 1 3 | title: 作为容器使用 4 | --- 5 | 6 | 可以作为容器使用,展示每一步骤的信息 7 | 8 | ```jsx 9 | import Hetu from 'hetu' 10 | 11 | const elementConfig = { 12 | type: 'HtGuiContainer', 13 | props: { 14 | style: { 15 | padding: '8px', 16 | }, 17 | }, 18 | children: [ 19 | { 20 | type: 'HtSteps', 21 | props: { 22 | current: 0, 23 | direction: 'horizontal', 24 | steps: [ 25 | { 26 | title: 'title1', 27 | description: 'description1', 28 | }, 29 | { 30 | title: 'title2', 31 | description: 'description2', 32 | }, 33 | { 34 | title: 'title3', 35 | description: 'description3', 36 | }, 37 | ], 38 | }, 39 | children: ['第一步', '第二步', '第三步'], 40 | }, 41 | ], 42 | } 43 | 44 | ReactDOM.render(, mountNode) 45 | ``` 46 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Alert/demo/basic.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 0 3 | title: 基本使用 4 | --- 5 | 6 | ```jsx 7 | import Hetu from 'hetu' 8 | 9 | const elementConfig = { 10 | type: 'HtForm', 11 | props: { 12 | url: '/', 13 | buttons: [], 14 | fields: [ 15 | { 16 | title: 'success', 17 | type: 'Alert', 18 | alertType: 'success', 19 | message: 'Success Text', 20 | }, 21 | { 22 | title: 'info', 23 | alertType: 'info', 24 | type: 'Alert', 25 | message: 'Info Text', 26 | }, 27 | { 28 | title: 'warning', 29 | type: 'Alert', 30 | alertType: 'warning', 31 | message: 'Warning Text', 32 | }, 33 | { 34 | title: 'error', 35 | type: 'Alert', 36 | alertType: 'error', 37 | message: 'Error Text', 38 | }, 39 | ], 40 | }, 41 | children: [], 42 | } 43 | 44 | ReactDOM.render(, mountNode) 45 | ``` 46 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Upload/utils.ts: -------------------------------------------------------------------------------- 1 | import _ from 'lodash' 2 | import { HtUploadFile, HtUploadValue } from './interface' 3 | 4 | export const formatFileList = (value: HtUploadValue): HtUploadFile[] => { 5 | if (_.isArray(value)) { 6 | return value 7 | .filter(v => v) 8 | .map((item, index) => { 9 | return { 10 | uid: Math.random() + '-' + index, 11 | status: 'done', 12 | name: item, 13 | url: item, 14 | thumbUrl: item, 15 | } 16 | }) 17 | } 18 | 19 | return [] 20 | } 21 | 22 | export const formatFileList2 = (urls: object[]): HtUploadFile[] => { 23 | if (_.isArray(urls)) { 24 | return urls 25 | .filter(v => v) 26 | .map((item, index) => { 27 | return { 28 | ...item, 29 | // @ts-ignore 30 | name: item.url, 31 | uid: Math.random() + '-' + index, 32 | status: 'done', 33 | } 34 | }) 35 | } 36 | 37 | return [] 38 | } 39 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Checkbox/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { BaseProps, JsonSchema } from '~/types' 2 | export type HtCheckboxValue = (string | number | boolean)[] 3 | 4 | export interface ExtraOption { 5 | label: string 6 | value: number | string | boolean 7 | } 8 | 9 | export interface HtCheckboxProps extends BaseProps { 10 | defaultValue?: HtCheckboxValue 11 | disabled?: boolean 12 | optionsSourceType?: JsonSchema.OptionsSourceType 13 | options?: JsonSchema.HtFieldOption[] 14 | optionsDependencies?: JsonSchema.HtFieldOption[] 15 | value: HtCheckboxValue 16 | onChange: (v: HtCheckboxValue) => void 17 | labelField?: string 18 | valueField?: string 19 | allCheck?: boolean 20 | // 是否允许动态添加选项 21 | canAddOption?: boolean 22 | // 弹框属性配置 23 | addModalConfig?: JsonSchema.DynamicObject 24 | } 25 | 26 | export interface HtCheckboxState { 27 | indeterminate: boolean 28 | checkAll: boolean 29 | isModalVisible: boolean 30 | // 用户自己添加的options 31 | extraOptions: ExtraOption[] 32 | } 33 | -------------------------------------------------------------------------------- /plugin/site/theme/template/IconDisplay/CopyableIcon.jsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import CopyToClipboard from 'react-copy-to-clipboard' 3 | import { Icon as AntdIcon, Badge } from 'antd' 4 | import classNames from 'classnames' 5 | 6 | const Icon = AntdIcon 7 | 8 | const CopyableIcon = ({ type, theme, isNew, justCopied, onCopied }) => { 9 | const className = classNames({ 10 | copied: justCopied === type, 11 | outlined: theme === 'twoTone', 12 | }) 13 | return ( 14 | ` 18 | : `` 19 | } 20 | onCopy={(text) => onCopied(type, text)} 21 | > 22 |
  • 23 | 24 | 25 | {type} 26 | 27 |
  • 28 |
    29 | ) 30 | } 31 | 32 | export default CopyableIcon 33 | -------------------------------------------------------------------------------- /plugin/site/theme/template/Color/ColorBlock.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import CopyToClipboard from 'react-copy-to-clipboard'; 3 | import { message } from 'antd'; 4 | 5 | export default class ColorBlock extends Component { 6 | getTextStyle() { 7 | const { color, index } = this.props; 8 | return { 9 | background: color, 10 | color: index > 5 ? '#fff' : 'unset', 11 | fontWeight: index === 6 ? 'bold' : 'normal', 12 | }; 13 | } 14 | 15 | onCopied = () => { 16 | const { color } = this.props; 17 | message.success(`Copied: ${color}`); 18 | }; 19 | 20 | render() { 21 | const { color, index } = this.props; 22 | return ( 23 | 24 |
    25 | color-{index} 26 | {color.toLowerCase()} 27 |
    28 |
    29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /server/src/task.ts: -------------------------------------------------------------------------------- 1 | require('module-alias').addAlias('~/src', __dirname + '/') 2 | import '@babel/polyfill' 3 | 4 | /* 5 | |-------------------------------------------------------------------------- 6 | | Ace Setup 7 | |-------------------------------------------------------------------------- 8 | | 9 | | Ace is the command line utility to create and run terminal commands. 10 | | Here we setup the environment and register ace commands. 11 | | 12 | */ 13 | // https://adonisjs.com/docs/4.1/installation 14 | // @ts-ignore 15 | import ace from '@adonisjs/ace' 16 | 17 | const registedCommandList = [ 18 | // 任务调度 19 | './commands/task/manage', // 任务调度 20 | './commands/summary/develop_report', // 研发提效报告 21 | './commands/summary/online_report', // 上线报告 22 | ] 23 | 24 | // register commands 25 | for (let command of registedCommandList) { 26 | ace.addCommand(require(command)['default']) 27 | } 28 | 29 | // 引入全局模块 30 | import '~/src/model/global' 31 | 32 | // Boot ace to execute commands 33 | ace.wireUpWithCommander() 34 | ace.invoke() 35 | -------------------------------------------------------------------------------- /client/src/routes/GuiEditor/components/SiderRight/index.module.less: -------------------------------------------------------------------------------- 1 | .the-sider-right { 2 | display: flex; 3 | flex-direction: column; 4 | height: 100vh; 5 | overflow: hidden; 6 | background-color: transparent; 7 | } 8 | 9 | .tabs { 10 | display: flex; 11 | height: 64px; 12 | margin: 0; 13 | border-bottom: 1px solid #000; 14 | } 15 | .tabs-item { 16 | padding: 0 24px; 17 | line-height: 64px; 18 | height: 64px; 19 | cursor: pointer; 20 | user-select: none; 21 | border-right: 1px solid #000; 22 | white-space: nowrap; 23 | overflow: hidden; 24 | color: rgba(255, 255, 255, 0.7); 25 | &.is-selected { 26 | border-bottom: 1px solid #262626; 27 | color: #fff; 28 | } 29 | } 30 | 31 | .the-tip { 32 | color: rgba(255, 255, 255, 0.75); 33 | padding: 8px 16px; 34 | font-size: 13px; 35 | } 36 | 37 | .the-tip-icon { 38 | margin-right: 6px; 39 | font-size: 12px; 40 | } 41 | 42 | .the-base-wrap { 43 | flex: 1; 44 | overflow: auto; 45 | color: rgba(255, 255, 255, 0.75); 46 | padding: 0 16px; 47 | } 48 | -------------------------------------------------------------------------------- /plugin/src/components/List/__editor__/defaultConfig.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | type: 'HtList', 3 | props: { 4 | url: '/mock/api/list', 5 | pageSize: 2, 6 | columns: [ 7 | { 8 | title: 'id', 9 | dataIndex: 'id', 10 | width: 50, 11 | tooltip: '你好', 12 | }, 13 | { 14 | title: 'banner', 15 | dataIndex: 'imageUrl', 16 | width: 60, 17 | renderType: 'img', 18 | sort: true, 19 | }, 20 | { 21 | title: '预览链接', 22 | dataIndex: 'preview', 23 | width: 80, 24 | renderType: 'a', 25 | }, 26 | { 27 | title: '标签', 28 | dataIndex: 'tags', 29 | renderType: 'tag', 30 | width: 100, 31 | isWrapper: true, 32 | }, 33 | { 34 | title: '开关', 35 | dataIndex: 'switch', 36 | renderType: 'switch', 37 | url: '/mock/api/update', 38 | width: 100, 39 | }, 40 | ], 41 | cardType: 'plain', 42 | }, 43 | children: [], 44 | } 45 | -------------------------------------------------------------------------------- /client/typings.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.css' 2 | declare module '*.less' 3 | declare module '*.module.less' 4 | declare module '*.scss' 5 | declare module '*.sass' 6 | declare module '*.svg' 7 | declare module '*.png' 8 | declare module '*.jpg' 9 | declare module '*.jpeg' 10 | declare module '*.gif' 11 | declare module '*.bmp' 12 | declare module '*.tiff' 13 | declare module 'react-css-modules' 14 | declare module 'dva-loading' 15 | 16 | interface Window { 17 | ENV: 'dev' | 'test' | 'prod' 18 | // 父级iframe的名称 19 | $$iframeParentName?: string 20 | $$isEditor?: boolean 21 | $$receiveIframeData?: (v: { type: string; data: dynamicObject }) => void 22 | $$changeIframePageConfig?: (v: dynamicObject) => void 23 | $$PUBLIC_URL?: string 24 | Hetu: any 25 | __POWERED_BY_QIANKUN__: boolean 26 | } 27 | 28 | declare interface dynamicObject { 29 | [key: string]: any 30 | } 31 | 32 | declare type dvaDispatch = (v: { type: string; payload: dynamicObject }) => any | Promise 33 | 34 | declare type BaseComponent = { 35 | pagestate: any 36 | } 37 | -------------------------------------------------------------------------------- /server/src/model/department.ts: -------------------------------------------------------------------------------- 1 | import Base from '~/src/model/base' 2 | import Knex from '~/src/library/mysql' 3 | import _ from 'lodash' 4 | 5 | export type Department = { 6 | id: string 7 | name: string 8 | order: number 9 | } 10 | 11 | class Project extends Base { 12 | // @todo(yaozeyuan) 临时测试先用project_new, 上线前记得把名字换回来 13 | static TABLE_NAME = 'department' 14 | static TABLE_COLUMN = [`id`, `name`, `order`] 15 | 16 | // 创建/更新 必传字段 17 | static requiredFields = ['name', 'project_code', 'proxy_host'] 18 | 19 | static async asyncGet(id: number) { 20 | let department: Department[] = await Knex.queryBuilder() 21 | .select('*') 22 | .from(this.TABLE_NAME) 23 | .where('id', id) 24 | .first() 25 | 26 | return department 27 | } 28 | 29 | static async asyncGetAll() { 30 | let departments: Department[] = await Knex.queryBuilder() 31 | .select('*') 32 | .from(this.TABLE_NAME) 33 | .orderBy('order', 'desc') 34 | 35 | return departments 36 | } 37 | } 38 | 39 | export default Project 40 | -------------------------------------------------------------------------------- /plugin/src/components/Steps/demo/basic.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 0 3 | title: 基本使用 4 | --- 5 | 6 | 可以通过alias定义的变量获取当前步骤,从而控制其它组件的显示、隐藏 7 | 8 | ```jsx 9 | import Hetu from 'hetu' 10 | 11 | const elementConfig = { 12 | type: 'HtGuiContainer', 13 | props: { 14 | style: { 15 | padding: '8px', 16 | }, 17 | }, 18 | children: [ 19 | "当前步骤:", 20 | "<%:= $$currentStep %>", 21 | { 22 | type: 'HtSteps', 23 | props: { 24 | alias: "$$currentStep", 25 | current: 0, 26 | direction: 'horizontal', 27 | steps: [ 28 | { 29 | title: 'title1', 30 | description: 'description1', 31 | }, 32 | { 33 | title: 'title2', 34 | description: 'description2', 35 | }, 36 | { 37 | title: 'title3', 38 | description: 'description3', 39 | }, 40 | ], 41 | }, 42 | children: [], 43 | }, 44 | ], 45 | } 46 | 47 | ReactDOM.render(, mountNode) 48 | ``` 49 | -------------------------------------------------------------------------------- /plugin/site/docs/editor/01-introduce.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 0 3 | title: 介绍 4 | --- 5 | 6 | 河图, 是一个 低代码 平台, 通过可视化界面, 快速生成各种后台页面, 极大减少开发成本。 7 | 8 | 河图是贝壳找房内部孵化项目, 目前已在公司大多数业务线落地, 完成200+项目, 1500+页面。 9 | 10 | ![操作视频](https://file.ljcdn.com/hetu-cdn/1575359874260.d60adb2b8a3131dec93e73a9e4adff15.gif) 11 | 12 | ## 特性 13 | - 🚴‍♀️ 操作简单、功能强大的可视化编辑器 14 | - 📦 开箱即用、高质量后台管理系统模版 15 | - ⚙️ 开发流程全部线上化,节省沟通、调试、运维成本 16 | - 🛡 使用 React、TypeScript、nodejs、express 开发 17 | - 18 | ## 兼容环境 19 | - 现代浏览器、IE11以上 20 | 21 | ## 链接 22 | - [项目文档](http://139.155.239.172/) 23 | - [项目首页](http://139.155.239.172:9536/) 24 | - [服务器部署](https://github.com/LianjiaTech/hetu/deploy.md) 25 | - [视频教程](http://139.155.239.172/docs/resources/video) 26 | 27 | ## 开发流程 28 | 29 | > 河图的开发、调试、测试、上线都是在浏览器中进行的 30 | ![](https://file.ljcdn.com/hetu-cdn/hetu-doc-demo-%E7%8E%AF%E5%A2%83-1596165724648.png) 31 | 32 | ## 系统架构图 33 | ![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ab52f389a41441cb84ec8f3ccebb8928~tplv-k3u1fbpfcp-zoom-1.image) 34 | 35 | ## 问题咨询 36 | - QQ群 【河图开源交流】 782899873 37 | - 群主QQ 1024371442 (备注河图开源咨询) 38 | -------------------------------------------------------------------------------- /client/src/types/models/guiEditor.d.ts: -------------------------------------------------------------------------------- 1 | import { pageConfig } from './global' 2 | import { selectedComponentData, reac, DataComponentType } from './editor.d' 3 | 4 | export { selectedComponentData, reac, DataComponentType } 5 | 6 | export type activeTab = 'code' | 'base' 7 | 8 | export interface ContainerData { 9 | type: string 10 | path: string 11 | } 12 | 13 | export interface guiEditorState { 14 | // iframe 查询参数 15 | query: null 16 | // 页面id 17 | pageId: null 18 | // 草稿id 19 | draftId: null 20 | // 项目id 21 | project: null 22 | // 页面配置 23 | pageConfig?: pageConfig 24 | // 编译结果 25 | pagestate?: any 26 | hoverComponentData?: selectedComponentData 27 | selectedComponentData?: selectedComponentData 28 | insertComponentData?: selectedComponentData 29 | containerData: ContainerData 30 | isIframeLoading: boolean 31 | // 是否展示占位符元素(用于添加组件) 32 | isInsertItemMode: boolean 33 | // 插入的ComponentData 34 | // 是否处于拖拽中 35 | isDragging: boolean 36 | // 右侧激活面板,默认为可视化编辑器 37 | activeTab: activeTab 38 | // 是否锁屏 39 | isLockIframe: true 40 | } 41 | -------------------------------------------------------------------------------- /plugin/src/components/BChart/shapes.ts: -------------------------------------------------------------------------------- 1 | import { Shape } from 'bizcharts' 2 | 3 | if (Shape.registerShape) { 4 | Shape.registerShape('point', 'gauge', { 5 | drawShape(cfg: any, group: any) { 6 | let point = cfg.points[0] // 获取第一个标记点 7 | // @ts-ignore 8 | point = this.parsePoint(point) 9 | // @ts-ignore 10 | const center = this.parsePoint({ 11 | // 获取极坐标系下画布中心点 12 | x: 0, 13 | y: 0, 14 | }) 15 | // 绘制指针 16 | group.addShape('line', { 17 | attrs: { 18 | x1: center.x, 19 | y1: center.y, 20 | x2: point.x, 21 | y2: point.y - 20, 22 | stroke: cfg.color, 23 | lineWidth: 5, 24 | lineCap: 'round', 25 | }, 26 | }) 27 | // 绘制圆 28 | return group.addShape('circle', { 29 | attrs: { 30 | x: center.x, 31 | y: center.y, 32 | r: 12, 33 | stroke: cfg.color, 34 | lineWidth: 4.5, 35 | fill: '#fff', 36 | }, 37 | }) 38 | }, 39 | }) 40 | } 41 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/Select/interface.d.ts: -------------------------------------------------------------------------------- 1 | import { BaseProps, JsonSchema } from '~/types' 2 | 3 | export type HtSelectValue = (string | number)[] | string | number 4 | 5 | export interface HtSelectProps extends BaseProps { 6 | value: T 7 | onChange: (v: T) => void 8 | labelField?: string 9 | valueField?: string 10 | showSearch?: boolean 11 | remote?: boolean 12 | optionsSourceType?: JsonSchema.OptionsSourceType 13 | options?: JsonSchema.HtFieldOption[] 14 | optionsDependencies?: JsonSchema.HtFieldOption[] 15 | optionsConfig?: { 16 | url: string 17 | method?: JsonSchema.Method 18 | params?: JsonSchema.DynamicObject 19 | data?: JsonSchema.DynamicObject 20 | field?: string 21 | transform?: Function 22 | } 23 | showIcon?: true 24 | searchOnFocus?: boolean 25 | // 是否为多选, 默认为false 26 | isMultiple?: boolean 27 | labelInValue: boolean 28 | // 是否可以全选, 默认为false 29 | isCheckAll?: boolean 30 | } 31 | 32 | export interface HtSelectState { 33 | plainOptions: any[] 34 | remote: boolean 35 | } 36 | -------------------------------------------------------------------------------- /plugin/src/components/Field/components/SelectMultiple/demo/basic.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 0 3 | title: 基本使用 4 | --- 5 | 6 | - `defaultValue` 设置默认值 7 | - `options` 下拉框选项 8 | - `isCheckAll` 设置是否全选 9 | 10 | 11 | ```jsx 12 | import Hetu from 'hetu' 13 | 14 | const elementConfig = { 15 | "type": "HtForm", 16 | "props": { 17 | "url": "/", 18 | "buttons": [], 19 | 20 | "fields": [ 21 | { 22 | "field": "hobbies", 23 | "title": "兴趣", 24 | "type": "SelectMultiple", 25 | "isCheckAll": true, 26 | "options": [ 27 | { 28 | "label": "吃饭", 29 | "value": "1" 30 | }, 31 | { 32 | "label": "睡觉", 33 | "value": "2" 34 | }, 35 | { 36 | "label": "打豆豆", 37 | "value": "3" 38 | } 39 | ], 40 | "defaultValue": [ 41 | "1", 42 | "2" 43 | ] 44 | } 45 | ], 46 | }, 47 | "children": [], 48 | } 49 | 50 | ReactDOM.render(, mountNode) 51 | ``` 52 | --------------------------------------------------------------------------------