门户定制

企业门户提供大量配置,以满足客户需求,参考《桌面端门户配置》和《移动端门户配置

在配置不能满足需求时,可以采用门户定制实现个性化需求

门户定制后,如果平台更新了“企业门户应用模板”,则定制的门户,需要

  • 升级 IDE,以得到最新的代码
  • 如果修改了原应用模板中的代码,还需手工合并代码
  • 发布门户应用

上面的过程,在每一次平台更新“企业门户应用模板”后,都需要操作一遍

为解决企业门户应用更新过程繁琐的问题,企业门户 V2 提供“门户自定义”组件,实现除定制门户的开发租户外,其余生产租户的门户无需定制。使用方法如下

  1. 使用一个开发租户用来定制门户,添加企业门户应用,门户应用中自带“门户自定义”组件
  2. 将所有的定制内容都写到“门户自定义”组件内
  3. 定制后,将定制应用中的“门户自定义”组件导出,上传到市场,更新市场中原来的“门户自定义”组件
  4. 使用 system 登录控制台,打开“我的开发-企业应用-企业门户 V2”的云 IDE,发布应用到市场(模板设置时提示“当前服务名为空”,请等待几分钟)
  5. 发布时,企业门户应用自动更新“门户自定义”组件,发布后,其余租户的门户重启即可

当平台升级版本,更新“企业门户应用模板”后,只需执行上面第4步和第5步即可

定制过程

开启定制

开启定制及门户调试方法,参考《门户调试

开启组件定制

开发环境中的组件,一般都是自动升级的,在 IDE 打开时和应用发布时,会从市场下载最新的组件资源。对于需要定制的组件,需要开启组件定制,对于定制状态的组件,系统不进行自动更新操作。

在组件列表中,找到“门户自定义”组件,点击“定制”开启组件定制,如下图所示

图 1

配置定制文件列表

开启定制的应用,使用的应用模板如果升级了,定制的应用可以通过“高级-立即升级”,执行代码升级

1719561121226

升级代码时,系统只对开发者未修改的文件进行代码更新,对于开发者修改过的文件,不进行处理。这就意味着修改过的文件,需要进行手工代码合并。

系统提供两种方法记录文件是否被修改过

  • 自动记录:对文件进行 md5 比较,如果不同,表示是被修改过的文件
  • 手工记录:将增删改的目录或文件,记录在 patchFiles.json 文件中

系统根据有无 patchFiles.json 文件,采用不同的方式判断文件是否修改过。

特别说明

  • 鉴于打开过文件,可能会影响文件 md5 的结果,建议使用手工记录的方式记录修改过的文件
  • 使用文件记录后,对于修改的文件,务必记录在文件中,否则 IDE 池重启后,修改的文件就会被还原

手工记录,参考《配置定制文件

门户定制,一切定制写在“门户自定义”组件内,将组件的前端目录和后端目录,写入配置定制文件 model/patchFiles.json 即可,如下图所示,在 model 目录中添加 patchFiles.json 文件,内容如下

{
    "update": ["UI2/comp/portalConfig",
                "service/comp/portalConfig"]
}

图 1

门户自定义组件

门户自定义组件 portalConfig,用于开发者在企业门户应用中,实现一些定制能力

  • 前端目录为 /model/UI2/comp/portalConfig
  • 后端目录为 /model/service/comp/portalConfig
    • 依赖门户调整开发,需要新增 springboot.embed 标识文件,main 模块会自动将该项目依赖加入到 pom.xml 中
    • 建议使用本地 ide,利用开发工具完成后端代码调试后再进行发布
  • 企业门户应用自带门户自定义组件,所有定制的文件都应在组件目录下
  • 门户自定义组件支持添加页面、数据和服务
  • 门户自定义组件提供扩展机制
    • 支持通过动作拦截,扩展现有的方法
    • 支持预留扩展点

添加页面、数据和服务

门户自定义组件和其他组件一样,支持在组件内添加页面、数据和服务

切换到组件端

IDE 顶部显示“端”列表,默认显示桌面端和移动端,还有在多项目多端中扩展的端。开启组件开发后,“端”列表中会显示出已开启定制的组件,如下图所示

1719812523417

切换到“门户自定义”组件端,页面、数据和服务中显示的是组件内部定义的页面、数据和服务

添加页面

切换到门户自定义组件端,打开“页面”设计区,这里显示的是“门户自定义”组件中的目录和文件,在组件目录上添加页面,如下图所示

1720432341193

文件类型选择页面,页面类型选择页面,会在组件的 dialog 目录下创建页面,如果没有 dialog 目录会创建 dialog 目录,如下图所示

1720432370931

添加数据

切换到门户自定义组件端,打开“数据”设计区,这里显示的是在“门户自定义”组件中定义的数据集,如下图所示

1719812567469

添加服务

切换到门户自定义组件端,打开“服务”设计区,这里显示的是在“门户自定义”组件中定义的服务,如下图所示

1719812602616

组件扩展

在 /UI2/pcx/portal.meta.json 描述文件中,列举了企业门户的所有配置项。包括门户页 index 和登录页 login 中的动作、方法和变量

  • 动作(类型 type 是 action):支持拦截处理,3个拦截时机:执行前 @before、执行后 @after、执行中 @replace。原则上所有页面实例上的函数,都可以作为 action 进行拦截,在描述中的函数是尽量保证兼容性的稳定接口,其他没有声明的接口,不能保证版本迭代过程的兼容性
  • 方法(类型 type 是 funciton):扩展点,通过定义一个函数实现扩展
  • 变量(类型 type 是 string):扩展点,通过定义一个变量实现扩展

门户页扩展

门户页 /entry/pcxapp/pcx/index.w 除了描述文件中,列举的方法,还提供了整体布局、顶部导航栏、左侧功能树的渲染方法,见下表

方法 用途 案例
headerActionsRender 顶部导航栏渲染 after-添加下拉组织选择
headerAvatarRender 头像渲染
headerTitleRender LOGO、标题渲染
menuRender 功能树渲染 replace-双层功能树
subMenuItemRender 子菜单渲染
menuItemRender 菜单项渲染
menuFooterRender 功能树底部区域渲染
layoutRender 整体布局渲染 after-顶部显示第三方系统入口
layoutContentRender 布局内容渲染 after-自定义渲染内容,默认展示初始tab内容

门户页还包括一个订阅组件,订阅组件的相关方法,也支持扩展,见下表

方法 用途 案例
onWxSubscribeMessage 订阅组件接收消息方法 after-右下角消息弹出提醒
setNotice 设置消息 after-显示待办任务数

系统使用 this.getConfig('xxx') 定义扩展点,例如在获取所有菜单数据 fetchMenu 方法中,定义 onProcessMenu 扩展点,代码如下

    //自定义处理菜单数据
    let defineMenus = await this.getConfig('onProcessMenu')?.({ menus });
扩展点 用途 案例
onProcessMenu({ menus }) 处理菜单数据 自定义登录 URL
onProcessOrg({ orgsArr, userInfo }) 处理组织信息
onProcessGroup({ groupArr, userInfo }) 处理组信息
onProcessUser({ user, userInfo }) 处理用户信息
onProcessUserName({ currentOrgName,userInfo }) 处理用户名
onProcessUserMenu({ menuItems,userInfo }) 处理右上角下拉菜单

登录页扩展

登录页 /entry/pcxapp/pcx/user/login.w 提供初始化页面状态、登录框的渲染方法,见下表

方法 用途 案例
onInitState 初始化页面状态 before-第三方密码登录
loginRender 登录框渲染 before-自定义登录页

其他预留扩展点

在 config.components.uixContainer.UserImplement 中包括如下扩展点

扩展点 用途 案例
loginUrl 登录 URL 自定义登录 URL
loginResultProcess(res) 登录结果处理 自定义登录 URL

使用动作拦截

针对页面已有的方法,根据页面路径、方法名,定义相应拦截时机的方法

  • @before:原方法执行前执行,参数:(...args),其中 args 是原方法自带参数
  • @after:原方法执行后执行,参数:(result,...args),其中 result 是原方法返回数据,args 是原方法自带参数
  • @replace:替换原方法,参数:(...args),其中 args 是原方法自带参数

特别说明

  • 上述3种方法,async 标识必须与原方法同步,即原方法是异步,自定义方法才能使用异步,否则不能使用
  • 上述3种方法,可同时使用
  • 自定义方法必须写在 w 页面路径下,写在 js 路径下无效

定义门户页 menuRender 方法的3个拦截时机的示例代码如下

        let portalConfig = {
            "config": {
                "/entry": {
                    "/pcxapp": {
                        "/pcx": {
                            "/index.w": {
                                "menuRender":{//方法
                                    /**
                                        * 原方法执行前执行
                                        * @param  {...any} args 原方法自带参数
                                        */
                                    "@before":(...args)=>{

                                    },
                                    /**
                                        * 原方法执行后执行
                                        * @param {*} result 原方法返回数据
                                        * @param  {...any} args 原方法自带参数
                                        */
                                    "@after":(result,...args)=>{

                                    },
                                    /**
                                        * 替换原方法
                                        * @param  {...any} args 原方法自带参数
                                        */
                                    "@replace":(...args)=>{

                                    }
                                }
                            }
                        }
                    }
                }
            }
        };

使用预留扩展点

根据扩展点所在的路径,定义相应的方法或变量。方法是同步还是异步,根据实际需求进行定制即可。使用扩展点示例如下

        let portalConfig = {
            "config": {
                "components": {
                    "uixContainer": {
                        "UserImplement": {
                             "loginUrl": "xxx",
                        }
                    }
                },
                "/entry": {
                    "/pcxapp": {
                        "/pcx": {
                            "/index.w": {
                                "onProcessMenu": ({ menus }) => {

                                }
                            }
                        }
                    }
                }
            }
        };

配置文件

桌面端门户的扩展点方法写在 /UI2/comp/portalConfig/components/portalConfig/portalConfig.config.pc.js 文件中 移动端门户的扩展点方法写在 /UI2/comp/portalConfig/components/portalConfig/portalConfig.config.mobile.js 文件中 门户的公共扩展点方法写在 /UI2/comp/portalConfig/components/portalConfig/portalConfig.config.js 文件中

特别说明

  • 配置文件识别顺序为:先找 portalConfig.config.(pc/mobile).js,再找 portalConfig.config.js
  • portalConfig.config.js 文件是“门户自定义”组件的基础脚本,该文件“不能删除,必须保留”,在运行时不区分端类型,即无论桌面端还是移动端都会加载执行
  • 如果定制内容是“桌面端专属”,需要复制 portalConfig.config.js 为 portalConfig.config.pc.js 文件,并在其脚本内进行内容定制
  • 如果定制内容是“移动端专属”,需要复制 portalConfig.config.js 为 portalConfig.config.mobile.js 文件,并在其脚本内进行移动内容定制

配置文件,示例代码如下

import { merge } from "lodash";
import ConfigContextProcessor from 'core/framework/ConfigContextProcessor';

export default {

    processConfigContext(configContext) {
    },

    //自定义
    async onConfigContextInit(configContextProcessor) {
        //获取当前页
        let _this = configContextProcessor.page;

        let portalConfig = {
            "config": {
                "/entry": {
                    "/pcxapp": {
                        "/pcx": {
                            "/index.w": {
                                "menuRender":{//方法
                                    /**
                                        * 原方法执行前执行
                                        * @param  {...any} args 原方法自带参数
                                        */
                                    "@before":(...args)=>{

                                    },
                                    /**
                                        * 原方法执行后执行
                                        * @param {*} result 原方法返回数据
                                        * @param  {...any} args 原方法自带参数
                                        */
                                    "@after":(result,...args)=>{

                                    },
                                    /**
                                        * 替换原方法
                                        * @param  {...any} args 原方法自带参数
                                        */
                                    "@replace":(...args)=>{

                                    }
                                },
                                /**
                                    * 定义动态方法
                                    * @param {*} param0 动态方法对应的参数,根据业务需要自行传参
                                    */
                                "onProcessMenu": function ({ menus }) {

                                }
                            }
                        }
                    }
                }
            }
        };
        //处理自定义内容,固定内容请勿随意删除
        merge(_this.configContext, portalConfig);
        ConfigContextProcessor.enhancePageAdvice(_this);
    }
}

results matching ""

    No results matching ""