using CloudBuilder.Core.DatabaseAccessor; using CloudBuilder.Core.DatabaseAccessor.Entity; using CloudBuilder.Core.Extensions; using CloudBuilder.Core.Service; using CloudBuilder.Security.Data; using CloudBuilder.Security.Entity; using CloudBuilder.Security.Policy; using CloudBuilder.Security.SearchCriteria; using CloudBuilder.Security.Utility; using DocumentFormat.OpenXml.Math; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using System.Diagnostics; namespace CloudBuilder.Security.Service { public class SecurityFunctionService : ISecurityFunctionService { private readonly IApplicationService service; private IRepository repository; public SecurityFunctionService(IApplicationService service) { this.service = service; repository = service.GetRepository>(); } [PermissionOperate(name: SecurityPermissionPolicy.SecurityFunction, operate: Operate.Find)] public SecurityFunctionData FindByKey(string key) { SecurityFunctionData data = new SecurityFunctionData(); if (string.IsNullOrEmpty(key)) return data; SecurityFunctionEntity function = repository.DetachedEntities.Where(x => x.FunctionName == key).FirstOrDefault(); if (function == null) return data; data.SecurityFunction = new SecurityFunctionDisplayData(function); IRepository repositoryMap = repository.GetRepository>(); SecurityPermissionFunctionMapEntity map = repositoryMap.Entities.Where(x => x.FunctionName == key).FirstOrDefault(); if (map != null) data.SecurityFunction.PermissionName = map.PermissionName; data.SecurityFunctionMapParents = repository.GetRepository>().DetachedEntities.Where(x => x.SonFunctionName == key).OrderBy(x => x.Orderby).ToArray(); data.SecurityFunctionMapSons = repository.GetRepository>().DetachedEntities.Where(x => x.ParentFunctionName == key).OrderBy(x => x.Orderby).ToArray(); return data; } [PermissionOperate(name: SecurityPermissionPolicy.SecurityFunction, operate: Operate.Find)] public SecurityFunctionResultData FindBySearchCriteria(SecurityFunctionSearchCriteria criteria) { SecurityFunctionResultData data = new SecurityFunctionResultData(); SecurityFunctionEntity[] list = null; int count = 0; string sqlWhere = null; if (criteria.Filter != null && criteria.Filter.Length > 0) { sqlWhere = SearchFilter.ComposeWhereClause(criteria.Filter); } SecurityFunctionEntity entity = SecurityFunctionEntity.GetInstance(); string sql = entity.GetSelectTopFrom(criteria.limit, criteria.page, criteria.orderby.StringToDbField(), criteria.orderbytag, sqlWhere); string err = null; try { list = repository.FromSql(sql).ToArray(); } catch (System.Exception ex) { err = ex.Message; } if (list != null && list.Length > 0) { sql = entity.GetSelectCountFrom(sqlWhere); count = (int)repository.ExecuteScalar(sql); data.SecurityFunctionDisplayDatas = list.Select(x => new SecurityFunctionDisplayData(x)).ToArray(); } else { data.SecurityFunctionDisplayDatas = null; } data.Limit = criteria.limit; data.Page = criteria.page; data.Total = count; //data.Sql = sql; data.ErrorMessage = err; return data; } [PermissionOperate(name: SecurityPermissionPolicy.SecurityFunction, operate: Operate.Print)] public dynamic PrintBySearchCriteria(SecurityFunctionSearchCriteria criteria) { throw new NotImplementedException(); } [PermissionOperate(name: SecurityPermissionPolicy.SecurityFunction, operate: Operate.Insert)] [UnitOfWork] public SecurityFunctionData Insert(SecurityFunctionData data) { SecurityFunctionEntity securityFunction = repository.DetachedEntities.Where(x => x.FunctionName == data.SecurityFunction.FunctionName).FirstOrDefault(); if (securityFunction != null) { throw new ValidatedException("记录已存在."); } Validate(data.SecurityFunction); securityFunction = new SecurityFunctionEntity(); ObjectCopyHelper.Copy(data.SecurityFunction, securityFunction); repository.InsertNow(securityFunction); SaveFunctionPermissionMap(data.SecurityFunction.FunctionName, data.SecurityFunction.PermissionName); SaveParentMaps(securityFunction.FunctionName, data.SecurityFunctionMapParents); SaveSonMaps(securityFunction.FunctionName, data.SecurityFunctionMapSons); return FindByKey(data.SecurityFunction.FunctionName); } [PermissionOperate(name: SecurityPermissionPolicy.SecurityFunction, operate: Operate.Update)] [UnitOfWork] public SecurityFunctionData Update(SecurityFunctionData data) { SecurityFunctionEntity securityFunction = repository.DetachedEntities.Where(x => x.FunctionName == data.SecurityFunction.FunctionName).FirstOrDefault(); if (securityFunction == null) { throw new ValidatedException("记录不存在."); } Validate(data.SecurityFunction); ObjectCopyHelper.Copy(data.SecurityFunction, securityFunction); repository.UpdateNow(securityFunction); SaveFunctionPermissionMap(data.SecurityFunction.FunctionName, data.SecurityFunction.PermissionName); SaveParentMaps(securityFunction.FunctionName, data.SecurityFunctionMapParents); SaveSonMaps(securityFunction.FunctionName, data.SecurityFunctionMapSons); return FindByKey(data.SecurityFunction.FunctionName); } [PermissionOperate(name: SecurityPermissionPolicy.SecurityFunction, operate: Operate.Delete)] [UnitOfWork] public void Delete(string key) { SecurityFunctionEntity securityFunction = repository.DetachedEntities.Where(x => x.FunctionName == key).FirstOrDefault(); if (securityFunction == null) { throw new ValidatedException("记录不存在."); } repository.DeleteNow(securityFunction); IRepository repositoryMapView = repository.GetRepository>(); IRepository repositoryMap = repository.GetRepository>(); SecurityFunctionMapViewEntity[] olds = repositoryMapView.Entities.Where(x => x.ParentFunctionName == key || x.SonFunctionName == key).ToArray(); if (olds != null && olds.Length > 0) { foreach (SecurityFunctionMapViewEntity old in olds) { repositoryMap.DeleteNow(new SecurityFunctionMapEntity() { FunctionNameSon = old.SonFunctionName, FunctionNameParent = old.ParentFunctionName }); } } } [PermissionOperate(name: SecurityPermissionPolicy.SecurityFunction, operate: Operate.Delete)] [UnitOfWork] public void Deletes(string[] keys) { foreach (string key in keys) { Delete(key); } } [AllowAnonymous] public SecurityFunctionEntity FindByFunctionName(string functionName) { return repository.DetachedEntities.Where(x => x.FunctionName == functionName || x.PageName == functionName).FirstOrDefault()!; } [AllowAnonymous] public SecurityFunctionDisplayData[] FindMenus() { SecurityFunctionEntity[] entities = repository.DetachedEntities.Where(x => x.FunctionIndc == YesNoPolicy.YES && x.PageUrl != null && x.PageUrl.Length > 0).ToArray(); SecurityPermissionFunctionMapEntity[] permissions = service.GetRepository>().DetachedEntities.ToArray(); var q = from e in entities join p in permissions on e.FunctionName equals p.FunctionName select new SecurityFunctionDisplayData(e) { PermissionName = p.PermissionName }; return q.ToArray(); } private void Validate(SecurityFunctionDisplayData securityFunctionDto) { List sysTableSchemas = service.ServiceProvider.GetRequiredService().FindByTableName(SecurityFunctionEntity.DB_NAME_SECURITY_FUNCTION); ValidateHelper.ValidateString(securityFunctionDto, sysTableSchemas.ToArray()); } private void SaveFunctionPermissionMap(string functionName, string permissionName) { IRepository repositoryMap = repository.GetRepository>(); SecurityPermissionFunctionMapEntity[] olds = repositoryMap.Entities.Where(x => x.FunctionName == functionName).ToArray(); if (olds != null && olds.Length > 0) { foreach (SecurityPermissionFunctionMapEntity old in olds) { repositoryMap.DeleteNow(old); } } if (string.IsNullOrEmpty(permissionName)) return; SecurityPermissionFunctionMapEntity map = new SecurityPermissionFunctionMapEntity(); map.FunctionName = functionName; map.PermissionName = permissionName; repositoryMap.InsertNow(map); } private void SaveParentMaps(string functionName, SecurityFunctionMapViewEntity[] maps) { IRepository repositoryMapView = repository.GetRepository>(); IRepository repositoryMap = repository.GetRepository>(); SecurityFunctionMapViewEntity[] olds = repositoryMapView.Entities.Where(x => x.SonFunctionName == functionName).ToArray(); if (olds != null && olds.Length > 0) { foreach (SecurityFunctionMapViewEntity old in olds) { repositoryMap.DeleteNow(new SecurityFunctionMapEntity() { FunctionNameSon = old.SonFunctionName, FunctionNameParent = old.ParentFunctionName }); } } if (maps == null || maps.Length == 0) return; int maxOrderBy = 0; foreach (SecurityFunctionMapViewEntity map in maps) { SecurityFunctionMapViewEntity[] oldMaps = repositoryMapView.Entities.Where(x => x.ParentFunctionName == map.ParentFunctionName).ToArray(); if (oldMaps != null && oldMaps.Count() > 0) maxOrderBy = oldMaps.Max(x => x.Orderby); repositoryMap.InsertNow(new SecurityFunctionMapEntity() { FunctionNameSon = functionName, FunctionNameParent = map.ParentFunctionName, Orderby = oldMaps == null ? 1 : maxOrderBy + 1 }); } } private void SaveSonMaps(string functionName, SecurityFunctionMapViewEntity[] maps) { IRepository repositoryMapView = repository.GetRepository>(); IRepository repositoryMap = repository.GetRepository>(); SecurityFunctionMapViewEntity[] olds = repositoryMapView.Entities.Where(x => x.ParentFunctionName == functionName).ToArray(); if (olds != null && olds.Length > 0) { foreach (SecurityFunctionMapViewEntity old in olds) { repositoryMap.DeleteNow(new SecurityFunctionMapEntity() { FunctionNameSon = old.SonFunctionName, FunctionNameParent = old.ParentFunctionName }); } } if (maps == null || maps.Length == 0) return; int i = 1; foreach (SecurityFunctionMapViewEntity map in maps.OrderBy(x => x.Orderby).ToArray()) { repositoryMap.InsertNow(new SecurityFunctionMapEntity() { FunctionNameSon = map.SonFunctionName, FunctionNameParent = functionName, Orderby = i++ }); } } } }