From 2c55fff55dcf0228613cc6eaf9c93229996a9b09 Mon Sep 17 00:00:00 2001 From: zhf <1204297681@qq.com> Date: Wed, 21 May 2025 21:23:33 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=A1=A5=E5=85=85=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/create-plugin/constant/plugin-list.ts | 36 +- .../create-plugin/template/global/README.md | 112 +++-- .../template/global/RUNTIME-PLUGIN-MODE.md | 74 --- .../template/global/package.json | 53 ++- .../template/global/public/docs/image.png | Bin 61974 -> 0 bytes .../template/global/public/docs/image2.png | Bin 105842 -> 0 bytes .../template/global/src/control/index.ts | 12 + .../{{pluginName}}-control.provider.ts | 5 + .../src/control/{{pluginName}}-control.scss | 3 + .../src/control/{{pluginName}}-control.tsx | 40 ++ .../template/global/src/editor/index.ts | 12 + .../editor/{{pluginName}}-editor.provider.ts | 21 + .../src/editor/{{pluginName}}-editor.scss | 3 + .../src/editor/{{pluginName}}-editor.tsx | 21 + .../template/global/src/form-detail/index.ts | 12 + .../{{pluginName}}-form-detail.provider.ts | 21 + .../{{pluginName}}-form-detail.scss | 3 + .../{{pluginName}}-form-detail.tsx | 28 ++ .../template/global/src/grid-column/index.ts | 12 + .../{{pluginName}}-grid-column.provider.ts | 19 + .../{{pluginName}}-grid-column.scss | 3 + .../{{pluginName}}-grid-column.tsx | 31 ++ .../template/global/src/index.ts | 27 +- .../template/global/src/method/index.ts | 10 + .../method/{{pluginName}}-method.provider.ts | 19 + .../src/method/{{pluginName}}-method.ts | 14 + .../template/global/src/panel-item/index.ts | 12 + .../{{pluginName}}-panel-item.provider.ts | 20 + .../panel-item/{{pluginName}}-panel-item.scss | 3 + .../panel-item/{{pluginName}}-panel-item.tsx | 33 ++ .../template/global/src/ui-action/index.ts | 10 + .../{{pluginName}}-ui-action.provider.ts | 17 + .../template/global/src/view/index.ts | 12 + .../src/view/{{pluginName}}-view.provider.ts | 5 + .../global/src/view/{{pluginName}}-view.scss | 3 + .../global/src/view/{{pluginName}}-view.tsx | 48 ++ .../platform/appcounter/.eslintrc.cjs | 52 +++ .../template/platform/appcounter/CHANGELOG.md | 3 + .../template/platform/appcounter/README.md | 65 +++ .../template/platform/appcounter/package.json | 106 +++++ .../platform/appcounter/scripts/link.sh | 6 + .../template/platform/appcounter/src/index.ts | 13 + .../appcounter/src/{{pluginName}}.provider.ts | 9 + .../platform/appcounter/src/{{pluginName}}.ts | 8 + .../platform/appcounter/tsconfig.json | 19 + .../platform/appcounter/tsconfig.node.json | 9 + .../platform/appcounter/vite.config.ts | 57 +++ .../platform/chart_render/package.json | 2 +- .../template/platform/custom/README.md | 2 +- .../template/platform/custom/package.json | 2 +- .../platform/dataview_render/package.json | 2 +- .../template/platform/demethod/.eslintrc.cjs | 52 +++ .../template/platform/demethod/CHANGELOG.md | 3 + .../template/platform/demethod/README.md | 65 +++ .../template/platform/demethod/package.json | 106 +++++ .../platform/demethod/scripts/link.sh | 6 + .../template/platform/demethod/src/index.ts | 13 + .../demethod/src/{{pluginName}}.provider.ts | 19 + .../platform/demethod/src/{{pluginName}}.ts | 14 + .../template/platform/demethod/tsconfig.json | 19 + .../platform/demethod/tsconfig.node.json | 9 + .../template/platform/demethod/vite.config.ts | 57 +++ .../platform/deuiaction/.eslintrc.cjs | 52 +++ .../template/platform/deuiaction/CHANGELOG.md | 3 + .../template/platform/deuiaction/README.md | 60 +++ .../template/platform/deuiaction/package.json | 106 +++++ .../platform/deuiaction/scripts/link.sh | 6 + .../template/platform/deuiaction/src/index.ts | 13 + .../deuiaction/src/{{pluginName}}.provider.ts | 17 + .../platform/deuiaction/tsconfig.json | 19 + .../platform/deuiaction/tsconfig.node.json | 9 + .../platform/deuiaction/vite.config.ts | 57 +++ .../platform/editform_render/package.json | 2 +- .../platform/editor_customstyle/package.json | 2 +- .../platform/form_usercontrol/package.json | 2 +- .../platform/grid_colrender/package.json | 2 +- .../platform/grid_render/package.json | 2 +- .../platform/list_render/package.json | 2 +- .../platform/portlet_custom/package.json | 2 +- .../platform/searchbar_render/.eslintrc.cjs | 52 +++ .../platform/searchbar_render/CHANGELOG.md | 3 + .../platform/searchbar_render/README.md | 71 +++ .../platform/searchbar_render/package.json | 106 +++++ .../platform/searchbar_render/scripts/link.sh | 6 + .../platform/searchbar_render/src/index.ts | 16 + .../src/{{pluginName}}.controller.ts | 3 + .../src/{{pluginName}}.provider.ts | 20 + .../searchbar_render/src/{{pluginName}}.scss | 3 + .../searchbar_render/src/{{pluginName}}.tsx | 46 ++ .../platform/searchbar_render/tsconfig.json | 19 + .../searchbar_render/tsconfig.node.json | 9 + .../platform/searchbar_render/vite.config.ts | 57 +++ .../platform/searchform_render/package.json | 2 +- .../platform/toolbar_item/package.json | 2 +- .../platform/toolbar_render/package.json | 2 +- .../platform/tree_render/package.json | 2 +- .../platform/uilogicnode/package.json | 2 +- .../platform/view_custom/.eslintrc.cjs | 52 +++ .../platform/view_custom/CHANGELOG.md | 3 + .../template/platform/view_custom/README.md | 130 ++++++ .../platform/view_custom/package.json | 106 +++++ .../platform/view_custom/scripts/link.sh | 6 + .../platform/view_custom/src/index.ts | 16 + .../src/{{pluginName}}.controller.ts | 8 + .../view_custom/src/{{pluginName}}.engine.ts | 3 + .../src/{{pluginName}}.provider.ts | 16 + .../view_custom/src/{{pluginName}}.scss | 3 + .../view_custom/src/{{pluginName}}.tsx | 49 ++ .../platform/view_custom/tsconfig.json | 19 + .../platform/view_custom/tsconfig.node.json | 9 + .../platform/view_custom/vite.config.ts | 57 +++ .../platform/wizardpanel_render/.eslintrc.cjs | 52 +++ .../platform/wizardpanel_render/CHANGELOG.md | 3 + .../platform/wizardpanel_render/README.md | 71 +++ .../platform/wizardpanel_render/package.json | 106 +++++ .../wizardpanel_render/scripts/link.sh | 6 + .../platform/wizardpanel_render/src/index.ts | 16 + .../src/{{pluginName}}.controller.ts | 3 + .../src/{{pluginName}}.provider.ts | 20 + .../src/{{pluginName}}.scss | 3 + .../wizardpanel_render/src/{{pluginName}}.tsx | 46 ++ .../platform/wizardpanel_render/tsconfig.json | 19 + .../wizardpanel_render/tsconfig.node.json | 9 + .../wizardpanel_render/vite.config.ts | 57 +++ .../create-plugin/template/theme/README.md | 148 ++---- .../create-plugin/template/theme/package.json | 56 ++- .../template/theme/public/docs/image.png | Bin 37958 -> 0 bytes .../template/theme/public/docs/image2.png | Bin 71825 -> 0 bytes .../template/theme/public/docs/image3.png | Bin 74202 -> 0 bytes .../create-plugin/template/theme/src/index.ts | 11 +- .../template/theme/src/layout/index.ts | 1 + .../theme/src/theme/custom-theme.scss | 421 ------------------ .../template/theme/src/theme/default/app.scss | 3 + .../theme/src/theme/default/ctrl.scss | 3 + .../theme/src/theme/default/editor.scss | 3 + .../theme/src/theme/default/element-plus.scss | 3 + .../theme/src/theme/default/index.scss | 6 + .../theme/src/theme/default/theme.scss | 3 + .../theme/src/theme/default/view.scss | 3 + .../template/theme/src/theme/index.scss | 7 +- 140 files changed, 3094 insertions(+), 711 deletions(-) delete mode 100644 packages/core/src/create-plugin/template/global/RUNTIME-PLUGIN-MODE.md delete mode 100644 packages/core/src/create-plugin/template/global/public/docs/image.png delete mode 100644 packages/core/src/create-plugin/template/global/public/docs/image2.png create mode 100644 packages/core/src/create-plugin/template/global/src/control/index.ts create mode 100644 packages/core/src/create-plugin/template/global/src/control/{{pluginName}}-control.provider.ts create mode 100644 packages/core/src/create-plugin/template/global/src/control/{{pluginName}}-control.scss create mode 100644 packages/core/src/create-plugin/template/global/src/control/{{pluginName}}-control.tsx create mode 100644 packages/core/src/create-plugin/template/global/src/editor/index.ts create mode 100644 packages/core/src/create-plugin/template/global/src/editor/{{pluginName}}-editor.provider.ts create mode 100644 packages/core/src/create-plugin/template/global/src/editor/{{pluginName}}-editor.scss create mode 100644 packages/core/src/create-plugin/template/global/src/editor/{{pluginName}}-editor.tsx create mode 100644 packages/core/src/create-plugin/template/global/src/form-detail/index.ts create mode 100644 packages/core/src/create-plugin/template/global/src/form-detail/{{pluginName}}-form-detail.provider.ts create mode 100644 packages/core/src/create-plugin/template/global/src/form-detail/{{pluginName}}-form-detail.scss create mode 100644 packages/core/src/create-plugin/template/global/src/form-detail/{{pluginName}}-form-detail.tsx create mode 100644 packages/core/src/create-plugin/template/global/src/grid-column/index.ts create mode 100644 packages/core/src/create-plugin/template/global/src/grid-column/{{pluginName}}-grid-column.provider.ts create mode 100644 packages/core/src/create-plugin/template/global/src/grid-column/{{pluginName}}-grid-column.scss create mode 100644 packages/core/src/create-plugin/template/global/src/grid-column/{{pluginName}}-grid-column.tsx create mode 100644 packages/core/src/create-plugin/template/global/src/method/index.ts create mode 100644 packages/core/src/create-plugin/template/global/src/method/{{pluginName}}-method.provider.ts create mode 100644 packages/core/src/create-plugin/template/global/src/method/{{pluginName}}-method.ts create mode 100644 packages/core/src/create-plugin/template/global/src/panel-item/index.ts create mode 100644 packages/core/src/create-plugin/template/global/src/panel-item/{{pluginName}}-panel-item.provider.ts create mode 100644 packages/core/src/create-plugin/template/global/src/panel-item/{{pluginName}}-panel-item.scss create mode 100644 packages/core/src/create-plugin/template/global/src/panel-item/{{pluginName}}-panel-item.tsx create mode 100644 packages/core/src/create-plugin/template/global/src/ui-action/index.ts create mode 100644 packages/core/src/create-plugin/template/global/src/ui-action/{{pluginName}}-ui-action.provider.ts create mode 100644 packages/core/src/create-plugin/template/global/src/view/index.ts create mode 100644 packages/core/src/create-plugin/template/global/src/view/{{pluginName}}-view.provider.ts create mode 100644 packages/core/src/create-plugin/template/global/src/view/{{pluginName}}-view.scss create mode 100644 packages/core/src/create-plugin/template/global/src/view/{{pluginName}}-view.tsx create mode 100644 packages/core/src/create-plugin/template/platform/appcounter/.eslintrc.cjs create mode 100644 packages/core/src/create-plugin/template/platform/appcounter/CHANGELOG.md create mode 100644 packages/core/src/create-plugin/template/platform/appcounter/README.md create mode 100644 packages/core/src/create-plugin/template/platform/appcounter/package.json create mode 100755 packages/core/src/create-plugin/template/platform/appcounter/scripts/link.sh create mode 100644 packages/core/src/create-plugin/template/platform/appcounter/src/index.ts create mode 100644 packages/core/src/create-plugin/template/platform/appcounter/src/{{pluginName}}.provider.ts create mode 100644 packages/core/src/create-plugin/template/platform/appcounter/src/{{pluginName}}.ts create mode 100644 packages/core/src/create-plugin/template/platform/appcounter/tsconfig.json create mode 100644 packages/core/src/create-plugin/template/platform/appcounter/tsconfig.node.json create mode 100644 packages/core/src/create-plugin/template/platform/appcounter/vite.config.ts create mode 100644 packages/core/src/create-plugin/template/platform/demethod/.eslintrc.cjs create mode 100644 packages/core/src/create-plugin/template/platform/demethod/CHANGELOG.md create mode 100644 packages/core/src/create-plugin/template/platform/demethod/README.md create mode 100644 packages/core/src/create-plugin/template/platform/demethod/package.json create mode 100755 packages/core/src/create-plugin/template/platform/demethod/scripts/link.sh create mode 100644 packages/core/src/create-plugin/template/platform/demethod/src/index.ts create mode 100644 packages/core/src/create-plugin/template/platform/demethod/src/{{pluginName}}.provider.ts create mode 100644 packages/core/src/create-plugin/template/platform/demethod/src/{{pluginName}}.ts create mode 100644 packages/core/src/create-plugin/template/platform/demethod/tsconfig.json create mode 100644 packages/core/src/create-plugin/template/platform/demethod/tsconfig.node.json create mode 100644 packages/core/src/create-plugin/template/platform/demethod/vite.config.ts create mode 100644 packages/core/src/create-plugin/template/platform/deuiaction/.eslintrc.cjs create mode 100644 packages/core/src/create-plugin/template/platform/deuiaction/CHANGELOG.md create mode 100644 packages/core/src/create-plugin/template/platform/deuiaction/README.md create mode 100644 packages/core/src/create-plugin/template/platform/deuiaction/package.json create mode 100755 packages/core/src/create-plugin/template/platform/deuiaction/scripts/link.sh create mode 100644 packages/core/src/create-plugin/template/platform/deuiaction/src/index.ts create mode 100644 packages/core/src/create-plugin/template/platform/deuiaction/src/{{pluginName}}.provider.ts create mode 100644 packages/core/src/create-plugin/template/platform/deuiaction/tsconfig.json create mode 100644 packages/core/src/create-plugin/template/platform/deuiaction/tsconfig.node.json create mode 100644 packages/core/src/create-plugin/template/platform/deuiaction/vite.config.ts create mode 100644 packages/core/src/create-plugin/template/platform/searchbar_render/.eslintrc.cjs create mode 100644 packages/core/src/create-plugin/template/platform/searchbar_render/CHANGELOG.md create mode 100644 packages/core/src/create-plugin/template/platform/searchbar_render/README.md create mode 100644 packages/core/src/create-plugin/template/platform/searchbar_render/package.json create mode 100755 packages/core/src/create-plugin/template/platform/searchbar_render/scripts/link.sh create mode 100644 packages/core/src/create-plugin/template/platform/searchbar_render/src/index.ts create mode 100644 packages/core/src/create-plugin/template/platform/searchbar_render/src/{{pluginName}}.controller.ts create mode 100644 packages/core/src/create-plugin/template/platform/searchbar_render/src/{{pluginName}}.provider.ts create mode 100644 packages/core/src/create-plugin/template/platform/searchbar_render/src/{{pluginName}}.scss create mode 100644 packages/core/src/create-plugin/template/platform/searchbar_render/src/{{pluginName}}.tsx create mode 100644 packages/core/src/create-plugin/template/platform/searchbar_render/tsconfig.json create mode 100644 packages/core/src/create-plugin/template/platform/searchbar_render/tsconfig.node.json create mode 100644 packages/core/src/create-plugin/template/platform/searchbar_render/vite.config.ts create mode 100644 packages/core/src/create-plugin/template/platform/view_custom/.eslintrc.cjs create mode 100644 packages/core/src/create-plugin/template/platform/view_custom/CHANGELOG.md create mode 100644 packages/core/src/create-plugin/template/platform/view_custom/README.md create mode 100644 packages/core/src/create-plugin/template/platform/view_custom/package.json create mode 100755 packages/core/src/create-plugin/template/platform/view_custom/scripts/link.sh create mode 100644 packages/core/src/create-plugin/template/platform/view_custom/src/index.ts create mode 100644 packages/core/src/create-plugin/template/platform/view_custom/src/{{pluginName}}.controller.ts create mode 100644 packages/core/src/create-plugin/template/platform/view_custom/src/{{pluginName}}.engine.ts create mode 100644 packages/core/src/create-plugin/template/platform/view_custom/src/{{pluginName}}.provider.ts create mode 100644 packages/core/src/create-plugin/template/platform/view_custom/src/{{pluginName}}.scss create mode 100644 packages/core/src/create-plugin/template/platform/view_custom/src/{{pluginName}}.tsx create mode 100644 packages/core/src/create-plugin/template/platform/view_custom/tsconfig.json create mode 100644 packages/core/src/create-plugin/template/platform/view_custom/tsconfig.node.json create mode 100644 packages/core/src/create-plugin/template/platform/view_custom/vite.config.ts create mode 100644 packages/core/src/create-plugin/template/platform/wizardpanel_render/.eslintrc.cjs create mode 100644 packages/core/src/create-plugin/template/platform/wizardpanel_render/CHANGELOG.md create mode 100644 packages/core/src/create-plugin/template/platform/wizardpanel_render/README.md create mode 100644 packages/core/src/create-plugin/template/platform/wizardpanel_render/package.json create mode 100755 packages/core/src/create-plugin/template/platform/wizardpanel_render/scripts/link.sh create mode 100644 packages/core/src/create-plugin/template/platform/wizardpanel_render/src/index.ts create mode 100644 packages/core/src/create-plugin/template/platform/wizardpanel_render/src/{{pluginName}}.controller.ts create mode 100644 packages/core/src/create-plugin/template/platform/wizardpanel_render/src/{{pluginName}}.provider.ts create mode 100644 packages/core/src/create-plugin/template/platform/wizardpanel_render/src/{{pluginName}}.scss create mode 100644 packages/core/src/create-plugin/template/platform/wizardpanel_render/src/{{pluginName}}.tsx create mode 100644 packages/core/src/create-plugin/template/platform/wizardpanel_render/tsconfig.json create mode 100644 packages/core/src/create-plugin/template/platform/wizardpanel_render/tsconfig.node.json create mode 100644 packages/core/src/create-plugin/template/platform/wizardpanel_render/vite.config.ts delete mode 100644 packages/core/src/create-plugin/template/theme/public/docs/image.png delete mode 100644 packages/core/src/create-plugin/template/theme/public/docs/image2.png delete mode 100644 packages/core/src/create-plugin/template/theme/public/docs/image3.png delete mode 100644 packages/core/src/create-plugin/template/theme/src/theme/custom-theme.scss create mode 100644 packages/core/src/create-plugin/template/theme/src/theme/default/app.scss create mode 100644 packages/core/src/create-plugin/template/theme/src/theme/default/ctrl.scss create mode 100644 packages/core/src/create-plugin/template/theme/src/theme/default/editor.scss create mode 100644 packages/core/src/create-plugin/template/theme/src/theme/default/element-plus.scss create mode 100644 packages/core/src/create-plugin/template/theme/src/theme/default/index.scss create mode 100644 packages/core/src/create-plugin/template/theme/src/theme/default/theme.scss create mode 100644 packages/core/src/create-plugin/template/theme/src/theme/default/view.scss diff --git a/packages/core/src/create-plugin/constant/plugin-list.ts b/packages/core/src/create-plugin/constant/plugin-list.ts index 4e819cf..09b3500 100644 --- a/packages/core/src/create-plugin/constant/plugin-list.ts +++ b/packages/core/src/create-plugin/constant/plugin-list.ts @@ -27,26 +27,26 @@ export const PluginList: IPluginType[] = [ { name: 'UILOGICNODE', caption: '界面逻辑节点' }, { name: 'VIEW_CUSTOM', caption: '实体视图绘制插件' }, { name: 'DEMETHOD', caption: '应用实体方法插件' }, - { name: 'APPUTIL', caption: '应用功能插件' }, + // { name: 'APPUTIL', caption: '应用功能插件' }, 未支持 { name: 'APPCOUNTER', caption: '应用计数器插件' }, - { name: 'DEDATAIMPORT', caption: '应用实体数据导入' }, - { name: 'DEDATAEXPORT', caption: '应用实体数据导出' }, - { name: 'DEFVALUERULE', caption: '应用实体属性值规则' }, - { name: 'APPVALUERULE', caption: '应用值规则' }, - { name: 'SEARCHBAR_ITEM', caption: '搜索栏项绘制插件' }, + // { name: 'DEDATAIMPORT', caption: '应用实体数据导入' }, 未支持 + // { name: 'DEDATAEXPORT', caption: '应用实体数据导出' }, 未支持 + // { name: 'DEFVALUERULE', caption: '应用实体属性值规则' }, 未支持 + // { name: 'APPVALUERULE', caption: '应用值规则' }, 未支持 + // { name: 'SEARCHBAR_ITEM', caption: '搜索栏项绘制插件' }, 未支持 { name: 'SEARCHBAR_RENDER', caption: '搜索栏绘制插件' }, { name: 'WIZARDPANEL_RENDER', caption: '向导面板绘制插件' }, { name: 'DEUIACTION', caption: '应用实体界面行为' }, - { name: 'CALENDAR_ITEM', caption: '日历部件项绘制插件' }, - { name: 'CALENDAR_RENDER', caption: '日历部件绘制插件' }, - { name: 'MAPVIEW_ITEM', caption: '地图部件项绘制插件' }, - { name: 'MAPVIEW_RENDER', caption: '地图部件绘制插件' }, - { name: 'PANEL_ITEM', caption: '面板部件成员绘制插件' }, - { name: 'PANEL_RENDER', caption: '面板部件绘制插件' }, - { name: 'DASHBOARD_ITEM', caption: '数据看板成员绘制插件' }, - { name: 'DASHBOARD_RENDER', caption: '数据看板绘制插件' }, - { name: 'APPUILOGIC', caption: '系统界面逻辑插件' }, - { name: 'APPMENU_ITEM', caption: '应用菜单项绘制插件' }, - { name: 'APPMENU_RENDER', caption: '应用菜单绘制插件' }, - { name: 'TITLEBAR_RENDER', caption: '标题栏绘制插件' }, + // { name: 'CALENDAR_ITEM', caption: '日历部件项绘制插件' }, modeling建模平台没有此类型的插件 + // { name: 'CALENDAR_RENDER', caption: '日历部件绘制插件' }, modeling建模平台没有此类型的插件 + // { name: 'MAPVIEW_ITEM', caption: '地图部件项绘制插件' }, modeling建模平台没有此类型的插件 + // { name: 'MAPVIEW_RENDER', caption: '地图部件绘制插件' }, modeling建模平台没有此类型的插件 + // { name: 'PANEL_ITEM', caption: '面板部件成员绘制插件' }, modeling建模平台没有此类型的插件 + // { name: 'PANEL_RENDER', caption: '面板部件绘制插件' }, modeling建模平台没有此类型的插件 + // { name: 'DASHBOARD_ITEM', caption: '数据看板成员绘制插件' }, modeling建模平台没有此类型的插件 + // { name: 'DASHBOARD_RENDER', caption: '数据看板绘制插件' }, modeling建模平台没有此类型的插件 + // { name: 'APPUILOGIC', caption: '系统界面逻辑插件' }, modeling建模平台没有此类型的插件 + // { name: 'APPMENU_ITEM', caption: '应用菜单项绘制插件' }, modeling建模平台没有此类型的插件 + // { name: 'APPMENU_RENDER', caption: '应用菜单绘制插件' }, modeling建模平台没有此类型的插件 + // { name: 'TITLEBAR_RENDER', caption: '标题栏绘制插件' }, modeling建模平台没有此类型的插件 ]; diff --git a/packages/core/src/create-plugin/template/global/README.md b/packages/core/src/create-plugin/template/global/README.md index 8e6b64a..6c6e052 100644 --- a/packages/core/src/create-plugin/template/global/README.md +++ b/packages/core/src/create-plugin/template/global/README.md @@ -1,66 +1,88 @@ # 全局插件 -## 新建自定义部件插件 +全局插件可替换标准的组件和功能,当标准组件或者功能无法满足要求时,可以通过全局插件来实现。modeling建模平台创建全局插件可参见 [插件开发](https://open.ibizlab.cn/apphub/zh/guide/plugin-dev.html) -新建自定义部件插件,需要注意的是插件标识需设置为GLOBAL_APP_UTIL,除此之外,运行时插件模式同时支持远程运行时插件,在实际运用的时候需根据当前项目所选择的插件模式来定义。详情参见 [运行时插件模式](./RUNTIME-PLUGIN-MODE.md) 篇。 +## 插件结构 - - -## 插件机制 - -应用初始化的时候,如果应用配置了应用插件,则会去加载应用插件,然后替换标准的组件和功能,详情如下: - -```tsx -// 加载应用插件 -async loadGlobalAppUtil(): Promise { - const appUtilTag: string = 'GLOBAL_APP_UTIL'; - const globalAppUtilPlugin = ibiz.hub.getPlugin( - appUtilTag.toLowerCase(), - this.appId, - ); - if (!globalAppUtilPlugin) return; - if ( - globalAppUtilPlugin.refMode !== 'APP' || - globalAppUtilPlugin.refTag !== appUtilTag - ) - return; - await ibiz.plugin.loadPlugin(globalAppUtilPlugin as ISysPFPlugin); -} +``` +|─ ─ {{pluginName}} 全局插件顶层目录 + |─ ─ src 全局插件源代码目录 +​ |─ ─ control 部件目录 +​ |─ ─ {{pluginName}}-control.provider.ts 部件适配器 +​ |─ ─ {{pluginName}}-control.scss 部件样式 +​ |─ ─ {{pluginName}}-control.tsx 部件组件 +​ |─ ─ index.ts 部件入口文件,替换标准部件逻辑 +​ |─ ─ editor 编辑器目录 +​ |─ ─ {{pluginName}}-editor.provider.ts 编辑器适配器 +​ |─ ─ {{pluginName}}-editor.scss 编辑器样式 +​ |─ ─ {{pluginName}}-editor.tsx 编辑器组件 +​ |─ ─ index.ts 编辑器入口文件,替换标准编辑器逻辑 +​ |─ ─ form-detail 表单成员目录 +​ |─ ─ {{pluginName}}-form-detail.provider.ts 表单成员适配器 +​ |─ ─ {{pluginName}}-form-detail.scss 表单成员样式 +​ |─ ─ {{pluginName}}-form-detail.tsx 表单成员组件 +​ |─ ─ index.ts 表单成员入口文件,替换标准表单成员逻辑 + |─ ─ grid-column 表格列目录 + ​ |─ ─ {{pluginName}}-grid-column.provider.ts 表格列适配器 + ​ |─ ─ {{pluginName}}-grid-column.scss 表格列样式 + ​ |─ ─ {{pluginName}}-grid-column.tsx 表格列组件 + ​ |─ ─ index.ts 表格列入口文件,替换标准表格列逻辑 + |─ ─ method 实体行为目录 + ​ |─ ─ {{pluginName}}-method.provider.ts 实体行为适配器 + ​ |─ ─ {{pluginName}}-method.ts 实体行为实现类 + ​ |─ ─ index.ts 实体行为入口文件,替换标准实体行为逻辑 + |─ ─ panel-item 面板项目录 + ​ |─ ─ {{pluginName}}-panel-item.provider.ts 面板项适配器 + ​ |─ ─ {{pluginName}}-panel-item.scss 面板项样式 + ​ |─ ─ {{pluginName}}-panel-item.tsx 面板项组件 + ​ |─ ─ index.ts 面板项入口文件,替换标准面板项逻辑 + |─ ─ ui-action 界面行为目录 + ​ |─ ─ {{pluginName}}-ui-action.provider.ts 界面行为适配器 + ​ |─ ─ index.ts 界面行为入口文件,替换标准界面行为逻辑 + |─ ─ view 视图目录 + ​ |─ ─ {{pluginName}}-view.provider.ts 视图适配器 + ​ |─ ─ {{pluginName}}-view.scss 视图样式 + ​ |─ ─ {{pluginName}}-view.tsx 视图组件 + ​ |─ ─ index.ts 视图入口文件,替换标准视图逻辑 +​ |─ ─ index.ts 全局插件入口文件,替换标准组件和功能 ``` -## 插件示例 +## 本地开发 -### 插件效果 +1. 安装依赖并link至全局 -表格加载数据后会弹出自定义提示 +```sh +// 安装依赖 +pnpm i - +// link底包 +./scripts/link.sh -### 插件结构 +// 启动 +pnpm dev +// link到全局 +pnpm link --global ``` -|─ ─ global 全局插件顶层目录,可根据实际业务命名 - |─ ─ src 全局插件源代码目录 -​ |─ ─ grid-view-engine.ts 表格视图引擎 -​ |─ ─ index.ts 全局插件入口文件 -``` -### 全局插件入口文件 +2. 主项目包中引用插件 + +```sh +// link插件 +pnpm link --global '{{pluginGroup}}/{{pluginName}}' +``` -全局插件入口文件会换标准的组件和功能,供外部使用。 +3. 主项目包中注册插件 -```typescript +```ts import { App } from 'vue'; -import { IViewController } from '@ibiz-template/runtime'; -import { GridViewEngine } from './grid-view-engine'; +import {{ pascalCasePluginName }} from '{{pluginGroup}}/{{pluginName}}' export default { - install(_app: App) { - // 替换标准的表格视图引擎 - ibiz.engine.register( - 'VIEW_GridView', - (c: IViewController) => new GridViewEngine(c), - ); + install(app: App) { + app.use({{ pascalCasePluginName }}); + // 设置本地开发需要忽略加载的插件,可填写正则或全匹配字符串。匹配插件在modeling建模平台配置的[运行时插件仓库配置]内容 + ibiz.plugin.setDevIgnore(/^{{pluginGroup}}\/{{pluginName}}/); }, }; ``` diff --git a/packages/core/src/create-plugin/template/global/RUNTIME-PLUGIN-MODE.md b/packages/core/src/create-plugin/template/global/RUNTIME-PLUGIN-MODE.md deleted file mode 100644 index dbe8a2b..0000000 --- a/packages/core/src/create-plugin/template/global/RUNTIME-PLUGIN-MODE.md +++ /dev/null @@ -1,74 +0,0 @@ -# 运行时插件模式 - -| 插件模式 | 是否已支持 | -| :------------: | :--------: | -| 非运行时插件 | 是 | -| 本地运行时插件 | 否 | -| 远程运行时插件 | 是 | - -## 非运行时插件 - -非运行时插件与主项目一起编译打包,主项目中可以直接引用该插件,并且通过vue插件的形式挂载。 - -```typescript -import { App } from 'vue'; -import plugin from '@ibiz-template-plugin-example/example-one'; - -// 挂载插件 -export default { - install(app: App): void { - app.use(plugin); - }, -}; -``` - -## 远程运行时插件 - -远程运行时插件单独部署在cdn上。主项目中不能直接引用该插件,在使用到时才会去远程加载该插件。cdn请求基础路径pluginBaseUrl可在environment.js中配置。运行时插件仓库配置填写需参照[unpkg规范](https://unpkg.com); - -```typescript -// 加载远程插件 -async loadPluginRef( - rtObjectName: string, - rtObjectRepo: string, - ): Promise { - if (this.isIgnore(rtObjectRepo)) { - return true; - } - if (this.pluginCache.has(rtObjectName)) { - return true; - } - let configData: unknown = null; - { - const pluginPath: string = rtObjectRepo; - const configUrl = this.urlReg.test(pluginPath) - ? `${pluginPath}/package.json` - : `${ibiz.env.pluginBaseUrl}/${join(pluginPath, 'package.json')}`; - const res = await ibiz.net.axios({ - method: 'get', - headers: { 'Access-Control-Allow-Origin': '*' }, - url: configUrl, - }); - if (res.status !== 200) { - throw new Error(`配置加载失败`); - } - configData = res.data; - } - const remotePlugin = new RemotePluginItem( - rtObjectName, - rtObjectRepo, - configData as RemotePluginConfig, - ); - if (remotePlugin) { - await this.loadPluginExternal(remotePlugin.config); - try { - await this.loadScript(remotePlugin); - this.pluginCache.set(rtObjectName, remotePlugin); - return true; - } catch (error) { - ibiz.log.error(error); - } - } - return false; - } -``` diff --git a/packages/core/src/create-plugin/template/global/package.json b/packages/core/src/create-plugin/template/global/package.json index 09acb52..7bcf063 100644 --- a/packages/core/src/create-plugin/template/global/package.json +++ b/packages/core/src/create-plugin/template/global/package.json @@ -15,7 +15,6 @@ "files": [ "dist", "public", - "RUNTIME-PLUGIN-MODE.md", "CHANGELOG.md", "README.md" ], @@ -29,36 +28,68 @@ }, "devDependencies": { "@floating-ui/dom": "^1.5.3", - "@ibiz-template/core": "0.7.40-alpha.13", - "@ibiz-template/model-helper": "0.7.40-alpha.13", - "@ibiz-template/runtime": "0.7.40-alpha.13", + "@ibiz-template/core": "^0.7.40-alpha.7", + "@ibiz-template/model-helper": "^0.7.40-alpha.8", + "@ibiz-template/runtime": "^0.7.40-alpha.8", "@ibiz-template/theme": "^0.7.39", - "@ibiz-template/vue3-util": "0.7.40-alpha.13", - "@ibiz/model-core": "^0.1.71", + "@ibiz-template/vue3-util": "^0.7.40-alpha.8", + "@ibiz/model-core": "^0.1.72", + "@qx-chitanda/vite-plugin-lib-legacy": "^4.1.1", "@types/lodash-es": "^4.17.12", "@types/ramda": "^0.29.6", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "@typescript-eslint/parser": "^6.11.0", + "@vitejs/plugin-vue": "^4.4.1", + "@vitejs/plugin-vue-jsx": "^3.0.2", "async-validator": "^4.2.5", "axios": "^1.6.2", "dayjs": "^1.11.10", "element-plus": "^2.4.2", + "eslint": "^8.53.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-prettier": "^9.0.0", + "eslint-plugin-import": "^2.29.0", + "eslint-plugin-prettier": "^5.0.1", + "eslint-plugin-unused-imports": "^3.0.0", + "eslint-plugin-vue": "^9.18.1", + "husky": "^8.0.3", + "lerna": "^8.0.0", + "lint-staged": "^15.1.0", "lodash-es": "^4.17.21", "pluralize": "^8.0.0", + "postcss": "^8.4.31", + "prettier": "^3.1.0", "qs": "^6.11.2", "qx-util": "^0.4.8", "ramda": "^0.29.1", + "rollup-plugin-visualizer": "^5.9.2", + "sass": "1.69.5", + "stylelint": "15.11.0", + "stylelint-config-prettier": "^9.0.5", + "stylelint-config-recess-order": "^4.3.0", + "stylelint-config-standard": "^34.0.0", + "stylelint-config-standard-scss": "^11.1.0", + "stylelint-scss": "5.3.1", + "terser": "^5.24.0", + "typescript": "5.2.2", + "vite": "^4.5.0", + "vite-plugin-dts": "^3.6.3", + "vite-plugin-eslint": "^1.8.1", "vite-plugin-libcss": "^1.1.1", "vue": "^3.3.8", + "vue-eslint-parser": "^9.3.2", "vue-router": "^4.2.5", + "vue-tsc": "1.8.22", "vuedraggable": "^4.1.0" }, "peerDependencies": { "@floating-ui/dom": "^1.5.1", - "@ibiz-template/core": "0.7.40-alpha.13", - "@ibiz-template/model-helper": "0.7.40-alpha.13", - "@ibiz-template/runtime": "0.7.40-alpha.13", + "@ibiz-template/core": "^0.7.40-alpha.7", + "@ibiz-template/model-helper": "^0.7.40-alpha.8", + "@ibiz-template/runtime": "^0.7.40-alpha.8", "@ibiz-template/theme": "^0.7.39", - "@ibiz-template/vue3-util": "0.7.40-alpha.13", - "@ibiz/model-core": "^0.1.71", + "@ibiz-template/vue3-util": "^0.7.40-alpha.8", + "@ibiz/model-core": "^0.1.72", "async-validator": "^4.2.5", "axios": "^1.6.2", "dayjs": "^1.11.10", diff --git a/packages/core/src/create-plugin/template/global/public/docs/image.png b/packages/core/src/create-plugin/template/global/public/docs/image.png deleted file mode 100644 index 0b6ef77af346457ecee219a9c1c60d57ebc5493b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61974 zcmdqJbyQUCA1_KXfOIJgU4n%8q6|oPcS|UU0un>;+GdJ8_0Hm~nw;AizvelOil9gNCT@Rdq( z@~Rqx>JXZj-;?!QJkNja6uHHi9Z5I1Y@KOq4P3Ki^!W#)>iDBTeE$0Qh~ii`ZIXLa zCA`(C_Pol~AK!Fxs#|Ce3E60w`MecM?zUy`x0n&iU4NgyX2m4P!a`69gS7EoIiue8Z&L|Km z95MLGs;LiBu8D_(!(y?{an$>>=lM#pp}Q8`&}}^%|9h%%O+t`CZnORf!3pq-=j4B5c}st5A$%r2d9oPkdu#=ko#rYOt~lqttA{j3Y`4! z^N8km#~z{}qFuZj6Ep=Q*9|zy_npw=$6Ry!+pS>4*4 z!@gI-zH^HM3KdW(_3-S~^~C$gO9Wj%zKs`g9_)}> z@haqPXB2~^MfwI)45w ztAUr)wza-1{b_V;23ekUb#*1|32|{!Hlvt<+?>y|Hw4@yD#q}?tg@ZV~>64=z#L4-eNLPcb#=bHL>WU|c&d7@z zdW@v@+t}n~obvWg#LJQ!S$*iEg((TBZjUy<60;MX4x+M~l@c}l*@daRb}%=VZ8v-2 zSMsDdq2?^v;&4FGQfMpJ?SO!4vP9NI^mF*OX3KnYm8fKkr#1GsHG5*3X5KVzzK<>m z3EdOKCim45>cs{Rt)@P6jh4{NpI#ozTAu&fvZe2gn}7LKUFmM zZcX4q$!$4aH<)riMbMe7e=TQqW;j=sIxSk5`n?~i!({cVLHKK&-5^JrqxDvaA_j}sCt6)<)kyPGIr4=bXE$e3Y z21$q?8nr|(Gm+cRUF)p|iDM8)6Hz@}Tb_Gm%4~%`rZ0C`!tJqe9v6gsTE3Swckynr z%2FAdP$pm~RoH#a&f7iYWTNI-`@6%$makct=f{sFMoiTDNR@aNmtU*&*BR!X-P*R0 z`iOTMQ?|n9BSzoVC3aqw6P@$V@xcl=c8U}6M)SS|-sO{vaB625k@%)~#I81UjAG5adT_N{g zCr)D1H+^_sRfa?-dp*Lhlf%KZwM9V1!-AOTo;V`y`n`o!SnE8NlW(*!0?}W|By%gb z&T(~6md=xGSn?G5b&#MYLo)5ujOA|8&>bgV;@gO4l*`D#h1awC#IcgmKd0RIH46?Q zzB60x@~7*olhUx~CU|%$%OZG84?C(~?-(<{lzuVyef6$U)%)k|(Iel9E%^DbO-Zt? zC;c(HzK~IQSlY{fK}l$>I7OYP`F-w?UELt7H58fWv39+-Ni}l3ut6~+DBr)KjwMOG zVyPM3BV$sCL0&C=M|v+9`P3J_({wyo*)Jk_Vd{o#^^HqRWaBI`X%R7c^Xz#{V#-=n zG=6D+V$Q|77#_jHYrph-0f>vABsms7)yQilf||2u8#rTMAOxDVy(P`hbF}g)qo}Iq zy?QOMuW9_+zj56$|9jP>_rPexjVMW59U6J@&{P~MEVFpMO62)1jYBiT6i-`Zgs%8& ze_5zh#}XX2Y`Zp`6Q^T@M-XdLXCyiMj+2TUn!7eTHH}nvQ3Y}gSK*uK}M=a)_Ph?YeycxCSFRM^i;hoxWd#|$$uaXoyH}2 z$7?Y_5B85lscTrG>2QwnNaah_?yFu1>MBeQVSjeWo=#gw@PRqAG$dP>lL^;$YWYA} zeo+X&$n{`l(2$4%=k43KhhNyz29^^|Y`@M&xg69vZ;Yg~rCk)-)6!rBE-w50vmFsB zpc!MzdPr2i>y&^8^+=dy;6>`JNaUG{3ClhOD98c3>#bWhO9r)V4j{VA)tKU;Hdw$*>K|`9c@Q&Jxk!1aJ&T;iSxvBs4RFgYl^{X)*L$L>A zneNB5RWH6-Z49KFedRDZ)5b!~pEOARGc_PAsHJ{p8^LFM&CVtEuG6IF1Zrdc&X$i$ zC9;bj9DN-KwK%AGxEA?thclB=LT!XqQ2bEcaHyJnfBuFgTcPC4b@Wt?R&FZ za}}+p6)GMCfkcWgEnLNISTg1b5eQSWtx3W)(38wp4Q_9Yvew%PMKhF>L_()x{L&&% zKg1E<8HB_k<(w4a1!?kYYoqtlr&NS`uuWY?Zfuz;>~=NN4xxI?UsSC1j3(T&+73Mm zSKvLXmfu-UORvvLf096N$%bH2a5Y*YuP^$&L$NJCsF|S^mttj$E^QWyOw7C^(a#Rq zG&}0qq~8>Pf{FIfPO|zAal|eG^V*%iQQA1MoD@9B+~#OBV+p+$4?zrCTa52Ho1Et< zjz4+v&Fd`Pp77RiMFoLoYEVZ-eSL8WhOCo$f!RoG;>ANQ*Fp%vf~85gsuuT`qzUbU z$r?LVLLsM=tqKgq-6G9`7{% zab}v@qM3-m*9vI2;vwKK)Z+cw6;7>gYpYyNeew>UIwNV8mrUSW2tQx6pVXYIp=ZzP zlB4smQ0~mlkL3S_V48v;$hj;dx2>>?Mw5(D>n6kr?VD0j|(K zG)3Dhw#hF=NF>Eh{U-O>7ggI&2Gxwj^v2Ov)3tki9w(k!4K6lknc|$4V zOe*$JBSS`FMEE|@JY*H0wh8U;`6NmNkjpmJbi&nWdd|IA)t@4AltPs}%|$Up+&P?I z@_ar|%=I_x^3N)Y!L?Xpz0Jmv{a*a`##Ccvjoi{YZC0fvspK`Bw&r&RUsXpOs^mK? z6H&fhI(XsbWjrk*^?>aoKVe*@`JpH5`JGg8=7R_U4w5`bpb&@p}{3Y&CpItQXdCf4aNkr!&=eHR@gl4SqjyA(^lgBKMl7L^ft|i>~%g@aDLkvWTdbFN|sl@Qhax z1`4SvOX=!*DZg#{GBR(aZ>SB++mJ_liavt<+F8~{KeZ3cx?PvuTM2{_f_Z42mI8*{ zeJ(Tbc6@d0jZ^3lYn^Sybh0X@C4Y7=ZY?{uG^Nc(-FuDrui2rFe?xQnT8sxAFuzcC zrUc!1WRKjc$52oYNluS~G!Oaug z_iIglv0hoF@4{^hz4u?D6p)C55$NrKhlutvd9DP{YPn~D`X9dFCywIRF6!lnlxyLk zhYj`L=K7mn0k$J{3l&0eZAf&3tuZlV&+cSm{)d(LAa~bq2!vNRURoFIaP~$mR)y@YVSzUF#=lINc@l6sQFxS1t@Xtv3le=l% zL4`zcNJhTA%ZKw_J~;S{Ud`B8MK&@aF#TTo7J66UKs^NwI;sgN{ILjNxs&1L zUF4LMgWppgqd(_W!bBy4p!-sA8K_xW>ff#>nG|{I@z?!#AEMSQqGJS>&OpFTj$5^e zAY7<5=n7!8eKI40qQXg(Fnozf{=6zi&*^P7v?b2>xM&QFNEb02^+fbB@-RYQ$2+&M zeAS5lK56Fv*pmWe;9*n`Lu{LzQ2;GS{ZXV(y4nFCoJJ(AaK|c7^9cz!ta354(U`4h zk{c;{#cc51NgJM0Y*3vMNK0jAttp)Ae!P8nvN#N|hh9~S?F=@b+o8orUNbB%gR1dS z=|I#@a#k|1!prgAyoHdYZ+gxEPi7+gu?IifOyzlBCrLN#r(Vvw-!tn%rKSG0Gp8yU zNDx}N^J~g3w4w9>Rt_+jI`(x6;gR96fZ>bzHeHL(kk^(gUq6(x4)F!TYooh4)Qf_r_>pIC_8}%I>G(?7n5wR(letVFGr@L}l7%8ls|r2uq}WJyr~@ z+IEsEHQl;=l^ch1{eh*UV`Pgm%k^N_7c#+&ABdv}#*d?xkPlWg%}<%achq%9>bB;% z*6RZ~3Tt3?XZs}e3zFH%nGf%R;T@%dW{Vx?G#OhWwZ}l_=ie!w^k|hXW)y-o_fc}di1kC4FEmouUcPIh zXX+DiDtt?KBnkE4hI6(@NRty_AxM~1;tb3-)F zZpYi?{NEJFp;pY&lP}1db!}8V#O|mZ@JHlEByliNGY+Xs^%)q;+E=uh1^9O&Xo~xv z+#yALT0i{NwNll3`}Ap&49T}J2%YwGuqx~&pe0p&@R>sG>k z($W0loSefo-^S|$)nH`d4Em z+0CBkUCfzL99(-?)SwKBD7Jn%SdoVx1cw>noX}!CP;A}uiP0}4u~U|Lyo5%3u`kR0s0~d_ zroo&!Lp{@!>ah!_@b$%o#q7KFt8a@keF%|xoGXfwwwqj*}(p|9)HIn zn7R~a5W9Z7-(uw@O@2_&WK{yr0uRy5NOJG5$<-6*RA9DA?y&H!{%aY6~dta z%Rs0*df|*#ztSzp%L|f`S`q+b*=x_aU-&pE{#G%8rb7egrn!e435yC~4v_n(6f`gU zQ?tqM=>!=Yx^Go8RzwGlBM)XG2%9OOwz*oxhNrY!6P1a$c+?^0_H=KMS8E&eNsnwu z2Jwa45a^*EmCuh^6^u0<)aLm$ROVepWWSTHh;Qq*oW+;feEV2!Di-TX%jrbxu`3>3 zHCz2E@jbgy&MSda)VI0ZM&fiI9r&O7moP%hk9vd%*jb-TobH~l45wt?{n*a%wj)rt zQF-K8vc9d20uq5T_vNYEU7T7PwTnqt{$uN-=3<^(ZDt)YEQ+Q%t-a*<%Oe~jU|Xsm z0gCz_Nho1qqnNW0uQY6Fq$ttYO+Sp%He#t8o4@$eEim71L(10FBBeTIEHDBC<{w%n zV`9@m=LhCk^P}+!>nc4;*xMN996ZmrYJl{N+L!lEutxV?n=5?5Q~1rm!X*rbqfXO$ z68`?e(6cYcnCJ`P-S2)(^$sIXJUdD1qxCvZnPSMeH|N(n-f&D-g@g!7C3Lcw<4iLZ z>Zyd4KuL0{L^g2j0m*Cx<0mR@qC+XUM-;@yNA^`ftbL#?g@)!G82>tYFuI%hlzR( zK;@^CYPJiKJfO8nbp@AxjmDS0apo*U_iHcJrTdBI3%`M>0TS>vceC-Wg_N&1x?4}plbpVu zk>=4Z?+ruaT*U{csGZ_)_*Iv(dGwO~W3xjcLS=Z5QKzzYa%2vD+x(K92O*jl1Hhqs zp-lxe8Ap~gR@sK3y$ABQukkvhwFaPT_b~v&l6Nrz=Tf3M&V_IY5~)w*r{0u?noBRPhY$+L zGR-cG<6lKcB~Het^))?MaAD9bXp1Y*GQ!Ej{&yiB_^8l2e1hV1V_HQqqJdoz5-*;lE@@zdJG8oG+qes5_ zvo8ot8i>38+v4*PD+4?XW6HaX_BYbzp$rJ~*tW0zf1E_{c8IJ2;X?ePEBaTx|C6Sf zkOG=q?fw+{8ixb5v}SYT5KF5gHM6p?RYh zH2bj7M=9URT{A5nHj0mGm4#kft z!1yf^lCC+(LIk-{39cXG__be)_`Rhkk^$YvaL9on3rPv#_7y{c0E{^&PXxU>Cg#NO zy?;Y;({&kO5^GvcI2dSRpbgh5U?*;ge98a`hz8vWX~IPiOXOxK(i5S8YhAr2!3eze z#K04$54+*sYubN7+ZN;)6)8YKxh_Td&x2-3!FStFI)X{rMMdYL2iJ#lEr0#YygmZ{p3hldcmW5B@69f~ELP*xLY92&5UU|Q3~JI69h%=yoS=&om5IS!%A2>Lv!2 z4`>ml6-6WpU3p&Yv6*^QQ9EvR>6MWBG2v5+6aef7XO1F4JhOUhmv{DU;yaa>-pvf)(HHM4>~KvY%bgcV_-XwvDF8q?^~B@Sbg zUvZK~lRyZ%H)%1!U>g#nzvU-M7rNA<55GnID6XXWY@?P^#xO^}GRG8ppGK&;%Fdg8 z#`_w5;nnasa*2TUaaRP5V!xOaIV&soLZyx;$sjz3Aot^5(g3>=mH+|kJriqB=0Cp}8$JoP0 zOA@CK#mQ2F-!5^HF}C`lmzZ0qolP7m5;N;2G|&`T6h61HKj-{B(ExzQsU)9`MGsN{yTH63w3{ zwX|%OFdVLBM#|(Ga2cN97VGVmyyrG2Ur!js9X>S8Rs6!C5djG#6#)Aey_zl%I!JX{6FX}(PO1|tV!CPO$CIaAwwARg@_u$=i0Ceu-Xow4Ik*{ zrNHpuF15&0Ns1{+SnQjw>sR0WQM^8quj#bE^yNKoztu)L)!RTMWIhrbEDKSja=}P= z5)*^I+lR{D)jYc(#^`{2^>lHSiraUFIU);*B$s{uppN5#-t?OM_InNT zeG|NTFp!=qg6=Xy_+cKdB-srJA5W7~@~$@G354rnwrb{X{3yQHmFc`G5)}G8&pbN{ z=>W7A^3}c2%2y@pcPjVE6Q_Wk0B{ahjq*5EDX9o@TTE=(c|saNDUfT3;0`Se!SNF48h&%CW@5$A z7F|+EapZ>rdG03`k4Mn(?NEvEr;DHe>X-fSj|ajdqv^>Vk?Zac*HxQ8#JDm83KG&s z{p{uXy;w2$^92$aYOq#$F%an>(%E7Q39o@^(=slqfJ?dqG4>d>xu>V5h3!h_1hX>>ZFQ2us2A@Iu7FZPsZUh@ODuav&3DBw`{t4LIK580DWc7;>5XQq=ea^BeU<0A zOJDU&F*MQ>7IP|(Gz7y&3MT-7MP8}d$Wh)_O=TbC0K#MRa4rz6eiFqh~!gRQPU21`5~98b4*`jVN!>|GTTP* zs)IE$sQYNlgzeEmEY7->lM#(BEHG+{hn<}`+M~n~>@u0F<>4EO_dX9hfh}@N7u{Wq z{xL+W4!QdvTY)vV&jN$Z*0HVD@KnfZ7)OH{5z6fFi*2SioM6gu8fIxddO%?Ij=^krM`2X zlaJV6PD)k1>&cwSA@rjso>ciNwvheT#wfKP()i0Un7BF_}n0e6bt}_=nxV_5GEku6S-Bp7#sEG8#4t6OD2MGbfNS&WD81D{^~Y` zi@Og{h3KXL$_@H@fdf(x!-JX25#cLUug12I$;tT!%b9UOum1M&kp-ZK);AsYKOA-k zhqv|9ng55w|G%BB?J945p}WlOgGwJ2k5RUlc0Cgje*F&=^9jF}SR2LL7|9J8?v@z; z17JO|)_x2Jhl90~4R(;rhhhK5o=_xtKbfO12M^wEIY{b^|ELAMO?JX~ri?FRep zVREASS~K3@Pdmx~4e;mxupH7nJDahLot;lBFHc_bfZH0>UD_Oti0ueErR@g15 z-vn&>;BfLu!>FrbVzUaJ_l0~_a?vhO_%nk^*@l4mZLv1+%zjlh=~4LE@s4aPt1@uV zDMELE4z2=1aQ2UijhhTSJ_9Gfpk^DLO4yC>+k0NgGrD9@VKJYj)b%5@elB1lY zP}*D{@Zx*&ondNjQ2?&HX?xFw=K4-+I3hv9Ep*Ovti&kHIW8d~#Qpx<=Bd|o#j^BZ zdG>$Fp0I|c@u;*ko{eRf7yVuaag|i6S*X)Y5TYDz*lDI_ zf>LmMywxdsllY^=i29Exhw~3aP!+-sov}}3DCXwpT$mV%btemU|Nno#m}F5Y^Ua8Kp3FNk3y~r(|F8ApWynJ z=Ha84Njo(_h36&Q&Z)3UDL}qK`krU3MS}^JbN!f;^8$4$M8xC%)C-tLPn?Lm;GL zmzC9@%y_TDP#Z$ffbD+tG1hKcc@VSk)xmU~BUlQ#iMe>CA8PTo5}x2w@qJQGdL&(_ zNmq3$d1~j?aJLh0iU|`laWIpw;C&ehh0u6nTwIW#`G|CaxqZhVnUT}(v8!uzP27h4 zPrbUJj56f{q{U!{tCH(OKZGZ8r>>DIT0TqEvR3tz0ufxAo(2#NJ4MM8+A^<8xBAnS z17gA}mFD?ls`)6wL!jz2dZnk!YQQS)yZ`$6o>GbxaRX=@i{FBxVpA;t5PHe%FKdARatj?=DiJzfRE$?qlj0t^(2Fv zgCnc>NezzUVZLrbI8+^JiGxi@n+4*UGH*j|bIJ5&BRuFRAM#4SotA=)&#@vHw;sFh zW7teoyoHf0WQ#gXen@&nXkHO3*8UE^Q?hzyut@)p$tL$2HnDXgs0&uv?THremgOpK zXWWD&NFc5BK(46#lO?{qm>8PDyx=f6{0;>X)I7>mK0G-oM{5u7&WmsA%PCWmv?zto=`fM`@` zjh_`?mQL|x*GdGfutHtkLn*$D+S>Pe(2CnJ>Ty&Ltsn@*Tz(ykTYzNvj~~Tvy0++wvJ_%TUx)N z(EBByHOIwGV2A~Fl3uS}sKco1mn*$j#h9AY>uLvG9>}e)_-4!qRZQR{9*#fpN~Z10fXkzaQ-H?_KX1Rm!a-*sGCUaLcx5Zn?G1d%BLYNxAG1!Vru@hb98mrel~dz%)`@&*IlURjQL~(F;fY0x16pa)=N!;J(Cenr6AQAER=9oM=qQjuOJB2DKf{Y}suB0A4&_*c- zSk`-_r8*}TOal>(MIoqb>>7WYFcnZ`ULOCV40;ZsJ6yVy9D^oaU))Y!_hZY7jqZt0 zes5D2Kr^D zRLQTX-!7tEIofyQlf14;+BAralS4SHe7yrk)RP5m)8`KL25DbpYBW2Fe(saZN4e5z zD9LRLaTSUCpAA9@EMIzgrLJDp&IdlAZ^h7aN)~ocnDxH)L|u{ z;Z0{5G#AMJHb1%{*N1nFvqLcbEUP)zE%|v~EqUtV;?uG%HO;BO$BUsBBoq%6GE4Zf zRfA&&oxNNU#P%-+>KtF1Ew%TJ-a^d3rRW6|F)Kt2DBV-++7~(2{i#h_dgE#V<)iUZ zF!c|a)NTR(Z-bzDZ+7c|Ntkd-{gccq)_LWtzSU$^@GCm~;;`ixK70>jf{;;)<&$@c zSp^&g?vO`GbQU9{R`;t|C@_=rin(3y*+dNoAIhPznIAl;+z8RNYO5n-65(h7=naB%2I1MV3E1((hs-c@R@709p;J?MR=K(!j+81We_h8jyDyADm?l4^pu zefu;!3bgxzL*YHiceV?Yu6piJ0MJm-UejbYmu&h+556gu^c{7y~o!c;xYT zpEyRyIE)y4bKQ-RWiwe=<8d2tzpt9R+zvbsP$zKzCx-0twr*&75aDnf_e0dw1Bhyh zp!AJR9Q0X_>$H%&@>TtN23W;5TLgi>4-W+R7IHDhv0bA?jj8SFGTc9DFJ_kDd4*}# zvyBtAy^v$^8T5|rja|h6Ny^(f+DSiYeU?W!y~Oyp9G@u&CPv>fg6C;g6zxmBw`9!d ziR(+B>^kZd7KI^_baNjRYh>@VBmDdcKVX!WXk<@*D7ZRVh(KrZkQWPyc;4}jXuHnU z>Ec|{ax?QI9s_l>W;C!>U(`X1l3#SJ?n*XjGk2)KclR5T2fm%sZaC?BdPLPR?Mufz zL8Pmu$7{B|`C?*>TmsykPiAta#OJQ7I6P}>U#b&u+(#G^EU@V}22BDl72vz{U$6r^ zmCGF*ZJpm!yL-{ zED_V!eoVy4p|63(s&;vHlu5lU-=%{yuOS7KCR`Fua;%7e3XmK)1b3&3czP)TtQ^YP zTu4lC55YiryPS%U9_Dw5=UYr4)r3)D3?F|xW8P+*K}_(lT-_*Mfd)f4=~jW=cCrgO zzft{qss>B0;NIaUu$|(N!f;#VBXW!ywW*cW@trr~1a12I;y9|qr5MpP#P%+nRd!eN zsW)sl>rVzTu~);i3U!P)%L`e*Y<|uI{Ts&-OE>DNI8o&JL%+n-Dg; zi*A>)yYu8_CrIU|4bGbsH3|t--`*j6mg2)c1InqPOkao**vwl0F(}Vp86=o3i7FjF zlFb00Z6Wgz!db^QD>j=iaw>fbj&I6FnecQp z3rNVJ4*G`Qr=m1-iyj>=J{k$XWuBCiWv|`ZV`=U%hySJ3R=`v#U*V{j;K~1;MMk7WvhXXuhVx%BtK9m)cu%L$ zdM~Ecs-o^osmmgIj+XgCqR%7n6i#UREU=2sOAuoJ3>O!@k%SciQe$eOcxkdl1f5uQ zJiHB5OyCs|8q1aA6G7RrLN>tn42gY^@VEI2c;av^b}v2xG=0SzZ=xjde?@QN{{=Vv zQ$VRc*w9cpqGI@Y2Y52{$d_p3FZ&0A&1C-~(`r$wr>Cd-{irCQUmhraYHUo7pyhgP z&36;6XerJ66db{#{##Ahjb$VR?3i81txnM6;IDr_)4=S4_v5ns4~PG!XYXbsYx90! z9%f#+X_aD;WX&{?{P|t_N(_QD0ZBSKQHi7ox^LF)79b@A?nAGJ;lT#O8so{aRGz}b zWefxID2lH&>uya&%3gaK0X$C5iJJTx6$D#jM+oZt=x z5Ivip0q!mZ5H=ISuE3=`8Cc-LI~ZtndvsVl?y{7BMk|S)&3Y5S(7`j_`CHJasO5n7 ztGu(a>hC;>GDyt>UC>H{TDT`JN=;1gTF6r!7d?b$8ih%We)CVSZ230bKPn1P)+9+^N*k6oP&E1-+=? zS$oyPpYFC_1rak@>@Ts~^S{1iFd@HFkBsv7nG%kE$Aq8PlI{Ez<8+QMHSK51=$^}oxrX(pg?7aguM*~-Qg>^r z8c1tC#%Hh;&$7aPZ0*ew?KtIega*=)te>+Gk2HGmP0FIXj@8^>n!8(rry)q|JocYz z$PdeLF;MZWD=pX7)o}>WQC^qoE7jc$DqF9WKT;O7#m^(fXe8|cLOQ73m4TM8xStxm z#!m;(nr|gLnyM+mZ^0LPJ9nnxI7qI}BfV3d7}y@h5fiSmG*gETM9|sNS2vS5O31f} z1RAE8Le-gWtL?J}TYlQge|~j&J_uY_DdNI>m5Y?Hs5SpcUERIY525h)bRDP9T$#TW zkkLFMJc}pXoHFeQN>@>jSbLi=7X4}ystpB0{IYO&WZ1o+2qeauY34CKhGwY$ty+H|z00YMpW#k*+&XcMe3C7$<1 z7KICbeLd^C4oZ_P*C@_glPud#B6c8nH*VpZjfwO{+CflxxBJMRoW!%{!1gAYE=5J5rG15 z>Ru{=LNKg5vuE9UuZ}+1v7uD$EYNN+5%x>lb;u}Z4e0Ce%|6uyRetBLoq?M9KUpOM z=)XT=JQ7d46^+Y3O%H=Nd}IBy?akG_Q&HxWoO)t6g`|rJppC5ozG>=4E-QUfI#q{{+)w-t9xTr-q6zap>H1_W`h#*;0J#vA-kDT z3~(aq9MduZWd~wmZii0>D~dr%ri{r0R#->US;RXzKd*8Fp*7iDtaZ&a#?@}2xJ|;N zcYzl@arwP97l{_c(Q@IxG#iS%%rerX87s<1`M!ZPg7<4SJu(;&k)>4pBtvj%pMcV~ z+u`rM4+pzPsw_!C{qg=nlx9`)=?b+jF%fVxjw}8C%+u(z!Jg9wl9B$DCa^h}p15)K zzRgEvd;IqJMg)%mMH;EPtLay2FUeG?pL|8VLWI#%t!Q0jsPanij!Db+ z^-K3>?s01{^il>xL&w=o%8xOnU=sFec*jSOf3g5lY=$H~k3gBH{e6Z-_L|0uxa8h@ znIzKE(hJKJk21WhVl@(+P0Wzgc)WM57i3jh;0&kM2}Q-}R#n%vWEmKE~MFDpye zqevt@S|X|aH+Lu@wW3)jcSG>HvaPap-zba#chUkB`Hg_8)3u6Pw`~Ydc3)uq#WO$( z7cgYa+deCqMzE@|0ojJ$z9%+{INHm6l{90KZk&`Dy4S{HD;Vd0J4BT#lG$l07=N1( zLsnr&H}C5zMujr`{WO9xz=ZY7@^@u(J*~1dWl+i#p3aH2K6Bgk>$vM*YxYlp0 z9~q&*Bhx(WqP83GClmp^*6>VC=8q+T%^#jbMp(KfR;D$wK~s3G!#){G4~Kr(ga~oU zW>Q+d*XX1PAr^`cUa_aqrrRbZg1#fKVpO(%oYrcaJnKA5q&Sa6l0gV+bh&!p`igzV zBdB{Y+H!T&Xs(rf$%%;_DcmS!3%thQ{(1Y>EfJ_~f*ik*W@=a9eZ#mlbchdNi=fU% z9A5Tv6yejp+~j^7Qj%K|LgwsE=v+;b+SjL9tGAXX@pjW?lBjpe$Fyl9`X1t0l4iQH zkpjJ{1b4K%*B!kbzxL$mt+)Z&^K&IFkaeyfsRL{?NIR1R$4V_1JDvT(jXFJlvNSc-G8NqHv zPSoRuV93?_Fy2@FwKySf*)jRi)sxB>Tt?oP&Zd8e*5L+EAIe8s!C@(@i=ezdXr`~u zNSL!9?QO1=KE8x?EI-2D%he!c;&rBjV3cNnKedvR{`C9omtP#bgL|BEDtavfbP>;t zj3Lo&y-gxRWb;w-+q~}HdffSV2zAV3F}@EHXcKo~hw-6St(*VI0PT=b07DrW#S30gEHZDVgd?^jTfpqcE!){ zdR|{$@+$6Ze6|;ec%S7GQDP~md7+gvZgU=#AwT!dQn4!lUKoD;Q>QNkB=S`oLS89K zRFaZdE!5ac7ac5-M!U1B8d7?Sxt05Qvf$x25LXQMMlqK| zEfv%9MP(tf^^2w_61-V={no_72*nSntg(EN0FFbN2^Zab{_oLTrM+0N$>&E4dVTpi z?1v3Kn3l!5Yqk^9WFLJC#6I-`8&|6i4~pN@wFeyA8{;txIM?3aa)Iu{1P_Q zU4d#1lqu+_b0lR{bWZ+`0B`;ID+p_WsZV$J{VAV<`3bTuOg`?PAFJHOydeh@Dy_PH zi>vq_2bh!@9~XPN{e(0fU(Q<}6P^J$hJx12GSHwRT+dlrQf7CNT70-8dG7J*-Yu}$ z0@jfyctb3V4mO7Tek5ws;DcBv_zFGpL+cmEm+SRhoB2P#viGkpVBDOH;=4-<*v`}G z{;HpHO`AXPL|y-?WRsA1`g5CSeYriGVI9BzFUk^Sh1N_8ofeO9a%%kKnChLpRMq zLDQFRP4r_b6pBK8r@fjN6NI1k|1r+^5kyTOOup~ZF8ntIDbYp?hRauG)(0YG2J1dzYGq!a z7&X2LFe&n<`Rm3aY{1)f#LgaSEPma@Sn#UWgK9axQB^=dKucXcx|dar5=@aE$Vh>9 zDA0gew#mBk|HUYcK|dtVS(Y2Uv)pUJfcBtr0SQmS~|?;`GmNn4C$E2eM&X3bWhs z@~urH&E@x$@jK(MBmBhak$<3VG?}i>l#;3wFhWHR)C<0`b91+yL|NtK5n@Ql`E&=~ znAfQwc@cD12=nvok%N?l(Ca@iWZz7Or22?W;&k8hR@H=J6-0oEH(D;+M^D5I zAd2|D&O7V3$Q~jKK6Eq&CP4ch1lF$+Utr%b)KcVlj&_r&$c&3*p zonQlOd4uKxvbCTs7=0%BWfXo)%etWqvvmiwoQL(j|fzcg8wHa z7KZG&aM+cvm=)y27(VTFZo~JNFNq5r?{_O8aw+U~c>h=GYu;o&OA-(XfSp~oy)7LG zA>Yxs@pV@}d@q;i`yBRH!jss>Y$Q+JX|ovJ0+d&`iCn5}dG2*4fz>@2B4^s^)?5#rNXtj;Xb(4BXITuhVJ5JaI5L z%}c?=`|{z8$HBKlf4YlSi{aOEp0cGaw61sO{rhjK*KdMoRo>TLRudK3Cyf~yj0P*? z-Or+6(ru) zZhwl_ObNAK0!%XRFN?iL#>tkjd2gTBY3+WuW^FhqRFdxd5D*lLynX+vm=cZQ#7#}$ zR^jLTOGhRc76DXFNKKDs>a$H|l3jD>zB@Y%c+=)&9N-58Y!5dIOLIVuG_*O1_H!|9 zbAQTX*);Df0h{UC=#u&kj^6(M+}E?NYzE16KeeL~=6d%zjp|1RTdYvM##bearwY() zLCEgMV5zc1hdjItuCa;i{k1jq(%Ph2c?$@~Y?PUBa^jvUBuIa6TF@%KN&YB&ZuwEb zF=tu(=@H}CzW40+0+D$cbkrX)eSL@_0m!F0I)n>4jdenFw$dSI19l`7hKW}KHG_cs z=iyjkNO~XSOnxzaHd&Pq+OF8~>C>-o;m9arXoS_z*(NsbHiV7p`}^WTWevhw(J@8H zAo%ewnbf(mJ@j9|tTn`okeYnfz&IBBI66b*Few0YEZh6LO`bZ+rJgLdK5pcC38c^_5DLDp_8W6+n*kpG>LJYN7$RB6vnh$ zUUlt_*vC$;_5^>;HqpOWt(ct0do*-Hkf#0Xp@!-p^-T??;lnTqdNp$lG$z>etlBB! zL+;`(A{xKO&RWUOKer65m54Q{mt#M}E3YJ;TrK7IyK-SDgQ{_>aONy9;7!jc=}6gB zs>rZCGI=;T$&PySr43cZ#eMgnS1M_Y*;9KU2oY@gM2Ni4DN6#FRW8HH&l}iOlIbI? zcgfgY;bgw&gJAT*4wm9L9y(;mGAMa2tUu|Fq@y&kf8K5r*Uk(ZUjd#h^@RL62=irV z7L?R3;PzRX8wLvnGBI4xsa`K+g6b2kOc{K$$2!C@91XFb=EX?YrfN#dyifO+<&T&~ z{T2^UXVwB08C$S(+rOc|zTJ&YySmiJbMINJ^}m&rIUg`I0veBJduuJ5hv;T815d?M z>9S;piWCOt(Gd(%N`H}lP*j;854FXV4IsZf2iqC}(kL*LbfZJaAS$7NbPXyc z-3%p-h#)zDNJ)2pd%W-Gd7tC>j`zp=@4j*7ntiRk_S$Qo>s;sdAK)yN@+F(chfBKj zxj;BLo7L|{_i{Bp$e4I7NHiZ4pRZ_##C$cH6GxCT zYw6`{RHoM#D=TYg0GiIudJ``ZOehN!`mxm1m|HKLZc;TLZ+^=obeXO*P=uwC=t&2X z5JnRU*0hL+v+i<`Fv-yMQ;Jk}u{~ER_%enaL;2q^z`Y_$;s7JyMr-Rav$H(e9K4Qg zD<~T`cl;I~A3IIY*C?bu!QZyceYu@p%3%7OX2-Aj+hM0YlD0A*%s{86`$+u0W3vIr zeJ%Ex>JqV=VM}YR9Qyk5zSK~*^1E6(5hxH`mZ+Jv^2$^D5~37C+!A&vXrX26Y;6f? z%t}m@Vs^AEqZ&((^E<7g$6}+?;NOJaEyW^ z;Jt*K;8|CMINCsdfyW4d3Dg8Zfqm~p5!XqXGytZDyn)Zx+Io$z`CQIx`IYKM{oj5@ zyDvbo>$-JbOe>5ebPnl02az#%r!m;I9lu?Nwn{FUz z>r^>2KYw|O9+|}wg?r%VX}egOtRn@em!$HM+BHyEm9>(0V%q}sq@VpsdAl4%4neh4EASI0R~VXi#iah3Kv~FWQIoSIkBslj`GB}S@9za?Qj&vj zFg0#+E`ho1LBC-JycX~%iBnm&LshxQ`BqqP^Dz9)a&SM(!49qXyP5Lo}42qh}-oj$Z3IHb|o;LUA$}JTI-xw(0srp z83d4}8F-fjyQwqwob;gHbRv&yGM^^OI8Z?IA&8UCZVs3&u5t{4E1>o~oy0bPe*Vlk z`DD6|8nn4fDR&npN2tN!_0VAqz5$bB-LrMxd?TPfXM-dM9-6O}&bFfjQ%fU7Cc!N~ zQS?@m_^G{pkcfGha})GfTHJ|Yt~tJ%u7v0-8`{08Z&-)HEMITVd&4KUGLmn6bhd?% ze<{ir3&l!bo;`+IjB|pca(J(hLAhPv(7T@PlHA<(XVM}jIbdc>rtLAIQO39Qa20J) zIthKJ7=IJTTgNnPuXT-ia6rSnn`Lv_XG%%71jOElQ@ghv_ok=>iuXqmM;1OYG9=Menw85n+ciiqCpGA36fuXx&gifUmO044Py`p6z(-Xz3-tp@b%quI}6k))y`$J>K>s%9cm@ zl9L`$Q4X`DI>x+wsQ9|o`z|^2ouPuT4!J#}Zw4;#FI`HJ_oLW<0iM#;tkMz!TtKPd zwD%Nz(YFG>K^Q;|{T2Z#spS|<1UvLZOt@0E7)mZT_IBv}yIu$->F2{KPi?cA>#_Jj zp#~+eHyF%dzQ#L^2T2WF*-U0#p;xPih$YSx)84DMwuXn!&h#Q|0GSZrljql&ur4&7|}qWt74ec!)1*v}|X!X@*>Q_#vI-B%}5;gs2vgQT9oN zNc7m@a0`7GP6$YvtDfz;brff6CSqQ_s8zdZgxAF$|1$nj4Lditiaza&?N+L*$vV%P z5IemL#SO~dT%l>4EeWmzmS*L)(Y|4wU+2zzYGc@Dn}03cew=G5_5l}h+dxgbt%~L< z%`x=kTJRLFL62X%Uhel5H5u*)T4CQ-X~muG*o_|Q54BI2swu9gioDLL0*8v4R4yW| z_X;eyh>_p^8ez=YCNH}KqZDyf%1`0BfS+;s>kIF|snuMo+ukP<@90OsRJ$JnT#>$> z-n|0X+Np{G?NsATmO4B_2@fzLNX5>`&VdvjK^O~jyGbOd!)rEJFBWNH4}PE#A_n0l z``VhD>^s807@u7(qXSZn_U2}T0r8?-Oc+M>3$= zE?!qS-mVj90C}uuP6JJQbc>z-WSr-p-rYL%8%*gtbz33WVrZHC5c@^NF>LvUTC0cQ@cl4{k*0CLUs{J1Y6=B6Z-@pAWqF zblxR|ql{c4ufg%itbq5$cOC<-!`@%ACFCRq@IpSlZ3XG4;}0jw7ayP=RU<{XBTl7) zPMF&xs$?wuSM17i__cfI+Z~u3eR<{p;gs8{HH*t+msi{Mu)dT6$1tOp!}Eh_`+Udx z9-DNl^@&zox3LlnApL!OcGm%On}CTNX*DHgop&cpgODWHr0q~oQVu3SASh5Bz`D4! z-KqvJ6zbQoD4#^2i5c|LXK?X#Y*BjJ*(pI11Kf{O^CbbnOEEe2Q{Ow`CH<$P2MvX0 zNn><#r72CEc=znIAO>8eZn1(!PX>6(`nF$%ugFgf9ZT`j(|H(_@(XU%S+igQTFc;b zfAzoEoch6to-YDx_LK9?rh%gAH#$hk%&KK zXKpb21D+L+RTrZ1*Y+G*wb**e7q3U|y?P4`T60M7*V_L(JY<-5@TRO}KelgT4 z)Zfi$_Mz{XTltE+&A%@8SQ^T!yE^)&gg&%ja z-U>Xie=H(FpRCspuQ%`6e7a#Wp_uE@UI3{-$Vn`v#k8mFi zP<|*MTv`@^aNGkZ2e~t=yb1&vbHiCgs9XqNUU5r~9)?A(T98*rZ+YBrO~0Q^1|)kY zk0Y)Kw1Xks`(x%sjH`=nY<(__en_n%Tvdj#$`U!G*)FK73Z^@Wk^@LuE+W*wWcS$N>i(Kwoe58UVK=5%@zWM50 zh1lYS`L^EuZhwJsoMn}1^PvZ%j=_Rua!4-r)ualq7i#Hgz2Jpmn;k*NB4|fr$!OCj zE9AuiE;E5Qr(?jR9#l^TEpmvt`A;is+p+;|Q2B!k{Wu@w#VH|vU+6N_ssVQ$e3l9$jNAba!rtCKWk&C9hB_vdk zqteUB*X=a+d3uwN*D>2hjS4g=OSCE6K)%?NQKxn{H&A3 zf`xV?Ujt)@POmCG?RG6+KC0@E0|N`IU9!LnAKSV5n|S0d%PU+8YK|AX&TpA>39B1d zKoh7v8Dm(3zm*vF0lAUj0qVl`O|KQ(mGeLDRk*x+9QsTl69qXsZk-vdGDvJ562yMc z_8LH_ulWD$zZSInzH&tcZ@*AjLc&E>5zg-7s3QW&O;gAYL+alwzua>=na!E~wlTu3 zYa*};Fjp*HMG|yXXGp6`491NgnKVB3|9H%Kb&b9c5M{b)aBQBrWho(g%k%1&x&Qta zR#EJVIgV?4CuimEa^E2!mRLc2?wU~J(w&4VRODYPUw zJW~$rcUg)km;h&&D-U&nTTdG^GWC))Yx$NGfX^{}AV4*Fs66gmCOvb#{#GBvBVvb; zGR!T$2n?L-ImK5p)j(%Ge?|53wib1`f)|HpqT+zJs2s=a4d=f=y)k$IYYp3NR+xte z3g}M~qYOX!L!z<>!5S*!e0Xoci|jeqz<6q!=VgfgotaC zWG|H+Tr|@+8eTeHXi%Kwc0zO?i&Cp$rX*>gOG+x)^DSy{4$~6(BD){F5)1e31@1io zPydO9-dilH-hcaLudvMqbN=x$x?4H4gffK$=N)@X0@AoOAqobX6f?TO3$Hw3yaRsJ zmJjP60dkb#5tB8T@P;dT;Va--?>OLsx2t(Kwr+Ry#9>qwyKP@bSWbdw{9*?yT1X^T z+d$#`Npk7By@GoTym0?M9Cwc`>?g}ZJlv1C2-+~9@$6evapU1pxthd6gb*=82Rt+k zghO(LL&;Ahi}ng-lu-Y3pcvPnYIPf;PkvRpb4sEHNASU}}G)F~H|N=%{HtS)~Aw2hB79oxQpkeTH7K z`Y83v9Zo?fDjbC3nB`{ld;-pE8Oz6VE~!A-+Vfa9=>?596l||eWY9oLMj79SY13FpRosQG-nzI8u%S5G zLxXdc5NFul8?ZB+ulCD{Ow z?SvphE_O43+STF6Eh`xAY&q(y}OI0D(xF;OHK_aG6#x zP^qDR2|viMlqDfsA-Ge*f=4;Gux2Gc)p7T?Q1;TQ1RV78>_a6z6!{N(r0)WX@14hN zlM50LPf~fSdSfvdsTTk%)0RIMJD;a*&g6VxK{*^h=~|!2rIA9$sPHFWW83F!7AQ(7 zUAsQz+~6D=a|3K{=2b>t1Ys9nmiT&iKn29lQ=#N83pox@%vh9dHBWa=RAr)S&5FMd zP?}88s}a?-8!Li@Yox(M{N0w49ic@_Wko9SOrPn#dV;2dD0od<)IH$;1{y82;rAPz zie;M44<6NRwGl3mt>|SMvk=hbu2h;>^xuOyqh94bw ztHT>EPM(M)&<7ta<=KsP$MW)G^ZZFC18`VW&j{QpTKLZA#Eq*$eTf>9f!K# z6R%udcoYrgtcR?1JSWB67B9s(Y#;A^x|RFQYO*=i@lhB#FgF3#!@dRkQ5v9I&kP;@ zjF)+BVeb0x_Fp2S1G^byweQRym#kiE?8*J|y%8Wz{1ySvRyGLg(aWI6I?}>?&5Of(=91%E}Jabu8U- z97RzBzERBTSc#B_@WDD?+;4~O)KU!`d9P)%{(k^J{@1%V@9-kELUb<$J8%dI-l4O& zmbd%s05(0GMoKWacRjXwK~))q6el1Q;2s^USD-~5JzwDNIRnrL}qI zM&tF)ca+2kR;&YLnC6%fT03Xc^OlFr=vUGsHa!-9SqCW$M}Jx#D!7NI z1Xp!$5$Zfzd<~UIGc3}@!yjusJO^|64al7+H6cuCMbA!WGqM-D;zu}>&B7rnb%JK! z2|@N?h^<~f>&1DWO@ShVv%~(dLCr3K@`%&r#Wet;MyEWioFE~+k(M%mUvj(B8hu>^ zQutt@-1lTrD1>K6e8zV{vu-7yA=;?sb?@wiX3=c|Bv1!<iV2hLO_F8En!}UHT%gsxJAs=P}cQsE2FVD1D zVE|L5&?FKQ@av5r8|yfAPho=wl594&KKZh%TO-r4THY%)@~L_z=@kZZ5FE~WO#_Wv^w)hG%w;IE%c;(BMKh5BoPiu z+2Rz~af`LFy6x%GfonrP0BYSWk9(l$gl77q_C{W-PRyYEtj3sS2&3%Da*h}%RVL&P z@R^i_zT&g_8h5$J5Co#^0!6Q+LjY4@xTK;pn&;HR^jMz4H^FIP#QXUZ)`B zC3Za|1#@G7Wsh%B%sn)!dJJ#)lIgT!YJxP{z(g>AU)%=R94$GXg|%(xOL~!EvZh+k z@AqQJRQGBT2(q80In0rcG+9=p#)^B{XKA-iqd!iGpg}H zvS41w*+K@kvK=pbaLZ-l3y^W(uwJ$}jKEwqhn?WB5p3h$gaXf0zpY8h470BHqxt9ghBPkHSOnNU<_^uQx3;`2~?J?F80P^Q;1eAY-`s$7 zt}@5y_085HcG1;EU_jB6{gMzRx5j-Mfky|*8nX=tBVEZN8ojr1fKrCLSz?bG5hy?k zKPz}v-ghS(9HM_Nd+*WXqW)2BZuu6jPe@WJSIlDo`m_BJ(;7v(gTpyw00+f{fa`I# z6Q}hB&duInV1Y-%fS}!6N1xH#drLb*&Ya(kr$GOFC%HL_oW-AE2a1dY1qJRpL~nNj zJCBgips%d4l4@Y!aoZPu&X#cWiuJ4-c3p_(dI#uBg5Rzkv% z%=;tO?nkSTVo)@>^(SBdE06jKx}Fy@9_P;{5z=YL1URmy4ZdY5Rk_S35sf^Eh_R8S z25@JEYcjf3?GmU8V7be~fSglY=rocqlHnc_6U#t;d35Bv-4PPIf4T%N;nBQ@z-(=k zQs&oEK=0`qKRv>4)$yh!|Cj#qsvpZ!Sv^+-=lZU<=&Uh^_qukY_9#!7*DoNF`OXl< zD=}icaw12-vBe%acM%z0-Q$3XhK$zyolg$1*qafFm&+t)C1!IRjmTgYWj-`f9t<*7icg zdtwouViW4ZEc^%I}ZPJ!xLvZ1=G2MqS^^aX<}nRLg} z?;lhThE1bMMvbx9vtU9Hs0n!|@_MT$5~RJybyN3R@&u83jT6x`qRL_chudtApr({z z_Un^(wcq;99%(-tb|RP&%igjZ#lt%WCy31llU7t9s{8&|NrkcRUyy3~EYhz_?;(p0 z&etenbFmbc!pv^yN^Hki#X*p!=wYHh&8N(m8~Yz`pmf+JhCkOx4aQ+o0KW)uj!Zd% z>!%SB1qSaFpV!r9I&r(d8TPkTPOsvm>>RyCJZ3#%0@XvAnN!@NvciTFBsra7+x!`h z;r3(2{y9}cIHcC5%+xSc1nq^zD8PLt5F}CEok?7k>%-YRV3!x81XnV!-BUP|A7FzZ z#iR*FvAoYvZLs)kheU!Ypic=m`NBZQ&=uS%GEAf6_o(pc?>rC^2}Paj*guvdz&ZSS zQ2I*@+~@P?TU56hupu@06JvZnD5c=`g`=Tg0YNkjJ^WYHUzHV%fU3<4)syZhJT@Qb zs;Hmh3FbE~Faj&K_J?3O{Jtu2Y>}Sf?1~=BJ~4?S5fKI@F{=cQ$U;U0kPZ61Hx-Vh z;+@B4LgDPM6_7jz^j>oBal%3=qaeufC_v$ANx!iRo~6KYA9(I<-1n*OG{h^E(32ZL zGMU~>27H!`%&L_<+AK}`Isy#M=AWT;1Fb+Lk%E@t(;Denxwfl-nx>LNPX^(+`UW$E z7d7GihE8q&EpPq7{nhJUe>Dwp)BxOZ-}QmFSA>Lb9VVQx5cCx2>$nR}5PB~(OR5}> zRH%?fZPo;NF9=>7`phzZeYiP{ZMPXB07L{X5wOtrimx2}W!gRlW2IR5ef&|M011dp zdO(WxmPGZ7(z&VH8&W`k8W-UZkHON_gm6J8zeZbothp-m@E)NZ_DwUL0ng1gDgcG6 z5^4%BzsJ}{2~0_FrRE2Ykg1ERtSQGap1q>0J!CJL@6_ND*w{{ zUW^yqgKvrPUX=LnJ1ZC05(AS+QuT)_B$1cWK-rY7b3yluh8~J+uDhI&U>b|~sbeR_ zBY+ndk*1#bMlTK!A(%0Mtl)&t2L3Md{%Y7OG8m{x;k`IlHz+&gfgoR*5iMWGLW90o zRYY>*><&FvSWFC?ULMM5=`5~WjMuOGB%KY&xkmewErlsOqf`YQ2r-lpj*8X3aQ&|55<5!*rsehhmHABXzDf?p9CRP((U zvI;eZ;4xrg44(&&`v5HO+xEN->z`MEFbq%^`yXbT%2E>0RRS0Yzy>?KfUNK^R?QLY zy*o03@_swEI>Df}4LFAIp8o#0-mF*D-S{DLZs5@L1(b=r_D79IKr_p7<(Nf*NrnAz zn&e>2;P;3@Y424k+0#Ez>`g7sR6x!GxuJv|s2KJZoKl|EZ#AknwcmI?6u{c}C=J^+ zA1x9aJ)EO5@{(RO(zujY^#9NrxjsY2{@zD+u~#6kgxB?{nj{m5N{)bf_)6{4?}vc1 z=h&Ar8y(Uc(b0aiy|Dbw;e*Hx5}~okn_yvY-6O$zpe}YLB#P+(LM#CEXv03zLM^~i z89o(qd6@+?g4)dm02+}8G~2_$wONY2$<6nxr=RhG>kyTCLBCl%Q?T#TmkMR|zgS@9 zYxvPK;h~lUM+Wd^9jfM?2y?7$!Cnmdq&X<&tjLFel*IhiBT!o-AIUW~)<_W!!zy)` zG#;30L`Ep}Yz7}no0ekmbbj>CaXFa@*i0a<_0IdVBFn*pxNxEgNmvOK6IW7n@mj;y zsIhKvrp>a3rvloqKiuokE6CTrL|@u$T4V|otx9hvixJ~}1c<1XT?xo+!-WV5R)Qn1J+AaI`> znzD)!$FUQSi*<*rKR(EE^-lL(o$}mhDsT?jFf|DaSo=P6x?3E(-x#oo^4L_JS|dMv zs-LX?T$W`iZ8s$G>f%nXkkE(yj}FvxYI>t3WH;I_vAoZYpAOCNE%q>*i;(EOR|+IJ zI4UFt;>tL<5dJuYgD{(K^hh#jTmE+A!9=n93-+f9m#w714}m74ODSRja7Gns$Jn3V zAe{}F+5I42_*;oK2zB&ZqC`-lL?Xyr7A~{yq(WWd+rbxWwe`u(d<51B?~AqA%bpL~ zJT2)U1&5+m5qv0IVf+2qnZ0`}9xeaT)AOU*i}hJSr0hXTr{^qSq%MBctz6$43N8Lz zR}PzxDi9C;ydsJYK7Zfo(@EcKcJ@u^TzA_c)4%qOIYm zLr4⁣e?bFE1W+sBx#mAZ&9EtZ*!?wWF+y>5*CRvHTx084p5e>n~!rqvlwlz&XMW zu-3-tU`!(C`}0xk$XkbKjU8&&1N2zN+1HGh=f;i;eWHU<=opn^Cmz!B=(!$E8hhFw zunv`NPDh&zy13yl1ro1OKp;?pS9k7)UJ3hf!`)+tgIXkp9PQLI||i>`Ff+i$W$E$K*Ql zBtUwi;jK{LV=S3&ks@u&c&fT-U!Wrk!DN~g{GF)F^TTf1yl2L#*>-C4ajG2#5+L73 zY@5;#N$p#BjVcK_f6~D)d(`P+b6k1|Ckhxjl5x8kFM$DffjwA=3qHSo4surkq|8p? zZL9W@{?twWWZU!lki*TMcky(vw!yUuGR@}LtaWg&R`Hom%1=k>-eD@(M$_rWJl(bY~D`TjXFYvf&~}rX+_N_Pg@-i4s^s$F$2zn3|*cL82syO4eooy~ki{85I=PlHY-o z<#&Sh?iqB14l!Y(brsvJSwMEuBmGksX2h86)n;~*s;R&p#>-s5fHMHXTV2_jIT3X9 z-3xy*$GSN;O4urE_KKQ8s`#{A%H1NN)EgBf*7h8M28Ut#!>KqbBSc*~DvWnLezOZw z##*y|Ay4uEZz8imKS(DN$5%z$rfke*KzuvrWc2qKFrAf1T}aiGK5rANn&biFoOF|93j+w#Mhfybzjtau$_QA ztp-D2shL`emeva1SPK5^p2T@nO$@bu!O0ZRe`k!yUayT`gDwOj_vFV%9_H9nx6Acr zMj8J@>Dgn~vbE3ke}vKGOtB2<_f!cgo}drhB7=VO9zek))0`UR+Kbf)Om=r@^hm?I*2jWUq=8*zITWmjRw%99ut%6k5s1EM;QXq zn;UeMBK0?QS6Opss?~5*&i>SN&A(_NZ$d4+++--Kl2{GmOw#8(;v8)^z8Yr3pKuLA z23B5FXiEa-TQ?_MOsC3k+tMtYDvA2}xd3_wtuy`7JcvSn-!5!a?z<(lCZ$DWJphJ_ z#BH{Eugb;(=dk{PjrjgN;6HB_w}_l+F1Qebwn&#~_EkNN^&ZIZ>Ug>|{872Vj)6=8G&hE|7Cj{pMI+ddWs4=tx5gHgP- z#LzLp-X9?vAF($b3H=$XSw->na%)xwk*fIqwA4!}YWi5ZqB*a59vfgVUw;qPTZO8) zvoLdPt!5BzDW}<|0ahk`9wl~VN?#3Qzx&mb1WMow_5cMO@V{5fxqt3Y2*C5bhe0M=xi4S2}$ z41q@*TEhO|14H;%!*WOs#I9pE(RlFHmLS70o9Viso*8gGUUrH-DFQrh`8~^!Xc&mc zrA)giT|~-<-SToLoBP&AAs2Pt__QUHhYr2>XFP$d^x@OGytAd%V;Z#h`V#F({va4^ zs6qhvk;c*N_%s8|xI;#z9rLppKL>E!8r`~!gGHcVc}ku611o z&kIpWFnc`X*~%r(;6G?QN8#QCQ;->pGkbZ#&d`8P)?6_Em?;N#K&xY1;CBZVH=qE1 zcl$Y+{>;BmLp&~Ifp*sXsby`Q%u>(#qu4hkN9q501da-AasD8fg%nckAQ|ncVF#0& z1Q9a>^JO)cd%etN!Y6uy0h&0(Sko&3tHc_NH~`c4A+WPXvP%PNdv!kp{A$M-ZrBG% zdy7uU=8Hr4UT(_^Y!1OmMFvYEllWkYQ4Re_fP4N$%XA$0e zkor0@^?b`f_ONvDxp?r!Qb_RDLO#oFLAcEByFoKJ5?&5&HlK`JH##+B%xD?TFGrd< z13xc%o}K}Qa!w5<@w<3I3ptFt@va4E`rm$?+>l!X`oA9GBRjrOo=`WTMEP=hEE`wc zZqUqCEZBRaMCs9bq~>x-LFhHV2pHu8sw-kG&A&Bjk?8CU1ab5m0GxXFB7eKaA?GGhTT^6Cyj-2{ zX29$t!9-`%>(m!Jm)W$9g-4+1Zae^gdFt%U{UWWj+2%Wu@)UO&wpbj*R<`~(_ZpwA z5{1s~q7NPurOrVr7(lki7d!oI@)Hr1J0sAeR+|%vChDr;Ya7%9J0{QDO6;Nx2EmtL zRjRmU__;*fm|N8(E|N@9OKK%|{zJe9kKAGHAa(OuZ*zmyj~vtN8pWdET?=B|xuezJ z`$xy_t@;0CNPC+<2ZIl+Y|aX0q1Ki?1Javjf51)DcC<~${cbd@X8O&vosGPTL_-xqfdkyfMyzDzfv_B@Vv(mW*k$hUPDLRY_DXGe zF6^3{O0rB*{uoGa?ncAzKb>v*%$0eNsPSE{ zGK98KjY`DksF~>68(+afR6sVrk{b*L}fuKi%vkFYl1N28GippS9A32G2JCmm3N4>QW zelEDoZxNlPgb?59x`^1Z_0x()`R1jAP1?<$UJs53H<~>Z;cbartpbO= zrV*Pd8~25e>M3)DgFX6_3{@(*MV7J66hW_B=0Qa6m^|hHA;g0gEL^jzl6c4?CS*zQ ze(_?{OVA!=RZ7b$_~b?f{dOY*KBL#e?aGp%Prj{$7NzJubYZCQ#-e}L$GKhBm+j|d zu>{bOCd7R(Erj{e9AK4D*vDaa)MRYLEe8=79KL+%+GO~PP_E^lo7DoTc1u}=|D3wN zIZhII)WfOnVtE_J3l}?oDzZ5TS@`%OYxOmXD`J)FC_iq)9!7B%?wp+%+A+>#Kgi`{VE0FTqydd~?qKT@pUD^bBHSe}49iIdt_3{J!(YfyFA zeJ!6RSm;^qMMa*kdLp;JfYZ;v8G$G{8O**7cEJ%#%s4to3{2w~^qmR0I+*OCHtLI~ z0%qI*Y>vf=BW@tl@Hd0)x$t@g1d5&!6NGc{X4^w-`B~t$W`Xy?-rMpPtb(_pF7i#| zEjq-MI4X}^y2x3CpM=eY<@iY&IL^LCnHaSmW8Fv-cKQ^eq6 z0?p3;q+MUatS1J2K9QU}01;CVM676(czoD`ihO{&`!1_PGLH7d*4M|glO^i8S@bx# zbzDPKFs^sgkOgX3ouT(RnB$hGV2*#nkg~lpct{w7$C&w}&V$LTzz7f=Qm~bfkl`Sn zL}2&h2@soI-rB?a{&`~&G5va)3A)N$)X6*e#}<)@HYvO?4e&6H8!jo}>&750w;_0# zswJt3iMpG0GT)pJ&M$}M(_=)_*mrzXHD#_bS)v&Do>jr>9Ud0}G=4+CvgYg5Ym}W} z_HP1^Wov*n#&+c7_6NPR7M8=~r9lC!a-BAPI(eYLcC{btOJNA+3#aX&`|{>P=lPm* z+o9I-#rVj>nKE~0iqy^mE-xIco7Do3{?#5YCM*<|Gm*SL$;=;ow!o}CU9A}T_s4O; zJ$hMNmSv`xaS(oRx^7deR$#rr6L^(%SUv$`#rwI!>qz(joZTG|>8M!)HAb2vU%qEk zU`c3U7iC~|{Ek*$ZrQ;nsbGi}#04W$uu=zauim02C)ZCL1j4R(T=Ub>8N2FLp^M^! z$_t7XXEOSO!TpPBdhJvjE|EXGWvLSKC$Br@;z!1lR5JS?oW4)GS9xsat%wb=HujCV z>KNk>Pt=OB;{xevivH7>g@W2+l8jHyPBPE({Ac_zM?;N1cLvN}5<*>YRP|2vwrnql zr8maY8n1@_gzyKl`qo!RNZ>uUme_kEM8|C$m@s_h@iL<&0y{CZr>vX;&eQfPZ_v~b@Hx-pZSM{!5@@b@Y6(OI? z1f&ZB6>XMDdj%et4i3Q-Njypz-{FlXF|)>vRnXDO$xWfAI+wK}a+0;dnqcJVG3=X@ zy!^(Q`KjMt4Zthve|Vp-zg6(OMbG5OB^!MAkKB&X`{dnVlTpr>$TT`Rc!C2fl5KQ*tun-I2WU^Y%}K zvkKvVPNe^Qv49jhr@6pd`q8-TF~Y(qqVM!Ts?c|$XPP2j!xPxqk$WrglRR&*3;NDF z36sa$QW5G5Qjl%4fRsGpZ9pB^3g?^2_`#uTDItvgY|C=9$*9b^-G* zR#AIi%J2LDeGCLmS6vh^F5)65jhY>K$s=-UCVn_{e=g5i$$cr^r{C_<3w4Tj?TC!)PjWlnshpN+q79y(p}ksP~MF@SY6FQw_}$%LbF&-_E;)@P+5C-qQoyUFnw5h5 z%d%|DFpdmTos}7EwlCMv*;djgS%}NQ2WeP*2#Hjv)+6{*Z^RsOf0m2oi{$TwDFs?$yVVZJq3_4uOU0#l?5PBgp7D!6^Z~UpAh)vzpq;J*_A5^`jC8 z{n((pe94HG|Jm)g_9m%Ru%yK1{;(a1$)=OwRjsJ#~lS3wbq#<0bxi$N6H& zH%w_t={E+zT;WayJ1$YN!G*H+%Yicv2D{{3Rit3&6lq z>>jV%R)D~4_0uiBW8L;x>gS4DlIbXZP0Fi(hT&cAE2Rl`0}`+s^y+`A?h)G#TX{28zE^^t=2*Biz&|9QxMe&O|d;31MA zfl4Y;h^^I$*DgWD~BJxk;FfVDGnjElo->oEN3T^$*%YfeBuL z^RcROqs{#{Gbs{yNca!&rFVNphWj&BPB{XL{DY%a{eE%-Oh~`aT0W=ZE-g{)v+iq3 zr;T(KAL3H>kLw84c-R*H#Z9UJ6OBKV_VeZ2pm zYp@xd>RBnt^}*-04edy>Bqk$O5CZkoi}@pUJC;5!@BL56618}FJqK|LC})6idp;bh zlGxv;y(C`qpWLmKb)}iJN$PuZ5Rl{|v{;La%=_-WQP=X(UKF)tj{>`he>1JYbqG8 zDwKX-%7|BA!2>J#1Ylr&Ize62rJJA=(az0hqG&p&n~A^Z1o>7UQaqXd-HO%46J09QeUtJx1Wh#{;FZv^IkjPnKUbVth83u zm0q!;7<;U-Mq)ssF*@-0Bxy$!M@4aNeJ`cMF{zt;m0 zSStME>If_~Fj447ef{T;{%9_EKH^~H!_$2ps=t1V4;#U9LB9J9 zrv1IAl;Ob@Cz*4EOntJ(tJ@4Q<6Zn<~z=VE( zS=E%-2bpgL5z|QD`#zr2@@H$77mEjWE|v?pD4bqEa4=g($zgxwU%XB)y_N^w4(<*% zE*r^CR>@2GBz&#B<{KgK^WCDK1pJ5n7arB}(rOOiMXrS5g|q_&!1GPnGq}54(lKS> zY|Uo#WiX+XWG}<1$%iKw9QDIFldh-9u3q{=0qnxs5=Xn=lV_;L6~IggbK}^>* z>vV{5_FKs1MAtHf*LM3QH_g0+$9RxL6v;|iZ z8#LFEJ#odOdUp%01oA=Bq-kMv+0>}&NE5>!m2{Kb+TUNW@oW(wmPz$ElwX>GA`dm6 z(TmbDJ@OCwcUJlAZmItKfoqly6KjZAm_vk^KApX=azC8*@yQ;PQnRALY3t;tO2;O` z(_qAPItAs)z|{lF{P$5iF3kWOf4t1E;;p(%cKvr2>8|N-5M&A#J1;*y+7tkc(I&t3 z{9y8wccGagqUzjOPjdjlZQ$){0#Z(@cUaCVa&UhxznRo#eA^>Hqs(PeJ4WD9pR3m& zBOM=FR+gvyIQ=SMUWTrL!;_5?c3EtT%I}IUenX`L9i5@mRg2J*S2RqAaB^m}sk~sC zbTF~BWzC9Zt;b?`e5dAM&IGaiWK&Rpq;!Q%J>g+)-gtN~$McW)ds#-cY!?oEyru%PggiK$4GD4IY&?9ncjLPY&N?n`+%qjC_T4kU z3H^h9bw+QTzb+Kb@~SAbG{I?(I29Q84)_I!o8lyI>R%N~uc8c=0B; zr0~Pez}U~6UE8tAw;>2EhQf18Mt>SSw}H0gK!ehp&F@?-)l4Itd&(s}PQutvMYnti zST_KLLfKCnns~@}uL>l;0@_i`R$H^XB~CkxRi0bHiU$w(EePhWVCD41EBJwqMNZA4GX$%B-?5LAWF_{r0yy7l(Hcv%C!kB$53C5FQx=etL z6xccP0b@rPfio{U`zFP|f6UAQ22vrEKuzMPkj6Tz{`)+veWAd<;InP?|NShs1_D0x zA_t*#hvT1zhAOClDMQi>fDyYxqD$1)|DptRb?@)rP@zBO|^;6p`gzPB~4h0-)$w%Pyn@Msue5zi(4c0v!yP*^L1cOT)-55kW6ttaBIO%Kw;8ffTR&29ycOfPEPMu&HoQr`IgjrImKOL;U;YwmXwsKeiRd6%UxGR^NdeFxxP zY$hYpLN1Ow01x-(115XbHX=nCu;^wU1#cWoO2nDz8pxU~FMwg89xwJJ#<@iPM3N<8 ztF~enW|-w=w;b&1`p+bJV+uFs=)}?F_JGG8KWp&OqOp#M1WVlLRUkh!eVIB(S7nqN zEYR^YIn}k!sZ|b1C)adPS#n2k-?@$p56N_q|G!T6^E%RHvWmKXqwa}2CJa9*uYT{_ zgV<1=bBh!u7$)>Q_CASZuFUWI%qI`sH)@vzjd#R&;b#*i=gzf<^Hr0sd`LiN>3m>& zda&McI(tdGsJwI1xn1*?FHm^TbNu4RruU(c1fKcD;a`P}#Y-d?ZQTjJ+l97d@KeGp1GQ@%RV(9n`Q zkr^qzfJ0Q!(#>{0&-6*X2cTX{sDEyr+ni7dkb|xT)Cz+Pvl5SGqyD+CD~kc@LqM*S zG%~5?8!STiG`s(V!zzpL$Q_9H&lUw`4Mx#EdR`ys$D%NX_YDJQm$GD+q$$e>kn;TbfFSxe~1ueBt820gH2pOc< z8ZYkSceH`3<+oc0i}?6~h8O{ge56#pAVk)bNV-J~*whGJ=1|%pLbD_~JN$>&#M0wZ zK`m@Kv5w$AU#Lm*eSa^7dfzrsu$MF-NKSNRt(AocNqiOZ{vI!MEfN37nbUdP-AB7l z%o-Y;&k>_HaIax;Ph_8C$r&G>d|u?43I;ctVW-{Y$tz}}1#+7qd+MF^{o@SQcJ8wejK5{O4mlbL1pHuhL$JQH}((NZp{iG<1x z)A{?_u{5N{ewd)L1gz0Ye}411o}|)FzG5cYxwLiqoCTFK*F0Equ{dl#J1zLa`f3N6 z!8GvO)@sK8a8ezj{m2^XWu&J{^Q34`;tDb@KWy=h;4iR0!;{tz**N?UOP&Aey(T9I zN!9!p9I4wA{l9Ibw%_Q#(;NMfU&(6|uLG35t44UHL1~Rp%>?0>A9VS8CKU_nyy2j< zmm5(hc>nv;S^(*}W(t6QwJ!|KZwR^oW5Wf2UB)>L5+w&%73Z(PJM|4YfzSU-PnoYv z$KNXc+8z+mx@OxJU-`YoZ=Zw#!ZVk)-)vO4rbN-(eQd%$4nQ2n_6fr^;Vb+ujgqzR zV$6+KLDx&$JSP9!z{EZ24^aKCyE7{LYNQpZ7iNfYbug5za+F5to94WeSGK$4i-m-?OIdWwM zhuJSNXeKto#0+0}cW3_7|7_9p_d3Q9z%LUZXn8ahymx)h<2EuBuixpyO+w zn_kw-iuyD*av5c*Oo!yXb(Zt@Go3r+f6gb+(RMuA#L3R*uv5Fk=d?^20U=xydxANs zau@6KNJ2zpf!Sp9Cn7BlIJ+?S;-n$h-EWin4*l31E5$Ce4HNX2zs}C6uVRhiDV36t z7qOPgKyg4{=}sm0#*H4FL(o+ZyU-FJ1R*M3=&VfI%;_2s_X+fk)d7Aaby3g{3q?#m zW!bQ;;EjW1OCZQJ1m0u;d6x}adG2)?uqT7{PidcI<6o~F1EqL|Q9zd4`nO(?r1|xp zUt??7?@JY#tBY)60sa%0En*6cxeoYcWt;(^6ltf#GE1mfP75&Kn#qA6?lscP3E;mb z-U5_rMgEst)|J6k>rYHl*aUlgBrb6m9dbE6C}DFrtq$wuxqCfY*c$h5V3oh@ssr%u z*PbMdg;^=(7vh?!Tc>`ly3#D3@R38?;VrZCkyQ$AjY5b@TT3Vu8@3FM5*XM!LA>+0V9(1{wkMpO=yEBmR%RKD1SpmfznCCtAiFgtsy z=1iBba5?)7oQRUV5Yq}tmHb_(a(A%i1C#aLn)C}z8hX(f_W48`6b$vW( zP7EUe0Qyi1QEap{U3o6kqYUG@keg`s?MK+jOrsB@n6BzHchUFlS*!I~kIOQHneFvV zlFC6*!5lOfsjsSYuAnTarFtg7B0{nN=D$QW3*UnCC><7{#TxZiYeb>7oTW|+O6Sul z{33w{N4}ETcjRO?$9h2Fe|-0|JxDO1eC}0kd!nB!eDtM_RtE)^D^zYi`z!`YF|{2A z0W$9f*n3QI`aaWF_N(qAFAQZ1EPk1|`Is^C6Rm%OIKTv^%IS=)?#9Sv?yT$9%r>fj zB2!L!6MGnz$IMJ}A11-)n&cwOiV{L9*+1Q1CDw5x0LG{M&=q~ZRF&|79AV(m1ZruJSI@-~T-i;BD5MJ)_t&>l{3O0AXhY7OhG@{f zM(`MQ)R~$B1z7oT--Vu3Vpd7}>Jcxl;aBr&?p%%qXVh8zMf#1_$XRP%#65_aJr}V> zf+QKcS1CoAalL5z>{FP7HfO3cE-sO2C{*!S9lN-n2e}%nixOA*$GDvDH<-|~)Qk%? z^F90os3T``Ulz%ByoX^ts{r} z0gbViU7f$RyAX8X<#hHLMupKpRRKrzX%Q+n-4pVjVVmkJpTQk;B-Zv?i~%|4n>Q{} zq-v}$8T;oe*tS)&JH5FTn?`jZ1y6VbnDawa4v1-JrnK~DnC4|PqUimgPf&A$&+Hc_ zH7N%TP3W;fPZoIuW%PreZuh+5lD&{hALvbbcRjOp=QSET@?x|?OBn7QW@_k1o*9ij{e*6e+*XKIU-EJL(uOUryPIss zt4oPX3yvY@n^wpUPph==)6valprpxvoUXkSqNUj+%6wBCK@m_}UoxXtZ(93{&_|Hh zvLc~h|Ne*~VYUCJ3(ddVg^aIyv~oDJXf%$HksA!D+beuz67{H|pcfDh%31otX+WYz zr&Xd*1;(h%%Z(RmzEsUE!K2P?4JDkNr8y$CLX=h^PW)O(84q6cmol|(&Bzb3N-8cM zEER-SYgsIXA@Iy{*7!O2&w6ad0Sfe#Ki zf1F4ZS}-vaa-q0%qPje#%IgHZp9d3hs!!5_U)Ub3qru1gZkk$r(yg$hCa%pPxP(@^ z>*|fatz4JGK!gCI-2<`c5pYC>G~KDp;hZ*M73S?Y?)#_?2eK%41U_{tnkLtL(yI`C z*wkZ_XlC9FX3lnCks~N4Br6;D#;gCX`CMF;(mNiW;HDqaX1L+#JVt((#fp%#>k*me z;ZwPl>|}uWUOgz&ptBBsUovbPSDTtCgEdZ5r>42Uk;whLAv*5i6*m|6c0nWvzFA|u zPZNsNf8o0e98GA@Y_2_mo;Q0sXwDj4#`t3OGt4fQ?h5GlC#v;UO7lsqoMS*#k_g@k zBAd~7aF;svXQ;5q>PX?iQ=-iLov2oFhDtm0jdm@EcDF%SQ_?Cxyse0W{0qdg;7xH- zVQ&Rk)#DcEzQJP#%{|f$*C`n9(({>9LAHB$z+L>>iB*}sqiKAD0)U>4dfsE1W=a-StT^uzRY^B6T_G%}eUH%?L zuiX`Po}i(9_AQnWc9NU!<#=aj5WrOJsdmtnf$2FPs)1A2z-h+>4*aS zWoLHk&DuHb{m}8cPsYq9m$|C#e2W^h6(M-j&O6t&{6!>u(dHtS^df@~3={KY9KH$n zKadj;a!v>lXFN!v`;bzpW3j;X)xvC6kM)pNLl}C;o8z#KL@`-=UJGfAg`t+VK4wKP zYvhy*d%4O`M%QV6?tm}Yzw`%kZ)v<()1p=FcI>R#ZOsMkl}O)fmJVK+B1dZc>?9!w zvijmY1SM;Uqfv`!Y=Q1rGokC0PktRKM9)dX3i698E4XuouWpg__%{>hlQhDPkJ!}x zG0I9+vIoH2lkd4FE7h<+ycB<&aVrs%)J%GJTN4hKux3^Np-!?^=+7<#3J#F!XRorU zN*!;>k2>N0$v;yR^4Mc?_L(r@zPIMx$9hr8O(SVX^x=<56&aBze40~iV&^_}w+yW@ z(->im~b0Bi(UN>=XO z;p~Z*L7uXm4!P6=kE~_(7x4)Kw>X_`U&&jbe%Qx-&<3g^gpo7A@0YM$nx~w*H<{wjcjA70#+w<_sUc zw>m+|)*6-+6BmUAN`C8O9^T7Wjaw)vd_hNI?sVL#-Y?Xe2eHx{dW0Gsral1+KhllT zXrrVnA?^@I3hmOtx)YLbPI#aC1ca<79ZUym5FBU#rc6oUeLXJ2W87>?mJ3@qooeP#_}%NS8#hp#k%1`Ebz&TqeX1MVIS>Dg|E zAYXUma3pESgFS`cZEeYQxF4$@!xc1Fhbn`)2smX-XomMHyhD3Y?f4uPd#&W-Vx3GSw-b*c{qc$Jy>{;tuj`jl360;d6DK6n(a3bLedKZsV=m|m zJ-SADg@(*wl<$kvBWFr<5GsZ~H&qm|0FXsBtd?94;*R=%_ZJa!1MS=J^iutF!RoED zWvwMhg)Qu%qe0CzHw}H=)?x3nfG`(Z2YjWjd1#l;`9qx$m39E8D;&ss>hsO9an`3{ zxr?X~T@&GbyO2ji1Rn9y(I*P9w|vIs;^NjCoeFoG zK#e=cAcng$=I^H5i<5m|q>d7)CqM^sY4TyN5)D8B2DXEEsh#iZ056#fI?7@cvK2@f zgFn1aFLrrd+4{=(=kbkb?)5aS`f*b1pYir)qA+5-;Ga?Lxs9sI(e13@f2tz1ooxGe zO17<61pc4RT%VHLX%i1ugU?j$iJ=sYM4N=sa)a{o;{0=gM-`H=-=ArQflzpl>Wbfb zYB0ge9^|`xlCcZDcRip}pG6|Yu0rvF1fU*vl2#0?Y93xR%rMeXn5o~|O*$&F|Q@GLBk=V;Y+IM1N0HL4{oxkMWue53}whJ9pLKS1N-G~B$- z%94ZwvD?JM9BERCm+2225Dzdn1x2t3De2)bK-%UQA8Ou>WZ}|^`CVi3FFKHh%MQ8v z=@e`@LM~cvF?pxD;$L~pM})rzW?`RW1TWwEi&1!JriRsm?Gf5C$t%GV@ZGzU6&BO( z7?WD|Qx$!JUM9}SIJ~^kzC?#CD$PrscwQ;_Dp7m0nn}3+j;wWG=0PB8di+DOXuhmw zY@9W8JP{+v@$hQATRPRHe~o=baD^krq;o~i{-uE%*WsxFo&txv{hfdR>j_W2OT+cc zHTmi7k#x%SR46zOdklyj=Z{V?rXyqn13(4$OMvf@nuXVa1t_wdy;^E9;;q(`uwf49 z=xkd;rtZ!i2 zI$uo9OB)YWZ-V9Zh$(@CMvy)@C`Q8?s&aF$u&7eCTwt&nNSDuiPq#$XSn*kMkkgKO zFssVdNOq1u6NP}S%$4v0x zk!5*Qr6fY;WwAQOFzZBWgU=>zfZ;87Hz1>hgEr9R43J+dQyvwl@?9?9ZguN^aGNNz z@+QRs9j3Lx8dmPHNX52)03`qh;~J_QDh<~j! z9GgeciI@V!wpy127cXMjv~Si@DuP_!qMEqeI2&*4hS*2R}n$eHRBwhTuVSu zvYNTU$6tInR|;~ZVpC-vcZti*7HwXu4ZcHfeOZ)%-U|Xap+2`lG9#r}+yM*Se5U8x znvL?xSU4t&Y5=E@y13Q(;TPcZt=cCgN+uiRO(Ua>Wb$RcjHR9_m||;WQC=Mj(}a}e z@#`)vrYej)BAm2XzIqg?d8A*sJ=VQDxLQcn3bp-yGF(k4{5;ZzQ=$DW0C1YG1N z176f=>AyarC;+JwokXzHmPdOIOqd(`0MN(@RgFGAs%HYAxfTN9Wu~x_sov}S_rL3g zbC(Y7u1#E9PUHsXwhYq=_TDp~z7?kJJFZI;$dF^Widb8;uwNb1@kcv`qMUYOs{T$m zI$!qF`s}Jgf)!A}yOYK+tVHV24d-)S9h;?h>TbG;U1m;l>h7Xpx2DRyHFH2O;@u&E z(}vF1QDk}h)uhZ$zo`!m^#!IQa8MCz7jOz2js+=R3wH*C)ZC zEMaC^uIHh#zjxA)yvh#$WF<1&xvOVJo)bWJx0yw5mDnxyb!lXG(jlKwfD;#LbO$LQ zycDfe$1AP0($mab%&t-kbT9e|;ONKUZSb$V7wVK2atQq{AUX0Yzv}=Xe|FsblrmUo zhmoJknkH4K$mJWZO?WRga)A7Nl|vmCRn-z=v07^(CJWkU&=_vD%yRvw<{|xB2+phm z{feS2+|9@dO@52MVYHwYBFTBqaK&DzE+{+YFQdh*#WM0V2&uh()fB}!wT1LV#NoRU zYZNY1sVMU<$MH_l*E0Dg%-E=f2I7Y8TxGg)0II?U1x(aE$-U*iD=cy(5EJ_{>QPFy z96FEOa70Fqr9no*a6$!dPl%Duf>f~kkLomDl;s^3IXh4uh^vZ3QSaeEa6K281>JRB z*;#i5j03>sT0pHVUhV6z3~sI)fu1y&>=-Xh|Kgb=#h+6JYKikQelkH3a#0} zKz^W%mS=9@%{j#f04yca5=~5FXvnX-0fJfiI=+1F2{**=+-=vc+bGNcXtT}`gIUI4 zTHU)#ce|z(3l>pwxEo(@1|HFdc(sOy0hHf+(|euL$t?g>BFhtFH2|wop3WXiR&qHl zcIBgs89>z3(((sJy`1GjO1X=Jk%_j5&)KNTX`itYk(hivW$x(Dfs}(_t6CIMDKzdX zFEq}nC3v7TawXiQ{dA`6j$=Sa|E8^c@-+c(xBJc6d~GQU6LO_mRbt4ZCPAdEFRPo^ zOjSsj(Ap9rMzbvC75-6@B~UlA$j)%kvmop{Zz`*Aah)@|=~wAo{cN#0Kqtcc;dL+0 zW9_Vyl)Skn+P<5yLfzWQZ58$p9z zcIHAy@7Mbr^xG{f%1DP~of!KvV)SGN(pZ^JxA$k)^*kPTFw!03ac5>-@ta%=<2+g4 zl1IyM($0x+@2Mi2kb@mU$d=``HwQPYS9U<nh;MKP!EFKZ&Rml-L4Y z_C}cA+8aTeN8@}m6BG=tTTVb3Jsl4I${AQKv%mb-xs2e4r*;`2iVaXlJmCE#J}Tgp zsp8%jQejoW6tAI2Yvmv*!;(3+)WaqVcsUn)9DLf0759;+rG8uY7H$8~UFz|>v7nq* ze+}Mimm1?OSX}{RmV_i~)Rrn}=~kKo&gFb;*D!z_ih*vG^+2d7;q1MaZP-fofOAj} zpA09GhGCbfOVh(t^V&B3W)o%({E}fQ;RVpAT=FNRB_j_yc(Ka4(42EPK8Ra_;X;(@ zUik4VrJ;y=-2_wm$1~HGjD|ndmlns{-w>1nRax%e0*vX!Fw0!_9HHTzby{)*dQLo4 zAXa4lO_VO$^D7$^jjBe0#0j97o|SL0)@VD`098HhIK<$~aNZMa2EJJ3Vct3xUt`@L z+P?cpWd}6bp=g#)$&e9kJfl$*JrW+N;S_g~(NTIg(*8ku@8h^K3b?-X;J9b2^d$L6$JV?B}m)2qY#Dh}7xMIRGY|7x z{JM{RxHlp(@+`Fga>(I?1tqHzm>UINK0;_<-@h&5|nHs2^bmm!?uhO}Z4me~=(cXtyDP>O}nC5($1Djtv#Pe(7j zC(k?>=Xi&nz8C8IKDc4Vb7E#s@Ob!6OhZcbKC^unh`y&RrO2QuY8ViElbS6PPAWUq zuvodPuf8V*?(N5Q_a}`QN5e17GBqBCeXRQ&{7!crEpoodPD8(6S90o$Hc&9yUC>p& zAX9r(iTI_;BnbmKR0?W!VHGPS6?c7DFUjP6p0O+Y-`X z1?p7y)NDHpQHqC>koet^mb@nI^vf_R+zRE|?gbsoL*zT}z0rC1_1OhkZSiocecmSt z4Sxe#IjJW~l~pnCZ3Q?FLdqYXo)_*ApKN%fT^mNSpY!aulPxJ+E^`5-TiR2fQr;;A zycPPhQ}1GLYjlD-uUmor=d=orw?E+}ovF9=6R+t1LfBfR@2UfxCg}NWj^4N~)3i^$ z{Rp?UNbqhXxtwOs_1207dodNeZgsaMwBR&kmAmQ;aUtwG)w^Al#~u4RT^`4!hx(d~ z^CFiX__vt*-WUKg)N^WNu}o5`(P53odoite&~y;a583Wb#FGzlSE3X7NYBwT*$-1* z^C?4Mjm>Ke8+dRdd;hESNFM1pa|NS;4nf(RkfREc8rH%Tw zt1%lz1V>o)8P#io1qY7z)+HAD<~jBmhb)8y0nBxjLH}~;AU5XrY>h&C4_yG9D_T6X3of{H> zeKkrI5+wD_bJ{?wmHd~C2D@=9(`y=liV!KVES;)D-}z3Lh=ob<#Y_Z_D0Y_Zz{eKw zA!~A?`e)>pJ9k}mb8$7Tm&Nc#7j#|jOgD~#4${)`rY8qyLVVdQITqn{ipl$g@ff=s zUD>I@`gdg{U>z~BGM)GPnT`%a`xN}{Uze}jNH5GC1)h^_9A}#I!7NsIzqcfp>iz}O zk4-qOT>hG`yvl|Hw*@03rpIW0zq==$Q~Qci?|cdMQh&B^8KBYmCCDNKoZ8)?)*VFz zEzkDT$?uBU<6XI|I-uONvca-_v2fzynY{N^hwJoroi}acbe!su`L|DKDmxn^|4%1nyN`e3+pqTSF2oXG$O_gy$|V%nb0_S@NBJKH;J{q)*CcWA7`?NfQ%NNlZwZ4UwPYC-u9LMyVN9@PYkR5 z^%uL3#)b2G|HajtHH7yf_pQ1cpLQ(uiS=CY5OLGcO48DezTJLJ^+;aR)WvZ6T(G#Ee^`I2NDZt9r=G0mZ+fkM9vyJ zv8i71Z}}rEqrdOULXfygL5CsMXZapzJPhmWlyx5DUzqISKnf`fUQJLax`lfs?-3jt z8VVclNQX^!=X_e2Tnq>Zu!O@U`4zpS(D8P~stHUoSM&U*tmiMLb&JgqgFW2VLAg){Z7`MU#{xY!$B4-8sqB z5rm(g(nrXQVWz2_&vEAz_C;PnL38#ix7d10Je(B|d`tv101P|ygQIgPQH|mOk7#Xe zCBq5C4~dkO#Snm!4dys{wPP`S$9Di5WTy2LRJ?sanR_vE>{ZYsgMsjg$=>{vSG2Xe zRIg@uJ2*Jh5=(xTSGGnx^WDmSG6b@PS#-<$vPTLF`~6IO^~y}P?6Z|@UnQ^g$tlUdI5L<0R?k^?fYFRfu_M_pIscdC@*d0mu_+V49mA&)h0JOL$DE-FJF+Yil z=9f}72X&)X5zPr}pPh2+uR2h9qn0Kw5?>;HL`s;iH97H3h+eu=w;#INOcO!;{T;D$;NW0`c({+1!Ri;~1A|k%&#e8EZ#=PeH;Jum zt=(Sh2v9i72*KpLO9s|}ukGX8m5=M2&eR+E!WmljC$Lo?GZ)bgrNU|I#c8ieH z&i8^U$g3^LX1eP}Stp3{mzm#L*m@m5?)tAv?SC(rFg5R>E|{$k{jxR?J~@5oyG1Bp zm#vJz7wXkZ)M?lOp@Wdjo~iiUu6gUI7Y5Bi{n3^1=5BRWM{1&_lT&6EJ6!{0Cm~T6%|nva~VN*4^1?-2vz~ z?*ndlOzYgxv50TgTlb~|n2F5I??L-8m%)K_IXR!!C2MmWklWwNYl6_N4V32FY{ma1 zGai6x9Nee}tZcnwGS4LH9eLpKbn@6UauM=!Jsb zE1!;UiMhQ7=z*KMTL0>Y97sC8)Gc|+hX9K3P)i1XDLei0CPG3Fh_5sN}Gm3U0E)YR07vo1|o2(j#8;kPX|8~RbMy>NJQVIDIC6RRqO zK7F*75Ffv>fSpBWO#;$HJbsC}?gF8|WDN zL4U8|=zE!_4!3UoO;d!}i;{J;cPMrJ*%sE9Ov9xFrl+Tqf9cnL398h&7bUgpx#SD}<-wP=+9nw}>z73>4>rhHHmeo2c$zoeF zM%RkL;QjE0c(szTQ(>$THmPk6C!Q%c86-9=5cjETXyuD-?vZoN;A1!69`HRxj|60q zvkGggbELkvVQa`F0?=x3g1Y{=HY~1Bd~YDiKd{^zzIgz?J_yEX_!d89RL9uJDAed& zj}p_|+-e*5&*DHriBQj(J@}CrM9JhYed0VF@>$&N8(XWs4PdICJ@S49%Oh(JgX=MW z*qT@+8f@<)lH5o6YikZ9;yR)Ny6KFf71wvcVum05@!Mdl4!wz@r9oYoloB;BMdUDZ)BiLyAo40xW22ArJ zpA8s2{CsotB|y9a8rlY@i0^MTvn}u!OJ* zP1)uk)~KhHm4%S}XWCr1O*5^T|2wJ9;%fZ4VN7=6CKE$~zVI84JiGRKWQWQ$Vw~o5#T6lh@+)K0;QktgL_r ze1LjxBG2XEkPwrrDujdZTc?2wVQpgr8uRd6|M1uT!U~|s*s$|TVc&-@8YQE^=9?GO zZ1Uz&@#O8f)mzFkGMrZvl?Jf+>Fx7xdTeH)#Da81?}d)8ejrXR0{h5zkEW~0bo@p) z5Tx>OvNgf<6YrScwYI`GvI~#?*sd=$djOe;krl<0cfw*x!I^tDVwhy&Pny6 z{7or;-xzxIx;9ip4s?vWEm1qTmmTUg_d#yMdu6H_wLJHOoJ0h| z$i9k!{@l~gKS3kEfv$&`^)5@`?7t@NKgn4@%xHck-!=aN+ms^w3++&VSSUP0=)-Vv zb5CRun#>)&ll#tUfaeDtk*G!f{=J&7xbi3qdw~wI>|>-Kw6UpaV2}e&Yc93!#rm6^ zXqmW;j}}}N<(d$NIZ#?EE8`GBY{5*FC7kQG>MJ1Pg4vYX?VS7mL76?&5>Pok?hlxQ zdz6(7JVHV^LrjnmnDsY=-aqmQ=U#jJ_u}mHtDLEnX=iHD d(#y3Sq{?8biO`PWzrcSQ7q4E(RJr-^e*nmzN>~5@ diff --git a/packages/core/src/create-plugin/template/global/public/docs/image2.png b/packages/core/src/create-plugin/template/global/public/docs/image2.png deleted file mode 100644 index 7b8b15983914faf0c4a046692bebb15241714b9a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 105842 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 CytZio diff --git a/packages/core/src/create-plugin/template/global/src/control/index.ts b/packages/core/src/create-plugin/template/global/src/control/index.ts new file mode 100644 index 0000000..685ad49 --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/control/index.ts @@ -0,0 +1,12 @@ +import { App } from 'vue'; +import { ControlType, registerControlProvider } from '@ibiz-template/runtime'; +import { {{ pascalCasePluginName }}Control } from './{{pluginName}}-control'; +import { {{ pascalCasePluginName }}ControlProvider } from './{{pluginName}}-control.provider'; + +export default { + install(app: App) { + // 替换标准逻辑 + app.component({{ pascalCasePluginName }}Control.name!, {{ pascalCasePluginName }}Control); + registerControlProvider(ControlType.FORM, () => new {{ pascalCasePluginName }}ControlProvider()); + }, +} \ No newline at end of file diff --git a/packages/core/src/create-plugin/template/global/src/control/{{pluginName}}-control.provider.ts b/packages/core/src/create-plugin/template/global/src/control/{{pluginName}}-control.provider.ts new file mode 100644 index 0000000..8d99552 --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/control/{{pluginName}}-control.provider.ts @@ -0,0 +1,5 @@ +import { IControlProvider } from '@ibiz-template/runtime'; + +export class {{ pascalCasePluginName }}ControlProvider implements IControlProvider { + component: string = 'IBiz{{ pascalCasePluginName }}Control'; +} diff --git a/packages/core/src/create-plugin/template/global/src/control/{{pluginName}}-control.scss b/packages/core/src/create-plugin/template/global/src/control/{{pluginName}}-control.scss new file mode 100644 index 0000000..fb057c9 --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/control/{{pluginName}}-control.scss @@ -0,0 +1,3 @@ +@include b({{pluginName}}-control) { + // 样式 +} diff --git a/packages/core/src/create-plugin/template/global/src/control/{{pluginName}}-control.tsx b/packages/core/src/create-plugin/template/global/src/control/{{pluginName}}-control.tsx new file mode 100644 index 0000000..b874b78 --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/control/{{pluginName}}-control.tsx @@ -0,0 +1,40 @@ +import { defineComponent, PropType } from 'vue'; +import { ControlController, IControlProvider } from '@ibiz-template/runtime'; +import { useControlController, useNamespace } from '@ibiz-template/vue3-util'; +import { IControl } from '@ibiz/model-core'; +import './{{pluginName}}-control.scss'; + +export const {{ pascalCasePluginName }}Control = defineComponent({ + name: 'IBiz{{ pascalCasePluginName }}Control', + props: { + /** + * @description 模型数据 + */ + modelData: { type: Object as PropType, required: true }, + /** + * @description 应用上下文对象 + */ + context: { type: Object as PropType, required: true }, + /** + * @description 视图参数对象 + * @default {} + */ + params: { type: Object as PropType, default: () => ({}) }, + /** + * @description 部件适配器 + */ + provider: { type: Object as PropType }, + }, + setup() { + const c = useControlController((...args) => new ControlController(...args)); + const ns = useNamespace('{{pluginName}}-control'); + + return { + c, + ns, + }; + }, + render() { + return
插件示例
; + }, +}); diff --git a/packages/core/src/create-plugin/template/global/src/editor/index.ts b/packages/core/src/create-plugin/template/global/src/editor/index.ts new file mode 100644 index 0000000..2a7f883 --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/editor/index.ts @@ -0,0 +1,12 @@ +import { App } from 'vue'; +import { registerEditorProvider } from '@ibiz-template/runtime'; +import { {{ pascalCasePluginName }}Editor } from './{{pluginName}}-editor'; +import { {{ pascalCasePluginName }}EditorProvider } from './{{pluginName}}-editor.provider'; + +export default { + install(app: App) { + // 替换标准逻辑 + app.component({{ pascalCasePluginName }}Editor.name!, {{ pascalCasePluginName }}Editor); + registerEditorProvider('SPAN', () => new {{ pascalCasePluginName }}EditorProvider()); + }, +} \ No newline at end of file diff --git a/packages/core/src/create-plugin/template/global/src/editor/{{pluginName}}-editor.provider.ts b/packages/core/src/create-plugin/template/global/src/editor/{{pluginName}}-editor.provider.ts new file mode 100644 index 0000000..b0f211d --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/editor/{{pluginName}}-editor.provider.ts @@ -0,0 +1,21 @@ +import { IEditor } from '@ibiz/model-core'; +import { + IEditorContainerController, + IEditorProvider, + EditorController, +} from '@ibiz-template/runtime'; + +export class {{ pascalCasePluginName }}EditorProvider implements IEditorProvider { + formEditor: string = 'IBiz{{ pascalCasePluginName }}Editor'; + + gridEditor: string = 'IBiz{{ pascalCasePluginName }}Editor'; + + async createController( + editorModel: IEditor, + parentController: IEditorContainerController, + ): Promise { + const c = new EditorController(editorModel, parentController); + await c.init(); + return c; + } +} diff --git a/packages/core/src/create-plugin/template/global/src/editor/{{pluginName}}-editor.scss b/packages/core/src/create-plugin/template/global/src/editor/{{pluginName}}-editor.scss new file mode 100644 index 0000000..d4b85aa --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/editor/{{pluginName}}-editor.scss @@ -0,0 +1,3 @@ +@include b({{pluginName}}-editor) { + // 样式 +} diff --git a/packages/core/src/create-plugin/template/global/src/editor/{{pluginName}}-editor.tsx b/packages/core/src/create-plugin/template/global/src/editor/{{pluginName}}-editor.tsx new file mode 100644 index 0000000..802f1b7 --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/editor/{{pluginName}}-editor.tsx @@ -0,0 +1,21 @@ +import { defineComponent } from 'vue'; +import { getEditorProps, useNamespace } from '@ibiz-template/vue3-util'; +import { EditorController } from '@ibiz-template/runtime'; +import './{{pluginName}}-editor.scss'; + +export const {{ pascalCasePluginName }}Editor = defineComponent({ + name: 'IBiz{{ pascalCasePluginName }}Editor', + props: getEditorProps(), + setup(props) { + const c = props.controller; + const ns = useNamespace('{{pluginName}}-editor'); + + return { + c, + ns, + }; + }, + render() { + return
插件示例
; + }, +}); diff --git a/packages/core/src/create-plugin/template/global/src/form-detail/index.ts b/packages/core/src/create-plugin/template/global/src/form-detail/index.ts new file mode 100644 index 0000000..dbeb121 --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/form-detail/index.ts @@ -0,0 +1,12 @@ +import { App } from 'vue'; +import { registerFormDetailProvider } from '@ibiz-template/runtime'; +import { {{ pascalCasePluginName }}FormDetail } from './{{pluginName}}-form-detail'; +import { {{ pascalCasePluginName }}FormDetailProvider } from './{{pluginName}}-form-detail.provider'; + +export default { + install(app: App) { + // 替换标准逻辑 + app.component({{ pascalCasePluginName }}FormDetail.name!, {{ pascalCasePluginName }}FormDetail); + registerFormDetailProvider('FORMITEM', () => new {{ pascalCasePluginName }}FormDetailProvider()); + }, +} \ No newline at end of file diff --git a/packages/core/src/create-plugin/template/global/src/form-detail/{{pluginName}}-form-detail.provider.ts b/packages/core/src/create-plugin/template/global/src/form-detail/{{pluginName}}-form-detail.provider.ts new file mode 100644 index 0000000..0351332 --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/form-detail/{{pluginName}}-form-detail.provider.ts @@ -0,0 +1,21 @@ +import { + FormController, + FormDetailController, + IFormDetailContainerController, + IFormDetailProvider, +} from '@ibiz-template/runtime'; +import { IDEFormDetail } from '@ibiz/model-core'; + +export class {{ pascalCasePluginName }}FormDetailProvider implements IFormDetailProvider { + component: string = 'IBiz{{ pascalCasePluginName }}FormDetail'; + + async createController( + detailModel: IDEFormDetail, + form: FormController, + parent: IFormDetailContainerController | undefined, + ): Promise { + const c = new FormDetailController(detailModel, form, parent); + await c.init(); + return c; + } +} diff --git a/packages/core/src/create-plugin/template/global/src/form-detail/{{pluginName}}-form-detail.scss b/packages/core/src/create-plugin/template/global/src/form-detail/{{pluginName}}-form-detail.scss new file mode 100644 index 0000000..fe0405b --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/form-detail/{{pluginName}}-form-detail.scss @@ -0,0 +1,3 @@ +@include b({{pluginName}}-form-detail) { + // 样式 +} diff --git a/packages/core/src/create-plugin/template/global/src/form-detail/{{pluginName}}-form-detail.tsx b/packages/core/src/create-plugin/template/global/src/form-detail/{{pluginName}}-form-detail.tsx new file mode 100644 index 0000000..d95d8fa --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/form-detail/{{pluginName}}-form-detail.tsx @@ -0,0 +1,28 @@ +import { defineComponent, PropType } from 'vue'; +import { useNamespace } from '@ibiz-template/vue3-util'; +import { IDEFormDetail } from '@ibiz/model-core'; +import { FormDetailController } from '@ibiz-template/runtime'; +import './{{pluginName}}-form-detail.scss'; + +export const {{ pascalCasePluginName }}FormDetail = defineComponent({ + name: 'IBiz{{ pascalCasePluginName }}FormDetail', + props: { + modelData: { + type: Object as PropType, + required: true, + }, + controller: { + type: Object as PropType, + required: true, + }, + }, + setup(props) { + const c = props.controller; + const ns = useNamespace('{{pluginName}}-form-detail'); + + return { c, ns }; + }, + render() { + return
插件示例
; + }, +}); diff --git a/packages/core/src/create-plugin/template/global/src/grid-column/index.ts b/packages/core/src/create-plugin/template/global/src/grid-column/index.ts new file mode 100644 index 0000000..34fb796 --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/grid-column/index.ts @@ -0,0 +1,12 @@ +import { App } from 'vue'; +import { registerGridColumnProvider } from '@ibiz-template/runtime'; +import { {{ pascalCasePluginName }}GridColumn } from './{{pluginName}}-grid-column'; +import { {{ pascalCasePluginName }}GridColumnProvider } from './{{pluginName}}-grid-column.provider'; + +export default { + install(app: App) { + // 替换标准逻辑 + app.component({{ pascalCasePluginName }}GridColumn.name!, {{ pascalCasePluginName }}GridColumn); + registerGridColumnProvider('DEFGRIDCOLUMN', () => new {{ pascalCasePluginName }}GridColumnProvider()); + }, +} \ No newline at end of file diff --git a/packages/core/src/create-plugin/template/global/src/grid-column/{{pluginName}}-grid-column.provider.ts b/packages/core/src/create-plugin/template/global/src/grid-column/{{pluginName}}-grid-column.provider.ts new file mode 100644 index 0000000..9714adc --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/grid-column/{{pluginName}}-grid-column.provider.ts @@ -0,0 +1,19 @@ +import { + GridController, + GridFieldColumnController, + IGridColumnProvider, +} from '@ibiz-template/runtime'; +import { IDEGridColumn } from '@ibiz/model-core'; + +export class {{ pascalCasePluginName }}GridColumnProvider implements IGridColumnProvider { + component: string = 'IBiz{{ pascalCasePluginName }}GridColumn'; + + async createController( + columnModel: IDEGridColumn, + grid: GridController, + ): Promise { + const c = new GridFieldColumnController(columnModel, grid); + await c.init(); + return c; + } +} diff --git a/packages/core/src/create-plugin/template/global/src/grid-column/{{pluginName}}-grid-column.scss b/packages/core/src/create-plugin/template/global/src/grid-column/{{pluginName}}-grid-column.scss new file mode 100644 index 0000000..f8230ef --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/grid-column/{{pluginName}}-grid-column.scss @@ -0,0 +1,3 @@ +@include b({{pluginName}}-grid-column) { + // 样式 +} diff --git a/packages/core/src/create-plugin/template/global/src/grid-column/{{pluginName}}-grid-column.tsx b/packages/core/src/create-plugin/template/global/src/grid-column/{{pluginName}}-grid-column.tsx new file mode 100644 index 0000000..7c4ef5f --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/grid-column/{{pluginName}}-grid-column.tsx @@ -0,0 +1,31 @@ +import { defineComponent } from 'vue'; +import { useNamespace } from '@ibiz-template/vue3-util'; +import { + GridFieldColumnController, + GridRowState, +} from '@ibiz-template/runtime'; +import './{{pluginName}}-grid-column.scss'; + +export const {{ pascalCasePluginName }}GridColumn = defineComponent({ + name: 'IBiz{{ pascalCasePluginName }}GridColumn', + props: { + controller: { + type: GridFieldColumnController, + required: true, + }, + row: { + type: GridRowState, + required: true, + }, + }, + setup() { + const ns = useNamespace('{{pluginName}}-grid-column'); + + return { + ns, + }; + }, + render() { + return
插件示例
; + }, +}); diff --git a/packages/core/src/create-plugin/template/global/src/index.ts b/packages/core/src/create-plugin/template/global/src/index.ts index 4cf22d2..6b9562c 100644 --- a/packages/core/src/create-plugin/template/global/src/index.ts +++ b/packages/core/src/create-plugin/template/global/src/index.ts @@ -1,7 +1,30 @@ import { App } from 'vue'; +import view from './view'; +import control from './control'; +import formDetail from './form-detail'; +import gridColumn from './grid-column'; +import panelItem from './panel-item'; +import editor from './editor'; +import method from './method'; +import uiAction from './ui-action'; export default { - install(_app: App) { - // todo 替换标准逻辑 + install(app: App) { + // 替换标准视图逻辑 + app.use(view); + // 替换标准部件逻辑 + app.use(control); + // 替换标准表单成员逻辑 + app.use(formDetail); + // 替换标准表格列逻辑 + app.use(gridColumn); + // 替换标准面板成员逻辑 + app.use(panelItem); + // 替换标准编辑器逻辑 + app.use(editor); + // 替换标准实体行为逻辑 + app.use(method); + // 替换标准界面行为逻辑 + app.use(uiAction); }, }; diff --git a/packages/core/src/create-plugin/template/global/src/method/index.ts b/packages/core/src/create-plugin/template/global/src/method/index.ts new file mode 100644 index 0000000..2ef1c3e --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/method/index.ts @@ -0,0 +1,10 @@ +import { App } from 'vue'; +import { registerDEMethodProvider } from '@ibiz-template/runtime'; +import { {{ pascalCasePluginName }}MethodProvider } from './{{pluginName}}-method.provider'; + +export default { + install(_app: App) { + // 替换标准逻辑 + registerDEMethodProvider('DEACTION', () => new {{ pascalCasePluginName }}MethodProvider()); + }, +} \ No newline at end of file diff --git a/packages/core/src/create-plugin/template/global/src/method/{{pluginName}}-method.provider.ts b/packages/core/src/create-plugin/template/global/src/method/{{pluginName}}-method.provider.ts new file mode 100644 index 0000000..cbaf643 --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/method/{{pluginName}}-method.provider.ts @@ -0,0 +1,19 @@ +import { IAppDataEntity, IAppDEMethod } from '@ibiz/model-core'; +import { + IAppDEService, + IDEMethodCreateOptions, + IDEMethodProvider, +} from '@ibiz-template/runtime'; +import { Method } from '@ibiz-template/runtime'; +import { {{ pascalCasePluginName }}Method } from './{{pluginName}}-method'; + +export class {{ pascalCasePluginName }}MethodProvider implements IDEMethodProvider { + create( + service: IAppDEService, + entity: IAppDataEntity, + method: IAppDEMethod, + opts: IDEMethodCreateOptions, + ): Method { + return new {{ pascalCasePluginName }}Method(service, entity, method, opts.localMode); + } +} diff --git a/packages/core/src/create-plugin/template/global/src/method/{{pluginName}}-method.ts b/packages/core/src/create-plugin/template/global/src/method/{{pluginName}}-method.ts new file mode 100644 index 0000000..137ff28 --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/method/{{pluginName}}-method.ts @@ -0,0 +1,14 @@ +import { HttpResponse } from '@ibiz-template/core'; +import { Method } from '@ibiz-template/runtime'; + +export class {{ pascalCasePluginName }}Method extends Method { + async exec( + context: IContext, + data?: IData | IData[], + params?: IParams, + header?: IData, + ): Promise> { + // 处理逻辑 + return new HttpResponse({}); + } +} diff --git a/packages/core/src/create-plugin/template/global/src/panel-item/index.ts b/packages/core/src/create-plugin/template/global/src/panel-item/index.ts new file mode 100644 index 0000000..c3bfdef --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/panel-item/index.ts @@ -0,0 +1,12 @@ +import { App } from 'vue'; +import { registerPanelItemProvider } from '@ibiz-template/runtime'; +import { {{ pascalCasePluginName }}PanelItem } from './{{pluginName}}-panel-item'; +import { {{ pascalCasePluginName }}PanelItemProvider } from './{{pluginName}}-panel-item.provider'; + +export default { + install(app: App) { + // 替换标准逻辑 + app.component({{ pascalCasePluginName }}PanelItem.name!, {{ pascalCasePluginName }}PanelItem); + registerPanelItemProvider('CONTAINER_ViewHeader', () => new {{ pascalCasePluginName }}PanelItemProvider()); + }, +} \ No newline at end of file diff --git a/packages/core/src/create-plugin/template/global/src/panel-item/{{pluginName}}-panel-item.provider.ts b/packages/core/src/create-plugin/template/global/src/panel-item/{{pluginName}}-panel-item.provider.ts new file mode 100644 index 0000000..338f1c0 --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/panel-item/{{pluginName}}-panel-item.provider.ts @@ -0,0 +1,20 @@ +import { + IPanelItemProvider, + PanelController, + PanelItemController, +} from '@ibiz-template/runtime'; +import { IPanelContainer } from '@ibiz/model-core'; + +export class {{ pascalCasePluginName }}PanelItemProvider implements IPanelItemProvider { + component: string = 'IBiz{{ pascalCasePluginName }}PanelItem'; + + async createController( + panelItem: IPanelContainer, + panel: PanelController, + parent: PanelItemController | undefined, + ): Promise { + const c = new PanelItemController(panelItem, panel, parent); + await c.init(); + return c; + } +} diff --git a/packages/core/src/create-plugin/template/global/src/panel-item/{{pluginName}}-panel-item.scss b/packages/core/src/create-plugin/template/global/src/panel-item/{{pluginName}}-panel-item.scss new file mode 100644 index 0000000..da472b6 --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/panel-item/{{pluginName}}-panel-item.scss @@ -0,0 +1,3 @@ +@include b({{pluginName}}-panel-item) { + // 样式 +} diff --git a/packages/core/src/create-plugin/template/global/src/panel-item/{{pluginName}}-panel-item.tsx b/packages/core/src/create-plugin/template/global/src/panel-item/{{pluginName}}-panel-item.tsx new file mode 100644 index 0000000..8b9f9e5 --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/panel-item/{{pluginName}}-panel-item.tsx @@ -0,0 +1,33 @@ +import { defineComponent, PropType } from 'vue'; +import { useNamespace } from '@ibiz-template/vue3-util'; +import { IPanelItem } from '@ibiz/model-core'; +import { PanelItemController } from '@ibiz-template/runtime'; +import './{{pluginName}}-panel-item.scss'; + +export const {{ pascalCasePluginName }}PanelItem = defineComponent({ + name: 'IBiz{{ pascalCasePluginName }}PanelItem', + props: { + /** + * @description 模型数据 + */ + modelData: { + type: Object as PropType, + required: true, + }, + /** + * @description 控制器 + */ + controller: { + type: PanelItemController, + required: true, + }, + }, + setup() { + const ns = useNamespace('{{pluginName}}-panel-item'); + + return { ns }; + }, + render() { + return
插件示例
; + }, +}); diff --git a/packages/core/src/create-plugin/template/global/src/ui-action/index.ts b/packages/core/src/create-plugin/template/global/src/ui-action/index.ts new file mode 100644 index 0000000..12f940d --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/ui-action/index.ts @@ -0,0 +1,10 @@ +import { App } from 'vue'; +import { registerUIActionProvider } from '@ibiz-template/runtime'; +import { {{ pascalCasePluginName }}UIActionProvider } from './{{pluginName}}-ui-action.provider'; + +export default { + install(_app: App) { + // 替换标准逻辑 + registerUIActionProvider('FRONT', () => new {{ pascalCasePluginName }}UIActionProvider()); + }, +} \ No newline at end of file diff --git a/packages/core/src/create-plugin/template/global/src/ui-action/{{pluginName}}-ui-action.provider.ts b/packages/core/src/create-plugin/template/global/src/ui-action/{{pluginName}}-ui-action.provider.ts new file mode 100644 index 0000000..5f159c7 --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/ui-action/{{pluginName}}-ui-action.provider.ts @@ -0,0 +1,17 @@ +import { IAppDEUIAction } from '@ibiz/model-core'; +import { + UIActionProviderBase, + IUILogicParams, + IUIActionResult, +} from '@ibiz-template/runtime'; + +export class {{ pascalCasePluginName }}UIActionProvider extends UIActionProviderBase { + async execAction( + action: IAppDEUIAction, + args: IUILogicParams, + ): Promise { + const actionResult: IUIActionResult = {}; + // 处理逻辑 + return actionResult; + } +} diff --git a/packages/core/src/create-plugin/template/global/src/view/index.ts b/packages/core/src/create-plugin/template/global/src/view/index.ts new file mode 100644 index 0000000..7108671 --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/view/index.ts @@ -0,0 +1,12 @@ +import { App } from 'vue'; +import { registerViewProvider } from '@ibiz-template/runtime'; +import { {{ pascalCasePluginName }}View } from './{{pluginName}}-view'; +import { {{ pascalCasePluginName }}ViewProvider } from './{{pluginName}}-view.provider'; + +export default { + install(app: App) { + // 替换标准逻辑 + app.component({{ pascalCasePluginName }}View.name!, {{ pascalCasePluginName }}View); + registerViewProvider('DEFAULT', () => new {{ pascalCasePluginName }}ViewProvider()); + }, +} \ No newline at end of file diff --git a/packages/core/src/create-plugin/template/global/src/view/{{pluginName}}-view.provider.ts b/packages/core/src/create-plugin/template/global/src/view/{{pluginName}}-view.provider.ts new file mode 100644 index 0000000..93720fc --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/view/{{pluginName}}-view.provider.ts @@ -0,0 +1,5 @@ +import { IViewProvider } from '@ibiz-template/runtime'; + +export class {{ pascalCasePluginName }}ViewProvider implements IViewProvider { + component: string = 'IBiz{{ pascalCasePluginName }}View'; +} diff --git a/packages/core/src/create-plugin/template/global/src/view/{{pluginName}}-view.scss b/packages/core/src/create-plugin/template/global/src/view/{{pluginName}}-view.scss new file mode 100644 index 0000000..44ac0a7 --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/view/{{pluginName}}-view.scss @@ -0,0 +1,3 @@ +@include b({{pluginName}}-view) { + // 样式 +} \ No newline at end of file diff --git a/packages/core/src/create-plugin/template/global/src/view/{{pluginName}}-view.tsx b/packages/core/src/create-plugin/template/global/src/view/{{pluginName}}-view.tsx new file mode 100644 index 0000000..833aa77 --- /dev/null +++ b/packages/core/src/create-plugin/template/global/src/view/{{pluginName}}-view.tsx @@ -0,0 +1,48 @@ +import { defineComponent, PropType } from 'vue'; +import { IModal, IViewProvider, ViewController } from '@ibiz-template/runtime'; +import { useNamespace, useViewController } from '@ibiz-template/vue3-util'; +import { IAppView } from '@ibiz/model-core'; +import './{{pluginName}}-view.scss'; + +export const {{ pascalCasePluginName }}View = defineComponent({ + name: 'IBiz{{ pascalCasePluginName }}View', + props: { + /** + * @description 应用上下文 + */ + context: { type: Object as PropType }, + /** + * @description 视图参数 + * @default {} + */ + params: { type: Object as PropType, default: () => ({}) }, + /** + * @description 视图模型 + */ + modelData: { type: Object as PropType, required: true }, + /** + * @description 视图模态操作对象,在模态等形式打开视图时,需给视图注入此对象 + */ + modal: { type: Object as PropType }, + /** + * @description 视图状态 + */ + state: { type: Object as PropType }, + /** + * @description 视图适配器 + */ + provider: { type: Object as PropType }, + }, + setup() { + const ns = useNamespace('{{pluginName}}-view'); + const c = useViewController((...args) => new ViewController(...args)); + + return { + c, + ns, + }; + }, + render() { + return
插件示例
; + }, +}); diff --git a/packages/core/src/create-plugin/template/platform/appcounter/.eslintrc.cjs b/packages/core/src/create-plugin/template/platform/appcounter/.eslintrc.cjs new file mode 100644 index 0000000..c6e5a1d --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/appcounter/.eslintrc.cjs @@ -0,0 +1,52 @@ +module.exports = { + root: true, + env: { + browser: true, + es2021: true, + }, + extends: ['airbnb-base', 'prettier', 'plugin:@typescript-eslint/recommended'], + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + }, + plugins: ['prettier', '@typescript-eslint', 'unused-imports'], + rules: { + 'prettier/prettier': 'error', + 'arrow-body-style': 'off', + 'prefer-arrow-callback': 'off', + 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', + 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', + 'no-new': [0], + 'no-continue': [0], + '@typescript-eslint/no-empty-interface': 'off', + 'no-use-before-define': [0], + 'no-restricted-syntax': [0], + 'no-empty-function': [0], + 'no-useless-constructor': [0], // 禁止空的构造函数 + 'no-param-reassign': [0], // 禁止修改传入函数的参数 + 'no-underscore-dangle': [0], // 禁止使用下划线开头的变量名 + 'no-plusplus': ['error', { allowForLoopAfterthoughts: true }], // 禁止使用 ++,-- + 'consistent-return': [0], // 函数可以有不同类型返回值 + 'class-methods-use-this': [0], // 方法内未使用此方法时,强制定义为静态方法 + 'import/prefer-default-export': [0], // 一个模块只能有默认导出,不可以有多个导出 + 'import/no-unresolved': [0], // 不允许未解决的模块 + 'import/extensions': [0], // 不允许导入文件时不带后缀 + 'unused-imports/no-unused-imports': 'error', + '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }], + '@typescript-eslint/no-inferrable-types': [0], + '@typescript-eslint/no-non-null-assertion': [0], + '@typescript-eslint/no-explicit-any': ['error'], + '@typescript-eslint/explicit-function-return-type': 'error', // 要求函数和类方法的显式返回类型 + '@typescript-eslint/explicit-module-boundary-types': 'error', // 要求导出函数和类的公共类方法的显式返回和参数类型 + 'import/no-extraneous-dependencies': [ + 0, + { + devDependencies: true, + peerDependencies: true, + // optionalDependencies: true, + // bundledDependencies: true + }, + ], + }, +}; diff --git a/packages/core/src/create-plugin/template/platform/appcounter/CHANGELOG.md b/packages/core/src/create-plugin/template/platform/appcounter/CHANGELOG.md new file mode 100644 index 0000000..8ac8e7f --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/appcounter/CHANGELOG.md @@ -0,0 +1,3 @@ +# 版本变更日志 + +添加变更日志 \ No newline at end of file diff --git a/packages/core/src/create-plugin/template/platform/appcounter/README.md b/packages/core/src/create-plugin/template/platform/appcounter/README.md new file mode 100644 index 0000000..b953295 --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/appcounter/README.md @@ -0,0 +1,65 @@ +# 计数器插件 + +计数器插件可自定义计数器数据加载逻辑,当标准逻辑无法满足要求时,可以通过计数器插件来实现。modeling建模平台创建计数器插件可参见 [插件开发](https://open.ibizlab.cn/apphub/zh/guide/plugin-dev.html) + +## 插件结构 + +``` +|─ ─ {{pluginName}} 计数器插件顶层目录 + |─ ─ src 计数器插件源代码目录 +​ |─ ─ {{pluginName}}.provider.ts 计数器插件适配器 +​ |─ ─ {{pluginName}}.ts 计数器插件实现类 +​ |─ ─ index.ts 计数器插件入口文件 +``` + +- 计数器插件入口文件 + +计数器插件入口文件会全局注册计数器插件适配器,供外部使用。 + +- 计数器插件实现类 + +计数器插件实现类可继承基础应用计数器AppCounter,重写对应的处理逻辑。 + +- 计数器插件适配器 + +计数器插件适配器的createCounter方法返回对应计数器插件实现类的实例。 + +## 本地开发 + +1. 安装依赖并link至全局 + +```sh +// 安装依赖 +pnpm i + +// link底包 +./scripts/link.sh + +// 启动 +pnpm dev + +// link到全局 +pnpm link --global +``` + +2. 主项目包中引用插件 + +```sh +// link插件 +pnpm link --global '{{pluginGroup}}/{{pluginName}}' +``` + +3. 主项目包中注册插件 + +```ts +import { App } from 'vue'; +import {{ pascalCasePluginName }} from '{{pluginGroup}}/{{pluginName}}' + +export default { + install(app: App) { + app.use({{ pascalCasePluginName }}); + // 设置本地开发需要忽略加载的插件,可填写正则或全匹配字符串。匹配插件在modeling建模平台配置的[运行时插件仓库配置]内容 + ibiz.plugin.setDevIgnore(/^{{pluginGroup}}\/{{pluginName}}/); + }, +}; +``` diff --git a/packages/core/src/create-plugin/template/platform/appcounter/package.json b/packages/core/src/create-plugin/template/platform/appcounter/package.json new file mode 100644 index 0000000..7bcf063 --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/appcounter/package.json @@ -0,0 +1,106 @@ +{ + "name": "{{pluginGroup}}/{{pluginName}}", + "version": "0.0.1", + "description": "{{pluginDescription}}", + "author": "iBiz", + "license": "MIT", + "type": "module", + "main": "dist/index.es.js", + "module": "dist/index.es.js", + "types": "dist/types/index.d.ts", + "system": "dist/index.legacy.js", + "styles": [ + "dist/style.css" + ], + "files": [ + "dist", + "public", + "CHANGELOG.md", + "README.md" + ], + "publishConfig": { + "registry": "https://registry.npmjs.org/" + }, + "scripts": { + "dev": "vite build --watch", + "build": "vue-tsc --noEmit && vite build", + "preview": "vite preview" + }, + "devDependencies": { + "@floating-ui/dom": "^1.5.3", + "@ibiz-template/core": "^0.7.40-alpha.7", + "@ibiz-template/model-helper": "^0.7.40-alpha.8", + "@ibiz-template/runtime": "^0.7.40-alpha.8", + "@ibiz-template/theme": "^0.7.39", + "@ibiz-template/vue3-util": "^0.7.40-alpha.8", + "@ibiz/model-core": "^0.1.72", + "@qx-chitanda/vite-plugin-lib-legacy": "^4.1.1", + "@types/lodash-es": "^4.17.12", + "@types/ramda": "^0.29.6", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "@typescript-eslint/parser": "^6.11.0", + "@vitejs/plugin-vue": "^4.4.1", + "@vitejs/plugin-vue-jsx": "^3.0.2", + "async-validator": "^4.2.5", + "axios": "^1.6.2", + "dayjs": "^1.11.10", + "element-plus": "^2.4.2", + "eslint": "^8.53.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-prettier": "^9.0.0", + "eslint-plugin-import": "^2.29.0", + "eslint-plugin-prettier": "^5.0.1", + "eslint-plugin-unused-imports": "^3.0.0", + "eslint-plugin-vue": "^9.18.1", + "husky": "^8.0.3", + "lerna": "^8.0.0", + "lint-staged": "^15.1.0", + "lodash-es": "^4.17.21", + "pluralize": "^8.0.0", + "postcss": "^8.4.31", + "prettier": "^3.1.0", + "qs": "^6.11.2", + "qx-util": "^0.4.8", + "ramda": "^0.29.1", + "rollup-plugin-visualizer": "^5.9.2", + "sass": "1.69.5", + "stylelint": "15.11.0", + "stylelint-config-prettier": "^9.0.5", + "stylelint-config-recess-order": "^4.3.0", + "stylelint-config-standard": "^34.0.0", + "stylelint-config-standard-scss": "^11.1.0", + "stylelint-scss": "5.3.1", + "terser": "^5.24.0", + "typescript": "5.2.2", + "vite": "^4.5.0", + "vite-plugin-dts": "^3.6.3", + "vite-plugin-eslint": "^1.8.1", + "vite-plugin-libcss": "^1.1.1", + "vue": "^3.3.8", + "vue-eslint-parser": "^9.3.2", + "vue-router": "^4.2.5", + "vue-tsc": "1.8.22", + "vuedraggable": "^4.1.0" + }, + "peerDependencies": { + "@floating-ui/dom": "^1.5.1", + "@ibiz-template/core": "^0.7.40-alpha.7", + "@ibiz-template/model-helper": "^0.7.40-alpha.8", + "@ibiz-template/runtime": "^0.7.40-alpha.8", + "@ibiz-template/theme": "^0.7.39", + "@ibiz-template/vue3-util": "^0.7.40-alpha.8", + "@ibiz/model-core": "^0.1.72", + "async-validator": "^4.2.5", + "axios": "^1.6.2", + "dayjs": "^1.11.10", + "element-plus": "^2.4.2", + "lodash-es": "^4.17.21", + "pluralize": "^8.0.0", + "qs": "^6.11.2", + "qx-util": "^0.4.8", + "ramda": "^0.29.1", + "vue": "^3.3.8", + "vue-router": "^4.2.5", + "vuedraggable": "^4.1.0" + } +} diff --git a/packages/core/src/create-plugin/template/platform/appcounter/scripts/link.sh b/packages/core/src/create-plugin/template/platform/appcounter/scripts/link.sh new file mode 100755 index 0000000..d4edc15 --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/appcounter/scripts/link.sh @@ -0,0 +1,6 @@ +pnpm link --global "@ibiz-template/vue3-util" +pnpm link --global "@ibiz-template/model-helper" +pnpm link --global "@ibiz-template/runtime" +pnpm link --global "@ibiz-template/core" +pnpm link --global "@ibiz-template/theme" +pnpm link --global "@ibiz-template/vue3-components" diff --git a/packages/core/src/create-plugin/template/platform/appcounter/src/index.ts b/packages/core/src/create-plugin/template/platform/appcounter/src/index.ts new file mode 100644 index 0000000..02efdd2 --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/appcounter/src/index.ts @@ -0,0 +1,13 @@ +import { App } from 'vue'; +import { registerAppCounterProvider } from '@ibiz-template/runtime'; +import { {{ pascalCasePluginName }}Provider } from './{{pluginName}}.provider'; + +export default { + install(_app: App) { + // 全局注册计数器插件适配器, APPCOUNTER是插件类型,{{pluginId}}是插件标识 + registerAppCounterProvider( + 'APPCOUNTER_{{pluginId}}', + () => new {{ pascalCasePluginName }}Provider(), + ); + }, +}; diff --git a/packages/core/src/create-plugin/template/platform/appcounter/src/{{pluginName}}.provider.ts b/packages/core/src/create-plugin/template/platform/appcounter/src/{{pluginName}}.provider.ts new file mode 100644 index 0000000..511a98d --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/appcounter/src/{{pluginName}}.provider.ts @@ -0,0 +1,9 @@ +import { IAppCounter } from '@ibiz/model-core'; +import { AppCounter, IAppCounterProvider } from '@ibiz-template/runtime'; +import { {{ pascalCasePluginName }} } from './{{pluginName}}'; + +export class {{ pascalCasePluginName }}Provider implements IAppCounterProvider { + createCounter(model: IAppCounter): AppCounter { + return new {{ pascalCasePluginName }}(model); + } +} diff --git a/packages/core/src/create-plugin/template/platform/appcounter/src/{{pluginName}}.ts b/packages/core/src/create-plugin/template/platform/appcounter/src/{{pluginName}}.ts new file mode 100644 index 0000000..8fe4d4f --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/appcounter/src/{{pluginName}}.ts @@ -0,0 +1,8 @@ +import { AppCounter } from '@ibiz-template/runtime'; + +export class {{ pascalCasePluginName }} extends AppCounter { + protected async load(): Promise { + // 加载逻辑 + return this.data; + } +} diff --git a/packages/core/src/create-plugin/template/platform/appcounter/tsconfig.json b/packages/core/src/create-plugin/template/platform/appcounter/tsconfig.json new file mode 100644 index 0000000..ba8f48b --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/appcounter/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "moduleResolution": "Node", + "strict": true, + "jsx": "preserve", + "jsxImportSource": "vue", + "sourceMap": true, + "resolveJsonModule": true, + "isolatedModules": true, + "esModuleInterop": true, + "lib": ["ESNext", "DOM"], + "skipLibCheck": true + }, + "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/packages/core/src/create-plugin/template/platform/appcounter/tsconfig.node.json b/packages/core/src/create-plugin/template/platform/appcounter/tsconfig.node.json new file mode 100644 index 0000000..9d31e2a --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/appcounter/tsconfig.node.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "composite": true, + "module": "ESNext", + "moduleResolution": "Node", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/packages/core/src/create-plugin/template/platform/appcounter/vite.config.ts b/packages/core/src/create-plugin/template/platform/appcounter/vite.config.ts new file mode 100644 index 0000000..fc3449a --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/appcounter/vite.config.ts @@ -0,0 +1,57 @@ +import { defineConfig } from 'vite'; +import vue from '@vitejs/plugin-vue'; +import vueJsx from '@vitejs/plugin-vue-jsx'; +import libLegacy from '@qx-chitanda/vite-plugin-lib-legacy'; +import dts from 'vite-plugin-dts'; +import libCss from 'vite-plugin-libcss'; +// https://vitejs.dev/config/ +export default defineConfig({ + build: { + lib: { + entry: './src/index.ts', + fileName: format => `index.${format}.js`, + }, + rollupOptions: { + external: [ + '@ibiz-template/core', + '@ibiz-template/model-helper', + '@ibiz-template/runtime', + '@ibiz-template/theme', + '@ibiz-template/vue3-util', + '@ibiz/dynamic-model-api', + '@floating-ui/dom', + 'async-validator', + 'axios', + 'dayjs', + 'element-plus', + 'lodash-es', + 'pluralize', + 'qs', + 'qx-util', + 'ramda', + 'vue', + 'vue-router', + 'vuedraggable', + ], + }, + }, + css: { + preprocessorOptions: { + scss: { + additionalData: '@import "@ibiz-template/theme/style/global.scss";', + }, + }, + }, + plugins: [ + // eslint({ + // include: 'src/**/*.{ts,tsx,js,jsx}', + // }), + vue(), + vueJsx(), + libLegacy(), + libCss(), + dts({ + outDir: 'dist/types', + }), + ], +}); diff --git a/packages/core/src/create-plugin/template/platform/chart_render/package.json b/packages/core/src/create-plugin/template/platform/chart_render/package.json index 526db31..7bcf063 100644 --- a/packages/core/src/create-plugin/template/platform/chart_render/package.json +++ b/packages/core/src/create-plugin/template/platform/chart_render/package.json @@ -2,7 +2,7 @@ "name": "{{pluginGroup}}/{{pluginName}}", "version": "0.0.1", "description": "{{pluginDescription}}", - "author": "tony001", + "author": "iBiz", "license": "MIT", "type": "module", "main": "dist/index.es.js", diff --git a/packages/core/src/create-plugin/template/platform/custom/README.md b/packages/core/src/create-plugin/template/platform/custom/README.md index 9439fe6..1795d76 100644 --- a/packages/core/src/create-plugin/template/platform/custom/README.md +++ b/packages/core/src/create-plugin/template/platform/custom/README.md @@ -28,7 +28,7 @@ - 部件插件控制器 -部件插件控制器可继承基础控制器,然后根据需求进行调整。其中,基础控制器可参考附录中控制器部分。 +部件插件控制器承载部件的逻辑控制,可继承基础控制器,然后根据需求进行调整。其中,基础控制器可参考附录中控制器部分。 ## 本地开发 diff --git a/packages/core/src/create-plugin/template/platform/custom/package.json b/packages/core/src/create-plugin/template/platform/custom/package.json index 526db31..7bcf063 100644 --- a/packages/core/src/create-plugin/template/platform/custom/package.json +++ b/packages/core/src/create-plugin/template/platform/custom/package.json @@ -2,7 +2,7 @@ "name": "{{pluginGroup}}/{{pluginName}}", "version": "0.0.1", "description": "{{pluginDescription}}", - "author": "tony001", + "author": "iBiz", "license": "MIT", "type": "module", "main": "dist/index.es.js", diff --git a/packages/core/src/create-plugin/template/platform/dataview_render/package.json b/packages/core/src/create-plugin/template/platform/dataview_render/package.json index 526db31..7bcf063 100644 --- a/packages/core/src/create-plugin/template/platform/dataview_render/package.json +++ b/packages/core/src/create-plugin/template/platform/dataview_render/package.json @@ -2,7 +2,7 @@ "name": "{{pluginGroup}}/{{pluginName}}", "version": "0.0.1", "description": "{{pluginDescription}}", - "author": "tony001", + "author": "iBiz", "license": "MIT", "type": "module", "main": "dist/index.es.js", diff --git a/packages/core/src/create-plugin/template/platform/demethod/.eslintrc.cjs b/packages/core/src/create-plugin/template/platform/demethod/.eslintrc.cjs new file mode 100644 index 0000000..c6e5a1d --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/demethod/.eslintrc.cjs @@ -0,0 +1,52 @@ +module.exports = { + root: true, + env: { + browser: true, + es2021: true, + }, + extends: ['airbnb-base', 'prettier', 'plugin:@typescript-eslint/recommended'], + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + }, + plugins: ['prettier', '@typescript-eslint', 'unused-imports'], + rules: { + 'prettier/prettier': 'error', + 'arrow-body-style': 'off', + 'prefer-arrow-callback': 'off', + 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', + 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', + 'no-new': [0], + 'no-continue': [0], + '@typescript-eslint/no-empty-interface': 'off', + 'no-use-before-define': [0], + 'no-restricted-syntax': [0], + 'no-empty-function': [0], + 'no-useless-constructor': [0], // 禁止空的构造函数 + 'no-param-reassign': [0], // 禁止修改传入函数的参数 + 'no-underscore-dangle': [0], // 禁止使用下划线开头的变量名 + 'no-plusplus': ['error', { allowForLoopAfterthoughts: true }], // 禁止使用 ++,-- + 'consistent-return': [0], // 函数可以有不同类型返回值 + 'class-methods-use-this': [0], // 方法内未使用此方法时,强制定义为静态方法 + 'import/prefer-default-export': [0], // 一个模块只能有默认导出,不可以有多个导出 + 'import/no-unresolved': [0], // 不允许未解决的模块 + 'import/extensions': [0], // 不允许导入文件时不带后缀 + 'unused-imports/no-unused-imports': 'error', + '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }], + '@typescript-eslint/no-inferrable-types': [0], + '@typescript-eslint/no-non-null-assertion': [0], + '@typescript-eslint/no-explicit-any': ['error'], + '@typescript-eslint/explicit-function-return-type': 'error', // 要求函数和类方法的显式返回类型 + '@typescript-eslint/explicit-module-boundary-types': 'error', // 要求导出函数和类的公共类方法的显式返回和参数类型 + 'import/no-extraneous-dependencies': [ + 0, + { + devDependencies: true, + peerDependencies: true, + // optionalDependencies: true, + // bundledDependencies: true + }, + ], + }, +}; diff --git a/packages/core/src/create-plugin/template/platform/demethod/CHANGELOG.md b/packages/core/src/create-plugin/template/platform/demethod/CHANGELOG.md new file mode 100644 index 0000000..8ac8e7f --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/demethod/CHANGELOG.md @@ -0,0 +1,3 @@ +# 版本变更日志 + +添加变更日志 \ No newline at end of file diff --git a/packages/core/src/create-plugin/template/platform/demethod/README.md b/packages/core/src/create-plugin/template/platform/demethod/README.md new file mode 100644 index 0000000..1c5bec6 --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/demethod/README.md @@ -0,0 +1,65 @@ +# 实体行为插件 + +实体行为插件可自定义实体行为处理逻辑,当标准逻辑无法满足要求时,可以通过实体行为插件来实现。modeling建模平台创建实体行为插件可参见 [插件开发](https://open.ibizlab.cn/apphub/zh/guide/plugin-dev.html) + +## 插件结构 + +``` +|─ ─ {{pluginName}} 实体行为插件顶层目录 + |─ ─ src 实体行为插件源代码目录 +​ |─ ─ {{pluginName}}.provider.ts 实体行为插件适配器 +​ |─ ─ {{pluginName}}.ts 实体行为插件实现类 +​ |─ ─ index.ts 实体行为插件入口文件 +``` + +- 实体行为插件入口文件 + +实体行为插件入口文件会全局注册实体行为插件适配器,供外部使用。 + +- 实体行为插件实现类 + +实体行为插件实现类可继承基础应用方法Method,重写对应的处理逻辑。 + +- 实体行为插件适配器 + +实体行为插件适配器的create方法返回对应实体行为插件实现类的实例。 + +## 本地开发 + +1. 安装依赖并link至全局 + +```sh +// 安装依赖 +pnpm i + +// link底包 +./scripts/link.sh + +// 启动 +pnpm dev + +// link到全局 +pnpm link --global +``` + +2. 主项目包中引用插件 + +```sh +// link插件 +pnpm link --global '{{pluginGroup}}/{{pluginName}}' +``` + +3. 主项目包中注册插件 + +```ts +import { App } from 'vue'; +import {{ pascalCasePluginName }} from '{{pluginGroup}}/{{pluginName}}' + +export default { + install(app: App) { + app.use({{ pascalCasePluginName }}); + // 设置本地开发需要忽略加载的插件,可填写正则或全匹配字符串。匹配插件在modeling建模平台配置的[运行时插件仓库配置]内容 + ibiz.plugin.setDevIgnore(/^{{pluginGroup}}\/{{pluginName}}/); + }, +}; +``` diff --git a/packages/core/src/create-plugin/template/platform/demethod/package.json b/packages/core/src/create-plugin/template/platform/demethod/package.json new file mode 100644 index 0000000..7bcf063 --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/demethod/package.json @@ -0,0 +1,106 @@ +{ + "name": "{{pluginGroup}}/{{pluginName}}", + "version": "0.0.1", + "description": "{{pluginDescription}}", + "author": "iBiz", + "license": "MIT", + "type": "module", + "main": "dist/index.es.js", + "module": "dist/index.es.js", + "types": "dist/types/index.d.ts", + "system": "dist/index.legacy.js", + "styles": [ + "dist/style.css" + ], + "files": [ + "dist", + "public", + "CHANGELOG.md", + "README.md" + ], + "publishConfig": { + "registry": "https://registry.npmjs.org/" + }, + "scripts": { + "dev": "vite build --watch", + "build": "vue-tsc --noEmit && vite build", + "preview": "vite preview" + }, + "devDependencies": { + "@floating-ui/dom": "^1.5.3", + "@ibiz-template/core": "^0.7.40-alpha.7", + "@ibiz-template/model-helper": "^0.7.40-alpha.8", + "@ibiz-template/runtime": "^0.7.40-alpha.8", + "@ibiz-template/theme": "^0.7.39", + "@ibiz-template/vue3-util": "^0.7.40-alpha.8", + "@ibiz/model-core": "^0.1.72", + "@qx-chitanda/vite-plugin-lib-legacy": "^4.1.1", + "@types/lodash-es": "^4.17.12", + "@types/ramda": "^0.29.6", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "@typescript-eslint/parser": "^6.11.0", + "@vitejs/plugin-vue": "^4.4.1", + "@vitejs/plugin-vue-jsx": "^3.0.2", + "async-validator": "^4.2.5", + "axios": "^1.6.2", + "dayjs": "^1.11.10", + "element-plus": "^2.4.2", + "eslint": "^8.53.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-prettier": "^9.0.0", + "eslint-plugin-import": "^2.29.0", + "eslint-plugin-prettier": "^5.0.1", + "eslint-plugin-unused-imports": "^3.0.0", + "eslint-plugin-vue": "^9.18.1", + "husky": "^8.0.3", + "lerna": "^8.0.0", + "lint-staged": "^15.1.0", + "lodash-es": "^4.17.21", + "pluralize": "^8.0.0", + "postcss": "^8.4.31", + "prettier": "^3.1.0", + "qs": "^6.11.2", + "qx-util": "^0.4.8", + "ramda": "^0.29.1", + "rollup-plugin-visualizer": "^5.9.2", + "sass": "1.69.5", + "stylelint": "15.11.0", + "stylelint-config-prettier": "^9.0.5", + "stylelint-config-recess-order": "^4.3.0", + "stylelint-config-standard": "^34.0.0", + "stylelint-config-standard-scss": "^11.1.0", + "stylelint-scss": "5.3.1", + "terser": "^5.24.0", + "typescript": "5.2.2", + "vite": "^4.5.0", + "vite-plugin-dts": "^3.6.3", + "vite-plugin-eslint": "^1.8.1", + "vite-plugin-libcss": "^1.1.1", + "vue": "^3.3.8", + "vue-eslint-parser": "^9.3.2", + "vue-router": "^4.2.5", + "vue-tsc": "1.8.22", + "vuedraggable": "^4.1.0" + }, + "peerDependencies": { + "@floating-ui/dom": "^1.5.1", + "@ibiz-template/core": "^0.7.40-alpha.7", + "@ibiz-template/model-helper": "^0.7.40-alpha.8", + "@ibiz-template/runtime": "^0.7.40-alpha.8", + "@ibiz-template/theme": "^0.7.39", + "@ibiz-template/vue3-util": "^0.7.40-alpha.8", + "@ibiz/model-core": "^0.1.72", + "async-validator": "^4.2.5", + "axios": "^1.6.2", + "dayjs": "^1.11.10", + "element-plus": "^2.4.2", + "lodash-es": "^4.17.21", + "pluralize": "^8.0.0", + "qs": "^6.11.2", + "qx-util": "^0.4.8", + "ramda": "^0.29.1", + "vue": "^3.3.8", + "vue-router": "^4.2.5", + "vuedraggable": "^4.1.0" + } +} diff --git a/packages/core/src/create-plugin/template/platform/demethod/scripts/link.sh b/packages/core/src/create-plugin/template/platform/demethod/scripts/link.sh new file mode 100755 index 0000000..d4edc15 --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/demethod/scripts/link.sh @@ -0,0 +1,6 @@ +pnpm link --global "@ibiz-template/vue3-util" +pnpm link --global "@ibiz-template/model-helper" +pnpm link --global "@ibiz-template/runtime" +pnpm link --global "@ibiz-template/core" +pnpm link --global "@ibiz-template/theme" +pnpm link --global "@ibiz-template/vue3-components" diff --git a/packages/core/src/create-plugin/template/platform/demethod/src/index.ts b/packages/core/src/create-plugin/template/platform/demethod/src/index.ts new file mode 100644 index 0000000..55cecba --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/demethod/src/index.ts @@ -0,0 +1,13 @@ +import { App } from 'vue'; +import { registerDEMethodProvider } from '@ibiz-template/runtime'; +import { {{ pascalCasePluginName }}Provider } from './{{pluginName}}.provider'; + +export default { + install(_app: App) { + // 全局注册实体行为插件适配器, DEMETHOD是插件类型,{{pluginId}}是插件标识 + registerDEMethodProvider( + 'DEMETHOD_{{pluginId}}', + () => new {{ pascalCasePluginName }}Provider(), + ); + }, +}; diff --git a/packages/core/src/create-plugin/template/platform/demethod/src/{{pluginName}}.provider.ts b/packages/core/src/create-plugin/template/platform/demethod/src/{{pluginName}}.provider.ts new file mode 100644 index 0000000..aed9a8f --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/demethod/src/{{pluginName}}.provider.ts @@ -0,0 +1,19 @@ +import { + IAppDEService, + IDEMethodCreateOptions, + IDEMethodProvider, + Method, +} from '@ibiz-template/runtime'; +import { IAppDataEntity, IAppDEMethod } from '@ibiz/model-core'; +import { {{ pascalCasePluginName }} } from './{{pluginName}}'; + +export class {{ pascalCasePluginName }}Provider implements IDEMethodProvider { + create( + service: IAppDEService, + entity: IAppDataEntity, + method: IAppDEMethod, + opts: IDEMethodCreateOptions, + ): Method { + return new {{ pascalCasePluginName }}(service, entity, method, opts.localMode); + } +} diff --git a/packages/core/src/create-plugin/template/platform/demethod/src/{{pluginName}}.ts b/packages/core/src/create-plugin/template/platform/demethod/src/{{pluginName}}.ts new file mode 100644 index 0000000..478d85c --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/demethod/src/{{pluginName}}.ts @@ -0,0 +1,14 @@ +import { HttpResponse } from '@ibiz-template/core'; +import { Method } from '@ibiz-template/runtime'; + +export class {{ pascalCasePluginName }} extends Method { + async exec( + context: IContext, + data?: IData | IData[], + params?: IParams, + header?: IData, + ): Promise> { + // 处理逻辑 + return new HttpResponse({}); + } +} diff --git a/packages/core/src/create-plugin/template/platform/demethod/tsconfig.json b/packages/core/src/create-plugin/template/platform/demethod/tsconfig.json new file mode 100644 index 0000000..ba8f48b --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/demethod/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "moduleResolution": "Node", + "strict": true, + "jsx": "preserve", + "jsxImportSource": "vue", + "sourceMap": true, + "resolveJsonModule": true, + "isolatedModules": true, + "esModuleInterop": true, + "lib": ["ESNext", "DOM"], + "skipLibCheck": true + }, + "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/packages/core/src/create-plugin/template/platform/demethod/tsconfig.node.json b/packages/core/src/create-plugin/template/platform/demethod/tsconfig.node.json new file mode 100644 index 0000000..9d31e2a --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/demethod/tsconfig.node.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "composite": true, + "module": "ESNext", + "moduleResolution": "Node", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/packages/core/src/create-plugin/template/platform/demethod/vite.config.ts b/packages/core/src/create-plugin/template/platform/demethod/vite.config.ts new file mode 100644 index 0000000..fc3449a --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/demethod/vite.config.ts @@ -0,0 +1,57 @@ +import { defineConfig } from 'vite'; +import vue from '@vitejs/plugin-vue'; +import vueJsx from '@vitejs/plugin-vue-jsx'; +import libLegacy from '@qx-chitanda/vite-plugin-lib-legacy'; +import dts from 'vite-plugin-dts'; +import libCss from 'vite-plugin-libcss'; +// https://vitejs.dev/config/ +export default defineConfig({ + build: { + lib: { + entry: './src/index.ts', + fileName: format => `index.${format}.js`, + }, + rollupOptions: { + external: [ + '@ibiz-template/core', + '@ibiz-template/model-helper', + '@ibiz-template/runtime', + '@ibiz-template/theme', + '@ibiz-template/vue3-util', + '@ibiz/dynamic-model-api', + '@floating-ui/dom', + 'async-validator', + 'axios', + 'dayjs', + 'element-plus', + 'lodash-es', + 'pluralize', + 'qs', + 'qx-util', + 'ramda', + 'vue', + 'vue-router', + 'vuedraggable', + ], + }, + }, + css: { + preprocessorOptions: { + scss: { + additionalData: '@import "@ibiz-template/theme/style/global.scss";', + }, + }, + }, + plugins: [ + // eslint({ + // include: 'src/**/*.{ts,tsx,js,jsx}', + // }), + vue(), + vueJsx(), + libLegacy(), + libCss(), + dts({ + outDir: 'dist/types', + }), + ], +}); diff --git a/packages/core/src/create-plugin/template/platform/deuiaction/.eslintrc.cjs b/packages/core/src/create-plugin/template/platform/deuiaction/.eslintrc.cjs new file mode 100644 index 0000000..c6e5a1d --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/deuiaction/.eslintrc.cjs @@ -0,0 +1,52 @@ +module.exports = { + root: true, + env: { + browser: true, + es2021: true, + }, + extends: ['airbnb-base', 'prettier', 'plugin:@typescript-eslint/recommended'], + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + }, + plugins: ['prettier', '@typescript-eslint', 'unused-imports'], + rules: { + 'prettier/prettier': 'error', + 'arrow-body-style': 'off', + 'prefer-arrow-callback': 'off', + 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', + 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', + 'no-new': [0], + 'no-continue': [0], + '@typescript-eslint/no-empty-interface': 'off', + 'no-use-before-define': [0], + 'no-restricted-syntax': [0], + 'no-empty-function': [0], + 'no-useless-constructor': [0], // 禁止空的构造函数 + 'no-param-reassign': [0], // 禁止修改传入函数的参数 + 'no-underscore-dangle': [0], // 禁止使用下划线开头的变量名 + 'no-plusplus': ['error', { allowForLoopAfterthoughts: true }], // 禁止使用 ++,-- + 'consistent-return': [0], // 函数可以有不同类型返回值 + 'class-methods-use-this': [0], // 方法内未使用此方法时,强制定义为静态方法 + 'import/prefer-default-export': [0], // 一个模块只能有默认导出,不可以有多个导出 + 'import/no-unresolved': [0], // 不允许未解决的模块 + 'import/extensions': [0], // 不允许导入文件时不带后缀 + 'unused-imports/no-unused-imports': 'error', + '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }], + '@typescript-eslint/no-inferrable-types': [0], + '@typescript-eslint/no-non-null-assertion': [0], + '@typescript-eslint/no-explicit-any': ['error'], + '@typescript-eslint/explicit-function-return-type': 'error', // 要求函数和类方法的显式返回类型 + '@typescript-eslint/explicit-module-boundary-types': 'error', // 要求导出函数和类的公共类方法的显式返回和参数类型 + 'import/no-extraneous-dependencies': [ + 0, + { + devDependencies: true, + peerDependencies: true, + // optionalDependencies: true, + // bundledDependencies: true + }, + ], + }, +}; diff --git a/packages/core/src/create-plugin/template/platform/deuiaction/CHANGELOG.md b/packages/core/src/create-plugin/template/platform/deuiaction/CHANGELOG.md new file mode 100644 index 0000000..8ac8e7f --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/deuiaction/CHANGELOG.md @@ -0,0 +1,3 @@ +# 版本变更日志 + +添加变更日志 \ No newline at end of file diff --git a/packages/core/src/create-plugin/template/platform/deuiaction/README.md b/packages/core/src/create-plugin/template/platform/deuiaction/README.md new file mode 100644 index 0000000..513a280 --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/deuiaction/README.md @@ -0,0 +1,60 @@ +# 界面行为插件 + +界面行为插件可自定义界面行为处理逻辑,当标准逻辑无法满足要求时,可以通过界面行为插件来实现。modeling建模平台创建界面行为插件可参见 [插件开发](https://open.ibizlab.cn/apphub/zh/guide/plugin-dev.html) + +## 插件结构 + +``` +|─ ─ {{pluginName}} 界面行为插件顶层目录 + |─ ─ src 界面行为插件源代码目录 +​ |─ ─ {{pluginName}}.provider.ts 界面行为插件适配器 +​ |─ ─ index.ts 界面行为插件入口文件 +``` + +- 界面行为插件入口文件 + +界面行为插件入口文件会全局注册界面行为插件适配器,供外部使用。 + +- 界面行为插件适配器 + +界面行为插件适配器主要通过重写execAction方法去自定义界面行为的处理逻辑。 + +## 本地开发 + +1. 安装依赖并link至全局 + +```sh +// 安装依赖 +pnpm i + +// link底包 +./scripts/link.sh + +// 启动 +pnpm dev + +// link到全局 +pnpm link --global +``` + +2. 主项目包中引用插件 + +```sh +// link插件 +pnpm link --global '{{pluginGroup}}/{{pluginName}}' +``` + +3. 主项目包中注册插件 + +```ts +import { App } from 'vue'; +import {{ pascalCasePluginName }} from '{{pluginGroup}}/{{pluginName}}' + +export default { + install(app: App) { + app.use({{ pascalCasePluginName }}); + // 设置本地开发需要忽略加载的插件,可填写正则或全匹配字符串。匹配插件在modeling建模平台配置的[运行时插件仓库配置]内容 + ibiz.plugin.setDevIgnore(/^{{pluginGroup}}\/{{pluginName}}/); + }, +}; +``` diff --git a/packages/core/src/create-plugin/template/platform/deuiaction/package.json b/packages/core/src/create-plugin/template/platform/deuiaction/package.json new file mode 100644 index 0000000..7bcf063 --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/deuiaction/package.json @@ -0,0 +1,106 @@ +{ + "name": "{{pluginGroup}}/{{pluginName}}", + "version": "0.0.1", + "description": "{{pluginDescription}}", + "author": "iBiz", + "license": "MIT", + "type": "module", + "main": "dist/index.es.js", + "module": "dist/index.es.js", + "types": "dist/types/index.d.ts", + "system": "dist/index.legacy.js", + "styles": [ + "dist/style.css" + ], + "files": [ + "dist", + "public", + "CHANGELOG.md", + "README.md" + ], + "publishConfig": { + "registry": "https://registry.npmjs.org/" + }, + "scripts": { + "dev": "vite build --watch", + "build": "vue-tsc --noEmit && vite build", + "preview": "vite preview" + }, + "devDependencies": { + "@floating-ui/dom": "^1.5.3", + "@ibiz-template/core": "^0.7.40-alpha.7", + "@ibiz-template/model-helper": "^0.7.40-alpha.8", + "@ibiz-template/runtime": "^0.7.40-alpha.8", + "@ibiz-template/theme": "^0.7.39", + "@ibiz-template/vue3-util": "^0.7.40-alpha.8", + "@ibiz/model-core": "^0.1.72", + "@qx-chitanda/vite-plugin-lib-legacy": "^4.1.1", + "@types/lodash-es": "^4.17.12", + "@types/ramda": "^0.29.6", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "@typescript-eslint/parser": "^6.11.0", + "@vitejs/plugin-vue": "^4.4.1", + "@vitejs/plugin-vue-jsx": "^3.0.2", + "async-validator": "^4.2.5", + "axios": "^1.6.2", + "dayjs": "^1.11.10", + "element-plus": "^2.4.2", + "eslint": "^8.53.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-prettier": "^9.0.0", + "eslint-plugin-import": "^2.29.0", + "eslint-plugin-prettier": "^5.0.1", + "eslint-plugin-unused-imports": "^3.0.0", + "eslint-plugin-vue": "^9.18.1", + "husky": "^8.0.3", + "lerna": "^8.0.0", + "lint-staged": "^15.1.0", + "lodash-es": "^4.17.21", + "pluralize": "^8.0.0", + "postcss": "^8.4.31", + "prettier": "^3.1.0", + "qs": "^6.11.2", + "qx-util": "^0.4.8", + "ramda": "^0.29.1", + "rollup-plugin-visualizer": "^5.9.2", + "sass": "1.69.5", + "stylelint": "15.11.0", + "stylelint-config-prettier": "^9.0.5", + "stylelint-config-recess-order": "^4.3.0", + "stylelint-config-standard": "^34.0.0", + "stylelint-config-standard-scss": "^11.1.0", + "stylelint-scss": "5.3.1", + "terser": "^5.24.0", + "typescript": "5.2.2", + "vite": "^4.5.0", + "vite-plugin-dts": "^3.6.3", + "vite-plugin-eslint": "^1.8.1", + "vite-plugin-libcss": "^1.1.1", + "vue": "^3.3.8", + "vue-eslint-parser": "^9.3.2", + "vue-router": "^4.2.5", + "vue-tsc": "1.8.22", + "vuedraggable": "^4.1.0" + }, + "peerDependencies": { + "@floating-ui/dom": "^1.5.1", + "@ibiz-template/core": "^0.7.40-alpha.7", + "@ibiz-template/model-helper": "^0.7.40-alpha.8", + "@ibiz-template/runtime": "^0.7.40-alpha.8", + "@ibiz-template/theme": "^0.7.39", + "@ibiz-template/vue3-util": "^0.7.40-alpha.8", + "@ibiz/model-core": "^0.1.72", + "async-validator": "^4.2.5", + "axios": "^1.6.2", + "dayjs": "^1.11.10", + "element-plus": "^2.4.2", + "lodash-es": "^4.17.21", + "pluralize": "^8.0.0", + "qs": "^6.11.2", + "qx-util": "^0.4.8", + "ramda": "^0.29.1", + "vue": "^3.3.8", + "vue-router": "^4.2.5", + "vuedraggable": "^4.1.0" + } +} diff --git a/packages/core/src/create-plugin/template/platform/deuiaction/scripts/link.sh b/packages/core/src/create-plugin/template/platform/deuiaction/scripts/link.sh new file mode 100755 index 0000000..d4edc15 --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/deuiaction/scripts/link.sh @@ -0,0 +1,6 @@ +pnpm link --global "@ibiz-template/vue3-util" +pnpm link --global "@ibiz-template/model-helper" +pnpm link --global "@ibiz-template/runtime" +pnpm link --global "@ibiz-template/core" +pnpm link --global "@ibiz-template/theme" +pnpm link --global "@ibiz-template/vue3-components" diff --git a/packages/core/src/create-plugin/template/platform/deuiaction/src/index.ts b/packages/core/src/create-plugin/template/platform/deuiaction/src/index.ts new file mode 100644 index 0000000..91b5e85 --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/deuiaction/src/index.ts @@ -0,0 +1,13 @@ +import { App } from 'vue'; +import { registerUIActionProvider } from '@ibiz-template/runtime'; +import { {{ pascalCasePluginName }}Provider } from './{{pluginName}}.provider'; + +export default { + install(_app: App) { + // 全局注册界面行为插件适配器,DEUIACTION是插件类型,{{pluginId}}是插件标识 + registerUIActionProvider( + 'DEUIACTION_{{pluginId}}', + () => new {{ pascalCasePluginName }}Provider(), + ); + }, +}; diff --git a/packages/core/src/create-plugin/template/platform/deuiaction/src/{{pluginName}}.provider.ts b/packages/core/src/create-plugin/template/platform/deuiaction/src/{{pluginName}}.provider.ts new file mode 100644 index 0000000..d7f09cf --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/deuiaction/src/{{pluginName}}.provider.ts @@ -0,0 +1,17 @@ +import { IAppDEUIAction } from '@ibiz/model-core'; +import { + IUIActionResult, + IUILogicParams, + UIActionProviderBase, +} from '@ibiz-template/runtime'; + +export class {{ pascalCasePluginName }}Provider extends UIActionProviderBase { + async execAction( + action: IAppDEUIAction, + args: IUILogicParams, + ): Promise { + const actionResult: IUIActionResult = {}; + // 处理逻辑 + return actionResult; + } +} diff --git a/packages/core/src/create-plugin/template/platform/deuiaction/tsconfig.json b/packages/core/src/create-plugin/template/platform/deuiaction/tsconfig.json new file mode 100644 index 0000000..ba8f48b --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/deuiaction/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "moduleResolution": "Node", + "strict": true, + "jsx": "preserve", + "jsxImportSource": "vue", + "sourceMap": true, + "resolveJsonModule": true, + "isolatedModules": true, + "esModuleInterop": true, + "lib": ["ESNext", "DOM"], + "skipLibCheck": true + }, + "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/packages/core/src/create-plugin/template/platform/deuiaction/tsconfig.node.json b/packages/core/src/create-plugin/template/platform/deuiaction/tsconfig.node.json new file mode 100644 index 0000000..9d31e2a --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/deuiaction/tsconfig.node.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "composite": true, + "module": "ESNext", + "moduleResolution": "Node", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/packages/core/src/create-plugin/template/platform/deuiaction/vite.config.ts b/packages/core/src/create-plugin/template/platform/deuiaction/vite.config.ts new file mode 100644 index 0000000..fc3449a --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/deuiaction/vite.config.ts @@ -0,0 +1,57 @@ +import { defineConfig } from 'vite'; +import vue from '@vitejs/plugin-vue'; +import vueJsx from '@vitejs/plugin-vue-jsx'; +import libLegacy from '@qx-chitanda/vite-plugin-lib-legacy'; +import dts from 'vite-plugin-dts'; +import libCss from 'vite-plugin-libcss'; +// https://vitejs.dev/config/ +export default defineConfig({ + build: { + lib: { + entry: './src/index.ts', + fileName: format => `index.${format}.js`, + }, + rollupOptions: { + external: [ + '@ibiz-template/core', + '@ibiz-template/model-helper', + '@ibiz-template/runtime', + '@ibiz-template/theme', + '@ibiz-template/vue3-util', + '@ibiz/dynamic-model-api', + '@floating-ui/dom', + 'async-validator', + 'axios', + 'dayjs', + 'element-plus', + 'lodash-es', + 'pluralize', + 'qs', + 'qx-util', + 'ramda', + 'vue', + 'vue-router', + 'vuedraggable', + ], + }, + }, + css: { + preprocessorOptions: { + scss: { + additionalData: '@import "@ibiz-template/theme/style/global.scss";', + }, + }, + }, + plugins: [ + // eslint({ + // include: 'src/**/*.{ts,tsx,js,jsx}', + // }), + vue(), + vueJsx(), + libLegacy(), + libCss(), + dts({ + outDir: 'dist/types', + }), + ], +}); diff --git a/packages/core/src/create-plugin/template/platform/editform_render/package.json b/packages/core/src/create-plugin/template/platform/editform_render/package.json index 526db31..7bcf063 100644 --- a/packages/core/src/create-plugin/template/platform/editform_render/package.json +++ b/packages/core/src/create-plugin/template/platform/editform_render/package.json @@ -2,7 +2,7 @@ "name": "{{pluginGroup}}/{{pluginName}}", "version": "0.0.1", "description": "{{pluginDescription}}", - "author": "tony001", + "author": "iBiz", "license": "MIT", "type": "module", "main": "dist/index.es.js", diff --git a/packages/core/src/create-plugin/template/platform/editor_customstyle/package.json b/packages/core/src/create-plugin/template/platform/editor_customstyle/package.json index 526db31..7bcf063 100644 --- a/packages/core/src/create-plugin/template/platform/editor_customstyle/package.json +++ b/packages/core/src/create-plugin/template/platform/editor_customstyle/package.json @@ -2,7 +2,7 @@ "name": "{{pluginGroup}}/{{pluginName}}", "version": "0.0.1", "description": "{{pluginDescription}}", - "author": "tony001", + "author": "iBiz", "license": "MIT", "type": "module", "main": "dist/index.es.js", diff --git a/packages/core/src/create-plugin/template/platform/form_usercontrol/package.json b/packages/core/src/create-plugin/template/platform/form_usercontrol/package.json index 526db31..7bcf063 100644 --- a/packages/core/src/create-plugin/template/platform/form_usercontrol/package.json +++ b/packages/core/src/create-plugin/template/platform/form_usercontrol/package.json @@ -2,7 +2,7 @@ "name": "{{pluginGroup}}/{{pluginName}}", "version": "0.0.1", "description": "{{pluginDescription}}", - "author": "tony001", + "author": "iBiz", "license": "MIT", "type": "module", "main": "dist/index.es.js", diff --git a/packages/core/src/create-plugin/template/platform/grid_colrender/package.json b/packages/core/src/create-plugin/template/platform/grid_colrender/package.json index 526db31..7bcf063 100644 --- a/packages/core/src/create-plugin/template/platform/grid_colrender/package.json +++ b/packages/core/src/create-plugin/template/platform/grid_colrender/package.json @@ -2,7 +2,7 @@ "name": "{{pluginGroup}}/{{pluginName}}", "version": "0.0.1", "description": "{{pluginDescription}}", - "author": "tony001", + "author": "iBiz", "license": "MIT", "type": "module", "main": "dist/index.es.js", diff --git a/packages/core/src/create-plugin/template/platform/grid_render/package.json b/packages/core/src/create-plugin/template/platform/grid_render/package.json index 526db31..7bcf063 100644 --- a/packages/core/src/create-plugin/template/platform/grid_render/package.json +++ b/packages/core/src/create-plugin/template/platform/grid_render/package.json @@ -2,7 +2,7 @@ "name": "{{pluginGroup}}/{{pluginName}}", "version": "0.0.1", "description": "{{pluginDescription}}", - "author": "tony001", + "author": "iBiz", "license": "MIT", "type": "module", "main": "dist/index.es.js", diff --git a/packages/core/src/create-plugin/template/platform/list_render/package.json b/packages/core/src/create-plugin/template/platform/list_render/package.json index 526db31..7bcf063 100644 --- a/packages/core/src/create-plugin/template/platform/list_render/package.json +++ b/packages/core/src/create-plugin/template/platform/list_render/package.json @@ -2,7 +2,7 @@ "name": "{{pluginGroup}}/{{pluginName}}", "version": "0.0.1", "description": "{{pluginDescription}}", - "author": "tony001", + "author": "iBiz", "license": "MIT", "type": "module", "main": "dist/index.es.js", diff --git a/packages/core/src/create-plugin/template/platform/portlet_custom/package.json b/packages/core/src/create-plugin/template/platform/portlet_custom/package.json index 526db31..7bcf063 100644 --- a/packages/core/src/create-plugin/template/platform/portlet_custom/package.json +++ b/packages/core/src/create-plugin/template/platform/portlet_custom/package.json @@ -2,7 +2,7 @@ "name": "{{pluginGroup}}/{{pluginName}}", "version": "0.0.1", "description": "{{pluginDescription}}", - "author": "tony001", + "author": "iBiz", "license": "MIT", "type": "module", "main": "dist/index.es.js", diff --git a/packages/core/src/create-plugin/template/platform/searchbar_render/.eslintrc.cjs b/packages/core/src/create-plugin/template/platform/searchbar_render/.eslintrc.cjs new file mode 100644 index 0000000..c6e5a1d --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/searchbar_render/.eslintrc.cjs @@ -0,0 +1,52 @@ +module.exports = { + root: true, + env: { + browser: true, + es2021: true, + }, + extends: ['airbnb-base', 'prettier', 'plugin:@typescript-eslint/recommended'], + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + }, + plugins: ['prettier', '@typescript-eslint', 'unused-imports'], + rules: { + 'prettier/prettier': 'error', + 'arrow-body-style': 'off', + 'prefer-arrow-callback': 'off', + 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', + 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', + 'no-new': [0], + 'no-continue': [0], + '@typescript-eslint/no-empty-interface': 'off', + 'no-use-before-define': [0], + 'no-restricted-syntax': [0], + 'no-empty-function': [0], + 'no-useless-constructor': [0], // 禁止空的构造函数 + 'no-param-reassign': [0], // 禁止修改传入函数的参数 + 'no-underscore-dangle': [0], // 禁止使用下划线开头的变量名 + 'no-plusplus': ['error', { allowForLoopAfterthoughts: true }], // 禁止使用 ++,-- + 'consistent-return': [0], // 函数可以有不同类型返回值 + 'class-methods-use-this': [0], // 方法内未使用此方法时,强制定义为静态方法 + 'import/prefer-default-export': [0], // 一个模块只能有默认导出,不可以有多个导出 + 'import/no-unresolved': [0], // 不允许未解决的模块 + 'import/extensions': [0], // 不允许导入文件时不带后缀 + 'unused-imports/no-unused-imports': 'error', + '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }], + '@typescript-eslint/no-inferrable-types': [0], + '@typescript-eslint/no-non-null-assertion': [0], + '@typescript-eslint/no-explicit-any': ['error'], + '@typescript-eslint/explicit-function-return-type': 'error', // 要求函数和类方法的显式返回类型 + '@typescript-eslint/explicit-module-boundary-types': 'error', // 要求导出函数和类的公共类方法的显式返回和参数类型 + 'import/no-extraneous-dependencies': [ + 0, + { + devDependencies: true, + peerDependencies: true, + // optionalDependencies: true, + // bundledDependencies: true + }, + ], + }, +}; diff --git a/packages/core/src/create-plugin/template/platform/searchbar_render/CHANGELOG.md b/packages/core/src/create-plugin/template/platform/searchbar_render/CHANGELOG.md new file mode 100644 index 0000000..8ac8e7f --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/searchbar_render/CHANGELOG.md @@ -0,0 +1,3 @@ +# 版本变更日志 + +添加变更日志 \ No newline at end of file diff --git a/packages/core/src/create-plugin/template/platform/searchbar_render/README.md b/packages/core/src/create-plugin/template/platform/searchbar_render/README.md new file mode 100644 index 0000000..9fc2145 --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/searchbar_render/README.md @@ -0,0 +1,71 @@ +# 搜索栏插件 + +搜索栏插件可自定义搜索栏内容的绘制,当标准逻辑无法满足搜索栏绘制要求时,可以通过搜索栏插件来实现。modeling建模平台创建搜索栏插件可参见 [插件开发](https://open.ibizlab.cn/apphub/zh/guide/plugin-dev.html) + +## 插件结构 + +``` +|─ ─ {{pluginName}} 搜索栏插件顶层目录 + |─ ─ src 搜索栏插件源代码目录 +​ |─ ─ {{pluginName}}.controller.ts 搜索栏插件控制器 +​ |─ ─ {{pluginName}}.provider.ts 搜索栏插件适配器 +​ |─ ─ {{pluginName}}.scss 搜索栏插件样式 +​ |─ ─ {{pluginName}}.tsx 搜索栏插件组件 +​ |─ ─ index.ts 搜索栏插件入口文件 +``` + +- 搜索栏插件入口文件 + +搜索栏插件入口文件会全局注册搜索栏插件适配器和搜索栏插件组件,供外部使用。 + +- 搜索栏插件组件 + +搜索栏插件组件使用tsx的书写方式,承载搜索栏绘制的内容。 + +- 搜索栏插件适配器 + +搜索栏插件适配器主要通过component属性指定搜索栏实际要绘制的组件,并且通过createController方法返回传递给搜索栏的控制器。 + +- 搜索栏插件控制器 + +搜索栏插件控制器承载搜索栏的逻辑控制。 + +## 本地开发 + +1. 安装依赖并link至全局 + +```sh +// 安装依赖 +pnpm i + +// link底包 +./scripts/link.sh + +// 启动 +pnpm dev + +// link到全局 +pnpm link --global +``` + +2. 主项目包中引用插件 + +```sh +// link插件 +pnpm link --global '{{pluginGroup}}/{{pluginName}}' +``` + +3. 主项目包中注册插件 + +```ts +import { App } from 'vue'; +import {{ pascalCasePluginName }} from '{{pluginGroup}}/{{pluginName}}' + +export default { + install(app: App) { + app.use({{ pascalCasePluginName }}); + // 设置本地开发需要忽略加载的插件,可填写正则或全匹配字符串。匹配插件在modeling建模平台配置的[运行时插件仓库配置]内容 + ibiz.plugin.setDevIgnore(/^{{pluginGroup}}\/{{pluginName}}/); + }, +}; +``` diff --git a/packages/core/src/create-plugin/template/platform/searchbar_render/package.json b/packages/core/src/create-plugin/template/platform/searchbar_render/package.json new file mode 100644 index 0000000..7bcf063 --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/searchbar_render/package.json @@ -0,0 +1,106 @@ +{ + "name": "{{pluginGroup}}/{{pluginName}}", + "version": "0.0.1", + "description": "{{pluginDescription}}", + "author": "iBiz", + "license": "MIT", + "type": "module", + "main": "dist/index.es.js", + "module": "dist/index.es.js", + "types": "dist/types/index.d.ts", + "system": "dist/index.legacy.js", + "styles": [ + "dist/style.css" + ], + "files": [ + "dist", + "public", + "CHANGELOG.md", + "README.md" + ], + "publishConfig": { + "registry": "https://registry.npmjs.org/" + }, + "scripts": { + "dev": "vite build --watch", + "build": "vue-tsc --noEmit && vite build", + "preview": "vite preview" + }, + "devDependencies": { + "@floating-ui/dom": "^1.5.3", + "@ibiz-template/core": "^0.7.40-alpha.7", + "@ibiz-template/model-helper": "^0.7.40-alpha.8", + "@ibiz-template/runtime": "^0.7.40-alpha.8", + "@ibiz-template/theme": "^0.7.39", + "@ibiz-template/vue3-util": "^0.7.40-alpha.8", + "@ibiz/model-core": "^0.1.72", + "@qx-chitanda/vite-plugin-lib-legacy": "^4.1.1", + "@types/lodash-es": "^4.17.12", + "@types/ramda": "^0.29.6", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "@typescript-eslint/parser": "^6.11.0", + "@vitejs/plugin-vue": "^4.4.1", + "@vitejs/plugin-vue-jsx": "^3.0.2", + "async-validator": "^4.2.5", + "axios": "^1.6.2", + "dayjs": "^1.11.10", + "element-plus": "^2.4.2", + "eslint": "^8.53.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-prettier": "^9.0.0", + "eslint-plugin-import": "^2.29.0", + "eslint-plugin-prettier": "^5.0.1", + "eslint-plugin-unused-imports": "^3.0.0", + "eslint-plugin-vue": "^9.18.1", + "husky": "^8.0.3", + "lerna": "^8.0.0", + "lint-staged": "^15.1.0", + "lodash-es": "^4.17.21", + "pluralize": "^8.0.0", + "postcss": "^8.4.31", + "prettier": "^3.1.0", + "qs": "^6.11.2", + "qx-util": "^0.4.8", + "ramda": "^0.29.1", + "rollup-plugin-visualizer": "^5.9.2", + "sass": "1.69.5", + "stylelint": "15.11.0", + "stylelint-config-prettier": "^9.0.5", + "stylelint-config-recess-order": "^4.3.0", + "stylelint-config-standard": "^34.0.0", + "stylelint-config-standard-scss": "^11.1.0", + "stylelint-scss": "5.3.1", + "terser": "^5.24.0", + "typescript": "5.2.2", + "vite": "^4.5.0", + "vite-plugin-dts": "^3.6.3", + "vite-plugin-eslint": "^1.8.1", + "vite-plugin-libcss": "^1.1.1", + "vue": "^3.3.8", + "vue-eslint-parser": "^9.3.2", + "vue-router": "^4.2.5", + "vue-tsc": "1.8.22", + "vuedraggable": "^4.1.0" + }, + "peerDependencies": { + "@floating-ui/dom": "^1.5.1", + "@ibiz-template/core": "^0.7.40-alpha.7", + "@ibiz-template/model-helper": "^0.7.40-alpha.8", + "@ibiz-template/runtime": "^0.7.40-alpha.8", + "@ibiz-template/theme": "^0.7.39", + "@ibiz-template/vue3-util": "^0.7.40-alpha.8", + "@ibiz/model-core": "^0.1.72", + "async-validator": "^4.2.5", + "axios": "^1.6.2", + "dayjs": "^1.11.10", + "element-plus": "^2.4.2", + "lodash-es": "^4.17.21", + "pluralize": "^8.0.0", + "qs": "^6.11.2", + "qx-util": "^0.4.8", + "ramda": "^0.29.1", + "vue": "^3.3.8", + "vue-router": "^4.2.5", + "vuedraggable": "^4.1.0" + } +} diff --git a/packages/core/src/create-plugin/template/platform/searchbar_render/scripts/link.sh b/packages/core/src/create-plugin/template/platform/searchbar_render/scripts/link.sh new file mode 100755 index 0000000..d4edc15 --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/searchbar_render/scripts/link.sh @@ -0,0 +1,6 @@ +pnpm link --global "@ibiz-template/vue3-util" +pnpm link --global "@ibiz-template/model-helper" +pnpm link --global "@ibiz-template/runtime" +pnpm link --global "@ibiz-template/core" +pnpm link --global "@ibiz-template/theme" +pnpm link --global "@ibiz-template/vue3-components" diff --git a/packages/core/src/create-plugin/template/platform/searchbar_render/src/index.ts b/packages/core/src/create-plugin/template/platform/searchbar_render/src/index.ts new file mode 100644 index 0000000..68e967a --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/searchbar_render/src/index.ts @@ -0,0 +1,16 @@ +import { App } from 'vue'; +import { registerControlProvider } from '@ibiz-template/runtime'; +import { {{ pascalCasePluginName }} } from './{{pluginName}}'; +import { {{ pascalCasePluginName }}Provider } from './{{pluginName}}.provider'; + +export default { + install(app: App) { + // 全局注册搜索栏插件组件 + app.component({{ pascalCasePluginName }}.name!, {{ pascalCasePluginName }}); + // 全局注册搜索栏插件适配器,SEARCHBAR_RENDER是插件类型,{{pluginId}}是插件标识 + registerControlProvider( + 'SEARCHBAR_RENDER_{{pluginId}}', + () => new {{ pascalCasePluginName }}Provider(), + ); + }, +}; diff --git a/packages/core/src/create-plugin/template/platform/searchbar_render/src/{{pluginName}}.controller.ts b/packages/core/src/create-plugin/template/platform/searchbar_render/src/{{pluginName}}.controller.ts new file mode 100644 index 0000000..5f24bcf --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/searchbar_render/src/{{pluginName}}.controller.ts @@ -0,0 +1,3 @@ +import { SearchBarController } from '@ibiz-template/runtime'; + +export class {{ pascalCasePluginName }}Controller extends SearchBarController {} diff --git a/packages/core/src/create-plugin/template/platform/searchbar_render/src/{{pluginName}}.provider.ts b/packages/core/src/create-plugin/template/platform/searchbar_render/src/{{pluginName}}.provider.ts new file mode 100644 index 0000000..9a32e3f --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/searchbar_render/src/{{pluginName}}.provider.ts @@ -0,0 +1,20 @@ +import { + CTX, + IControlController, + IControlProvider, +} from '@ibiz-template/runtime'; +import { IControl } from '@ibiz/model-core'; +import { {{ pascalCasePluginName }}Controller } from './{{pluginName}}.controller'; + +export class {{ pascalCasePluginName }}Provider implements IControlProvider { + component: string = 'IBiz{{ pascalCasePluginName }}'; + + createController( + model: IControl, + context: IContext, + params: IParams, + ctx: CTX, + ): IControlController { + return new {{ pascalCasePluginName }}Controller(model, context, params, ctx); + } +} diff --git a/packages/core/src/create-plugin/template/platform/searchbar_render/src/{{pluginName}}.scss b/packages/core/src/create-plugin/template/platform/searchbar_render/src/{{pluginName}}.scss new file mode 100644 index 0000000..f494ab6 --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/searchbar_render/src/{{pluginName}}.scss @@ -0,0 +1,3 @@ +@include b({{pluginName}}){ + // 样式 +} \ No newline at end of file diff --git a/packages/core/src/create-plugin/template/platform/searchbar_render/src/{{pluginName}}.tsx b/packages/core/src/create-plugin/template/platform/searchbar_render/src/{{pluginName}}.tsx new file mode 100644 index 0000000..48ca729 --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/searchbar_render/src/{{pluginName}}.tsx @@ -0,0 +1,46 @@ +import { defineComponent, PropType } from 'vue'; +import { useControlController, useNamespace } from '@ibiz-template/vue3-util'; +import { ISearchBar } from '@ibiz/model-core'; +import { IControlProvider } from '@ibiz-template/runtime'; +import { {{ pascalCasePluginName }}Controller } from './{{pluginName}}.controller'; +import './{{pluginName}}.scss'; + +export const {{ pascalCasePluginName }} = defineComponent({ + name: 'IBiz{{ pascalCasePluginName }}', + props: { + /** + * @description 搜索栏模型数据 + */ + modelData: { + type: Object as PropType, + required: true, + }, + /** + * @description 应用上下文对象 + */ + context: { type: Object as PropType, required: true }, + /** + * @description 视图参数对象 + * @default {} + */ + params: { type: Object as PropType, default: () => ({}) }, + /** + * @description 部件适配器 + */ + provider: { type: Object as PropType }, + }, + setup() { + const c = useControlController( + (...args) => new {{ pascalCasePluginName }}Controller(...args), + ); + const ns = useNamespace('{{pluginName}}'); + + return { + c, + ns, + }; + }, + render() { + return
插件示例
; + }, +}); diff --git a/packages/core/src/create-plugin/template/platform/searchbar_render/tsconfig.json b/packages/core/src/create-plugin/template/platform/searchbar_render/tsconfig.json new file mode 100644 index 0000000..ba8f48b --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/searchbar_render/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "moduleResolution": "Node", + "strict": true, + "jsx": "preserve", + "jsxImportSource": "vue", + "sourceMap": true, + "resolveJsonModule": true, + "isolatedModules": true, + "esModuleInterop": true, + "lib": ["ESNext", "DOM"], + "skipLibCheck": true + }, + "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/packages/core/src/create-plugin/template/platform/searchbar_render/tsconfig.node.json b/packages/core/src/create-plugin/template/platform/searchbar_render/tsconfig.node.json new file mode 100644 index 0000000..9d31e2a --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/searchbar_render/tsconfig.node.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "composite": true, + "module": "ESNext", + "moduleResolution": "Node", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/packages/core/src/create-plugin/template/platform/searchbar_render/vite.config.ts b/packages/core/src/create-plugin/template/platform/searchbar_render/vite.config.ts new file mode 100644 index 0000000..fc3449a --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/searchbar_render/vite.config.ts @@ -0,0 +1,57 @@ +import { defineConfig } from 'vite'; +import vue from '@vitejs/plugin-vue'; +import vueJsx from '@vitejs/plugin-vue-jsx'; +import libLegacy from '@qx-chitanda/vite-plugin-lib-legacy'; +import dts from 'vite-plugin-dts'; +import libCss from 'vite-plugin-libcss'; +// https://vitejs.dev/config/ +export default defineConfig({ + build: { + lib: { + entry: './src/index.ts', + fileName: format => `index.${format}.js`, + }, + rollupOptions: { + external: [ + '@ibiz-template/core', + '@ibiz-template/model-helper', + '@ibiz-template/runtime', + '@ibiz-template/theme', + '@ibiz-template/vue3-util', + '@ibiz/dynamic-model-api', + '@floating-ui/dom', + 'async-validator', + 'axios', + 'dayjs', + 'element-plus', + 'lodash-es', + 'pluralize', + 'qs', + 'qx-util', + 'ramda', + 'vue', + 'vue-router', + 'vuedraggable', + ], + }, + }, + css: { + preprocessorOptions: { + scss: { + additionalData: '@import "@ibiz-template/theme/style/global.scss";', + }, + }, + }, + plugins: [ + // eslint({ + // include: 'src/**/*.{ts,tsx,js,jsx}', + // }), + vue(), + vueJsx(), + libLegacy(), + libCss(), + dts({ + outDir: 'dist/types', + }), + ], +}); diff --git a/packages/core/src/create-plugin/template/platform/searchform_render/package.json b/packages/core/src/create-plugin/template/platform/searchform_render/package.json index 526db31..7bcf063 100644 --- a/packages/core/src/create-plugin/template/platform/searchform_render/package.json +++ b/packages/core/src/create-plugin/template/platform/searchform_render/package.json @@ -2,7 +2,7 @@ "name": "{{pluginGroup}}/{{pluginName}}", "version": "0.0.1", "description": "{{pluginDescription}}", - "author": "tony001", + "author": "iBiz", "license": "MIT", "type": "module", "main": "dist/index.es.js", diff --git a/packages/core/src/create-plugin/template/platform/toolbar_item/package.json b/packages/core/src/create-plugin/template/platform/toolbar_item/package.json index 526db31..7bcf063 100644 --- a/packages/core/src/create-plugin/template/platform/toolbar_item/package.json +++ b/packages/core/src/create-plugin/template/platform/toolbar_item/package.json @@ -2,7 +2,7 @@ "name": "{{pluginGroup}}/{{pluginName}}", "version": "0.0.1", "description": "{{pluginDescription}}", - "author": "tony001", + "author": "iBiz", "license": "MIT", "type": "module", "main": "dist/index.es.js", diff --git a/packages/core/src/create-plugin/template/platform/toolbar_render/package.json b/packages/core/src/create-plugin/template/platform/toolbar_render/package.json index 526db31..7bcf063 100644 --- a/packages/core/src/create-plugin/template/platform/toolbar_render/package.json +++ b/packages/core/src/create-plugin/template/platform/toolbar_render/package.json @@ -2,7 +2,7 @@ "name": "{{pluginGroup}}/{{pluginName}}", "version": "0.0.1", "description": "{{pluginDescription}}", - "author": "tony001", + "author": "iBiz", "license": "MIT", "type": "module", "main": "dist/index.es.js", diff --git a/packages/core/src/create-plugin/template/platform/tree_render/package.json b/packages/core/src/create-plugin/template/platform/tree_render/package.json index 526db31..7bcf063 100644 --- a/packages/core/src/create-plugin/template/platform/tree_render/package.json +++ b/packages/core/src/create-plugin/template/platform/tree_render/package.json @@ -2,7 +2,7 @@ "name": "{{pluginGroup}}/{{pluginName}}", "version": "0.0.1", "description": "{{pluginDescription}}", - "author": "tony001", + "author": "iBiz", "license": "MIT", "type": "module", "main": "dist/index.es.js", diff --git a/packages/core/src/create-plugin/template/platform/uilogicnode/package.json b/packages/core/src/create-plugin/template/platform/uilogicnode/package.json index 526db31..7bcf063 100644 --- a/packages/core/src/create-plugin/template/platform/uilogicnode/package.json +++ b/packages/core/src/create-plugin/template/platform/uilogicnode/package.json @@ -2,7 +2,7 @@ "name": "{{pluginGroup}}/{{pluginName}}", "version": "0.0.1", "description": "{{pluginDescription}}", - "author": "tony001", + "author": "iBiz", "license": "MIT", "type": "module", "main": "dist/index.es.js", diff --git a/packages/core/src/create-plugin/template/platform/view_custom/.eslintrc.cjs b/packages/core/src/create-plugin/template/platform/view_custom/.eslintrc.cjs new file mode 100644 index 0000000..c6e5a1d --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/view_custom/.eslintrc.cjs @@ -0,0 +1,52 @@ +module.exports = { + root: true, + env: { + browser: true, + es2021: true, + }, + extends: ['airbnb-base', 'prettier', 'plugin:@typescript-eslint/recommended'], + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + }, + plugins: ['prettier', '@typescript-eslint', 'unused-imports'], + rules: { + 'prettier/prettier': 'error', + 'arrow-body-style': 'off', + 'prefer-arrow-callback': 'off', + 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', + 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', + 'no-new': [0], + 'no-continue': [0], + '@typescript-eslint/no-empty-interface': 'off', + 'no-use-before-define': [0], + 'no-restricted-syntax': [0], + 'no-empty-function': [0], + 'no-useless-constructor': [0], // 禁止空的构造函数 + 'no-param-reassign': [0], // 禁止修改传入函数的参数 + 'no-underscore-dangle': [0], // 禁止使用下划线开头的变量名 + 'no-plusplus': ['error', { allowForLoopAfterthoughts: true }], // 禁止使用 ++,-- + 'consistent-return': [0], // 函数可以有不同类型返回值 + 'class-methods-use-this': [0], // 方法内未使用此方法时,强制定义为静态方法 + 'import/prefer-default-export': [0], // 一个模块只能有默认导出,不可以有多个导出 + 'import/no-unresolved': [0], // 不允许未解决的模块 + 'import/extensions': [0], // 不允许导入文件时不带后缀 + 'unused-imports/no-unused-imports': 'error', + '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }], + '@typescript-eslint/no-inferrable-types': [0], + '@typescript-eslint/no-non-null-assertion': [0], + '@typescript-eslint/no-explicit-any': ['error'], + '@typescript-eslint/explicit-function-return-type': 'error', // 要求函数和类方法的显式返回类型 + '@typescript-eslint/explicit-module-boundary-types': 'error', // 要求导出函数和类的公共类方法的显式返回和参数类型 + 'import/no-extraneous-dependencies': [ + 0, + { + devDependencies: true, + peerDependencies: true, + // optionalDependencies: true, + // bundledDependencies: true + }, + ], + }, +}; diff --git a/packages/core/src/create-plugin/template/platform/view_custom/CHANGELOG.md b/packages/core/src/create-plugin/template/platform/view_custom/CHANGELOG.md new file mode 100644 index 0000000..8ac8e7f --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/view_custom/CHANGELOG.md @@ -0,0 +1,3 @@ +# 版本变更日志 + +添加变更日志 \ No newline at end of file diff --git a/packages/core/src/create-plugin/template/platform/view_custom/README.md b/packages/core/src/create-plugin/template/platform/view_custom/README.md new file mode 100644 index 0000000..dce9c6e --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/view_custom/README.md @@ -0,0 +1,130 @@ +# 视图插件 + +视图插件可自定义视图内容的绘制,当标准逻辑无法满足视图绘制要求时,可以通过视图插件来实现。modeling建模平台创建视图插件可参见 [插件开发](https://open.ibizlab.cn/apphub/zh/guide/plugin-dev.html) + +## 插件结构 + +``` +|─ ─ {{pluginName}} 视图插件顶层目录 + |─ ─ src 视图插件源代码目录 +​ |─ ─ {{pluginName}}.controller.ts 视图插件控制器 +​ |─ ─ {{pluginName}}.engine.ts 视图插件引擎 +​ |─ ─ {{pluginName}}.provider.ts 视图插件适配器 +​ |─ ─ {{pluginName}}.scss 视图插件样式 +​ |─ ─ {{pluginName}}.tsx 视图插件组件 +​ |─ ─ index.ts 视图插件入口文件 +``` + +- 视图插件入口文件 + +视图插件入口文件会全局注册视图插件适配器和视图插件组件,供外部使用。 + +- 视图插件组件 + +视图插件组件使用tsx的书写方式,承载视图绘制的内容,可拷贝基础UI绘制,然后根据需求进行调整。其中,基础UI绘制可参考附录中UI呈现部分。 + +- 视图插件适配器 + +视图插件适配器主要通过component属性指定视图实际要绘制的组件,并且通过createController方法返回传递给视图的控制器。 + +- 视图插件控制器 + +视图插件控制器承载视图的逻辑控制,可继承基础控制器,然后根据需求进行调整。其中,基础控制器可参考附录中控制器部分。 + +- 视图插件引擎 + +视图插件引擎承载视图的界面驱动逻辑控制,可继承基础引擎,然后根据需求进行调整。其中,基础引擎可参考附录中引擎部分。 + +## 本地开发 + +1. 安装依赖并link至全局 + +```sh +// 安装依赖 +pnpm i + +// link底包 +./scripts/link.sh + +// 启动 +pnpm dev + +// link到全局 +pnpm link --global +``` + +2. 主项目包中引用插件 + +```sh +// link插件 +pnpm link --global '{{pluginGroup}}/{{pluginName}}' +``` + +3. 主项目包中注册插件 + +```ts +import { App } from 'vue'; +import {{ pascalCasePluginName }} from '{{pluginGroup}}/{{pluginName}}' + +export default { + install(app: App) { + app.use({{ pascalCasePluginName }}); + // 设置本地开发需要忽略加载的插件,可填写正则或全匹配字符串。匹配插件在modeling建模平台配置的[运行时插件仓库配置]内容 + ibiz.plugin.setDevIgnore(/^{{pluginGroup}}\/{{pluginName}}/); + }, +}; +``` + +## 附录 + +| 视图类型 | UI呈现 | 控制器 | 引擎 | +| :----------------------------: | :-----------: | :-------------------------: | :----------------------: | +| 应用数据导入视图 | View | AppDataUploadViewController | AppDataUploadViewEngine | +| 日历导航视图 | View | ViewController | CalendarExpViewEngine | +| 日历视图 | View | ViewController | CalendarViewEngine | +| 图表导航视图 | View | ViewController | ChartExpViewEngine | +| 图表视图 | View | ViewController | ChartViewEngine | +| 自定义视图 | View | ViewController | CustomViewEngine | +| 卡片导航视图 | View | ViewController | DataViewExpViewEngine | +| 卡片视图 | View | ViewController | DataViewEngine | +| 实体首页视图 | View | ViewController | DEIndexViewEngine | +| 编辑视图 | View | ViewController | EditViewEngine | +| 编辑视图2(左右关系) | View | ViewController | EditView2Engine | +| 编辑视图3(分页关系) | View | ViewController | EditView3Engine | +| 编辑视图4(上下关系) | View | ViewController | EditView4Engine | +| 表单选择数据视图 | View | ViewController | FormPickupDataViewEngine | +| 甘特图视图 | View | ViewController | GanttViewEngine | +| 表格导航视图 | View | ViewController | GridExpViewEngine | +| 表格视图 | View | ViewController | GridViewEngine | +| 首页视图 | View | ViewController | IndexViewEngine | +| 看板视图 | View | ViewController | KanbanViewEngine | +| 列表导航视图 | View | ViewController | ListExpViewEngine | +| 列表视图 | View | ViewController | ListViewEngine | +| 登录视图 | View | ViewController | LoginViewEngine | +| 地图视图 | View | ViewController | MapViewEngine | +| 多数据自定义视图 | View | ViewController | MDCustomViewEngine | +| 多表单编辑视图 | View | ViewController | MEditView9Engine | +| 多数据选择视图 | View | ViewController | MPickupViewEngine | +| 多数据选择视图(左右关系) | View | ViewController | MPickupView2Engine | +| 选项操作视图 | View | ViewController | OptViewEngine | +| 面板视图 | View | ViewController | PanelViewEngine | +| 选择数据视图 | View | ViewController | PickupDataViewEngine | +| 选择表格视图 | View | ViewController | PickupGridViewEngine | +| 选择树视图 | View | ViewController | PickupTreeViewEngine | +| 数据选择视图 | View | ViewController | PickupViewEngine | +| 数据选择视图(左右关系) | View | ViewController | PickupView2Engine | +| 数据看板视图 | PortalView | ViewController | PortalViewEngine | +| 报表视图 | View | ViewController | ReportViewEngine | +| 子系统引用视图 | SubAppRefView | ViewController | SubAppRefViewEngine | +| 分页导航视图 | View | ViewController | TabExpViewEngine | +| 分页搜索视图 | View | ViewController | TabSearchViewEngine | +| 树导航视图 | View | ViewController | TreeExpViewEngine | +| 树表格视图(增强) | View | ViewController | TreeGridExViewEngine | +| 树表格视图 | View | ViewController | TreeGridViewEngine | +| 树视图 | View | ViewController | TreeViewEngine | +| 工作流动态操作视图 | View | ViewController | WFDynaActionViewEngine | +| 工作流动态编辑视图 | View | ViewController | WFDynaEditViewEngine | +| 工作流动态编辑视图(分页关系) | View | ViewController | WFDynaEditView3Engine | +| 工作流动态启动视图 | View | ViewController | WFDynaStartViewEngine | +| 应用流程处理记录视图 | View | ViewController | WFStepDataViewEngine | +| 向导视图 | View | ViewController | WizardViewEngine | diff --git a/packages/core/src/create-plugin/template/platform/view_custom/package.json b/packages/core/src/create-plugin/template/platform/view_custom/package.json new file mode 100644 index 0000000..7bcf063 --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/view_custom/package.json @@ -0,0 +1,106 @@ +{ + "name": "{{pluginGroup}}/{{pluginName}}", + "version": "0.0.1", + "description": "{{pluginDescription}}", + "author": "iBiz", + "license": "MIT", + "type": "module", + "main": "dist/index.es.js", + "module": "dist/index.es.js", + "types": "dist/types/index.d.ts", + "system": "dist/index.legacy.js", + "styles": [ + "dist/style.css" + ], + "files": [ + "dist", + "public", + "CHANGELOG.md", + "README.md" + ], + "publishConfig": { + "registry": "https://registry.npmjs.org/" + }, + "scripts": { + "dev": "vite build --watch", + "build": "vue-tsc --noEmit && vite build", + "preview": "vite preview" + }, + "devDependencies": { + "@floating-ui/dom": "^1.5.3", + "@ibiz-template/core": "^0.7.40-alpha.7", + "@ibiz-template/model-helper": "^0.7.40-alpha.8", + "@ibiz-template/runtime": "^0.7.40-alpha.8", + "@ibiz-template/theme": "^0.7.39", + "@ibiz-template/vue3-util": "^0.7.40-alpha.8", + "@ibiz/model-core": "^0.1.72", + "@qx-chitanda/vite-plugin-lib-legacy": "^4.1.1", + "@types/lodash-es": "^4.17.12", + "@types/ramda": "^0.29.6", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "@typescript-eslint/parser": "^6.11.0", + "@vitejs/plugin-vue": "^4.4.1", + "@vitejs/plugin-vue-jsx": "^3.0.2", + "async-validator": "^4.2.5", + "axios": "^1.6.2", + "dayjs": "^1.11.10", + "element-plus": "^2.4.2", + "eslint": "^8.53.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-prettier": "^9.0.0", + "eslint-plugin-import": "^2.29.0", + "eslint-plugin-prettier": "^5.0.1", + "eslint-plugin-unused-imports": "^3.0.0", + "eslint-plugin-vue": "^9.18.1", + "husky": "^8.0.3", + "lerna": "^8.0.0", + "lint-staged": "^15.1.0", + "lodash-es": "^4.17.21", + "pluralize": "^8.0.0", + "postcss": "^8.4.31", + "prettier": "^3.1.0", + "qs": "^6.11.2", + "qx-util": "^0.4.8", + "ramda": "^0.29.1", + "rollup-plugin-visualizer": "^5.9.2", + "sass": "1.69.5", + "stylelint": "15.11.0", + "stylelint-config-prettier": "^9.0.5", + "stylelint-config-recess-order": "^4.3.0", + "stylelint-config-standard": "^34.0.0", + "stylelint-config-standard-scss": "^11.1.0", + "stylelint-scss": "5.3.1", + "terser": "^5.24.0", + "typescript": "5.2.2", + "vite": "^4.5.0", + "vite-plugin-dts": "^3.6.3", + "vite-plugin-eslint": "^1.8.1", + "vite-plugin-libcss": "^1.1.1", + "vue": "^3.3.8", + "vue-eslint-parser": "^9.3.2", + "vue-router": "^4.2.5", + "vue-tsc": "1.8.22", + "vuedraggable": "^4.1.0" + }, + "peerDependencies": { + "@floating-ui/dom": "^1.5.1", + "@ibiz-template/core": "^0.7.40-alpha.7", + "@ibiz-template/model-helper": "^0.7.40-alpha.8", + "@ibiz-template/runtime": "^0.7.40-alpha.8", + "@ibiz-template/theme": "^0.7.39", + "@ibiz-template/vue3-util": "^0.7.40-alpha.8", + "@ibiz/model-core": "^0.1.72", + "async-validator": "^4.2.5", + "axios": "^1.6.2", + "dayjs": "^1.11.10", + "element-plus": "^2.4.2", + "lodash-es": "^4.17.21", + "pluralize": "^8.0.0", + "qs": "^6.11.2", + "qx-util": "^0.4.8", + "ramda": "^0.29.1", + "vue": "^3.3.8", + "vue-router": "^4.2.5", + "vuedraggable": "^4.1.0" + } +} diff --git a/packages/core/src/create-plugin/template/platform/view_custom/scripts/link.sh b/packages/core/src/create-plugin/template/platform/view_custom/scripts/link.sh new file mode 100755 index 0000000..d4edc15 --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/view_custom/scripts/link.sh @@ -0,0 +1,6 @@ +pnpm link --global "@ibiz-template/vue3-util" +pnpm link --global "@ibiz-template/model-helper" +pnpm link --global "@ibiz-template/runtime" +pnpm link --global "@ibiz-template/core" +pnpm link --global "@ibiz-template/theme" +pnpm link --global "@ibiz-template/vue3-components" diff --git a/packages/core/src/create-plugin/template/platform/view_custom/src/index.ts b/packages/core/src/create-plugin/template/platform/view_custom/src/index.ts new file mode 100644 index 0000000..84829da --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/view_custom/src/index.ts @@ -0,0 +1,16 @@ +import { App } from 'vue'; +import { registerViewProvider } from '@ibiz-template/runtime'; +import { {{ pascalCasePluginName }} } from './{{pluginName}}'; +import { {{ pascalCasePluginName }}Provider } from './{{pluginName}}.provider'; + +export default { + install(app: App) { + // 全局注册视图插件组件 + app.component({{ pascalCasePluginName }}.name!, {{ pascalCasePluginName }}); + // 全局注册视图插件适配器,VIEW_CUSTOM是插件类型,{{pluginId}}是插件标识 + registerViewProvider( + 'VIEW_CUSTOM_{{pluginId}}', + () => new {{ pascalCasePluginName }}Provider(), + ); + }, +}; diff --git a/packages/core/src/create-plugin/template/platform/view_custom/src/{{pluginName}}.controller.ts b/packages/core/src/create-plugin/template/platform/view_custom/src/{{pluginName}}.controller.ts new file mode 100644 index 0000000..685fb13 --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/view_custom/src/{{pluginName}}.controller.ts @@ -0,0 +1,8 @@ +import { ViewController } from '@ibiz-template/runtime'; +import { {{ pascalCasePluginName }}Engine } from './{{pluginName}}.engine'; + +export class {{ pascalCasePluginName }}Controller extends ViewController { + protected initEngines(): void { + this.engines.push(new {{ pascalCasePluginName }}Engine(this)); + } +} diff --git a/packages/core/src/create-plugin/template/platform/view_custom/src/{{pluginName}}.engine.ts b/packages/core/src/create-plugin/template/platform/view_custom/src/{{pluginName}}.engine.ts new file mode 100644 index 0000000..072185f --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/view_custom/src/{{pluginName}}.engine.ts @@ -0,0 +1,3 @@ +import { ViewEngineBase } from '@ibiz-template/runtime'; + +export class {{ pascalCasePluginName }}Engine extends ViewEngineBase {} diff --git a/packages/core/src/create-plugin/template/platform/view_custom/src/{{pluginName}}.provider.ts b/packages/core/src/create-plugin/template/platform/view_custom/src/{{pluginName}}.provider.ts new file mode 100644 index 0000000..7613863 --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/view_custom/src/{{pluginName}}.provider.ts @@ -0,0 +1,16 @@ +import { CTX, IViewController, IViewProvider } from '@ibiz-template/runtime'; +import { IAppView } from '@ibiz/model-core'; +import { {{ pascalCasePluginName }}Controller } from './{{pluginName}}.controller'; + +export class {{ pascalCasePluginName }}Provider implements IViewProvider { + component: string = 'IBiz{{ pascalCasePluginName }}'; + + createController( + model: IAppView, + context: IContext, + params?: IParams, + ctx?: CTX, + ): IViewController { + return new {{ pascalCasePluginName }}Controller(model, context, params, ctx); + } +} diff --git a/packages/core/src/create-plugin/template/platform/view_custom/src/{{pluginName}}.scss b/packages/core/src/create-plugin/template/platform/view_custom/src/{{pluginName}}.scss new file mode 100644 index 0000000..f494ab6 --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/view_custom/src/{{pluginName}}.scss @@ -0,0 +1,3 @@ +@include b({{pluginName}}){ + // 样式 +} \ No newline at end of file diff --git a/packages/core/src/create-plugin/template/platform/view_custom/src/{{pluginName}}.tsx b/packages/core/src/create-plugin/template/platform/view_custom/src/{{pluginName}}.tsx new file mode 100644 index 0000000..960749f --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/view_custom/src/{{pluginName}}.tsx @@ -0,0 +1,49 @@ +import { PropType, defineComponent } from 'vue'; +import { IModal, IViewProvider } from '@ibiz-template/runtime'; +import { useNamespace, useViewController } from '@ibiz-template/vue3-util'; +import { IAppView } from '@ibiz/model-core'; +import { {{ pascalCasePluginName }}Controller } from './{{pluginName}}.controller'; +import './{{pluginName}}.scss'; + +export const {{ pascalCasePluginName }} = defineComponent({ + name: 'IBiz{{ pascalCasePluginName }}', + props: { + /** + * @description 应用上下文 + */ + context: { type: Object as PropType }, + /** + * @description 视图参数 + * @default {} + */ + params: { type: Object as PropType, default: () => ({}) }, + /** + * @description 视图模型 + */ + modelData: { type: Object as PropType, required: true }, + /** + * @description 视图模态操作对象,在模态等形式打开视图时,需给视图注入此对象 + */ + modal: { type: Object as PropType }, + /** + * @description 视图状态 + */ + state: { type: Object as PropType }, + /** + * @description 视图适配器 + */ + provider: { type: Object as PropType }, + }, + setup() { + const c = useViewController((...args) => new {{ pascalCasePluginName }}Controller(...args)); + const ns = useNamespace('{{pluginName}}'); + + return { + c, + ns, + }; + }, + render() { + return
插件示例
; + }, +}); diff --git a/packages/core/src/create-plugin/template/platform/view_custom/tsconfig.json b/packages/core/src/create-plugin/template/platform/view_custom/tsconfig.json new file mode 100644 index 0000000..ba8f48b --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/view_custom/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "moduleResolution": "Node", + "strict": true, + "jsx": "preserve", + "jsxImportSource": "vue", + "sourceMap": true, + "resolveJsonModule": true, + "isolatedModules": true, + "esModuleInterop": true, + "lib": ["ESNext", "DOM"], + "skipLibCheck": true + }, + "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/packages/core/src/create-plugin/template/platform/view_custom/tsconfig.node.json b/packages/core/src/create-plugin/template/platform/view_custom/tsconfig.node.json new file mode 100644 index 0000000..9d31e2a --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/view_custom/tsconfig.node.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "composite": true, + "module": "ESNext", + "moduleResolution": "Node", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/packages/core/src/create-plugin/template/platform/view_custom/vite.config.ts b/packages/core/src/create-plugin/template/platform/view_custom/vite.config.ts new file mode 100644 index 0000000..fc3449a --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/view_custom/vite.config.ts @@ -0,0 +1,57 @@ +import { defineConfig } from 'vite'; +import vue from '@vitejs/plugin-vue'; +import vueJsx from '@vitejs/plugin-vue-jsx'; +import libLegacy from '@qx-chitanda/vite-plugin-lib-legacy'; +import dts from 'vite-plugin-dts'; +import libCss from 'vite-plugin-libcss'; +// https://vitejs.dev/config/ +export default defineConfig({ + build: { + lib: { + entry: './src/index.ts', + fileName: format => `index.${format}.js`, + }, + rollupOptions: { + external: [ + '@ibiz-template/core', + '@ibiz-template/model-helper', + '@ibiz-template/runtime', + '@ibiz-template/theme', + '@ibiz-template/vue3-util', + '@ibiz/dynamic-model-api', + '@floating-ui/dom', + 'async-validator', + 'axios', + 'dayjs', + 'element-plus', + 'lodash-es', + 'pluralize', + 'qs', + 'qx-util', + 'ramda', + 'vue', + 'vue-router', + 'vuedraggable', + ], + }, + }, + css: { + preprocessorOptions: { + scss: { + additionalData: '@import "@ibiz-template/theme/style/global.scss";', + }, + }, + }, + plugins: [ + // eslint({ + // include: 'src/**/*.{ts,tsx,js,jsx}', + // }), + vue(), + vueJsx(), + libLegacy(), + libCss(), + dts({ + outDir: 'dist/types', + }), + ], +}); diff --git a/packages/core/src/create-plugin/template/platform/wizardpanel_render/.eslintrc.cjs b/packages/core/src/create-plugin/template/platform/wizardpanel_render/.eslintrc.cjs new file mode 100644 index 0000000..c6e5a1d --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/wizardpanel_render/.eslintrc.cjs @@ -0,0 +1,52 @@ +module.exports = { + root: true, + env: { + browser: true, + es2021: true, + }, + extends: ['airbnb-base', 'prettier', 'plugin:@typescript-eslint/recommended'], + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + }, + plugins: ['prettier', '@typescript-eslint', 'unused-imports'], + rules: { + 'prettier/prettier': 'error', + 'arrow-body-style': 'off', + 'prefer-arrow-callback': 'off', + 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', + 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', + 'no-new': [0], + 'no-continue': [0], + '@typescript-eslint/no-empty-interface': 'off', + 'no-use-before-define': [0], + 'no-restricted-syntax': [0], + 'no-empty-function': [0], + 'no-useless-constructor': [0], // 禁止空的构造函数 + 'no-param-reassign': [0], // 禁止修改传入函数的参数 + 'no-underscore-dangle': [0], // 禁止使用下划线开头的变量名 + 'no-plusplus': ['error', { allowForLoopAfterthoughts: true }], // 禁止使用 ++,-- + 'consistent-return': [0], // 函数可以有不同类型返回值 + 'class-methods-use-this': [0], // 方法内未使用此方法时,强制定义为静态方法 + 'import/prefer-default-export': [0], // 一个模块只能有默认导出,不可以有多个导出 + 'import/no-unresolved': [0], // 不允许未解决的模块 + 'import/extensions': [0], // 不允许导入文件时不带后缀 + 'unused-imports/no-unused-imports': 'error', + '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }], + '@typescript-eslint/no-inferrable-types': [0], + '@typescript-eslint/no-non-null-assertion': [0], + '@typescript-eslint/no-explicit-any': ['error'], + '@typescript-eslint/explicit-function-return-type': 'error', // 要求函数和类方法的显式返回类型 + '@typescript-eslint/explicit-module-boundary-types': 'error', // 要求导出函数和类的公共类方法的显式返回和参数类型 + 'import/no-extraneous-dependencies': [ + 0, + { + devDependencies: true, + peerDependencies: true, + // optionalDependencies: true, + // bundledDependencies: true + }, + ], + }, +}; diff --git a/packages/core/src/create-plugin/template/platform/wizardpanel_render/CHANGELOG.md b/packages/core/src/create-plugin/template/platform/wizardpanel_render/CHANGELOG.md new file mode 100644 index 0000000..8ac8e7f --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/wizardpanel_render/CHANGELOG.md @@ -0,0 +1,3 @@ +# 版本变更日志 + +添加变更日志 \ No newline at end of file diff --git a/packages/core/src/create-plugin/template/platform/wizardpanel_render/README.md b/packages/core/src/create-plugin/template/platform/wizardpanel_render/README.md new file mode 100644 index 0000000..c8d5791 --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/wizardpanel_render/README.md @@ -0,0 +1,71 @@ +# 向导面板插件 + +向导面板插件可自定义向导面板内容的绘制,当标准逻辑无法满足向导面板绘制要求时,可以通过向导面板插件来实现。modeling建模平台创建向导面板插件可参见 [插件开发](https://open.ibizlab.cn/apphub/zh/guide/plugin-dev.html) + +## 插件结构 + +``` +|─ ─ {{pluginName}} 向导面板插件顶层目录 + |─ ─ src 向导面板插件源代码目录 +​ |─ ─ {{pluginName}}.controller.ts 向导面板插件控制器 +​ |─ ─ {{pluginName}}.provider.ts 向导面板插件适配器 +​ |─ ─ {{pluginName}}.scss 向导面板插件样式 +​ |─ ─ {{pluginName}}.tsx 向导面板插件组件 +​ |─ ─ index.ts 向导面板插件入口文件 +``` + +- 向导面板插件入口文件 + +向导面板插件入口文件会全局注册向导面板插件适配器和向导面板插件组件,供外部使用。 + +- 向导面板插件组件 + +向导面板插件组件使用tsx的书写方式,承载向导面板绘制的内容。 + +- 向导面板插件适配器 + +向导面板插件适配器主要通过component属性指定向导面板实际要绘制的组件,并且通过createController方法返回传递给向导面板的控制器。 + +- 向导面板插件控制器 + +向导面板插件控制器承载向导面板的逻辑控制。 + +## 本地开发 + +1. 安装依赖并link至全局 + +```sh +// 安装依赖 +pnpm i + +// link底包 +./scripts/link.sh + +// 启动 +pnpm dev + +// link到全局 +pnpm link --global +``` + +2. 主项目包中引用插件 + +```sh +// link插件 +pnpm link --global '{{pluginGroup}}/{{pluginName}}' +``` + +3. 主项目包中注册插件 + +```ts +import { App } from 'vue'; +import {{ pascalCasePluginName }} from '{{pluginGroup}}/{{pluginName}}' + +export default { + install(app: App) { + app.use({{ pascalCasePluginName }}); + // 设置本地开发需要忽略加载的插件,可填写正则或全匹配字符串。匹配插件在modeling建模平台配置的[运行时插件仓库配置]内容 + ibiz.plugin.setDevIgnore(/^{{pluginGroup}}\/{{pluginName}}/); + }, +}; +``` diff --git a/packages/core/src/create-plugin/template/platform/wizardpanel_render/package.json b/packages/core/src/create-plugin/template/platform/wizardpanel_render/package.json new file mode 100644 index 0000000..7bcf063 --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/wizardpanel_render/package.json @@ -0,0 +1,106 @@ +{ + "name": "{{pluginGroup}}/{{pluginName}}", + "version": "0.0.1", + "description": "{{pluginDescription}}", + "author": "iBiz", + "license": "MIT", + "type": "module", + "main": "dist/index.es.js", + "module": "dist/index.es.js", + "types": "dist/types/index.d.ts", + "system": "dist/index.legacy.js", + "styles": [ + "dist/style.css" + ], + "files": [ + "dist", + "public", + "CHANGELOG.md", + "README.md" + ], + "publishConfig": { + "registry": "https://registry.npmjs.org/" + }, + "scripts": { + "dev": "vite build --watch", + "build": "vue-tsc --noEmit && vite build", + "preview": "vite preview" + }, + "devDependencies": { + "@floating-ui/dom": "^1.5.3", + "@ibiz-template/core": "^0.7.40-alpha.7", + "@ibiz-template/model-helper": "^0.7.40-alpha.8", + "@ibiz-template/runtime": "^0.7.40-alpha.8", + "@ibiz-template/theme": "^0.7.39", + "@ibiz-template/vue3-util": "^0.7.40-alpha.8", + "@ibiz/model-core": "^0.1.72", + "@qx-chitanda/vite-plugin-lib-legacy": "^4.1.1", + "@types/lodash-es": "^4.17.12", + "@types/ramda": "^0.29.6", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "@typescript-eslint/parser": "^6.11.0", + "@vitejs/plugin-vue": "^4.4.1", + "@vitejs/plugin-vue-jsx": "^3.0.2", + "async-validator": "^4.2.5", + "axios": "^1.6.2", + "dayjs": "^1.11.10", + "element-plus": "^2.4.2", + "eslint": "^8.53.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-prettier": "^9.0.0", + "eslint-plugin-import": "^2.29.0", + "eslint-plugin-prettier": "^5.0.1", + "eslint-plugin-unused-imports": "^3.0.0", + "eslint-plugin-vue": "^9.18.1", + "husky": "^8.0.3", + "lerna": "^8.0.0", + "lint-staged": "^15.1.0", + "lodash-es": "^4.17.21", + "pluralize": "^8.0.0", + "postcss": "^8.4.31", + "prettier": "^3.1.0", + "qs": "^6.11.2", + "qx-util": "^0.4.8", + "ramda": "^0.29.1", + "rollup-plugin-visualizer": "^5.9.2", + "sass": "1.69.5", + "stylelint": "15.11.0", + "stylelint-config-prettier": "^9.0.5", + "stylelint-config-recess-order": "^4.3.0", + "stylelint-config-standard": "^34.0.0", + "stylelint-config-standard-scss": "^11.1.0", + "stylelint-scss": "5.3.1", + "terser": "^5.24.0", + "typescript": "5.2.2", + "vite": "^4.5.0", + "vite-plugin-dts": "^3.6.3", + "vite-plugin-eslint": "^1.8.1", + "vite-plugin-libcss": "^1.1.1", + "vue": "^3.3.8", + "vue-eslint-parser": "^9.3.2", + "vue-router": "^4.2.5", + "vue-tsc": "1.8.22", + "vuedraggable": "^4.1.0" + }, + "peerDependencies": { + "@floating-ui/dom": "^1.5.1", + "@ibiz-template/core": "^0.7.40-alpha.7", + "@ibiz-template/model-helper": "^0.7.40-alpha.8", + "@ibiz-template/runtime": "^0.7.40-alpha.8", + "@ibiz-template/theme": "^0.7.39", + "@ibiz-template/vue3-util": "^0.7.40-alpha.8", + "@ibiz/model-core": "^0.1.72", + "async-validator": "^4.2.5", + "axios": "^1.6.2", + "dayjs": "^1.11.10", + "element-plus": "^2.4.2", + "lodash-es": "^4.17.21", + "pluralize": "^8.0.0", + "qs": "^6.11.2", + "qx-util": "^0.4.8", + "ramda": "^0.29.1", + "vue": "^3.3.8", + "vue-router": "^4.2.5", + "vuedraggable": "^4.1.0" + } +} diff --git a/packages/core/src/create-plugin/template/platform/wizardpanel_render/scripts/link.sh b/packages/core/src/create-plugin/template/platform/wizardpanel_render/scripts/link.sh new file mode 100755 index 0000000..d4edc15 --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/wizardpanel_render/scripts/link.sh @@ -0,0 +1,6 @@ +pnpm link --global "@ibiz-template/vue3-util" +pnpm link --global "@ibiz-template/model-helper" +pnpm link --global "@ibiz-template/runtime" +pnpm link --global "@ibiz-template/core" +pnpm link --global "@ibiz-template/theme" +pnpm link --global "@ibiz-template/vue3-components" diff --git a/packages/core/src/create-plugin/template/platform/wizardpanel_render/src/index.ts b/packages/core/src/create-plugin/template/platform/wizardpanel_render/src/index.ts new file mode 100644 index 0000000..3b849f2 --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/wizardpanel_render/src/index.ts @@ -0,0 +1,16 @@ +import { App } from 'vue'; +import { registerControlProvider } from '@ibiz-template/runtime'; +import { {{ pascalCasePluginName }} } from './{{pluginName}}'; +import { {{ pascalCasePluginName }}Provider } from './{{pluginName}}.provider'; + +export default { + install(app: App) { + // 全局注册向导面板插件组件 + app.component({{ pascalCasePluginName }}.name!, {{ pascalCasePluginName }}); + // 全局注册向导面板插件适配器,WIZARDPANEL_RENDER是插件类型,{{pluginId}}是插件标识 + registerControlProvider( + 'WIZARDPANEL_RENDER_{{pluginId}}', + () => new {{ pascalCasePluginName }}Provider(), + ); + }, +}; diff --git a/packages/core/src/create-plugin/template/platform/wizardpanel_render/src/{{pluginName}}.controller.ts b/packages/core/src/create-plugin/template/platform/wizardpanel_render/src/{{pluginName}}.controller.ts new file mode 100644 index 0000000..55779eb --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/wizardpanel_render/src/{{pluginName}}.controller.ts @@ -0,0 +1,3 @@ +import { WizardPanelController } from '@ibiz-template/runtime'; + +export class {{ pascalCasePluginName }}Controller extends WizardPanelController {} diff --git a/packages/core/src/create-plugin/template/platform/wizardpanel_render/src/{{pluginName}}.provider.ts b/packages/core/src/create-plugin/template/platform/wizardpanel_render/src/{{pluginName}}.provider.ts new file mode 100644 index 0000000..9a32e3f --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/wizardpanel_render/src/{{pluginName}}.provider.ts @@ -0,0 +1,20 @@ +import { + CTX, + IControlController, + IControlProvider, +} from '@ibiz-template/runtime'; +import { IControl } from '@ibiz/model-core'; +import { {{ pascalCasePluginName }}Controller } from './{{pluginName}}.controller'; + +export class {{ pascalCasePluginName }}Provider implements IControlProvider { + component: string = 'IBiz{{ pascalCasePluginName }}'; + + createController( + model: IControl, + context: IContext, + params: IParams, + ctx: CTX, + ): IControlController { + return new {{ pascalCasePluginName }}Controller(model, context, params, ctx); + } +} diff --git a/packages/core/src/create-plugin/template/platform/wizardpanel_render/src/{{pluginName}}.scss b/packages/core/src/create-plugin/template/platform/wizardpanel_render/src/{{pluginName}}.scss new file mode 100644 index 0000000..f494ab6 --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/wizardpanel_render/src/{{pluginName}}.scss @@ -0,0 +1,3 @@ +@include b({{pluginName}}){ + // 样式 +} \ No newline at end of file diff --git a/packages/core/src/create-plugin/template/platform/wizardpanel_render/src/{{pluginName}}.tsx b/packages/core/src/create-plugin/template/platform/wizardpanel_render/src/{{pluginName}}.tsx new file mode 100644 index 0000000..50925c5 --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/wizardpanel_render/src/{{pluginName}}.tsx @@ -0,0 +1,46 @@ +import { defineComponent, PropType } from 'vue'; +import { useControlController, useNamespace } from '@ibiz-template/vue3-util'; +import { IDEWizardPanel } from '@ibiz/model-core'; +import { IControlProvider } from '@ibiz-template/runtime'; +import { {{ pascalCasePluginName }}Controller } from './{{pluginName}}.controller'; +import './{{pluginName}}.scss'; + +export const {{ pascalCasePluginName }} = defineComponent({ + name: 'IBiz{{ pascalCasePluginName }}', + props: { + /** + * @description 向导面板模型数据 + */ + modelData: { + type: Object as PropType, + required: true, + }, + /** + * @description 应用上下文对象 + */ + context: { type: Object as PropType, required: true }, + /** + * @description 视图参数对象 + * @default {} + */ + params: { type: Object as PropType, default: () => ({}) }, + /** + * @description 部件适配器 + */ + provider: { type: Object as PropType }, + }, + setup() { + const c = useControlController( + (...args) => new {{ pascalCasePluginName }}Controller(...args), + ); + const ns = useNamespace('{{pluginName}}'); + + return { + c, + ns, + }; + }, + render() { + return
插件示例
; + }, +}); diff --git a/packages/core/src/create-plugin/template/platform/wizardpanel_render/tsconfig.json b/packages/core/src/create-plugin/template/platform/wizardpanel_render/tsconfig.json new file mode 100644 index 0000000..ba8f48b --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/wizardpanel_render/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "moduleResolution": "Node", + "strict": true, + "jsx": "preserve", + "jsxImportSource": "vue", + "sourceMap": true, + "resolveJsonModule": true, + "isolatedModules": true, + "esModuleInterop": true, + "lib": ["ESNext", "DOM"], + "skipLibCheck": true + }, + "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/packages/core/src/create-plugin/template/platform/wizardpanel_render/tsconfig.node.json b/packages/core/src/create-plugin/template/platform/wizardpanel_render/tsconfig.node.json new file mode 100644 index 0000000..9d31e2a --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/wizardpanel_render/tsconfig.node.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "composite": true, + "module": "ESNext", + "moduleResolution": "Node", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/packages/core/src/create-plugin/template/platform/wizardpanel_render/vite.config.ts b/packages/core/src/create-plugin/template/platform/wizardpanel_render/vite.config.ts new file mode 100644 index 0000000..fc3449a --- /dev/null +++ b/packages/core/src/create-plugin/template/platform/wizardpanel_render/vite.config.ts @@ -0,0 +1,57 @@ +import { defineConfig } from 'vite'; +import vue from '@vitejs/plugin-vue'; +import vueJsx from '@vitejs/plugin-vue-jsx'; +import libLegacy from '@qx-chitanda/vite-plugin-lib-legacy'; +import dts from 'vite-plugin-dts'; +import libCss from 'vite-plugin-libcss'; +// https://vitejs.dev/config/ +export default defineConfig({ + build: { + lib: { + entry: './src/index.ts', + fileName: format => `index.${format}.js`, + }, + rollupOptions: { + external: [ + '@ibiz-template/core', + '@ibiz-template/model-helper', + '@ibiz-template/runtime', + '@ibiz-template/theme', + '@ibiz-template/vue3-util', + '@ibiz/dynamic-model-api', + '@floating-ui/dom', + 'async-validator', + 'axios', + 'dayjs', + 'element-plus', + 'lodash-es', + 'pluralize', + 'qs', + 'qx-util', + 'ramda', + 'vue', + 'vue-router', + 'vuedraggable', + ], + }, + }, + css: { + preprocessorOptions: { + scss: { + additionalData: '@import "@ibiz-template/theme/style/global.scss";', + }, + }, + }, + plugins: [ + // eslint({ + // include: 'src/**/*.{ts,tsx,js,jsx}', + // }), + vue(), + vueJsx(), + libLegacy(), + libCss(), + dts({ + outDir: 'dist/types', + }), + ], +}); diff --git a/packages/core/src/create-plugin/template/theme/README.md b/packages/core/src/create-plugin/template/theme/README.md index 8e5b307..8a91568 100644 --- a/packages/core/src/create-plugin/template/theme/README.md +++ b/packages/core/src/create-plugin/template/theme/README.md @@ -1,126 +1,64 @@ # 主题插件 -## 新建主题 +主题插件可自定义主题样式和视图布局,当标准主题无法满足要求时,可以通过主题插件来实现。modeling建模平台创建主题插件可参见 [主题定制](https://open.ibizlab.cn/apphub/zh/guide/theme-custom.html) -新建界面主题,需要注意的是主题标识需要和主题插件包中的主题class类名一致,并且配置主题参数theme-package-path,主题参数的值是主题插件包信息。 +## 插件结构 - - -## 插件机制 - -应用初始化的时候,如果应用配置了主题,则会加载其对应的主题包插件,从而应用自定义主题样式和覆盖指定的默认视图布局,详情如下: - -```typescript -async initModel(context: IParams, permission: boolean = true): Promise { - // 没初始化或者初始化了但是切换模型 - if ( - !this.hasModelInit || - (this.hasModelInit && this.noPermissionModel !== permission) - ) { - // 清空重置基座 - ibiz.hub.reset(); - const helper = new ModelHelper( - async (url: string, params?: IParams) => { - const res = await ibiz.net.get( - `${ibiz.env.remoteModelUrl}${url}`, - params, - permission ? {} : { srfdcsystem: ibiz.env.dcSystem }, - ); - return res.data; - }, - ibiz.env.appId, - context, - permission, - ); - const tempApp = await helper.getAppModel(); - await this.initEnvironment(tempApp); - const app = await ibiz.hub.getAppAsync(ibiz.env.appId); - await AppHooks.initedApp.call({ context, app }); - const appModel = app.model; - ibiz.env.isMob = appModel.mobileApp === true; - if (ibiz.env.isEnableMultiLan) { - const lang = ibiz.i18n.getLang(); - const m = await helper.getPSAppLang( - lang.replace('-', '_').toUpperCase(), - ); - const items = m.languageItems || []; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const data: any = {}; - items.forEach(item => { - data[item.lanResTag!] = item.content; - }); - i18n.global.mergeLocaleMessage(lang, data); - } - const module = await import('@ibiz-template/web-theme'); - const theme = module.default || module; - AppHooks.useComponent.callSync(null, theme); - if (ibiz.config.theme) ibiz.util.theme.setTheme(ibiz.config.theme); - if (appModel.appUIThemes) { - await this.loadTheme(); - } - - // 设置浏览器标题 - if (app.model.title) { - ibiz.util.setBrowserTitle(''); - } - } - - this.noPermissionModel = permission; - this.hasModelInit = true; - } +``` +|─ ─ {{pluginName}} 主题插件顶层目录 + |─ ─ src 主题插件源代码目录 +​ |─ ─ layout 布局目录 + |─ ─ de-grid-view-layout.ts 默认实体表格视图布局模型 + |─ ─ index.ts 布局入口文件,覆盖默认视图布局 + |─ ─ theme 主题目录 + |─ ─ default 自定义主题目录 + |─ ─ app.scss 应用级主题样式 + |─ ─ ctrl.scss 部件级主题样式 + |─ ─ editor.scss 编辑器主题样式 + |─ ─ element-plus.scss element-plus主题样式 + |─ ─ theme.scss 样式变量 + |─ ─ view.scss 视图级主题样式 + |─ ─ index.scss 自定义主题入口文件,加载自定义主题样式 + |─ ─ index.ts 主题入口文件,加载主题样式 +​ |─ ─ index.ts 主题插件入口文件,加载主题样式和覆盖默认视图布局 ``` -## 插件示例 +## 本地开发 -### 插件效果 +1. 安装依赖并link至全局 -#### 使用插件前 +```sh +// 安装依赖 +pnpm i - +// link底包 +./scripts/link.sh -#### 使用插件后 +// 启动 +pnpm dev - +// link到全局 +pnpm link --global +``` -### 插件结构 +2. 主项目包中引用插件 +```sh +// link插件 +pnpm link --global '{{pluginGroup}}/{{pluginName}}' ``` -|─ ─ theme 主题插件顶层目录,可根据实际业务命名 - |─ ─ src 主题插件源代码目录 -​ |─ ─ layout 布局目录 - |─ ─ de-grid-view-layout.ts 默认表格视图布局json - |─ ─ index.ts 布局入口文件 - |─ ─ theme 主题目录 - |─ ─ custom-theme.scss 自定义主题 - |─ ─ index.ts 主题入口文件 -​ |─ ─ index.ts 主题插件入口文件 -``` - -### 主题插件入口文件 -主题插件入口文件会加载自定义主题样式,并且覆盖指定的默认视图布局,供外部使用。 +3. 主项目包中注册插件 -```typescript -import WebTheme from '@ibiz-template/web-theme'; -import { install } from './layout'; -import './theme/index.scss'; +```ts +import { App } from 'vue'; +import {{ pascalCasePluginName }} from '{{pluginGroup}}/{{pluginName}}' export default { - install(): void { - // 安装默认主题 - WebTheme.install(); - // 覆盖默认视图布局 - install((key: string, model: any) => { - ibiz.util.layoutPanel.register(key, model); - }); + install(app: App) { + app.use({{ pascalCasePluginName }}); + // 设置本地开发需要忽略加载的插件,可填写正则或全匹配字符串。匹配插件在modeling建模平台配置的[运行时插件仓库配置]内容 + ibiz.plugin.setDevIgnore(/^{{pluginGroup}}\/{{pluginName}}/); }, }; ``` - -### 布局入口文件 - -布局入口文件会覆盖指定的默认视图布局,可以重新定义默认视图布局的json结构。 - -### 主题入口文件 - -主题入口文件会加载自定义主题样式。 diff --git a/packages/core/src/create-plugin/template/theme/package.json b/packages/core/src/create-plugin/template/theme/package.json index 65ace5f..545839a 100644 --- a/packages/core/src/create-plugin/template/theme/package.json +++ b/packages/core/src/create-plugin/template/theme/package.json @@ -28,38 +28,70 @@ }, "devDependencies": { "@floating-ui/dom": "^1.5.3", - "@ibiz-template/core": "0.7.40-alpha.13", - "@ibiz-template/model-helper": "0.7.40-alpha.13", - "@ibiz-template/runtime": "0.7.40-alpha.13", + "@ibiz-template/core": "^0.7.40-alpha.7", + "@ibiz-template/model-helper": "^0.7.40-alpha.8", + "@ibiz-template/runtime": "^0.7.40-alpha.8", "@ibiz-template/theme": "^0.7.39", - "@ibiz-template/vue3-util": "0.7.40-alpha.13", - "@ibiz-template/web-theme": "3.1.0", - "@ibiz/model-core": "^0.1.71", + "@ibiz-template/vue3-util": "^0.7.40-alpha.8", + "@ibiz-template/web-theme": "^3.4.0", + "@ibiz/model-core": "^0.1.72", + "@qx-chitanda/vite-plugin-lib-legacy": "^4.1.1", "@types/lodash-es": "^4.17.12", "@types/ramda": "^0.29.6", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "@typescript-eslint/parser": "^6.11.0", + "@vitejs/plugin-vue": "^4.4.1", + "@vitejs/plugin-vue-jsx": "^3.0.2", "async-validator": "^4.2.5", "axios": "^1.6.2", "dayjs": "^1.11.10", "element-plus": "^2.4.2", + "eslint": "^8.53.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-prettier": "^9.0.0", + "eslint-plugin-import": "^2.29.0", + "eslint-plugin-prettier": "^5.0.1", + "eslint-plugin-unused-imports": "^3.0.0", + "eslint-plugin-vue": "^9.18.1", + "husky": "^8.0.3", + "lerna": "^8.0.0", + "lint-staged": "^15.1.0", "lodash-es": "^4.17.21", "pluralize": "^8.0.0", + "postcss": "^8.4.31", + "prettier": "^3.1.0", "qs": "^6.11.2", "qx-util": "^0.4.8", "ramda": "^0.29.1", + "rollup-plugin-visualizer": "^5.9.2", + "sass": "1.69.5", + "stylelint": "15.11.0", + "stylelint-config-prettier": "^9.0.5", + "stylelint-config-recess-order": "^4.3.0", + "stylelint-config-standard": "^34.0.0", + "stylelint-config-standard-scss": "^11.1.0", + "stylelint-scss": "5.3.1", + "terser": "^5.24.0", + "typescript": "5.2.2", + "vite": "^4.5.0", + "vite-plugin-dts": "^3.6.3", + "vite-plugin-eslint": "^1.8.1", "vite-plugin-libcss": "^1.1.1", "vue": "^3.3.8", + "vue-eslint-parser": "^9.3.2", "vue-router": "^4.2.5", + "vue-tsc": "1.8.22", "vuedraggable": "^4.1.0" }, "peerDependencies": { "@floating-ui/dom": "^1.5.1", - "@ibiz-template/core": "0.7.40-alpha.13", - "@ibiz-template/model-helper": "0.7.40-alpha.13", - "@ibiz-template/runtime": "0.7.40-alpha.13", + "@ibiz-template/core": "^0.7.40-alpha.7", + "@ibiz-template/model-helper": "^0.7.40-alpha.8", + "@ibiz-template/runtime": "^0.7.40-alpha.8", "@ibiz-template/theme": "^0.7.39", - "@ibiz-template/vue3-util": "0.7.40-alpha.13", - "@ibiz-template/web-theme": "3.1.0", - "@ibiz/model-core": "^0.1.71", + "@ibiz-template/vue3-util": "^0.7.40-alpha.8", + "@ibiz-template/web-theme": "^3.4.0", + "@ibiz/model-core": "^0.1.72", "async-validator": "^4.2.5", "axios": "^1.6.2", "dayjs": "^1.11.10", diff --git a/packages/core/src/create-plugin/template/theme/public/docs/image.png b/packages/core/src/create-plugin/template/theme/public/docs/image.png deleted file mode 100644 index 3e0baf5adf280c04430d161b63ad2f491dfadb82..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37958 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 z 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

sv}yn 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 GJO3BFhTqEo diff --git a/packages/core/src/create-plugin/template/theme/public/docs/image3.png b/packages/core/src/create-plugin/template/theme/public/docs/image3.png deleted file mode 100644 index 39dc57287e66f32a9a964e328d93d9f5a289bd0d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 74202 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 A;Q#;t diff --git a/packages/core/src/create-plugin/template/theme/src/index.ts b/packages/core/src/create-plugin/template/theme/src/index.ts index 21767cc..0aa030d 100644 --- a/packages/core/src/create-plugin/template/theme/src/index.ts +++ b/packages/core/src/create-plugin/template/theme/src/index.ts @@ -1,14 +1,15 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import WebTheme from '@ibiz-template/web-theme'; -// import { install } from './layout'; -// import './theme/index.scss'; +import { install } from './layout'; +import './theme/index.scss'; export default { install(): void { // 安装默认主题 WebTheme.install(); // 覆盖默认视图布局 - // install((key: string, model: any) => { - // ibiz.util.layoutPanel.register(key, model); - // }); + install((key: string, model: any) => { + ibiz.util.layoutPanel.register(key, model); + }); }, }; diff --git a/packages/core/src/create-plugin/template/theme/src/layout/index.ts b/packages/core/src/create-plugin/template/theme/src/layout/index.ts index 5bf3441..f02b952 100644 --- a/packages/core/src/create-plugin/template/theme/src/layout/index.ts +++ b/packages/core/src/create-plugin/template/theme/src/layout/index.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import DEGridView from './de-grid-view-layout'; export function install(callBack: (key: string, model: any) => void): void { diff --git a/packages/core/src/create-plugin/template/theme/src/theme/custom-theme.scss b/packages/core/src/create-plugin/template/theme/src/theme/custom-theme.scss deleted file mode 100644 index 347a3a4..0000000 --- a/packages/core/src/create-plugin/template/theme/src/theme/custom-theme.scss +++ /dev/null @@ -1,421 +0,0 @@ -/* stylelint-disable selector-class-pattern */ -:root.custom_theme { -// 红色 -#{getCssVarName(red, 0)}: 254, 242, 237; -#{getCssVarName(red, 1)}: 254, 221, 210; -#{getCssVarName(red, 2)}: 253, 183, 164; -#{getCssVarName(red, 3)}: 251, 144, 120; -#{getCssVarName(red, 4)}: 250, 102, 75; -#{getCssVarName(red, 5)}: 249, 57, 31; -#{getCssVarName(red, 6)}: 213, 37, 20; -#{getCssVarName(red, 7)}: 177, 20, 13; -#{getCssVarName(red, 8)}: 142, 7, 5; -#{getCssVarName(red, 9)}: 106, 2, 3; - -// 粉色 -#{getCssVarName(pink, 0)}: 253, 236, 239; -#{getCssVarName(pink, 1)}: 251, 207, 216; -#{getCssVarName(pink, 2)}: 246, 160, 181; -#{getCssVarName(pink, 3)}: 242, 115, 150; -#{getCssVarName(pink, 4)}: 238, 72, 122; -#{getCssVarName(pink, 5)}: 233, 31, 99; -#{getCssVarName(pink, 6)}: 197, 18, 86; -#{getCssVarName(pink, 7)}: 162, 11, 72; -#{getCssVarName(pink, 8)}: 126, 4, 58; -#{getCssVarName(pink, 9)}: 90, 1, 44; - -// 紫色 -#{getCssVarName(purple, 0)}: 247, 233, 247; -#{getCssVarName(purple, 1)}: 239, 202, 239; -#{getCssVarName(purple, 2)}: 221, 155, 224; -#{getCssVarName(purple, 3)}: 201, 112, 209; -#{getCssVarName(purple, 4)}: 180, 73, 194; -#{getCssVarName(purple, 5)}: 158, 40, 179; -#{getCssVarName(purple, 6)}: 135, 30, 159; -#{getCssVarName(purple, 7)}: 112, 23, 138; -#{getCssVarName(purple, 8)}: 92, 14, 117; -#{getCssVarName(purple, 9)}: 72, 11, 97; - -// 紫罗兰色 -#{getCssVarName(violet, 0)}: 243, 237, 249; -#{getCssVarName(violet, 1)}: 226, 209, 244; -#{getCssVarName(violet, 2)}: 196, 167, 233; -#{getCssVarName(violet, 3)}: 166, 126, 221; -#{getCssVarName(violet, 4)}: 136, 91, 210; -#{getCssVarName(violet, 5)}: 106, 58, 199; -#{getCssVarName(violet, 6)}: 87, 47, 179; -#{getCssVarName(violet, 7)}: 70, 36, 158; -#{getCssVarName(violet, 8)}: 54, 28, 138; -#{getCssVarName(violet, 9)}: 40, 20, 117; - -// 靛蓝 -#{getCssVarName(indigo, 0)}: 237, 239, 248; -#{getCssVarName(indigo, 1)}: 209, 216, 240; -#{getCssVarName(indigo, 2)}: 167, 179, 225; -#{getCssVarName(indigo, 3)}: 128, 144, 211; -#{getCssVarName(indigo, 4)}: 94, 111, 196; -#{getCssVarName(indigo, 5)}: 63, 81, 181; -#{getCssVarName(indigo, 6)}: 51, 66, 161; -#{getCssVarName(indigo, 7)}: 41, 52, 140; -#{getCssVarName(indigo, 8)}: 31, 40, 120; -#{getCssVarName(indigo, 9)}: 23, 29, 99; - -// 蓝色 -#{getCssVarName(blue, 0)}: 234, 245, 255; -#{getCssVarName(blue, 1)}: 203, 231, 254; -#{getCssVarName(blue, 2)}: 152, 205, 253; -#{getCssVarName(blue, 3)}: 101, 179, 252; -#{getCssVarName(blue, 4)}: 51, 149, 252; -#{getCssVarName(blue, 5)}: 3, 118, 250; -#{getCssVarName(blue, 6)}: 2, 97, 214; -#{getCssVarName(blue, 7)}: 2, 79, 179; -#{getCssVarName(blue, 8)}: 0, 61, 143; -#{getCssVarName(blue, 9)}: 0, 44, 107; - -// 浅蓝色 -#{getCssVarName(light, blue, 0)}: 234, 247, 253; -#{getCssVarName(light, blue, 1)}: 202, 236, 252; -#{getCssVarName(light, blue, 2)}: 149, 216, 248; -#{getCssVarName(light, blue, 3)}: 97, 195, 245; -#{getCssVarName(light, blue, 4)}: 48, 172, 241; -#{getCssVarName(light, blue, 5)}: 0, 149, 238; -#{getCssVarName(light, blue, 6)}: 0, 123, 202; -#{getCssVarName(light, blue, 7)}: 0, 99, 167; -#{getCssVarName(light, blue, 8)}: 0, 75, 131; -#{getCssVarName(light, blue, 9)}: 0, 53, 95; - -// 青色 -#{getCssVarName(cyan, 0)}: 229, 247, 248; -#{getCssVarName(cyan, 1)}: 194, 239, 240; -#{getCssVarName(cyan, 2)}: 138, 221, 225; -#{getCssVarName(cyan, 3)}: 87, 203, 211; -#{getCssVarName(cyan, 4)}: 44, 184, 197; -#{getCssVarName(cyan, 5)}: 6, 164, 182; -#{getCssVarName(cyan, 6)}: 3, 134, 152; -#{getCssVarName(cyan, 7)}: 2, 105, 121; -#{getCssVarName(cyan, 8)}: 0, 77, 91; -#{getCssVarName(cyan, 9)}: 1, 50, 61; - -// 蓝绿色 -#{getCssVarName(teal, 0)}: 227, 247, 244; -#{getCssVarName(teal, 1)}: 192, 240, 232; -#{getCssVarName(teal, 2)}: 135, 224, 211; -#{getCssVarName(teal, 3)}: 84, 209, 193; -#{getCssVarName(teal, 4)}: 39, 194, 176; -#{getCssVarName(teal, 5)}: 5, 179, 161; -#{getCssVarName(teal, 6)}: 0, 149, 137; -#{getCssVarName(teal, 7)}: 0, 119, 111; -#{getCssVarName(teal, 8)}: 0, 90, 85; -#{getCssVarName(teal, 9)}: 1, 60, 58; - -// 绿色 -#{getCssVarName(green, 0)}: 236, 246, 236; -#{getCssVarName(green, 1)}: 208, 240, 208; -#{getCssVarName(green, 2)}: 164, 224, 167; -#{getCssVarName(green, 3)}: 126, 209, 130; -#{getCssVarName(green, 4)}: 90, 194, 98; -#{getCssVarName(green, 5)}: 59, 179, 70; -#{getCssVarName(green, 6)}: 49, 149, 58; -#{getCssVarName(green, 7)}: 37, 119, 47; -#{getCssVarName(green, 8)}: 26, 89, 36; -#{getCssVarName(green, 9)}: 18, 60, 24; - -// 浅绿色 -#{getCssVarName(light, green, 0)}: 243, 248, 236; -#{getCssVarName(light, green, 1)}: 226, 240, 208; -#{getCssVarName(light, green, 2)}: 200, 225, 165; -#{getCssVarName(light, green, 3)}: 173, 211, 127; -#{getCssVarName(light, green, 4)}: 147, 197, 91; -#{getCssVarName(light, green, 5)}: 123, 182, 60; -#{getCssVarName(light, green, 6)}: 100, 152, 47; -#{getCssVarName(light, green, 7)}: 79, 121, 38; -#{getCssVarName(light, green, 8)}: 57, 91, 27; -#{getCssVarName(light, green, 9)}: 36, 61, 18; - -// 清柠色 -#{getCssVarName(lime, 0)}: 241, 250, 230; -#{getCssVarName(lime, 1)}: 227, 246, 197; -#{getCssVarName(lime, 2)}: 203, 237, 142; -#{getCssVarName(lime, 3)}: 183, 226, 91; -#{getCssVarName(lime, 4)}: 168, 218, 44; -#{getCssVarName(lime, 5)}: 154, 209, 0; -#{getCssVarName(lime, 6)}: 125, 174, 0; -#{getCssVarName(lime, 7)}: 99, 139, 2; -#{getCssVarName(lime, 8)}: 72, 104, 0; -#{getCssVarName(lime, 9)}: 47, 70, 0; - -// 黄色 -#{getCssVarName(yellow, 0)}: 255, 253, 234; -#{getCssVarName(yellow, 1)}: 255, 250, 203; -#{getCssVarName(yellow, 2)}: 253, 243, 152; -#{getCssVarName(yellow, 3)}: 252, 231, 101; -#{getCssVarName(yellow, 4)}: 251, 218, 49; -#{getCssVarName(yellow, 5)}: 249, 200, 0; -#{getCssVarName(yellow, 6)}: 208, 170, 0; -#{getCssVarName(yellow, 7)}: 167, 139, 0; -#{getCssVarName(yellow, 8)}: 125, 106, 0; -#{getCssVarName(yellow, 9)}: 83, 72, 0; - -// 琥珀色 -#{getCssVarName(amber, 0)}: 255, 251, 236; -#{getCssVarName(amber, 1)}: 252, 245, 206; -#{getCssVarName(amber, 2)}: 249, 232, 158; -#{getCssVarName(amber, 3)}: 246, 216, 110; -#{getCssVarName(amber, 4)}: 243, 198, 65; -#{getCssVarName(amber, 5)}: 240, 177, 20; -#{getCssVarName(amber, 6)}: 200, 138, 16; -#{getCssVarName(amber, 7)}: 160, 102, 10; -#{getCssVarName(amber, 8)}: 120, 70, 5; -#{getCssVarName(amber, 9)}: 80, 43, 3; - -// 橙色 -#{getCssVarName(orange, 0)}: 255, 243, 224; -#{getCssVarName(orange, 1)}: 255, 223, 177; -#{getCssVarName(orange, 2)}: 255, 204, 128; -#{getCssVarName(orange, 3)}: 254, 183, 77; -#{getCssVarName(orange, 4)}: 255, 167, 38; -#{getCssVarName(orange, 5)}: 255, 152, 0; -#{getCssVarName(orange, 6)}: 250, 141, 0; -#{getCssVarName(orange, 7)}: 245, 124, 2; -#{getCssVarName(orange, 8)}: 239, 108, 0; -#{getCssVarName(orange, 9)}: 230, 81, 0; - -// 灰色 -#{getCssVarName(grey, 0)}: 249, 249, 249; -#{getCssVarName(grey, 1)}: 230, 232, 234; -#{getCssVarName(grey, 2)}: 198, 202, 205; -#{getCssVarName(grey, 3)}: 167, 171, 175; -#{getCssVarName(grey, 4)}: 136, 141, 145; -#{getCssVarName(grey, 5)}: 107, 102, 116; -#{getCssVarName(grey, 6)}: 85, 91, 97; -#{getCssVarName(grey, 7)}: 65, 70, 76; -#{getCssVarName(grey, 8)}: 46, 50, 55; -#{getCssVarName(grey, 9)}: 29, 31, 35; - - -// 蓝青色 -#{getCssVarName(blue, cyan, 0)}: 217, 236, 255; -#{getCssVarName(blue, cyan, 1)}: 164, 201, 238; -#{getCssVarName(blue, cyan, 2)}: 131, 171, 212; -#{getCssVarName(blue, cyan, 3)}: 105, 148, 190; -#{getCssVarName(blue, cyan, 4)}: 85, 125, 165; -#{getCssVarName(blue, cyan, 5)}: 70, 107, 144; -#{getCssVarName(blue, cyan, 6)}: 48, 81, 115; -#{getCssVarName(blue, cyan, 7)}: 36, 65, 96; -#{getCssVarName(blue, cyan, 8)}: 26, 52, 79; -#{getCssVarName(blue, cyan, 9)}: 16, 41, 68; - -// 天蓝色 -#{getCssVarName(sky, blue, 0)}: 232, 249, 255; -#{getCssVarName(sky, blue, 1)}: 183, 232, 251; -#{getCssVarName(sky, blue, 2)}: 135, 212, 248; -#{getCssVarName(sky, blue, 3)}: 89, 190, 244; -#{getCssVarName(sky, blue, 4)}: 44, 165, 241; -#{getCssVarName(sky, blue, 5)}: 0, 137, 237; -#{getCssVarName(sky, blue, 6)}: 0, 108, 197; -#{getCssVarName(sky, blue, 7)}: 0, 81, 157; -#{getCssVarName(sky, blue, 8)}: 0, 56, 117; -#{getCssVarName(sky, blue, 9)}: 0, 34, 77; - -// 黑、白色 -#{getCssVarName(white)}: 255, 255, 255; -#{getCssVarName(black)}: 0, 0, 0; - -// 功能色 -#{getCssVarName(color, white)}: rgba(var(#{getCssVarName(white)}),1); // 浅色模式下深色背景内容Inverse -#{getCssVarName(color, black)}: rgba(var(#{getCssVarName(black)}),1); // 深色模式下浅色背景内容Inverse - -// 主要颜色 -#{getCssVarName(color, primary)}: rgba(var(#{getCssVarName(sky, blue, 5)}),1); // 主要颜色。仅在需要非常强调的情况下使用。 -#{getCssVarName(color, primary, text)}: rgba(var(#{getCssVarName(white)}), 1); // 主要颜色文字色,和背景色形成对比 -#{getCssVarName(color, primary, hover)}: rgba(var(#{getCssVarName(sky, blue, 4)}),1); // 主要颜色悬浮态 -#{getCssVarName(color, primary, hover, text)}: rgba(var(#{getCssVarName(white)}), 1); // 主要颜色文字色,和背景色形成对比 -#{getCssVarName(color, primary, active)}: rgba(var(#{getCssVarName(sky, blue, 6)}),1); // 主要颜色激活态 -#{getCssVarName(color, primary, active, text)}: rgba(var(#{getCssVarName(white)}), 1); // 主要颜色文字色,和背景色形成对比 -#{getCssVarName(color, primary, disabled)}: rgba(var(#{getCssVarName(sky, blue, 2)}),1); // 主要颜色禁用态 -#{getCssVarName(color, primary, disabled, text)}: rgba(var(#{getCssVarName(white)}), 1); // 主要颜色文字色,和背景色形成对比 -#{getCssVarName(color, primary, light, default)}: rgba(var(#{getCssVarName(sky, blue, 0)}),1); // 浅版主要颜色(多用于背景)。仅在需要非常强调的情况下使用。 -#{getCssVarName(color, primary, light, hover)}: rgba(var(#{getCssVarName(sky, blue, 1)}),1); // 浅版主要颜色悬浮态 -#{getCssVarName(color, primary, light, active)}: rgba(var(#{getCssVarName(sky, blue, 2)}),1); // 浅版主要颜色激活态 - -// 次要颜色 -#{getCssVarName(color, secondary)}: rgba(var(#{getCssVarName(light, blue, 5)}),1); // 次要颜色。强调作用次于主要颜色,但仍然具有强调作用。 -#{getCssVarName(color, secondary, text)}: rgba(var(#{getCssVarName(white)}), 1); // 次要颜色文字色,和背景色形成对比 -#{getCssVarName(color, secondary, hover)}: rgba(var(#{getCssVarName(light, blue, 6)}),1); // 次要颜色悬浮态 -#{getCssVarName(color, secondary, hover, text)}: rgba(var(#{getCssVarName(white)}), 1); // 次要颜色文字色,和背景色形成对比 -#{getCssVarName(color, secondary, active)}: rgba(var(#{getCssVarName(light, blue, 7)}),1); // 次要颜色激活态 -#{getCssVarName(color, secondary, active, text)}: rgba(var(#{getCssVarName(white)}), 1); // 次要颜色文字色,和背景色形成对比 -#{getCssVarName(color, secondary, disabled)}: rgba(var(#{getCssVarName(light, blue, 2)}),1); // 次要颜色禁用态 -#{getCssVarName(color, secondary, disabled, text)}: rgba(var(#{getCssVarName(white)}), 1); // 次要颜色文字色,和背景色形成对比 -#{getCssVarName(color, secondary, light, default)}: rgba(var(#{getCssVarName(light, blue, 0)}),1); // 浅版次要颜色(多用于背景)。强调作用次于主要颜色,但仍然具有强调作用。 -#{getCssVarName(color, secondary, light, hover)}: rgba(var(#{getCssVarName(light, blue, 1)}),1); // 浅版次要颜色悬浮态 -#{getCssVarName(color, secondary, light, active)}: rgba(var(#{getCssVarName(light, blue, 2)}),1); // 浅版次要颜色激活态 - -// 第三颜色 -#{getCssVarName(color, tertiary)}: rgba(var(#{getCssVarName(grey, 5)}),1); // 第三颜色,可以在页面上多次使用 -#{getCssVarName(color, tertiary, text)}: rgba(var(#{getCssVarName(white)}), 1); // 第三颜色文字色,和背景色形成对比 -#{getCssVarName(color, tertiary, hover)}: rgba(var(#{getCssVarName(grey, 4)}),1); // 第三颜色悬浮态 -#{getCssVarName(color, tertiary, hover, text)}: rgba(var(#{getCssVarName(white)}), 1); // 第三颜色文字色,和背景色形成对比 -#{getCssVarName(color, tertiary, active)}: rgba(var(#{getCssVarName(grey, 6)}),1); // 第三颜色激活态 -#{getCssVarName(color, tertiary, active, text)}: rgba(var(#{getCssVarName(white)}), 1); // 第三颜色文字色,和背景色形成对比 -#{getCssVarName(color, tertiary, light, default)}: rgba(var(#{getCssVarName(grey, 0)}),1); // 浅版第三颜色(多用于背景),可以在页面上多次使用 -#{getCssVarName(color, tertiary, light, hover)}: rgba(var(#{getCssVarName(grey, 1)}),1); // 浅版第三颜色悬浮态 -#{getCssVarName(color, tertiary, light, active)}: rgba(var(#{getCssVarName(grey, 2)}),1); // 浅版第三颜色激活态 - -// 信息色 -#{getCssVarName(color, info)}: rgba(var(#{getCssVarName(sky, blue, 5)}),1); // 信息色, 通常用于表达客观、中立信息 -#{getCssVarName(color, info, text)}: rgba(var(#{getCssVarName(white)}), 1); // 信息颜色文字色,和背景色形成对比 -#{getCssVarName(color, info, hover)}: rgba(var(#{getCssVarName(sky, blue, 4)}),1); // 信息色悬浮态 -#{getCssVarName(color, info, hover, text)}: rgba(var(#{getCssVarName(white)}), 1); // 信息颜色文字色,和背景色形成对比 -#{getCssVarName(color, info, active)}: rgba(var(#{getCssVarName(sky, blue, 6)}),1); // 信息色激活态 -#{getCssVarName(color, info, active, text)}: rgba(var(#{getCssVarName(white)}), 1); // 信息颜色文字色,和背景色形成对比 -#{getCssVarName(color, info, disabled)}: rgba(var(#{getCssVarName(sky, blue, 2)}),1); // 信息色禁用态 -#{getCssVarName(color, info, disabled, text)}: rgba(var(#{getCssVarName(white)}), 1); // 信息颜色文字色,和背景色形成对比 -#{getCssVarName(color, info, light, default)}: rgba(var(#{getCssVarName(sky, blue, 0)}),1); // 浅版信息色(多用于背景),通常用于表达客观、中立信息 -#{getCssVarName(color, info, light, hover)}: rgba(var(#{getCssVarName(sky, blue, 1)}),1); // 浅版信息色悬浮态 -#{getCssVarName(color, info, light, active)}: rgba(var(#{getCssVarName(sky, blue, 2)}),1); // 浅版信息色激活态 - -// 成功色 -#{getCssVarName(color, success)}: rgba(var(#{getCssVarName(green, 5)}),1); // 成功色,表示安全、成功、开启的状态 -#{getCssVarName(color, success, text)}: rgba(var(#{getCssVarName(white)}), 1); // 成功颜色文字色,和背景色形成对比 -#{getCssVarName(color, success, hover)}: rgba(var(#{getCssVarName(green, 4)}),1); // 成功色悬浮态 -#{getCssVarName(color, success, hover, text)}: rgba(var(#{getCssVarName(white)}), 1); // 成功颜色文字色,和背景色形成对比 -#{getCssVarName(color, success, active)}: rgba(var(#{getCssVarName(green, 6)}),1); // 成功色激活态 -#{getCssVarName(color, success, active, text)}: rgba(var(#{getCssVarName(white)}), 1); // 成功颜色文字色,和背景色形成对比 -#{getCssVarName(color, success, disabled)}: rgba(var(#{getCssVarName(green, 2)}),1); // 成功色禁用态 -#{getCssVarName(color, success, disabled, text)}: rgba(var(#{getCssVarName(white)}), 1); // 成功颜色文字色,和背景色形成对比 -#{getCssVarName(color, success, light, default)}: rgba(var(#{getCssVarName(green, 0)}),1); // 浅版成功色(多用于背景),表示安全、成功、开启的状态 -#{getCssVarName(color, success, light, hover)}: rgba(var(#{getCssVarName(green, 1)}),1); // 浅版成功色悬浮态 -#{getCssVarName(color, success, light, active)}: rgba(var(#{getCssVarName(green, 2)}),1); // 浅版成功色激活态 - -// 警示色 -#{getCssVarName(color, warning)}: rgba(var(#{getCssVarName(orange, 5)}),1); // 警示色,表示警告、不安全的状态 -#{getCssVarName(color, warning, text)}: rgba(var(#{getCssVarName(white)}), 1); // 警告颜色文字色,和背景色形成对比 -#{getCssVarName(color, warning, hover)}: rgba(var(#{getCssVarName(orange, 4)}),1); // 警示色悬浮态 -#{getCssVarName(color, warning, hover, text)}: rgba(var(#{getCssVarName(white)}), 1); // 警告颜色文字色,和背景色形成对比 -#{getCssVarName(color, warning, active)}: rgba(var(#{getCssVarName(orange, 6)}),1); // 警示色激活态 -#{getCssVarName(color, warning, active, text)}: rgba(var(#{getCssVarName(white)}), 1); // 警告颜色文字色,和背景色形成对比 -#{getCssVarName(color, warning, light, default)}: rgba(var(#{getCssVarName(orange, 0)}),1); // 浅版警示色(多用于背景),表示警告、不安全的状态 -#{getCssVarName(color, warning, light, hover)}: rgba(var(#{getCssVarName(orange, 1)}),1); // 浅版警示色悬浮态 -#{getCssVarName(color, warning, light, active)}: rgba(var(#{getCssVarName(orange, 2)}),1); // 浅版警示色激活态 - -// 危险色 -#{getCssVarName(color, danger)}: rgba(var(#{getCssVarName(red, 5)}),1); // 危险色,表示危险的操作、或需要特别注意的危险信息 -#{getCssVarName(color, danger, text)}: rgba(var(#{getCssVarName(white)}), 1); // 危险颜色文字色,和背景色形成对比 -#{getCssVarName(color, danger, hover)}: rgba(var(#{getCssVarName(red, 4)}),1); // 危险色悬浮态 -#{getCssVarName(color, danger, hover, text)}: rgba(var(#{getCssVarName(white)}), 1); // 危险颜色文字色,和背景色形成对比 -#{getCssVarName(color, danger, active)}: rgba(var(#{getCssVarName(red, 6)}),1); // 危险色激活态 -#{getCssVarName(color, danger, active, text)}: rgba(var(#{getCssVarName(white)}), 1); // 危险颜色文字色,和背景色形成对比 -#{getCssVarName(color, danger, light, default)}: rgba(var(#{getCssVarName(red, 0)}),1); // 浅版危险色(多用于背景),表示危险的操作、或需要特别注意的危险信息 -#{getCssVarName(color, danger, light, hover)}: rgba(var(#{getCssVarName(red, 1)}),1); // 浅版危险色悬浮态 -#{getCssVarName(color, danger, light, active)}: rgba(var(#{getCssVarName(red, 2)}),1); // 浅版危险色激活态 - -// 文本/图标颜色 -#{getCssVarName(color, text, 0)}: rgba(var(#{getCssVarName(grey, 9)}),1); // 文本/图标颜色 - 最主要 -#{getCssVarName(color, text, 1)}: rgba(var(#{getCssVarName(grey, 7)}),1); // 文本/图标颜色 - 稍次要 -#{getCssVarName(color, text, 2)}: rgba(var(#{getCssVarName(grey, 6)}),1); // 文本/图标颜色 - 次要 -#{getCssVarName(color, text, 3)}: rgba(var(#{getCssVarName(grey, 4)}),1); // 文本/图标颜色 - 最次要 -#{getCssVarName(color, text, menu)}: rgba(var(#{getCssVarName(grey, 9)}),1); // 文本 - 特殊-菜单颜色 - -// 链接颜色 -#{getCssVarName(color, link)}: rgba(var(#{getCssVarName(sky, blue, 5)}),1); // 链接颜色 -#{getCssVarName(color, link, hover)}: rgba(var(#{getCssVarName(sky, blue, 4)}),1); // 链接颜色 - 悬浮态 -#{getCssVarName(color, link, active)}: rgba(var(#{getCssVarName(sky, blue, 6)}),1); // 链接颜色 - 激活态 -#{getCssVarName(color, link, visited)}: rgba(var(#{getCssVarName(sky, blue, 5)}),1); // 链接颜色 - 已访问 - -// 背景色 -#{getCssVarName(color, bg, 0)}: rgba(var(#{getCssVarName(grey, 0)}),1); // 背景色 - 最下层(底部页面) -#{getCssVarName(color, bg, 1)}: rgba(var(#{getCssVarName(white)}),1); // 背景色 - 次下层(页面中需要提升的内容) -#{getCssVarName(color, bg, 2)}: rgba(var(#{getCssVarName(white)}),1); // 背景色 - 中间层(模态等容器) -#{getCssVarName(color, bg, 3)}: rgba(var(#{getCssVarName(white)}),1); // 背景色 - 次上层(通知,Toast等) -#{getCssVarName(color, bg, 4)}: rgba(var(#{getCssVarName(white)}),1); // 背景色 - 最上层(特殊) -#{getCssVarName(color, bg, 5)}: rgba(var(#{getCssVarName(sky, blue, 4)}),1); // 背景色(特殊) - 应用搜索框使用 -#{getCssVarName(color, bg, overlay)}: rgba(22 22 26 / 60%); // 蒙层背景色 - -// 填充色 -#{getCssVarName(color, fill, 0)}: rgba(var(#{getCssVarName(grey, 8)}),0.05); // 填充色 - 默认态 -#{getCssVarName(color, fill, 1)}: rgba(var(#{getCssVarName(grey, 8)}),0.1); // 填充色 - 悬浮态 -#{getCssVarName(color, fill, 2)}: rgba(var(#{getCssVarName(grey, 8), }),0.13); // 填充色 - 激活态 -#{getCssVarName(color, scroll, menu)}: rgba(var(#{getCssVarName(grey, 8), }),0.13); // 填充色 - 特殊-菜单滚动条颜色 - - -// 边框 -#{getCssVarName(color, border)}: rgba(var(#{getCssVarName(grey, 9)}),0.1); // 默认描边颜色 - -// 禁用态 -#{getCssVarName(color, disabled, text)}: rgba(var(#{getCssVarName(grey, 9)}), 0.35); // 禁用态 - 文字 -#{getCssVarName(color, disabled, border)}: rgba(var(#{getCssVarName(grey, 1)}),1); // 禁用态 - 描边 -#{getCssVarName(color, disabled, bg)}: rgba(var(#{getCssVarName(grey, 1)}),1); // 禁用态 - 背景 -#{getCssVarName(color, disabled, fill)}: rgba(var(#{getCssVarName(grey, 8)}),0.04); // 禁用态 - 填充 - -// 阴影 -#{getCssVarName(color, shadow)}: rgba(var(#{getCssVarName(black)}),0.04); // 用于模拟描边的阴影颜色 -#{getCssVarName(shadow, elevated)}: - 0 0 1px rgba(0 0 0 / 30%), - 0 4px 14px rgba(0 0 0 / 10%); // 用于toast, modal, popover等需要提升层级的界面元素 - -// 字号 -#{getCssVarName('font-size', 'small')}: 12px; -#{getCssVarName('font-size', 'regular')}: 14px; -#{getCssVarName('font-size', 'header-6')}: 16px; -#{getCssVarName('font-size', 'header-5')}: 18px; -#{getCssVarName('font-size', 'header-4')}: 20px; -#{getCssVarName('font-size', 'header-3')}: 24px; -#{getCssVarName('font-size', 'header-2')}: 28px; -#{getCssVarName('font-size', 'header-1')}: 32px; - -// 字重 -#{getCssVarName('font-weight', 'light')}: 200; -#{getCssVarName('font-weight', 'regular')}: 400; -#{getCssVarName('font-weight', 'bold')}: 800; - -// 圆角 -#{getCssVarName(border, radius, extra, small)}: 2px; // 超小圆角,用于 checkbox 内圆角 -#{getCssVarName(border, radius, small)}: 4px; // 小圆角, 用于 button、tag、tabs 等大多数组件, 比较常用 -#{getCssVarName(border, radius, medium)}: 8px; // 中圆角, 用于 dropdown、scrollist、transfer 等菜单类组件 -#{getCssVarName(border, radius, large)}: 12px; // 大圆角, 用于 modal -#{getCssVarName(border, radius, circle)}: 50%; // 全圆角, 用于 avatar, badge 等组件 -#{getCssVarName(border, radius, full)}: 9999px; // 用于创建全尺寸圆角,如胶囊标签等 - -// 高度 -#{getCssVarName('height-control', 'small')}: 24px; -#{getCssVarName('height-control', 'default')}: 32px; -#{getCssVarName('height-control', 'large')}: 40px; - -// 描边尺寸 -#{getCssVarName('border-thickness')}: 0; -#{getCssVarName('border-thickness', 'control')}: 1px; -#{getCssVarName('border-thickness', 'control-focus')}: 1px; - -// 图标尺寸 -#{getCssVarName('width-icon', 'extra-small')}: 8px; -#{getCssVarName('width-icon', 'small')}: 12px; -#{getCssVarName('width-icon', 'medium')}: 16px; -#{getCssVarName('width-icon', 'large')}: 20px; -#{getCssVarName('width-icon', 'extra-large')}: 24px; - -// 间距 -#{getCssVarName('spacing', 'none')}: 0; -#{getCssVarName('spacing', 'super-tight')}: 2px; -#{getCssVarName('spacing', 'extra-tight')}: 4px; -#{getCssVarName('spacing', 'tight')}: 8px; -#{getCssVarName('spacing', 'base-tight')}: 12px; -#{getCssVarName('spacing', 'base')}: 16px; -#{getCssVarName('spacing', 'base-loose')}: 20px; -#{getCssVarName('spacing', 'loose')}: 24px; -#{getCssVarName('spacing', 'extra-loose')}: 32px; -#{getCssVarName('spacing', 'super-loose')}: 40px; -} - -// 主题下的区域性样式覆盖 - -:root.custom_theme { - @include b(panel-app-header) { - #{getCssVarName(grey, 9)}: 255, 255, 255; - #{getCssVarName(color, text, 0)}: rgba(var(#{getCssVarName(grey, 9)}), 1); // 文本/图标颜色 - 最主要 - #{getCssVarName(color, text, 1)}: rgba(var(#{getCssVarName(grey, 9)}), .8); // 文本/图标颜色 - 稍次要 - #{getCssVarName(color, text, 2)}: rgba(var(#{getCssVarName(grey, 9)}), .6); // 文本/图标颜色 - 次要 - #{getCssVarName(color, text, 3)}: rgba(var(#{getCssVarName(grey, 9)}), .35); // 文本/图标颜色 - 最次要 - #{getCssVarName(color, text, menu)}: rgba(var(#{getCssVarName(grey, 9)}), 1); - } -} \ No newline at end of file diff --git a/packages/core/src/create-plugin/template/theme/src/theme/default/app.scss b/packages/core/src/create-plugin/template/theme/src/theme/default/app.scss new file mode 100644 index 0000000..7c3329a --- /dev/null +++ b/packages/core/src/create-plugin/template/theme/src/theme/default/app.scss @@ -0,0 +1,3 @@ +:root.{{pluginName}} { + // 应用级主题样式 +} \ No newline at end of file diff --git a/packages/core/src/create-plugin/template/theme/src/theme/default/ctrl.scss b/packages/core/src/create-plugin/template/theme/src/theme/default/ctrl.scss new file mode 100644 index 0000000..92ac5e2 --- /dev/null +++ b/packages/core/src/create-plugin/template/theme/src/theme/default/ctrl.scss @@ -0,0 +1,3 @@ +:root.{{pluginName}} { + // 部件级主题样式 +} \ No newline at end of file diff --git a/packages/core/src/create-plugin/template/theme/src/theme/default/editor.scss b/packages/core/src/create-plugin/template/theme/src/theme/default/editor.scss new file mode 100644 index 0000000..f0e540f --- /dev/null +++ b/packages/core/src/create-plugin/template/theme/src/theme/default/editor.scss @@ -0,0 +1,3 @@ +:root.{{pluginName}} { + // 编辑器主题样式 +} \ No newline at end of file diff --git a/packages/core/src/create-plugin/template/theme/src/theme/default/element-plus.scss b/packages/core/src/create-plugin/template/theme/src/theme/default/element-plus.scss new file mode 100644 index 0000000..d821fb4 --- /dev/null +++ b/packages/core/src/create-plugin/template/theme/src/theme/default/element-plus.scss @@ -0,0 +1,3 @@ +:root.{{pluginName}} { + // element-plus主题样式 +} \ No newline at end of file diff --git a/packages/core/src/create-plugin/template/theme/src/theme/default/index.scss b/packages/core/src/create-plugin/template/theme/src/theme/default/index.scss new file mode 100644 index 0000000..4dc118e --- /dev/null +++ b/packages/core/src/create-plugin/template/theme/src/theme/default/index.scss @@ -0,0 +1,6 @@ +@import './app'; +@import './ctrl'; +@import './editor'; +@import './element-plus'; +@import './theme'; +@import './view'; \ No newline at end of file diff --git a/packages/core/src/create-plugin/template/theme/src/theme/default/theme.scss b/packages/core/src/create-plugin/template/theme/src/theme/default/theme.scss new file mode 100644 index 0000000..40a4e85 --- /dev/null +++ b/packages/core/src/create-plugin/template/theme/src/theme/default/theme.scss @@ -0,0 +1,3 @@ +:root.{{pluginName}} { + // 样式变量 +} \ No newline at end of file diff --git a/packages/core/src/create-plugin/template/theme/src/theme/default/view.scss b/packages/core/src/create-plugin/template/theme/src/theme/default/view.scss new file mode 100644 index 0000000..2fc2c42 --- /dev/null +++ b/packages/core/src/create-plugin/template/theme/src/theme/default/view.scss @@ -0,0 +1,3 @@ +:root.{{pluginName}} { + // 视图级主题样式 +} \ No newline at end of file diff --git a/packages/core/src/create-plugin/template/theme/src/theme/index.scss b/packages/core/src/create-plugin/template/theme/src/theme/index.scss index 001af84..7eaf0d6 100644 --- a/packages/core/src/create-plugin/template/theme/src/theme/index.scss +++ b/packages/core/src/create-plugin/template/theme/src/theme/index.scss @@ -1,2 +1,5 @@ -/* 自定义主题 */ -@import './custom-theme'; +/* 引用基础包 */ +@import '../../node_modules/@ibiz-template/web-theme/src/theme/index'; + +/* 引用自定义主题 */ +@import './default/index'; -- Gitee