添加项目文件。

This commit is contained in:
zel
2025-03-05 19:42:01 +08:00
parent 659f1a2ad9
commit 47dcdeb55d
582 changed files with 242004 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
namespace WaterCloud.Code
{
/// <summary>
/// 管理员特性MVC使用
/// </summary>
public class HandlerAdminAttribute : ActionFilterAttribute
{
private readonly bool _isSuper;
public HandlerAdminAttribute(bool isSuper = true)
{
_isSuper = isSuper;
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (OperatorProvider.Provider.GetCurrent() != null && _isSuper == true ? OperatorProvider.Provider.GetCurrent().IsSuperAdmin : OperatorProvider.Provider.GetCurrent().IsAdmin)
{
return;
}
else
{
//filterContext.HttpContext.Response.WriteAsync("<script>top.location.href ='" + filterContext.HttpContext.Request.PathBase + "/Home/Error?msg=403" + "';if(document.all) window.event.returnValue = false;</script>");
filterContext.Result = new RedirectResult(filterContext.HttpContext.Request.PathBase + "/Home/Error?msg=403");
return;
}
}
}
}

View File

@@ -0,0 +1,34 @@
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.ActionConstraints;
using Microsoft.AspNetCore.Routing;
using System;
namespace WaterCloud.Code
{
/// <summary>
/// ajax验证
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public class HandlerAjaxOnlyAttribute : ActionMethodSelectorAttribute
{
public bool Ignore { get; set; }
public HandlerAjaxOnlyAttribute(bool ignore = false)
{
Ignore = ignore;
}
public override bool IsValidForRequest(RouteContext routeContext, ActionDescriptor action)
{
if (Ignore)
return true;
bool result = false;
var xreq = routeContext.HttpContext.Request.Headers.ContainsKey("x-requested-with");
if (xreq)
{
result = routeContext.HttpContext.Request.Headers.ContainsKey("x-requested-with");
}
return result;
}
}
}

View File

@@ -0,0 +1,56 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
namespace WaterCloud.Code
{
/// <summary>
/// 防重复锁MVC使用
/// </summary>
public class HandlerLockAttribute : ActionFilterAttribute
{
public HandlerLockAttribute()
{
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (OperatorProvider.Provider.GetCurrent() == null)
{
WebHelper.WriteCookie("WaterCloud_login_error", "overdue");
//filterContext.HttpContext.Response.WriteAsync("<script>top.location.href ='" + filterContext.HttpContext.Request.PathBase + "/Home/Error?msg=408" + "';if(document.all) window.event.returnValue = false;</script>");
OperatorProvider.Provider.EmptyCurrent("pc_").GetAwaiter().GetResult();
filterContext.Result = new RedirectResult(filterContext.HttpContext.Request.PathBase + "/Home/Error?msg=408");
return;
}
else
{
string token = filterContext.HttpContext.Request.Cookies["pc_" + GlobalContext.SystemConfig.TokenName];
string cacheToken = CacheHelper.GetAsync<string>("pc_" + GlobalContext.SystemConfig.TokenName + "_" + OperatorProvider.Provider.GetCurrent().UserId + "_" + OperatorProvider.Provider.GetCurrent().LoginTime).GetAwaiter().GetResult();
if (string.IsNullOrWhiteSpace(token))
{
filterContext.Result = new JsonResult(new AlwaysResult { state = ResultType.error.ToString(), message = "token不能空" });
return;
}
if (string.IsNullOrWhiteSpace(cacheToken))
{
filterContext.Result = new JsonResult(new AlwaysResult { state = ResultType.error.ToString(), message = "token不能空" });
return;
}
if (token != cacheToken)
{
filterContext.Result = new JsonResult(new AlwaysResult { state = ResultType.error.ToString(), message = "请求异常" });
return;
}
//固定加锁5秒
bool result = CacheHelper.SetNx(token, token, 5);
if (!result)
{
filterContext.Result = new JsonResult(new AlwaysResult { state = ResultType.error.ToString(), message = "请求太频繁,请稍后" });
return;
}
}
//随机值
base.OnActionExecuting(filterContext);
}
}
}

View File

@@ -0,0 +1,52 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Diagnostics;
using System.Threading.Tasks;
namespace WaterCloud.Code
{
/// <summary>
/// 防重复提交,api使用
/// </summary>
public class LockAttribute : ActionFilterAttribute
{
/// <summary>
/// 拦截
/// </summary>
/// <param name="context"></param>
/// <param name="next"></param>
/// <returns></returns>
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
Stopwatch sw = new Stopwatch();
sw.Start();
if (GlobalContext.SystemConfig.Debug == false)
{
if (OperatorProvider.Provider.GetCurrent() == null)
{
context.Result = new JsonResult(new AlwaysResult { state = ResultType.error.ToString(), message = "抱歉,没有操作权限" });
return;
}
else
{
string token = context.HttpContext.Request.Headers[GlobalContext.SystemConfig.TokenName].ParseToString();
if (string.IsNullOrWhiteSpace(token))
{
context.Result = new JsonResult(new AlwaysResult { state = ResultType.error.ToString(), message = "token不能空" });
return;
}
//固定加锁5秒
bool result = CacheHelper.SetNx(token, token, 5);
if (!result)
{
context.Result = new JsonResult(new AlwaysResult { state = ResultType.error.ToString(), message = "请求太频繁,请稍后" });
return;
}
}
}
await next();
sw.Stop();
}
}
}

View File

@@ -0,0 +1,23 @@
using System;
namespace WaterCloud.Code
{
[AttributeUsage(AttributeTargets.Class, Inherited = true)]
public class ServiceDescriptionAttribute : Attribute
{
public string ClassDescription
{
get;
set;
}
private ServiceDescriptionAttribute()
{
}
public ServiceDescriptionAttribute(string classDescription)
{
ClassDescription = classDescription;
}
}
}

View File

@@ -0,0 +1,468 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace WaterCloud.Code
{
public abstract class BaseHelper : RedisHelper<BaseHelper>
{ }
public abstract class HandleLogHelper : RedisHelper<HandleLogHelper>
{ }
public class CacheHelper
{
private static string cacheProvider = GlobalContext.SystemConfig.CacheProvider;
/// <summary>
/// 添加缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="value">缓存Value</param>
/// <param name="expiresIn">缓存时长h</param>
/// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>
/// <returns></returns>
public static async Task<bool> SetAsync(string key, object value, int expiresIn = -1, bool isSliding = true)
{
return await SetBySecondAsync(key, value, expiresIn * 3600, isSliding);
}
/// <summary>
/// 添加缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="value">缓存Value</param>
/// <param name="expiresIn">缓存时长秒</param>
/// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>
/// <returns></returns>
public static async Task<bool> SetBySecondAsync(string key, object value, int expiresIn = -1, bool isSliding = true)
{
if (string.IsNullOrEmpty(key))
throw new ArgumentNullException(nameof(key));
if (value == null)
throw new ArgumentNullException(nameof(value));
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
if (expiresIn > 0)
{
await BaseHelper.SetAsync(key, value, expiresIn);
}
else
{
await BaseHelper.SetAsync(key, value);
}
return await ExistsAsync(key);
case Define.CACHEPROVIDER_MEMORY:
if (expiresIn > 0)
{
MemoryCacheHelper.Set(key, value, TimeSpan.FromSeconds(expiresIn), isSliding);
}
else
{
MemoryCacheHelper.Set(key, value);
}
return await ExistsAsync(key);
default:
if (expiresIn > 0)
{
MemoryCacheHelper.Set(key, value, TimeSpan.FromSeconds(expiresIn), isSliding);
}
else
{
MemoryCacheHelper.Set(key, value);
}
return await ExistsAsync(key);
}
}
/// <summary>
/// 添加缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="value">缓存Value</param>
/// <param name="expiresIn">缓存时长秒</param>
/// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>
/// <returns></returns>
public static bool SetBySecond(string key, object value, int expiresIn = -1, bool isSliding = true)
{
if (string.IsNullOrEmpty(key))
throw new ArgumentNullException(nameof(key));
if (value == null)
throw new ArgumentNullException(nameof(value));
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
if (expiresIn > 0)
{
BaseHelper.Set(key, value, expiresIn);
}
else
{
BaseHelper.Set(key, value);
}
return Exists(key);
case Define.CACHEPROVIDER_MEMORY:
if (expiresIn > 0)
{
MemoryCacheHelper.Set(key, value, TimeSpan.FromSeconds(expiresIn), isSliding);
}
else
{
MemoryCacheHelper.Set(key, value);
}
return Exists(key);
default:
if (expiresIn > 0)
{
MemoryCacheHelper.Set(key, value, TimeSpan.FromSeconds(expiresIn), isSliding);
}
else
{
MemoryCacheHelper.Set(key, value);
}
return Exists(key);
}
}
/// <summary>
/// 获取缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public static async Task<T> GetAsync<T>(string key)
{
if (string.IsNullOrEmpty(key))
throw new ArgumentNullException(nameof(key));
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
return await BaseHelper.GetAsync<T>(key);
case Define.CACHEPROVIDER_MEMORY:
return MemoryCacheHelper.Get<T>(key);
default:
return MemoryCacheHelper.Get<T>(key);
}
}
/// <summary>
/// 获取缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public static T Get<T>(string key)
{
if (string.IsNullOrEmpty(key))
throw new ArgumentNullException(nameof(key));
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
return BaseHelper.Get<T>(key);
case Define.CACHEPROVIDER_MEMORY:
return MemoryCacheHelper.Get<T>(key);
default:
return MemoryCacheHelper.Get<T>(key);
}
}
/// <summary>
/// 删除缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public static async Task RemoveAsync(string key)
{
if (string.IsNullOrEmpty(key))
throw new ArgumentNullException(nameof(key));
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
await BaseHelper.DelAsync(key);
break;
case Define.CACHEPROVIDER_MEMORY:
MemoryCacheHelper.Remove(key);
break;
}
}
/// <summary>
/// 删除缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public static void Remove(string key)
{
if (string.IsNullOrEmpty(key))
throw new ArgumentNullException(nameof(key));
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
BaseHelper.Del(key);
break;
case Define.CACHEPROVIDER_MEMORY:
MemoryCacheHelper.Remove(key);
break;
}
}
/// <summary>
/// 验证缓存项是否存在
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public static async Task<bool> ExistsAsync(string key)
{
if (string.IsNullOrEmpty(key))
throw new ArgumentNullException(nameof(key));
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
return await BaseHelper.ExistsAsync(key);
case Define.CACHEPROVIDER_MEMORY:
return MemoryCacheHelper.Exists(key);
default:
return MemoryCacheHelper.Exists(key);
}
}
/// <summary>
/// 验证缓存项是否存在
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public static bool Exists(string key)
{
if (string.IsNullOrEmpty(key))
throw new ArgumentNullException(nameof(key));
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
return BaseHelper.Exists(key);
case Define.CACHEPROVIDER_MEMORY:
return MemoryCacheHelper.Exists(key);
default:
return MemoryCacheHelper.Exists(key);
}
}
/// <summary>
/// 缓存续期
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="hour">时间小时</param>
/// <returns></returns>
public static async Task ExpireAsync(string key, int hour)
{
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
await BaseHelper.ExpireAtAsync(key, DateTime.Now.AddHours(hour));
break;
default:
break;
}
}
/// <summary>
/// 缓存续期
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="hour">时间小时</param>
/// <returns></returns>
public static void Expire(string key, int hour)
{
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
BaseHelper.ExpireAt(key, DateTime.Now.AddHours(hour));
break;
default:
break;
}
}
/// <summary>
/// 清空缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public static async Task FlushAllAsync()
{
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
await BaseHelper.NodesServerManager.FlushDbAsync();
break;
case Define.CACHEPROVIDER_MEMORY:
MemoryCacheHelper.RemoveCacheAll();
break;
default:
MemoryCacheHelper.RemoveCacheAll();
break;
}
}
/// <summary>
/// 清空缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public static void FlushAll1()
{
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
BaseHelper.NodesServerManager.FlushDb();
break;
case Define.CACHEPROVIDER_MEMORY:
MemoryCacheHelper.RemoveCacheAll();
break;
default:
MemoryCacheHelper.RemoveCacheAll();
break;
}
}
/// <summary>
/// 不存在就插入
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="value">缓存Value</param>
/// <param name="second">过期时间</param>
/// <returns></returns>
public static async Task<bool> SetNxAsync(string key, object value, int second = 10)
{
bool result = false;
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
result = await BaseHelper.SetNxAsync(key, value);
await BaseHelper.ExpireAtAsync(key, DateTime.Now.AddSeconds(second));
break;
case Define.CACHEPROVIDER_MEMORY:
if (MemoryCacheHelper.Exists(key))
{
result = false;
MemoryCacheHelper.Get(key);
}
else
{
result = true;
MemoryCacheHelper.Set(key, value, TimeSpan.FromSeconds(second), true);
}
break;
default:
if (MemoryCacheHelper.Exists(key))
{
result = false;
MemoryCacheHelper.Get(key);
}
else
{
result = true;
MemoryCacheHelper.Set(key, value, TimeSpan.FromSeconds(second), true);
}
break;
}
return result;
}
/// <summary>
/// 不存在就插入
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="value">缓存Value</param>
/// <param name="second">过期时间</param>
/// <returns></returns>
public static bool SetNx(string key, object value, int second = 10)
{
bool result = false;
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
result = BaseHelper.SetNx(key, value);
BaseHelper.ExpireAt(key, DateTime.Now.AddSeconds(second));
break;
case Define.CACHEPROVIDER_MEMORY:
if (MemoryCacheHelper.Exists(key))
{
result = false;
MemoryCacheHelper.Get(key);
}
else
{
result = true;
MemoryCacheHelper.Set(key, value, TimeSpan.FromSeconds(second), true);
}
break;
default:
if (MemoryCacheHelper.Exists(key))
{
result = false;
MemoryCacheHelper.Get(key);
}
else
{
result = true;
MemoryCacheHelper.Set(key, value, TimeSpan.FromSeconds(second), true);
}
break;
}
return result;
}
public static async Task<IEnumerable<string>> GetAllKeyAsync<V>()
{
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
return await BaseHelper.KeysAsync("SqlSugarDataCache.*");
case Define.CACHEPROVIDER_MEMORY:
return MemoryCacheHelper.GetCacheKeys();
default:
return MemoryCacheHelper.GetCacheKeys();
}
}
public static IEnumerable<string> GetAllKey<V>()
{
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
return BaseHelper.Keys("SqlSugarDataCache.*");
case Define.CACHEPROVIDER_MEMORY:
return MemoryCacheHelper.GetCacheKeys();
default:
return MemoryCacheHelper.GetCacheKeys();
}
}
}
}

View File

@@ -0,0 +1,244 @@
using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
namespace WaterCloud.Code
{
/// <summary>
/// 缓存帮助类
/// </summary>
public class MemoryCacheHelper
{
private static readonly MemoryCache Cache = new MemoryCache(new MemoryCacheOptions());
/// <summary>
/// 验证缓存项是否存在
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public static bool Exists(string key)
{
if (key == null)
throw new ArgumentNullException(nameof(key));
return Cache.TryGetValue(key, out _);
}
/// <summary>
/// 添加缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="value">缓存Value</param>
/// <param name="expiresSliding">滑动过期时长(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>
/// <param name="expiressAbsoulte">绝对过期时长</param>
/// <returns></returns>
public static bool Set(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte)
{
if (key == null)
throw new ArgumentNullException(nameof(key));
if (value == null)
throw new ArgumentNullException(nameof(value));
Cache.Set(key, value.ToJson(),
new MemoryCacheEntryOptions().SetSlidingExpiration(expiresSliding)
.SetAbsoluteExpiration(expiressAbsoulte));
return Exists(key);
}
/// <summary>
/// 添加缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="value">缓存Value</param>
/// <param name="expiresIn">缓存时长</param>
/// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>
/// <returns></returns>
public static bool Set(string key, object value, TimeSpan expiresIn, bool isSliding = false)
{
if (key == null)
throw new ArgumentNullException(nameof(key));
if (value == null)
throw new ArgumentNullException(nameof(value));
Cache.Set(key, value.ToJson(),
isSliding
? new MemoryCacheEntryOptions().SetSlidingExpiration(expiresIn)
: new MemoryCacheEntryOptions().SetAbsoluteExpiration(expiresIn));
return Exists(key);
}
/// <summary>
/// 添加缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="value">缓存Value</param>
/// <returns></returns>
public static bool Set(string key, object value)
{
if (key == null)
throw new ArgumentNullException(nameof(key));
if (value == null)
throw new ArgumentNullException(nameof(value));
Cache.Set(key, value.ToJson());
return Exists(key);
}
#region
/// <summary>
/// 删除缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public static void Remove(string key)
{
if (key == null)
throw new ArgumentNullException(nameof(key));
Cache.Remove(key);
}
/// <summary>
/// 批量删除缓存
/// </summary>
/// <returns></returns>
public static void RemoveAll(IEnumerable<string> keys)
{
if (keys == null)
throw new ArgumentNullException(nameof(keys));
keys.ToList().ForEach(item => Cache.Remove(item));
}
#endregion
#region
/// <summary>
/// 获取缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public static T Get<T>(string key)
{
if (key == null)
throw new ArgumentNullException(nameof(key));
object temp;
if (Cache.TryGetValue(key, out temp))
{
return temp.ToString().ToObject<T>();
}
return default(T);
}
/// <summary>
/// 获取缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public static string Get(string key)
{
if (key == null)
throw new ArgumentNullException(nameof(key));
if (Cache.Get(key) == null)
{
return string.Empty;
}
return Cache.Get(key).ToString();
}
/// <summary>
/// 获取缓存集合
/// </summary>
/// <param name="keys">缓存Key集合</param>
/// <returns></returns>
public static IDictionary<string, object> GetAll(IEnumerable<string> keys)
{
if (keys == null)
throw new ArgumentNullException(nameof(keys));
var dict = new Dictionary<string, object>();
keys.ToList().ForEach(item => dict.Add(item, Cache.Get(item)));
return dict;
}
#endregion
/// <summary>
/// 删除所有缓存
/// </summary>
public static void RemoveCacheAll()
{
var l = GetCacheKeys();
foreach (var s in l)
{
Remove(s);
}
}
/// <summary>
/// 删除匹配到的缓存
/// </summary>
/// <param name="pattern"></param>
/// <returns></returns>
public static void RemoveCacheRegex(string pattern)
{
IEnumerable<string> l = SearchCacheRegex(pattern);
foreach (var s in l)
{
Remove(s);
}
}
/// <summary>
/// 搜索 匹配到的缓存
/// </summary>
/// <param name="pattern"></param>
/// <returns></returns>
public static IEnumerable<string> SearchCacheRegex(string pattern)
{
var cacheKeys = GetCacheKeys();
var l = cacheKeys.Where(k => Regex.IsMatch(k, pattern)).ToList();
return l.AsReadOnly();
}
/// <summary>
/// 获取所有缓存键
/// </summary>
/// <returns></returns>
public static List<string> GetCacheKeys()
{
#if NET8_0
const BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
var entries = Cache.GetType().GetField("_coherentState", flags)?.GetValue(Cache);
var cacheItems = entries?.GetType()?.GetProperty("EntriesCollection", flags)?.GetValue(entries) as ICollection; //entries as IDictionary;
var keys = new List<string>();
if (cacheItems == null) return keys;
foreach (var item in cacheItems)
{
var methodInfo = item.GetType().GetProperty("Key");
var val = methodInfo.GetValue(item);
keys.Add(val.ToString());
}
return keys;
#else
const BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
var entries = Cache.GetType().GetField("_entries", flags).GetValue(Cache);
var cacheItems = entries as IDictionary;
var keys = new List<string>();
if (cacheItems == null) return keys;
foreach (DictionaryEntry cacheItem in cacheItems)
{
keys.Add(cacheItem.Key.ToString());
}
return keys;
#endif
}
}
}

View File

@@ -0,0 +1,368 @@
using Autofac;
using CSRedis;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.ResponseCompression;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using Serenity.Abstractions;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Text.Encodings.Web;
using System.Text.Unicode;
using WaterCloud.Code.Model;
namespace WaterCloud.Code
{
public class DefaultStartUp
{
protected IConfiguration Configuration { get; set; }
protected IWebHostEnvironment WebHostEnvironment { get; set; }
public DefaultStartUp(IConfiguration configuration, IWebHostEnvironment env)
{
Configuration = configuration;
WebHostEnvironment = env;
GlobalContext.LogWhenStart(env);
GlobalContext.HostingEnvironment = env;
}
public virtual void ConfigureServices(IServiceCollection services)
{
var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
//没有设置环境变量就默认生产环境
if (string.IsNullOrWhiteSpace(environment))
environment = "Production";
Configuration = new ConfigurationBuilder().AddJsonFile($"appsettings.{environment}.json", optional: true, reloadOnChange: true).Build();
GlobalContext.SystemConfig = Configuration.GetSection("SystemConfig").Get<SystemConfig>();
GlobalContext.Services = services;
GlobalContext.Configuration = Configuration;
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
//解决session问题
services.AddSession(options =>
{
options.Cookie.IsEssential = true;//是否强制存储cookie
options.Cookie.SameSite = SameSiteMode.None;
});
//代替HttpContext.Current
services.AddHttpContextAccessor();
//缓存缓存选择
if (GlobalContext.SystemConfig.CacheProvider != Define.CACHEPROVIDER_REDIS)
{
services.AddMemoryCache();
}
else
{
//redis 注入服务
string redisConnectiong = GlobalContext.SystemConfig.RedisConnectionString;
// 多客户端 1、基础 2、操作日志
var redisDB1 = new CSRedisClient(redisConnectiong + ",defaultDatabase=" + 0);
BaseHelper.Initialization(redisDB1);
var redisDB2 = new CSRedisClient(redisConnectiong + ",defaultDatabase=" + 1);
HandleLogHelper.Initialization(redisDB2);
services.AddSingleton(redisDB1);
services.AddSingleton(redisDB2);
}
//连续guid初始化,示例IDGen.NextId()
services.AddSingleton<IDistributedIDGenerator, SequentialGuidIDGenerator>();
services.AddCors(options => options.AddPolicy("CorsPolicy",
builder =>
{
builder.AllowAnyMethod().AllowAnyHeader()
.WithOrigins(GlobalContext.SystemConfig.AllowCorsSite.Split(","))
.AllowCredentials();
}));
services.AddOptions();
services.AddHttpClient();
services.AddAntiforgery(options => options.HeaderName = "X-CSRF-TOKEN");
services.AddControllersWithViews().AddControllersAsServices();
//启用 Gzip 和 Brotil 压缩功能
services.AddResponseCompression(options =>
{
options.Providers.Add<BrotliCompressionProvider>();
options.Providers.Add<GzipCompressionProvider>();
options.MimeTypes =
ResponseCompressionDefaults.MimeTypes.Concat(
new[] { "image/svg+xml" });
});
services.Configure<BrotliCompressionProviderOptions>(options =>
{
options.Level = CompressionLevel.SmallestSize;
});
services.AddDataProtection().PersistKeysToFileSystem(new DirectoryInfo(GlobalContext.HostingEnvironment.ContentRootPath + Path.DirectorySeparatorChar + "DataProtection"));
}
/// <summary>
/// Autofac配置
/// </summary>
/// <param name="builder"></param>
/// <param name="projects">扫描程序</param>
/// <param name="controller">控制器</param>
/// <param name="IService">服务接口</param>
/// <param name="program">程序</param>
public void AutofacConfigureContainer(ContainerBuilder builder, List<string> projects, Type controller, Type IService, Type program)
{
if (projects == null)
{
projects = new List<string>();
}
var baseType = IService;//IDenpendency 是一个接口(所有要实现依赖注入的借口都要继承该接口)
var controllerBaseType = controller;
foreach (var item in projects)
{
var assemblys = Assembly.Load(item);//Service是继承接口的实现方法类库名称
builder.RegisterAssemblyTypes(assemblys).Where(m => baseType.IsAssignableFrom(m) && m != baseType)
.InstancePerLifetimeScope()//生命周期,这里没有使用接口方式
.PropertiesAutowired();//属性注入
//插件Controller中使用属性注入
builder.RegisterAssemblyTypes(assemblys)
.Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType)
.PropertiesAutowired();
}
//Controller中使用属性注入
builder.RegisterAssemblyTypes(program.Assembly)
.Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType)
.PropertiesAutowired();
//注册html解析
builder.RegisterInstance(HtmlEncoder.Create(UnicodeRanges.All)).SingleInstance();
}
public virtual void Configure(IApplicationBuilder app)
{
GlobalContext.RootServices = app.ApplicationServices;
//实时通讯跨域
app.UseCors("CorsPolicy");
if (WebHostEnvironment.IsDevelopment())
{
GlobalContext.SystemConfig.Debug = true;
app.UseDeveloperExceptionPage();
}
else
{
app.UseDeveloperExceptionPage();
}
//文件地址Resource
//静态资源wwwroot
app.UseStaticFiles(new StaticFileOptions
{
ContentTypeProvider = new CustomerFileExtensionContentTypeProvider(),
OnPrepareResponse = GlobalContext.SetCacheControl
});
//启用 Gzip 和 Brotil 压缩功能
app.UseResponseCompression();
app.Use(async (context, next) =>
{
context.Request.EnableBuffering();
// 执行下一个中间件
await next.Invoke();
// 释放所有未托管的服务提供器
GlobalContext.DisposeUnmanagedObjects();
});
//session
app.UseSession();
//路径
app.UseRouting();
}
}
/// <summary>
/// StartUp扩展
/// </summary>
public static class StartUpExtends
{
/// <summary>
/// 默认MVC配置
/// </summary>
/// <param name="services"></param>
/// <returns></returns>
public static IMvcBuilder AddDefaultMVC(this IServiceCollection services)
{
return services.AddControllersWithViews(options =>
{
options.Filters.Add<GlobalExceptionFilter>();
options.Filters.Add<ModelActionFilter>();
options.ModelMetadataDetailsProviders.Add(new ModelBindingMetadataProvider());
//options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});
}
/// <summary>
/// 默认API配置
/// </summary>
/// <param name="services"></param>
/// <returns></returns>
public static IMvcBuilder AddDefaultAPI(this IServiceCollection services)
{
services.AddDirectoryBrowser();
return services.AddControllers(options =>
{
options.Filters.Add<ModelActionFilter>();
options.ModelMetadataDetailsProviders.Add(new ModelBindingMetadataProvider());
}).ConfigureApiBehaviorOptions(options =>
{
options.SuppressModelStateInvalidFilter = true;
});
}
/// <summary>
/// 默认API配置
/// </summary>
/// <param name="services"></param>
/// <returns></returns>
public static IServiceCollection AddDefaultSwaggerGen(this IServiceCollection services, string name)
{
services.AddSwaggerGen(config =>
{
foreach (var item in GlobalContext.SystemConfig.DocumentSettings.GroupOpenApiInfos)
{
config.SwaggerDoc($"{item.Group}", new OpenApiInfo { Title = item.Title, Version = item.Version, Description = item.Description });
}
var xmlFile = $"{name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
config.IncludeXmlComments(xmlPath, true); //添加控制器层注释true表示显示控制器注释
config.AddSecurityDefinition(GlobalContext.SystemConfig.TokenName, new OpenApiSecurityScheme
{
Description = "header token",
Name = GlobalContext.SystemConfig.TokenName,
In = ParameterLocation.Header,
Scheme = "",
Type = SecuritySchemeType.ApiKey,//设置类型
BearerFormat = ""
});
config.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = GlobalContext.SystemConfig.TokenName }
},
new List<string>()
}
});
});
return services;
}
/// <summary>
/// 默认API配置
/// </summary>
/// <param name="services"></param>
/// <returns></returns>
public static IApplicationBuilder AddDefaultSwaggerGen(this IApplicationBuilder app)
{
app.UseSwagger(c =>
{
c.RouteTemplate = "api-doc/{documentName}/swagger.json";
});
app.UseSwaggerUI(c =>
{
c.RoutePrefix = "api-doc";
foreach (var item in GlobalContext.SystemConfig.DocumentSettings.GroupOpenApiInfos)
{
c.SwaggerEndpoint($"{item.Group}/swagger.json", $"{item.Title}");
}
});
return app;
}
/// <summary>
/// 注入RabbitMq
/// </summary>
/// <param name="this"></param>
/// <param name="configuration">json配置</param>
/// <param name="lifeTime">生命周期,默认:单例模式</param>
/// <returns></returns>
public static IServiceCollection AddRabbitMq(
this IServiceCollection @this,
ServiceLifetime lifeTime = ServiceLifetime.Singleton)
{
if (GlobalContext.SystemConfig.RabbitMq.Enabled == false)
return @this;
switch (lifeTime)
{
case ServiceLifetime.Singleton:
@this.AddSingleton(x => new RabbitMqHelper(GlobalContext.SystemConfig.RabbitMq));
break;
case ServiceLifetime.Scoped:
@this.AddScoped(x => new RabbitMqHelper(GlobalContext.SystemConfig.RabbitMq));
break;
case ServiceLifetime.Transient:
@this.AddTransient(x => new RabbitMqHelper(GlobalContext.SystemConfig.RabbitMq));
break;
default:
break;
}
return @this;
}
#region AddWorkerService
/// <summary>
/// 自动注入 继承 BackgroundService 的后台服务
/// </summary>
/// <param name="this"></param>
/// <returns></returns>
public static IServiceCollection AddWorkerService(
this IServiceCollection @this)
{
var ret = new List<Type>();
var assemblies = Directory.GetFiles(AppContext.BaseDirectory, "WaterCloud.*.dll")
.Select(x => x.Substring(@"\").Substring(@"/").Replace(".dll", ""))
.Select(x => Assembly.Load(x)).ToArray();
//排除列表
var ignoreList= new List<string>{ "EventBusHostedService" };
foreach (var item in assemblies)
{
ret.AddRange(item.GetTypes() //获取当前类库下所有类型
.Where(t => typeof(BackgroundService).IsAssignableFrom(t)) //获取间接或直接继承t的所有类型
.Where(t => !t.IsAbstract && t.IsClass && !ignoreList.Contains(t.Name)));//获取非抽象类 排除接口继承
}
foreach (var item in ret)
{
@this.AddTransient(typeof(IHostedService), item);
}
return @this;
}
#endregion AddWorkerService
#region AddIf
/// <summary>
/// 根据条件注入服务
/// </summary>
/// <param name="this"></param>
/// <param name="condition"></param>
/// <param name="action"></param>
/// <returns></returns>
public static IServiceCollection AddIf(
this IServiceCollection @this,
bool condition,
Action<IServiceCollection> action)
{
if (condition && action != null)
action(@this);
return @this;
}
#endregion AddIf
}
}

View File

@@ -0,0 +1,40 @@
// -----------------------------------------------------------------------------
// 让 .NET 开发更简单,更通用,更流行。
// Copyright © 2020-2021 Furion, 百小僧, Baiqian Co.,Ltd.
//
// 框架名称Furion
// 框架作者:百小僧
// 框架版本2.7.9
// 源码地址Gitee https://gitee.com/dotnetchina/Furion
// Githubhttps://github.com/monksoul/Furion
// 开源协议Apache-2.0https://gitee.com/dotnetchina/Furion/blob/master/LICENSE
// -----------------------------------------------------------------------------
using System.ComponentModel;
namespace WaterCloud.Code
{
/// <summary>
/// 连续 GUID 类型选项
/// </summary>
public enum SequentialGuidType
{
/// <summary>
/// 标准连续 GUID 字符串
/// </summary>
[Description("标准连续 GUID 字符串")]
SequentialAsString,
/// <summary>
/// Byte 数组类型的连续 `GUID` 字符串
/// </summary>
[Description("Byte 数组类型的连续 `GUID` 字符串")]
SequentialAsBinary,
/// <summary>
/// 连续部分在末尾展示
/// </summary>
[Description("连续部分在末尾展示")]
SequentialAtEnd
}
}

View File

@@ -0,0 +1,27 @@
// -----------------------------------------------------------------------------
// 让 .NET 开发更简单,更通用,更流行。
// Copyright © 2020-2021 Furion, 百小僧, Baiqian Co.,Ltd.
//
// 框架名称Furion
// 框架作者:百小僧
// 框架版本2.7.9
// 源码地址Gitee https://gitee.com/dotnetchina/Furion
// Githubhttps://github.com/monksoul/Furion
// 开源协议Apache-2.0https://gitee.com/dotnetchina/Furion/blob/master/LICENSE
// -----------------------------------------------------------------------------
namespace WaterCloud.Code
{
/// <summary>
/// 分布式 ID 生成器
/// </summary>
public interface IDistributedIDGenerator
{
/// <summary>
/// 生成逻辑
/// </summary>
/// <param name="idGeneratorOptions"></param>
/// <returns></returns>
object Create(object idGeneratorOptions = default);
}
}

View File

@@ -0,0 +1,86 @@
// -----------------------------------------------------------------------------
// 让 .NET 开发更简单,更通用,更流行。
// Copyright © 2020-2021 Furion, 百小僧, Baiqian Co.,Ltd.
//
// 框架名称Furion
// 框架作者:百小僧
// 框架版本2.7.9
// 源码地址Gitee https://gitee.com/dotnetchina/Furion
// Githubhttps://github.com/monksoul/Furion
// 开源协议Apache-2.0https://gitee.com/dotnetchina/Furion/blob/master/LICENSE
// -----------------------------------------------------------------------------
using System;
using System.Security.Cryptography;
namespace WaterCloud.Code
{
/// <summary>
/// 连续 GUID ID 生成器
/// <para>代码参考自https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql/blob/ebe011a6f1b2a2a9709fe558cfc7ed3215b55c37/src/EFCore.MySql/ValueGeneration/Internal/MySqlSequentialGuidValueGenerator.cs </para>
/// </summary>
public class SequentialGuidIDGenerator : IDistributedIDGenerator
{
/// <summary>
/// 随机数生成器
/// </summary>
private static readonly RandomNumberGenerator _rng = RandomNumberGenerator.Create();
/// <summary>
/// 生成逻辑
/// </summary>
/// <param name="idGeneratorOptions"></param>
/// <returns></returns>
public object Create(object idGeneratorOptions = null)
{
// According to RFC 4122:
// dddddddd-dddd-Mddd-Ndrr-rrrrrrrrrrrr
// - M = RFC version, in this case '4' for random UUID
// - N = RFC variant (plus other bits), in this case 0b1000 for variant 1
// - d = nibbles based on UTC date/time in ticks
// - r = nibbles based on random bytes
var options = (idGeneratorOptions ?? new SequentialGuidSettings()) as SequentialGuidSettings;
var randomBytes = new byte[7];
_rng.GetBytes(randomBytes);
var ticks = (ulong)options.TimeNow.Ticks;
var uuidVersion = (ushort)4;
var uuidVariant = (ushort)0b1000;
var ticksAndVersion = (ushort)((ticks << 48 >> 52) | (ushort)(uuidVersion << 12));
var ticksAndVariant = (byte)((ticks << 60 >> 60) | (byte)(uuidVariant << 4));
if (options.LittleEndianBinary16Format)
{
var guidBytes = new byte[16];
var tickBytes = BitConverter.GetBytes(ticks);
if (BitConverter.IsLittleEndian)
{
Array.Reverse(tickBytes);
}
Buffer.BlockCopy(tickBytes, 0, guidBytes, 0, 6);
guidBytes[6] = (byte)(ticksAndVersion << 8 >> 8);
guidBytes[7] = (byte)(ticksAndVersion >> 8);
guidBytes[8] = ticksAndVariant;
Buffer.BlockCopy(randomBytes, 0, guidBytes, 9, 7);
return new Guid(guidBytes);
}
var guid = new Guid((uint)(ticks >> 32), (ushort)(ticks << 32 >> 48), ticksAndVersion,
ticksAndVariant,
randomBytes[0],
randomBytes[1],
randomBytes[2],
randomBytes[3],
randomBytes[4],
randomBytes[5],
randomBytes[6]);
return guid;
}
}
}

View File

@@ -0,0 +1,45 @@
// -----------------------------------------------------------------------------
// 让 .NET 开发更简单,更通用,更流行。
// Copyright © 2020-2021 Furion, 百小僧, Baiqian Co.,Ltd.
//
// 框架名称Furion
// 框架作者:百小僧
// 框架版本2.7.9
// 源码地址Gitee https://gitee.com/dotnetchina/Furion
// Githubhttps://github.com/monksoul/Furion
// 开源协议Apache-2.0https://gitee.com/dotnetchina/Furion/blob/master/LICENSE
// -----------------------------------------------------------------------------
using System;
namespace WaterCloud.Code
{
/// <summary>
/// ID 生成器
/// </summary>
public static class IDGen
{
/// <summary>
/// 生成唯一 ID
/// </summary>
/// <param name="idGeneratorOptions"></param>
/// <param name="serviceProvider"></param>
/// <returns></returns>
public static object NextID(object idGeneratorOptions)
{
return ((IDistributedIDGenerator)GlobalContext.RootServices.GetService(typeof(IDistributedIDGenerator))).Create(idGeneratorOptions);
}
/// <summary>
/// 生成连续 GUID
/// </summary>
/// <param name="guidType"></param>
/// <param name="serviceProvider"></param>
/// <returns></returns>
public static Guid NextID(SequentialGuidType guidType = SequentialGuidType.SequentialAsString)
{
var sequentialGuid = GlobalContext.RootServices.GetService(typeof(IDistributedIDGenerator)) as IDistributedIDGenerator;
return (Guid)sequentialGuid.Create();
}
}
}

View File

@@ -0,0 +1,32 @@
// -----------------------------------------------------------------------------
// 让 .NET 开发更简单,更通用,更流行。
// Copyright © 2020-2021 Furion, 百小僧, Baiqian Co.,Ltd.
//
// 框架名称Furion
// 框架作者:百小僧
// 框架版本2.7.9
// 源码地址Gitee https://gitee.com/dotnetchina/Furion
// Githubhttps://github.com/monksoul/Furion
// 开源协议Apache-2.0https://gitee.com/dotnetchina/Furion/blob/master/LICENSE
// -----------------------------------------------------------------------------
using System;
namespace WaterCloud.Code
{
/// <summary>
/// 连续 GUID 配置
/// </summary>
public sealed class SequentialGuidSettings
{
/// <summary>
/// 当前时间
/// </summary>
public DateTimeOffset TimeNow { get; set; } = DateTimeOffset.UtcNow;
/// <summary>
/// LittleEndianBinary 16 格式化
/// </summary>
public bool LittleEndianBinary16Format { get; set; } = false;
}
}

View File

@@ -0,0 +1,35 @@
// -----------------------------------------------------------------------------
// 让 .NET 开发更简单,更通用,更流行。
// Copyright © 2020-2021 Furion, 百小僧, Baiqian Co.,Ltd.
//
// 框架名称Furion
// 框架作者:百小僧
// 框架版本2.7.9
// 源码地址Gitee https://gitee.com/dotnetchina/Furion
// Githubhttps://github.com/monksoul/Furion
// 开源协议Apache-2.0https://gitee.com/dotnetchina/Furion/blob/master/LICENSE
// -----------------------------------------------------------------------------
namespace WaterCloud.Code
{
/// <summary>
/// 短 ID 约束
/// </summary>
internal static class Constants
{
/// <summary>
/// 最小长度
/// </summary>
public const int MinimumAutoLength = 8;
/// <summary>
/// 最大长度
/// </summary>
public const int MaximumAutoLength = 14;
/// <summary>
/// 最小可选字符长度
/// </summary>
public const int MinimumCharacterSetLength = 50;
}
}

View File

@@ -0,0 +1,46 @@
// -----------------------------------------------------------------------------
// 让 .NET 开发更简单,更通用,更流行。
// Copyright © 2020-2021 Furion, 百小僧, Baiqian Co.,Ltd.
//
// 框架名称Furion
// 框架作者:百小僧
// 框架版本2.7.9
// 源码地址Gitee https://gitee.com/dotnetchina/Furion
// Githubhttps://github.com/monksoul/Furion
// 开源协议Apache-2.0https://gitee.com/dotnetchina/Furion/blob/master/LICENSE
// -----------------------------------------------------------------------------
using System;
namespace WaterCloud.Code
{
/// <summary>
/// 随机数帮助类
/// </summary>
internal static class RandomHelpers
{
/// <summary>
/// 随机数对象
/// </summary>
private static readonly Random Random = new();
/// <summary>
/// 线程锁
/// </summary>
private static readonly object ThreadLock = new();
/// <summary>
/// 生成线程安全的范围内随机数
/// </summary>
/// <param name="min"></param>
/// <param name="max"></param>
/// <returns></returns>
public static int GenerateNumberInRange(int min, int max)
{
lock (ThreadLock)
{
return Random.Next(min, max);
}
}
}
}

View File

@@ -0,0 +1,37 @@
// -----------------------------------------------------------------------------
// 让 .NET 开发更简单,更通用,更流行。
// Copyright © 2020-2021 Furion, 百小僧, Baiqian Co.,Ltd.
//
// 框架名称Furion
// 框架作者:百小僧
// 框架版本2.7.9
// 源码地址Gitee https://gitee.com/dotnetchina/Furion
// Githubhttps://github.com/monksoul/Furion
// 开源协议Apache-2.0https://gitee.com/dotnetchina/Furion/blob/master/LICENSE
// -----------------------------------------------------------------------------
namespace WaterCloud.Code
{
/// <summary>
/// 短 ID 生成配置选项
/// </summary>
public class GenerationOptions
{
/// <summary>
/// 是否使用数字
/// <para>默认 false</para>
/// </summary>
public bool UseNumbers { get; set; }
/// <summary>
/// 是否使用特殊字符
/// <para>默认 true</para>
/// </summary>
public bool UseSpecialCharacters { get; set; } = true;
/// <summary>
/// 设置短 ID 长度
/// </summary>
public int Length { get; set; } = RandomHelpers.GenerateNumberInRange(Constants.MinimumAutoLength, Constants.MaximumAutoLength);
}
}

View File

@@ -0,0 +1,161 @@
// -----------------------------------------------------------------------------
// 让 .NET 开发更简单,更通用,更流行。
// Copyright © 2020-2021 Furion, 百小僧, Baiqian Co.,Ltd.
//
// 框架名称Furion
// 框架作者:百小僧
// 框架版本2.7.9
// 源码地址Gitee https://gitee.com/dotnetchina/Furion
// Githubhttps://github.com/monksoul/Furion
// 开源协议Apache-2.0https://gitee.com/dotnetchina/Furion/blob/master/LICENSE
// -----------------------------------------------------------------------------
using System;
using System.Linq;
using System.Text;
namespace WaterCloud.Code
{
/// <summary>
/// 短 ID 生成核心代码
/// <para>代码参考自https://github.com/bolorundurowb/shortid </para>
/// </summary>
public static class ShortIDGen
{
/// <summary>
/// 短 ID 生成器期初数据
/// </summary>
private static Random _random = new();
private const string Bigs = "ABCDEFGHIJKLMNPQRSTUVWXY";
private const string Smalls = "abcdefghjklmnopqrstuvwxyz";
private const string Numbers = "0123456789";
private const string Specials = "_-";
private static string _pool = $"{Smalls}{Bigs}";
/// <summary>
/// 线程安全锁
/// </summary>
private static readonly object ThreadLock = new();
/// <summary>
/// 生成目前比较主流的短 ID
/// <para>包含字母、数字,不包含特殊字符</para>
/// <para>默认生成 8 位</para>
/// </summary>
/// <returns></returns>
public static string NextID()
{
return NextID(new GenerationOptions
{
UseNumbers = true,
UseSpecialCharacters = false,
Length = 8
});
}
/// <summary>
/// 生成短 ID
/// </summary>
/// <param name="options"></param>
/// <returns></returns>
public static string NextID(GenerationOptions options)
{
// 配置必填
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
// 判断生成的长度是否小于规定的长度,规定为 8
if (options.Length < Constants.MinimumAutoLength)
{
throw new ArgumentException(
$"The specified length of {options.Length} is less than the lower limit of {Constants.MinimumAutoLength} to avoid conflicts.");
}
var characterPool = _pool;
var poolBuilder = new StringBuilder(characterPool);
// 是否包含数字
if (options.UseNumbers)
{
poolBuilder.Append(Numbers);
}
// 是否包含特殊字符
if (options.UseSpecialCharacters)
{
poolBuilder.Append(Specials);
}
var pool = poolBuilder.ToString();
// 生成拼接
var output = new char[options.Length];
for (var i = 0; i < options.Length; i++)
{
lock (ThreadLock)
{
var charIndex = _random.Next(0, pool.Length);
output[i] = pool[charIndex];
}
}
return new string(output);
}
/// <summary>
/// 设置参与运算的字符,最少 50 位
/// </summary>
/// <param name="characters"></param>
public static void SetCharacters(string characters)
{
if (string.IsNullOrWhiteSpace(characters))
{
throw new ArgumentException("The replacement characters must not be null or empty.");
}
var charSet = characters
.ToCharArray()
.Where(x => !char.IsWhiteSpace(x))
.Distinct()
.ToArray();
if (charSet.Length < Constants.MinimumCharacterSetLength)
{
throw new InvalidOperationException(
$"The replacement characters must be at least {Constants.MinimumCharacterSetLength} letters in length and without whitespace.");
}
lock (ThreadLock)
{
_pool = new string(charSet);
}
}
/// <summary>
/// 设置种子步长
/// </summary>
/// <param name="seed"></param>
public static void SetSeed(int seed)
{
lock (ThreadLock)
{
_random = new Random(seed);
}
}
/// <summary>
/// 重置所有配置
/// </summary>
public static void Reset()
{
lock (ThreadLock)
{
_random = new Random();
_pool = $"{Smalls}{Bigs}";
}
}
}
}

View File

@@ -0,0 +1,788 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System;
using System.Collections;
using System.Collections.Generic;
namespace WaterCloud.Code
{
public static partial class Extensions
{
#region
/// <summary>
/// 转换为整型
/// </summary>
/// <param name="data">数据</param>
public static int ToInt(this object data)
{
if (data == null)
return 0;
int result;
var success = int.TryParse(data.ToString(), out result);
if (success)
return result;
try
{
return Convert.ToInt32(ToDouble(data, 0));
}
catch (Exception)
{
return 0;
}
}
/// <summary>
/// 将object转换为long若转换失败则返回0。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static long ToLong(this object obj)
{
try
{
return long.Parse(obj.ToString());
}
catch
{
return 0L;
}
}
/// <summary>
/// 转换为可空整型
/// </summary>
/// <param name="data">数据</param>
public static int? ToIntOrNull(this object data)
{
if (data == null)
return null;
int result;
bool isValid = int.TryParse(data.ToString(), out result);
if (isValid)
return result;
return null;
}
/// <summary>
/// 转换为双精度浮点数
/// </summary>
/// <param name="data">数据</param>
public static double ToDouble(this object data)
{
if (data == null)
return 0;
double result;
return double.TryParse(data.ToString(), out result) ? result : 0;
}
/// <summary>
/// 转换为双精度浮点数,并按指定的小数位4舍5入
/// </summary>
/// <param name="data">数据</param>
/// <param name="digits">小数位数</param>
public static double ToDouble(this object data, int digits)
{
return Math.Round(ToDouble(data), digits);
}
/// <summary>
/// 转换为可空双精度浮点数
/// </summary>
/// <param name="data">数据</param>
public static double? ToDoubleOrNull(this object data)
{
if (data == null)
return null;
double result;
bool isValid = double.TryParse(data.ToString(), out result);
if (isValid)
return result;
return null;
}
/// <summary>
/// 转换为高精度浮点数
/// </summary>
/// <param name="data">数据</param>
public static decimal ToDecimal(this object data)
{
if (data == null)
return 0;
decimal result;
return decimal.TryParse(data.ToString(), out result) ? result : 0;
}
/// <summary>
/// 转换为高精度浮点数,并按指定的小数位4舍5入
/// </summary>
/// <param name="data">数据</param>
/// <param name="digits">小数位数</param>
public static decimal ToDecimal(this object data, int digits)
{
return Math.Round(ToDecimal(data), digits);
}
/// <summary>
/// 转换为可空高精度浮点数
/// </summary>
/// <param name="data">数据</param>
public static decimal? ToDecimalOrNull(this object data)
{
if (data == null)
return null;
decimal result;
bool isValid = decimal.TryParse(data.ToString(), out result);
if (isValid)
return result;
return null;
}
/// <summary>
/// 转换为可空高精度浮点数,并按指定的小数位4舍5入
/// </summary>
/// <param name="data">数据</param>
/// <param name="digits">小数位数</param>
public static decimal? ToDecimalOrNull(this object data, int digits)
{
var result = ToDecimalOrNull(data);
if (result == null)
return null;
return Math.Round(result.Value, digits);
}
#endregion
#region
/// <summary>
/// 转换为日期
/// </summary>
/// <param name="data">数据</param>
public static DateTime ToDate(this object data)
{
if (data == null)
return DateTime.MinValue;
DateTime result;
return DateTime.TryParse(data.ToString(), out result) ? result : DateTime.MinValue;
}
/// <summary>
/// 转换为可空日期
/// </summary>
/// <param name="data">数据</param>
public static DateTime? ToDateOrNull(this object data)
{
if (data == null)
return null;
DateTime result;
bool isValid = DateTime.TryParse(data.ToString(), out result);
if (isValid)
return result;
return null;
}
#endregion
#region
/// <summary>
/// 转换为布尔值
/// </summary>
/// <param name="data">数据</param>
public static bool ToBool(this object data)
{
if (data == null)
return false;
bool? value = GetBool(data);
if (value != null)
return value.Value;
bool result;
return bool.TryParse(data.ToString(), out result) && result;
}
/// <summary>
/// 获取布尔值
/// </summary>
private static bool? GetBool(this object data)
{
switch (data.ToString().Trim().ToLower())
{
case "0":
return false;
case "1":
return true;
case "是":
return true;
case "否":
return false;
case "yes":
return true;
case "no":
return false;
default:
return null;
}
}
/// <summary>
/// 转换为可空布尔值
/// </summary>
/// <param name="data">数据</param>
public static bool? ToBoolOrNull(this object data)
{
if (data == null)
return null;
bool? value = GetBool(data);
if (value != null)
return value.Value;
bool result;
bool isValid = bool.TryParse(data.ToString(), out result);
if (isValid)
return result;
return null;
}
#endregion
#region
/// <summary>
/// 是否为空
/// </summary>
/// <param name="value">值</param>
public static bool IsEmpty(this string value)
{
return string.IsNullOrWhiteSpace(value);
}
/// <summary>
/// 是否为空
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static bool IsEmpty(this object value)
{
if (value != null && !string.IsNullOrEmpty(value.ToString()))
{
return false;
}
else
{
return true;
}
}
/// <summary>
/// 是否为空
/// </summary>
/// <param name="value">值</param>
public static bool IsEmpty(this Guid? value)
{
if (value == null)
return true;
return IsEmpty(value.Value);
}
/// <summary>
/// 是否为空
/// </summary>
/// <param name="value">值</param>
public static bool IsEmpty(this Guid value)
{
if (value == Guid.Empty)
return true;
return false;
}
#endregion
#region
/// <summary>
/// 强制转换类型
/// </summary>
/// <typeparam name="TResult"></typeparam>
/// <param name="source"></param>
/// <returns></returns>
public static IEnumerable<TResult> CastSuper<TResult>(this IEnumerable source)
{
foreach (object item in source)
{
yield return (TResult)Convert.ChangeType(item, typeof(TResult));
}
}
#endregion
#region long
/// <summary>
/// 将object转换为long若转换失败则返回0。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static long ParseToLong(this object obj)
{
try
{
return long.Parse(obj.ToString());
}
catch
{
return 0L;
}
}
/// <summary>
/// 将object转换为long若转换失败则返回指定值。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static long ParseToLong(this string str, long defaultValue)
{
try
{
return long.Parse(str);
}
catch
{
return defaultValue;
}
}
#endregion long
#region int
/// <summary>
/// 将object转换为int若转换失败则返回0。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static int ParseToInt(this object str)
{
try
{
return Convert.ToInt32(str);
}
catch
{
return 0;
}
}
/// <summary>
/// 将object转换为int若转换失败则返回指定值。不抛出异常。
/// null返回默认值
/// </summary>
/// <param name="str"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static int ParseToInt(this object str, int defaultValue)
{
if (str == null)
{
return defaultValue;
}
try
{
return Convert.ToInt32(str);
}
catch
{
return defaultValue;
}
}
#endregion int
#region short
/// <summary>
/// 将object转换为short若转换失败则返回0。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static short ParseToShort(this object obj)
{
try
{
return short.Parse(obj.ToString());
}
catch
{
return 0;
}
}
/// <summary>
/// 将object转换为short若转换失败则返回指定值。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static short ParseToShort(this object str, short defaultValue)
{
try
{
return short.Parse(str.ToString());
}
catch
{
return defaultValue;
}
}
#endregion short
#region demical
/// <summary>
/// 将object转换为demical若转换失败则返回指定值。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static decimal ParseToDecimal(this object str, decimal defaultValue)
{
try
{
return decimal.Parse(str.ToString());
}
catch
{
return defaultValue;
}
}
/// <summary>
/// 将object转换为demical若转换失败则返回0。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static decimal ParseToDecimal(this object str)
{
try
{
return decimal.Parse(str.ToString());
}
catch
{
return 0;
}
}
#endregion demical
#region bool
/// <summary>
/// 将object转换为bool若转换失败则返回false。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static bool ParseToBool(this object str)
{
try
{
return bool.Parse(str.ToString());
}
catch
{
return false;
}
}
/// <summary>
/// 将object转换为bool若转换失败则返回指定值。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static bool ParseToBool(this object str, bool result)
{
try
{
return bool.Parse(str.ToString());
}
catch
{
return result;
}
}
#endregion bool
#region float
/// <summary>
/// 将object转换为float若转换失败则返回0。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static float ParseToFloat(this object str)
{
try
{
return float.Parse(str.ToString());
}
catch
{
return 0;
}
}
/// <summary>
/// 将object转换为float若转换失败则返回指定值。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static float ParseToFloat(this object str, float result)
{
try
{
return float.Parse(str.ToString());
}
catch
{
return result;
}
}
#endregion float
#region Guid
/// <summary>
/// 将string转换为Guid若转换失败则返回Guid.Empty。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static Guid ParseToGuid(this string str)
{
try
{
return new Guid(str);
}
catch
{
return Guid.Empty;
}
}
#endregion Guid
#region DateTime
/// <summary>
/// 将string转换为DateTime若转换失败则返回日期最小值。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static DateTime ParseToDateTime(this string str)
{
try
{
if (string.IsNullOrWhiteSpace(str))
{
return DateTime.MinValue;
}
if (str.Contains("-") || str.Contains("/"))
{
return DateTime.Parse(str);
}
else
{
int length = str.Length;
switch (length)
{
case 4:
return DateTime.ParseExact(str, "yyyy", System.Globalization.CultureInfo.CurrentCulture);
case 6:
return DateTime.ParseExact(str, "yyyyMM", System.Globalization.CultureInfo.CurrentCulture);
case 8:
return DateTime.ParseExact(str, "yyyyMMdd", System.Globalization.CultureInfo.CurrentCulture);
case 10:
return DateTime.ParseExact(str, "yyyyMMddHH", System.Globalization.CultureInfo.CurrentCulture);
case 12:
return DateTime.ParseExact(str, "yyyyMMddHHmm", System.Globalization.CultureInfo.CurrentCulture);
case 14:
return DateTime.ParseExact(str, "yyyyMMddHHmmss", System.Globalization.CultureInfo.CurrentCulture);
default:
return DateTime.ParseExact(str, "yyyyMMddHHmmss", System.Globalization.CultureInfo.CurrentCulture);
}
}
}
catch
{
return DateTime.MinValue;
}
}
/// <summary>
/// 将string转换为DateTime若转换失败则返回默认值。
/// </summary>
/// <param name="str"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static DateTime ParseToDateTime(this string str, DateTime? defaultValue)
{
try
{
if (string.IsNullOrWhiteSpace(str))
{
return defaultValue.GetValueOrDefault();
}
if (str.Contains("-") || str.Contains("/"))
{
return DateTime.Parse(str);
}
else
{
int length = str.Length;
switch (length)
{
case 4:
return DateTime.ParseExact(str, "yyyy", System.Globalization.CultureInfo.CurrentCulture);
case 6:
return DateTime.ParseExact(str, "yyyyMM", System.Globalization.CultureInfo.CurrentCulture);
case 8:
return DateTime.ParseExact(str, "yyyyMMdd", System.Globalization.CultureInfo.CurrentCulture);
case 10:
return DateTime.ParseExact(str, "yyyyMMddHH", System.Globalization.CultureInfo.CurrentCulture);
case 12:
return DateTime.ParseExact(str, "yyyyMMddHHmm", System.Globalization.CultureInfo.CurrentCulture);
case 14:
return DateTime.ParseExact(str, "yyyyMMddHHmmss", System.Globalization.CultureInfo.CurrentCulture);
default:
return DateTime.ParseExact(str, "yyyyMMddHHmmss", System.Globalization.CultureInfo.CurrentCulture);
}
}
}
catch
{
return defaultValue.GetValueOrDefault();
}
}
#endregion DateTime
#region string
/// <summary>
/// 将object转换为string若转换失败则返回""。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string ParseToString(this object obj)
{
try
{
if (obj == null)
{
return string.Empty;
}
else
{
return obj.ToString();
}
}
catch
{
return string.Empty;
}
}
public static string ParseToStrings<T>(this object obj)
{
try
{
var list = obj as IEnumerable<T>;
if (list != null)
{
return string.Join(",", list);
}
else
{
return obj.ToString();
}
}
catch
{
return string.Empty;
}
}
#endregion string
#region double
/// <summary>
/// 将object转换为double若转换失败则返回0。不抛出异常。
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static double ParseToDouble(this object obj)
{
try
{
return double.Parse(obj.ToString());
}
catch
{
return 0;
}
}
/// <summary>
/// 将object转换为double若转换失败则返回指定值。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static double ParseToDouble(this object str, double defaultValue)
{
try
{
return double.Parse(str.ToString());
}
catch
{
return defaultValue;
}
}
#endregion double
/// <summary>
/// 安全返回值
/// </summary>
/// <param name="value">可空值</param>
public static T SafeValue<T>(this T? value) where T : struct
{
return value ?? default(T);
}
}
}

View File

@@ -0,0 +1,187 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System;
using System.Text;
namespace WaterCloud.Code
{
public static partial class Extensions
{
/// <summary>
/// 获取格式化字符串,带时分秒,格式:"yyyy-MM-dd HH:mm:ss"
/// </summary>
/// <param name="dateTime">日期</param>
/// <param name="isRemoveSecond">是否移除秒</param>
public static string ToDateTimeString(this DateTime dateTime, bool isRemoveSecond = false)
{
if (isRemoveSecond)
return dateTime.ToString("yyyy-MM-dd HH:mm");
return dateTime.ToString("yyyy-MM-dd HH:mm:ss");
}
/// <summary>
/// 获取格式化字符串,带时分秒,格式:"yyyy-MM-dd HH:mm:ss"
/// </summary>
/// <param name="dateTime">日期</param>
/// <param name="isRemoveSecond">是否移除秒</param>
public static string ToDateTimeString(this DateTime? dateTime, bool isRemoveSecond = false)
{
if (dateTime == null)
return string.Empty;
return ToDateTimeString(dateTime.Value, isRemoveSecond);
}
/// <summary>
/// 获取格式化字符串,不带时分秒,格式:"yyyy-MM-dd"
/// </summary>
/// <param name="dateTime">日期</param>
public static string ToDateString(this DateTime dateTime)
{
return dateTime.ToString("yyyy-MM-dd");
}
/// <summary>
/// 获取格式化字符串,不带时分秒,格式:"yyyy-MM-dd"
/// </summary>
/// <param name="dateTime">日期</param>
public static string ToDateString()
{
return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
}
/// <summary>
/// 获取格式化字符串,不带时分秒,格式:"yyyy-MM-dd"
/// </summary>
/// <param name="dateTime">日期</param>
public static string ToDateString(this DateTime? dateTime)
{
if (dateTime == null)
return string.Empty;
return ToDateString(dateTime.Value);
}
/// <summary>
/// 获取格式化字符串,不带年月日,格式:"HH:mm:ss"
/// </summary>
/// <param name="dateTime">日期</param>
public static string ToTimeString(this DateTime dateTime)
{
return dateTime.ToString("HH:mm:ss");
}
/// <summary>
/// 获取格式化字符串,不带年月日,格式:"HH:mm:ss"
/// </summary>
/// <param name="dateTime">日期</param>
public static string ToTimeString(this DateTime? dateTime)
{
if (dateTime == null)
return string.Empty;
return ToTimeString(dateTime.Value);
}
/// <summary>
/// 获取格式化字符串,带毫秒,格式:"yyyy-MM-dd HH:mm:ss.fff"
/// </summary>
/// <param name="dateTime">日期</param>
public static string ToMillisecondString(this DateTime dateTime)
{
return dateTime.ToString("yyyy-MM-dd HH:mm:ss.fff");
}
/// <summary>
/// 获取格式化字符串,带毫秒,格式:"yyyy-MM-dd HH:mm:ss.fff"
/// </summary>
/// <param name="dateTime">日期</param>
public static string ToMillisecondString(this DateTime? dateTime)
{
if (dateTime == null)
return string.Empty;
return ToMillisecondString(dateTime.Value);
}
/// <summary>
/// 获取格式化字符串,不带时分秒,格式:"yyyy年MM月dd日"
/// </summary>
/// <param name="dateTime">日期</param>
public static string ToChineseDateString(this DateTime dateTime)
{
return string.Format("{0}年{1}月{2}日", dateTime.Year, dateTime.Month, dateTime.Day);
}
/// <summary>
/// 获取格式化字符串,不带时分秒,格式:"yyyy年MM月dd日"
/// </summary>
/// <param name="dateTime">日期</param>
public static string ToChineseDateString(this DateTime? dateTime)
{
if (dateTime == null)
return string.Empty;
return ToChineseDateString(dateTime.SafeValue());
}
/// <summary>
/// 获取格式化字符串,带时分秒,格式:"yyyy年MM月dd日 HH时mm分"
/// </summary>
/// <param name="dateTime">日期</param>
/// <param name="isRemoveSecond">是否移除秒</param>
public static string ToChineseDateTimeString(this DateTime dateTime, bool isRemoveSecond = false)
{
StringBuilder result = new StringBuilder();
result.AppendFormat("{0}年{1}月{2}日", dateTime.Year, dateTime.Month, dateTime.Day);
result.AppendFormat(" {0}时{1}分", dateTime.Hour, dateTime.Minute);
if (isRemoveSecond == false)
result.AppendFormat("{0}秒", dateTime.Second);
return result.ToString();
}
/// <summary>
/// 获取格式化字符串,带时分秒,格式:"yyyy年MM月dd日 HH时mm分"
/// </summary>
/// <param name="dateTime">日期</param>
/// <param name="isRemoveSecond">是否移除秒</param>
public static string ToChineseDateTimeString(this DateTime? dateTime, bool isRemoveSecond = false)
{
if (dateTime == null)
return string.Empty;
return ToChineseDateTimeString(dateTime.Value);
}
#region
/// <summary>
/// 毫秒转天时分秒
/// </summary>
/// <param name="ms"></param>
/// <returns></returns>
public static string FormatTime(long ms)
{
int ss = 1000;
int mi = ss * 60;
int hh = mi * 60;
int dd = hh * 24;
long day = ms / dd;
long hour = (ms - day * dd) / hh;
long minute = (ms - day * dd - hour * hh) / mi;
long second = (ms - day * dd - hour * hh - minute * mi) / ss;
long milliSecond = ms - day * dd - hour * hh - minute * mi - second * ss;
string sDay = day < 10 ? "0" + day : "" + day; //天
string sHour = hour < 10 ? "0" + hour : "" + hour;//小时
string sMinute = minute < 10 ? "0" + minute : "" + minute;//分钟
string sSecond = second < 10 ? "0" + second : "" + second;//秒
string sMilliSecond = milliSecond < 10 ? "0" + milliSecond : "" + milliSecond;//毫秒
sMilliSecond = milliSecond < 100 ? "0" + sMilliSecond : "" + sMilliSecond;
return string.Format("{0} 天 {1} 小时 {2} 分 {3} 秒", sDay, sHour, sMinute, sSecond);
}
#endregion
}
}

View File

@@ -0,0 +1,114 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
namespace WaterCloud.Code
{
public static partial class Extensions
{
#region dictionary类型
/// <summary>
/// 转成dictionary类型
/// </summary>
/// <param name="enumType"></param>
/// <returns></returns>
public static Dictionary<int, string> EnumToDictionary(this Type enumType)
{
Dictionary<int, string> dictionary = new Dictionary<int, string>();
Type typeDescription = typeof(DescriptionAttribute);
FieldInfo[] fields = enumType.GetFields();
int sValue = 0;
string sText = string.Empty;
foreach (FieldInfo field in fields)
{
if (field.FieldType.IsEnum)
{
sValue = ((int)enumType.InvokeMember(field.Name, BindingFlags.GetField, null, null, null));
object[] arr = field.GetCustomAttributes(typeDescription, true);
if (arr.Length > 0)
{
DescriptionAttribute da = (DescriptionAttribute)arr[0];
sText = da.Description;
}
else
{
sText = field.Name;
}
dictionary.Add(sValue, sText);
}
}
return dictionary;
}
/// <summary>
/// 枚举成员转成键值对Json字符串
/// </summary>
/// <param name="enumType"></param>
/// <returns></returns>
public static string EnumToDictionaryString(this Type enumType)
{
List<KeyValuePair<int, string>> dictionaryList = EnumToDictionary(enumType).ToList();
var sJson = JsonConvert.SerializeObject(dictionaryList);
return sJson;
}
#endregion dictionary类型
#region
/// <summary>
/// 获取枚举值对应的描述
/// </summary>
/// <param name="enumType"></param>
/// <returns></returns>
public static string GetDescription(this System.Enum enumType)
{
FieldInfo EnumInfo = enumType.GetType().GetField(enumType.ToString());
if (EnumInfo != null)
{
DescriptionAttribute[] EnumAttributes = (DescriptionAttribute[])EnumInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (EnumAttributes.Length > 0)
{
return EnumAttributes[0].Description;
}
}
return enumType.ToString();
}
#endregion
#region
public static string GetDescriptionByEnum<T>(this object obj)
{
var tEnum = System.Enum.Parse(typeof(T), obj.ParseToString()) as System.Enum;
var description = tEnum.GetDescription();
return description;
}
/// <summary>
/// 枚举
/// </summary>
/// <param name="enumType"></param>
/// <returns></returns>
public static string ToDescription(this Enum enumType)
{
if (enumType == null)
return "";
System.Reflection.FieldInfo fieldInfo = enumType.GetType().GetField(enumType.ToString());
object[] attribArray = fieldInfo.GetCustomAttributes(false);
if (attribArray.Length == 0)
return enumType.ToString();
else
return (attribArray[0] as DescriptionAttribute).Description;
}
#endregion
}
}

View File

@@ -0,0 +1,14 @@
using System;
namespace WaterCloud.Code
{
public static partial class Extensions
{
public static Exception GetOriginalException(this Exception ex)
{
if (ex.InnerException == null) return ex;
return ex.InnerException.GetOriginalException();
}
}
}

View File

@@ -0,0 +1,156 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
namespace WaterCloud.Code
{
public static partial class Extensions
{
/// <summary>
/// 获取描述
/// </summary>
/// <param name="value">布尔值</param>
public static string Description(this bool value)
{
return value ? "是" : "否";
}
/// <summary>
/// 获取描述
/// </summary>
/// <param name="value">布尔值</param>
public static string Description(this bool? value)
{
return value == null ? "" : Description(value.Value);
}
/// <summary>
/// 获取格式化字符串
/// </summary>
/// <param name="number">数值</param>
/// <param name="defaultValue">空值显示的默认文本</param>
public static string Format(this int number, string defaultValue = "")
{
if (number == 0)
return defaultValue;
return number.ToString();
}
/// <summary>
/// 获取格式化字符串
/// </summary>
/// <param name="number">数值</param>
/// <param name="defaultValue">空值显示的默认文本</param>
public static string Format(this int? number, string defaultValue = "")
{
return Format(number.SafeValue(), defaultValue);
}
/// <summary>
/// 获取格式化字符串
/// </summary>
/// <param name="number">数值</param>
/// <param name="defaultValue">空值显示的默认文本</param>
public static string Format(this decimal number, string defaultValue = "")
{
if (number == 0)
return defaultValue;
return string.Format("{0:0.##}", number);
}
/// <summary>
/// 获取格式化字符串
/// </summary>
/// <param name="number">数值</param>
/// <param name="defaultValue">空值显示的默认文本</param>
public static string Format(this decimal? number, string defaultValue = "")
{
return Format(number.SafeValue(), defaultValue);
}
/// <summary>
/// 获取格式化字符串
/// </summary>
/// <param name="number">数值</param>
/// <param name="defaultValue">空值显示的默认文本</param>
public static string Format(this double number, string defaultValue = "")
{
if (number == 0)
return defaultValue;
return string.Format("{0:0.##}", number);
}
/// <summary>
/// 获取格式化字符串
/// </summary>
/// <param name="number">数值</param>
/// <param name="defaultValue">空值显示的默认文本</param>
public static string Format(this double? number, string defaultValue = "")
{
return Format(number.SafeValue(), defaultValue);
}
/// <summary>
/// 获取格式化字符串,带¥
/// </summary>
/// <param name="number">数值</param>
public static string FormatRmb(this decimal number)
{
if (number == 0)
return "¥0";
return string.Format("¥{0:0.##}", number);
}
/// <summary>
/// 获取格式化字符串,带¥
/// </summary>
/// <param name="number">数值</param>
public static string FormatRmb(this decimal? number)
{
return FormatRmb(number.SafeValue());
}
/// <summary>
/// 获取格式化字符串,带%
/// </summary>
/// <param name="number">数值</param>
public static string FormatPercent(this decimal number)
{
if (number == 0)
return string.Empty;
return string.Format("{0:0.##}%", number);
}
/// <summary>
/// 获取格式化字符串,带%
/// </summary>
/// <param name="number">数值</param>
public static string FormatPercent(this decimal? number)
{
return FormatPercent(number.SafeValue());
}
/// <summary>
/// 获取格式化字符串,带%
/// </summary>
/// <param name="number">数值</param>
public static string FormatPercent(this double number)
{
if (number == 0)
return string.Empty;
return string.Format("{0:0.##}%", number);
}
/// <summary>
/// 获取格式化字符串,带%
/// </summary>
/// <param name="number">数值</param>
public static string FormatPercent(this double? number)
{
return FormatPercent(number.SafeValue());
}
}
}

View File

@@ -0,0 +1,211 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace WaterCloud.Code
{
public static partial class ExtLinq
{
public static Expression Property(this Expression expression, string propertyName)
{
return Expression.Property(expression, propertyName);
}
public static Expression AndAlso(this Expression left, Expression right)
{
return Expression.AndAlso(left, right);
}
public static Expression OrElse(this Expression left, Expression right)
{
return Expression.OrElse(left, right);
}
public static Expression Call(this Expression instance, string methodName, params Expression[] arguments)
{
return Expression.Call(instance, instance.Type.GetMethod(methodName), arguments);
}
public static Expression GreaterThan(this Expression left, Expression right)
{
return Expression.GreaterThan(left, right);
}
public static Expression<T> ToLambda<T>(this Expression body, params ParameterExpression[] parameters)
{
return Expression.Lambda<T>(body, parameters);
}
public static Expression<Func<T, bool>> True<T>()
{ return param => true; }
public static Expression<Func<T, bool>> False<T>()
{ return param => false; }
public static Expression<Func<T, bool>> AndAlso<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
{
return first.Compose(second, Expression.AndAlso);
}
public static Expression<Func<T, bool>> OrElse<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
{
return first.Compose(second, Expression.OrElse);
}
public static Expression<T> Compose<T>(this Expression<T> first, Expression<T> second, Func<Expression, Expression, Expression> merge)
{
var map = first.Parameters
.Select((f, i) => new { f, s = second.Parameters[i] })
.ToDictionary(p => p.s, p => p.f);
var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);
return Expression.Lambda<T>(merge(first.Body, secondBody), first.Parameters);
}
private class ParameterRebinder : ExpressionVisitor
{
private readonly Dictionary<ParameterExpression, ParameterExpression> map;
/// <summary>
/// Initializes a new instance of the <see cref="ParameterRebinder"/> class.
/// </summary>
/// <param name="map">The map.</param>
private ParameterRebinder(Dictionary<ParameterExpression, ParameterExpression> map)
{
this.map = map ?? new Dictionary<ParameterExpression, ParameterExpression>();
}
/// <summary>
/// Replaces the parameters.
/// </summary>
/// <param name="map">The map.</param>
/// <param name="exp">The exp.</param>
/// <returns>Expression</returns>
public static Expression ReplaceParameters(Dictionary<ParameterExpression, ParameterExpression> map, Expression exp)
{
return new ParameterRebinder(map).Visit(exp);
}
protected override Expression VisitParameter(ParameterExpression p)
{
ParameterExpression replacement;
if (map.TryGetValue(p, out replacement))
{
p = replacement;
}
return base.VisitParameter(p);
}
}
public static ParameterExpression CreateLambdaParam<T>(string name)
{
return Expression.Parameter(typeof(T), name);
}
/// <summary>
/// 创建完整的lambda
/// </summary>
public static LambdaExpression GenerateLambda(this ParameterExpression param, Expression body)
{
//c=>c.XXX=="XXX"
return Expression.Lambda(body, param);
}
public static Expression<Func<T, bool>> GenerateTypeLambda<T>(this ParameterExpression param, Expression body)
{
return (Expression<Func<T, bool>>)(param.GenerateLambda(body));
}
public static Expression Or(this Expression expression, Expression expressionRight)
{
return Expression.Or(expression, expressionRight);
}
public static Expression And(this Expression expression, Expression expressionRight)
{
return Expression.And(expression, expressionRight);
}
public static IOrderedQueryable<TEntity> SortBy<TEntity>(this IQueryable<TEntity> query, Expression<Func<TEntity, dynamic>> sortPredicate)
where TEntity : class, new()
{
return InvokeSortBy(query, sortPredicate, SortOrder.Ascending);
}
public static IOrderedQueryable<TEntity> SortByDescending<TEntity>(this IQueryable<TEntity> query, Expression<Func<TEntity, dynamic>> sortPredicate)
where TEntity : class, new()
{
return InvokeSortBy(query, sortPredicate, SortOrder.Descending);
}
private static IOrderedQueryable<TEntity> InvokeSortBy<TEntity>(IQueryable<TEntity> query,
Expression<Func<TEntity, dynamic>> sortPredicate, SortOrder sortOrder)
where TEntity : class, new()
{
var param = sortPredicate.Parameters[0];
string propertyName = null;
Type propertyType = null;
Expression bodyExpression = null;
if (sortPredicate.Body is UnaryExpression)
{
var unaryExpression = sortPredicate.Body as UnaryExpression;
bodyExpression = unaryExpression.Operand;
}
else if (sortPredicate.Body is MemberExpression)
{
bodyExpression = sortPredicate.Body;
}
else
throw new ArgumentException(@"The body of the sort predicate expression should be
either UnaryExpression or MemberExpression.", "sortPredicate");
var memberExpression = (MemberExpression)bodyExpression;
propertyName = memberExpression.Member.Name;
if (memberExpression.Member.MemberType == MemberTypes.Property)
{
var propertyInfo = memberExpression.Member as PropertyInfo;
if (propertyInfo != null) propertyType = propertyInfo.PropertyType;
}
else
throw new InvalidOperationException(@"Cannot evaluate the type of property since the member expression
represented by the sort predicate expression does not contain a PropertyInfo object.");
var funcType = typeof(Func<,>).MakeGenericType(typeof(TEntity), propertyType);
var convertedExpression = Expression.Lambda(funcType,
Expression.Convert(Expression.Property(param, propertyName), propertyType), param);
var sortingMethods = typeof(Queryable).GetMethods(BindingFlags.Public | BindingFlags.Static);
var sortingMethodName = GetSortingMethodName(sortOrder);
var sortingMethod = sortingMethods.First(sm => sm.Name == sortingMethodName &&
sm.GetParameters().Length == 2);
return (IOrderedQueryable<TEntity>)sortingMethod
.MakeGenericMethod(typeof(TEntity), propertyType)
.Invoke(null, new object[] { query, convertedExpression });
}
private static string GetSortingMethodName(SortOrder sortOrder)
{
switch (sortOrder)
{
case SortOrder.Ascending:
return "OrderBy";
case SortOrder.Descending:
return "OrderByDescending";
default:
throw new ArgumentException("Sort Order must be specified as either Ascending or Descending.",
"sortOrder");
}
}
}
}

View File

@@ -0,0 +1,103 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace WaterCloud.Code
{
public static partial class Extensions
{
/// <summary>
/// 获取表里某页的数据
/// </summary>
/// <param name="data">表数据</param>
/// <param name="pageIndex">当前页</param>
/// <param name="pageSize">分页大小</param>
/// <param name="allPage">返回总页数</param>
/// <returns>返回当页表数据</returns>
public static List<T> GetPage<T>(this List<T> data, int pageIndex, int pageSize, out int allPage)
{
allPage = 1;
return null;
}
/// <summary>
/// IList转成List<T>
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
/// <returns></returns>
public static List<T> IListToList<T>(IList list)
{
T[] array = new T[list.Count];
list.CopyTo(array, 0);
return new List<T>(array);
}
/// <summary>
/// 去除空元素
/// </summary>
public static List<string> removeNull(List<string> oldList)
{
// 临时集合
List<string> listTemp = new List<string>();
foreach (var item in oldList)
{
if (!string.IsNullOrEmpty(item))
{
listTemp.Add(item);
}
}
return listTemp;
}
}
public class ExtList<T> : IEqualityComparer<T> where T : class, new()
{
private string[] comparintFiledName = { };
public ExtList()
{ }
public ExtList(params string[] comparintFiledName)
{
this.comparintFiledName = comparintFiledName;
}
bool IEqualityComparer<T>.Equals(T x, T y)
{
if (x == null && y == null)
{
return false;
}
if (comparintFiledName.Length == 0)
{
return x.Equals(y);
}
bool result = true;
var typeX = x.GetType();//获取类型
var typeY = y.GetType();
foreach (var filedName in comparintFiledName)
{
var xPropertyInfo = (from p in typeX.GetProperties() where p.Name.Equals(filedName) select p).FirstOrDefault();
var yPropertyInfo = (from p in typeY.GetProperties() where p.Name.Equals(filedName) select p).FirstOrDefault();
result = result
&& xPropertyInfo != null && yPropertyInfo != null
&& xPropertyInfo.GetValue(x, null).ToString().Equals(yPropertyInfo.GetValue(y, null));
}
return result;
}
int IEqualityComparer<T>.GetHashCode(T obj)
{
return obj.ToString().GetHashCode();
}
}
}

View File

@@ -0,0 +1,59 @@
using AutoMapper;
using System;
using System.Collections;
using System.Collections.Generic;
namespace WaterCloud.Code
{
public static partial class Extensions
{
/// <summary>
/// 类型映射
/// </summary>
public static T MapTo<T>(this object obj)
{
if (obj == null) return default(T);
var config = new MapperConfiguration(cfg => cfg.CreateMap(obj.GetType(), typeof(T)));
var mapper = config.CreateMapper();
return mapper.Map<T>(obj);
}
/// <summary>
/// 集合列表类型映射
/// </summary>
public static List<TDestination> MapToList<TDestination>(this IEnumerable source)
{
Type sourceType = source.GetType().GetGenericArguments()[0]; //获取枚举的成员类型
var config = new MapperConfiguration(cfg => cfg.CreateMap(sourceType, typeof(TDestination)));
var mapper = config.CreateMapper();
return mapper.Map<List<TDestination>>(source);
}
/// <summary>
/// 集合列表类型映射
/// </summary>
public static List<TDestination> MapToList<TSource, TDestination>(this IEnumerable<TSource> source)
{
var config = new MapperConfiguration(cfg => cfg.CreateMap(typeof(TSource), typeof(TDestination)));
var mapper = config.CreateMapper();
return mapper.Map<List<TDestination>>(source);
}
/// <summary>
/// 类型映射
/// </summary>
public static TDestination MapTo<TSource, TDestination>(this TSource source, TDestination destination)
where TSource : class
where TDestination : class
{
if (source == null) return destination;
var config = new MapperConfiguration(cfg => cfg.CreateMap(typeof(TSource), typeof(TDestination)));
var mapper = config.CreateMapper();
return mapper.Map<TDestination>(source);
}
}
}

View File

@@ -0,0 +1,96 @@
using System;
using System.Text;
using System.Collections.Generic;
using System.Security.Cryptography;
namespace WaterCloud.Code
{
/// <summary>
/// 数值扩展类
/// </summary>
public static partial class Extensions
{
#region
/// <summary>
/// 10进制转换到2-36进制
/// </summary>
/// <param name="this">10进制数字</param>
/// <param name="radix">进制范围2-36</param>
/// <param name="digits">编码取值规则,最大转换位数不能大于该字符串的长度</param>
/// <returns></returns>
public static string ToBase(this long @this, int radix, string digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
{
const int BitsInLong = 64;
if (radix < 2 || radix > digits.Length)
throw new ArgumentException("The radix must be >= 2 and <= " + digits.Length.ToString());
if (@this == 0)
return "0";
var index = BitsInLong - 1;
var currentNumber = Math.Abs(@this);
var charArray = new char[BitsInLong];
while (currentNumber != 0)
{
var remainder = (int)(currentNumber % radix);
charArray[index--] = digits[remainder];
currentNumber /= radix;
}
var result = new string(charArray, index + 1, BitsInLong - index - 1);
if (@this < 0)
{
result = "-" + result;
}
return result;
}
/// <summary>
/// byte转16进制
/// </summary>
/// <param name="this"></param>
/// <returns></returns>
public static string ToHex(this byte @this) => Convert.ToString(@this, 16);
/// <summary>
/// 2进制转16进制
/// </summary>
/// <param name="this"></param>
/// <returns></returns>
public static string ToHex(this string @this) => Convert.ToString(Convert.ToInt64(@this, 2), 16);
/// <summary>
/// 16进制转2进制
/// </summary>
/// <param name="this"></param>
/// <returns></returns>
public static string ToBinary(this string @this) => Convert.ToString(Convert.ToInt64(@this, 16), 2);
/// <summary>
/// 2进制/16进制转8进制
/// </summary>
/// <param name="this"></param>
/// <param name="fromBase">2或者16表示2进制或者16进制</param>
/// <returns></returns>
public static string ToOctal(this string @this, int fromBase) => Convert.ToString(Convert.ToInt64(@this, fromBase), 8);
/// <summary>
/// 2进制/16进制转10进制
/// </summary>
/// <param name="this"></param>
/// <param name="fromBase">2或者16表示2进制或者16进制</param>
/// <returns></returns>
public static string ToDecimalism(this string @this, int fromBase)
{
if (fromBase == 16)
return Convert.ToInt32(@this, 16).ToString();
else
return Convert.ToString(Convert.ToInt64(@this, 2), 10);
}
#endregion
}
}

View File

@@ -0,0 +1,37 @@
using System;
namespace WaterCloud.Code
{
/// <summary>
/// string扩展类
/// </summary>
public static partial class Extensions
{
/// <summary>
/// 从分隔符开始向尾部截取字符串
/// </summary>
/// <param name="this">源字符串</param>
/// <param name="separator">分隔符</param>
/// <param name="lastIndexOf">true从最后一个匹配的分隔符开始截取false从第一个匹配的分隔符开始截取默认true</param>
/// <returns>string</returns>
public static string Substring(this string @this, string separator, bool lastIndexOf = true)
{
var startIndex = (lastIndexOf ?
@this.LastIndexOf(separator, StringComparison.OrdinalIgnoreCase) :
@this.IndexOf(separator, StringComparison.OrdinalIgnoreCase)) +
separator.Length;
var length = @this.Length - startIndex;
return @this.Substring(startIndex, length);
}
#region
public static string ReplaceFrist(this string str, string oldChar, string newChar)
{
int idx = str.IndexOf(oldChar);
str = str.Remove(idx, oldChar.Length);
str = str.Insert(idx, newChar);
return str;
}
#endregion
}
}

View File

@@ -0,0 +1,70 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System.Data;
namespace WaterCloud.Code
{
public static partial class Extensions
{
/// <summary>
/// 获取表里某页的数据
/// </summary>
/// <param name="data">表数据</param>
/// <param name="pageIndex">当前页</param>
/// <param name="pageSize">分页大小</param>
/// <param name="allPage">返回总页数</param>
/// <returns>返回当页表数据</returns>
public static DataTable GetPage(this DataTable data, int pageIndex, int pageSize, out int allPage)
{
allPage = data.Rows.Count / pageSize;
allPage += data.Rows.Count % pageSize == 0 ? 0 : 1;
DataTable Ntable = data.Clone();
int startIndex = pageIndex * pageSize;
int endIndex = startIndex + pageSize > data.Rows.Count ? data.Rows.Count : startIndex + pageSize;
if (startIndex < endIndex)
for (int i = startIndex; i < endIndex; i++)
{
Ntable.ImportRow(data.Rows[i]);
}
return Ntable;
}
/// <summary>
/// 根据字段过滤表的内容
/// </summary>
/// <param name="data">表数据</param>
/// <param name="condition">条件</param>
/// <returns></returns>
///
public static DataTable GetDataFilter(DataTable data, string condition)
{
if (data != null && data.Rows.Count > 0)
{
if (condition.Trim() == "")
{
return data;
}
else
{
DataTable newdt = new DataTable();
newdt = data.Clone();
DataRow[] dr = data.Select(condition);
for (int i = 0; i < dr.Length; i++)
{
newdt.ImportRow((DataRow)dr[i]);
}
return newdt;
}
}
else
{
return null;
}
}
}
}

View File

@@ -0,0 +1,30 @@
using Microsoft.AspNetCore.Http;
using System;
namespace WaterCloud.Code
{
public static partial class Extensions
{
public static bool IsNullOrZero(this object value)
{
if (value == null || value.ParseToString().Trim() == "0")
{
return true;
}
else
{
return false;
}
}
public static bool IsAjaxRequest(this HttpRequest request)
{
if (request == null)
throw new ArgumentNullException("request");
if (request.Headers != null)
return request.Headers["X-Requested-With"] == "XMLHttpRequest";
return false;
}
}
}

View File

@@ -0,0 +1,41 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Threading.Tasks;
namespace WaterCloud.Code
{
/// <summary>
/// 全局异常过滤器,MVC使用
/// </summary>
public class GlobalExceptionFilter : IExceptionFilter, IAsyncExceptionFilter
{
public void OnException(ExceptionContext context)
{
LogHelper.WriteWithTime(context);
if (context.HttpContext.Request.IsAjaxRequest())
{
AlwaysResult obj = new AlwaysResult();
obj.state = ResultType.error.ToString();
obj.message = context.Exception.GetOriginalException().Message;
if (string.IsNullOrEmpty(obj.message))
{
obj.message = "抱歉,系统错误,请联系管理员!";
}
context.Result = new JsonResult(obj);
context.ExceptionHandled = true;
}
else
{
//context.HttpContext.Response.WriteAsync("<script>top.location.href ='" + context.HttpContext.Request.PathBase + "/Home/Error?msg=500" + "';if(document.all) window.event.returnValue = false;</script>");
context.Result = new RedirectResult(context.HttpContext.Request.PathBase + "/Home/Error?msg=500");
context.ExceptionHandled = true;
}
}
public Task OnExceptionAsync(ExceptionContext context)
{
OnException(context);
return Task.CompletedTask;
}
}
}

View File

@@ -0,0 +1,47 @@
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using System;
using System.Net;
using System.Threading.Tasks;
namespace WaterCloud.Code
{
/// <summary>
/// 全局异常中间件api使用
/// </summary>
public class GlobalExceptionMiddleware
{
private readonly RequestDelegate next;
public GlobalExceptionMiddleware(RequestDelegate next)
{
this.next = next;
}
public async Task Invoke(HttpContext context /* other dependencies */)
{
try
{
await next(context);
}
catch (Exception ex)
{
await HandleExceptionAsync(context, ex);
}
}
private static Task HandleExceptionAsync(HttpContext context, Exception exception)
{
var code = HttpStatusCode.OK;
LogHelper.WriteWithTime(exception);
var result = JsonConvert.SerializeObject(new AlwaysResult
{
state = ResultType.error.ToString(),
message = exception.Message
});
context.Response.ContentType = "application/json";
context.Response.StatusCode = (int)code;
return context.Response.WriteAsync(result);
}
}
}

View File

@@ -0,0 +1,31 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
namespace WaterCloud.Code
{
/// <summary>
/// 模型验证过滤器
/// </summary>
public class ModelActionFilter : ActionFilterAttribute, IActionFilter
{
public override void OnActionExecuting(ActionExecutingContext context)
{
string message = "";
if (!context.ModelState.IsValid)
{
foreach (var item in context.ModelState.Values)
{
foreach (var error in item.Errors)
{
message = message += error.ErrorMessage + "|";
}
}
if (message.Length > 0)
{
message = message.Substring(0, message.Length - 1);
}
context.Result = new JsonResult(new AlwaysResult { state = ResultType.error.ToString(), message = message });
}
}
}
}

View File

@@ -0,0 +1,13 @@
using System.Collections.Generic;
namespace WaterCloud.Code
{
public class Flow
{
public string title { get; set; }
public int initNum { get; set; }
public List<FlowLine> lines { get; set; }
public List<FlowNode> nodes { get; set; }
public List<FlowArea> areas { get; set; }
}
}

View File

@@ -0,0 +1,18 @@
namespace WaterCloud.Code
{
public class FlowArea
{
public string id { get; set; }
public string name { get; set; }
public string color { get; set; }
public int left { get; set; }
public int top { get; set; }
public int width { get; set; }
public int height { get; set; }
public bool alt { get; set; }
}
}

View File

@@ -0,0 +1,272 @@
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Linq;
namespace WaterCloud.Code
{
/// <summary>
/// 流程连线
/// </summary>
public class FlowLine
{
public string id { get; set; }
public string label { get; set; }
public string type { get; set; }
public string from { get; set; }
public string to { get; set; }
public string name { get; set; }
public bool dash { get; set; }
public double M { get; set; }
public bool alt { get; set; }
/// <summary> 分支条件 </summary>
public List<DataCompare> Compares { get; set; }
public bool Compare(JObject frmDataJson)
{
bool result = true;
foreach (var compare in Compares)
{
compare.FieldName = compare.FieldName.ToLower();
compare.Value = compare.Value.ToLower();
decimal value = 0; //参考值
decimal frmvalue = 0; //表单中填写的值
if (compare.Operation != DataCompare.Equal && compare.Operation != DataCompare.NotEqual)
{
value = decimal.Parse(compare.Value);
frmvalue = decimal.Parse(frmDataJson.GetValue(compare.FieldName.ToLower()).ToString()); //表单中填写的值
}
bool res = false;
if (compare.Condition == "and")
{
switch (compare.Operation)
{
case DataCompare.Equal:
result &= compare.Value == frmDataJson.GetValue(compare.FieldName).ToString();
break;
case DataCompare.NotEqual:
result &= compare.Value != frmDataJson.GetValue(compare.FieldName).ToString();
break;
case DataCompare.Larger:
result &= frmvalue > value;
break;
case DataCompare.Less:
result &= frmvalue < value;
break;
case DataCompare.LargerEqual:
result &= frmvalue <= value;
break;
case DataCompare.LessEqual:
result &= frmvalue <= value;
break;
case DataCompare.In:
if (compare.FieldName == "申请人" || compare.FieldName == "所属部门")
{
var arr = compare.Value.Split(',');
foreach (var item in frmDataJson.GetValue(compare.FieldName).ToString().Split(','))
{
if (arr.Contains(item))
{
res = true;
break;
}
}
result &= res;
break;
}
else
{
var arr = compare.Value.Split(',');
if (arr.Contains(frmvalue.ToString()))
{
res = true;
break;
}
result &= res;
break;
}
case DataCompare.NotIn:
if (compare.FieldName == "申请人" || compare.FieldName == "所属部门")
{
var arr = compare.Value.Split(',');
foreach (var item in frmDataJson.GetValue(compare.FieldName).ToString().Split(','))
{
if (arr.Contains(item))
{
res = false;
break;
}
}
result &= res;
break;
}
else
{
var arr = compare.Value.Split(',');
if (arr.Contains(frmvalue.ToString()))
{
res = false;
break;
}
result &= res;
break;
}
}
}
else
{
switch (compare.Operation)
{
case DataCompare.Equal:
if (compare.FieldName == "申请人" || compare.FieldName == "所属部门")
{
var arr = compare.Value.Split(',');
foreach (var item in frmDataJson.GetValue(compare.FieldName).ToString().Split(','))
{
if (arr.Contains(item))
{
res = true;
break;
}
}
result |= res;
break;
}
result |= compare.Value == frmDataJson.GetValue(compare.FieldName).ToString();
break;
case DataCompare.NotEqual:
if (compare.FieldName == "申请人" || compare.FieldName == "所属部门")
{
var arr = compare.Value.Split(',');
foreach (var item in frmDataJson.GetValue(compare.FieldName).ToString().Split(','))
{
if (arr.Contains(item))
{
res = false;
break;
}
}
result |= res;
break;
}
result |= compare.Value != frmDataJson.GetValue(compare.FieldName).ToString();
break;
case DataCompare.Larger:
result |= frmvalue > value;
break;
case DataCompare.Less:
result |= frmvalue < value;
break;
case DataCompare.LargerEqual:
result |= frmvalue <= value;
break;
case DataCompare.LessEqual:
result |= frmvalue <= value;
break;
case DataCompare.In:
if (compare.FieldName == "申请人" || compare.FieldName == "所属部门")
{
var arr = compare.Value.Split(',');
foreach (var item in frmDataJson.GetValue(compare.FieldName).ToString().Split(','))
{
if (arr.Contains(item))
{
res = true;
break;
}
}
result |= res;
break;
}
else
{
var arr = compare.Value.Split(',');
if (arr.Contains(frmvalue.ToString()))
{
res = true;
}
result |= res;
break;
}
case DataCompare.NotIn:
if (compare.FieldName == "申请人" || compare.FieldName == "所属部门")
{
var arr = compare.Value.Split(',');
foreach (var item in frmDataJson.GetValue(compare.FieldName).ToString().Split(','))
{
if (arr.Contains(item))
{
res = false;
break;
}
}
result |= res;
break;
}
else
{
var arr = compare.Value.Split(',');
if (arr.Contains(frmvalue.ToString()))
{
res = false;
}
result |= res;
break;
}
}
}
}
return result;
}
}
/// <summary>
/// 分支条件
/// </summary>
public class DataCompare
{
public const string Larger = ">";
public const string Less = "<";
public const string LargerEqual = ">=";
public const string LessEqual = "<=";
public const string NotEqual = "!=";
public const string Equal = "=";
public const string In = "in";
public const string NotIn = "not in";
/// <summary>操作类型比如大于/等于/小于</summary>
public string Operation { get; set; }
/// <summary> form种的字段名称 </summary>
public string FieldName { get; set; }
/// <summary> 字段类型:"form":为表单中的字段,后期扩展系统表等. </summary>
public string FieldType { get; set; }
/// <summary>实际的值</summary>
public string Value { get; set; }
/// <summary>
/// 显示值
/// </summary>
public string Name { get; set; }
/// <summary>
/// 条件关系
/// </summary>
public string Condition { get; set; }
}
}

View File

@@ -0,0 +1,131 @@
namespace WaterCloud.Code
{
/// <summary>
/// 流程节点
/// </summary>
public class FlowNode
{
public const string START = "start round mix";
public const string END = "end round";
public const string NODE = "node";
public const string FORK = "fork"; //会签开始节点
public const string JOIN = "join"; //会签结束节点
public string id { get; set; }
public string name { get; set; }
public string type { get; set; }
public int left { get; set; }
public int top { get; set; }
public int width { get; set; }
public int height { get; set; }
public bool alt { get; set; }
/// <summary>
/// 节点的附加数据项
/// </summary>
/// <value>The set information.</value>
public Setinfo setInfo { get; set; }
}
public class Setinfo
{
public const string SPECIAL_USER = "SPECIAL_USER"; //指定用户
public const string ALL_USER = "ALL_USER"; //所有用户
public const string SPECIAL_ROLE = "SPECIAL_ROLE"; //指定角色
public const string DEPARTMENT_MANAGER = "DEPARTMENT_MANAGER"; //部门负责人
public const string USER_MANAGER = "USER_MANAGER"; //直属上级
public const string MORE_USER_MANAGER = "MORE_USER_MANAGER"; //连续多级直属上级
public const string RUNTIME_SPECIAL_ROLE = "RUNTIME_SPECIAL_ROLE"; //运行时指定角色
public const string RUNTIME_SPECIAL_USER = "RUNTIME_SPECIAL_USER"; //运行时指定用户
/// <summary>
/// 节点执行权限类型
/// </summary>
public string NodeDesignate { get; set; }
public Nodedesignatedata NodeDesignateData { get; set; }
public string NodeCode { get; set; }
public string NodeName { get; set; }
/// <summary>
/// 流程执行时三方回调的URL地址
/// </summary>
public string ThirdPartyUrl { get; set; }
/// <summary>
/// 驳回节点0"前一步"1"第一步"2"某一步" 3"不处理"
/// </summary>
public string NodeRejectType { get; set; }
public int? Taged { get; set; }
public string UserName { get; set; }
public string UserId { get; set; }
public string Description { get; set; }
public string TagedTime { get; set; }
//节点会签方式,
//all/空:默认为全部通过
//one :至少有一个通过
public string NodeConfluenceType { get; set; }
/// <summary>
/// 会签通过的个数
/// </summary>
public int? ConfluenceOk { get; set; }
/// <summary>
/// 会签拒绝的个数
/// </summary>
public int? ConfluenceNo { get; set; }
/// <summary>
/// 可写的表单项ID
/// </summary>
public string[] CanWriteFormItemIds { get; set; }
}
/// <summary>
/// 节点执行人
/// </summary>
public class Nodedesignatedata
{
public string[] users { get; set; }
public string[] roles { get; set; }
public string[] orgs { get; set; }
public bool currentDepart { get; set; }
}
/// <summary>
/// 节点执行结果标签
/// </summary>
public class Tag
{
/// <summary>
/// 1: 通过
/// 2不通过
/// 3驳回
/// </summary>
public int Taged { get; set; }
public string UserId { get; set; }
public string UserName { get; set; }
public string Description { get; set; }
public string TagedTime { get; set; }
}
/// <summary>
/// 1: 通过
/// 2不通过
/// 3驳回
/// </summary>
public enum TagState
{
Ok = 1,
No,
Reject
}
}

View File

@@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
namespace WaterCloud.Code
{
public class FormUtil
{
/// <summary>
/// 获取值
/// </summary>
/// <param name="form">The form.</param>
/// <returns>System.String.</returns>
public static List<string> SetValue(string content)
{
List<FormValue> list = JsonHelper.ToObject<List<FormValue>>(content);
List<string> temp = new List<string>();
SetFormValue(list, temp);
return temp;
}
private static List<string> SetFormValue(List<FormValue> list, List<string> temp)
{
foreach (var item in list)
{
if (item.tag == "grid")
{
foreach (var column in item.columns)
{
SetFormValue(column.list, temp);
}
}
else
{
temp.Add(item.id);
}
}
return temp;
}
public static List<string> SetValueByWeb(string webForm)
{
var path = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory;
var referencedAssemblies = Directory.GetFiles(path, "*.dll").Select(Assembly.LoadFrom).ToArray();
var t = referencedAssemblies
.SelectMany(a => a.GetTypes().Where(t => t.FullName.Contains("WaterCloud.Domain.") && t.FullName.Contains("." + webForm + "Entity"))).First();
List<string> temp = new List<string>();
PropertyInfo[] pArray = t.GetProperties();
Array.ForEach<PropertyInfo>(pArray, p =>
{
temp.Add(p.Name);
});
return temp;
}
}
}

View File

@@ -0,0 +1,24 @@
using System.Collections.Generic;
namespace WaterCloud.Code
{
/// <summary>
/// 表单设计类
/// </summary>
public class FormValue
{
public string id { get; set; }
public string label { get; set; }
public int index { get; set; }
public string tag { get; set; }
public int span { get; set; }
public List<FormEx> columns { get; set; }
public string name { get; set; }
}
public class FormEx
{
public int span { get; set; }
public List<FormValue> list { get; set; }
}
}

View File

@@ -0,0 +1,254 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyModel;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using System.Text;
using WaterCloud.Code.Model;
namespace WaterCloud.Code
{
public static class GlobalContext
{
/// <summary>
/// 构造函数
/// </summary>
static GlobalContext()
{
// 未托管的对象
UnmanagedObjects = new ConcurrentBag<IDisposable>();
Assemblies = GetAssemblies();
EffectiveTypes = Assemblies.SelectMany(GetTypes);
}
/// <summary>
/// 服务集合
/// </summary>
public static IServiceCollection Services { get; set; }
/// <summary>
/// 根服务
/// </summary>
public static IServiceProvider RootServices { get; set; }
public static IConfiguration Configuration { get; set; }
public static IWebHostEnvironment HostingEnvironment { get; set; }
/// <summary>
/// 未托管的对象集合
/// </summary>
public static readonly ConcurrentBag<IDisposable> UnmanagedObjects;
public static HttpContext HttpContext => RootServices?.GetService<IHttpContextAccessor>()?.HttpContext;
public static SystemConfig SystemConfig { get; set; }
/// <summary>
/// 应用有效程序集(类型为project,项目应用的,不包括包和手动应用)
/// </summary>
public static readonly IEnumerable<Assembly> Assemblies;
/// <summary>
/// 有效程序集类型
/// </summary>
public static readonly IEnumerable<System.Type> EffectiveTypes;
/// <summary>
/// 获取请求生存周期的服务(未注册返回null)
/// </summary>
/// <typeparam name="TService"></typeparam>
/// <param name="serviceProvider"></param>
/// <returns></returns>
public static TService GetService<TService>(IServiceProvider serviceProvider = null) where TService : class
{
return GetService(typeof(TService), serviceProvider) as TService;
}
/// <summary>
/// 获取请求生存周期的服务(未注册返回null)
/// </summary>
/// <param name="type"></param>
/// <param name="serviceProvider"></param>
/// <returns></returns>
public static object GetService(Type type, IServiceProvider serviceProvider = null)
{
return (serviceProvider ?? GetServiceProvider(type)).GetService(type);
}
/// <summary>
/// 获取请求生存周期的服务(未注册异常)
/// </summary>
/// <typeparam name="TService"></typeparam>
/// <param name="serviceProvider"></param>
/// <returns></returns>
public static TService GetRequiredService<TService>(IServiceProvider serviceProvider = null) where TService : class
{
return GetRequiredService(typeof(TService), serviceProvider) as TService;
}
/// <summary>
/// 获取请求生存周期的服务(未注册异常)
/// </summary>
/// <typeparam name="type"></typeparam>
/// <param name="serviceProvider"></param>
/// <returns></returns>
public static object GetRequiredService(Type type, IServiceProvider serviceProvider = null)
{
return (serviceProvider ?? GetServiceProvider(type)).GetRequiredService(type);
}
/// <summary>
/// 获取服务注册器
/// </summary>
/// <param name="serviceType"></param>
/// <returns></returns>
public static IServiceProvider GetServiceProvider(Type serviceType)
{
if (HostingEnvironment == null)
{
return RootServices;
}
if (RootServices != null && Services.Where((ServiceDescriptor u) => u.ServiceType == (serviceType.IsGenericType ? serviceType.GetGenericTypeDefinition() : serviceType)).Any((ServiceDescriptor u) => u.Lifetime == ServiceLifetime.Singleton))
{
return RootServices;
}
// 第二选择是获取 HttpContext 对象的 RequestServices
var httpContext = HttpContext;
if (httpContext?.RequestServices != null) return httpContext.RequestServices;
// 第三选择,创建新的作用域并返回服务提供器
else if (RootServices != null)
{
var scoped = RootServices.CreateScope();
UnmanagedObjects.Add(scoped);
return scoped.ServiceProvider;
}
// 第四选择,构建新的服务对象(性能最差)
else
{
var serviceProvider = Services.BuildServiceProvider();
UnmanagedObjects.Add(serviceProvider);
return serviceProvider;
}
}
/// <summary>
/// GC 回收默认间隔
/// </summary>
private const int GC_COLLECT_INTERVAL_SECONDS = 5;
/// <summary>
/// 记录最近 GC 回收时间
/// </summary>
private static DateTime? LastGCCollectTime { get; set; }
/// <summary>
/// 释放所有未托管的对象
/// </summary>
public static void DisposeUnmanagedObjects()
{
foreach (var dsp in UnmanagedObjects)
{
try
{
dsp?.Dispose();
}
finally { }
}
// 强制手动回收 GC 内存
if (UnmanagedObjects.Any())
{
var nowTime = DateTime.UtcNow;
if ((LastGCCollectTime == null || (nowTime - LastGCCollectTime.Value).TotalSeconds > GC_COLLECT_INTERVAL_SECONDS))
{
LastGCCollectTime = nowTime;
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
UnmanagedObjects.Clear();
}
/// <summary>
/// 获取版本号
/// </summary>
/// <returns></returns>
public static string GetVersion()
{
Version version = Assembly.GetEntryAssembly().GetName().Version;
return version.ToString();
}
/// <summary>
/// 获取请求跟踪 Id
/// </summary>
/// <returns></returns>
public static string GetTraceId()
{
return Activity.Current?.Id ?? (RootServices == null ? default : HttpContext?.TraceIdentifier);
}
/// <summary>
/// 程序启动时,记录目录
/// </summary>
/// <param name="env"></param>
public static void LogWhenStart(IWebHostEnvironment env)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("程序启动");
sb.AppendLine("ContentRootPath:" + env.ContentRootPath);
sb.AppendLine("WebRootPath:" + env.WebRootPath);
sb.AppendLine("IsDevelopment:" + env.IsDevelopment());
LogHelper.WriteWithTime(sb.ToString());
}
/// <summary>
/// 设置cache control
/// </summary>
/// <param name="context"></param>
public static void SetCacheControl(StaticFileResponseContext context)
{
int second = 365 * 24 * 60 * 60;
context.Context.Response.Headers.Add("Cache-Control", new[] { "public,max-age=" + second });
context.Context.Response.Headers.Add("Expires", new[] { DateTime.UtcNow.AddYears(1).ToString("R") }); // Format RFC1123
}
public static IEnumerable<Assembly> GetAssemblies()
{
var projects = DependencyContext
.Default
.RuntimeLibraries
.Where(u => u.Type == "project" || u.Type == "reference")
.Select(u => AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(u.Name)));
return projects;
}
/// <summary>
/// 加载程序集中的所有类型
/// </summary>
/// <param name="ass"></param>
/// <returns></returns>
private static IEnumerable<System.Type> GetTypes(Assembly ass)
{
var types = Array.Empty<System.Type>();
try
{
types = ass.GetTypes();
}
catch
{
Console.WriteLine($"Error load `{ass.FullName}` assembly.");
}
return types.Where(u => u.IsPublic);
}
}
}

View File

@@ -0,0 +1,45 @@
using System.Collections.Generic;
namespace WaterCloud.Code
{
public class FilterSo
{
/**
* 唯一id
*/
public long id { get; set; }
/**
* 前缀 and、or
*/
public string prefix { get; set; }
/**
* 模式 in、condition、date
*/
public string mode { get; set; }
/**
* 字段名
*/
public string field { get; set; }
/**
* 筛选类型
*/
public string type { get; set; }
/**
* 是否有分隔符
*/
public string split { get; set; }
/**
* 筛选值
*/
public string value { get; set; }
/**
* 筛选值
*/
public List<string> values { get; set; }
/**
* 子组数据
*/
public List<FilterSo> children { get; set; }
}
}

View File

@@ -0,0 +1,210 @@
using Serenity;
using System;
using System.Collections.Generic;
using System.Linq;
namespace WaterCloud.Code
{
/// <summary>
///封装table查询数据
/// </summary>
/// <typeparam name="T"></typeparam>
public class SoulPage<T>
{
/**
* layui表格必须参数⬇⬇⬇⬇⬇⬇
*/
public int state { get; set; }
public string message { get; set; }
/**
* 总记录
*/
public int count { get; set; }
/**
* 显示的记录
*/
public List<T> data { get; set; }
/**
* 请求条件
*/
public object obj { get; set; }
/**
* 查询条件
*/
public Dictionary<string, object> condition = new Dictionary<string, object>();
/**
* 请求参数⬇⬇⬇⬇⬇⬇
*/
/**
* 当前页 从1开始
*/
public int page { get; set; }
/**
* 页大小
*/
public int rows { get; set; }
/**
* 查询列数据
*/
public string columns { get; set; }
/**
* 表格列类型
*/
public string tableFilterType { get; set; }
/**
* 筛选信息
*/
public string filterSos { get; set; }
/**
* 排序信息
*/
public string field { get; set; }
public string order { get; set; }
public SoulPage()
{
this.state = 0;
this.message = "";
this.page = 1;
this.rows = 100000000;
this.order = "asc";
}
public SoulPage(int page, int limit)
{
this.state = 0;
this.message = "";
this.page = 1;
this.rows = 100000000;
this.order = "asc";
this.page = page;
this.rows = limit;
}
public List<FilterSo> getFilterSos()
{
if (string.IsNullOrEmpty(filterSos))
{
return new List<FilterSo>();
}
return filterSos.ToObject<List<FilterSo>>();
}
public bool isColumn()
{
return getColumns().Count > 0;
}
public int getOffset()
{
return (page - 1) * rows;
}
public List<string> getColumns()
{
return !string.IsNullOrEmpty(columns) ? columns.ToObject<List<string>>() : new List<string>();
}
private string dateFormat(DateTime date, string format)
{
if (string.IsNullOrEmpty(format))
{
return date.ToString("yyyy-MM-dd HH:mm:ss");
}
else
{
return date.ToString(format);
}
}
public Dictionary<string, Dictionary<string, string>> getTypeMap()
{
Dictionary<string, Dictionary<string, string>> typeMap = new Dictionary<string, Dictionary<string, string>>();
if (!string.IsNullOrEmpty(tableFilterType))
{
Dictionary<string, string> filterType = tableFilterType.ToObject<Dictionary<string, string>>();
foreach (var item in filterType)
{
Dictionary<string, string> map = new Dictionary<string, string>();
map.Add("type", item.Value.Substring(0, item.Value.IndexOf("[")));
int IndexofA = item.Value.IndexOf('['); //字符串的话总以第一位为指定位置
int IndexofB = item.Value.IndexOf(']');
map.Add("value", item.Value.Substring(IndexofA + 1, IndexofB - IndexofA - 1));
typeMap.Add(item.Key, map);
};
}
return typeMap;
}
public string getFormatValue(Dictionary<string, Dictionary<string, string>> typeMap, string column, object columnObject)
{
string columnValue;
if (typeMap.ContainsKey(column))
{
if ("date".Equals(typeMap.Get(column).Get("type")) && columnObject is DateTime)
{
columnValue = dateFormat((DateTime)columnObject, typeMap.Get(column).Get("value"));
}
else
{
columnValue = columnObject.ToString();
}
}
else
{
if (columnObject is DateTime || columnObject is Nullable<DateTime>)
{
columnValue = dateFormat((DateTime)columnObject, null);
}
else if (columnObject is bool || columnObject is Nullable<bool>)
{
columnValue = (bool)columnObject == true ? "1" : "0";
}
else
{
columnValue = columnObject.ToString();
}
}
return columnValue;
}
public Object setData(List<T> data)
{
if (isColumn())
{
Dictionary<string, Dictionary<string, string>> typeMap = getTypeMap();
Dictionary<string, HashSet<string>> columnMap = new Dictionary<string, HashSet<string>>();
foreach (T datum in data)
{
foreach (string column in getColumns())
{
if (!columnMap.ContainsKey(column))
{
columnMap.Add(column, new HashSet<string>());
}
var columnObject = ReflectionHelper.GetObjectPropertyValue(datum, column);
if (columnObject != null)
{ //空值不展示
columnMap.Get(column).Add(getFormatValue(typeMap, column, columnObject));
}
}
}
Dictionary<string, List<string>> columnSortMap = new Dictionary<string, List<string>>();
foreach (var item in columnMap)
{
columnSortMap.Add(item.Key, item.Value.ToList());
}
return columnSortMap;
}
else
{
this.data = data;
return this;
}
}
}
}

View File

@@ -0,0 +1,83 @@
namespace WaterCloud.Code
{
/// <summary>
/// LayUI Table 列
/// </summary>
public class TableCols
{
/// <summary>
/// 类型normal常规列、checkbox复选框、radio单选框、numbers序号、space
/// </summary>
public string type { get; set; }
/// <summary>
/// 字段
/// </summary>
public string field { get; set; }
/// <summary>
/// 标题
/// </summary>
public string title { get; set; }
/// <summary>
/// 宽度
/// </summary>
public int? width { get; set; }
/// <summary>
/// 最小宽度
/// </summary>
public int? minWidth { get; set; }
/// <summary>
/// 是否全选
/// </summary>
public bool? LAY_CHECKED { get; set; }
/// <summary>
/// 固定列
/// </summary>
public string Fixed { get; set; }
/// <summary>
/// 隐藏
/// </summary>
public string hide { get; set; }
/// <summary>
/// 排序
/// </summary>
public bool? sort { get; set; }
/// <summary>
/// 是否禁用拖到列
/// </summary>
public bool? unresize { get; set; }
/// <summary>
/// 样式
/// </summary>
public string style { get; set; }
/// <summary>
/// 对齐方式
/// </summary>
public string align { get; set; }
/// <summary>
/// 所占列数
/// </summary>
public int? colspan { get; set; }
/// <summary>
/// 所占行数
/// </summary>
public int? rowspan { get; set; }
/// <summary>
/// 绑定工具栏模板
/// </summary>
public string toolbar { get; set; }
}
}

View File

@@ -0,0 +1,15 @@
using System.ComponentModel;
using System.ComponentModel.DataAnnotations.Schema;
namespace WaterCloud.Code.Model
{
/// <summary>
/// 这个是移动端Api用的
/// </summary>
public class BaseApiToken
{
[NotMapped]
[Description("WebApi没有Cookie和Session所以需要传入Token来标识用户身份请加在Url后面")]
public string Token { get; set; }
}
}

View File

@@ -0,0 +1,7 @@
namespace WaterCloud.Code.Model
{
public class AppLogEntity
{
public string FileName { get; set; }
}
}

View File

@@ -0,0 +1,41 @@
/*******************************************************************************
* Copyright © 2020 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System.ComponentModel;
namespace WaterCloud.Code
{
public enum DbLogType
{
[Description("其他")]
Other = 0,
[Description("登录")]
Login = 1,
[Description("退出")]
Exit = 2,
[Description("访问")]
Visit = 3,
[Description("新增")]
Create = 4,
[Description("删除")]
Delete = 5,
[Description("修改")]
Update = 6,
[Description("提交")]
Submit = 7,
[Description("异常")]
Exception = 8,
}
}

View File

@@ -0,0 +1,18 @@
namespace WaterCloud.Code
{
public static class Define
{
public const string PROVIDER_COOKIE = "Cookie";
public const string PROVIDER_SESSION = "Session";
public const string PROVIDER_WEBAPI = "WebApi";
public const string CACHEPROVIDER_REDIS = "Redis";
public const string CACHEPROVIDER_MEMORY = "Memory";
public const string DATAPRIVILEGE_LOGINUSER = "{loginUser}"; //数据权限配置中当前登录用户的key
public const string DATAPRIVILEGE_LOGINROLE = "{loginRole}"; //数据权限配置中当前登录用户角色的key
public const string DATAPRIVILEGE_LOGINORG = "{loginOrg}"; //数据权限配置中当前登录用户部门的key
public const string SQL_MORE = "MoreSql";//多库
public const string SQL_TENANT = "TenantSql";//多租户
}
}

View File

@@ -0,0 +1,22 @@
namespace WaterCloud.Code
{
public class Filter
{
public string Key { get; set; }
public string Value { get; set; }
public string Contrast { get; set; }
public string Text { get; set; }
}
public class FilterList
{
/// <summary>
/// and
/// </summary>
public string Operation { get; set; }
public string Filters { get; set; }
public string Description { get; set; }
}
}

View File

@@ -0,0 +1,9 @@
namespace WaterCloud.Code
{
public class KeyValue
{
public string Key { get; set; }
public string Value { get; set; }
public string Description { get; set; }
}
}

View File

@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WaterCloud.Code.Model
{
public class PrintEntity
{
public string cmd { get; set; } = "print";
public string requestId { get; set; }
public PrintDetail data { get; set; }
}
public class PrintDetail
{
public PrintInitInfo printIniInfo { get; set; }
public object data { get; set; }
}
public class PrintInitInfo
{
public string filePath { get; set; }
public string realName { get; set; }
public int? printType { get; set; } = 1;
public string printName { get; set; } = "";
public bool landscape { get; set; } = true;
public string paperSize { get; set; }
public string duplex { get; set; }
public bool? isBatch { get; set; } = false;
}
}

View File

@@ -0,0 +1,185 @@
using System.Collections.Generic;
namespace WaterCloud.Code.Model
{
public class SystemConfig
{
/// <summary>
/// 是否是Demo模式
/// </summary>
public bool Demo { get; set; }
/// <summary>
/// 是否是调试模式
/// </summary>
public bool Debug { get; set; }
/// <summary>
/// 允许一个用户在多个电脑同时登录
/// </summary>
public bool LoginMultiple { get; set; }
/// <summary>
/// 允许跨域的站点
/// </summary>
public string AllowCorsSite { get; set; }
/// <summary>
/// 主库数据库类型
/// </summary>
public string DBProvider { get; set; }
/// <summary>
/// 主库数据库连接
/// </summary>
public string DBConnectionString { get; set; }
/// <summary>
/// 数据库连接超时
/// </summary>
public int DBCommandTimeout { get; set; }
/// <summary>
/// 是否初始化数据库
/// </summary>
public bool IsInitDb { get; set; }
/// <summary>
/// 是否初始化种子数据
/// </summary>
public bool IsSeedData { get; set; }
/// <summary>
/// 缓存类型
/// </summary>
public string CacheProvider { get; set; }
/// <summary>
/// redis连接串
/// </summary>
public string RedisConnectionString { get; set; }
/// <summary>
/// api token名称
/// </summary>
public string TokenName { get; set; }
//缓存过期时间
public int LoginExpire { get; set; }
/// <summary>
/// 主页
/// </summary>
public string HomePage { get; set; }
/// <summary>
/// 是否局域网
/// </summary>
public bool? LocalLAN { get; set; }
/// <summary>
/// 数据库模式
/// </summary>
public string SqlMode { get; set; }
/// <summary>
/// 项目前缀
/// </summary>
public string ProjectPrefix { get; set; }
/// <summary>
/// 是否重置密码
/// </summary>
public bool? ReviseSystem { get; set; }
/// <summary>
/// 登录错误次数
/// </summary>
public int? LoginErrorCount { get; set; }
/// <summary>
/// 多数据库组
/// </summary>
public List<DBConfig> SqlConfig { get; set; }
/// <summary>
/// 是否集群
/// </summary>
public bool? IsCluster { get; set; }
/// <summary>
/// 是否删除定时调度任务
/// </summary>
public bool? NeedClear { get; set; }
/// <summary>
/// 主程序数据库编号
/// </summary>
public string MainDbNumber { get; set; }
/// <summary>
/// 是否开启定时任务
/// </summary>
public bool? OpenQuartz { get; set; }
/// <summary>
/// api文档配置
/// </summary>
public DocumentSettings DocumentSettings { get; set; }
/// <summary>
/// rabbitmq配置
/// </summary>
public MqConfig RabbitMq { get; set; }
}
public class DocumentSettings
{
/// <summary>
/// 标题
/// </summary>
public string DocumentTitle { get; set; }
public List<GroupOpenApiInfo> GroupOpenApiInfos { get; set; }
}
public class GroupOpenApiInfo
{
/// <summary>
/// 分组
/// </summary>
public string Group { get; set; }
/// <summary>
/// 组标题
/// </summary>
public string Title { get; set; }
/// <summary>
/// 描述
/// </summary>
public string Description { get; set; }
/// <summary>
/// 版本
/// </summary>
public string Version { get; set; }
}
public class DBConfig
{
/// <summary>
/// 数据库序号
/// </summary>
public string DBNumber { get; set; }
/// <summary>
/// 数据库类型
/// </summary>
public string DBProvider { get; set; }
/// <summary>
/// 数据库连接
/// </summary>
public string DBConnectionString { get; set; }
}
}

View File

@@ -0,0 +1,47 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System;
namespace WaterCloud.Code
{
/// <summary>
/// 当前用户信息
/// </summary>
public class OperatorModel
{
public string UserId { get; set; }
public string UserCode { get; set; }
public string UserName { get; set; }
public string UserPwd { get; set; }
public string CompanyId { get; set; }
public string OrganizeId { get; set; }
public string RoleId { get; set; }
public string LoginIPAddress { get; set; }
public string LoginIPAddressName { get; set; }
public string LoginToken { get; set; }
public DateTime LoginTime { get; set; }
//超管
public bool IsSuperAdmin { get; set; }
public bool IsAdmin { get; set; }
public bool IsBoss { get; set; }
public bool IsSenior { get; set; }
public bool IsSaleman { get; set; }
// 拓展字段2019-03-03
public string DdUserId { get; set; }
public string WxOpenId { get; set; }
public string Avatar { get; set; }
public string loginMark { get; set; }
//扩展字段 数据库序号2021-05-12
public string DbNumber { get; set; }
}
}

View File

@@ -0,0 +1,395 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace WaterCloud.Code
{
public class OperatorProvider
{
//是否允许一个账户在多处登录
private static bool LoginMultiple = GlobalContext.SystemConfig.LoginMultiple;
//缓存过期时间
private static int LoginExpire = GlobalContext.SystemConfig.LoginExpire;
private static string projectPrefix = GlobalContext.SystemConfig.ProjectPrefix;
public static OperatorProvider Provider
{
get { return new OperatorProvider(); }
}
//watercloud_operator_pc_ PC端登录
//watercloud_operator_info_ 登录次数
//
/// <summary>
/// 缓存操作类
/// </summary>
private string cacheKeyOperator = projectPrefix + "_operator_";// +登录者token
private string cacheKeyToken = projectPrefix + "_token_";// +登录者token
private string cacheKeyError = projectPrefix + "_error_";// + Mark
/// <summary>
/// 秘钥
/// </summary>
private string LoginUserToken = projectPrefix + "_Token";
/// <summary>
/// 标记登录的浏览器
/// </summary>
private string LoginUserMarkKey = projectPrefix + "_Mark";
public string GetProvider(string key)
{
var token = GetToken();
if (!string.IsNullOrEmpty(token))
return token;
token = WebHelper.GetCookie(key).ToString();
if (!string.IsNullOrEmpty(token))
return token;
return WebHelper.GetSession(key).ToString();
}
public void SetProvider(string key, string value)
{
WebHelper.WriteCookie(key, value);
WebHelper.WriteSession(key, value);
}
public string GetToken()
{
try
{
if (GlobalContext.HttpContext == null)
{
return null;
}
//查请求头
string token = GlobalContext.HttpContext.Request.Headers[GlobalContext.SystemConfig.TokenName].ParseToString();
if (!String.IsNullOrEmpty(token)) return token;
//查参数
token = GlobalContext.HttpContext.Request.Query[GlobalContext.SystemConfig.TokenName];
if (!String.IsNullOrEmpty(token)) return token;
//查cookies
string cookie = GlobalContext.HttpContext.Request.Cookies[GlobalContext.SystemConfig.TokenName];
return cookie == null ? string.Empty : cookie;
}
catch (Exception)
{
return null;
}
}
public void RemoveProvider(string key)
{
WebHelper.RemoveCookie(key);
WebHelper.RemoveSession(key);
}
public OperatorModel GetCurrent()
{
OperatorModel operatorModel = new OperatorModel();
try
{
string loginMark = GetProvider(LoginUserMarkKey);
operatorModel = CacheHelper.Get<OperatorModel>(cacheKeyOperator + loginMark);
}
catch
{
operatorModel = null;
}
return operatorModel;
}
/// <summary>
/// 获取浏览器设配号
/// </summary>
/// <returns></returns>
public string GetMark()
{
string cookieMark = GetProvider(LoginUserMarkKey);
if (string.IsNullOrEmpty(cookieMark))
{
cookieMark = Guid.NewGuid().ToString();
SetProvider(LoginUserMarkKey, cookieMark);
}
return cookieMark;
}
/// <summary>
/// 登录者信息添加到缓存中
/// </summary>
/// <param name="userEntity">用户</param>
/// <param name="loginMark">设备标识uid</param>
/// <param name="facilityMark">设备类型</param>
/// <param name="cookie">是否保存cookie默认是</param>
/// <returns></returns>
public async Task<string> AddLoginUser(OperatorModel operatorModel, string loginMark, string facilityMark)
{
string token = Guid.NewGuid().ToString();
try
{
// 填写登录信息
operatorModel.LoginToken = token;
//登录信息更新
if (string.IsNullOrEmpty(loginMark))
{
string cookieMark = GetProvider(LoginUserMarkKey);
if (string.IsNullOrEmpty(cookieMark))
{
operatorModel.loginMark = Guid.NewGuid().ToString();
SetProvider(LoginUserMarkKey, operatorModel.loginMark);
}
else
{
operatorModel.loginMark = cookieMark;
}
SetProvider(LoginUserToken, token);
}
else
{
operatorModel.loginMark = loginMark;
RemoveProvider(LoginUserMarkKey);
}
//redis 登录token列表更新
Dictionary<string, string> tokenMarkList = await CacheHelper.GetAsync<Dictionary<string, string>>(cacheKeyToken + operatorModel.UserId);
if (tokenMarkList == null)// 此账号第一次登录
{
tokenMarkList = new Dictionary<string, string>();
tokenMarkList.Add(operatorModel.loginMark, token);
}
else
{
if (tokenMarkList.ContainsKey(operatorModel.loginMark))
{
tokenMarkList[operatorModel.loginMark] = token;
}
else
{
tokenMarkList.Add(operatorModel.loginMark, token);
}
}
await CacheHelper.SetAsync(cacheKeyToken + operatorModel.UserId, tokenMarkList);
await CacheHelper.SetAsync(cacheKeyOperator + operatorModel.loginMark, operatorModel, LoginExpire);
await CacheHelper.RemoveAsync(cacheKeyOperator + facilityMark + operatorModel.UserId);
await CacheHelper.SetAsync(cacheKeyOperator + facilityMark + operatorModel.UserId, token, LoginExpire);
return token;
}
catch (Exception)
{
throw;
}
}
/// <summary>
/// 清空当前登录信息
/// </summary>
/// <param name="apitoken">apitoken</param>
/// <param name="facilityMark">设备类型</param>
public async Task EmptyCurrent(string facilityMark)
{
try
{
string token = GetProvider(LoginUserToken);
string loginMark = GetProvider(LoginUserMarkKey);
await EmptyCurrent(token, facilityMark, loginMark);
RemoveProvider(LoginUserMarkKey.Trim());
RemoveProvider(LoginUserToken.Trim());
}
catch (Exception)
{
}
}
/// <summary>
/// 清空当前登录信息
/// </summary>
/// <param name="token">登录票据</param>
/// <param name="facilityMark">登录设备</param>
/// <param name="loginMark">登录设备标识</param>
public async Task EmptyCurrent(string token, string facilityMark, string loginMark)
{
try
{
OperatorModel operatorInfo = await CacheHelper.GetAsync<OperatorModel>(cacheKeyOperator + loginMark);
if (operatorInfo != null)
{
Dictionary<string, string> tokenMarkList = await CacheHelper.GetAsync<Dictionary<string, string>>(cacheKeyToken + operatorInfo.UserId);
tokenMarkList.Remove(loginMark);
await CacheHelper.RemoveAsync(cacheKeyOperator + loginMark);
if (operatorInfo.LoginToken == token || facilityMark == "api_")
{
await CacheHelper.RemoveAsync(cacheKeyOperator + facilityMark + operatorInfo.UserId);
}
await CacheHelper.SetAsync(cacheKeyToken + operatorInfo.UserId, tokenMarkList);
await CacheHelper.RemoveAsync(facilityMark + GlobalContext.SystemConfig.TokenName + "_" + operatorInfo.UserId + "_" + operatorInfo.LoginTime);
}
}
catch (Exception)
{
}
}
/// <summary>
/// 判断登录状态
/// </summary>
/// <param name="facilityMark">登录设备</param>
/// <param name="apitoken">apitoken</param>
/// <returns>-1未登录,1登录成功,0登录过期,-2账号被顶</returns>
public async Task<OperatorResult> IsOnLine(string facilityMark)
{
try
{
string token = GetProvider(LoginUserToken);
string loginMark = GetProvider(LoginUserMarkKey);
return await IsOnLine(token, facilityMark, loginMark);
}
catch (Exception)
{
return new OperatorResult { stateCode = -1 };
}
}
/// <summary>
/// 判断登录状态
/// </summary>
/// <param name="token">登录票据</param>
/// <param name="facilityMark">登录设备</param>
/// <param name="loginMark">登录设备标识</param>
/// <returns>-1未登录,1登录成功,0登录过期,-2账号被顶</returns>
public async Task<OperatorResult> IsOnLine(string token, string facilityMark, string loginMark)
{
OperatorResult operatorResult = new OperatorResult();
operatorResult.stateCode = -1; // -1未登录,1登录成功,0登录过期
try
{
if (string.IsNullOrEmpty(token) || string.IsNullOrEmpty(loginMark))
{
return operatorResult;
}
OperatorModel operatorInfo = await CacheHelper.GetAsync<OperatorModel>(cacheKeyOperator + loginMark);
if (operatorInfo != null)
{
Dictionary<string, string> tokenMarkList = await CacheHelper.GetAsync<Dictionary<string, string>>(cacheKeyToken + operatorInfo.UserId);
if ((token == operatorInfo.LoginToken || facilityMark == "api_") && tokenMarkList.ContainsKey(operatorInfo.loginMark) && tokenMarkList[operatorInfo.loginMark] == operatorInfo.LoginToken)
{
////账号被顶(排除admin)
if (!LoginMultiple && !operatorInfo.IsSuperAdmin && operatorInfo.LoginToken != await CacheHelper.GetAsync<string>(cacheKeyOperator + facilityMark + operatorInfo.UserId))
{
operatorResult.stateCode = -2;
tokenMarkList = await CacheHelper.GetAsync<Dictionary<string, string>>(cacheKeyToken + operatorInfo.UserId);
tokenMarkList.Remove(loginMark);
await CacheHelper.SetAsync(cacheKeyToken + operatorInfo.UserId, tokenMarkList);
await CacheHelper.RemoveAsync(cacheKeyOperator + loginMark);
}
else
{
operatorResult.userInfo = operatorInfo;
operatorResult.stateCode = 1;
await CacheHelper.ExpireAsync(cacheKeyOperator + loginMark, LoginExpire);
await CacheHelper.ExpireAsync(cacheKeyOperator + facilityMark + operatorInfo.UserId, LoginExpire);
await CacheHelper.ExpireAsync(facilityMark + GlobalContext.SystemConfig.TokenName + "_" + operatorInfo.UserId + "_" + operatorInfo.LoginTime, LoginExpire);
}
}
}
return operatorResult;
}
catch (Exception)
{
return operatorResult;
}
}
#region
/// <summary>
/// 获取当前登录错误次数
/// </summary>
/// <returns></returns>
public async Task<int> GetCurrentErrorNum()
{
int res = 0;
try
{
string cookieMark = GetProvider(LoginUserMarkKey);
if (string.IsNullOrEmpty(cookieMark))
{
cookieMark = Guid.NewGuid().ToString();
SetProvider(LoginUserMarkKey, cookieMark);
}
string num = await CacheHelper.GetAsync<string>(cacheKeyError + cookieMark);
if (!string.IsNullOrEmpty(num))
{
res = Convert.ToInt32(num);
}
}
catch (Exception)
{
}
return res;
}
/// <summary>
/// 增加错误次数
/// </summary>
/// <returns></returns>
public async Task<int> AddCurrentErrorNum()
{
int res = 0;
try
{
string cookieMark = GetProvider(LoginUserMarkKey);
if (string.IsNullOrEmpty(cookieMark))
{
cookieMark = Guid.NewGuid().ToString();
SetProvider(LoginUserMarkKey, cookieMark);
}
string num = await CacheHelper.GetAsync<string>(cacheKeyError + cookieMark);
if (!string.IsNullOrEmpty(num))
{
res = Convert.ToInt32(num);
}
res++;
num = res + "";
await CacheHelper.SetAsync(cacheKeyError + cookieMark, num, 24);
}
catch (Exception)
{
}
return res;
}
/// <summary>
/// 清除当前登录错误次数
/// </summary>
public async Task ClearCurrentErrorNum()
{
try
{
string cookieMark = GetProvider(LoginUserMarkKey);
if (string.IsNullOrEmpty(cookieMark))
{
cookieMark = Guid.NewGuid().ToString();
SetProvider(LoginUserMarkKey, cookieMark);
}
await CacheHelper.RemoveAsync(cacheKeyError + cookieMark);
}
catch (Exception)
{
}
}
#endregion
}
}

View File

@@ -0,0 +1,15 @@
namespace WaterCloud.Code
{
public class OperatorResult
{
/// <summary>
/// 状态码-1未登录,1登录成功,0登录过期
/// </summary>
public int stateCode { get; set; }
/// <summary>
/// 登录者用户信息
/// </summary>
public OperatorModel userInfo { get; set; }
}
}

View File

@@ -0,0 +1,50 @@
using System;
namespace WaterCloud.Code
{
public class OperatorUserInfo
{
//密码
public string F_UserPassword { get; set; }
//
public string F_UserSecretkey { get; set; }
//登录时间设置
public DateTime? F_AllowStartTime { get; set; }
public DateTime? F_AllowEndTime { get; set; }
//锁定时间设置
public DateTime? F_LockStartDate { get; set; }
public DateTime? F_LockEndDate { get; set; }
//第一次登录
public DateTime? F_FirstVisitTime { get; set; }
//上一次登录时间
public DateTime? F_PreviousVisitTime { get; set; }
//最后一次登录时间
public DateTime? F_LastVisitTime { get; set; }
//修改密码时间
public DateTime? F_ChangePasswordDate { get; set; }
//登录次数
public int? F_LogOnCount { get; set; }
//在线标记
public bool? F_UserOnLine { get; set; }
//安全问题
public string F_Question { get; set; }
//问题答案
public string F_AnswerQuestion { get; set; }
//默认主题
public string F_Theme { get; set; }
}
}

View File

@@ -0,0 +1,27 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:59747/",
"sslPort": 44332
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"WaterCloud.Code": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:5001;http://localhost:5000"
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,18 @@
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
namespace WaterCloud.Code
{
/// <summary>
/// Controller Model Binding 处理
/// </summary>
public class ModelBindingMetadataProvider : IMetadataDetailsProvider, IDisplayMetadataProvider
{
public void CreateDisplayMetadata(DisplayMetadataProviderContext context)
{
if (context.Key.MetadataKind == ModelMetadataKind.Property)
{
context.DisplayMetadata.ConvertEmptyStringToNull = false;
}
}
}
}

View File

@@ -0,0 +1,238 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System;
using System.Security.Cryptography;
using System.Text;
namespace WaterCloud.Code
{
/// <summary>
/// DES加密、解密帮助类
/// </summary>
public class DESEncrypt
{
private static string DESKey = "WaterCloud_desencrypt_2019";
#region ================
/// <summary>
/// 加密
/// </summary>
/// <param name="Text"></param>
/// <returns></returns>
public static string Encrypt(string Text)
{
return Encrypt(Text, DESKey);
}
/// <summary>
/// 加密数据用Web.Security的Hash方式加密
/// </summary>
/// <param name="Text"></param>
/// <param name="sKey"></param>
/// <returns></returns>
public static string Encrypt(string Text, string sKey)
{
DES des = DES.Create();
byte[] inputByteArray;
inputByteArray = Encoding.Default.GetBytes(Text);
des.Key = ASCIIEncoding.ASCII.GetBytes(DecryptMd5(sKey));
des.IV = ASCIIEncoding.ASCII.GetBytes(DecryptMd5(sKey));
System.IO.MemoryStream ms = new System.IO.MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
StringBuilder ret = new StringBuilder();
foreach (byte b in ms.ToArray())
{
ret.AppendFormat("{0:X2}", b);
}
return ret.ToString();
}
/// <summary>
/// 加密数据, 用Security.MD5而非Web.Security的Hash方式加密
/// </summary>
/// <param name="Text"></param>
/// <returns></returns>
public static string Encrypt2(string Text)
{
return Encrypt2(Text, DESKey);
}
/// <summary>
/// 加密数据, 用Security.MD5而非Web.Security的Hash方式加密
/// </summary>
/// <param name="Text"></param>
/// <param name="sKey"></param>
/// <returns></returns>
public static string Encrypt2(string Text, string sKey)
{
DES des = DES.Create();
byte[] inputByteArray;
inputByteArray = Encoding.Default.GetBytes(Text);
sKey = MD5(sKey).Substring(0, 8);
des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
System.IO.MemoryStream ms = new System.IO.MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
StringBuilder ret = new StringBuilder();
foreach (byte b in ms.ToArray())
{
ret.AppendFormat("{0:X2}", b);
}
return ret.ToString();
}
#endregion ================
#region ================
/// <summary>
/// 解密
/// </summary>
/// <param name="Text"></param>
/// <returns></returns>
public static string Decrypt(string Text)
{
if (!string.IsNullOrEmpty(Text))
{
return Decrypt(Text, DESKey);
}
else
{
return "";
}
}
/// <summary>
/// 解密数据用Web.Security的Hash方式加密
/// </summary>
/// <param name="Text"></param>
/// <param name="sKey"></param>
/// <returns></returns>
public static string Decrypt(string Text, string sKey)
{
DES des = DES.Create();
int len;
len = Text.Length / 2;
byte[] inputByteArray = new byte[len];
int x, i;
for (x = 0; x < len; x++)
{
i = Convert.ToInt32(Text.Substring(x * 2, 2), 16);
inputByteArray[x] = (byte)i;
}
des.Key = ASCIIEncoding.ASCII.GetBytes(DecryptMd5(sKey));
des.IV = ASCIIEncoding.ASCII.GetBytes(DecryptMd5(sKey));
System.IO.MemoryStream ms = new System.IO.MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
return Encoding.Default.GetString(ms.ToArray());
}
public static string DecryptMd5(string str)
{
string strEncrypt = string.Empty;
var md5 = System.Security.Cryptography.MD5.Create();
var data = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
StringBuilder builder = new StringBuilder();
// 循环遍历哈希数据的每一个字节并格式化为十六进制字符串
for (int i = 0; i < data.Length; i++)
{
builder.Append(data[i].ToString("X2"));
}
strEncrypt = builder.ToString().Substring(0, 8);
return strEncrypt;
}
/// <summary>
/// 解密数据,用Security.MD5而非Web.Security的Hash方式加密
/// </summary>
/// <param name="Text"></param>
/// <returns></returns>
public static string Decrypt2(string Text)
{
if (!string.IsNullOrEmpty(Text))
{
return Decrypt2(Text, DESKey);
}
else
{
return "";
}
}
/// <summary>
/// 解密数据,用Security.MD5而非Web.Security的Hash方式加密
/// </summary>
/// <param name="Text"></param>
/// <param name="sKey"></param>
/// <returns></returns>
public static string Decrypt2(string Text, string sKey)
{
DES des = DES.Create();
int len;
len = Text.Length / 2;
byte[] inputByteArray = new byte[len];
int x, i;
for (x = 0; x < len; x++)
{
i = Convert.ToInt32(Text.Substring(x * 2, 2), 16);
inputByteArray[x] = (byte)i;
}
sKey = MD5(sKey).Substring(0, 8);
des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
System.IO.MemoryStream ms = new System.IO.MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
return Encoding.Default.GetString(ms.ToArray());
}
#endregion ================
public static string MD5(string pwd)
{
MD5 md5 = System.Security.Cryptography.MD5.Create();
byte[] data = System.Text.Encoding.Default.GetBytes(pwd);
byte[] md5data = md5.ComputeHash(data);
md5.Clear();
string str = "";
for (int i = 0; i < md5data.Length; i++)
{
str += md5data[i].ToString("x").PadLeft(2, '0');
}
return str;
}
/// <summary>
/// 基于Sha1的自定义加密字符串方法输入一个字符串返回一个由40个字符组成的十六进制的哈希散列字符串
/// </summary>
/// <param name="str">要加密的字符串</param>
/// <returns>加密后的十六进制的哈希散列(字符串)</returns>
public static string Sha1(string str)
{
var buffer = Encoding.UTF8.GetBytes(str);
var data = SHA1.Create().ComputeHash(buffer);
var sb = new StringBuilder();
foreach (var t in data)
{
sb.Append(t.ToString("X2"));
}
return sb.ToString();
}
}
}

View File

@@ -0,0 +1,95 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System;
using System.Security.Cryptography;
using System.Text;
namespace WaterCloud.Code
{
/// <summary>
/// MD5加密
/// </summary>
public class Md5
{
/// <summary>
/// MD5加密
/// </summary>
/// <param name="str">加密字符</param>
/// <param name="code">加密位数16/32</param>
/// <returns></returns>
public static string md5(string str, int code)
{
string strEncrypt = string.Empty;
if (code == 16)
{
var md5 = System.Security.Cryptography.MD5.Create();
var data = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
StringBuilder builder = new StringBuilder();
// 循环遍历哈希数据的每一个字节并格式化为十六进制字符串
for (int i = 0; i < data.Length; i++)
{
builder.Append(data[i].ToString("X2"));
}
strEncrypt = builder.ToString().Substring(8, 16);
}
if (code == 32)
{
var md5 = System.Security.Cryptography.MD5.Create();
var data = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
StringBuilder builder = new StringBuilder();
// 循环遍历哈希数据的每一个字节并格式化为十六进制字符串
for (int i = 0; i < data.Length; i++)
{
builder.Append(data[i].ToString("X2"));
}
strEncrypt = builder.ToString();
}
return strEncrypt;
}
public static string MD5(string str)
{
MD5 md5 = System.Security.Cryptography.MD5.Create();
byte[] data = System.Text.Encoding.Default.GetBytes(str);
byte[] md5data = md5.ComputeHash(data);
md5.Clear();
str = "";
for (int i = 0; i < md5data.Length; i++)
{
str += md5data[i].ToString("x").PadLeft(2, '0');
}
return str;
}
public static string MD5Lower16(string str)
{
return MD5(str).ToLower().Substring(8, 16);
}
public static string MD5Lower32(string str)
{
return MD5(str).ToLower(); ;
}
/// <summary>
/// 32位小写
/// </summary>
/// <returns></returns>
public static string SHA1(string s)
{
SHA1 sha1 = System.Security.Cryptography.SHA1.Create();
byte[] hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(s));
string shaStr = BitConverter.ToString(hash);
shaStr = shaStr.Replace("-", "");
shaStr = shaStr.ToLower();
return s.ToLower();
}
}
}

View File

@@ -0,0 +1,28 @@
using System;
using System.Threading.Tasks;
namespace WaterCloud.Code
{
public class AsyncTaskHelper
{
/// <summary>
/// 开始异步任务
/// </summary>
/// <param name="action"></param>
public static void StartTask(Action action)
{
try
{
Action newAction = () =>
{ };
newAction += action;
Task task = new Task(newAction);
task.Start();
}
catch (Exception ex)
{
LogHelper.WriteWithTime(ex);
}
}
}
}

View File

@@ -0,0 +1,124 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
namespace WaterCloud.Code
{
public enum StatusEnum
{
[Description("启用")]
Yes = 1,
[Description("禁用")]
No = 0
}
public enum IsEnum
{
[Description("是")]
Yes = 1,
[Description("否")]
No = 0
}
public enum NeedEnum
{
[Description("不需要")]
NotNeed = 0,
[Description("需要")]
Need = 1
}
public enum OperateStatusEnum
{
[Description("失败")]
Fail = 0,
[Description("成功")]
Success = 1
}
public enum UploadFileType
{
[Description("头像")]
Portrait = 1,
[Description("新闻图片")]
News = 2,
[Description("导入的文件")]
Import = 10
}
public enum PlatformEnum
{
[Description("Web后台")]
Web = 1,
[Description("WebApi")]
WebApi = 2
}
public enum PayStatusEnum
{
[Description("未知")]
Unknown = 0,
[Description("已支付")]
Success = 1,
[Description("转入退款")]
Refund = 2,
[Description("未支付")]
NotPay = 3,
[Description("已关闭")]
Closed = 4,
[Description("已撤销(付款码支付)")]
Revoked = 5,
[Description("用户支付中(付款码支付)")]
UserPaying = 6,
[Description("支付失败(其他原因,如银行返回失败)")]
PayError = 7
}
public class EnumHelper
{
/// <summary>
/// 获取枚举列表
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static Dictionary<int, string> EnumToDic<T>()
{
Dictionary<int, string> list = new Dictionary<int, string>();
foreach (var e in Enum.GetValues(typeof(T)))
{
list.Add(Convert.ToInt32(e), e.GetDescriptionByEnum<T>());
}
return list;
}
/// <summary>
/// 获取枚举列表
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static List<string> EnumToList<T>()
{
List<string> list = new List<string>();
foreach (var e in Enum.GetValues(typeof(T)))
{
list.Add(e.GetDescriptionByEnum<T>());
}
return list;
}
}
}

View File

@@ -0,0 +1,150 @@
using System;
using System.Runtime.InteropServices;
namespace WaterCloud.Code
{
public class ComputerHelper
{
public static ComputerInfo GetComputerInfo()
{
ComputerInfo computerInfo = new ComputerInfo();
try
{
MemoryMetricsClient client = new MemoryMetricsClient();
MemoryMetrics memoryMetrics = client.GetMetrics();
computerInfo.TotalRAM = Math.Ceiling(memoryMetrics.Total / 1024).ToString() + " GB";
computerInfo.RAMRate = Math.Ceiling(100 * memoryMetrics.Used / memoryMetrics.Total).ToString();
computerInfo.CPURate = Math.Ceiling(GetCPURate().ToDouble()).ToString();
computerInfo.RunTime = GetRunTime();
}
catch (Exception ex)
{
LogHelper.WriteWithTime(ex);
}
return computerInfo;
}
public static bool IsUnix()
{
var isUnix = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
return isUnix;
}
public static string GetCPURate()
{
string cpuRate = string.Empty;
if (IsUnix())
{
string output = ShellHelper.Bash("top -b -n1 | grep \"Cpu(s)\" | awk '{print $2 + $4}'");
cpuRate = output.Trim();
}
else
{
string output = ShellHelper.Cmd("wmic", "cpu get LoadPercentage");
cpuRate = output.Replace("LoadPercentage", string.Empty).Trim();
}
return cpuRate;
}
public static string GetRunTime()
{
string runTime = string.Empty;
try
{
if (IsUnix())
{
string output = ShellHelper.Bash("uptime -s");
output = output.Trim();
runTime = Extensions.FormatTime((DateTime.Now - output.ToDate()).TotalMilliseconds.ToString().Split('.')[0].ToLong());
}
else
{
string output = ShellHelper.Cmd("wmic", "OS get LastBootUpTime/Value");
string[] outputArr = output.Split("=", StringSplitOptions.RemoveEmptyEntries);
if (outputArr.Length == 2)
{
runTime = Extensions.FormatTime((DateTime.Now - outputArr[1].Split('.')[0].ToDate()).TotalMilliseconds.ToString().Split('.')[0].ToLong());
}
}
}
catch (Exception ex)
{
LogHelper.WriteWithTime(ex);
}
return runTime;
}
}
public class MemoryMetrics
{
public double Total { get; set; }
public double Used { get; set; }
public double Free { get; set; }
}
public class MemoryMetricsClient
{
public MemoryMetrics GetMetrics()
{
if (ComputerHelper.IsUnix())
{
return GetUnixMetrics();
}
return GetWindowsMetrics();
}
private MemoryMetrics GetWindowsMetrics()
{
string output = ShellHelper.Cmd("wmic", "OS get FreePhysicalMemory,TotalVisibleMemorySize /Value");
var lines = output.Trim().Split("\n");
var freeMemoryParts = lines[0].Split("=", StringSplitOptions.RemoveEmptyEntries);
var totalMemoryParts = lines[1].Split("=", StringSplitOptions.RemoveEmptyEntries);
var metrics = new MemoryMetrics();
metrics.Total = Math.Round(double.Parse(totalMemoryParts[1]) / 1024, 0);
metrics.Free = Math.Round(double.Parse(freeMemoryParts[1]) / 1024, 0);
metrics.Used = metrics.Total - metrics.Free;
return metrics;
}
private MemoryMetrics GetUnixMetrics()
{
string output = ShellHelper.Bash("free -m");
var lines = output.Split("\n");
var memory = lines[1].Split(" ", StringSplitOptions.RemoveEmptyEntries);
var metrics = new MemoryMetrics();
metrics.Total = double.Parse(memory[1]);
metrics.Used = double.Parse(memory[2]);
metrics.Free = double.Parse(memory[3]);
return metrics;
}
}
public class ComputerInfo
{
/// <summary>
/// CPU使用率
/// </summary>
public string CPURate { get; set; }
/// <summary>
/// 总内存
/// </summary>
public string TotalRAM { get; set; }
/// <summary>
/// 内存使用率
/// </summary>
public string RAMRate { get; set; }
/// <summary>
/// 系统运行时间
/// </summary>
public string RunTime { get; set; }
}
}

View File

@@ -0,0 +1,140 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
namespace WaterCloud.Code
{
public class ConcurrentList<T> : IList<T>
{
protected static object _lock = new object();
protected List<T> _interalList = new List<T>();
public IEnumerator<T> GetEnumerator()
{
return Clone().GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return Clone().GetEnumerator();
}
public int Count
{ get { return _interalList.Count; } }
public bool IsReadOnly
{ get { return false; } }
public T this[int index]
{
get
{
lock (_lock)
{
return _interalList[index];
}
}
set
{
lock (_lock)
{
_interalList[index] = value;
}
}
}
public List<T> Clone()
{
List<T> newList = new List<T>();
lock (_lock)
{
_interalList.ForEach(x => newList.Add(x));
}
return newList;
}
public int IndexOf(T item)
{
return _interalList.IndexOf(item);
}
public void Insert(int index, T item)
{
_interalList.Insert(index, item);
}
public void RemoveAt(int index)
{
lock (_lock)
{
_interalList.RemoveAt(index);
}
}
public void Add(T item)
{
lock (_lock)
{
_interalList.Add(item);
}
}
public void AddRange(IEnumerable<T> list)
{
foreach (T item in list)
{
Add(item);
}
}
public void Clear()
{
lock (_lock)
{
_interalList.Clear();
}
}
public bool Contains(T item)
{
return _interalList.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
_interalList.CopyTo(array, arrayIndex);
}
public bool Remove(T item)
{
if (item == null)
{
return false;
}
lock (_lock)
{
return _interalList.Remove(item);
}
}
public void RemoveAll(Predicate<T> match)
{
if (match == null)
{
return;
}
Contract.Ensures(Contract.Result<int>() >= 0);
Contract.Ensures(Contract.Result<int>() <= Contract.OldValue(Count));
Contract.EndContractBlock();
foreach (T t in Clone())
{
if (match(t))
{
Remove(t);
}
}
}
}
}

View File

@@ -0,0 +1,128 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;
namespace WaterCloud.Code
{
public static class DataTableHelper
{
public static DataTable ListToDataTable<T>(List<T> entitys)
{
//检查实体集合不能为空
if (entitys == null || entitys.Count < 1)
{
throw new Exception("需转换的集合为空");
}
//取出第一个实体的所有Propertie
Type entityType = entitys[0].GetType();
PropertyInfo[] entityProperties = entityType.GetProperties();
//生成DataTable的structure
//生产代码中应将生成的DataTable结构Cache起来此处略
DataTable dt = new DataTable();
for (int i = 0; i < entityProperties.Length; i++)
{
dt.Columns.Add(entityProperties[i].Name);
}
//将所有entity添加到DataTable中
foreach (object entity in entitys)
{
//检查所有的的实体都为同一类型
if (entity.GetType() != entityType)
{
throw new Exception("要转换的集合元素类型不一致");
}
object[] entityValues = new object[entityProperties.Length];
for (int i = 0; i < entityProperties.Length; i++)
{
entityValues[i] = entityProperties[i].GetValue(entity, null);
}
dt.Rows.Add(entityValues);
}
return dt;
}
/// <summary>
/// List过滤
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entitys"></param>
/// <param name="list"></param>
/// <returns></returns>
public static List<T> ListFilter<T>(List<T> entitys, List<string> list)
{
//检查实体集合不能为空
if (entitys == null || entitys.Count < 1)
{
throw new Exception("需转换的集合为空");
}
//取出第一个实体的所有Propertie
Type entityType = entitys[0].GetType();
PropertyInfo[] entityProperties = entityType.GetProperties();
//将所有entity过滤
foreach (object entity in entitys)
{
//检查所有的的实体都为同一类型
if (entity.GetType() != entityType)
{
throw new Exception("要转换的集合元素类型不一致");
}
for (int i = 0; i < entityProperties.Length; i++)
{
if (!list.Contains(entityProperties[i].Name))
{
entityProperties[i].SetValue(entity, null);
}
}
}
return entitys;
}
/// <summary>
/// DataTable转成List
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="dt"></param>
/// <returns></returns>
public static List<T> ToDataList<T>(this DataTable dt)
{
var list = new List<T>();
var plist = new List<PropertyInfo>(typeof(T).GetProperties());
foreach (DataRow item in dt.Rows)
{
T s = Activator.CreateInstance<T>();
for (int i = 0; i < dt.Columns.Count; i++)
{
PropertyInfo info = plist.Find(p => p.Name == dt.Columns[i].ColumnName);
if (info != null)
{
try
{
if (!Convert.IsDBNull(item[i]))
{
object v = null;
if (info.PropertyType.ToString().Contains("System.Nullable"))
{
v = Convert.ChangeType(item[i], Nullable.GetUnderlyingType(info.PropertyType));
}
else
{
v = Convert.ChangeType(item[i], info.PropertyType);
}
info.SetValue(s, v, null);
}
}
catch (Exception ex)
{
throw new Exception("字段[" + info.Name + "]转换出错," + ex.Message);
}
}
}
list.Add(s);
}
return list;
}
}
}

View File

@@ -0,0 +1,697 @@
using System;
using System.Data;
using System.IO;
using System.Text;
namespace WaterCloud.Code
{
public class FileHelper
{
public static string MapPath(string path)
{
try
{
string rootdir = Directory.GetCurrentDirectory();
//DirectoryInfo Dir = Directory.GetParent(rootdir);
//string root = Dir.Parent.Parent.Parent.FullName;
return rootdir + path;
}
catch (Exception)
{
return path;
}
}
#region
/// <summary>
/// 读取指定位置文件列表到集合中
/// </summary>
/// <param name="path">指定路径</param>
/// <returns></returns>
public static DataTable GetFileTable(string path)
{
DataTable dt = new DataTable();
dt.Columns.Add("name", typeof(string));
dt.Columns.Add("ext", typeof(string));
dt.Columns.Add("size", typeof(long));
dt.Columns.Add("time", typeof(DateTime));
if (Directory.Exists(path))
{
DirectoryInfo dirinfo = new DirectoryInfo(path);
FileInfo fi;
DirectoryInfo dir;
string FileName, FileExt;
long FileSize = 0;
DateTime FileModify;
try
{
foreach (FileSystemInfo fsi in dirinfo.GetFileSystemInfos())
{
FileName = string.Empty;
FileExt = string.Empty;
if (fsi is FileInfo)
{
fi = (FileInfo)fsi;
//获取文件名称
FileName = fi.Name;
//获取文件扩展名
FileExt = fi.Extension;
//获取文件大小
FileSize = fi.Length;
//获取文件最后修改时间
FileModify = fi.LastWriteTime;
}
else
{
dir = (DirectoryInfo)fsi;
//获取目录名
FileName = dir.Name;
//获取目录最后修改时间
FileModify = dir.LastWriteTime;
//设置目录文件为文件夹
FileExt = "文件夹";
}
DataRow dr = dt.NewRow();
dr["name"] = FileName;
dr["ext"] = FileExt;
dr["size"] = FileSize;
dr["time"] = FileModify;
dt.Rows.Add(dr);
}
}
catch
{
throw;
}
}
return dt;
}
#endregion
#region
/// <summary>
/// 检测指定路径是否存在
/// </summary>
/// <param name="path">目录的绝对路径</param>
public static bool IsExistDirectory(string path)
{
return Directory.Exists(path);
}
#endregion
#region ,true
/// <summary>
/// 检测指定文件是否存在,如果存在则返回true
/// </summary>
/// <param name="filePath">文件的绝对路径</param>
public static bool IsExistFile(string filePath)
{
return File.Exists(filePath);
}
#endregion ,true
#region
/// <summary>
/// 创建文件夹
/// </summary>
/// <param name="folderPath">文件夹的绝对路径</param>
public static void CreateFolder(string folderPath)
{
if (!IsExistDirectory(folderPath))
{
Directory.CreateDirectory(folderPath);
}
}
#endregion
#region
/// <summary>
/// 判断上传文件后缀名
/// </summary>
/// <param name="strExtension">后缀名</param>
public static bool IsCanEdit(string strExtension)
{
strExtension = strExtension.ToLower();
if (strExtension.LastIndexOf(".", StringComparison.Ordinal) >= 0)
{
strExtension = strExtension.Substring(strExtension.LastIndexOf(".", StringComparison.Ordinal));
}
else
{
strExtension = ".txt";
}
string[] strArray = new string[] { ".htm", ".html", ".txt", ".js", ".css", ".xml", ".sitemap" };
for (int i = 0; i < strArray.Length; i++)
{
if (strExtension.Equals(strArray[i]))
{
return true;
}
}
return false;
}
public static bool IsSafeName(string strExtension)
{
strExtension = strExtension.ToLower();
if (strExtension.LastIndexOf(".") >= 0)
{
strExtension = strExtension.Substring(strExtension.LastIndexOf("."));
}
else
{
strExtension = ".txt";
}
string[] strArray = new string[] { ".jpg", ".gif", ".png" };
for (int i = 0; i < strArray.Length; i++)
{
if (strExtension.Equals(strArray[i]))
{
return true;
}
}
return false;
}
public static bool IsZipName(string strExtension)
{
strExtension = strExtension.ToLower();
if (strExtension.LastIndexOf(".") >= 0)
{
strExtension = strExtension.Substring(strExtension.LastIndexOf("."));
}
else
{
strExtension = ".txt";
}
string[] strArray = new string[] { ".zip", ".rar" };
for (int i = 0; i < strArray.Length; i++)
{
if (strExtension.Equals(strArray[i]))
{
return true;
}
}
return false;
}
#endregion
#region
/// <summary>
/// 创建文件夹
/// </summary>
/// <param name="fileName">文件的绝对路径</param>
public static void CreateSuffic(string fileName)
{
try
{
if (!Directory.Exists(fileName))
{
Directory.CreateDirectory(fileName);
}
}
catch (Exception)
{
throw;
}
}
/// <summary>
/// 创建文件夹
/// </summary>
/// <param name="fileName">文件的绝对路径</param>
public static void CreateFiles(string fileName)
{
try
{
//判断文件是否存在,不存在创建该文件
if (!IsExistFile(fileName))
{
FileInfo file = new FileInfo(fileName);
FileStream fs = file.Create();
fs.Close();
}
}
catch (Exception ex)
{
LogHelper.WriteWithTime(ex);
}
}
#region
/// <summary>
/// 创建文件
/// </summary>
/// <param name="path"></param>
/// <param name="content"></param>
public static void CreateFile(string path, string content)
{
if (!Directory.Exists(Path.GetDirectoryName(path)))
{
Directory.CreateDirectory(Path.GetDirectoryName(path));
}
using (StreamWriter sw = new StreamWriter(path, false, Encoding.UTF8))
{
sw.Write(content);
}
}
#endregion
/// <summary>
/// 创建一个文件,并将字节流写入文件。
/// </summary>
/// <param name="filePath">文件的绝对路径</param>
/// <param name="buffer">二进制流数据</param>
public static void CreateFile(string filePath, byte[] buffer)
{
try
{
//判断文件是否存在,不存在创建该文件
if (!IsExistFile(filePath))
{
FileInfo file = new FileInfo(filePath);
FileStream fs = file.Create();
fs.Write(buffer, 0, buffer.Length);
fs.Close();
}
else
{
File.WriteAllBytes(filePath, buffer);
}
}
catch (Exception ex)
{
LogHelper.WriteWithTime(ex);
}
}
#endregion
#region
/// <summary>
/// 将文件移动到指定目录
/// </summary>
/// <param name="sourceFilePath">需要移动的源文件的绝对路径</param>
/// <param name="descDirectoryPath">移动到的目录的绝对路径</param>
public static void Move(string sourceFilePath, string descDirectoryPath)
{
string sourceName = GetFileName(sourceFilePath);
if (IsExistDirectory(descDirectoryPath))
{
//如果目标中存在同名文件,则删除
if (IsExistFile(descDirectoryPath + "\\" + sourceFilePath))
{
DeleteFile(descDirectoryPath + "\\" + sourceFilePath);
}
else
{
//将文件移动到指定目录
File.Move(sourceFilePath, descDirectoryPath + "\\" + sourceFilePath);
}
}
}
#endregion
#region
/// <summary>
/// 将源文件的内容复制到目标文件中
/// </summary>
/// <param name="sourceFilePath">源文件的绝对路径</param>
/// <param name="descDirectoryPath">目标文件的绝对路径</param>
public static void Copy(string sourceFilePath, string descDirectoryPath)
{
File.Copy(sourceFilePath, descDirectoryPath, true);
}
#endregion
#region ( )
/// <summary>
/// 从文件的绝对路径中获取文件名( 不包含扩展名 )
/// </summary>
/// <param name="filePath">文件的绝对路径</param>
public static string GetFileName(string filePath)
{
FileInfo file = new FileInfo(filePath);
return file.Name;
}
#endregion ( )
#region
/// <summary>
/// 获取文件的后缀名
/// </summary>
/// <param name="filePath">文件的绝对路径</param>
public static string GetExtension(string filePath)
{
FileInfo file = new FileInfo(filePath);
return file.Extension;
}
/// <summary>
/// 返回文件扩展名,不含“.”
/// </summary>
/// <param name="filepath">文件全名称</param>
/// <returns>string</returns>
public static string GetFileExt(string filepath)
{
if (string.IsNullOrEmpty(filepath))
{
return "";
}
if (filepath.LastIndexOf(".", StringComparison.Ordinal) > 0)
{
return filepath.Substring(filepath.LastIndexOf(".", StringComparison.Ordinal) + 1); //文件扩展名,不含“.”
}
return "";
}
#endregion
#region
/// <summary>
/// 删除指定文件
/// </summary>
/// <param name="filePath">文件的绝对路径</param>
public static void DeleteFile(string filePath)
{
if (IsExistFile(filePath))
{
File.Delete(filePath);
}
}
#endregion
#region
/// <summary>
/// 删除指定目录及其所有子目录
/// </summary>
/// <param name="directoryPath">文件的绝对路径</param>
public static void DeleteDirectory(string directoryPath)
{
if (IsExistDirectory(directoryPath))
{
Directory.Delete(directoryPath);
}
}
#endregion
#region ,.
/// <summary>
/// 清空指定目录下所有文件及子目录,但该目录依然保存.
/// </summary>
/// <param name="directoryPath">指定目录的绝对路径</param>
public static void ClearDirectory(string directoryPath)
{
if (!IsExistDirectory(directoryPath)) return;
//删除目录中所有的文件
string[] fileNames = GetFileNames(directoryPath);
for (int i = 0; i < fileNames.Length; i++)
{
DeleteFile(fileNames[i]);
}
//删除目录中所有的子目录
string[] directoryNames = GetDirectories(directoryPath);
for (int i = 0; i < directoryNames.Length; i++)
{
DeleteDirectory(directoryNames[i]);
}
}
#endregion ,.
#region
/// <summary>
/// 剪切文件
/// </summary>
/// <param name="source">原路径</param>
/// <param name="destination">新路径</param>
public bool FileMove(string source, string destination)
{
bool ret = false;
FileInfo file_s = new FileInfo(source);
FileInfo file_d = new FileInfo(destination);
if (file_s.Exists)
{
if (!file_d.Exists)
{
file_s.MoveTo(destination);
ret = true;
}
}
if (ret == true)
{
//Response.Write("<script>alert('剪切文件成功!');</script>");
}
else
{
//Response.Write("<script>alert('剪切文件失败!');</script>");
}
return ret;
}
#endregion
#region
/// <summary>
/// 检测指定目录是否为空
/// </summary>
/// <param name="directoryPath">指定目录的绝对路径</param>
public static bool IsEmptyDirectory(string directoryPath)
{
try
{
//判断文件是否存在
string[] fileNames = GetFileNames(directoryPath);
if (fileNames.Length > 0)
{
return false;
}
//判断是否存在文件夹
string[] directoryNames = GetDirectories(directoryPath);
if (directoryNames.Length > 0)
{
return false;
}
return true;
}
catch (Exception)
{
return true;
}
}
#endregion
#region
/// <summary>
/// 获取指定目录中所有文件列表
/// </summary>
/// <param name="directoryPath">指定目录的绝对路径</param>
public static string[] GetFileNames(string directoryPath)
{
if (!IsExistDirectory(directoryPath))
{
throw new FileNotFoundException();
}
return Directory.GetFiles(directoryPath);
}
#endregion
#region
/// <summary>
/// 获取指定目录中所有子目录列表,若要搜索嵌套的子目录列表,请使用重载方法
/// </summary>
/// <param name="directoryPath">指定目录的绝对路径</param>
public static string[] GetDirectories(string directoryPath)
{
return Directory.GetDirectories(directoryPath);
}
/// <summary>
/// 获取指定目录及子目录中所有子目录列表
/// </summary>
/// <param name="directoryPath">指定目录的绝对路径</param>
/// <param name="searchPattern">模式字符串,"*"代表0或N个字符"?"代表1个字符。
/// 范例:"Log*.xml"表示搜索所有以Log开头的Xml文件。</param>
/// <param name="isSearchChild">是否搜索子目录</param>
public static string[] GetDirectories(string directoryPath, string searchPattern, bool isSearchChild)
{
if (isSearchChild)
{
return Directory.GetDirectories(directoryPath, searchPattern, SearchOption.AllDirectories);
}
else
{
return Directory.GetDirectories(directoryPath, searchPattern, SearchOption.TopDirectoryOnly);
}
}
#endregion
#region
/// <summary>
/// 获取一个文件的长度,单位为Byte
/// </summary>
/// <param name="filePath">文件的绝对路径</param>
public static int GetFileSize(string filePath)
{
//创建一个文件对象
FileInfo fi = new FileInfo(filePath);
//获取文件的大小
return (int)fi.Length;
}
/// <summary>
/// 获取一个文件的长度,单位为KB
/// </summary>
/// <param name="filePath">文件的路径</param>
public static double GetFileSizeByKb(string filePath)
{
//创建一个文件对象
FileInfo fi = new FileInfo(filePath);
//获取文件的大小
return Math.Round(Convert.ToDouble(filePath.Length) / 1024, 2);// ConvertHelper.ToDouble(ConvertHelper.ToDouble(fi.Length) / 1024, 1);
}
/// <summary>
/// 获取一个文件的长度,单位为MB
/// </summary>
/// <param name="filePath">文件的路径</param>
public static double GetFileSizeByMb(string filePath)
{
//创建一个文件对象
FileInfo fi = new FileInfo(filePath);
//获取文件的大小
return Math.Round(Convert.ToDouble(Convert.ToDouble(fi.Length) / 1024 / 1024), 2);
}
#endregion
#region BKBGBTB
/// <summary>
/// 计算文件大小函数(保留两位小数),Size为字节大小
/// </summary>
/// <param name="size">初始文件大小</param>
/// <returns></returns>
public static string ToFileSize(long size)
{
string m_strSize = "";
long FactSize = 0;
FactSize = size;
if (FactSize < 1024.00)
m_strSize = FactSize.ToString("F2") + " 字节";
else if (FactSize >= 1024.00 && FactSize < 1048576)
m_strSize = (FactSize / 1024.00).ToString("F2") + " KB";
else if (FactSize >= 1048576 && FactSize < 1073741824)
m_strSize = (FactSize / 1024.00 / 1024.00).ToString("F2") + " MB";
else if (FactSize >= 1073741824)
m_strSize = (FactSize / 1024.00 / 1024.00 / 1024.00).ToString("F2") + " GB";
return m_strSize;
}
#endregion BKBGBTB
#region
/// <summary>
/// 将文件读取到字符串中
/// </summary>
/// <param name="filePath">文件的绝对路径</param>
public static string FileToString(string filePath)
{
return FileToString(filePath, Encoding.UTF8);
}
/// <summary>
/// 将文件读取到字符串中
/// </summary>
/// <param name="filePath">文件的绝对路径</param>
/// <param name="encoding">字符编码</param>
public static string FileToString(string filePath, Encoding encoding)
{
//创建流读取器
StreamReader reader = new StreamReader(filePath, encoding);
try
{
//读取流
return reader.ReadToEnd();
}
finally
{
//关闭流读取器
reader.Close();
}
}
#endregion
#region
// 判断文件是否是bai图片
public static bool IsPicture(string fileName)
{
string strFilter = ".jpeg|.gif|.jpg|.png|.bmp|.pic|.tiff|.ico|.iff|.lbm|.mag|.mac|.mpt|.opt|";
char[] separtor = { '|' };
string[] tempFileds = StringSplit(strFilter, separtor);
foreach (string str in tempFileds)
{
if (str.ToUpper() == fileName.Substring(fileName.LastIndexOf("."), fileName.Length - fileName.LastIndexOf(".")).ToUpper()) { return true; }
}
return false;
}
// 判断文件是否是excle
public static bool IsExcel(string fileName)
{
string strFilter = ".xls|.xlsx|";
char[] separtor = { '|' };
string[] tempFileds = StringSplit(strFilter, separtor);
foreach (string str in tempFileds)
{
if (str.ToUpper() == fileName.Substring(fileName.LastIndexOf("."), fileName.Length - fileName.LastIndexOf(".")).ToUpper()) { return true; }
}
return false;
}
// 通过字符串分隔符返回zhistring[]数组 
public static string[] StringSplit(string s, char[] separtor)
{
string[] tempFileds = s.Trim().Split(separtor); return tempFileds;
}
#endregion
}
}

View File

@@ -0,0 +1,225 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
namespace WaterCloud.Code
{
public class HttpWebClient
{
private IHttpClientFactory _httpClientFactory;
public HttpWebClient(IHttpClientFactory httpClientFactory)
{
this._httpClientFactory = httpClientFactory;
}
/// <summary>
/// Get异步请求
/// </summary>
/// <param name="url"></param>
/// <param name="dicHeaders"></param>
/// <param name="timeoutSecond"></param>
/// <returns></returns>
public async Task<string> GetAsync(string url, Dictionary<string, string> dicHeaders, int timeoutSecond = 120)
{
var client = _httpClientFactory.CreateClient();
var request = new HttpRequestMessage(HttpMethod.Get, url);
if (dicHeaders != null)
{
foreach (var header in dicHeaders)
{
request.Headers.Add(header.Key, header.Value);
}
}
client.Timeout = TimeSpan.FromSeconds(timeoutSecond);
var response = await client.SendAsync(request);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsStringAsync();
return result;
}
else
{
throw new CustomerHttpException($"接口请求错误,错误代码{response.StatusCode},错误原因{response.ReasonPhrase}");
}
}
/// <summary>
///
/// </summary>
/// <param name="url"></param>
/// <param name="requestString"></param>
/// <param name="dicHeaders"></param>
/// <param name="timeoutSecond"></param>
/// <returns></returns>
public async Task<string> PostAsync(string url, string requestString, Dictionary<string, string> dicHeaders, int timeoutSecond)
{
var client = _httpClientFactory.CreateClient();
var requestContent = new StringContent(requestString);
if (dicHeaders != null)
{
foreach (var head in dicHeaders)
{
requestContent.Headers.Add(head.Key, head.Value);
}
}
client.Timeout = TimeSpan.FromSeconds(timeoutSecond);
var response = await client.PostAsync(url, requestContent);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsStringAsync();
return result;
}
else
{
throw new CustomerHttpException($"接口请求错误,错误代码{response.StatusCode},错误原因{response.ReasonPhrase}");
}
}
/// <summary>
///
/// </summary>
/// <param name="url"></param>
/// <param name="requestString"></param>
/// <param name="dicHeaders"></param>
/// <param name="timeoutSecond"></param>
/// <returns></returns>
public async Task<string> PutAsync(string url, string requestString, Dictionary<string, string> dicHeaders, int timeoutSecond)
{
var client = _httpClientFactory.CreateClient();
var requestContent = new StringContent(requestString);
if (dicHeaders != null)
{
foreach (var head in dicHeaders)
{
requestContent.Headers.Add(head.Key, head.Value);
}
}
client.Timeout = TimeSpan.FromSeconds(timeoutSecond);
var response = await client.PutAsync(url, requestContent);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsStringAsync();
return result;
}
else
{
throw new CustomerHttpException($"接口请求错误,错误代码{response.StatusCode},错误原因{response.ReasonPhrase}");
}
}
/// <summary>
/// Patch异步请求
/// </summary>
/// <param name="url"></param>
/// <param name="requestString"></param>
/// <param name="dicHeaders"></param>
/// <param name="timeoutSecond"></param>
/// <returns></returns>
public async Task<string> PatchAsync(string url, string requestString, Dictionary<string, string> dicHeaders, int timeoutSecond)
{
var client = _httpClientFactory.CreateClient();
var requestContent = new StringContent(requestString);
if (dicHeaders != null)
{
foreach (var head in dicHeaders)
{
requestContent.Headers.Add(head.Key, head.Value);
}
}
client.Timeout = TimeSpan.FromSeconds(timeoutSecond);
var response = await client.PatchAsync(url, requestContent);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsStringAsync();
return result;
}
else
{
throw new CustomerHttpException($"接口请求错误,错误代码{response.StatusCode},错误原因{response.ReasonPhrase}");
}
}
public async Task<string> DeleteAsync(string url, Dictionary<string, string> dicHeaders, int timeoutSecond)
{
var client = _httpClientFactory.CreateClient();
var request = new HttpRequestMessage(HttpMethod.Delete, url);
if (dicHeaders != null)
{
foreach (var head in dicHeaders)
{
request.Headers.Add(head.Key, head.Value);
}
}
client.Timeout = TimeSpan.FromSeconds(timeoutSecond);
var response = await client.SendAsync(request);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsStringAsync();
return result;
}
else
{
throw new CustomerHttpException($"接口请求错误,错误代码{response.StatusCode},错误原因{response.ReasonPhrase}");
}
}
/// <summary>
/// 异步请求(通用)
/// </summary>
/// <param name="url"></param>
/// <param name="method"></param>
/// <param name="requestString"></param>
/// <param name="dicHeaders"></param>
/// <param name="timeoutSecond"></param>
/// <returns></returns>
public async Task<string> ExecuteAsync(string url, HttpMethod method, string requestString, Dictionary<string, string> dicHeaders, int timeoutSecond = 120,
string accept = "application/json")
{
var client = _httpClientFactory.CreateClient();
if (url.IndexOf('?') > -1)
{
url += "&v=" + DateTime.Now.ToString("yyyyMMddhhmmss");
}
else
{
url += "?v=" + DateTime.Now.ToString("yyyyMMddhhmmss");
}
var request = new HttpRequestMessage(method, url)
{
Content = new StringContent(requestString),
};
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
if (dicHeaders != null)
{
foreach (var header in dicHeaders)
{
request.Headers.Add(header.Key, header.Value);
}
}
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(accept) { CharSet = "utf-8" });
var response = await client.SendAsync(request);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsStringAsync();
return result;
}
else
{
throw new CustomerHttpException($"接口请求错误,错误代码{response.StatusCode},错误原因{response.ReasonPhrase}");
}
}
}
public class CustomerHttpException : Exception
{
public CustomerHttpException() : base()
{ }
public CustomerHttpException(string message) : base(message)
{
}
}
}

View File

@@ -0,0 +1,138 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
namespace WaterCloud.Code
{
#region JsonHelper
public static class JsonHelper
{
/// <summary>
/// 把数组转为逗号连接的字符串
/// </summary>
/// <param name="data"></param>
/// <param name="Str"></param>
/// <returns></returns>
public static string ArrayToString(dynamic data, string Str)
{
string resStr = Str;
foreach (var item in data)
{
if (resStr != "")
{
resStr += ",";
}
if (item is string)
{
resStr += item;
}
else
{
resStr += item.Value;
}
}
return resStr;
}
public static object ToObject(this string Json)
{
return string.IsNullOrEmpty(Json) ? null : JsonConvert.DeserializeObject(Json);
}
public static T ToObject<T>(this string Json)
{
Json = Json.Replace("&nbsp;", "");
return Json == null ? default(T) : JsonConvert.DeserializeObject<T>(Json);
}
public static JObject ToJObject(this string Json)
{
return Json == null ? JObject.Parse("{}") : JObject.Parse(Json.Replace("&nbsp;", ""));
}
public static List<T> ToList<T>(this string Json)
{
return Json == null ? null : JsonConvert.DeserializeObject<List<T>>(Json);
}
public static string ToJson(this object obj, string dateFormat = "yyyy/MM/dd HH:mm:ss")
{
return obj == null ? string.Empty : JsonConvert.SerializeObject(obj, new IsoDateTimeConverter { DateTimeFormat = dateFormat });
}
}
#endregion JsonHelper
#region JsonConverter
/// <summary>
/// Json数据返回到前端js的时候把数值很大的long类型转成字符串
/// </summary>
public class StringJsonConverter : JsonConverter
{
public StringJsonConverter()
{ }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return reader.Value.ToLong();
}
public override bool CanConvert(Type objectType)
{
return true;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
writer.WriteNull();
return;
}
string sValue = value.ToString();
writer.WriteValue(sValue);
}
}
/// <summary>
/// DateTime类型序列化的时候转成指定的格式
/// </summary>
public class DateTimeJsonConverter : JsonConverter
{
public DateTimeJsonConverter()
{ }
public override bool CanConvert(Type objectType)
{
return true;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return reader.Value.ParseToString().ToDate();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
writer.WriteNull();
return;
}
DateTime? dt = value as DateTime?;
if (dt == null)
{
writer.WriteNull();
return;
}
writer.WriteValue(dt.Value.ToString("yyyy/MM/dd HH:mm:ss"));
}
}
#endregion JsonConverter
}

View File

@@ -0,0 +1,252 @@
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace WaterCloud.Code
{
public class LogHelper
{
private static object lockHelper = new object();
#region
/// <summary>
/// 写日志 异步
/// 默认路径:根目录/Log/yyyy-MM/
/// 默认文件yyyy-MM-dd.log
/// </summary>
/// <param name="logContent">日志内容 自动附加时间</param>
public static void Write(string logContent)
{
string logPath = DateTime.Now.ToString("yyyy-MM");
Write(logPath, logContent);
}
public static void WriteWithTime(string logContent)
{
string logPath = DateTime.Now.ToString("yyyy-MM");
logContent = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + Environment.NewLine + logContent;
Write(logPath, logContent);
}
#endregion
#region
/// <summary>
/// 写异常日志
/// </summary>
/// <param name="ex"></param>
public static void Write(Exception ex)
{
string logContent = string.Empty;
string logPath = DateTime.Now.ToString("yyyy-MM");
logContent += GetExceptionMessage(ex);
Write(logPath, logContent);
}
public static void WriteWithTime(Exception ex)
{
string logContent = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + Environment.NewLine;
string logPath = DateTime.Now.ToString("yyyy-MM");
logContent += GetExceptionMessage(ex);
Write(logPath, logContent);
}
public static void WriteWithTime(ExceptionContext ex)
{
if (ex == null)
return;
string logContent = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + Environment.NewLine;
logContent += "程序异常" + Environment.NewLine;
string logPath = DateTime.Now.ToString("yyyy-MM");
Exception Error = ex.Exception;
LogMessage logMessage = new LogMessage();
logMessage.OperationTime = DateTime.Now;
logMessage.Url = ex.HttpContext.Request.GetDisplayUrl();
if (ex.ActionDescriptor != null)
{
logMessage.Class = ex.ActionDescriptor.DisplayName;
}
else
{
logMessage.Class = "服务器配置问题";
}
logMessage.Ip = WebHelper.Ip;
logMessage.Host = ex.HttpContext.Request.Host.ToString();
var current = OperatorProvider.Provider.GetCurrent();
if (current != null)
{
logMessage.UserName = current.UserCode + "" + current.UserName + "";
}
var err = Error.GetOriginalException();
logMessage.ExceptionInfo = err.Message;
logMessage.ExceptionSource = err.Source;
logMessage.ExceptionRemark = err.StackTrace;
logContent += ExceptionFormat(logMessage);
Write(logPath, logContent);
}
private static string GetExceptionMessage(Exception ex)
{
string message = string.Empty;
if (ex != null)
{
message += ex.Message;
message += Environment.NewLine;
Exception originalException = ex.GetOriginalException();
if (originalException != null)
{
if (originalException.Message != ex.Message)
{
message += originalException.Message;
message += Environment.NewLine;
}
}
message += ex.StackTrace;
message += Environment.NewLine;
}
return message;
}
#endregion
#region
/// <summary>
/// 写日志 异步
/// 默认文件yyyy-MM-dd.log
/// </summary>
/// <param name="logPath">日志目录[默认程序根目录\Log\下添加,故使用相对路径,如:营销任务]</param>
/// <param name="logContent">日志内容 自动附加时间</param>
public static void Write(string logPath, string logContent)
{
string logFileName = DateTime.Now.ToString("yyyy-MM-dd") + ".log";
Write(logPath, logFileName, logContent);
}
/// <summary>
/// 写日志 异步
/// </summary>
/// <param name="logPath">日志目录</param>
/// <param name="logFileName">日志文件名</param>
/// <param name="logContent">日志内容 自动附加时间</param>
public static void Write(string logPath, string logFileName, string logContent)
{
if (string.IsNullOrWhiteSpace(logContent))
{
return;
}
if (string.IsNullOrWhiteSpace(logPath))
{
logPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logs", DateTime.Now.ToString("yyyy-MM"));
}
else
{
logPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logs", logPath.Trim('\\'));
}
if (string.IsNullOrWhiteSpace(logFileName))
{
logFileName = DateTime.Now.ToString("yyyy-MM-dd") + ".log";
}
if (!Directory.Exists(logPath))
{
Directory.CreateDirectory(logPath);
}
string fileName = Path.Combine(logPath, logFileName);
Action taskAction = () =>
{
lock (lockHelper)
{
using (StreamWriter sw = File.AppendText(fileName))
{
sw.WriteLine(logContent + Environment.NewLine);
sw.Flush();
sw.Close();
}
}
};
Task task = new Task(taskAction);
task.Start();
}
/// <summary>
/// 生成异常信息
/// </summary>
/// <param name="logMessage">对象</param>
/// <returns></returns>
public static string ExceptionFormat(LogMessage logMessage)
{
StringBuilder strInfo = new StringBuilder();
strInfo.Append("1. 调试: >> 操作时间: " + logMessage.OperationTime + " 操作人: " + logMessage.UserName + " \r\n");
strInfo.Append("2. 地址: " + logMessage.Url + " \r\n");
strInfo.Append("3. 类名: " + logMessage.Class + " \r\n");
strInfo.Append("4. 主机: " + logMessage.Host + " Ip : " + logMessage.Ip + " \r\n");
strInfo.Append("5. 异常: " + logMessage.ExceptionInfo + "\r\n");
strInfo.Append("6. 来源: " + logMessage.ExceptionSource + "\r\n");
strInfo.Append("7. 实例: " + logMessage.ExceptionRemark + "\r\n");
strInfo.Append("-----------------------------------------------------------------------------------------------------------------------------\r\n");
return strInfo.ToString();
}
/// <summary>
/// 格式化异常信息
/// </summary>
/// <param name="logMessage">对象</param>
/// <returns></returns>
public static string ExMsgFormat(string message)
{
//数据库异常
if (message.Contains("An exception occurred while executing DbCommand."))
{
if (message.Contains("Duplicate entry '") && message.Contains("key"))
{
message = "数据违反唯一约束,请检查";
}
else if (message.Contains("Data too long for column"))
{
message = "数据长度过长,请检查";
}
else
{
message = "数据操作异常,请联系管理员";
}
}
//其他异常
else
{
if (message.Contains("Object reference not set to an instance of an object."))
{
message = "操作对象为空,请联系管理员";
}
else if (message.Contains("Value cannot be null"))
{
message = "值为空,请联系管理员";
}
}
if (!IsHasCHZN(message))
{
message = "程序内部异常,请联系管理员";
}
return message;
}
/// <summary>
/// 检测是否有中文字符
/// </summary>
/// <param name="inputData"></param>
/// <returns></returns>
private static bool IsHasCHZN(string inputData)
{
Regex RegCHZN = new Regex("[\u4e00-\u9fa5]");
Match m = RegCHZN.Match(inputData);
return m.Success;
}
#endregion
}
}

View File

@@ -0,0 +1,57 @@
using System;
namespace WaterCloud.Code
{
public class LogMessage
{
/// <summary>
/// 操作时间
/// </summary>
public DateTime OperationTime { get; set; }
/// <summary>
/// Url地址
/// </summary>
public string Url { get; set; }
/// <summary>
/// 类名
/// </summary>
public string Class { get; set; }
/// <summary>
/// IP
/// </summary>
public string Ip { get; set; }
/// <summary>
/// 主机
/// </summary>
public string Host { get; set; }
/// <summary>
/// 操作人
/// </summary>
public string UserName { get; set; }
/// <summary>
/// 内容
/// </summary>
public string Content { get; set; }
/// <summary>
/// 异常信息
/// </summary>
public string ExceptionInfo { get; set; }
/// <summary>
/// 异常来源
/// </summary>
public string ExceptionSource { get; set; }
/// <summary>
/// 异常信息备注
/// </summary>
public string ExceptionRemark { get; set; }
}
}

View File

@@ -0,0 +1,236 @@
using System;
using System.Collections;
namespace WaterCloud.Code
{
// 通过自己定义一个静态类
// 将所有的Content Type都扔进去吧
// 调用的时候直接调用静态方法即可。
public static class MimeMapping
{
private static Hashtable _mimeMappingTable;
private static void AddMimeMapping(string extension, string MimeType)
{
MimeMapping._mimeMappingTable.Add(extension, MimeType);
}
public static string GetMimeMapping(string FileName)
{
string text = null;
int num = FileName.LastIndexOf('.');
if (0 < num && num > FileName.LastIndexOf('\\'))
{
text = (string)MimeMapping._mimeMappingTable[FileName.Substring(num)];
}
if (text == null)
{
text = (string)MimeMapping._mimeMappingTable[".*"];
}
return text;
}
static MimeMapping()
{
MimeMapping._mimeMappingTable = new Hashtable(190, StringComparer.CurrentCultureIgnoreCase);
MimeMapping.AddMimeMapping(".323", "text/h323");
MimeMapping.AddMimeMapping(".asx", "video/x-ms-asf");
MimeMapping.AddMimeMapping(".acx", "application/internet-property-stream");
MimeMapping.AddMimeMapping(".ai", "application/postscript");
MimeMapping.AddMimeMapping(".aif", "audio/x-aiff");
MimeMapping.AddMimeMapping(".aiff", "audio/aiff");
MimeMapping.AddMimeMapping(".axs", "application/olescript");
MimeMapping.AddMimeMapping(".aifc", "audio/aiff");
MimeMapping.AddMimeMapping(".asr", "video/x-ms-asf");
MimeMapping.AddMimeMapping(".avi", "video/x-msvideo");
MimeMapping.AddMimeMapping(".asf", "video/x-ms-asf");
MimeMapping.AddMimeMapping(".au", "audio/basic");
MimeMapping.AddMimeMapping(".application", "application/x-ms-application");
MimeMapping.AddMimeMapping(".bin", "application/octet-stream");
MimeMapping.AddMimeMapping(".bas", "text/plain");
MimeMapping.AddMimeMapping(".bcpio", "application/x-bcpio");
MimeMapping.AddMimeMapping(".bmp", "image/bmp");
MimeMapping.AddMimeMapping(".cdf", "application/x-cdf");
MimeMapping.AddMimeMapping(".cat", "application/vndms-pkiseccat");
MimeMapping.AddMimeMapping(".crt", "application/x-x509-ca-cert");
MimeMapping.AddMimeMapping(".c", "text/plain");
MimeMapping.AddMimeMapping(".css", "text/css");
MimeMapping.AddMimeMapping(".cer", "application/x-x509-ca-cert");
MimeMapping.AddMimeMapping(".crl", "application/pkix-crl");
MimeMapping.AddMimeMapping(".cmx", "image/x-cmx");
MimeMapping.AddMimeMapping(".csh", "application/x-csh");
MimeMapping.AddMimeMapping(".cod", "image/cis-cod");
MimeMapping.AddMimeMapping(".cpio", "application/x-cpio");
MimeMapping.AddMimeMapping(".clp", "application/x-msclip");
MimeMapping.AddMimeMapping(".crd", "application/x-mscardfile");
MimeMapping.AddMimeMapping(".deploy", "application/octet-stream");
MimeMapping.AddMimeMapping(".dll", "application/x-msdownload");
MimeMapping.AddMimeMapping(".dot", "application/msword");
MimeMapping.AddMimeMapping(".doc", "application/msword");
MimeMapping.AddMimeMapping(".dvi", "application/x-dvi");
MimeMapping.AddMimeMapping(".dir", "application/x-director");
MimeMapping.AddMimeMapping(".dxr", "application/x-director");
MimeMapping.AddMimeMapping(".der", "application/x-x509-ca-cert");
MimeMapping.AddMimeMapping(".dib", "image/bmp");
MimeMapping.AddMimeMapping(".dcr", "application/x-director");
MimeMapping.AddMimeMapping(".disco", "text/xml");
MimeMapping.AddMimeMapping(".exe", "application/octet-stream");
MimeMapping.AddMimeMapping(".etx", "text/x-setext");
MimeMapping.AddMimeMapping(".evy", "application/envoy");
MimeMapping.AddMimeMapping(".eml", "message/rfc822");
MimeMapping.AddMimeMapping(".eps", "application/postscript");
MimeMapping.AddMimeMapping(".flr", "x-world/x-vrml");
MimeMapping.AddMimeMapping(".fif", "application/fractals");
MimeMapping.AddMimeMapping(".gtar", "application/x-gtar");
MimeMapping.AddMimeMapping(".gif", "image/gif");
MimeMapping.AddMimeMapping(".gz", "application/x-gzip");
MimeMapping.AddMimeMapping(".hta", "application/hta");
MimeMapping.AddMimeMapping(".htc", "text/x-component");
MimeMapping.AddMimeMapping(".htt", "text/webviewhtml");
MimeMapping.AddMimeMapping(".h", "text/plain");
MimeMapping.AddMimeMapping(".hdf", "application/x-hdf");
MimeMapping.AddMimeMapping(".hlp", "application/winhlp");
MimeMapping.AddMimeMapping(".html", "text/html");
MimeMapping.AddMimeMapping(".htm", "text/html");
MimeMapping.AddMimeMapping(".hqx", "application/mac-binhex40");
MimeMapping.AddMimeMapping(".isp", "application/x-internet-signup");
MimeMapping.AddMimeMapping(".iii", "application/x-iphone");
MimeMapping.AddMimeMapping(".ief", "image/ief");
MimeMapping.AddMimeMapping(".ivf", "video/x-ivf");
MimeMapping.AddMimeMapping(".ins", "application/x-internet-signup");
MimeMapping.AddMimeMapping(".ico", "image/x-icon");
MimeMapping.AddMimeMapping(".jpg", "image/jpeg");
MimeMapping.AddMimeMapping(".jfif", "image/pjpeg");
MimeMapping.AddMimeMapping(".jpe", "image/jpeg");
MimeMapping.AddMimeMapping(".jpeg", "image/jpeg");
MimeMapping.AddMimeMapping(".js", "application/x-javascript");
MimeMapping.AddMimeMapping(".lsx", "video/x-la-asf");
MimeMapping.AddMimeMapping(".latex", "application/x-latex");
MimeMapping.AddMimeMapping(".lsf", "video/x-la-asf");
MimeMapping.AddMimeMapping(".manifest", "application/x-ms-manifest");
MimeMapping.AddMimeMapping(".mhtml", "message/rfc822");
MimeMapping.AddMimeMapping(".mny", "application/x-msmoney");
MimeMapping.AddMimeMapping(".mht", "message/rfc822");
MimeMapping.AddMimeMapping(".mid", "audio/mid");
MimeMapping.AddMimeMapping(".mpv2", "video/mpeg");
MimeMapping.AddMimeMapping(".man", "application/x-troff-man");
MimeMapping.AddMimeMapping(".mvb", "application/x-msmediaview");
MimeMapping.AddMimeMapping(".mpeg", "video/mpeg");
MimeMapping.AddMimeMapping(".m3u", "audio/x-mpegurl");
MimeMapping.AddMimeMapping(".mdb", "application/x-msaccess");
MimeMapping.AddMimeMapping(".mpp", "application/vnd.ms-project");
MimeMapping.AddMimeMapping(".m1v", "video/mpeg");
MimeMapping.AddMimeMapping(".mpa", "video/mpeg");
MimeMapping.AddMimeMapping(".me", "application/x-troff-me");
MimeMapping.AddMimeMapping(".m13", "application/x-msmediaview");
MimeMapping.AddMimeMapping(".movie", "video/x-sgi-movie");
MimeMapping.AddMimeMapping(".m14", "application/x-msmediaview");
MimeMapping.AddMimeMapping(".mpe", "video/mpeg");
MimeMapping.AddMimeMapping(".mp2", "video/mpeg");
MimeMapping.AddMimeMapping(".mov", "video/quicktime");
MimeMapping.AddMimeMapping(".mp3", "audio/mpeg");
MimeMapping.AddMimeMapping(".mpg", "video/mpeg");
MimeMapping.AddMimeMapping(".ms", "application/x-troff-ms");
MimeMapping.AddMimeMapping(".nc", "application/x-netcdf");
MimeMapping.AddMimeMapping(".nws", "message/rfc822");
MimeMapping.AddMimeMapping(".oda", "application/oda");
MimeMapping.AddMimeMapping(".ods", "application/oleobject");
MimeMapping.AddMimeMapping(".pmc", "application/x-perfmon");
MimeMapping.AddMimeMapping(".p7r", "application/x-pkcs7-certreqresp");
MimeMapping.AddMimeMapping(".p7b", "application/x-pkcs7-certificates");
MimeMapping.AddMimeMapping(".p7s", "application/pkcs7-signature");
MimeMapping.AddMimeMapping(".pmw", "application/x-perfmon");
MimeMapping.AddMimeMapping(".ps", "application/postscript");
MimeMapping.AddMimeMapping(".p7c", "application/pkcs7-mime");
MimeMapping.AddMimeMapping(".pbm", "image/x-portable-bitmap");
MimeMapping.AddMimeMapping(".ppm", "image/x-portable-pixmap");
MimeMapping.AddMimeMapping(".pub", "application/x-mspublisher");
MimeMapping.AddMimeMapping(".pnm", "image/x-portable-anymap");
MimeMapping.AddMimeMapping(".png", "image/png");
MimeMapping.AddMimeMapping(".pml", "application/x-perfmon");
MimeMapping.AddMimeMapping(".p10", "application/pkcs10");
MimeMapping.AddMimeMapping(".pfx", "application/x-pkcs12");
MimeMapping.AddMimeMapping(".p12", "application/x-pkcs12");
MimeMapping.AddMimeMapping(".pdf", "application/pdf");
MimeMapping.AddMimeMapping(".pps", "application/vnd.ms-powerpoint");
MimeMapping.AddMimeMapping(".p7m", "application/pkcs7-mime");
MimeMapping.AddMimeMapping(".pko", "application/vndms-pkipko");
MimeMapping.AddMimeMapping(".ppt", "application/vnd.ms-powerpoint");
MimeMapping.AddMimeMapping(".pmr", "application/x-perfmon");
MimeMapping.AddMimeMapping(".pma", "application/x-perfmon");
MimeMapping.AddMimeMapping(".pot", "application/vnd.ms-powerpoint");
MimeMapping.AddMimeMapping(".prf", "application/pics-rules");
MimeMapping.AddMimeMapping(".pgm", "image/x-portable-graymap");
MimeMapping.AddMimeMapping(".qt", "video/quicktime");
MimeMapping.AddMimeMapping(".ra", "audio/x-pn-realaudio");
MimeMapping.AddMimeMapping(".rgb", "image/x-rgb");
MimeMapping.AddMimeMapping(".ram", "audio/x-pn-realaudio");
MimeMapping.AddMimeMapping(".rmi", "audio/mid");
MimeMapping.AddMimeMapping(".ras", "image/x-cmu-raster");
MimeMapping.AddMimeMapping(".roff", "application/x-troff");
MimeMapping.AddMimeMapping(".rtf", "application/rtf");
MimeMapping.AddMimeMapping(".rtx", "text/richtext");
MimeMapping.AddMimeMapping(".sv4crc", "application/x-sv4crc");
MimeMapping.AddMimeMapping(".spc", "application/x-pkcs7-certificates");
MimeMapping.AddMimeMapping(".setreg", "application/set-registration-initiation");
MimeMapping.AddMimeMapping(".snd", "audio/basic");
MimeMapping.AddMimeMapping(".stl", "application/vndms-pkistl");
MimeMapping.AddMimeMapping(".setpay", "application/set-payment-initiation");
MimeMapping.AddMimeMapping(".stm", "text/html");
MimeMapping.AddMimeMapping(".shar", "application/x-shar");
MimeMapping.AddMimeMapping(".sh", "application/x-sh");
MimeMapping.AddMimeMapping(".sit", "application/x-stuffit");
MimeMapping.AddMimeMapping(".spl", "application/futuresplash");
MimeMapping.AddMimeMapping(".sct", "text/scriptlet");
MimeMapping.AddMimeMapping(".scd", "application/x-msschedule");
MimeMapping.AddMimeMapping(".sst", "application/vndms-pkicertstore");
MimeMapping.AddMimeMapping(".src", "application/x-wais-source");
MimeMapping.AddMimeMapping(".sv4cpio", "application/x-sv4cpio");
MimeMapping.AddMimeMapping(".tex", "application/x-tex");
MimeMapping.AddMimeMapping(".tgz", "application/x-compressed");
MimeMapping.AddMimeMapping(".t", "application/x-troff");
MimeMapping.AddMimeMapping(".tar", "application/x-tar");
MimeMapping.AddMimeMapping(".tr", "application/x-troff");
MimeMapping.AddMimeMapping(".tif", "image/tiff");
MimeMapping.AddMimeMapping(".txt", "text/plain");
MimeMapping.AddMimeMapping(".texinfo", "application/x-texinfo");
MimeMapping.AddMimeMapping(".trm", "application/x-msterminal");
MimeMapping.AddMimeMapping(".tiff", "image/tiff");
MimeMapping.AddMimeMapping(".tcl", "application/x-tcl");
MimeMapping.AddMimeMapping(".texi", "application/x-texinfo");
MimeMapping.AddMimeMapping(".tsv", "text/tab-separated-values");
MimeMapping.AddMimeMapping(".ustar", "application/x-ustar");
MimeMapping.AddMimeMapping(".uls", "text/iuls");
MimeMapping.AddMimeMapping(".vcf", "text/x-vcard");
MimeMapping.AddMimeMapping(".wps", "application/vnd.ms-works");
MimeMapping.AddMimeMapping(".wav", "audio/wav");
MimeMapping.AddMimeMapping(".wrz", "x-world/x-vrml");
MimeMapping.AddMimeMapping(".wri", "application/x-mswrite");
MimeMapping.AddMimeMapping(".wks", "application/vnd.ms-works");
MimeMapping.AddMimeMapping(".wmf", "application/x-msmetafile");
MimeMapping.AddMimeMapping(".wcm", "application/vnd.ms-works");
MimeMapping.AddMimeMapping(".wrl", "x-world/x-vrml");
MimeMapping.AddMimeMapping(".wdb", "application/vnd.ms-works");
MimeMapping.AddMimeMapping(".wsdl", "text/xml");
MimeMapping.AddMimeMapping(".xap", "application/x-silverlight-app");
MimeMapping.AddMimeMapping(".xml", "text/xml");
MimeMapping.AddMimeMapping(".xlm", "application/vnd.ms-excel");
MimeMapping.AddMimeMapping(".xaf", "x-world/x-vrml");
MimeMapping.AddMimeMapping(".xla", "application/vnd.ms-excel");
MimeMapping.AddMimeMapping(".xls", "application/vnd.ms-excel");
MimeMapping.AddMimeMapping(".xof", "x-world/x-vrml");
MimeMapping.AddMimeMapping(".xlt", "application/vnd.ms-excel");
MimeMapping.AddMimeMapping(".xlc", "application/vnd.ms-excel");
MimeMapping.AddMimeMapping(".xsl", "text/xml");
MimeMapping.AddMimeMapping(".xbm", "image/x-xbitmap");
MimeMapping.AddMimeMapping(".xlw", "application/vnd.ms-excel");
MimeMapping.AddMimeMapping(".xpm", "image/x-xpixmap");
MimeMapping.AddMimeMapping(".xwd", "image/x-xwindowdump");
MimeMapping.AddMimeMapping(".xsd", "text/xml");
MimeMapping.AddMimeMapping(".z", "application/x-compress");
MimeMapping.AddMimeMapping(".zip", "application/x-zip-compressed");
MimeMapping.AddMimeMapping(".*", "application/octet-stream");
MimeMapping.AddMimeMapping(".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
}
}
}

View File

@@ -0,0 +1,58 @@
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace WaterCloud.Code
{
public class PdfHelper
{
}
public class PDFFooter : PdfPageEventHelper
{
// write on top of document
public override void OnOpenDocument(PdfWriter writer, Document document)
{
base.OnOpenDocument(writer, document);
PdfPTable tabFot = new PdfPTable(new float[] { 1F });
tabFot.SpacingAfter = 10F;
PdfPCell cell;
tabFot.TotalWidth = 300F;
cell = new PdfPCell(new Phrase("Header"));
tabFot.AddCell(cell);
tabFot.WriteSelectedRows(0, -1, 150, document.Top, writer.DirectContent);
}
// write on start of each page
public override void OnStartPage(PdfWriter writer, Document document)
{
base.OnStartPage(writer, document);
}
// write on end of each page
public override void OnEndPage(PdfWriter writer, Document document)
{
base.OnEndPage(writer, document);
//PdfPTable tabFot = new PdfPTable(new float[] { 1F });
//tabFot.TotalWidth = 700f;
//tabFot.DefaultCell.Border = 0;
//// var footFont = FontFactory.GetFont("Lato", 12 * 0.667f, new Color(60, 60, 60));
//string fontpath = HttpContext.Current.Server.MapPath("~/App_Data");
//BaseFont customfont = BaseFont.CreateFont(fontpath + "\\Lato-Regular.ttf", BaseFont.CP1252, BaseFont.EMBEDDED);
//var footFont = new Font(customfont, 12 * 0.667f, Font.NORMAL, new Color(170, 170, 170));
//PdfPCell cell;
//cell = new PdfPCell(new Phrase("@ 2016 . All Rights Reserved", footFont));
//cell.VerticalAlignment = Element.ALIGN_CENTER;
//cell.Border = 0;
//cell.PaddingLeft = 100f;
//tabFot.AddCell(cell);
//tabFot.WriteSelectedRows(0, -1, 150, document.Bottom, writer.DirectContent);
}
//write on close of document
public override void OnCloseDocument(PdfWriter writer, Document document)
{
base.OnCloseDocument(writer, document);
}
}
}

View File

@@ -0,0 +1,162 @@
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
namespace WaterCloud.Code
{
/// <summary>
/// 队列工具类,用于另起线程处理执行类型数据
/// </summary>
/// <typeparam name="T"></typeparam>
public class QueueHelper<T> : IDisposable
{
#region Private Field
/// <summary>
/// The inner queue.
/// </summary>
private readonly ConcurrentQueue<T> _innerQueue;
/// <summary>
/// The deal task.
/// </summary>
private readonly Task _dealTask;
/// <summary>
/// The flag for end thread.
/// </summary>
private bool _endThreadFlag = false;
/// <summary>
/// The auto reset event.
/// </summary>
private readonly AutoResetEvent _autoResetEvent = new(true);
#endregion Private Field
#region Public Property
/// <summary>
/// The deal action.
/// </summary>
public Action<T> DealAction { get; set; }
#endregion Public Property
#region Constructor
/// <summary>
/// Initializes a new instance of the QueueHelper`1 class.
/// </summary>
public QueueHelper()
{
this._innerQueue = new();
this._dealTask = Task.Run(() => this.DealQueue());
}
/// <summary>
/// Initializes a new instance of the QueueHelper&lt;T&gt; class.
/// </summary>
/// <param name="DealAction">The deal action.</param>
public QueueHelper(Action<T> DealAction)
{
this.DealAction = DealAction;
this._innerQueue = new();
this._dealTask = Task.Run(() => this.DealQueue());
}
#endregion Constructor
#region Public Method
/// <summary>
/// Save entity to Queue.
/// </summary>
/// <param name="entity">The entity what will be deal.</param>
public bool Enqueue(T entity)
{
if (!this._endThreadFlag)
{
this._innerQueue.Enqueue(entity);
this._autoResetEvent.Set();
return true;
}
return false;
}
/// <summary>
/// Disposes current instance, end the deal thread and inner queue.
/// </summary>
public void Dispose()
{
if (!this._endThreadFlag)
{
this._endThreadFlag = true;
this._innerQueue.Enqueue(default);
this._autoResetEvent.Set();
if (!this._dealTask.IsCompleted)
this._dealTask.Wait();
this._dealTask.Dispose();
this._autoResetEvent.Dispose();
this._autoResetEvent.Close();
}
}
#endregion Public Method
#region Private Method
/// <summary>
/// Out Queue.
/// </summary>
/// <param name="entity">The init entity.</param>
/// <returns>The entity what will be deal.</returns>
private bool Dequeue(out T entity)
{
return this._innerQueue.TryDequeue(out entity);
}
/// <summary>
/// Deal entity in Queue.
/// </summary>
private void DealQueue()
{
try
{
while (true)
{
if (this.Dequeue(out T entity))
{
if (this._endThreadFlag && Equals(entity, default(T)))
return;
try
{
this.DealAction?.Invoke(entity);
}
catch (Exception ex)
{
LogHelper.Write(ex);
}
}
else
{
this._autoResetEvent.WaitOne();
}
}
}
catch (Exception ex)
{
LogHelper.Write(ex);
}
}
#endregion Private Method
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,120 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
namespace WaterCloud.Code
{
public class ReflectionHelper
{
private static ConcurrentDictionary<string, object> dictCache = new ConcurrentDictionary<string, object>();
private static List<string> exceptionList = new List<string> { "BaseService", "BaseController" };
#region
/// <summary>
/// 得到类里面的属性集合
/// </summary>
/// <param name="type"></param>
/// <param name="columns"></param>
/// <returns></returns>
public static PropertyInfo[] GetProperties(Type type, string[] columns = null)
{
PropertyInfo[] properties = null;
if (dictCache.ContainsKey(type.FullName))
{
properties = dictCache[type.FullName] as PropertyInfo[];
}
else
{
properties = type.GetProperties();
dictCache.TryAdd(type.FullName, properties);
}
if (columns != null && columns.Length > 0)
{
// 按columns顺序返回属性
var columnPropertyList = new List<PropertyInfo>();
foreach (var column in columns)
{
var columnProperty = properties.Where(p => p.Name == column).FirstOrDefault();
if (columnProperty != null)
{
columnPropertyList.Add(columnProperty);
}
}
return columnPropertyList.ToArray();
}
else
{
return properties;
}
}
public static object GetObjectPropertyValue<T>(T t, string propertyname)
{
Type type = typeof(T);
PropertyInfo property = type.GetProperty(propertyname);
if (property == null) return string.Empty;
object o = property.GetValue(t, null);
if (o == null) return string.Empty;
return o;
}
#endregion
/// <summary>
/// StackTrace获取名称
/// </summary>
/// <param name="count">搜索层级</param>
/// <param name="prefix">前缀</param>
/// <returns></returns>
public static string GetModuleName(int count = 10, bool isReplace = true, string prefix = "Service")
{
try
{
string moduleName = "";
for (int i = 0; i < count; i++)
{
if (!string.IsNullOrEmpty(moduleName))
{
break;
}
string className = new StackFrame(i, true).GetMethod().DeclaringType.FullName;
className = className.Split('+')[0];
className = className.Split('.').LastOrDefault();
bool skip = false;
foreach (var item in exceptionList)
{
if (className.Contains(item))
{
skip = true;
break;
}
}
if (skip)
{
continue;
}
if (className.IndexOf(prefix) > -1)
{
moduleName = className;
if (isReplace)
{
moduleName = moduleName.Replace(prefix, "");
}
}
}
return moduleName;
}
catch (Exception ex)
{
LogHelper.WriteWithTime(ex);
return "";
}
}
}
}

View File

@@ -0,0 +1,44 @@
using System.Diagnostics;
namespace WaterCloud.Code
{
public class ShellHelper
{
public static string Bash(string command)
{
var escapedArgs = command.Replace("\"", "\\\"");
var process = new Process()
{
StartInfo = new ProcessStartInfo
{
FileName = "/bin/bash",
Arguments = $"-c \"{escapedArgs}\"",
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true,
}
};
process.Start();
string result = process.StandardOutput.ReadToEnd();
process.WaitForExit();
process.Dispose();
return result;
}
public static string Cmd(string fileName, string args)
{
string output = string.Empty;
var info = new ProcessStartInfo();
info.FileName = fileName;
info.Arguments = args;
info.RedirectStandardOutput = true;
using (var process = Process.Start(info))
{
output = process.StandardOutput.ReadToEnd();
}
return output;
}
}
}

View File

@@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace WaterCloud.Code
{
public class TextHelper
{
/// <summary>
/// 获取默认值
/// </summary>
/// <param name="value"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static string GetCustomValue(string value, string defaultValue)
{
if (string.IsNullOrEmpty(value))
{
return defaultValue;
}
else
{
return value;
}
}
/// <summary>
/// 截取指定长度的字符串
/// </summary>
/// <param name="value"></param>
/// <param name="length"></param>
/// <returns></returns>
public static string GetSubString(string value, int length, bool ellipsis = false)
{
if (string.IsNullOrEmpty(value))
{
return value;
}
if (value.Length > length)
{
value = value.Substring(0, length);
if (ellipsis)
{
value += "...";
}
}
return value;
}
/// <summary>
/// 字符串转指定类型数组
/// </summary>
/// <param name="value"></param>
/// <param name="split"></param>
/// <returns></returns>
public static T[] SplitToArray<T>(string value, char split)
{
T[] arr = value.Split(new string[] { split.ToString() }, StringSplitOptions.RemoveEmptyEntries).CastSuper<T>().ToArray();
return arr;
}
/// <summary>
/// 判断是否有交集
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list1"></param>
/// <param name="list2"></param>
/// <returns></returns>
public static bool IsArrayIntersection<T>(List<T> list1, List<T> list2)
{
List<T> t = list1.Distinct().ToList();
var exceptArr = t.Except(list2).ToList();
if (exceptArr.Count < t.Count)
{
return true;
}
else
{
return false;
}
}
}
}

View File

@@ -0,0 +1,37 @@
using System;
namespace WaterCloud.Code
{
public class Utils
{
#region
/// <summary>
/// 表示全局唯一标识符 (GUID)。
/// </summary>
/// <returns></returns>
public static string GuId()
{
return IDGen.NextID().ToString();
}
/// <summary>
/// 自动生成编号 201008251145409865
/// </summary>
/// <returns></returns>
public static string CreateNo()
{
Random random = new Random();
string strRandom = random.Next(1000, 10000).ToString(); //生成编号
string code = DateTime.Now.ToString("yyyyMMddHHmmss") + strRandom;//形如
return code;
}
#endregion
public static string GetGuid()
{
return IDGen.NextID().ToString().Replace("-", string.Empty).ToLower();
}
}
}

View File

@@ -0,0 +1,379 @@
using System;
using System.Linq;
using System.Text.RegularExpressions;
namespace WaterCloud.Code
{
public static class ValidatorHelper
{
#region ()
/// <summary>
/// 验证输入字符串为带小数点正数
/// </summary>
/// <param name="str">输入字符</param>
/// <returns>返回一个bool类型的值</returns>
public static bool IsNumber(this string str)
{
return Regex.IsMatch(str, "^([0]|([1-9]+\\d{0,}?))(.[\\d]+)?$");
}
/// <summary>
/// 验证输入字符串为带小数点正负数
/// </summary>
/// <param name="str">输入字符</param>
/// <returns>返回一个bool类型的值</returns>
public static bool IsNumberic(this string str)
{
return Regex.IsMatch(str, "^-?\\d+$|^(-?\\d+)(\\.\\d+)?$");
}
#endregion ()
#region 010-85849685
/// <summary>
/// 验证中国电话格式是否有效格式010-85849685
/// </summary>
/// <param name="str">输入字符</param>
/// <returns>返回一个bool类型的值</returns>
public static bool IsTel(this string str)
{
return Regex.IsMatch(str, @"^(0[0-9]{2,3}\-)?([2-9][0-9]{6,7})+(\-[0-9]{1,4})?$", RegexOptions.IgnoreCase);
}
#endregion 010-85849685
#region
/// <summary>
/// 验证输入字符串为电话号码
/// </summary>
/// <param name="str">输入字符</param>
/// <returns>返回一个bool类型的值</returns>
public static bool IsPhone(this string str)
{
return Regex.IsMatch(str, @"(^(\d{2,4}[-_—]?)?\d{3,8}([-_—]?\d{3,8})?([-_—]?\d{1,7})?$)|(^0?1[35]\d{9}$)");
//弱一点的验证: @"\d{3,4}-\d{7,8}"
}
#endregion
#region
/// <summary>
/// 验证是否是有效传真号码
/// </summary>
/// <param name="str">输入字符</param>
/// <returns>返回一个bool类型的值</returns>
public static bool IsFax(this string str)
{
return Regex.IsMatch(str, @"^[+]{0,1}(\d){1,3}[ ]?([-]?((\d)|[ ]){1,12})+$");
}
#endregion
#region
/// <summary>
/// 验证手机号是否合法 号段为13,14,15,16,17,18,19 086开头将自动识别
/// </summary>
/// <param name="str">输入字符</param>
/// <returns>返回一个bool类型的值</returns>
public static bool IsMobile(this string str)
{
if (!str.StartsWith("1"))
{
str = str.TrimStart(new char[] { '8', '6', }).TrimStart('0');
}
return Regex.IsMatch(str, @"^(13|14|15|16|17|18|19)\d{9}$");
}
#endregion
#region
/// <summary>
/// 验证身份证是否有效
/// </summary>
/// <param name="str">输入字符</param>
/// <returns>返回一个bool类型的值</returns>
public static bool IsIDCard(this string str)
{
switch (str.Length)
{
case 18:
{
return str.IsIDCard18();
}
case 15:
{
return str.IsIDCard15();
}
default:
return false;
}
}
/// <summary>
/// 验证输入字符串为18位的身份证号码
/// </summary>
/// <param name="str">输入字符</param>
/// <returns>返回一个bool类型的值</returns>
public static bool IsIDCard18(this string str)
{
long n = 0;
if (long.TryParse(str.Remove(17), out n) == false || n < Math.Pow(10, 16) || long.TryParse(str.Replace('x', '0').Replace('X', '0'), out n) == false)
{
return false;//数字验证
}
const string address = "11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91";
if (address.IndexOf(str.Remove(2), StringComparison.Ordinal) == -1)
{
return false;//省份验证
}
string birth = str.Substring(6, 8).Insert(6, "-").Insert(4, "-");
DateTime time;
if (DateTime.TryParse(birth, out time) == false)
{
return false;//生日验证
}
string[] arrVarifyCode = ("1,0,x,9,8,7,6,5,4,3,2").Split(',');
string[] wi = ("7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2").Split(',');
char[] ai = str.Remove(17).ToCharArray();
int sum = 0;
for (int i = 0; i < 17; i++)
{
sum += int.Parse(wi[i]) * int.Parse(ai[i].ToString());
}
int y = -1;
Math.DivRem(sum, 11, out y);
return arrVarifyCode[y] == str.Substring(17, 1).ToLower();
}
/// <summary>
/// 验证输入字符串为15位的身份证号码
/// </summary>
/// <param name="str">输入字符</param>
/// <returns>返回一个bool类型的值</returns>
public static bool IsIDCard15(this string str)
{
long n = 0;
if (long.TryParse(str, out n) == false || n < Math.Pow(10, 14))
{
return false;//数字验证
}
const string address = "11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91";
if (address.IndexOf(str.Remove(2), StringComparison.Ordinal) == -1)
{
return false;//省份验证
}
string birth = str.Substring(6, 6).Insert(4, "-").Insert(2, "-");
DateTime time;
return DateTime.TryParse(birth, out time) != false;
}
#endregion
#region
/// <summary>
/// 验证是否是有效邮箱地址
/// </summary>
/// <param name="str">输入字符</param>
/// <returns>返回一个bool类型的值</returns>
public static bool IsEmail(this string str)
{
return Regex.IsMatch(str, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
}
#endregion
#region
/// <summary>
/// 验证是否只含有汉字
/// </summary>
/// <param name="strln">输入字符</param>
/// <returns></returns>
public static bool IsOnlyChinese(this string strln)
{
return Regex.IsMatch(strln, @"^[\u4e00-\u9fa5]+$");
}
#endregion
#region SQL注入
/// <summary>
/// 是否有多余的字符 防止SQL注入
/// </summary>
/// <param name="str">输入字符</param>
/// <returns></returns>
public static bool IsBadString(this string str)
{
if (string.IsNullOrEmpty(str))
return false;
//列举一些特殊字符串
const string badChars = "@,*,#,$,!,+,',=,--,%,^,&,?,(,), <,>,[,],{,},/,\\,;,:,\",\"\",delete,update,drop,alert,select";
var arraryBadChar = badChars.Split(',');
return arraryBadChar.Any(t => !str.Contains(t));
}
#endregion SQL注入
#region 26线
/// <summary>
/// 是否由数字、26个英文字母或者下划线組成的字串
/// </summary>
/// <param name="str">输入字符</param>
/// <returns></returns>
public static bool IsNzx(this string str)
{
return Regex.Match(str, "^[0-9a-zA-Z_]+$").Success;
}
#endregion 26线
#region 26
/// <summary>
/// 由数字、26个英文字母、汉字組成的字串
/// </summary>
/// <param name="str">输入字符</param>
/// <returns></returns>
public static bool IsSzzmChinese(this string str)
{
return Regex.Match(str, @"^[0-9a-zA-Z\u4e00-\u9fa5]+$").Success;
}
#endregion 26
#region 26
/// <summary>
/// 是否由数字、26个英文字母組成的字串
/// </summary>
/// <param name="str">输入字符</param>
/// <returns></returns>
public static bool IsSzzm(this string str)
{
return Regex.Match(str, @"^[0-9a-zA-Z]+$").Success;
}
#endregion 26
#region
/// <summary>
/// 验证输入字符串为邮政编码
/// </summary>
/// <param name="str">输入字符</param>
/// <returns>返回一个bool类型的值</returns>
public static bool IsPostCode(this string str)
{
return Regex.IsMatch(str, @"\d{6}");
}
#endregion
#region
/// <summary>
/// 检查对象的输入长度
/// </summary>
/// <param name="str">输入字符</param>
/// <param name="length">指定的长度</param>
/// <returns>false 太长true -太短</returns>
public static bool CheckLength(this string str, int length)
{
if (str.Length > length)
{
return false;//长度太长
}
return str.Length >= length;
}
#endregion
#region
/// <summary>
/// 判断用户输入是否为日期
/// </summary>
/// <param name="str">输入字符</param>
/// <returns>返回一个bool类型的值</returns>
/// <remarks>
/// 可判断格式如下(其中-可替换为/,不影响验证)
/// YYYY | YYYY-MM | YYYY-MM-DD | YYYY-MM-DD HH:MM:SS | YYYY-MM-DD HH:MM:SS.FFF
/// </remarks>
public static bool IsDateTime(this string str)
{
if (null == str)
{
return false;
}
const string regexDate = @"[1-2]{1}[0-9]{3}((-|\/|\.){1}(([0]?[1-9]{1})|(1[0-2]{1}))((-|\/|\.){1}((([0]?[1-9]{1})|([1-2]{1}[0-9]{1})|(3[0-1]{1})))( (([0-1]{1}[0-9]{1})|2[0-3]{1}):([0-5]{1}[0-9]{1}):([0-5]{1}[0-9]{1})(\.[0-9]{3})?)?)?)?$";
if (Regex.IsMatch(str, regexDate))
{
//以下各月份日期验证,保证验证的完整性
int indexY = -1;
int indexM = -1;
int indexD = -1;
if (-1 != (indexY = str.IndexOf("-", StringComparison.Ordinal)))
{
indexM = str.IndexOf("-", indexY + 1, StringComparison.Ordinal);
indexD = str.IndexOf(":", StringComparison.Ordinal);
}
else
{
indexY = str.IndexOf("/", StringComparison.Ordinal);
indexM = str.IndexOf("/", indexY + 1, StringComparison.Ordinal);
indexD = str.IndexOf(":", StringComparison.Ordinal);
}
//不包含日期部分直接返回true
if (-1 == indexM)
return true;
if (-1 == indexD)
{
indexD = str.Length + 3;
}
int iYear = Convert.ToInt32(str.Substring(0, indexY));
int iMonth = Convert.ToInt32(str.Substring(indexY + 1, indexM - indexY - 1));
int iDate = Convert.ToInt32(str.Substring(indexM + 1, indexD - indexM - 4));
//判断月份日期
if ((iMonth < 8 && 1 == iMonth % 2) || (iMonth > 8 && 0 == iMonth % 2))
{
if (iDate < 32)
return true;
}
else
{
if (iMonth != 2)
{
if (iDate < 31)
return true;
}
else
{
//闰年
if ((0 == iYear % 400) || (0 == iYear % 4 && 0 < iYear % 100))
{
if (iDate < 30)
return true;
}
else
{
if (iDate < 29)
return true;
}
}
}
}
return false;
}
#endregion
}
}

View File

@@ -0,0 +1,86 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System;
using System.DrawingCore;
using System.DrawingCore.Imaging;
using System.IO;
namespace WaterCloud.Code
{
public class VerifyCodeHelper
{
public byte[] GetVerifyCode()
{
int codeW = 80;
int codeH = 30;
int fontSize = 16;
string chkCode = string.Empty;
//颜色列表,用于验证码、噪线、噪点
Color[] color = { Color.Black, Color.Red, Color.Blue, Color.Green, Color.Orange, Color.Brown, Color.Brown, Color.DarkBlue };
//字体列表,用于验证码
string[] font = { "Times New Roman" };
//验证码的字符集,去掉了一些容易混淆的字符
char[] character = { '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'd', 'e', 'f', 'h', 'k', 'm', 'n', 'r', 'x', 'y', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'R', 'S', 'T', 'W', 'X', 'Y' };
Random rnd = new Random();
//生成验证码字符串
for (int i = 0; i < 4; i++)
{
chkCode += character[rnd.Next(character.Length)];
}
//写入Session、验证码加密
WebHelper.WriteSession("wcloud_session_verifycode", Md5.md5(chkCode.ToLower(), 16));
//创建画布
Bitmap bmp = new Bitmap(codeW, codeH);
Graphics g = Graphics.FromImage(bmp);
g.Clear(Color.White);
//画噪线
for (int i = 0; i < 3; i++)
{
int x1 = rnd.Next(codeW);
int y1 = rnd.Next(codeH);
int x2 = rnd.Next(codeW);
int y2 = rnd.Next(codeH);
Color clr = color[rnd.Next(color.Length)];
g.DrawLine(new Pen(clr), x1, y1, x2, y2);
}
//画验证码字符串
for (int i = 0; i < chkCode.Length; i++)
{
string fnt = font[rnd.Next(font.Length)];
Font ft = new Font(fnt, fontSize);
Color clr = color[rnd.Next(color.Length)];
g.DrawString(chkCode[i].ToString(), ft, new SolidBrush(clr), (float)i * 18, (float)0);
}
//将验证码图片写入内存流,并将其以 "image/Png" 格式输出
MemoryStream ms = new MemoryStream();
try
{
bmp.Save(ms, ImageFormat.Png);
return ms.ToArray();
}
catch (Exception)
{
return null;
}
finally
{
g.Dispose();
bmp.Dispose();
}
}
}
public class GetJsVesion
{
public static string GetVcode()
{
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalSeconds).ToString();
}
}
}

View File

@@ -0,0 +1,685 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Net.Sockets;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.RegularExpressions;
using System.Web;
namespace WaterCloud.Code
{
public class WebHelper
{
#region ResolveUrl(Url)
/// <summary>
/// 解析相对Url
/// </summary>
/// <param name="relativeUrl">相对Url</param>
public static string ResolveUrl(string relativeUrl)
{
if (string.IsNullOrWhiteSpace(relativeUrl))
return string.Empty;
relativeUrl = relativeUrl.Replace("\\", "/");
if (relativeUrl.StartsWith("/"))
return relativeUrl;
if (relativeUrl.Contains("://"))
return relativeUrl;
return VirtualPathUtility.ToAbsolute(relativeUrl);
}
#endregion ResolveUrl(Url)
#region HtmlEncode(html字符串进行编码)
/// <summary>
/// 对html字符串进行编码
/// </summary>
/// <param name="html">html字符串</param>
public static string HtmlEncode(string html)
{
return HttpUtility.HtmlEncode(html);
}
/// <summary>
/// 对html字符串进行解码
/// </summary>
/// <param name="html">html字符串</param>
public static string HtmlDecode(string html)
{
return HttpUtility.HtmlDecode(html);
}
#endregion HtmlEncode(html字符串进行编码)
#region UrlEncode(Url进行编码)
/// <summary>
/// 对Url进行编码
/// </summary>
/// <param name="url">url</param>
/// <param name="isUpper">编码字符是否转成大写,范例,"http://"转成"http%3A%2F%2F"</param>
public static string UrlEncode(string url, bool isUpper = false)
{
return UrlEncode(url, Encoding.UTF8, isUpper);
}
/// <summary>
/// 对Url进行编码
/// </summary>
/// <param name="url">url</param>
/// <param name="encoding">字符编码</param>
/// <param name="isUpper">编码字符是否转成大写,范例,"http://"转成"http%3A%2F%2F"</param>
public static string UrlEncode(string url, Encoding encoding, bool isUpper = false)
{
var result = HttpUtility.UrlEncode(url, encoding);
if (!isUpper)
return result;
return GetUpperEncode(result);
}
/// <summary>
/// 获取大写编码字符串
/// </summary>
private static string GetUpperEncode(string encode)
{
var result = new StringBuilder();
int index = int.MinValue;
for (int i = 0; i < encode.Length; i++)
{
string character = encode[i].ToString();
if (character == "%")
index = i;
if (i - index == 1 || i - index == 2)
character = character.ToUpper();
result.Append(character);
}
return result.ToString();
}
#endregion UrlEncode(Url进行编码)
#region UrlDecode(Url进行解码)
/// <summary>
/// 对Url进行解码,对于javascript的encodeURIComponent函数编码参数,应使用utf-8字符编码来解码
/// </summary>
/// <param name="url">url</param>
public static string UrlDecode(string url)
{
return HttpUtility.UrlDecode(url);
}
/// <summary>
/// 对Url进行解码,对于javascript的encodeURIComponent函数编码参数,应使用utf-8字符编码来解码
/// </summary>
/// <param name="url">url</param>
/// <param name="encoding">字符编码,对于javascript的encodeURIComponent函数编码参数,应使用utf-8字符编码来解码</param>
public static string UrlDecode(string url, Encoding encoding)
{
return HttpUtility.UrlDecode(url, encoding);
}
#endregion UrlDecode(Url进行解码)
#region Session操作
/// <summary>
/// 写Session
/// </summary>
/// <param name="key">Session的键名</param>
/// <param name="value">Session的键值</param>
public static void WriteSession(string key, string value)
{
if (key.IsEmpty())
return;
GlobalContext.HttpContext?.Session.SetString(key, value);
}
/// <summary>
/// 读取Session的值
/// </summary>
/// <param name="key">Session的键名</param>
public static string GetSession(string key)
{
if (string.IsNullOrEmpty(key))
{
return string.Empty;
}
return GlobalContext.HttpContext?.Session.GetString(key) ?? "";
}
/// <summary>
/// 删除指定Session
/// </summary>
/// <param name="key">Session的键名</param>
public static void RemoveSession(string key)
{
if (string.IsNullOrEmpty(key))
{
return;
}
GlobalContext.HttpContext?.Session.Remove(key);
}
#endregion Session操作
#region Cookie操作
/// <summary>
/// 写cookie值
/// </summary>
/// <param name="strName">名称</param>
/// <param name="strValue">值</param>
public static void WriteCookie(string strName, string strValue, CookieOptions option = null)
{
if (option == null)
{
option = new CookieOptions();
option.Expires = DateTime.Now.AddDays(30);
}
GlobalContext.HttpContext?.Response.Cookies.Append(strName, strValue, option);
}
/// <summary>
/// 写cookie值
/// </summary>
/// <param name="strName">名称</param>
/// <param name="strValue">值</param>
/// <param name="strValue">过期时间(分钟)</param>
public static void WriteCookie(string strName, string strValue, int expires)
{
CookieOptions option = new CookieOptions();
option.Expires = DateTime.Now.AddMinutes(expires);
GlobalContext.HttpContext?.Response.Cookies.Append(strName, strValue, option);
}
/// <summary>
/// 读cookie值
/// </summary>
/// <param name="strName">名称</param>
/// <returns>cookie值</returns>
public static string GetCookie(string strName)
{
return GlobalContext.HttpContext?.Request.Cookies[strName] ?? "";
}
/// <summary>
/// 删除Cookie对象
/// </summary>
/// <param name="CookiesName">Cookie对象名称</param>
public static void RemoveCookie(string CookiesName)
{
GlobalContext.HttpContext?.Response.Cookies.Delete(CookiesName);
}
#endregion Cookie操作
#region HTML标记
/// <summary>
/// 去除HTML标记
/// </summary>
/// <param name="NoHTML">包括HTML的源码 </param>
/// <returns>已经去除后的文字</returns>
public static string NoHtml(string Htmlstring)
{
//删除脚本
Htmlstring = Regex.Replace(Htmlstring, @"<script[^>]*?>.*?</script>", "", RegexOptions.IgnoreCase);
//删除HTML
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 = Regex.Replace(Htmlstring, @"&hellip;", "", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"&mdash;", "", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"&ldquo;", "", RegexOptions.IgnoreCase);
Htmlstring.Replace("<", "");
Htmlstring = Regex.Replace(Htmlstring, @"&rdquo;", "", RegexOptions.IgnoreCase);
Htmlstring.Replace(">", "");
Htmlstring.Replace("\r\n", "");
Htmlstring = HtmlEncoder.Default.Encode(Htmlstring).Trim();
return Htmlstring;
}
#endregion HTML标记
#region SQL注入
/// <summary>
/// 格式化文本防止SQL注入
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string Formatstr(string html)
{
System.Text.RegularExpressions.Regex regex1 = new System.Text.RegularExpressions.Regex(@"<script[\s\S]+</script *>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex2 = new System.Text.RegularExpressions.Regex(@" href *= *[\s\S]*script *:", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex3 = new System.Text.RegularExpressions.Regex(@" on[\s\S]*=", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex4 = new System.Text.RegularExpressions.Regex(@"<iframe[\s\S]+</iframe *>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex5 = new System.Text.RegularExpressions.Regex(@"<frameset[\s\S]+</frameset *>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex10 = new System.Text.RegularExpressions.Regex(@"select", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex11 = new System.Text.RegularExpressions.Regex(@"update", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex12 = new System.Text.RegularExpressions.Regex(@"delete", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
html = regex1.Replace(html, ""); //过滤<script></script>标记
html = regex2.Replace(html, ""); //过滤href=javascript: (<A>) 属性
html = regex3.Replace(html, " _disibledevent="); //过滤其它控件的on...事件
html = regex4.Replace(html, ""); //过滤iframe
html = regex10.Replace(html, "s_elect");
html = regex11.Replace(html, "u_pudate");
html = regex12.Replace(html, "d_elete");
html = html.Replace("'", "");
html = html.Replace("&nbsp;", " ");
return html;
}
#endregion SQL注入
#region
public static HttpContext HttpContext
{
get { return GlobalContext.HttpContext; }
}
#endregion
#region
public static string Ip
{
get
{
string result = string.Empty;
try
{
if (HttpContext != null)
{
result = GetWebClientIp();
}
if (string.IsNullOrEmpty(result))
{
result = GetLanIp();
}
}
catch (Exception)
{
return string.Empty;
}
return result;
}
}
private static string GetWebClientIp()
{
try
{
string ip = GetWebRemoteIp();
foreach (var hostAddress in Dns.GetHostAddresses(ip))
{
if (hostAddress.AddressFamily == AddressFamily.InterNetwork)
{
return hostAddress.ToString();
}
else if (hostAddress.AddressFamily == AddressFamily.InterNetworkV6)
{
return hostAddress.MapToIPv4().ToString();
}
}
}
catch (Exception)
{
return string.Empty;
}
return string.Empty;
}
public static string GetLanIp()
{
try
{
foreach (var hostAddress in Dns.GetHostAddresses(Dns.GetHostName()))
{
if (hostAddress.AddressFamily == AddressFamily.InterNetwork)
{
return hostAddress.ToString();
}
else if (hostAddress.AddressFamily == AddressFamily.InterNetworkV6)
{
return hostAddress.MapToIPv4().ToString();
}
}
}
catch (Exception)
{
return string.Empty;
}
return string.Empty;
}
public static string GetWanIp()
{
string ip = string.Empty;
try
{
string url = "http://www.net.cn/static/customercare/yourip.asp";
string html = "";
using (var client = new HttpClient())
{
var reponse = client.GetAsync(url).GetAwaiter().GetResult();
reponse.EnsureSuccessStatusCode();
html = reponse.Content.ReadAsStringAsync().GetAwaiter().GetResult();
}
if (!string.IsNullOrEmpty(html))
{
ip = WebHelper.Resove(html, "<h2>", "</h2>");
}
}
catch (Exception)
{
return string.Empty;
}
return ip;
}
private static string GetWebRemoteIp()
{
try
{
string ip = HttpContext?.Connection?.RemoteIpAddress.ParseToString();
if (HttpContext != null && HttpContext.Request != null)
{
if (HttpContext.Request.Headers.ContainsKey("X-Real-IP"))
{
ip = HttpContext.Request.Headers["X-Real-IP"].ToString();
}
if (HttpContext.Request.Headers.ContainsKey("X-Forwarded-For"))
{
ip = HttpContext.Request.Headers["X-Forwarded-For"].ToString();
}
}
return ip;
}
catch (Exception)
{
return string.Empty;
}
}
public static string UserAgent
{
get
{
string userAgent = string.Empty;
try
{
userAgent = HttpContext?.Request?.Headers["User-Agent"];
}
catch (Exception ex)
{
LogHelper.WriteWithTime(ex);
}
return userAgent;
}
}
public static string GetOSVersion()
{
var osVersion = string.Empty;
try
{
var userAgent = UserAgent;
if (userAgent.Contains("NT 10"))
{
osVersion = "Windows 10";
}
else if (userAgent.Contains("NT 6.3"))
{
osVersion = "Windows 8";
}
else if (userAgent.Contains("NT 6.1"))
{
osVersion = "Windows 7";
}
else if (userAgent.Contains("NT 6.0"))
{
osVersion = "Windows Vista/Server 2008";
}
else if (userAgent.Contains("NT 5.2"))
{
osVersion = "Windows Server 2003";
}
else if (userAgent.Contains("NT 5.1"))
{
osVersion = "Windows XP";
}
else if (userAgent.Contains("NT 5"))
{
osVersion = "Windows 2000";
}
else if (userAgent.Contains("NT 4"))
{
osVersion = "Windows NT4";
}
else if (userAgent.Contains("Android"))
{
osVersion = "Android";
}
else if (userAgent.Contains("Me"))
{
osVersion = "Windows Me";
}
else if (userAgent.Contains("98"))
{
osVersion = "Windows 98";
}
else if (userAgent.Contains("95"))
{
osVersion = "Windows 95";
}
else if (userAgent.Contains("Mac"))
{
osVersion = "Mac";
}
else if (userAgent.Contains("Unix"))
{
osVersion = "UNIX";
}
else if (userAgent.Contains("Linux"))
{
osVersion = "Linux";
}
else if (userAgent.Contains("SunOS"))
{
osVersion = "SunOS";
}
}
catch (Exception ex)
{
LogHelper.WriteWithTime(ex);
}
return osVersion;
}
#endregion
#region IP位置查询
public static string GetIpLocation(string ipAddress)
{
string ipLocation = "未知";
try
{
if (!IsInnerIP(ipAddress))
{
ipLocation = GetIpLocationFromPCOnline(ipAddress);
}
else
{
ipLocation = "本地局域网";
}
}
catch (Exception)
{
return ipLocation;
}
return ipLocation;
}
private static string GetIpLocationFromPCOnline(string ipAddress)
{
string ipLocation = "未知";
try
{
var res = "";
using (var client = new HttpClient())
{
var URL = "http://whois.pconline.com.cn/ip.jsp?ip=" + ipAddress;
var response = client.GetAsync(URL).GetAwaiter().GetResult();
response.EnsureSuccessStatusCode();
res = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
}
if (!string.IsNullOrEmpty(res))
{
ipLocation = res.Trim();
}
}
catch
{
ipLocation = "未知";
}
return ipLocation;
}
#endregion IP位置查询
#region IP
public static bool IsInnerIP(string ipAddress)
{
bool isInnerIp = false;
long ipNum = GetIpNum(ipAddress);
/**
私有IPA类 10.0.0.0-10.255.255.255
B类 172.16.0.0-172.31.255.255
C类 192.168.0.0-192.168.255.255
当然还有127这个网段是环回地址
**/
long aBegin = GetIpNum("10.0.0.0");
long aEnd = GetIpNum("10.255.255.255");
long bBegin = GetIpNum("172.16.0.0");
long bEnd = GetIpNum("172.31.255.255");
long cBegin = GetIpNum("192.168.0.0");
long cEnd = GetIpNum("192.168.255.255");
isInnerIp = IsInner(ipNum, aBegin, aEnd) || IsInner(ipNum, bBegin, bEnd) || IsInner(ipNum, cBegin, cEnd) || ipAddress.Equals("127.0.0.1");
return isInnerIp;
}
/// <summary>
/// 把IP地址转换为Long型数字
/// </summary>
/// <param name="ipAddress">IP地址字符串</param>
/// <returns></returns>
private static long GetIpNum(string ipAddress)
{
string[] ip = ipAddress.Split('.');
long a = int.Parse(ip[0]);
long b = int.Parse(ip[1]);
long c = int.Parse(ip[2]);
long d = int.Parse(ip[3]);
long ipNum = a * 256 * 256 * 256 + b * 256 * 256 + c * 256 + d;
return ipNum;
}
private static bool IsInner(long userIp, long begin, long end)
{
return (userIp >= begin) && (userIp <= end);
}
#endregion IP
#region html处理
/// <summary>
/// Get part Content from HTML by apply prefix part and subfix part
/// </summary>
/// <param name="html">souce html</param>
/// <param name="prefix">prefix</param>
/// <param name="subfix">subfix</param>
/// <returns>part content</returns>
public static string Resove(string html, string prefix, string subfix)
{
int inl = html.IndexOf(prefix);
if (inl == -1)
{
return null;
}
inl += prefix.Length;
int inl2 = html.IndexOf(subfix, inl);
string s = html.Substring(inl, inl2 - inl);
return s;
}
public static string ResoveReverse(string html, string subfix, string prefix)
{
int inl = html.IndexOf(subfix);
if (inl == -1)
{
return null;
}
string subString = html.Substring(0, inl);
int inl2 = subString.LastIndexOf(prefix);
if (inl2 == -1)
{
return null;
}
string s = subString.Substring(inl2 + prefix.Length, subString.Length - inl2 - prefix.Length);
return s;
}
public static List<string> ResoveList(string html, string prefix, string subfix)
{
List<string> list = new List<string>();
int index = prefix.Length * -1;
do
{
index = html.IndexOf(prefix, index + prefix.Length);
if (index == -1)
{
break;
}
index += prefix.Length;
int index4 = html.IndexOf(subfix, index);
string s78 = html.Substring(index, index4 - index);
list.Add(s78);
}
while (index > -1);
return list;
}
#endregion html处理
}
}

View File

@@ -0,0 +1,51 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<Optimize>false</Optimize>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Extend\**" />
<Compile Remove="Extension\**" />
<EmbeddedResource Remove="Extend\**" />
<EmbeddedResource Remove="Extension\**" />
<None Remove="Extend\**" />
<None Remove="Extension\**" />
</ItemGroup>
<ItemGroup>
<Compile Include="Extend\Ext.Mapper.cs" />
<Compile Include="Extend\Ext.Convert.cs" />
<Compile Include="Extend\Ext.DateTime.cs" />
<Compile Include="Extend\Ext.Enum.cs" />
<Compile Include="Extend\Ext.Exception.cs" />
<Compile Include="Extend\Ext.Format.cs" />
<Compile Include="Extend\Ext.String.cs" />
<Compile Include="Extend\Ext.Validate.cs" />
<Compile Include="Extend\Ext.Linq.cs" />
<Compile Include="Extend\Ext.List.cs" />
<Compile Include="Extend\Ext.Table.cs" />
<Compile Include="Extend\Ext.Number.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autofac" Version="8.0.0" />
<PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="CSRedisCore" Version="3.8.803" />
<PackageReference Include="iTextSharp.LGPLv2.Core.Fix" Version="1.4.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="8.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Serenity.Web" Version="3.14.5" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
<PackageReference Include="System.Drawing.Common" Version="8.0.7" />
<PackageReference Include="ZKWeb.System.Drawing" Version="4.0.1" />
<PackageReference Include="RabbitMQ.Client" Version="6.8.1" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,94 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
namespace WaterCloud.Code
{
/// <summary>
/// 常用返回结果
/// </summary>
public class AlwaysResult
{
/// <summary>
/// 操作结果类型
/// </summary>
public object state { get; set; }
/// <summary>
/// 获取 消息内容
/// </summary>
public string message { get; set; }
}
/// <summary>
/// 常用返回结果
/// </summary>
public class AlwaysResult<T> : AlwaysResult
{
/// <summary>
/// 列表的记录数
/// </summary>
public int count { get; set; }
/// <summary>
/// 获取 返回数据
/// </summary>
public T data { get; set; }
}
/// <summary>
/// DTree返回结果
/// </summary>
public class DTreeResult
{
/// <summary>
/// 操作结果类型
/// </summary>
public StatusInfo status { get; set; }
/// 此页要显示的记录列表
/// </summary>
public object data { get; set; }
}
public class StatusInfo
{
/// <summary>
/// 操作结果类型
/// </summary>
public object code { get; set; }
/// 此页要显示的记录列表
/// </summary>
public object message { get; set; }
}
/// <summary>
/// 表示 ajax 操作结果类型的枚举
/// </summary>
public enum ResultType
{
/// <summary>
/// 消息结果类型
/// </summary>
info,
/// <summary>
/// 成功结果类型
/// </summary>
success,
/// <summary>
/// 警告结果类型
/// </summary>
warning,
/// <summary>
/// 异常结果类型
/// </summary>
error
}
}

View File

@@ -0,0 +1,216 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using System.Text.RegularExpressions;
namespace WaterCloud.Code
{
public class Browser
{
public static bool IsMobile
{
get
{
HttpContext current = GlobalContext.HttpContext;
string text = current.Request.Headers["HTTP_USER_AGENT"];
Regex regex = new Regex("android|avantgo|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\\\/|plucker|pocket|psp|symbian|treo|up\\\\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino", RegexOptions.IgnoreCase | RegexOptions.Multiline);
Regex regex2 = new Regex("1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\\\-(n|u)|c55\\\\/|capi|ccwa|cdm\\\\-|cell|chtm|cldc|cmd\\\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\\\-|_)|g1 u|g560|gene|gf\\\\-5|g\\\\-mo|go(\\\\.w|od)|gr(ad|un)|haie|hcit|hd\\\\-(m|p|t)|hei\\\\-|hi(pt|ta)|hp( i|ip)|hs\\\\-c|ht(c(\\\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\\\-(20|go|ma)|i230|iac( |\\\\-|\\\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\\\/)|klon|kpt |kwc\\\\-|kyo(c|k)|le(no|xi)|lg( g|\\\\/(k|l|u)|50|54|e\\\\-|e\\\\/|\\\\-[a-w])|libw|lynx|m1\\\\-w|m3ga|m50\\\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\\\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\\\-2|po(ck|rt|se)|prox|psio|pt\\\\-g|qa\\\\-a|qc(07|12|21|32|60|\\\\-[2-7]|i\\\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\\\-|oo|p\\\\-)|sdk\\\\/|se(c(\\\\-|0|1)|47|mc|nd|ri)|sgh\\\\-|shar|sie(\\\\-|m)|sk\\\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\\\-|v\\\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\\\-|tdg\\\\-|tel(i|m)|tim\\\\-|t\\\\-mo|to(pl|sh)|ts(70|m\\\\-|m3|m5)|tx\\\\-9|up(\\\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|xda(\\\\-|2|g)|yas\\\\-|your|zeto|zte\\\\-", RegexOptions.IgnoreCase | RegexOptions.Multiline);
return regex.IsMatch(text) || regex2.IsMatch(text.Substring(0, 4));
}
}
public static string IP
{
get
{
string text = string.Empty;
text = GlobalContext.HttpContext.Request.Headers["HTTP_X_FORWARDED_FOR"];
string result;
if (text != null && text != string.Empty)
{
if (text.IndexOf(".") == -1)
{
text = null;
}
else if (text.IndexOf(",") != -1)
{
text = text.Replace(" ", "").Replace("\"", "");
string[] array = text.Split(",;".ToCharArray());
for (int i = 0; i < array.Length; i++)
{
if (Browser.IsIPAddress(array[i]) && array[i].Substring(0, 3) != "10." && array[i].Substring(0, 7) != "192.168" && array[i].Substring(0, 7) != "172.16.")
{
result = array[i];
return result;
}
}
}
else
{
if (Browser.IsIPAddress(text))
{
result = text;
return result;
}
text = null;
}
}
if (text == null || text == string.Empty)
{
text = GlobalContext.HttpContext.Request.Headers["REMOTE_ADDR"];
}
if (text == null || text == string.Empty)
{
text = GlobalContext.HttpContext.Features.Get<IHttpConnectionFeature>()?.RemoteIpAddress.ToString();
}
result = text;
return result;
}
}
public static string OS
{
get
{
string text = GlobalContext.HttpContext.Request.Headers["HTTP_USER_AGENT"];
string result;
if (text.IndexOf("NT 4.0") > 0)
{
result = "Windows NT ";
}
else if (text.IndexOf("NT 5.0") > 0)
{
result = "Windows 2000";
}
else if (text.IndexOf("NT 5.1") > 0)
{
result = "Windows XP";
}
else if (text.IndexOf("NT 5.2") > 0)
{
result = "Windows 2003";
}
else if (text.IndexOf("NT 6.0") > 0)
{
result = "Windows Vista";
}
else if (text.IndexOf("NT 6.1") > 0)
{
result = "Windows 2008";
}
else if (text.IndexOf("WindowsCE") > 0)
{
result = "Windows CE";
}
else if (text.IndexOf("NT") > 0)
{
result = "Windows NT ";
}
else if (text.IndexOf("9x") > 0)
{
result = "Windows ME";
}
else if (text.IndexOf("98") > 0)
{
result = "Windows 98";
}
else if (text.IndexOf("95") > 0)
{
result = "Windows 95";
}
else if (text.IndexOf("Win32") > 0)
{
result = "Win32";
}
else if (text.IndexOf("Linux") > 0)
{
result = "Linux";
}
else if (text.IndexOf("SunOS") > 0)
{
result = "SunOS";
}
else if (text.IndexOf("Mac") > 0)
{
result = "Mac";
}
else if (text.IndexOf("Linux") > 0)
{
result = "Linux";
}
else if (text.IndexOf("Windows") > 0)
{
result = "Windows";
}
else
{
result = "未知类型";
}
return result;
}
}
public static string MobileOS
{
get
{
HttpContext current = GlobalContext.HttpContext;
string input = current.Request.Headers["HTTP_USER_AGENT"];
Regex regex = new Regex("android|avantgo|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\\\/|plucker|pocket|psp|symbian|treo|up\\\\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino", RegexOptions.IgnoreCase | RegexOptions.Multiline);
MatchCollection matchCollection = regex.Matches(input);
string result;
if (matchCollection.Count < 1)
{
result = Browser.OS;
}
else
{
result = matchCollection[0].Value;
}
return result;
}
}
public static string PhoneNumber
{
get
{
string text = "";
HttpContext current = GlobalContext.HttpContext;
if (current.Request.Headers.ContainsKey("DEVICEID"))
{
text = current.Request.Headers["DEVICEID"].ToString();
}
if (current.Request.Headers.ContainsKey("HTTP_X_UP_subno"))
{
text = current.Request.Headers["HTTP_X_UP_subno"].ToString();
text = text.Substring(3, 11);
}
if (current.Request.Headers.ContainsKey("HTTP_X_NETWORK_INFO"))
{
text = current.Request.Headers["HTTP_X_NETWORK_INFO"].ToString();
}
if (current.Request.Headers.ContainsKey("HTTP_X_UP_CALLING_LINE_ID"))
{
text = current.Request.Headers["HTTP_X_UP_CALLING_LINE_ID"].ToString();
}
return text;
}
}
private static bool IsIPAddress(string str1)
{
bool result;
if (str1 == null || str1 == string.Empty || str1.Length < 7 || str1.Length > 15)
{
result = false;
}
else
{
string pattern = "^\\d{1,3}[\\.]\\d{1,3}[\\.]\\d{1,3}[\\.]\\d{1,3}$";
Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
result = regex.IsMatch(str1);
}
return result;
}
}
}

View File

@@ -0,0 +1,58 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
namespace WaterCloud.Code
{
/// <summary>
/// 分页信息
/// </summary>
public class Pagination
{
/// <summary>
/// 每页行数
/// </summary>
public int rows { get; set; }
/// <summary>
/// 当前页
/// </summary>
public int page { get; set; }
/// <summary>
/// 排序列
/// </summary>
public string field { get; set; }
/// <summary>
/// 排序类型
/// </summary>
public string order { get; set; }
/// <summary>
/// 总记录数
/// </summary>
public int records { get; set; }
/// <summary>
/// 总页数
/// </summary>
public int total
{
get
{
if (records > 0)
{
return records % this.rows == 0 ? records / this.rows : records / this.rows + 1;
}
else
{
return 0;
}
}
}
}
}

View File

@@ -0,0 +1,47 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System.Collections.Generic;
using System.Text;
namespace WaterCloud.Code
{
public static class TreeSelect
{
public static string TreeSelectJson(this List<TreeSelectModel> data)
{
StringBuilder sb = new StringBuilder();
sb.Append("[");
sb.Append(TreeSelectJson(data, "0", ""));
sb.Append("]");
return sb.ToString();
}
private static string TreeSelectJson(List<TreeSelectModel> data, string parentId, string blank)
{
StringBuilder sb = new StringBuilder();
var ChildNodeList = data.FindAll(t => t.parentId == parentId);
var tabline = "";
if (parentId != "0")
{
tabline = "  ";
}
if (ChildNodeList.Count > 0)
{
tabline = tabline + blank;
}
foreach (TreeSelectModel entity in ChildNodeList)
{
entity.text = tabline + entity.text;
string strJson = entity.ToJson();
sb.Append(strJson);
sb.Append(TreeSelectJson(data, entity.id, tabline));
}
return sb.ToString().Replace("}{", "},{");
}
}
}

View File

@@ -0,0 +1,18 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
namespace WaterCloud.Code
{
public class TreeSelectModel
{
public string id { get; set; }
public string text { get; set; }
public string code { get; set; }
public string parentId { get; set; }
public object data { get; set; }
}
}

View File

@@ -0,0 +1,60 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System.Collections.Generic;
using System.Text;
namespace WaterCloud.Code
{
public static class TreeGrid
{
public static string TreeGridJson(this List<TreeGridModel> data)
{
StringBuilder sb = new StringBuilder();
sb.Append(TreeGridJson(data, "0"));
return sb.ToString();
}
private static string TreeGridJson(List<TreeGridModel> data, string parentId)
{
StringBuilder sb = new StringBuilder();
var ChildNodeList = data.FindAll(t => t.parentId == parentId);
sb.Append("[");
if (ChildNodeList.Count > 0)
{
foreach (TreeGridModel entity in ChildNodeList)
{
string strJson = entity.ToJson() + ",";
strJson = strJson.Insert(1, "\"children\":" + TreeGridJson(data, entity.id) + ",");
sb.Append(strJson);
}
sb = sb.Remove(sb.Length - 1, 1);
}
sb.Append("]");
return sb.ToString().Replace("}{", "},{");
}
public static List<TreeGridModel> TreeList(this List<TreeGridModel> data)
{
return TreeList(data, "0");
}
private static List<TreeGridModel> TreeList(List<TreeGridModel> data, string parentId)
{
var ChildNodeList = data.FindAll(t => t.parentId == parentId);
if (ChildNodeList.Count > 0)
{
foreach (TreeGridModel entity in ChildNodeList)
{
entity.children = TreeList(data, entity.id);
}
}
return ChildNodeList;
}
}
}

View File

@@ -0,0 +1,22 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System.Collections.Generic;
namespace WaterCloud.Code
{
public class TreeGridModel
{
public string id { get; set; }
public string parentId { get; set; }
public string title { get; set; }
public object self { get; set; }
public object checkArr { get; set; }
public bool? disabled { get; set; }
public List<TreeGridModel> children { get; set; }
}
}

View File

@@ -0,0 +1,48 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
namespace WaterCloud.Code
{
public static class TreeQuery
{
public static List<T> TreeWhere<T>(this List<T> entityList, Predicate<T> condition, string keyValue = "F_Id", string parentId = "F_ParentId") where T : class
{
List<T> locateList = entityList.FindAll(condition);
var parameter = Expression.Parameter(typeof(T), "t");
List<T> treeList = new List<T>();
foreach (T entity in locateList)
{
treeList.Add(entity);
string pId = entity.GetType().GetProperty(parentId).GetValue(entity, null).ToString();
while (true)
{
if (string.IsNullOrEmpty(pId) && pId == "0")
{
break;
}
Predicate<T> upLambda = (Expression.Equal(parameter.Property(keyValue), Expression.Constant(pId))).ToLambda<Predicate<T>>(parameter).Compile();
T upRecord = entityList.Find(upLambda);
if (upRecord != null)
{
treeList.Add(upRecord);
pId = upRecord.GetType().GetProperty(parentId).GetValue(upRecord, null).ToString();
}
else
{
break;
}
}
}
return treeList.Distinct().ToList();
}
}
}

View File

@@ -0,0 +1,60 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System.Collections.Generic;
using System.Text;
namespace WaterCloud.Code
{
public static class TreeView
{
public static string TreeViewJson(this List<TreeViewModel> data, string parentId = "0")
{
StringBuilder strJson = new StringBuilder();
List<TreeViewModel> item = data.FindAll(t => t.parentId == parentId);
strJson.Append("[");
if (item.Count > 0)
{
foreach (TreeViewModel entity in item)
{
strJson.Append("{");
strJson.Append("\"id\":\"" + entity.id + "\",");
strJson.Append("\"text\":\"" + entity.text.Replace("&nbsp;", "") + "\",");
strJson.Append("\"value\":\"" + entity.value + "\",");
if (entity.title != null && !string.IsNullOrEmpty(entity.title.Replace("&nbsp;", "")))
{
strJson.Append("\"title\":\"" + entity.title.Replace("&nbsp;", "") + "\",");
}
if (entity.img != null && !string.IsNullOrEmpty(entity.img.Replace("&nbsp;", "")))
{
strJson.Append("\"img\":\"" + entity.img.Replace("&nbsp;", "") + "\",");
}
if (entity.checkstate != null)
{
strJson.Append("\"checkstate\":" + entity.checkstate + ",");
}
if (entity.parentId != null)
{
strJson.Append("\"parentnodes\":\"" + entity.parentId + "\",");
}
strJson.Append("\"showcheck\":" + entity.showcheck.ToString().ToLower() + ",");
strJson.Append("\"isexpand\":" + entity.isexpand.ToString().ToLower() + ",");
if (entity.complete == true)
{
strJson.Append("\"complete\":" + entity.complete.ToString().ToLower() + ",");
}
strJson.Append("\"hasChildren\":" + entity.hasChildren.ToString().ToLower() + ",");
strJson.Append("\"ChildNodes\":" + TreeViewJson(data, entity.id) + "");
strJson.Append("},");
}
strJson = strJson.Remove(strJson.Length - 1, 1);
}
strJson.Append("]");
return strJson.ToString();
}
}
}

View File

@@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
namespace WaterCloud.Code
{
public class TreeViewModel
{
public string parentId { get; set; }
public string id { get; set; }
public string text { get; set; }
public string value { get; set; }
public int? checkstate { get; set; }
public bool showcheck { get; set; }
public bool complete { get; set; }
public bool isexpand { get; set; }
public bool hasChildren { get; set; }
public string img { get; set; }
public string title { get; set; }
}
}