页面树结构
转至元数据结尾
转至元数据起始

在第三方系统用户集成文档中,介绍了三种同步用户到 Smartbi 系统中的方法。对于其中的第二种方法“在第三方系统中使用 Smartbi 用户管理的远程调用接口实现用户等信息的同步”,我们也可以创建自定义计划任务,调用 SDK 接口方法,进行用户和机构信息同步。具体操作如下:

 

1、参考:任务 新建计划任务任务类型 选择“定制”,然后将如下代码粘贴到代码编辑区,根据实际业务逻辑修改。

用户和机构自动同步”,自定义计划任务代码:

importPackage(Packages.java.io);
importPackage(Packages.java.lang);
importPackage(Packages.java.util);
importPackage(Packages.smartbi.usermanager);
importPackage(Packages.smartbi.sdk);
importPackage(Packages.smartbi.sdk.service.user);
importPackage(Packages.smartbi.sdk.service.datasource);
 
/**
 * 从外部数据库中定时同步用户、机构信息到知识库中
 *
 * 代码说明:
 *      1)该同步代码默认会在"根组"下创建一个"顶级机构",所有同步过来的机构皆是其子机构
 *      2)用户可以属于多个机构,多个机构名称之间用 # 号分割
 */
var usrManagerService = new UserManagerService(connector);
var datasrcService = new DataSourceService(connector);
 
//
// 创建"顶级机构"
// 下面这段代码不能删除,如果不需要"顶级机构"可以将needTopGroup设置为false   
//
var needTopGroup = true; // 是否创建一个"顶级机构"
var topGroup = usrManagerService.getDepartmentById("DEPARTMENT");
if (needTopGroup) {
    topGroup = usrManagerService.getDepartmentByName("YourTopGroupName"); //需要建立的顶级机构名称
    if (!topGroup) {
        var groupId = usrManagerService.createDepartment("DEPARTMENT", "YourTopGroupName", "YourTopGroupName", "", "");   //在根组下建立顶级机构
        topGroup = usrManagerService.getDepartmentById(groupId);
    }
}
 
//
// 同步机构:获取第三方系统中的机构信息
// 该SQL语句获取第三方系统中的机构信息,查询字段由用户根据第三方系统机构表结构自主修改
var sqlGroup = "select orgName, orgAlias, orgParentName, isUse, orgLevel from org order by orgLevel"; 
var gridDataGroup = datasrcService.executeNoCacheable("DS.northwind", sqlGroup);
for (var i = 0; i < gridDataGroup.getRowsCount(); i++) {
    var orgName       = gridDataGroup.get(i, 0).getValue();
    var orgAlias      = gridDataGroup.get(i, 1).getValue();
    var orgParentName = gridDataGroup.get(i, 2).getValue();
    var isUse         = gridDataGroup.get(i, 3).getValue();
    System.out.println("=====正在同步机构:名称/别名/父机构/是否生效:" + orgName + "/" + orgAlias + "/" + orgParentName + "/" + isUse);
    // 判断机构是否已经同步,根据机构名称判断是否存在
    var group = usrManagerService.getDepartmentByName(orgName);
    if (!group) { //如果不存在则创建
        var parentGroup = usrManagerService.getDepartmentByName(orgParentName);//父机构
        if (!parentGroup) 
            parentGroup = topGroup;
        usrManagerService.createDepartment(parentGroup.getId(), orgName, orgAlias, "", "");
    } else { //如果存在则判断父机构是否正确
        var parentGroup = usrManagerService.getDepartmentByName(orgParentName);
        if (parentGroup && (parentGroup.getId() != usrManagerService.getParentDepartment(group.getId()).getId())) {
            usrManagerService.moveDepartment(group.getId(), parentGroup.getId());
        }
    }
}
 
//
// 同步角色:获取第三方系统中的角色信息,orgName的意思是表示这个角色是建立在哪个组下的
//
var sqlRole = "select roleName, roleAlias, orgName from roles"; // 该SQL语句获取第三方系统中的机构信息
var gridDataRole = datasrcService.executeNoCacheable("DS.northwind", sqlRole);
for (var i = 0; i < gridDataRole.getRowsCount(); i++) {
    var roleName  = gridDataRole.get(i, 0).getValue();
    var roleAlias = gridDataRole.get(i, 1).getValue();
    var orgName   = gridDataRole.get(i, 2).getValue();
    System.out.println("=====正在同步角色:名称/别名/父机构:" + roleName + "/" + roleAlias + "/" + orgName);
    var group = topGroup;
    if (orgName) {
        group = usrManagerService.getDepartmentByName(orgName);
		if (group) {
        	orgName = group.getId();
		} else {
			orgName = topGroup.getId();
		}
	}
    // 判断角色是否已经同步
    var role = usrManagerService.getRoleByName2(roleName);
    if (!role) { //如果不存在则创建
        usrManagerService.createRole(roleName, roleAlias, "", orgName);
    } else { //如果存在则判断父机构是否正确
        usrManagerService.updateRole(role.getId(), roleAlias, "");
    }
}

//
// 同步用户:获取第三方系统中的用户信息
//
var sqlUser = "select userName, userAlias, orgName, isUse, userPwd, roleName from orgUser   where  userName not in ('admin','scheduleAdmin','service')"; //同步用户需要时需要排除掉smartbi中内置用户,内置用户有"'admin','scheduleAdmin','service'"  该SQL语句获取第三方系统中的用户信息
var gridDataUser = datasrcService.executeNoCacheable("DS.northwind", sqlUser);
for (var i = 0; i < gridDataUser.getRowsCount(); i++) {
    var userName  = gridDataUser.get(i, 0).getValue();
    var userAlias = gridDataUser.get(i, 1).getValue();
    var orgName   = gridDataUser.get(i, 2).getValue();
    var isUse     = gridDataUser.get(i, 3).getValue();
    var userPwd   = gridDataUser.get(i, 4).getValue();
    var roleName  = gridDataUser.get(i, 5).getValue();
    System.out.println("=====正在同步用户:名称/别名/所属机构/是否生效/密码:" + userName + "/" + userAlias + "/" + orgName + "/" + isUse + "/" + userPwd);
    // 获取用户所属机构ID
    var usrOrgNameList = (orgName || "").split("#");
    var usrOrgIdList = [];
    for (var j = 0; j < usrOrgNameList.length; j++) {
        var parentGroup = usrManagerService.getDepartmentByName(usrOrgNameList[j] || "NonEmptyOrgName");
        if (parentGroup) {
			usrOrgIdList.push(parentGroup.getId());
      	}
    }
    if (usrOrgIdList.length < 1) 
        usrOrgIdList.push(topGroup.getId());
    // 判断用户是否已经同步
    var user = usrManagerService.getUserByName(userName);
    if (!user) {
        // "123456" 是初始密码
        usrManagerService.createUser(usrOrgIdList[0], userName, userAlias, "", "123456", ((isUse) ? true: false));
        user = usrManagerService.getUserByName(userName);
    }
    // 设置用户所属机构
    usrManagerService.assignDepartmentsToUser(user.getId(), usrOrgIdList);
    // 设置用户角色
    var usrRoleNameList = (roleName  || "").split("#");
    var usrRoleIdList = [];
    for (var j = 0; j < usrRoleNameList.length; j++) {
        var userRole = usrManagerService.getRoleByName2(usrRoleNameList[j]);
        if (userRole) {
			usrRoleIdList.push(userRole.getId());
        }
    }
    usrManagerService.assignRolesToUser(user.getId(), usrRoleIdList);
     
	// 更新用户别名、描述等信息
    // updateUser方法会将传入的明文密码,MD5后存入smartbi知识库
    //usrManagerService.updateUser(user.getId(), userAlias, "", userPwd, ((isUse) ? true: false));
    //
    // 或者,调用updateUserByEncryptedPassword方法同步密码
    // 在第三方系统密码的前面添加标识:"0" + MD5; "1" + DES; "2" + 明文密码
    //如果第三方系统中用户密码是以MD5加密的方式储存的,调用updateUserByEncryptedPassword方法时需要在密码前加"0",登录Smartbi时输入加密前的密码
    //如果第三方系统中用户密码是以DES加密的方式储存的,调用updateUserByEncryptedPassword方法时需要在密码前加"1",登录Smartbi时输入加密前的密码
    //如果第三方系统中用户密码是明文存储的,调用updateUserByEncryptedPassword方法时需要在密码前加"2",登录Smartbi时输入不含2的明文才可成功登录
    var encryptedPwd = "0" + userPwd;
    usrManagerService.updateUserByEncryptedPassword(user.getId(), userAlias, "", encryptedPwd, ((isUse) ? true: false));
}
 
//
// 同步完成!
//
System.out.print("\n\n\n\n\n========================================");



注意:请参考代码中的注视,修改其中的必要信息,比如下面这些。

  • usrManagerService.getDepartmentByName("YourTopGroupName"); // 顶级机构名称
  • var sqlGroup = "select orgName, orgAlias, orgParentName, isUse from org"; // 从第三方系统查询机构信息的SQL语句
  • var gridDataGroup = datasrcService.executeNoCacheable("DS.test", sqlGroup); // 第一个参数是“数据源的ID”,需要在“定制管理 -> 数据管理 -> 数据源”中新建关系数据源,所有的SQL需要在该数据源上执行。
  • 该计划任务对用户的同步时,同步的是该用户的所属默认组。若同一个用户存在多条记录,则同步到Smartbi中该用户的所属默认组为最后执行的一条记录。不能同步用户属于多个组的情况。

 

2、保存创建的任务,参考计划 创建一个执行计划,设置定时执行同步任务。

 

您也可以直接下载 示例资源:下载地址,导入本地系统, 根据自己的实际情况对任务代码及计划进行修改

 

  • 无标签

2 评论

  1. 杨礼显 发表:

    用户加密后的密码同步方法 updateUserByEncryptedPassword,签名如下:

    	/**
    	 * 修改用户信息设置加密后的密码
    	 * 
    	 * @param userId
    	 *            用户ID
    	 * @param alias
    	 *            别名
    	 * @param desc
    	 *            描述
    	 * @param password
    	 *            加密密码
    	 * @param isEnabled
    	 *            用户是否可用
    	 * @return 如果修改成功返回true,否则false
    	 */
    	public boolean updateUserByEncryptedPassword(String userId, String alias, String desc,
    			String password, boolean isEnabled);
  2. 郭佳铃 发表:

    若系统使用的是第三封登陆验证类,则运行任务或者计划时会报”Caused by: 连接服务器异常:无法使用“scheduleAdmin”登录应用服务器。“错误。

    此时有两种方式:

    1.在【计划】中修改执行用户为”特定用户“,选择一个可以正常登陆的用户帐号。并且,这种修改方式,只能在计划中测试运行,在任务中测试运行仍然会报错。。

     

    2.修改第三方登陆验证类,将scheduleAdmin用户作为例外,该用户单独使用smartbi的登陆验证流程。