增加同步物流模块

修改现有架构,改为分模块( 简易版)
This commit is contained in:
chfei committed 2026-09-22 17:52:42 +08:00
1 parent 15e11618c9
commit fa03add754
120 files changed
+9438 -299

No files matched your search

+18
View File
@@ -20,6 +20,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Store.User", "Store.User\St
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Store.Framework", "Store.Framework\Store.Framework.csproj", "{CD6FB773-0431-4FAE-9E30-65953118FEBF}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Store.Framework", "Store.Framework\Store.Framework.csproj", "{CD6FB773-0431-4FAE-9E30-65953118FEBF}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MAX.Core", "MAX.Core\MAX.Core.csproj", "{281F6609-E5BC-8A5C-8382-CD7C4670ACBF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Store.Contracts", "Store.Contracts\Store.Contracts.csproj", "{3694EDE2-3192-44E6-B45C-9CDC99916876}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Store.SyncLogistics", "Store.SyncLogistics\Store.SyncLogistics.csproj", "{11AF9AF8-8DA0-E764-D5FF-8EF35E1FF7C8}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@@ -42,6 +48,18 @@ Global
{CD6FB773-0431-4FAE-9E30-65953118FEBF}.Debug|Any CPU.Build.0 = Debug|Any CPU {CD6FB773-0431-4FAE-9E30-65953118FEBF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CD6FB773-0431-4FAE-9E30-65953118FEBF}.Release|Any CPU.ActiveCfg = Release|Any CPU {CD6FB773-0431-4FAE-9E30-65953118FEBF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CD6FB773-0431-4FAE-9E30-65953118FEBF}.Release|Any CPU.Build.0 = Release|Any CPU {CD6FB773-0431-4FAE-9E30-65953118FEBF}.Release|Any CPU.Build.0 = Release|Any CPU
{281F6609-E5BC-8A5C-8382-CD7C4670ACBF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{281F6609-E5BC-8A5C-8382-CD7C4670ACBF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{281F6609-E5BC-8A5C-8382-CD7C4670ACBF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{281F6609-E5BC-8A5C-8382-CD7C4670ACBF}.Release|Any CPU.Build.0 = Release|Any CPU
{3694EDE2-3192-44E6-B45C-9CDC99916876}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3694EDE2-3192-44E6-B45C-9CDC99916876}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3694EDE2-3192-44E6-B45C-9CDC99916876}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3694EDE2-3192-44E6-B45C-9CDC99916876}.Release|Any CPU.Build.0 = Release|Any CPU
{11AF9AF8-8DA0-E764-D5FF-8EF35E1FF7C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{11AF9AF8-8DA0-E764-D5FF-8EF35E1FF7C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{11AF9AF8-8DA0-E764-D5FF-8EF35E1FF7C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{11AF9AF8-8DA0-E764-D5FF-8EF35E1FF7C8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@@ -1,4 +1,4 @@
using KJD_Web.Requests; using Store.Framework.Dtos;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@@ -1,4 +1,4 @@
using KJD_Web.Requests; using Store.Framework.Dtos;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@@ -1,4 +1,4 @@
using KJD_Web.Requests; using Store.Framework.Dtos;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
+2 -1
View File
@@ -2,12 +2,13 @@ using KJD_Web.BLL.WXXD.Dtos;
using KJD_Web.BLL.WXXD.Requests; using KJD_Web.BLL.WXXD.Requests;
using KJD_Web.Model; using KJD_Web.Model;
using KJD_Web.Model.WxModel; using KJD_Web.Model.WxModel;
using KJD_Web.Requests;
using KJD_Web.Utils; using KJD_Web.Utils;
using NaiBa.Util.Extension; using NaiBa.Util.Extension;
using NaiBa.Util.Helper; using NaiBa.Util.Helper;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Serialization; using Newtonsoft.Json.Serialization;
using Store.Framework.Dtos;
using Store.Framework.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data; using System.Data;
+86 -76
View File
@@ -1,92 +1,102 @@
using Autofac; //using Autofac;
using Autofac.Integration.WebApi; //using Autofac.Core;
using FreeSql; //using Autofac.Integration.WebApi;
using KJD_Web.Repository; //using FreeSql;
using MAX.Core.DependencyInjection; //using KJD_Web.Repository;
using MAX.Core.Logger; //using MAX.Core;
using MAX.Framework.Logger; //using MAX.Core.DependencyInjection;
using System; //using MAX.Core.Helpers;
using System.Collections.Generic; //using MAX.Core.Interfaces;
using System.Configuration; //using MAX.Core.Logger;
using System.Linq; //using MAX.Core.Reflections;
using System.Reflection; //using MAX.Framework.Logger;
using System.Web; //using Store.Framework.Commons;
//using Store.VirtualLogistics.Services;
//using System;
//using System.Collections.Generic;
//using System.Configuration;
//using System.Diagnostics;
//using System.Linq;
//using System.Reflection;
//using System.Web;
//using System.Web.Services.Description;
namespace KJD_Web; //namespace KJD_Web;
public class ContainerConfig //public class ContainerConfig
{ //{
public static IContainer BuildContainer() // public static IContainer BuildContainer()
{ // {
var builder = new ContainerBuilder(); // var builder = new ContainerBuilder();
var appAssembly = Assembly.GetExecutingAssembly(); // var appAssembly = StoreAppTypeFinder.Current.GetAssemblies().ToArray();
var connection = ConfigurationManager.ConnectionStrings["ConnKJD"]; // var connection = ConfigurationManager.ConnectionStrings["ConnKJD"];
if (connection == null || string.IsNullOrWhiteSpace(connection.ConnectionString)) // if (connection == null || string.IsNullOrWhiteSpace(connection.ConnectionString))
{ // {
throw new ConfigurationErrorsException("未配置连接字符串:ConnKJD"); // throw new ConfigurationErrorsException("未配置连接字符串:ConnKJD");
} // }
// var ss = StoreAppTypeFinder.Current.Find<VirtualLogisticsService>();
// // ImageCacheService 使用独立的 imagecache 数据库。
// builder.Register(_ =>
// {
// return new FreeSqlBuilder()
// .UseConnectionString(
// DataType.MySql,
// connection.ConnectionString)
// .Build();
// })
// .As<IFreeSql>()
// .SingleInstance();
// ImageCacheService 使用独立的 imagecache 数据库。 // builder.RegisterGeneric(typeof(AutofacRepository<>))
builder.Register(_ => // .As(typeof(IBaseRepository<>))
{ // .UsingConstructor(typeof(IFreeSql))
return new FreeSqlBuilder() // .InstancePerRequest();
.UseConnectionString(
DataType.MySql,
connection.ConnectionString)
.Build();
})
.As<IFreeSql>()
.SingleInstance();
builder.RegisterGeneric(typeof(AutofacRepository<>))
.As(typeof(IBaseRepository<>))
.UsingConstructor(typeof(IFreeSql))
.InstancePerRequest();
// 注册 Web API 所有 Controller // // 注册 Web API 所有 Controller
builder.RegisterApiControllers(appAssembly); // builder.RegisterApiControllers(appAssembly);
builder.RegisterInstance(NLogger.Instance).As<ILoggerFacade>().SingleInstance(); // builder.RegisterInstance(NLogger.Instance).As<ILoggerFacade>().SingleInstance();
#region 注册所有IOC接口 // #region 注册所有IOC接口
Type typeSingleton = typeof(ISingletonDependency); // Type typeSingleton = typeof(ISingletonDependency);
builder.RegisterAssemblyTypes(appAssembly) // builder.RegisterAssemblyTypes(appAssembly)
.Where(a => // .Where(a =>
typeSingleton.IsAssignableFrom(a) // typeSingleton.IsAssignableFrom(a)
&& a.IsClass // && a.IsClass
&& !a.IsAbstract // && !a.IsAbstract
) // )
.AsImplementedInterfaces() // .AsImplementedInterfaces()
.AsSelf() // .AsSelf()
.SingleInstance(); // .SingleInstance();
Type typeTransient = typeof(ITransientDependency); // Type typeTransient = typeof(ITransientDependency);
builder.RegisterAssemblyTypes(appAssembly) // builder.RegisterAssemblyTypes(appAssembly)
.Where(a => // .Where(a =>
typeTransient.IsAssignableFrom(a) // typeTransient.IsAssignableFrom(a)
&& a.IsClass // && a.IsClass
&& !a.IsAbstract // && !a.IsAbstract
) // )
.AsImplementedInterfaces() // .AsImplementedInterfaces()
.AsSelf() // .AsSelf()
.InstancePerDependency(); // .InstancePerDependency();
Type typeScoped = typeof(IScopedDependency); // Type typeScoped = typeof(IScopedDependency);
builder.RegisterAssemblyTypes(appAssembly) // builder.RegisterAssemblyTypes(appAssembly)
.Where(a => typeScoped.IsAssignableFrom(a) && a.IsClass && !a.IsAbstract) // .Where(a => typeScoped.IsAssignableFrom(a) && a.IsClass && !a.IsAbstract)
.AsImplementedInterfaces() // .AsImplementedInterfaces()
.AsSelf() // .AsSelf()
.InstancePerRequest(); // .InstancePerRequest();
#endregion // #endregion
// var app = builder.Build();
// return app;
// }
return builder.Build(); //}
}
}
@@ -1,6 +1,7 @@
using KJD_Web.BLL.WXXD; using KJD_Web.BLL.WXXD;
using KJD_Web.Requests; using KJD_Web.Requests;
using KJD_Web.Utils; using KJD_Web.Utils;
using Store.Framework.Base;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
@@ -1,7 +1,7 @@
using KJD_Web.Model; using KJD_Web.Services;
using KJD_Web.Services;
using MAX.Core.Logger; using MAX.Core.Logger;
using MySqlX.XDevAPI.Common; using MySqlX.XDevAPI.Common;
using Store.Framework.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Web.Http; using System.Web.Http;
@@ -1,7 +1,8 @@
using KJD_Web.Model; using KJD_Web.Requests.Users;
using KJD_Web.Requests.Users;
using KJD_Web.Responses.Users; using KJD_Web.Responses.Users;
using KJD_Web.Services.Users; using KJD_Web.Services.Users;
using Store.Framework.Base;
using Store.Framework.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@@ -1,9 +1,9 @@
using KJD_Web.BLL.WXXD; using KJD_Web.BLL.WXXD;
using KJD_Web.Model;
using KJD_Web.Requests;
using KJD_Web.Requests.Users; using KJD_Web.Requests.Users;
using KJD_Web.Utils; using KJD_Web.Utils;
using NaiBa.Util.Extension; using NaiBa.Util.Extension;
using Store.Framework.Dtos;
using Store.Framework.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@@ -1,11 +1,11 @@
using KJD_Web.BLL.WXXD; using KJD_Web.BLL.WXXD;
using KJD_Web.Model;
using KJD_Web.Requests;
using KJD_Web.Requests.Users; using KJD_Web.Requests.Users;
using KJD_Web.Services.Users; using KJD_Web.Services.Users;
using MAX.Core.Logger; using MAX.Core.Logger;
using NaiBa.Util.Extension; using NaiBa.Util.Extension;
using Org.BouncyCastle.Ocsp; using Org.BouncyCastle.Ocsp;
using Store.Framework.Dtos;
using Store.Framework.Models;
using System; using System;
using System.Web.Http; using System.Web.Http;
@@ -1,69 +0,0 @@
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);
}
}
-16
View File
@@ -1,16 +0,0 @@
namespace MAX.Core.Logger
{
/// <summary>
/// 日志等级
/// </summary>
public enum LogLevel
{
Trace = 0,
Debug = 1,
Info = 2,
Warn = 3,
Error = 4,
Fatal = 5,
None = 6
}
}
@@ -1,9 +0,0 @@
namespace MAX.Core.DependencyInjection
{
/// <summary>
/// 作用域(每个 Scope/请求一个实例)
/// </summary>
public interface IScopedDependency
{
}
}
@@ -1,9 +0,0 @@
namespace MAX.Core.DependencyInjection
{
/// <summary>
/// 单例
/// </summary>
public interface ISingletonDependency
{
}
}
@@ -1,9 +0,0 @@
namespace MAX.Core.DependencyInjection
{
/// <summary>
/// 每次实例化
/// </summary>
public interface ITransientDependency
{
}
}
+4 -17
View File
@@ -1,5 +1,6 @@
using Autofac; using Autofac;
using Autofac.Integration.WebApi; using Autofac.Integration.WebApi;
using AutoMapper;
using FreeSql; using FreeSql;
using KJD_Web.Repository; using KJD_Web.Repository;
using KJD_Web.Utils; using KJD_Web.Utils;
@@ -8,6 +9,7 @@ using MAX.Core.Logger;
using MAX.Framework.Logger; using MAX.Framework.Logger;
using MySql.Data.MySqlClient; using MySql.Data.MySqlClient;
using NLog; using NLog;
using Store.Framework.DependencyInjection;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Configuration; using System.Configuration;
@@ -27,30 +29,15 @@ namespace KJD_Web
NLogger.Instance.Info("应用程序启动"); NLogger.Instance.Info("应用程序启动");
var container = ContainerConfig.BuildContainer(); var container = ContainerConfig.BuildContainer();
// 让 Web API 用 Autofac 解析 Controller // 让 Web API 用 Autofac 解析 Controller
GlobalConfiguration.Configuration.DependencyResolver = GlobalConfiguration.Configuration.DependencyResolver =
new AutofacWebApiDependencyResolver(container); new AutofacWebApiDependencyResolver(container);
GlobalConfiguration.Configure(WebApiConfig.Register); GlobalConfiguration.Configure(WebApiConfig.Register);
} }
private static IFreeSql CreateImageCacheFreeSql()
{
var connection = ConfigurationManager.ConnectionStrings["ConnKJD"];
if (connection == null || string.IsNullOrWhiteSpace(connection.ConnectionString))
{
throw new ConfigurationErrorsException("未配置连接字符串:ConnKJD");
}
//var connectionBuilder = new MySqlConnectionStringBuilder(connection.ConnectionString)
//{
// Database = "imagecache"
//};
return new FreeSqlBuilder()
.UseConnectionString(DataType.MySql, connection.ConnectionString)
.UseAutoSyncStructure(false)
.Build();
}
protected void Session_Start(object sender, EventArgs e) protected void Session_Start(object sender, EventArgs e)
{ {
+23 -26
View File
@@ -190,7 +190,6 @@
<Compile Include="BLL\WXXD\WXShopRevenueStatisticsManage.cs" /> <Compile Include="BLL\WXXD\WXShopRevenueStatisticsManage.cs" />
<Compile Include="BLL\WXXD\WXUserManage.cs" /> <Compile Include="BLL\WXXD\WXUserManage.cs" />
<Compile Include="ContainerConfig.cs" /> <Compile Include="ContainerConfig.cs" />
<Compile Include="Controllers\ApiControllerBase.cs" />
<Compile Include="Controllers\AsmxApiController.cs" /> <Compile Include="Controllers\AsmxApiController.cs" />
<Compile Include="Controllers\ImageCacheController.cs" /> <Compile Include="Controllers\ImageCacheController.cs" />
<Compile Include="Controllers\WX\OEMController.cs" /> <Compile Include="Controllers\WX\OEMController.cs" />
@@ -214,12 +213,7 @@
<Compile Include="Controllers\UpdateController.cs" /> <Compile Include="Controllers\UpdateController.cs" />
<Compile Include="Controllers\ShopController.cs" /> <Compile Include="Controllers\ShopController.cs" />
<Compile Include="Controllers\UserController.cs" /> <Compile Include="Controllers\UserController.cs" />
<Compile Include="Core\Logger\ILoggerFacade.cs" /> <Compile Include="Mappers\WeOrderMapper.cs" />
<Compile Include="Core\Logger\LogLevel.cs" />
<Compile Include="Core\Logger\NLogger.cs" />
<Compile Include="DependencyInjection\IScopedDependency.cs" />
<Compile Include="DependencyInjection\ISingletonDependency.cs" />
<Compile Include="DependencyInjection\ITransientDependency.cs" />
<Compile Include="Model\WxModel\oms_wei_ewaybill_path.cs" /> <Compile Include="Model\WxModel\oms_wei_ewaybill_path.cs" />
<Compile Include="Entitys\OEMEntity.cs" /> <Compile Include="Entitys\OEMEntity.cs" />
<Compile Include="Entitys\UserPaymentRecordEntity.cs" /> <Compile Include="Entitys\UserPaymentRecordEntity.cs" />
@@ -233,7 +227,6 @@
<Compile Include="Entitys\UserPointsRecordEntity.cs" /> <Compile Include="Entitys\UserPointsRecordEntity.cs" />
<Compile Include="Entitys\UserPointsShopExpire.cs" /> <Compile Include="Entitys\UserPointsShopExpire.cs" />
<Compile Include="LogHelper.cs" /> <Compile Include="LogHelper.cs" />
<Compile Include="Model\ApiResult.cs" />
<Compile Include="Model\ErpModel\ErpMerchantInfo.cs" /> <Compile Include="Model\ErpModel\ErpMerchantInfo.cs" />
<Compile Include="Model\JSTDownProdSkuInfo.cs" /> <Compile Include="Model\JSTDownProdSkuInfo.cs" />
<Compile Include="Model\PddModel\BuyerLoginInfo.cs" /> <Compile Include="Model\PddModel\BuyerLoginInfo.cs" />
@@ -278,8 +271,8 @@
<Compile Include="Services\Users\UserService.OEM.cs" /> <Compile Include="Services\Users\UserService.OEM.cs" />
<Compile Include="Services\Users\UserService.cs" /> <Compile Include="Services\Users\UserService.cs" />
<Compile Include="SignValidateFilterAttribute.cs" /> <Compile Include="SignValidateFilterAttribute.cs" />
<Compile Include="Utils\ApiRequestLogger.cs" />
<Compile Include="GetPostActionSelector.cs" /> <Compile Include="GetPostActionSelector.cs" />
<Compile Include="Startup.cs" />
<Compile Include="WebApiConfig.cs" /> <Compile Include="WebApiConfig.cs" />
<Compile Include="Upload\Prod\BaseClass.cs" /> <Compile Include="Upload\Prod\BaseClass.cs" />
<Compile Include="Upload\Prod\BaseWxProd.cs" /> <Compile Include="Upload\Prod\BaseWxProd.cs" />
@@ -297,8 +290,6 @@
<Compile Include="Upload\Prod\WXProd.aspx.designer.cs"> <Compile Include="Upload\Prod\WXProd.aspx.designer.cs">
<DependentUpon>WXProd.aspx</DependentUpon> <DependentUpon>WXProd.aspx</DependentUpon>
</Compile> </Compile>
<Compile Include="Utils\HttpUtils.cs" />
<Compile Include="Utils\RandomUtils.cs" />
<Compile Include="Global.asax.cs"> <Compile Include="Global.asax.cs">
<DependentUpon>Global.asax</DependentUpon> <DependentUpon>Global.asax</DependentUpon>
</Compile> </Compile>
@@ -316,21 +307,6 @@
<Compile Include="Model\TemuDBOrderInfo.cs" /> <Compile Include="Model\TemuDBOrderInfo.cs" />
<Compile Include="Model\UserLoginResultParam.cs" /> <Compile Include="Model\UserLoginResultParam.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Utils\EncrypUtil.cs" />
<Compile Include="Utils\Extension\Extension.Convert.cs" />
<Compile Include="Utils\Extension\Extension.Enum.cs" />
<Compile Include="Utils\Extension\Extension.Exception.cs" />
<Compile Include="Utils\Extension\Extension.Linq.cs" />
<Compile Include="Utils\Extension\Extension.Validate.cs" />
<Compile Include="Utils\Helper\HtmlHelper.cs" />
<Compile Include="Utils\Helper\JsonHelper.cs" />
<Compile Include="Utils\Helper\ReflectionHelper.cs" />
<Compile Include="Utils\Helper\RegexHelper.cs" />
<Compile Include="Utils\HtmlUtils.cs" />
<Compile Include="Utils\JsonUtils.cs" />
<Compile Include="Utils\MySqlUtils.cs" />
<Compile Include="Utils\RegexUtils.cs" />
<Compile Include="Utils\TimeUtils.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="packages.config" /> <None Include="packages.config" />
@@ -349,6 +325,27 @@
<Version>3.5.311</Version> <Version>3.5.311</Version>
</PackageReference> </PackageReference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MAX.Core\MAX.Core.csproj">
<Project>{281F6609-E5BC-8A5C-8382-CD7C4670ACBF}</Project>
<Name>MAX.Core</Name>
</ProjectReference>
<ProjectReference Include="..\Store.Contracts\Store.Contracts.csproj">
<Project>{3694ede2-3192-44e6-b45c-9cdc99916876}</Project>
<Name>Store.Contracts</Name>
</ProjectReference>
<ProjectReference Include="..\Store.Framework\Store.Framework.csproj">
<Project>{cd6fb773-0431-4fae-9e30-65953118febf}</Project>
<Name>Store.Framework</Name>
</ProjectReference>
<ProjectReference Include="..\Store.SyncLogistics\Store.SyncLogistics.csproj">
<Project>{11af9af8-8da0-e764-d5ff-8ef35e1ff7c8}</Project>
<Name>Store.SyncLogistics</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="Services\Order\" />
</ItemGroup>
<PropertyGroup> <PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion> <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+13
View File
@@ -0,0 +1,13 @@
using AutoMapper;
using KJD_Web.Entitys;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace KJD_Web.Mapper;
public class WeOrderProfile : Profile
{
}
+2 -2
View File
@@ -1,6 +1,6 @@
using KJD_Web.Model; using Newtonsoft.Json;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization; using Newtonsoft.Json.Serialization;
using Store.Framework.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
+1 -13
View File
@@ -1,21 +1,9 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using Store.Framework.Dtos;
using System; using System;
namespace KJD_Web.Requests; namespace KJD_Web.Requests;
/// <summary>
/// Sign签名
/// </summary>
public class SignRequestBase
{
public string time { get; set; }
public string code { get; set; }
public string code_version { get; set; }
public string version { get; set; }
[JsonProperty("user_name")]
public string UserName { get; set; }
public string path { get; set; }
}
@@ -1,4 +1,5 @@
using System; using Store.Framework.Dtos;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Web; using System.Web;
@@ -1,4 +1,5 @@
using System; using Store.Framework.Dtos;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Web; using System.Web;
@@ -1,10 +1,12 @@
using KJD_Web.Entitys; using KJD_Web.Entitys;
using KJD_Web.Model.WxModel; using KJD_Web.Model.WxModel;
using MySqlX.XDevAPI; using MySqlX.XDevAPI;
using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data.Common; using System.Data.Common;
using System.Diagnostics; using System.Diagnostics;
using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Web; using System.Web;
@@ -267,8 +269,170 @@ namespace KJD_Web.Services.Users
summary.ConsumeTotal = (long)Math.Round(sum * 100m); summary.ConsumeTotal = (long)Math.Round(sum * 100m);
return summary; return summary;
} }
} }
/// <summary>
/// 填充历史数据
/// </summary>
// public void FillHistoryOemAmount()
// {
// List<UserPaymentRecordSmall> data = new List<UserPaymentRecordSmall>();
// string path = @"d:\ddddd.json";
// if (File.Exists(path))
// {
// data = JsonConvert.DeserializeObject<List<UserPaymentRecordSmall>>(File.ReadAllText(path));
// }
// else
// {
// data = _freeSql.Select<UserPaymentRecordSmall>()
// .Where(a => a.type == 20 || a.type == 26)
// .Where(a => a.create_time > DateTime.Parse("2026-09-01 00:00:00"))
// .OrderBy(a => a.id)
// .ToList();
// }
// Debug.WriteLine($"共;{data.Count}");
// int max = 500;
// int count = 0;
// List<UserPaymentRecordSmall> list = new List<UserPaymentRecordSmall>();
// foreach (var item in data)
// {
// //if (item.IsFill) continue;
// try
// {
// if (!string.IsNullOrEmpty(item.remark))
// {
// item.OrderId = item.remark.Split(':')[1];
// list.Add(item);
// if (list.Count == max)
// {
// var orderNames = list.Select(a => a.OrderId);
// List<weiOrder> orders = _freeSql.Select<weiOrder>()
// .Where(a => orderNames.Contains(a.order_id))
// .ToList();
// fillOemAmount(list, orders);
// var uCount = _freeSql.Update<UserPaymentRecordSmall>()
// .SetSource(list)
// .UpdateColumns(a => new { a.oem_amount })
// .ExecuteAffrows();
// if (uCount != list.Count)
// {
// Debug.WriteLine("数量不对");
// }
// list.ForEach(a => a.IsFill = true);
// File.WriteAllText(path, JsonConvert.SerializeObject(data));
// count += list.Count;
// list.Clear();
// Debug.WriteLine($"成功修改;{list.Count}");
// Debug.WriteLine($"共修改;{count}");
// }
// }
// }
// finally
// {
// }
// }
// }
// private void fillOemAmount(List<UserPaymentRecordSmall> list, List<weiOrder> orders)
// {
// foreach (var item in list)
// {
// var order = orders.FirstOrDefault(a => a.order_id == item.OrderId);
// if (order != null)
// {
// item.oem_amount = getoemamount(order.province_name, item.amount.Value, item.type);
// }
// }
// }
// private Dictionary<string, decimal> DicWarehousePostage = new Dictionary<string, decimal>
// {
// { "湖北", 2.2m },
//{ "湖南", 2.2m },
//{ "江西", 2.2m },
//{ "河南", 2.2m },
//{ "上海", 3m },
//{ "浙江", 2.2m },
//{ "安徽", 2.2m },
//{ "江苏", 2.2m },
//{ "河北", 2.2m },
//{ "山东", 2.2m },
//{ "福建", 2.2m },
//{ "广东", 2.2m },
//{ "深圳", 2.8m },
//{ "天津", 2.2m },
//{ "北京", 3.2m },
//{ "山西", 2.2m },
//{ "陕西", 2.2m },
//{ "广西", 2.2m },
//{ "云南", 2.2m },
//{ "贵州", 2.2m },
//{ "四川", 2.2m },
//{ "重庆", 2.2m },
//{ "黑龙江", 2.7m },
//{ "吉林", 2.7m },
//{ "辽宁", 2.7m },
//{ "青海", 2.7m },
//{ "宁夏", 2.7m },
//{ "甘肃", 2.7m },
//{ "内蒙", 4.5m },
//{ "海南", 4.5m },
//{ "新疆", 12.5m },
//{ "西藏", 12.5m },
// };
// private decimal getoemamount(string province, decimal amount, int type)
// {
// foreach (var item in DicWarehousePostage)
// {
// if (province.StartsWith(item.Key))
// {
// if (type == 20)
// return amount - item.Value;
// if (type == 26)
// return amount - item.Value - 0.3m;
// }
// }
// return amount;
// }
//}
//[FreeSql.DataAnnotations.Table(Name = "wxxd.user_payment_record")]
//public class UserPaymentRecordSmall()
//{
// public long id { get; set; }
// public int type { get; set; }
// /// <summary>
// /// 金额(元)
// /// </summary>
// public decimal? amount { get; set; }
// /// <summary>
// /// 归属oem用户的金额
// /// </summary>
// public decimal? oem_amount { get; set; }
// public string remark { get; set; }
// public DateTime create_time { get; set; }
// [FreeSql.DataAnnotations.Column(IsIgnore = true)]
// public bool IsFill { get; set; }
// [FreeSql.DataAnnotations.Column(IsIgnore = true)]
// public string OrderId { get; set; }
//}
//[FreeSql.DataAnnotations.Table(Name = "erp.oms_wei_order")]
//public class weiOrder
//{
// public string order_id { get; set; }
// public string province_name { get; set; }
//}
public class UserAmountSummary public class UserAmountSummary
{ {
/// <summary> /// <summary>
@@ -1,7 +1,7 @@
using KJD_Web.Model; using KJD_Web.Utils;
using KJD_Web.Requests;
using KJD_Web.Utils;
using Newtonsoft.Json; using Newtonsoft.Json;
using Store.Framework.Dtos;
using Store.Framework.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
+30
View File
@@ -0,0 +1,30 @@
using Autofac;
using FreeSql;
using KJD_Web.Repository;
using MAX.Core.DependencyInjection;
using MAX.Core.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace KJD_Web;
public class Startup : IStartup
{
public int Priority => IntPriority.Normal;
public void Initialize()
{
}
public void Register(IServiceRegistrar registrar)
{
(registrar.Services as ContainerBuilder).RegisterGeneric(typeof(AutofacRepository<>))
.As(typeof(IBaseRepository<>))
.UsingConstructor(typeof(IFreeSql))
.InstancePerRequest();
}
}
+7
View File
@@ -82,6 +82,13 @@
<staticContent> <staticContent>
<mimeMap fileExtension=".asmx" mimeType="application/octet-stream" /> <mimeMap fileExtension=".asmx" mimeType="application/octet-stream" />
</staticContent> </staticContent>
<security>
<requestFiltering>
<verbs>
<add verb="CONNECT" allowed="false" />
</verbs>
</requestFiltering>
</security>
</system.webServer> </system.webServer>
<system.codedom> <system.codedom>
<compilers> <compilers>
-1
View File
@@ -22,7 +22,6 @@
<package id="MySql.Data" version="8.0.30" targetFramework="net472" /> <package id="MySql.Data" version="8.0.30" targetFramework="net472" />
<package id="Newtonsoft.Json" version="13.0.4" targetFramework="net472" /> <package id="Newtonsoft.Json" version="13.0.4" targetFramework="net472" />
<package id="Newtonsoft.Json.Bson" version="1.0.2" targetFramework="net472" /> <package id="Newtonsoft.Json.Bson" version="1.0.2" targetFramework="net472" />
<package id="NLog" version="6.2.0" targetFramework="net472" />
<package id="Portable.BouncyCastle" version="1.9.0" targetFramework="net472" /> <package id="Portable.BouncyCastle" version="1.9.0" targetFramework="net472" />
<package id="System.Buffers" version="4.6.1" targetFramework="net472" /> <package id="System.Buffers" version="4.6.1" targetFramework="net472" />
<package id="System.Diagnostics.DiagnosticSource" version="10.0.0" targetFramework="net472" /> <package id="System.Diagnostics.DiagnosticSource" version="10.0.0" targetFramework="net472" />
+99
View File
@@ -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();
}
+168
View File
@@ -0,0 +1,168 @@
using MAX.Core.DependencyInjection;
using MAX.Core.Interfaces;
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 SingleInstanceLittleCache<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();
}
}
+37
View File
@@ -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; }
}
+55
View File
@@ -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; }
}
+69
View File
@@ -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);
}
}
+215
View File
@@ -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
}
+62
View File
@@ -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);
}
}
+51
View File
@@ -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,15 @@
using MAX.Core.Interfaces;
namespace MAX.Core.DependencyInjection;
/// <summary>
/// 依赖注册器:把当前模块的服务注册到 <see cref="IServiceRegistrar"/>。
/// 底层使用哪个容器由宿主项目决定,MAX.Core 不引用任何容器。
/// </summary>
public interface IDependencyRegistrar: IPriority
{
/// <summary>
/// 注册服务
/// </summary>
void Register(IServiceRegistrar registrar);
}
@@ -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
{
object Services { get; }
/// <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,37 @@
//using MAX.Core.Autofac;
//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;
// }
//}
+218
View File
@@ -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;
}
}
+55
View File
@@ -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
}
+78
View File
@@ -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)
{
}
}
+385
View File
@@ -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
+110
View File
@@ -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);
}
}
+341
View File
@@ -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;
}
}
+65
View File
@@ -0,0 +1,65 @@
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()
{
// 1. 检查环境变量
var envVar = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT") ??
Environment.GetEnvironmentVariable("ENVIRONMENT");
if (!string.IsNullOrEmpty(envVar))
{
return envVar;
}
// 检查当前机器名
var machineName = Environment.MachineName;
if (machineName.ToUpper().Contains("DEV") ||
machineName.ToUpper().Contains("TEST"))
{
return machineName.Contains("TEST") ? "Test" : "Development";
}
// 4. 默认返回 Production
return "Production";
}
// 获取环境描述
public static string EnvironmentDescription
{
get
{
if (IsTest) return "测试环境";
if (IsDevelopment) return "开发环境";
if (IsProduction) return "生产环境";
return $"未知环境 ({CurrentEnvironment})";
}
}
}
+188
View File
@@ -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
+45
View File
@@ -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();
//}
}
+369
View File
@@ -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;
}
}
+614
View File
@@ -0,0 +1,614 @@
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设置显示名称
/// </summary>
/// <typeparam name="T">类型</typeparam>
public static string GetDisplayName<T>()
{
return GetDisplayName(Common.GetType<T>());
}
/// <summary>
/// 获取显示名称,使用DisplayAttribute或DisplayNameAttribute设置显示名称
/// </summary>
public static string GetDisplayName(MemberInfo member)
{
if (member == null)
{
return string.Empty;
}
if (member.GetCustomAttribute<DisplayNameAttribute>() is DisplayNameAttribute displayNameAttribute)
{
return displayNameAttribute.DisplayName;
}
return string.Empty;
}
/// <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)
{
string result = GetDisplayName(member);
return string.IsNullOrWhiteSpace(result) ? GetDescription(member) : result;
}
/// <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];
}
}
+149
View File
@@ -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
}
+33
View File
@@ -0,0 +1,33 @@
namespace MAX.Core.Interfaces;
public interface IPriority
{
/// <summary> 优先级(优先级越高越先执行) </summary>
int Priority { get; }
}
public static class IntPriority
{
public const int Highest = 5000;
public const int VeryHigh = 4000;
public const int Higher = 3000;
public const int High = 2000;
public const int AboveNormal = 1000;
public const int Normal = 0;
public const int BelowNormal = -1000;
public const int Low = -2000;
public const int Lower = -3000;
public const int VeryLow = -4000;
public const int Lowest = -5000;
}
+18
View File
@@ -0,0 +1,18 @@
using MAX.Core.DependencyInjection;
namespace MAX.Core.Interfaces;
/// <summary>
/// 启动器:实现 <see cref="IDependencyRegistrar"/>,由宿主项目统一发现并按 <see cref="Priority"/> 排序执行。
/// </summary>
public interface IStartup : IDependencyRegistrar
{
/// <summary>
/// 优先级(优先级越高越先执行)
/// </summary>
int Priority { get; }
/// <summary>
/// 初始化
/// </summary>
void Initialize();
}
+42
View File
@@ -0,0 +1,42 @@
using System;
using System.Reflection;
namespace MAX.Core.Interfaces;
/// <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)");
}
}
}
+124
View File
@@ -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);
}
}
}
+11
View File
@@ -0,0 +1,11 @@
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);
}
+68
View File
@@ -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);
}
+15
View File
@@ -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
}
+14
View File
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<NoWarn>NU1608;CS1574;CS1573;CS1572;CS1571;CS1711;CS1570;CS1591</NoWarn>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="System.Web" />
</ItemGroup>
</Project>
+197
View File
@@ -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."];
}
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&lt;&gt;</c>)</description></item>
/// <item><description>普通基类类型(例如 <c>BaseHandler</c>)</description></item>
/// <item><description>开放泛型基类类型(例如 <c>BaseHandler&lt;&gt;</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&lt;T&gt; 的类
/// var handlers = FindAllDerivedTypes(typeof(IEnumDisplayHandler&lt;&gt;));
///
/// // 查找所有实现了 IMyService 的类
/// var services = FindAllDerivedTypes(typeof(IMyService));
///
/// // 查找所有继承 BaseHandler 的类
/// var subclasses = FindAllDerivedTypes(typeof(BaseHandler));
///
/// // 查找所有继承开放泛型基类 BaseHandler&lt;T&gt; 的类
/// var genericSubclasses = FindAllDerivedTypes(typeof(BaseHandler&lt;&gt;));
/// </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&lt;&gt;</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&lt;IEnumDisplayHandler&lt;&gt;&gt;();
/// var services = FindAllDerivedTypes&lt;IMyService&gt;();
/// var subclasses = FindAllDerivedTypes&lt;BaseHandler&gt;();
/// var genericSubclasses = FindAllDerivedTypes&lt;BaseHandler&lt;&gt;&gt;();
/// </code>
/// </remarks>
public static Type[] FindAllDerivedTypes<T>() => FindAllDerivedTypes(typeof(T));
}
+129
View File
@@ -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>
protected virtual 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());
}
}
+45
View File
@@ -0,0 +1,45 @@
/***
* _ooOoo_
* o8888888o
* 88" . "88
* (| -_- |)
* O\ = /O
* ____/`---'\____
* . ' \\| |// `.
* / \\||| : |||// \
* / _||||| -:- |||||- \
* | | \\\ - /// | |
* | \_| ''\---/'' | |
* \ .-\__ `-` ___/-. /
* ___`. .' /--.--\ `. . __
* ."" '< `.___\_<|>_/___.' >'"".
* | | : `- \`.;`\ _ /`;.`/ - ` : | |
* \ \ `-. \_ __\ /__ _/ .-` / /
* ======`-.____`-.___\_____/___.-`____.-'======
* `=---='
*
* .............................................
* 佛祖保佑 永无BUG
* 快加工资 不改需求
*/
using MAX.Core.DependencyInjection;
using MAX.Core.Interfaces;
namespace MAX.Core;
public class Startup : IStartup
{
public int Priority => int.MaxValue;
public void Initialize()
{
}
public void Register(IServiceRegistrar registrar)
{
// 示例:恢复 LazyServiceProvider 后,可在这里注册为单例
// registrar.RegisterSingleton<ILazyServiceProvider, LazyServiceProvider>();
}
}
+6
View File
@@ -0,0 +1,6 @@
namespace Store.Contracts;
public class Class1
{
}
@@ -0,0 +1,128 @@
using FreeSql.DataAnnotations;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Store.Contracts.Order.Entitys;
/// <summary>
/// 拼多多买手订单表
/// </summary>
[Table(Name = "wxxd.order_pdd_buyer_order")]
public class OrderPddBuyerOrderEntity
{
/// <summary>
/// id
/// </summary>
[Column(Name = "id", IsPrimary = true, IsIdentity = true)]
public long Id { get; set; }
/// <summary>
/// 微信订单
/// </summary>
[Column(Name = "wx_order_id")]
public string WxOrderId { get; set; }
/// <summary>
/// 微信订单sku
/// </summary>
[Column(Name = "wx_sku_id")]
public string WxSkuId { get; set; }
/// <summary>
/// 微信订单发货类型 0 中转仓,1店铺后台直发
/// </summary>
[Column(Name = "wx_send_type")]
public byte WxSendType { get; set; }
/// <summary>
/// 中转单创建时间
/// </summary>
[Column(Name = "TransitCreateTime")]
public DateTime? TransitCreateTime { get; set; }
/// <summary>
/// 中转仓取号状态
/// </summary>
[Column(Name = "pre_allocated_order_no")]
public int? PreAllocatedOrderNo { get; set; }
/// <summary>
/// 买手编号
/// </summary>
[Column(Name = "buyerId")]
public string BuyerId { get; set; }
/// <summary>
/// 买手名称
/// </summary>
[Column(Name = "buyerName")]
public string BuyerName { get; set; }
/// <summary>
/// 买手单号
/// </summary>
[Column(Name = "order_sn")]
public string OrderSn { get; set; }
/// <summary>
/// 拍单订单金额
/// </summary>
[Column(Name = "order_amount")]
public int? OrderAmount { get; set; }
/// <summary>
/// 拍单时间
/// </summary>
[Column(Name = "order_time")]
public long? OrderTime { get; set; }
/// <summary>
/// 物流公司名称缩写
/// </summary>
[Column(Name = "outExpressCompanyCode")]
public string OutExpressCompanyCode { get; set; }
/// <summary>
/// 拍单物流单号
/// </summary>
[Column(Name = "tracking_number")]
public string TrackingNumber { get; set; }
/// <summary>
/// 订单状态
/// </summary>
[Column(Name = "order_status_prompt")]
public string OrderStatusPrompt { get; set; }
/// <summary>
/// 买手售后状态 2, 3, 4, 5, 7, 8, 10, 31 // 为售后,不支持修改物流 0:无售后 2:买家申请退款,待商家处理 3:退货退款,待商家处理 4:商家同意退款,退款中 5:平台同意退款,退款中 6:驳回退款,待买家处理 7:已同意退货退款,待用户发货 8:平台处理中 9:平台拒绝退款,退款关闭 10:退款成功 11:买家撤销 12:买家逾期未处理,退款失败 13:买家逾期,超过有效期 14:换货补寄待商家处理 15:换货补寄待用户处理 16:换货补寄成功 17:换货补寄失败 18:换货补寄待用户确认完成 21:待商家同意维修 22:待用户确认发货 24:维修关闭 25:维修成功 27:待用户确认收货 31:已同意拒收退款,待用户拒收 32:补寄待商家发货
/// </summary>
[Column(Name = "after_sales_status")]
public int? AfterSalesStatus { get; set; }
/// <summary>
/// 买手订单详情
/// </summary>
[Column(Name = "order_detail")]
public string OrderDetail { get; set; }
/// <summary>
/// add_time
/// </summary>
[Column(Name = "add_time")]
public DateTime AddTime { get; set; }
/// <summary>
/// mdy_time
/// </summary>
[Column(Name = "mdy_time")]
public DateTime MdyTime { get; set; }
/// <summary>
/// 取件码
/// </summary>
[Column(Name = "pickup_code")]
public string PickupCode { get; set; }
}
@@ -0,0 +1,416 @@
using FreeSql.DataAnnotations;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Store.Contracts.Order.Entitys;
/// <summary>
/// 微信订单表
/// </summary>
[Table(Name = "erp.oms_wei_order")]
public class WeiOrderEntity
{
/// <summary>
/// id
/// </summary>
[Column(Name = "id", IsPrimary = true, IsIdentity = true)]
public long Id { get; set; }
/// <summary>
/// 店铺id
/// </summary>
[Column(Name = "shop_id")]
public long ShopId { get; set; }
/// <summary>
/// 店铺名称
/// </summary>
[Column(Name = "shop_name")]
public string ShopName { get; set; }
/// <summary>
/// 商户id
/// </summary>
[Column(Name = "merchant_id")]
public long MerchantId { get; set; }
/// <summary>
/// 订单号
/// </summary>
[Column(Name = "order_id")]
public string OrderId { get; set; }
/// <summary>
/// 买家身份标识
/// </summary>
[Column(Name = "openid")]
public string Openid { get; set; }
/// <summary>
/// 秒级时间戳
/// </summary>
[Column(Name = "create_time")]
public int? CreateTime { get; set; }
/// <summary>
/// 秒级时间戳
/// </summary>
[Column(Name = "update_time")]
public int? UpdateTime { get; set; }
/// <summary>
/// unionid
/// </summary>
[Column(Name = "unionid")]
public string Unionid { get; set; }
/// <summary>
/// 状态10 待付款;20 待发货;21 部分发货;30 待收货;100 完成;200 全部商品售后之后,订单取消;250 未付款用户主动取消或超时未付款订单自动取消;
/// </summary>
[Column(Name = "status")]
public int? Status { get; set; }
/// <summary>
/// 售后信息json
/// </summary>
[Column(Name = "aftersale_detail")]
public string AftersaleDetail { get; set; }
/// <summary>
/// 支付信息json
/// </summary>
[Column(Name = "pay_info")]
public string PayInfo { get; set; }
/// <summary>
/// 额外信息
/// </summary>
[Column(Name = "ext_info")]
public string ExtInfo { get; set; }
/// <summary>
/// 商品总价,单位为分
/// </summary>
[Column(Name = "product_price")]
public int? ProductPrice { get; set; }
/// <summary>
/// 订单金额,单位为分,order_price=original_order_price-discounted_price-deduction_price-change_down_price
/// </summary>
[Column(Name = "order_price")]
public int? OrderPrice { get; set; }
/// <summary>
/// 采购价,单位为分
/// </summary>
[Column(Name = "purchase_price")]
public int? PurchasePrice { get; set; }
/// <summary>
/// 采购时间
/// </summary>
[Column(Name = "purchase_time")]
public int? PurchaseTime { get; set; }
/// <summary>
/// 运费,单位为分
/// </summary>
[Column(Name = "freight")]
public int? Freight { get; set; }
/// <summary>
/// 平台服务费(微信小店:预计技术服务费),单位为分
/// </summary>
[Column(Name = "predict_commission_fee")]
public int? PredictCommissionFee { get; set; }
/// <summary>
/// 达人佣金(微信小店:分账金额),单位为分
/// </summary>
[Column(Name = "commission_amount")]
public int CommissionAmount { get; set; }
/// <summary>
/// 优惠券优惠金额,单位为分
/// </summary>
[Column(Name = "discounted_price")]
public int? DiscountedPrice { get; set; }
/// <summary>
/// 利润(实付金额-采购价-平台服务费-达人佣金,达人佣金、采购价为空值则为0)
/// </summary>
[Column(Name = "profit")]
public int? Profit { get; set; }
/// <summary>
/// 采购状态,默认值为:0未采购,推送仓库时修改为1采购
/// </summary>
[Column(Name = "purchase_status")]
public int PurchaseStatus { get; set; }
/// <summary>
/// 延迟发货时间(微信小店:商品发货时效,超时此时间未发货即为发货超时)
/// </summary>
[Column(Name = "delivery_deadline")]
public int? DeliveryDeadline { get; set; }
/// <summary>
/// 发货时间
/// </summary>
[Column(Name = "delivery_time")]
public int? DeliveryTime { get; set; }
/// <summary>
/// 收货人姓名
/// </summary>
[Column(Name = "user_name")]
public string UserName { get; set; }
/// <summary>
/// 邮编
/// </summary>
[Column(Name = "postal_code")]
public string PostalCode { get; set; }
/// <summary>
/// 省份
/// </summary>
[Column(Name = "province_name")]
public string ProvinceName { get; set; }
/// <summary>
/// 城市
/// </summary>
[Column(Name = "city_name")]
public string CityName { get; set; }
/// <summary>
/// 区
/// </summary>
[Column(Name = "county_name")]
public string CountyName { get; set; }
/// <summary>
/// 详细地址
/// </summary>
[Column(Name = "detail_info")]
public string DetailInfo { get; set; }
/// <summary>
/// 联系方式
/// </summary>
[Column(Name = "tel_number")]
public string TelNumber { get; set; }
/// <summary>
/// 门牌号码
/// </summary>
[Column(Name = "house_number")]
public string HouseNumber { get; set; }
/// <summary>
/// 虚拟发货订单联系方式(deliver_method=1时返回)
/// </summary>
[Column(Name = "virtual_order_tel_number")]
public string VirtualOrderTelNumber { get; set; }
/// <summary>
/// 额外的联系方式信息(虚拟号码相关)
/// </summary>
[Column(Name = "tel_number_ext_info")]
public string TelNumberExtInfo { get; set; }
/// <summary>
/// 0:不使用虚拟号码,1:使用虚拟号码
/// </summary>
[Column(Name = "use_tel_number")]
public int? UseTelNumber { get; set; }
/// <summary>
/// 标识当前店铺下一个唯一的用户收货地址
/// </summary>
[Column(Name = "hash_code")]
public string HashCode { get; set; }
/// <summary>
/// 发货物流信息JSON
/// </summary>
[Column(Name = "delivery_product_info")]
public string DeliveryProductInfo { get; set; }
/// <summary>
/// 发货完成时间,秒级时间戳
/// </summary>
[Column(Name = "ship_done_time")]
public int? ShipDoneTime { get; set; }
/// <summary>
/// 电子面单代发时的订单密文
/// </summary>
[Column(Name = "ewaybill_order_code")]
public string EwaybillOrderCode { get; set; }
/// <summary>
/// 结算信息json
/// </summary>
[Column(Name = "settle_info")]
public string SettleInfo { get; set; }
/// <summary>
/// 订单审核状态(0待审核1已审核)
/// </summary>
[Column(Name = "audit_status")]
public int? AuditStatus { get; set; }
/// <summary>
/// 订单审核时间
/// </summary>
[Column(Name = "audit_time")]
public DateTime? AuditTime { get; set; }
/// <summary>
/// erp发货快递公司
/// </summary>
[Column(Name = "erp_send_company")]
public string ErpSendCompany { get; set; }
/// <summary>
/// erp发货快递单号
/// </summary>
[Column(Name = "erp_send_code")]
public string ErpSendCode { get; set; }
/// <summary>
/// erp发货状态
/// </summary>
[Column(Name = "erp_send_status")]
public int? ErpSendStatus { get; set; }
/// <summary>
/// erp发货时间
/// </summary>
[Column(Name = "erp_send_time")]
public DateTime? ErpSendTime { get; set; }
/// <summary>
/// 旗帜颜色备注,1:灰旗,2:红旗,3:橙旗,4:绿旗,5:天蓝旗,6:紫旗
/// </summary>
[Column(Name = "colour_flag")]
public int? ColourFlag { get; set; }
/// <summary>
/// 旗帜备注时间
/// </summary>
[Column(Name = "colour_flag_update_time")]
public DateTime? ColourFlagUpdateTime { get; set; }
/// <summary>
/// 供应商备注异常单
/// </summary>
[Column(Name = "supplier_remark_exception")]
public string SupplierRemarkException { get; set; }
/// <summary>
/// 礼物单状态,默认值0:不存在礼物单,1:礼物单已发货,2:礼物单信息已更正,3:礼物单发货失败
/// </summary>
[Column(Name = "gift_order_status")]
public byte GiftOrderStatus { get; set; }
/// <summary>
/// 店铺备注:取微信ext_info.merchant_notes
/// </summary>
[Column(Name = "shop_remark")]
public string ShopRemark { get; set; }
/// <summary>
/// 商家的系统备注
/// </summary>
[Column(Name = "soft_remark")]
public string SoftRemark { get; set; }
/// <summary>
/// 外采金额(单位:分,整数存储)
/// </summary>
[Column(Name = "out_amount")]
public int OutAmount { get; set; }
/// <summary>
/// 外采账户
/// </summary>
[Column(Name = "out_account")]
public string OutAccount { get; set; }
/// <summary>
/// 外采订单号
/// </summary>
[Column(Name = "out_order_no")]
public string OutOrderNo { get; set; }
/// <summary>
/// 外采快递公司
/// </summary>
[Column(Name = "out_express_company")]
public string OutExpressCompany { get; set; }
/// <summary>
/// 外采快递单号
/// </summary>
[Column(Name = "out_express_no")]
public string OutExpressNo { get; set; }
/// <summary>
/// 外采是否发货(0 未发货,1 已发货)
/// </summary>
[Column(Name = "out_shipped")]
public byte OutShipped { get; set; }
/// <summary>
/// 判断是否优化过发货0 未优化, 1已优化
/// </summary>
[Column(Name = "is_shipment_optimized")]
public int IsShipmentOptimized { get; set; }
/// <summary>
/// 判断是否优随机使用快递单号0 未使用, 1已使用
/// </summary>
[Column(Name = "is_express_no_used")]
public int IsExpressNoUsed { get; set; }
/// <summary>
/// 外采订单售后状态
/// </summary>
[Column(Name = "out_after_sale_status")]
public string OutAfterSaleStatus { get; set; }
/// <summary>
/// 是否支持运费险:0-不支持,1-支持
/// </summary>
[Column(Name = "has_freight_insurance")]
public byte HasFreightInsurance { get; set; }
/// <summary>
/// 运费险金额(单位:元)
/// </summary>
[Column(Name = "freight_insurance_amount")]
public decimal FreightInsuranceAmount { get; set; }
/// <summary>
/// 是否外采礼物单:0-否,1-是(外采订单)
/// </summary>
[Column(Name = "external_gift")]
public byte ExternalGift { get; set; }
/// <summary>
/// 中转仓的状态 0未使用,1已创建,2创建失败(购买失败),3已创建未有上游快递单号,4已创建有上游快递单号
/// </summary>
[Column(Name = "transfer_warehouse_status")]
public byte? TransferWarehouseStatus { get; set; }
/// <summary>
/// 商品运费(由店铺买家支付的)
/// </summary>
[Column(Name = "postage_price")]
public int? PostagePrice { get; set; }
}
@@ -0,0 +1,236 @@
using FreeSql.DataAnnotations;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Store.Contracts.Order.Entitys;
/// <summary>
/// 微信订单商品明细表
/// </summary>
[Table(Name = "erp.oms_wei_order_item")]
public class WeiOrderItemEntity
{
/// <summary>
/// id
/// </summary>
[Column(Name = "id", IsPrimary = true, IsIdentity = true)]
public long Id { get; set; }
/// <summary>
/// 店铺id
/// </summary>
[Column(Name = "shop_id")]
public long ShopId { get; set; }
/// <summary>
/// 商户id
/// </summary>
[Column(Name = "merchant_id")]
public long MerchantId { get; set; }
/// <summary>
/// 订单id(平台订单id)
/// </summary>
[Column(Name = "order_id")]
public string OrderId { get; set; }
/// <summary>
/// 商品spuid
/// </summary>
[Column(Name = "product_id")]
public string ProductId { get; set; }
/// <summary>
/// 商品skuid
/// </summary>
[Column(Name = "sku_id")]
public string SkuId { get; set; }
/// <summary>
/// sku小图
/// </summary>
[Column(Name = "thumb_img")]
public string ThumbImg { get; set; }
/// <summary>
/// sku数量
/// </summary>
[Column(Name = "sku_cnt")]
public int SkuCnt { get; set; }
/// <summary>
/// 售卖单价(单位:分)
/// </summary>
[Column(Name = "sale_price")]
public int? SalePrice { get; set; }
/// <summary>
/// 商品标题
/// </summary>
[Column(Name = "title")]
public string Title { get; set; }
/// <summary>
/// 正在售后/退款流程中的 sku 数量
/// </summary>
[Column(Name = "on_aftersale_sku_cnt")]
public int? OnAftersaleSkuCnt { get; set; }
/// <summary>
/// 完成售后/退款的 sku 数量
/// </summary>
[Column(Name = "finish_aftersale_sku_cnt")]
public int? FinishAftersaleSkuCnt { get; set; }
/// <summary>
/// 商品编码
/// </summary>
[Column(Name = "sku_code")]
public string SkuCode { get; set; }
/// <summary>
/// 市场单价(单位:分)
/// </summary>
[Column(Name = "market_price")]
public int? MarketPrice { get; set; }
/// <summary>
/// sku属性JSON
/// </summary>
[Column(Name = "sku_attrs")]
public string SkuAttrs { get; set; }
/// <summary>
/// sku实付总价,取estimate_price和change_price中较小值
/// </summary>
[Column(Name = "real_price")]
public int? RealPrice { get; set; }
/// <summary>
/// 商品外部spuid
/// </summary>
[Column(Name = "out_product_id")]
public string OutProductId { get; set; }
/// <summary>
/// 采购价
/// </summary>
[Column(Name = "purchase_price")]
public int? PurchasePrice { get; set; }
/// <summary>
/// 运费
/// </summary>
[Column(Name = "freight")]
public int? Freight { get; set; }
/// <summary>
/// 商品外部skuid
/// </summary>
[Column(Name = "out_sku_id")]
public string OutSkuId { get; set; }
/// <summary>
/// 是否有优惠金额,非必填,默认为false
/// </summary>
[Column(Name = "is_discounted")]
public string IsDiscounted { get; set; }
/// <summary>
/// 优惠后sku总价,非必填,is_discounted为true时有值
/// </summary>
[Column(Name = "estimate_price")]
public int? EstimatePrice { get; set; }
/// <summary>
/// 是否修改过价格,非必填,默认为false
/// </summary>
[Column(Name = "is_change_price")]
public string IsChangePrice { get; set; }
/// <summary>
/// 改价后sku总价,非必填,is_change_price为true时有值
/// </summary>
[Column(Name = "change_price")]
public int? ChangePrice { get; set; }
/// <summary>
/// 订单内商品维度平台券优惠金额 (利润需要计算这个金额在内)
/// </summary>
[Column(Name = "cash_coupon_discounted_price")]
public int? CashCouponDiscountedPrice { get; set; }
/// <summary>
/// 区域库存id
/// </summary>
[Column(Name = "out_warehouse_id")]
public string OutWarehouseId { get; set; }
/// <summary>
/// 退货地址
/// </summary>
[Column(Name = "return_address")]
public string ReturnAddress { get; set; }
/// <summary>
/// 商品发货信息JSON
/// </summary>
[Column(Name = "sku_deliver_info")]
public string SkuDeliverInfo { get; set; }
/// <summary>
/// 商品额外服务信息JSON
/// </summary>
[Column(Name = "extra_service")]
public string ExtraService { get; set; }
/// <summary>
/// 是否使用了会员积分抵扣
/// </summary>
[Column(Name = "use_deduction")]
public string UseDeduction { get; set; }
/// <summary>
/// 会员积分抵扣金额,单位为分
/// </summary>
[Column(Name = "deduction_price")]
public int? DeductionPrice { get; set; }
/// <summary>
/// 平台服务费(微信小店:预计技术服务费),单位为分
/// </summary>
[Column(Name = "predict_commission_fee")]
public int? PredictCommissionFee { get; set; }
/// <summary>
/// 达人佣金(微信小店:分账金额),单位为分
/// </summary>
[Column(Name = "commission_amount")]
public int? CommissionAmount { get; set; }
/// <summary>
/// 商品优惠券信息,逐步替换 order.order_detail.coupon_info
/// </summary>
[Column(Name = "order_product_coupon_info_list")]
public string OrderProductCouponInfoList { get; set; }
/// <summary>
/// 商品id(o_goods外键)
/// </summary>
[Column(Name = "erp_goods_id")]
public long ErpGoodsId { get; set; }
/// <summary>
/// 商品skuid(o_goods_sku外键)
/// </summary>
[Column(Name = "erp_goods_sku_id")]
public long ErpGoodsSkuId { get; set; }
/// <summary>
/// 售后状态 1:无售后或售后关闭,2:售后处理中,3:退款中,4: 退款成功 11 已取消
/// </summary>
[Column(Name = "refund_status")]
public int RefundStatus { get; set; }
}
@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Store.Contracts.Order.Interfaces;
/// <summary>
/// 拼多多买手号订单服务
/// </summary>
public interface IOrderPddBuyerService
{
/// <summary>
/// 获取微信订单号,从品多多订单号
/// </summary>
/// <param name="orderId"></param>
/// <returns></returns>
string GetWeChatOrderIdByPddOrderId(string orderId);
}
+16
View File
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\MAX.Core\MAX.Core.csproj" />
<ProjectReference Include="..\Store.Framework\Store.Framework.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="User\" />
</ItemGroup>
</Project>
+59
View File
@@ -0,0 +1,59 @@
using KJD_Web.Utils;
using Newtonsoft.Json;
using Store.Framework.Dtos;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using System.Web.Http.Controllers;
namespace Store.Framework.Base;
public abstract class ApiControllerBase : ApiController
{
protected bool ValidateSign(SignRequestBase request, bool isUserLogin = false)
{
if (request == null || string.IsNullOrEmpty(request.time) || string.IsNullOrEmpty(request.code))
{
return false;
}
int time;
if (!int.TryParse(request.time, out time))
{
return false;
}
if (request.code != EncrypUtil.Encryption(time))
{
return false;
}
if (!isUserLogin && string.IsNullOrWhiteSpace(request.UserName))
{
return false;
}
return true;
}
private bool IsAllowAnonymous(HttpActionContext context)
{
// Action 上
if (context.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any())
return true;
// Controller 上
if (context.ControllerContext.ControllerDescriptor.ControllerType
.GetCustomAttributes(typeof(AllowAnonymousAttribute), true).Any())
return true;
return false;
}
private async Task<HttpResponseMessage> OkResponseAsync(object content)
{
IHttpActionResult result = Ok(content);
return await result.ExecuteAsync(CancellationToken.None);
}
}
-6
View File
@@ -1,6 +0,0 @@
namespace Store.Framework;
public class Class1
{
}
@@ -0,0 +1,25 @@
using MAX.Core.Reflections;
using System.Reflection;
namespace Store.Framework.Commons
{
public sealed class StoreAppTypeFinder : AppTypeFinder
{
public static StoreAppTypeFinder Current { get; } = new();
/// <summary>
/// 获取程序集列表
/// </summary>
public override List<Assembly> GetAssemblies()
{
LoadAssemblies(Environment.CurrentDirectory);
return GetAssembliesFromCurrentAppDomain();
}
protected override List<string> AvailablePrefix()
{
return ["Max", "Store"];
}
}
}
@@ -0,0 +1,99 @@
using Autofac;
using Autofac.Core;
using Autofac.Integration.WebApi;
using FreeSql;
using MAX.Core.DependencyInjection;
using MAX.Core.Helpers;
using MAX.Core.Interfaces;
using MAX.Core.Logger;
using MAX.Framework.Logger;
using Store.Framework.Commons;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Store.Framework.DependencyInjection;
public class ContainerConfig
{
public static IContainer BuildContainer()
{
var builder = new ContainerBuilder();
var appAssembly = StoreAppTypeFinder.Current.GetAssemblies().ToArray();
var connection = ConfigurationManager.ConnectionStrings["ConnKJD"];
if (connection == null || string.IsNullOrWhiteSpace(connection.ConnectionString))
{
throw new ConfigurationErrorsException("未配置连接字符串:ConnKJD");
}
// ImageCacheService 使用独立的 imagecache 数据库。
builder.Register(_ =>
{
return new FreeSqlBuilder()
.UseConnectionString(
DataType.MySql,
connection.ConnectionString)
.Build();
})
.As<IFreeSql>()
.SingleInstance();
// 注册 Web API 所有 Controller
builder.RegisterApiControllers(appAssembly);
builder.RegisterInstance(NLogger.Instance).As<ILoggerFacade>().SingleInstance();
#region 注册所有IOC接口
Type typeSingleton = typeof(ISingletonDependency);
builder.RegisterAssemblyTypes(appAssembly)
.Where(a =>
typeSingleton.IsAssignableFrom(a)
&& a.IsClass
&& !a.IsAbstract
)
.AsImplementedInterfaces()
.AsSelf()
.SingleInstance();
Type typeTransient = typeof(ITransientDependency);
builder.RegisterAssemblyTypes(appAssembly)
.Where(a =>
typeTransient.IsAssignableFrom(a)
&& a.IsClass
&& !a.IsAbstract
)
.AsImplementedInterfaces()
.AsSelf()
.InstancePerDependency();
Type typeScoped = typeof(IScopedDependency);
builder.RegisterAssemblyTypes(appAssembly)
.Where(a => typeScoped.IsAssignableFrom(a) && a.IsClass && !a.IsAbstract)
.AsImplementedInterfaces()
.AsSelf()
.InstancePerRequest();
#endregion
IServiceRegistrar registrar = new ServiceRegistrarProxy(builder);
IEnumerable<IStartup> startupList = ReflectionHelper.GetInstancesByInterface<IStartup>(appAssembly);
foreach (IStartup item in startupList.OrderByDescending(a => a.Priority))
{
Debug.WriteLine($"Startup : {item.GetType()}");
item.Initialize();
item.Register(registrar);
}
var app = builder.Build();
return app;
}
}
@@ -0,0 +1,135 @@
using Autofac;
using Autofac.Core;
using MAX.Core.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Store.Framework.DependencyInjection;
internal class ServiceRegistrarProxy : IServiceRegistrar
{
private readonly ContainerBuilder _services;
public object Services => _services;
public ServiceRegistrarProxy(ContainerBuilder builder)
{
_services = builder ?? throw new ArgumentNullException(nameof(builder));
}
// ---------------- Scoped ----------------
public void RegisterScoped<TService>(Func<IServiceProvider, TService> factory)
where TService : class
{
_services.Register(c => factory(c.Resolve<IServiceProvider>()))
.As<TService>()
.InstancePerLifetimeScope();
}
public void RegisterScoped<TService>(object? serviceKey,
Func<IServiceProvider, object?, TService> factory)
where TService : class
{
_services.Register(c => factory(c.Resolve<IServiceProvider>(), serviceKey))
.Keyed<TService>(serviceKey ?? throw new ArgumentNullException(nameof(serviceKey)))
.InstancePerLifetimeScope();
}
void IServiceRegistrar.RegisterScoped<TService, TImplementation>()
{
_services.RegisterType<TImplementation>()
.As<TService>()
.InstancePerLifetimeScope();
}
void IServiceRegistrar.RegisterScoped<TService, TImplementation>(object? serviceKey)
{
_services.RegisterType<TImplementation>()
.Keyed<TService>(serviceKey ?? throw new ArgumentNullException(nameof(serviceKey)))
.InstancePerLifetimeScope();
}
// ---------------- Singleton ----------------
public void RegisterSingleton<TService>(TService instance)
where TService : class
{
_services.RegisterInstance(instance)
.As<TService>()
.SingleInstance();
}
public void RegisterSingleton<TService>(Func<IServiceProvider, TService> factory)
where TService : class
{
_services.Register(c => factory(c.Resolve<IServiceProvider>()))
.As<TService>()
.SingleInstance();
}
public void RegisterSingleton<TService>(object? serviceKey, TService instance)
where TService : class
{
_services.RegisterInstance(instance)
.Keyed<TService>(serviceKey ?? throw new ArgumentNullException(nameof(serviceKey)))
.SingleInstance();
}
public void RegisterSingleton<TService>(object? serviceKey,
Func<IServiceProvider, object?, TService> factory)
where TService : class
{
_services.Register(c => factory(c.Resolve<IServiceProvider>(), serviceKey))
.Keyed<TService>(serviceKey ?? throw new ArgumentNullException(nameof(serviceKey)))
.SingleInstance();
}
void IServiceRegistrar.RegisterSingleton<TService, TImplementation>()
{
_services.RegisterType<TImplementation>()
.As<TService>()
.SingleInstance();
}
void IServiceRegistrar.RegisterSingleton<TService, TImplementation>(object? serviceKey)
{
_services.RegisterType<TImplementation>()
.Keyed<TService>(serviceKey ?? throw new ArgumentNullException(nameof(serviceKey)))
.SingleInstance();
}
// ---------------- Transient ----------------
public void RegisterTransient<TService>(Func<IServiceProvider, TService> factory)
where TService : class
{
_services.Register(c => factory(c.Resolve<IServiceProvider>()))
.As<TService>()
.InstancePerDependency();
}
public void RegisterTransient<TService>(object? serviceKey,
Func<IServiceProvider, object?, TService> factory)
where TService : class
{
_services.Register(c => factory(c.Resolve<IServiceProvider>(), serviceKey))
.Keyed<TService>(serviceKey ?? throw new ArgumentNullException(nameof(serviceKey)))
.InstancePerDependency();
}
void IServiceRegistrar.RegisterTransient<TService, TImplementation>()
{
_services.RegisterType<TImplementation>()
.As<TService>()
.InstancePerDependency();
}
void IServiceRegistrar.RegisterTransient<TService, TImplementation>(object? serviceKey)
{
_services.RegisterType<TImplementation>()
.Keyed<TService>(serviceKey ?? throw new ArgumentNullException(nameof(serviceKey)))
.InstancePerDependency();
}
}
+19
View File
@@ -0,0 +1,19 @@
using Newtonsoft.Json;
using System;
namespace Store.Framework.Dtos;
/// <summary>
/// Sign签名
/// </summary>
public class SignRequestBase
{
public string time { get; set; }
public string code { get; set; }
public string code_version { get; set; }
public string version { get; set; }
[JsonProperty("user_name")]
public string UserName { get; set; }
public string path { get; set; }
}
File renamed without changes.
@@ -1,8 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace KJD_Web.Model namespace Store.Framework.Models
{ {
public static class ResultCode public static class ResultCode
{ {
+25
View File
@@ -0,0 +1,25 @@
using MAX.Core.DependencyInjection;
using MAX.Core.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace Store.Framework;
internal class Startup : IStartup
{
public int Priority => IntPriority.Normal;
public void Initialize()
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
}
public void Register(IServiceRegistrar registrar)
{
}
}
+10 -1
View File
@@ -2,15 +2,24 @@
<PropertyGroup> <PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Autofac" Version="9.3.2" /> <PackageReference Include="Autofac" Version="9.3.2" />
<PackageReference Include="Autofac.WebApi2" Version="6.2.0" /> <PackageReference Include="Autofac.WebApi2" Version="6.2.0" />
<PackageReference Include="AutoMapper" Version="10.1.1" />
<PackageReference Include="FreeSql.Provider.MySql" Version="3.5.311" /> <PackageReference Include="FreeSql.Provider.MySql" Version="3.5.311" />
<PackageReference Include="FreeSql.Repository" Version="3.5.311" /> <PackageReference Include="FreeSql.Repository" Version="3.5.311" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="NLog" Version="6.2.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MAX.Core\MAX.Core.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="System.Web" />
</ItemGroup> </ItemGroup>
</Project> </Project>
File renamed without changes.
@@ -1,5 +1,4 @@
using KJD_Web.Upload.Prod; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Drawing; using System.Drawing;
@@ -184,8 +184,9 @@ namespace KJD_Web.Utils
} }
else else
request = (HttpWebRequest)WebRequest.Create(url); request = (HttpWebRequest)WebRequest.Create(url);
request.KeepAlive = true; request.KeepAlive = true;
request.Headers.Add("sec-ch-ua", @"""Not(A:Brand"";v=""8"", ""Chromium"";v=""144"", ""Google Chrome"";v=""144"""); request.Headers.Add("sec-ch-ua", @"""Not(A:Brand"";v=""8"", ""Chromium"";v=""144"", ""Google Chrome"";v=""144""");
request.Headers.Add("sec-ch-ua-mobile", @"?0"); request.Headers.Add("sec-ch-ua-mobile", @"?0");
request.Headers.Add("sec-ch-ua-platform", @"""Windows"""); request.Headers.Add("sec-ch-ua-platform", @"""Windows""");
File renamed without changes.
@@ -7,7 +7,6 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Web; using System.Web;
using System.Web.UI.WebControls.WebParts;
namespace KJD_Web.Utils namespace KJD_Web.Utils
{ {
File renamed without changes.
Loaded 100 of 120 files, more files were not shown because too many files have changed in this diff. Show more