瀏覽代碼

从最新API项目迁移与升级

shenzhoukai@aliyun.com 2 周之前
父節點
當前提交
7527f3542d

+ 4 - 2
Alchemy.Core.csproj

@@ -8,10 +8,12 @@
 
   <ItemGroup>
     <PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.3.0" />
-    <PackageReference Include="Microsoft.IdentityModel.Tokens" Version="8.7.0" />
+    <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="9.0.6" />
+    <PackageReference Include="Microsoft.IdentityModel.Tokens" Version="8.12.0" />
+    <PackageReference Include="NCalcSync" Version="5.4.2" />
     <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
     <PackageReference Include="RestSharp" Version="112.1.0" />
-    <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.7.0" />
+    <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.12.0" />
   </ItemGroup>
 
 </Project>

+ 19 - 9
Extensions/HttpContextExtension.cs

@@ -13,10 +13,7 @@ namespace Alchemy.Core.Extensions
         /// <returns></returns>
         public static string GetReferer(this HttpContext context)
         {
-            if (context.Request.Headers.ContainsKey("Referer"))
-                return context.Request.Headers["Referer"].ToString();
-            else
-                return string.Empty;
+            return context.GetHeaderValue("Referer");
         }
         /// <summary>
         /// 判断是否本地请求
@@ -61,16 +58,29 @@ namespace Alchemy.Core.Extensions
         /// <returns></returns>
         public static string GetAuthorization(this HttpContext context)
         {
-            return context.Request.Headers["Authorization"].ToString();
+            return context.GetHeaderValue("Authorization");
         }
         /// <summary>
-        /// 判断是否包含Authorization
+        /// 获取X-User-Token
         /// </summary>
         /// <param name="context"></param>
         /// <returns></returns>
-        public static bool ContainsAuthorization(this HttpContext context)
+        public static string GetXUserToken(this HttpContext context)
         {
-            return context.Request.Headers.ContainsKey("Authorization");
+            return context.GetHeaderValue("X-USER-TOKEN");
+        }
+        /// <summary>
+        /// 获取请求头的参数
+        /// </summary>
+        /// <param name="context"></param>
+        /// <param name="strKey"></param>
+        /// <returns></returns>
+        public static string GetHeaderValue(this HttpContext context, string strKey)
+        {
+            if (context.Request.Headers.ContainsKey(strKey))
+                return context.Request.Headers[strKey].ToString();
+            else
+                return string.Empty;
         }
         /// <summary>
         /// 获取UA
@@ -79,7 +89,7 @@ namespace Alchemy.Core.Extensions
         /// <returns></returns>
         public static string GetUserAgent(this HttpContext context)
         {
-            return context.Request.Headers["User-Agent"].ToString();
+            return context.GetHeaderValue("User-Agent");
         }
         /// <summary>
         /// 获取请求者IP

+ 9 - 0
Extensions/LongExtension.cs

@@ -2,6 +2,15 @@
 {
     public static class LongExtension
     {
+        /// <summary>
+        /// MB转Byte
+        /// </summary>
+        /// <param name="value"></param>
+        /// <returns></returns>
+        public static long MbToByte(this long value)
+        {
+            return value * (long)1024 * (long)1024;
+        }
         /// <summary>
         /// 时间戳转DateTime
         /// </summary>

+ 136 - 0
Extensions/NCalcExtensions.cs

@@ -0,0 +1,136 @@
+using NCalc;
+using System.Text.RegularExpressions;
+
+namespace Alchemy.Core.Extensions
+{
+    public static class NCalcExtensions
+    {
+        /// <summary>
+        /// 注册自定义函数
+        /// </summary>
+        /// <param name="expression"></param>
+        /// <exception cref="ArgumentException"></exception>
+        public static void AddExtraFunction(this Expression expression)
+        {
+            expression.EvaluateFunction += (name, args) =>
+            {
+                object paramX = args.Parameters[0].Evaluate();
+                double doubleParamX = paramX.ToString().ToDouble();
+                object paramY = null;
+                double doubleParamY = 0;
+                if (args.Parameters.Count() > 1)
+                {
+                    paramY = args.Parameters[1].Evaluate();
+                    doubleParamY = paramY.ToString().ToDouble();
+                }
+                switch (name.ToLower())
+                {
+                    // 阶乘函数
+                    case "fact":
+                        int number = paramX.ToString().ToInt();
+                        args.Result = CalculateFactorial(number);
+                        break;
+                    // 反三角函数(返回弧度)
+                    case "sin":
+                        args.Result = Math.Sin(paramX.ToString().ToDouble());
+                        break;
+                    case "cos":
+                        args.Result = Math.Cos(paramX.ToString().ToDouble());
+                        break;
+                    case "tan":
+                        args.Result = Math.Tan(paramX.ToString().ToDouble());
+                        break;
+                    // 反三角函数(返回弧度)
+                    case "arcsin":
+                    case "asin":
+                        if (doubleParamX < -1 || doubleParamX > 1)
+                            throw new ArgumentException("反正弦 x∈[-1,1]");
+                        args.Result = Math.Asin(paramX.ToString().ToDouble());
+                        break;
+                    case "arccos":
+                    case "acos":
+                        if (doubleParamX < -1 || doubleParamX > 1)
+                            throw new ArgumentException("反余弦 x∈[-1,1]");
+                        args.Result = Math.Acos(paramX.ToString().ToDouble());
+                        break;
+                    case "arctan":
+                    case "atan":
+                        args.Result = Math.Atan(paramX.ToString().ToDouble());
+                        break;
+                    // 角度/弧度转换函数
+                    case "rad": // 角度转弧度
+                        args.Result = paramX.ToString().ToDouble() * Math.PI / 180;
+                        break;
+                    //case "deg": // 弧度转角度
+                    //    args.Result = Convert.ToDouble(param) * 180 / Math.PI;
+                    //    break;
+                    // 平方根函数
+                    case "sqrt":
+                        if (doubleParamX < 0)
+                            throw new ArgumentException("平方根 x∈[0,+∞)");
+                        args.Result = Math.Sqrt(doubleParamX);
+                        break;
+                    // 次幂函数
+                    case "pow":
+                        args.Result = Math.Pow(doubleParamX, doubleParamY);
+                        break;
+                }
+            };
+        }
+        /// <summary>
+        /// 注册常量
+        /// </summary>
+        /// <param name="expression"></param>
+        public static void AddExtraConst(this Expression expression)
+        {
+            expression.Parameters["e"] = Math.E;    // 自然常数 e
+            expression.Parameters["pi"] = Math.PI;  // 圆周率 π
+        }
+        public static object Evaluate(this string strFormula, string strAngleMode)
+        {
+            strFormula = Regex.Replace(
+                strFormula,
+                @"(\d+)\!",
+                "fact($1)");
+            strFormula = Regex.Replace(
+                strFormula,
+                @"([^\(\)^]+)\^([^\(\)^]+)",
+                "pow($1,$2)");
+            if (strAngleMode.Equals("deg"))
+            {
+                strFormula = Regex.Replace(
+                    strFormula,
+                    @"(?<!a)r?(sin|cos|tan)(?![a-z])\(([^)]+)\)",
+                    "$1(rad($2))");
+            }
+            strFormula = strFormula.Replace(
+                "×",
+                "*"
+            ).Replace(
+                "x",
+                "*"
+            ).Replace(
+                "√",
+                "sqrt"
+            ).Replace(
+                "π",
+                "pi"
+            ).Replace(
+                "%",
+                "*0.01"
+            );
+            Expression expression = new Expression(strFormula);
+            expression.AddExtraFunction();
+            expression.AddExtraConst();
+            string strEvalResult = expression.Evaluate().ToString();
+            double doubleResult = strEvalResult.ToDouble();
+            double roundedResult = Math.Round(doubleResult, 6);
+            return roundedResult;
+        }
+        private static int CalculateFactorial(int number)
+        {
+            if (number <= 1) return 1;
+            return number * CalculateFactorial(number - 1);
+        }
+    }
+}

+ 43 - 1
Extensions/ObjectExtension.cs

@@ -1,4 +1,7 @@
-namespace Alchemy.Core.Extensions
+using System.Reflection;
+using System.Text.RegularExpressions;
+
+namespace Alchemy.Core.Extensions
 {
     public static class ObjectExtension
     {
@@ -15,5 +18,44 @@
         {
             return !obj.IsNull();
         }
+        public static bool SetPropValue(this object? obj, string strPropName, object value)
+        {
+            bool result = false;
+            if (obj.IsNull())
+                return result;
+            Type type = obj.GetType();
+            PropertyInfo propertyInfo = type.GetProperty(strPropName);
+            if (propertyInfo != null && propertyInfo.CanWrite)
+            {
+                propertyInfo.SetValue(obj, value, null);
+                result = true;
+            }
+            return result;
+        }
+        /// <summary>
+        /// 下划线转驼峰的转换
+        /// </summary>
+        /// <param name="obj"></param>
+        /// <returns></returns>
+        /// <exception cref="ArgumentNullException"></exception>
+        public static Dictionary<string, object> ToDictionary(this object? obj)
+        {
+            if (obj == null)
+                throw new ArgumentNullException(nameof(obj));
+
+            var dictionary = new Dictionary<string, object>();
+            foreach (var property in obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public))
+            {
+                var key = ToCamelCase(property.Name);
+                var value = property.GetValue(obj, null);
+                dictionary[key] = value;
+            }
+
+            return dictionary;
+        }
+        private static string ToCamelCase(string input)
+        {
+            return Regex.Replace(input, "([a-z])_([a-z])", m => m.Groups[1].Value + m.Groups[2].Value.ToUpperInvariant());
+        }
     }
 }

+ 11 - 12
Extensions/StringExtension.cs

@@ -1,4 +1,5 @@
 using Alchemy.Core.Services;
+using System.Text.RegularExpressions;
 
 namespace Alchemy.Core.Extensions
 {
@@ -178,18 +179,7 @@ namespace Alchemy.Core.Extensions
                 return false;
             if (strIP.Length < 7 || strIP.Length > 15)
                 return false;
-            string pattern = @"^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$";
-            return RegexService.IsMatch(strIP, pattern);
-        }
-        /// <summary>
-        /// 检测是否手机号
-        /// </summary>
-        /// <param name="strMobilePhone"></param>
-        /// <returns></returns>
-        public static bool IsMobilePhone(this string strMobilePhone)
-        {
-            string pattern = @"^1[3-9]\d{9}$";
-            return RegexService.IsMatch(strMobilePhone, pattern);
+            return RegexService.IsMatch(strIP, @"^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$");
         }
         /// <summary>
         /// 判断是否版本号
@@ -213,5 +203,14 @@ namespace Alchemy.Core.Extensions
             }
             return value;
         }
+        /// <summary>
+        /// 判断是否包含中文
+        /// </summary>
+        /// <param name="strParam"></param>
+        /// <returns></returns>
+        public static bool ContainsChinese(this string strParam)
+        {
+            return Regex.IsMatch(strParam, @"[\u4e00-\u9fa5]");
+        }
     }
 }

+ 1 - 1
Services/ApiClientService.cs

@@ -3,7 +3,7 @@ using Newtonsoft.Json.Linq;
 using RestSharp;
 namespace Alchemy.Core.Services
 {
-    public static class ApiClientService
+    public class ApiClientService
     {
         /// <summary>
         /// 发起API请求

+ 0 - 44
Services/ConvertService.cs

@@ -1,44 +0,0 @@
-using Alchemy.Core.Extensions;
-using System.Reflection;
-namespace Alchemy.Core.Services
-{
-    public class ConvertService
-    {
-        /// <summary>
-        /// 字节数组转换为16进制表示的字符串
-        /// </summary>
-        public static string ByteArrayToHexString(byte[] buf)
-        {
-            string returnStr = string.Empty;
-            if (buf.IsNotNull())
-            {
-                for (int i = 0; i < buf.Length; i++)
-                {
-                    returnStr += buf[i].ToString("X2");
-                }
-            }
-            return returnStr;
-        }
-        /// <summary>
-        /// 类转换成IDic
-        /// </summary>
-        /// <param name="obj"></param>
-        /// <returns></returns>
-        public static Dictionary<string, string> ObjToDictionary(object obj)
-        {
-            Type type = obj.GetType();
-            PropertyInfo[] properties = type.GetProperties();
-            Dictionary<string, string> dict = new Dictionary<string, string>();
-            foreach (PropertyInfo property in properties)
-            {
-                if (!property.CanRead || !property.CanWrite)
-                    continue;
-                object value = property.GetValue(obj);
-                string key = property.Name;
-                string strValue = value?.ToString();
-                dict[key] = strValue ?? string.Empty;
-            }
-            return dict;
-        }
-    }
-}

+ 315 - 0
Services/CryptoService.cs

@@ -0,0 +1,315 @@
+using Alchemy.Core.Extensions;
+using System.Security.Cryptography;
+using System.Security.Cryptography.X509Certificates;
+using System.Text;
+namespace Alchemy.Core.Services
+{
+    public class CryptoService
+    {
+        /// <summary>
+        /// 将一条十六进制字符串转换为ASCII
+        /// </summary>
+        /// <param name="hexstring">一条十六进制字符串</param>
+        /// <returns>返回一条ASCII码</returns>
+        public static string HexStringToASCII(string hexstring)
+        {
+            byte[] bt = HexStringToBinary(hexstring);
+            string lin = "";
+            for (int i = 0; i < bt.Length; i++)
+            {
+                lin = lin + bt[i] + " ";
+            }
+            string[] ss = lin.Trim().Split(new char[] { ' ' });
+            char[] c = new char[ss.Length];
+            int a;
+            for (int i = 0; i < c.Length; i++)
+            {
+                a = Convert.ToInt32(ss[i]);
+                c[i] = Convert.ToChar(a);
+            }
+            string b = new string(c);
+            return b;
+        }
+        /**/
+        /// <summary>
+        /// 16进制字符串转换为二进制数组
+        /// </summary>
+        /// <param name="hexstring">字符串每个字节之间都应该有空格,大多数的串口通讯资料上面的16进制都是字节之间都是用空格来分割的。</param>
+        /// <returns>返回一个二进制字符串</returns>
+        public static byte[] HexStringToBinary(string hexstring)
+        {
+            string[] tmpary = hexstring.Trim().Split(' ');
+            byte[] buff = new byte[tmpary.Length];
+            for (int i = 0; i < buff.Length; i++)
+            {
+                buff[i] = Convert.ToByte(tmpary[i], 16);
+            }
+            return buff;
+        }
+        /// <summary>
+        /// AES 解密
+        /// </summary>
+        /// <param name="strEncoded"></param>
+        /// <param name="strKey"></param>
+        /// <returns></returns>
+        public static string DecodeAes(string strEncoded, string strKey)
+        {
+            string strResult = string.Empty;
+            byte[] encryptedBytes = Convert.FromBase64String(strEncoded);
+            byte[] keyBytes = Encoding.UTF8.GetBytes(strKey);
+            using (Aes aes = Aes.Create())
+            {
+                aes.Key = keyBytes;
+                aes.IV = new byte[aes.BlockSize / 8];
+                using (MemoryStream memStream = new MemoryStream())
+                {
+                    using (CryptoStream cryptoStream = new CryptoStream(memStream, aes.CreateDecryptor(), CryptoStreamMode.Write))
+                    {
+                        cryptoStream.Write(encryptedBytes, 0, encryptedBytes.Length);
+                        cryptoStream.FlushFinalBlock();
+                        byte[] decryptedBytes = memStream.ToArray();
+                        strResult = Encoding.UTF8.GetString(decryptedBytes);
+                    }
+                }
+            }
+            return strResult;
+        }
+        /// <summary>
+        /// 唯一识别ID加密算法
+        /// </summary>
+        /// <param name="numID"></param>
+        /// <param name="strString"></param>
+        /// <returns></returns>
+        public static string EncodeUniqId(int numID, string strString)
+        {
+            string strUserIDHashed = EncodeMD5(numID.ToString());
+            string strUserNameHashed = EncodeMD5(strString);
+            string strDatetimeHashed = EncodeMD5(DateTimeService.Now());
+            string value = EncodeMD5(EncodeBase64(strUserIDHashed + strUserNameHashed + strDatetimeHashed));
+            return value;
+        }
+        /// <summary>
+        /// 用户密码加密算法,使用基础加密算法
+        /// </summary>
+        /// <param name="strPwd">输入未加密的密码</param>
+        /// <returns></returns>
+        public static string EncodeUserPwd(string strPwd)
+        {
+            //string value = EncodeMD5(EncodeBase64(EncodeMD5(strPwd)));
+            return EncodeMD5(strPwd);
+        }
+        /// <summary>
+        /// 基础加密算法,先MD5再Base64再MD5
+        /// </summary>
+        /// <param name="strData">输入未加密的数据</param>
+        /// <returns></returns>
+        public static string EncodeBasicCrypto(string strData)
+        {
+            string value = EncodeMD5(EncodeBase64(EncodeMD5(strData)));
+            return value;
+        }
+        /// <summary>
+        /// 不安全加密算法,3次Base64
+        /// </summary>
+        /// <param name="strData"></param>
+        /// <returns></returns>
+        public static string EncodeUnsafeCrypto(string strData)
+        {
+            string value = EncodeBase64(EncodeBase64(EncodeBase64(strData)));
+            return value;
+        }
+        public static string DecodeUnsafeCrypto(string strData)
+        {
+            string value = DecodeBase64(DecodeBase64(DecodeBase64(strData)));
+            return value;
+        }
+        /// <summary>
+        /// MD5加密,输出32位小写
+        /// </summary>
+        /// <param name="strData">输入字符串</param>
+        /// <returns></returns>
+        public static string EncodeMD5(string strData)
+        {
+            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
+            byte[] bytValue, bytHash;
+            bytValue = Encoding.UTF8.GetBytes(strData);
+            bytHash = md5.ComputeHash(bytValue);
+            md5.Clear();
+            string sTemp = "";
+            for (int i = 0; i < bytHash.Length; i++)
+            {
+                sTemp += bytHash[i].ToString("X").PadLeft(2, '0');
+            }
+            return sTemp.ToLower();
+        }
+        /// <summary>
+        /// Base64加密
+        /// </summary>
+        /// <param name="strData">输入字符串</param>
+        /// <returns></returns>
+        public static string EncodeBase64(string strData)
+        {
+            byte[] arrData = Encoding.UTF8.GetBytes(strData);
+            string strBase64 = Convert.ToBase64String(arrData);
+            return strBase64;
+        }
+        /// <summary>
+        /// Base64解密
+        /// </summary>
+        /// <param name="strData">输入字符串</param>
+        /// <returns></returns>
+        public static string DecodeBase64(string strData)
+        {
+            string strRaw = string.Empty;
+            try
+            {
+                byte[] bytes = Convert.FromBase64String(strData);
+                strRaw = Encoding.UTF8.GetString(bytes);
+            }
+            catch (Exception ex)
+            {
+                //throw new Exception(ex.Message);
+                strRaw = strData;
+            }
+            return strRaw;
+        }
+        /// <summary>
+        /// HMACSHA256加密算法
+        /// </summary>
+        /// <param name="strData"></param>
+        /// <param name="strSecret"></param>
+        /// <returns></returns>
+        public static string EncodeHMACSHA256forWx(string strSecret)
+        {
+            return EncodeHMACSHA256("", strSecret);
+        }
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="strData"></param>
+        /// <param name="strSecret"></param>
+        /// <returns></returns>
+        public static string EncodeHMACSHA256(string strData, string strSecret)
+        {
+            // 1. 将密钥字符串转换为UTF-8字节数组(不进行Base64解码)
+            byte[] keyBytes = Encoding.UTF8.GetBytes(strSecret);
+
+            // 2. 处理空字符串:使用空字节数组
+            byte[] dataBytes = string.IsNullOrEmpty(strData)
+                ? new byte[0]
+                : Encoding.UTF8.GetBytes(strData);
+
+            // 3. 计算HMAC-SHA256
+            using var hmac = new HMACSHA256(keyBytes);
+            byte[] hashBytes = hmac.ComputeHash(dataBytes);
+
+            // 4. 转换为小写十六进制字符串
+            return Convert.ToHexString(hashBytes).ToLowerInvariant();
+        }
+        /// <summary>
+        /// 生成短链接
+        /// </summary>
+        /// <param name="strKey"></param>
+        /// <param name="len"></param>
+        /// <returns></returns>
+        public static string EncodeShortUrl(string strKey, int len = 6)
+        {
+            string value = string.Empty;
+            List<string> listFilter = new List<string>();
+            listFilter.Add("o");
+            listFilter.Add("0");
+            listFilter.Add("O");
+            listFilter.Add("I");
+            listFilter.Add("l");
+            listFilter.Add("i");
+            listFilter.Add("1");
+            for (int i = 0; i < len; i++)
+            {
+                string strChar = EncodeMD5(strKey + Guid.NewGuid().ToString()).ToUpper().Substring(i, 1);
+                while (!listFilter.Contains(strChar))
+                {
+                    strChar = EncodeMD5(strKey + Guid.NewGuid().ToString()).ToUpper().Substring(i, 1);
+                }
+                value += strChar;
+            }
+            return value;
+        }
+        /// <summary>
+        /// 生成外部订单号
+        /// </summary>
+        /// <param name="strPrefix"></param>
+        /// <returns></returns>
+        public static string EncodeOutTradeNo(string strPrefix)
+        {
+            return strPrefix + EncodeUniqId(9999, Guid.NewGuid().ToString()).ToUpper();
+        }
+        /// <summary>
+        /// RSA加密
+        /// </summary>
+        /// <param name="text"></param>
+        /// <param name="publicKey"></param>
+        /// <returns></returns>
+        public static string EncodeRSA(string text, byte[] publicKey)
+        {
+            using (var x509 = new X509Certificate2(publicKey))
+            {
+                using (var rsa = (RSACryptoServiceProvider)x509.PublicKey.Key)
+                {
+                    var buff = rsa.Encrypt(Encoding.UTF8.GetBytes(text), true);
+                    return Convert.ToBase64String(buff);
+                }
+            }
+        }
+        /// <summary>
+        /// 计算文件的 MD5 值
+        /// </summary>
+        /// <param name="fileName">要计算 MD5 值的文件名和路径</param>
+        /// <returns>MD5 值16进制字符串</returns>
+        //public static string EncodeMd5FileHash(string fileName)
+        //{
+        //    return HashFile(fileName, "md5");
+        //}
+        /// <summary>
+        /// 计算文件的哈希值
+        /// </summary>
+        /// <param name="fileName">要计算哈希值的文件名和路径</param>
+        /// <param name="algName">算法:sha1,md5</param>
+        /// <returns>哈希值16进制字符串</returns>
+        //private static string HashFile(string fileName, string algName)
+        //{
+        //    if (!File.Exists(fileName))
+        //        return string.Empty;
+        //    FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
+        //    byte[] hashBytes = HashData(fs, algName);
+        //    fs.Close();
+        //    return ConvertService.ByteArrayToHexString(hashBytes);
+        //}
+        /// <summary>
+        /// 计算哈希值
+        /// </summary>
+        /// <param name="stream">要计算哈希值的 Stream</param>
+        /// <param name="algName">算法:sha1,md5</param>
+        /// <returns>哈希值字节数组</returns>
+        private static byte[] HashData(Stream stream, string algName)
+        {
+            HashAlgorithm algorithm;
+            if (algName.IsNull())
+            {
+                throw new ArgumentNullException("algName 不能为 null");
+            }
+            if (string.Compare(algName, "sha1", true) == 0)
+            {
+                algorithm = SHA1.Create();
+            }
+            else
+            {
+                if (string.Compare(algName, "md5", true) != 0)
+                {
+                    throw new Exception("algName 只能使用 sha1 或 md5");
+                }
+                algorithm = MD5.Create();
+            }
+            return algorithm.ComputeHash(stream);
+        }
+    }
+}

+ 143 - 0
Services/FileService.cs

@@ -1,4 +1,5 @@
 using System.Text;
+
 namespace Alchemy.Core.Services
 {
     public class FileService
@@ -27,5 +28,147 @@ namespace Alchemy.Core.Services
         {
             File.WriteAllText(strFilePath, strContent, _enc);
         }
+        public static long GetFolderSize(string folderPath)
+        {
+            DirectoryInfo directoryInfo = new DirectoryInfo(folderPath);
+            return GetDirectorySize(directoryInfo);
+        }
+        public static string GetFileSizeToShowTxt(string filePath)
+        {
+            FileInfo fileInfo = new FileInfo(filePath);
+            long byteSize = fileInfo.Length;
+            if (byteSize < 1024)
+                return $"{byteSize}B";
+            else
+            {
+                if (byteSize < 1024 * 1024)
+                    return $"{byteSize / 1024}KB";
+                else
+                    return $"{byteSize / 1024 / 1024}MB";
+            }
+        }
+        public static string GetFolderSizeToShowTxt(string folderPath)
+        {
+            DirectoryInfo directoryInfo = new DirectoryInfo(folderPath);
+            long byteSize = GetDirectorySize(directoryInfo);
+            if (byteSize < 1024)
+                return $"{byteSize}B";
+            else
+            {
+                if (byteSize < 1024 * 1024)
+                    return $"{byteSize / 1024}KB";
+                else
+                    return $"{byteSize / 1024 / 1024}MB";
+            }
+        }
+        private static long GetDirectorySize(DirectoryInfo directoryInfo)
+        {
+            long size = 0;
+            FileInfo[] files = directoryInfo.GetFiles();
+            DirectoryInfo[] directories = directoryInfo.GetDirectories();
+            foreach (FileInfo file in files)
+            {
+                size += file.Length;
+            }
+            foreach (DirectoryInfo dir in directories)
+            {
+                size += GetDirectorySize(dir);
+            }
+            return size;
+        }
+        /// <summary>
+        /// 写入文本内容
+        /// </summary>
+        /// <param name="strFilePath"></param>
+        /// <param name="lines"></param>
+        public static void WriteAllLines(string strFilePath, string[] lines)
+        {
+            File.WriteAllLines(strFilePath, lines, Encoding.UTF8);
+        }
+        public static bool Empty(DirectoryInfo directory)
+        {
+            try
+            {
+                foreach (FileInfo file in directory.GetFiles("*", SearchOption.AllDirectories))
+                {
+                    try
+                    {
+                        File.Delete(file.FullName);
+                    }
+                    catch (UnauthorizedAccessException)
+                    {
+                        File.SetAttributes(file.FullName, FileAttributes.Normal);
+                        File.Delete(file.FullName);
+                    }
+                }
+                foreach (DirectoryInfo subDirectory in directory.GetDirectories())
+                {
+                    DeleteFolder(subDirectory);
+                }
+                return true;
+            }
+            catch (Exception ex)
+            {
+                return false;
+            }
+        }
+        private static void DeleteFolder(DirectoryInfo subDirectory)
+        {
+            try
+            {
+                foreach (FileInfo file in subDirectory.GetFiles("*", SearchOption.AllDirectories))
+                {
+                    try
+                    {
+                        File.Delete(file.FullName);
+                    }
+                    catch (UnauthorizedAccessException)
+                    {
+                        File.SetAttributes(file.FullName, FileAttributes.Normal);
+                        File.Delete(file.FullName);
+                    }
+                }
+                foreach (DirectoryInfo subDir in subDirectory.GetDirectories())
+                {
+                    DeleteFolder(subDir);
+                }
+                subDirectory.Delete(true);
+            }
+            catch (Exception ex)
+            {
+            }
+        }
+        public static long GetFolderSize2(string folderPath)
+        {
+            DirectoryInfo directory = new DirectoryInfo(folderPath);
+            return directory.EnumerateFiles("*", SearchOption.AllDirectories)
+                            .Sum(file => file.Length);
+        }
+        public static string FindOlderestFolder(string path)
+        {
+
+            DirectoryInfo dir = new DirectoryInfo(path);
+            DirectoryInfo[] directories = dir.GetDirectories();
+
+            DateTime earliestTime = DateTime.MaxValue;
+            DirectoryInfo earliestDir = null;
+
+            foreach (DirectoryInfo directory in directories)
+            {
+                if (directory.CreationTime < earliestTime)
+                {
+                    earliestTime = directory.CreationTime;
+                    earliestDir = directory;
+                }
+            }
+            if (earliestDir != null)
+            {
+                return earliestDir.FullName;
+            }
+            else
+            {
+                return "";
+            }
+        }
     }
 }

+ 0 - 17
Services/GenService.cs

@@ -1,17 +0,0 @@
-namespace Alchemy.Core.Services
-{
-    public class GenService
-    {
-        public static string GenNumberCode(int degit)
-        {
-            if (degit > 1)
-            {
-                Random random = new Random();
-                string code = random.Next(10 ^ degit - 1, 10 ^ degit).ToString();
-                return code.PadLeft(degit, '0');
-            }
-            else
-                return "0";
-        }
-    }
-}

+ 34 - 15
Services/JsonService.cs

@@ -6,6 +6,20 @@ namespace Alchemy.Core.Services
 {
     public class JsonService
     {
+        /// <summary>
+        /// 尝试获取
+        /// </summary>
+        /// <param name="strJson"></param>
+        /// <param name="strKey"></param>
+        /// <returns></returns>
+        public static string TryGetValue(string strJson, string strKey)
+        {
+            JObject? jo = strJson.FromJson<JObject>();
+            string strResullt = string.Empty;
+            if (jo.ContainsKey(strKey))
+                strResullt = GetValue(strJson, strKey);
+            return strResullt;
+        }
         /// <summary>
         /// 写入JSON
         /// </summary>
@@ -19,10 +33,10 @@ namespace Alchemy.Core.Services
         /// 写入JSON
         /// </summary>
         /// <param name="strJsonPath"></param>
-        /// <param name="strValue"></param>
-        public static void WriteJson(string strJsonPath, string strValue)
+        /// <param name="strJson"></param>
+        public static void WriteJson(string strJsonPath, string strJson)
         {
-            JObject jo = strValue.FromJson<JObject>();
+            JObject? jo = strJson.FromJson<JObject>();
             string output = JsonConvert.SerializeObject(jo, Formatting.Indented);
             File.WriteAllText(strJsonPath, output);
         }
@@ -30,19 +44,19 @@ namespace Alchemy.Core.Services
         /// 写入JSON
         /// </summary>
         /// <param name="fi"></param>
-        /// <param name="strValue"></param>
-        public static void WriteJsonArray(FileInfo fi, string strValue)
+        /// <param name="strJson"></param>
+        public static void WriteJsonArray(FileInfo fi, string strJson)
         {
-            WriteJsonArray(fi.FullName, strValue);
+            WriteJsonArray(fi.FullName, strJson);
         }
         /// <summary>
         /// 写入JSON
         /// </summary>
         /// <param name="strJsonPath"></param>
-        /// <param name="strValue"></param>
-        public static void WriteJsonArray(string strJsonPath, string strValue)
+        /// <param name="strJson"></param>
+        public static void WriteJsonArray(string strJsonPath, string strJson)
         {
-            JArray ja = strValue.FromJson<JArray>();
+            JArray? ja = strJson.FromJson<JArray>();
             string output = JsonConvert.SerializeObject(ja, Formatting.Indented);
             File.WriteAllText(strJsonPath, output);
         }
@@ -66,7 +80,7 @@ namespace Alchemy.Core.Services
         /// <param name="strValue"></param>
         public static void SetJson(string strJsonPath, string strJson, string strKey, string strValue)
         {
-            JObject jo = strJson.FromJson<JObject>();
+            JObject? jo = strJson.FromJson<JObject>();
             jo[strKey] = strValue.FromJson<JToken>();
             string output = JsonConvert.SerializeObject(jo, Formatting.Indented);
             File.WriteAllText(strJsonPath, output);
@@ -91,7 +105,7 @@ namespace Alchemy.Core.Services
         /// <param name="strValue"></param>
         public static void SetValue(string strJsonPath, string strJson, string strKey, string strValue)
         {
-            JObject jo = (JObject)JsonConvert.DeserializeObject(strJson);
+            JObject? jo = strJson.FromJson<JObject>();
             jo[strKey] = strValue;
             string output = JsonConvert.SerializeObject(jo, Formatting.Indented);
             FileService.WriteAll(strJsonPath, output);
@@ -133,7 +147,7 @@ namespace Alchemy.Core.Services
         /// <returns></returns>
         public static string GetJson(string strJson, string strKey)
         {
-            JObject jo = (JObject)JsonConvert.DeserializeObject(strJson);
+            JObject? jo = strJson.FromJson<JObject>();
             return jo[strKey].ToJson();
         }
         /// <summary>
@@ -155,7 +169,7 @@ namespace Alchemy.Core.Services
         /// <returns></returns>
         public static string GetValue(string strJson, string strKey)
         {
-            JObject jo = (JObject)JsonConvert.DeserializeObject(strJson);
+            JObject? jo = strJson.FromJson<JObject>();
             return jo[strKey].ToString();
         }
         /// <summary>
@@ -179,8 +193,13 @@ namespace Alchemy.Core.Services
         /// <returns></returns>
         public static string GetValue(string strJson, int index, string strKey)
         {
-            JArray ja = (JArray)JsonConvert.DeserializeObject(strJson);
-            return ja[index][strKey]?.ToJson();
+            JArray? ja = strJson.FromJson<JArray>();
+            return ja[index][strKey].ToJson();
+        }
+
+        internal static string GetValue(object filePath_AppSettingsJson, string strKey)
+        {
+            throw new NotImplementedException();
         }
     }
 }

+ 15 - 0
Services/RegexService.cs

@@ -14,5 +14,20 @@ namespace Alchemy.Core.Services
             Regex regex = new Regex(strFormat, RegexOptions.None);
             return regex.IsMatch(strRaw);
         }
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="strInput"></param>
+        /// <param name="strStart"></param>
+        /// <param name="strEnd"></param>
+        /// <returns></returns>
+        public static string GetStringBetween(string strInput, string strStart, string strEnd)
+        {
+            string pattern = Regex.Escape(strStart) + "(.*?)" + Regex.Escape(strEnd);
+            Match match = Regex.Match(strInput, pattern);
+            if (match.Success)
+                return match.Groups[1].Value;
+            return string.Empty;
+        }
     }
 }

+ 0 - 7
Services/ValidService.cs

@@ -1,7 +0,0 @@
-namespace Alchemy.Core.Services
-{
-    public class ValidService
-    {
-
-    }
-}