本文描述了在系统门户开发中,实现用户登录后默认打开指定应用首页界面的需求场景、思路与方案以及具体的实现过程。通过新建单据页面分配应用首页,注册插件实现权限控制,利用开发平台扩展门户管理和应用页签,最终实现用户登录后自动打开指定应用首页,并支持从应用卡片跳转到对应页签的功能。实现过程涉及代码逻辑,如权限检查、应用信息查询、页面扩展等。
关键词:门户首页
一、需求场景
用户登录系统后默认打开指定应用的首页界面
二、思路与方案
因涉及对系统门户进行开发,故我们可在登录系统之后,在【首页】界面按 ctrl+alt+g 进入其设计器界面,然后针对该页面进行二次扩展开发即可。
三、实现过程
1. 新建单据页面,用于管理员给各员工分配登录后默认进入的应用首页,其设计器界面如下图所示。
2. 在第 1 步新建的页面中注册插件,并实现业务逻辑:如果登录用户是管理员, 则可看到所有人员和对应分配的应用; 如果登录用户是普通用户, 则只能看到本人已分配的应用, 且不能新增、删除、修改应用。
@Override public void afterCreateNewData(EventObject e) { super.afterCreateNewData(e); // 获取当前登录用户的id String currUserId = RequestContext.get().getUserId(); // 判断当前登录用户是否为管理员 boolean isAdminUser = PermissionServiceHelper.isAdminUser(Long.valueOf(currUserId)); // 如果当前登录用户不是管理员,则隐藏用户(单据体)和应用(子单据体)上的"新增"、"删除"按钮、"保存"、"取消"按钮 getView().setVisible(isAdminUser, "kdec_advconap", "kdec_advcontoolbarap1", "kdec_flex_button"); } /** * 将用户列表数据和应用列表数据加载到页面上 */ @Override public void afterBindData(EventObject e) { super.afterBindData(e); this.setPageStyle(e); } /** * 如果登录用户是管理员,则可看到所有人员和对应分配的应用 * 如果登录用户是普通用户,则只能看到本人已分配的应用,且不能新增、删除、修改应用 * @param e */ private void setPageStyle(EventObject e) { // 获取用户(单据体)控件 EntryGrid userEntity = getControl(KEY_USER_ENTITY); // 临时变量,当前登录用户在用户(单据体)中所在的行号 int currUserEntryRowIndex = -1; // 每页展示记录的行数 int userEntrypageRows = userEntity.getPageRow(); // 当前页码 int currUserEntryPageNo = 0; // 用户(单据体)是否分页 Boolean userEntityIsSplitPage = Boolean.valueOf(userEntity.isSplitPage()); // 获取当前登录用户的id String currUserId = RequestContext.get().getUserId(); // 当前登陆人员对应分配的应用 DynamicObjectCollection apps = null; // 查询所有的用户和分配的应用信息 // 如修改了用户(单据体)的标识,则变量selectFields中需同步修改 String selectFields = "id, kdec_entryentity_user, kdec_entryentity_user.kdec_user, " + "kdec_entryentity_user.kdec_subentryentity_app, " + "kdec_entryentity_user.kdec_subentryentity_app.*"; DynamicObject [] datas = BusinessDataServiceHelper.load(BILL, selectFields, null); int totalDataCnt = datas.length; String tempUserId = null; for (int i = 0; i < totalDataCnt; i++) { // 获取所有已添加的用户信息 DynamicObjectCollection users = datas[i].getDynamicObjectCollection(KEY_USER_ENTITY); int userCnt = users.size(); for (int j = 0; j < userCnt; j++) { tempUserId = String.valueOf(users.get(j).getDynamicObject(KEY_USER_ENTITY_USER).getPkValue()); if (StringUtils.equals(currUserId, tempUserId)) { apps = users.get(j).getDynamicObjectCollection(KEY_APP_ENTITY); if (userEntityIsSplitPage) { currUserEntryPageNo = j / userEntrypageRows; currUserEntryRowIndex = j % userEntrypageRows; } else { currUserEntryRowIndex = j; } } } } // 判断当前登录用户是否为管理员 boolean isAdminUser = PermissionServiceHelper.isAdminUser(Long.valueOf(currUserId)); // 如果当前登录用户不是管理员,则将用户(单据体)中的焦点聚焦在当前登录用户所在的行,并隐藏用户(单据体)和应用(子单据体)上的“新增”、"删除"按钮、锁定应用字段列 if (!isAdminUser) { // 翻页 int tempCurrUserEntryPageNo = currUserEntryPageNo; while (tempCurrUserEntryPageNo > 0) { userEntity.next(); tempCurrUserEntryPageNo--; } // 选中当前登录用户在用户(单据体)中所在的行 userEntity.selectRows((currUserEntryPageNo * userEntrypageRows + currUserEntryRowIndex), true); // 隐藏用户(单据体) & 应用(子单据体)上的"新增"、"删除"按钮 getView().setVisible(false, "kdec_advconap", "kdec_advcontoolbarap1"); for (int i = 0; apps != null && i < apps.size(); i++) { // 锁定应用(子单据体)上的应用字段列 getView().setEnable(false, i, KEY_APP_ENTITY_FIELDS[1], KEY_APP_ENTITY_FIELDS[2]); } } }
3. 进入【开发平台】->【系统服务云】,点击【门户管理】应用右下角的扩展图标进行应用扩展,然后进入扩展后的【门户管理】应用,在【首页】分组找到页面“PC主页面”(pc_main_console),点击左下角的扩展图标进行页面扩展。
4. 在第 3 步扩展后的页面“PC主页面(扩)”(****_pc_main_console_ext,****代表开发商标识符)中注册插件,实现业务逻辑:用户登录后自动打开指定应用的首页。
@Override public void afterCreateNewData(EventObject e) { super.afterCreateNewData(e); // 显示页签:指定应用的首页界面 this.showSpecialForm("tabap"); } private void showSpecialForm(String tagetKey) { // 获取当前登陆用户的ID String currUserId = RequestContext.get().getUserId(); // 如修改了用户(单据体)和应用(子单据体)的标识,则变量selectFields,filter中需同步修改 String selectFields = "id, kdec_entryentity_user.kdec_subentryentity_app.kdec_bizapp.id, " + "kdec_entryentity_user.kdec_subentryentity_app.kdec_bizapp.number, " + "kdec_entryentity_user.kdec_subentryentity_app.kdec_bizapp.name, " + "kdec_entryentity_user.kdec_subentryentity_app.kdec_bizapp.deploystatus, " + "kdec_entryentity_user.kdec_subentryentity_app.kdec_bizapp.mainformid, " + "kdec_entryentity_user.kdec_subentryentity_app.kdec_isdefaultapp"; QFilter filter = new QFilter("kdec_entryentity_user.kdec_user", QCP.equals, currUserId); // 根据当前用户ID查询该用户已分配的应用 DynamicObjectCollection defaultAppCol = QueryServiceHelper.query(BILL, selectFields, filter.toArray()); for (DynamicObject defaultAppInfo : defaultAppCol) { if (defaultAppInfo.getBoolean("kdec_entryentity_user.kdec_subentryentity_app.kdec_isdefaultapp")) { String appId = defaultAppInfo.getString("kdec_entryentity_user.kdec_subentryentity_app.kdec_bizapp.id"); String appNumber = defaultAppInfo.getString("kdec_entryentity_user.kdec_subentryentity_app.kdec_bizapp.number"); String appName = defaultAppInfo.getString("kdec_entryentity_user.kdec_subentryentity_app.kdec_bizapp.name"); String specialFormId = defaultAppInfo.getString("kdec_entryentity_user.kdec_subentryentity_app.kdec_bizapp.mainformid"); // 再次验证当前用户是否是否具有该应用的权限,且该应用是否已启用 Boolean hasPermission = PermissionServiceHelper.checkUserBizApp(Long.valueOf(currUserId), appId); if (StringUtils.equals("2", defaultAppInfo.getString("kdec_entryentity_user.kdec_subentryentity_app.kdec_bizapp.deploystatus")) && hasPermission) { DynamicObject mainPageInfo = BusinessDataServiceHelper.loadSingleFromCache("bos_entitymeta", new QFilter[] {new QFilter("id", QCP.equals, specialFormId)}); specialFormId = mainPageInfo.getString("number"); // 进入指定的默认应用首页 this.showDesignatedAppMainPage(appNumber, appName, tagetKey, specialFormId); } break; } } }
5. 进入【开发平台】->【系统服务云】->【门户管理(扩)】应用 ->【应用页签】,找到页面“我的应用”(tenant_myapp),点击左下角的扩展图标进行页面扩展。
6. 在第 5 步扩展后的页面“我的应用(扩)”(****_tenant_myapp_ext,****代表开发商标识符)中注册插件,实现业务逻辑:点击“应用”页面上的应用卡片跳转到对应的页签。
@Override public void itemClick(ItemClickEvent evt) { super.itemClick(evt); String operationKey = evt.getOperationKey(); JSONObject arg = (StringUtils.isEmpty(evt.getItemKey()) ? null : (JSONObject) JSON.parse(evt.getItemKey())); switch (operationKey) { case "gotoapp": this.gotoApp(arg); break; } } private void gotoApp(JSONObject arg) { // 当前登录用户分配的默认应用 String specialAppId = null; String specialAppNumber = null; String specialAppName = null; String specialFormId = null; // 获取当前登录用户 String currUserId = RequestContext.get().getUserId(); // 如修改了用户(单据体)和应用(子单据体)的标识,则变量selectFields, filter中需同步修改 String selectFields = "id, kdec_entryentity_user.kdec_subentryentity_app.kdec_bizapp.id, " + "kdec_entryentity_user.kdec_subentryentity_app.kdec_bizapp.number, " + "kdec_entryentity_user.kdec_subentryentity_app.kdec_bizapp.name, " + "kdec_entryentity_user.kdec_subentryentity_app.kdec_bizapp.deploystatus, " + "kdec_entryentity_user.kdec_subentryentity_app.kdec_bizapp.mainformid, " + "kdec_entryentity_user.kdec_subentryentity_app.kdec_isdefaultapp"; QFilter filter = new QFilter("kdec_entryentity_user.kdec_user", QCP.equals, currUserId); // 根据当前用户ID查询该用户已分配的应用 DynamicObjectCollection defaultAppCol = QueryServiceHelper.query(BILL, selectFields, filter.toArray()); for (DynamicObject defaultAppInfo : defaultAppCol) { if (defaultAppInfo.getBoolean("kdec_entryentity_user.kdec_subentryentity_app.kdec_isdefaultapp")) { specialAppId = defaultAppInfo.getString("kdec_entryentity_user.kdec_subentryentity_app.kdec_bizapp.id"); specialAppNumber = defaultAppInfo.getString("kdec_entryentity_user.kdec_subentryentity_app.kdec_bizapp.number"); specialAppName = defaultAppInfo.getString("kdec_entryentity_user.kdec_subentryentity_app.kdec_bizapp.name"); specialFormId = defaultAppInfo.getString("kdec_entryentity_user.kdec_subentryentity_app.kdec_bizapp.mainformid"); // 再次验证当前用户是否是否具有该应用的权限,且该应用是否已启用 Boolean hasPermission = PermissionServiceHelper.checkUserBizApp(Long.valueOf(currUserId), specialAppId); if (StringUtils.equals("2", defaultAppInfo.getString("kdec_entryentity_user.kdec_subentryentity_app.kdec_bizapp.deploystatus")) && hasPermission) { DynamicObject mainPageInfo = BusinessDataServiceHelper.loadSingleFromCache("bos_entitymeta", new QFilter[] {new QFilter("id", QFilter.equals, specialFormId)}); specialFormId = mainPageInfo.getString("number"); } break; } } // 获取当前点击的应用的ID String appId = arg.getString("appid"); if (StringUtils.equals(specialAppId, appId)) { IFormView mainPageView = getView().getMainView(); String pageId = mainPageView.getPageId(); if (mainPageView.getViewNoPlugin(specialAppNumber + pageId) != null) { Map<String, Object> map = new HashMap<String, Object>(); map.put("view", getView()); map.put("appname", specialAppName); map.put("formnumber", specialFormId); map.put("parametertype", "FormShowParameter"); PopAppUtils.activatePage(specialAppNumber + pageId, mainPageView, map); } } getView().sendFormAction(getView().getMainView()); }
四、效果图
1. 以具有管理员权限的账号登录系统,打开【案例云】->【案例合集】->【首页固定指定应用页签】->【人员应用维护】,维护数据:给指定人员分配其登录系统后默认进入的应用。
例:管理员为用户(宋江)分配默认进入【消息中心】应用。
2. 换上一步被指定的人员登录系统即可查看效果。
例:普通用户(宋江、不具有管理员权限)登录系统即定位到【消息中心】首页界面。
五、开发环境版本
不限
六、注意事项
1. 开发该功能 请务必在本地轻量级环境中进行,不要团队协作开发环境中开发。开发过程中会扩展门户首页页面注册插件,如果在团队协作开发环境中进行,会导致团队内的其他成员在登录系统的时候报异常:ClassNotFound。只有在本地轻量级开发环境中开发完成才能部署到团队协作开发环境、测试环境中。
2. 文章附件包含样例元数据补丁包、Java代码源码。解压之后请在MC中以更新补丁的形式将元数据压缩包导入平台里,Java代码放到本地开发工具(Eclipse/Idea)中,重启服务,运行代码即可查看效果。
七、参考资料
用户登录系统后默认打开指定应用的首页界面.zip(115.30KB)
推荐阅读