xiaoxue 4 vuotta sitten
vanhempi
commit
582247e549

+ 4 - 4
Admin.Core.Common/Admin.Core.Common.csproj

@@ -3,7 +3,7 @@
   <PropertyGroup>
     <TargetFramework>netcoreapp3.1</TargetFramework>
     <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
-    <Version>1.2.0</Version>
+    <Version>1.3.0</Version>
     <Authors>xiaoxue</Authors>
     <Company>xiaoxue</Company>
     <Description>中台Admin后端通用库</Description>
@@ -30,9 +30,9 @@
     <PackageReference Include="FreeSql.Provider.SqlServer" Version="1.5.0-preview0509" />
     <PackageReference Include="FreeSql.Repository" Version="1.5.0-preview0509" />
     <PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
-    <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="3.1.3" />
-    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.3" />
-    <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.1.3" />
+    <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="3.1.4" />
+    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.4" />
+    <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.1.4" />
     <PackageReference Include="Microsoft.IdentityModel.Tokens" Version="6.5.1" />
     <PackageReference Include="System.Drawing.Common" Version="4.7.0" />
     <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.5.1" />

+ 0 - 0
Admin.Core.Common/Attributes/SingletonAttribute.cs → Admin.Core.Common/Attributes/SingleInstanceAttribute.cs


+ 2 - 0
Admin.Core.Common/Auth/UserToken.cs

@@ -5,9 +5,11 @@ using System.Security.Claims;
 using System.IdentityModel.Tokens.Jwt;
 using Microsoft.IdentityModel.Tokens;
 using Admin.Core.Common.Configs;
+using Admin.Core.Common.Attributes;
 
 namespace Admin.Core.Common.Auth
 {
+    [SingleInstance]
     public class UserToken : IUserToken
     {
         private readonly JwtConfig _jwtConfig;

+ 6 - 0
Admin.Core.Common/Cache/CacheType.cs

@@ -6,7 +6,13 @@ namespace Admin.Core.Common.Cache
     /// </summary>
     public enum CacheType
     {
+        /// <summary>
+        /// 内存缓存
+        /// </summary>
         Memory,
+        /// <summary>
+        /// Redis缓存
+        /// </summary>
         Redis
     }
 }

+ 10 - 10
Admin.Core.Common/Configs/AppConfig.cs

@@ -6,29 +6,29 @@
     public class AppConfig
     {
         /// <summary>
-        /// Swagger文档
+        /// Api地址,默认 http://*:8888
         /// </summary>
-        public bool Swagger { get; set; }
+        public string Urls { get; set; } = "http://*:8888";
 
         /// <summary>
-        /// Api地址,默认 http://*:8888
+        /// Swagger文档
         /// </summary>
-        public string Urls { get; set; } = "http://*:8888";
+        public bool Swagger { get; set; } = false;
 
         /// <summary>
         /// Aop配置
         /// </summary>
-        public AopConfig Aop { get; set; }
+        public AopConfig Aop { get; set; } = new AopConfig();
 
         /// <summary>
         /// 日志配置
         /// </summary>
-        public LogConfig Log { get; set; }
+        public LogConfig Log { get; set; } = new LogConfig();
 
         /// <summary>
         /// 验证码配置
         /// </summary>
-        public VarifyCodeConfig VarifyCode { get; set; }
+        public VarifyCodeConfig VarifyCode { get; set; } = new VarifyCodeConfig();
     }
 
     /// <summary>
@@ -39,7 +39,7 @@
         /// <summary>
         /// 事物
         /// </summary>
-        public bool Transaction { get; set; }
+        public bool Transaction { get; set; } = true;
     }
 
     /// <summary>
@@ -50,7 +50,7 @@
         /// <summary>
         /// 操作日志
         /// </summary>
-        public bool Operation { get; set; }
+        public bool Operation { get; set; } = true;
     }
 
     /// <summary>
@@ -61,6 +61,6 @@
         /// <summary>
         /// 操作日志
         /// </summary>
-        public string[] Font { get; set; }
+        public string[] Font { get; set; } = { "Times New Roman", "Verdana", "Arial", "Gungsuh", "Impact" };
     }
 }

+ 6 - 3
Admin.Core.Common/Configs/CacheConfig.cs

@@ -12,19 +12,22 @@ namespace Admin.Core.Common.Configs
         /// <summary>
         /// 缓存类型
         /// </summary>
-        public CacheType Type { get; set; }
+        public CacheType Type { get; set; } = CacheType.Memory;
 
         /// <summary>
         /// Redis配置
         /// </summary>
-        public RedisConfig Redis { get; set; }
+        public RedisConfig Redis { get; set; } = new RedisConfig();
     }
 
+    /// <summary>
+    /// Redis配置
+    /// </summary>
     public class RedisConfig
     {
         /// <summary>
         /// 连接字符串
         /// </summary>
-        public string ConnectionString { get; set; }
+        public string ConnectionString { get; set; } = "127.0.0.1:6379,password=,defaultDatabase=2";
     }
 }

+ 8 - 8
Admin.Core.Common/Configs/DbConfig.cs

@@ -11,32 +11,32 @@ namespace Admin.Core.Common.Configs
         /// <summary>
         /// 数据库类型
         /// </summary>
-        public DataType Type { get; set; }
+        public DataType Type { get; set; } = DataType.Sqlite;
 
         /// <summary>
         /// 数据库字符串
         /// </summary>
-        public string ConnectionString { get; set; }
+        public string ConnectionString { get; set; } = "Data Source=|DataDirectory|\\admindb.db; Pooling=true;Min Pool Size=1";
 
         /// <summary>
         /// 生成数据
         /// </summary>
-        public bool GenerateData { get; set; }
+        public bool GenerateData { get; set; } = false;
 
         /// <summary>
         /// 同步结构
         /// </summary>
-        public bool SyncStructure { get; set; }
+        public bool SyncStructure { get; set; } = true;
 
         /// <summary>
         /// 同步数据
         /// </summary>
-        public bool SyncData { get; set; }
+        public bool SyncData { get; set; } = true;
 
         /// <summary>
         /// 建库
         /// </summary>
-        public bool CreateDb { get; set; }
+        public bool CreateDb { get; set; } = true;
 
         /// <summary>
         /// 建库连接字符串
@@ -51,11 +51,11 @@ namespace Admin.Core.Common.Configs
         /// <summary>
         /// 监听所有操作
         /// </summary>
-        public bool MonitorCommand { get; set; }
+        public bool MonitorCommand { get; set; } = false;
 
         /// <summary>
         /// 监听Curd操作
         /// </summary>
-        public bool Curd { get; set; }
+        public bool Curd { get; set; } = false;
     }
 }

+ 4 - 4
Admin.Core.Common/Configs/JwtConfig.cs

@@ -11,21 +11,21 @@ namespace Admin.Core.Common.Configs
         /// <summary>
         /// 发行者
         /// </summary>
-        public string Issuer { get; set; }
+        public string Issuer { get; set; } = "http://127.0.0.1:8888";
 
         /// <summary>
         /// 订阅者
         /// </summary>
-        public string Audience { get; set; }
+        public string Audience { get; set; } = "http://127.0.0.1:8888";
 
         /// <summary>
         /// 密钥
         /// </summary>
-        public string SecurityKey { get; set; }
+        public string SecurityKey { get; set; } = "ertJKl#521*a@790asD&1#";
 
         /// <summary>
         /// 有效期(分钟)
         /// </summary>
-        public int Expires { get; set; }
+        public int Expires { get; set; } = 120;
     }
 }

+ 416 - 0
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
+{
+    /// <summary>
+    /// Html操作相关类
+    /// </summary>
+    [SingleInstance]
+    public class HtmlHelper
+    {
+        #region 私有字段
+        private readonly string _ContentType = "application/x-www-form-urlencoded";
+        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 公有属性
+        /// <summary> 
+        /// Cookie
+        /// </summary> 
+        public CookieContainer CookieContainer { get; } = new CookieContainer();
+
+        /// <summary> 
+        /// 语言
+        /// </summary> 
+        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
+        /// <summary>
+        /// 获取HTML
+        /// </summary>
+        /// <param name="url">地址</param>
+        /// <param name="postData">post 提交的字符串</param>
+        /// <param name="isPost">是否是post</param>
+        /// <param name="cookieContainer">CookieContainer</param>
+        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;
+            }
+        }
+
+        /// <summary>
+        /// 获取HTML
+        /// </summary>
+        /// <param name="url">地址</param>
+        /// <param name="cookieContainer">CookieContainer</param>
+        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 获取字符流
+        /// <summary>
+        /// 获取字符流
+        /// </summary>
+        //---------------------------------------------------------------------------------------------------------------
+        // 示例:
+        // 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);
+        //---------------------------------------------------------------------------------------------------------------
+        /// <param name="url">地址</param>
+        /// <param name="cookieContainer">cookieContainer</param>
+        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标记
+        /// <summary>
+        /// 清除HTML标记
+        /// </summary>
+        /// <param name="Htmlstring"></param>
+        /// <returns>已经去除后的文字</returns>
+        public string NoHTML(string Htmlstring)
+        {
+            //删除脚本   
+            Htmlstring = Regex.Replace(Htmlstring, @"<script[^>]*?>.*?</script>", "", 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, @"<!--.*", "", RegexOptions.IgnoreCase);
+
+            Htmlstring = Regex.Replace(Htmlstring, @"&(quot|#34);", "\"", RegexOptions.IgnoreCase);
+            Htmlstring = Regex.Replace(Htmlstring, @"&(amp|#38);", "&", RegexOptions.IgnoreCase);
+            Htmlstring = Regex.Replace(Htmlstring, @"&(lt|#60);", "<", RegexOptions.IgnoreCase);
+            Htmlstring = Regex.Replace(Htmlstring, @"&(gt|#62);", ">", RegexOptions.IgnoreCase);
+            Htmlstring = Regex.Replace(Htmlstring, @"&(nbsp|#160);", "   ", RegexOptions.IgnoreCase);
+            Htmlstring = Regex.Replace(Htmlstring, @"&(iexcl|#161);", "\xa1", RegexOptions.IgnoreCase);
+            Htmlstring = Regex.Replace(Htmlstring, @"&(cent|#162);", "\xa2", RegexOptions.IgnoreCase);
+            Htmlstring = Regex.Replace(Htmlstring, @"&(pound|#163);", "\xa3", RegexOptions.IgnoreCase);
+            Htmlstring = Regex.Replace(Htmlstring, @"&(copy|#169);", "\xa9", RegexOptions.IgnoreCase);
+            Htmlstring = Regex.Replace(Htmlstring, @"&#(\d+);", "", RegexOptions.IgnoreCase);
+
+            Htmlstring.Replace("<", "");
+            Htmlstring.Replace(">", "");
+            Htmlstring.Replace("\r\n", "");
+
+            return Htmlstring;
+        }
+        #endregion
+
+        #region 删除文本中带的HTML标记
+        /// <summary>
+        /// 删除文本中带的HTML标记
+        /// </summary>
+        /// <param name="InString">输入要删除带HTML的字符串</param>    
+        /// <returns>返回处理过的字符串</returns>
+        public string DelHtmlCode(string InString)
+        {
+            string strTemp = InString;
+            while (strTemp.Contains("<"))
+            {
+                if (!strTemp.Contains(">")) { break; }    //当字符串内不包含">"时退出循环
+                int htmlBeginNum = strTemp.IndexOf("<");
+                int htmlEndNum = strTemp.IndexOf(">");
+                //删除从"<"到">"之间的所有字符串
+                strTemp = strTemp.Remove(htmlBeginNum, htmlEndNum - htmlBeginNum + 1);
+            }
+            strTemp = strTemp.Replace("\n", "");
+            strTemp = strTemp.Replace("\r", "");
+            strTemp = strTemp.Replace("\n\r", "");
+            strTemp = strTemp.Replace("&nbsp;", "");
+            strTemp = strTemp.Replace(" ", "");
+            strTemp = strTemp.Trim();
+            return strTemp;
+        }
+        #endregion
+
+        #region 匹配页面的链接
+        /// <summary>
+        /// 获取页面的链接正则
+        /// </summary>
+        public string GetHref(string HtmlCode)
+        {
+            string MatchVale = "";
+            string Reg = @"(h|H)(r|R)(e|E)(f|F) *= *('|"")?((\w|\\|\/|\.|:|-|_)+)[\S]*";
+            foreach (Match m in Regex.Matches(HtmlCode, Reg))
+            {
+                MatchVale += (m.Value).ToLower().Replace("href=", "").Trim() + "|";
+            }
+            return MatchVale;
+        }
+        #endregion
+
+        #region 匹配页面的图片地址
+        /// <summary>
+        /// 匹配页面的图片地址
+        /// </summary>
+        /// <param name="HtmlCode"></param>
+        /// <param name="imgHttp">要补充的http://路径信息</param>
+        /// <returns></returns>
+        public string GetImgSrc(string HtmlCode, string imgHttp)
+        {
+            string MatchVale = "";
+            string Reg = @"<img.+?>";
+            foreach (Match m in Regex.Matches(HtmlCode.ToLower(), Reg))
+            {
+                MatchVale += GetImg((m.Value).ToLower().Trim(), imgHttp) + "|";
+            }
+
+            return MatchVale;
+        }
+
+        /// <summary>
+        /// 匹配<img src="" />中的图片路径实际链接
+        /// </summary>
+        /// <param name="ImgString"><img src="" />字符串</param>
+        /// <param name="imgHttp"></param>
+        /// <returns></returns>
+        public string GetImg(string ImgString, string imgHttp)
+        {
+            string MatchVale = "";
+            string Reg = @"src=.+\.(bmp|jpg|gif|png|)";
+            foreach (Match m in Regex.Matches(ImgString.ToLower(), Reg))
+            {
+                MatchVale += (m.Value).ToLower().Trim().Replace("src=", "");
+            }
+            if (MatchVale.IndexOf(".net") != -1 || MatchVale.IndexOf(".com") != -1 || MatchVale.IndexOf(".org") != -1 || MatchVale.IndexOf(".cn") != -1 || MatchVale.IndexOf(".cc") != -1 || MatchVale.IndexOf(".info") != -1 || MatchVale.IndexOf(".biz") != -1 || MatchVale.IndexOf(".tv") != -1)
+                return (MatchVale);
+            else
+                return (imgHttp + MatchVale);
+        }
+        #endregion
+
+        #region 抓取远程页面内容
+        /// <summary>
+        /// 以GET方式抓取远程页面内容
+        /// </summary>
+        public string Get_Http(string tUrl)
+        {
+            string strResult;
+            try
+            {
+                HttpWebRequest hwr = (HttpWebRequest)WebRequest.Create(tUrl);
+                hwr.Timeout = 19600;
+                HttpWebResponse hwrs = (HttpWebResponse)hwr.GetResponse();
+                Stream myStream = hwrs.GetResponseStream();
+                StreamReader sr = new StreamReader(myStream, Encoding.Default);
+                StringBuilder sb = new StringBuilder();
+                while (-1 != sr.Peek())
+                {
+                    sb.Append(sr.ReadLine() + "\r\n");
+                }
+                strResult = sb.ToString();
+                hwrs.Close();
+            }
+            catch (Exception ee)
+            {
+                strResult = ee.Message;
+            }
+            return strResult;
+        }
+
+        /// <summary>
+        /// 以POST方式抓取远程页面内容
+        /// </summary>
+        /// <param name="url"></param>
+        /// <param name="postData">参数列表</param>
+        /// <param name="encodeType"></param>
+        /// <returns></returns>
+        public string Post_Http(string url, string postData, string encodeType)
+        {
+            string strResult;
+            try
+            {
+                Encoding encoding = Encoding.GetEncoding(encodeType);
+                byte[] POST = encoding.GetBytes(postData);
+                HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(url);
+                myRequest.Method = "POST";
+                myRequest.ContentType = "application/x-www-form-urlencoded";
+                myRequest.ContentLength = POST.Length;
+                Stream newStream = myRequest.GetRequestStream();
+                newStream.Write(POST, 0, POST.Length); //设置POST
+                newStream.Close();
+                HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
+                StreamReader reader = new StreamReader(myResponse.GetResponseStream(), Encoding.Default);
+                strResult = reader.ReadToEnd();
+            }
+            catch (Exception ex)
+            {
+                strResult = ex.Message;
+            }
+            return strResult;
+        }
+        #endregion
+
+        #region 压缩HTML输出
+        /// <summary>
+        /// 压缩HTML输出
+        /// </summary>
+        public string ZipHtml(string Html)
+        {
+            Html = Regex.Replace(Html, @">\s+?<", "><");//去除HTML中的空白字符
+            Html = Regex.Replace(Html, @"\r\n\s*", "");
+            Html = Regex.Replace(Html, @"<body([\s|\S]*?)>([\s|\S]*?)</body>", @"<body$1>$2</body>", RegexOptions.IgnoreCase);
+            return Html;
+        }
+        #endregion
+
+        #region 过滤指定HTML标签
+        /// <summary>
+        /// 过滤指定HTML标签
+        /// </summary>
+        /// <param name="s_TextStr">要过滤的字符</param>
+        /// <param name="html_Str">a img p div</param>
+        public string DelHtml(string s_TextStr, string html_Str)
+        {
+            string rStr = "";
+            if (!string.IsNullOrEmpty(s_TextStr))
+            {
+                rStr = Regex.Replace(s_TextStr, "<" + html_Str + "[^>]*>", "", RegexOptions.IgnoreCase);
+                rStr = Regex.Replace(rStr, "</" + html_Str + ">", "", RegexOptions.IgnoreCase);
+            }
+            return rStr;
+        }
+        #endregion
+    }
+}

+ 5 - 0
Admin.Core.Common/Input/PageInput.cs

@@ -19,5 +19,10 @@
         /// 查询条件
         /// </summary>
         public T Filter { get; set; }
+
+        /// <summary>
+        /// 高级查询条件
+        /// </summary>
+        public FreeSql.Internal.Model.DynamicFilterInfo DynamicFilter { get; set; } = null;
     }
 }

+ 1 - 1
Admin.Core.Model/Admin.Core.Model.csproj

@@ -3,7 +3,7 @@
   <PropertyGroup>
     <TargetFramework>netcoreapp3.1</TargetFramework>
     <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
-    <Version>1.2.0</Version>
+    <Version>1.3.0</Version>
     <Authors>xiaoxue</Authors>
     <Company>xiaoxue</Company>
     <Description>中台Admin后端实体库</Description>

+ 1 - 1
Admin.Core.Model/Admin/ViewEntity.cs

@@ -8,7 +8,7 @@ namespace Admin.Core.Model.Admin
     /// 视图管理
     /// </summary>
 	[Table(Name = "ad_view")]
-    [Index("uk_view_path", nameof(Path), true)]
+    [Index("uk_view_parentid_label", nameof(ParentId) + "," + nameof(Label), true)]
     public class ViewEntity : EntityBase
     {
         /// <summary>

+ 1 - 1
Admin.Core.Repository/Admin.Core.Repository.csproj

@@ -2,7 +2,7 @@
 
   <PropertyGroup>
     <TargetFramework>netcoreapp3.1</TargetFramework>
-    <Version>1.2.0</Version>
+    <Version>1.3.0</Version>
     <Authors>xiaoxue</Authors>
     <Company>xiaoxue</Company>
     <Description>中台Admin后端仓储库</Description>

+ 10 - 2
Admin.Core.Repository/Base/RepositoryBase.cs

@@ -35,7 +35,11 @@ namespace Admin.Core.Repository
         public async Task<bool> SoftDeleteAsync(TKey id)
         {
             await UpdateDiy
-                .SetDto(new { IsDeleted = true, ModifiedUserId = _user.Id, ModifiedUserName = _user.Name })
+                .SetDto(new { 
+                    IsDeleted = true, 
+                    ModifiedUserId = _user.Id, 
+                    ModifiedUserName = _user.Name 
+                })
                 .WhereDynamic(id)
                 .ExecuteAffrowsAsync();
             return true;
@@ -44,7 +48,11 @@ namespace Admin.Core.Repository
         public async Task<bool> SoftDeleteAsync(TKey[] ids)
         {
             await UpdateDiy
-                .SetDto(new { IsDeleted = true, ModifiedUserId = _user.Id, ModifiedUserName = _user.Name })
+                .SetDto(new { 
+                    IsDeleted = true, 
+                    ModifiedUserId = _user.Id, 
+                    ModifiedUserName = _user.Name 
+                })
                 .WhereDynamic(ids)
                 .ExecuteAffrowsAsync();
             return true;

+ 1 - 1
Admin.Core.Services/Admin.Core.Service.csproj

@@ -3,7 +3,7 @@
   <PropertyGroup>
     <TargetFramework>netcoreapp3.1</TargetFramework>
     <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
-    <Version>1.2.0</Version>
+    <Version>1.3.0</Version>
     <Authors>xiaoxue</Authors>
     <Company>xiaoxue</Company>
     <Description>中台Admin后端服务库</Description>

+ 3 - 3
Admin.Core.Services/Admin/Permission/PermissionService.cs

@@ -59,16 +59,16 @@ namespace Admin.Core.Service.Admin.Permission
             return ResponseOutput.Ok(result);
         }
 
-        public async Task<IResponseOutput> ListAsync(string key,DateTime? start,DateTime? end)
+        public async Task<IResponseOutput> ListAsync(string key, DateTime? start, DateTime? end)
         {
             if (end.HasValue)
             {
                 end = end.Value.AddDays(1);
             }
-            
+
             var data = await _permissionRepository
                 .WhereIf(key.NotNull(), a => a.Path.Contains(key) || a.Label.Contains(key))
-                .WhereIf(start.HasValue && end.HasValue,a=>a.CreatedTime.Value.BetweenEnd(start.Value,end.Value))
+                .WhereIf(start.HasValue && end.HasValue, a => a.CreatedTime.Value.BetweenEnd(start.Value, end.Value))
                 .OrderBy(a => a.ParentId)
                 .OrderBy(a => a.Sort)
                 .ToListAsync(a => new PermissionListOutput { ApiPath = a.Api.Path });

+ 1 - 0
Admin.Core.Services/Admin/User/UserService.cs

@@ -96,6 +96,7 @@ namespace Admin.Core.FrameWork.Service.User
 
             var list = await _userRepository.Select
             .WhereIf(key.NotNull(), a => a.Status >= 0 && (a.UserName.Contains(key) || a.NickName.Contains(key)))
+            .WhereDynamicFilter(input.DynamicFilter)
             .Count(out var total)
             .OrderByDescending(true, a => a.Id)
             .IncludeMany(a => a.Roles.Select(b => new RoleEntity{ Name = b.Name }))

+ 120 - 4
Admin.Core/Admin.Core.Common.xml

@@ -229,6 +229,16 @@
             缓存类型
             </summary>
         </member>
+        <member name="F:Admin.Core.Common.Cache.CacheType.Memory">
+            <summary>
+            内存缓存
+            </summary>
+        </member>
+        <member name="F:Admin.Core.Common.Cache.CacheType.Redis">
+            <summary>
+            Redis缓存
+            </summary>
+        </member>
         <member name="T:Admin.Core.Common.Cache.ICache">
             <summary>
             缓存接口
@@ -345,14 +355,14 @@
             应用配置
             </summary>
         </member>
-        <member name="P:Admin.Core.Common.Configs.AppConfig.Swagger">
+        <member name="P:Admin.Core.Common.Configs.AppConfig.Urls">
             <summary>
-            Swagger文档
+            Api地址,默认 http://*:8888
             </summary>
         </member>
-        <member name="P:Admin.Core.Common.Configs.AppConfig.Urls">
+        <member name="P:Admin.Core.Common.Configs.AppConfig.Swagger">
             <summary>
-            Api地址,默认 http://*:8888
+            Swagger文档
             </summary>
         </member>
         <member name="P:Admin.Core.Common.Configs.AppConfig.Aop">
@@ -415,6 +425,11 @@
             Redis配置
             </summary>
         </member>
+        <member name="T:Admin.Core.Common.Configs.RedisConfig">
+            <summary>
+            Redis配置
+            </summary>
+        </member>
         <member name="P:Admin.Core.Common.Configs.RedisConfig.ConnectionString">
             <summary>
             连接字符串
@@ -855,6 +870,102 @@
             <param name="encode">编码格式</param>
             <returns></returns>
         </member>
+        <member name="T:Admin.Core.Common.Helpers.HtmlHelper">
+            <summary>
+            Html操作相关类
+            </summary>
+        </member>
+        <member name="P:Admin.Core.Common.Helpers.HtmlHelper.CookieContainer">
+            <summary> 
+            Cookie
+            </summary> 
+        </member>
+        <member name="P:Admin.Core.Common.Helpers.HtmlHelper.Encoding">
+            <summary> 
+            语言
+            </summary> 
+        </member>
+        <member name="M:Admin.Core.Common.Helpers.HtmlHelper.GetHtml(System.String,System.String,System.Boolean,System.Net.CookieContainer)">
+            <summary>
+            获取HTML
+            </summary>
+            <param name="url">地址</param>
+            <param name="postData">post 提交的字符串</param>
+            <param name="isPost">是否是post</param>
+            <param name="cookieContainer">CookieContainer</param>
+        </member>
+        <member name="M:Admin.Core.Common.Helpers.HtmlHelper.GetHtml(System.String,System.Net.CookieContainer)">
+            <summary>
+            获取HTML
+            </summary>
+            <param name="url">地址</param>
+            <param name="cookieContainer">CookieContainer</param>
+        </member>
+        <member name="M:Admin.Core.Common.Helpers.HtmlHelper.GetStream(System.String,System.Net.CookieContainer)">
+            <param name="url">地址</param>
+            <param name="cookieContainer">cookieContainer</param>
+        </member>
+        <member name="M:Admin.Core.Common.Helpers.HtmlHelper.NoHTML(System.String)">
+            <summary>
+            清除HTML标记
+            </summary>
+            <param name="Htmlstring"></param>
+            <returns>已经去除后的文字</returns>
+        </member>
+        <member name="M:Admin.Core.Common.Helpers.HtmlHelper.DelHtmlCode(System.String)">
+            <summary>
+            删除文本中带的HTML标记
+            </summary>
+            <param name="InString">输入要删除带HTML的字符串</param>    
+            <returns>返回处理过的字符串</returns>
+        </member>
+        <member name="M:Admin.Core.Common.Helpers.HtmlHelper.GetHref(System.String)">
+            <summary>
+            获取页面的链接正则
+            </summary>
+        </member>
+        <member name="M:Admin.Core.Common.Helpers.HtmlHelper.GetImgSrc(System.String,System.String)">
+            <summary>
+            匹配页面的图片地址
+            </summary>
+            <param name="HtmlCode"></param>
+            <param name="imgHttp">要补充的http://路径信息</param>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.Core.Common.Helpers.HtmlHelper.GetImg(System.String,System.String)">
+            <summary>
+            匹配<img src="" />中的图片路径实际链接
+            </summary>
+            <param name="ImgString"><img src="" />字符串</param>
+            <param name="imgHttp"></param>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.Core.Common.Helpers.HtmlHelper.Get_Http(System.String)">
+            <summary>
+            以GET方式抓取远程页面内容
+            </summary>
+        </member>
+        <member name="M:Admin.Core.Common.Helpers.HtmlHelper.Post_Http(System.String,System.String,System.String)">
+            <summary>
+            以POST方式抓取远程页面内容
+            </summary>
+            <param name="url"></param>
+            <param name="postData">参数列表</param>
+            <param name="encodeType"></param>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.Core.Common.Helpers.HtmlHelper.ZipHtml(System.String)">
+            <summary>
+            压缩HTML输出
+            </summary>
+        </member>
+        <member name="M:Admin.Core.Common.Helpers.HtmlHelper.DelHtml(System.String,System.String)">
+            <summary>
+            过滤指定HTML标签
+            </summary>
+            <param name="s_TextStr">要过滤的字符</param>
+            <param name="html_Str">a img p div</param>
+        </member>
         <member name="M:Admin.Core.Common.Helpers.IPHelper.IsIP(System.String)">
             <summary>
             是否为ip
@@ -1000,6 +1111,11 @@
             查询条件
             </summary>
         </member>
+        <member name="P:Admin.Core.Common.Input.PageInput`1.DynamicFilter">
+            <summary>
+            高级查询条件
+            </summary>
+        </member>
         <member name="T:Admin.Core.Common.Output.IResponseOutput">
             <summary>
             响应数据输出接口

+ 3 - 3
Admin.Core/Admin.Core.csproj

@@ -5,7 +5,7 @@
     <!--<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>-->
     <AspNetCoreHostingModel>OutOfProcess</AspNetCoreHostingModel>
     <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
-    <Version>1.2.0</Version>
+    <Version>1.3.0</Version>
     <PackageLicenseExpression>MIT</PackageLicenseExpression>
     <Authors>xiaoxue</Authors>
     <Company>xiaoxue</Company>
@@ -43,8 +43,8 @@
     <PackageReference Include="Autofac.Extensions.DependencyInjection" Version="6.0.0" />
     <PackageReference Include="Autofac.Extras.DynamicProxy" Version="5.0.0" />
     <PackageReference Include="FluentValidation.AspNetCore" Version="8.6.2" />
-    <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.3" />
-    <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.3" />
+    <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.4" />
+    <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.4" />
     <PackageReference Include="Microsoft.Extensions.PlatformAbstractions" Version="1.1.0" />
     <PackageReference Include="Swashbuckle.AspNetCore" Version="5.4.1" />
 

+ 1 - 1
Admin.Core/Aop/AopHelper.cs

@@ -19,7 +19,7 @@ namespace Admin.Core.Aop
             catch (Exception ex)
             {
                 exceptionAction?.Invoke(ex);
-                throw;
+                return default;
             }
             finally
             {

+ 33 - 80
Admin.Core/Aop/TransactionInterceptor.cs

@@ -1,4 +1,4 @@
-using System;
+using System.Reflection;
 using System.Threading.Tasks;
 using Castle.DynamicProxy;
 using FreeSql;
@@ -6,6 +6,7 @@ using Admin.Core.Common.Extensions;
 using Admin.Core.Common.Output;
 using Admin.Core.Common.Attributes;
 
+
 namespace Admin.Core.Aop
 {
     public class TransactionInterceptor : IInterceptor
@@ -18,97 +19,49 @@ namespace Admin.Core.Aop
             _unitOfWorkManager = unitOfWorkManager;
         }
 
-        public async void Intercept(IInvocation invocation)
+        public void Intercept(IInvocation invocation)
         {
             var method = invocation.MethodInvocationTarget ?? invocation.Method;
-            
             if (method.HasAttribute<TransactionAttribute>())
             {
-                try
-                {
-                    var transaction = method.GetAttribute<TransactionAttribute>();
-                    _unitOfWork = _unitOfWorkManager.Begin(transaction.Propagation, transaction.IsolationLevel);
-                    invocation.Proceed();
+                InterceptTransaction(invocation, method);
+            }
+            else
+            {
+                invocation.Proceed();
+            }
+        }
 
-                    if (method.IsAsync())
-                    {
-                        if (invocation.Method.ReturnType == typeof(Task))
-                        {
-                            try
-                            {
-                                await (Task)invocation.ReturnValue;
-                                _unitOfWork.Commit();
-                            }
-                            catch (Exception ex)
-                            {
-                                _unitOfWork.Rollback();
-                                throw ex;
-                            }
-                            finally
-                            {
-                                _unitOfWork.Dispose();
-                            }
-                        }
-                        else
-                        {
-                            AopHelper.CallGenericMethod(
-                            invocation,
-                            res => 
-                            {
-                                if (res == null)
-                                {
-                                    return;
-                                }
+        private async void InterceptTransaction(IInvocation invocation, MethodInfo method)
+        {
+            try
+            {
+                var transaction = method.GetAttribute<TransactionAttribute>();
+                _unitOfWork = _unitOfWorkManager.Begin(transaction.Propagation, transaction.IsolationLevel);
+                invocation.Proceed();
 
-                                var responseOutput = res as IResponseOutput;
-                                if (responseOutput != null && !responseOutput.Success)
-                                {
-                                    _unitOfWork.Rollback();
-                                }
-                                else
-                                {
-                                    _unitOfWork.Commit();
-                                }
-                            },
-                            ex =>
-                            {
-                                _unitOfWork.Rollback();
-                            },
-                            ()=>
-                            {
-                                _unitOfWork.Dispose();
-                            });
-                        }
-                    }
-                    else
-                    {
-                        if (invocation.Method.ReturnType != typeof(void))
-                        {
-                            var responseOutput = invocation.ReturnValue as Task<IResponseOutput>;
-                            if (responseOutput != null && !responseOutput.Result.Success)
-                            {
-                                _unitOfWork.Rollback();
-                            }
-                            else
-                            {
-                                _unitOfWork.Commit();
-                            }
-                        }
-                        else
-                        {
-                            _unitOfWork.Commit();
-                        }
-                    }
+                dynamic returnValue = invocation.ReturnValue;
+                if (returnValue is Task)
+                {
+                    returnValue = await returnValue;
                 }
-                catch (Exception ex)
+
+                if (returnValue is IResponseOutput res && !res.Success)
                 {
                     _unitOfWork.Rollback();
-                    throw ex;
+                }
+                else
+                {
+                    _unitOfWork.Commit();
                 }
             }
-            else
+            catch
             {
-                invocation.Proceed();
+                _unitOfWork.Rollback();
+            }
+            finally
+            {
+                _unitOfWork.Dispose();
             }
         }
     }

+ 2 - 1
Admin.Core/Attributes/VersionRouteAttribute.cs

@@ -13,7 +13,8 @@ namespace Admin.Core.Attributes
     {
         public string GroupName { get; set; }
 
-        public VersionRouteAttribute(ApiVersion version, string actionName = "") : base($"/api/{version.ToString()}/[area]/[controller]/{actionName}")
+        public VersionRouteAttribute(ApiVersion version = ApiVersion.V2, string action = "[action]")
+            : base($"/api/{version}/[area]/[controller]/{action}")
         {
             GroupName = version.ToString();
         }

+ 2 - 0
Admin.Core/Auth/PermissionHandler.cs

@@ -1,5 +1,6 @@
 using System.Linq;
 using System.Threading.Tasks;
+using Admin.Core.Common.Attributes;
 using Admin.Core.Service.Admin.User;
 
 namespace Admin.Core.Auth
@@ -7,6 +8,7 @@ namespace Admin.Core.Auth
     /// <summary>
     /// 权限处理
     /// </summary>
+   [SingleInstance]
     public class PermissionHandler : IPermissionHandler
     {
         private readonly IUserService _userService;

+ 0 - 1
Admin.Core/Db/DbHelper.cs

@@ -10,7 +10,6 @@ using FreeSql.DataAnnotations;
 using Admin.Core.Common.Configs;
 using Admin.Core.Common.Helpers;
 using Admin.Core.Model.Admin;
-using System.Reflection;
 
 namespace Admin.Core.Db
 {

+ 3 - 3
Admin.Core/Db/ServiceCollectionExtensions.cs

@@ -87,11 +87,11 @@ namespace Admin.Core.Db
             #region 审计数据
             //计算服务器时间
             //var serverTime = fsql.Select<T>().Limit(1).First(a => DateTime.local);
-            //var timeOffset = DateTime.UtcNow.Subtract(serverTime); 
+            //var timeOffset = DateTime.UtcNow.Subtract(serverTime);
+            var user = services.BuildServiceProvider().GetService<IUser>();
             fsql.Aop.AuditValue += (s, e) =>
             {
-                var user = services.BuildServiceProvider().GetService<IUser>();
-                if(user == null || !(user.Id > 0))
+                if (user == null || user.Id <= 0)
                 {
                     return;
                 }

+ 2 - 2
Admin.Core/Filters/LogActionFilter.cs

@@ -10,9 +10,9 @@ namespace Admin.Core.Filters
     {
         private readonly ILogHandler _logHandler;
 
-        public LogActionFilter(ILogHandler opratoinLogHandler)
+        public LogActionFilter(ILogHandler logHandler)
         {
-            _logHandler = opratoinLogHandler;
+            _logHandler = logHandler;
         }
 
         public Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)

+ 0 - 1
Admin.Core/Logs/LogHandler.cs

@@ -32,7 +32,6 @@ namespace Admin.Core.Logs
             sw.Start();
 
             dynamic actionResult = (await next()).Result;
-
             sw.Stop();
 
             //操作参数

+ 48 - 27
Admin.Core/Startup.cs

@@ -23,7 +23,6 @@ using AutoMapper;
 //using FluentValidation.AspNetCore;
 using Admin.Core.Common.Helpers;
 using Admin.Core.Common.Configs;
-using Admin.Core.Common.Auth;
 using Admin.Core.Auth;
 using Admin.Core.Enums;
 using Admin.Core.Filters;
@@ -31,26 +30,33 @@ using Admin.Core.Db;
 using Admin.Core.Common.Cache;
 using Admin.Core.Aop;
 using Admin.Core.Logs;
-using PermissionHandler = Admin.Core.Auth.PermissionHandler;
 using Admin.Core.Extensions;
 using Admin.Core.Common.Attributes;
+using Admin.Core.Common.Auth;
+
 
 namespace Admin.Core
 {
     public class Startup
     {
-        private readonly IHostEnvironment _env;
         private static string basePath => AppContext.BaseDirectory;
+        private readonly IHostEnvironment _env;
+        private readonly ConfigHelper _configHelper;
         private readonly AppConfig _appConfig;
 
         public Startup(IWebHostEnvironment env)
         {
             _env = env;
-            _appConfig = new ConfigHelper().Get<AppConfig>("appconfig", env.EnvironmentName) ?? new AppConfig();
+            _configHelper = new ConfigHelper();
+            _appConfig = _configHelper.Get<AppConfig>("appconfig", env.EnvironmentName) ?? new AppConfig();
         }
 
         public void ConfigureServices(IServiceCollection services)
         {
+            //用户信息
+            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
+            services.TryAddSingleton<IUser, User>();
+
             //数据库
             services.AddDb(_env, _appConfig);
 
@@ -58,7 +64,7 @@ namespace Admin.Core
             services.AddSingleton(_appConfig);
 
             //上传配置
-            var uploadConfig = new ConfigHelper().Load("uploadconfig", _env.EnvironmentName, true);
+            var uploadConfig = _configHelper.Load("uploadconfig", _env.EnvironmentName, true);
             services.Configure<UploadConfig>(uploadConfig);
 
             #region AutoMapper 自动映射
@@ -76,6 +82,18 @@ namespace Admin.Core
                     .AllowAnyHeader()
                     .AllowAnyMethod();
                 });
+
+                /*
+                //浏览器会发起2次请求,使用OPTIONS发起预检请求,第二次才是api异步请求
+                c.AddPolicy("All", policy =>
+                {
+                    policy
+                    .AllowAnyOrigin()
+                    .SetPreflightMaxAge(new TimeSpan(0, 10, 0))
+                    .AllowAnyHeader()
+                    .AllowAnyMethod();
+                });
+                */
             });
             #endregion
 
@@ -139,13 +157,8 @@ namespace Admin.Core
             #endregion
 
             #region Jwt身份认证
-            var jwtConfig = new ConfigHelper().Get<JwtConfig>("jwtconfig", _env.EnvironmentName);
+            var jwtConfig = _configHelper.Get<JwtConfig>("jwtconfig", _env.EnvironmentName);
             services.TryAddSingleton(jwtConfig);
-            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
-            services.TryAddSingleton<IUser, User>();
-            services.TryAddSingleton<IUserToken, UserToken>();
-            services.AddScoped<IPermissionHandler, PermissionHandler>();
-
             services.AddAuthentication(options =>
             {
                 options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
@@ -181,6 +194,8 @@ namespace Admin.Core
                 {
                     options.Filters.Add<LogActionFilter>();
                 }
+                //禁止去除ActionAsync后缀
+                options.SuppressAsyncSuffixInActionNames = false;
             })
             //.AddFluentValidation(config =>
             //{
@@ -199,7 +214,7 @@ namespace Admin.Core
             #endregion
 
             #region 缓存
-            var cacheConfig = new ConfigHelper().Get<CacheConfig>("cacheconfig", _env.EnvironmentName);
+            var cacheConfig = _configHelper.Get<CacheConfig>("cacheconfig", _env.EnvironmentName);
             if (cacheConfig.Type == CacheType.Redis)
             {
                 var csredis = new CSRedis.CSRedisClient(cacheConfig.Redis.ConnectionString);
@@ -222,6 +237,20 @@ namespace Admin.Core
             #region AutoFac IOC容器
             try
             {
+                #region SingleInstance
+                //无接口注入单例
+                var assemblyCore = Assembly.Load("Admin.Core");
+                var assemblyCommon = Assembly.Load("Admin.Core.Common");
+                builder.RegisterAssemblyTypes(assemblyCore, assemblyCommon)
+                .Where(t => t.GetCustomAttribute<SingleInstanceAttribute>() != null)
+                .SingleInstance();
+                //有接口注入单例
+                builder.RegisterAssemblyTypes(assemblyCore, assemblyCommon)
+                .Where(t => t.GetCustomAttribute<SingleInstanceAttribute>() != null)
+                .AsImplementedInterfaces()
+                .SingleInstance();
+                #endregion
+
                 #region Aop
                 var interceptorServiceTypes = new List<Type>();
                 if (_appConfig.Aop.Transaction)
@@ -231,15 +260,6 @@ namespace Admin.Core
                 }
                 #endregion
 
-                #region Service
-                var assemblyServices = Assembly.Load("Admin.Core.Service");
-                builder.RegisterAssemblyTypes(assemblyServices)
-                .AsImplementedInterfaces()
-                .InstancePerDependency()
-                .EnableInterfaceInterceptors()
-                .InterceptedBy(interceptorServiceTypes.ToArray());
-                #endregion
-
                 #region Repository
                 var assemblyRepository = Assembly.Load("Admin.Core.Repository");
                 builder.RegisterAssemblyTypes(assemblyRepository)
@@ -247,12 +267,13 @@ namespace Admin.Core
                 .InstancePerDependency();
                 #endregion
 
-                #region SingleInstance
-                var assemblyCore = Assembly.Load("Admin.Core");
-                var assemblyCommon = Assembly.Load("Admin.Core.Common");
-                builder.RegisterAssemblyTypes(assemblyCore, assemblyCommon)
-                .Where(t => t.GetCustomAttribute<SingleInstanceAttribute>() != null)
-                .SingleInstance(); 
+                #region Service
+                var assemblyServices = Assembly.Load("Admin.Core.Service");
+                builder.RegisterAssemblyTypes(assemblyServices)
+                .AsImplementedInterfaces()
+                .InstancePerDependency()
+                .EnableInterfaceInterceptors()
+                .InterceptedBy(interceptorServiceTypes.ToArray());
                 #endregion
             }
             catch (Exception ex)

+ 3 - 2
Admin.Core/configs/dbconfig.json

@@ -18,11 +18,12 @@
   //建库连接字符串
   //MySql "Server=localhost; Port=3306; Database=mysql; Uid=root; Pwd=pwd; Charset=utf8mb4;"
   //SqlServer "Data Source=.;Integrated Security=True;Initial Catalog=master;Pooling=true;Min Pool Size=1"
-  //PostgreSQL "CREATE DATABASE \"admindb\" WITH ENCODING = 'UTF8'"
+  //PostgreSQL "Host=localhost;Port=5432;Username=postgres;Password=; Database=postgres;Pooling=true;Minimum Pool Size=1",
   "createDbConnectionString": "Server=localhost; Port=3306; Database=mysql; Uid=root; Pwd=pwd; Charset=utf8mb4;",
   //建库脚本
   //MySql "CREATE DATABASE `admindb` CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_general_ci'"
   //SqlServer "CREATE DATABASE [admindb]"
+  //PostgreSQL "CREATE DATABASE \"admindb\" WITH ENCODING = 'UTF8'"
   "createDbSql": "CREATE DATABASE `admindb` CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_general_ci'",
 
   //数据库配置 https://github.com/dotnetcore/FreeSql/wiki/入门
@@ -31,7 +32,7 @@
   //连接字符串
   //MySql "Server=localhost; Port=3306; Database=admindb; Uid=root; Pwd=pwd; Charset=utf8mb4;"
   //SqlServer "Data Source=.;Integrated Security=True;Initial Catalog=admindb;Pooling=true;Min Pool Size=1"
-  //Sqlite "Data Source=|DataDirectory|\\admindb.db; Pooling=true;Min Pool Size=1"
   //PostgreSQL "Host=localhost;Port=5432;Username=postgres;Password=; Database=admindb;Pooling=true;Minimum Pool Size=1"
+  //Sqlite "Data Source=|DataDirectory|\\admindb.db; Pooling=true;Min Pool Size=1"
   "connectionString": "Data Source=|DataDirectory|\\admindb.db; Pooling=true;Min Pool Size=1"
 }

+ 2 - 2
Admin.Core/configs/jwtconfig.json

@@ -1,8 +1,8 @@
 {
   //发行者
-  "issuer": "https://www.admin.zhontai.com",
+  "issuer": "http://127.0.0.1:8888",
   //订阅者
-  "audience": "https://www.admin.zhontai.com",
+  "audience": "http://127.0.0.1:8888",
   //密钥
   "securityKey": "ertJKl#521*a@790asD&1#",
   //有效期(分钟)