diff --git a/Common/Class1.cs b/Common/Class1.cs new file mode 100644 index 0000000..e0f23b9 --- /dev/null +++ b/Common/Class1.cs @@ -0,0 +1,7 @@ +namespace Common +{ + public class Class1 + { + + } +} diff --git a/Common/Common.csproj b/Common/Common.csproj new file mode 100644 index 0000000..132c02c --- /dev/null +++ b/Common/Common.csproj @@ -0,0 +1,9 @@ + + + + net6.0 + enable + enable + + + diff --git a/Common/Const/SqlSugarConst.cs b/Common/Const/SqlSugarConst.cs new file mode 100644 index 0000000..345e3d4 --- /dev/null +++ b/Common/Const/SqlSugarConst.cs @@ -0,0 +1,23 @@ +namespace Common.Const +{ + /// + /// SqlSugar相关常量 + /// + public class SqlSugarConst + { + /// + /// 默认主数据库标识(默认租户) + /// + public const string MainConfigId = "1300000000001"; + + /// + /// 默认日志数据库标识 + /// + public const string LogConfigId = "1300000000002"; + + /// + /// 默认表主键 + /// + public const string PrimaryKey = "Id"; + } +} diff --git a/Common/Enum/YesNoEnum.cs b/Common/Enum/YesNoEnum.cs new file mode 100644 index 0000000..45829db --- /dev/null +++ b/Common/Enum/YesNoEnum.cs @@ -0,0 +1,23 @@ +using System.ComponentModel; + +namespace Common.Enum +{ + /// + /// 是否枚举 + /// + [Description("是否枚举")] + public enum YesNoEnum + { + /// + /// 是 + /// + [Description("是")] + Y = 1, + + /// + /// 否 + /// + [Description("否")] + N = 2 + } +} diff --git a/Entity/Base/EntityBase.cs b/Entity/Base/EntityBase.cs new file mode 100644 index 0000000..5bd97e9 --- /dev/null +++ b/Entity/Base/EntityBase.cs @@ -0,0 +1,87 @@ +using SqlSugar; + +namespace Entity.Base +{ + /// + /// 框架实体基类Id + /// + public abstract class EntityBaseId + { + /// + /// 雪花Id + /// + [SugarColumn(ColumnName = "id", ColumnDescription = "主键Id", IsPrimaryKey = true, IsIdentity = false)] + public virtual long Id { get; set; } + } + /// + /// 框架实体基类 + /// + [SugarIndex("index_{table}_CT", nameof(CreateTime), OrderByType.Asc)] + public abstract class EntityBase : EntityBaseId, IDeletedFilter + { + /// + /// 创建时间 + /// + [SugarColumn(ColumnDescription = "创建时间", IsOnlyIgnoreUpdate = true, ColumnName = "create_time")] + public virtual DateTime? CreateTime { get; set; } + + /// + /// 更新时间 + /// + [SugarColumn(ColumnDescription = "更新时间", ColumnName = "update_time")] + public virtual DateTime? UpdateTime { get; set; } + + /// + /// 创建者Id + /// + [SugarColumn(ColumnDescription = "创建者Id", IsOnlyIgnoreUpdate = true, ColumnName = "create_user_id")] + public virtual long? CreateUserId { get; set; } + + + + /// + /// 创建者姓名 + /// + [SugarColumn(ColumnDescription = "创建者姓名", Length = 64, IsOnlyIgnoreUpdate = true, ColumnName = "create_user_name")] + public virtual string? CreateUserName { get; set; } + + /// + /// 修改者Id + /// + [SugarColumn(ColumnDescription = "修改者Id", ColumnName = "update_user_id")] + public virtual long? UpdateUserId { get; set; } + + + /// + /// 修改者姓名 + /// + [SugarColumn(ColumnDescription = "修改者姓名", Length = 64, ColumnName = "update_user_name")] + public virtual string? UpdateUserName { get; set; } + + /// + /// 软删除 + /// + [SugarColumn(ColumnDescription = "软删除", ColumnName = "is_delete")] + public virtual bool IsDelete { get; set; } = false; + } + + + /// + /// 业务数据实体基类(数据权限) + /// + public abstract class EntityBaseData : EntityBase, IOrgIdFilter + { + /// + /// 创建者部门Id + /// + [SugarColumn(ColumnDescription = "创建者部门Id", IsOnlyIgnoreUpdate = true, ColumnName = "creat_org_id")] + public virtual long? CreateOrgId { get; set; } + + + /// + /// 创建者部门名称 + /// + [SugarColumn(ColumnDescription = "创建者部门名称", Length = 64, IsOnlyIgnoreUpdate = true, ColumnName = "creat_org_name")] + public virtual string? CreateOrgName { get; set; } + } +} diff --git a/Entity/Base/IEntityFilter.cs b/Entity/Base/IEntityFilter.cs new file mode 100644 index 0000000..3c70977 --- /dev/null +++ b/Entity/Base/IEntityFilter.cs @@ -0,0 +1,34 @@ +namespace Entity.Base +{ + /// + /// 租户Id接口过滤器 + /// + public interface ITenantIdFilter + { + /// + /// 租户Id + /// + long? TenantId { get; set; } + } + /// + /// 假删除接口过滤器 + /// + public interface IDeletedFilter + { + /// + /// 软删除 + /// + bool IsDelete { get; set; } + } + + /// + /// 机构Id接口过滤器 + /// + internal interface IOrgIdFilter + { + /// + /// 创建者部门Id + /// + long? CreateOrgId { get; set; } + } +} diff --git a/Entity/Base/SqlSugarPagedList.cs b/Entity/Base/SqlSugarPagedList.cs new file mode 100644 index 0000000..89fa8ba --- /dev/null +++ b/Entity/Base/SqlSugarPagedList.cs @@ -0,0 +1,157 @@ +using System.Linq.Expressions; +using SqlSugar; + +namespace Entity.Base +{ + /// + /// 分页泛型集合 + /// + /// + public class SqlSugarPagedList + { + /// + /// 页码 + /// + public int Page { get; set; } + + /// + /// 页容量 + /// + public int PageSize { get; set; } + + /// + /// 总条数 + /// + public int Total { get; set; } + + /// + /// 总页数 + /// + public int TotalPages { get; set; } + + /// + /// 当前页集合 + /// + public IEnumerable Items { get; set; } + + /// + /// 是否有上一页 + /// + public bool HasPrevPage { get; set; } + + /// + /// 是否有下一页 + /// + public bool HasNextPage { get; set; } + } + + /// + /// 分页拓展类 + /// + public static class SqlSugarPagedExtensions + { + /// + /// 分页拓展 + /// + /// 对象 + /// 当前页码,从1开始 + /// 页码容量 + /// 查询结果 Select 表达式 + /// + public static SqlSugarPagedList ToPagedList(this ISugarQueryable query, + int pageIndex, int pageSize, + Expression> expression) + { + var total = 0; + var items = query.ToPageList(pageIndex, pageSize, ref total, expression); + return CreateSqlSugarPagedList(items, total, pageIndex, pageSize); + } + + /// + /// 分页拓展 + /// + /// 对象 + /// 当前页码,从1开始 + /// 页码容量 + /// + public static SqlSugarPagedList ToPagedList(this ISugarQueryable query, + int pageIndex, int pageSize) + { + var total = 0; + var items = query.ToPageList(pageIndex, pageSize, ref total); + return CreateSqlSugarPagedList(items, total, pageIndex, pageSize); + } + + /// + /// 分页拓展 + /// + /// 对象 + /// 当前页码,从1开始 + /// 页码容量 + /// 查询结果 Select 表达式 + /// + public static async Task> ToPagedListAsync( + this ISugarQueryable query, int pageIndex, int pageSize, + Expression> expression) + { + RefAsync total = 0; + var items = await query.ToPageListAsync(pageIndex, pageSize, total, expression); + return CreateSqlSugarPagedList(items, total, pageIndex, pageSize); + } + + /// + /// 分页拓展 + /// + /// 对象 + /// 当前页码,从1开始 + /// 页码容量 + /// + public static async Task> ToPagedListAsync( + this ISugarQueryable query, int pageIndex, int pageSize) + { + RefAsync total = 0; + var items = await query.ToPageListAsync(pageIndex, pageSize, total); + return CreateSqlSugarPagedList(items, total, pageIndex, pageSize); + } + + /// + /// 分页拓展 + /// + /// 集合对象 + /// 当前页码,从1开始 + /// 页码容量 + /// + public static SqlSugarPagedList ToPagedList(this IEnumerable list, int pageIndex, + int pageSize) + { + var total = list.Count(); + var items = list.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList(); + return CreateSqlSugarPagedList(items, total, pageIndex, pageSize); + } + + /// + /// 创建 对象 + /// + /// + /// 分页内容的对象集合 + /// 总条数 + /// 当前页码,从1开始 + /// 页码容量 + /// + public static SqlSugarPagedList CreateSqlSugarPagedList(IEnumerable items, int total, + int pageIndex, int pageSize) + { + var totalPages = pageSize > 0 ? (int)Math.Ceiling(total / (double)pageSize) : 0; + return new SqlSugarPagedList + { + Page = pageIndex, + PageSize = pageSize, + Items = items, + Total = total, + TotalPages = totalPages, + HasNextPage = pageIndex < totalPages, + HasPrevPage = pageIndex - 1 > 0 + }; + } + } +} \ No newline at end of file diff --git a/Entity/DbModel/System/SysConfig.cs b/Entity/DbModel/System/SysConfig.cs new file mode 100644 index 0000000..c5f8d6f --- /dev/null +++ b/Entity/DbModel/System/SysConfig.cs @@ -0,0 +1,61 @@ +using System.ComponentModel.DataAnnotations; +using Common.Enum; +using Entity.Base; +using SqlSugar; + +namespace Entity.DbModel.System.SysBaseObject +{ + /// + /// 系统参数配置表 + /// + [SugarTable("sys_config")] + public partial class SysConfig : EntityBase + { + /// + /// 名称 + /// + [SugarColumn(ColumnDescription = "名称", Length = 64, ColumnName = "name")] + [Required, MaxLength(64)] + public virtual string Name { get; set; } + + /// + /// 编码 + /// + [SugarColumn(ColumnDescription = "编码", Length = 64, ColumnName = "code")] + [MaxLength(64)] + public string? Code { get; set; } + + /// + /// 属性值 + /// + [SugarColumn(ColumnDescription = "属性值", Length = 64, ColumnName = "value")] + [MaxLength(64)] + public string? Value { get; set; } + + /// + /// 是否是内置参数(Y-是,N-否) + /// + [SugarColumn(ColumnDescription = "是否是内置参数", ColumnName = "sys_flag")] + public YesNoEnum SysFlag { get; set; } + + /// + /// 分组编码 + /// + [SugarColumn(ColumnDescription = "分组编码", Length = 64, ColumnName = "group_code")] + [MaxLength(64)] + public string? GroupCode { get; set; } + + /// + /// 排序 + /// + [SugarColumn(ColumnDescription = "排序", ColumnName = "order_no")] + public int OrderNo { get; set; } = 100; + + /// + /// 备注 + /// + [SugarColumn(ColumnDescription = "备注", Length = 256, ColumnName = "remark")] + [MaxLength(256)] + public string? Remark { get; set; } + } +} \ No newline at end of file diff --git a/Entity/Dto/Req/BaseIdReq.cs b/Entity/Dto/Req/BaseIdReq.cs new file mode 100644 index 0000000..dc99a22 --- /dev/null +++ b/Entity/Dto/Req/BaseIdReq.cs @@ -0,0 +1,17 @@ +using System.ComponentModel.DataAnnotations; + +namespace Entity.Dto.Req +{ + /// + /// 主键Id输入参数 + /// + public class BaseIdReq + { + /// + /// 主键Id + /// + [Required(ErrorMessage = "Id不能为空")] + //[DataValidation(ValidationTypes.Numeric)] + public virtual long Id { get; set; } + } +} diff --git a/Entity/Dto/Req/BasePageReq.cs b/Entity/Dto/Req/BasePageReq.cs new file mode 100644 index 0000000..49a46e8 --- /dev/null +++ b/Entity/Dto/Req/BasePageReq.cs @@ -0,0 +1,34 @@ +namespace Entity.Dto.Req +{ + /// + /// 全局分页查询输入参数 + /// + public class BasePageReq + { + /// + /// 当前页码 + /// + public virtual int Page { get; set; } = 1; + + /// + /// 页码容量 + /// + //[Range(0, 100, ErrorMessage = "页码容量超过最大限制")] + public virtual int PageSize { get; set; } = 20; + + /// + /// 排序字段 + /// + public virtual string Field { get; set; } = ""; + + /// + /// 排序方向 + /// + public virtual string OrderDirection { get; set; } = "Desc"; + + /// + /// 降序排序 + /// + public virtual string DescStr { get; set; } = "descending"; + } +} diff --git a/Entity/Dto/Req/ConfigReq.cs b/Entity/Dto/Req/ConfigReq.cs new file mode 100644 index 0000000..62e1bbb --- /dev/null +++ b/Entity/Dto/Req/ConfigReq.cs @@ -0,0 +1,38 @@ +using Entity.DbModel.System.SysBaseObject; + +namespace Entity.Dto.Req +{ + public class ConfigReq : BaseIdReq + { + } + + public class PageConfigReq : BasePageReq + { + /// + /// 名称 + /// + public string Name { get; set; } = ""; + + /// + /// 编码 + /// + public string Code { get; set; } = ""; + + /// + /// 分组编码 + /// + public string GroupCode { get; set; } = ""; + } + + public class AddConfigReq : SysConfig + { + } + + public class UpdateConfigReq : AddConfigReq + { + } + + public class DeleteConfigReq : BaseIdReq + { + } +} diff --git a/Entity/Entity.csproj b/Entity/Entity.csproj index b49ee37..8240d3f 100644 --- a/Entity/Entity.csproj +++ b/Entity/Entity.csproj @@ -1,4 +1,4 @@ - + net6.0 @@ -12,7 +12,14 @@ + + + + + + + diff --git a/HybirdFrameworkCore/Redis/RedisHelper.cs b/HybirdFrameworkCore/Redis/RedisHelper.cs index d932523..d9dfbfe 100644 --- a/HybirdFrameworkCore/Redis/RedisHelper.cs +++ b/HybirdFrameworkCore/Redis/RedisHelper.cs @@ -123,4 +123,9 @@ public class RedisHelper : IDisposable var db = GetConnect().GetDatabase(_defaultDB); return await db.StringSetAsync(key, value); } + public bool Remove(string key) + { + var db = GetConnect().GetDatabase(_defaultDB); + return db.KeyDelete(key); + } } \ No newline at end of file diff --git a/Repository/BaseRepository.cs b/Repository/BaseRepository.cs index 2cf9e53..b321142 100644 --- a/Repository/BaseRepository.cs +++ b/Repository/BaseRepository.cs @@ -1,4 +1,5 @@ using System.Linq.Expressions; +using Entity.Dto.Req; using HybirdFrameworkCore.Entity; using SqlSugar; @@ -58,6 +59,44 @@ public abstract class BaseRepository where T : class, new() .WithNoLockOrNot(blUseNoLock) .ToList(); } + public async Task> QueryPageAsync( + bool isWhere1, Expression> expression1, + bool isWhere2, Expression> expression2, + bool isWhere3, Expression> expression3, + int pageNumber, int pageSize, RefAsync totalNumber, + PageConfigReq input, bool blUseNoLock = false) + { + var page = await DbBaseClient + .Queryable() + .WhereIF(isWhere1, expression1) + .WhereIF(isWhere2, expression2) + .WhereIF(isWhere3, expression3) + .OrderBuilder(input) + .WithNoLockOrNot(blUseNoLock) + .ToPageListAsync(pageNumber, pageSize, totalNumber); + return page; + } + + public async Task UpdateAsync(T updateObj, bool ignoreAllNullColumns) + { + return await DbBaseClient + .Updateable(updateObj) + .IgnoreColumns(ignoreAllNullColumns) + .ExecuteCommandAsync(); + } + + public async Task> QueryByGroupByAsync( + Expression> expression, + Expression> expression2 + ) + { + return await DbBaseClient + .Queryable() + .GroupBy(expression) + .Select(expression2) + .ToListAsync(); + } + /// /// 根据主值列表查询单条数据 @@ -1004,97 +1043,98 @@ public abstract class BaseRepository where T : class, new() { return await DbBaseClient.Queryable().Where(predicate).WithNoLockOrNot(blUseNoLock).SumAsync(field); } - /// - /// 根据条件查询表单数据(分页) - /// - /// 页数 - /// 每页几条数据 - /// 是否使用WITH(NOLOCK) - /// - public IPage QueryIPageByCause(QueryPageModel page, Expression> predicate) + /// + /// 根据条件查询表单数据(分页) + /// + /// 页数 + /// 每页几条数据 + /// 是否使用WITH(NOLOCK) + /// + public IPage QueryIPageByCause(QueryPageModel page, Expression> predicate) + { + if (null == predicate) { - if (null == predicate) { - return this.QueryIPage(page); - } - int totalCount = 0; + return this.QueryIPage(page); + } + int totalCount = 0; - List pageList = DbBaseClient - .Queryable() - .Where(predicate) - .WithNoLockOrNot(false) - .ToPageList(page.Page, page.PageSize, ref totalCount); - + List pageList = DbBaseClient + .Queryable() + .Where(predicate) + .WithNoLockOrNot(false) + .ToPageList(page.Page, page.PageSize, ref totalCount); - return new IPage(totalCount, page, pageList); - } - /// - /// 根据条件查询表单数据(分页) 异步 - /// - /// - /// - /// - public async Task> QueryIPageByCauseAsync(QueryPageModel page, Expression> predicate) - { - if (null == predicate) - { - return await this.QueryIPageAsync(page); - } - RefAsync totalCount = 0; + return new IPage(totalCount, page, pageList); + } + /// + /// 根据条件查询表单数据(分页) 异步 + /// + /// + /// + /// + public async Task> QueryIPageByCauseAsync(QueryPageModel page, Expression> predicate) + { + if (null == predicate) + { + return await this.QueryIPageAsync(page); + } + RefAsync totalCount = 0; - List pageList = await DbBaseClient - .Queryable() - .Where(predicate) - .WithNoLockOrNot(false) - .ToPageListAsync(page.Page, page.PageSize, totalCount); + List pageList = await DbBaseClient + .Queryable() + .Where(predicate) + .WithNoLockOrNot(false) + .ToPageListAsync(page.Page, page.PageSize, totalCount); - return new IPage(totalCount, page, pageList); - } - - - /// - /// 查询表单所有数据(分页) - /// - /// 页数 - /// 每页几条数据 - /// 是否使用WITH(NOLOCK) - /// - public IPage QueryIPage(QueryPageModel page) - { - int totalCount = 0; - //page.Page = page.Page == 0 ? 1 : page.Page;//默认第一页 10条数据 - //page.PageSize = page.PageSize == 0 ? 10 : page.PageSize; - List pageList = DbBaseClient - .Queryable() - .WithNoLockOrNot(false) - .ToPageList(page.Page, page.PageSize, ref totalCount); + return new IPage(totalCount, page, pageList); + } - return new IPage(totalCount, page, pageList); - } - /// - /// 查询表单所有数据(分页) 异步 - /// - /// - /// - public async Task> QueryIPageAsync(QueryPageModel page) - { - RefAsync totalCount = 0; + /// + /// 查询表单所有数据(分页) + /// + /// 页数 + /// 每页几条数据 + /// 是否使用WITH(NOLOCK) + /// + public IPage QueryIPage(QueryPageModel page) + { + int totalCount = 0; + //page.Page = page.Page == 0 ? 1 : page.Page;//默认第一页 10条数据 + //page.PageSize = page.PageSize == 0 ? 10 : page.PageSize; - List pageList = await DbBaseClient + List pageList = DbBaseClient .Queryable() .WithNoLockOrNot(false) - .ToPageListAsync(page.Page, page.PageSize, totalCount); + .ToPageList(page.Page, page.PageSize, ref totalCount); + + return new IPage(totalCount, page, pageList); + } + + /// + /// 查询表单所有数据(分页) 异步 + /// + /// + /// + public async Task> QueryIPageAsync(QueryPageModel page) + { + RefAsync totalCount = 0; + + List pageList = await DbBaseClient + .Queryable() + .WithNoLockOrNot(false) + .ToPageListAsync(page.Page, page.PageSize, totalCount); + + return new IPage(totalCount, page, pageList); + } - return new IPage(totalCount, page, pageList); - } - /// /// 查询-2表查询 diff --git a/Repository/RepositoryExtension.cs b/Repository/RepositoryExtension.cs new file mode 100644 index 0000000..2f50d84 --- /dev/null +++ b/Repository/RepositoryExtension.cs @@ -0,0 +1,408 @@ +using System.Reflection; +using Common.Const; +using Entity.Base; +using Entity.Dto.Req; +using Mapster; +using MapsterMapper; +using SqlSugar; + +namespace Repository +{ + public static class RepositoryExtension + { + /// + /// 实体假删除 _rep.FakeDelete(entity) + /// + /// + /// + /// + /// + public static int FakeDelete(this ISugarRepository repository, T entity) where T : EntityBase, new() + { + return repository.Context.FakeDelete(entity); + } + + /// + /// 实体假删除 db.FakeDelete(entity) + /// + /// + /// + /// + /// + public static int FakeDelete(this ISqlSugarClient db, T entity) where T : EntityBase, new() + { + return db.Updateable(entity).AS().ReSetValue(x => { x.IsDelete = true; }) + .IgnoreColumns(ignoreAllNullColumns: true) + .EnableDiffLogEvent() // 记录差异日志 + .UpdateColumns(x => new { x.IsDelete, x.UpdateTime, x.UpdateUserId }) // 允许更新的字段-AOP拦截自动设置UpdateTime、UpdateUserId + .ExecuteCommand(); + } + + /// + /// 实体集合批量假删除 _rep.FakeDelete(entity) + /// + /// + /// + /// + /// + public static int FakeDelete(this ISugarRepository repository, List entity) where T : EntityBase, new() + { + return repository.Context.FakeDelete(entity); + } + + /// + /// 实体集合批量假删除 db.FakeDelete(entity) + /// + /// + /// + /// + /// + public static int FakeDelete(this ISqlSugarClient db, List entity) where T : EntityBase, new() + { + return db.Updateable(entity).AS().ReSetValue(x => { x.IsDelete = true; }) + .IgnoreColumns(ignoreAllNullColumns: true) + .EnableDiffLogEvent() // 记录差异日志 + .UpdateColumns(x => new { x.IsDelete, x.UpdateTime, x.UpdateUserId }) // 允许更新的字段-AOP拦截自动设置UpdateTime、UpdateUserId + .ExecuteCommand(); + } + + /// + /// 实体假删除异步 _rep.FakeDeleteAsync(entity) + /// + /// + /// + /// + /// + public static Task FakeDeleteAsync(this ISugarRepository repository, T entity) where T : EntityBase, new() + { + return repository.Context.FakeDeleteAsync(entity); + } + + /// + /// 实体假删除 db.FakeDelete(entity) + /// + /// + /// + /// + /// + public static Task FakeDeleteAsync(this ISqlSugarClient db, T entity) where T : EntityBase, new() + { + return db.Updateable(entity).AS().ReSetValue(x => { x.IsDelete = true; }) + .IgnoreColumns(ignoreAllNullColumns: true) + .EnableDiffLogEvent() // 记录差异日志 + .UpdateColumns(x => new { x.IsDelete, x.UpdateTime, x.UpdateUserId }) // 允许更新的字段-AOP拦截自动设置UpdateTime、UpdateUserId + .ExecuteCommandAsync(); + } + + /// + /// 实体集合批量假删除异步 _rep.FakeDeleteAsync(entity) + /// + /// + /// + /// + /// + public static Task FakeDeleteAsync(this ISugarRepository repository, List entity) where T : EntityBase, new() + { + return repository.Context.FakeDeleteAsync(entity); + } + + /// + /// 实体集合批量假删除 db.FakeDelete(entity) + /// + /// + /// + /// + /// + public static Task FakeDeleteAsync(this ISqlSugarClient db, List entity) where T : EntityBase, new() + { + return db.Updateable(entity).AS().ReSetValue(x => { x.IsDelete = true; }) + .IgnoreColumns(ignoreAllNullColumns: true) + .EnableDiffLogEvent() // 记录差异日志 + .UpdateColumns(x => new { x.IsDelete, x.UpdateTime, x.UpdateUserId }) // 允许更新的字段-AOP拦截自动设置UpdateTime、UpdateUserId + .ExecuteCommandAsync(); + } + + /// + /// 排序方式(默认降序) + /// + /// + /// + /// + /// 默认排序字段 + /// 是否降序 + /// + public static ISugarQueryable OrderBuilder(this ISugarQueryable queryable, BasePageReq pageInput, string prefix = "", string defaultSortField = "Id", bool descSort = true) + { + // 约定默认每张表都有Id排序 + var orderStr = string.IsNullOrWhiteSpace(defaultSortField) ? "" : $"{prefix}{defaultSortField}" + (descSort ? " Desc" : " Asc"); + + TypeAdapterConfig typeAdapterConfig = new(); + typeAdapterConfig.ForType().IgnoreNullValues(true); + Mapper mapper = new(typeAdapterConfig); // 务必将mapper设为单实例 + var nowPagerInput = mapper.Map(pageInput); + // 排序是否可用-排序字段和排序顺序都为非空才启用排序 + if (!string.IsNullOrEmpty(nowPagerInput.Field) && !string.IsNullOrEmpty(nowPagerInput.OrderDirection)) + { + var col = queryable.Context.EntityMaintenance.GetEntityInfo().Columns.FirstOrDefault(u => u.PropertyName.Equals(nowPagerInput.Field, StringComparison.CurrentCultureIgnoreCase)); + orderStr = col != null + ? $"{prefix}{col.DbColumnName} {(nowPagerInput.OrderDirection == nowPagerInput.DescStr ? "Desc" : "Asc")}" + : $"{prefix}{nowPagerInput.Field} {(nowPagerInput.OrderDirection == nowPagerInput.DescStr ? "Desc" : "Asc")}"; + } + return queryable.OrderByIF(!string.IsNullOrWhiteSpace(orderStr), orderStr); + } + + /// + /// 更新实体并记录差异日志 _rep.UpdateWithDiffLog(entity) + /// + /// + /// + /// + /// + /// + public static int UpdateWithDiffLog(this ISugarRepository repository, T entity, bool ignoreAllNullColumns = true) where T : EntityBase, new() + { + return repository.Context.UpdateWithDiffLog(entity, ignoreAllNullColumns); + } + + /// + /// 更新实体并记录差异日志 _rep.UpdateWithDiffLog(entity) + /// + /// + /// + /// + /// + /// + public static int UpdateWithDiffLog(this ISqlSugarClient db, T entity, bool ignoreAllNullColumns = true) where T : EntityBase, new() + { + return db.Updateable(entity).AS() + .IgnoreColumns(ignoreAllNullColumns: ignoreAllNullColumns) + .EnableDiffLogEvent() + .ExecuteCommand(); + } + + /// + /// 更新实体并记录差异日志 _rep.UpdateWithDiffLogAsync(entity) + /// + /// + /// + /// + /// + /// + public static Task UpdateWithDiffLogAsync(this ISugarRepository repository, T entity, bool ignoreAllNullColumns = true) where T : EntityBase, new() + { + return repository.Context.UpdateWithDiffLogAsync(entity, ignoreAllNullColumns); + } + + /// + /// 更新实体并记录差异日志 _rep.UpdateWithDiffLogAsync(entity) + /// + /// + /// + /// + /// + /// + public static Task UpdateWithDiffLogAsync(this ISqlSugarClient db, T entity, bool ignoreAllNullColumns = true) where T : EntityBase, new() + { + return db.Updateable(entity) + .IgnoreColumns(ignoreAllNullColumns: ignoreAllNullColumns) + .EnableDiffLogEvent() + .ExecuteCommandAsync(); + } + + /// + /// 新增实体并记录差异日志 _rep.InsertWithDiffLog(entity) + /// + /// + /// + /// + /// + public static int InsertWithDiffLog(this ISugarRepository repository, T entity) where T : EntityBase, new() + { + return repository.Context.InsertWithDiffLog(entity); + } + + /// + /// 新增实体并记录差异日志 _rep.InsertWithDiffLog(entity) + /// + /// + /// + /// + /// + public static int InsertWithDiffLog(this ISqlSugarClient db, T entity) where T : EntityBase, new() + { + return db.Insertable(entity).AS().EnableDiffLogEvent().ExecuteCommand(); + } + + /// + /// 新增实体并记录差异日志 _rep.InsertWithDiffLogAsync(entity) + /// + /// + /// + /// + /// + public static Task InsertWithDiffLogAsync(this ISugarRepository repository, T entity) where T : EntityBase, new() + { + return repository.Context.InsertWithDiffLogAsync(entity); + } + + /// + /// 新增实体并记录差异日志 _rep.InsertWithDiffLog(entity) + /// + /// + /// + /// + /// + public static Task InsertWithDiffLogAsync(this ISqlSugarClient db, T entity) where T : EntityBase, new() + { + return db.Insertable(entity).AS().EnableDiffLogEvent().ExecuteCommandAsync(); + } + + /// + /// 多库查询 + /// + /// + /// + public static ISugarQueryable AS(this ISugarQueryable queryable) + { + var info = GetTableInfo(); + return queryable.AS($"{info.Item1}.{info.Item2}"); + } + + /// + /// 多库查询 + /// + /// + /// + /// + /// + public static ISugarQueryable AS(this ISugarQueryable queryable) + { + var info = GetTableInfo(); + return queryable.AS($"{info.Item1}.{info.Item2}"); + } + + /// + /// 多库更新 + /// + /// + /// + public static IUpdateable AS(this IUpdateable updateable) where T : EntityBase, new() + { + var info = GetTableInfo(); + return updateable.AS($"{info.Item1}.{info.Item2}"); + } + + /// + /// 多库新增 + /// + /// + /// + public static IInsertable AS(this IInsertable insertable) where T : EntityBase, new() + { + var info = GetTableInfo(); + return insertable.AS($"{info.Item1}.{info.Item2}"); + } + + /// + /// 多库删除 + /// + /// + /// + public static IDeleteable AS(this IDeleteable deleteable) where T : EntityBase, new() + { + var info = GetTableInfo(); + return deleteable.AS($"{info.Item1}.{info.Item2}"); + } + + /// + /// 根据实体类型获取表信息 + /// + /// + /// + private static Tuple GetTableInfo() + { + var entityType = typeof(T); + var attr = entityType.GetCustomAttribute(); + var configId = attr == null ? SqlSugarConst.MainConfigId : attr.configId.ToString(); + var tableName = entityType.GetCustomAttribute().TableName; + return new Tuple(configId, tableName); + } + + /// + /// 禁用过滤器-适用于更新和删除操作(只对当前请求有效,禁止使用异步) + /// + /// + /// 禁止异步 + /// + public static void RunWithoutFilter(this ISugarRepository repository, Action action) + { + repository.Context.QueryFilter.ClearAndBackup(); // 清空并备份过滤器 + action.Invoke(); + repository.Context.QueryFilter.Restore(); // 还原过滤器 + + // 用例 + //_rep.RunWithoutFilter(() => + //{ + // 执行更新或者删除 + // 禁止使用异步函数 + //}); + } + + /// + /// 忽略租户 + /// + /// + /// 是否忽略 默认true + /// + public static ISugarQueryable IgnoreTenant(this ISugarQueryable queryable, bool ignore = true) + { + return ignore ? queryable.ClearFilter() : queryable; + } + + /// + /// 导航+子表过滤 创建一个扩展函数,默认是Class不支持Where + /// + /// + /// + /// + /// + public static List Where(this T thisValue, Func whereExpression) where T : class, new() + { + return new List() { thisValue }; + } + + /// + /// 导航+子表过滤 创建一个扩展函数,默认是Class不支持WhereIF + /// + /// + /// + /// + /// + /// + public static List WhereIF(this T thisValue, bool isWhere, Func whereExpression) where T : class, new() + { + return new List() { thisValue }; + } + + /// + /// 只更新某些列 + /// + /// + /// + /// + /// + public static IUpdateable OnlyUpdateColumn(this IUpdateable updateable) where T : EntityBase, new() where R : class, new() + { + if (updateable.UpdateBuilder.UpdateColumns == null) + updateable.UpdateBuilder.UpdateColumns = new List(); + + foreach (PropertyInfo info in typeof(R).GetProperties()) + { + // 判断是否是相同属性 + if (typeof(T).GetProperty(info.Name) != null) + updateable.UpdateBuilder.UpdateColumns.Add(info.Name); + } + return updateable; + } + } +} diff --git a/Repository/System/SysConfigRepository.cs b/Repository/System/SysConfigRepository.cs new file mode 100644 index 0000000..065d821 --- /dev/null +++ b/Repository/System/SysConfigRepository.cs @@ -0,0 +1,16 @@ +using Entity.DbModel.System.SysBaseObject; +using HybirdFrameworkCore.Autofac.Attribute; +using SqlSugar; + +namespace Repository.System +{ + [Scope("SingleInstance")] + public class SysConfigRepository : BaseRepository + { + private ISqlSugarClient DbBaseClient; + public SysConfigRepository(ISqlSugarClient sqlSugar) : base(sqlSugar) + { + DbBaseClient = sqlSugar; + } + } +} diff --git a/Service/Service.csproj b/Service/Service.csproj index ce4df4b..cb2f6cb 100644 --- a/Service/Service.csproj +++ b/Service/Service.csproj @@ -18,6 +18,7 @@ + diff --git a/Service/System/SysConfigService.cs b/Service/System/SysConfigService.cs new file mode 100644 index 0000000..0d4faac --- /dev/null +++ b/Service/System/SysConfigService.cs @@ -0,0 +1,155 @@ +using System.ComponentModel; +using Autofac; +using Common.Enum; +using Entity.Base; +using Entity.DbModel.System.SysBaseObject; +using Entity.Dto.Req; +using HybirdFrameworkCore.Autofac; +using HybirdFrameworkCore.Autofac.Attribute; +using HybirdFrameworkCore.Redis; +using Mapster; +using Microsoft.AspNetCore.Mvc; +using Repository.System; +using SqlSugar; + + +namespace Service.System +{ + [Scope("SingleInstance")] + public class SysConfigService : BaseServices + { + private readonly SysConfigRepository _sysConfigRep; + + public SysConfigService(SysConfigRepository sysConfigRep) + { + _sysConfigRep = sysConfigRep; + } + RedisHelper redisHelper = AppInfo.Container.Resolve(); + /// + /// 获取参数配置分页列表 🔖 + /// + /// + /// + public async Task> Page(PageConfigReq input) + { + RefAsync total = 0; + var items = await _sysConfigRep.QueryPageAsync( + !string.IsNullOrEmpty(input.Name), u => u.Name.Contains(input.Name), + !string.IsNullOrEmpty(input.Code), u => u.Code.Contains(input.Code), + !string.IsNullOrEmpty(input.GroupCode), u => u.GroupCode.Equals(input.GroupCode), + input.Page, input.PageSize, total, input); + return SqlSugarPagedExtensions.CreateSqlSugarPagedList(items, total, input.Page, input.PageSize); + } + + /// + /// 获取参数配置列表 🔖 + /// + /// + [DisplayName("获取参数配置列表")] + public async Task> GetList() + { + return await _sysConfigRep.QueryAsync(); + } + + /// + /// 获取分组列表 🔖 + /// + /// + public async Task> GetGroupList() + { + return await _sysConfigRep.QueryByGroupByAsync(u => u.GroupCode, u => u.GroupCode); + } + + + /// + /// 增加参数配置 🔖 + /// + /// + /// + //[ApiDescriptionSettings(Name = "Add"), HttpPost] + public async Task AddConfig(AddConfigReq input) + { + string result = ""; + var isExist = await _sysConfigRep.QueryByClauseAsync(u => u.Name == input.Name || u.Code == input.Code); + if (isExist != null) + result = "已存在同名或同编码参数配置"; + int insertSesult = await _sysConfigRep.InsertAsync(input.Adapt()); + if (insertSesult > 0) + result = "增加参数配置成功"; + return result; + + } + + /// + /// 更新参数配置 🔖 + /// + /// + /// + // [ApiDescriptionSettings(Name = "Update"), HttpPost] + [DisplayName("更新参数配置")] + public async Task UpdateConfig(UpdateConfigReq input) + { + string result = ""; + var isExist = await _sysConfigRep.QueryByClauseAsync(u => (u.Name == input.Name || u.Code == input.Code) && u.Id != input.Id); + if (isExist != null) + result = "已存在同名或同编码参数配置"; + var config = input.Adapt(); + int updateResult = await _sysConfigRep.UpdateAsync(config,true); + if (updateResult > 0) + result = "更新参数配置成功"; + redisHelper.Remove(config.Code); + return result; + } + /// + /// 删除参数配置 🔖 + /// + /// + /// + //[ApiDescriptionSettings(Name = "Delete"), HttpPost] + [DisplayName("删除参数配置")] + public async Task DeleteConfig(DeleteConfigReq input) + { + string result = ""; + var config = await _sysConfigRep.QueryByClauseAsync(u => u.Id == input.Id); + if (config.SysFlag == YesNoEnum.Y) // 禁止删除系统参数 + result = "禁止删除系统参数"; + bool deleteResult = await _sysConfigRep.DeleteAsync(config); + if (deleteResult) + result = "删除参数配置成功"; + redisHelper.Remove(config.Code); + return result; + } + + /// + /// 批量删除参数配置 🔖 + /// + /// + /// + // [ApiDescriptionSettings(Name = "BatchDelete"), HttpPost] + [DisplayName("批量删除参数配置")] + public async Task BatchDeleteConfig(List ids) + { + foreach (var id in ids) + { + var config = await _sysConfigRep.QueryByClauseAsync(u => u.Id == id); + if (config.SysFlag == YesNoEnum.Y) // 禁止删除系统参数 + continue; + await _sysConfigRep.DeleteAsync(config); + redisHelper.Remove(config.Code); + } + } + + /// + /// 获取参数配置详情 🔖 + /// + /// + /// + [DisplayName("获取参数配置详情")] + public async Task GetDetail([FromQuery] ConfigReq input) + { + return await _sysConfigRep.QueryByClauseAsync(u => u.Id == input.Id); + } + + + } +} diff --git a/WebStarter/Controllers/System/SysConfigController.cs b/WebStarter/Controllers/System/SysConfigController.cs new file mode 100644 index 0000000..f59279c --- /dev/null +++ b/WebStarter/Controllers/System/SysConfigController.cs @@ -0,0 +1,76 @@ + +using Entity.Base; +using Entity.DbModel.System.SysBaseObject; +using Entity.Dto.Req; +using Microsoft.AspNetCore.Mvc; +using Service.System; + +namespace WebStarter.Controllers.System +{ + [Produces("application/json")] + [ApiController] + public class SysConfigController + { + private readonly SysConfigService _sysConfigService; + public SysConfigController(SysConfigService sysConfigService) + { + _sysConfigService = sysConfigService; + } + + [HttpPost] + [Route("/api/sysConfig/page")] + public async Task> Page(PageConfigReq input) + { + return await _sysConfigService.Page(input); + } + + [HttpGet] + [Route("/api/sysConfig/list")] + public async Task> GetList() + { + return await _sysConfigService.GetList(); + } + + [HttpGet] + [Route("/api/sysConfig/detail")] + public async Task GetDetail([FromQuery] ConfigReq input) + { + return await _sysConfigService.GetDetail(input); + } + + [HttpGet] + [Route("/api/sysConfig/groupList")] + public async Task> GetGroupList() + { + return await _sysConfigService.GetGroupList(); + } + + [HttpPost] + [Route("/api/sysConfig/add")] + public async Task Add(AddConfigReq input) + { + await _sysConfigService.AddConfig(input); + } + + [HttpPost] + [Route("/api/sysConfig/update")] + public async Task Update(UpdateConfigReq input) + { + await _sysConfigService.UpdateConfig(input); + } + + [HttpPost] + [Route("/api/sysConfig/delete")] + public async Task Delete(DeleteConfigReq input) + { + await _sysConfigService.DeleteConfig(input); + } + + [HttpPost] + [Route("/api/sysConfig/batchDelete")] + public async Task BatchDelete(List input) + { + await _sysConfigService.BatchDeleteConfig(input); + } + } +}