一. DB设计
1. 说明
框架的基础功能包括:用户管理、角色管理、登录日志、操作日志模块,1个角色可以配置多个权限,1个用户可以配置多个角色,相关表设计如下,大致思路:登录→根据userId拿到所有角色Id→获取所有角色Id对应的权限信息→对这些权限信息去重。
2.详细结构分享
(1). 用户表
(2). 角色表
(3). 菜单权限表
(4). 用户-角色关联表
(5). 角色-菜单权限关联表
(6). 操作日志表
(7). 登录日志表
二. 业务接口编写
1. 说明
控制器按区域存放,路由匹配规则为:[Route("Api/[area]/[controller]/[action]")],相关接口设计详见下面代码,在后续章节将结合EasyUI框架中的各种组件来分析接口业务。
2. 详细接口分享
(1). 主控制器- SysMainApiController
[Area("AdminApi_Areas")] [Route("Api/[area]/[controller]/[action]")] [SkipLogin] public class SysMainApiController : Controller { public IBaseService _baseService; public IConfiguration _configuration; public SysMainApiController(IBaseService baseService, IConfiguration configuration) { this._baseService = baseService; this._configuration = configuration; } #region 01-校验登录 /// <summary> /// 校验登录 /// </summary> /// <param name="userAccount">账号</param> /// <param name="passWord">密码</param> /// <returns></returns> [SkipAll] public IActionResult CheckLogin(string userAccount, string passWord) { try { //1.校验账号是否存在 var userInfor = _baseService.Entities<T_SysUser>().Where(u => u.userAccount == userAccount).FirstOrDefault(); if (userInfor != null) { //2. 账号和密码是否匹配 var passWord1 = SecurityHelp.SHA(passWord); if (passWord1.Equals(userInfor.userPwd, StringComparison.InvariantCultureIgnoreCase)) { //3. 产生token进行返回 //过期时间(可以不设置,下面表示签名后 12个小时过期) double exp = (DateTime.UtcNow.AddHours(12) - new DateTime(1970, 1, 1)).TotalSeconds; //进行组装 var payload = new Dictionary<string, object> { {"userId", userInfor.id }, {"userAccount", userInfor.userAccount }, {"exp",exp } }; var token = JWTHelp.JWTJiaM(payload, _configuration["JWTSecret"]); //4.记录登录日志 T_SysLoginLog sysLoginLog = new T_SysLoginLog() { id = Guid.NewGuid().ToString("N"), userId = userInfor.id, userAccount = userInfor.userAccount, loginTime = DateTime.Now, delFlag = 0, loginIp = HttpContext.Connection.RemoteIpAddress.ToString() }; _baseService.Add(sysLoginLog); return Json(new { status = "ok", msg = "登录成功", data = token }); } else { //密码不正确 return Json(new { status = "error", msg = "密码不正确", data = "" }); } } else { return Json(new { status = "error", msg = "账号不存在", data = "" }); }; } catch (Exception ex) { LogUtils.Error(ex); ; return Json(new { status = "error", msg = "登录失败", data = "" }); } } #endregion #region 02-获取左侧菜单权限结构(EasyUI版本)【已修改】 /// <summary> /// 获取权限信息 /// </summary> /// <returns></returns> [HttpPost] public async Task<string> GetEasyLeftMenu() { try { var jwtData = JsonHelp.ToObject<JwtData>(ControllerContext.RouteData.Values["auth"].ToString()); var userId = jwtData.userId; //根据用户Id,查出来所有的角色,然后把所有角色对应的权限id查出来并去重 var data1 = _baseService.Entities<T_SysUserRole>(); var data2 = _baseService.Entities<T_SysRolePer>(); var data = await (from a in data1 join b in data2 on a.roleId equals b.roleId where a.userId == userId select b).Select(p => p.perId).Distinct().ToListAsync(); //根据权限Id组装固定格式的权限信息进行反馈 var perList = await _baseService.GetListByAsync<T_SysPermisson>(u => u.delFlag == 0 && data.Contains(u.id)); List<EasyUiMenuInfor> menuList = GetOwnAllPer(perList, "1"); return JsonHelp.ToJsonString(menuList); } catch (Exception ex) { LogUtils.Error(ex); return ""; } } /// <summary> /// 获取所有自己的菜单信息 /// </summary> /// <param name="perList">所有的自己的菜单权限</param> /// <param name="parentId">父菜单id</param> /// <returns></returns> public List<EasyUiMenuInfor> GetOwnAllPer(List<T_SysPermisson> perList, string parentId) { var perListMain = perList.Where(p => p.parentId == parentId).OrderBy(u => u.sortFlag).ToList(); if (perListMain.Count() > 0) { //最新的组装形式 List<EasyUiMenuInfor> menuList = new List<EasyUiMenuInfor>(); foreach (var item in perListMain) { EasyUiMenuInfor menuItem = new EasyUiMenuInfor(); menuItem.id = item.id; menuItem.text = item.menuName; var myUrl = item.frontUrl; menuItem.attributes = myUrl; menuItem.iconCls = item.iconClassName; menuItem.children = GetChildPer(perList, item.id); menuItem.state = menuItem.children.Count() == 0 ? "open" : "closed"; menuList.Add(menuItem); } return menuList; } else { return new List<EasyUiMenuInfor>(); //返回空集合 } } /// <summary> /// 获取所有的子菜单权限 /// </summary> /// <param name="perList"></param> /// <param name="childId"></param> /// <returns></returns> public List<EasyUiMenuInfor> GetChildPer(List<T_SysPermisson> perList, string childId) { var perListMain = perList.Where(p => p.parentId == childId).OrderBy(u => u.sortFlag).ToList(); if (perListMain.Count() > 0) { return GetOwnAllPer(perList, childId); } else { return new List<EasyUiMenuInfor>(); //返回空集合 } } #endregion }