代码之家  ›  专栏  ›  技术社区  ›  Johan W.

自适应用户管理

  •  0
  • Johan W.  · 技术社区  · 7 年前

    我基于Google的“people viewer”模板构建了一个评论应用程序,允许经理为其直接下属创建和编辑评论。

    • 该应用程序包含目录模型以及三个角色:管理员、HR、最终用户。
    • 该应用程序包含一个用户设置模型,允许创建和存储类似于“人际技能”模板的用户设置。
    • 该应用程序包含一个审查模型,该模型将包含每个员工的审查。由于一名员工可以有多个评论,这将是一个一对多的关系,可以链接到目录模型或用户设置模型。

    审查应由经理链的经理阅读。为此,我创建了一个服务器脚本,假设EmployeeEmail将额外存储在review中。但也许有更好的选择?

    function getDirectReportsChainForUser_(query) {
      var userQuery = app.models.Directory.newQuery();
      userQuery.filters.PrimaryEmail._equals = query.parameters.PrimaryEmail;
    
      userQuery.prefetch.DirectReports._add();
      userQuery.prefetch.DirectReports.DirectReports._add();
    
      var users = userQuery.run();
    
      if (users.length === 0) {
       return [];
      }
    
      var user = users[0];
      var directs = user.DirectReports;
      var records = [];
      for (var i = 0; i <= directs.length; i++) {
        records.push(directs[i].PrimaryEmail);
      }
      // The following lines are based on the asumption that the EmployeeEmail 
      // will be stored in the review in case that there is no better alternative. 
      //The question that then remains is how to recursively add the DirectReports 
      //of the DirectReports to the array???
      var reviewQuery = app.models.Reviews.newQuery();
      reviewQuery.filters.EmployeeEmail._in = records; 
     return reviewQuery.run();
    }
    

    经理应该能够确定他的一个或多个副手是否也能阅读本部门的评论。我的想法是通过目录和审阅模型之间的多对多关系来解决这个问题,但我不知道如何实现它?

    此外,一旦经理或其副手离职,管理员应该可以解除联系,并将审查重新连接到继任者。因此,我想在管理页面中集成一个multiselect。这是否可行?

    2 回复  |  直到 7 年前
        1
  •  1
  •   Pavel Shkleinik    7 年前

    在这里,我看到了至少两个截然不同的问题:

    有没有更好的方法将目录模型的记录和普通数据模型关联起来,而不仅仅是将主电子邮件字段添加到数据模型中

    不,目前无法在数据(SQL/驱动器表)和目录模型之间建立关系。

    如何递归获取用户的所有直接下属

    App Maker的目录模型是 G Suit Admin SDK's Directory API 这只展示了其强大功能的一小部分。添加目录模型时,App Maker会自动插入相应的应用脚本高级服务:

    Directory model and Directory API

    因为我们已经配置了目录API,所以我们可以释放它的全部功能,只需一次调用(如果需要支持分页,可以多次调用)就可以轻松地获取所有管理者的下属。为了做到这一点,我们将使用 Users.List API方法 managerId query参数(唯一允许我们查询树下所有下级的参数)。以下是引用自全文的最小搜索查询参数集的参考 search documentation (如果没有这些参数,查询将无法工作,或者无法以我们需要的方式工作):

    • managerId :直接或在管理链上的用户经理的ID。
    • 领域 :域名。使用此字段仅从一个域获取字段。要返回客户帐户的所有域,请使用 customer 改为查询参数。或者 顾客 或者 domain 参数 必须提供
    • 视图类型 :是仅获取管理员视图还是获取用户的全域公共视图。有关更多信息,请参阅 Retrieve a user as a non-administrator ( admin_view 是默认值,因此我们需要用 domain_view )。
    • 查询 :用于搜索用户字段的查询字符串。有关构造用户查询的详细信息,请参见 Search for Users
    /**
     * Fetches all reviews associated with all subordinate employees (both direct
     * and indirect reports).
     */
    function getAllReportsEmails(managerId) {
      var emails = [];
      var result = AdminDirectory.Users.list({
        domain: 'ENTER HERE YOUR DOMAIN (exapmle.com)',
        query: 'managerId=' + managerId,
        viewType: 'domain_public',
        maxResults: 100
      });
    
      if (result.users) {
        emails = result.users.map(function (user) {
          return user.primaryEmail;
        });
      }
    
      return emails;
    }
    
    
    /**
     * Fetches all reviews associated with all subordinate employees (both direct
     * and indirect reports).
     */
    function getAllReportsReviewsForManager_(query) {
      var userQuery = app.models.Directory.newQuery();
      // For better security I would recommend to use
      // Session.getActiveUser().getEmail() instead of parameter
      // passed from the client.
      userQuery.filters.PrimaryEmail._equals = Session.getActiveUser().getEmail();
    
      var users = userQuery.run();
    
      if (users.length === 0) {
       return [];
      }
    
      var manager = users[0];
      var managerId = manager._key;
      var allReportsEmails = getAllReportsEmails(managerId);
    
      var reviewQuery = app.models.Reviews.newQuery();
      reviewQuery.filters.EmployeeEmail._in = allReportsEmails; 
    
      return reviewQuery.run();
    }
    
        2
  •  0
  •   Johan W.    7 年前

    Pavel,我尝试将您给我的想法集成到一个服务器脚本中,该脚本返回一组经理及其整个下属链(直接报告+间接报告),以便我可以在需要时使用它。我将其转换为递归函数,以获取下一个较低级别的直接报告和间接报告。有没有办法得到整个链条?

    function getSubordinatesChainForUser(query) {
      var userQuery = app.models.Directory.newQuery();
      userQuery.filters.PrimaryEmail._equals = Session.getActiveUser().getEmail();
      userQuery.prefetch.DirectReports._add();
      userQuery.prefetch.DirectReports.DirectReports._add();
      var users = userQuery.run();
      if (users.length === 0) {
        return [];
      }  
    
      var userEmails = users.map(function(manager){
        var employeeEmails = manager.DirectReports.map(function(employee){
          return employee.PrimaryEmail;
        });
        return manager.PrimaryEmail + ',' + employeeEmails;
      });
    
      return userEmails;
    }