diff --git a/Admin.Core.Common/Admin.Core.Common.csproj b/Admin.Core.Common/Admin.Core.Common.csproj
index 3a029b93e..c79eacd9d 100644
--- a/Admin.Core.Common/Admin.Core.Common.csproj
+++ b/Admin.Core.Common/Admin.Core.Common.csproj
@@ -2,21 +2,41 @@
netcoreapp3.1
+ true
+ 1.4.1
+ xiaoxue
+ xiaoxue
+ 中台Admin后端通用库
+ ZhonTai Admin;WebApi
+ git
+ https://github.com/zhontai/Admin.Core
+ https://github.com/zhontai/Admin.Core
+ MIT
+
+
+
+ ..\Admin.Core\Admin.Core.Common.xml
+ 1701;1702;1591
+
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
+
+
diff --git a/Admin.Core.Common/Attributes/SingleInstanceAttribute.cs b/Admin.Core.Common/Attributes/SingleInstanceAttribute.cs
new file mode 100644
index 000000000..0f67acbba
--- /dev/null
+++ b/Admin.Core.Common/Attributes/SingleInstanceAttribute.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace Admin.Core.Common.Attributes
+{
+ ///
+ /// 单例注入
+ ///
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property)]
+ public class SingleInstanceAttribute : Attribute
+ {
+ }
+}
diff --git a/Admin.Core.Common/Attributes/TransactionAttribute.cs b/Admin.Core.Common/Attributes/TransactionAttribute.cs
index fc6059554..61a1d7d66 100644
--- a/Admin.Core.Common/Attributes/TransactionAttribute.cs
+++ b/Admin.Core.Common/Attributes/TransactionAttribute.cs
@@ -1,6 +1,8 @@
using System;
+using System.Data;
+using FreeSql;
-namespace Admin.Core.Common
+namespace Admin.Core.Common.Attributes
{
///
/// 启用事物
@@ -8,6 +10,14 @@ namespace Admin.Core.Common
[AttributeUsage(AttributeTargets.Method, Inherited = true)]
public class TransactionAttribute : Attribute
{
+ ///
+ /// 事务传播方式
+ ///
+ public Propagation Propagation { get; set; } = Propagation.Requierd;
+ ///
+ /// 事务隔离级别
+ ///
+ public IsolationLevel? IsolationLevel { get; set; }
}
}
diff --git a/Admin.Core.Common/Auth/ClaimAttributes.cs b/Admin.Core.Common/Auth/ClaimAttributes.cs
new file mode 100644
index 000000000..38f494842
--- /dev/null
+++ b/Admin.Core.Common/Auth/ClaimAttributes.cs
@@ -0,0 +1,33 @@
+namespace Admin.Core.Common.Auth
+{
+ ///
+ /// Claim属性
+ ///
+ public static class ClaimAttributes
+ {
+ ///
+ /// 用户Id
+ ///
+ public const string UserId = "id";
+
+ ///
+ /// 认证授权用户Id
+ ///
+ public const string IdentityServerUserId = "sub";
+
+ ///
+ /// 用户名
+ ///
+ public const string UserName = "na";
+
+ ///
+ /// 姓名
+ ///
+ public const string UserNickName = "nn";
+
+ ///
+ /// 刷新有效期
+ ///
+ public const string RefreshExpires = "re";
+ }
+}
diff --git a/Admin.Core.Common/Auth/IUser.cs b/Admin.Core.Common/Auth/IUser.cs
index 1292f0d77..c86757ec5 100644
--- a/Admin.Core.Common/Auth/IUser.cs
+++ b/Admin.Core.Common/Auth/IUser.cs
@@ -1,14 +1,23 @@
-using System.Collections.Generic;
-using System.Security.Claims;
-
-namespace Admin.Core.Common.Auth
+namespace Admin.Core.Common.Auth
{
+ ///
+ /// 用户信息接口
+ ///
public interface IUser
{
+ ///
+ /// 主键
+ ///
long Id { get; }
+
+ ///
+ /// 用户名
+ ///
string Name { get; }
- bool IsAuthenticated();
- IEnumerable GetClaimsIdentity();
- List GetClaimValueByType(string ClaimType);
+
+ ///
+ /// 昵称
+ ///
+ string NickName { get; }
}
}
diff --git a/Admin.Core.Common/Auth/IUserToken.cs b/Admin.Core.Common/Auth/IUserToken.cs
index f62c326db..6af13ec4b 100644
--- a/Admin.Core.Common/Auth/IUserToken.cs
+++ b/Admin.Core.Common/Auth/IUserToken.cs
@@ -4,6 +4,8 @@ namespace Admin.Core.Common.Auth
{
public interface IUserToken
{
- string Build(Claim[] claims);
+ string Create(Claim[] claims);
+
+ Claim[] Decode(string jwtToken);
}
}
diff --git a/Admin.Core.Common/Auth/User.cs b/Admin.Core.Common/Auth/User.cs
index 553fb8426..989db75b3 100644
--- a/Admin.Core.Common/Auth/User.cs
+++ b/Admin.Core.Common/Auth/User.cs
@@ -1,7 +1,5 @@
-using System.Collections.Generic;
-using System.Linq;
-using System.Security.Claims;
-using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Http;
+using Admin.Core.Common.Helpers;
namespace Admin.Core.Common.Auth
{
@@ -20,7 +18,7 @@ public User(IHttpContextAccessor accessor)
///
/// 用户Id
///
- public long Id
+ public virtual long Id
{
get
{
@@ -51,82 +49,22 @@ public string Name
}
}
-
- ///
- /// 用户IP
- ///
- public string IP
- {
- get
- {
- if (_accessor?.HttpContext?.Connection == null)
- return "";
-
- return _accessor.HttpContext.Connection.RemoteIpAddress.ToString();
- }
- }
-
///
- /// 用户IPv4
+ /// 昵称
///
- public string IPv4
+ public string NickName
{
get
{
- if (_accessor?.HttpContext?.Connection == null)
- return "";
+ var name = _accessor?.HttpContext?.User?.FindFirst(ClaimAttributes.UserNickName);
- return _accessor.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString();
- }
- }
-
- ///
- /// 用户IPv6
- ///
- public string IPv6
- {
- get
- {
- if (_accessor?.HttpContext?.Connection == null)
- return "";
+ if (name != null && name.Value.NotNull())
+ {
+ return name.Value;
+ }
- return _accessor.HttpContext.Connection.RemoteIpAddress.MapToIPv6().ToString();
+ return "";
}
}
-
- public bool IsAuthenticated()
- {
- return _accessor.HttpContext.User.Identity.IsAuthenticated;
- }
-
- public IEnumerable GetClaimsIdentity()
- {
- return _accessor.HttpContext.User.Claims;
- }
-
- public List GetClaimValueByType(string ClaimType)
- {
-
- return (from item in GetClaimsIdentity()
- where item.Type == ClaimType
- select item.Value).ToList();
-
- }
- }
-
- ///
- /// Claim属性
- ///
- public static class ClaimAttributes
- {
- ///
- /// 用户Id
- ///
- public const string UserId = "id";
-
- ///
- /// 用户名
- ///
- public const string UserName = "na";
}
}
diff --git a/Admin.Core.Common/Auth/UserIdentiyServer.cs b/Admin.Core.Common/Auth/UserIdentiyServer.cs
new file mode 100644
index 000000000..400cd0e9f
--- /dev/null
+++ b/Admin.Core.Common/Auth/UserIdentiyServer.cs
@@ -0,0 +1,34 @@
+using Microsoft.AspNetCore.Http;
+using Admin.Core.Common.Helpers;
+
+namespace Admin.Core.Common.Auth
+{
+ ///
+ /// 用户信息
+ ///
+ public class UserIdentiyServer : User
+ {
+ private readonly IHttpContextAccessor _accessor;
+
+ public UserIdentiyServer(IHttpContextAccessor accessor) : base(accessor)
+ {
+ _accessor = accessor;
+ }
+
+ ///
+ /// 用户Id
+ ///
+ public override long Id
+ {
+ get
+ {
+ var id = _accessor?.HttpContext?.User?.FindFirst(ClaimAttributes.IdentityServerUserId);
+ if (id != null && id.Value.NotNull())
+ {
+ return id.Value.ToLong();
+ }
+ return 0;
+ }
+ }
+ }
+}
diff --git a/Admin.Core.Common/Auth/UserToken.cs b/Admin.Core.Common/Auth/UserToken.cs
index 480e684f5..24d0dfcdc 100644
--- a/Admin.Core.Common/Auth/UserToken.cs
+++ b/Admin.Core.Common/Auth/UserToken.cs
@@ -5,9 +5,13 @@
using System.IdentityModel.Tokens.Jwt;
using Microsoft.IdentityModel.Tokens;
using Admin.Core.Common.Configs;
+using Admin.Core.Common.Attributes;
+using System.Linq;
+using Admin.Core.Common.Extensions;
namespace Admin.Core.Common.Auth
{
+ [SingleInstance]
public class UserToken : IUserToken
{
private readonly JwtConfig _jwtConfig;
@@ -17,10 +21,12 @@ public UserToken(JwtConfig jwtConfig)
_jwtConfig = jwtConfig;
}
- public string Build(Claim[] claims)
+ public string Create(Claim[] claims)
{
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtConfig.SecurityKey));
var signingCredentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
+ var timestamp = DateTime.Now.AddMinutes(_jwtConfig.Expires + _jwtConfig.RefreshExpires).ToTimestamp().ToString();
+ claims = claims.Append(new Claim(ClaimAttributes.RefreshExpires, timestamp)).ToArray();
var token = new JwtSecurityToken(
issuer: _jwtConfig.Issuer,
@@ -32,5 +38,12 @@ public string Build(Claim[] claims)
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
+
+ public Claim[] Decode(string jwtToken)
+ {
+ var jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
+ var jwtSecurityToken = jwtSecurityTokenHandler.ReadJwtToken(jwtToken);
+ return jwtSecurityToken?.Claims?.ToArray();
+ }
}
}
diff --git a/Admin.Core.Model/Base/Entity.cs b/Admin.Core.Common/BaseModel/Entity.cs
similarity index 62%
rename from Admin.Core.Model/Base/Entity.cs
rename to Admin.Core.Common/BaseModel/Entity.cs
index a0d0c9ecb..0961d1e87 100644
--- a/Admin.Core.Model/Base/Entity.cs
+++ b/Admin.Core.Common/BaseModel/Entity.cs
@@ -1,6 +1,7 @@
using FreeSql.DataAnnotations;
+using System.ComponentModel;
-namespace Admin.Core.Model
+namespace Admin.Core.Common.BaseModel
{
public interface IEntity
{
@@ -9,9 +10,10 @@ public interface IEntity
public class Entity : IEntity
{
///
- /// 主键Id
+ /// 编号
///
- [Column(Position = 1,IsIdentity = true)]
+ [Description("编号")]
+ [Column(Position = 1, IsIdentity = true)]
public virtual TKey Id { get; set; }
}
diff --git a/Admin.Core.Model/Base/EntityAdd.cs b/Admin.Core.Common/BaseModel/EntityAdd.cs
similarity index 65%
rename from Admin.Core.Model/Base/EntityAdd.cs
rename to Admin.Core.Common/BaseModel/EntityAdd.cs
index 5c1c38575..49a4d026b 100644
--- a/Admin.Core.Model/Base/EntityAdd.cs
+++ b/Admin.Core.Common/BaseModel/EntityAdd.cs
@@ -1,29 +1,33 @@
-using FreeSql.DataAnnotations;
-using System;
+using System;
+using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
+using FreeSql.DataAnnotations;
-namespace Admin.Core.Model
+namespace Admin.Core.Common.BaseModel
{
///
/// 实体创建审计
///
- public class EntityAdd : Entity, IEntityAdd
+ public class EntityAdd : Entity, IEntityAdd where TKey : struct
{
///
/// 创建者Id
///
+ [Description("创建者Id")]
[Column(Position = -3, CanUpdate = false)]
- public long? CreatedUserId { get; set; }
+ public TKey? CreatedUserId { get; set; }
///
/// 创建者
///
+ [Description("创建者")]
[Column(Position = -2, CanUpdate = false), MaxLength(50)]
public string CreatedUserName { get; set; }
///
/// 创建时间
///
+ [Description("创建时间")]
[Column(Position = -1, CanUpdate = false, ServerTime = DateTimeKind.Local)]
public DateTime? CreatedTime { get; set; }
}
diff --git a/Admin.Core.Model/Base/EntityBase.cs b/Admin.Core.Common/BaseModel/EntityBase.cs
similarity index 63%
rename from Admin.Core.Model/Base/EntityBase.cs
rename to Admin.Core.Common/BaseModel/EntityBase.cs
index 6e5849aeb..806a4750f 100644
--- a/Admin.Core.Model/Base/EntityBase.cs
+++ b/Admin.Core.Common/BaseModel/EntityBase.cs
@@ -1,60 +1,69 @@
-using FreeSql.DataAnnotations;
-using System;
+using System;
+using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
+using FreeSql.DataAnnotations;
-namespace Admin.Core.Model
+namespace Admin.Core.Common.BaseModel
{
///
/// 实体审计
///
- public class EntityBase : Entity, IEntityVersion, IEntitySoftDelete,IEntityAdd,IEntityUpdate
+ public class EntityBase : Entity, IEntityVersion, IEntitySoftDelete, IEntityAdd, IEntityUpdate where TKey : struct
{
///
/// 版本
///
+ [Description("版本")]
[Column(Position = -9, IsVersion = true)]
public long Version { get; set; }
///
/// 是否删除
///
+ [Description("是否删除")]
[Column(Position = -8)]
public bool IsDeleted { get; set; } = false;
///
/// 创建者Id
///
+ [Description("创建者Id")]
[Column(Position = -7, CanUpdate = false)]
- public long? CreatedUserId { get; set; }
+ public TKey? CreatedUserId { get; set; }
///
/// 创建者
///
- [Column(Position = -6, CanUpdate = false),MaxLength(50)]
+ [Description("创建者")]
+ [Column(Position = -6, CanUpdate = false), MaxLength(50)]
public string CreatedUserName { get; set; }
///
/// 创建时间
///
+ [Description("创建时间")]
[Column(Position = -5, CanUpdate = false, ServerTime = DateTimeKind.Local)]
public DateTime? CreatedTime { get; set; }
///
/// 修改者Id
///
+ [Description("修改者Id")]
[Column(Position = -4, CanInsert = false)]
- public long? ModifiedUserId { get; set; }
+ public TKey? ModifiedUserId { get; set; }
///
/// 修改者
///
- [Column(Position = -2, CanInsert = false),MaxLength(50)]
+ [Description("修改者")]
+ [Column(Position = -2, CanInsert = false), MaxLength(50)]
public string ModifiedUserName { get; set; }
///
/// 修改时间
///
- [Column(Position = -1, CanInsert = false,ServerTime = DateTimeKind.Local)]
+ [Description("修改时间")]
+ [Column(Position = -1, CanInsert = false, ServerTime = DateTimeKind.Local)]
public DateTime? ModifiedTime { get; set; }
}
diff --git a/Admin.Core.Model/Base/EntitySoftDelete.cs b/Admin.Core.Common/BaseModel/EntitySoftDelete.cs
similarity index 79%
rename from Admin.Core.Model/Base/EntitySoftDelete.cs
rename to Admin.Core.Common/BaseModel/EntitySoftDelete.cs
index eb18f5f28..3c7f2527c 100644
--- a/Admin.Core.Model/Base/EntitySoftDelete.cs
+++ b/Admin.Core.Common/BaseModel/EntitySoftDelete.cs
@@ -1,6 +1,7 @@
using FreeSql.DataAnnotations;
+using System.ComponentModel;
-namespace Admin.Core.Model
+namespace Admin.Core.Common.BaseModel
{
///
/// 实体软删除
@@ -10,6 +11,7 @@ public class EntitySoftDelete : Entity,IEntitySoftDelete
///
/// 是否删除
///
+ [Description("是否删除")]
[Column(Position = -1)]
public bool IsDeleted { get; set; } = false;
}
diff --git a/Admin.Core.Model/Base/EntityUpdate.cs b/Admin.Core.Common/BaseModel/EntityUpdate.cs
similarity index 63%
rename from Admin.Core.Model/Base/EntityUpdate.cs
rename to Admin.Core.Common/BaseModel/EntityUpdate.cs
index cf2072cfd..fa631dcd2 100644
--- a/Admin.Core.Model/Base/EntityUpdate.cs
+++ b/Admin.Core.Common/BaseModel/EntityUpdate.cs
@@ -1,30 +1,34 @@
-using FreeSql.DataAnnotations;
-using System;
+using System;
+using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
+using FreeSql.DataAnnotations;
-namespace Admin.Core.Model
+namespace Admin.Core.Common.BaseModel
{
///
/// 实体修改审计
///
- public class EntityUpdate : Entity, IEntityUpdate
+ public class EntityUpdate : Entity, IEntityUpdate where TKey : struct
{
///
/// 修改者Id
///
+ [Description("修改者Id")]
[Column(Position = -3, CanInsert = false)]
- public long? ModifiedUserId { get; set; }
+ public TKey? ModifiedUserId { get; set; }
///
/// 修改者
///
+ [Description("修改者")]
[Column(Position = -2, CanInsert = false), MaxLength(50)]
public string ModifiedUserName { get; set; }
///
/// 修改时间
///
- [Column(Position = -1, CanInsert = false,ServerTime = DateTimeKind.Local)]
+ [Description("修改时间")]
+ [Column(Position = -1, CanInsert = false, ServerTime = DateTimeKind.Local)]
public DateTime? ModifiedTime { get; set; }
}
diff --git a/Admin.Core.Model/Base/EntityVersion.cs b/Admin.Core.Common/BaseModel/EntityVersion.cs
similarity index 80%
rename from Admin.Core.Model/Base/EntityVersion.cs
rename to Admin.Core.Common/BaseModel/EntityVersion.cs
index 95d8ab06b..0b7038da0 100644
--- a/Admin.Core.Model/Base/EntityVersion.cs
+++ b/Admin.Core.Common/BaseModel/EntityVersion.cs
@@ -1,6 +1,7 @@
using FreeSql.DataAnnotations;
+using System.ComponentModel;
-namespace Admin.Core.Model
+namespace Admin.Core.Common.BaseModel
{
///
/// 实体版本
@@ -10,6 +11,7 @@ public class EntityVersion : Entity, IEntityVersion
///
/// 版本
///
+ [Description("版本")]
[Column(Position = -1, IsVersion = true)]
public long Version { get; set; }
}
diff --git a/Admin.Core.Common/BaseModel/IEntityAdd.cs b/Admin.Core.Common/BaseModel/IEntityAdd.cs
new file mode 100644
index 000000000..7ace39cac
--- /dev/null
+++ b/Admin.Core.Common/BaseModel/IEntityAdd.cs
@@ -0,0 +1,11 @@
+using System;
+
+namespace Admin.Core.Common.BaseModel
+{
+ public interface IEntityAdd where TKey: struct
+ {
+ TKey? CreatedUserId { get; set; }
+ string CreatedUserName { get; set; }
+ DateTime? CreatedTime { get; set; }
+ }
+}
diff --git a/Admin.Core.Model/Base/IEntitySoftDelete.cs b/Admin.Core.Common/BaseModel/IEntitySoftDelete.cs
similarity index 81%
rename from Admin.Core.Model/Base/IEntitySoftDelete.cs
rename to Admin.Core.Common/BaseModel/IEntitySoftDelete.cs
index f5e58212f..9b93e10df 100644
--- a/Admin.Core.Model/Base/IEntitySoftDelete.cs
+++ b/Admin.Core.Common/BaseModel/IEntitySoftDelete.cs
@@ -1,5 +1,5 @@
-namespace Admin.Core.Model
+namespace Admin.Core.Common.BaseModel
{
public interface IEntitySoftDelete
{
diff --git a/Admin.Core.Common/BaseModel/IEntityUpdate.cs b/Admin.Core.Common/BaseModel/IEntityUpdate.cs
new file mode 100644
index 000000000..465a90611
--- /dev/null
+++ b/Admin.Core.Common/BaseModel/IEntityUpdate.cs
@@ -0,0 +1,11 @@
+using System;
+
+namespace Admin.Core.Common.BaseModel
+{
+ public interface IEntityUpdate where TKey : struct
+ {
+ TKey? ModifiedUserId { get; set; }
+ string ModifiedUserName { get; set; }
+ DateTime? ModifiedTime { get; set; }
+ }
+}
diff --git a/Admin.Core.Model/Base/IEntityVersion.cs b/Admin.Core.Common/BaseModel/IEntityVersion.cs
similarity index 63%
rename from Admin.Core.Model/Base/IEntityVersion.cs
rename to Admin.Core.Common/BaseModel/IEntityVersion.cs
index 0c547eeeb..df9d54397 100644
--- a/Admin.Core.Model/Base/IEntityVersion.cs
+++ b/Admin.Core.Common/BaseModel/IEntityVersion.cs
@@ -1,7 +1,4 @@
-using FreeSql.DataAnnotations;
-using Newtonsoft.Json;
-
-namespace Admin.Core.Model
+namespace Admin.Core.Common.BaseModel
{
public interface IEntityVersion
{
diff --git a/Admin.Core.Common/Cache/CacheKey.cs b/Admin.Core.Common/Cache/CacheKey.cs
index 06708fed2..5b5d817c9 100644
--- a/Admin.Core.Common/Cache/CacheKey.cs
+++ b/Admin.Core.Common/Cache/CacheKey.cs
@@ -1,4 +1,6 @@
+using System.ComponentModel;
+
namespace Admin.Core.Common.Cache
{
///
@@ -9,16 +11,19 @@ public static class CacheKey
///
/// 验证码 admin:verify:code:guid
///
+ [Description("验证码")]
public const string VerifyCodeKey = "admin:verify:code:{0}";
///
- /// 密码 admin:password:guid
+ /// 密码加密 admin:password:encrypt:guid
///
- public const string PassWordKey = "admin:password:{0}";
+ [Description("密码加密")]
+ public const string PassWordEncryptKey = "admin:password:encrypt:{0}";
///
/// 用户权限 admin:user:用户主键:permissions
///
+ [Description("用户权限")]
public const string UserPermissions = "admin:user:{0}:permissions";
}
}
diff --git a/Admin.Core.Common/Cache/CacheType.cs b/Admin.Core.Common/Cache/CacheType.cs
index 70639fbff..afa606d85 100644
--- a/Admin.Core.Common/Cache/CacheType.cs
+++ b/Admin.Core.Common/Cache/CacheType.cs
@@ -6,7 +6,13 @@ namespace Admin.Core.Common.Cache
///
public enum CacheType
{
+ ///
+ /// 内存缓存
+ ///
Memory,
+ ///
+ /// Redis缓存
+ ///
Redis
}
}
diff --git a/Admin.Core.Common/Cache/MemoryCache.cs b/Admin.Core.Common/Cache/MemoryCache.cs
index 93188bd2a..590db614f 100644
--- a/Admin.Core.Common/Cache/MemoryCache.cs
+++ b/Admin.Core.Common/Cache/MemoryCache.cs
@@ -7,6 +7,7 @@
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Memory;
+using Admin.Core.Common.Helpers;
namespace Admin.Core.Common.Cache
{
diff --git a/Admin.Core.Common/Configs/AppConfig.cs b/Admin.Core.Common/Configs/AppConfig.cs
index 5313d9930..b923060c4 100644
--- a/Admin.Core.Common/Configs/AppConfig.cs
+++ b/Admin.Core.Common/Configs/AppConfig.cs
@@ -5,24 +5,97 @@
///
public class AppConfig
{
+ ///
+ /// Api地址,默认 http://*:8000
+ ///
+ public string[] Urls { get; set; }// = new[]{ "http://*:8000" };
+
+ ///
+ /// 跨域地址,默认 http://*:9000
+ ///
+ public string[] CorUrls { get; set; }// = new[]{ "http://*:9000" };
+
///
/// Swagger文档
///
- public bool Swagger { get; set; }
+ public bool Swagger { get; set; } = false;
+
+ ///
+ /// 统一认证授权服务器
+ ///
+ public IdentityServer IdentityServer { get; set; } = new IdentityServer();
+
+ ///
+ /// Aop配置
+ ///
+ public AopConfig Aop { get; set; } = new AopConfig();
///
- /// Api地址,默认 http://*:8081
+ /// 日志配置
///
- public string Urls { get; set; } = "http://*:8081";
+ public LogConfig Log { get; set; } = new LogConfig();
- public AopConfig Aop { get; set; }
+ ///
+ /// 限流
+ ///
+ public bool RateLimit { get; set; } = false;
+
+ ///
+ /// 验证码配置
+ ///
+ public VarifyCodeConfig VarifyCode { get; set; } = new VarifyCodeConfig();
}
+ ///
+ /// 统一认证授权服务器配置
+ ///
+ public class IdentityServer
+ {
+ ///
+ /// 启用
+ ///
+ public bool Enable { get; set; } = false;
+ ///
+ /// 地址
+ ///
+ public string Url { get; set; } = "https://localhost:5000";
+ }
+
+ ///
+ /// Aop配置
+ ///
public class AopConfig
{
///
/// 事物
///
- public bool Transaction { get; set; }
+ public bool Transaction { get; set; } = true;
+ }
+
+ ///
+ /// 日志配置
+ ///
+ public class LogConfig
+ {
+ ///
+ /// 操作日志
+ ///
+ public bool Operation { get; set; } = true;
+ }
+
+ ///
+ /// 验证码配置
+ ///
+ public class VarifyCodeConfig
+ {
+ ///
+ /// 启用
+ ///
+ public bool Enable { get; set; } = true;
+
+ ///
+ /// 操作日志
+ ///
+ public string[] Fonts { get; set; }// = new[] { "Times New Roman", "Verdana", "Arial", "Gungsuh", "Impact" };
}
}
diff --git a/Admin.Core.Common/Configs/CacheConfig.cs b/Admin.Core.Common/Configs/CacheConfig.cs
index 32c665520..c41f6bacd 100644
--- a/Admin.Core.Common/Configs/CacheConfig.cs
+++ b/Admin.Core.Common/Configs/CacheConfig.cs
@@ -12,19 +12,32 @@ public class CacheConfig
///
/// 缓存类型
///
- public CacheType Type { get; set; }
+ public CacheType Type { get; set; } = CacheType.Memory;
+
+ ///
+ /// 限流缓存类型
+ ///
+ public CacheType TypeRateLimit { get; set; } = CacheType.Memory;
///
/// Redis配置
///
- public RedisConfig Redis { get; set; }
+ public RedisConfig Redis { get; set; } = new RedisConfig();
}
+ ///
+ /// Redis配置
+ ///
public class RedisConfig
{
///
/// 连接字符串
///
- public string ConnectionString { get; set; }
+ public string ConnectionString { get; set; } = "127.0.0.1:6379,password=,defaultDatabase=2";
+
+ ///
+ /// 限流连接字符串
+ ///
+ public string ConnectionStringRateLimit { get; set; } = "127.0.0.1:6379,password=,defaultDatabase=1";
}
}
diff --git a/Admin.Core.Common/Configs/DbConfig.cs b/Admin.Core.Common/Configs/DbConfig.cs
index 5e28160f8..2bfd88ff9 100644
--- a/Admin.Core.Common/Configs/DbConfig.cs
+++ b/Admin.Core.Common/Configs/DbConfig.cs
@@ -11,32 +11,32 @@ public class DbConfig
///
/// 数据库类型
///
- public DataType Type { get; set; }
+ public DataType Type { get; set; } = DataType.Sqlite;
///
/// 数据库字符串
///
- public string ConnectionString { get; set; }
+ public string ConnectionString { get; set; } = "Data Source=|DataDirectory|\\admindb.db; Pooling=true;Min Pool Size=1";
///
/// 生成数据
///
- public bool GenerateData { get; set; }
+ public bool GenerateData { get; set; } = false;
///
/// 同步结构
///
- public bool SyncStructure { get; set; }
+ public bool SyncStructure { get; set; } = true;
///
/// 同步数据
///
- public bool SyncData { get; set; }
+ public bool SyncData { get; set; } = true;
///
/// 建库
///
- public bool CreateDb { get; set; }
+ public bool CreateDb { get; set; } = true;
///
/// 建库连接字符串
@@ -51,11 +51,11 @@ public class DbConfig
///
/// 监听所有操作
///
- public bool MonitorCommand { get; set; }
+ public bool MonitorCommand { get; set; } = false;
///
/// 监听Curd操作
///
- public bool Curd { get; set; }
+ public bool Curd { get; set; } = false;
}
}
diff --git a/Admin.Core.Common/Configs/JwtConfig.cs b/Admin.Core.Common/Configs/JwtConfig.cs
index 67b75b967..aa1ccedc3 100644
--- a/Admin.Core.Common/Configs/JwtConfig.cs
+++ b/Admin.Core.Common/Configs/JwtConfig.cs
@@ -11,21 +11,26 @@ public class JwtConfig
///
/// 发行者
///
- public string Issuer { get; set; }
+ public string Issuer { get; set; } = "http://127.0.0.1:8888";
///
/// 订阅者
///
- public string Audience { get; set; }
+ public string Audience { get; set; } = "http://127.0.0.1:8888";
///
- /// 秘钥
+ /// 密钥
///
- public string SecurityKey { get; set; }
+ public string SecurityKey { get; set; } = "ertJKl#521*a@790asD&1#";
///
/// 有效期(分钟)
///
- public int Expires { get; set; }
+ public int Expires { get; set; } = 120;
+
+ ///
+ /// 刷新有效期(分钟)
+ ///
+ public int RefreshExpires { get; set; } = 480;
}
}
diff --git a/Admin.Core.Common/Configs/UploadConfig.cs b/Admin.Core.Common/Configs/UploadConfig.cs
new file mode 100644
index 000000000..779ec4bcd
--- /dev/null
+++ b/Admin.Core.Common/Configs/UploadConfig.cs
@@ -0,0 +1,80 @@
+using System;
+using System.IO;
+
+namespace Admin.Core.Common.Configs
+{
+ ///
+ /// 上传配置
+ ///
+ public class UploadConfig
+ {
+ ///
+ /// 头像上传配置
+ ///
+ public FileUploadConfig Avatar { get; set; }
+
+ ///
+ /// 文档图片上传配置
+ ///
+ public FileUploadConfig Document { get; set; }
+ }
+
+ ///
+ /// 文件上传配置
+ ///
+ public class FileUploadConfig
+ {
+ private string _uploadPath;
+ ///
+ /// 上传路径
+ ///
+ public string UploadPath
+ {
+ get
+ {
+ if (_uploadPath.IsNull())
+ {
+ _uploadPath = Path.Combine(AppContext.BaseDirectory, "upload").ToPath();
+ }
+
+ if (!Path.IsPathRooted(_uploadPath))
+ {
+ _uploadPath = Path.Combine(AppContext.BaseDirectory, _uploadPath).ToPath();
+ }
+
+ return _uploadPath;
+ }
+ set => _uploadPath = value;
+ }
+
+ ///
+ /// 请求路径
+ ///
+ public string RequestPath { get; set; }
+
+ ///
+ /// 路径格式
+ ///
+ public string Format { get; set; }
+
+ ///
+ /// 路径日期格式
+ ///
+ public string DateTimeFormat { get; set; }
+
+ ///
+ /// 文件大小 10M = 10 * 1024 * 1024
+ ///
+ public long MaxSize { get; set; }
+
+ ///
+ /// 最大允许上传个数 -1不限制
+ ///
+ public int Limit { get; set; } = -1;
+
+ ///
+ /// 文件格式
+ ///
+ public string[] ContentType { get; set; }
+ }
+}
diff --git a/Admin.Core.Common/Extensions/DateTimeExtensions.cs b/Admin.Core.Common/Extensions/DateTimeExtensions.cs
new file mode 100644
index 000000000..e677d2292
--- /dev/null
+++ b/Admin.Core.Common/Extensions/DateTimeExtensions.cs
@@ -0,0 +1,36 @@
+using System;
+
+namespace Admin.Core.Common.Extensions
+{
+ public static class DateTimeExtensions
+ {
+ ///
+ /// 时间戳起始日期
+ ///
+ public static DateTime TimestampStart = new DateTime(1970, 1, 1, 0, 0, 0, 0);
+
+ ///
+ /// 转换为时间戳
+ ///
+ ///
+ /// 是否使用毫秒
+ ///
+ public static long ToTimestamp(this DateTime dateTime, bool milliseconds = false)
+ {
+ var timestamp = dateTime.ToUniversalTime() - TimestampStart;
+ return (long)(milliseconds ? timestamp.TotalMilliseconds : timestamp.TotalSeconds);
+ }
+
+ ///
+ /// 获取周几
+ ///
+ ///
+ ///
+ public static string GetWeekName(this DateTime datetime)
+ {
+ var day = (int)datetime.DayOfWeek;
+ var week = new string[] { "周日", "周一", "周二", "周三", "周四", "周五", "周六" };
+ return week[day];
+ }
+ }
+}
diff --git a/Admin.Core.Common/Extensions/EnumExtensions.cs b/Admin.Core.Common/Extensions/EnumExtensions.cs
new file mode 100644
index 000000000..4ad2c76ab
--- /dev/null
+++ b/Admin.Core.Common/Extensions/EnumExtensions.cs
@@ -0,0 +1,54 @@
+using Admin.Core.Common.Output;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Reflection;
+
+namespace Admin.Core.Common.Extensions
+{
+ public static class EnumExtensions
+ {
+ public static string ToDescription(this Enum item)
+ {
+ string name = item.ToString();
+ var desc = item.GetType().GetField(name)?.GetCustomAttribute();
+ return desc?.Description ?? name;
+ }
+
+ public static long ToInt64(this Enum item)
+ {
+ return Convert.ToInt64(item);
+ }
+
+ public static List ToList(this Enum value, bool ignoreUnKnown = false)
+ {
+ var enumType = value.GetType();
+
+ if (!enumType.IsEnum)
+ return null;
+
+ return Enum.GetValues(enumType).Cast()
+ .Where(m => !ignoreUnKnown || !m.ToString().Equals("UnKnown")).Select(x => new OptionOutput
+ {
+ Label = x.ToDescription(),
+ Value = x
+ }).ToList();
+ }
+
+ public static List ToList(bool ignoreUnKnown = false)
+ {
+ var enumType = typeof(T);
+
+ if (!enumType.IsEnum)
+ return null;
+
+ return Enum.GetValues(enumType).Cast()
+ .Where(m => !ignoreUnKnown || !m.ToString().Equals("UnKnown")).Select(x => new OptionOutput
+ {
+ Label = x.ToDescription(),
+ Value = x
+ }).ToList();
+ }
+ }
+}
diff --git a/Admin.Core.Common/Extensions/GuidExtensions.cs b/Admin.Core.Common/Extensions/GuidExtensions.cs
index dba34ea74..4d6902f88 100644
--- a/Admin.Core.Common/Extensions/GuidExtensions.cs
+++ b/Admin.Core.Common/Extensions/GuidExtensions.cs
@@ -1,6 +1,6 @@
using System;
-namespace Admin.Core
+namespace Admin.Core.Common.Extensions
{
public static class GuidExtensions
{
diff --git a/Admin.Core.Common/Extensions/MethodInfoExtensions.cs b/Admin.Core.Common/Extensions/MethodInfoExtensions.cs
index 9890475a8..0d7645f47 100644
--- a/Admin.Core.Common/Extensions/MethodInfoExtensions.cs
+++ b/Admin.Core.Common/Extensions/MethodInfoExtensions.cs
@@ -1,15 +1,20 @@
-using System.Linq;
+using System;
+using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
-namespace Admin.Core.Extensions
+namespace Admin.Core.Common.Extensions
{
public static class MethodInfoExtensions
{
public static bool HasAttribute(this MethodInfo method)
{
- return method.GetCustomAttributes(true).FirstOrDefault(x => x.GetType() == typeof(T)) is T;
+ return method.GetCustomAttributes(typeof(T), false).FirstOrDefault() is T;
+ }
+ public static T GetAttribute(this MethodInfo method) where T : Attribute
+ {
+ return method.GetCustomAttributes(typeof(T), false).FirstOrDefault() as T;
}
public static bool IsAsync(this MethodInfo method)
diff --git a/Admin.Core.Common/Extensions/StringExtensions.cs b/Admin.Core.Common/Extensions/StringExtensions.cs
index 2317349cb..af639b552 100644
--- a/Admin.Core.Common/Extensions/StringExtensions.cs
+++ b/Admin.Core.Common/Extensions/StringExtensions.cs
@@ -1,6 +1,7 @@
using System;
using System.Linq;
using System.Text;
+using Admin.Core.Common.Helpers;
namespace Admin.Core
{
@@ -89,5 +90,13 @@ public static string ToBase64(this string s, Encoding encoding)
var bytes = encoding.GetBytes(s);
return bytes.ToBase64();
}
+
+ public static string ToPath(this string s)
+ {
+ if (s.IsNull())
+ return string.Empty;
+
+ return s.Replace(@"\", "/");
+ }
}
}
diff --git a/Admin.Core.Common/Files/FileInfo.cs b/Admin.Core.Common/Files/FileInfo.cs
new file mode 100644
index 000000000..1e171d1eb
--- /dev/null
+++ b/Admin.Core.Common/Files/FileInfo.cs
@@ -0,0 +1,77 @@
+namespace Admin.Core.Common.Files
+{
+ ///
+ /// 文件信息
+ ///
+ public class FileInfo
+ {
+ public FileInfo() { }
+
+ ///
+ /// 初始化文件信息
+ ///
+ /// 文件名称
+ /// 大小
+ public FileInfo(string fileName, long size = 0L)
+ {
+ FileName = fileName;
+ Size = new FileSize(size);
+ Extension = System.IO.Path.GetExtension(FileName)?.TrimStart('.');
+ }
+
+ ///
+ /// 上传路径
+ ///
+ public string UploadPath { get; set; }
+
+ ///
+ /// 请求路径
+ ///
+ public string RequestPath { get; set; }
+
+ ///
+ /// 相对路径
+ ///
+ public string RelativePath { get; set; }
+
+ ///
+ /// 文件名
+ ///
+ public string FileName { get; set; }
+
+ ///
+ /// 保存名
+ ///
+ public string SaveName { get; set; }
+
+ ///
+ /// 文件大小
+ ///
+ public FileSize Size { get; set; }
+
+ ///
+ /// 扩展名
+ ///
+ public string Extension { get; set; }
+
+ ///
+ /// 文件目录
+ ///
+ public string FileDirectory => System.IO.Path.Combine(UploadPath, RelativePath).ToPath();
+
+ ///
+ /// 文件请求路径
+ ///
+ public string FileRequestPath => System.IO.Path.Combine(RequestPath, RelativePath, SaveName).ToPath();
+
+ ///
+ /// 文件相对路径
+ ///
+ public string FileRelativePath => System.IO.Path.Combine(RelativePath, SaveName).ToPath();
+
+ ///
+ /// 文件路径
+ ///
+ public string FilePath => System.IO.Path.Combine(UploadPath, RelativePath, SaveName).ToPath();
+ }
+}
diff --git a/Admin.Core.Common/Files/FileSize.cs b/Admin.Core.Common/Files/FileSize.cs
new file mode 100644
index 000000000..1d32f03d9
--- /dev/null
+++ b/Admin.Core.Common/Files/FileSize.cs
@@ -0,0 +1,82 @@
+using Admin.Core.Common.Extensions;
+using Admin.Core.Common.Helpers;
+
+namespace Admin.Core.Common.Files
+{
+ ///
+ /// 文件大小
+ ///
+ public struct FileSize
+ {
+ ///
+ /// 初始化文件大小
+ ///
+ /// 文件大小
+ /// 文件大小单位
+ public FileSize(long size, FileSizeUnit unit = FileSizeUnit.Byte)
+ {
+ switch (unit)
+ {
+ case FileSizeUnit.K:
+ Size = size * 1024; break;
+ case FileSizeUnit.M:
+ Size = size * 1024 * 1024; break;
+ case FileSizeUnit.G:
+ Size = size * 1024 * 1024 * 1024; break;
+ default:
+ Size = size; break;
+ }
+ }
+
+ ///
+ /// 文件字节长度
+ ///
+ public long Size { get; }
+
+ ///
+ /// 获取文件大小,单位:字节
+ ///
+ public long GetSize()
+ {
+ return Size;
+ }
+
+ ///
+ /// 获取文件大小,单位:K
+ ///
+ public double GetSizeByK()
+ {
+ return (Size / 1024.0).ToDouble(2);
+ }
+
+ ///
+ /// 获取文件大小,单位:M
+ ///
+ public double GetSizeByM()
+ {
+ return (Size / 1024.0 / 1024.0).ToDouble(2);
+ }
+
+ ///
+ /// 获取文件大小,单位:G
+ ///
+ public double GetSizeByG()
+ {
+ return (Size / 1024.0 / 1024.0 / 1024.0).ToDouble(2);
+ }
+
+ ///
+ /// 输出描述
+ ///
+ public override string ToString()
+ {
+ if (Size >= 1024 * 1024 * 1024)
+ return $"{GetSizeByG()} {FileSizeUnit.G.ToDescription()}";
+ if (Size >= 1024 * 1024)
+ return $"{GetSizeByM()} {FileSizeUnit.M.ToDescription()}";
+ if (Size >= 1024)
+ return $"{GetSizeByK()} {FileSizeUnit.K.ToDescription()}";
+ return $"{Size} {FileSizeUnit.Byte.ToDescription()}";
+ }
+ }
+}
\ No newline at end of file
diff --git a/Admin.Core.Common/Files/FileSizeUnit.cs b/Admin.Core.Common/Files/FileSizeUnit.cs
new file mode 100644
index 000000000..b1c6fde1d
--- /dev/null
+++ b/Admin.Core.Common/Files/FileSizeUnit.cs
@@ -0,0 +1,31 @@
+using System.ComponentModel;
+
+namespace Admin.Core.Common.Files
+{
+ ///
+ /// 文件大小单位
+ ///
+ public enum FileSizeUnit
+ {
+ ///
+ /// 字节
+ ///
+ [Description("B")]
+ Byte,
+ ///
+ /// K字节
+ ///
+ [Description("KB")]
+ K,
+ ///
+ /// M字节
+ ///
+ [Description("MB")]
+ M,
+ ///
+ /// G字节
+ ///
+ [Description("GB")]
+ G
+ }
+}
\ No newline at end of file
diff --git a/Admin.Core.Common/Helpers/ConfigHelper.cs b/Admin.Core.Common/Helpers/ConfigHelper.cs
index 348cdb8f9..79ae94cef 100644
--- a/Admin.Core.Common/Helpers/ConfigHelper.cs
+++ b/Admin.Core.Common/Helpers/ConfigHelper.cs
@@ -9,6 +9,17 @@ namespace Admin.Core.Common.Helpers
///
public class ConfigHelper
{
+ /* 使用热更新
+ var uploadConfig = new ConfigHelper().Load("uploadconfig", _env.EnvironmentName, true);
+ services.Configure(uploadConfig);
+
+ private readonly UploadConfig _uploadConfig;
+ public ImgController(IOptionsMonitor uploadConfig)
+ {
+ _uploadConfig = uploadConfig.CurrentValue;
+ }
+ */
+
///
/// 加载配置文件
///
@@ -28,7 +39,7 @@ public IConfiguration Load(string fileName, string environmentName = "", bool re
if (environmentName.NotNull())
{
- builder.AddJsonFile(fileName.ToLower() + "." + environmentName + ".json", true, reloadOnChange);
+ builder.AddJsonFile(fileName.ToLower() + "." + environmentName + ".json", optional: true, reloadOnChange: reloadOnChange);
}
return builder.Build();
@@ -38,8 +49,8 @@ public IConfiguration Load(string fileName, string environmentName = "", bool re
/// 获得配置信息
///
/// 配置信息
- ///
- /// 文件名称
+ /// 文件名称
+ /// 环境名称
/// 自动更新
///
public T Get(string fileName, string environmentName = "", bool reloadOnChange = false)
@@ -50,5 +61,21 @@ public T Get(string fileName, string environmentName = "", bool reloadOnChang
return configuration.Get();
}
+
+ ///
+ /// 绑定实例配置信息
+ ///
+ /// 文件名称
+ /// 实例配置
+ /// 环境名称
+ /// 自动更新
+ public void Bind(string fileName, object instance, string environmentName = "", bool reloadOnChange = false)
+ {
+ var configuration = Load(fileName, environmentName, reloadOnChange);
+ if (configuration == null || instance == null)
+ return;
+
+ configuration.Bind(instance);
+ }
}
}
diff --git a/Admin.Core.Common/Helpers/ConsoleHelper.cs b/Admin.Core.Common/Helpers/ConsoleHelper.cs
index 5beca332b..0f875ab13 100644
--- a/Admin.Core.Common/Helpers/ConsoleHelper.cs
+++ b/Admin.Core.Common/Helpers/ConsoleHelper.cs
@@ -1,6 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Text;
namespace Admin.Core.Common.Helpers
{
diff --git a/Admin.Core.Common/Helpers/HtmlHelper.cs b/Admin.Core.Common/Helpers/HtmlHelper.cs
new file mode 100644
index 000000000..16d4407ab
--- /dev/null
+++ b/Admin.Core.Common/Helpers/HtmlHelper.cs
@@ -0,0 +1,416 @@
+using System;
+using System.Text;
+using System.Net;
+using System.IO;
+using System.Threading;
+using System.Text.RegularExpressions;
+using Admin.Core.Common.Attributes;
+
+namespace Admin.Core.Common.Helpers
+{
+ ///
+ /// Html操作相关类
+ ///
+ [SingleInstance]
+ public class HtmlHelper
+ {
+ #region 私有字段
+ private readonly string _ContentType = "application/json";
+ private readonly string _Accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/x-silverlight, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, application/x-silverlight-2-b1, */*";
+ private readonly string _UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)";
+ private int _Delay = 1000;
+ private int _CurrentTry = 0;
+ #endregion
+
+ #region 公有属性
+ ///
+ /// Cookie
+ ///
+ public CookieContainer CookieContainer { get; } = new CookieContainer();
+
+ ///
+ /// 语言
+ ///
+ public Encoding Encoding { get; set; } = Encoding.GetEncoding("utf-8");
+
+ public int NetworkDelay
+ {
+ get
+ {
+ Random r = new Random();
+ return r.Next(_Delay, _Delay * 2);
+ }
+ set
+ {
+ _Delay = value;
+ }
+ }
+
+ public int MaxTry { get; set; } = 300;
+ #endregion
+
+ #region 获取HTML
+ ///
+ /// 获取HTML
+ ///
+ /// 地址
+ /// post 提交的字符串
+ /// 是否是post
+ /// CookieContainer
+ public string GetHtml(string url, string postData, bool isPost, CookieContainer cookieContainer)
+ {
+ if (string.IsNullOrEmpty(postData)) return GetHtml(url, cookieContainer);
+ Thread.Sleep(NetworkDelay);
+ _CurrentTry++;
+ HttpWebRequest httpWebRequest = null;
+ HttpWebResponse httpWebResponse = null;
+ try
+ {
+ byte[] byteRequest = Encoding.Default.GetBytes(postData);
+ httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
+ httpWebRequest.CookieContainer = cookieContainer;
+ httpWebRequest.ContentType = _ContentType;
+ httpWebRequest.ServicePoint.ConnectionLimit = MaxTry;
+ httpWebRequest.Referer = url;
+ httpWebRequest.Accept = _Accept;
+ httpWebRequest.UserAgent = _UserAgent;
+ httpWebRequest.Method = isPost ? "POST" : "GET";
+ httpWebRequest.ContentLength = byteRequest.Length;
+ Stream stream = httpWebRequest.GetRequestStream();
+ stream.Write(byteRequest, 0, byteRequest.Length);
+ stream.Close();
+ httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
+ Stream responseStream = httpWebResponse.GetResponseStream();
+ StreamReader streamReader = new StreamReader(responseStream, Encoding);
+ string html = streamReader.ReadToEnd();
+ streamReader.Close();
+ responseStream.Close();
+ _CurrentTry = 0;
+ httpWebRequest.Abort();
+ httpWebResponse.Close();
+ return html;
+ }
+ catch
+ {
+ if (_CurrentTry <= MaxTry) GetHtml(url, postData, isPost, cookieContainer);
+ _CurrentTry--;
+ if (httpWebRequest != null) httpWebRequest.Abort();
+ if (httpWebResponse != null) httpWebResponse.Close();
+ return string.Empty;
+ }
+ }
+
+ ///
+ /// 获取HTML
+ ///
+ /// 地址
+ /// CookieContainer
+ public string GetHtml(string url, CookieContainer cookieContainer)
+ {
+ Thread.Sleep(NetworkDelay);
+ _CurrentTry++;
+ HttpWebRequest httpWebRequest = null;
+ HttpWebResponse httpWebResponse = null;
+ try
+ {
+ httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
+ httpWebRequest.CookieContainer = cookieContainer;
+ httpWebRequest.ContentType = _ContentType;
+ httpWebRequest.ServicePoint.ConnectionLimit = MaxTry;
+ httpWebRequest.Referer = url;
+ httpWebRequest.Accept = _Accept;
+ httpWebRequest.UserAgent = _UserAgent;
+ httpWebRequest.Method = "GET";
+ httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
+ Stream responseStream = httpWebResponse.GetResponseStream();
+ StreamReader streamReader = new StreamReader(responseStream, Encoding);
+ string html = streamReader.ReadToEnd();
+ streamReader.Close();
+ responseStream.Close();
+ _CurrentTry--;
+ httpWebRequest.Abort();
+ httpWebResponse.Close();
+ return html;
+ }
+ catch (Exception)
+ {
+ if (_CurrentTry <= MaxTry) GetHtml(url, cookieContainer);
+ _CurrentTry--;
+ if (httpWebRequest != null) httpWebRequest.Abort();
+ if (httpWebResponse != null) httpWebResponse.Close();
+ return string.Empty;
+ }
+ }
+ #endregion
+
+ #region 获取字符流
+ //---------------------------------------------------------------------------------------------------------------
+ // 示例:
+ // System.Net.CookieContainer cookie = new System.Net.CookieContainer();
+ // Stream s = HttpHelper.GetStream("http://ptlogin2.qq.com/getimage?aid=15000102&0.43878429697395826", cookie);
+ // picVerify.Image = Image.FromStream(s);
+ //---------------------------------------------------------------------------------------------------------------
+ ///
+ /// 获取字符流
+ ///
+ /// 地址
+ /// cookieContainer
+ public Stream GetStream(string url, CookieContainer cookieContainer)
+ {
+ _CurrentTry++;
+
+ HttpWebRequest httpWebRequest = null;
+ HttpWebResponse httpWebResponse = null;
+
+ try
+ {
+ httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
+ httpWebRequest.CookieContainer = cookieContainer;
+ httpWebRequest.ContentType = _ContentType;
+ httpWebRequest.ServicePoint.ConnectionLimit = MaxTry;
+ httpWebRequest.Referer = url;
+ httpWebRequest.Accept = _Accept;
+ httpWebRequest.UserAgent = _UserAgent;
+ httpWebRequest.Method = "GET";
+
+ httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
+ Stream responseStream = httpWebResponse.GetResponseStream();
+ _CurrentTry--;
+ return responseStream;
+ }
+ catch (Exception)
+ {
+ if (_CurrentTry <= MaxTry)
+ {
+ GetHtml(url, cookieContainer);
+ }
+
+ _CurrentTry--;
+
+ if (httpWebRequest != null)
+ {
+ httpWebRequest.Abort();
+ } if (httpWebResponse != null)
+ {
+ httpWebResponse.Close();
+ }
+ return null;
+ }
+ }
+ #endregion
+
+ #region 清除HTML标记
+ ///
+ /// 清除HTML标记
+ ///
+ ///
+ /// 已经去除后的文字
+ public string NoHTML(string Htmlstring)
+ {
+ //删除脚本
+ Htmlstring = Regex.Replace(Htmlstring, @"", "", RegexOptions.IgnoreCase);
+
+ //删除HTML
+ Regex regex = new Regex("<.+?>", RegexOptions.IgnoreCase);
+ Htmlstring = regex.Replace(Htmlstring, "");
+ Htmlstring = Regex.Replace(Htmlstring, @"<(.[^>]*)>", "", RegexOptions.IgnoreCase);
+ Htmlstring = Regex.Replace(Htmlstring, @"([\r\n])[\s]+", "", RegexOptions.IgnoreCase);
+ Htmlstring = Regex.Replace(Htmlstring, @"-->", "", RegexOptions.IgnoreCase);
+ Htmlstring = Regex.Replace(Htmlstring, @"
OutOfProcess
+ false
+ 1.4.1
+ MIT
+ xiaoxue
+ xiaoxue
+ git
+ 中台Admin后端WebApi
+ https://github.com/zhontai/Admin.Core
+ https://github.com/zhontai/Admin.Core
+ ZhonTai Admin;WebApi
+ Admin.Core
+ Admin.Core
@@ -14,16 +26,12 @@
-
-
-
-
@@ -32,16 +40,18 @@
+
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
@@ -49,6 +59,9 @@
+
+ Always
+
Always
@@ -62,6 +75,7 @@
+
diff --git a/Admin.Core/Admin.Core.xml b/Admin.Core/Admin.Core.xml
index b357f11cb..5119ad4fa 100644
--- a/Admin.Core/Admin.Core.xml
+++ b/Admin.Core/Admin.Core.xml
@@ -9,6 +9,11 @@
启用登录
+
+
+ 禁用操作日志
+
+
启用权限
@@ -21,7 +26,7 @@
- 自定义路由 /api/{version}/[controler]/[action]
+ 自定义路由 /api/{version}/[area]/[controler]/[action]
@@ -74,7 +79,7 @@
-
+
查询分页接口
@@ -128,6 +133,13 @@
授权管理
+
+
+ 获得token
+
+
+
+
获取验证码
@@ -135,7 +147,7 @@
上次验证码键
-
+
获取密钥
@@ -155,6 +167,32 @@
登录信息
+
+
+ 刷新Token
+ 以旧换新
+
+
+
+
+
+
+ 缓存管理
+
+
+
+
+ 获取缓存列表
+
+
+
+
+
+ 清除缓存
+
+
+
+
数据字典
@@ -167,7 +205,7 @@
-
+
查询分页数据字典
@@ -195,33 +233,133 @@
-
+
- 图片管理
+ 文档管理
-
+
+
+ 查询文档列表
+
+
+
+
+
+
+
- 获取头像
+ 查询文档图片列表
-
-
+
-
+
- 下载图片
+ 查询单条分组
-
-
+
-
+
- 上传图片
- 支持多图片上传
+ 查询单条菜单
-
+
+
+
+
+
+ 查询单条文档内容
+
+
+
+
+
+
+ 查询精简文档列表
+
+
+
+
+
+ 新增分组
+
+
+
+
+
+
+ 新增菜单
+
+
+
+
+
+
+ 修改分组
+
+
+
+
+
+
+ 修改菜单
+
+
+
+
+
+
+ 修改文档内容
+
+
+
+
+
+
+ 删除文档
+
+
+
+
+
+
+ 删除图片
+
+
+
+
+
+
+
+ 上传文档图片
+
+
+
+
+
+
+ 登录日志管理
+
+
+
+
+ 查询分页登录日志
+
+
+
+
+
+
+ 操作日志管理
+
+
+
+
+ 查询分页操作日志
+
+
@@ -259,9 +397,16 @@
+
+
+ 查询单条权限点
+
+
+
+
- 查询权限分配界面权限列表
+ 查询角色权限-权限列表
@@ -293,6 +438,13 @@
+
+
+ 新增权限点
+
+
+
+
修改分组
@@ -314,6 +466,13 @@
+
+
+ 修改权限点
+
+
+
+
删除权限
@@ -340,7 +499,7 @@
-
+
查询分页角色
@@ -393,7 +552,7 @@
-
+
查询分页用户
@@ -442,6 +601,13 @@
+
+
+ 上传头像
+
+
+
+
视图管理
@@ -461,7 +627,7 @@
-
+
查询分页视图
@@ -522,18 +688,20 @@
-
+
同步结构
-
+
- 初始化数据
+ 初始化数据表数据
+
+
@@ -543,7 +711,7 @@
-
+
同步数据
@@ -613,9 +781,50 @@
系统内部错误(非业务代码里显式抛出的异常,例如由于数据不正确导致空指针异常、数据库异常等等)
-
+
+
+ 添加Ip限流
+
+
+
+
+
+
+
+ Admin异常错误过滤
+
+
+
+
+ Api帮助类
+
+
+
+
+ 接口名称
+
+
+
+
+ 接口地址
+
+
+
+
+ 操作日志处理接口
+
+
+
+
+ 写操作日志
+
+
+
+
+
+
- 全局异常错误过滤
+ 操作日志处理
diff --git a/Admin.Core/Aop/AopHelper.cs b/Admin.Core/Aop/AopHelper.cs
index a909d8fe4..ab016cc92 100644
--- a/Admin.Core/Aop/AopHelper.cs
+++ b/Admin.Core/Aop/AopHelper.cs
@@ -8,7 +8,7 @@ namespace Admin.Core.Aop
{
public class AopHelper
{
- public static async Task ExecuteGenericMethod(Task returnValue, Action callBackAction, Action exceptionAction)
+ public static async Task ExecuteGenericMethod(Task returnValue, Action callBackAction, Action exceptionAction, Action finallyAction)
{
try
{
@@ -19,16 +19,20 @@ public static async Task ExecuteGenericMethod(Task returnValue, Action<
catch (Exception ex)
{
exceptionAction?.Invoke(ex);
- throw;
+ return default;
+ }
+ finally
+ {
+ finallyAction?.Invoke();
}
}
- public static object CallGenericMethod(IInvocation invocation, Action