完善功能

This commit is contained in:
2025-09-22 14:30:54 +08:00
parent fde5919d99
commit 365cd2397a
31 changed files with 1849 additions and 467 deletions

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace .Utility
{
public class ContentTypeUtils
{
public static string GetContentType(string fileName)
{
return System.Web.MimeMapping.GetMimeMapping(fileName);
}
}
}

View File

@@ -0,0 +1,215 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace .Utility
{
public class EventBus
{
private static object _lock = new object();
private List<CallBacks> list;
private List<StrCallBacks> strlist;
/// <summary>
/// 单例,防止实例化
/// </summary>
private EventBus()
{
list = new List<CallBacks>();
strlist = new List<StrCallBacks>();
}
private static EventBus _instance;
/// <summary>
/// 获取实例
/// </summary>
public static EventBus Instance
{
get
{
if (_instance == null)
{
_instance = new EventBus();
return _instance;
}
return _instance;
}
}
/// <summary>
/// 订阅消息obj这个对象订阅T这个消息发布消息时调用回调方法
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <param name="callBackFunc"></param>
public void Subscribe<T>(object obj, Action<T> callBackFunc) where T : IEvent
{
try
{
//判断有没有注册过,注册过就不能再注册。疑惑点,一个类中多次注册行不行??
if (list.Any(it => it.Subscriber == obj && it.EventType == typeof(T)))
{
return;
}
list.Add(new CallBacks
{
Subscriber = obj,
EventType = typeof(T),
Action = new Action<object>(o => callBackFunc((T)o))
});
}
catch (Exception ex)
{
}
}
/// <summary>
/// 取消订阅obj这个对象取消订阅T这个消息
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
public void UnSubscribe<T>(object obj) where T : IEvent
{
try
{
list.RemoveAll(it => it.Subscriber == obj && it.EventType == typeof(T));
}
catch (Exception ex)
{
}
}
/// <summary>
/// 发布消息
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="data"></param>
public void Publish<T>(T data) where T : IEvent
{
list.Where(it => it.EventType == typeof(T)).ToList().ForEach(it =>
{
//Task.Run(() => it.Action(data));
try
{
it.Action(data);
}
catch (Exception ex)
{
}
});
}
public void Subscribe(object obj, string eventName, Action<string> callBackFunc)
{
try
{
//判断有没有注册过,注册过就不能再注册。疑惑点,一个类中多次注册行不行??
if (strlist.Any(it => it.Subscriber == obj && it.EventName == eventName))
{
return;
}
strlist.Add(new StrCallBacks
{
Subscriber = obj,
EventName = eventName,
Action = callBackFunc
});
}
catch (Exception ex)
{
}
}
public void UnSubscribe(object obj, string eventName)
{
try
{
strlist.RemoveAll(it => it.Subscriber == obj && it.EventName == eventName);
}
catch (Exception ex)
{
}
}
public void Publish(string eventName, string data)
{
try
{
strlist.Where(it => it.EventName == eventName).ToList().ForEach(it =>
{
it.Action(data);
});
}
catch (Exception ex)
{
}
}
/// <summary>
/// 内部类
/// </summary>
class CallBacks
{
/// <summary>
/// T的类型
/// </summary>
public Type EventType { get; set; }
/// <summary>
/// 谁订阅对象
/// </summary>
public object Subscriber { get; set; }
public Action<object> Action { get; set; }
}
class StrCallBacks
{
/// <summary>
/// T的类型
/// </summary>
public string EventName { get; set; }
/// <summary>
/// 谁订阅对象
/// </summary>
public object Subscriber { get; set; }
public Action<string> Action { get; set; }
}
}
public interface IEvent { }
public class ConsoleLogEvent : IEvent
{
public DateTime DateTime { get; set; }
public string Message { get; set; }
public string Type { get; set; }
public ConsoleLogEvent(string message) : this("I", message)
{
}
public ConsoleLogEvent(string type, string message)
{
this.Type = type;
this.Message = message;
this.DateTime = DateTime.Now;
}
public override string ToString()
{
return $"{DateTime.ToString("yyyy-MM-dd HH:mm:ss.fff")}[{Type}]->{Message}";
}
}
public class ClearLogEvent : IEvent
{
}
}

View File

@@ -18,6 +18,8 @@ namespace 电子展板.Utility.Extension
}
public static string Root(string vPath)
{
if (vPath == null)
vPath = "";
string path = Environment.CurrentDirectory.Replace("/", "\\");
if (!path.EndsWith("\\")) path += "\\";
vPath = vPath.Replace("/", "\\");

View File

@@ -0,0 +1,53 @@
using System;
namespace .Utility.Other
{
public class CalcUtils
{
/// <summary>
/// 计算两个坐标的距离
/// </summary>
/// <param name="long1">经度1</param>
/// <param name="lat1">纬度1</param>
/// <param name="long2">经度2</param>
/// <param name="lat2">纬度2</param>
/// <returns></returns>
public static double getDistance(double long1, double lat1, double long2, double lat2)
{
double a, b, R;
R = 6371393; // 地球半径
lat1 = lat1 * Math.PI / 180.0;
lat2 = lat2 * Math.PI / 180.0;
a = lat1 - lat2;
b = (long1 - long2) * Math.PI / 180.0;
double d;
double sa2, sb2;
sa2 = Math.Sin(a / 2.0);
sb2 = Math.Sin(b / 2.0);
d = 2 * R * Math.Asin(Math.Sqrt(sa2 * sa2 + Math.Cos(lat1) * Math.Cos(lat2) * sb2 * sb2));
return d;
}
public static double algorithm(double longitude1, double latitude1, double longitude2, double latitude2)
{
double Lat1 = rad(latitude1); // 纬度
double Lat2 = rad(latitude2);
double a = Lat1 - Lat2;//两点纬度之差
double b = rad(longitude1) - rad(longitude2); //经度之差
double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) + Math.Cos(Lat1) * Math.Cos(Lat2) * Math.Pow(Math.Sin(b / 2), 2)));//计算两点距离的公式
s = s * 6378137.0;//弧长乘地球半径(半径为米)
s = Math.Round(s * 10000d) / 10000d;//精确距离的数值
return s;
}
private static double rad(double d)
{
return d * Math.PI / 180.00; //角度转换成弧度
}
public static double getVectorAngle(double x1, double y1, double x2, double y2)
{
return Math.Acos((x1 * x2 + y1 * y2) / (Math.Sqrt(x1 * x1 + y1 * y1) * Math.Sqrt(x2 * x2 + y2 * y2))) * 180.0 / Math.PI;
}
}
}

View File

@@ -0,0 +1,40 @@
using System;
namespace .Utility.Other
{
public class PositionUtils
{
private static double pi = 3.1415926535897932384626;
private static double a = 6378245.0;
private static double ee = 0.00669342162296594323;
private static double bd_pi = 3.14159265358979324 * 3000.0 / 180.0;
/// <summary>
/// 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 将 GCJ-02 坐标转换成 BD-09 坐标
/// </summary>
/// <param name="lat"></param>
/// <param name="lon"></param>
public static void gcj02_To_Bd09(ref double lat, ref double lon)
{
double x = lon, y = lat;
double z = Math.Sqrt(x * x + y * y) + 0.00002 * Math.Sin(y * bd_pi);
double theta = Math.Atan2(y, x) + 0.000003 * Math.Cos(x * bd_pi);
lon = z * Math.Cos(theta) + 0.0065;
lat = z * Math.Sin(theta) + 0.006;
}
/// <summary>
/// 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 * * 将 BD-09 坐标转换成GCJ-02 坐标
/// </summary>
/// <param name="lat"></param>
/// <param name="lon"></param>
public static void bd09_To_Gcj02(ref double lat, ref double lon)
{
double x = lon - 0.0065, y = lat - 0.006;
double z = Math.Sqrt(x * x + y * y) - 0.00002 * Math.Sin(y * bd_pi);
double theta = Math.Atan2(y, x) - 0.000003 * Math.Cos(x * bd_pi);
lon = z * Math.Cos(theta);
lat = z * Math.Sin(theta);
}
}
}

View File

@@ -0,0 +1,13 @@
using System;
namespace .Utility.Other
{
public class RandomUtils
{
public static int GetRandomInt(int start, int end)
{
Random rand = new Random();
return rand.Next(start, end);
}
}
}

View File

@@ -0,0 +1,203 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace .Utility.Other
{
public class SnowFlakeHelper
{
private static readonly object _obj = new object();
private static SnowFlakeHelper Instance;
private SnowFlakeHelper()
{
}
/// <summary>
/// 获取雪花帮助类对象
/// </summary>
/// <param name="datacenterId">数据中心ID</param>
/// <param name="workerId">工作机器Id</param>
/// <returns></returns>
public static SnowFlakeHelper GetSnowInstance(long datacenterId = 1, long workerId = 1)
{
//双if 加锁
if (Instance == null)
{
lock (_obj)
{
if (Instance == null)
{
Instance = new SnowFlakeHelper(datacenterId, workerId);
}
}
}
return Instance;
}
// 开始时间截((new DateTime(2020, 1, 1, 0, 0, 0, DateTimeKind.Utc)-Jan1st1970).TotalMilliseconds)
private const long twepoch = 1577836800000L;
// 机器id所占的位数
private const int workerIdBits = 5;
// 数据标识id所占的位数
private const int datacenterIdBits = 5;
// 支持的最大机器id结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数)
private const long maxWorkerId = -1L ^ (-1L << workerIdBits);
// 支持的最大数据标识id结果是31
private const long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
// 序列在id中占的位数
private const int sequenceBits = 12;
// 数据标识id向左移17位(12+5)
private const int datacenterIdShift = sequenceBits + workerIdBits;
// 机器ID向左移12位
private const int workerIdShift = sequenceBits;
// 时间截向左移22位(5+5+12)
private const int timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
// 生成序列的掩码这里为4095 (0b111111111111=0xfff=4095)
private const long sequenceMask = -1L ^ (-1L << sequenceBits);
// 数据中心ID(0~31)
public long datacenterId { get; private set; }
// 工作机器ID(0~31)
public long workerId { get; private set; }
// 毫秒内序列(0~4095)
public long sequence { get; private set; }
// 上次生成ID的时间截
public long lastTimestamp { get; private set; }
/// <summary>
/// 雪花ID
/// </summary>
/// <param name="datacenterId">数据中心ID</param>
/// <param name="workerId">工作机器ID</param>
private SnowFlakeHelper(long datacenterId, long workerId)
{
if (datacenterId > maxDatacenterId || datacenterId < 0)
{
throw new Exception(string.Format("datacenter Id can't be greater than {0} or less than 0", maxDatacenterId));
}
if (workerId > maxWorkerId || workerId < 0)
{
throw new Exception(string.Format("worker Id can't be greater than {0} or less than 0", maxWorkerId));
}
this.workerId = workerId;
this.datacenterId = datacenterId;
this.sequence = 0L;
this.lastTimestamp = -1L;
}
/// <summary>
/// 获得下一个ID
/// </summary>
/// <returns></returns>
public long NextId()
{
lock (this)
{
long timestamp = GetCurrentTimestamp();
if (timestamp > lastTimestamp) //时间戳改变,毫秒内序列重置
{
sequence = 0L;
}
else if (timestamp == lastTimestamp) //如果是同一时间生成的,则进行毫秒内序列
{
sequence = (sequence + 1) & sequenceMask;
if (sequence == 0) //毫秒内序列溢出
{
timestamp = GetNextTimestamp(lastTimestamp); //阻塞到下一个毫秒,获得新的时间戳
}
}
else //当前时间小于上一次ID生成的时间戳证明系统时钟被回拨此时需要做回拨处理
{
sequence = (sequence + 1) & sequenceMask;
if (sequence > 0)
{
timestamp = lastTimestamp; //停留在最后一次时间戳上,等待系统时间追上后即完全度过了时钟回拨问题。
}
else //毫秒内序列溢出
{
timestamp = lastTimestamp + 1; //直接进位到下一个毫秒
}
//throw new Exception(string.Format("Clock moved backwards. Refusing to generate id for {0} milliseconds", lastTimestamp - timestamp));
}
lastTimestamp = timestamp; //上次生成ID的时间截
//移位并通过或运算拼到一起组成64位的ID
var id = ((timestamp - twepoch) << timestampLeftShift)
| (datacenterId << datacenterIdShift)
| (workerId << workerIdShift)
| sequence;
return id;
}
}
/// <summary>
/// 解析雪花ID
/// </summary>
/// <returns></returns>
public static string AnalyzeId(long Id)
{
StringBuilder sb = new StringBuilder();
var timestamp = (Id >> timestampLeftShift);
var time = Jan1st1970.AddMilliseconds(timestamp + twepoch);
sb.Append(time.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss:fff"));
var datacenterId = (Id ^ (timestamp << timestampLeftShift)) >> datacenterIdShift;
sb.Append("_" + datacenterId);
var workerId = (Id ^ ((timestamp << timestampLeftShift) | (datacenterId << datacenterIdShift))) >> workerIdShift;
sb.Append("_" + workerId);
var sequence = Id & sequenceMask;
sb.Append("_" + sequence);
return sb.ToString();
}
/// <summary>
/// 阻塞到下一个毫秒,直到获得新的时间戳
/// </summary>
/// <param name="lastTimestamp">上次生成ID的时间截</param>
/// <returns>当前时间戳</returns>
private static long GetNextTimestamp(long lastTimestamp)
{
long timestamp = GetCurrentTimestamp();
while (timestamp <= lastTimestamp)
{
timestamp = GetCurrentTimestamp();
}
return timestamp;
}
/// <summary>
/// 获取当前时间戳
/// </summary>
/// <returns></returns>
private static long GetCurrentTimestamp()
{
return (long)(DateTime.UtcNow - Jan1st1970).TotalMilliseconds;
}
private static readonly DateTime Jan1st1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
}
}

View File

@@ -0,0 +1,47 @@
using System;
namespace .Utility.Other
{
public class UUID
{
public static long SnowId
{
get
{
return SnowFlakeHelper.GetSnowInstance().NextId();
}
}
public static string StrSnowId
{
get
{
return Convert.ToString(SnowId);
}
}
public static string NewTimeUUID
{
get
{
return DateTime.Today.ToString("yyyyMMdd") + Guid.NewGuid().ToString().Replace("-", "").ToUpper().Substring(0, 10);
}
}
public static string NewTimeUUID2
{
get
{
return DateTime.Today.ToString("yyyyMMdd") + Guid.NewGuid().ToString().Replace("-", "").ToUpper();
}
}
public static string NewUUID
{
get
{
return Guid.NewGuid().ToString().Replace("-", "").ToUpper();
}
}
}
}

View File

@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace .Utility.Web
{
public class WithExtensionMultipartFormDataStreamProvider : MultipartFormDataStreamProvider
{
public string guid { get; set; }
public string OriginalName { get; set; }
public string Ext { get; set; }
public WithExtensionMultipartFormDataStreamProvider(string rootPath, string guidStr) : base(rootPath)
{
guid = guidStr;
}
public override string GetLocalFileName(System.Net.Http.Headers.HttpContentHeaders headers)
{
OriginalName = !string.IsNullOrWhiteSpace(headers.ContentDisposition.FileName) ? GetValidFileName(headers.ContentDisposition.FileName) : "";
Ext = !string.IsNullOrWhiteSpace(OriginalName) ? Path.GetExtension(GetValidFileName(OriginalName)) : "";
return guid + Ext;
}
private string GetValidFileName(string filePath)
{
char[] invalids = System.IO.Path.GetInvalidFileNameChars();
return string.Join("_", filePath.Split(invalids, StringSplitOptions.RemoveEmptyEntries)).TrimEnd('.');
}
}
}