Learn.Archives/Learn.Archives.Core/Common/AppCommon.cs

247 lines
8.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using FreeRedis;
using Learn.Archives.Core.Model;
using Learn.Archives.Core.Model.Interface;
using Microsoft.Extensions.DependencyModel;
using Microsoft.IdentityModel.Tokens;
using SqlSugar;
using SqlSugar.IOC;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.PortableExecutable;
using System.Runtime.Loader;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using UserCenter.Model.Interface;
using MiniExcelLibs;
using MiniExcelLibs.OpenXml;
using Microsoft.AspNetCore.Http;
using Learn.Archives.Core.Model.Dto;
namespace Learn.Archives.Core.Common
{
/// <summary>
/// 程序 公共变量
/// </summary>
public static class AppCommon
{
/// <summary>
/// 应用有效程序集
/// </summary>
public static readonly IEnumerable<Assembly> Assemblies;
/// <summary>
/// 主库数据库表类型
/// </summary>
public static readonly IEnumerable<Type> DbMatserType;
public static readonly IEnumerable<Type> UserCenterType;
public static readonly Dictionary<string, Type> EnumType;
static AppCommon()
{
try
{
var projectName = Assembly.GetExecutingAssembly().GetName().Name;
Assemblies = ExpandFunction.GetAssemblies();
var assembliesType = Assemblies
//.Where(s => s.FullName.Contains(projectName))
.SelectMany(s => s.ExportedTypes.Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass && u.IsDefined(typeof(SugarTable), false)));
DbMatserType = assembliesType
.Where(u => u.GetInterfaces().Contains(typeof(IDB)));
UserCenterType = assembliesType
.Where(u => u.FullName.Contains("UserCenter"));
EnumType = Assemblies
.Where(s => s.FullName.Contains("Model")|| s.FullName.Contains("Core"))
.SelectMany(s => s.GetTypes().Where(x => x.IsEnum))
.DistinctBy(s=>s.Name)
.ToDictionary(s => s.Name, s => s);
}
catch
{
throw;
}
}
/// <summary>
/// 程序配置
/// </summary>
public static AppConfig Config = new AppConfig();
/// <summary>
/// ServiceProvider
/// </summary>
public static IServiceProvider? Services;
}
/// <summary>
/// 拓展函数
/// </summary>
public static class ExpandFunction
{
const string SheetName = "Sheet1";
public static byte[] ExportExcel(this IEnumerable<object> resultList)
{
var config = new OpenXmlConfiguration()
{
TableStyles = TableStyles.None
};
using var memoryStream = new MemoryStream();
memoryStream.SaveAs(resultList, true, SheetName, ExcelType.XLSX, config);
memoryStream.Seek(0, SeekOrigin.Begin);
return memoryStream.ToArray();
}
public static string GetMD5(this string input)
{
using (MD5 md5 = MD5.Create())
{
byte[] hashBytes = md5.ComputeHash(Encoding.UTF8.GetBytes(input));
return Convert.ToHexString(hashBytes).ToUpper(); // 或者保留大写
}
}
public static DateTime? ExtractDateTime(this string input)
{
if (string.IsNullOrWhiteSpace(input))
return null;
// 定义日期模式的正则表达式
string pattern = @"(\d{4})[年./\s-](\d{1,2})[月./\s-](\d{1,2})日?";
var match = Regex.Match(input, pattern);
if (match.Success && match.Groups.Count == 4)
{
if (int.TryParse(match.Groups[1].Value, out int year) &&
int.TryParse(match.Groups[2].Value, out int month) &&
int.TryParse(match.Groups[3].Value, out int day))
{
try
{
return new DateTime(year, month, day);
}
catch (ArgumentOutOfRangeException)
{
// 处理无效日期如2月30日
return null;
}
}
}
return null;
}
/// <summary>
/// 对象转化为JSON字符串
/// </summary>
/// <param name="o">拓展对象</param>
/// <param name="WriteIndented">美化输出?</param>
/// <returns></returns>
public static string ToJson(this object o, bool WriteIndented = false)
{
var jsonOptions = new JsonSerializerOptions
{
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = WriteIndented // 如果需要美化输出
};
return JsonSerializer.Serialize(o, jsonOptions);
}
/// <summary>
/// 解析Excel为对象数组
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="context"></param>
/// <returns></returns>
public static async Task<T[]?> ParsingExcelAsync<T>(this IHttpContextAccessor context) where T: class, new()
{
if (context == null) Oh.ModelError("传入无效的请求上下文数据");
var fl =context?.HttpContext?.Request.Form.Files[0];
if (fl == null) Oh.ModelError("传入无效的Excel数据");
if (!Path.GetExtension(fl.FileName).Equals(".xlsx", StringComparison.OrdinalIgnoreCase))
Oh.ModelError("请选择导入文件为.xlsx的后缀名!");
try
{
//分析excel
IEnumerable<T> dataList;
using var stream = new MemoryStream();
{
await fl.CopyToAsync(stream);
return stream.Query<T>().ToArray();
}
}
catch (Exception ex)
{
return Oh.Error<T[]>("分析失败"+ex.Message);
}
}
/// <summary>
/// 获取应用有效程序集
/// </summary>
/// <returns>IEnumerable</returns>
public static List<Assembly> GetAssemblies()
{
// 获取当前解决方案的所有程序集
var assembliesStr = DependencyContext.Default.RuntimeLibraries
.Where(u => !u.Name.StartsWith(nameof(Microsoft))
&& !u.Name.StartsWith(nameof(System))
&& !u.Name.StartsWith("netstandard")
&& u.Type == "project");
var assemblies = assembliesStr.Select(a => AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(a.Name))).ToList();
var assemblies1 = Assembly.GetEntryAssembly().GetReferencedAssemblies().Where(x => x.Name.StartsWith("App.") || x.Name.StartsWith("UserCenter."))
.Select(a => AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(a.Name))).ToList();
foreach (var item in assemblies1)
{
if (!assemblies.Contains(item))
assemblies.Add(item);
}
return assemblies;
}
/// <summary>
/// 获取下一个枚举值
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="current"></param>
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
public static T? NextEnum<T>(this T current) where T : struct, Enum
{
if (!typeof(T).IsEnum)
throw new ArgumentException("传入类型不是枚举");
T[] values = (T[])Enum.GetValues(typeof(T));
int currentIndex = Array.IndexOf(values, current);
if (currentIndex == values.Length - 1)
return null;
int nextIndex = (currentIndex + 1) % values.Length;
return values[nextIndex];
}
/// <summary>
/// 转化枚举
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static T? ToEnum<T>(this object value) where T : struct, Enum
{
try
{
if (value is null || string.IsNullOrEmpty(value.ToString()))
return null;
if (Enum.TryParse<T>(value.ToString(), true, out var result) && Enum.IsDefined(typeof(T), result))
return result;
return null;
}
catch (Exception)
{
return null;
}
}
}
}