美文网首页
go 封装角色模块权限控制

go 封装角色模块权限控制

作者: 五岁小孩 | 来源:发表于2021-03-22 08:14 被阅读0次

go 封装角色模块权限控制

目的

创建通用代码方法实现角色模块的权限控制

实现

  • 表结构

    查看

  • 保存

    • JS
    function saveData() {
        let powerPriArr= [];
        $(".role-menu").each(function (i, v) {
            let privilegeJson={}
            if ($("#Privilege-"+$(v).attr("data-modNo")).length>0){
                //存在模块操作权限
              $($("#Privilege-"+$(v).attr("data-modNo")).find('input[type=checkbox]'))
                  .each(function (m,n) {
                    privilegeJson[$(n).attr("data-name")]=$(n).is(":checked")
                })
            }
            let powerPriJson = {
                "mod_no":$(v).attr("data-modNo"), //模块编号
                "is_selected":$(v).is(":checked"), //是否选中
                "power_privilege":JSON.stringify(privilegeJson), 
            };
            powerPriArr.push(powerPriJson)
        });
    
        let data = {
            "SaveRole": {
                "RoleId": parseInt($("#page-data-id").val()),
                "Name": $("#inputName").val(),
                "Memo": $("#textMemo").val()
            },
            //"SavePower": JSON.stringify(powerJson)
            "save_power_privilege":powerPriArr
        };
    
        $.ajax({
            type: 'POST',
            url: "/systemRole/save",
            data: JSON.stringify(data),
            dataType: 'json',
            contentType: "application/json",
            async: false,
            success: function (result) {
                if (result.success) {
                    $("#page-data-id").val(result.id)
                    swal("", result.message, "success");
                    setTimeout(function () {
                        window.location.href = "/systemRole"
                    }, 1000);
                } else {
                    let errMsg = result.error ? result.message + "\n" + 
                        result.error : result.message
                    swal("", errMsg, "error");
                }
            }
        });
    
    }
    
  • service
type RoleSavePowerBasicReqParam struct {
  ModNo          string `json:"mod_no"`          //模块编号
  IsSelected     bool   `json:"is_selected"`     //是否选中
    //模块下的具体权限(如增删改查{"Add":true,"Delete":true,"Edit":true,"Import":true,"Query":true})
    //当IsSelected==true时生效
  PowerPrivilege string `json:"power_privilege"` 
}
type RoleSaveParam struct {
  SaveRole model.SysRole
    //角色拥有的菜单模块权限
  SavePowerPrivilege []RoleSavePowerBasicReqParam `json:"save_power_privilege"`
    
}
// RoleSaveService 保存
func RoleSaveService(c *gin.Context) {
  var saveParam RoleSaveParam
  var err error
  var errMsg string
  var gormDB *gorm.DB
  // 判断记录是否重复
  ifExistsModel := &model.SysRole{}
  ifExistsModelArr := &[]model.SysRole{}
  err = c.BindJSON(&saveParam)
  // 检查参数是否有效
  if err != nil {
      goto ERR
  }

  // 检查参数必填项目
  if common.IsEmpty(saveParam.SaveRole.Name) {
      errMsg = fmt.Sprintf("%s", "角色名称不能为空!")
      err = errors.New(errMsg)
      goto ERR
  }
  gormDB = dao.QueryArrays(ifExistsModel.TableName(), ifExistsModelArr, []string{}, 
                             "RoleId!=? and Name=?",
                             &[]interface{}{saveParam.SaveRole.RoleId,
                                            saveParam.SaveRole.Name},
                             []string{})
  if gormDB.Error == nil && len(*ifExistsModelArr) > 0 {
      // exist record
      errMsg = fmt.Sprintf("%s", "角色名称")
      err = errors.New(errMsg)
      goto ERR
  }

  // 保存记录

  if saveParam.SaveRole.RoleId == 0 {
      // 新增
      gormDB = dao.Insert(&saveParam.SaveRole)
  } else {
      // 更新
      updateVal := map[string]interface{}{
          "Name":      saveParam.SaveRole.Name, //varchar(200) not null,
          "Memo":      saveParam.SaveRole.Memo, //varchar(200),
          "Privilege": saveParam.SaveRole.Privilege,
      }
      gormDB = dao.UpdateById(saveParam.SaveRole, "RoleId", saveParam.SaveRole.RoleId, 
                                updateVal)
  }
  if gormDB.Error != nil {
      err = gormDB.Error
      errMsg = "数据保存失败"
      goto ERR
  }
  //add Power
  if len(saveParam.SavePowerPrivilege) > 0 {
      for _, power := range saveParam.SavePowerPrivilege {
          powerModel := model.SysRolePrivilege{
              RoleId:          saveParam.SaveRole.RoleId,
              MeuNo:           power.ModNo,
              PrivilegeDetail: power.PowerPrivilege,
              PrivilegeFlag:   1, // 1:有权限;9:无权限
          }
          //当前模块未选中,执行删除
          if !power.IsSelected {
              errByDelPower := dao.DeleteByQuery(powerModel, "1=? And RoleId=? And MeuNo=?",
                                                   &[]interface{}{1, powerModel.RoleId,
                                                                  powerModel.MeuNo})
              if errByDelPower.Error != nil {
                  logs.Error("RoleSaveService,删除用户(%v)菜单(%v)权限失败,error:%v",
                               powerModel.RoleId, power.ModNo, errByDelPower.Error.Error())
              }
              //跳出当前循环
              continue
          }
          //当前模块选中,执行保存更新
          //添加 save
          errBySavePower := dao.MySQLConn.Save(&powerModel)
          if errBySavePower.Error != nil {
              logs.Error("RoleSaveService,保存用户(%v)菜单(%v)权限失败,error:%v",
                           powerModel.RoleId, power.ModNo, errBySavePower.Error.Error())
          }
      }
  }
ERR:
  if err != nil {
      logs.Error("RoleSaveService,保存失败,%s,error:%v", errMsg, err.Error())
      c.JSON(http.StatusOK, gin.H{
          "success": false,
          "message": "失败",
          "error":   errMsg,
      })
      return
  }
  // success
  c.JSON(http.StatusOK, gin.H{
      "id":      saveParam.SaveRole.RoleId,
      "success": true,
      "message": "成功!",
  })
  return
}
  • 数据回显

    • service
    
    type RoleMenuPowerPrivilegeBasicParam struct {
      NameZhCN   string `json:"Name_zhCN"`   //具体操作的中文名称,如查询
      NameTwCN   string `json:"Name_zhTW"`   //具体操作的繁体名称,如查询
      NameEnUS   string `json:"Name_enUS"`   //具体操作的英文名称,如Query
      IsSelected bool   `json:"is_selected"` //是否选中
    }
    type RoleMenuRespParam struct {
      model.SysMenu
      ModNo          string                             `json:"mod_no"`      //模块编号
      IsSelected     bool                               `json:"is_selected"` //是否选中
      PowerPrivilege []RoleMenuPowerPrivilegeBasicParam `json:"power_privilege"`
      ChildNum       int                                `json:"child_num"`
      Children       []RoleMenuRespParam                `json:"children"` //子节点模块
    
    }
    
    // RoleEditService 编辑
    func RoleEditService(c *gin.Context) {
      var err error
      var errMsg string
      var gormDB *gorm.DB
      usrPowerMenuModel := model.SysRolePrivilege{}
      var userMenusArr []model.SysRolePrivilege
      modelRtn := model.SysRole{}
      var menus *[]base.BpmMenuArr
      userMenusMap := make(map[string]interface{})
      id := c.Param("id")
      // 查询系统菜单列表
      roleMenuPower, _ := TPFunGetRoleMenuService(id)
      if common.IsEmpty(id) {
          errMsg = fmt.Sprintf("%s", "角色不存在")
          err = errors.New(errMsg)
          goto ERR
      }
    
      // 如果记录不存在则返回到列表页
      gormDB = dao.QueryById(&modelRtn, "RoleId", id)
      if gormDB.Error != nil || gormDB.RowsAffected != 1 {
          c.Redirect(http.StatusPermanentRedirect, "/systemRole")
          return
      }
      //查询菜单
      //userMenus := service.GetSysUserMenu(userId)
      menus = base.GetSysUserMenu("")
      gormDB = dao.QueryArrays(usrPowerMenuModel.TableName(), &userMenusArr, 
                                 []string{"MeuNo"}, "1=? And RoleId=?", &[]interface{}{1, id}, nil)
      if gormDB.Error != nil {
          logs.Error("RoleEditService,查询用户菜单失败,error:%v", gormDB.Error.Error())
      }
      for _, p := range userMenusArr {
          userMenusMap[p.MeuNo] = true
      }
    
    ERR:
      if err != nil {
          c.HTML(http.StatusOK, "role_edit.html", base.GinHData(c, "Account", gin.H{
              "success":       false,
              "message":       "失败",
              "error":         err,
              "id":            id,
              "roleMenus":     menus,
              "userMenusMap":  userMenusMap,
              "model":         modelRtn,
              "roleMenuPower": roleMenuPower,
          }))
          return
      }
      c.HTML(http.StatusOK, "role_edit.html", base.GinHData(c, "Account", gin.H{
          "success":       true,
          "message":       "success",
          "id":            id,
          "roleMenus":     menus,
          "userMenusMap":  userMenusMap,
          "model":         modelRtn,
          "roleMenuPower": roleMenuPower,
      }))
      return
    }
    
    //封装角色权限数据
    func TPFunGetRoleMenuService(usrId string) ([]RoleMenuRespParam, error) {
    
      var err error
      var gormDB *gorm.DB
      privilegeModel := model.SysRolePrivilege{}
      var privilegeList = make([]model.SysRolePrivilege, 0)
      var privilegeMap = make(map[string]map[string]bool)
      //查询用户拥有的权限
      gormDB = dao.QueryArrays(privilegeModel.TableName(), &privilegeList,
                                 []string{"MeuNo"}, "1=? And RoleId=?", &[]interface{}{1, usrId}, nil)
      if gormDB.Error != nil {
          logs.Error("RoleEditService,查询用户菜单失败,error:%v", gormDB.Error.Error())
      }
      for _, p := range privilegeList {
          var privilegeDetailMap = make(map[string]bool)
          _ = json.Unmarshal([]byte(p.PrivilegeDetail), &privilegeDetailMap)
          privilegeMap[p.MeuNo] = privilegeDetailMap
      }
      //menuArrRtn := &[]base.BpmMenuArr{}
      respData := &[]RoleMenuRespParam{}
      // 查询数据库
      menuBasicModel := &model.SysMenu{}
      var menuBasicList = make([]model.SysMenu, 0)
      var queryStr = "1=?"
    
      queryErrDb := dao.QueryArrays(menuBasicModel.TableName(), &menuBasicList,
                                      []string{"SortString asc"}, queryStr, &[]interface{}{1}, nil)
      if queryErrDb.Error != nil {
          logs.Error("查询系统菜单失败:", queryErrDb.Error)
      }
      for _, v := range menuBasicList {
          // 权限,如果该用户所属角色没有该菜单权限,则不添加到返回数组
          var power = make([]base.MenuPowerDefine, 0)
          if !common.IsEmpty(v.Privilege) {
              powerMarshalErr := json.Unmarshal([]byte(v.Privilege), &power)
              if powerMarshalErr != nil {
                  logs.Error("Invalid Menu Power,", v.MeuNo, v.NameEn, v.Privilege)
              }
          }
          TPFunAddMenuToRespArr(respData, &v, privilegeMap)
    
      }
      return *respData, err
    }
    func TPFunAddMenuToRespArr(respData *[]RoleMenuRespParam, menuModel *model.SysMenu, 
                               privilegeMap map[string]map[string]bool) {
    
      if len(*respData) == 0 || menuModel.LevNo == 1 {
          var powerPrivilegeList = make([]RoleMenuPowerPrivilegeBasicParam, 0)
          var power = make([]base.MenuPowerDefine, 0)
          _ = json.Unmarshal([]byte(menuModel.Privilege), &power)
          for _, p := range power {
              var powerPrivilege = RoleMenuPowerPrivilegeBasicParam{
                  NameZhCN:   p.NameZhCN,//具体操作的中文名称,如查询
                  NameTwCN:   p.NameTwCN, //具体操作的繁体名称,如查询
                  NameEnUS:   p.NameEnUS,//具体操作的英文名称,如Query
                  IsSelected: privilegeMap[menuModel.MeuNo][p.NameEnUS], //是否选中
              }
              powerPrivilegeList = append(powerPrivilegeList, powerPrivilege)
          }
          isSelected := false
          if _, ok := privilegeMap[menuModel.MeuNo]; ok {
              isSelected = true
          }
          *respData = append(*respData, RoleMenuRespParam{
              SysMenu:        *menuModel,
              ModNo:          menuModel.MeuNo,
              PowerPrivilege: powerPrivilegeList,
              IsSelected:     isSelected,
              Children:       []RoleMenuRespParam{},
          })
    
      } else {
    
          var lastMenuArr = respData
    
      Search:
    
          for {
    
              for i, m := range *lastMenuArr {
                  if strings.Index(menuModel.SortString, m.SortString) == 0 {
    
                      var levNoDiff = len(menuModel.SortString) - len(m.SortString)
    
                      switch {
                      case levNoDiff == 2:
                          var powerPrivilegeList = make([]RoleMenuPowerPrivilegeBasicParam, 0)
                          var power = make([]base.MenuPowerDefine, 0)
                          _ = json.Unmarshal([]byte(menuModel.Privilege), &power)
                          for _, p := range power {
                              var powerPrivilege = RoleMenuPowerPrivilegeBasicParam{
                                  NameZhCN:   p.NameZhCN, //具体操作的中文名称,如查询
                                  NameTwCN:   p.NameTwCN,//具体操作的繁体名称,如查询
                                  NameEnUS:   p.NameEnUS, //具体操作的英文名称,如Query
                                       //是否选中
                                  IsSelected: privilegeMap[menuModel.MeuNo][p.NameEnUS],
                                   
                              }
                              powerPrivilegeList = append(powerPrivilegeList, powerPrivilege)
                          }
                          isSelected := false
                          if _, ok := privilegeMap[menuModel.MeuNo]; ok {
                              isSelected = true
                          }
                          m.Children = append(m.Children, RoleMenuRespParam{
                              SysMenu:        *menuModel,
                              ModNo:          menuModel.MeuNo,
                              PowerPrivilege: powerPrivilegeList,
                              IsSelected:     isSelected,
                              Children:       []RoleMenuRespParam{},
                          })
    
                          m.ChildNum = len(m.Children)
    
                          // 放到父节点
                          (*lastMenuArr)[i] = m
                          break Search
    
                      case levNoDiff > 2:
                          // 同层级下钻
                          lastMenuArr = &m.Children
                          continue Search
                      }
                  }
              }
    
              break Search
          }
    
      }
    
    }
    
    
    • html

    内部代码:

    <div class="form-group">
                        <label class="col-sm-2 control-label form-label"
                               style="font-weight:normal;text-align: right;">权限</label>
                        <div class="col-sm-10">
                            <p class="">&nbsp;</p>
                            {{range $i,$v:=$.roleMenuPower}}
                                {{/*一级菜单  MAIN/SYSTEM */}}
                                <div class="checkbox checkbox-success" style="display: none;">
                                    <input type="checkbox" id="{{$v.MeuNo}}" class="role-menu" data-modNo="{{$v.MeuNo}}"
                                           value="option1" checked="checked">
                                    <label for="{{$v.MeuNo}}"> {{$v.NameZh}} </label>
                                </div>
                                <div></div>
                                {{if gt $v.ChildNum 0}}
                                    {{/*遍历二级菜单*/}}
                                    {{range $a,$b:=$v.Children}}
                                        <div>
                                            <div class="col-sm-12 margin-b-10 checkbox checkbox-success margin-l-10">
                                                <input type="checkbox" id="{{$b.MeuNo}}"
                                                       class="role-menu" data-modNo="{{$b.MeuNo}}"
                                                       value="option1" {{if eq $v.IsSelected true}}checked{{end}}>
                                                <label for="{{$b.MeuNo}}"> {{$b.NameZh}}</label>
                                            </div>
                                            {{if gt $b.ChildNum 0}}
                                                <div class="col-sm-12  panel-default margin-l-10">
                                                    {{/* 遍历三级菜单 panel panel-default*/}}
                                                    {{range $c,$d:=$b.Children}}
                                                        <div>
                                                            <div class="checkbox  checkbox-inline mod-checkbox-input margin-b-5">
                                                                <input type="checkbox" id="{{$d.MeuNo}}" data-modNo="{{$d.MeuNo}}"
                                                                       class="{{$d.ParentModNo}} role-menu"
                                                                       {{if eq $d.IsSelected true}}checked{{end}}>
                                                                <label for="{{$d.MeuNo}}"> {{$d.NameZh}} </label>
                                                            </div>
                                                            {{if gt $d.ChildNum 0}}
                                                                {{range $e,$f:=$d.Children}}
                                                                    <div class="checkbox  checkbox-inline ">
                                                                        <input type="checkbox" id="{{$f.MeuNo}}"
                                                                               class="{{$f.ParentModNo}} role-menu" data-modNo="{{$f.MeuNo}}"
                                                                               value="option1"
                                                                               {{if eq $f.IsSelected true}}checked{{end}}>
                                                                        <label for="{{$f.MeuNo}}"> {{$f.NameZh}} </label>
                                                                    </div>
                                                                {{end}}
                                                            {{else}}
                                                                {{if gt (len $d.PowerPrivilege) 0}}
                                                                    <div class="panel panel-default">
                                                                        {{/*当前模块无子模块,展示模块权限*/}}
                                                                        {{/*新添加*/}}
                                                                        <div id="Privilege-{{$d.MeuNo}}">
                                                                            {{range $m,$n:=$d.PowerPrivilege}}
                                                                                <div class="checkbox  checkbox-inline ">
                                                                                    <input id="{{$d.MeuNo}}-PriInput-{{$n.NameEnUS}}"
                                                                                           class="role-menu-pri {{$d.MeuNo}}PriInput" data-name="{{$n.NameEnUS}}"
                                                                                           {{if eq $n.IsSelected true}}checked{{end}}
                                                                                           type="checkbox">
                                                                                    <label for="{{$d.MeuNo}}-PriInput-{{$n.NameEnUS}}"> {{$n.NameZhCN}}</label>
                                                                                </div>
                                                                            {{end}}
                                                                        </div>
                                                                    </div>
                                                                {{end}}
                                                            {{end}}
                                                        </div>
    
                                                    {{end}}
                                                </div>
                                            {{else}}
                                                {{if gt (len $b.PowerPrivilege) 0}}
                                                    <div class="col-sm-12 panel panel-default padding-10 margin-b-5 margin-l-25">
                                                        {{/*当前模块无子模块,展示模块权限*/}}
                                                        {{/*新添加*/}}
                                                        <div id="Privilege-{{$b.MeuNo}}">
                                                            {{range $m,$n:=$b.PowerPrivilege}}
                                                                <div class="checkbox  checkbox-inline ">
                                                                    <input id="{{$b.MeuNo}}-PriInput-{{$n.NameEnUS}}"
                                                                           class="role-menu-pri {{$b.MeuNo}}PriInput" data-name="{{$n.NameEnUS}}"
                                                                           {{if eq $n.IsSelected true}}checked{{end}}
                                                                           type="checkbox">
                                                                    <label for="{{$b.MeuNo}}-PriInput-{{$n.NameEnUS}}"> {{$n.NameZhCN}}</label>
                                                                </div>
                                                            {{end}}
                                                        </div>
                                                    </div>
                                                {{end}}
                                            {{end}}
                                        </div>
    
                                    {{end}}
                                {{end}}
    
                            {{end}}
    
                        </div>
    
                    </div>
    
    • js
    $(function () {
        //控制模块的点击
        $(".role-menu").on('change', function (e) {
            //获取当前状态
            let isChecked = $(this).attr("checked");
            if (isNotNull(isChecked)) {
                //选中变不选中(包括子节点)
                $($(this).parent().parent().find('input[type=checkbox]')).each(function (i, v) {
                    $(v).removeAttr("checked");
                    $(v).next().removeClass("menu-child-checkbox")
                })
    
            } else {
    
                $($(this).parent().parent().find('input[type=checkbox]')).each(function (i, v) {
                    //不选中变选中(不包括子节点)
                    $(v).attr("checked", "checked");
                    //选中
                    $(v).next().addClass("menu-child-checkbox")
                })
            }
        })
        //控制模块权限的点击
        $(".role-menu-pri").on('change', function (e) {
            //获取当前状态
            let isChecked = $(this).attr("checked");
            if (isNotNull(isChecked)) {
                //选中变不选中(包括子节点)
                $(this).removeAttr("checked");
                $(this).next().removeClass("menu-child-checkbox")
    
            } else {
                //不选中变选中(不包括子节点)
                $(this).attr("checked", "checked");
                //选中
                $(this).next().addClass("menu-child-checkbox")
            }
        })
    
    
    });
    

相关文章

网友评论

      本文标题:go 封装角色模块权限控制

      本文链接:https://www.haomeiwen.com/subject/mmugxltx.html