using System; using System.IO; using System.Linq; using System.Reflection; using System.Security.Cryptography; using System.Text; using System.Text.Encodings.Web; using System.Text.Json; using System.Text.Json.Serialization; using System.Text.RegularExpressions; using System.Text.Unicode; using System.Xml.Serialization; namespace SimApi.Helpers; public static class SimApiUtil { /// /// 当前CST时间 /// public static DateTime CstNow => DateTime.UtcNow.AddHours(8); /// /// JSON序列化常规选项 /// public static JsonSerializerOptions JsonOption => new() { // ReferenceHandler = ReferenceHandler.Preserve, Encoder = JavaScriptEncoder.Create(UnicodeRanges.All), PropertyNamingPolicy = JsonNamingPolicy.CamelCase, // DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }; public static string SimApiVersion { get { // 这里使用当前类(属于 NuGet 包)的程序集 var assembly = typeof(SimApiUtil).Assembly; // 优先获取 AssemblyInformationalVersion(通常对应 NuGet 包版本,可能包含预发布标签) var informationalVersion = assembly.GetCustomAttribute()?.InformationalVersion; if (!string.IsNullOrEmpty(informationalVersion)) { return informationalVersion; } // 若不存在,则获取 AssemblyVersion(编译时版本) var version = assembly.GetName().Version?.ToString(); return version ?? "Unknown"; } } public static string AppVersion { get { // 获取外层应用的入口程序集(通常是启动项目的程序集) var entryAssembly = Assembly.GetEntryAssembly(); if (entryAssembly == null) { // 特殊场景(如单元测试、某些宿主环境)下,入口程序集可能为 null,可尝试获取调用栈中的上层程序集 entryAssembly = Assembly.GetCallingAssembly(); // 或 Assembly.GetExecutingAssembly() 视场景调整 } // 优先获取应用的 AssemblyInformationalVersion var informationalVersion = entryAssembly.GetCustomAttribute() ?.InformationalVersion; if (!string.IsNullOrEmpty(informationalVersion)) { return informationalVersion; } // 若不存在,则获取 AssemblyVersion var version = entryAssembly.GetName().Version?.ToString(); return version ?? "Unknown"; } } /// /// 当前秒级时间戳 /// public static double TimestampNow => (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds; /// /// 检测手机号是否正确 /// /// 手机号码 /// public static bool CheckCell(string cell) { var regex = new Regex("^1[3456789]\\d{9}$"); return regex.IsMatch(cell); } /// /// MD5加密字符串 /// /// 源字符串 /// 加密结果"x2"结果为32位,"x3"结果为48位,"x4"结果为64位 /// public static string Md5(string source, string mode = "x2") { var sourceBytes = Encoding.UTF8.GetBytes(source); var result = MD5.HashData(sourceBytes); var stringBuilder = new StringBuilder(40); foreach (var t in result) { stringBuilder.Append(t.ToString(mode)); } return stringBuilder.ToString(); } /// /// sha1加密字符串 /// /// 源字符串 /// 加密结果"x2"结果为32位,"x3"结果为48位,"x4"结果为64位 /// public static string Sha1(string source, string mode = "x2") { var hash = SHA1.HashData(Encoding.UTF8.GetBytes(source)); var sb = new StringBuilder(hash.Length * 2); foreach (var b in hash) { sb.Append(b.ToString(mode)); } return sb.ToString(); } /// /// 将XML字符串序列化为对象 /// /// /// /// public static T XmlDeserialize(string source) { var xmlConvertor = new XmlSerializer(typeof(T)); using var reader = new StringReader(source); return (T)xmlConvertor.Deserialize(reader)!; } /// /// 将对象序列化成JSON (控制台输出中文不会被编码) /// /// /// public static string Json(object? obj) { return JsonSerializer.Serialize(obj, JsonOption); } /// /// 分页 /// /// /// 页码 /// 每页数量 /// /// public static IQueryable Paginate(this IQueryable query, int page, int count) { if (page < 1) page = 1; if (count <= 0) count = 10; return query.Skip((page - 1) * count).Take(count); } }