用户服务模块
系统使用 UAA(User Account and Authentication) 实现用户账户和身份验证。每个应用中都包括用户服务模块,位于 model/service/uaa 目录。下图是企业门户应用架构图中的用户服务模块
- 在用户服务模块中,定义了组织机构和用户的数据模型:orgs.data.m 和 users.data.m
- 在页面上,支持添加组织机构和用户的数据组件
- 在 Java 中,支持引用用户服务模块中的数据对象 import uaa.model.*;
- 系统使用服务代理,将使用 DBRest 访问当前应用的组织机构和用户数据的请求,代理到企业门户的组织机构和用户数据上,即对于 /xxx/uaa 请求改为 /entry/aaa 的请求
- 企业门户应用和企业应用是两个独立的应用,一般情况下,它们连接的是不同的数据库,不能执行数据库的关联查询,建议业务数据中冗余存储组织和用户信息。如需关联查询,参考《输出数据集》中的关联查询
- 用户服务模块提供客户端访问 API:com.justep.clients.api.UaaAcountApi
- 用户服务模块提供4个环境变量
- 开发时运行时都可配置,开发时配置如上图所示,运行是配置如下图所示
- 是否自动通知:当组织用户数据变化后,是否自动发送通知给“组织同步配置”中配置的应用
- 最小时间间隔:发送通知最小时间间隔
- 账户锁定时间:设置多次登录失败后,用户锁定时间(单位:分钟),在锁定时间内,密码输入正确也不能登录
- 用户默认密码:设置新建用户的密码,系统默认密码是 aSDF1@#$
前端访问组织
前端访问组织支持两种方式:
- 使用数据组件:获取组织数据
- 使用组织组件:显示组织、选择组织
获取组织数据
用户服务 UAA 提供的“组织机构”数据集和“用户”数据集,如下图所示,放到页面上,使用方法同当前应用中的数据集
使用组织机构数据集,获取组织数据
使用用户数据集,获取用户数据
特别说明
- 访问当前应用的用户服务中的数据集,访问到的是企业门户中用户服务的数据集,是因为系统默认做了服务代理,如下图所示,即所有对于 uaa 的访问都会访问到 /entry/uaa 上
- 企业门户应用和当前应用是两个独立的应用,一般情况下,它们连接的是不同的数据库,不能执行数据库的关联查询,系统支持跨库关联查询,参考《输出数据集》中的关联查询
组织组件
系统提供5个组织组件,用于下拉选择组织,弹出选择组织以及显示组织树
组织选择器
组织选择器组件用于下拉选择组织,支持单选和多选,在选择器组件的基础上,绑定了下拉数据,运行效果如下图所示
组件属性和用法同选择器组件(参考《桌面端表单类组件》),多了一个“包含组织类型”属性,用来设置下拉的组织树上显示哪些组织类型,如下图所示,只选择了机构和部门,意味着下拉的组织树中只显示机构和部门,不会显示岗位和人员成员
组织树
组织树组件用于显示组织树,在树组件的基础上,绑定了组织数据,运行效果如下图所示
组件属性和用法同树组件(参考《桌面端列表类组件》),多了一个“包含组织类型”属性,用来设置组织树上显示哪些组织类型,参考组织选择器一节的说明
组织对话框
组织对话框组件用于弹出选择组织,支持单选和多选,在对话框组件的基础上,绑定了组织数据,运行效果如下图所示
组件属性和用法同对话框组件,多了一些属性
多选
单选的界面如上图所示,多选的界面如下图所示,左侧是全部组织,右侧是已选择组织
级联选择
级联选择是选择父节点后,会自动选择已经加载到前端的子节点
包含组织类型
使用方法同组织选择器组件
禁用组织类型
设置能显示,但是不能选择的组织类型
禁用组织
设置能显示,但是不能选择的组织节点。例如下面设置的是禁用名为“北京公司”的组织节点
禁用组织中的行记录,表示加载到前端的组织数据中的每一条记录
运行效果如下图所示
除了支持表达式,也支持调用 JS 方法,返回 true,表示禁用该组织节点。JS 方法示例代码如下
getDisabledOrg = (row) =>{
return row.name == "北京公司";
}
表达式编辑器中调用 JS 方法,传入行记录,如下图所示
- react:$page.getDisabledOrg(行记录)
- vue:getDisabledOrg(行记录)
图标
图标属性用于设置组织节点显示的图标,为空则显示原始图片
上图中“上海公司”显示了名为 fast-backward,outlined 的图标,其它组织节点照常显示,设计界面如下图所示
表达式编辑器中支持选择图标
默认展开
设置对话框中的组织树,默认展开根或者展开全部
根过滤条件
设置对话框中的组织树,显示的根组织节点。默认显示组织树的根组织节点。该属性只在查询根时生效。如下图所示,组织树上仅显示上海公司和领导办公室。图中的阳光集团是虚根,仅显示,不能选择
根过滤条件是数据组件的根过滤条件,过滤条件是一个 JSON 数组。写法参考:《JS 动态设置 restData 的 filter》
上图中根组织只显示上海公司和领导办公室,根过滤条件为:[{op:"LBRAC"},{'name':'name','value':'上海公司','op':'eq'},{'name':'name','value':'领导办公室','op':'eq',kind:'or'},{op:"RBRAC"}],注意多个条件时,必须增加左右括号。设计界面如下图所示
数据过滤条件
设置对话框中的组织树,显示的组织节点。默认显示组织树的全部组织节点。该属性在所有查询组织时都生效(包括对根的查询,因此过滤条件中必须考虑包括根的条件)。如下图所示,组织树上仅根组织和显示名称包含“公司”的组织。
数据过滤条件是数据组件的过滤条件,过滤条件是一个 JSON 数组。写法参考:《JS 动态设置 restData 的 filter》
上图中只显示根组织和显示名称包含“公司”的组织,过滤条件为:[{op:'LBRAC'},{'name':'name','value':'公司','op':'ilike'},{'name':'parentID','op':'isNull',kind:'or'},{op:'RBRAC'}],注意多个条件时,必须增加左右括号。设计界面如下图所示
默认选中条件
默认选中条件属性用于,当组织对话框组件设置为多选时,设置选择框右侧区域默认显示的组织,如下图所示,默认显示了北京公司和上海公司
特别说明
- 组织对话框组件设置为多选时,默认选中条件才起作用
- 默认选中条件用于过滤数据,因此它就是数据组件的过滤条件,过滤条件的写法参考:《JS 动态设置 restData 的 filter》
上图中显示了北京公司和上海公司,默认选中条件为:[{'name': 'name', 'value': '北京公司', 'op': 'eq'}, {'name': 'name', 'value': '上海公司', 'op': 'eq', 'kind': 'or'}],设计界面如下图所示
数据映射
弹出窗口中的“结果数据集”是用户选择的组织,和主窗口的数据映射,获取用户选择的组织,如下图所示
消息接收
数据映射不能满足需求时,在消息接收事件中,写代码处理组织对话框返回的数据,返回的数据格式如下图所示
在消息接收事件中处理返回的数据 message.data,示例代码如下
onOrgDialog2Message = ({message}) => {
if(!message.data) return;
let createDeptIDs = [];
let createDepts = [];
message.data.forEach(item=>createDepts.push(item.name));
message.data.forEach(item=>createDeptIDs.push(item.id));
this.comp("orderData").setValue("createDeptID",createDeptIDs.join(","));
this.comp("orderData").setValue("createDept",createDepts.join(","));
}
组织列表
组织列表组件用于弹出选择组织,支持单选和多选,弹出组织对话框,运行效果如下图所示
组织列表组件中组织对话框的使用,参考上面“组织对话框”一节
组织列表组件支持将组织表中的三列数据,写入业务表,对应关系如下,设计界面如下图所示
- 选择项值:写入绑定数据列
- 选择项名称:写入绑定显示列
- 选择项扩展:写入绑定扩展列
分隔符属性用于多选时,选项值的拼接,默认使用逗号拼接,如下图所示
用户对话框
用户对话框组件用于弹出选择用户,支持单选和多选,在对话框组件的基础上,绑定了组织数据、用户数据,运行效果如下图所示
用户对话框分为4个区域
- 所属部门:通过“显示组织机构、所属部门、所属部门条件”等属性设置,默认是当前登录者的部门
- 组织机构:通过“显示组织机构、排除组织名称、排除组织类型、排除所属部门、组织机构根、组织机构根条件”等属性设置,默认是当前登录者的机构
- 用户列表:通过“默认过滤方式、显示副岗、特定组织、特定组织条件”等属性设置,默认过滤方式为“所属部门”,则打开用户对话框时,显示所属部门下的用户列表,默认过滤方式为“组织机构”,则显示当前组织机构下的用户列表。之后随组织机构和所属部门的切换而改变
- 已选人员:通过“默认选中用户、默认选中用户条件”等属性设置打开用户对话框时显示的人员
组件属性和用法同对话框组件,多了一些属性
多选
设置单选或多选
显示副岗
设置用户列表中只显示主岗,还是也显示副岗
显示确认
设置点击确定按钮关闭用户对话框时,是否弹出确认提示
显示组织机构
设置用户对话框中是否显示左侧的所属部门和组织树
排除组织名称
设置在左侧组织树上不显示的组织名称,多个组织用逗号分隔,例如:北京公司,上海公司
排除组织类型
设置在左侧组织树上不显示的组织类型,多个组织类型用逗号分隔,例如:不显示岗位设置为pos
排除所属部门
设置在左侧组织树上不显示所属部门
机构类型、部门类型、岗位类型
重新设置机构类型、部门类型和岗位类型,改变用户对话框里面的默认行为
默认过滤方式
设置用户对话框右侧用户列表的默认过滤条件
- 所属部门:显示所属部门下的用户
- 组织机构:显示当前用户所属机构下的用户
默认选中用户、默认选中用户条件
设置用户对话框中默认选中的用户
- 默认选中用户:设置人员成员的orgid,多个人员成员的orgid 用逗号分隔,例如:10003@10001,10003@10002
- 默认选中用户条件:设置数据组件的过滤条件,过滤条件是一个 JSON 数组。写法参考:《JS 动态设置 restData 的 filter》。例如:默认用户设置为“领导1”的代码:[{'name':'name','value':'领导1','op':'eq'}] 默认用户设置为“领导1”和“领导2”的代码:[{'name':'name','value':'领导1','op':'eq'},{'name':'name','value':'领导1','op':'eq','kind':'or'}]
拥有角色
设置用户对话框右侧用户列表的过滤条件
只能设置一个角色编码,设置后在左侧组织的基础上过滤显示拥有这个角色的用户
所属部门、所属部门条件
设置用户对话框中显示的所属部门,默认是当前登录者的部门
- 所属部门:设置部门 ID,例如:10003
- 所属部门条件:设置数据组件的过滤条件,过滤条件是一个 JSON 数组。写法参考:《JS 动态设置 restData 的 filter》。例如:所属部门设置为“北京公司”的代码:[{'name':'name','value':'北京公司','op':'eq'}]
组织机构根、组织机构根条件
设置用户对话框中组织树的根节点
- 组织机构根:设置组织 ID,例如:10004
- 组织机构根条件:设置数据组件的过滤条件,过滤条件是一个 JSON 数组。写法参考:《JS 动态设置 restData 的 filter》。 例如:根组织设置为“北京公司”的代码:[{'name':'name','value':'北京公司','op':'eq'}] 根组织设置为“组织根节点”的代码:[{'name':'parentID','op':'isNull'}]
特定组织、特定组织条件
特定组织设置后,用户对话框不显示左侧所属部门和组织树。只显示用户列表和已选择用户列表。用户列表中显示特定组织下的人员。
- 特定组织:设置组织 ID,多个组织 ID 用逗号分隔,例如:10005,10006
- 特定组织条件:设置数据组件的过滤条件,过滤条件是一个 JSON 数组。写法参考:《JS 动态设置 restData 的 filter》。例如:特定组织设置为“北京公司”的代码:[{'name':'name','value':'北京公司','op':'eq'}]
数据映射
弹出窗口中的“选中用户”是用户选择的用户,和主窗口的数据映射,获取用户选择的用户,如下图所示
消息接收
数据映射不能满足需求时,在消息接收事件中,写代码处理用户对话框返回的数据,用法同组织对话框的消息接收
后端访问组织
组织表在企业门户应用中,在企业应用中使用 DBRest Java SDK 访问,参考《DBRest Java SDK》
下面列举三个案例
查询组织表
组织表 orgs,SQL 写为
select * from orgs
Java 代码如下
import uaa.model.*;
import com.justep.tools.mybatis.*;
import com.justep.tools.DbrestResult;
public List<Orgs> getOrg() throws Exception {
DbrestWrapper<?> wrapper = new DbrestWrapper<>("entry","uaa","orgs");
List<Orgs> list = DbrestUtil.selectAll(wrapper, Orgs.class);
return list;
}
查询组织表关联用户表
组织表 orgs,用户表 users,组织表关联用户表,查询用户手机号。SQL 写为
select orgs.*,users.phone_number from orgs left join users on orgs.id = users.id
Java 代码如下,在 Java 中使用 DbrestResult 时,可以调用 DbrestResult 的 toJson 方法获取 JSON 对象
import com.justep.tools.mybatis.*;
import com.justep.tools.DbrestResult;
public String getOrgIncludePhone() throws Exception {
DbrestWrapper<?> wrapper = new DbrestWrapper<>("entry","uaa","orgs");
wrapper.select("A.*","B.phoneNumber");
wrapper.setMainTableAlias("A");
wrapper.leftJoin("users").alias("B").on("id.eq.id");
DbrestResult ret = DbrestUtil.get(wrapper, null);
return ret.getResult();
}
查询组织表,子查询用户表
组织表 orgs,用户表 users,通过用户表的主岗组织 ID(data7)只查询主岗人员成员。SQL 写为
select orgs.* from orgs where orgs.type!='psm' or orgs.org_id in (select concat(id,'@',data7) from users)
Java 代码如下
import com.justep.tools.mybatis.*;
import com.justep.tools.DbrestResult;
import uaa.model.*;
public List<Orgs> getMainOrg() throws Exception {
DbrestWrapper<?> wrapper = (DbrestWrapper<?>)new DbrestWrapper<String>("entry", "uaa", "orgs");
DbrestWrapper<?> subquery0 = new DbrestWrapper<String>("entry", "uaa", "users");
subquery0.select("concat(id,'@',data7)");
wrapper.ne("type","psm").or().in("orgID", DbrestWrapper.SubQueryPrefix + "subquery0");
wrapper.addSubQueryWrapper("subquery0", subquery0);
List<Orgs> list = DbrestUtil.selectAll(wrapper, Orgs.class);
return list;
}
上面代码中使用了 concat 函数,需要在 DBRest 的函数白名单中定义后才能使用。在应用服务管理中,打开企业门户的环境设置,如下图所示
设置 DBRest 的环境变量:函数白名单,如下图所示,多个函数名之间用逗号分隔