主要开源组件说明

Magicodes.Pay(统一支付库)

Nuget

主要功能

Magicodes.Pay,是心莱科技团队提供的统一支付库,相关库均使用.NET标准库编写,支持.NET
Framework以及.NET Core。目前支持以下支付方式和功能:

  • 支付宝支付

  • APP支付

  • Wap支付

  • 支付宝国际支付

  • 支持分账

  • 微信支付

  • 小程序支付

  • APP支付

  • 订单查询

  • 企业付款(提现)

  • 退款申请

  • 普通红包

  • 统一支付回调处理

  • 支持日志函数注入(不依赖支付库)

  • 支持支付配置函数注入,以便于支持自定义配置获取逻辑,以应用于不同的场景(比如从配置文件、用户设置获取配置,或者多租户支持)

目前此库我们在很多项目上已经进行了验证,由于项目赶工,许多功能我们并没有添加、迁移或者重构过来,在后续的过程中,我们会逐步来完成这些工作。同时,在Magicodes.Admin开源库中,我们也编写了相关的Demo和实现。

Magicodes.Admin开源库地址:https://gitee.com/magicodes/Magicodes.Admin.Core

整个支付实现这块,我们在Magicodes.Admin开源库中已经提供了统一支付的Demo,而且我们将会提供根据请求头来自动调用相关支付的功能。如下图所示:

40

在各个业务支付场景中,我们可以非常方便的调用此统一支付,如下图所示:

41

42

VNext

这是目前的下个版本的规划:

  • 支付宝PC支付

  • 微信H5支付

  • 提供默认的回调管理逻辑,支持回调处理函数的注入

具体功能我们会根据项目的情况来迭代,如果你有好的建议或者意见,可以关注我们的公众号“magiccodes”来提交您的意见或者意见。

如何配置

相关库的配置相对比较简单,一般均使用相关Builder类来配置自定义日志逻辑、配置获取逻辑等,具体可以查阅Builder目录下的代码。

配置参考

相关配置请参考此代码:https://gitee.com/magicodes/Magicodes.Admin.Core/blob/develop/src/unity/Magicodes.Pay/Startup/PayStartup.cs

部分代码如下所示:

1 (1)

2

支付相关代码可以参考:
https://gitee.com/magicodes/Magicodes.Admin.Core/blob/develop/src/unity/Magicodes.Pay/Services/PayAppService.cs

配置界面参考

如下图所示:

10

11

12

Demo

微信支付Demo

if (WeChatPayApi == null)

{

throw new UserFriendlyException(“支付未开放,请联系管理员!”);

}

var appPayInput = new WeChat.Pay.Dto.AppPayInput

{

Body = input.Body,

OutTradeNo = input.OutTradeNo,

Attach = input.CustomData,

TotalFee = input.TotalAmount,

SpbillCreateIp = _clientInfoProvider?.ClientIpAddress

};

try

{

var appPayOutput = WeChatPayApi.AppPay(appPayInput);

return Task.FromResult(appPayOutput);

}

catch (Exception ex)

{

throw new UserFriendlyException(ex.Message);

}

支付宝支付Demo

if (AlipayAppService == null)

{

throw new UserFriendlyException(“支付未开放,请联系管理员!”);

}

var appPayInput = new Alipay.Dto.AppPayInput

{

Body = input.Body,

Subject = input.Subject,

TradeNo = input.OutTradeNo,

PassbackParams = input.CustomData,

TotalAmount = input.TotalAmount

};

try

{

var appPayOutput = await AlipayAppService.AppPay(appPayInput);

return appPayOutput.Response.Body;

}

catch (Exception ex)

{

throw new UserFriendlyException(ex.Message);

}

支付宝国际支付Demo

if (GlobalAlipayAppService == null)

{

throw new UserFriendlyException(“支付未开放,请联系管理员!”);

}

var payInput = new Alipay.Global.Dto.PayInput

{

Body = input.Body,

Subject = input.Subject,

TradeNo = input.OutTradeNo,

//PassbackParams = input.CustomData,

TotalFee = input.TotalAmount,

};

try

{

return await GlobalAlipayAppService.Pay(payInput);

}

catch (Exception ex)

{

throw new UserFriendlyException(ex.Message);

}

国际支付宝分账参考界面

12

支付回调

目的

统一回调处理逻辑和回调处理地址

代码参考

20

上图的PayAction参考:

void PayAction(string key, string outTradeNo, string transactionId, int
totalFee, JObject data)

{

using (var paymentCallbackManagerObj =
iocManager.ResolveAsDisposable<PaymentCallbackManager>())

{

var paymentCallbackManager = paymentCallbackManagerObj?.Object;

if (paymentCallbackManager == null)

{

throw new ApplicationException(“支付回调管理器异常,无法执行回调!”);

}

AsyncHelper.RunSync(async () => await
paymentCallbackManager.ExecuteCallback(key, outTradeNo, transactionId, totalFee,
data));

}

}

完整回调代码请参考此代码:https://gitee.com/magicodes/Magicodes.Admin.Core/blob/develop/src/unity/Magicodes.Pay/Startup/PayStartup.cs

回调逻辑参考:

30

Magicodes.Storage(统一存储库)

说明

Magicodes.Storage,是心莱科技团队提供的统一存储库,相关库均使用.NET标准库(netstandard2.0)编写,支持.NET
Framework以及.NET Core。

我们希望,使用了Magicodes.Storage之后,开发者可以很快的从本地存储切换到云端存储;我们希望,使用了Magicodes.Storage之后,开发者可以快速地从不同的云存储供应商之间切换。

目前主要支持以下存储:

  • 本地存储(本地站点目录)

  • 阿里云存储

  • 腾讯云存储

相关Nuget包

相关实践

我们围绕Magicodes.Admin开源库做了许多实践。如下图所示:

1 (2)

Magicodes.Admin开源库地址:https://gitee.com/magicodes/Magicodes.Admin.Core

VNext

这是目前的下个版本的规划:

  • 支持分块上传

  • 支持存储桶的创建和删除

  • 支持Azure存储

  • 支持亚马逊存储

  • 支持七牛云

  • 阿里云的SDK包更新为官方的包(目前还存在问题)

具体功能我们会根据项目的情况来迭代,如果你有好的建议或者意见,可以关注我们的公众号“magiccodes”来提交您的意见或者意见。

如何配置

相关库的配置相对比较简单,一般均使用相关Builder类来配置自定义日志逻辑、配置获取逻辑等,具体可以查阅Builder目录下的代码。

配置参考

相关配置请参考此代码:https://gitee.com/magicodes/Magicodes.Admin.Core/blob/develop/src/unity/Magicodes.Unity/Storage/StorageManager.cs

部分代码如下所示:

2 (1)

使用代码可以参考:

3 (1)

具体链接:
https://gitee.com/magicodes/Magicodes.Admin.Core/blob/develop/src/app/api/App.Host/Controllers/AttachmentController.cs

单元测试:

5

Magicodes.WeChat.SDK(微信、小程序SDK)

相关介绍见http://www.cnblogs.com/codelove/p/6061406.html

已添加小程序SDK,具体使用见相关单元测试以及相关框架

Magicodes.Sms(短信支持库)

短信服务核心库。

官方网址:http://xin-lai.com

开源库地址:https://github.com/xin-lai

博客地址:http://www.cnblogs.com/codelove/

交流QQ群:85318032

小店地址:https://shop113059108.taobao.com/

最新框架(完全支持.NET
Core):https://gitee.com/magicodes/Magicodes.Admin.Core

已更新为.NET标准库,支持.NET Core

已编写单元测试,可以自行配置。

配置

AliyunSmsBuilder.Create()

//设置日志记录

.WithLoggerAction((tag, message) =>

{

Console.WriteLine(string.Format(“Tag:{0}\tMessage:{1}”, tag, message));

}).SetSettingsFunc(() =>

{

//TODO:请自行配置自己的配置

//如果是一个项目多个配置,请使用key来获取相关配置

return ConfigHelper.LoadConfig(“aliyun_app”);

}).Build();

阿里云短信发送

[Theory(DisplayName = “短信发送测试”)]

[InlineData(“你的手机号码”, “验证码”)]

public async Task SendCodeAsync_Test(string phone, string code)

{

var smsService = new AliyunSmsService();

var result = await smsService.SendCodeAsync(phone, code);

result.Success.ShouldBeTrue();

}

Magicodes.ExporterAndImporter(导入导出)

特点

  • 封装导入导出业务,目前仅支持Excel,后续将支持CSV以及其他业务

  • 配置特性即可控制相关逻辑和显示结果,无需修改逻辑代码

  • 推荐配合DTO使用

  • 导出支持列头自定义处理以便支持多语言等场景

  • 导出支持文本自定义过滤或处理

  • 导入支持验证逻辑(即将支持)

  • 导入支持自定义过滤或处理(即将支持)

  • 导入支持自动根据DTO生成导入模板(即将支持)

导出Demo

Demo1

普通导出

1 (3)

public class ExportTestData

{

public string Name1 { get; set; }

public string Name2 { get; set; }

public string Name3 { get; set; }

public string Name4 { get; set; }

}

var result = await Exporter.Export(filePath, new List<ExportTestData>()

{

new ExportTestData()

{

Name1 = “1”,

Name2 = “test”,

Name3 = “12”,

Name4 = “11”,

},

new ExportTestData()

{

Name1 = “1”,

Name2 = “test”,

Name3 = “12”,

Name4 = “11”,

}

});

Demo2

特性导出

2 (2)

[ExcelExporter(Name = “测试”, TableStyle = “Light10”)]

public class ExportTestDataWithAttrs

{

[ExporterHeader(DisplayName = “加粗文本”, IsBold = true)]

public string Text { get; set; }

[ExporterHeader(DisplayName = “普通文本”)]

public string Text2 { get; set; }

[ExporterHeader(DisplayName = “忽略”, IsIgnore = true)]

public string Text3 { get; set; }

[ExporterHeader(DisplayName = “数值”, Format = “#,##0”)]

public double Number { get; set; }

[ExporterHeader(DisplayName = “名称”, IsAutoFit = true)]

public string Name { get; set; }

}

var result = await Exporter.Export(filePath, new
List<ExportTestDataWithAttrs>()

{

new ExportTestDataWithAttrs()

{

Text = “啊实打实大苏打撒”,

Name=”aa”,

Number =5000,

Text2 = “w萨达萨达萨达撒”,

Text3 = “sadsad打发打发士大夫的”

},

new ExportTestDataWithAttrs()

{

Text = “啊实打实大苏打撒”,

Name=”啊实打实大苏打撒”,

Number =6000,

Text2 = “w萨达萨达萨达撒”,

Text3 = “sadsad打发打发士大夫的”

},

new ExportTestDataWithAttrs()

{

Text = “啊实打实速度大苏打撒”,

Name=”萨达萨达”,

Number =6000,

Text2 = “突然他也让他人”,

Text3 = “sadsad打发打发士大夫的”

},

});

Demo3

列头处理或者多语言支持

3 (2)

[ExcelExporter(Name = “测试”, TableStyle = “Light10”)]

public class AttrsLocalizationTestData

{

[ExporterHeader(DisplayName = “加粗文本”, IsBold = true)]

public string Text { get; set; }

[ExporterHeader(DisplayName = “普通文本”)]

public string Text2 { get; set; }

[ExporterHeader(DisplayName = “忽略”, IsIgnore = true)]

public string Text3 { get; set; }

[ExporterHeader(DisplayName = “数值”, Format = “#,##0”)]

public double Number { get; set; }

[ExporterHeader(DisplayName = “名称”, IsAutoFit = true)]

public string Name { get; set; }

}

ExcelBuilder.Create().WithLocalStringFunc((key) =>

{

if (key.Contains(“文本”))

{

return “Text”;

}

return “未知语言”;

}).Build();

var filePath = Path.Combine(Directory.GetCurrentDirectory(),
“testAttrsLocalization.xlsx”);

if (File.Exists(filePath)) File.Delete(filePath);

var result = await Exporter.Export(filePath, new
List<AttrsLocalizationTestData>()

{

new AttrsLocalizationTestData()

{

Text = “啊实打实大苏打撒”,

Name=”aa”,

Number =5000,

Text2 = “w萨达萨达萨达撒”,

Text3 = “sadsad打发打发士大夫的”

},

new AttrsLocalizationTestData()

{

Text = “啊实打实大苏打撒”,

Name=”啊实打实大苏打撒”,

Number =6000,

Text2 = “w萨达萨达萨达撒”,

Text3 = “sadsad打发打发士大夫的”

},

new AttrsLocalizationTestData()

{

Text = “啊实打实速度大苏打撒”,

Name=”萨达萨达”,

Number =6000,

Text2 = “突然他也让他人”,

Text3 = “sadsad打发打发士大夫的”

},

});

Magicodes.SwaggerUI(API文档生成)

快速配置和集成SwaggerUI Magicodes SwaggerUI扩展库

配置Demo:

“SwaggerDoc”: {

“IsEnabled”: “true”,

“Title”: “Api Documents”,

“Version”: “v1”,

“Description”: “”,

“Contact”: {

“Name”: “心莱科技”,

“Email”: “xinlai@xin-lai.com”

},

//以便于在界面上显示验证(Authorize)按钮,验证按钮处理逻辑基于
wwwroot/swagger/ui/index.html

“Authorize”: “true”,

“HiddenApi”: {

“IsEnabled”: “false”,

“HiddenUrls”: “”

},

//将枚举值以字符串显示

“DescribeAllEnumsAsStrings”: true,

//设置api首页从嵌入资源中加载

“ManifestResourceAssembly”: “Magicodes.Admin.Web.Host”,

“ManifestResourceUrl”: “Magicodes.Admin.Web.wwwroot.swagger.ui.index.html”

},

注入代码:

//添加自定义API文档生成(支持文档配置) public IServiceProvider
ConfigureServices(IServiceCollection services) {
services.AddCustomSwaggerGen(_appConfiguration, _hostingEnvironment); }

public void Configure(IApplicationBuilder app, IHostingEnvironment env,
ILoggerFactory loggerFactory) { //启用自定义API文档(支持文档配置)
app.UseCustomSwaggerUI(_appConfiguration); }

Magicodes.Districts(行政区域)

行政区域信息核心库。以便于获取最新的行政区域数据用于自动更新业务数据库等。

官方网址:http://xin-lai.com

开源库地址:https://github.com/xin-lai

博客地址:http://www.cnblogs.com/codelove/

交流QQ群:85318032

小店地址:https://shop113059108.taobao.com/

最新框架(完全支持.NET
Core):https://gitee.com/magicodes/Magicodes.Admin.Core

已更新为.NET标准库,支持.NET Core

已编写单元测试,可以自行配置。

目前只支持通过高德API获取。后续再对接其他服务商。

高德接口配置

请先申请高德的开发者Key。

var districtsProvider = new AmapDistrictsProvider(settings.ApiKey);

获取中国省市区街道信息

var result = await DistrictsProvider.GetDistricts();

具体见单元测试:

[Fact]

public async Task GetDistricts_TestsAsync()

{

var result = await DistrictsProvider.GetDistricts();

result.ShouldNotBeNull();

//一级行政区(省级行政区):34个(23个省、5个自治区、4个直辖市、2个特别行政区)
…台湾

result[0].Children.Count.ShouldBeGreaterThanOrEqualTo(34);

//二级行政区(地级行政区):334个(294个地级市、7个地区、30个自治州、3个盟)

result[0].Children.Sum(p =>
p.Children.Count).ShouldBeGreaterThanOrEqualTo(334);

}

[Fact]

public async Task GetDistrictsByKeywords_TestsAsync()

{

var result = await DistrictsProvider.GetDistricts(“湖南”);

result.ShouldNotBeNull();

//截止2017年9月12日,湖南省共计划分为14个地区(13地级市和1自治州),122个县级行政区包括35个市辖区、17个县级市、63个县和7个自治县

result[0].Children.Count.ShouldBeGreaterThanOrEqualTo(14);

result[0].Children.Sum(p =>
p.Children.Count).ShouldBeGreaterThanOrEqualTo(122);

}

Magicodes.Echarts(基于EChart封装的映射库)

Magicodes.ECharts是心莱团队基于百度EChart封装的开源的.NET类库,以便让用户更快更便捷的上手开发EChart图表。
相关资料请访问我们的官方博客。

使用教程:http://www.cnblogs.com/codelove/p/5969036.html

官方博客:http://www.cnblogs.com/codelove/

相关开源库地址:https://github.com/xin-lai

我们的官网:http://xin-lai.com

在开始之前,您需要了解以下内容:

  • Magicodes.ECharts是基于百度EChart封装的开源的.NET类库,封装的目的便于使用强类型语言约束后台代码,以便于更好维护和重构代码,并且封装自身业务

  • Magicodes.EChartsJS是基于knockoutJs封装的组件,结合Magicodes.ECharts能够很方便的利用Ajax加载Echart图表

  • 目前Magicodes.ECharts已经支持大部分图表,但是尚不能支持所有图表和所有情形

  • 本着按需设计的原则,在遇到不支持的情形,希望您能够自行扩展并贡献自己的代码。众人拾材火焰高,Magicodes.ECharts在不断地实践中会更加完善的

  • 在设计上,我们不会过多设计,但是后续版本可能会不断地进行重构

源码中提供了一些Demo,在开始之前,请进行阅读。

Magicodes.Mvc.TrustIP(服务端授信IP中间件)

基于ASP.NET
Core的筛选器和中间件打造的通用授信IP通用库,支持筛选器和中间件配置,支持全局和局部使用.

Nuget

VNext

  • 黑名单

  • 支持内存缓存以及分布式缓存

  • 本地IP是否授信

配置

支持配置多个授信IP,如下”TrustIpList”所示:

{ “TrustIpList”: [ “218.76.8.29”, “::1” ] }

注意:0.0.0.0 表示支持任意Ip

使用

筛选器

启用全局筛选器

services.AddMvc(options =>
options.Filters.Add(typeof(TrustIPFilter))).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

在控制器中使用

// GET api/values

[HttpGet]

//也可以单独配置

[ServiceFilter(typeof(TrustIpFilter))]

public ActionResult<IEnumerable<string>> Get()

{

return new string[] { “value1”, “value2” };

}

中间件

启用中间件: app.UseTrustIP(loggerFactory, Configuration);

结果

如当前请求IP未在授信IP列表之内,则返回http状态码403

注意事项

Nginx 代理不能获取IP问题

app.UseForwardedHeaders(new ForwardedHeadersOptions

{

ForwardedHeaders = ForwardedHeaders.XForwardedFor |
ForwardedHeaders.XForwardedProto

});


 上一篇
持续集成 持续集成
使用Jenkins来实现内部的持续集成流程安装和配置注:不要将Jenkins安装在带空格的目录中(特别是workspace的目录) 比如C:\ProgramFiles (x86)\Jenkins\workspace\ 没错 Files附近有
2019-05-06
下一篇 
常见问题 常见问题
服务器不支持HttpPut和HttpDelete建议增加以下配置进行尝试: <system.webServer> <modules> <remove name=”WebDAVModule” /> <
2019-05-06
  目录