Merge branch 'erp'

This commit is contained in:
橙子
2022-01-11 16:41:09 +08:00
22 changed files with 319 additions and 49 deletions

View File

@@ -0,0 +1,25 @@
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/azds.yaml
**/bin
**/charts
**/docker-compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md

View File

@@ -16,6 +16,7 @@ using Yi.Framework.DTOModel;
using Yi.Framework.Interface;
using Yi.Framework.Model.Models;
using Yi.Framework.WebCore;
using Yi.Framework.WebCore.AuthorizationPolicy;
using Yi.Framework.WebCore.Mapper;
namespace Yi.Framework.ApiMicroservice.Controllers
@@ -32,7 +33,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers
private CacheClientDB _cacheClientDB;
private IRoleService _roleService;
private IHttpContextAccessor _httpContext;
public AccountController(ILogger<UserController> logger, IUserService userService, IMenuService menuService,RabbitMQInvoker rabbitMQInvoker,CacheClientDB cacheClientDB, IRoleService roleService, IHttpContextAccessor httpContext)
public AccountController(ILogger<UserController> logger, IUserService userService, IMenuService menuService, RabbitMQInvoker rabbitMQInvoker, CacheClientDB cacheClientDB, IRoleService roleService, IHttpContextAccessor httpContext)
{
_logger = logger;
_userService = userService;
@@ -52,18 +53,20 @@ namespace Yi.Framework.ApiMicroservice.Controllers
[HttpPost]
public async Task<Result> Login(loginDto login)
{
var _user= MapperHelper.Map<user, loginDto>(login);
var _user = MapperHelper.Map<user, loginDto>(login);
var user_data = await _userService.Login(_user);
if (user_data == null)
{
return Result.Error("该用户不存在");
}
var menuList = await _menuService.GetTopMenuByUserId(user_data.id);
if ( user_data!=null)
{
var token = MakeJwt.app(new jwtUser() {user=user_data,menuIds= menuList});
if (user_data != null)
{
var token = MakeJwt.app(new jwtUser() { user = user_data, menuIds = menuList });
JobModel.visitNum += 1;
//同时要将api路径放置到redis中
var menuDto = MapperHelper.MapList<menuDto,menu>(menuList);
_userService.SaveUserApi(user_data.id, menuDto);
return Result.Success().SetData(new { user = new { user_data.id, user_data.username, user_data.introduction, user_data.icon, user_data.nick }, token });
}
return Result.Error();
@@ -73,6 +76,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers
/// 不用写,单纯制作日志
/// </summary>
/// <returns></returns>
[HttpPost]
public Result Logout()
{
@@ -88,17 +92,17 @@ namespace Yi.Framework.ApiMicroservice.Controllers
[HttpPost]
public async Task<Result> Register(user _user, string code)
{
_user.username=_user.username.Trim();
if(string.IsNullOrEmpty(_user.username))
code = code.Trim();
_user.username = _user.username.Trim();
if (string.IsNullOrEmpty(_user.username))
code = code.Trim();
string trueCode= _cacheClientDB.Get<string>(RedisConst.keyCode + _user.phone);
string trueCode = _cacheClientDB.Get<string>(RedisConst.keyCode + _user.phone);
if (code == trueCode)
{
//设置默认头像
var setting = JsonHelper.StrToObj<SettingDto>(_cacheClientDB.Get<string>(RedisConst.key));
_user.icon = setting.InitIcon;
_user.ip = _httpContext.HttpContext.Request.Headers["X-Real-IP"].FirstOrDefault();//通过上下文获取ip
_user.ip = _httpContext.HttpContext?.Request.Headers["X-Real-IP"].FirstOrDefault();//通过上下文获取ip
//设置默认角色
if (string.IsNullOrEmpty(setting.InitRole))
{
@@ -120,7 +124,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers
/// <param name="SMSAddress"></param>
/// <returns></returns>
[HttpPost]
public async Task<Result> SendSMS(string SMSAddress)
public async Task<Result> SendSMS(string SMSAddress)
{
if (string.IsNullOrEmpty(SMSAddress))
{
@@ -131,15 +135,15 @@ namespace Yi.Framework.ApiMicroservice.Controllers
{
SMSQueueModel sMSQueueModel = new SMSQueueModel();
sMSQueueModel.phone = SMSAddress;
sMSQueueModel.code =RandomHelper.GenerateCheckCodeNum(6);
sMSQueueModel.code = RandomHelper.GenerateCheckCodeNum(6);
//10分钟过期
_cacheClientDB.Set(RedisConst.keyCode+sMSQueueModel.phone, sMSQueueModel.code, TimeSpan.FromMinutes(10));
_cacheClientDB.Set(RedisConst.keyCode + sMSQueueModel.phone, sMSQueueModel.code, TimeSpan.FromMinutes(10));
_rabbitMQInvoker.Send(new Common.IOCOptions.RabbitMQConsumerModel() { ExchangeName = RabbitConst.SMS_Exchange, QueueName = RabbitConst.SMS_Queue_Send }, JsonHelper.ObjToStr(sMSQueueModel));
return Result.Success("发送短信成功10分钟后过期请留意短信接收");
}
return Result.Error("该号码已被注册");
return Result.Error("该号码已被注册");
}
/// <summary>
@@ -179,11 +183,11 @@ namespace Yi.Framework.ApiMicroservice.Controllers
[HttpPut]
[Authorize]
public async Task<Result> ChangePassword(ChangePwdDto pwdDto)
{
{
var user_data = await _userService.GetUserById(pwdDto.user.id);
string msg = "修改成功";
if (! string.IsNullOrEmpty( pwdDto.newPassword))
{
if (!string.IsNullOrEmpty(pwdDto.newPassword))
{
if (user_data.password == pwdDto.user.password)
{
@@ -195,7 +199,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers
user_data.address = pwdDto.user.address;
user_data.nick = pwdDto.user.nick;
await _userService.UpdateAsync(user_data);
user_data.password = null;
return Result.Success(msg);
@@ -219,6 +223,6 @@ namespace Yi.Framework.ApiMicroservice.Controllers
return Result.Success(msg);
}
}
}

View File

@@ -19,9 +19,11 @@ namespace Yi.Framework.ApiMicroservice.Controllers
public class MenuController : ControllerBase
{
private IMenuService _menuService;
public MenuController(IMenuService menuService)
private IUserService _userService;
public MenuController(IMenuService menuService,IUserService userService)
{
_menuService = menuService;
_userService = userService;
}
/// <summary>
/// 这个是要递归的,但是要过滤掉删除的,所以,可以写一个通用过滤掉删除的方法
@@ -105,8 +107,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers
[HttpGet]
public async Task<Result> GetTopMenusByHttpUser()
{
HttpContext.GetCurrentUserInfo(out List<int> menuIds);
var menuIds = _userService.GetCurrentMenuInfo(HttpContext.GetCurrentUserInfo().id);
return Result.Success().SetData(await _menuService.GetTopMenusByTopMenuIds(menuIds));
}
}

View File

@@ -10,6 +10,7 @@ using Yi.Framework.DTOModel;
using Yi.Framework.Interface;
using Yi.Framework.Model.Models;
using Yi.Framework.WebCore;
using Yi.Framework.WebCore.AuthorizationPolicy;
namespace Yi.Framework.ApiMicroservice.Controllers
{
@@ -31,6 +32,8 @@ namespace Yi.Framework.ApiMicroservice.Controllers
/// 查
/// </summary>
/// <returns></returns>
[Authorize(PolicyName.Menu)]
[HttpGet]
public async Task<Result> GetUser()
{
@@ -43,6 +46,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers
/// <param name="_user"></param>
/// <returns></returns>
[HttpPut]
[Authorize(PolicyName.Menu)]
public async Task<Result> UpdateUser(user _user)
{
await _userService.UpdateAsync(_user);
@@ -56,6 +60,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers
/// <param name="_ids"></param>
/// <returns></returns>
[HttpDelete]
[Authorize(PolicyName.Menu)]
public async Task<Result> DelListUser(List<int> _ids)
{
await _userService.DelListByUpdateAsync(_ids);
@@ -68,6 +73,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers
/// <param name="_user"></param>
/// <returns></returns>
[HttpPost]
[Authorize(PolicyName.Menu)]
public async Task<Result> AddUser(user _user)
{
await _userService.AddAsync(_user);
@@ -109,7 +115,7 @@ namespace Yi.Framework.ApiMicroservice.Controllers
[HttpGet]
public async Task<Result> GetMenuByHttpUser()
{
HttpContext.GetCurrentUserInfo(out var allMenuIds);
var allMenuIds= _userService.GetCurrentMenuInfo(HttpContext.GetCurrentUserInfo().id);
return Result.Success().SetData(await _userService.GetMenuByHttpUser(allMenuIds));
}
@@ -121,8 +127,8 @@ namespace Yi.Framework.ApiMicroservice.Controllers
[HttpGet]
public async Task<Result> GetAxiosByRouter(string router)
{
var _user = HttpContext.GetCurrentUserInfo(out List<int> menuIds);
var _user = HttpContext.GetCurrentUserInfo();
var menuIds = _userService.GetCurrentMenuInfo(_user.id);
if (menuIds == null)
{
return Result.Error();

View File

@@ -67,6 +67,10 @@ builder.Services.AddCorsService();
#endregion
builder.Services.AddJwtService();
#region
//<2F><>Ȩ<EFBFBD><C8A8><EFBFBD><EFBFBD>
#endregion
builder.Services.AddAuthorizationService();
#region
//<2F><><EFBFBD>ݿ<EFBFBD><DDBF><EFBFBD><EFBFBD><EFBFBD>
#endregion
builder.Services.AddDbService();

View File

@@ -4,6 +4,8 @@
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<UserSecretsId>f5ce4739-9524-4330-9aea-cfcdb41501de</UserSecretsId>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
@@ -23,6 +25,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.14.0" />
</ItemGroup>
<ItemGroup>

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -14,6 +14,8 @@ namespace Yi.Framework.Common.Const
public const string key = "YiFramework:data";
public const string keyCode = "YiFramework:code";
public const string userMenusApi = "YiFramework:userMenusApi";
///// <summary>
///// 初始化角色名
///// </summary>

View File

@@ -1040,9 +1040,14 @@ namespace Yi.Framework.Core
public bool SetEntryInHash<T>(string hashId, string key, T value)
{
return this.TryCatch<bool>(() => this.client.SetEntryInHash(hashId, key, TextExtensions.SerializeToString<T>(value)), hashId);
}
public bool SetEntryInHash<T>(string hashId, string key, T value, TimeSpan expiresIn)
{
return this.TryCatch<bool>(() => this.client.SetEntryInHash(hashId, key, TextExtensions.SerializeToString<T>(value)), hashId);
}
public T GetValueFromHash<T>(string hashId, string key)
{
return this.TryCatch<T>(() => JsonSerializer.DeserializeFromString<T>(this.client.GetValueFromHash(hashId, key)), hashId);

View File

@@ -37,10 +37,11 @@ namespace Yi.Framework.Core
claims.Add(new Claim(JwtRegisteredClaimNames.Exp, $"{new DateTimeOffset(DateTime.Now.AddMinutes(30)).ToUnixTimeSeconds()}"));
claims.Add(new Claim(ClaimTypes.Name, _user.user.username));
claims.Add(new Claim(ClaimTypes.Sid, _user.user.id.ToString()));
foreach (var k in _user?.menuIds)
{
claims.Add(new Claim("menuIds",k.id.ToString()));
}
//现在不存放在jwt中而存放在redis中
//foreach (var k in _user?.menuIds)
//{
// claims.Add(new Claim("menuIds",k.id.ToString()));
//}
foreach (var k in _user.user.roles)
{
claims.Add(new Claim(ClaimTypes.Role, k.role_name));

View File

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Model.Models;
namespace Yi.Framework.DTOModel
{
public class menuDto
{
public int id { get; set; }
public string icon { get; set; }
public string router { get; set; }
public string menu_name { get; set; }
public mould mould { get; set; }
}
}

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.DTOModel;
using Yi.Framework.Model.Models;
namespace Yi.Framework.Interface
@@ -67,5 +68,19 @@ namespace Yi.Framework.Interface
/// <returns></returns>
Task<List<menu>> GetAxiosByRouter(string router,int userId, List<int> menuIds);
/// <summary>
/// 将登录用户的api保存的redis中
/// </summary>
/// <param name="_user"></param>
/// <returns></returns>
public bool SaveUserApi(int userId, List<menuDto> menus);
/// <summary>
/// 通过用户id得到redis中菜单列表
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
public List<int> GetCurrentMenuInfo(int userId);
}
}

View File

@@ -17,6 +17,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Yi.Framework.DTOModel\Yi.Framework.DTOModel.csproj" />
<ProjectReference Include="..\Yi.Framework.Model\Yi.Framework.Model.csproj" />
</ItemGroup>

View File

@@ -66,7 +66,10 @@ namespace Yi.Framework.Service
var m = u.menus.Where(u => u.is_delete == Normal).ToList();
menuList = menuList.Union(m).ToList();
});
return menuList;
var menuIds=menuList.Select(u => u.id).ToList();
return await _DbRead.Set<menu>().Include(u => u.mould).Where(u => menuIds.Contains(u.id)).ToListAsync();
}
}

View File

@@ -5,7 +5,9 @@ using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Common.Const;
using Yi.Framework.Core;
using Yi.Framework.DTOModel;
using Yi.Framework.Interface;
using Yi.Framework.Model;
using Yi.Framework.Model.ModelFactory;
@@ -15,6 +17,11 @@ namespace Yi.Framework.Service
{
public partial class UserService : BaseService<user>, IUserService
{
CacheClientDB _cacheClientDB;
public UserService(CacheClientDB cacheClientDB, IDbContextFactory DbFactory) : base(DbFactory)
{
_cacheClientDB = cacheClientDB;
}
short Normal = (short)Common.Enum.DelFlagEnum.Normal;
public async Task<bool> PhoneIsExsit(string smsAddress)
{
@@ -42,42 +49,43 @@ namespace Yi.Framework.Service
/// <returns></returns>
public async Task<user> GetUserById(int userId)
{
return await _DbRead.Set<user>().Include(u => u.roles).ThenInclude(u => u.menus).ThenInclude(u => u.children).ThenInclude(u => u.mould).Where(u=>u.id==userId).FirstOrDefaultAsync();
return await _DbRead.Set<user>().Include(u => u.roles).ThenInclude(u => u.menus).ThenInclude(u => u.children).ThenInclude(u => u.mould).Where(u => u.id == userId).FirstOrDefaultAsync();
}
public async Task<List<menu>> GetAxiosByRouter(string router, int userId, List<int> menuIds)
public async Task<List<menu>> GetAxiosByRouter(string router, int userId, List<int> menuIds)
{
var user_data =await GetUserById(userId);
var user_data = await GetUserById(userId);
List<menu> menuList = new();
foreach(var item in user_data.roles)
foreach (var item in user_data.roles)
{
var m=item.menus.Where(u =>u?.router?.ToUpper() == router.ToUpper()).FirstOrDefault();
var m = item.menus.Where(u => u?.router?.ToUpper() == router.ToUpper()).FirstOrDefault();
if (m == null) { break; }
menuList = m.children?.Where(u => menuIds.Contains(u.id)&&u.is_delete==Normal).ToList();
menuList = m.children?.Where(u => menuIds.Contains(u.id) && u.is_delete == Normal).ToList();
}
return menuList;
}
return menuList;
}
public async Task<menu> GetMenuByHttpUser(List<int> allMenuIds)
{
var topMenu =await _DbRead.Set<menu>().Include(u => u.children).ThenInclude(u => u.children).ThenInclude(u => u.children).ThenInclude(u => u.children).ThenInclude(u => u.children).Where(u => u.is_top == (short)Common.Enum.ShowFlagEnum.Show).FirstOrDefaultAsync();
var topMenu = await _DbRead.Set<menu>().Include(u => u.children).ThenInclude(u => u.children).ThenInclude(u => u.children).ThenInclude(u => u.children).ThenInclude(u => u.children).Where(u => u.is_top == (short)Common.Enum.ShowFlagEnum.Show).FirstOrDefaultAsync();
//现在要开始关联菜单了
return TreeMenuBuild.Sort(TreeMenuBuild.ShowFormat(topMenu, allMenuIds)); ;
}
}
public async Task<user> GetUserInRolesByHttpUser(int userId)
{
var data = await GetUserById(userId);
data.roles?.ForEach(u=> {
data.roles?.ForEach(u =>
{
u.users = null;
u.menus = null;
});
return data;
return data;
}
public async Task<user> Login(user _user)
{
var user_data = await _DbRead.Set<user>().Include(u => u.roles).Where(u => u.username == _user.username && u.password ==_user.password &&u.is_delete == Normal).FirstOrDefaultAsync();
var user_data = await _DbRead.Set<user>().Include(u => u.roles).Where(u => u.username == _user.username && u.password == _user.password && u.is_delete == Normal).FirstOrDefaultAsync();
return user_data;
}
@@ -93,12 +101,19 @@ namespace Yi.Framework.Service
public async Task<bool> SetRoleByUser(List<int> roleIds, List<int> userIds)
{
var user_data = await _DbRead.Set<user>().Include(u => u.roles).Where(u => userIds.Contains(u.id)).ToListAsync();
var user_data = await _DbRead.Set<user>().Include(u => u.roles).Where(u => userIds.Contains(u.id)).ToListAsync();
var roleList = await _DbRead.Set<role>().Where(u => roleIds.Contains(u.id)).ToListAsync();
user_data.ForEach(u => u.roles = roleList);
user_data.ForEach(u => u.roles = roleList);
return await UpdateListAsync(user_data);
}
public bool SaveUserApi(int userId, List<menuDto> menus)
{
return _cacheClientDB.Set(RedisConst.userMenusApi+":"+userId.ToString(),menus,new TimeSpan(0,30,0));
}
public List<int> GetCurrentMenuInfo(int userId)
{
return _cacheClientDB.Get<List<menuDto>>(RedisConst.userMenusApi+":"+userId).Select(u=>u.id).ToList();
}
}
}

View File

@@ -18,6 +18,7 @@
<ItemGroup>
<ProjectReference Include="..\Yi.Framework.Core\Yi.Framework.Core.csproj" />
<ProjectReference Include="..\Yi.Framework.DTOModel\Yi.Framework.DTOModel.csproj" />
<ProjectReference Include="..\Yi.Framework.Interface\Yi.Framework.Interface.csproj" />
<ProjectReference Include="..\Yi.Framework.Model\Yi.Framework.Model.csproj" />
</ItemGroup>

View File

@@ -0,0 +1,89 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Yi.Framework.Common.Const;
using Yi.Framework.Core;
using Yi.Framework.DTOModel;
using Yi.Framework.Model.Models;
namespace Yi.Framework.WebCore.AuthorizationPolicy
{
//策略验证的Handler 继承AuthorizationHandler 泛型类 泛型参数为 策略参数
public class CustomAuthorizationHandler : AuthorizationHandler<CustomAuthorizationRequirement>
{
private CacheClientDB _cacheClientDB;
/// <summary>
/// 构造函数
/// </summary>
public CustomAuthorizationHandler(CacheClientDB cacheClientDB)
{
_cacheClientDB= cacheClientDB;
}
//验证的方法就在这里
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CustomAuthorizationRequirement requirement)
{
var currentClaim = context.User.Claims.FirstOrDefault(u => u.Type == ClaimTypes.Sid);
if (currentClaim==null) //说明没有写入Sid 没有登录
{
return Task.CompletedTask; //验证不同过
}
int currentUserId = 0;
if (!string.IsNullOrWhiteSpace(currentClaim.Value))
{
currentUserId = Convert.ToInt32(currentClaim.Value);
}
DefaultHttpContext httpcontext = (DefaultHttpContext)context.Resource;
Dictionary<string, string> dicMenueDictionary = new Dictionary<string, string>();
//现在只需要登录的时候把用户的api路径添加到redis去
//每次访问的时候进行redis判断一下即可
//注意一下redis不能一直保存和jwt一样搞一个期限
var menuList=_cacheClientDB.Get<List<menuDto>>(RedisConst.userMenusApi+":"+currentUserId);
foreach (var k in menuList)
{
if (k.mould != null)
{
dicMenueDictionary.Add(k.mould?.id.ToString(), "/api"+ k.mould?.url);
}
}
if (dicMenueDictionary.ContainsValue(httpcontext.Request.Path))
{
context.Succeed(requirement); //验证通过了
}
return Task.CompletedTask; //验证不同过
}
}
/// <summary>
/// 菜单权限策略
/// </summary>
public static class CustomAuthorizationHandlerExtension
{
public static Task AuthorizationMenueExtension(this AuthorizationHandlerContext handlerContext, CustomAuthorizationRequirement requirement)
{
bool bog = true;
if (bog)
{
return Task.Run(() =>
{
handlerContext.Succeed(requirement); //验证通过了
});
}
else
{
return Task.CompletedTask; //验证不同过
}
}
}
}

View File

@@ -0,0 +1,19 @@
using Microsoft.AspNetCore.Authorization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Yi.Framework.WebCore.AuthorizationPolicy
{
//定义策略参数必须实现这个IAuthorizationRequirement接口
public class CustomAuthorizationRequirement: IAuthorizationRequirement
{
public CustomAuthorizationRequirement(PolicyEnum policyname)
{
this.PolicyName = policyname;
}
public PolicyEnum PolicyName { get; set; }
}
}

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Yi.Framework.WebCore.AuthorizationPolicy
{
public enum PolicyEnum
{
/// <summary>
/// 菜单
/// </summary>
MenuPermissions,
//...还可以定义其他的各种权限策略名称
}
public static class PolicyName
{
public const string Menu = "Menu";
}
}

View File

@@ -26,6 +26,7 @@ namespace Yi.Framework.WebCore
/// <summary>
/// 基于HttpContext,当前鉴权方式解析,获取用户信息
/// 现在使用redis作为缓存不需要将菜单存放至jwt中了
/// </summary>
/// <param name="httpContext"></param>
/// <returns></returns>

View File

@@ -28,5 +28,13 @@ namespace Yi.Framework.WebCore.Mapper
IMapper mapper = new AutoMapper.Mapper(config);
return mapper.Map<Source, Target>(source);
}
public static List<Target> MapList<Target, Source>(List<Source> source)
{
var cfg = new MapperConfigurationExpression();
cfg.CreateMap<Source, Target>();
var config = new MapperConfiguration(cfg);
IMapper mapper = new AutoMapper.Mapper(config);
return mapper.Map<List<Source>, List<Target>>(source);
}
}
}

View File

@@ -0,0 +1,28 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.WebCore.AuthorizationPolicy;
namespace Yi.Framework.WebCore.MiddlewareExtend
{
public static class AuthorizationExtension
{
public static IServiceCollection AddAuthorizationService(this IServiceCollection services)
{
services.AddAuthorization(options =>
{
options.AddPolicy(PolicyName.Menu, polic =>
{
polic.AddRequirements(new CustomAuthorizationRequirement(PolicyEnum.MenuPermissions));
});
});
services.AddSingleton<IAuthorizationHandler, CustomAuthorizationHandler>();
return services;
}
}
}