RBAC权限管理
一、SQL数据库操作
创建数据库,有五个基础的表,分别是用户表,角色表,用户角色表,菜单表,角色菜单表,他们是一对多的关系
一、API后台
在后台中安装依赖包

安装完之后开始分配类库

在对应的类库中写相关的操作 Model放在了SysDomain中,数据访问层写在了BaWei.RBACExam.Repository=》Repository
在Startup中操作
using BaWei.RBACExam.Config;
using BaWei.RBACExam.Repository.Repository;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BaWei.RBACExam
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//原样输出
services.AddControllers()
.AddNewtonsoftJson(options => {
// 忽略循环引用
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
// 不使用驼峰
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
// 设置时间格式
options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
// 如字段为 null 值,该字段不会返回到前端
// options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
});
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "BaWei.RBACExam", Version = "v1" });
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
{
Description = "在下框中输入请求头中需要添加Jwt授权Token:Bearer Token",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey,
BearerFormat = "JWT",
Scheme = "Bearer"
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference {
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
new string[] { }
}
});
});
//跨域:
services.AddCors(option =>
{
option.AddDefaultPolicy(p => {
p.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
});
});
//配置 Redis
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = Configuration.GetSection("RedisConnectionStrings").Value;
//options.InstanceName = "SampleInstance";
});
services.AddTransient<MenuRepository>();
services.AddTransient<UserRepository>();
services.AddTransient<RoleRepository>();
services.AddSingleton<JwtHelpers>();
//验证
services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
// 當驗證失敗時,回應標頭會包含 WWW-Authenticate 標頭,這裡會顯示失敗的詳細錯誤原因
options.IncludeErrorDetails = true; // 預設值為 true,有時會特別關閉
options.TokenValidationParameters = new TokenValidationParameters
{
// 透過這項宣告,就可以從 "sub" 取值並設定給 User.Identity.Name
NameClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier",
// 透過這項宣告,就可以從 "roles" 取值,並可讓 [Authorize] 判斷角色
RoleClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
// 一般我們都會驗證 Issuer
ValidateIssuer = true,
ValidIssuer = Configuration.GetValue<string>("JwtSettings:Issuer"),
// 通常不太需要驗證 Audience
ValidateAudience = false,
//ValidAudience = "JwtAuthDemo", // 不驗證就不需要填寫
// 一般我們都會驗證 Token 的有效期間
ValidateLifetime = true,
// 如果 Token 中包含 key 才需要驗證,一般都只有簽章而已
ValidateIssuerSigningKey = false,
// "1234567890123456" 應該從 IConfiguration 取得
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration.GetValue<string>("JwtSettings:SignKey")))
};
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "BaWei.RBACExam v1"));
}
app.UseRouting();
app.UseCors();
//验证
app.UseAuthentication();
//授权
app.UseAuthorization();
//静态文件 中间件使用
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(env.ContentRootPath, "Images")),
RequestPath = "/StaticFiles"
});
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
在appsettings中加入连接接数据库的操作
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"MsSqlServer": "Data Source=.;Initial Catalog=RBACDB;User ID=sa;pwd=123456;"
},
"RedisConnectionStrings": "127.0.0.1:6379",
"JwtSettings": {
"Issuer": "JwtAuthDemo",
"SignKey": "12eqwewr212weq2eqe3223reewer122ewqr567d"
}
}
- 用户表的操作代码
using BaWei.RBACExam.Model.SysDomain;
using Dapper;
using Microsoft.Extensions.Configuration;
using Surpass.Model;
using Surpass.Model.Dto.ResponseDto.ResponseModel.ResultModel;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BaWei.RBACExam.Repository.Repository
{
public class UserRepository
{
private readonly IConfiguration _configuration;
public UserRepository(IConfiguration configuration)
{
_configuration = configuration;
}
public List<UserModel> ShowUser(out int totalcount,int pageindex=1,int pagesize=3,string email="",string userName="")
{
using (IDbConnection conn = new SqlConnection(_configuration.GetConnectionString("MsSqlServer")))
{
//var list= conn.GetListPaged<UserModel>(pageindex, pagesize, "", "");
//totalcount = conn.RecordCount<UserModel>();
var sql = "select * from [User] where Deleted=1 ";
if (!string.IsNullOrEmpty(userName))
{
sql += " and UserName like '%" + userName + "%'";
}
if (!string.IsNullOrEmpty(email))
{
sql += " and Email like '%" + email + "%'"; ;
}
var list = conn.Query<UserModel>(sql);
totalcount = list.Count();
list = list.OrderBy(m => m.UserId).Skip((pageindex - 1) * pagesize).Take(pagesize).ToList();
return list.ToList();
}
}
public int Del(int id)
{
using (IDbConnection conn = new SqlConnection(_configuration.GetConnectionString("MsSqlServer")))
{
var sql = "update [User] set Deleted=0 where UserId='"+id+"'";
var list= conn.Execute(sql);
return list;
}
}
public int DelAll(string id)
{
using (IDbConnection conn = new SqlConnection(_configuration.GetConnectionString("MsSqlServer")))
{
var sql = "update [User] set Deleted=0 where UserId in (ids)";
var list = conn.Execute(sql);
return list;
}
}
public int AddUser(UserModel userModel)
{
using (IDbConnection conn = new SqlConnection(_configuration.GetConnectionString("MsSqlServer")))
{
var sql = ($"insert into [User] values('{userModel.UserId}','{userModel.UserName}','{userModel.PassWord}','{userModel.Email}','{userModel.Sex}',1,0,GETDATE(),0,GETDATE(),0,'')");
conn.Execute(sql);
return 1;
}
}
public PageResponse<UserModel> FanUser(long userId)
{
var result = new PageResponse<UserModel>();
using(IDbConnection conn=new SqlConnection(_configuration.GetConnectionString("MsSqlServer")))
{
var sql = $"select * from [User] where UserId={userId}";
result.PageData = conn.Query<UserModel>(sql).ToList();
}
return result;
}
public int UpdateUser(UserModel userModel)
{
using (IDbConnection conn = new SqlConnection(_configuration.GetConnectionString("MsSqlServer")))
{
var sql = $"update [User] set UserName='{userModel.UserName}',[PassWord]='{userModel.PassWord}',Email='{userModel.Email}',Sex='{userModel.Sex}' where UserId='{userModel.UserId}'";
var list= conn.Execute(sql);
return list;
}
}
public int DelUR(long userId)
{
using (IDbConnection conn = new SqlConnection(_configuration.GetConnectionString("MsSqlServer")))
{
var list = conn.Execute($"delete from URRelation where UserId='{userId}'");
return list;
}
}
public ResponseModel<UserModel> Login(string userName,string passWord)
{
ResponseModel<UserModel> responseModel = new ResponseModel<UserModel>();
using (IDbConnection conn = new SqlConnection(_configuration.GetConnectionString("MsSqlServer")))
{
var list = conn.Query<UserModel>($"select * from [User] where UserName='{userName}' and [PassWord]='{passWord}'").FirstOrDefault();
if(list!=null)
{
return responseModel.Succeed(list);
}
else
{
return responseModel.Fail(ResponseCode.LoginFail, "登录失败");
}
//if(list.PassWord!=passWord)
//{
// return responseModel.Fail(ResponseCode.LoginFail, "密码不存在");
//}
}
}
}
}
- 角色表代码
using BaWei.RBACExam.Model.Dto.Response.ResponseDtoModel.PermissionDtoModel;
using BaWei.RBACExam.Model.SysDomain;
using Dapper;
using Microsoft.Extensions.Configuration;
using Surpass.Model.Dto.ResponseDto.ResponseModel.ResultModel;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BaWei.RBACExam.Repository.Repository
{
public class RoleRepository
{
private readonly IConfiguration _configuration;
public RoleRepository(IConfiguration configuration)
{
_configuration = configuration;
}
public PageResponse<RoleModel> ShowRole(string roleName = "")
{
var result = new PageResponse<RoleModel>();
using (IDbConnection conn = new SqlConnection(_configuration.GetConnectionString("MsSqlServer")))
{
var sql = "select * from [Role] where Deleted=1 ";
if(!string.IsNullOrWhiteSpace(roleName))
{
sql += " and RoleName like '%" + roleName + "%'";
}
result.PageData = conn.Query<RoleModel>(sql).ToList();
return result;
}
}
public PageResponse<RoleModel> ShowRoles()
{
var result = new PageResponse<RoleModel>();
using (IDbConnection conn = new SqlConnection(_configuration.GetConnectionString("MsSqlServer")))
{
var sql = "select * from [Role] where Deleted=1 ";
result.PageData = conn.Query<RoleModel>(sql).ToList();
return result;
}
}
//public ResponseModel<bool> AddUR(UserRoleRelationDtoModel userRoleRelationDtoModel)
//{
// var result = new ResponseModel<bool>();
// using (IDbConnection conn = new SqlConnection(_configuration.GetConnectionString("MsSqlServer")))
// {
// var kk = conn.Execute($"delete URRelation where UserId='{userRoleRelationDtoModel.UserId}'");
// conn.Open();
// using (var begin = conn.BeginTransaction())
// {
// try
// {
// if (kk>0)
// {
// foreach (var item in userRoleRelationDtoModel.RoleIds.Split(','))
// {
// conn.Execute($"insert into URRelation values({userRoleRelationDtoModel.UserId},{item},1,0,GETDATE(),0,GETDATE(),0)", null, begin);
// }
// }
// begin.Commit();
// return result.Succeed(true);
// }
// catch (Exception ex)
// {
// begin.Rollback();
// throw ex;
// }
// }
// }
//}
public PageResponse<RoleDtoModel> ShowRoless()
{
var result = new PageResponse<RoleDtoModel>();
using (IDbConnection conn = new SqlConnection(_configuration.GetConnectionString("MsSqlServer")))
{
var sql = "select a.*,b.UserName,c.RoleName from URRelation a join[User] b on a.UserId = b.UserId join[Role] c on a.RoleId = c.RoleId where a.Deleted = 1 ";
result.PageData = conn.Query<RoleDtoModel>(sql).ToList();
return result;
}
}
public PageResponse<URRelationModel> FanRole(long userId)
{
var result = new PageResponse<URRelationModel>();
using (IDbConnection conn = new SqlConnection(_configuration.GetConnectionString("MsSqlServer")))
{
conn.Open();
var sql = $"select * from URRelation where UserId={userId}";
result.PageData = conn.Query<URRelationModel>(sql).ToList();
}
return result;
}
public int Del(int id)
{
using (IDbConnection conn = new SqlConnection(_configuration.GetConnectionString("MsSqlServer")))
{
var list = conn.Execute($"update [Role] set Deleted=0 where RoleId='{id}'");
return list;
}
}
public int AddRole(RoleModel roleModel)
{
using (IDbConnection conn = new SqlConnection(_configuration.GetConnectionString("MsSqlServer")))
{
var list = conn.Execute($"insert into [Role] values('{roleModel.RoleId}','{roleModel.RoleName}','{roleModel.RoleDesc}',1,GETDATE(),0,GETDATE(),0)");
return list;
}
}
public int UpdateRole(RoleModel roleModel)
{
using (IDbConnection conn = new SqlConnection(_configuration.GetConnectionString("MsSqlServer")))
{
var list = conn.Execute($"update [Role] set RoleName='{roleModel.RoleName}',RoleDesc='{roleModel.RoleDesc}' where RoleId='{roleModel.RoleId}'");
return list;
}
}
public int AddUR(UserRoleRelationDtoModel userRoleRelationDtoModel)
{
using (IDbConnection conn = new SqlConnection(_configuration.GetConnectionString("MsSqlServer")))
{
//var kk = conn.Execute($"delete URRelation where UserId='{userRoleRelationDtoModel.UserId}'");
var list = 0;
//if (kk > 0)
// {
foreach (var item in userRoleRelationDtoModel.RoleIds.Split(','))
{
list = conn.Execute($"insert into URRelation values('{userRoleRelationDtoModel.UserId}','{item}',0,1,GETDATE(),0,GETDATE(),0)");
}
// }
return list;
}
}
public int AddRM(RoleMenuRelationDtoModel roleMenuRelationDtoModel)
{
using (IDbConnection conn = new SqlConnection(_configuration.GetConnectionString("MsSqlServer")))
{
var kk = conn.Execute($"delete RMRelation where RoleId='{roleMenuRelationDtoModel.RoleId}'");
var list = 0;
if (kk>0)
{
foreach (var item in roleMenuRelationDtoModel.MenuIds.Split(','))
{
list = conn.Execute($"insert into RMRelation values('{roleMenuRelationDtoModel.RoleId}','{item}',0,1,GETDATE(),0,GETDATE(),0)");
}
}
return list;
}
}
public PageResponse<RMRelationModel> FanMenu(long id)
{
var result = new PageResponse<RMRelationModel>();
using (IDbConnection conn = new SqlConnection(_configuration.GetConnectionString("MsSqlServer")))
{
conn.Open();
var sql = $"select * from RMRelation where RoleId={id}";
result.PageData = conn.Query<RMRelationModel>(sql).ToList();
}
return result;
}
}
}
- 菜单表代码
using BaWei.RBACExam.Model.Dto.Response.ResponseDtoModel.MenuDtoModel;
using BaWei.RBACExam.Model.SysDomain;
using Dapper;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BaWei.RBACExam.Repository.Repository
{
public class MenuRepository
{
private readonly IConfiguration _configuration;
private readonly IDistributedCache _cache;
public MenuRepository(IConfiguration configuration,IDistributedCache cache)
{
_configuration = configuration;
_cache = cache;
}
public List<MenuResponse> GetMenuss(string menuName = "", int orderIndex = 0)
{
using (IDbConnection conn = new SqlConnection(_configuration.GetConnectionString("MsSqlServer")))
{
var sql = $"select * from Menu where Deleted=0 ";
if(!string.IsNullOrEmpty(menuName))
{
sql += " and MenuName like '%" + menuName + "%'";
}
if(orderIndex>0)
{
sql += " and OrderIndex='" + orderIndex + "'";
}
var list = conn.Query<MenuModel>(sql).ToList();
return GetMenuResponsess(list);
}
}
public List<MenuResponse> GetMenuResponsess(List<MenuModel> menuModels, string parentMenuId = "")
{
return menuModels.Where(m => m.Type == Config.SysConstants.MenuType.Menu && m.Deleted == false && m.ParentMenuId == parentMenuId).Select(m => new MenuResponse
{
Icon = m.Icon,
Level = m.Level,
Type = m.Type,
MenuId = m.MenuId,
MenuName = m.MenuName,
OrderIndex = m.OrderIndex,
ParentMenuId = m.ParentMenuId,
Url = m.Url,
ChildMenus = GetMenuResponsess(menuModels, m.MenuId)
}).ToList();
}
public int Del(string menuId)
{
using(IDbConnection conn=new SqlConnection(_configuration.GetConnectionString("MsSqlServer")))
{
var list= conn.Execute($"update Menu set Deleted=1 where MenuId='{menuId}'");
return list;
}
}
public List<MenuShowDtoModel> GetMenu(long userId)
{
using (IDbConnection conn = new SqlConnection(_configuration.GetConnectionString("MsSqlServer")))
{
var list = conn.Query<MenuShowDtoModel>($"select distinct a.MenuId,a.MenuName,a.Icon,a.ParentMenuId,a.Level,a.Url from Menu a join RMRelation b on a.MenuId=b.MenuId join URRelation c on b.RoleId=c.RoleId where c.UserId='{userId}'").ToList();
return list;
}
}
public List<MenuResponse> CheckMenus(long? userId)
{
using (IDbConnection conn = new SqlConnection(_configuration.GetConnectionString("MsSqlServer")))
{
var sql = $"select distinct a.MenuId,a.MenuName,a.Icon,a.ParentMenuId,a.Level,a.Url,a.Type from Menu a join RMRelation b on a.MenuId=b.MenuId join URRelation c on b.RoleId=c.RoleId where 1=1 ";
if (userId != null)
{
sql += $" and c.UserId={userId}";
}
var list = conn.Query<MenuModel>(sql).ToList();
return GetMenuResponsekk(list);
}
}
public List<MenuResponse> GetMenuResponsekk(List<MenuModel> menuModels, string parentMenuId = "")
{
return menuModels.Where(m => m.Type == Config.SysConstants.MenuType.Menu && m.Deleted == false && m.ParentMenuId == parentMenuId).Select(t => new MenuResponse
{
Icon = t.Icon,
Level = t.Level,
Type = t.Type,
MenuId = t.MenuId,
MenuName = t.MenuName,
OrderIndex = t.OrderIndex,
ParentMenuId = t.ParentMenuId,
Url = t.Url,
ChildMenus = GetMenuResponsekk(menuModels, t.MenuId).Count == 0 ? null:GetMenuResponsekk(menuModels, t.MenuId)
}).ToList();
}
}
}
控制器操作
- 用户表控制器
using BaWei.RBACExam.Config; using BaWei.RBACExam.Model.SysDomain; using BaWei.RBACExam.Repository.Repository; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace BaWei.RBACExam.Controllers { [Authorize] [Route("api/[controller]/[action]")] [ApiController] public class UserController : ControllerBase { private readonly UserRepository _userRepository; private readonly JwtHelpers _jwtHelpers; public UserController(UserRepository userRepository,JwtHelpers jwtHelpers) { _userRepository = userRepository; _jwtHelpers = jwtHelpers; } [HttpGet] public IActionResult ShowUser(int pageindex=1, int pagesize=3, string email="", string userName="") { var totalcount = 0; var list = _userRepository.ShowUser(out totalcount,pageindex, pagesize, email, userName); return Ok(new { list, totalcount }); } [HttpGet] public IActionResult Del(int id) { return Ok(_userRepository.Del(id)); } [HttpGet] public IActionResult DelAll(string ids) { return Ok(_userRepository.DelAll(ids)); } [HttpPost] public IActionResult AddUser(UserModel userModel) { return Ok(_userRepository.AddUser(userModel)); } [HttpPost] public IActionResult UpdateUser(UserModel userModel) { return Ok(_userRepository.UpdateUser(userModel)); } [HttpGet] public IActionResult FanUser(long userId) { return Ok(_userRepository.FanUser(userId)); } [HttpGet] public IActionResult DelUR(long userId) { return Ok(_userRepository.DelUR(userId)); } //任何请求都可以访问该方法 [AllowAnonymous] [HttpPost] public IActionResult Login(string userName, string passWord) { var user = _userRepository.Login(userName, passWord); if (user.Success) { var token = _jwtHelpers.GenerateToken(userName); HttpContext.Response.Headers.Add("token", token); HttpContext.Response.Headers["Access-Control-Expose-Headers"] = "token"; return Ok(user); } else { return Ok(user); } } } } - 角色表控制器
using BaWei.RBACExam.Model.Dto.Response.ResponseDtoModel.PermissionDtoModel; using BaWei.RBACExam.Model.SysDomain; using BaWei.RBACExam.Repository.Repository; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace BaWei.RBACExam.Controllers { [Route("api/[controller]/[action]")] [ApiController] public class RoleController : ControllerBase { private readonly RoleRepository _roleRepository; public RoleController(RoleRepository roleRepository) { _roleRepository = roleRepository; } [HttpGet] public IActionResult ShowRoles() { return Ok(_roleRepository.ShowRoles()); } [HttpGet] public IActionResult ShowRoless() { return Ok(_roleRepository.ShowRoless()); } [HttpGet] public IActionResult FanRole(long userId) { return Ok(_roleRepository.FanRole(userId)); } [HttpGet] public IActionResult Del(int id) { return Ok(_roleRepository.Del(id)); } [HttpGet] public IActionResult ShowRole(string roleName = "") { return Ok(_roleRepository.ShowRole(roleName)); } [HttpPost] public IActionResult AddRole(RoleModel roleModel) { return Ok(_roleRepository.AddRole(roleModel)); } [HttpPost] public IActionResult UpdateRole(RoleModel roleModel) { return Ok(_roleRepository.UpdateRole(roleModel)); } [HttpPost] public IActionResult AddUR(UserRoleRelationDtoModel userRoleRelationDtoModel) { return Ok(_roleRepository.AddUR(userRoleRelationDtoModel)); } [HttpPost] public IActionResult AddRM(RoleMenuRelationDtoModel roleMenuRelationDtoModel) { return Ok(_roleRepository.AddRM(roleMenuRelationDtoModel)); } [HttpGet] public IActionResult FanMenu(long id) { return Ok(_roleRepository.FanMenu(id)); } } } - 菜单表控制器
using BaWei.RBACExam.Repository.Repository; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace BaWei.RBACExam.Controllers { [Route("api/[controller]/[action]")] [ApiController] public class MenuController : ControllerBase { private readonly MenuRepository _menuRepository; public MenuController(MenuRepository menuRepository) { _menuRepository = menuRepository; } [HttpGet] public IActionResult GetMenuss(string menuName = "", int orderIndex = 0) { return Ok(_menuRepository.GetMenuss(menuName, orderIndex)); } [HttpGet] public IActionResult Del(string menuId) { return Ok(_menuRepository.Del(menuId)); } [HttpGet] public IActionResult GetMenu(long userId) { return Ok(_menuRepository.GetMenu(userId)); } [HttpGet] public IActionResult CheckMenus(long? userId) { //var kk= _menuRepository.CheckMenus(userId); return Ok(_menuRepository.CheckMenus(userId)); } } }
三、前台VsCode+VUE
- 安装axios,elemenut-ui等
- 创建一个文件夹,用来存储js文件
- 在main中引入,在index中去分配路径
import Vue from 'vue' import App from './App.vue' import router from './router' import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; import axios from './request/http' Vue.config.productionTip = false //Vue.prototype.$axios=axios Vue.use(ElementUI); Vue.prototype.$http=axios; new Vue({ router, render: h => h(App) }).$mount('#app') import Vue from 'vue' import VueRouter from 'vue-router' import Home from '../views/Home.vue' Vue.use(VueRouter) const routes = [ { path: '/', name: 'Home', component:Home, children:[{ path: '', name: 'About', // route level code-splitting // this generates a separate chunk (about.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import(/* webpackChunkName: "about" */ '../views/About.vue') }, { path: '/menu', name: 'Menu', // route level code-splitting // this generates a separate chunk (about.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import(/* webpackChunkName: "about" */ '../views/Menu.vue') }, { path: '/role', name: 'Role', // route level code-splitting // this generates a separate chunk (about.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import(/* webpackChunkName: "about" */ '../views/Role.vue') }, { path: '/dept', name: 'Dept', // route level code-splitting // this generates a separate chunk (about.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import(/* webpackChunkName: "about" */ '../views/Dept.vue') }] }, { path: '/login', name: 'Login', // route level code-splitting // this generates a separate chunk (about.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import(/* webpackChunkName: "about" */ '../views/Login.vue') } ] const router = new VueRouter({ routes }) export default router - 写一个拦截的js文件
import axios from 'axios'; //初始化 const $http=axios.create({ baseURL:'http://localhost:4098/api/', timeout:8000 //超时时间 }) //请求拦截 $http.interceptors.request.use(config=>{ const token=localStorage.getItem('token'); if(token){ config.headers.Authorization='Bearer '+token; } return config; }) //导出 export default $http - 登录页面
<template> <div class="kkk"> <div class="kk"> <el-input v-model="userName" placeholder="请输入用户名"></el-input> </div> <div class="kk"> <el-input v-model="passWord" placeholder="请输入密码"></el-input> </div> <div class="k"> <el-button type="primary" class="kkkk" @click="deng">登录</el-button> </div> </div> </template> <script> export default { data() { return { userName: "", passWord: "", }; }, methods: { deng() { this.$http .post( "User/Login?userName=" + this.userName + "&passWord=" + this.passWord + "" ) .then((res) => { if (res.data.Code==200) { localStorage.setItem("userid", res.data.Data.UserId); localStorage.setItem('token',res.headers.token); var kk=localStorage.getItem('token'); console.log(kk); this.$message.success("登录成功"); this.$router.push('/'); } else { this.$message.error(res.data.Message); } }); }, }, created() {}, }; </script> <style> .kkk { width: 800px; height: 300px; border: 1px solid #ccc; margin: auto; margin-top: 150px; } .kk { width: 600px; height: 50px; margin: auto; margin-top: 20px; } .k { margin-top: 20px; } .kkkk { width: 300px; height: 50px; } </style> - 主体页面+左侧菜单+菜单组件
<template> <div> <el-container> <el-header>八维标头</el-header> <el-container> <el-aside width="200px"> <!-- <el-menu default-active="2" class="el-menu-vertical-demo" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b" v-for="(item,index) in showData" :key="index"> <el-submenu index="1"> <template slot="title"> <i class="el-icon-location"></i> <span>{{item.MenuName}}</span> </template> <el-menu-item :index="items.MenuId" v-for="(items,indexs) in item.ChildMenus" :key="indexs" >{{items.MenuName}}</el-menu-item> </el-submenu> </el-menu> --> <!-- 使用组件 --> <MenuTree :showData="this.showData"></MenuTree> </el-aside> <el-main> <router-view /> </el-main> </el-container> </el-container> </div> </template> <script> import MenuTree from "../components/MenuTree"; //引用组件 export default { // data(){ // return{ // showData:[] // } // }, // methods: { // show(){ // this.$axios.get('Menu/GetMenus').then(res=>{ // this.showData=res.data; // }) // } // }, // created(){ // this.show(); // } name: "Home", components: { MenuTree, //挂载组件 }, data() { return { showData: [], }; }, methods: { // show(){ // this.$axios.get('Menu/GetMenus').then(res=>{ // this.showData=res.data; // console.log(this.showData); // }) // }, show() { let userid = localStorage.getItem("userid"); this.$http .get("Menu/CheckMenus?userId=" + userid) .then((res) => { this.showData = res.data; console.log(this.showData); }); }, }, created() { let userid = localStorage.getItem("userid"); if (userid != null) { this.show(); } else { this.$router.push("/login"); } }, }; </script> <style scoped> .el-header, .el-footer { background-color: #b3c0d1; color: #333; text-align: center; line-height: 60px; } .el-aside { background-color: #d3dce6; color: #333; text-align: center; line-height: 200px; } .el-main { background-color: #e9eef3; color: #333; text-align: center; line-height: 60px; } body > .el-container { margin-bottom: 40px; } .el-container:nth-child(5) .el-aside, .el-container:nth-child(6) .el-aside { line-height: 260px; } .el-container:nth-child(7) .el-aside { line-height: 320px; } </style><template> <div> <el-menu default-active="2" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b" router > <!-- <template v-for="item in this.showData"> <el-submenu v-if="item.ChildMenus.length>0" :index="item.MenuId.toString()" :key="item.MenuId"> <template slot="title"> <i v-bind:class="item.Icon"></i> <span>{{item.MenuName}}</span> </template> <MenuTree :showData="item.ChildMenus"></MenuTree> </el-submenu> <el-menu-item v-else :key="item.MenuId" :index="item.Url" > <i :class="item.Icon"></i> {{item.MenuName}}</el-menu-item> </template> --> <template v-for="item in this.showData"> <el-submenu v-if="item.ChildMenus!=null" :index="item.MenuId.toString()" :key="item.MenuId"> <template slot="title"> <i v-bind:class="item.Icon"></i> <span>{{item.MenuName}}</span> </template> <MenuTree :showData="item.ChildMenus"></MenuTree> </el-submenu> <el-menu-item v-else :key="item.MenuId" :index="item.Url" > <i :class="item.Icon"></i> {{item.MenuName}}</el-menu-item> </template> </el-menu> </div> </template> <script> export default { name:'MenuTree', data(){ return{ } }, props:['showData'], //子组件接收父组件的数据 components:{ } } </script> <style> </style> - 用户页面
<template> <div> <div> <el-row> <el-col :span="2"> <span>用户名</span> </el-col> <el-col :span="4"> <el-input v-model="userName" placeholder="用户名"></el-input> </el-col> <el-col :span="2"> <span>邮箱</span> </el-col> <el-col :span="4"> <el-input v-model="email" placeholder="邮箱"></el-input> </el-col> <el-col :span="2"> <el-button type="primary" @click="show">查询</el-button> </el-col> <el-col :span="2"> <el-button type="success" @click="dialogVisible = true" >添加</el-button > </el-col> </el-row> </div> <div> <el-table ref="multipleTable" :data="showData" tooltip-effect="dark" style="width: 100%" @selection-change="handleSelectionChange" > <el-table-column type="selection" width="55"> </el-table-column> <el-table-column prop="UserName" label="用户名"> </el-table-column> <el-table-column prop="PassWord" label="密码"> </el-table-column> <el-table-column prop="Email" label="邮箱"> </el-table-column> <el-table-column label="操作"> <template slot-scope="scope"> <el-button @click="update(scope.row)">编辑</el-button> <el-button type="danger" @click="del(scope.row.UserId)" >删除</el-button > <el-button type="warning" @click="fen(scope.row)" >分配角色</el-button > </template> </el-table-column> </el-table> </div> <div> <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="pageindex" :page-sizes="[1, 3, 5, 10]" :page-size="pagesize" layout="total, sizes, prev, pager, next, jumper" :total="totalcount" > </el-pagination> </div> <el-dialog title="添加用户" :visible.sync="dialogVisible" width="80%" :before-close="handleClose" class="dialog" > <el-form ref="form" :model="addData" label-width="80px"> <el-form-item label="用户ID"> <el-input v-model="addData.UserId"></el-input> </el-form-item> <el-form-item label="用户名"> <el-input v-model="addData.UserName"></el-input> </el-form-item> <el-form-item label="密码"> <el-input v-model="addData.PassWord"></el-input> </el-form-item> <el-form-item label="邮箱"> <el-input v-model="addData.Email"></el-input> </el-form-item> <el-form-item label="性别"> <el-radio-group v-model="addData.Sex"> <el-radio label="0">男</el-radio> <el-radio label="1">女</el-radio> </el-radio-group> </el-form-item> <el-form-item> <el-button type="primary" @click="onSubmit">添加</el-button> </el-form-item> </el-form> <span slot="footer" class="dialog-footer"> <el-button @click="dialogVisible = false">取 消</el-button> <el-button type="primary" @click="dialogVisible = false" >确 定</el-button > </span> </el-dialog> <el-dialog title="编辑用户" :visible.sync="dialogVisiblek" width="80%" :before-close="handleClose" class="dialog" > <el-form ref="form" :model="fanData" label-width="80px"> <el-form-item label="用户名"> <el-input v-model="fanData.UserName"></el-input> </el-form-item> <el-form-item label="密码"> <el-input v-model="fanData.PassWord"></el-input> </el-form-item> <el-form-item label="邮箱"> <el-input v-model="fanData.Email"></el-input> </el-form-item> <el-form-item label="性别"> <el-radio-group v-model="fanData.Sex"> <el-radio :label="0">男</el-radio> <el-radio :label="1">女</el-radio> </el-radio-group> </el-form-item> <el-form-item> <el-button type="primary" @click="xiu">立即修改</el-button> </el-form-item> </el-form> <span slot="footer" class="dialog-footer"> <el-button @click="dialogVisiblek = false">取 消</el-button> <el-button type="primary" @click="dialogVisiblek = false" >确 定</el-button > </span> </el-dialog> <el-dialog title="分配角色" :visible.sync="dialogVisibles" width="20%" :before-close="handleClose" class="dialog" > <el-tree :data="roleData" show-checkbox node-key="RoleId" ref="tree" :props="defaultProps" > </el-tree> <span slot="footer" class="dialog-footer"> <el-button @click="dialogVisibles = false">取 消</el-button> <el-button type="primary" @click="addUR">确 定</el-button> </span> </el-dialog> </div> </template> <script> export default { data() { return { showData: [], userName: "", email: "", pageindex: 1, pagesize: 3, totalcount: 0, ids: [], dialogVisible: false, addData: { UserId: "", UserName: "", PassWord: "", Email: "", Sex: "", }, fanData: { UserId: "", UserName: "", PassWord: "", Email: "", Sex: "", }, dialogVisibles: false, dialogVisiblek: false, roleData: [], defaultProps: { children: "children", label: "RoleName", id: "RoleId", }, UserId: "", roles: [], arr: [], }; }, methods: { update(row) { this.dialogVisiblek = true; this.fanData = row; }, xiu() { this.$http .post("User/UpdateUser", this.fanData) .then((res) => { if (res.data > 0) { this.$message.success("修改成功"); this.show(); this.dialogVisiblek = false; } else { this.$message.error("修改失败"); } }); }, show() { this.$http .get("User/ShowUser?", { params: { pageindex: this.pageindex, pagesize: this.pagesize, email: this.email, userName: this.userName, }, }) .then((res) => { this.showData = res.data.list; this.totalcount = res.data.totalcount; }); }, handleSizeChange(val) { this.pagesize = val; this.show(); console.log(`每页 ${val} 条`); }, handleCurrentChange(val) { this.pageindex = val; this.show(); console.log(`当前页: ${val}`); }, del(id) { this.$confirm("此操作将永久删除该文件, 是否继续?", "提示", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning", }) .then(() => { this.$http .get("User/Del?id=" + id) .then((res) => { if (res.data > 0) { this.$message.success("删除成功"); this.show(); } else { this.$message.error("删除失败"); } }); }) .catch(() => { this.$message({ type: "info", message: "已取消删除", }); }); }, handleSelectionChange(val) { this.multipleSelection = val; for (var i = 0; i < val.length; i++) { this.ids.push(val[i].UserId); } }, onSubmit() { console.log(this.addData); this.$http .post("User/AddUser", this.addData) .then((res) => { if (res.data > 0) { this.$message.success("添加成功"); this.show(); } else { this.$message.error("添加失败"); } }); }, handleClose(done) { this.$confirm("确认关闭?").then(() => { done(); }); }, fen(row) { this.dialogVisibles = true; this.$http .get("Role/ShowRoles") .then((res) => { this.roleData = res.data.PageData; }); this.UserId = ""; this.roles = []; this.UserId = row.UserId; this.$http .get("Role/FanRole?userId=" + this.UserId) .then((res) => { res.data.PageData.forEach((item) => { this.roles.push(item.RoleId); }); this.$nextTick(() => { this.$refs.tree.setCheckedKeys(this.roles); }); }); }, addUR() { let nodes = this.$refs.tree.getCheckedNodes(); nodes.filter((item) => { this.roles.push(item.RoleId); }); this.$http .post("Role/AddUR", { UserId: this.UserId, RoleIds: this.roles.toString(), }) .then((res) => { if(res.data>0) { this.$message.success("添加成功"); this.dialogVisibles = false; this.show(); } else { this.$message.error("添加失败"); } }); }, }, created() { this.show(); }, }; </script> <style> .dialog { text-align: left; } </style> - 角色页面
<template> <div> <div> <el-row> <el-col :span="2"> <span>角色名称</span> </el-col> <el-col :span="4"> <el-input v-model="roleName" placeholder="角色名称"></el-input> </el-col> <el-col :span="2"> <el-button type="primary" @click="show">查询</el-button> </el-col> <el-col :span="2"> <el-button type="success" @click="dialogVisible = true" >添加</el-button > </el-col> </el-row> </div> <div> <el-table ref="multipleTable" :data="showData" tooltip-effect="dark" style="width: 100%" @selection-change="handleSelectionChange" > <el-table-column type="selection" width="55"> </el-table-column> <el-table-column prop="RoleName" label="角色"> </el-table-column> <el-table-column prop="RoleDesc" label="备注"> </el-table-column> <el-table-column label="权限列表"> </el-table-column> <el-table-column label="关联用户"> </el-table-column> <el-table-column label="操作"> <template slot-scope="scope"> <el-button @click="update(scope.row)">编辑</el-button> <el-button type="danger" @click="del(scope.row)">删除</el-button> <el-button type="warning" @click="fen(scope.row)" >设置权限</el-button > </template> </el-table-column> </el-table> </div> <el-dialog title="提示" :visible.sync="dialogVisible" width="30%" :before-close="handleClose" > <el-form ref="form" :model="addData" label-width="80px"> <el-form-item label="角色ID"> <el-input v-model="addData.RoleId"></el-input> </el-form-item> <el-form-item label="角色名称"> <el-input v-model="addData.RoleName"></el-input> </el-form-item> <el-form-item label="简介"> <el-input v-model="addData.RoleDesc"></el-input> </el-form-item> </el-form> <span slot="footer" class="dialog-footer"> <el-button @click="dialogVisible = false">取 消</el-button> <el-button type="primary" @click="add">确 定</el-button> </span> </el-dialog> <el-dialog title="提示" :visible.sync="dialogVisibles" width="30%" :before-close="handleClose" > <el-form ref="form" :model="fanData" label-width="80px"> <el-form-item label="角色名称"> <el-input v-model="fanData.RoleName"></el-input> </el-form-item> <el-form-item label="简介"> <el-input v-model="fanData.RoleDesc"></el-input> </el-form-item> </el-form> <span slot="footer" class="dialog-footer"> <el-button @click="dialogVisibles = false">取 消</el-button> <el-button type="primary" @click="xiu">确 定</el-button> </span> </el-dialog> <el-dialog title="设置权限" :visible.sync="dialogVisiblek" width="20%" :before-close="handleClose" class="dialog" > <el-tree :data="roleData" show-checkbox default-expand-all node-key="MenuId" ref="permissionTree" highlight-current :props="defaultProps"> </el-tree> <span slot="footer" class="dialog-footer"> <el-button @click="dialogVisiblek = false">取 消</el-button> <el-button type="primary" @click="addRM">确 定</el-button> </span> </el-dialog> </div> </template> <script> export default { data() { return { showData: [], ids: [], roleName: "", dialogVisible: false, dialogVisibles: false, dialogVisiblek: false, addData: { RoleId: "", RoleName: "", RoleDesc: "", }, fanData: { RoleId: "", RoleName: "", RoleDesc: "", }, roleData: [], defaultProps: { children: "ChildMenus", label: "MenuName", id: "MenuId", }, menus:[], menusk:[], RId:'' }; }, methods: { fen(row) { this.dialogVisiblek = true; this.$http .get("Menu/GetMenus") .then((res) => { this.roleData = res.data; }); this.RId=row.RoleId; this.$http.get('Role/FanMenu?id='+this.RId).then(res=>{ this.$refs.permissionTree.setCheckedKeys([]); res.data.PageData.forEach((item) => { var node=this.$refs.permissionTree.getNode(item.MenuId) if(node.isLeaf) { this.$refs.permissionTree.setChecked(node,true); } }); }) }, addRM(){ this.menus=this.$refs.permissionTree.getCheckedKeys(); this.menusk=this.$refs.permissionTree.getHalfCheckedKeys(); this.$http.post('Role/AddRM',{ RoleId:this.RId, MenuIds:this.menus.concat(this.menusk).toString() }).then(res=>{ if (res.data > 0) { this.$message.success("添加成功"); this.dialogVisiblek = false; this.show(); } else { this.$message.error("添加失败"); } }) }, update(row) { this.dialogVisibles = true; this.fanData = row; }, xiu() { this.$http .post("Role/UpdateRole", this.fanData) .then((res) => { if (res.data > 0) { this.$message.success("修改成功"); this.show(); this.dialogVisibles = false; } else { this.$message.error("修改失败"); } }); }, add() { this.$http .post("Role/AddRole", this.addData) .then((res) => { if (res.data > 0) { this.$message.success("添加成功"); this.dialogVisible = false; this.show(); } else { this.$message.error("添加失败"); } }); }, show() { this.$http .get( "Role/ShowRole?roleName=" + this.roleName ) .then((res) => { this.showData = res.data.PageData; }); }, handleSelectionChange(val) { this.multipleSelection = val; for (var i = 0; i < val.length; i++) { this.ids.push(val[i].UserId); } }, del(row) { this.$confirm("此操作将永久删除该文件, 是否继续?", "提示", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning", }) .then(() => { this.$http .get("Role/Del?id=" + row.RoleId) .then((res) => { if (res.data > 0) { this.$message.success("删除成功"); this.show(); } else { this.$message.error("删除失败"); } }); }) .catch(() => { this.$message({ type: "info", message: "已取消删除", }); }); }, handleClose(done) { this.$confirm("确认关闭?").then(() => { done(); }); }, }, created() { this.show(); }, }; </script> <style> </style> - 菜单页面
<template> <div> <div> <el-row> <el-col :span="2"><span>菜单名称</span></el-col> <el-col :span="4"> <el-input v-model="menuName" placeholder="请输入菜单名称"></el-input> </el-col> <el-col :span="2"><span>菜单状态</span></el-col> <el-col :span="4"> <el-input v-model="orderIndex" placeholder="请输入菜单状态" ></el-input> </el-col> <el-col :span="2"> <el-button @click="show">查询</el-button> </el-col> <el-col :span="2"> <el-button>重置</el-button> </el-col> </el-row> <el-row> <el-col :span="2"> <el-button @click="addMenu">添加</el-button> </el-col> </el-row> </div> <div> <el-table :data="showData" style="width: 100%; margin-bottom: 20px" row-key="MenuId" border default-expand-all :tree-props="{ children: 'ChildMenus' }" > <el-table-column prop="MenuName" label="菜单名称" sortable> </el-table-column> <el-table-column prop="Icon" label="图标" sortable> </el-table-column> <el-table-column prop="Type" label="菜单类型"> <template slot-scope="scope"> {{ scope.row.Type == 1 ? "菜单" : "" }} </template> </el-table-column> <el-table-column prop="Url" label="路由地址"> </el-table-column> <el-table-column prop="State" label="菜单状态"> </el-table-column> <el-table-column label="操作"> <template slot-scope="scope"> <el-button @click="addMenu">新增</el-button> <el-button @click="fan">编辑</el-button> <el-button type="danger" @click="del(scope.row.MenuId)" >删除</el-button > </template> </el-table-column> </el-table> </div> <el-dialog title="角色新增" :visible.sync="dialogVisible" width="80%" style="text-align: left" :before-close="handleClose" > <el-form ref="form" :model="form" label-width="80px"> <el-form-item label="父级菜单"> <el-select v-model="form.Level" placeholder="请选择"> <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" > </el-option> </el-select> </el-form-item> <el-form-item label="菜单状态"> <el-radio-group v-model="form.orderIndex"> <el-radio label="0">正常</el-radio> <el-radio label="1">停用</el-radio> </el-radio-group> </el-form-item> <el-form-item label="菜单名称"> <el-input v-model="form.MenuName"></el-input> </el-form-item> <el-form-item label="菜单图标"> <el-input v-model="form.Icon"></el-input> </el-form-item> <el-form-item label="路由地址"> <el-input v-model="form.Url"></el-input> </el-form-item> </el-form> <span slot="footer" class="dialog-footer"> <el-button @click="dialogVisible = false">取 消</el-button> <el-button type="primary" @click="addRole">确 定</el-button> </span> </el-dialog> </div> </template> <script> export default { data() { return { showData: [], menuName: "", orderIndex: 0, dialogVisible: false, form: { MenuId: "", MenuName: "", ParentMenuId: "", Level: "", Url: "", Type: "", Icon: "", OrderIndex: "", }, options:[] }; }, methods: { show() { this.$http .get("Menu/GetMenuss?", { params: { menuName: this.menuName, orderIndex: this.orderIndex, }, }) .then((res) => { this.showData = res.data; }); }, addMenu() { this.dialogVisible = true; }, addRole() { this.dialogVisible = false; }, fan() {}, del(id) { this.$confirm("此操作将永久删除该文件, 是否继续?", "提示", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning", }) .then(() => { this.$http .get("Menu/Del?menuId="+id) .then((res) => { if (res.data > 0) { this.$message.success("删除成功"); this.show(); } else { this.$message.error("删除失败"); } }); }) .catch(() => { this.$message({ type: "info", message: "已取消删除", }); }); }, handleClose(done) { this.$confirm("确认关闭?").then(() => { done(); }); }, }, created() { this.show(); }, }; </script> <style> </style>
四、效果展示

浙公网安备 33010602011771号