页面树结构

版本比较

标识

  • 该行被添加。
  • 该行被删除。
  • 格式已经改变。


注意

注意:该文档中的更新和覆盖机制,默认覆盖全部用户所属组。

1.说明    

     

...

Smartbi提供创建自定义计划任务,调用 SDK

...

Image Removed

具体操作如下:

...

接口方法,进行用户和机构信息同步的功能。


面板
borderColor#BBBBBB
bgColor#F0F0F0
borderWidth1
borderStylesolid

目录


       Image Added

2.具体操作

1、在系统运维-》计划任务-》任务-》新建任务,任务类型 选择“定制”,然后将如下代码粘贴到代码编辑区,根据实际业务逻辑修改。

...

以下自定义计划任务代码是基于已设置好的数据源ID,将第三方数据库中的用户,机构,角色等信息同步到Smartbi的知识库中。

代码块
languagejs
linenumberstrue

...

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);
  
/**
 * 从外部数据库中定时同步用户、机构、角色信息到知识库中。
 *

...


 * needTopGroup变量用来控制是否创建一个"顶级机构"。
 *      

...

如果needTopGroup为true,则会创建一个名称为topGroupName的机构,同步通过的机构都放到它下面。
 *

...

      如果needTopGroup为false,则不会创建顶级机构,而同步过来的机构全部放到默认的"根组"下面。
 */
var needTopGroup = true;
var topGroupName = "YourTopGroupName";
/**
 * 数据源的ID值。后面sqlGroup、sqlRole、sqlUser等SQL语句都在该数据源下执行。
 */
var datasrcId = "DS.YourDatasourceId";
/**
 * 该SQL语句获取第三方系统中的机构信息。<br/>
 * 注意!可以根据第三方系统中机构表修改下面的SQL语句,但输出字段的个数、顺序,必须和下面的一模一样,否则会出错。
 * 查询结果集需要按顺序排列,越上级的机构需要在结果集排越前,子机构需要排在其所有父机构之后。
 * 

...

     orgName :机构名称
 * 

...

     orgAlias :机构别名
 * 

...

     orgParentName :父机构名称
 *     

...

 

...

isUse :是否有效
 */
var sqlGroup = "select orgName, orgAlias, orgParentName, isUse, orgCode from org";
/**
 * 该SQL语句获取第三方系统中的角色信息。<br/>
 * 注意!可以根据第三方系统中角色表修改下面的SQL语句,但输出字段的个数、顺序,必须和下面的一模一样,否则会出错。
 

...

* 

...

     roleName :角色名称
 *      

...

roleAlias :角色别名
 *   

...

   

...

orgName :机构名称,所创建的角色放在该机构下
 *      orgCode:机构代码,若不需要可以不设置该字段
 */
var sqlRole = "select roleName, roleAlias, orgName from roles";
/**
 * 该SQL语句获取第三方系统中的用户信息。 <br/>
 * 注意!可以根据第三方系统中用户表修改下面的SQL语句,但输出字段的个数、顺序,必须和下面的一模一样,否则会出错。
 * 

...

 

...

 

...

  

...

 

...

userId 

...

: 用户id
 * 

...

 

...

   

...

 

...

userName 

...

:用户名称
 * 

...

 

...

   

...

 userAlias :用户别名
 *      orgName :机构名称,如果一个用户属于多个机构,则orgName字段值是多个机构名称用#拼接在一起,如:org1#org2#org3
 *      isUse :是否有效
 *      userPwd :用户密码
 *      roleName :角色名称,如果一个用户拥有多个角色,则roleName字段值是多个角色名称用#拼接在一起,如:role1#role2#role3
 */
var sqlUser = "select userId, userName, userAlias, orgName, isUse, userPwd, roleName from orgUser  where  userName not in ('admin','scheduleAdmin','service')"; //同步用户需要时需要排除掉smartbi中内置用户,内置用户有"'admin','scheduleAdmin','service'"
/**
 * 是否删除已经赋予的角色。
 * 

...

     如果为true,则之前给用户赋予的角色全部删除;
 * 

...

     如果为false,则之前赋予的角色全部保存,同步时给用户追加新角色。
 */
var removeAllAssignedRoles = true;
  
/**
 * 开始同步机构、角色、用户等信息。
 *

...


 * 如果本项目上不需要同步角色,可以将synchronizeRoleFromOtherDb代码行注释掉。
 *

...


 */
var topGroup = getTopGroup(needTopGroup, topGroupName);
synchronizeGroupFromOtherDb(datasrcId, sqlGroup, topGroup);
synchronizeRoleFromOtherDb(datasrcId, sqlRole, topGroup);
synchronizeUserFromOtherDb(datasrcId, sqlUser, topGroup, removeAllAssignedRoles);

...

logger.

...

info("\n\n==============同步完成!===============");
  
/**
 * 创建"顶级机构"。
 *
 

...

* @param needTopGroup
 *            是否创建一个"顶级机构"。如果该变量为false,则同步过来的机构全部放到"根组"下面。
 * @param topGroupName
 *            如果needTopGroup为true,则会创建一个名称为topGroupName的机构,同步通过的机构都放到它下面。
 * @returns 返回创建的顶级机构对象。
 */
function getTopGroup(needTopGroup, topGroupName) {
    

...

var usrManagerService = new UserManagerService(connector);
  

...

    var topGroup = usrManagerService.getDepartmentById("DEPARTMENT"); // 根组

...

    if (needTopGroup && topGroupName) {

...


        topGroup = usrManagerService.getDepartmentByName(topGroupName);

...


        if (!topGroup) {

...

  

...

 

...

         var groupId = usrManagerService.createDepartment("DEPARTMENT", topGroupName, topGroupName, "", ""); // 在根组下建立顶级机构

...

            topGroup = usrManagerService.getDepartmentById(groupId);

...

        }
    }
    return topGroup;
}
  
/**
 * 同步机构:获取第三方系统中的机构信息。
 *

...


 * @param dsId
 *            数据源ID值。
 * @param sqlGroup
 *            用来同步机构的SQL语句。
 * @param topGroup
 *            顶级机构。
 */
function synchronizeGroupFromOtherDb(dsId, sqlGroup, topGroup) {
 

...

   var usrManagerService = new UserManagerService(connector);

...

 

...

 

...

  var datasrcService = new DataSourceService(connector);
  
    

...

var gridDataGroup = datasrcService.executeNoCacheable(dsId, 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();

...

        var orgCode = gridDataGroup.get(i, 4).getValue();
        logger.info("=====正在同步机构:名称/别名/父机构名称/是否生效:" + orgName + "/" + orgAlias + "/" + orgParentName + "/"
  

...

 

...

   

...

 

...

 

...

 

...

 

...

      + isUse);
  
        // 查找父机构
        var parentGroup = usrManagerService.getDepartmentByName(

...

orgParentName);

...


        if (!

...

parentGroup) {

...

 

...

 

...

 

...

 

...

 

...

 

...

 

...

 

...

 

...

 

...

 

...

 

...

parentGroup

...

 

...

= 

...

topGroup;
        }
 

...

 

...

 

...

  

...

   

...

 

...

 

...

// 根据机构名称判断是否存在

...

        var group = usrManagerService.getDepartmentByName(orgName);

...

  

...

 

...

 

...

  

...

  if (!group) {
       

...

  

...

 

...

 

...

 // 

...

如果不存在则创建
           

...

 usrManagerService.createDepartment(parentGroup.getId(), orgName, orgAlias, "", orgCode);
        } else {
            // 存在则更新
            usrManagerService.updateDepartment(group.getId(), orgAlias,"", orgCode);
            // 然后判断父机构是否正确
            if (parentGroup.getId() != usrManagerService.getParentDepartment(group.getId()).getId()) {
                usrManagerService.moveDepartment(group.getId(), parentGroup.getId());
            }
        }
    }
}
  
/**
 * 

...

同步角色:获取第三方系统中的角色信息。
 *

...


 * @param dsId
 *            数据源ID值。
 * @param 

...

sqlRole
 *            

...

用来同步角色的SQL语句。
 * @param topGroup
 *            顶级机构。
 *

...

/
function 

...

synchronizeRoleFromOtherDb(dsId, 

...

sqlRole, topGroup

...

) {
    

...

var usrManagerService = new UserManagerService(connector);

...

    var datasrcService = new DataSourceService(connector);
  

...


    var gridDataRole = datasrcService.executeNoCacheable(dsId, 

...

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();

...

 

...

 

...

 

...

 

...

 

...

 

...

 

...

 

...

logger.

...

info("=====正在同步角色:名称/别名/父机构名称:" + roleName 

...

+ "/" + roleAlias + "/" + orgName);
  
        // 查找父机构
        var group = usrManagerService.getDepartmentByName(orgName || "NonEmptyOrgName");
        if (!group) {
            group = topGroup;
        }
  
        // 判断角色是否已经同步
        var role = usrManagerService.getRoleByName2(roleName);
        if (!role) {
            // 如果不存在则创建
            usrManagerService.createRole(roleName, roleAlias, "", group.getId());
        } else {
            // 如果存在则更新其信息
            usrManagerService.updateRole(role.getId(), roleAlias, "");
        }
    }
}
  
/**
 * 同步用户:获取第三方系统中的用户信息。
 *
 * @param dsId
 *            数据源ID值。
 * @param sqlUser
 *            用来同步用户的SQL语句。
 * @param topGroup
 *            顶级机构。
 * @param removeAllAssignedRoles
 *            是否删除已经赋予的角色。如果为false,则之前的角色全部保存,同步只是追加新角色。
 */
function synchronizeUserFromOtherDb(dsId, sqlUser, topGroup, removeAllAssignedRoles) {
    var usrManagerService = new UserManagerService(connector);
    var datasrcService = new DataSourceService(connector);
  
    var gridDataUser = datasrcService.executeNoCacheable(dsId, sqlUser);
    for (var i = 0; i < gridDataUser.getRowsCount(); i++) {
		var userId = gridDataUser.get(i, 0).getValue();
        var userName = gridDataUser.get(i, 1).getValue();
        var userAlias = gridDataUser.get(i, 2).getValue();
        var orgName = gridDataUser.get(i, 3).getValue();
        var isUse = gridDataUser.get(i, 4).getValue();
        var userPwd = gridDataUser.get(i, 5).getValue();
        var roleName = gridDataUser.get(i, 6).getValue();
        logger.info("=====正在同步用户:名称/别名/所属机构名称/是否生效/密码/角色名称:" + userName + "/" + userAlias + "/" + orgName + "/"
                + isUse + "/" + userPwd + "/" + roleName);
  
        // 是否生效
        isUse = ("" + isUse).toLowerCase();
        isUse = (isUse === "0" || isUse === "false" || !isUse) ? false : true;
  
        // 获取用户所属机构ID
        var usrOrgIdList = [];
        var usrOrgNameList = (orgName || "").split("#");
        for (var j = 0; j < usrOrgNameList.length; j++) {
            var parentGroup = usrManagerService.getDepartmentByName(usrOrgNameList[j] || "NonEmptyOrgName");
            if (parentGroup) {
                usrOrgIdList.push(parentGroup.getId());
            }
        }
        // 如果未找到父机构,则将该用户放到topGroup下面
        if (usrOrgIdList.length < 1) {
            usrOrgIdList.push(topGroup.getId());
        }
  
        // 判断用户是否已经同步
        var user = usrManagerService.getUserByName(userName);
        if (!user) {
            usrManagerService.createUserById(usrOrgIdList[0], userId, userName, userAlias, "", userPwd, isUse);
            user = usrManagerService.getUserByName(userName);
        }
        // 设置用户所属机构
        usrManagerService.assignDepartmentsToUser(user.getId(), usrOrgIdList);
  
        // 设置用户角色
        var usrRoleIdList = [];
        var usrRoleNameList = (roleName || "").split("#");

...


        for (var 

...

k = 0; 

...

k < 

...

usrRoleNameList.length; 

...

k++) {

...


            var userRole = usrManagerService.

...

getRoleByName2(

...

usrRoleNameList[

...

k]

...

);
            if (userRole) {
                usrRoleIdList.push(userRole.getId());
            }
        }
        if (!removeAllAssignedRoles) {
            // 是否保留旧角色
            var oldAssignedRoles = usrManagerService.getAssignedRolesOfUser(user.getId());

...


            for (var m = 0;

...

 m < oldAssignedRoles.size(); m++) {
                var oldRoleId = oldAssignedRoles.get(m).getId();

...


                if (usrRoleIdList.join("###").indexOf

...

(oldRoleId) < 0)
                    usrRoleIdList.push(oldRoleId);

...


            }
        }
        usrManagerService.assignRolesToUser(user.getId(

...

), usrRoleIdList);
  
        

...

// 更新用户别名、描述等信息。updateUser方法会将传入的明文密码,MD5后存入smartbi知识库

...


        // usrManagerService.updateUser(user.getId(), userAlias, "", userPwd, isUse);

...


        //

...

        // 或者,调用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);
    

...

}
}

...



提示

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

  • var needTopGroup :是否需要顶级机构。
  • var topGroupName :顶级机构名称。
  • var datasrcId :数据源的ID值。需要在“定制管理 -> 数据管理 -> 数据源”中新建关系数据源,所有的SQL需要在该数据源上执行。
  • var sqlGroup :用来同步机构的SQL语句。
  • var sqlRole :用来同步角色的SQL语句。
  • var sqlUser :原来同步用户的SQL语句。
  • var removeAllAssignedRoles :同步时是否删除已有角色。

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

...

       Image Added

3、gif演示示例的源码请参考: 通过计划任务自动同步用户机构和角色.rar

...