代码之家  ›  专栏  ›  技术社区  ›  AT-2017

获取父菜单的所有子详细信息

  •  2
  • AT-2017  · 技术社区  · 6 年前

    我正在开发一个菜单访问权限系统,管理员可以将用户分配到包含菜单访问权限的组。单独授予用户权限很简单。但对于团体许可,我没有什么标准可以匹配。下面是表结构和示例数据:

    ----USER DETAILS----
    CREATE TABLE HRD.USER_DETAILS
    (
      EMPNO VARCHAR2(20 BYTE),
      ENAME VARCHAR2(40 BYTE),
      ENTRY_DATE DATE,
      STATUS INT
    );
    
    EMP-0001    John    6/10/2018   1
    EMP-0002    Jack    5/12/2018   1
    
    ----GROUP DETAILS----
    CREATE TABLE HRD.GROUP_DETAILS
    (
      GROUPNO VARCHAR2(20 BYTE),
      GROUPNAME VARCHAR2(40 BYTE),
      DETAILS VARCHAR2(100 BYTE),
      ENTRY_DATE DATE,
      STATUS INT
    );
    
    GROUP-0001  GROUP-1     1/1/2018    1
    GROUP-0002  GROUP-2     1/1/2018    1
    
    ----MENU DETAILS----
    CREATE TABLE HRD.MENU_DETAILS
    (
      MENUNO VARCHAR2(20 BYTE),
      MENUNAME VARCHAR2(40 BYTE),
      DETAILS VARCHAR2(100 BYTE),
      PARENT VARCHAR2(10 BYTE),
      ENTRY_DATE DATE,
      STATUS INT
    );
    
    1001    User Details        0   1/1/2018    1
    1002    Add User        1001    1/1/2018    1
    1003    Department Details      0   1/1/2018    1
    1004    Add Department      1003    1/1/2018    1
    
    ----ASSIGN MENU DETAILS----
    CREATE TABLE HRD.ASSIGN_MENU_DETAILS
    (
      GROUPNO VARCHAR2(20 BYTE),
      MENUNO VARCHAR2(20 BYTE),
      DETAILS VARCHAR2(100 BYTE),
      ENTRY_DATE DATE,
      STATUS INT
    );
    
    GROUP-0001  1001        1/1/2018    1
    GROUP-0001  1004        1/1/2018    1
    
    ----USER GROUP DETAILS----
    CREATE TABLE HRD.USER_GROUP_DETAILS
    (
      EMPNO VARCHAR2(20 BYTE),
      GROUPNO VARCHAR2(20 BYTE),
      DETAILS VARCHAR2(100 BYTE),
      ENTRY_DATE DATE,
      STATUS INT
    );
    
    EMP-0001    GROUP-0001      1/1/2018    1
    EMP-0001    GROUP-0002      1/1/2018    1
    

    因此,使用下面的查询,我得到以下结果:

    SELECT M.EMPNO, M.GROUPNO, K.MENUNO, Q.MENUNAME FROM USER_GROUP_DETAILS m INNER JOIN ASSIGN_MENU_DETAILS k ON K.GROUPNO = M.GROUPNO
    LEFT JOIN (SELECT P.MENUNO, P.MENUNAME FROM MENU_DETAILS p WHERE P.PARENT = '0' OR P.PARENT <> '0') q ON Q.MENUNO = K.MENUNO 
    GROUP BY M.EMPNO, M.GROUPNO, K.MENUNO, Q.MENUNAME;
    
    EMP-0001    GROUP-0001  1001    User Details
    EMP-0001    GROUP-0001  1004    Add Department
    

    组-0002 ,则查询中不应显示任何菜单。这是最重要的一件事:那就是 第0001组 有两个菜单权限1)用户详细信息2)添加部门

    “用户详细信息”菜单是的父菜单,“添加部门”是的子菜单 添加部门 菜单中有父菜单 部门详情

    C# 但是试过了 C# 代码也一样,但逻辑似乎不是完美构建的。

    C# :

    foreach (var parent in GetViewModel())
    {
       foreach (var child in GetViewModel2(parent.Parent))
       {
           sampleDynamicNav = new List<NavBarItem> {
                new NavBarItem {
                    D = 1, Text = parent.MenuName, Icon = new ItemIcon {Default =  HRMS_New_VS2.Properties.Resources.nav_new_home, Hover = HRMS_New_VS2.Properties.Resources.nav_new_home, Selected = HRMS_New_VS2.Properties.Resources.nav_new_home}, ToolTip = "tooltip Main Menu", Height = 40,
    
                    Childs = new List<NavBarItem> {
                        new NavBarItem {ID = child.MenuNo, Text = child.MenuName, Height = 30 },
                   }
               }
           };
       }
    }
    
    public IEnumerable<EmpViewModel> GetParent()
    {
         List<EmpViewModel> lstEmp = new List<EmpViewModel>();
    
         string query = "SELECT M.EMPNO, M.GROUPNO, K.MENUNO, Q.MENUNAME, Q.PARENT FROM USER_GROUP_DETAILS m INNER JOIN ASSIGN_MENU_DETAILS k ON K.GROUPNO = M.GROUPNO " +
                        "LEFT JOIN (SELECT P.MENUNO, P.MENUNAME, P.PARENT FROM MENU_DETAILS p) q ON Q.MENUNO = K.MENUNO WHERE M.EMPNO = 'EMP-0001' " +
                        "GROUP BY M.EMPNO, M.GROUPNO, K.MENUNO, Q.MENUNAME, Q.PARENT";
    
          DataTable dt = SelectData(query);
    
          if (dt != null && dt.Rows.Count > 0)
          {
              foreach (DataRow dr in dt.Rows)
              {
                  EmpViewModel bo = new EmpViewModel();
                  bo.Parent = dr["PARENT"].ToString();
                  bo.MenuName = dr["MENUNAME"].ToString();
                  bo.MenuNo = Convert.ToInt32(dr["MENUNO"].ToString());
    
                  lstEmp.Add(bo);
              }
           }
    
         return lstEmp;
    }
    
    
    
    public IEnumerable<EmpViewModel> GetChild(string menuNo)
    {
        List<EmpViewModel> lstEmp = new List<EmpViewModel>();
    
        string query = "SELECT M.EMPNO, M.GROUPNO, K.MENUNO, Q.MENUNAME, Q.PARENT FROM USER_GROUP_DETAILS m INNER JOIN ASSIGN_MENU_DETAILS k ON K.GROUPNO = M.GROUPNO " +
                       "LEFT JOIN (SELECT P.MENUNO, P.MENUNAME, P.PARENT FROM MENU_DETAILS p) q ON Q.MENUNO = K.MENUNO WHERE M.EMPNO = 'EMP-0001' AND Q.PARENT = '" + menuNo + "'" +
                       "GROUP BY M.EMPNO, M.GROUPNO, K.MENUNO, Q.MENUNAME, Q.PARENT";
    
         DataTable dt = SelectData(query);
    
         if (dt != null && dt.Rows.Count > 0)
         {
             foreach (DataRow dr in dt.Rows)
             {
                EmpViewModel bo = new EmpViewModel();
                bo.Parent = dr["PARENT"].ToString();
                bo.MenuName = dr["MENUNAME"].ToString();
                bo.MenuNo = Convert.ToInt32(dr["MENUNO"].ToString());
    
                lstEmp.Add(bo);
             }
         }
        return lstEmp;
    }
    

    预期输出-对于菜单权限: 对于用户

    Menu - 01: User Details
    Menu - 02: Department Details
               -> Add Department
    

    注: 一个用户可以被分配到多个组,该组可以重复菜单权限两次。在这种情况下,它应该反映不同的菜单,保持父菜单和子菜单相邻。暂时把它放在一边。

    1 回复  |  直到 6 年前
        1
  •  2
  •   sticky bit    6 年前

    WITH 
    CTE (MENUNO,
         MENUNAME,
         PARENT) AS
    (
    SELECT M.MENUNO,
           M.MENUNAME,
           M.PARENT
           FROM USER_DETAILS U
                INNER JOIN USER_GROUP_DETAILS UG
                           ON UG.EMPNO = U.EMPNO
                INNER JOIN ASSIGN_MENU_DETAILS AM
                           ON AM.GROUPNO = UG.GROUPNO
                INNER JOIN MENU_DETAILS M
                           ON M.MENUNO = AM.MENUNO
           WHERE U.EMPNO = 'EMP-0001'
    UNION ALL
    SELECT M.MENUNO,
           M.MENUNAME,
           M.PARENT
           FROM MENU_DETAILS M
                INNER JOIN CTE C
                           ON C.PARENT = M.MENUNO
    )
    SELECT DISTINCT
           MENUNO,
           MENUNAME
           FROM CTE;
    

    db<>fiddle