Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
256a0c24f9 | ||
|
|
085f275620 | ||
|
|
0d98b80a3c | ||
|
|
16cdd3d46e | ||
|
|
c2dcedd238 | ||
|
|
0a3e5af6a9 |
No files matched your search
@@ -0,0 +1,24 @@
|
||||
<Project>
|
||||
|
||||
<!-- See https://aka.ms/dotnet/msbuild/customize for more details on customizing your build -->
|
||||
<PropertyGroup>
|
||||
<DefaultTargetFramework>net462</DefaultTargetFramework>
|
||||
<TargetFramework>$(DefaultTargetFramework)</TargetFramework>
|
||||
<LangVersion>12.0</LangVersion>
|
||||
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
|
||||
<CheckEolTargetFramework>false</CheckEolTargetFramework>
|
||||
<SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
|
||||
<Nullable>annotations</Nullable>
|
||||
<NoWarn>CS1591</NoWarn>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="PolySharp" Version="1.16.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
|
||||
namespace MAX.Core.Autofac
|
||||
{
|
||||
/// <summary>
|
||||
/// 自动填充属性特性
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class AutowiredAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using Autofac.Core;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace MAX.Core.Autofac
|
||||
{
|
||||
/// <summary>
|
||||
/// autofac 找出所有属性上是否摸个特性
|
||||
/// </summary>
|
||||
public class CustomPropertySelector : IPropertySelector
|
||||
{
|
||||
public bool InjectProperty(PropertyInfo propertyInfo, object instance)
|
||||
{
|
||||
if (propertyInfo.CustomAttributes.Any(iterator => iterator.AttributeType == typeof(AutowiredAttribute)))
|
||||
{
|
||||
|
||||
}
|
||||
//需要一个判断
|
||||
//;如果标记的有CustomPropertyAttribute特性返回True:返回true;就构造实例
|
||||
return propertyInfo.CustomAttributes.Any(iterator => iterator.AttributeType == typeof(AutowiredAttribute));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using Autofac;
|
||||
|
||||
namespace MAX.Core.Autofac
|
||||
{
|
||||
public interface IDependencyRegistrar
|
||||
{
|
||||
void Register(ContainerBuilder builder);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
using Autofac;
|
||||
using Autofac.Core;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MAX.Core.DependencyInjection;
|
||||
|
||||
/// <summary>
|
||||
/// 容器
|
||||
/// </summary>
|
||||
public static partial class IocManager
|
||||
{
|
||||
/// <summary>
|
||||
/// 默认容器
|
||||
/// </summary>
|
||||
public static IContainer Container { get; internal set; }
|
||||
public static void SetContainer(IContainer container)
|
||||
{
|
||||
Container = container;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 确定指定的服务在上下文中是否可用。
|
||||
/// </summary>
|
||||
/// <typeparam name="TService"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static bool IsRegistered<TService>()
|
||||
{
|
||||
return Container.IsRegistered<TService>();
|
||||
}
|
||||
/// <summary>
|
||||
/// 确定指定的服务在上下文中是否可用。
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsRegistered(Type serverType)
|
||||
{
|
||||
return Container.IsRegistered(serverType);
|
||||
}
|
||||
|
||||
public static TService Resolve<TService>()
|
||||
{
|
||||
if (Container.IsRegistered<TService>())
|
||||
{
|
||||
return Container.Resolve<TService>();
|
||||
}
|
||||
return default;
|
||||
}
|
||||
public static object Resolve(Type serviceType)
|
||||
{
|
||||
if (Container.IsRegistered(serviceType))
|
||||
{
|
||||
return Container.Resolve(serviceType);
|
||||
}
|
||||
return default;
|
||||
}
|
||||
public static TService Resolve<TService>(params Parameter[] parameters)
|
||||
{
|
||||
if (Container.IsRegistered<TService>())
|
||||
{
|
||||
return Container.Resolve<TService>(parameters);
|
||||
}
|
||||
return default;
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取所有注册
|
||||
/// </summary>
|
||||
/// <typeparam name="TService"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static TService[] ResolveAll<TService>()
|
||||
{
|
||||
return ResolveAll(typeof(TService)) as TService[];
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取所有注册
|
||||
/// </summary>
|
||||
/// <typeparam name="TService"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static object[] ResolveAll(Type type)
|
||||
{
|
||||
Type enumerableOfType = typeof(IEnumerable<>).MakeGenericType(type);
|
||||
return (object[])Container.ResolveService(new TypedService(enumerableOfType));
|
||||
}
|
||||
|
||||
public static Type GetRegistrationType(string key)
|
||||
{
|
||||
foreach (IComponentRegistration registration in Container.ComponentRegistry.Registrations)
|
||||
{
|
||||
foreach (Service service in registration.Services)
|
||||
{
|
||||
if (service is KeyedService ks)
|
||||
{
|
||||
if (key.Equals(ks.ServiceKey.ToString(), StringComparison.Ordinal))
|
||||
{
|
||||
if (Container.ComponentRegistry.TryGetServiceRegistration(service, out ServiceRegistration serviceRegistration))
|
||||
{
|
||||
return serviceRegistration.Registration.Target.Activator.LimitType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
using System;
|
||||
|
||||
namespace MAX.Core.Caches;
|
||||
|
||||
/// <summary>
|
||||
/// 缓存
|
||||
/// </summary>
|
||||
public interface ICache
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否存在指定键的缓存
|
||||
/// </summary>
|
||||
/// <param name="key">缓存键</param>
|
||||
bool Exists(string key);
|
||||
/// <summary>
|
||||
/// 从缓存中获取数据
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
T Get<T>(string key);
|
||||
/// <summary>
|
||||
/// 从缓存中获取数据,如果不存在,则执行获取数据操作并添加到缓存中
|
||||
/// </summary>
|
||||
/// <typeparam name="T">缓存数据类型</typeparam>
|
||||
/// <param name="key">缓存键</param>
|
||||
/// <param name="func">获取数据操作</param>
|
||||
T Get<T>(string key, Func<T> func);
|
||||
/// <summary>
|
||||
/// 当缓存数据不存在则添加,已存在不会添加,添加成功返回true
|
||||
/// </summary>
|
||||
/// <typeparam name="T">缓存数据类型</typeparam>
|
||||
/// <param name="key">缓存键</param>
|
||||
/// <param name="value">值</param>
|
||||
bool TryAdd<T>(string key, T value);
|
||||
/// <summary>
|
||||
/// 覆盖添加
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
bool OverlayAdd<T>(string key, T value);
|
||||
/// <summary>
|
||||
/// 移除缓存
|
||||
/// </summary>
|
||||
/// <param name="key">缓存键</param>
|
||||
void Remove(string key);
|
||||
/// <summary>
|
||||
/// 清空缓存
|
||||
/// </summary>
|
||||
void Clear();
|
||||
}
|
||||
|
||||
public interface ICache<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否存在指定键的缓存
|
||||
/// </summary>
|
||||
/// <param name="key">缓存键</param>
|
||||
bool Exists(string key);
|
||||
|
||||
/// <summary>
|
||||
/// 从缓存中获取数据,如果不存在,则执行获取数据操作并添加到缓存中
|
||||
/// </summary>
|
||||
/// <typeparam name="T">缓存数据类型</typeparam>
|
||||
/// <param name="key">缓存键</param>
|
||||
T Get(string key);
|
||||
/// <summary>
|
||||
/// 从缓存中获取数据,如果不存在,则执行获取数据操作并添加到缓存中
|
||||
/// </summary>
|
||||
/// <typeparam name="T">缓存数据类型</typeparam>
|
||||
/// <param name="key">缓存键</param>
|
||||
/// <param name="func">获取数据操作</param>
|
||||
T Get(string key, Func<T> func);
|
||||
/// <summary>
|
||||
/// 当缓存数据不存在则添加,已存在不会添加,添加成功返回true
|
||||
/// </summary>
|
||||
/// <typeparam name="T">缓存数据类型</typeparam>
|
||||
/// <param name="key">缓存键</param>
|
||||
/// <param name="value">值</param>
|
||||
bool TryAdd(string key, T value);
|
||||
/// <summary>
|
||||
/// 覆盖添加
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
bool OverlayAdd(string key, T value);
|
||||
/// <summary>
|
||||
/// 移除缓存
|
||||
/// </summary>
|
||||
/// <param name="key">缓存键</param>
|
||||
void Remove(string key);
|
||||
/// <summary>
|
||||
/// 清空缓存
|
||||
/// </summary>
|
||||
void Clear();
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
|
||||
using MAX.Core.DependencyInjection;
|
||||
using MAX.Core.Infrastructure;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
|
||||
namespace MAX.Core.Caches;
|
||||
|
||||
/// <summary>
|
||||
/// 内存缓存
|
||||
/// </summary>
|
||||
public class MemoryCache : ICache, ISingletonDependency
|
||||
{
|
||||
//private static readonly Object _locker = new object();
|
||||
private readonly ConcurrentDictionary<string, object> _cache = new();
|
||||
|
||||
public virtual void Clear()
|
||||
{
|
||||
_cache.Clear();
|
||||
}
|
||||
|
||||
public virtual bool Exists(string key)
|
||||
{
|
||||
return _cache.ContainsKey(key);
|
||||
}
|
||||
public virtual T Get<T>(string key)
|
||||
{
|
||||
if (Exists(key))
|
||||
{
|
||||
return (T)_cache[key];
|
||||
}
|
||||
return default;
|
||||
}
|
||||
public virtual TResult Get<TResult>(string key, Func<TResult> func)
|
||||
{
|
||||
if (Exists(key))
|
||||
{
|
||||
return (TResult)_cache[key];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (func != null)
|
||||
{
|
||||
TResult t = func();
|
||||
TryAdd(key, t);
|
||||
return t;
|
||||
}
|
||||
}
|
||||
return default;
|
||||
}
|
||||
|
||||
public virtual bool OverlayAdd<T>(string key, T value)
|
||||
{
|
||||
if (Exists(key))
|
||||
{
|
||||
_cache[key] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
_cache.TryAdd(key, value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void Remove(string key)
|
||||
{
|
||||
_cache.TryRemove(key, out _);
|
||||
}
|
||||
|
||||
public virtual bool TryAdd<T>(string key, T value)
|
||||
{
|
||||
_cache.AddOrUpdate(key, value, (oldkey, oldvalue) => value);
|
||||
return true;
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取所有Key
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string[] AllKeys()
|
||||
{
|
||||
return _cache.Keys.ToArray();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 单例缓存抽象类
|
||||
/// </summary>
|
||||
/// <typeparam name="TModel">单例对象</typeparam>
|
||||
/// <typeparam name="TValue">缓存类型</typeparam>
|
||||
public abstract class SingleInstanceCache<TModel, TValue> : SingleInstance<TModel>, ICache<TValue> where TModel : class
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, TValue> _cache = new();
|
||||
/// <summary>
|
||||
/// 自定义前缀
|
||||
/// </summary>
|
||||
//public abstract string KeyPrefix { get; }
|
||||
//private string FormatKey(string key)
|
||||
//{
|
||||
// return KeyPrefix + key;
|
||||
//}
|
||||
|
||||
public virtual void Clear()
|
||||
{
|
||||
_cache.Clear();
|
||||
}
|
||||
|
||||
public virtual bool Exists(string key)
|
||||
{
|
||||
return _cache.ContainsKey(key);
|
||||
}
|
||||
public virtual TValue Get(string key)
|
||||
{
|
||||
if (Exists(key))
|
||||
{
|
||||
return _cache[key];
|
||||
}
|
||||
return default;
|
||||
}
|
||||
public virtual TValue Get(string key, Func<TValue> func)
|
||||
{
|
||||
if (Exists(key))
|
||||
{
|
||||
return _cache[key];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (func != null)
|
||||
{
|
||||
TValue t = func();
|
||||
TryAdd(key, t);
|
||||
return t;
|
||||
}
|
||||
}
|
||||
return default;
|
||||
}
|
||||
|
||||
public virtual bool OverlayAdd(string key, TValue value)
|
||||
{
|
||||
if (Exists(key))
|
||||
{
|
||||
_cache[key] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
_cache.TryAdd(key, value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void Remove(string key)
|
||||
{
|
||||
_cache.TryRemove(key, out _);
|
||||
}
|
||||
|
||||
public virtual bool TryAdd(string key, TValue value)
|
||||
{
|
||||
_cache.AddOrUpdate(key, value, (oldkey, oldvalue) => value);
|
||||
return true;
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取所有Key
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string[] AllKeys()
|
||||
{
|
||||
return _cache.Keys.ToArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
namespace MAX.Core.Commons;
|
||||
|
||||
/// <summary>
|
||||
/// 公共Value
|
||||
/// </summary>
|
||||
/// <typeparam name="TValue"></typeparam>
|
||||
public class CommonValue<TValue>
|
||||
{
|
||||
public CommonValue() { }
|
||||
public CommonValue(TValue value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
public TValue Value { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 公共TextValue
|
||||
/// </summary>
|
||||
/// <typeparam name="TValue"></typeparam>
|
||||
public class CommonTextValue<TValue> : CommonValue<TValue>
|
||||
{
|
||||
public string Text { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 公共TextValue
|
||||
/// </summary>
|
||||
public class CommonTextValue : CommonTextValue<string>
|
||||
{
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 默认公共键值对 Key Value
|
||||
/// </summary>
|
||||
public class CommonKeyValue : CommonValue<string>
|
||||
{
|
||||
public string Key { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
|
||||
namespace MAX.Core.Commons;
|
||||
|
||||
/// <summary>
|
||||
/// 通用返回
|
||||
/// </summary>
|
||||
public class Result
|
||||
{
|
||||
/// <summary>
|
||||
/// 返回结果是否成功
|
||||
/// </summary>
|
||||
public bool Success { get; set; } = false;
|
||||
/// <summary>
|
||||
/// 返回消息
|
||||
/// </summary>
|
||||
public string Msg { get; set; } = "";
|
||||
/// <summary>
|
||||
/// 返回内容
|
||||
/// </summary>
|
||||
public object Data { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// 返回状态码
|
||||
/// </summary>
|
||||
public int Code { get; set; }
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 通用返回 指定Data类型
|
||||
/// </summary>
|
||||
/// <typeparam name="TData">数据类型</typeparam>
|
||||
public class Result<TData> : Result
|
||||
{
|
||||
/// <summary>
|
||||
/// 返回内容
|
||||
/// </summary>
|
||||
public new TData Data { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 通用返回
|
||||
/// </summary>
|
||||
/// <typeparam name="TStatus">状态类型枚举</typeparam>
|
||||
/// <typeparam name="TData">数据类型</typeparam>
|
||||
public class Result<TStatus, TData> : Result where TStatus : Enum
|
||||
{
|
||||
/// <summary>
|
||||
/// 状态
|
||||
/// </summary>
|
||||
public TStatus Status { get; set; }
|
||||
/// <summary>
|
||||
/// 返回内容
|
||||
/// </summary>
|
||||
public new TData Data { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace MAX.Core.Cryptography;
|
||||
|
||||
public class Base64Helper
|
||||
{
|
||||
/// <summary>
|
||||
/// Base64加密
|
||||
/// </summary>
|
||||
/// <param name="codeName">加密采用的编码方式</param>
|
||||
/// <param name="source">待加密的明文</param>
|
||||
/// <returns></returns>
|
||||
public static string Encode(string source, Encoding encode)
|
||||
{
|
||||
string encodeValue = "";
|
||||
byte[] bytes = encode.GetBytes(source);
|
||||
try
|
||||
{
|
||||
encodeValue = Convert.ToBase64String(bytes);
|
||||
}
|
||||
catch
|
||||
{
|
||||
encodeValue = source;
|
||||
}
|
||||
return encodeValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base64加密,采用utf8编码方式加密
|
||||
/// </summary>
|
||||
/// <param name="source">待加密的明文</param>
|
||||
/// <returns>加密后的字符串</returns>
|
||||
public static string Encode(string source)
|
||||
{
|
||||
return Encode(source, Encoding.UTF8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base64解密
|
||||
/// </summary>
|
||||
/// <param name="codeName">解密采用的编码方式,注意和加密时采用的方式一致</param>
|
||||
/// <param name="result">待解密的密文</param>
|
||||
/// <returns>解密后的字符串</returns>
|
||||
public static string Decode(string result, Encoding encode)
|
||||
{
|
||||
string decode = "";
|
||||
byte[] bytes = Convert.FromBase64String(result);
|
||||
try
|
||||
{
|
||||
decode = encode.GetString(bytes);
|
||||
}
|
||||
catch
|
||||
{
|
||||
decode = result;
|
||||
}
|
||||
return decode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base64解密,采用utf8编码方式解密
|
||||
/// </summary>
|
||||
/// <param name="result">待解密的密文</param>
|
||||
/// <returns>解密后的字符串</returns>
|
||||
public static string Decode(string result)
|
||||
{
|
||||
return Decode(result, Encoding.UTF8);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace MAX.Core.Cryptography;
|
||||
|
||||
public sealed class DESHelper
|
||||
{
|
||||
|
||||
//默认密钥向量
|
||||
private static readonly byte[] IVKey = { 36, 109, 97, 120, 111, 110, 120, 36 };
|
||||
/// <summary>
|
||||
/// DES加密字符串
|
||||
/// </summary>
|
||||
/// <param name="encryptString">待加密的字符串</param>
|
||||
/// <param name="encryptKey">加密密钥,要求为8位</param>
|
||||
/// <returns>加密成功返回加密后的字符串,失败返回源串</returns>
|
||||
public static string Encrypt(string encryptString, string encryptKey)
|
||||
{
|
||||
try
|
||||
{
|
||||
encryptKey = GetSubString(encryptKey, 8, "");
|
||||
encryptKey = encryptKey.PadRight(8, ' ');
|
||||
byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8));
|
||||
byte[] rgbIV = IVKey;
|
||||
byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
|
||||
DES dCSP = DES.Create();
|
||||
MemoryStream mStream = new();
|
||||
CryptoStream cStream = new(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
|
||||
cStream.Write(inputByteArray, 0, inputByteArray.Length);
|
||||
cStream.FlushFinalBlock();
|
||||
return Convert.ToBase64String(mStream.ToArray());
|
||||
}
|
||||
catch
|
||||
{
|
||||
return encryptString;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DES解密字符串
|
||||
/// </summary>
|
||||
/// <param name="decryptString">待解密的字符串</param>
|
||||
/// <param name="decryptKey">解密密钥,要求为8位,和加密密钥相同</param>
|
||||
/// <returns>解密成功返回解密后的字符串,失败返源串</returns>
|
||||
public static string Decrypt(string decryptString, string decryptKey)
|
||||
{
|
||||
try
|
||||
{
|
||||
decryptKey = GetSubString(decryptKey, 0, 8, "");
|
||||
decryptKey = decryptKey.PadRight(8, ' ');
|
||||
byte[] rgbKey = Encoding.UTF8.GetBytes(decryptKey);
|
||||
byte[] rgbIV = IVKey;
|
||||
byte[] inputByteArray = Convert.FromBase64String(decryptString);
|
||||
DES DCSP = DES.Create();
|
||||
|
||||
MemoryStream mStream = new();
|
||||
CryptoStream cStream = new(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
|
||||
cStream.Write(inputByteArray, 0, inputByteArray.Length);
|
||||
cStream.FlushFinalBlock();
|
||||
return Encoding.UTF8.GetString(mStream.ToArray());
|
||||
}
|
||||
catch
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#region 截取字符串函数
|
||||
|
||||
/// <summary>
|
||||
/// 截取字符串函数
|
||||
/// </summary>
|
||||
/// <param name="Str">所要截取的字符串</param>
|
||||
/// <param name="Num">截取字符串的长度</param>
|
||||
/// <returns></returns>
|
||||
public static string GetSubString(string Str, int Num)
|
||||
{
|
||||
if (Str is null or "")
|
||||
{
|
||||
return "";
|
||||
}
|
||||
string outstr = string.Empty;
|
||||
int n = 0;
|
||||
foreach (char ch in Str)
|
||||
{
|
||||
n += Encoding.Default.GetByteCount(ch.ToString());
|
||||
|
||||
if (n > Num)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
outstr += ch;
|
||||
}
|
||||
}
|
||||
|
||||
return outstr;
|
||||
}
|
||||
/// <summary>
|
||||
/// 截取字符串函数,如果超过指定长度则将超出的部分用指定字符串代替
|
||||
/// </summary>
|
||||
/// <param name="Str">所要截取的字符串</param>
|
||||
/// <param name="Num">截取字符串的长度</param>
|
||||
/// <param name="LastStr">截取字符串后省略部分的字符串</param>
|
||||
/// <returns></returns>
|
||||
public static string GetSubString(string Str, int Num, string LastStr)
|
||||
{
|
||||
return GetSubString(Str, 0, Num, LastStr);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 截取字符串,超过部分用指定字符串替换
|
||||
|
||||
/* 宗波于 2010-6-12 日添加, 来源于DiscuzNt */
|
||||
/// <summary>
|
||||
/// 取指定长度的字符串
|
||||
/// </summary>
|
||||
/// <param name="p_SrcString">要检查的字符串</param>
|
||||
/// <param name="p_StartIndex">起始位置</param>
|
||||
/// <param name="p_Length">指定长度</param>
|
||||
/// <param name="p_TailString">用于替换的字符串</param>
|
||||
/// <returns>截取后的字符串</returns>
|
||||
public static string GetSubString(string p_SrcString, int p_StartIndex, int p_Length, string p_TailString)
|
||||
{
|
||||
string myResult = p_SrcString;
|
||||
|
||||
byte[] bComments = Encoding.UTF8.GetBytes(p_SrcString);
|
||||
foreach (char c in Encoding.UTF8.GetChars(bComments))
|
||||
{ //当是日文或韩文时(注:中文的范围:\u4e00 - \u9fa5, 日文在\u0800 - \u4e00, 韩文为\xAC00-\xD7A3)
|
||||
if (c is (> '\u0800' and < '\u4e00') or (> '\xAC00' and < '\xD7A3'))
|
||||
{
|
||||
//if (System.Text.RegularExpressions.Regex.IsMatch(p_SrcString, "[\u0800-\u4e00]+") || System.Text.RegularExpressions.Regex.IsMatch(p_SrcString, "[\xAC00-\xD7A3]+"))
|
||||
//当截取的起始位置超出字段串长度时
|
||||
if (p_StartIndex >= p_SrcString.Length)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
else
|
||||
{
|
||||
return p_SrcString.Substring(p_StartIndex,
|
||||
p_Length + p_StartIndex > p_SrcString.Length ? p_SrcString.Length - p_StartIndex : p_Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p_Length >= 0)
|
||||
{
|
||||
byte[] bsSrcString = Encoding.Default.GetBytes(p_SrcString);
|
||||
|
||||
//当字符串长度大于起始位置
|
||||
if (bsSrcString.Length > p_StartIndex)
|
||||
{
|
||||
int p_EndIndex = bsSrcString.Length;
|
||||
|
||||
//当要截取的长度在字符串的有效长度范围内
|
||||
if (bsSrcString.Length > p_StartIndex + p_Length)
|
||||
{
|
||||
p_EndIndex = p_Length + p_StartIndex;
|
||||
}
|
||||
else
|
||||
{ //当不在有效范围内时,只取到字符串的结尾
|
||||
|
||||
p_Length = bsSrcString.Length - p_StartIndex;
|
||||
p_TailString = "";
|
||||
}
|
||||
|
||||
int nRealLength = p_Length;
|
||||
int[] anResultFlag = new int[p_Length];
|
||||
byte[] bsResult = null;
|
||||
|
||||
int nFlag = 0;
|
||||
for (int i = p_StartIndex; i < p_EndIndex; i++)
|
||||
{
|
||||
if (bsSrcString[i] > 127)
|
||||
{
|
||||
nFlag++;
|
||||
if (nFlag == 3)
|
||||
{
|
||||
nFlag = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nFlag = 0;
|
||||
}
|
||||
|
||||
anResultFlag[i] = nFlag;
|
||||
}
|
||||
|
||||
if (bsSrcString[p_EndIndex - 1] > 127 && anResultFlag[p_Length - 1] == 1)
|
||||
{
|
||||
nRealLength = p_Length + 1;
|
||||
}
|
||||
|
||||
bsResult = new byte[nRealLength];
|
||||
|
||||
Array.Copy(bsSrcString, p_StartIndex, bsResult, 0, nRealLength);
|
||||
|
||||
myResult = Encoding.Default.GetString(bsResult);
|
||||
myResult += p_TailString;
|
||||
}
|
||||
}
|
||||
|
||||
return myResult;
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace MAX.Core.Cryptography;
|
||||
|
||||
public class MD5Helper
|
||||
{
|
||||
/// <summary>
|
||||
/// MD5加密
|
||||
/// </summary>
|
||||
/// <param name="instring"></param>
|
||||
/// <returns></returns>
|
||||
public static string Md5_32(string instring)
|
||||
{
|
||||
return _Md532(instring);
|
||||
}
|
||||
public static string Md5_Lower32(string instring)
|
||||
{
|
||||
return _Md532(instring, true);
|
||||
}
|
||||
public static string _Md532(string instring, bool IsLower = false)
|
||||
{
|
||||
byte[] result = Encoding.UTF8.GetBytes(string.IsNullOrEmpty(instring) ? "" : instring.Trim());
|
||||
MD5 md5 = MD5.Create();
|
||||
byte[] output = md5.ComputeHash(result);
|
||||
string value = BitConverter.ToString(output).Replace("-", "");
|
||||
if (IsLower)
|
||||
{
|
||||
return value.ToLower();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// MD5加密
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static long GetLong(byte[] result)
|
||||
{
|
||||
return
|
||||
Convert.ToInt64(
|
||||
BitConverter.ToString(MD5.Create().ComputeHash(result), 4,
|
||||
8).Replace("-", ""), 16);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// MD5 16位加密转long
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <returns></returns>
|
||||
public static long GetLong(string url)
|
||||
{
|
||||
if (string.IsNullOrEmpty(url))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Convert.ToInt64(BitConverter.ToString(MD5.Create().ComputeHash(Encoding.Default.GetBytes(url)), 4, 8).Replace("-", ""), 16);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System.Text;
|
||||
|
||||
namespace MAX.Core.Cryptography;
|
||||
|
||||
/// <summary>
|
||||
/// Url 加密 解密
|
||||
/// </summary>
|
||||
public class UrlHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Url加密
|
||||
/// </summary>
|
||||
/// <param name="codeName">加密采用的编码方式</param>
|
||||
/// <param name="source">待加密的明文</param>
|
||||
/// <returns></returns>
|
||||
public static string Encode(string source, Encoding encode)
|
||||
{
|
||||
return System.Web.HttpUtility.UrlEncode(source, encode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Url加密,采用utf8编码方式加密
|
||||
/// </summary>
|
||||
/// <param name="source">待加密的明文</param>
|
||||
/// <returns>加密后的字符串</returns>
|
||||
public static string Encode(string source)
|
||||
{
|
||||
return Encode(source, Encoding.UTF8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Url解密
|
||||
/// </summary>
|
||||
/// <param name="codeName">解密采用的编码方式,注意和加密时采用的方式一致</param>
|
||||
/// <param name="result">待解密的密文</param>
|
||||
/// <returns>解密后的字符串</returns>
|
||||
public static string Decode(string result, Encoding encode)
|
||||
{
|
||||
return System.Web.HttpUtility.UrlDecode(result, Encoding.UTF8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Url解密,采用utf8编码方式解密
|
||||
/// </summary>
|
||||
/// <param name="result">待解密的密文</param>
|
||||
/// <returns>解密后的字符串</returns>
|
||||
public static string Decode(string result)
|
||||
{
|
||||
return Decode(result, Encoding.UTF8);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace MAX.Core.DependencyInjection;
|
||||
|
||||
/// <summary>
|
||||
/// 作用域(每个 Scope/请求一个实例)
|
||||
/// </summary>
|
||||
public interface IScopedDependency
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
//using System;
|
||||
|
||||
//namespace MAX.Core.DependencyInjection;
|
||||
|
||||
///// <summary>
|
||||
///// 依赖注册抽象(由 MAX.Core 自己定义,不依赖任何第三方 DI 容器)。
|
||||
///// 具体实现由宿主项目提供,内部适配外部容器(Autofac、Microsoft.Extensions.DependencyInjection 等)。
|
||||
///// </summary>
|
||||
//public interface IServiceRegistrar
|
||||
//{
|
||||
// /// <summary>
|
||||
// /// 注册单例:<typeparamref name="TImplementation"/> 实现 <typeparamref name="TService"/>
|
||||
// /// </summary>
|
||||
// void RegisterSingleton<TService, TImplementation>() where TService : class where TImplementation : class, TService;
|
||||
|
||||
// /// <summary>
|
||||
// /// 注册单例实例
|
||||
// /// </summary>
|
||||
// void RegisterSingleton<TService>(TService instance) where TService : class;
|
||||
|
||||
// /// <summary>
|
||||
// /// 注册单例(匿名工厂)
|
||||
// /// </summary>
|
||||
// void RegisterSingleton<TService>(Func<IServiceProvider, TService> factory) where TService : class;
|
||||
|
||||
// /// <summary>
|
||||
// /// 注册单例(key):<typeparamref name="TImplementation"/> 实现 <typeparamref name="TService"/>
|
||||
// /// </summary>
|
||||
// void RegisterSingleton<TService, TImplementation>(object? serviceKey) where TService : class where TImplementation : class, TService;
|
||||
|
||||
// /// <summary>
|
||||
// /// 注册单例实例(key)
|
||||
// /// </summary>
|
||||
// void RegisterSingleton<TService>(object? serviceKey, TService instance) where TService : class;
|
||||
|
||||
// /// <summary>
|
||||
// /// 注册单例(key + 匿名工厂)
|
||||
// /// </summary>
|
||||
// void RegisterSingleton<TService>(object? serviceKey, Func<IServiceProvider, object?, TService> factory) where TService : class;
|
||||
|
||||
// /// <summary>
|
||||
// /// 注册作用域生命周期
|
||||
// /// </summary>
|
||||
// void RegisterScoped<TService, TImplementation>() where TService : class where TImplementation : class, TService;
|
||||
|
||||
// /// <summary>
|
||||
// /// 注册作用域生命周期(匿名工厂)
|
||||
// /// </summary>
|
||||
// void RegisterScoped<TService>(Func<IServiceProvider, TService> factory) where TService : class;
|
||||
|
||||
// /// <summary>
|
||||
// /// 注册作用域生命周期(key):<typeparamref name="TImplementation"/> 实现 <typeparamref name="TService"/>
|
||||
// /// </summary>
|
||||
// void RegisterScoped<TService, TImplementation>(object? serviceKey) where TService : class where TImplementation : class, TService;
|
||||
|
||||
// /// <summary>
|
||||
// /// 注册作用域生命周期(key + 匿名工厂)
|
||||
// /// </summary>
|
||||
// void RegisterScoped<TService>(object? serviceKey, Func<IServiceProvider, object?, TService> factory) where TService : class;
|
||||
|
||||
// /// <summary>
|
||||
// /// 注册瞬时生命周期
|
||||
// /// </summary>
|
||||
// void RegisterTransient<TService, TImplementation>() where TService : class where TImplementation : class, TService;
|
||||
|
||||
// /// <summary>
|
||||
// /// 注册瞬时生命周期(匿名工厂)
|
||||
// /// </summary>
|
||||
// void RegisterTransient<TService>(Func<IServiceProvider, TService> factory) where TService : class;
|
||||
|
||||
// /// <summary>
|
||||
// /// 注册瞬时生命周期(key):<typeparamref name="TImplementation"/> 实现 <typeparamref name="TService"/>
|
||||
// /// </summary>
|
||||
// void RegisterTransient<TService, TImplementation>(object? serviceKey) where TService : class where TImplementation : class, TService;
|
||||
|
||||
// /// <summary>
|
||||
// /// 注册瞬时生命周期(key + 匿名工厂)
|
||||
// /// </summary>
|
||||
// void RegisterTransient<TService>(object? serviceKey, Func<IServiceProvider, object?, TService> factory) where TService : class;
|
||||
|
||||
//}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace MAX.Core.DependencyInjection;
|
||||
|
||||
/// <summary>
|
||||
/// 单例
|
||||
/// </summary>
|
||||
public interface ISingletonDependency
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace MAX.Core.DependencyInjection;
|
||||
|
||||
/// <summary>
|
||||
/// 每次实例化
|
||||
/// </summary>
|
||||
public interface ITransientDependency
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using MAX.Core.Infrastructure;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace MAX.Core.DependencyInjection;
|
||||
|
||||
public interface ILazyServiceProvider
|
||||
{
|
||||
object LazyGetService(Type serviceType);
|
||||
T LazyGetService<T>();
|
||||
}
|
||||
|
||||
public class LazyServiceProvider : SingleInstance<LazyServiceProvider>, ILazyServiceProvider
|
||||
{
|
||||
protected ConcurrentDictionary<Type, Lazy<object>> CachedServices { get; }
|
||||
private LazyServiceProvider()
|
||||
{
|
||||
CachedServices = new ConcurrentDictionary<Type, Lazy<object>>();
|
||||
}
|
||||
public virtual T LazyGetService<T>()
|
||||
{
|
||||
return (T)LazyGetService(typeof(T));
|
||||
}
|
||||
|
||||
public virtual object LazyGetService(Type serviceType)
|
||||
{
|
||||
return GetService(serviceType);
|
||||
}
|
||||
public virtual object GetService(Type serviceType)
|
||||
{
|
||||
return CachedServices.GetOrAdd(
|
||||
serviceType,
|
||||
_ => new Lazy<object>(() => IocManager.Resolve(serviceType))
|
||||
).Value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
using MAX.Core.Helpers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace MAX.Core.Extensions;
|
||||
|
||||
/// <summary>
|
||||
/// 系统扩展 - 类型转换
|
||||
/// </summary>
|
||||
public static partial class Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// IsNullOrEmpty
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsNullOrEmpty(this string input)
|
||||
{
|
||||
return string.IsNullOrEmpty(input);
|
||||
}
|
||||
/// <summary>
|
||||
/// 安全转换为字符串,去除两端空格,当值为null时返回""
|
||||
/// </summary>
|
||||
/// <param name="input">输入值</param>
|
||||
public static string SafeString(this object input)
|
||||
{
|
||||
return input?.ToString().Trim() ?? string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为bool
|
||||
/// </summary>
|
||||
/// <param name="obj">数据</param>
|
||||
public static bool ToBool(this string obj, bool defvalue = false)
|
||||
{
|
||||
return Helpers.Convert.ToBool(obj, defvalue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为可空bool
|
||||
/// </summary>
|
||||
/// <param name="obj">数据</param>
|
||||
public static bool? ToBoolOrNull(this string obj)
|
||||
{
|
||||
return Helpers.Convert.ToBoolOrNull(obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为int
|
||||
/// </summary>
|
||||
/// <param name="obj">数据</param>
|
||||
public static int ToInt(this string obj, int defvalue = 0)
|
||||
{
|
||||
return Helpers.Convert.ToInt(obj, defvalue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为可空int
|
||||
/// </summary>
|
||||
/// <param name="obj">数据</param>
|
||||
public static int? ToIntOrNull(this string obj)
|
||||
{
|
||||
return Helpers.Convert.ToIntOrNull(obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为long
|
||||
/// </summary>
|
||||
/// <param name="obj">数据</param>
|
||||
public static long ToLong(this string obj, long defvalue = 0)
|
||||
{
|
||||
return Helpers.Convert.ToLong(obj, defvalue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为可空long
|
||||
/// </summary>
|
||||
/// <param name="obj">数据</param>
|
||||
public static long? ToLongOrNull(this string obj)
|
||||
{
|
||||
return Helpers.Convert.ToLongOrNull(obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为double
|
||||
/// </summary>
|
||||
/// <param name="obj">数据</param>
|
||||
public static double ToDouble(this string obj, double defvalue = 0)
|
||||
{
|
||||
return Helpers.Convert.ToDouble(obj, defvalue: defvalue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为可空double
|
||||
/// </summary>
|
||||
/// <param name="obj">数据</param>
|
||||
public static double? ToDoubleOrNull(this string obj)
|
||||
{
|
||||
return Helpers.Convert.ToDoubleOrNull(obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为decimal
|
||||
/// </summary>
|
||||
/// <param name="obj">数据</param>
|
||||
public static decimal ToDecimal(this string obj, decimal defvalue = 0)
|
||||
{
|
||||
return Helpers.Convert.ToDecimal(obj, defvalue: defvalue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为可空decimal
|
||||
/// </summary>
|
||||
/// <param name="obj">数据</param>
|
||||
public static decimal? ToDecimalOrNull(this string obj)
|
||||
{
|
||||
return Helpers.Convert.ToDecimalOrNull(obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为日期
|
||||
/// </summary>
|
||||
/// <param name="obj">数据</param>
|
||||
public static DateTime ToDate(this string obj)
|
||||
{
|
||||
return Helpers.Convert.ToDate(obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为可空日期
|
||||
/// </summary>
|
||||
/// <param name="obj">数据</param>
|
||||
public static DateTime? ToDateOrNull(this string obj)
|
||||
{
|
||||
return Helpers.Convert.ToDateOrNull(obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为Guid
|
||||
/// </summary>
|
||||
/// <param name="obj">数据</param>
|
||||
public static Guid ToGuid(this string obj)
|
||||
{
|
||||
return Helpers.Convert.ToGuid(obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为可空Guid
|
||||
/// </summary>
|
||||
/// <param name="obj">数据</param>
|
||||
public static Guid? ToGuidOrNull(this string obj)
|
||||
{
|
||||
return Helpers.Convert.ToGuidOrNull(obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为Guid集合
|
||||
/// </summary>
|
||||
/// <param name="obj">数据,范例: "83B0233C-A24F-49FD-8083-1337209EBC9A,EAB523C6-2FE7-47BE-89D5-C6D440C3033A"</param>
|
||||
public static List<Guid> ToGuidList(this string obj)
|
||||
{
|
||||
return Helpers.Convert.ToGuidList(obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为Guid集合
|
||||
/// </summary>
|
||||
/// <param name="obj">字符串集合</param>
|
||||
public static List<Guid> ToGuidList(this IList<string> obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
return obj.Select(t => t.ToGuid()).ToList();
|
||||
}
|
||||
/// <summary>
|
||||
/// 转换枚举描述
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
/// <returns></returns>
|
||||
public static string ToDescription(this Enum obj)
|
||||
{
|
||||
return EnumHelper.GetDescription(obj.GetType(), obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 枚举值 → 单个 EnumItem
|
||||
/// </summary>
|
||||
/// <typeparam name="TEnum"></typeparam>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static EnumItem<TEnum> ToItem<TEnum>(this TEnum value) where TEnum : struct, Enum
|
||||
{
|
||||
return new EnumItem<TEnum>(value);
|
||||
}
|
||||
/// <summary>
|
||||
/// 是否单一标记
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsSingleFlag(Enum obj)
|
||||
{
|
||||
return EnumHelper.IsSingleFlag(obj);
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取第一个标记
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="obj"></param>
|
||||
/// <returns></returns>
|
||||
public static Enum GetFirstFlag(this Enum obj)
|
||||
{
|
||||
return EnumHelper.GetFirstFlag(obj);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using MAX.Core.Cryptography;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace MAX.Core.Extensions;
|
||||
|
||||
public static class DictionaryExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 字典转url Get 参数
|
||||
/// </summary>
|
||||
/// <param name="parameters"></param>
|
||||
/// <returns></returns>
|
||||
public static string ToUrlParams(this IDictionary<string, string> parameters, bool IsUrlEncode = true)
|
||||
{
|
||||
IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(parameters);
|
||||
IEnumerator<KeyValuePair<string, string>> dem = sortedParams.GetEnumerator();
|
||||
StringBuilder sb = new("");
|
||||
while (dem.MoveNext())
|
||||
{
|
||||
string key = dem.Current.Key;
|
||||
string value = dem.Current.Value;
|
||||
if (!string.IsNullOrEmpty(key))
|
||||
{
|
||||
sb.Append(key).Append("=").Append(IsUrlEncode ? UrlHelper.Encode(value) : value).Append("&");
|
||||
|
||||
}
|
||||
}
|
||||
string content = sb.ToString().Substring(0, sb.Length - 1);
|
||||
|
||||
return content;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
|
||||
namespace MAX.Core.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// 常用公共操作
|
||||
/// </summary>
|
||||
public static partial class Common
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取类型
|
||||
/// </summary>
|
||||
/// <typeparam name="T">类型</typeparam>
|
||||
public static Type GetType<T>()
|
||||
{
|
||||
return GetType(typeof(T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取类型
|
||||
/// </summary>
|
||||
/// <param name="type">类型</param>
|
||||
public static Type GetType(Type type)
|
||||
{
|
||||
return Nullable.GetUnderlyingType(type) ?? type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 换行符
|
||||
/// </summary>
|
||||
public static string Line => Environment.NewLine;
|
||||
|
||||
|
||||
#if NET5_0
|
||||
/// <summary>
|
||||
/// 是否Linux操作系统
|
||||
/// </summary>
|
||||
public static bool IsLinux => RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
|
||||
|
||||
/// <summary>
|
||||
/// 是否Windows操作系统
|
||||
/// </summary>
|
||||
public static bool IsWindows => RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||
|
||||
/// <summary>
|
||||
/// 是否苹果操作系统
|
||||
/// </summary>
|
||||
public static bool IsOsx => RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
|
||||
|
||||
/// <summary>
|
||||
/// 当前操作系统
|
||||
/// </summary>
|
||||
public static string System => IsWindows ? "Windows" : IsLinux ? "Linux" : IsOsx ? "OSX" : string.Empty;
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using System;
|
||||
|
||||
namespace MAX.Core.Helpers;
|
||||
|
||||
public class CommonItem : IComparable<CommonItem>
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
/// </summary>
|
||||
/// <param name="text">文本</param>
|
||||
/// <param name="value">值</param>
|
||||
/// <param name="sortId">排序号</param>
|
||||
/// <param name="group">组</param>
|
||||
/// <param name="disabled">禁用</param>
|
||||
public CommonItem(string text, object value, string des = "", int? sortId = null, string group = null, bool? disabled = null)
|
||||
{
|
||||
Text = text;
|
||||
Value = value;
|
||||
Description = des;
|
||||
SortId = sortId;
|
||||
Group = group;
|
||||
Disabled = disabled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 文本
|
||||
/// </summary>
|
||||
public string Text { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 值
|
||||
/// </summary>
|
||||
public object Value { get; protected set; }
|
||||
/// <summary>
|
||||
/// 描述
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
/// <summary>
|
||||
/// 排序号
|
||||
/// </summary>
|
||||
public int? SortId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 组
|
||||
/// </summary>
|
||||
public string Group { get; }
|
||||
/// <summary>
|
||||
/// 是否选中
|
||||
/// </summary>
|
||||
public bool IsSelected { get; set; }
|
||||
/// <summary>
|
||||
/// 禁用
|
||||
/// </summary>
|
||||
public bool? Disabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 比较
|
||||
/// </summary>
|
||||
/// <param name="other">其它列表项</param>
|
||||
public int CompareTo(CommonItem other)
|
||||
{
|
||||
return string.Compare(Text, other.Text, StringComparison.CurrentCulture);
|
||||
}
|
||||
}
|
||||
|
||||
public class CommonItem<T> : CommonItem
|
||||
{
|
||||
public new T Value
|
||||
{
|
||||
get { return (T)base.Value; }
|
||||
set { base.Value = value; }
|
||||
}
|
||||
public CommonItem(string text, T value, string des = "", int? sortId = null, string group = null, bool? disabled = null) : base(text, value, des, sortId, group, disabled)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,385 @@
|
||||
using MAX.Core.Extensions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace MAX.Core.Helpers;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field)]
|
||||
public class ConvertAttribute : Attribute
|
||||
{
|
||||
public Type ConverterType { get; set; }
|
||||
public ConvertAttribute(Type type)
|
||||
{
|
||||
ConverterType = type;
|
||||
}
|
||||
}
|
||||
public interface IConverter
|
||||
{
|
||||
object Converter(object input);
|
||||
}
|
||||
/// <summary>
|
||||
/// 类型转换
|
||||
/// </summary>
|
||||
public static partial class Convert
|
||||
{
|
||||
/// <summary>
|
||||
/// 转换为32位整型
|
||||
/// </summary>
|
||||
/// <param name="input">输入值</param>
|
||||
public static int ToInt(object input, int defvalue = 0)
|
||||
{
|
||||
return ToIntOrNull(input) ?? defvalue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为32位可空整型
|
||||
/// </summary>
|
||||
/// <param name="input">输入值</param>
|
||||
public static int? ToIntOrNull(object input)
|
||||
{
|
||||
bool success = int.TryParse(input.SafeString(), out int result);
|
||||
if (success)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
double? temp = ToDoubleOrNull(input, 0);
|
||||
if (temp == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return System.Convert.ToInt32(temp);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为64位整型
|
||||
/// </summary>
|
||||
/// <param name="input">输入值</param>
|
||||
public static long ToLong(object input, long defvalue = 0)
|
||||
{
|
||||
return ToLongOrNull(input) ?? defvalue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为64位可空整型
|
||||
/// </summary>
|
||||
/// <param name="input">输入值</param>
|
||||
public static long? ToLongOrNull(object input)
|
||||
{
|
||||
bool success = long.TryParse(input.SafeString(), out long result);
|
||||
if (success)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
decimal? temp = ToDecimalOrNull(input, 0);
|
||||
if (temp == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return System.Convert.ToInt64(temp);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为32位浮点型,并按指定小数位舍入
|
||||
/// </summary>
|
||||
/// <param name="input">输入值</param>
|
||||
/// <param name="digits">小数位数</param>
|
||||
public static float ToFloat(object input, int? digits = null)
|
||||
{
|
||||
return ToFloatOrNull(input, digits) ?? 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为32位可空浮点型,并按指定小数位舍入
|
||||
/// </summary>
|
||||
/// <param name="input">输入值</param>
|
||||
/// <param name="digits">小数位数</param>
|
||||
public static float? ToFloatOrNull(object input, int? digits = null)
|
||||
{
|
||||
bool success = float.TryParse(input.SafeString(), out float result);
|
||||
if (!success)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (digits == null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return (float)Math.Round(result, digits.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为64位浮点型,并按指定小数位舍入
|
||||
/// </summary>
|
||||
/// <param name="input">输入值</param>
|
||||
/// <param name="digits">小数位数</param>
|
||||
public static double ToDouble(object input, int? digits = null, double defvalue = 0)
|
||||
{
|
||||
return ToDoubleOrNull(input, digits) ?? defvalue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为64位可空浮点型,并按指定小数位舍入
|
||||
/// </summary>
|
||||
/// <param name="input">输入值</param>
|
||||
/// <param name="digits">小数位数</param>
|
||||
public static double? ToDoubleOrNull(object input, int? digits = null)
|
||||
{
|
||||
if (input is bool b)
|
||||
{
|
||||
return b ? 1 : 0;
|
||||
}
|
||||
bool success = double.TryParse(input.SafeString(), out double result);
|
||||
if (!success)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (digits == null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return Math.Round(result, digits.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为128位浮点型,并按指定小数位舍入
|
||||
/// </summary>
|
||||
/// <param name="input">输入值</param>
|
||||
/// <param name="digits">小数位数</param>
|
||||
public static decimal ToDecimal(object input, int? digits = null, decimal defvalue = 0)
|
||||
{
|
||||
return ToDecimalOrNull(input, digits) ?? defvalue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为128位可空浮点型,并按指定小数位舍入
|
||||
/// </summary>
|
||||
/// <param name="input">输入值</param>
|
||||
/// <param name="digits">小数位数</param>
|
||||
public static decimal? ToDecimalOrNull(object input, int? digits = null)
|
||||
{
|
||||
bool success = decimal.TryParse(input.SafeString(), out decimal result);
|
||||
if (!success)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (digits == null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return Math.Round(result, digits.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为布尔值
|
||||
/// </summary>
|
||||
/// <param name="input">输入值</param>
|
||||
public static bool ToBool(object input, bool defvalue = false)
|
||||
{
|
||||
return ToBoolOrNull(input) ?? defvalue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为可空布尔值
|
||||
/// </summary>
|
||||
/// <param name="input">输入值</param>
|
||||
public static bool? ToBoolOrNull(object input)
|
||||
{
|
||||
bool? value = GetBool(input);
|
||||
if (value != null)
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
|
||||
return bool.TryParse(input.SafeString(), out bool result) ? result : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取布尔值
|
||||
/// </summary>
|
||||
private static bool? GetBool(object input)
|
||||
{
|
||||
return input.SafeString().ToLower() switch
|
||||
{
|
||||
"0" => false,
|
||||
"否" => false,
|
||||
"不" => false,
|
||||
"no" => false,
|
||||
"fail" => false,
|
||||
"1" => true,
|
||||
"是" => true,
|
||||
"ok" => true,
|
||||
"yes" => true,
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为日期
|
||||
/// </summary>
|
||||
/// <param name="input">输入值</param>
|
||||
public static DateTime ToDate(object input)
|
||||
{
|
||||
return ToDateOrNull(input) ?? DateTime.MinValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为可空日期
|
||||
/// </summary>
|
||||
/// <param name="input">输入值</param>
|
||||
public static DateTime? ToDateOrNull(object input)
|
||||
{
|
||||
return DateTime.TryParse(input.SafeString(), out DateTime result) ? result : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为Guid
|
||||
/// </summary>
|
||||
/// <param name="input">输入值</param>
|
||||
public static Guid ToGuid(object input)
|
||||
{
|
||||
return ToGuidOrNull(input) ?? Guid.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为可空Guid
|
||||
/// </summary>
|
||||
/// <param name="input">输入值</param>
|
||||
public static Guid? ToGuidOrNull(object input)
|
||||
{
|
||||
return Guid.TryParse(input.SafeString(), out Guid result) ? result : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为Guid集合
|
||||
/// </summary>
|
||||
/// <param name="input">以逗号分隔的Guid集合字符串,范例:83B0233C-A24F-49FD-8083-1337209EBC9A,EAB523C6-2FE7-47BE-89D5-C6D440C3033A</param>
|
||||
public static List<Guid> ToGuidList(string input)
|
||||
{
|
||||
return ToList<Guid>(input);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 泛型集合转换
|
||||
/// </summary>
|
||||
/// <typeparam name="T">目标元素类型</typeparam>
|
||||
/// <param name="input">以逗号分隔的元素集合字符串,范例:83B0233C-A24F-49FD-8083-1337209EBC9A,EAB523C6-2FE7-47BE-89D5-C6D440C3033A</param>
|
||||
public static List<T> ToList<T>(string input)
|
||||
{
|
||||
List<T> result = [];
|
||||
if (string.IsNullOrWhiteSpace(input))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
string[] array = input.Split(',');
|
||||
result.AddRange(from each in array where !string.IsNullOrWhiteSpace(each) select To<T>(each));
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通用泛型转换
|
||||
/// </summary>
|
||||
/// <typeparam name="T">目标类型</typeparam>
|
||||
/// <param name="input">输入值</param>
|
||||
public static T To<T>(object input)
|
||||
{
|
||||
Type type = Common.GetType<T>();
|
||||
return (T)To(type, input);
|
||||
}
|
||||
public static object To(Type type, object input)
|
||||
{
|
||||
object defValue = null;
|
||||
if (type != null)
|
||||
{
|
||||
defValue = type.IsValueType ? Activator.CreateInstance(type) : null;
|
||||
}
|
||||
if (input == null)
|
||||
{
|
||||
return defValue;
|
||||
}
|
||||
|
||||
if (input is string && string.IsNullOrWhiteSpace(input.ToString()))
|
||||
{
|
||||
return defValue;
|
||||
}
|
||||
|
||||
string typeName = type.Name.ToLower();
|
||||
try
|
||||
{
|
||||
if (typeName == "string")
|
||||
{
|
||||
return input.ToString();
|
||||
}
|
||||
|
||||
if (typeName == "guid")
|
||||
{
|
||||
return new Guid(input.ToString());
|
||||
}
|
||||
|
||||
if (type.IsEnum)
|
||||
{
|
||||
return EnumHelper.Parse(type, input);
|
||||
}
|
||||
|
||||
if (typeof(IConverter).IsAssignableFrom(type))
|
||||
{
|
||||
object instance = Activator.CreateInstance(type);
|
||||
return ((IConverter)instance).Converter(input);
|
||||
}
|
||||
if (input is IConvertible)
|
||||
{
|
||||
return System.Convert.ChangeType(input, type);
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return defValue;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 转换为字节数组
|
||||
/// </summary>
|
||||
/// <param name="input">输入值</param>
|
||||
public static byte[] ToBytes(string input)
|
||||
{
|
||||
return ToBytes(input, Encoding.UTF8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为字节数组
|
||||
/// </summary>
|
||||
/// <param name="input">输入值</param>
|
||||
/// <param name="encoding">字符编码</param>
|
||||
public static byte[] ToBytes(string input, Encoding encoding)
|
||||
{
|
||||
return string.IsNullOrWhiteSpace(input) ? new byte[] { } : encoding.GetBytes(input);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,110 @@
|
||||
using System;
|
||||
|
||||
namespace MAX.Core.Helpers;
|
||||
|
||||
public class DateHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Unix纪元时间
|
||||
/// </summary>
|
||||
private static readonly DateTime UnixEpoch = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
|
||||
/// <summary>
|
||||
/// 将时间转换为秒级时间戳
|
||||
/// </summary>
|
||||
/// <param name="dateTime"></param>
|
||||
/// <returns></returns>
|
||||
public static long GetUnixTimestampInSeconds(DateTime dateTime)
|
||||
{
|
||||
TimeSpan timeSpan = dateTime.ToUniversalTime() - UnixEpoch;
|
||||
return (long)timeSpan.TotalSeconds;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将时间转换为毫秒级时间戳
|
||||
/// </summary>
|
||||
/// <param name="dateTime"></param>
|
||||
/// <returns></returns>
|
||||
public static long GetUnixTimestampInMilliseconds(DateTime dateTime)
|
||||
{
|
||||
TimeSpan timeSpan = dateTime.ToUniversalTime() - UnixEpoch;
|
||||
return (long)timeSpan.TotalMilliseconds;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将时间转换为微秒时间戳
|
||||
/// </summary>
|
||||
/// <param name="dateTime"></param>
|
||||
/// <returns></returns>
|
||||
public static long GetUnixTimestampInMicroseconds(DateTime dateTime)
|
||||
{
|
||||
long us = dateTime.ToUniversalTime().Ticks - UnixEpoch.Ticks;
|
||||
return us;
|
||||
}
|
||||
/// <summary>
|
||||
/// 将时间Ticks转换为毫微秒时间戳
|
||||
/// </summary>
|
||||
/// <param name="dateTime"></param>
|
||||
/// <returns></returns>
|
||||
public static long GetUnixTimestampInMicroseconds(long ticks)
|
||||
{
|
||||
long us = ticks - UnixEpoch.Ticks;
|
||||
return us;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将秒级时间戳转换为时间
|
||||
/// </summary>
|
||||
/// <param name="timestamp"></param>
|
||||
/// <returns></returns>
|
||||
public static DateTime ConvertFromUnixTimestampInSeconds(long timestamp)
|
||||
{
|
||||
return UnixEpoch.AddSeconds(timestamp).ToLocalTime();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将毫秒级时间戳转换为时间
|
||||
/// </summary>
|
||||
/// <param name="timestamp"></param>
|
||||
/// <returns></returns>
|
||||
public static DateTime ConvertFromUnixTimestampInMilliseconds(long timestamp)
|
||||
{
|
||||
return UnixEpoch.AddMilliseconds(timestamp).ToLocalTime();
|
||||
}
|
||||
/// <summary>
|
||||
/// 将微秒级时间戳转换为时间
|
||||
/// </summary>
|
||||
/// <param name="timestamp"></param>
|
||||
/// <returns></returns>
|
||||
public static DateTime ConvertFromUnixTimestampInMicroseconds(long timestamp)
|
||||
{
|
||||
long us = timestamp + UnixEpoch.Ticks;
|
||||
return new DateTime(us);
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取当前时间的秒级时间戳
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static long GetCurrentUnixTimestampInSeconds()
|
||||
{
|
||||
return GetUnixTimestampInSeconds(DateTime.UtcNow);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前时间的毫秒级时间戳
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static long GetCurrentUnixTimestampInMilliseconds()
|
||||
{
|
||||
return GetUnixTimestampInMilliseconds(DateTime.UtcNow);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前时间的微秒级时间戳
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static long GetCurrentUnixTimestampInMicroseconds()
|
||||
{
|
||||
return GetUnixTimestampInMicroseconds(DateTime.UtcNow);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,341 @@
|
||||
using MAX.Core.Extensions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace MAX.Core.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// 枚举操作
|
||||
/// </summary>
|
||||
public static partial class EnumHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取实例
|
||||
/// </summary>
|
||||
/// <typeparam name="TEnum">枚举类型</typeparam>
|
||||
/// <param name="member">成员名或值,范例:Enum1枚举有成员A=0,则传入"A"或"0"获取 Enum1.A</param>
|
||||
public static TEnum Parse<TEnum>(object member)
|
||||
{
|
||||
string value = member.SafeString();
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
if (typeof(TEnum).IsGenericType)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
throw new ArgumentNullException(nameof(member));
|
||||
}
|
||||
return (TEnum)Enum.Parse(Common.GetType<TEnum>(), value, true);
|
||||
}
|
||||
public static object Parse(Type enumObj, object member)
|
||||
{
|
||||
string value = member.SafeString();
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
if (enumObj.IsGenericType)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
throw new ArgumentNullException(nameof(member));
|
||||
}
|
||||
return Enum.Parse(enumObj, value, true);
|
||||
}
|
||||
public static TEnum ParseByDescription<TEnum>(string description)
|
||||
{
|
||||
return (TEnum)ParseByDescription(Common.GetType<TEnum>(), description);
|
||||
}
|
||||
public static object ParseByDescription(Type enumObj, string description)
|
||||
{
|
||||
List<EnumItem> listitem = GetItems(enumObj);
|
||||
foreach (EnumItem item in listitem)
|
||||
{
|
||||
if (item.Description == description)
|
||||
{
|
||||
return Enum.Parse(enumObj, item.Numeric.ToString(), true);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取成员名
|
||||
/// </summary>
|
||||
/// <typeparam name="TEnum">枚举类型</typeparam>
|
||||
/// <param name="member">成员名、值、实例均可,范例:Enum1枚举有成员A=0,则传入Enum1.A或0,获取成员名"A"</param>
|
||||
public static string GetName<TEnum>(object member)
|
||||
{
|
||||
return GetName(Common.GetType<TEnum>(), member);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取成员名
|
||||
/// </summary>
|
||||
/// <param name="type">枚举类型</param>
|
||||
/// <param name="member">成员名、值、实例均可</param>
|
||||
public static string GetName(Type type, object member)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
if (member == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
if (member is string)
|
||||
{
|
||||
return member.ToString();
|
||||
}
|
||||
|
||||
if (type.GetTypeInfo().IsEnum == false)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return Enum.GetName(type, member);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取成员值
|
||||
/// </summary>
|
||||
/// <typeparam name="TEnum">枚举类型</typeparam>
|
||||
/// <param name="member">成员名、值、实例均可,范例:Enum1枚举有成员A=0,可传入"A"、0、Enum1.A,获取值0</param>
|
||||
public static int GetValue<TEnum>(object member)
|
||||
{
|
||||
return GetValue(Common.GetType<TEnum>(), member);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取成员值
|
||||
/// </summary>
|
||||
/// <param name="type">枚举类型</param>
|
||||
/// <param name="member">成员名、值、实例均可</param>
|
||||
public static int GetValue(Type type, object member)
|
||||
{
|
||||
string value = member.SafeString();
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(member));
|
||||
}
|
||||
|
||||
return (int)Enum.Parse(type, member.ToString(), true);
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取描述,使用System.ComponentModel.Description特性设置描述
|
||||
/// </summary>
|
||||
/// <typeparam name="TEnum">枚举类型</typeparam>
|
||||
/// <param name="member">成员名、值、实例均可</param>
|
||||
public static string GetDescription<TEnum>(object member)
|
||||
{
|
||||
return ReflectionHelper.GetDescription<TEnum>(GetName<TEnum>(member));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取描述,使用System.ComponentModel.Description特性设置描述
|
||||
/// </summary>
|
||||
/// <param name="type">枚举类型</param>
|
||||
/// <param name="member">成员名、值、实例均可</param>
|
||||
public static string GetDescription(Type type, object member)
|
||||
{
|
||||
return ReflectionHelper.GetDescription(type, GetName(type, member));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取项集合,文本设置为Description,值为Value
|
||||
/// </summary>
|
||||
/// <typeparam name="TEnum">枚举类型</typeparam>
|
||||
public static List<EnumItem> GetItems<TEnum>()
|
||||
{
|
||||
return GetItems(typeof(TEnum));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取项集合,文本设置为Description,值为Value
|
||||
/// </summary>
|
||||
/// <param name="type">枚举类型</param>
|
||||
public static List<EnumItem> GetItems(Type type)
|
||||
{
|
||||
type = Common.GetType(type);
|
||||
if (type.IsEnum == false)
|
||||
{
|
||||
throw new InvalidOperationException($"类型 {type} 不是枚举");
|
||||
}
|
||||
|
||||
List<EnumItem> result = [];
|
||||
foreach (FieldInfo field in type.GetFields())
|
||||
{
|
||||
AddItem(type, result, field);
|
||||
}
|
||||
|
||||
return result.OrderBy(t => t.Numeric).ToList();
|
||||
}
|
||||
|
||||
public static CommonItem GetItem(object obj)
|
||||
{
|
||||
CommonItem item = null;
|
||||
if (obj is Enum em)
|
||||
{
|
||||
//item.Text = em.get
|
||||
string text = em.ToString();
|
||||
int value = GetValue(obj.GetType(), obj);
|
||||
string description = em.ToDescription();
|
||||
item = new CommonItem(text, value, des: description);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加描述项
|
||||
/// </summary>
|
||||
private static void AddItem(Type type, ICollection<EnumItem> result, FieldInfo field)
|
||||
{
|
||||
if (!field.FieldType.IsEnum)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string text = field.Name;
|
||||
int value = GetValue(type, field.Name);
|
||||
string description = ReflectionHelper.GetDescription(field);
|
||||
result.Add(new EnumItem(text, value, description));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取名称集合
|
||||
/// </summary>
|
||||
/// <typeparam name="TEnum">枚举类型</typeparam>
|
||||
public static List<string> GetNames<TEnum>()
|
||||
{
|
||||
return GetNames(typeof(TEnum));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取名称集合
|
||||
/// </summary>
|
||||
/// <param name="type">枚举类型</param>
|
||||
public static List<string> GetNames(Type type)
|
||||
{
|
||||
type = Common.GetType(type);
|
||||
if (type.IsEnum == false)
|
||||
{
|
||||
throw new InvalidOperationException($"类型 {type} 不是枚举");
|
||||
}
|
||||
|
||||
List<string> result = [];
|
||||
foreach (FieldInfo field in type.GetFields())
|
||||
{
|
||||
if (!field.FieldType.IsEnum)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
result.Add(field.Name);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取名称集合
|
||||
/// </summary>
|
||||
/// <typeparam name="TEnum">枚举类型</typeparam>
|
||||
public static List<string> GetDescriptions<TEnum>()
|
||||
{
|
||||
return GetDescriptions(typeof(TEnum));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取名称集合
|
||||
/// </summary>
|
||||
/// <param name="type">枚举类型</param>
|
||||
public static List<string> GetDescriptions(Type type)
|
||||
{
|
||||
type = Common.GetType(type);
|
||||
if (type.IsEnum == false)
|
||||
{
|
||||
throw new InvalidOperationException($"类型 {type} 不是枚举");
|
||||
}
|
||||
|
||||
List<string> result = [];
|
||||
foreach (FieldInfo field in type.GetFields())
|
||||
{
|
||||
if (!field.FieldType.IsEnum)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string description = ReflectionHelper.GetDescription(field);
|
||||
result.Add(description);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/// <summary>
|
||||
/// 是否单一标记
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsSingleFlag(Enum obj)
|
||||
{
|
||||
int intValue = GetValue(obj.GetType(), obj);
|
||||
return (intValue > 0) && ((intValue & (intValue - 1)) == 0);
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取第一个标记
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static T GetFirstFlag<T>(T value) where T : Enum
|
||||
{
|
||||
long v = System.Convert.ToInt64(value);
|
||||
long first = v & -v;
|
||||
return Enum.GetValues(typeof(T)).Cast<T>().First(flag => System.Convert.ToInt64(flag) == first);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Enum展示类型
|
||||
/// </summary>
|
||||
public enum EnumDisplayType
|
||||
{
|
||||
Text,
|
||||
Value,
|
||||
Description,
|
||||
CommonItem
|
||||
}
|
||||
public class EnumItem
|
||||
{
|
||||
public string Name { get; init; }
|
||||
public int Numeric { get; init; }
|
||||
public string Description { get; init; }
|
||||
|
||||
public EnumItem(string name, int numeric, string description)
|
||||
{
|
||||
Name = name;
|
||||
Numeric = numeric;
|
||||
Description = description;
|
||||
}
|
||||
}
|
||||
public class EnumItem<TEnum> : EnumItem where TEnum : struct, Enum
|
||||
{
|
||||
public TEnum Value { get; }
|
||||
|
||||
public EnumItem(TEnum value)
|
||||
: base(value.ToString(), System.Convert.ToInt32(value), GetDescription(value))
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
private static string GetDescription(TEnum value)
|
||||
{
|
||||
var field = typeof(TEnum).GetField(value.ToString())!;
|
||||
var attr = field.GetCustomAttribute<DescriptionAttribute>();
|
||||
return attr?.Description ?? string.Empty;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MAX.Core.Helpers;
|
||||
|
||||
public class EnvironmentHelper
|
||||
{
|
||||
private static string? _currentEnvironment;
|
||||
|
||||
// 获取当前环境
|
||||
public static string CurrentEnvironment
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_currentEnvironment == null)
|
||||
{
|
||||
_currentEnvironment = DetermineEnvironment();
|
||||
}
|
||||
return _currentEnvironment;
|
||||
}
|
||||
}
|
||||
public static bool IsTest => CurrentEnvironment.Equals("Test", StringComparison.OrdinalIgnoreCase);
|
||||
public static bool IsDevelopment => CurrentEnvironment.Equals("Development", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
public static bool IsProduction => CurrentEnvironment.Equals("Production", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
private static string DetermineEnvironment()
|
||||
{
|
||||
#if RELEASE
|
||||
// Release 构建:只允许生产环境,不允许其他环境
|
||||
return "Production";
|
||||
#else
|
||||
// 1. 检查环境变量
|
||||
var envVar = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT") ??
|
||||
Environment.GetEnvironmentVariable("ENVIRONMENT");
|
||||
|
||||
if (!string.IsNullOrEmpty(envVar))
|
||||
{
|
||||
return envVar;
|
||||
}
|
||||
|
||||
|
||||
// 检查当前机器名
|
||||
string machineName = Environment.MachineName.ToLower();
|
||||
if (machineName.Contains("dev") ||
|
||||
machineName.Contains("test"))
|
||||
{
|
||||
return machineName.Contains("TEST") ? "Test" : "Development";
|
||||
}
|
||||
|
||||
// 4. 默认返回 Production
|
||||
return "Production";
|
||||
#endif
|
||||
}
|
||||
|
||||
// 获取环境描述
|
||||
public static string EnvironmentDescription
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsTest) return "测试环境";
|
||||
if (IsDevelopment) return "开发环境";
|
||||
if (IsProduction) return "生产环境";
|
||||
return $"未知环境 ({CurrentEnvironment})";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MAX.Core.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// 文件和流操作
|
||||
/// </summary>
|
||||
public static partial class FileHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 流转换为字节流
|
||||
/// </summary>
|
||||
/// <param name="stream">流</param>
|
||||
public static async Task<byte[]> ToBytesAsync(Stream stream)
|
||||
{
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
byte[] buffer = new byte[stream.Length];
|
||||
await stream.ReadAsync(buffer, 0, buffer.Length);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 流转换为字节流
|
||||
/// </summary>
|
||||
/// <param name="stream">流</param>
|
||||
public static byte[] ToBytes(Stream stream)
|
||||
{
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
byte[] buffer = new byte[stream.Length];
|
||||
stream.Read(buffer, 0, buffer.Length);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 字符串转换成字节数组
|
||||
/// </summary>
|
||||
/// <param name="data">数据,默认字符编码utf-8</param>
|
||||
public static byte[] ToBytes(string data)
|
||||
{
|
||||
return ToBytes(data, Encoding.UTF8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 字符串转换成字节数组
|
||||
/// </summary>
|
||||
/// <param name="data">数据</param>
|
||||
/// <param name="encoding">字符编码</param>
|
||||
public static byte[] ToBytes(string data, Encoding encoding)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(data))
|
||||
{
|
||||
return new byte[] { };
|
||||
}
|
||||
|
||||
return encoding.GetBytes(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将文件读取到字节流中
|
||||
/// </summary>
|
||||
/// <param name="filePath">文件的绝对路径</param>
|
||||
public static byte[] Read(string filePath)
|
||||
{
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
FileInfo fileInfo = new(filePath);
|
||||
using BinaryReader reader = new(fileInfo.Open(FileMode.Open));
|
||||
return reader.ReadBytes((int)fileInfo.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 流转换成字符串
|
||||
/// </summary>
|
||||
/// <param name="stream">流</param>
|
||||
/// <param name="encoding">字符编码</param>
|
||||
/// <param name="bufferSize">缓冲区大小</param>
|
||||
/// <param name="isCloseStream">读取完成是否释放流,默认为true</param>
|
||||
public static string ToString(Stream stream, Encoding encoding = null, int bufferSize = 1024 * 2, bool isCloseStream = true)
|
||||
{
|
||||
if (stream == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
encoding ??= Encoding.UTF8;
|
||||
|
||||
if (stream.CanRead == false)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
using StreamReader reader = new(stream, encoding, true, bufferSize, !isCloseStream);
|
||||
if (stream.CanSeek)
|
||||
{
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
string result = reader.ReadToEnd();
|
||||
if (stream.CanSeek)
|
||||
{
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 流转换成字符串
|
||||
/// </summary>
|
||||
/// <param name="stream">流</param>
|
||||
/// <param name="encoding">字符编码</param>
|
||||
/// <param name="bufferSize">缓冲区大小</param>
|
||||
/// <param name="isCloseStream">读取完成是否释放流,默认为true</param>
|
||||
public static async Task<string> ToStringAsync(Stream stream, Encoding encoding = null, int bufferSize = 1024 * 2, bool isCloseStream = true)
|
||||
{
|
||||
if (stream == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
encoding ??= Encoding.UTF8;
|
||||
|
||||
if (stream.CanRead == false)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
using StreamReader reader = new(stream, encoding, true, bufferSize, !isCloseStream);
|
||||
if (stream.CanSeek)
|
||||
{
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
string result = await reader.ReadToEndAsync();
|
||||
if (stream.CanSeek)
|
||||
{
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 复制流并转换成字符串
|
||||
/// </summary>
|
||||
/// <param name="stream">流</param>
|
||||
/// <param name="encoding">字符编码</param>
|
||||
public static async Task<string> CopyToStringAsync(Stream stream, Encoding encoding = null)
|
||||
{
|
||||
if (stream == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
encoding ??= Encoding.UTF8;
|
||||
|
||||
if (stream.CanRead == false)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
using MemoryStream memoryStream = new();
|
||||
using StreamReader reader = new(memoryStream, encoding);
|
||||
if (stream.CanSeek)
|
||||
{
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
stream.CopyTo(memoryStream);
|
||||
if (memoryStream.CanSeek)
|
||||
{
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
string result = await reader.ReadToEndAsync();
|
||||
if (stream.CanSeek)
|
||||
{
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,45 @@
|
||||
namespace MAX.Core.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// 标识生成器
|
||||
/// </summary>
|
||||
public static partial class IdHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 标识
|
||||
/// </summary>
|
||||
private static string _id;
|
||||
|
||||
/// <summary>
|
||||
/// 设置标识
|
||||
/// </summary>
|
||||
/// <param name="id">Id</param>
|
||||
public static void SetId(string id)
|
||||
{
|
||||
_id = id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重置标识
|
||||
/// </summary>
|
||||
public static void Reset()
|
||||
{
|
||||
_id = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用Guid创建标识,去掉分隔符
|
||||
/// </summary>
|
||||
public static string Guid()
|
||||
{
|
||||
return string.IsNullOrWhiteSpace(_id) ? System.Guid.NewGuid().ToString("N") : _id;
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// 获取Guid
|
||||
///// </summary>
|
||||
//public static Guid GetGuid()
|
||||
//{
|
||||
// return string.IsNullOrWhiteSpace(_id) ? System.Guid.NewGuid() : _id.ToGuid();
|
||||
//}
|
||||
}
|
||||
@@ -0,0 +1,369 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
|
||||
namespace MAX.Core.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// This is a generic parameters base class used for Dialog Parameters and Navigation Parameters.
|
||||
/// </summary>
|
||||
public abstract class ParametersBase : IEnumerable<KeyValuePair<string, object>>
|
||||
{
|
||||
private readonly List<KeyValuePair<string, object>> _entries = [];
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor.
|
||||
/// </summary>
|
||||
protected ParametersBase()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a list of parameters.
|
||||
/// </summary>
|
||||
/// <param name="query">Query string to be parsed.</param>
|
||||
protected ParametersBase(string query)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(query))
|
||||
{
|
||||
int num = query.Length;
|
||||
for (int i = ((query.Length > 0) && (query[0] == '?')) ? 1 : 0; i < num; i++)
|
||||
{
|
||||
int startIndex = i;
|
||||
int num4 = -1;
|
||||
while (i < num)
|
||||
{
|
||||
char ch = query[i];
|
||||
if (ch == '=')
|
||||
{
|
||||
if (num4 < 0)
|
||||
{
|
||||
num4 = i;
|
||||
}
|
||||
}
|
||||
else if (ch == '&')
|
||||
{
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
string key = null;
|
||||
string value;
|
||||
if (num4 >= 0)
|
||||
{
|
||||
key = query.Substring(startIndex, num4 - startIndex);
|
||||
value = query.Substring(num4 + 1, i - num4 - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = query.Substring(startIndex, i - startIndex);
|
||||
}
|
||||
|
||||
if (key != null)
|
||||
{
|
||||
Add(Uri.UnescapeDataString(key), Uri.UnescapeDataString(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches Parameter collection and returns value if Collection contains key.
|
||||
/// Otherwise returns null.
|
||||
/// </summary>
|
||||
/// <param name="key">The key for the value to be returned.</param>
|
||||
/// <returns>The value of the parameter referenced by the key; otherwise <c>null</c>.</returns>
|
||||
public object this[string key]
|
||||
{
|
||||
get
|
||||
{
|
||||
foreach (KeyValuePair<string, object> entry in _entries)
|
||||
{
|
||||
if (string.Compare(entry.Key, key, StringComparison.Ordinal) == 0)
|
||||
{
|
||||
return entry.Value;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The count, or number, of parameters in collection.
|
||||
/// </summary>
|
||||
public int Count => _entries.Count;
|
||||
|
||||
/// <summary>
|
||||
/// Returns an IEnumerable of the Keys in the collection.
|
||||
/// </summary>
|
||||
public IEnumerable<string> Keys =>
|
||||
_entries.Select(x => x.Key);
|
||||
|
||||
/// <summary>
|
||||
/// Adds the key and value to the parameters collection.
|
||||
/// </summary>
|
||||
/// <param name="key">The key to reference this value in the parameters collection.</param>
|
||||
/// <param name="value">The value of the parameter to store.</param>
|
||||
public void Add(string key, object value) =>
|
||||
_entries.Add(new KeyValuePair<string, object>(key, value));
|
||||
|
||||
|
||||
public void Remove(string key)
|
||||
{
|
||||
_entries.RemoveAll(x => x.Key == key);
|
||||
}
|
||||
|
||||
public void Update(string key, object value)
|
||||
{
|
||||
_entries.RemoveAll(x => x.Key == key);
|
||||
Add(key, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks collection for presence of key.
|
||||
/// </summary>
|
||||
/// <param name="key">The key to check in the collection.</param>
|
||||
/// <returns><c>true</c> if key exists; else returns <c>false</c>.</returns>
|
||||
public bool ContainsKey(string key)
|
||||
{
|
||||
return _entries.Any(x => string.Compare(x.Key, key, StringComparison.Ordinal) == 0);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets an enumerator for the KeyValuePairs in parameter collection.
|
||||
/// </summary>
|
||||
/// <returns>Enumerator.</returns>
|
||||
public IEnumerator<KeyValuePair<string, object>> GetEnumerator() =>
|
||||
_entries.GetEnumerator();
|
||||
|
||||
/// <summary>
|
||||
/// Returns the value of the member referenced by key.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of object to be returned.</typeparam>
|
||||
/// <param name="key">The key for the value to be returned.</param>
|
||||
/// <returns>Returns a matching parameter of <typeparamref name="T"/> if one exists in the Collection.</returns>
|
||||
public T GetValue<T>(string key) =>
|
||||
_entries.GetValue<T>(key);
|
||||
|
||||
/// <summary>
|
||||
/// Returns an IEnumerable of all parameters.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type for the values to be returned.</typeparam>
|
||||
/// <param name="key">The key for the values to be returned.</param>
|
||||
///<returns>Returns a IEnumerable of all the instances of type <typeparamref name="T"/>.</returns>
|
||||
public IEnumerable<T> GetValues<T>(string key) =>
|
||||
_entries.GetValues<T>(key);
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if the parameter collection contains the value.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type for the values to be returned.</typeparam>
|
||||
/// <param name="key">The key for the value to be returned.</param>
|
||||
/// <param name="value">Value of the returned parameter if it exists.</param>
|
||||
public bool TryGetValue<T>(string key, out T value) =>
|
||||
_entries.TryGetValue(key, out value);
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() =>
|
||||
GetEnumerator();
|
||||
|
||||
/// <summary>
|
||||
/// Converts parameter collection to a parameter string.
|
||||
/// </summary>
|
||||
/// <returns>A string representation of the parameters.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder queryBuilder = new();
|
||||
|
||||
if (_entries.Count > 0)
|
||||
{
|
||||
queryBuilder.Append('?');
|
||||
bool first = true;
|
||||
|
||||
foreach (KeyValuePair<string, object> kvp in _entries)
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
queryBuilder.Append('&');
|
||||
}
|
||||
else
|
||||
{
|
||||
first = false;
|
||||
}
|
||||
|
||||
queryBuilder.Append(Uri.EscapeDataString(kvp.Key));
|
||||
queryBuilder.Append('=');
|
||||
queryBuilder.Append(Uri.EscapeDataString(kvp.Value != null ? kvp.Value.ToString() : ""));
|
||||
}
|
||||
}
|
||||
|
||||
return queryBuilder.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a collection of parameters to the local parameter list.
|
||||
/// </summary>
|
||||
/// <param name="parameters">An IEnumerable of KeyValuePairs to add to the current parameter list.</param>
|
||||
public void FromParameters(IEnumerable<KeyValuePair<string, object>> parameters) =>
|
||||
_entries.AddRange(parameters);
|
||||
}
|
||||
|
||||
|
||||
public static class ParametersExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Searches <paramref name="parameters"/> for <paramref name="key"/>
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the parameter to return</typeparam>
|
||||
/// <param name="parameters">A collection of parameters to search</param>
|
||||
/// <param name="key">The key of the parameter to find</param>
|
||||
/// <returns>A matching value of <typeparamref name="T"/> if it exists</returns>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static T GetValue<T>(this IEnumerable<KeyValuePair<string, object>> parameters, string key) =>
|
||||
(T)GetValue(parameters, key, typeof(T));
|
||||
|
||||
/// <summary>
|
||||
/// Searches <paramref name="parameters"/> for value referenced by <paramref name="key"/>
|
||||
/// </summary>
|
||||
/// <param name="parameters">A collection of parameters to search</param>
|
||||
/// <param name="key">The key of the parameter to find</param>
|
||||
/// <param name="type">The type of the parameter to return</param>
|
||||
/// <returns>A matching value of <paramref name="type"/> if it exists</returns>
|
||||
/// <exception cref="InvalidCastException">Unable to convert the value of Type</exception>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static object GetValue(this IEnumerable<KeyValuePair<string, object>> parameters, string key, Type type)
|
||||
{
|
||||
foreach (KeyValuePair<string, object> kvp in parameters)
|
||||
{
|
||||
if (string.Compare(kvp.Key, key, StringComparison.Ordinal) == 0)
|
||||
{
|
||||
if (TryGetValueInternal(kvp, type, out object value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
throw new InvalidCastException($"Unable to convert the value of Type '{kvp.Value.GetType().FullName}' to '{type.FullName}' for the key '{key}' ");
|
||||
}
|
||||
}
|
||||
|
||||
return GetDefault(type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches <paramref name="parameters"/> for value referenced by <paramref name="key"/>
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the parameter to return</typeparam>
|
||||
/// <param name="parameters">A collection of parameters to search</param>
|
||||
/// <param name="key">The key of the parameter to find</param>
|
||||
/// <param name="value">The value of parameter to return</param>
|
||||
/// <returns>Success if value is found; otherwise returns <c>false</c></returns>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static bool TryGetValue<T>(this IEnumerable<KeyValuePair<string, object>> parameters, string key, out T value)
|
||||
{
|
||||
Type type = typeof(T);
|
||||
|
||||
foreach (KeyValuePair<string, object> kvp in parameters)
|
||||
{
|
||||
if (string.Compare(kvp.Key, key, StringComparison.Ordinal) == 0)
|
||||
{
|
||||
bool success = TryGetValueInternal(kvp, typeof(T), out object valueAsObject);
|
||||
value = (T)valueAsObject;
|
||||
return success;
|
||||
}
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches <paramref name="parameters"/> for value referenced by <paramref name="key"/>
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the parameter to return</typeparam>
|
||||
/// <param name="parameters">A collection of parameters to search</param>
|
||||
/// <param name="key">The key of the parameter to find</param>
|
||||
/// <returns>An IEnumerable{T} of all the values referenced by key</returns>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static IEnumerable<T> GetValues<T>(this IEnumerable<KeyValuePair<string, object>> parameters, string key)
|
||||
{
|
||||
List<T> values = [];
|
||||
Type type = typeof(T);
|
||||
|
||||
foreach (KeyValuePair<string, object> kvp in parameters)
|
||||
{
|
||||
if (string.Compare(kvp.Key, key, StringComparison.Ordinal) == 0)
|
||||
{
|
||||
TryGetValueInternal(kvp, type, out object value);
|
||||
values.Add((T)value);
|
||||
}
|
||||
}
|
||||
|
||||
return values.AsEnumerable();
|
||||
}
|
||||
|
||||
private static bool TryGetValueInternal(KeyValuePair<string, object> kvp, Type type, out object value)
|
||||
{
|
||||
value = GetDefault(type);
|
||||
bool success = false;
|
||||
if (kvp.Value == null)
|
||||
{
|
||||
success = true;
|
||||
}
|
||||
else if (kvp.Value.GetType() == type)
|
||||
{
|
||||
success = true;
|
||||
value = kvp.Value;
|
||||
}
|
||||
else if (type.IsAssignableFrom(kvp.Value.GetType()))
|
||||
{
|
||||
success = true;
|
||||
value = kvp.Value;
|
||||
}
|
||||
else if (type.IsEnum)
|
||||
{
|
||||
string valueAsString = kvp.Value.ToString();
|
||||
if (Enum.IsDefined(type, valueAsString))
|
||||
{
|
||||
success = true;
|
||||
value = Enum.Parse(type, valueAsString);
|
||||
}
|
||||
else if (int.TryParse(valueAsString, out int numericValue))
|
||||
{
|
||||
success = true;
|
||||
value = Enum.ToObject(type, numericValue);
|
||||
}
|
||||
}
|
||||
|
||||
if (!success && type.GetInterface("System.IConvertible") != null)
|
||||
{
|
||||
success = true;
|
||||
value = System.Convert.ChangeType(kvp.Value, type);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if key exists in parameter collection
|
||||
/// </summary>
|
||||
/// <param name="parameters">IEnumerable to search</param>
|
||||
/// <param name="key">The key to search the <paramref name="parameters"/> for existence</param>
|
||||
/// <returns><c>true</c> if key exists; <c>false</c> otherwise</returns>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static bool ContainsKey(this IEnumerable<KeyValuePair<string, object>> parameters, string key) =>
|
||||
parameters.Any(x => string.Compare(x.Key, key, StringComparison.Ordinal) == 0);
|
||||
|
||||
private static object GetDefault(Type type)
|
||||
{
|
||||
if (type.IsValueType)
|
||||
{
|
||||
return Activator.CreateInstance(type);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MAX.Core.Helpers
|
||||
{
|
||||
public sealed class RandomHelper
|
||||
{
|
||||
private static readonly char[] RandChar = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
|
||||
private static Random rand = new Random(unchecked((int)DateTime.Now.Ticks));
|
||||
private static int seed = 1;
|
||||
|
||||
private RandomHelper()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据规则随机生成字符串
|
||||
/// </summary>
|
||||
/// <param name="pattern">样式:"?"表明一个字符,"#"表明一个一位数字,"*"表明一个字符串或一个一位数字</param>
|
||||
/// <returns>随机字符串</returns>
|
||||
public static string GetRandStringByPattern(string pattern)
|
||||
{
|
||||
if (!pattern.Contains("#") && !pattern.Contains("?") && !pattern.Contains("*"))
|
||||
{
|
||||
return pattern;
|
||||
}
|
||||
|
||||
char[] nums = pattern.ToCharArray();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < nums.Length; i++)
|
||||
{
|
||||
switch (nums[i])
|
||||
{
|
||||
case '?':
|
||||
nums[i] = RandChar[rand.Next(10, 62)];
|
||||
break;
|
||||
case '#':
|
||||
nums[i] = RandChar[rand.Next(0, 10)];
|
||||
break;
|
||||
case '*':
|
||||
nums[i] = RandChar[rand.Next(62)];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
sb.Append(nums[i]);
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
/// <summary>
|
||||
/// 生成随机的数值
|
||||
/// </summary>
|
||||
/// <param name="max">随机数的上界</param>
|
||||
/// <returns>随机的数值</returns>
|
||||
public static int GetRandomNumber(int max)
|
||||
{
|
||||
return GetRandomNumber(0, max);
|
||||
}
|
||||
/// <summary>
|
||||
/// 生成随机的数值
|
||||
/// </summary>
|
||||
/// <param name="min">随机数可取该下界值</param>
|
||||
/// <param name="max">随机数的上界</param>
|
||||
/// <returns>随机的数值</returns>
|
||||
public static int GetRandomNumber(int min, int max)
|
||||
{
|
||||
int num = 0;
|
||||
Random ro = new Random(unchecked(seed * (int)DateTime.Now.Ticks));
|
||||
num = ro.Next(min, max);
|
||||
seed++;
|
||||
return num;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定长度和字符的随机字符串
|
||||
/// 经过调用 Random 类的 Next() 方法,先得到一个大于或等于 0 而小于 pwdchars 长度的整数
|
||||
/// 以该数做为索引值,从可用字符串中随机取字符,以指定的密码长度为循环次数
|
||||
/// 依次链接取得的字符,最后即获得所需的随机密码串了。
|
||||
/// </summary>
|
||||
/// <param name="pwdchars">随机字符串里包含的字符</param>
|
||||
/// <param name="pwdlen">随机字符串的长度</param>
|
||||
/// <returns>随机产生的字符串</returns>
|
||||
public static string GetRandomString(string pwdchars, int pwdlen)
|
||||
{
|
||||
StringBuilder tmpstr = new StringBuilder();
|
||||
int randNum;
|
||||
|
||||
for (int i = 0; i < pwdlen; i++)
|
||||
{
|
||||
randNum = rand.Next(pwdchars.Length);
|
||||
tmpstr.Append(pwdchars[randNum]);
|
||||
}
|
||||
|
||||
return tmpstr.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定长度的随机字符串
|
||||
/// </summary>
|
||||
/// <param name="pwdlen">随机字符串的长度</param>
|
||||
/// <returns>随机产生的字符串</returns>
|
||||
public static string GetRandomString(int pwdlen)
|
||||
{
|
||||
return GetRandomString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_*", pwdlen);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定长度的纯字母随机字符串
|
||||
/// </summary>
|
||||
/// <param name="pwdlen">数字串长度</param>
|
||||
/// <returns>纯字母随机字符串</returns>
|
||||
public static string GetRandWord(int pwdlen)
|
||||
{
|
||||
return GetRandomString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", pwdlen);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定长度的纯数字随机数字串
|
||||
/// </summary>
|
||||
/// <param name="intlong">数字串长度</param>
|
||||
/// <returns>纯数字随机数字串</returns>
|
||||
public static string GetRandomLengthNumString(int intlong)
|
||||
{
|
||||
StringBuilder w = new StringBuilder(string.Empty);
|
||||
|
||||
for (int i = 0; i < intlong; i++)
|
||||
{
|
||||
w.Append(rand.Next(10));
|
||||
}
|
||||
return w.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取按照年月时分秒随机数生成的文件名
|
||||
/// </summary>
|
||||
/// <returns>随机文件名</returns>
|
||||
public static string GetFileRndName()
|
||||
{
|
||||
return DateTime.Now.ToString("yyyyMMddHHmmss", CultureInfo.CurrentCulture) + GetRandomString("0123456789", 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,586 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace MAX.Core.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// 反射操作
|
||||
/// </summary>
|
||||
public static class ReflectionHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取类型描述,使用DescriptionAttribute设置描述
|
||||
/// </summary>
|
||||
/// <typeparam name="T">类型</typeparam>
|
||||
public static string GetDescription<T>()
|
||||
{
|
||||
return GetDescription(Common.GetType<T>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取类型成员描述,使用DescriptionAttribute设置描述
|
||||
/// </summary>
|
||||
/// <typeparam name="T">类型</typeparam>
|
||||
/// <param name="memberName">成员名称</param>
|
||||
public static string GetDescription<T>(string memberName)
|
||||
{
|
||||
return GetDescription(Common.GetType<T>(), memberName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取类型成员描述,使用DescriptionAttribute设置描述
|
||||
/// </summary>
|
||||
/// <param name="type">类型</param>
|
||||
/// <param name="memberName">成员名称</param>
|
||||
public static string GetDescription(Type type, string memberName)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(memberName))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return GetDescription(type.GetTypeInfo().GetMember(memberName).FirstOrDefault());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取类型成员描述,使用DescriptionAttribute设置描述
|
||||
/// </summary>
|
||||
/// <param name="member">成员</param>
|
||||
public static string GetDescription(MemberInfo member)
|
||||
{
|
||||
if (member == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return member.GetCustomAttribute<DescriptionAttribute>() is DescriptionAttribute attribute ? attribute.Description : member.Name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取显示名称或描述,使用DisplayNameAttribute设置显示名称,使用DescriptionAttribute设置描述
|
||||
/// </summary>
|
||||
/// <typeparam name="T">类型</typeparam>
|
||||
public static string GetDisplayNameOrDescription<T>()
|
||||
{
|
||||
return GetDisplayNameOrDescription(Common.GetType<T>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取属性显示名称或描述,使用DisplayAttribute或DisplayNameAttribute设置显示名称,使用DescriptionAttribute设置描述
|
||||
/// </summary>
|
||||
public static string GetDisplayNameOrDescription(MemberInfo member)
|
||||
{
|
||||
return GetDescription(member);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类型列表
|
||||
/// </summary>
|
||||
/// <typeparam name="TFind">查找类型</typeparam>
|
||||
/// <param name="assemblies">待查找的程序集列表</param>
|
||||
public static List<Type> FindTypes<TFind>(params Assembly[] assemblies)
|
||||
{
|
||||
Type findType = typeof(TFind);
|
||||
return FindTypes(findType, assemblies);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类型列表
|
||||
/// </summary>
|
||||
/// <param name="findType">查找类型</param>
|
||||
/// <param name="assemblies">待查找的程序集列表</param>
|
||||
public static List<Type> FindTypes(Type findType, params Assembly[] assemblies)
|
||||
{
|
||||
List<Type> result = [];
|
||||
foreach (Assembly assembly in assemblies)
|
||||
{
|
||||
result.AddRange(GetTypes(findType, assembly));
|
||||
}
|
||||
|
||||
return result.Distinct().ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取类型列表
|
||||
/// </summary>
|
||||
private static List<Type> GetTypes(Type findType, Assembly assembly)
|
||||
{
|
||||
List<Type> result = [];
|
||||
if (assembly == null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
Type[] types;
|
||||
try
|
||||
{
|
||||
types = assembly.GetTypes();
|
||||
}
|
||||
catch (ReflectionTypeLoadException ex)
|
||||
{
|
||||
Debug.WriteLine(ex);
|
||||
return result;
|
||||
}
|
||||
foreach (Type type in types)
|
||||
{
|
||||
AddType(result, findType, type);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加类型
|
||||
/// </summary>
|
||||
private static void AddType(List<Type> result, Type findType, Type type)
|
||||
{
|
||||
if (type.IsInterface || type.IsAbstract)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (findType.IsAssignableFrom(type) == false && MatchGeneric(findType, type) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
result.Add(type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 泛型匹配
|
||||
/// </summary>
|
||||
private static bool MatchGeneric(Type findType, Type type)
|
||||
{
|
||||
if (findType.IsGenericTypeDefinition == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Type definition = findType.GetGenericTypeDefinition();
|
||||
foreach (Type implementedInterface in type.FindInterfaces((filter, criteria) => true, null))
|
||||
{
|
||||
if (implementedInterface.IsGenericType == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return definition.IsAssignableFrom(implementedInterface.GetGenericTypeDefinition());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取实现了接口的所有实例
|
||||
/// </summary>
|
||||
/// <typeparam name="TInterface">接口类型</typeparam>
|
||||
/// <param name="assemblies">待查找的程序集列表</param>
|
||||
public static List<TInterface> GetInstancesByInterface<TInterface>(params Assembly[] assemblies)
|
||||
{
|
||||
return FindTypes<TInterface>(assemblies)
|
||||
.Select(t => CreateInstance<TInterface>(t)).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 动态创建实例
|
||||
/// </summary>
|
||||
/// <typeparam name="T">目标类型</typeparam>
|
||||
/// <param name="type">类型</param>
|
||||
/// <param name="parameters">传递给构造函数的参数</param>
|
||||
public static T CreateInstance<T>(Type type, params object[] parameters)
|
||||
{
|
||||
return Convert.To<T>(Activator.CreateInstance(type, parameters));
|
||||
}
|
||||
|
||||
public static Type GetType(string typeName)
|
||||
{
|
||||
|
||||
Type type = null;
|
||||
|
||||
Assembly[] assemblyArray = AppDomain.CurrentDomain.GetAssemblies();
|
||||
|
||||
int assemblyArrayLength = assemblyArray.Length;
|
||||
|
||||
for (int i = 0; i < assemblyArrayLength; ++i)
|
||||
{
|
||||
|
||||
type = assemblyArray[i].GetType(typeName);
|
||||
|
||||
if (type != null)
|
||||
{
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < assemblyArrayLength; ++i)
|
||||
{
|
||||
Type[] typeArray = assemblyArray[i].GetTypes();
|
||||
int typeArrayLength = typeArray.Length;
|
||||
for (int j = 0; j < typeArrayLength; ++j)
|
||||
{
|
||||
if (typeArray[j].Name.Equals(typeName))
|
||||
{
|
||||
return typeArray[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return type;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取程序集
|
||||
/// </summary>
|
||||
/// <param name="assemblyName">程序集名称</param>
|
||||
public static Assembly GetAssembly(string assemblyName)
|
||||
{
|
||||
return Assembly.Load(new AssemblyName(assemblyName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否布尔类型
|
||||
/// </summary>
|
||||
/// <param name="member">成员</param>
|
||||
public static bool IsBool(MemberInfo member)
|
||||
{
|
||||
if (member == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return member.MemberType switch
|
||||
{
|
||||
MemberTypes.TypeInfo => member.ToString() == "System.Boolean",
|
||||
MemberTypes.Property => IsBool((PropertyInfo)member),
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否布尔类型
|
||||
/// </summary>
|
||||
private static bool IsBool(PropertyInfo property)
|
||||
{
|
||||
return property.PropertyType == typeof(bool) || property.PropertyType == typeof(bool?);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否枚举类型
|
||||
/// </summary>
|
||||
/// <param name="member">成员</param>
|
||||
public static bool IsEnum(MemberInfo member)
|
||||
{
|
||||
if (member == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return member.MemberType switch
|
||||
{
|
||||
MemberTypes.TypeInfo => ((TypeInfo)member).IsEnum,
|
||||
MemberTypes.Property => IsEnum((PropertyInfo)member),
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否枚举类型
|
||||
/// </summary>
|
||||
private static bool IsEnum(PropertyInfo property)
|
||||
{
|
||||
if (property.PropertyType.GetTypeInfo().IsEnum)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Type value = Nullable.GetUnderlyingType(property.PropertyType);
|
||||
if (value == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return value.GetTypeInfo().IsEnum;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否日期类型
|
||||
/// </summary>
|
||||
/// <param name="member">成员</param>
|
||||
public static bool IsDate(MemberInfo member)
|
||||
{
|
||||
if (member == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return member.MemberType switch
|
||||
{
|
||||
MemberTypes.TypeInfo => member.ToString() == "System.DateTime",
|
||||
MemberTypes.Property => IsDate((PropertyInfo)member),
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否日期类型
|
||||
/// </summary>
|
||||
private static bool IsDate(PropertyInfo property)
|
||||
{
|
||||
if (property.PropertyType == typeof(DateTime))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (property.PropertyType == typeof(DateTime?))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否整型
|
||||
/// </summary>
|
||||
/// <param name="member">成员</param>
|
||||
public static bool IsInt(MemberInfo member)
|
||||
{
|
||||
if (member == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return member.MemberType switch
|
||||
{
|
||||
MemberTypes.TypeInfo => member.ToString() is "System.Int32" or "System.Int16" or "System.Int64",
|
||||
MemberTypes.Property => IsInt((PropertyInfo)member),
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否整型
|
||||
/// </summary>
|
||||
private static bool IsInt(PropertyInfo property)
|
||||
{
|
||||
if (property.PropertyType == typeof(int))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (property.PropertyType == typeof(int?))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (property.PropertyType == typeof(short))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (property.PropertyType == typeof(short?))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (property.PropertyType == typeof(long))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (property.PropertyType == typeof(long?))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否数值类型
|
||||
/// </summary>
|
||||
/// <param name="member">成员</param>
|
||||
public static bool IsNumber(MemberInfo member)
|
||||
{
|
||||
if (member == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsInt(member))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return member.MemberType switch
|
||||
{
|
||||
MemberTypes.TypeInfo => member.ToString() is "System.Double" or "System.Decimal" or "System.Single",
|
||||
MemberTypes.Property => IsNumber((PropertyInfo)member),
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否数值类型
|
||||
/// </summary>
|
||||
private static bool IsNumber(PropertyInfo property)
|
||||
{
|
||||
if (property.PropertyType == typeof(double))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (property.PropertyType == typeof(double?))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (property.PropertyType == typeof(decimal))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (property.PropertyType == typeof(decimal?))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (property.PropertyType == typeof(float))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (property.PropertyType == typeof(float?))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否集合
|
||||
/// </summary>
|
||||
/// <param name="type">类型</param>
|
||||
public static bool IsCollection(Type type)
|
||||
{
|
||||
if (type.IsArray)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return IsGenericCollection(type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否泛型集合
|
||||
/// </summary>
|
||||
/// <param name="type">类型</param>
|
||||
public static bool IsGenericCollection(Type type)
|
||||
{
|
||||
if (!type.IsGenericType)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Type typeDefinition = type.GetGenericTypeDefinition();
|
||||
return typeDefinition == typeof(IEnumerable<>)
|
||||
|| typeDefinition == typeof(IReadOnlyCollection<>)
|
||||
|| typeDefinition == typeof(IReadOnlyList<>)
|
||||
|| typeDefinition == typeof(ICollection<>)
|
||||
|| typeDefinition == typeof(IList<>)
|
||||
|| typeDefinition == typeof(List<>);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从目录中获取所有程序集
|
||||
/// </summary>
|
||||
/// <param name="directoryPath">目录绝对路径</param>
|
||||
public static List<Assembly> GetAssemblies(string directoryPath)
|
||||
{
|
||||
return Directory.GetFiles(directoryPath, "*.*", SearchOption.AllDirectories).ToList()
|
||||
.Where(t => t.EndsWith(".exe") || t.EndsWith(".dll"))
|
||||
.Select(path => Assembly.Load(new AssemblyName(path))).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取公共属性列表
|
||||
/// </summary>
|
||||
/// <param name="instance">实例</param>
|
||||
public static List<CommonItem> GetPublicProperties(object instance)
|
||||
{
|
||||
PropertyInfo[] properties = instance.GetType().GetProperties();
|
||||
return properties.ToList().Select(t => new CommonItem(t.Name, t.GetValue(instance))).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取顶级基类
|
||||
/// </summary>
|
||||
/// <typeparam name="T">类型</typeparam>
|
||||
public static Type GetTopBaseType<T>()
|
||||
{
|
||||
return GetTopBaseType(typeof(T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取顶级基类
|
||||
/// </summary>
|
||||
/// <param name="type">类型</param>
|
||||
public static Type GetTopBaseType(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (type.IsInterface)
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
if (type.BaseType == typeof(object))
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
return GetTopBaseType(type.BaseType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取元素类型,如果是集合,返回集合的元素类型
|
||||
/// </summary>
|
||||
/// <param name="type">类型</param>
|
||||
public static Type GetElementType(Type type)
|
||||
{
|
||||
if (IsCollection(type) == false)
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
if (type.IsArray)
|
||||
{
|
||||
return type.GetElementType();
|
||||
}
|
||||
|
||||
Type[] genericArgumentsTypes = type.GetTypeInfo().GetGenericArguments();
|
||||
if (genericArgumentsTypes == null || genericArgumentsTypes.Length == 0)
|
||||
{
|
||||
throw new ArgumentException("泛型类型参数不能为空");
|
||||
}
|
||||
|
||||
return genericArgumentsTypes[0];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace MAX.Core.Helpers;
|
||||
|
||||
public class UriHelper
|
||||
{
|
||||
#region 对外公开方法
|
||||
/// <summary>
|
||||
/// 带有前缀的域名
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetSchemeDomain(string url)
|
||||
{
|
||||
Uri uri = new(url);
|
||||
return $"{uri.Scheme}://{uri.Authority}";
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取域名
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetDomain(string url)
|
||||
{
|
||||
Uri uri = new(url);
|
||||
return uri.Host;
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取 URL
|
||||
/// </summary>
|
||||
/// <param name="url">URL 地址</param>
|
||||
/// <returns></returns>
|
||||
public static string GetUrl(string url)
|
||||
{
|
||||
Uri uri = new(url);
|
||||
return uri.AbsolutePath;
|
||||
}
|
||||
/// <summary>
|
||||
/// URL 解码
|
||||
/// </summary>
|
||||
/// <param name="url">URL 地址</param>
|
||||
/// <returns></returns>
|
||||
public static string UrlDecode(string url)
|
||||
{
|
||||
return System.Web.HttpUtility.UrlDecode(url);
|
||||
}
|
||||
/// <summary>
|
||||
/// URL 解码
|
||||
/// </summary>
|
||||
/// <param name="url">URL 地址</param>
|
||||
/// <param name="encoding">编码格式</param>
|
||||
/// <returns></returns>
|
||||
public static string UrlDecode(string url, Encoding encoding)
|
||||
{
|
||||
return System.Web.HttpUtility.UrlDecode(url, encoding);
|
||||
}
|
||||
/// <summary>
|
||||
/// URL 编码
|
||||
/// </summary>
|
||||
/// <param name="url">URL 地址</param>
|
||||
/// <returns></returns>
|
||||
public static string UrlEncode(string url)
|
||||
{
|
||||
return System.Web.HttpUtility.UrlEncode(url);
|
||||
}
|
||||
/// <summary>
|
||||
/// URL 编码
|
||||
/// </summary>
|
||||
/// <param name="url">URL 地址</param>
|
||||
/// <param name="encoding">编码格式</param>
|
||||
/// <returns></returns>
|
||||
public static string UrlEncode(string url, Encoding encoding)
|
||||
{
|
||||
return System.Web.HttpUtility.UrlEncode(url, encoding);
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取参数列表
|
||||
/// </summary>
|
||||
/// <param name="url">Url 地址</param>
|
||||
/// <returns></returns>
|
||||
public static List<string> GetQueryList(string url)
|
||||
{
|
||||
return GetQueryList(url, Encoding.UTF8);
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取参数列表
|
||||
/// </summary>
|
||||
/// <param name="url">Url 地址</param>
|
||||
/// <param name="encoding">编码格式</param>
|
||||
/// <returns></returns>
|
||||
public static List<string> GetQueryList(string url, Encoding encoding)
|
||||
{
|
||||
Uri uri = new(url);
|
||||
string query = uri.PathAndQuery;
|
||||
if (query.IndexOf(".") > 0)
|
||||
{
|
||||
query = query.Substring(0, query.IndexOf("."));
|
||||
}
|
||||
|
||||
List<string> dataList = [];
|
||||
string[] queryDataList = query.Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (queryDataList != null && queryDataList.Length > 0)
|
||||
{
|
||||
foreach (string queryData in queryDataList)
|
||||
{
|
||||
dataList.Add(System.Web.HttpUtility.UrlDecode(queryData, encoding));
|
||||
}
|
||||
}
|
||||
return dataList;
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取参数字典
|
||||
/// </summary>
|
||||
/// <param name="url">Url 地址</param>
|
||||
/// <returns></returns>
|
||||
public static Dictionary<string, string> GetQueryDict(string url)
|
||||
{
|
||||
return GetQueryDict(url, Encoding.UTF8);
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取参数字典
|
||||
/// </summary>
|
||||
/// <param name="url">Url 地址</param>
|
||||
/// <param name="encoding">编码格式</param>
|
||||
/// <returns></returns>
|
||||
public static Dictionary<string, string> GetQueryDict(string url, Encoding encoding)
|
||||
{
|
||||
Uri uri = new(url);
|
||||
string query = uri.Query.TrimStart(new char[] { '?' });
|
||||
|
||||
Dictionary<string, string> dataDict = [];
|
||||
string[] queryDataList = query.Split(new string[] { "&" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (queryDataList != null && queryDataList.Length > 0)
|
||||
{
|
||||
foreach (string queryData in queryDataList)
|
||||
{
|
||||
string[] keyValue = queryData.Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (!dataDict.ContainsKey(keyValue[0]))
|
||||
{
|
||||
dataDict.Add(keyValue[0].ToLower(), System.Web.HttpUtility.UrlDecode(keyValue[1], encoding));
|
||||
}
|
||||
}
|
||||
}
|
||||
return dataDict;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
|
||||
using Autofac;
|
||||
using MAX.Core.Autofac;
|
||||
using MAX.Core.DependencyInjection;
|
||||
using MAX.Core.Helpers;
|
||||
using MAX.Core.Infrastructure;
|
||||
using MAX.Core.Reflections;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace LittleCow.Core.Infrastructure
|
||||
{
|
||||
public class Bootstrap
|
||||
{
|
||||
public static void Builder()
|
||||
{
|
||||
var Builder = new ContainerBuilder();
|
||||
Assembly[] assemblies = AppTypeFinder.Assemblies.ToArray();
|
||||
// Make sure any not specifically registered concrete type can resolve.
|
||||
IEnumerable<IStartup> startupList = ReflectionHelper.GetInstancesByInterface<IStartup>(assemblies);
|
||||
int index = 1;
|
||||
foreach (IStartup item in startupList.OrderByDescending(a => a.Priority))
|
||||
{
|
||||
Debug.WriteLine($"Startup - {index++} : {item.GetType()}");
|
||||
item.Initialize();
|
||||
}
|
||||
// Make sure any not specifically registered concrete type can resolve.
|
||||
IEnumerable<IDependencyRegistrar> ListDependency = ReflectionHelper.GetInstancesByInterface<IDependencyRegistrar>(assemblies);
|
||||
foreach (IDependencyRegistrar item in ListDependency)
|
||||
{
|
||||
item.Register(Builder);
|
||||
}
|
||||
IocManager.SetContainer(Builder.Build());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using MAX.Core.Autofac;
|
||||
using MAX.Core.DependencyInjection;
|
||||
|
||||
namespace MAX.Core.Infrastructure;
|
||||
|
||||
/// <summary>
|
||||
/// 启动器:实现 <see cref="IDependencyRegistrar"/>,由宿主项目统一发现并按 <see cref="Priority"/> 排序执行。
|
||||
/// </summary>
|
||||
public interface IStartup : IDependencyRegistrar, IPriority
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
/// </summary>
|
||||
void Initialize();
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace MAX.Core.Infrastructure;
|
||||
|
||||
/// <summary>
|
||||
/// 单例,需要在当前类中定义
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class SingleInstance<T> where T : class
|
||||
{
|
||||
private static readonly object lockObj = new();
|
||||
private static T mySelf;//= default(T);
|
||||
public static T Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (lockObj)
|
||||
{
|
||||
mySelf ??= InstanceCreator.CreateInstance<T>();
|
||||
}
|
||||
|
||||
return mySelf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class InstanceCreator
|
||||
{
|
||||
public static T CreateInstance<T>()
|
||||
{
|
||||
Type type = typeof(T);
|
||||
try
|
||||
{
|
||||
return (T)type.Assembly.CreateInstance(type.FullName, true, BindingFlags.NonPublic | BindingFlags.Instance, null, null, null, null);
|
||||
}
|
||||
catch (MissingMethodException ex)
|
||||
{
|
||||
throw new Exception($"{ex.Message}\n(单例模式下,构造函数必须为 private)");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
namespace MAX.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 优先级(优先级越高越先执行)
|
||||
/// </summary>
|
||||
public interface IPriority
|
||||
{
|
||||
/// <summary>
|
||||
/// 优先级(优先级越高越先执行)
|
||||
/// </summary>
|
||||
int Priority { get; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 优先级
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// </remarks>
|
||||
public static class IntPriority
|
||||
{
|
||||
/// <summary>
|
||||
/// 最高优先级 (5000)
|
||||
/// </summary>
|
||||
public const int Highest = 5000;
|
||||
|
||||
/// <summary>
|
||||
/// 非常高优先级 (4000)
|
||||
/// </summary>
|
||||
public const int VeryHigh = 4000;
|
||||
|
||||
/// <summary>
|
||||
/// 较高优先级 (3000)
|
||||
/// </summary>
|
||||
public const int Higher = 3000;
|
||||
|
||||
/// <summary>
|
||||
/// 高优先级 (2000)
|
||||
/// </summary>
|
||||
public const int High = 2000;
|
||||
|
||||
/// <summary>
|
||||
/// 高于正常优先级 (1000)
|
||||
/// </summary>
|
||||
public const int AboveNormal = 1000;
|
||||
|
||||
/// <summary>
|
||||
/// 正常优先级 (0)
|
||||
/// </summary>
|
||||
public const int Normal = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 低于正常优先级 (-1000)
|
||||
/// </summary>
|
||||
public const int BelowNormal = -1000;
|
||||
|
||||
/// <summary>
|
||||
/// 低优先级 (-2000)
|
||||
/// </summary>
|
||||
public const int Low = -2000;
|
||||
|
||||
/// <summary>
|
||||
/// 较低优先级 (-3000)
|
||||
/// </summary>
|
||||
public const int Lower = -3000;
|
||||
|
||||
/// <summary>
|
||||
/// 非常低优先级 (-4000)
|
||||
/// </summary>
|
||||
public const int VeryLow = -4000;
|
||||
|
||||
/// <summary>
|
||||
/// 最低优先级 (-5000)
|
||||
/// </summary>
|
||||
public const int Lowest = -5000;
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
|
||||
namespace MAX.Core.Logger;
|
||||
|
||||
/// <summary>
|
||||
/// Implementation of <see cref="ILoggerBase"/> that logs into a <see cref="TextWriter"/>.
|
||||
/// </summary>
|
||||
public class ConsoleLogger : ILoggerFacade
|
||||
{
|
||||
private readonly bool _debug;
|
||||
private readonly bool _console;
|
||||
|
||||
public bool IsDebugEnabled => true;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="ConsoleLogger"/> that writes to
|
||||
/// the console output.
|
||||
/// </summary>
|
||||
public ConsoleLogger(bool debug = true, bool console = true)
|
||||
{
|
||||
_debug = debug;
|
||||
_console = console;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///// <summary>
|
||||
///// Disposes the associated <see cref="TextWriter"/>.
|
||||
///// </summary>
|
||||
///// <param name="disposing">When <see langword="true"/>, disposes the associated <see cref="TextWriter"/>.</param>
|
||||
//protected virtual void Dispose(bool disposing)
|
||||
//{
|
||||
// if (disposing)
|
||||
// {
|
||||
// writer?.Dispose();
|
||||
// }
|
||||
//}
|
||||
|
||||
///<summary>
|
||||
///Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||
///</summary>
|
||||
/// <remarks>Calls <see cref="Dispose(bool)"/></remarks>.
|
||||
///<filterpriority>2</filterpriority>
|
||||
public void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
public void Debug(Exception ex, string message)
|
||||
{
|
||||
Log(message, LogLevel.Debug);
|
||||
}
|
||||
|
||||
public void Debug(string message)
|
||||
{
|
||||
Log(message, LogLevel.Debug);
|
||||
}
|
||||
|
||||
public void Info(Exception ex, string message)
|
||||
{
|
||||
Log(message, LogLevel.Info);
|
||||
}
|
||||
|
||||
public void Info(string message)
|
||||
{
|
||||
Log(message, LogLevel.Info);
|
||||
}
|
||||
|
||||
public void Warn(Exception ex, string message)
|
||||
{
|
||||
Log(message, LogLevel.Warn);
|
||||
}
|
||||
|
||||
public void Warn(string message)
|
||||
{
|
||||
Log(message, LogLevel.Warn);
|
||||
}
|
||||
|
||||
public void Error(Exception ex, string message)
|
||||
{
|
||||
Log(message, LogLevel.Error);
|
||||
}
|
||||
|
||||
public void Error(string message)
|
||||
{
|
||||
Log(message, LogLevel.Error);
|
||||
}
|
||||
|
||||
public void Fatal(Exception ex, string message)
|
||||
{
|
||||
Log(message, LogLevel.Fatal);
|
||||
}
|
||||
|
||||
public void Fatal(string message)
|
||||
{
|
||||
Log(message, LogLevel.Fatal);
|
||||
}
|
||||
|
||||
public void Error(Exception ex)
|
||||
{
|
||||
Log(ex.Message, LogLevel.Error);
|
||||
}
|
||||
|
||||
public void Log(string message, LogLevel level)
|
||||
{
|
||||
string messageToLog = string.Format(CultureInfo.InvariantCulture, "{1}: {2}. Timestamp:{0:u}.", DateTime.Now,
|
||||
level.ToString().ToUpper(CultureInfo.InvariantCulture), message);
|
||||
//Trace.WriteLine(messageToLog);
|
||||
if (_debug)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(messageToLog);
|
||||
}
|
||||
if (_console)
|
||||
{
|
||||
Console.WriteLine(messageToLog);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using MAX.Core.Infrastructure;
|
||||
|
||||
namespace MAX.Core.Logger;
|
||||
|
||||
/// <summary>自定义日志记录器接口</summary>
|
||||
public interface ICustomLogger
|
||||
{
|
||||
/// <summary>记录日志信息</summary>
|
||||
/// <param name="group">日志分组</param>
|
||||
/// <param name="message">日志内容</param>
|
||||
void Log(string group, string message);
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
|
||||
namespace MAX.Core.Logger;
|
||||
|
||||
/// <summary>
|
||||
/// 日志操作
|
||||
/// </summary>
|
||||
public interface ILoggerFacade
|
||||
{
|
||||
/// <summary>
|
||||
/// 调试级别是否启用
|
||||
/// </summary>
|
||||
bool IsDebugEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 调试
|
||||
/// </summary>
|
||||
void Debug(Exception ex, string message);
|
||||
/// <summary>
|
||||
/// 调试
|
||||
/// </summary>
|
||||
/// <param name="message">日志消息</param>
|
||||
void Debug(string message);
|
||||
/// <summary>
|
||||
/// 信息
|
||||
/// </summary>
|
||||
void Info(Exception ex, string message);
|
||||
/// <summary>
|
||||
/// 信息
|
||||
/// </summary>
|
||||
/// <param name="message">日志消息</param>
|
||||
void Info(string message);
|
||||
/// <summary>
|
||||
/// 警告
|
||||
/// </summary>
|
||||
void Warn(Exception ex, string message);
|
||||
/// <summary>
|
||||
/// 警告
|
||||
/// </summary>
|
||||
/// <param name="message">日志消息</param>
|
||||
void Warn(string message);
|
||||
/// <summary>
|
||||
/// 错误
|
||||
/// </summary>
|
||||
void Error(Exception ex, string message);
|
||||
/// <summary>
|
||||
/// 错误
|
||||
/// </summary>
|
||||
/// <param name="message">日志消息</param>
|
||||
void Error(string message);
|
||||
/// <summary>
|
||||
/// 致命错误
|
||||
/// </summary>
|
||||
void Fatal(Exception ex, string message);
|
||||
/// <summary>
|
||||
/// 致命错误
|
||||
/// </summary>
|
||||
/// <param name="message">日志消息</param>
|
||||
void Fatal(string message);
|
||||
void Error(Exception ex);
|
||||
|
||||
/// <summary>
|
||||
/// 写入日志
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="level"></param>
|
||||
void Log(string message, LogLevel level);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace MAX.Core.Logger;
|
||||
|
||||
/// <summary>
|
||||
/// 日志等级
|
||||
/// </summary>
|
||||
public enum LogLevel
|
||||
{
|
||||
Trace = 0,
|
||||
Debug = 1,
|
||||
Info = 2,
|
||||
Warn = 3,
|
||||
Error = 4,
|
||||
Fatal = 5,
|
||||
None = 6
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MediatR" Version="9.0.0" />
|
||||
<PackageReference Include="Autofac" Version="9.3.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Web" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,197 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace MAX.Core.Reflections;
|
||||
|
||||
public partial class AppTypeFinder : Finder
|
||||
{
|
||||
public static AppTypeFinder Instance { get; } = new AppTypeFinder();
|
||||
|
||||
/// <summary>
|
||||
/// 所有程序集
|
||||
/// </summary>
|
||||
public static List<Assembly> Assemblies => Instance.GetAssemblies();
|
||||
|
||||
public static Exception LoadDLL(string dllPath, out Assembly assembly)
|
||||
{
|
||||
return Instance.LoadAssemblyToAppDomain(dllPath, out assembly);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 程序集是否匹配
|
||||
/// </summary>
|
||||
protected override bool Match(string assemblyName)
|
||||
{
|
||||
if (base.Match(assemblyName))
|
||||
{
|
||||
if (AvailablePrefix().Exists(assemblyName.StartsWith))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return Regex.IsMatch(assemblyName, "^(MAX\\.)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
protected virtual List<string> AvailablePrefix()
|
||||
{
|
||||
return ["MAX.", "Store."];
|
||||
}
|
||||
|
||||
public static IEnumerable<Type> GetAllTypes()
|
||||
{
|
||||
List<Type> types = [];
|
||||
foreach (Assembly item in Assemblies)
|
||||
{
|
||||
try
|
||||
{
|
||||
types.AddRange(item.GetTypes());
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找当前程序集中所有继承或实现了指定类型的非抽象类。
|
||||
/// </summary>
|
||||
/// <param name="targetType">
|
||||
/// 要匹配的目标类型,可以是:
|
||||
/// <list type="bullet">
|
||||
/// <item><description>普通接口类型(例如 <c>IMyService</c>)</description></item>
|
||||
/// <item><description>开放泛型接口类型(例如 <c>IRepository<></c>)</description></item>
|
||||
/// <item><description>普通基类类型(例如 <c>BaseHandler</c>)</description></item>
|
||||
/// <item><description>开放泛型基类类型(例如 <c>BaseHandler<></c>)</description></item>
|
||||
/// </list>
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// 所有满足条件的具体类(非抽象类)的 <see cref="Type"/> 数组。
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// 当 <paramref name="targetType"/> 为 <c>null</c> 时抛出。
|
||||
/// </exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// 此方法会遍历 <c>GetAllTypes()</c> 返回的所有类型,并筛选出:
|
||||
/// <list type="bullet">
|
||||
/// <item><description>实现了指定接口的类(包括开放泛型接口的封闭实现)</description></item>
|
||||
/// <item><description>继承了指定基类的类(包括开放泛型基类的封闭实现)</description></item>
|
||||
/// </list>
|
||||
/// </para>
|
||||
/// <para>示例:</para>
|
||||
/// <code>
|
||||
/// // 查找所有实现了 IEnumDisplayHandler<T> 的类
|
||||
/// var handlers = FindAllDerivedTypes(typeof(IEnumDisplayHandler<>));
|
||||
///
|
||||
/// // 查找所有实现了 IMyService 的类
|
||||
/// var services = FindAllDerivedTypes(typeof(IMyService));
|
||||
///
|
||||
/// // 查找所有继承 BaseHandler 的类
|
||||
/// var subclasses = FindAllDerivedTypes(typeof(BaseHandler));
|
||||
///
|
||||
/// // 查找所有继承开放泛型基类 BaseHandler<T> 的类
|
||||
/// var genericSubclasses = FindAllDerivedTypes(typeof(BaseHandler<>));
|
||||
/// </code>
|
||||
/// </remarks>
|
||||
public static Type[] FindAllDerivedTypes(Type targetType)
|
||||
{
|
||||
if (targetType == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(targetType));
|
||||
}
|
||||
|
||||
return GetAllTypes().Where(t =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!t.IsClass || t.IsAbstract)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 开放泛型接口
|
||||
if (targetType.IsInterface && targetType.IsGenericTypeDefinition)
|
||||
{
|
||||
return t.GetInterfaces().Any(i =>
|
||||
i.IsGenericType && i.GetGenericTypeDefinition() == targetType);
|
||||
}
|
||||
|
||||
// 普通接口
|
||||
if (targetType.IsInterface)
|
||||
{
|
||||
return targetType.IsAssignableFrom(t);
|
||||
}
|
||||
|
||||
// 开放泛型基类
|
||||
if (targetType.IsGenericTypeDefinition)
|
||||
{
|
||||
return IsSubclassOfRawGeneric(t, targetType);
|
||||
}
|
||||
|
||||
// 普通基类
|
||||
return targetType.IsAssignableFrom(t) && t != targetType;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查指定类型是否继承自某个开放泛型基类。
|
||||
/// </summary>
|
||||
/// <param name="type">要检查的类型。</param>
|
||||
/// <param name="generic">开放泛型基类类型,例如 <c>BaseHandler<></c>。</param>
|
||||
/// <returns>
|
||||
/// 如果 <paramref name="type"/> 的继承链中存在指定的开放泛型基类,则返回 <c>true</c>;否则返回 <c>false</c>。
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// 此方法会沿着 <paramref name="type"/> 的继承链向上遍历,
|
||||
/// 并在每一级检查是否为指定的开放泛型基类定义。
|
||||
/// </remarks>
|
||||
private static bool IsSubclassOfRawGeneric(Type type, Type generic)
|
||||
{
|
||||
while (type != null && type != typeof(object))
|
||||
{
|
||||
Type cur = type.IsGenericType ? type.GetGenericTypeDefinition() : type;
|
||||
if (generic == cur)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
type = type.BaseType;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 泛型包装方法,查找所有继承或实现了指定类型 <typeparamref name="T"/> 的非抽象类。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">
|
||||
/// 目标类型,可以是接口、开放泛型接口、基类或开放泛型基类。
|
||||
/// </typeparam>
|
||||
/// <returns>
|
||||
/// 所有满足条件的具体类(非抽象类)的 <see cref="Type"/> 数组。
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// 调用示例:
|
||||
/// <code>
|
||||
/// var handlers = FindAllDerivedTypes<IEnumDisplayHandler<>>();
|
||||
/// var services = FindAllDerivedTypes<IMyService>();
|
||||
/// var subclasses = FindAllDerivedTypes<BaseHandler>();
|
||||
/// var genericSubclasses = FindAllDerivedTypes<BaseHandler<>>();
|
||||
/// </code>
|
||||
/// </remarks>
|
||||
public static Type[] FindAllDerivedTypes<T>() => FindAllDerivedTypes(typeof(T));
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
using MAX.Core.Helpers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace MAX.Core.Reflections;
|
||||
|
||||
public class Finder
|
||||
{
|
||||
/// <summary>
|
||||
/// 跳过的程序集
|
||||
/// </summary>
|
||||
private const string SkipAssemblies = "^System|^Microsoft|^mscorlib|^netstandard|^Autofac|^AutoMapper|^EntityFramework|^Newtonsoft|^Castle|^NLog|^Pomelo|^AspectCore|^Xunit|^Nito|^Npgsql|^Exceptionless|^MySqlConnector|^Anonymously|^libuv|^api-ms|^clrcompression|^clretwrc|^clrjit|^coreclr|^dbgshim|^e_sqlite3|^hostfxr|^hostpolicy|^MessagePack|^mscordaccore|^mscordbi|^mscorrc|^sni|^sos|^SOS\\.NETCore|^sos_amd64|^SQLitePCLRaw|^StackExchange|^Swashbuckle|^WindowsBase|^ucrtbase|^DotNetCore\\.CAP|^MongoDB|^Confluent\\.Kafka|^librdkafka|^EasyCaching|^RabbitMQ|^Consul|^Dapper|^EnyimMemcachedCore|^Pipelines|^DnsClient|^IdentityModel|^zlib|^Runtime\\.|^Google|^Grpc|^Internal\\.|^Azure|^DevExpress\\.|^FreeSql\\.|^PresentationFramework|^PresentationCore|^Prism|^DirectWriteForwarder|^MAX\\.Common|^ReflectionHelperTypesPublicWrappers|^UIAutomation|^WindowsFormsIntegration";
|
||||
|
||||
/// <summary>
|
||||
/// 获取程序集列表
|
||||
/// </summary>
|
||||
public virtual List<Assembly> GetAssemblies()
|
||||
{
|
||||
LoadAssemblies(AppDomain.CurrentDomain.BaseDirectory);
|
||||
return GetAssembliesFromCurrentAppDomain();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载程序集到当前应用程序域
|
||||
/// </summary>
|
||||
/// <param name="path">目录绝对路径</param>
|
||||
protected void LoadAssemblies(string path)
|
||||
{
|
||||
foreach (string file in Directory.GetFiles(path, "*.dll"))
|
||||
{
|
||||
if (Match(Path.GetFileName(file)) == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
LoadAssemblyToAppDomain(file, out _);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 程序集是否匹配
|
||||
/// </summary>
|
||||
protected virtual bool Match(string assemblyName)
|
||||
{
|
||||
return Regex.IsMatch(assemblyName, SkipAssemblies, RegexOptions.IgnoreCase | RegexOptions.Compiled) == false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将程序集添加当前应用程序域
|
||||
/// </summary>
|
||||
protected Exception LoadAssemblyToAppDomain(string file, out Assembly assembly)
|
||||
{
|
||||
try
|
||||
{
|
||||
//Debug.WriteLine($"Load Assembly : {Path.GetFileName(file)}");
|
||||
AssemblyName assemblyName = AssemblyName.GetAssemblyName(file);
|
||||
assembly = AppDomain.CurrentDomain.Load(assemblyName);
|
||||
return null;
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
// 如果找不到文件,回退到 LoadFrom 方式
|
||||
try
|
||||
{
|
||||
assembly = Assembly.LoadFrom(file);
|
||||
return null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
assembly = null;
|
||||
return ex;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
assembly = null;
|
||||
return ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从当前应用程序域获取程序集列表
|
||||
/// </summary>
|
||||
private List<Assembly> GetAssembliesFromCurrentAppDomain()
|
||||
{
|
||||
List<Assembly> result = [];
|
||||
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
if (Match(assembly))
|
||||
{
|
||||
result.Add(assembly);
|
||||
}
|
||||
}
|
||||
return result.Distinct().ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 程序集是否匹配
|
||||
/// </summary>
|
||||
private bool Match(Assembly assembly)
|
||||
{
|
||||
return !Regex.IsMatch(assembly.FullName, SkipAssemblies, RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类型列表
|
||||
/// </summary>
|
||||
/// <typeparam name="T">查找类型</typeparam>
|
||||
/// <param name="assemblies">在指定的程序集列表中查找</param>
|
||||
public List<Type> Find<T>(List<Assembly> assemblies = null)
|
||||
{
|
||||
return Find(typeof(T), assemblies);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类型列表
|
||||
/// </summary>
|
||||
/// <param name="findType">查找类型</param>
|
||||
/// <param name="assemblies">在指定的程序集列表中查找</param>
|
||||
public List<Type> Find(Type findType, List<Assembly> assemblies = null)
|
||||
{
|
||||
assemblies ??= GetAssemblies();
|
||||
return ReflectionHelper.FindTypes(findType, assemblies.ToArray());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/***
|
||||
* _ooOoo_
|
||||
* o8888888o
|
||||
* 88" . "88
|
||||
* (| -_- |)
|
||||
* O\ = /O
|
||||
* ____/`---'\____
|
||||
* . ' \\| |// `.
|
||||
* / \\||| : |||// \
|
||||
* / _||||| -:- |||||- \
|
||||
* | | \\\ - /// | |
|
||||
* | \_| ''\---/'' | |
|
||||
* \ .-\__ `-` ___/-. /
|
||||
* ___`. .' /--.--\ `. . __
|
||||
* ."" '< `.___\_<|>_/___.' >'"".
|
||||
* | | : `- \`.;`\ _ /`;.`/ - ` : | |
|
||||
* \ \ `-. \_ __\ /__ _/ .-` / /
|
||||
* ======`-.____`-.___\_____/___.-`____.-'======
|
||||
* `=---='
|
||||
*
|
||||
* .............................................
|
||||
* 佛祖保佑 永无BUG
|
||||
* 快加工资 不改需求
|
||||
*/
|
||||
|
||||
using Autofac;
|
||||
using MAX.Core.DependencyInjection;
|
||||
using MAX.Core.Infrastructure;
|
||||
using MAX.Core.Logger;
|
||||
using MAX.Core.Reflections;
|
||||
using MediatR;
|
||||
using System.Reflection;
|
||||
|
||||
namespace MAX.Core;
|
||||
|
||||
public class Startup : IStartup
|
||||
{
|
||||
public int Priority => int.MaxValue;
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void Register(ContainerBuilder builder)
|
||||
{
|
||||
builder.RegisterInstance(new ConsoleLogger()).As<ILoggerFacade>().SingleInstance();
|
||||
|
||||
#region 注册MediatR
|
||||
Assembly[] assemblies = AppTypeFinder.Assemblies.ToArray();
|
||||
|
||||
//builder.RegisterType<MediatorManager>().As<IMediator>().AsSelf().SingleInstance();
|
||||
|
||||
builder.RegisterAssemblyTypes(assemblies)
|
||||
.AsClosedTypesOf(typeof(INotificationHandler<>))
|
||||
.AsImplementedInterfaces()
|
||||
.AsSelf()
|
||||
.InstancePerLifetimeScope();
|
||||
|
||||
builder.RegisterAssemblyTypes(assemblies)
|
||||
.AsClosedTypesOf(typeof(IRequestHandler<>))
|
||||
.AsImplementedInterfaces()
|
||||
.AsSelf()
|
||||
.InstancePerLifetimeScope();
|
||||
|
||||
builder.Register<ServiceFactory>(ctx =>
|
||||
{
|
||||
var c = ctx.Resolve<IComponentContext>();
|
||||
return t => c.Resolve(t);
|
||||
}).SingleInstance();
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System.Text;
|
||||
|
||||
namespace MAX.Framework.Commons
|
||||
{
|
||||
public struct KeyValue
|
||||
{
|
||||
public KeyValue(string key, string value)
|
||||
{
|
||||
Key = key;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public string Key { get; set; }
|
||||
public string Value { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.Append('[');
|
||||
if (Key != null)
|
||||
{
|
||||
stringBuilder.Append(Key.ToString());
|
||||
}
|
||||
|
||||
stringBuilder.Append(", ");
|
||||
if (Value != null)
|
||||
{
|
||||
stringBuilder.Append(Value.ToString());
|
||||
}
|
||||
|
||||
stringBuilder.Append(']');
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using Newtonsoft.Json;
|
||||
using ConfigHelper = MAX.Framework.Helpers.ConfigHelper;
|
||||
|
||||
namespace MAX.Framework.Configs
|
||||
{
|
||||
public abstract class ConfigBase
|
||||
{
|
||||
[JsonIgnore]
|
||||
public abstract string ConfigName { get; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置
|
||||
/// </summary>
|
||||
public abstract class ConfigBase<TConfig> : ConfigBase where TConfig : ConfigBase, new()
|
||||
{
|
||||
private static TConfig mySelf;//= default(T);
|
||||
public static TConfig Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (mySelf == null)
|
||||
{
|
||||
mySelf = new TConfig();
|
||||
}
|
||||
|
||||
return mySelf;
|
||||
}
|
||||
}
|
||||
|
||||
public static TConfig LoadConfig()
|
||||
{
|
||||
try
|
||||
{
|
||||
TConfig config = ConfigHelper.LoadConfig<TConfig>();
|
||||
mySelf = config;
|
||||
return mySelf;
|
||||
}
|
||||
catch { }
|
||||
return default;
|
||||
}
|
||||
public void SaveConfig()
|
||||
{
|
||||
ConfigHelper.SaveConfig(ConfigName, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace MAX.Framework
|
||||
{
|
||||
/// <summary>
|
||||
/// 全局配置
|
||||
/// </summary>
|
||||
public class GlobalConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据库名
|
||||
/// </summary>
|
||||
public const string DbName = "db.db";
|
||||
|
||||
/// <summary>
|
||||
/// app启动路径
|
||||
/// </summary>
|
||||
public static string AppDirectory
|
||||
{
|
||||
get
|
||||
{
|
||||
return AppDomain.CurrentDomain.BaseDirectory;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace MAX.Framework.Controls.Attach;
|
||||
|
||||
/// <summary>
|
||||
/// 弹出窗口属性值
|
||||
/// </summary>
|
||||
public class DialogWindowProperty
|
||||
{
|
||||
public static readonly DependencyProperty WindowStartupLocationProperty = DependencyProperty.RegisterAttached(
|
||||
"WindowStartupLocation", typeof(WindowStartupLocation), typeof(DialogWindowProperty), new PropertyMetadata(WindowStartupLocation.CenterScreen));
|
||||
public static void SetWindowStartupLocation(DependencyObject element, WindowStartupLocation value)
|
||||
=> element.SetValue(WindowStartupLocationProperty, value);
|
||||
public static WindowStartupLocation GetWindowStartupLocation(DependencyObject element)
|
||||
=> (WindowStartupLocation)element.GetValue(WindowStartupLocationProperty);
|
||||
|
||||
|
||||
public static readonly DependencyProperty ResizeModeProperty = DependencyProperty.RegisterAttached(
|
||||
"ResizeMode", typeof(ResizeMode), typeof(DialogWindowProperty), new PropertyMetadata(ResizeMode.CanResize));
|
||||
public static void SetResizeMode(DependencyObject element, ResizeMode value)
|
||||
=> element.SetValue(ResizeModeProperty, value);
|
||||
public static ResizeMode GetResizeMode(DependencyObject element)
|
||||
=> (ResizeMode)element.GetValue(ResizeModeProperty);
|
||||
|
||||
|
||||
|
||||
public static readonly DependencyProperty WidthProperty = DependencyProperty.RegisterAttached(
|
||||
"Width", typeof(double), typeof(DialogWindowProperty), new PropertyMetadata(double.NaN));
|
||||
public static void SetWidth(DependencyObject element, double value)
|
||||
=> element.SetValue(WidthProperty, value);
|
||||
public static double GetWidth(DependencyObject element)
|
||||
=> (double)element.GetValue(WidthProperty);
|
||||
|
||||
|
||||
|
||||
public static readonly DependencyProperty HeightProperty = DependencyProperty.RegisterAttached(
|
||||
"Height", typeof(double), typeof(DialogWindowProperty), new PropertyMetadata(double.NaN));
|
||||
public static void SetHeight(DependencyObject element, double value)
|
||||
=> element.SetValue(HeightProperty, value);
|
||||
public static double GetHeight(DependencyObject element)
|
||||
=> (double)element.GetValue(HeightProperty);
|
||||
}
|
||||
@@ -0,0 +1,290 @@
|
||||
using MAX.Core.Commons;
|
||||
using Prism.Commands;
|
||||
using Prism.Mvvm;
|
||||
using Prism.Services.Dialogs;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace MAX.Framework.Controls;
|
||||
|
||||
public static class IDialogServiceExtension
|
||||
{
|
||||
public static void ShowDialog<TParameter>(this IDialogService dialogService, string name, TParameter parameter, Action<IDialogResult> callback) where TParameter : class
|
||||
{
|
||||
dialogService.ShowDialog(name, new DialogParameters
|
||||
{
|
||||
{"parameter", parameter},
|
||||
}, callback);
|
||||
}
|
||||
public static void Show<TParameter>(this IDialogService dialogService, string name, TParameter parameter, Action<IDialogResult> callback) where TParameter : class
|
||||
{
|
||||
dialogService.Show(name, new DialogParameters
|
||||
{
|
||||
{"parameter", parameter},
|
||||
}, callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 确定取消对话框 ViewModel
|
||||
/// </summary>
|
||||
public class ConfirmDialogViewModel : BindableBase, IDialogAware
|
||||
{
|
||||
public ConfirmDialogViewModel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private string title = "";
|
||||
private bool _enableConfirm = true;
|
||||
private bool _ShowConfirm = true;
|
||||
private bool _ShowCancel = true;
|
||||
private bool _ShowErrorMsg = true;
|
||||
private string _ErrorMsg = "";
|
||||
private string confirmText = "确定";
|
||||
private string cancelText = "取消";
|
||||
private string backText = "返回";
|
||||
private bool allowEscape = true;
|
||||
private bool allowEnter = true;
|
||||
private bool isLoading = false;
|
||||
|
||||
public string Title
|
||||
{
|
||||
get => title;
|
||||
protected set => SetProperty(ref title, value);
|
||||
}
|
||||
|
||||
public bool AllowEscape
|
||||
{
|
||||
get => allowEscape;
|
||||
set => SetProperty(ref allowEscape, value);
|
||||
}
|
||||
|
||||
public bool AllowEnter
|
||||
{
|
||||
get => allowEnter;
|
||||
set => SetProperty(ref allowEnter, value);
|
||||
}
|
||||
|
||||
public bool IsLoading
|
||||
{
|
||||
get => isLoading;
|
||||
set => SetProperty(ref isLoading, value, () =>
|
||||
{
|
||||
AllowEscape = !value;
|
||||
AllowEnter = !value;
|
||||
EnableConfirm = !value;
|
||||
});
|
||||
}
|
||||
//<UserControl.Resources>
|
||||
// <SolidColorBrush x:Key="RegionBrush" Color="Red"/>
|
||||
// </UserControl.Resources>
|
||||
private SolidColorBrush _Underpaint = new SolidColorBrush(Color.FromRgb(238, 238, 238));
|
||||
/// <summary>
|
||||
/// 背景底色
|
||||
/// </summary>
|
||||
public SolidColorBrush Underpaint
|
||||
{
|
||||
get => _Underpaint;
|
||||
set => SetProperty(ref _Underpaint, value);
|
||||
}
|
||||
|
||||
public event Action<IDialogResult> RequestClose;
|
||||
protected void OnRequestClose(IDialogResult result)
|
||||
{
|
||||
RequestClose?.Invoke(result);
|
||||
}
|
||||
|
||||
public virtual bool CanCloseDialog()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void OnDialogClosed()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void OnDialogOpened(IDialogParameters parameters)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public bool EnableConfirm
|
||||
{
|
||||
get => _enableConfirm;
|
||||
set => SetProperty(ref _enableConfirm, value);
|
||||
}
|
||||
|
||||
public bool ShowConfirm
|
||||
{
|
||||
get => _ShowConfirm;
|
||||
set => SetProperty(ref _ShowConfirm, value);
|
||||
}
|
||||
public bool ShowCancel
|
||||
{
|
||||
get => _ShowCancel;
|
||||
set => SetProperty(ref _ShowCancel, value);
|
||||
}
|
||||
public bool ShowErrorMsg
|
||||
{
|
||||
get => _ShowErrorMsg;
|
||||
set => SetProperty(ref _ShowErrorMsg, value);
|
||||
}
|
||||
|
||||
public string ConfirmText
|
||||
{
|
||||
get => confirmText;
|
||||
set => SetProperty(ref confirmText, value);
|
||||
}
|
||||
public string CancelText
|
||||
{
|
||||
get => cancelText;
|
||||
set => SetProperty(ref cancelText, value);
|
||||
}
|
||||
public string BackText
|
||||
{
|
||||
get => backText;
|
||||
set => SetProperty(ref backText, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 错误提示
|
||||
/// </summary>
|
||||
public string ErrorMsg
|
||||
{
|
||||
get => _ErrorMsg;
|
||||
set => SetProperty(ref _ErrorMsg, value);
|
||||
}
|
||||
|
||||
public virtual ICommand ConfirmCommand => new DelegateCommand(_Confirm);
|
||||
|
||||
protected virtual void _Confirm()
|
||||
{
|
||||
DialogResult ret = Confirm();
|
||||
if (ret != null)
|
||||
{
|
||||
RequestClose?.Invoke(ret);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual DialogResult Confirm()
|
||||
{
|
||||
return new DialogResult(ButtonResult.OK);
|
||||
}
|
||||
|
||||
public virtual ICommand CancelCommand => new DelegateCommand(_Cancel);
|
||||
|
||||
protected virtual void _Cancel()
|
||||
{
|
||||
DialogResult ret = Cancel();
|
||||
if (ret != null)
|
||||
{
|
||||
RequestClose?.Invoke(ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
RequestClose?.Invoke(new DialogResult(ButtonResult.Cancel));
|
||||
}
|
||||
}
|
||||
protected virtual DialogResult Cancel()
|
||||
{
|
||||
return new DialogResult(ButtonResult.Cancel);
|
||||
}
|
||||
|
||||
public virtual void Loaded(object content)
|
||||
{
|
||||
var bb = Application.Current.TryFindResource("BackgroundBrush") as SolidColorBrush;
|
||||
if (bb != null)
|
||||
{
|
||||
Underpaint = bb;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class AsyncConfirmDialogViewModel : ConfirmDialogViewModel
|
||||
{
|
||||
public override ICommand ConfirmCommand => new AsyncDelegateCommand(_Confirm);
|
||||
|
||||
protected new async Task _Confirm()
|
||||
{
|
||||
DialogResult ret = await Confirm();
|
||||
if (ret != null)
|
||||
{
|
||||
OnRequestClose(ret);
|
||||
}
|
||||
}
|
||||
|
||||
protected new virtual async Task<DialogResult> Confirm()
|
||||
{
|
||||
return await Task.FromResult(new DialogResult(ButtonResult.OK));
|
||||
}
|
||||
}
|
||||
|
||||
public interface IDialogClassParameters
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
/// 确定取消对话框
|
||||
/// </summary>
|
||||
/// <typeparam name="TParameter">参数Model</typeparam>
|
||||
public class ConfirmDialogViewModel<TParameter> : ConfirmDialogViewModel where TParameter : class
|
||||
{
|
||||
protected TParameter Args { get; set; }
|
||||
public override void OnDialogOpened(IDialogParameters parameters)
|
||||
{
|
||||
base.OnDialogOpened(parameters);
|
||||
if (parameters.TryGetValue("parameter", out TParameter parameter))
|
||||
{
|
||||
Args = parameter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class ConfirmDialogViewModel<TParameter, TResult> : ConfirmDialogViewModel where TParameter : class where TResult : DialogResult/*, new()*/
|
||||
{
|
||||
protected TParameter Args { get; set; }
|
||||
public override void OnDialogOpened(IDialogParameters parameters)
|
||||
{
|
||||
base.OnDialogOpened(parameters);
|
||||
if (parameters.TryGetValue("parameter", out TParameter parameter))
|
||||
{
|
||||
Args = parameter;
|
||||
}
|
||||
}
|
||||
protected override void _Confirm()
|
||||
{
|
||||
TResult ret = Confirm();
|
||||
if (ret != null)
|
||||
{
|
||||
base.OnRequestClose(ret);
|
||||
}
|
||||
}
|
||||
protected new abstract TResult Confirm();
|
||||
|
||||
protected override void _Cancel()
|
||||
{
|
||||
TResult ret = Cancel();
|
||||
if (ret != null)
|
||||
{
|
||||
base.OnRequestClose(ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
base.OnRequestClose(new DialogResult(ButtonResult.Cancel));
|
||||
}
|
||||
}
|
||||
protected new abstract TResult Cancel();
|
||||
}
|
||||
|
||||
|
||||
//public abstract class ConfirmDialogParameterViewModel : ConfirmDialogViewModel<ConfirmDialogParameterViewModel.Parameter>
|
||||
//{
|
||||
// public abstract class Parameter;
|
||||
//}
|
||||
@@ -0,0 +1,93 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace MAX.Framework.Extensions;
|
||||
|
||||
public static class StyleExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 合并指定的 <see cref="Style"/>。
|
||||
/// </summary>
|
||||
/// <param name="style1"></param>
|
||||
/// <param name="style2"></param>
|
||||
public static void Merge(this Style style1, Style style2)
|
||||
{
|
||||
if (style1 == null)
|
||||
{
|
||||
throw new ArgumentNullException("style1");
|
||||
}
|
||||
if (style2 == null)
|
||||
{
|
||||
throw new ArgumentNullException("style2");
|
||||
}
|
||||
|
||||
if (style1.TargetType.IsAssignableFrom(style2.TargetType))
|
||||
{
|
||||
style1.TargetType = style2.TargetType;
|
||||
}
|
||||
|
||||
if (style2.BasedOn != null)
|
||||
{
|
||||
style1.Merge(style2.BasedOn);
|
||||
}
|
||||
|
||||
foreach (SetterBase currentSetter in style2.Setters)
|
||||
{
|
||||
style1.Setters.Add(currentSetter);
|
||||
}
|
||||
|
||||
|
||||
foreach (TriggerBase currentTrigger in style2.Triggers)
|
||||
{
|
||||
style1.Triggers.Add(currentTrigger);
|
||||
}
|
||||
|
||||
// This code is only needed when using DynamicResources.
|
||||
foreach (object key in style2.Resources.Keys)
|
||||
{
|
||||
style1.Resources[key] = style2.Resources[key];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 集合是否有值。
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="source"></param>
|
||||
/// <returns></returns>
|
||||
public static bool HasValue<T>(this IEnumerable<T> source)
|
||||
{
|
||||
return source != null && source.Any();
|
||||
}
|
||||
|
||||
public static ResourceDictionary FindResourceDictionary(this Style style, object resourceKey)
|
||||
{
|
||||
if (style.Resources != null && style.Resources.Contains(resourceKey))
|
||||
{
|
||||
return style.Resources;
|
||||
}
|
||||
if (style.BasedOn != null)
|
||||
{
|
||||
return style.BasedOn.FindResourceDictionary(resourceKey);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void Merge(this ResourceDictionary resourceDictionary, ResourceDictionary mergee)
|
||||
{
|
||||
if (resourceDictionary != null && mergee != null && mergee.Count > 0)
|
||||
{
|
||||
foreach (var key in mergee.Keys)
|
||||
{
|
||||
if (!resourceDictionary.Contains(key))
|
||||
{
|
||||
resourceDictionary.Add(key, mergee[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using MAX.Core.DependencyInjection;
|
||||
using MAX.Framework.Configs;
|
||||
using MAX.Framework.Interfaces;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace MAX.Framework.Helpers
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置
|
||||
/// </summary>
|
||||
public class ConfigHelper
|
||||
{
|
||||
private static IFolderConfig _folderConfig = LazyServiceProvider.Instance.LazyGetService<IFolderConfig>();
|
||||
public static string prvategp = "4Z-zy_VP";//pIuEFX-0-OZm%tP2qtKw
|
||||
public static T LoadConfig<T>() where T : ConfigBase
|
||||
{
|
||||
string filename = Activator.CreateInstance<T>().ConfigName;
|
||||
return LoadConfig<T>(filename);
|
||||
}
|
||||
|
||||
public static T LoadConfig<T>(string fileName) where T : ConfigBase
|
||||
{
|
||||
try
|
||||
{
|
||||
string filePath = GetConfigUserPath(fileName);
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
string content = File.ReadAllText(filePath, Encoding.UTF8);
|
||||
return JsonConvert.DeserializeObject<T>(content);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
return default;
|
||||
}
|
||||
|
||||
public static void SaveConfig<T>(T config) where T : ConfigBase
|
||||
{
|
||||
string filename = Activator.CreateInstance<T>().ConfigName;
|
||||
SaveConfig(filename, config);
|
||||
}
|
||||
|
||||
public static void SaveConfig<T>(string fileName, T config) where T : ConfigBase
|
||||
{
|
||||
try
|
||||
{
|
||||
string filePath = GetConfigUserPath(fileName);
|
||||
FileHelper.CreateDirectory(filePath);
|
||||
string content = JsonConvert.SerializeObject(config);
|
||||
File.WriteAllText(filePath, content, Encoding.UTF8);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
public static void SaveConfig(string fileName, string content)
|
||||
{
|
||||
try
|
||||
{
|
||||
string filePath = GetConfigUserPath(fileName);
|
||||
FileHelper.CreateDirectory(filePath);
|
||||
File.WriteAllText(filePath, content, Encoding.UTF8);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
public static string GetConfigUserPath(string fileName)
|
||||
{
|
||||
string filePath = Path.Combine(_folderConfig.LocalAppFolder, "config", fileName);
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace MAX.Framework.Helpers
|
||||
{
|
||||
/// <summary>
|
||||
/// 文件操作帮助类
|
||||
/// </summary>
|
||||
public class FileHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取文件MD5值
|
||||
/// </summary>
|
||||
/// <param name="FilePath"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetFileMd5(string FilePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
FileStream get_file = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
System.Security.Cryptography.MD5CryptoServiceProvider get_md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
|
||||
byte[] hash_byte = get_md5.ComputeHash(get_file);
|
||||
string resule = BitConverter.ToString(hash_byte);
|
||||
resule = resule.Replace("-", "");
|
||||
get_file.Close();
|
||||
return resule;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return e.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取所有内容 相对路径Or绝对路径
|
||||
/// </summary>
|
||||
/// <param name="file"></param>
|
||||
/// <returns></returns>
|
||||
public static string ReadAllText(string file)
|
||||
{
|
||||
if (!Path.IsPathRooted(file))
|
||||
{
|
||||
file = Path.Combine(GlobalConfig.AppDirectory, file);
|
||||
}
|
||||
if (File.Exists(file))
|
||||
{
|
||||
return _ReadAllText(file, Encoding.UTF8);
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
/// <summary>
|
||||
/// 读取所有内容 绝对路径
|
||||
/// </summary>
|
||||
/// <param name="file"></param>
|
||||
/// <returns></returns>
|
||||
public static string ReadAbsAllText(string file)
|
||||
{
|
||||
return _ReadAllText(file, Encoding.UTF8);
|
||||
}
|
||||
/// <summary>
|
||||
/// 读取所有内容 相对路径
|
||||
/// </summary>
|
||||
/// <param name="file"></param>
|
||||
/// <returns></returns>
|
||||
public static string ReadPartialAllText(string file)
|
||||
{
|
||||
string _file = Path.Combine(GlobalConfig.AppDirectory, file);
|
||||
return _ReadAllText(_file, Encoding.UTF8);
|
||||
}
|
||||
|
||||
private static string _ReadAllText(string file, Encoding encoding)
|
||||
{
|
||||
if (File.Exists(file))
|
||||
{
|
||||
return File.ReadAllText(file, encoding);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"缺失文件{file}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建目录
|
||||
/// </summary>
|
||||
/// <param name="dir"></param>
|
||||
public static void CreateDirectory(string dir)
|
||||
{
|
||||
if (Path.HasExtension(dir))
|
||||
{
|
||||
dir = Path.GetDirectoryName(dir);
|
||||
}
|
||||
if (!Directory.Exists(dir))
|
||||
{
|
||||
Directory.CreateDirectory(dir);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool DeleteDirectory(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.Delete(path, true);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void CopyDirectory(string sourceDir, string destinationDir, bool recursive = true)
|
||||
{
|
||||
// Get information about the source directory
|
||||
DirectoryInfo dir = new DirectoryInfo(sourceDir);
|
||||
|
||||
// Check if the source directory exists
|
||||
if (!dir.Exists)
|
||||
{
|
||||
throw new DirectoryNotFoundException($"Source directory not found: {dir.FullName}");
|
||||
}
|
||||
|
||||
// Cache directories before we start copying
|
||||
DirectoryInfo[] dirs = dir.GetDirectories();
|
||||
|
||||
// Create the destination directory
|
||||
Directory.CreateDirectory(destinationDir);
|
||||
|
||||
// Get the files in the source directory and copy to the destination directory
|
||||
foreach (FileInfo file in dir.GetFiles())
|
||||
{
|
||||
string targetFilePath = Path.Combine(destinationDir, file.Name);
|
||||
file.CopyTo(targetFilePath);
|
||||
}
|
||||
|
||||
// If recursive and copying subdirectories, recursively call this method
|
||||
if (recursive)
|
||||
{
|
||||
foreach (DirectoryInfo subDir in dirs)
|
||||
{
|
||||
string newDestinationDir = Path.Combine(destinationDir, subDir.Name);
|
||||
CopyDirectory(subDir.FullName, newDestinationDir, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取文件夹大小
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
public static long GetDirectorySize(string path)
|
||||
{
|
||||
long result = 0;
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
dynamic fso = Activator.CreateInstance(Type.GetTypeFromProgID("Scripting.FileSystemObject"));
|
||||
dynamic fldr = fso.GetFolder(path);
|
||||
result = (long)fldr.size;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace MAX.Framework.Helpers
|
||||
{
|
||||
public static class ObjectHelper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, PropertyInfo> CachedObjectProperties =
|
||||
new ConcurrentDictionary<string, PropertyInfo>();
|
||||
|
||||
public static void TrySetProperty<TObject, TValue>(
|
||||
TObject obj,
|
||||
Expression<Func<TObject, TValue>> propertySelector,
|
||||
Func<TValue> valueFactory,
|
||||
params Type[] ignoreAttributeTypes
|
||||
)
|
||||
{
|
||||
TrySetProperty(obj, propertySelector, x => valueFactory(), ignoreAttributeTypes);
|
||||
}
|
||||
|
||||
public static void TrySetProperty<TObject, TValue>(
|
||||
TObject obj,
|
||||
Expression<Func<TObject, TValue>> propertySelector,
|
||||
Func<TObject, TValue> valueFactory,
|
||||
params Type[] ignoreAttributeTypes
|
||||
)
|
||||
{
|
||||
string cacheKey =
|
||||
$"{obj?.GetType().FullName}-"
|
||||
+ $"{propertySelector}-"
|
||||
+ $"{(ignoreAttributeTypes != null ? "-" + string.Join("-", ignoreAttributeTypes.Select(x => x.FullName)) : "")}";
|
||||
|
||||
PropertyInfo property = CachedObjectProperties.GetOrAdd(
|
||||
cacheKey,
|
||||
(name) =>
|
||||
{
|
||||
if (propertySelector.Body.NodeType != ExpressionType.MemberAccess)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
MemberExpression memberExpression = (MemberExpression)propertySelector.Body;
|
||||
|
||||
PropertyInfo propertyInfo = obj?.GetType()
|
||||
.GetProperties()
|
||||
.FirstOrDefault(
|
||||
x =>
|
||||
x.Name == memberExpression.Member.Name
|
||||
&& x.GetSetMethod(true) != null
|
||||
);
|
||||
|
||||
if (propertyInfo == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (
|
||||
ignoreAttributeTypes != null
|
||||
&& ignoreAttributeTypes.Any(
|
||||
ignoreAttribute => propertyInfo.IsDefined(ignoreAttribute, true)
|
||||
)
|
||||
)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return propertyInfo;
|
||||
}
|
||||
);
|
||||
|
||||
property?.SetValue(obj, valueFactory(obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MAX.Framework.Helpers;
|
||||
public class StringTypeHelper
|
||||
{
|
||||
public static object ConvertToObject(string input, out Type type)
|
||||
{
|
||||
type = typeof(string);
|
||||
object value = input;
|
||||
|
||||
// 1. 检查布尔值(支持多种表示形式)
|
||||
if (IsBoolean(input, out bool boolValue))
|
||||
{
|
||||
type = typeof(bool);
|
||||
value = boolValue;
|
||||
return value;
|
||||
}
|
||||
|
||||
// 2. 检查整数
|
||||
if (int.TryParse(input, NumberStyles.Integer, CultureInfo.InvariantCulture, out int intValue))
|
||||
{
|
||||
type = typeof(int);
|
||||
value = intValue;
|
||||
return value;
|
||||
}
|
||||
|
||||
// 3. 检查无符号整数
|
||||
if (ulong.TryParse(input, NumberStyles.Integer, CultureInfo.InvariantCulture, out ulong ulongValue))
|
||||
{
|
||||
type = typeof(ulong);
|
||||
value = ulongValue;
|
||||
return value;
|
||||
}
|
||||
|
||||
// 4. 检查双精度浮点数
|
||||
if (double.TryParse(input, NumberStyles.Number | NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent,
|
||||
CultureInfo.InvariantCulture, out double doubleValue))
|
||||
{
|
||||
type = typeof(double);
|
||||
value = doubleValue;
|
||||
return value;
|
||||
}
|
||||
|
||||
// 5. 检查十进制数
|
||||
if (decimal.TryParse(input, NumberStyles.Number | NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent,
|
||||
CultureInfo.InvariantCulture, out decimal decimalValue))
|
||||
{
|
||||
type = typeof(decimal);
|
||||
value = decimalValue;
|
||||
return value;
|
||||
}
|
||||
|
||||
// 6. 检查日期时间
|
||||
if (IsDateTime(input, out DateTime dateTimeValue))
|
||||
{
|
||||
type = typeof(DateTime);
|
||||
value = dateTimeValue;
|
||||
return value;
|
||||
}
|
||||
|
||||
// 7. 检查null
|
||||
if (input == null)
|
||||
{
|
||||
type = typeof(string);
|
||||
value = null;
|
||||
return value;
|
||||
}
|
||||
|
||||
// 8. 默认返回字符串类型
|
||||
type = typeof(string);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
private static bool IsBoolean(string input, out bool boolValue)
|
||||
{
|
||||
boolValue = false;
|
||||
// 支持多种布尔值表示形式
|
||||
if (input.Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase) ||
|
||||
input.Equals(bool.FalseString, StringComparison.OrdinalIgnoreCase) ||
|
||||
input.Equals("t", StringComparison.OrdinalIgnoreCase) ||
|
||||
input.Equals("f", StringComparison.OrdinalIgnoreCase) ||
|
||||
input.Equals("1", StringComparison.Ordinal) ||
|
||||
input.Equals("0", StringComparison.Ordinal) ||
|
||||
input.Equals("yes", StringComparison.OrdinalIgnoreCase) ||
|
||||
input.Equals("no", StringComparison.OrdinalIgnoreCase) ||
|
||||
input.Equals("真", StringComparison.Ordinal) ||
|
||||
input.Equals("假", StringComparison.Ordinal))
|
||||
{
|
||||
boolValue = input.Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase) ||
|
||||
input.Equals("t", StringComparison.OrdinalIgnoreCase) ||
|
||||
input.Equals("1", StringComparison.Ordinal) ||
|
||||
input.Equals("yes", StringComparison.OrdinalIgnoreCase) ||
|
||||
input.Equals("真", StringComparison.Ordinal);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool IsDateTime(string input, out DateTime dateTimeValue)
|
||||
{
|
||||
dateTimeValue = default;
|
||||
// 首先尝试使用默认的DateTime.TryParse进行解析
|
||||
if (DateTime.TryParse(input, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime dateTime))
|
||||
{
|
||||
dateTimeValue = dateTime;
|
||||
return true;
|
||||
}
|
||||
|
||||
// 如果解析失败,尝试使用不同的格式字符串进行解析
|
||||
string[] formats = {
|
||||
"yyyy-MM-dd",
|
||||
"yyyy/MM/dd",
|
||||
"yyyy.MM.dd",
|
||||
"yyyyMMdd",
|
||||
"yyyy-MM-dd HH:mm",
|
||||
"yyyy/MM/dd HH:mm",
|
||||
"yyyy.MM.dd HH:mm",
|
||||
"yyyy-MM-dd HH:mm:ss",
|
||||
"yyyy/MM/dd HH:mm:ss",
|
||||
"yyyy.MM.dd HH:mm:ss",
|
||||
"yyyy-MM-dd HH:mm:ss.fff",
|
||||
"yyyy-MM-ddTHH:mm:ss.fffK" // 支持ISO 8601格式带时区
|
||||
};
|
||||
|
||||
// 使用TryParseExact尝试解析,提供多种格式字符串
|
||||
foreach (string format in formats)
|
||||
{
|
||||
if (DateTime.TryParseExact(input, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
|
||||
{
|
||||
dateTimeValue = dateTime;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MAX.Framework.Helpers;
|
||||
|
||||
public class SystemHelper
|
||||
{
|
||||
public static bool IsAdministratorSafe
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return IsAdministrator;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static bool IsAdministrator
|
||||
{
|
||||
get
|
||||
{
|
||||
WindowsIdentity current = WindowsIdentity.GetCurrent();
|
||||
WindowsPrincipal windowsPrincipal = new(current);
|
||||
return windowsPrincipal.IsInRole(WindowsBuiltInRole.Administrator);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
using MAX.Core.Commons;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
namespace MAX.Framework.Helpers
|
||||
{
|
||||
public class WinCmdHelper
|
||||
{
|
||||
#region 执行Dos命令
|
||||
|
||||
/// <summary>
|
||||
/// 执行Dos命令
|
||||
/// </summary>
|
||||
/// <param name="cmd">Dos命令及参数</param>
|
||||
/// <param name="isShowCmdWindow">是否显示cmd窗口</param>
|
||||
/// <param name="isCloseCmdProcess">执行完毕后是否关闭cmd进程</param>
|
||||
/// <returns>成功返回true,失败返回false</returns>
|
||||
public static Result ExcuteDosCommand(string cmd, string workdir, bool isShowCmdWindow = false, bool isWaitForExit = false, bool isCloseCmdProcess = true)
|
||||
{
|
||||
Result result = new Result();
|
||||
try
|
||||
{
|
||||
StringBuilder errString = new StringBuilder();
|
||||
StringBuilder outString = new StringBuilder();
|
||||
Process p = new Process();
|
||||
p.StartInfo.FileName = "cmd";
|
||||
p.StartInfo.WorkingDirectory = workdir;
|
||||
p.StartInfo.Arguments = "/c " + cmd;
|
||||
p.StartInfo.StandardOutputEncoding = Encoding.UTF8;
|
||||
p.StartInfo.StandardErrorEncoding = Encoding.UTF8;
|
||||
p.StartInfo.UseShellExecute = false;
|
||||
p.StartInfo.RedirectStandardOutput = true;
|
||||
p.StartInfo.RedirectStandardError = true;
|
||||
p.StartInfo.CreateNoWindow = !isShowCmdWindow;
|
||||
p.OutputDataReceived += new DataReceivedEventHandler(delegate (object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(e.Data))
|
||||
{
|
||||
outString.AppendLine(e.Data);
|
||||
Debug.WriteLine(e.Data);
|
||||
}
|
||||
});
|
||||
p.ErrorDataReceived += new DataReceivedEventHandler(delegate (object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(e.Data))
|
||||
{
|
||||
errString.AppendLine(e.Data);
|
||||
}
|
||||
});
|
||||
p.Start();
|
||||
p.BeginOutputReadLine();
|
||||
p.BeginErrorReadLine();
|
||||
if (isWaitForExit)
|
||||
{
|
||||
p.WaitForExit();
|
||||
}
|
||||
|
||||
if (isCloseCmdProcess)
|
||||
{
|
||||
p.Close();
|
||||
}
|
||||
if (errString.Length <= 0)
|
||||
{
|
||||
result.Success = true;
|
||||
result.Data = outString.ToString();
|
||||
}
|
||||
Console.WriteLine(string.Format("成功执行Dos命令[{0}]!", cmd));
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("执行命令失败,请检查输入的命令是否正确:" + ex.Message, ex);
|
||||
result.Msg = ex.Message;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void P_ErrorDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 判断指定的进程是否在运行中
|
||||
|
||||
/// <summary>
|
||||
/// 判断指定的进程是否在运行中
|
||||
/// </summary>
|
||||
/// <param name="processName">要判断的进程名称,不包括扩展名exe</param>
|
||||
/// <param name="processFileName">进程文件的完整路径</param>
|
||||
/// <returns>存在返回true,否则返回false</returns>
|
||||
public static bool CheckProcessExists(string processName, string processFileName)
|
||||
{
|
||||
Process[] processes = Process.GetProcessesByName(processName);
|
||||
foreach (Process p in processes)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(processFileName))
|
||||
{
|
||||
if (processFileName == p?.MainModule?.FileName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 结束指定的windows进程
|
||||
|
||||
/// <summary>
|
||||
/// 结束指定的windows进程,如果进程存在
|
||||
/// </summary>
|
||||
/// <param name="processName">进程名称,不包含扩展名</param>
|
||||
/// <param name="processFileName">进程文件完整路径,如果为空则删除所有进程名为processName参数值的进程</param>
|
||||
public static bool KillProcessExists(string processName, string processFileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
Process[] processes = Process.GetProcessesByName(processName);
|
||||
foreach (Process p in processes)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(processFileName))
|
||||
{
|
||||
if (processFileName == p.MainModule.FileName)
|
||||
{
|
||||
p.Kill();
|
||||
p.Close();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p.Kill();
|
||||
p.Close();
|
||||
}
|
||||
}
|
||||
Console.WriteLine(string.Format("成功结束[{0}]进程!", processes));
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("结束指定的Widnows进程异常:" + ex.Message, ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,292 @@
|
||||
|
||||
using System.Xml;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using System;
|
||||
|
||||
namespace MAX.Framework.Helpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Xml的操作公共类
|
||||
/// </summary>
|
||||
public class XmlHelper
|
||||
{
|
||||
#region 字段定义
|
||||
/// <summary>
|
||||
/// /// XML文件的物理路径
|
||||
/// </summary>
|
||||
private string _filePath = string.Empty;
|
||||
/// <summary>
|
||||
/// Xml文档
|
||||
/// </summary>
|
||||
private XmlDocument _xml;
|
||||
/// <summary>
|
||||
/// XML的根节点
|
||||
/// </summary>
|
||||
private XmlElement _element;
|
||||
#endregion
|
||||
|
||||
#region 构造方法
|
||||
/// <summary>
|
||||
/// 实例化XmlHelper对象
|
||||
/// </summary>
|
||||
/// <param name="xmlFilePath">Xml文件的相对路径</param>
|
||||
public XmlHelper(string xmlFilePath)
|
||||
{
|
||||
//获取XML文件的绝对路径
|
||||
_filePath = xmlFilePath;
|
||||
//创建一个XML对象
|
||||
_xml = new XmlDocument();
|
||||
if (File.Exists(xmlFilePath))
|
||||
{
|
||||
//加载XML文件
|
||||
_xml.Load(xmlFilePath);
|
||||
}
|
||||
_element = _xml.DocumentElement;
|
||||
}
|
||||
public XmlHelper(Stream stream)
|
||||
{
|
||||
//创建一个XML对象
|
||||
_xml = new XmlDocument();
|
||||
if (stream != null)
|
||||
{
|
||||
//加载XML
|
||||
_xml.Load(stream);
|
||||
}
|
||||
_element = _xml.DocumentElement;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region 获取指定XPath表达式的节点对象
|
||||
/// <summary>
|
||||
/// 获取指定XPath表达式的节点对象
|
||||
/// </summary>
|
||||
/// <param name="xPath">XPath表达式,
|
||||
/// 范例1: @"Skill/First/SkillItem", 等效于 @"//Skill/First/SkillItem"
|
||||
/// 范例2: @"Table[USERNAME='a']" , []表示筛选,USERNAME是Table下的一个子节点.
|
||||
/// 范例3: @"ApplyPost/Item[@itemName='岗位编号']",@itemName是Item节点的属性.
|
||||
/// </param>
|
||||
public XmlNode GetNode(string xPath)
|
||||
{
|
||||
//返回XPath节点
|
||||
return _element.SelectSingleNode(xPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定XPath表达式的节点对象
|
||||
/// </summary>
|
||||
/// <param name="xPath">XPath表达式,
|
||||
/// 范例1: @"Skill/First/SkillItem", 等效于 @"//Skill/First/SkillItem"
|
||||
/// 范例2: @"Table[USERNAME='a']" , []表示筛选,USERNAME是Table下的一个子节点.
|
||||
/// 范例3: @"ApplyPost/Item[@itemName='岗位编号']",@itemName是Item节点的属性.
|
||||
/// </param>
|
||||
public XmlNodeList GetNodes(string xPath)
|
||||
{
|
||||
//返回XPath节点
|
||||
return _element.SelectNodes(xPath);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 获取指定XPath表达式节点的值
|
||||
/// <summary>
|
||||
/// 获取指定XPath表达式节点的值
|
||||
/// </summary>
|
||||
/// <param name="xPath">XPath表达式,
|
||||
/// 范例1: @"Skill/First/SkillItem", 等效于 @"//Skill/First/SkillItem"
|
||||
/// 范例2: @"Table[USERNAME='a']" , []表示筛选,USERNAME是Table下的一个子节点.
|
||||
/// 范例3: @"ApplyPost/Item[@itemName='岗位编号']",@itemName是Item节点的属性.
|
||||
/// </param>
|
||||
public string GetValue(string xPath)
|
||||
{
|
||||
//返回XPath节点的值
|
||||
string value = _element.SelectSingleNode(xPath)?.InnerText ?? "";
|
||||
return value;
|
||||
}
|
||||
public T GetValue<T>(string xPath, T? def = default)
|
||||
{
|
||||
string value = GetValue(xPath);
|
||||
if (value == null)
|
||||
return def;
|
||||
else
|
||||
return (T)Convert.ChangeType(value, typeof(T));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 获取指定XPath表达式节点的属性值
|
||||
/// <summary>
|
||||
/// 获取指定XPath表达式节点的属性值
|
||||
/// </summary>
|
||||
/// <param name="xPath">XPath表达式,
|
||||
/// 范例1: @"Skill/First/SkillItem", 等效于 @"//Skill/First/SkillItem"
|
||||
/// 范例2: @"Table[USERNAME='a']" , []表示筛选,USERNAME是Table下的一个子节点.
|
||||
/// 范例3: @"ApplyPost/Item[@itemName='岗位编号']",@itemName是Item节点的属性.
|
||||
/// </param>
|
||||
/// <param name="attributeName">属性名</param>
|
||||
public string GetAttributeValue(string xPath, string attributeName)
|
||||
{
|
||||
//返回XPath节点的属性值
|
||||
return _element.SelectSingleNode(xPath).Attributes[attributeName].Value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 新增节点
|
||||
/// <summary>
|
||||
/// 1. 功能:新增节点。
|
||||
/// 2. 使用条件:将任意节点插入到当前Xml文件中。
|
||||
/// </summary>
|
||||
/// <param name="xmlNode">要插入的Xml节点</param>
|
||||
public void AppendNode(XmlNode xmlNode)
|
||||
{
|
||||
//导入节点
|
||||
XmlNode node = _xml.ImportNode(xmlNode, true);
|
||||
|
||||
//将节点插入到根节点下
|
||||
_element.AppendChild(node);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 1. 功能:新增节点。
|
||||
/// 2. 使用条件:将DataSet中的第一条记录插入Xml文件中。
|
||||
/// </summary>
|
||||
/// <param name="ds">DataSet的实例,该DataSet中应该只有一条记录</param>
|
||||
public void AppendNode(DataSet ds)
|
||||
{
|
||||
//创建XmlDataDocument对象
|
||||
XmlDataDocument xmlDataDocument = new XmlDataDocument(ds);
|
||||
|
||||
//导入节点
|
||||
XmlNode node = xmlDataDocument.DocumentElement.FirstChild;
|
||||
|
||||
//将节点插入到根节点下
|
||||
AppendNode(node);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 删除节点
|
||||
/// <summary>
|
||||
/// 删除指定XPath表达式的节点
|
||||
/// </summary>
|
||||
/// <param name="xPath">XPath表达式,
|
||||
/// 范例1: @"Skill/First/SkillItem", 等效于 @"//Skill/First/SkillItem"
|
||||
/// 范例2: @"Table[USERNAME='a']" , []表示筛选,USERNAME是Table下的一个子节点.
|
||||
/// 范例3: @"ApplyPost/Item[@itemName='岗位编号']",@itemName是Item节点的属性.
|
||||
/// </param>
|
||||
public void RemoveNode(string xPath)
|
||||
{
|
||||
//获取要删除的节点
|
||||
XmlNode node = _xml.SelectSingleNode(xPath);
|
||||
|
||||
//删除节点
|
||||
_element.RemoveChild(node);
|
||||
}
|
||||
#endregion //删除节点
|
||||
|
||||
#region 保存XML文件
|
||||
/// <summary>
|
||||
/// 保存XML文件
|
||||
/// </summary>
|
||||
public void Save()
|
||||
{
|
||||
if (string.IsNullOrEmpty(_filePath))
|
||||
{
|
||||
throw new Exception("Xml文件路径不能为空!");
|
||||
}
|
||||
//保存XML文件
|
||||
_xml.Save(_filePath);
|
||||
}
|
||||
public void Save(string filePath)
|
||||
{
|
||||
//保存XML文件
|
||||
_xml.Save(filePath);
|
||||
}
|
||||
#endregion //保存XML文件
|
||||
|
||||
#region 静态方法
|
||||
|
||||
#region 创建根节点对象
|
||||
/// <summary>
|
||||
/// 创建根节点对象
|
||||
/// </summary>
|
||||
/// <param name="xmlFilePath">Xml文件的相对路径</param>
|
||||
private static XmlElement CreateRootElement(string xmlFilePath)
|
||||
{
|
||||
//定义变量,表示XML文件的绝对路径
|
||||
string filePath = "";
|
||||
|
||||
//获取XML文件的绝对路径
|
||||
filePath = xmlFilePath;
|
||||
|
||||
//创建XmlDocument对象
|
||||
XmlDocument xmlDocument = new XmlDocument();
|
||||
//加载XML文件
|
||||
xmlDocument.Load(filePath);
|
||||
|
||||
//返回根节点
|
||||
return xmlDocument.DocumentElement;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 获取指定XPath表达式节点的值
|
||||
/// <summary>
|
||||
/// 获取指定XPath表达式节点的值
|
||||
/// </summary>
|
||||
/// <param name="xmlFilePath">Xml文件的相对路径</param>
|
||||
/// <param name="xPath">XPath表达式,
|
||||
/// 范例1: @"Skill/First/SkillItem", 等效于 @"//Skill/First/SkillItem"
|
||||
/// 范例2: @"Table[USERNAME='a']" , []表示筛选,USERNAME是Table下的一个子节点.
|
||||
/// 范例3: @"ApplyPost/Item[@itemName='岗位编号']",@itemName是Item节点的属性.
|
||||
/// </param>
|
||||
public static string GetValue(string xmlFilePath, string xPath)
|
||||
{
|
||||
//创建根对象
|
||||
XmlElement rootElement = CreateRootElement(xmlFilePath);
|
||||
|
||||
//返回XPath节点的值
|
||||
return rootElement.SelectSingleNode(xPath).InnerText;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 获取指定XPath表达式节点的属性值
|
||||
/// <summary>
|
||||
/// 获取指定XPath表达式节点的属性值
|
||||
/// </summary>
|
||||
/// <param name="xmlFilePath">Xml文件的相对路径</param>
|
||||
/// <param name="xPath">XPath表达式,
|
||||
/// 范例1: @"Skill/First/SkillItem", 等效于 @"//Skill/First/SkillItem"
|
||||
/// 范例2: @"Table[USERNAME='a']" , []表示筛选,USERNAME是Table下的一个子节点.
|
||||
/// 范例3: @"ApplyPost/Item[@itemName='岗位编号']",@itemName是Item节点的属性.
|
||||
/// </param>
|
||||
/// <param name="attributeName">属性名</param>
|
||||
public static string GetAttributeValue(string xmlFilePath, string xPath, string attributeName)
|
||||
{
|
||||
//创建根对象
|
||||
XmlElement rootElement = CreateRootElement(xmlFilePath);
|
||||
|
||||
//返回XPath节点的属性值
|
||||
return rootElement.SelectSingleNode(xPath).Attributes[attributeName].Value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static class XmlHelExtension
|
||||
{
|
||||
public static string GetAttributeValue(this XmlNode node, string attributeName)
|
||||
{
|
||||
return node.Attributes[attributeName].Value;
|
||||
}
|
||||
public static T GetAttributeValue<T>(this XmlNode node, string attributeName)
|
||||
{
|
||||
var value = node.Attributes[attributeName].Value;
|
||||
if (string.IsNullOrEmpty(value))
|
||||
return default(T);
|
||||
return (T)Convert.ChangeType(value, typeof(T));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using MAX.Core.DependencyInjection;
|
||||
|
||||
namespace MAX.Framework.Interfaces
|
||||
{
|
||||
public interface IAppConfig : ISingletonDependency
|
||||
{
|
||||
/// <summary>
|
||||
/// 公司名称
|
||||
/// </summary>
|
||||
string CompanyName { get; }
|
||||
/// <summary>
|
||||
/// 软件名称
|
||||
/// </summary>
|
||||
string AppName { get; }
|
||||
T GetValue<T>(string key, T defaultValue = default);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using MAX.Core;
|
||||
using MAX.Core.DependencyInjection;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MAX.Framework.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化接口
|
||||
/// </summary>
|
||||
public interface IAppInitialize : ISingletonDependency, IPriority
|
||||
{
|
||||
/// <summary>
|
||||
/// 描述
|
||||
/// </summary>
|
||||
string Description { get; }
|
||||
|
||||
/// <summary>
|
||||
/// App 初始化数据
|
||||
/// </summary>
|
||||
void AppInitialize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化接口(异步)
|
||||
/// </summary>
|
||||
public interface IAppInitializeAsync : ISingletonDependency, IPriority
|
||||
{
|
||||
/// <summary>
|
||||
/// 描述
|
||||
/// </summary>
|
||||
string Description { get; }
|
||||
|
||||
/// <summary>
|
||||
/// App 初始化数据
|
||||
/// </summary>
|
||||
Task AppInitializeAsync();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using MAX.Core.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MAX.Framework.Interfaces
|
||||
{
|
||||
public interface IFolderConfig: ISingletonDependency
|
||||
{
|
||||
/// <summary>
|
||||
/// 执行目录
|
||||
/// </summary>
|
||||
string LocalFolder { get; }
|
||||
string LocalAppFolder { get; }
|
||||
string TargetFolder { get; }
|
||||
string LoggingFolder { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
using MAX.Core.DependencyInjection;
|
||||
using MAX.Core.Infrastructure;
|
||||
using MAX.Core.Logger;
|
||||
using MAX.Framework.Interfaces;
|
||||
using NLog;
|
||||
using NLog.Targets;
|
||||
using System;
|
||||
using LLogLevel = MAX.Core.Logger.LogLevel;
|
||||
using NLogLevel = NLog.LogLevel;
|
||||
|
||||
namespace MAX.Framework.Logger
|
||||
{
|
||||
public class NLogger : ILoggerFacade, ISingletonDependency
|
||||
{
|
||||
private readonly ILogger _log;
|
||||
public static ILoggerFacade Instance => LazyServiceProvider.Instance.LazyGetService<ILoggerFacade>();
|
||||
public NLogger(IFolderConfig folderConfig = null)
|
||||
{
|
||||
if (folderConfig != null)
|
||||
{
|
||||
Target target = new FileTarget("log1")
|
||||
{
|
||||
FileName = $"{folderConfig.LoggingFolder}\\{DateTime.Now:yyyy-MM-dd}.txt",
|
||||
};
|
||||
var config = new NLog.Config.LoggingConfiguration();
|
||||
config.AddRule(NLogLevel.Debug, NLogLevel.Fatal, target);
|
||||
|
||||
LogManager.Configuration = config;
|
||||
}
|
||||
_log = LogManager.GetLogger("GlobalLogger");
|
||||
}
|
||||
|
||||
public bool IsDebugEnabled { get; private set; } = false;
|
||||
|
||||
public void Debug(Exception ex, string message)
|
||||
{
|
||||
Execute(NLogLevel.Debug, ex, message);
|
||||
}
|
||||
|
||||
public void Debug(string message)
|
||||
{
|
||||
Execute(NLogLevel.Debug, message);
|
||||
}
|
||||
public void Error(Exception ex)
|
||||
{
|
||||
Execute(NLogLevel.Error, ex);
|
||||
}
|
||||
public void Error(Exception ex, string message)
|
||||
{
|
||||
Execute(NLogLevel.Error, ex, message);
|
||||
}
|
||||
|
||||
public void Error(string message)
|
||||
{
|
||||
Execute(NLogLevel.Error, message);
|
||||
}
|
||||
|
||||
public void Fatal(Exception ex, string message)
|
||||
{
|
||||
Execute(NLogLevel.Fatal, ex, message);
|
||||
}
|
||||
|
||||
public void Fatal(string message)
|
||||
{
|
||||
Execute(NLogLevel.Fatal, message);
|
||||
}
|
||||
|
||||
public void Info(Exception ex, string message)
|
||||
{
|
||||
Execute(NLogLevel.Info, ex, message);
|
||||
}
|
||||
|
||||
public void Info(string message)
|
||||
{
|
||||
Execute(NLogLevel.Info, message);
|
||||
}
|
||||
|
||||
public void Warn(Exception ex, string message)
|
||||
{
|
||||
Execute(NLogLevel.Warn, ex, message);
|
||||
}
|
||||
|
||||
public void Warn(string message)
|
||||
{
|
||||
Execute(NLogLevel.Warn, message);
|
||||
}
|
||||
public void Log(string message, LLogLevel level)
|
||||
{
|
||||
NLogLevel lv = NLogLevel.Info;
|
||||
switch (level)
|
||||
{
|
||||
case LLogLevel.Trace:
|
||||
lv = NLogLevel.Trace;
|
||||
break;
|
||||
case LLogLevel.Debug:
|
||||
lv = NLogLevel.Debug;
|
||||
break;
|
||||
case LLogLevel.Info:
|
||||
lv = NLogLevel.Info;
|
||||
break;
|
||||
case LLogLevel.Warn:
|
||||
lv = NLogLevel.Warn;
|
||||
break;
|
||||
case LLogLevel.Error:
|
||||
lv = NLogLevel.Error;
|
||||
break;
|
||||
case LLogLevel.Fatal:
|
||||
lv = NLogLevel.Fatal;
|
||||
break;
|
||||
case LLogLevel.None:
|
||||
lv = NLogLevel.Off;
|
||||
break;
|
||||
}
|
||||
Execute(lv, message);
|
||||
}
|
||||
/// <summary>
|
||||
/// 是否启用
|
||||
/// </summary>
|
||||
private bool Enabled(NLogLevel level)
|
||||
{
|
||||
if (level > NLogLevel.Debug)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return IsDebugEnabled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行
|
||||
/// </summary>
|
||||
private void Execute(NLogLevel level, Exception ex, string message = "")
|
||||
{
|
||||
if (Enabled(level))
|
||||
{
|
||||
_log.Log(level, ex, message, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 执行
|
||||
/// </summary>
|
||||
private void Execute(NLogLevel level, string message)
|
||||
{
|
||||
if (Enabled(level))
|
||||
{
|
||||
_log.Log(level, message);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Controls\**" />
|
||||
<Compile Remove="Extensions\**" />
|
||||
<Compile Remove="PrismExtension\**" />
|
||||
<EmbeddedResource Remove="Controls\**" />
|
||||
<EmbeddedResource Remove="Extensions\**" />
|
||||
<EmbeddedResource Remove="PrismExtension\**" />
|
||||
<None Remove="Controls\**" />
|
||||
<None Remove="Extensions\**" />
|
||||
<None Remove="PrismExtension\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Autofac" Version="9.3.2" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||
<PackageReference Include="NLog" Version="6.2.0" />
|
||||
<!--<PackageReference Include="Prism.Wpf" Version="8.1.97" />-->
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\MAX.Core\MAX.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,243 @@
|
||||
using System.Linq.Expressions;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Prism.Properties;
|
||||
|
||||
|
||||
namespace Prism.Commands
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Provides an implementation of the <see cref="IAsyncCommand"/>
|
||||
/// </summary>
|
||||
public class AsyncDelegateCommand : DelegateCommandBase, IAsyncCommand
|
||||
{
|
||||
private bool _enableParallelExecution = false;
|
||||
private bool _isExecuting = false;
|
||||
private readonly Func<CancellationToken, Task> _executeMethod;
|
||||
private Func<bool> _canExecuteMethod;
|
||||
private Func<CancellationToken> _getCancellationToken = () => CancellationToken.None;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="AsyncDelegateCommand"/> with the <see cref="Func{Task}"/> to invoke on execution.
|
||||
/// </summary>
|
||||
/// <param name="executeMethod">The <see cref="Func{Task}"/> to invoke when <see cref="ICommand.Execute(object)"/> is called.</param>
|
||||
public AsyncDelegateCommand(Func<Task> executeMethod)
|
||||
#if NET6_0_OR_GREATER
|
||||
: this (c => executeMethod().WaitAsync(c), () => true)
|
||||
#else
|
||||
: this(c => executeMethod(), () => true)
|
||||
#endif
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="AsyncDelegateCommand"/> with the <see cref="Func{Task}"/> to invoke on execution.
|
||||
/// </summary>
|
||||
/// <param name="executeMethod">The <see cref="Func{CancellationToken, Task}"/> to invoke when <see cref="ICommand.Execute(object)"/> is called.</param>
|
||||
public AsyncDelegateCommand(Func<CancellationToken, Task> executeMethod)
|
||||
: this(executeMethod, () => true)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="DelegateCommand"/> with the <see cref="Func{Task}"/> to invoke on execution
|
||||
/// and a <see langword="Func" /> to query for determining if the command can execute.
|
||||
/// </summary>
|
||||
/// <param name="executeMethod">The <see cref="Func{Task}"/> to invoke when <see cref="ICommand.Execute"/> is called.</param>
|
||||
/// <param name="canExecuteMethod">The delegate to invoke when <see cref="ICommand.CanExecute"/> is called</param>
|
||||
public AsyncDelegateCommand(Func<Task> executeMethod, Func<bool> canExecuteMethod)
|
||||
#if NET6_0_OR_GREATER
|
||||
: this(c => executeMethod().WaitAsync(c), canExecuteMethod)
|
||||
#else
|
||||
: this(c => executeMethod(), canExecuteMethod)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="DelegateCommand"/> with the <see cref="Func{Task}"/> to invoke on execution
|
||||
/// and a <see langword="Func" /> to query for determining if the command can execute.
|
||||
/// </summary>
|
||||
/// <param name="executeMethod">The <see cref="Func{CancellationToken, Task}"/> to invoke when <see cref="ICommand.Execute"/> is called.</param>
|
||||
/// <param name="canExecuteMethod">The delegate to invoke when <see cref="ICommand.CanExecute"/> is called</param>
|
||||
public AsyncDelegateCommand(Func<CancellationToken, Task> executeMethod, Func<bool> canExecuteMethod)
|
||||
: base()
|
||||
{
|
||||
if (executeMethod == null || canExecuteMethod == null)
|
||||
throw new ArgumentNullException(nameof(executeMethod), "Neither the executeMethod nor the canExecuteMethod delegates can be null");
|
||||
|
||||
_executeMethod = executeMethod;
|
||||
_canExecuteMethod = canExecuteMethod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current state of the AsyncDelegateCommand
|
||||
/// </summary>
|
||||
public bool IsExecuting
|
||||
{
|
||||
get => _isExecuting;
|
||||
private set
|
||||
{
|
||||
_isExecuting = value;
|
||||
OnCanExecuteChanged();
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
/// Executes the command.
|
||||
///</summary>
|
||||
public async Task Execute(CancellationToken? cancellationToken = null)
|
||||
{
|
||||
var token = cancellationToken ?? _getCancellationToken();
|
||||
try
|
||||
{
|
||||
if (!_enableParallelExecution && IsExecuting)
|
||||
return;
|
||||
|
||||
IsExecuting = true;
|
||||
await _executeMethod(token)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
IsExecuting = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the command can be executed.
|
||||
/// </summary>
|
||||
/// <returns>Returns <see langword="true"/> if the command can execute,otherwise returns <see langword="false"/>.</returns>
|
||||
public bool CanExecute()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!_enableParallelExecution && IsExecuting)
|
||||
return false;
|
||||
|
||||
return _canExecuteMethod?.Invoke() ?? true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle the internal invocation of <see cref="ICommand.Execute(object)"/>
|
||||
/// </summary>
|
||||
/// <param name="parameter">Command Parameter</param>
|
||||
protected override async void Execute(object parameter)
|
||||
{
|
||||
// We don't want to wrap this in a try/catch because we already handle
|
||||
// or mean to rethrow the exception in the call with the CancellationToken.
|
||||
var cancellationToken = _getCancellationToken();
|
||||
await Execute(cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle the internal invocation of <see cref="ICommand.CanExecute(object)"/>
|
||||
/// </summary>
|
||||
/// <param name="parameter"></param>
|
||||
/// <returns><see langword="true"/> if the Command Can Execute, otherwise <see langword="false" /></returns>
|
||||
protected override bool CanExecute(object parameter)
|
||||
{
|
||||
return CanExecute();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables Parallel Execution of Async Tasks
|
||||
/// </summary>
|
||||
/// <returns>The current instance of <see cref="AsyncDelegateCommand"/>.</returns>
|
||||
public AsyncDelegateCommand EnableParallelExecution()
|
||||
{
|
||||
_enableParallelExecution = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="CancellationTokenSourceFactory(Func{CancellationToken})"/> based on the specified timeout.
|
||||
/// </summary>
|
||||
/// <param name="timeout">A specified timeout.</param>
|
||||
/// <returns>The current instance of <see cref="AsyncDelegateCommand{T}"/>.</returns>
|
||||
public AsyncDelegateCommand CancelAfter(TimeSpan timeout) =>
|
||||
CancellationTokenSourceFactory(() => new CancellationTokenSource(timeout).Token);
|
||||
|
||||
/// <summary>
|
||||
/// Provides a delegate callback to provide a default CancellationToken when the Command is invoked.
|
||||
/// </summary>
|
||||
/// <param name="factory">The default <see cref="CancellationToken"/> Factory.</param>
|
||||
/// <returns>The current instance of <see cref="AsyncDelegateCommand"/>.</returns>
|
||||
public AsyncDelegateCommand CancellationTokenSourceFactory(Func<CancellationToken> factory)
|
||||
{
|
||||
_getCancellationToken = factory;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Observes a property that implements INotifyPropertyChanged, and automatically calls DelegateCommandBase.RaiseCanExecuteChanged on property changed notifications.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The object type containing the property specified in the expression.</typeparam>
|
||||
/// <param name="propertyExpression">The property expression. Example: ObservesProperty(() => PropertyName).</param>
|
||||
/// <returns>The current instance of <see cref="AsyncDelegateCommand"/>.</returns>
|
||||
public AsyncDelegateCommand ObservesProperty<T>(Expression<Func<T>> propertyExpression)
|
||||
{
|
||||
ObservesPropertyInternal(propertyExpression);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Observes a property that is used to determine if this command can execute, and if it implements INotifyPropertyChanged it will automatically call DelegateCommandBase.RaiseCanExecuteChanged on property changed notifications.
|
||||
/// </summary>
|
||||
/// <param name="canExecuteExpression">The property expression. Example: ObservesCanExecute(() => PropertyName).</param>
|
||||
/// <returns>The current instance of <see cref="AsyncDelegateCommand"/>.</returns>
|
||||
public AsyncDelegateCommand ObservesCanExecute(Expression<Func<bool>> canExecuteExpression)
|
||||
{
|
||||
_canExecuteMethod = canExecuteExpression.Compile();
|
||||
ObservesPropertyInternal(canExecuteExpression);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides the ability to connect a delegate to catch exceptions encountered by CanExecute or the Execute methods of the DelegateCommand
|
||||
/// </summary>
|
||||
/// <param name="catch">TThe callback when a specific exception is encountered</param>
|
||||
/// <returns>The current instance of <see cref="AsyncDelegateCommand"/>.</returns>
|
||||
public AsyncDelegateCommand Catch<TException>(Action<TException> @catch)
|
||||
where TException : Exception
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides the ability to connect a delegate to catch exceptions encountered by CanExecute or the Execute methods of the DelegateCommand
|
||||
/// </summary>
|
||||
/// <param name="catch">The generic / default callback when an exception is encountered</param>
|
||||
/// <returns>The current instance of <see cref="AsyncDelegateCommand"/>.</returns>
|
||||
public AsyncDelegateCommand Catch(Action<Exception> @catch)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
Task IAsyncCommand.ExecuteAsync(object parameter)
|
||||
{
|
||||
return Execute(_getCancellationToken());
|
||||
}
|
||||
|
||||
Task IAsyncCommand.ExecuteAsync(object parameter, CancellationToken cancellationToken)
|
||||
{
|
||||
return Execute(cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,284 @@
|
||||
using System.Linq.Expressions;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using System.Reflection.Emit;
|
||||
using System.Resources;
|
||||
|
||||
namespace Prism.Commands
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides an implementation of the <see cref="IAsyncCommand"/> with a generic parameter type.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class AsyncDelegateCommand<T> : DelegateCommandBase, IAsyncCommand
|
||||
{
|
||||
private bool _enableParallelExecution = false;
|
||||
private bool _isExecuting = false;
|
||||
private readonly Func<T, CancellationToken, Task> _executeMethod;
|
||||
private Func<T, bool> _canExecuteMethod;
|
||||
private Func<CancellationToken> _getCancellationToken = () => CancellationToken.None;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="AsyncDelegateCommand{T}"/> with the <see cref="Func{Task}"/> to invoke on execution.
|
||||
/// </summary>
|
||||
/// <param name="executeMethod">The <see cref="Func{T, Task}"/> to invoke when <see cref="ICommand.Execute(object)"/> is called.</param>
|
||||
public AsyncDelegateCommand(Func<T, Task> executeMethod)
|
||||
#if NET6_0_OR_GREATER
|
||||
: this((p,t) => executeMethod(p).WaitAsync(t), _ => true)
|
||||
#else
|
||||
: this((p, t) => executeMethod(p), _ => true)
|
||||
#endif
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="AsyncDelegateCommand{T}"/> with the <see cref="Func{Task}"/> to invoke on execution.
|
||||
/// </summary>
|
||||
/// <param name="executeMethod">The <see cref="Func{T, CancellationToken, Task}"/> to invoke when <see cref="ICommand.Execute(object)"/> is called.</param>
|
||||
public AsyncDelegateCommand(Func<T, CancellationToken, Task> executeMethod)
|
||||
: this(executeMethod, _ => true)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="DelegateCommand"/> with the <see cref="Func{Task}"/> to invoke on execution
|
||||
/// and a <see langword="Func" /> to query for determining if the command can execute.
|
||||
/// </summary>
|
||||
/// <param name="executeMethod">The <see cref="Func{T, Task}"/> to invoke when <see cref="ICommand.Execute"/> is called.</param>
|
||||
/// <param name="canExecuteMethod">The delegate to invoke when <see cref="ICommand.CanExecute"/> is called</param>
|
||||
public AsyncDelegateCommand(Func<T, Task> executeMethod, Func<T, bool> canExecuteMethod)
|
||||
#if NET6_0_OR_GREATER
|
||||
: this((p, c) => executeMethod(p).WaitAsync(c), canExecuteMethod)
|
||||
#else
|
||||
: this((p, c) => executeMethod(p), canExecuteMethod)
|
||||
#endif
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="DelegateCommand"/> with the <see cref="Func{Task}"/> to invoke on execution
|
||||
/// and a <see langword="Func" /> to query for determining if the command can execute.
|
||||
/// </summary>
|
||||
/// <param name="executeMethod">The <see cref="Func{T, CancellationToken, Task}"/> to invoke when <see cref="ICommand.Execute"/> is called.</param>
|
||||
/// <param name="canExecuteMethod">The delegate to invoke when <see cref="ICommand.CanExecute"/> is called</param>
|
||||
public AsyncDelegateCommand(Func<T, CancellationToken, Task> executeMethod, Func<T, bool> canExecuteMethod)
|
||||
: base()
|
||||
{
|
||||
if (executeMethod == null || canExecuteMethod == null)
|
||||
throw new ArgumentNullException(nameof(executeMethod), "Neither the executeMethod nor the canExecuteMethod delegates can be null");
|
||||
|
||||
|
||||
_executeMethod = executeMethod;
|
||||
_canExecuteMethod = canExecuteMethod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current state of the AsyncDelegateCommand
|
||||
/// </summary>
|
||||
public bool IsExecuting
|
||||
{
|
||||
get => _isExecuting;
|
||||
private set
|
||||
{
|
||||
_isExecuting = value;
|
||||
OnCanExecuteChanged();
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>
|
||||
/// Executes the command.
|
||||
///</summary>
|
||||
public async Task Execute(T parameter, CancellationToken? cancellationToken = null)
|
||||
{
|
||||
var token = cancellationToken ?? _getCancellationToken();
|
||||
|
||||
try
|
||||
{
|
||||
if (!_enableParallelExecution && IsExecuting)
|
||||
return;
|
||||
|
||||
IsExecuting = true;
|
||||
await _executeMethod(parameter, token)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
IsExecuting = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the command can be executed.
|
||||
/// </summary>
|
||||
/// <returns>Returns <see langword="true"/> if the command can execute,otherwise returns <see langword="false"/>.</returns>
|
||||
public bool CanExecute(T parameter)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!_enableParallelExecution && IsExecuting)
|
||||
return false;
|
||||
|
||||
return _canExecuteMethod?.Invoke(parameter) ?? true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
throw;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle the internal invocation of <see cref="ICommand.Execute(object)"/>
|
||||
/// </summary>
|
||||
/// <param name="parameter">Command Parameter</param>
|
||||
protected override async void Execute(object parameter)
|
||||
{
|
||||
var cancellationToken = _getCancellationToken();
|
||||
T parameterAsT;
|
||||
try
|
||||
{
|
||||
parameterAsT = (T)parameter;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
// If we had an exception casting the parameter to T ,
|
||||
// we would have already returned. We want to surface any
|
||||
// exceptions thrown by the Execute method.
|
||||
await Execute(parameterAsT, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle the internal invocation of <see cref="ICommand.CanExecute(object)"/>
|
||||
/// </summary>
|
||||
/// <param name="parameter"></param>
|
||||
/// <returns><see langword="true"/> if the Command Can Execute, otherwise <see langword="false" /></returns>
|
||||
protected override bool CanExecute(object parameter)
|
||||
{
|
||||
try
|
||||
{
|
||||
return CanExecute((T)parameter);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables Parallel Execution of Async Tasks
|
||||
/// </summary>
|
||||
/// <returns>The current instance of <see cref="AsyncDelegateCommand{T}"/>.</returns>
|
||||
public AsyncDelegateCommand<T> EnableParallelExecution()
|
||||
{
|
||||
_enableParallelExecution = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="CancellationTokenSourceFactory(Func{CancellationToken})"/> based on the specified timeout.
|
||||
/// </summary>
|
||||
/// <param name="timeout">A specified timeout.</param>
|
||||
/// <returns>The current instance of <see cref="AsyncDelegateCommand{T}"/>.</returns>
|
||||
public AsyncDelegateCommand<T> CancelAfter(TimeSpan timeout) =>
|
||||
CancellationTokenSourceFactory(() => new CancellationTokenSource(timeout).Token);
|
||||
|
||||
/// <summary>
|
||||
/// Provides a delegate callback to provide a default CancellationToken when the Command is invoked.
|
||||
/// </summary>
|
||||
/// <param name="factory">The default <see cref="CancellationToken"/> Factory.</param>
|
||||
/// <returns>The current instance of <see cref="AsyncDelegateCommand{T}"/>.</returns>
|
||||
public AsyncDelegateCommand<T> CancellationTokenSourceFactory(Func<CancellationToken> factory)
|
||||
{
|
||||
_getCancellationToken = factory;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Observes a property that implements INotifyPropertyChanged, and automatically calls DelegateCommandBase.RaiseCanExecuteChanged on property changed notifications.
|
||||
/// </summary>
|
||||
/// <typeparam name="TType">The type of the return value of the method that this delegate encapsulates</typeparam>
|
||||
/// <param name="propertyExpression">The property expression. Example: ObservesProperty(() => PropertyName).</param>
|
||||
/// <returns>The current instance of <see cref="AsyncDelegateCommand{T}"/>.</returns>
|
||||
public AsyncDelegateCommand<T> ObservesProperty<TType>(Expression<Func<TType>> propertyExpression)
|
||||
{
|
||||
ObservesPropertyInternal(propertyExpression);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Observes a property that is used to determine if this command can execute, and if it implements INotifyPropertyChanged it will automatically call DelegateCommandBase.RaiseCanExecuteChanged on property changed notifications.
|
||||
/// </summary>
|
||||
/// <param name="canExecuteExpression">The property expression. Example: ObservesCanExecute(() => PropertyName).</param>
|
||||
/// <returns>The current instance of <see cref="AsyncDelegateCommand{T}"/>.</returns>
|
||||
public AsyncDelegateCommand<T> ObservesCanExecute(Expression<Func<bool>> canExecuteExpression)
|
||||
{
|
||||
Expression<Func<T, bool>> expression = Expression.Lambda<Func<T, bool>>(canExecuteExpression.Body, Expression.Parameter(typeof(T), "o"));
|
||||
_canExecuteMethod = expression.Compile();
|
||||
ObservesPropertyInternal(canExecuteExpression);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides the ability to connect a delegate to catch exceptions encountered by CanExecute or the Execute methods of the DelegateCommand
|
||||
/// </summary>
|
||||
/// <param name="catch">TThe callback when a specific exception is encountered</param>
|
||||
/// <returns>The current instance of <see cref="AsyncDelegateCommand{T}"/>.</returns>
|
||||
public AsyncDelegateCommand<T> Catch<TException>(Action<TException> @catch)
|
||||
where TException : Exception
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides the ability to connect a delegate to catch exceptions encountered by CanExecute or the Execute methods of the DelegateCommand
|
||||
/// </summary>
|
||||
/// <param name="catch">The generic / default callback when an exception is encountered</param>
|
||||
/// <returns>The current instance of <see cref="AsyncDelegateCommand{T}"/>.</returns>
|
||||
public AsyncDelegateCommand<T> Catch(Action<Exception> @catch)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
async Task IAsyncCommand.ExecuteAsync(object parameter)
|
||||
{
|
||||
try
|
||||
{
|
||||
// If T is not nullable this may throw an exception
|
||||
await Execute((T)parameter, _getCancellationToken());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
async Task IAsyncCommand.ExecuteAsync(object parameter, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
// If T is not nullable this may throw an exception
|
||||
await Execute((T)parameter, cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Prism.Commands
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Provides an abstraction layer for custom controls which want to make use of Async Commands
|
||||
/// </summary>
|
||||
public interface IAsyncCommand : ICommand
|
||||
{
|
||||
/// <summary>
|
||||
/// Executes the Command with a specified parameter and the Default <see cref="CancellationToken"/>.
|
||||
/// </summary>
|
||||
/// <param name="parameter">The Command Parameter</param>
|
||||
/// <returns>An Asynchronous Task</returns>
|
||||
Task ExecuteAsync(object parameter);
|
||||
|
||||
/// <summary>
|
||||
/// Executes the Command with a specified parameter and using a <see cref="CancellationToken"/>
|
||||
/// </summary>
|
||||
/// <param name="parameter">The Command Parameter</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
|
||||
/// <returns>An Asynchronous Task</returns>
|
||||
Task ExecuteAsync(object parameter, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,334 @@
|
||||
using Autofac;
|
||||
using Autofac.Core;
|
||||
using Autofac.Features.ResolveAnything;
|
||||
using MAX.Core;
|
||||
using MAX.Core.Autofac;
|
||||
using MAX.Core.DependencyInjection;
|
||||
using MAX.Core.Helpers;
|
||||
using MAX.Core.Infrastructure;
|
||||
using MAX.Core.Reflections;
|
||||
using MAX.Framework.Interfaces;
|
||||
using MAX.Framework.Prism.Autofac;
|
||||
using Prism.Ioc;
|
||||
using Prism.Ioc.Internals;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Prism.Autofac
|
||||
{
|
||||
public class AutofacContainerExtension : IContainerExtension<IContainer>, IContainerInfo
|
||||
{
|
||||
private AutofacScopedProvider _currentScope;
|
||||
public readonly ContainerBuilder Builder;
|
||||
|
||||
public IContainer Instance { get; private set; }
|
||||
|
||||
public IScopedProvider CurrentScope => _currentScope;
|
||||
public AutofacContainerExtension()
|
||||
{
|
||||
Builder = new ContainerBuilder();
|
||||
string currentContainer = "CurrentContainer";
|
||||
Builder.RegisterInstance(this).Named(currentContainer, typeof(AutofacContainerExtension));
|
||||
Builder.RegisterInstance(this).As<IContainerExtension>();
|
||||
Builder.RegisterInstance(this).As<IContainerProvider>();
|
||||
//设置过滤AOP
|
||||
//IAspectConfiguration configuration = new AspectConfiguration();
|
||||
//foreach (var item in AppTypeFinder.Assemblies)
|
||||
//{
|
||||
// string _namespace = item.FullName;
|
||||
// if (!Regex.IsMatch(_namespace, "^MAX", RegexOptions.IgnoreCase | RegexOptions.Compiled))
|
||||
// {
|
||||
// configuration.NonAspectPredicates.AddNamespace(_namespace);
|
||||
// }
|
||||
//}
|
||||
//Builder.RegisterDynamicProxy(configuration);
|
||||
}
|
||||
public AutofacContainerExtension(ContainerBuilder builder)
|
||||
{
|
||||
Builder = builder;
|
||||
string currentContainer = "CurrentContainer";
|
||||
//Builder.RegisterDynamicProxy();
|
||||
Builder.RegisterInstance(this).Named(currentContainer, typeof(AutofacContainerExtension));
|
||||
Builder.RegisterInstance(this).As<IContainerExtension>();
|
||||
Builder.RegisterInstance(this).As<IContainerProvider>();
|
||||
}
|
||||
public IScopedProvider CreateScope()
|
||||
{
|
||||
return CreateScopeInternal();
|
||||
}
|
||||
protected IScopedProvider CreateScopeInternal()
|
||||
{
|
||||
_currentScope = new AutofacScopedProvider(Instance);
|
||||
return _currentScope;
|
||||
}
|
||||
public void FinalizeExtension()
|
||||
{
|
||||
if (Instance != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Assembly[] assemblies = AppTypeFinder.Assemblies.ToArray();
|
||||
|
||||
// Make sure any not specifically registered concrete type can resolve.
|
||||
IEnumerable<IStartup> startupList = ReflectionHelper.GetInstancesByInterface<IStartup>(assemblies);
|
||||
int index = 1;
|
||||
foreach (IStartup item in startupList.OrderByDescending(a => a.Priority))
|
||||
{
|
||||
Debug.WriteLine($"Startup - {index++} : {item.GetType()}");
|
||||
item.Initialize();
|
||||
}
|
||||
|
||||
// Make sure any not specifically registered concrete type can resolve.
|
||||
IEnumerable<IDependencyRegistrar> ListDependency = ReflectionHelper.GetInstancesByInterface<IDependencyRegistrar>(assemblies);
|
||||
foreach (IDependencyRegistrar item in ListDependency)
|
||||
{
|
||||
item.Register(Builder);
|
||||
}
|
||||
|
||||
IEnumerable<IPreRegisterTypes> PreRegisterTypes = ReflectionHelper.GetInstancesByInterface<IPreRegisterTypes>(assemblies);
|
||||
foreach (IPreRegisterTypes item in PreRegisterTypes)
|
||||
{
|
||||
item.RegisterTypes(this);
|
||||
}
|
||||
|
||||
Builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource());
|
||||
Instance = Builder.Build();
|
||||
IocManager.SetContainer(Instance);
|
||||
|
||||
}
|
||||
|
||||
public bool IsRegistered(Type type)
|
||||
{
|
||||
return Instance.IsRegistered(type);
|
||||
}
|
||||
|
||||
public bool IsRegistered(Type type, string name)
|
||||
{
|
||||
return Instance.IsRegisteredWithName(name, type);
|
||||
}
|
||||
|
||||
public IContainerRegistry Register(Type from, Type to)
|
||||
{
|
||||
Builder.RegisterType(to).As(from);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IContainerRegistry Register(Type from, Type to, string name)
|
||||
{
|
||||
Builder.RegisterType(to).Named(name, from);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public IContainerRegistry RegisterInstance(Type type, object instance)
|
||||
{
|
||||
Builder.RegisterInstance(instance).As(type);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IContainerRegistry RegisterInstance(Type type, object instance, string name)
|
||||
{
|
||||
Builder.RegisterInstance(instance).Named(name, type);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IContainerRegistry RegisterSingleton(Type from, Type to)
|
||||
{
|
||||
Builder.RegisterType(to).As(from).SingleInstance();
|
||||
return this;
|
||||
}
|
||||
|
||||
public IContainerRegistry RegisterSingleton(Type from, Type to, string name)
|
||||
{
|
||||
Builder.RegisterType(to).Named(name, from).SingleInstance();
|
||||
return this;
|
||||
}
|
||||
|
||||
public IContainerRegistry RegisterSingleton(Type type, Func<object> factoryMethod)
|
||||
{
|
||||
Debugger.Break();
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IContainerRegistry RegisterSingleton(Type type, Func<IContainerProvider, object> factoryMethod)
|
||||
{
|
||||
Debugger.Break();
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public object Resolve(Type type)
|
||||
{
|
||||
return Instance.Resolve(type);
|
||||
}
|
||||
|
||||
public object Resolve(Type type, params (Type Type, object Instance)[] parameters)
|
||||
{
|
||||
List<TypedParameter> listps = new List<TypedParameter>();
|
||||
foreach ((Type Type, object Instance) item in parameters)
|
||||
{
|
||||
TypedParameter ps = new TypedParameter(item.Type, item.Instance);
|
||||
listps.Add(ps);
|
||||
}
|
||||
return Instance.Resolve(type, listps);
|
||||
}
|
||||
|
||||
public object Resolve(Type type, string name)
|
||||
{
|
||||
return Instance.ResolveNamed(name, type);
|
||||
}
|
||||
|
||||
public object Resolve(Type type, string name, params (Type Type, object Instance)[] parameters)
|
||||
{
|
||||
List<TypedParameter> listps = new List<TypedParameter>();
|
||||
foreach ((Type Type, object Instance) item in parameters)
|
||||
{
|
||||
TypedParameter ps = new TypedParameter(item.Type, item.Instance);
|
||||
listps.Add(ps);
|
||||
}
|
||||
return Instance.ResolveNamed(name, type, listps);
|
||||
}
|
||||
|
||||
public IContainerRegistry Register(Type type, Func<object> factoryMethod)
|
||||
{
|
||||
Debugger.Break();
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IContainerRegistry Register(Type type, Func<IContainerProvider, object> factoryMethod)
|
||||
{
|
||||
Debugger.Break();
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
public IContainerRegistry RegisterMany(Type type, params Type[] serviceTypes)
|
||||
{
|
||||
Debugger.Break();
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IContainerRegistry RegisterManySingleton(Type type, params Type[] serviceTypes)
|
||||
{
|
||||
Debugger.Break();
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IContainerRegistry RegisterScoped(Type from, Type to)
|
||||
{
|
||||
Debugger.Break();
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IContainerRegistry RegisterScoped(Type type, Func<object> factoryMethod)
|
||||
{
|
||||
Debugger.Break();
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IContainerRegistry RegisterScoped(Type type, Func<IContainerProvider, object> factoryMethod)
|
||||
{
|
||||
Debugger.Break();
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Type GetRegistrationType(string key)
|
||||
{
|
||||
Type retType = null;
|
||||
//First try friendly name registration. If not found, try type registration
|
||||
foreach (IComponentRegistration registration in Instance.ComponentRegistry.Registrations)
|
||||
{
|
||||
//System.Diagnostics.Debug.WriteLine(registration.ToString());
|
||||
foreach (Service service in registration.Services)
|
||||
{
|
||||
//System.Diagnostics.Debug.WriteLine(service.ToString());
|
||||
if (service is KeyedService ks)
|
||||
{
|
||||
if (key.Equals(ks.ServiceKey.ToString(), StringComparison.Ordinal))
|
||||
{
|
||||
if (Instance.ComponentRegistry.TryGetServiceRegistration(service, out ServiceRegistration serviceRegistration))
|
||||
{
|
||||
retType = serviceRegistration.Registration.Target.Activator.LimitType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Instance.TryResolveService
|
||||
//retType = Instance.ResolveNamed<object>(key).GetType();
|
||||
if (retType == null)
|
||||
{
|
||||
retType = Instance.ResolveNamed<object>(key).GetType();
|
||||
if (retType == null)
|
||||
{
|
||||
retType = typeof(System.Object);
|
||||
}
|
||||
}
|
||||
return retType;
|
||||
}
|
||||
|
||||
public Type GetRegistrationType(Type serviceType)
|
||||
{
|
||||
Debugger.Break();
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private class AutofacScopedProvider : IScopedProvider
|
||||
{
|
||||
private readonly IContainer _container;
|
||||
|
||||
public bool IsAttached { get; set; }
|
||||
|
||||
public IScopedProvider CurrentScope => this;
|
||||
|
||||
public IScopedProvider CreateScope()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
public AutofacScopedProvider(IContainer container)
|
||||
{
|
||||
_container = container;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_container.Dispose();
|
||||
}
|
||||
|
||||
public object Resolve(Type type)
|
||||
{
|
||||
return _container.Resolve(type);
|
||||
}
|
||||
|
||||
public object Resolve(Type type, params (Type Type, object Instance)[] parameters)
|
||||
{
|
||||
List<TypedParameter> listps = new List<TypedParameter>();
|
||||
foreach ((Type Type, object Instance) item in parameters)
|
||||
{
|
||||
TypedParameter ps = new TypedParameter(item.Type, item.Instance);
|
||||
listps.Add(ps);
|
||||
}
|
||||
return _container.Resolve(type, listps);
|
||||
}
|
||||
|
||||
public object Resolve(Type type, string name)
|
||||
{
|
||||
return _container.ResolveNamed(name, type);
|
||||
}
|
||||
|
||||
public object Resolve(Type type, string name, params (Type Type, object Instance)[] parameters)
|
||||
{
|
||||
List<TypedParameter> list = new List<TypedParameter>();
|
||||
foreach ((Type Type, object Instance) item in parameters)
|
||||
{
|
||||
TypedParameter ps = new TypedParameter(item.Type, item.Instance);
|
||||
list.Add(ps);
|
||||
}
|
||||
return _container.ResolveNamed(name, type, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using Autofac;
|
||||
using Prism.Ioc;
|
||||
|
||||
namespace Prism.Autofac
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides customization extensions for Autofac Applications
|
||||
/// </summary>
|
||||
public interface IAutofacContainerExtension : IContainerExtension<IContainer>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ContainerBuilder"/> used to register the services for the application
|
||||
/// </summary>
|
||||
ContainerBuilder Builder { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using Prism.Ioc;
|
||||
|
||||
namespace MAX.Framework.Prism.Autofac
|
||||
{
|
||||
public interface IPreRegisterTypes
|
||||
{
|
||||
void RegisterTypes(IContainerRegistry containerRegistry);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using Prism.Ioc;
|
||||
using System;
|
||||
using System.Windows;
|
||||
using AutofacCore = Autofac.Core;
|
||||
|
||||
namespace Prism.Autofac
|
||||
{
|
||||
/// <summary>
|
||||
/// Base application class that uses <see cref="UnityContainerExtension"/> as it's container.
|
||||
/// </summary>
|
||||
public abstract class PrismApplication : PrismApplicationBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Create a new <see cref="UnityContainerExtension"/> used by Prism.
|
||||
/// </summary>
|
||||
/// <returns>A new <see cref="UnityContainerExtension"/>.</returns>
|
||||
protected override IContainerExtension CreateContainerExtension()
|
||||
{
|
||||
return new AutofacContainerExtension();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers the <see cref="Type"/>s of the Exceptions that are not considered
|
||||
/// root exceptions by the <see cref="ExceptionExtensions"/>.
|
||||
/// </summary>
|
||||
protected override void RegisterFrameworkExceptionTypes()
|
||||
{
|
||||
ExceptionExtensions.RegisterFrameworkExceptionType(typeof(AutofacCore.DependencyResolutionException));
|
||||
ExceptionExtensions.RegisterFrameworkExceptionType(typeof(AutofacCore.Registration.ComponentNotRegisteredException));
|
||||
|
||||
}
|
||||
|
||||
protected override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
}
|
||||
|
||||
|
||||
protected override Window CreateShell()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using Prism.Ioc;
|
||||
using System;
|
||||
using AutofacCore = Autofac.Core;
|
||||
|
||||
namespace Prism.Autofac
|
||||
{
|
||||
/// <summary>
|
||||
/// Base bootstrapper class that uses <see cref="UnityContainerExtension"/> as it's container.
|
||||
/// </summary>
|
||||
public abstract class PrismBootstrapper : PrismBootstrapperBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Create a new <see cref="UnityContainerExtension"/> used by Prism.
|
||||
/// </summary>
|
||||
/// <returns>A new <see cref="UnityContainerExtension"/>.</returns>
|
||||
protected override IContainerExtension CreateContainerExtension()
|
||||
{
|
||||
return new AutofacContainerExtension();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers the <see cref="Type"/>s of the Exceptions that are not considered
|
||||
/// root exceptions by the <see cref="ExceptionExtensions"/>.
|
||||
/// </summary>
|
||||
protected override void RegisterFrameworkExceptionTypes()
|
||||
{
|
||||
ExceptionExtensions.RegisterFrameworkExceptionType(typeof(AutofacCore.DependencyResolutionException));
|
||||
ExceptionExtensions.RegisterFrameworkExceptionType(typeof(AutofacCore.Registration.ComponentNotRegisteredException));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using Autofac;
|
||||
using Prism.Ioc;
|
||||
|
||||
namespace Prism.Autofac
|
||||
{
|
||||
/// <summary>
|
||||
/// Extensions help get the underlying <see cref="IUnityContainer" />
|
||||
/// </summary>
|
||||
public static class PrismIocExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IUnityContainer" /> from the <see cref="IContainerProvider" />
|
||||
/// </summary>
|
||||
/// <param name="containerProvider">The current <see cref="IContainerProvider" /></param>
|
||||
/// <returns>The underlying <see cref="IUnityContainer" /></returns>
|
||||
public static IContainer GetContainer(this IContainerProvider containerProvider)
|
||||
{
|
||||
return ((IContainerExtension<IContainer>)containerProvider).Instance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IUnityContainer" /> from the <see cref="IContainerProvider" />
|
||||
/// </summary>
|
||||
/// <param name="containerRegistry">The current <see cref="IContainerRegistry" /></param>
|
||||
/// <returns>The underlying <see cref="IUnityContainer" /></returns>
|
||||
public static IContainer GetContainer(this IContainerRegistry containerRegistry)
|
||||
{
|
||||
return ((IContainerExtension<IContainer>)containerRegistry).Instance;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ContainerBuilder"/> used to register services.
|
||||
/// </summary>
|
||||
/// <param name="registry"></param>
|
||||
/// <returns>The current <see cref="ContainerBuilder"/></returns>
|
||||
public static ContainerBuilder GetBuilder(this IContainerRegistry registry)
|
||||
{
|
||||
return ((IAutofacContainerExtension)registry).Builder;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using Prism.Regions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using Autofac;
|
||||
using Autofac.Core;
|
||||
using System.Windows.Input;
|
||||
using MAX.Core.DependencyInjection;
|
||||
namespace MAX.Framework.PrismExtension;
|
||||
public static class RegionManagerExtension
|
||||
{
|
||||
public static FrameworkElement GetView(this IRegionManager regionManager, string regionName, string target)
|
||||
{
|
||||
var region = regionManager.Regions[regionName];
|
||||
if (region != null)
|
||||
{
|
||||
|
||||
var viewType = IocManager.GetRegistrationType(target);
|
||||
foreach (var viewItem in region.Views)
|
||||
{
|
||||
if (viewItem.GetType() == viewType)
|
||||
{
|
||||
if (viewItem is FrameworkElement fk)
|
||||
{
|
||||
return fk;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
using Autofac;
|
||||
using MAX.Core;
|
||||
using MAX.Core.Autofac;
|
||||
using MAX.Core.DependencyInjection;
|
||||
using MAX.Core.Infrastructure;
|
||||
using MAX.Core.Logger;
|
||||
using MAX.Core.Reflections;
|
||||
using MAX.Framework.Logger;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace MAX.Framework;
|
||||
|
||||
public class Startup : IStartup
|
||||
{
|
||||
public int Priority => int.MaxValue - 1;
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void Register(ContainerBuilder builder)
|
||||
{
|
||||
#region 注册所有IOC接口
|
||||
|
||||
Assembly[] assemblies = AppTypeFinder.Assemblies.ToArray();
|
||||
|
||||
Type typeSingleton = typeof(ISingletonDependency);
|
||||
builder.RegisterAssemblyTypes(assemblies)
|
||||
.Where(a =>
|
||||
typeSingleton.IsAssignableFrom(a)
|
||||
&& a.IsClass
|
||||
&& !a.IsAbstract
|
||||
)
|
||||
.AsImplementedInterfaces()
|
||||
.AsSelf()
|
||||
.SingleInstance();
|
||||
|
||||
|
||||
Type typeTransient = typeof(ITransientDependency);
|
||||
builder.RegisterAssemblyTypes(assemblies)
|
||||
.Where(a =>
|
||||
typeTransient.IsAssignableFrom(a)
|
||||
&& a.IsClass
|
||||
&& !a.IsAbstract
|
||||
)
|
||||
.AsImplementedInterfaces()
|
||||
.AsSelf()
|
||||
.InstancePerDependency();
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Store.Client.Agent
|
||||
{
|
||||
/// <summary>
|
||||
/// 代理配置
|
||||
/// </summary>
|
||||
public class AgentConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 代理码
|
||||
/// </summary>
|
||||
public static string AgentCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 代理名称
|
||||
/// </summary>
|
||||
public static string AgentName { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Store.Framework.Apis;
|
||||
|
||||
public class ApiResponse<T>
|
||||
{
|
||||
public int Code { get; set; }
|
||||
|
||||
public string Msg { get; set; }
|
||||
|
||||
public T Data { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
using MAX.Core.DependencyInjection;
|
||||
using MAX.Core.Helpers;
|
||||
using Store.Client.HttpExtension;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Store.Client.Apis
|
||||
{
|
||||
/// <summary>
|
||||
/// 公共基础数据Api
|
||||
/// </summary>
|
||||
public partial class CommonApi : AppApiRequestBase, ITransientDependency
|
||||
{
|
||||
#region 公共基础
|
||||
/// <summary>
|
||||
/// 获取服务器时间校准时间
|
||||
/// </summary>
|
||||
public DateTime GetServerTime()
|
||||
{
|
||||
HttpResult result = ServerRequest(new HttpItem { URL = $"{_config.Host}/time.php" });
|
||||
if (result.StatusCode == HttpStatusCode.OK)
|
||||
{
|
||||
if (DateTime.TryParse(result.Html, out DateTime dt))
|
||||
{
|
||||
return dt;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("连接服务器失败,将导致无法登录");
|
||||
}
|
||||
|
||||
}
|
||||
return DateTime.Now;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取签名验证配置
|
||||
/// </summary>
|
||||
public string GetAuthConfig()
|
||||
{
|
||||
HttpItem item = new HttpItem();
|
||||
item.URL = $"{_config.Host}?obj=api/config&act=auth_config";
|
||||
HttpResult result = ServerRequest(item);
|
||||
if (result.StatusCode == HttpStatusCode.OK)
|
||||
{
|
||||
return result.Html;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取缓存服务集群负载比例
|
||||
/// </summary>
|
||||
public string GetCacheServerRatio()
|
||||
{
|
||||
|
||||
HttpItem item = new HttpItem();
|
||||
item.URL = _config.Host + "?" + _config.ObjUrl + "config&act=cache_service_mode";
|
||||
item.Method = MethodType.Post;
|
||||
//item.SignUser();
|
||||
HttpResult result = ServerRequest(item);
|
||||
if (result.StatusCode == HttpStatusCode.OK)
|
||||
{
|
||||
return result.Html;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
#endregion
|
||||
|
||||
///// <summary>
|
||||
///// 获取服务器图片缓存
|
||||
///// </summary>
|
||||
///// <param name="imgUrl"></param>
|
||||
///// <returns></returns>
|
||||
//public HttpResult GetImageCache(string imgUrl)
|
||||
//{
|
||||
// long id = MD5Helper.GetLong(imgUrl);
|
||||
// HttpItem item = new HttpItem();
|
||||
// item.Method = MethodType.Post;
|
||||
// item.URL = _config.Host + "?" + _config.ObjUrl + "add_img";
|
||||
// item.Postdata = "act=get&table=" + Math.Abs(id % 1024) + "&id=" + id;
|
||||
// return ServerRequest(item);
|
||||
//}
|
||||
|
||||
#region 默认服务接口
|
||||
/// <summary>
|
||||
/// common&act=get_agent_ip
|
||||
/// </summary>
|
||||
public HttpResult GetAgentIp(string postdata = "")
|
||||
{
|
||||
return Post("common&act=get_agent_ip", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// config&act=get_service_url
|
||||
/// </summary>
|
||||
public HttpResult GetServiceUrl(string postdata = "")
|
||||
{
|
||||
return Post("config&act=get_service_url", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// cookies&act=save
|
||||
/// </summary>
|
||||
public HttpResult SaveCookies(string postdata = "")
|
||||
{
|
||||
return Post("cookies&act=save", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// data_change&act=get_cache_title
|
||||
/// </summary>
|
||||
public HttpResult GetCacheTitle(string postdata = "")
|
||||
{
|
||||
return Post("data_change&act=get_cache_title", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// data_change&act=get_pid
|
||||
/// </summary>
|
||||
public HttpResult GetPid(string postdata = "")
|
||||
{
|
||||
return Post("data_change&act=get_pid", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// decode&act=get
|
||||
/// </summary>
|
||||
public HttpResult GetDecode(string postdata = "")
|
||||
{
|
||||
return Post("decode&act=get", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// decode&act=getx
|
||||
/// </summary>
|
||||
public HttpResult GetDecodeList(string postdata = "")
|
||||
{
|
||||
return Post("decode&act=getx", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// get_taobao_sign&act=get_tb_sign
|
||||
/// </summary>
|
||||
public HttpResult GetTaobaoSign(string postdata = "")
|
||||
{
|
||||
return Post("get_taobao_sign&act=get_tb_sign", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// nav_group_list
|
||||
/// </summary>
|
||||
public HttpResult GetNavGroupList(string postdata = "")
|
||||
{
|
||||
return Post("nav_group_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// oem_config&act=get_config_info
|
||||
/// </summary>
|
||||
public HttpResult GetOemConfigInfo(string postdata = "")
|
||||
{
|
||||
return Post("oem_config&act=get_config_info", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// oem_config&act=get_version
|
||||
/// </summary>
|
||||
public HttpResult GetOemVersion(string postdata = "")
|
||||
{
|
||||
return Post("oem_config&act=get_version", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// regedit
|
||||
/// </summary>
|
||||
public HttpResult Regedit(string postdata = "")
|
||||
{
|
||||
return PostPublic("regedit", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// reset_password
|
||||
/// </summary>
|
||||
public HttpResult ResetPassword(string postdata = "")
|
||||
{
|
||||
return PostPublic("reset_password", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// sign
|
||||
/// </summary>
|
||||
public HttpResult GetPackageSign(string postdata = "")
|
||||
{
|
||||
return Post("sign", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// sign&act=get&type={type}&client_id={clientId}
|
||||
/// </summary>
|
||||
public HttpResult GetSign(string type, string clientId, string postdata = "")
|
||||
{
|
||||
return Post("sign&act=get&type=" + type + "&client_id=" + clientId, postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// sms_gate
|
||||
/// </summary>
|
||||
public HttpResult SmsGate(string postdata = "")
|
||||
{
|
||||
return PostPublic("sms_gate", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// upid&act=getx&page={page}
|
||||
/// </summary>
|
||||
public HttpResult GetUpidList(int page, string postdata = "")
|
||||
{
|
||||
return Post("upid&act=getx&page=" + page, postdata);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 默认兼容接口
|
||||
/// <summary>
|
||||
/// update/get_update_new
|
||||
/// </summary>
|
||||
public HttpResult DefaultUpdateGetUpdateNew(string postdata = "")
|
||||
{
|
||||
return PostDefault("update/get_update_new", postdata);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
using MAX.Core.DependencyInjection;
|
||||
using MAX.Core.Helpers;
|
||||
using Store.Client.HttpExtension;
|
||||
|
||||
namespace Store.Client.Apis
|
||||
{
|
||||
public partial class OrderApi : AppApiRequestBase, ITransientDependency
|
||||
{
|
||||
#region 默认服务接口
|
||||
/// <summary>
|
||||
/// order/add_order
|
||||
/// </summary>
|
||||
public HttpResult AddOrder(string postdata = "")
|
||||
{
|
||||
return Post("order/add_order", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// order/add_order_code_file
|
||||
/// </summary>
|
||||
public HttpResult AddOrderCodeFile(string postdata = "")
|
||||
{
|
||||
return Post("order/add_order_code_file", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// order/get_order_code_file
|
||||
/// </summary>
|
||||
public HttpResult GetOrderCodeFile(string postdata = "")
|
||||
{
|
||||
return Post("order/get_order_code_file", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// order/get_order_list
|
||||
/// </summary>
|
||||
public HttpResult GetOrderList(string postdata = "")
|
||||
{
|
||||
return Post("order/get_order_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// order/save_order_code_file_link
|
||||
/// </summary>
|
||||
public HttpResult SaveOrderCodeFileLink(string postdata = "")
|
||||
{
|
||||
return Post("order/save_order_code_file_link", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// order/update_order_status
|
||||
/// </summary>
|
||||
public HttpResult UpdateOrderStatus(string postdata = "")
|
||||
{
|
||||
return Post("order/update_order_status", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// order/update_order_status1
|
||||
/// </summary>
|
||||
public HttpResult UpdateOrderStatus1(string postdata = "")
|
||||
{
|
||||
return Post("order/update_order_status1", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// order/upload_order
|
||||
/// </summary>
|
||||
public HttpResult UploadOrder(string postdata = "")
|
||||
{
|
||||
return Post("order/upload_order", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// pay_group_order&act=get_confirm_order&buy_type={buyType}&page={page}
|
||||
/// </summary>
|
||||
public HttpResult GetPayGroupConfirmOrder(string buyType, int page, string postdata = "")
|
||||
{
|
||||
return Post("pay_group_order&act=get_confirm_order&buy_type=" + buyType + "&page=" + page, postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// pay_group_order&act=reset_status
|
||||
/// </summary>
|
||||
public HttpResult ResetPayGroupOrderStatus(string postdata = "")
|
||||
{
|
||||
return Post("pay_group_order&act=reset_status", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// pay_group_order&act=update&buy_type={buyType}
|
||||
/// </summary>
|
||||
public HttpResult UpdatePayGroupOrder(string buyType, string postdata = "")
|
||||
{
|
||||
return Post("pay_group_order&act=update&buy_type=" + buyType, postdata);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 微信服务接口
|
||||
/// <summary>
|
||||
/// order/get_erp_order_list
|
||||
/// </summary>
|
||||
public HttpResult WxGetErpOrderList(string postdata = "")
|
||||
{
|
||||
return PostWx("order/get_erp_order_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// order/wx_del_erp_transit_warehouse_order
|
||||
/// </summary>
|
||||
public HttpResult WxDelErpTransitWarehouseOrder(string postdata = "")
|
||||
{
|
||||
return PostWx("order/wx_del_erp_transit_warehouse_order", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// order/wx_get_transit_order
|
||||
/// </summary>
|
||||
public HttpResult WxGetTransitOrder(string postdata = "")
|
||||
{
|
||||
return PostWx("order/wx_get_transit_order", postdata);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
using MAX.Core.DependencyInjection;
|
||||
using MAX.Core.Helpers;
|
||||
using Store.Client.HttpExtension;
|
||||
|
||||
namespace Store.Client.Apis
|
||||
{
|
||||
public partial class PriceApi : AppApiRequestBase, ITransientDependency
|
||||
{
|
||||
#region 默认服务接口
|
||||
/// <summary>
|
||||
/// price/add_price
|
||||
/// </summary>
|
||||
public HttpResult AddPrice(string postdata = "")
|
||||
{
|
||||
return Post("price/add_price", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// price/add_purchase_price
|
||||
/// </summary>
|
||||
public HttpResult AddPurchasePrice(string postdata = "")
|
||||
{
|
||||
return Post("price/add_purchase_price", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// price/del_db_price
|
||||
/// </summary>
|
||||
public HttpResult DelDbPrice(string postdata = "")
|
||||
{
|
||||
return Post("price/del_db_price", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// price/get_price_list
|
||||
/// </summary>
|
||||
public HttpResult GetPriceList(string postdata = "")
|
||||
{
|
||||
return Post("price/get_price_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// price/get_purchase_price_list
|
||||
/// </summary>
|
||||
public HttpResult GetPurchasePriceList(string postdata = "")
|
||||
{
|
||||
return Post("price/get_purchase_price_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// price/mdy_db_price
|
||||
/// </summary>
|
||||
public HttpResult MdyDbPrice(string postdata = "")
|
||||
{
|
||||
return Post("price/mdy_db_price", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// price/mdy_purchase_price
|
||||
/// </summary>
|
||||
public HttpResult MdyPurchasePrice(string postdata = "")
|
||||
{
|
||||
return Post("price/mdy_purchase_price", postdata);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 拼多多服务接口
|
||||
/// <summary>
|
||||
/// price/add_ext_code_price
|
||||
/// </summary>
|
||||
public HttpResult PddAddExtCodePrice(string postdata = "")
|
||||
{
|
||||
return PostPdd("price/add_ext_code_price", postdata);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,654 @@
|
||||
using MAX.Core.DependencyInjection;
|
||||
using MAX.Core.Helpers;
|
||||
using Store.Client.HttpExtension;
|
||||
|
||||
namespace Store.Client.Apis
|
||||
{
|
||||
public partial class ProductApi : AppApiRequestBase, ITransientDependency
|
||||
{
|
||||
#region 默认服务接口
|
||||
/// <summary>
|
||||
/// product/add_cate_size_weight_config_v2
|
||||
/// </summary>
|
||||
public HttpResult AddCateSizeWeightConfigV2(string postdata = "")
|
||||
{
|
||||
return Post("product/add_cate_size_weight_config_v2", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/add_product
|
||||
/// </summary>
|
||||
public HttpResult AddProduct(string postdata = "")
|
||||
{
|
||||
return Post("product/add_product", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/add_sku_image
|
||||
/// </summary>
|
||||
public HttpResult AddSkuImage(string postdata = "")
|
||||
{
|
||||
return Post("product/add_sku_image", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/add_sku_img
|
||||
/// </summary>
|
||||
public HttpResult AddSkuImg(string postdata = "")
|
||||
{
|
||||
return Post("product/add_sku_img", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/add_sku_img_replace
|
||||
/// </summary>
|
||||
public HttpResult AddSkuImgReplace(string postdata = "")
|
||||
{
|
||||
return Post("product/add_sku_img_replace", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/add_user_select_product
|
||||
/// </summary>
|
||||
public HttpResult AddUserSelectProduct(string postdata = "")
|
||||
{
|
||||
return Post("product/add_user_select_product", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/admin_get_user_select_product_list
|
||||
/// </summary>
|
||||
public HttpResult AdminGetUserSelectProductList(string postdata = "")
|
||||
{
|
||||
return Post("product/admin_get_user_select_product_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/del_db_product
|
||||
/// </summary>
|
||||
public HttpResult DelDbProduct(string postdata = "")
|
||||
{
|
||||
return Post("product/del_db_product", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/del_select_product
|
||||
/// </summary>
|
||||
public HttpResult DelSelectProduct(string postdata = "")
|
||||
{
|
||||
return Post("product/del_select_product", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/del_sku_image
|
||||
/// </summary>
|
||||
public HttpResult DelSkuImage(string postdata = "")
|
||||
{
|
||||
return Post("product/del_sku_image", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/get_cate_size_weight_config_v2
|
||||
/// </summary>
|
||||
public HttpResult GetCateSizeWeightConfigV2(string postdata = "")
|
||||
{
|
||||
return Post("product/get_cate_size_weight_config_v2", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/get_pdd_prod_wx_complate_list
|
||||
/// </summary>
|
||||
public HttpResult GetPddProdWxComplateList(string postdata = "")
|
||||
{
|
||||
return Post("product/get_pdd_prod_wx_complate_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/get_pdd_product_cates
|
||||
/// </summary>
|
||||
public HttpResult GetPddProductCates(string postdata = "")
|
||||
{
|
||||
return Post("product/get_pdd_product_cates", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/get_pdd_product_detail_list
|
||||
/// </summary>
|
||||
public HttpResult GetPddProductDetailList(string postdata = "")
|
||||
{
|
||||
return Post("product/get_pdd_product_detail_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/get_pdd_product_list_random
|
||||
/// </summary>
|
||||
public HttpResult GetPddProductListRandom(string postdata = "")
|
||||
{
|
||||
return Post("product/get_pdd_product_list_random", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/get_product_detail_list
|
||||
/// </summary>
|
||||
public HttpResult GetProductDetailList(string postdata = "")
|
||||
{
|
||||
return Post("product/get_product_detail_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/get_product_group_list
|
||||
/// </summary>
|
||||
public HttpResult GetProductGroupList(string postdata = "")
|
||||
{
|
||||
return Post("product/get_product_group_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/get_product_list
|
||||
/// </summary>
|
||||
public HttpResult GetProductList(string postdata = "")
|
||||
{
|
||||
return Post("product/get_product_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/get_product_list_random
|
||||
/// </summary>
|
||||
public HttpResult GetProductListRandom(string postdata = "")
|
||||
{
|
||||
return Post("product/get_product_list_random", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/get_random_company_product_config
|
||||
/// </summary>
|
||||
public HttpResult GetRandomCompanyProductConfig(string postdata = "")
|
||||
{
|
||||
return Post("product/get_random_company_product_config", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/get_select_prod_db_id_map_draft_id_list
|
||||
/// </summary>
|
||||
public HttpResult GetSelectProdDbIdMapDraftIdList(string postdata = "")
|
||||
{
|
||||
return Post("product/get_select_prod_db_id_map_draft_id_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/get_select_prod_map_up_spu_id_list
|
||||
/// </summary>
|
||||
public HttpResult GetSelectProdMapUpSpuIdList(string postdata = "")
|
||||
{
|
||||
return Post("product/get_select_prod_map_up_spu_id_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/get_sku_image_list
|
||||
/// </summary>
|
||||
public HttpResult GetSkuImageList(string postdata = "")
|
||||
{
|
||||
return Post("product/get_sku_image_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/get_sku_img_replace_list
|
||||
/// </summary>
|
||||
public HttpResult GetSkuImgReplaceList(string postdata = "")
|
||||
{
|
||||
return Post("product/get_sku_img_replace_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/get_sku_replace_img_list_random
|
||||
/// </summary>
|
||||
public HttpResult GetSkuReplaceImgListRandom(string postdata = "")
|
||||
{
|
||||
return Post("product/get_sku_replace_img_list_random", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/get_user_select_product_list
|
||||
/// </summary>
|
||||
public HttpResult GetUserSelectProductList(string postdata = "")
|
||||
{
|
||||
return Post("product/get_user_select_product_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/is_get_wx_recommend_hot_prod
|
||||
/// </summary>
|
||||
public HttpResult IsGetWxRecommendHotProd(string postdata = "")
|
||||
{
|
||||
return Post("product/is_get_wx_recommend_hot_prod", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/mdy_base64_img_url
|
||||
/// </summary>
|
||||
public HttpResult MdyBase64ImgUrl(string postdata = "")
|
||||
{
|
||||
return Post("product/mdy_base64_img_url", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/mdy_base64_img_use_count
|
||||
/// </summary>
|
||||
public HttpResult MdyBase64ImgUseCount(string postdata = "")
|
||||
{
|
||||
return Post("product/mdy_base64_img_use_count", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/mdy_best_sale_prod
|
||||
/// </summary>
|
||||
public HttpResult MdyBestSaleProd(string postdata = "")
|
||||
{
|
||||
return Post("product/mdy_best_sale_prod", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/mdy_db_product
|
||||
/// </summary>
|
||||
public HttpResult MdyDbProduct(string postdata = "")
|
||||
{
|
||||
return Post("product/mdy_db_product", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/mdy_product
|
||||
/// </summary>
|
||||
public HttpResult MdyProduct(string postdata = "")
|
||||
{
|
||||
return Post("product/mdy_product", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/mdy_product_category
|
||||
/// </summary>
|
||||
public HttpResult MdyProductCategory(string postdata = "")
|
||||
{
|
||||
return Post("product/mdy_product_category", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/mdy_product_select_notes
|
||||
/// </summary>
|
||||
public HttpResult MdyProductSelectNotes(string postdata = "")
|
||||
{
|
||||
return Post("product/mdy_product_select_notes", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/mdy_sku_img_replace
|
||||
/// </summary>
|
||||
public HttpResult MdySkuImgReplace(string postdata = "")
|
||||
{
|
||||
return Post("product/mdy_sku_img_replace", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/mdy_user_select_product_status
|
||||
/// </summary>
|
||||
public HttpResult MdyUserSelectProductStatus(string postdata = "")
|
||||
{
|
||||
return Post("product/mdy_user_select_product_status", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/set_random_company_product_config
|
||||
/// </summary>
|
||||
public HttpResult SetRandomCompanyProductConfig(string postdata = "")
|
||||
{
|
||||
return Post("product/set_random_company_product_config", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/set_select_product_sub_sa
|
||||
/// </summary>
|
||||
public HttpResult SetSelectProductSubSa(string postdata = "")
|
||||
{
|
||||
return Post("product/set_select_product_sub_sa", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/wx_add_mdy_after_sale
|
||||
/// </summary>
|
||||
public HttpResult WxAddMdyAfterSale(string postdata = "")
|
||||
{
|
||||
return Post("product/wx_add_mdy_after_sale", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/wx_del_address
|
||||
/// </summary>
|
||||
public HttpResult WxDelAddress(string postdata = "")
|
||||
{
|
||||
return Post("product/wx_del_address", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/wx_del_qualification_image
|
||||
/// </summary>
|
||||
public HttpResult WxDelQualificationImage(string postdata = "")
|
||||
{
|
||||
return Post("product/wx_del_qualification_image", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/wx_get_after_sale
|
||||
/// </summary>
|
||||
public HttpResult WxGetAfterSale(string postdata = "")
|
||||
{
|
||||
return Post("product/wx_get_after_sale", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/wx_get_after_sale_list
|
||||
/// </summary>
|
||||
public HttpResult WxGetAfterSaleList(string postdata = "")
|
||||
{
|
||||
return Post("product/wx_get_after_sale_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/wx_get_qualification_image
|
||||
/// </summary>
|
||||
public HttpResult WxGetQualificationImage(string postdata = "")
|
||||
{
|
||||
return Post("product/wx_get_qualification_image", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/wx_get_random_after_sale_list
|
||||
/// </summary>
|
||||
public HttpResult WxGetRandomAfterSaleList(string postdata = "")
|
||||
{
|
||||
return Post("product/wx_get_random_after_sale_list", postdata);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 拼多多服务接口
|
||||
/// <summary>
|
||||
/// product/add_jst_sku
|
||||
/// </summary>
|
||||
public HttpResult PddAddJstSku(string postdata = "")
|
||||
{
|
||||
return PostPdd("product/add_jst_sku", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/add_mdy_jst_product_ban
|
||||
/// </summary>
|
||||
public HttpResult PddAddMdyJstProductBan(string postdata = "")
|
||||
{
|
||||
return PostPdd("product/add_mdy_jst_product_ban", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/add_prod_down_sku
|
||||
/// </summary>
|
||||
public HttpResult PddAddProdDownSku(string postdata = "")
|
||||
{
|
||||
return PostPdd("product/add_prod_down_sku", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/add_prod_wx_complate
|
||||
/// </summary>
|
||||
public HttpResult PddAddProdWxComplate(string postdata = "")
|
||||
{
|
||||
return PostPdd("product/add_prod_wx_complate", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/add_product
|
||||
/// </summary>
|
||||
public HttpResult PddAddProduct(string postdata = "")
|
||||
{
|
||||
return PostPdd("product/add_product", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/add_product_groups
|
||||
/// </summary>
|
||||
public HttpResult PddAddProductGroups(string postdata = "")
|
||||
{
|
||||
return PostPdd("product/add_product_groups", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/add_product_notes
|
||||
/// </summary>
|
||||
public HttpResult PddAddProductNotes(string postdata = "")
|
||||
{
|
||||
return PostPdd("product/add_product_notes", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/add_relation
|
||||
/// </summary>
|
||||
public HttpResult PddAddRelation(string postdata = "")
|
||||
{
|
||||
return PostPdd("product/add_relation", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/del_db_product
|
||||
/// </summary>
|
||||
public HttpResult PddDelDbProduct(string postdata = "")
|
||||
{
|
||||
return PostPdd("product/del_db_product", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/del_product_groups
|
||||
/// </summary>
|
||||
public HttpResult PddDelProductGroups(string postdata = "")
|
||||
{
|
||||
return PostPdd("product/del_product_groups", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/del_product_notes
|
||||
/// </summary>
|
||||
public HttpResult PddDelProductNotes(string postdata = "")
|
||||
{
|
||||
return PostPdd("product/del_product_notes", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/get_jst_product_coid_list
|
||||
/// </summary>
|
||||
public HttpResult PddGetJstProductCoidList(string postdata = "")
|
||||
{
|
||||
return PostPdd("product/get_jst_product_coid_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/get_jst_sku_list
|
||||
/// </summary>
|
||||
public HttpResult PddGetJstSkuList(string postdata = "")
|
||||
{
|
||||
return PostPdd("product/get_jst_sku_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/get_prod_down_sku_lst_by_sku_codes
|
||||
/// </summary>
|
||||
public HttpResult PddGetProdDownSkuLstBySkuCodes(string postdata = "")
|
||||
{
|
||||
return PostPdd("product/get_prod_down_sku_lst_by_sku_codes", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/get_product_detail_list
|
||||
/// </summary>
|
||||
public HttpResult PddGetProductDetailList(string postdata = "")
|
||||
{
|
||||
return PostPdd("product/get_product_detail_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/get_product_groups
|
||||
/// </summary>
|
||||
public HttpResult PddGetProductGroups(string postdata = "")
|
||||
{
|
||||
return PostPdd("product/get_product_groups", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/get_product_list
|
||||
/// </summary>
|
||||
public HttpResult PddGetProductList(string postdata = "")
|
||||
{
|
||||
return PostPdd("product/get_product_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/get_product_notes
|
||||
/// </summary>
|
||||
public HttpResult PddGetProductNotes(string postdata = "")
|
||||
{
|
||||
return PostPdd("product/get_product_notes", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/get_product_spu_id_list
|
||||
/// </summary>
|
||||
public HttpResult PddGetProductSpuIdList(string postdata = "")
|
||||
{
|
||||
return PostPdd("product/get_product_spu_id_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/get_relation
|
||||
/// </summary>
|
||||
public HttpResult PddGetRelation(string postdata = "")
|
||||
{
|
||||
return PostPdd("product/get_relation", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/mdy_db_product
|
||||
/// </summary>
|
||||
public HttpResult PddMdyDbProduct(string postdata = "")
|
||||
{
|
||||
return PostPdd("product/mdy_db_product", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/mdy_jst_sku
|
||||
/// </summary>
|
||||
public HttpResult PddMdyJstSku(string postdata = "")
|
||||
{
|
||||
return PostPdd("product/mdy_jst_sku", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/mdy_product
|
||||
/// </summary>
|
||||
public HttpResult PddMdyProduct(string postdata = "")
|
||||
{
|
||||
return PostPdd("product/mdy_product", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/mdy_violation_prod
|
||||
/// </summary>
|
||||
public HttpResult PddMdyViolationProd(string postdata = "")
|
||||
{
|
||||
return PostPdd("product/mdy_violation_prod", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/wx_api_category_classify
|
||||
/// </summary>
|
||||
public HttpResult PddWxApiCategoryClassify(string postdata = "")
|
||||
{
|
||||
return PostPdd("product/wx_api_category_classify", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/wx_api_get_all_cate
|
||||
/// </summary>
|
||||
public HttpResult PddWxApiGetAllCate(string postdata = "")
|
||||
{
|
||||
return PostPdd("product/wx_api_get_all_cate", postdata);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 微信服务接口
|
||||
/// <summary>
|
||||
/// product/e57_get_freight_template
|
||||
/// </summary>
|
||||
public HttpResult E57GetFreightTemplate(string postdata = "")
|
||||
{
|
||||
return PostWx("product/e57_get_freight_template", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/get_hot_product_detail_list
|
||||
/// </summary>
|
||||
public HttpResult WxGetHotProductDetailList(string postdata = "")
|
||||
{
|
||||
return PostWx("product/get_hot_product_detail_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/get_hot_product_list
|
||||
/// </summary>
|
||||
public HttpResult WxGetHotProductList(string postdata = "")
|
||||
{
|
||||
return PostWx("product/get_hot_product_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/wx_add_mdy_qualification_image
|
||||
/// </summary>
|
||||
public HttpResult WxAddMdyQualificationImage(string postdata = "")
|
||||
{
|
||||
return PostWx("product/wx_add_mdy_qualification_image", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/wx_add_mdy_shipping_template
|
||||
/// </summary>
|
||||
public HttpResult WxAddMdyShippingTemplate(string postdata = "")
|
||||
{
|
||||
return PostWx("product/wx_add_mdy_shipping_template", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/wx_get_product_latest_buy_amount_list
|
||||
/// </summary>
|
||||
public HttpResult WxGetProductLatestBuyAmountList(string postdata = "")
|
||||
{
|
||||
return PostWx("product/wx_get_product_latest_buy_amount_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product/wx_get_shipping_template
|
||||
/// </summary>
|
||||
public HttpResult WxGetShippingTemplate(string postdata = "")
|
||||
{
|
||||
return PostWx("product/wx_get_shipping_template", postdata);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 微信图片服务接口
|
||||
/// <summary>
|
||||
/// product/wx_api_upload_image
|
||||
/// </summary>
|
||||
public HttpResult WxApiUploadImage(string postdata = "")
|
||||
{
|
||||
return PostWxImg("product/wx_api_upload_image", postdata);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
using MAX.Core.DependencyInjection;
|
||||
using MAX.Core.Helpers;
|
||||
using Store.Client.HttpExtension;
|
||||
|
||||
namespace Store.Client.Apis
|
||||
{
|
||||
public partial class ProductThirdApi : AppApiRequestBase, ITransientDependency
|
||||
{
|
||||
#region 默认服务接口
|
||||
/// <summary>
|
||||
/// product_third/add_product
|
||||
/// </summary>
|
||||
public HttpResult AddProduct(string postdata = "")
|
||||
{
|
||||
return Post("product_third/add_product", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product_third/add_user_select_product
|
||||
/// </summary>
|
||||
public HttpResult AddUserSelectProduct(string postdata = "")
|
||||
{
|
||||
return Post("product_third/add_user_select_product", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product_third/admin_get_user_select_product_list
|
||||
/// </summary>
|
||||
public HttpResult AdminGetUserSelectProductList(string postdata = "")
|
||||
{
|
||||
return Post("product_third/admin_get_user_select_product_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product_third/del_select_product
|
||||
/// </summary>
|
||||
public HttpResult DelSelectProduct(string postdata = "")
|
||||
{
|
||||
return Post("product_third/del_select_product", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product_third/get_product_detail_list
|
||||
/// </summary>
|
||||
public HttpResult GetProductDetailList(string postdata = "")
|
||||
{
|
||||
return Post("product_third/get_product_detail_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product_third/get_product_detail_list_bak
|
||||
/// </summary>
|
||||
public HttpResult GetProductDetailListBak(string postdata = "")
|
||||
{
|
||||
return Post("product_third/get_product_detail_list_bak", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product_third/get_product_list
|
||||
/// </summary>
|
||||
public HttpResult GetProductList(string postdata = "")
|
||||
{
|
||||
return Post("product_third/get_product_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product_third/get_select_prod_db_id_map_draft_id_list
|
||||
/// </summary>
|
||||
public HttpResult GetSelectProdDbIdMapDraftIdList(string postdata = "")
|
||||
{
|
||||
return Post("product_third/get_select_prod_db_id_map_draft_id_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product_third/get_user_select_product_list
|
||||
/// </summary>
|
||||
public HttpResult GetUserSelectProductList(string postdata = "")
|
||||
{
|
||||
return Post("product_third/get_user_select_product_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product_third/mdy_db_product
|
||||
/// </summary>
|
||||
public HttpResult MdyDbProduct(string postdata = "")
|
||||
{
|
||||
return Post("product_third/mdy_db_product", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product_third/mdy_product_category
|
||||
/// </summary>
|
||||
public HttpResult MdyProductCategory(string postdata = "")
|
||||
{
|
||||
return Post("product_third/mdy_product_category", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product_third/mdy_product_select_notes
|
||||
/// </summary>
|
||||
public HttpResult MdyProductSelectNotes(string postdata = "")
|
||||
{
|
||||
return Post("product_third/mdy_product_select_notes", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product_third/mdy_user_select_product_status
|
||||
/// </summary>
|
||||
public HttpResult MdyUserSelectProductStatus(string postdata = "")
|
||||
{
|
||||
return Post("product_third/mdy_user_select_product_status", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// product_third/set_select_product_sub_sa
|
||||
/// </summary>
|
||||
public HttpResult SetSelectProductSubSa(string postdata = "")
|
||||
{
|
||||
return Post("product_third/set_select_product_sub_sa", postdata);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
|
||||
namespace Store.Client.Apis
|
||||
{
|
||||
///// <summary>
|
||||
///// 服务器
|
||||
///// </summary>
|
||||
//public class ServerHttpBase : ITransientDependency
|
||||
//{
|
||||
|
||||
// /// <summary>
|
||||
// /// 日志
|
||||
// /// </summary>
|
||||
// [Autowired]
|
||||
// protected ILog _log { get; set; }
|
||||
|
||||
// /// <summary>
|
||||
// /// 服务器配置
|
||||
// /// </summary>
|
||||
// [Autowired]
|
||||
// protected IServerConfig _config { get; set; }
|
||||
|
||||
// public ServerHttpBase()
|
||||
// {
|
||||
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// /// <summary>
|
||||
// /// 服务器请求
|
||||
// /// </summary>
|
||||
// /// <param name="item"></param>
|
||||
// /// <returns></returns>
|
||||
// public HttpResult ServerRequest(HttpItem item)
|
||||
// {
|
||||
// if (!item.URL.StartsWith("http"))
|
||||
// {
|
||||
// item.URL += _config.Host + item.URL;
|
||||
// }
|
||||
// item.Encoding = Encoding.UTF8;
|
||||
// // ////item
|
||||
// //#if PROXY
|
||||
// // item.ProxyIp = "127.0.0.1:8080";
|
||||
// //#endif
|
||||
// HttpHelper http = new HttpHelper();
|
||||
// HttpResult result = http.GetHtml(item);
|
||||
// if (result.StatusCode == HttpStatusCode.OK)
|
||||
// {
|
||||
// if (!string.IsNullOrEmpty(result.Html))
|
||||
// {
|
||||
// if (result.Html[0] == 65279)
|
||||
// {
|
||||
// result.Html = result.Html.Remove(0, 1);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
|
||||
// }
|
||||
// return result;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
@@ -0,0 +1,472 @@
|
||||
using MAX.Core.DependencyInjection;
|
||||
using MAX.Core.Helpers;
|
||||
using Store.Client.HttpExtension;
|
||||
|
||||
namespace Store.Client.Apis
|
||||
{
|
||||
public partial class ShopApi : AppApiRequestBase, ITransientDependency
|
||||
{
|
||||
#region 默认服务接口
|
||||
/// <summary>
|
||||
/// pdd_shop_temp&act=goup
|
||||
/// </summary>
|
||||
public HttpResult GoupPddShopTemp(string postdata = "")
|
||||
{
|
||||
return Post("pdd_shop_temp&act=goup", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// pdd_shop_tempx&act=get_shop_cookies_list
|
||||
/// </summary>
|
||||
public HttpResult GetPddShopCookiesList(string postdata = "")
|
||||
{
|
||||
return Post("pdd_shop_tempx&act=get_shop_cookies_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop&act=get_shop_token
|
||||
/// </summary>
|
||||
public HttpResult GetShopToken(string postdata = "")
|
||||
{
|
||||
return Post("shop&act=get_shop_token", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop&act=update_mall_id
|
||||
/// </summary>
|
||||
public HttpResult UpdateMallId(string postdata = "")
|
||||
{
|
||||
return Post("shop&act=update_mall_id", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/active_jit_card_code
|
||||
/// </summary>
|
||||
public HttpResult ActiveJitCardCode(string postdata = "")
|
||||
{
|
||||
return Post("shop/active_jit_card_code", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/add_mdy_express_optimize_remark
|
||||
/// </summary>
|
||||
public HttpResult AddMdyExpressOptimizeRemark(string postdata = "")
|
||||
{
|
||||
return Post("shop/add_mdy_express_optimize_remark", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/add_mdy_express_optimize_rst
|
||||
/// </summary>
|
||||
public HttpResult AddMdyExpressOptimizeRst(string postdata = "")
|
||||
{
|
||||
return Post("shop/add_mdy_express_optimize_rst", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/add_mdy_shop_client_info
|
||||
/// </summary>
|
||||
public HttpResult AddMdyShopClientInfo(string postdata = "")
|
||||
{
|
||||
return Post("shop/add_mdy_shop_client_info", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/add_shop
|
||||
/// </summary>
|
||||
public HttpResult AddShop(string postdata = "")
|
||||
{
|
||||
return Post("shop/add_shop", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/add_waybill
|
||||
/// </summary>
|
||||
public HttpResult AddWaybill(string postdata = "")
|
||||
{
|
||||
return Post("shop/add_waybill", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/admin_add_shop
|
||||
/// </summary>
|
||||
public HttpResult AdminAddShop(string postdata = "")
|
||||
{
|
||||
return Post("shop/admin_add_shop", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/admin_del_shop
|
||||
/// </summary>
|
||||
public HttpResult AdminDelShop(string postdata = "")
|
||||
{
|
||||
return Post("shop/admin_del_shop", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/admin_get_shop_list
|
||||
/// </summary>
|
||||
public HttpResult AdminGetShopList(string postdata = "")
|
||||
{
|
||||
return Post("shop/admin_get_shop_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/admin_mdy_shop
|
||||
/// </summary>
|
||||
public HttpResult AdminMdyShop(string postdata = "")
|
||||
{
|
||||
return Post("shop/admin_mdy_shop", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/create_shop_card_code
|
||||
/// </summary>
|
||||
public HttpResult CreateShopCardCode(string postdata = "")
|
||||
{
|
||||
return Post("shop/create_shop_card_code", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/del_shop
|
||||
/// </summary>
|
||||
public HttpResult DelShop(string postdata = "")
|
||||
{
|
||||
return Post("shop/del_shop", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/del_shop_card_code
|
||||
/// </summary>
|
||||
public HttpResult DelShopCardCode(string postdata = "")
|
||||
{
|
||||
return Post("shop/del_shop_card_code", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/del_waybill
|
||||
/// </summary>
|
||||
public HttpResult DelWaybill(string postdata = "")
|
||||
{
|
||||
return Post("shop/del_waybill", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/e57_get_wx_shop_token
|
||||
/// </summary>
|
||||
public HttpResult E57GetWxShopToken(string postdata = "")
|
||||
{
|
||||
return Post("shop/e57_get_wx_shop_token", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/e57_get_wx_tokens
|
||||
/// </summary>
|
||||
public HttpResult E57GetWxTokens(string postdata = "")
|
||||
{
|
||||
return Post("shop/e57_get_wx_tokens", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/get_express_optimize_remark
|
||||
/// </summary>
|
||||
public HttpResult GetExpressOptimizeRemark(string postdata = "")
|
||||
{
|
||||
return Post("shop/get_express_optimize_remark", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/get_express_optimize_rst
|
||||
/// </summary>
|
||||
public HttpResult GetExpressOptimizeRst(string postdata = "")
|
||||
{
|
||||
return Post("shop/get_express_optimize_rst", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/get_shop_card_code_list
|
||||
/// </summary>
|
||||
public HttpResult GetShopCardCodeList(string postdata = "")
|
||||
{
|
||||
return Post("shop/get_shop_card_code_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/get_shop_list
|
||||
/// </summary>
|
||||
public HttpResult GetShopList(string postdata = "")
|
||||
{
|
||||
return Post("shop/get_shop_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/get_waybill
|
||||
/// </summary>
|
||||
public HttpResult GetWaybill(string postdata = "")
|
||||
{
|
||||
return Post("shop/get_waybill", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/get_waybill_no_user_name
|
||||
/// </summary>
|
||||
public HttpResult GetWaybillNoUserName(string postdata = "")
|
||||
{
|
||||
return Post("shop/get_waybill_no_user_name", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/get_weidian_shop
|
||||
/// </summary>
|
||||
public HttpResult GetWeidianShop(string postdata = "")
|
||||
{
|
||||
return Post("shop/get_weidian_shop", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/mdy_anti_content
|
||||
/// </summary>
|
||||
public HttpResult MdyAntiContent(string postdata = "")
|
||||
{
|
||||
return Post("shop/mdy_anti_content", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/mdy_shop
|
||||
/// </summary>
|
||||
public HttpResult MdyShop(string postdata = "")
|
||||
{
|
||||
return Post("shop/mdy_shop", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/mdy_shop_ads_cookie_and_login_status
|
||||
/// </summary>
|
||||
public HttpResult MdyShopAdsCookieAndLoginStatus(string postdata = "")
|
||||
{
|
||||
return Post("shop/mdy_shop_ads_cookie_and_login_status", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/mdy_shop_cookie_and_login_status
|
||||
/// </summary>
|
||||
public HttpResult MdyShopCookieAndLoginStatus(string postdata = "")
|
||||
{
|
||||
return Post("shop/mdy_shop_cookie_and_login_status", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/select_waybill
|
||||
/// </summary>
|
||||
public HttpResult SelectWaybill(string postdata = "")
|
||||
{
|
||||
return Post("shop/select_waybill", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/set_shop_sub_sa
|
||||
/// </summary>
|
||||
public HttpResult SetShopSubSa(string postdata = "")
|
||||
{
|
||||
return Post("shop/set_shop_sub_sa", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/update_add_prod_remaining
|
||||
/// </summary>
|
||||
public HttpResult UpdateAddProdRemaining(string postdata = "")
|
||||
{
|
||||
return Post("shop/update_add_prod_remaining", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/update_used_waybill
|
||||
/// </summary>
|
||||
public HttpResult UpdateUsedWaybill(string postdata = "")
|
||||
{
|
||||
return Post("shop/update_used_waybill", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/wx_add_mdy_29wx_pdd_shop
|
||||
/// </summary>
|
||||
public HttpResult WxAddMdy29wxPddShop(string postdata = "")
|
||||
{
|
||||
return Post("shop/wx_add_mdy_29wx_pdd_shop", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/wx_add_mdy_buy_url_notes
|
||||
/// </summary>
|
||||
public HttpResult WxAddMdyBuyUrlNotes(string postdata = "")
|
||||
{
|
||||
return Post("shop/wx_add_mdy_buy_url_notes", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/wx_add_mdy_order_address
|
||||
/// </summary>
|
||||
public HttpResult WxAddMdyOrderAddress(string postdata = "")
|
||||
{
|
||||
return Post("shop/wx_add_mdy_order_address", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/wx_add_mdy_shop_default_address
|
||||
/// </summary>
|
||||
public HttpResult WxAddMdyShopDefaultAddress(string postdata = "")
|
||||
{
|
||||
return Post("shop/wx_add_mdy_shop_default_address", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/wx_del_shop_default_address
|
||||
/// </summary>
|
||||
public HttpResult WxDelShopDefaultAddress(string postdata = "")
|
||||
{
|
||||
return Post("shop/wx_del_shop_default_address", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/wx_get_29wx_pdd_shop
|
||||
/// </summary>
|
||||
public HttpResult WxGet29wxPddShop(string postdata = "")
|
||||
{
|
||||
return Post("shop/wx_get_29wx_pdd_shop", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/wx_get_buy_url_notes
|
||||
/// </summary>
|
||||
public HttpResult WxGetBuyUrlNotes(string postdata = "")
|
||||
{
|
||||
return Post("shop/wx_get_buy_url_notes", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/wx_get_order_address
|
||||
/// </summary>
|
||||
public HttpResult WxGetOrderAddress(string postdata = "")
|
||||
{
|
||||
return Post("shop/wx_get_order_address", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/wx_get_shop_default_address_list
|
||||
/// </summary>
|
||||
public HttpResult WxGetShopDefaultAddressList(string postdata = "")
|
||||
{
|
||||
return Post("shop/wx_get_shop_default_address_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/wx_mdy_29wx_pdd_cookie_and_login_status
|
||||
/// </summary>
|
||||
public HttpResult WxMdy29wxPddCookieAndLoginStatus(string postdata = "")
|
||||
{
|
||||
return Post("shop/wx_mdy_29wx_pdd_cookie_and_login_status", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// taobao_id&act=add
|
||||
/// </summary>
|
||||
public HttpResult AddTaobaoId(string postdata = "")
|
||||
{
|
||||
return Post("taobao_id&act=add", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// taobao_id&act=get
|
||||
/// </summary>
|
||||
public HttpResult GetTaobaoId(string postdata = "")
|
||||
{
|
||||
return Post("taobao_id&act=get", postdata);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 拼多多服务接口
|
||||
/// <summary>
|
||||
/// shop/add_vdian
|
||||
/// </summary>
|
||||
public HttpResult PddAddVdian(string postdata = "")
|
||||
{
|
||||
return PostPdd("shop/add_vdian", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/add_weidian_shop
|
||||
/// </summary>
|
||||
public HttpResult PddAddWeidianShop(string postdata = "")
|
||||
{
|
||||
return PostPdd("shop/add_weidian_shop", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/admin_get_shop_list
|
||||
/// </summary>
|
||||
public HttpResult PddAdminGetShopList(string postdata = "")
|
||||
{
|
||||
return PostPdd("shop/admin_get_shop_list", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/del_weidian_shop
|
||||
/// </summary>
|
||||
public HttpResult PddDelWeidianShop(string postdata = "")
|
||||
{
|
||||
return PostPdd("shop/del_weidian_shop", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/e57_get_pdd_shop_token
|
||||
/// </summary>
|
||||
public HttpResult PddE57GetPddShopToken(string postdata = "")
|
||||
{
|
||||
return PostPdd("shop/e57_get_pdd_shop_token", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/get_pdd_client_info
|
||||
/// </summary>
|
||||
public HttpResult PddGetPddClientInfo(string postdata = "")
|
||||
{
|
||||
return PostPdd("shop/get_pdd_client_info", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/get_shop_client_info
|
||||
/// </summary>
|
||||
public HttpResult PddGetShopClientInfo(string postdata = "")
|
||||
{
|
||||
return PostPdd("shop/get_shop_client_info", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/mdy_vdian
|
||||
/// </summary>
|
||||
public HttpResult PddMdyVdian(string postdata = "")
|
||||
{
|
||||
return PostPdd("shop/mdy_vdian", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/mdy_vdian_cookie
|
||||
/// </summary>
|
||||
public HttpResult PddMdyVdianCookie(string postdata = "")
|
||||
{
|
||||
return PostPdd("shop/mdy_vdian_cookie", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// shop/mdy_weidian_shop_cookie
|
||||
/// </summary>
|
||||
public HttpResult PddMdyWeidianShopCookie(string postdata = "")
|
||||
{
|
||||
return PostPdd("shop/mdy_weidian_shop_cookie", postdata);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,395 @@
|
||||
using MAX.Core.DependencyInjection;
|
||||
using MAX.Core.Extensions;
|
||||
using MAX.Core.Helpers;
|
||||
using Store.Client.Agent;
|
||||
using Store.Client.HttpExtension;
|
||||
using Store.Framework;
|
||||
using Store.Framework.Tools;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Store.Client.Apis
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户操作Api
|
||||
/// 登录,注册
|
||||
/// </summary>
|
||||
public partial class UserApi : AppApiRequestBase, ITransientDependency
|
||||
{
|
||||
|
||||
public HttpResult Login(string username, string password)
|
||||
{
|
||||
_logger.Info("123");
|
||||
int r2 = RandomHelper.GetRandomNumber(100000000, 899999999); //生成随机码
|
||||
HttpItem item = new HttpItem();
|
||||
item.URL = base.BuildServiceUrl("user/user_login");
|
||||
item.Method = MethodType.Post;
|
||||
Dictionary<string, string> param = new Dictionary<string, string>
|
||||
{
|
||||
{ "mobile", username },
|
||||
{ "r2", r2.ToString() },
|
||||
{ "password", password },
|
||||
{ "hw_code", HardwareTool.HardWareCode },
|
||||
{ "hw_code_new", HardwareTool.HardWareCodeNew },
|
||||
{ "hw_code_v3", HardwareTool.HardWareCodeV3 },
|
||||
{ "agent_code", AgentConfig.AgentCode },
|
||||
{ "version",Config.Version}
|
||||
//,
|
||||
//{ "client_ip", _client.Ip },
|
||||
//{ "client_addr", _client.Address }
|
||||
};
|
||||
item.Postdata = param.ToUrlParams();
|
||||
HttpResult result = ServerRequest(item);
|
||||
if (result.StatusCode == HttpStatusCode.OK)
|
||||
{
|
||||
string chCode = Regex.Match(result.Html, "<c>([^<]+)</c>")?.Groups[1]?.Value ?? "";
|
||||
if (!string.IsNullOrEmpty(chCode))
|
||||
{
|
||||
string codex = Encryption(r2);
|
||||
if (chCode != codex)
|
||||
{
|
||||
result.StatusCode = HttpStatusCode.Unauthorized;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#region 默认服务接口
|
||||
/// <summary>
|
||||
/// user&act=add_user_lock
|
||||
/// </summary>
|
||||
public HttpResult AddUserLock(string postdata = "")
|
||||
{
|
||||
return Post("user&act=add_user_lock", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/add_sub_user
|
||||
/// </summary>
|
||||
public HttpResult AddSubUser(string postdata = "")
|
||||
{
|
||||
return Post("user/add_sub_user", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/add_user
|
||||
/// </summary>
|
||||
public HttpResult AddUser(string postdata = "")
|
||||
{
|
||||
return Post("user/add_user", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/apply_oem_withdrawal
|
||||
/// </summary>
|
||||
public HttpResult ApplyOemWithdrawal(string postdata = "")
|
||||
{
|
||||
return Post("user/apply_oem_withdrawal", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/delete_user
|
||||
/// </summary>
|
||||
public HttpResult DeleteUser(string postdata = "")
|
||||
{
|
||||
return Post("user/delete_user", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/get_all_user
|
||||
/// </summary>
|
||||
public HttpResult GetAllUser(string postdata = "")
|
||||
{
|
||||
return Post("user/get_all_user", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/get_package_sign
|
||||
/// </summary>
|
||||
public HttpResult GetPackageSign(string postdata = "")
|
||||
{
|
||||
return Post("user/get_package_sign", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/get_sub_user
|
||||
/// </summary>
|
||||
public HttpResult GetSubUser(string postdata = "")
|
||||
{
|
||||
return Post("user/get_sub_user", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/get_user_amount
|
||||
/// </summary>
|
||||
public HttpResult GetUserAmount(string postdata = "")
|
||||
{
|
||||
return Post("user/get_user_amount", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/is_get_return_package
|
||||
/// </summary>
|
||||
public HttpResult IsGetReturnPackage(string postdata = "")
|
||||
{
|
||||
return Post("user/is_get_return_package", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/oem_audit_withdrawal
|
||||
/// </summary>
|
||||
public HttpResult OemAuditWithdrawal(string postdata = "")
|
||||
{
|
||||
return Post("user/oem_audit_withdrawal", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/oem_settle_flows
|
||||
/// </summary>
|
||||
public HttpResult OemSettleFlows(string postdata = "")
|
||||
{
|
||||
return Post("user/oem_settle_flows", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/oem_withdrawals
|
||||
/// </summary>
|
||||
public HttpResult OemWithdrawals(string postdata = "")
|
||||
{
|
||||
return Post("user/oem_withdrawals", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/update_sub_user
|
||||
/// </summary>
|
||||
public HttpResult UpdateSubUser(string postdata = "")
|
||||
{
|
||||
return Post("user/update_sub_user", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/update_user
|
||||
/// </summary>
|
||||
public HttpResult UpdateUser(string postdata = "")
|
||||
{
|
||||
return Post("user/update_user", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/update_user_balance
|
||||
/// </summary>
|
||||
public HttpResult UpdateUserBalance(string postdata = "")
|
||||
{
|
||||
return Post("user/update_user_balance", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/update_user_points
|
||||
/// </summary>
|
||||
public HttpResult UpdateUserPoints(string postdata = "")
|
||||
{
|
||||
return Post("user/update_user_points", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/user_login
|
||||
/// </summary>
|
||||
public HttpResult UserLogin(string postdata = "")
|
||||
{
|
||||
return PostPublic("user/user_login", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user_login_cookies&act=get
|
||||
/// </summary>
|
||||
public HttpResult GetUserLoginCookies(string postdata = "")
|
||||
{
|
||||
return Post("user_login_cookies&act=get", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user_login_cookies&act=insert
|
||||
/// </summary>
|
||||
public HttpResult InsertUserLoginCookies(string postdata = "")
|
||||
{
|
||||
return Post("user_login_cookies&act=insert", postdata);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 拼多多服务接口
|
||||
/// <summary>
|
||||
/// user/add_buyer
|
||||
/// </summary>
|
||||
public HttpResult PddAddBuyer(string postdata = "")
|
||||
{
|
||||
return PostPdd("user/add_buyer", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/del_buyer
|
||||
/// </summary>
|
||||
public HttpResult PddDelBuyer(string postdata = "")
|
||||
{
|
||||
return PostPdd("user/del_buyer", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/get_buyer
|
||||
/// </summary>
|
||||
public HttpResult PddGetBuyer(string postdata = "")
|
||||
{
|
||||
return PostPdd("user/get_buyer", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/get_scm121_cookie
|
||||
/// </summary>
|
||||
public HttpResult PddGetScm121Cookie(string postdata = "")
|
||||
{
|
||||
return PostPdd("user/get_scm121_cookie", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/mdy_buyer
|
||||
/// </summary>
|
||||
public HttpResult PddMdyBuyer(string postdata = "")
|
||||
{
|
||||
return PostPdd("user/mdy_buyer", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/mdy_buyer_cookie
|
||||
/// </summary>
|
||||
public HttpResult PddMdyBuyerCookie(string postdata = "")
|
||||
{
|
||||
return PostPdd("user/mdy_buyer_cookie", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/update_scm121_cookie
|
||||
/// </summary>
|
||||
public HttpResult PddUpdateScm121Cookie(string postdata = "")
|
||||
{
|
||||
return PostPdd("user/update_scm121_cookie", postdata);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 微信服务接口
|
||||
/// <summary>
|
||||
/// user/add_mdy_oem
|
||||
/// </summary>
|
||||
public HttpResult WxAddMdyOem(string postdata = "")
|
||||
{
|
||||
return PostWx("user/add_mdy_oem", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/del_oem
|
||||
/// </summary>
|
||||
public HttpResult WxDelOem(string postdata = "")
|
||||
{
|
||||
return PostWx("user/del_oem", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/get_all_user
|
||||
/// </summary>
|
||||
public HttpResult WxGetAllUser(string postdata = "")
|
||||
{
|
||||
return PostWx("user/get_all_user", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/get_e57_authorization
|
||||
/// </summary>
|
||||
public HttpResult WxGetE57Authorization(string postdata = "")
|
||||
{
|
||||
return PostWx("user/get_e57_authorization", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/get_oem
|
||||
/// </summary>
|
||||
public HttpResult WxGetOem(string postdata = "")
|
||||
{
|
||||
return PostWx("user/get_oem", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/get_oem_config_info
|
||||
/// </summary>
|
||||
public HttpResult WxGetOemConfigInfo(string postdata = "")
|
||||
{
|
||||
return PostWx("user/get_oem_config_info", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/get_oem_version
|
||||
/// </summary>
|
||||
public HttpResult WxGetOemVersion(string postdata = "")
|
||||
{
|
||||
return PostWx("user/get_oem_version", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/get_top_up_qrcode
|
||||
/// </summary>
|
||||
public HttpResult WxGetTopUpQrcode(string postdata = "")
|
||||
{
|
||||
return PostWx("user/get_top_up_qrcode", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/get_user_balance
|
||||
/// </summary>
|
||||
public HttpResult WxGetUserBalance(string postdata = "")
|
||||
{
|
||||
return PostWx("user/get_user_balance", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/get_user_points
|
||||
/// </summary>
|
||||
public HttpResult WxGetUserPoints(string postdata = "")
|
||||
{
|
||||
return PostWx("user/get_user_points", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/get_wx_sale_assistant_cookie
|
||||
/// </summary>
|
||||
public HttpResult WxGetWxSaleAssistantCookie(string postdata = "")
|
||||
{
|
||||
return PostWx("user/get_wx_sale_assistant_cookie", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/update_top_up_qrcode
|
||||
/// </summary>
|
||||
public HttpResult WxUpdateTopUpQrcode(string postdata = "")
|
||||
{
|
||||
return PostWx("user/update_top_up_qrcode", postdata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// user/update_wx_sale_assistant_cookie
|
||||
/// </summary>
|
||||
public HttpResult WxUpdateWxSaleAssistantCookie(string postdata = "")
|
||||
{
|
||||
return PostWx("user/update_wx_sale_assistant_cookie", postdata);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
//using MAX.Core.Helpers;
|
||||
//using Polly;
|
||||
//using Store.Framework.HttpResultParser;
|
||||
//using System;
|
||||
//using System.Collections.Generic;
|
||||
//using System.Linq;
|
||||
//using System.Text;
|
||||
//using System.Threading.Tasks;
|
||||
|
||||
//namespace Store.Framework.Attributes
|
||||
//{
|
||||
// /// <summary>
|
||||
// /// Http请求请求失败重新尝试 HttpStatusCode 状态不为Ok一律重新尝试
|
||||
// /// </summary>
|
||||
// [AttributeUsage(AttributeTargets.Method)]
|
||||
// public class HttpTryAttribute : AbstractInterceptorAttribute
|
||||
// {
|
||||
// /// <summary>
|
||||
// /// 最大尝试次数
|
||||
// /// </summary>
|
||||
// public int MaxRetryTimes { get; set; } = 3;
|
||||
// /// <summary>
|
||||
// /// 重新尝试延迟时间毫秒
|
||||
// /// </summary>
|
||||
// public int RetryIntervalMilliseconds { get; set; } = 1000;
|
||||
// protected Type[] VerifyTypes { get; set; }
|
||||
// //public HttpTryAttribute()
|
||||
// //{
|
||||
|
||||
// //}
|
||||
|
||||
// public HttpTryAttribute(params Type[] verifyTypes)
|
||||
// {
|
||||
// VerifyTypes = (verifyTypes ?? new Type[0]);
|
||||
// }
|
||||
// public override Task Invoke(AspectContext context, AspectDelegate next)
|
||||
// {
|
||||
// var verify = HttpResultVerify.TryVerify(() =>
|
||||
// {
|
||||
// next(context).Wait();
|
||||
// return (HttpResult)context.ReturnValue;
|
||||
// }, MaxRetryTimes, RetryIntervalMilliseconds);
|
||||
// if (VerifyTypes != null && VerifyTypes.Count() > 0)
|
||||
// {
|
||||
// foreach (Type item in VerifyTypes)
|
||||
// {
|
||||
// if (typeof(IHttpResultVerify).IsAssignableFrom(item))
|
||||
// {
|
||||
// verify.UseCheckResult((IHttpResultVerify)Activator.CreateInstance(item));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// verify.Exec();
|
||||
// return Task.FromResult(0);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,70 @@
|
||||
//using AspectCore.DynamicProxy;
|
||||
////using System;
|
||||
//using System.Collections.Generic;
|
||||
//using System.Linq;
|
||||
//using System.Reflection;
|
||||
//using System.Text;
|
||||
//using System.Threading;
|
||||
//using System.Threading.Tasks;
|
||||
|
||||
//namespace Store.Framework.Attributes
|
||||
//{
|
||||
// /// <summary>
|
||||
// /// Aop延迟时间
|
||||
// /// </summary>
|
||||
// ///
|
||||
// public class SleepAttribute : AopInterceptorAttribute
|
||||
// {
|
||||
// /// <summary>
|
||||
// /// 毫秒
|
||||
// /// </summary>
|
||||
// public int Millisecond { get; set; }
|
||||
// /// <summary>
|
||||
// /// 间隔区间
|
||||
// /// </summary>
|
||||
// public Tuple<int, int> ExtentMillisecond { get; set; }
|
||||
// /// <summary>
|
||||
// /// 执行位置
|
||||
// /// </summary>
|
||||
// public ExecOrder Location { get; set; } = ExecOrder.Before;
|
||||
// public SleepAttribute(int millisecond)
|
||||
// {
|
||||
// Millisecond = millisecond;
|
||||
// }
|
||||
// public SleepAttribute(int StartMillisecond, int EndMillisecond)
|
||||
// {
|
||||
// ExtentMillisecond = new Tuple<int, int>(StartMillisecond, EndMillisecond);
|
||||
// }
|
||||
// public override void BeforeAction(AspectContext context)
|
||||
// {
|
||||
// if (Location == ExecOrder.Before)
|
||||
// Exec();
|
||||
// }
|
||||
|
||||
// public override void AfterAction(AspectContext context)
|
||||
// {
|
||||
// if (Location == ExecOrder.After)
|
||||
// Exec();
|
||||
// }
|
||||
|
||||
// private void Exec()
|
||||
// {
|
||||
// if (ExtentMillisecond != null)
|
||||
// {
|
||||
// Millisecond = new Random().Next(ExtentMillisecond.Item1, ExtentMillisecond.Item2);
|
||||
// }
|
||||
// Thread.Sleep(Millisecond);
|
||||
// }
|
||||
// public enum ExecOrder
|
||||
// {
|
||||
// /// <summary>
|
||||
// /// 方法执行前
|
||||
// /// </summary>
|
||||
// Before,
|
||||
// /// <summary>
|
||||
// /// 方法执行后
|
||||
// /// </summary>
|
||||
// After
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,121 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Store.Client.Commons
|
||||
{
|
||||
///// <summary>
|
||||
///// 商铺列表信息管理
|
||||
///// </summary>
|
||||
//public abstract class ShopManage<T> : ISingletonDependency, ILoginSuccessed where T : ShopBase
|
||||
//{
|
||||
// /// <summary>
|
||||
// /// 日志
|
||||
// /// </summary>
|
||||
// [Autowired]
|
||||
// protected ILog _log { get; set; }
|
||||
// [Autowired]
|
||||
// internal ShopService _shopService { get; set; }
|
||||
// /// <summary>
|
||||
// /// 私有商铺集合
|
||||
// /// </summary>
|
||||
// private List<T> _shopsData = new List<T>();
|
||||
// /// <summary>
|
||||
// /// 私有商铺分组
|
||||
// /// </summary>
|
||||
// /// <returns></returns>
|
||||
// private List<string> _shopGroups = new List<string>();
|
||||
|
||||
// /// <summary>
|
||||
// /// 所有商铺
|
||||
// /// </summary>
|
||||
// public List<T> Shops
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// return _shopsData;
|
||||
// }
|
||||
// }
|
||||
// /// <summary>
|
||||
// /// 商铺分组
|
||||
// /// </summary>
|
||||
// public List<string> ShopGroups
|
||||
// {
|
||||
// get => _shopGroups;
|
||||
// }
|
||||
// /// <summary>
|
||||
// /// 获取随机Cookie
|
||||
// /// </summary>
|
||||
// /// <returns></returns>
|
||||
// public Cookies GetRandomCookies()
|
||||
// {
|
||||
// return Shops[RandomHelper.GetRandomNumber(Shops.Count - 1)].Cookie;
|
||||
// }
|
||||
|
||||
|
||||
// /// <summary>
|
||||
// /// 刷新
|
||||
// /// </summary>
|
||||
// public void Refresh()
|
||||
// {
|
||||
// LoadServerShops();
|
||||
// }
|
||||
|
||||
// void ILoginSuccessed.LoginSuccess(UserInfo user)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// LoadServerShops();
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// _log.Error(ex, "加载商铺列表");
|
||||
// }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// 加载服务器商铺
|
||||
// /// </summary>
|
||||
// private void LoadServerShops()
|
||||
// {
|
||||
// _shopsData = _shopService.GetShops<T>();
|
||||
// _getshopGroup();
|
||||
// RefreshShopsCookie();
|
||||
// }
|
||||
|
||||
// private void RefreshShopsCookie()
|
||||
// {
|
||||
// var shops = Shops.Select(a => a as ShopBase).ToList();
|
||||
// _shopService.GetShopCookie(shops);
|
||||
// }
|
||||
// /// <summary>
|
||||
// /// 检测商铺登录状态
|
||||
// /// </summary>
|
||||
// public abstract void CheckShopStatus(T shop);
|
||||
// //{
|
||||
// // //string urlx = "https://myseller.taobao.com/ajaxProxy.do?_ksTS=1548152154745_13&callback=seller_layout_head&action=FrameworkLayoutAction&event_submit_do_layout_data=true";
|
||||
// // //string refere = "https://myseller.taobao.com";
|
||||
// // //string htmlx = GetPostTaobaoHtml.GetUrl(urlx, refere, true, "", Shop.Cookies);
|
||||
// // //Shop.MsgForCookiesLogin = htmlx.Contains("\"shopName\":\"") ? "登录成功" : "会话已过期";
|
||||
// // //GetTaobaoShops.ShopsTemp.Add(Shop);
|
||||
// //}
|
||||
|
||||
|
||||
// /// <summary>
|
||||
// /// 商铺分组
|
||||
// /// </summary>
|
||||
// private void _getshopGroup()
|
||||
// {
|
||||
// _shopGroups.Clear();
|
||||
// List<string> list = (from a in _shopsData group a by a.GroupName into b select b.Key).ToList();
|
||||
// foreach (var item in list)
|
||||
// {
|
||||
// _shopGroups.Add(item);
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
//}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using MAX.Framework.Helpers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Store.Framework;
|
||||
|
||||
public static class Config
|
||||
{
|
||||
public const string AppVersion = "1312";
|
||||
|
||||
/// <summary>
|
||||
/// API 项目路径。
|
||||
/// </summary>
|
||||
public const string MainPath = "29wx";
|
||||
|
||||
public static bool IsRelease
|
||||
{
|
||||
get
|
||||
{
|
||||
#if RELEASE
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public static Guid SessionID { get; }
|
||||
public static DateTime AppStartTime { get; }
|
||||
public static string Version => AppVersion;
|
||||
static Config()
|
||||
{
|
||||
SessionID = Guid.NewGuid();
|
||||
AppStartTime = DateTime.Now;
|
||||
|
||||
//FileVersionInfo info = FileVersionInfo.GetVersionInfo(Assembly.GetEntryAssembly().Location);
|
||||
//Version = new VersionStruct(info.FileMajorPart, info.ProductMinorPart, info.FileBuildPart, info.FilePrivatePart);
|
||||
|
||||
}
|
||||
public static string GetFullVersionString()
|
||||
{
|
||||
static IEnumerable<string> GetStrings()
|
||||
{
|
||||
yield return Version.ToString();
|
||||
yield return IsRelease ? "Release" : "Debug";
|
||||
if (SystemHelper.IsAdministratorSafe)
|
||||
{
|
||||
yield return "管理员权限";
|
||||
}
|
||||
}
|
||||
return string.Join(" - ", GetStrings());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Store.Framework.Configs
|
||||
{
|
||||
/// <summary>
|
||||
/// 全局配置
|
||||
/// </summary>
|
||||
public class GlobalConfig
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// app启动路径
|
||||
/// </summary>
|
||||
public static string AppDirectory
|
||||
{
|
||||
get
|
||||
{
|
||||
return AppDomain.CurrentDomain.BaseDirectory;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
|
||||
namespace Store.Client
|
||||
{
|
||||
public interface IApiServerConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 服务器地址
|
||||
/// </summary>
|
||||
string Host { get; }
|
||||
/// <summary>
|
||||
/// 项目地址
|
||||
/// </summary>
|
||||
string ObjUrl { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
//namespace Store.Client
|
||||
//{
|
||||
// /// <summary>
|
||||
// /// 根据 DI 注册 Key 获取服务配置。
|
||||
// /// Keyed DI 配置作为初始值,登录后获取到的服务地址可以覆盖初始值。
|
||||
// /// </summary>
|
||||
// public interface IServiceConfigProvider
|
||||
// {
|
||||
// /// <summary>
|
||||
// /// 获取指定 Key 的服务配置。
|
||||
// /// </summary>
|
||||
// IServerConfig Get(string key);
|
||||
|
||||
// /// <summary>
|
||||
// /// 尝试获取指定 Key 的服务配置。
|
||||
// /// </summary>
|
||||
// bool TryGet(string key, out IServerConfig config);
|
||||
|
||||
// /// <summary>
|
||||
// /// 设置或覆盖指定 Key 的完整服务配置。
|
||||
// /// </summary>
|
||||
// void Set(string key, IServerConfig config);
|
||||
|
||||
// /// <summary>
|
||||
// /// 设置或覆盖指定 Key 的服务配置。
|
||||
// /// </summary>
|
||||
// void Set(string key, string host, string objUrl);
|
||||
|
||||
// /// <summary>
|
||||
// /// 只更新指定 Key 的 Host,保留原有 ObjUrl。
|
||||
// /// </summary>
|
||||
// void SetHost(string key, string host);
|
||||
|
||||
// /// <summary>
|
||||
// /// 删除运行时覆盖配置。删除后会回退到 Keyed DI 初始配置。
|
||||
// /// </summary>
|
||||
// bool Remove(string key);
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Store.Client
|
||||
{
|
||||
internal class ServerConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 服务器时间差
|
||||
/// </summary>
|
||||
public static long TimeDifferent { get; internal set; }
|
||||
/// <summary>
|
||||
/// 是否使用新签名算法
|
||||
/// </summary>
|
||||
public static bool IsNewSignatureAuth { get; internal set; } = true;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace Store.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// 服务配置默认 Key。
|
||||
/// </summary>
|
||||
public static class ServiceConfigKeys
|
||||
{
|
||||
/// <summary>
|
||||
/// 基础 Store API 使用的默认配置 Key。
|
||||
/// </summary>
|
||||
public const string Default = "Default";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
//using Autofac.Core.Registration;
|
||||
//using Autofac.Features.Indexed;
|
||||
//using MAX.Core.DependencyInjection;
|
||||
//using MAX.Core.Infrastructure;
|
||||
//using System;
|
||||
//using System.Collections.Concurrent;
|
||||
//using System.Collections.Generic;
|
||||
|
||||
//namespace Store.Client
|
||||
//{
|
||||
// /// <summary>
|
||||
// /// 从 Autofac Keyed Service 中获取服务配置。
|
||||
// /// 登录后服务端下发的新地址会保存在运行时配置中,并优先于 Keyed DI 初始配置。
|
||||
// /// </summary>
|
||||
// public sealed class ServiceConfigProvider : IServiceConfigProvider, ISingletonDependency
|
||||
// {
|
||||
// private readonly IIndex<string, IApiServerConfig> _configs;
|
||||
// private readonly ConcurrentDictionary<string, IApiServerConfig> _runtimeConfigs = new ConcurrentDictionary<string, IApiServerConfig>();
|
||||
|
||||
// public ServiceConfigProvider(IIndex<string, IApiServerConfig> configs)
|
||||
// {
|
||||
// _configs = configs ?? throw new ArgumentNullException(nameof(configs));
|
||||
// }
|
||||
|
||||
// public IApiServerConfig Get(string key)
|
||||
// {
|
||||
// if (TryGet(key, out IApiServerConfig config))
|
||||
// {
|
||||
// return config;
|
||||
// }
|
||||
|
||||
// throw new InvalidOperationException($"未注册 Key 为“{key}”的 IApiServerConfig。");
|
||||
// }
|
||||
|
||||
// public bool TryGet(string key, out IApiServerConfig config)
|
||||
// {
|
||||
// config = null;
|
||||
// if (string.IsNullOrWhiteSpace(key))
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// if (_runtimeConfigs.TryGetValue(key, out config))
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// try
|
||||
// {
|
||||
// config = _configs[key];
|
||||
// return config != null;
|
||||
// }
|
||||
// catch (KeyNotFoundException)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// catch (ComponentNotRegisteredException)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
|
||||
// public void Set(string key, IApiServerConfig config)
|
||||
// {
|
||||
// if (string.IsNullOrWhiteSpace(key))
|
||||
// {
|
||||
// throw new ArgumentException("服务配置 Key 不能为空。", nameof(key));
|
||||
// }
|
||||
// if (config == null)
|
||||
// {
|
||||
// throw new ArgumentNullException(nameof(config));
|
||||
// }
|
||||
|
||||
// _runtimeConfigs[key] = config;
|
||||
// }
|
||||
|
||||
// public void Set(string key, string host, string objUrl)
|
||||
// {
|
||||
// Set(key, new ServiceConfig(host, objUrl));
|
||||
// }
|
||||
|
||||
// public void SetHost(string key, string host)
|
||||
// {
|
||||
// string objUrl = TryGet(key, out IApiServerConfig config)
|
||||
// ? config.ObjUrl
|
||||
// : string.Empty;
|
||||
// Set(key, new ServiceConfig(host, objUrl));
|
||||
// }
|
||||
|
||||
// public bool Remove(string key)
|
||||
// {
|
||||
// return !string.IsNullOrWhiteSpace(key) && _runtimeConfigs.TryRemove(key, out _);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,41 @@
|
||||
//using Autofac;
|
||||
//using System;
|
||||
|
||||
//namespace Store.Client
|
||||
//{
|
||||
// /// <summary>
|
||||
// /// IServerConfig 的 Keyed DI 注册扩展。
|
||||
// /// </summary>
|
||||
// public static class ServiceConfigRegistrationExtensions
|
||||
// {
|
||||
// /// <summary>
|
||||
// /// 注册指定 Key 的服务配置。
|
||||
// /// </summary>
|
||||
// public static ContainerBuilder RegisterServiceConfig(this ContainerBuilder builder, string key, IServerConfig config)
|
||||
// {
|
||||
// if (builder == null)
|
||||
// {
|
||||
// throw new ArgumentNullException(nameof(builder));
|
||||
// }
|
||||
// if (string.IsNullOrWhiteSpace(key))
|
||||
// {
|
||||
// throw new ArgumentException("服务配置 Key 不能为空。", nameof(key));
|
||||
// }
|
||||
// if (config == null)
|
||||
// {
|
||||
// throw new ArgumentNullException(nameof(config));
|
||||
// }
|
||||
|
||||
// builder.RegisterInstance(config).Keyed<IServerConfig>(key);
|
||||
// return builder;
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// 注册指定 Key 的服务配置。
|
||||
// /// </summary>
|
||||
// public static ContainerBuilder RegisterServiceConfig(this ContainerBuilder builder, string key, string host, string objUrl)
|
||||
// {
|
||||
// return builder.RegisterServiceConfig(key, new ServiceConfig(host, objUrl));
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Store.Framework.Enums;
|
||||
|
||||
/// <summary>
|
||||
/// 平台类型
|
||||
/// </summary>
|
||||
public enum PlatformType
|
||||
{
|
||||
/// <summary>
|
||||
/// 未知
|
||||
/// </summary>
|
||||
[Description("未知")]
|
||||
None = 0,
|
||||
/// <summary>
|
||||
/// 多多
|
||||
/// </summary>
|
||||
[Description("多多")]
|
||||
PDD = 1,
|
||||
/// <summary>
|
||||
/// 微信
|
||||
/// </summary>
|
||||
[Description("微信")]
|
||||
WX = 2,
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Store.Framework.Enums;
|
||||
|
||||
/// <summary>
|
||||
/// 商铺状态
|
||||
/// </summary>
|
||||
public enum ShopStatus
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using MAX.Core.Cryptography;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Store.Framework.Extensions
|
||||
{
|
||||
public static class DictionaryExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 字典转url Get 参数
|
||||
/// </summary>
|
||||
/// <param name="parameters"></param>
|
||||
/// <returns></returns>
|
||||
public static string ToUrlParams(this IDictionary<string, string> parameters, bool IsUrlEncode = true)
|
||||
{
|
||||
IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(parameters);
|
||||
IEnumerator<KeyValuePair<string, string>> dem = sortedParams.GetEnumerator();
|
||||
StringBuilder sb = new StringBuilder("");
|
||||
while (dem.MoveNext())
|
||||
{
|
||||
string key = dem.Current.Key;
|
||||
string value = dem.Current.Value;
|
||||
if (!string.IsNullOrEmpty(key))
|
||||
{
|
||||
sb.Append(key).Append("=").Append(IsUrlEncode ? UrlHelper.Encode(value) : value).Append("&");
|
||||
|
||||
}
|
||||
}
|
||||
string content = sb.ToString().Substring(0, sb.Length - 1);
|
||||
|
||||
return content;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loaded 100 of 242 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user