From c8d28d7297a8bcb5c18e552a52d0b6bc79d24407 Mon Sep 17 00:00:00 2001 From: TsMask <340112800@qq.com> Date: Tue, 29 Aug 2023 16:15:03 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=92=E8=89=B2=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- features/sys_role/api_sys_role.go | 384 ++++++++++++++++++ features/sys_role/model/sys_role.go | 38 ++ features/sys_role/service/repo_sys_role.go | 357 ++++++++++++++++ features/sys_role/service/service_sys_role.go | 163 ++++++++ 4 files changed, 942 insertions(+) create mode 100644 features/sys_role/api_sys_role.go create mode 100644 features/sys_role/model/sys_role.go create mode 100644 features/sys_role/service/repo_sys_role.go create mode 100644 features/sys_role/service/service_sys_role.go diff --git a/features/sys_role/api_sys_role.go b/features/sys_role/api_sys_role.go new file mode 100644 index 00000000..11b0d36e --- /dev/null +++ b/features/sys_role/api_sys_role.go @@ -0,0 +1,384 @@ +package sysrole + +import ( + "fmt" + "net/http" + "strings" + + "ems.agt/features/sys_role/model" + "ems.agt/features/sys_role/service" + userService "ems.agt/features/sys_user/service" + "ems.agt/lib/core/utils/ctx" + "ems.agt/lib/core/utils/parse" + "ems.agt/lib/core/vo/result" + "ems.agt/lib/midware" + "ems.agt/lib/services" + "ems.agt/restagent/config" +) + +// 角色接口添加到路由 +func Routers() []services.RouterItem { + // 实例化控制层 SysRoleApi 结构体 + var apis = &SysRoleApi{ + sysRoleService: service.NewServiceSysRole, + sysUserService: userService.NewServiceSysUser, + } + + rs := [...]services.RouterItem{ + { + Method: "GET", + Pattern: "/roleManage/{apiVersion}/list", + Handler: apis.List, + Middleware: midware.Authorize(map[string][]string{ + "hasPerms": {"system:menu:list"}, + }), + }, + { + Method: "GET", + Pattern: "/roleManage/{apiVersion}/info/{roleId}", + Handler: apis.Info, + Middleware: midware.Authorize(map[string][]string{ + "hasPerms": {"system:menu:query"}, + }), + }, + { + Method: "POST", + Pattern: "/roleManage/{apiVersion}/add", + Handler: apis.Add, + Middleware: midware.Authorize(map[string][]string{ + "hasPerms": {"system:menu:add"}, + }), + }, + { + Method: "PUT", + Pattern: "/roleManage/{apiVersion}/edit", + Handler: apis.Edit, + Middleware: midware.Authorize(map[string][]string{ + "hasPerms": {"system:menu:edit"}, + }), + }, + { + Method: "DELETE", + Pattern: "/roleManage/{apiVersion}/del/{roleIds}", + Handler: apis.Remove, + Middleware: midware.Authorize(map[string][]string{ + "hasPerms": {"system:menu:edit"}, + }), + }, + { + Method: "PUT", + Pattern: "/roleManage/{apiVersion}/changeStatus", + Handler: apis.Status, + Middleware: midware.Authorize(map[string][]string{ + "hasPerms": {"system:role:edit"}, + }), + }, + { + Method: "GET", + Pattern: "/roleManage/{apiVersion}/authUser/allocatedList", + Handler: apis.AuthUserAllocatedList, + Middleware: midware.Authorize(map[string][]string{ + "hasPerms": {"system:user:list"}, + }), + }, + { + Method: "PUT", + Pattern: "/roleManage/{apiVersion}/authUser/checked", + Handler: apis.AuthUserChecked, + Middleware: midware.Authorize(map[string][]string{ + "hasPerms": {"system:role:edit"}, + }), + }, + // 添加更多的 Router 对象... + } + + // 生成两组前缀路由 + rsPrefix := []services.RouterItem{} + for _, v := range rs { + path := v.Pattern + // 固定前缀 + v.Pattern = config.DefaultUriPrefix + path + rsPrefix = append(rsPrefix, v) + // 可配置 + v.Pattern = config.UriPrefix + path + rsPrefix = append(rsPrefix, v) + } + return rsPrefix +} + +// // 实例化控制层 SysRoleApi 结构体 +// var NewSysRole = &SysRoleApi{ +// sysRoleService: sysrole.NewServiceSysRole, +// sysUserService: sysuser.NewServiceSysUser, +// } + +// 角色信息 +// +// PATH /roleManage +type SysRoleApi struct { + // 角色服务 + sysRoleService *service.ServiceSysRole + // 用户服务 + sysUserService *userService.ServiceSysUser +} + +// 角色列表 +// +// GET /list +func (s *SysRoleApi) List(w http.ResponseWriter, r *http.Request) { + querys := ctx.QueryMap(r) + data := s.sysRoleService.SelectRolePage(querys) + ctx.JSON(w, 200, result.Ok(data)) +} + +// 角色信息详情 +// +// GET /:roleId +func (s *SysRoleApi) Info(w http.ResponseWriter, r *http.Request) { + roleId := ctx.Param(r, "roleId") + if roleId == "" { + ctx.JSON(w, 400, result.CodeMsg(400, "参数错误")) + return + } + data := s.sysRoleService.SelectRoleById(roleId) + if data.RoleID == roleId { + ctx.JSON(w, 200, result.OkData(data)) + return + } + ctx.JSON(w, 200, result.Err(nil)) +} + +// 角色信息新增 +// +// POST / +func (s *SysRoleApi) Add(w http.ResponseWriter, r *http.Request) { + var body model.SysRole + err := ctx.ShouldBindJSON(r, &body) + if err != nil || body.RoleID != "" { + ctx.JSON(w, 400, result.CodeMsg(400, "参数错误")) + return + } + + // 判断角色名称是否唯一 + uniqueRoleName := s.sysRoleService.CheckUniqueRoleName(body.RoleName, "") + if !uniqueRoleName { + msg := fmt.Sprintf("角色新增【%s】失败,角色名称已存在", body.RoleName) + ctx.JSON(w, 200, result.ErrMsg(msg)) + return + } + + // 判断角色键值是否唯一 + uniqueRoleKey := s.sysRoleService.CheckUniqueRoleKey(body.RoleKey, "") + if !uniqueRoleKey { + msg := fmt.Sprintf("角色新增【%s】失败,角色键值已存在", body.RoleName) + ctx.JSON(w, 200, result.ErrMsg(msg)) + return + } + + body.CreateBy = ctx.LoginUserToUserName(r) + insertId := s.sysRoleService.InsertRole(body) + if insertId != "" { + ctx.JSON(w, 200, result.Ok(nil)) + return + } + ctx.JSON(w, 200, result.Err(nil)) +} + +// 角色信息修改 +// +// PUT / +func (s *SysRoleApi) Edit(w http.ResponseWriter, r *http.Request) { + var body model.SysRole + err := ctx.ShouldBindJSON(r, &body) + if err != nil || body.RoleID == "" { + ctx.JSON(w, 400, result.CodeMsg(400, "参数错误")) + return + } + + // 检查是否管理员角色 + if body.RoleID == "1" { + ctx.JSON(w, 200, result.ErrMsg("不允许操作管理员角色")) + return + } + + // 检查是否存在 + role := s.sysRoleService.SelectRoleById(body.RoleID) + if role.RoleID != body.RoleID { + ctx.JSON(w, 200, result.ErrMsg("没有权限访问角色数据!")) + return + } + + // 判断角色名称是否唯一 + uniqueRoleName := s.sysRoleService.CheckUniqueRoleName(body.RoleName, body.RoleID) + if !uniqueRoleName { + msg := fmt.Sprintf("角色修改【%s】失败,角色名称已存在", body.RoleName) + ctx.JSON(w, 200, result.ErrMsg(msg)) + return + } + + // 判断角色键值是否唯一 + uniqueRoleKey := s.sysRoleService.CheckUniqueRoleKey(body.RoleKey, body.RoleID) + if !uniqueRoleKey { + msg := fmt.Sprintf("角色修改【%s】失败,角色键值已存在", body.RoleName) + ctx.JSON(w, 200, result.ErrMsg(msg)) + return + } + + body.UpdateBy = ctx.LoginUserToUserName(r) + rows := s.sysRoleService.UpdateRole(body) + if rows > 0 { + ctx.JSON(w, 200, result.Ok(nil)) + return + } + ctx.JSON(w, 200, result.Err(nil)) +} + +// 角色信息删除 +// +// DELETE /:roleIds +func (s *SysRoleApi) Remove(w http.ResponseWriter, r *http.Request) { + roleIds := ctx.Param(r, "roleIds") + if roleIds == "" { + ctx.JSON(w, 400, result.CodeMsg(400, "参数错误")) + return + } + // 处理字符转id数组后去重 + ids := strings.Split(roleIds, ",") + uniqueIDs := parse.RemoveDuplicates(ids) + if len(uniqueIDs) <= 0 { + ctx.JSON(w, 200, result.Err(nil)) + return + } + // 检查是否管理员角色 + for _, id := range uniqueIDs { + if id == "1" { + ctx.JSON(w, 200, result.ErrMsg("不允许操作管理员角色")) + return + } + } + rows, err := s.sysRoleService.DeleteRoleByIds(uniqueIDs) + if err != nil { + ctx.JSON(w, 200, result.ErrMsg(err.Error())) + return + } + msg := fmt.Sprintf("删除成功:%d", rows) + ctx.JSON(w, 200, result.OkMsg(msg)) +} + +// 角色状态变更 +// +// PUT /changeStatus +func (s *SysRoleApi) Status(w http.ResponseWriter, r *http.Request) { + var body struct { + // 角色ID + RoleID string `json:"roleId" binding:"required"` + // 状态 + Status string `json:"status" binding:"required"` + } + err := ctx.ShouldBindJSON(r, &body) + if err != nil { + ctx.JSON(w, 400, result.CodeMsg(400, "参数错误")) + return + } + + // 检查是否管理员角色 + if body.RoleID == "1" { + ctx.JSON(w, 200, result.ErrMsg("不允许操作管理员角色")) + return + } + + // 检查是否存在 + role := s.sysRoleService.SelectRoleById(body.RoleID) + if role.RoleID != body.RoleID { + ctx.JSON(w, 200, result.ErrMsg("没有权限访问角色数据!")) + return + } + + // 与旧值相等不变更 + if role.Status == body.Status { + ctx.JSON(w, 200, result.ErrMsg("变更状态与旧值相等!")) + return + } + + // 更新状态不刷新缓存 + userName := ctx.LoginUserToUserName(r) + SysRoleApi := model.SysRole{ + RoleID: body.RoleID, + Status: body.Status, + UpdateBy: userName, + } + rows := s.sysRoleService.UpdateRole(SysRoleApi) + if rows > 0 { + ctx.JSON(w, 200, result.Ok(nil)) + return + } + ctx.JSON(w, 200, result.Err(nil)) +} + +// 角色分配用户列表 +// +// GET /authUser/allocatedList +func (s *SysRoleApi) AuthUserAllocatedList(w http.ResponseWriter, r *http.Request) { + querys := ctx.QueryMap(r) + roleId, ok := querys["roleId"] + if !ok || roleId == "" { + ctx.JSON(w, 400, result.CodeMsg(400, "参数错误")) + return + } + + // 检查是否存在 + role := s.sysRoleService.SelectRoleById(roleId.(string)) + if role.RoleID != roleId { + ctx.JSON(w, 200, result.ErrMsg("没有权限访问角色数据!")) + return + } + + data := s.sysUserService.SelectAllocatedPage(querys) + ctx.JSON(w, 200, result.Ok(data)) +} + +// 角色分配选择授权 +// +// PUT /authUser/checked +func (s *SysRoleApi) AuthUserChecked(w http.ResponseWriter, r *http.Request) { + var body struct { + // 角色ID + RoleID string `json:"roleId" binding:"required"` + // 用户ID组 + UserIDs string `json:"userIds" binding:"required"` + // 选择操作 添加true 取消false + Checked bool `json:"checked"` + } + err := ctx.ShouldBindJSON(r, &body) + if err != nil { + ctx.JSON(w, 400, result.CodeMsg(400, "参数错误")) + return + } + + // 处理字符转id数组后去重 + ids := strings.Split(body.UserIDs, ",") + uniqueIDs := parse.RemoveDuplicates(ids) + if len(uniqueIDs) <= 0 { + ctx.JSON(w, 200, result.Err(nil)) + return + } + + // 检查是否存在 + role := s.sysRoleService.SelectRoleById(body.RoleID) + if role.RoleID != body.RoleID { + ctx.JSON(w, 200, result.ErrMsg("没有权限访问角色数据!")) + return + } + + var rows int64 + if body.Checked { + rows = s.sysRoleService.InsertAuthUsers(body.RoleID, uniqueIDs) + } else { + rows = s.sysRoleService.DeleteAuthUsers(body.RoleID, uniqueIDs) + } + if rows > 0 { + ctx.JSON(w, 200, result.Ok(nil)) + return + } + ctx.JSON(w, 200, result.Err(nil)) +} diff --git a/features/sys_role/model/sys_role.go b/features/sys_role/model/sys_role.go new file mode 100644 index 00000000..921fd252 --- /dev/null +++ b/features/sys_role/model/sys_role.go @@ -0,0 +1,38 @@ +package model + +// SysRole 角色对象 sys_role +type SysRole struct { + // 角色ID + RoleID string `json:"roleId"` + // 角色名称 + RoleName string `json:"roleName" binding:"required"` + // 角色键值 + RoleKey string `json:"roleKey" binding:"required"` + // 显示顺序 + RoleSort int `json:"roleSort"` + // 菜单树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示) + MenuCheckStrictly string `json:"menuCheckStrictly"` + // 部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示) + DeptCheckStrictly string `json:"deptCheckStrictly"` + // 角色状态(0停用 1正常) + Status string `json:"status"` + // 删除标志(0代表存在 1代表删除) + DelFlag string `json:"delFlag"` + // 创建者 + CreateBy string `json:"createBy"` + // 创建时间 + CreateTime int64 `json:"createTime"` + // 更新者 + UpdateBy string `json:"updateBy"` + // 更新时间 + UpdateTime int64 `json:"updateTime"` + // 备注 + Remark string `json:"remark"` + + // ====== 非数据库字段属性 ====== + + // 菜单组 + MenuIds []string `json:"menuIds,omitempty"` + // 部门组(数据权限) + DeptIds []string `json:"deptIds,omitempty"` +} diff --git a/features/sys_role/service/repo_sys_role.go b/features/sys_role/service/repo_sys_role.go new file mode 100644 index 00000000..3aa66407 --- /dev/null +++ b/features/sys_role/service/repo_sys_role.go @@ -0,0 +1,357 @@ +package service + +import ( + "fmt" + "strings" + "time" + + "ems.agt/features/sys_role/model" + "ems.agt/lib/core/datasource" + "ems.agt/lib/core/utils/date" + "ems.agt/lib/core/utils/parse" + "github.com/go-admin-team/go-admin-core/logger" +) + +// 实例化数据层 RepoSysRole 结构体 +var NewRepoSysRole = &RepoSysRole{ + selectSql: `select distinct + r.role_id, r.role_name, r.role_key, r.role_sort, r.menu_check_strictly, + r.dept_check_strictly, r.status, r.del_flag, r.create_time, r.remark + from sys_role r + left join sys_user_role ur on ur.role_id = r.role_id + left join sys_user u on u.user_id = ur.user_id + left join sys_dept d on u.dept_id = d.dept_id`, + + resultMap: map[string]string{ + "role_id": "RoleID", + "role_name": "RoleName", + "role_key": "RoleKey", + "role_sort": "RoleSort", + "menu_check_strictly": "MenuCheckStrictly", + "dept_check_strictly": "DeptCheckStrictly", + "status": "Status", + "del_flag": "DelFlag", + "create_by": "CreateBy", + "create_time": "CreateTime", + "update_by": "UpdateBy", + "update_time": "UpdateTime", + "remark": "Remark", + }, +} + +// RepoSysRole 角色表 数据层处理 +type RepoSysRole struct { + // 查询视图对象SQL + selectSql string + // 结果字段与实体映射 + resultMap map[string]string +} + +// convertResultRows 将结果记录转实体结果组 +func (r *RepoSysRole) convertResultRows(rows []map[string]any) []model.SysRole { + arr := make([]model.SysRole, 0) + for _, row := range rows { + sysRole := model.SysRole{} + for key, value := range row { + if keyMapper, ok := r.resultMap[key]; ok { + datasource.SetFieldValue(&sysRole, keyMapper, value) + } + } + arr = append(arr, sysRole) + } + return arr +} + +// SelectRolePage 根据条件分页查询角色数据 +func (r *RepoSysRole) SelectRolePage(query map[string]any) map[string]any { + // 查询条件拼接 + var conditions []string + var params []any + if v, ok := query["roleId"]; ok && v != "" { + conditions = append(conditions, "r.role_id = ?") + params = append(params, v) + } + if v, ok := query["roleName"]; ok && v != "" { + conditions = append(conditions, "r.role_name like concat(?, '%')") + params = append(params, v) + } + if v, ok := query["roleKey"]; ok && v != "" { + conditions = append(conditions, "r.role_key like concat(?, '%')") + params = append(params, v) + } + if v, ok := query["status"]; ok && v != "" { + conditions = append(conditions, "r.status = ?") + params = append(params, v) + } + beginTime, ok := query["beginTime"] + if !ok { + beginTime, ok = query["params[beginTime]"] + } + if ok && beginTime != "" { + conditions = append(conditions, "r.create_time >= ?") + beginDate := date.ParseStrToDate(beginTime.(string), date.YYYY_MM_DD) + params = append(params, beginDate.UnixMilli()) + } + endTime, ok := query["endTime"] + if !ok { + endTime, ok = query["params[endTime]"] + } + if ok && endTime != "" { + conditions = append(conditions, "r.create_time <= ?") + endDate := date.ParseStrToDate(endTime.(string), date.YYYY_MM_DD) + params = append(params, endDate.UnixMilli()) + } + if v, ok := query["deptId"]; ok && v != "" { + conditions = append(conditions, `(u.dept_id = ? or u.dept_id in ( + select t.dept_id from sys_dept t where find_in_set(?, ancestors) + ))`) + params = append(params, v) + params = append(params, v) + } + + // 构建查询条件语句 + whereSql := " where r.del_flag = '0' " + if len(conditions) > 0 { + whereSql += " and " + strings.Join(conditions, " and ") + } + + // 查询数量 长度为0直接返回 + totalSql := `select count(distinct r.role_id) as 'total' from sys_role r + left join sys_user_role ur on ur.role_id = r.role_id + left join sys_user u on u.user_id = ur.user_id + left join sys_dept d on u.dept_id = d.dept_id` + totalRows, err := datasource.RawDB("", totalSql+whereSql, params) + if err != nil { + logger.Errorf("total err => %v", err) + } + total := parse.Number(totalRows[0]["total"]) + if total == 0 { + return map[string]any{ + "total": total, + "rows": []model.SysRole{}, + } + } + + // 分页 + pageNum, pageSize := datasource.PageNumSize(query["pageNum"], query["pageSize"]) + pageSql := " order by r.role_sort asc limit ?,? " + params = append(params, pageNum*pageSize) + params = append(params, pageSize) + + // 查询数据 + querySql := r.selectSql + whereSql + pageSql + results, err := datasource.RawDB("", querySql, params) + if err != nil { + logger.Errorf("query err => %v", err) + } + + // 转换实体 + rows := r.convertResultRows(results) + return map[string]any{ + "total": total, + "rows": rows, + } +} + +// SelectRoleList 根据条件查询角色数据 +func (r *RepoSysRole) SelectRoleList(sysRole model.SysRole) []model.SysRole { + // 查询条件拼接 + var conditions []string + var params []any + if sysRole.RoleID != "" { + conditions = append(conditions, "r.role_id = ?") + params = append(params, sysRole.RoleID) + } + if sysRole.RoleKey != "" { + conditions = append(conditions, "r.role_key like concat(?, '%')") + params = append(params, sysRole.RoleKey) + } + if sysRole.RoleName != "" { + conditions = append(conditions, "r.role_name like concat(?, '%')") + params = append(params, sysRole.RoleName) + } + if sysRole.Status != "" { + conditions = append(conditions, "r.status = ?") + params = append(params, sysRole.Status) + } + + // 构建查询条件语句 + whereSql := " where r.del_flag = '0' " + if len(conditions) > 0 { + whereSql += " and " + strings.Join(conditions, " and ") + } + + // 查询数据 + orderSql := " order by r.role_sort" + querySql := r.selectSql + whereSql + orderSql + rows, err := datasource.RawDB("", querySql, params) + if err != nil { + logger.Errorf("query err => %v", err) + return []model.SysRole{} + } + return r.convertResultRows(rows) +} + +// SelectRoleListByUserId 根据用户ID获取角色选择框列表 +func (r *RepoSysRole) SelectRoleListByUserId(userId string) []model.SysRole { + querySql := r.selectSql + " where r.del_flag = '0' and ur.user_id = ?" + results, err := datasource.RawDB("", querySql, []any{userId}) + if err != nil { + logger.Errorf("query err => %v", err) + return []model.SysRole{} + } + return r.convertResultRows(results) +} + +// SelectRoleByIds 通过角色ID查询角色 +func (r *RepoSysRole) SelectRoleByIds(roleIds []string) []model.SysRole { + placeholder := datasource.KeyPlaceholderByQuery(len(roleIds)) + querySql := r.selectSql + " where r.role_id in (" + placeholder + ")" + parameters := datasource.ConvertIdsSlice(roleIds) + results, err := datasource.RawDB("", querySql, parameters) + if err != nil { + logger.Errorf("query err => %v", err) + return []model.SysRole{} + } + // 转换实体 + return r.convertResultRows(results) +} + +// UpdateRole 修改角色信息 +func (r *RepoSysRole) UpdateRole(sysRole model.SysRole) int64 { + // 参数拼接 + params := make(map[string]any) + if sysRole.RoleName != "" { + params["role_name"] = sysRole.RoleName + } + if sysRole.RoleKey != "" { + params["role_key"] = sysRole.RoleKey + } + if sysRole.RoleSort > 0 { + params["role_sort"] = sysRole.RoleSort + } + if sysRole.MenuCheckStrictly != "" { + params["menu_check_strictly"] = sysRole.MenuCheckStrictly + } + if sysRole.DeptCheckStrictly != "" { + params["dept_check_strictly"] = sysRole.DeptCheckStrictly + } + if sysRole.Status != "" { + params["status"] = sysRole.Status + } + if sysRole.Remark != "" { + params["remark"] = sysRole.Remark + } + if sysRole.UpdateBy != "" { + params["update_by"] = sysRole.UpdateBy + params["update_time"] = time.Now().UnixMilli() + } + + // 构建执行语句 + keys, values := datasource.KeyValueByUpdate(params) + sql := "update sys_role set " + strings.Join(keys, ",") + " where role_id = ?" + + // 执行更新 + values = append(values, sysRole.RoleID) + rows, err := datasource.ExecDB("", sql, values) + if err != nil { + logger.Errorf("update row : %v", err.Error()) + return 0 + } + return rows +} + +// InsertRole 新增角色信息 +func (r *RepoSysRole) InsertRole(sysRole model.SysRole) string { + // 参数拼接 + params := make(map[string]any) + if sysRole.RoleID != "" { + params["role_id"] = sysRole.RoleID + } + if sysRole.RoleName != "" { + params["role_name"] = sysRole.RoleName + } + if sysRole.RoleKey != "" { + params["role_key"] = sysRole.RoleKey + } + if sysRole.RoleSort > 0 { + params["role_sort"] = sysRole.RoleSort + } + if sysRole.MenuCheckStrictly != "" { + params["menu_check_strictly"] = sysRole.MenuCheckStrictly + } + if sysRole.DeptCheckStrictly != "" { + params["dept_check_strictly"] = sysRole.DeptCheckStrictly + } + if sysRole.Status != "" { + params["status"] = sysRole.Status + } + if sysRole.Remark != "" { + params["remark"] = sysRole.Remark + } + if sysRole.CreateBy != "" { + params["create_by"] = sysRole.CreateBy + params["create_time"] = time.Now().UnixMilli() + } + + // 构建执行语句 + keys, placeholder, values := datasource.KeyPlaceholderValueByInsert(params) + sql := "insert into sys_role (" + strings.Join(keys, ",") + ")values(" + placeholder + ")" + + // 执行插入 + rows, err := datasource.ExecDB("", sql, values) + if err != nil { + logger.Errorf("insert row : %v", err.Error()) + return "" + } + + return fmt.Sprint(rows) +} + +// DeleteRoleByIds 批量删除角色信息 +func (r *RepoSysRole) DeleteRoleByIds(roleIds []string) int64 { + placeholder := datasource.KeyPlaceholderByQuery(len(roleIds)) + sql := "update sys_role set del_flag = '1' where role_id in (" + placeholder + ")" + parameters := datasource.ConvertIdsSlice(roleIds) + results, err := datasource.ExecDB("", sql, parameters) + if err != nil { + logger.Errorf("delete err => %v", err) + return 0 + } + return results +} + +// CheckUniqueRole 校验角色是否唯一 +func (r *RepoSysRole) CheckUniqueRole(sysRole model.SysRole) string { + // 查询条件拼接 + var conditions []string + var params []any + if sysRole.RoleName != "" { + conditions = append(conditions, "r.role_name = ?") + params = append(params, sysRole.RoleName) + } + if sysRole.RoleKey != "" { + conditions = append(conditions, "r.role_key = ?") + params = append(params, sysRole.RoleKey) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } else { + return "" + } + + // 查询数据 + querySql := "select role_id as 'str' from sys_role r " + whereSql + " and r.del_flag = '0' limit 1" + results, err := datasource.RawDB("", querySql, params) + if err != nil { + logger.Errorf("query err %v", err) + return "" + } + if len(results) > 0 { + return fmt.Sprintf("%v", results[0]["str"]) + } + return "" +} diff --git a/features/sys_role/service/service_sys_role.go b/features/sys_role/service/service_sys_role.go new file mode 100644 index 00000000..41c659a8 --- /dev/null +++ b/features/sys_role/service/service_sys_role.go @@ -0,0 +1,163 @@ +package service + +import ( + "errors" + "fmt" + + "ems.agt/features/sys_role/model" + sysrolemenu "ems.agt/features/sys_role_menu" + sysuserrole "ems.agt/features/sys_user_role" +) + +// 实例化服务层 ServiceSysRole 结构体 +var NewServiceSysRole = &ServiceSysRole{ + sysRoleRepository: NewRepoSysRole, + sysUserRoleRepository: sysuserrole.NewRepoSysUserRole, + sysRoleMenuRepository: sysrolemenu.NewRepoSysRoleMenu, +} + +// ServiceSysRole 角色 服务层处理 +type ServiceSysRole struct { + // 角色服务 + sysRoleRepository *RepoSysRole + // 用户与角色关联服务 + sysUserRoleRepository *sysuserrole.RepoSysUserRole + // 角色与菜单关联服务 + sysRoleMenuRepository *sysrolemenu.RepoSysRoleMenu +} + +// SelectRolePage 根据条件分页查询角色数据 +func (r *ServiceSysRole) SelectRolePage(query map[string]any) map[string]any { + return r.sysRoleRepository.SelectRolePage(query) +} + +// SelectRoleList 根据条件查询角色数据 +func (r *ServiceSysRole) SelectRoleList(sysRole model.SysRole) []model.SysRole { + return r.sysRoleRepository.SelectRoleList(sysRole) +} + +// SelectRoleListByUserId 根据用户ID获取角色选择框列表 +func (r *ServiceSysRole) SelectRoleListByUserId(userId string) []model.SysRole { + return r.sysRoleRepository.SelectRoleListByUserId(userId) +} + +// SelectRoleById 通过角色ID查询角色 +func (r *ServiceSysRole) SelectRoleById(roleId string) model.SysRole { + if roleId == "" { + return model.SysRole{} + } + posts := r.sysRoleRepository.SelectRoleByIds([]string{roleId}) + if len(posts) > 0 { + return posts[0] + } + return model.SysRole{} +} + +// UpdateRole 修改角色信息 +func (r *ServiceSysRole) UpdateRole(sysRole model.SysRole) int64 { + rows := r.sysRoleRepository.UpdateRole(sysRole) + if rows > 0 && len(sysRole.MenuIds) > 0 { + // 删除角色与菜单关联 + r.sysRoleMenuRepository.DeleteRoleMenu([]string{sysRole.RoleID}) + r.insertRoleMenu(sysRole.RoleID, sysRole.MenuIds) + } + return rows +} + +// InsertRole 新增角色信息 +func (r *ServiceSysRole) InsertRole(sysRole model.SysRole) string { + insertId := r.sysRoleRepository.InsertRole(sysRole) + if insertId != "" && len(sysRole.MenuIds) > 0 { + r.insertRoleMenu(insertId, sysRole.MenuIds) + } + return insertId +} + +// insertRoleMenu 新增角色菜单信息 +func (r *ServiceSysRole) insertRoleMenu(roleId string, menuIds []string) int64 { + if roleId == "" || len(menuIds) <= 0 { + return 0 + } + + sysRoleMenus := []sysrolemenu.SysRoleMenu{} + for _, menuId := range menuIds { + if menuId == "" { + continue + } + sysRoleMenus = append(sysRoleMenus, sysrolemenu.NewSysRoleMenu(roleId, menuId)) + } + + return r.sysRoleMenuRepository.BatchRoleMenu(sysRoleMenus) +} + +// DeleteRoleByIds 批量删除角色信息 +func (r *ServiceSysRole) DeleteRoleByIds(roleIds []string) (int64, error) { + // 检查是否存在 + roles := r.sysRoleRepository.SelectRoleByIds(roleIds) + if len(roles) <= 0 { + return 0, errors.New("没有权限访问角色数据!") + } + for _, role := range roles { + // 检查是否为已删除 + if role.DelFlag == "1" { + return 0, errors.New(role.RoleID + " 角色信息已经删除!") + } + // 检查分配用户 + userCount := r.sysUserRoleRepository.CountUserRoleByRoleId(role.RoleID) + if userCount > 0 { + msg := fmt.Sprintf("【%s】已分配给用户,不能删除", role.RoleName) + return 0, errors.New(msg) + } + } + if len(roles) == len(roleIds) { + // 删除角色与菜单关联 + r.sysRoleMenuRepository.DeleteRoleMenu(roleIds) + rows := r.sysRoleRepository.DeleteRoleByIds(roleIds) + return rows, nil + } + return 0, errors.New("删除角色信息失败!") +} + +// CheckUniqueRoleName 校验角色名称是否唯一 +func (r *ServiceSysRole) CheckUniqueRoleName(roleName, roleId string) bool { + uniqueId := r.sysRoleRepository.CheckUniqueRole(model.SysRole{ + RoleName: roleName, + }) + if uniqueId == roleId { + return true + } + return uniqueId == "" +} + +// CheckUniqueRoleKey 校验角色权限是否唯一 +func (r *ServiceSysRole) CheckUniqueRoleKey(roleKey, roleId string) bool { + uniqueId := r.sysRoleRepository.CheckUniqueRole(model.SysRole{ + RoleKey: roleKey, + }) + if uniqueId == roleId { + return true + } + return uniqueId == "" +} + +// DeleteAuthUsers 批量取消授权用户角色 +func (r *ServiceSysRole) DeleteAuthUsers(roleId string, userIds []string) int64 { + return r.sysUserRoleRepository.DeleteUserRoleByRoleId(roleId, userIds) +} + +// InsertAuthUsers 批量新增授权用户角色 +func (r *ServiceSysRole) InsertAuthUsers(roleId string, userIds []string) int64 { + if roleId == "" || len(userIds) <= 0 { + return 0 + } + + sysUserRoles := []sysuserrole.SysUserRole{} + for _, userId := range userIds { + if userId == "" { + continue + } + sysUserRoles = append(sysUserRoles, sysuserrole.NewSysUserRole(userId, roleId)) + } + + return r.sysUserRoleRepository.BatchUserRole(sysUserRoles) +}