【愚公系列】2022年03月 .NET架构班 016-ABP vNext 设置模块

举报
愚公搬代码 发表于 2022/03/08 03:26:31 2022/03/08
【摘要】 一、设置模块 1.设置模块定义Abp.SettingUi是一个用来管理Abp中设置的模块, 简单来讲它可以让用户通过UI来管理ABP中各个设置的值, 比如修改默认语言, 设置密码复杂度等等, 可以说装上这个模块你就开启了ABP的"隐藏功能",应该说设置管理是一个很重要的功能, 但是ABP的社区版没有内置, 只在ABP的商业版中才有设置的UI, 但仍需开发者通过代码来为各个设置项进行适配才可...

一、设置模块

1.设置模块定义

Abp.SettingUi是一个用来管理Abp中设置的模块, 简单来讲它可以让用户通过UI来管理ABP中各个设置的值, 比如修改默认语言, 设置密码复杂度等等, 可以说装上这个模块你就开启了ABP的"隐藏功能",应该说设置管理是一个很重要的功能, 但是ABP的社区版没有内置, 只在ABP的商业版中才有设置的UI, 但仍需开发者通过代码来为各个设置项进行适配才可以,而SettingUi会自动扫描系统中所有的设置, 并在UI中显示出来, 无需开发者过多干预, 开箱即用

2.设置模块源码

下载地址:

https://github.com/abpframework/abp/tree/dev/modules/SettingManagement

二、集成设置模块

1.EBusiness.Domain.Shared集成设置模块

1、先在项目中通过Nuget下载

Volo.Abp.SettingManagement.Domain.Shared

2、然后在EBusinessDomainSharedModule文件上增加

[DependsOn(
        typeof(AbpSettingManagementDomainSharedModule)
        )]
 public class EBusinessDomainSharedModule : AbpModule
 {}

2.EBusiness.Domain集成设置模块

1、先在项目中通过Nuget下载

Volo.Abp.SettingManagement.Domain

2、然后在EBusinessDomainModule文件上增加

[DependsOn(
        typeof(AbpSettingManagementDomainModule)
        )]
    public class EBusinessDomainSharedModule : AbpModule

 {}

3.EBusiness.EntityFrameworkCore集成设置模块

1、先在项目中通过Nuget下载

Volo.Abp.SettingManagement.EntityFrameworkCore

2、然后在EBusinessEntityFrameworkCoreModule文件上增加

[DependsOn(
        typeof(AbpSettingManagementEntityFrameworkCoreModule)
        )]
    public class EBusinessEntityFrameworkCoreModule: AbpModule

 {}

3、然后在EBusinessDbContext类上实现ISettingManagementDbContext上下文

 public DbSet<SettingGrant> SettingGrants { get; }

4、然后在EBusinessDbContext类上添加

 [ReplaceDbContext(typeof(ISettingManagementDbContext))]
    [ConnectionStringName("Default")]
    public class EBusinessDbContext : 
        AbpDbContext<EBusinessDbContext>,
        ISettingManagementDbContext
    {
        .....
    	public DbSet<Setting> Settings { get; set; }
        .....
    }

5、然后在OnModelCreating方法中添加

 protected override void OnModelCreating(ModelBuilder builder)
 {
 	base.OnModelCreating(builder);

    /* Include modules to your migration db context */
    .....          
    builder.ConfigureSettingManagement();
    .....
 }

7、最后启动YDT.EBusiness.DbMigrator迁移项目,生成设置表
在这里插入图片描述

4.EBusiness.Application.Contracts集成设置模块

1、先在项目中通过Nuget下载

Volo.Abp.SettingManagement.Application.Contracts

2、然后在EBusinessApplicationContractsModule文件上增加

[DependsOn(
        typeof(AbpSettingManagementApplicationContractsModule)
        )]
 public class EBusinessApplicationContractsModule: AbpModule
 {}

5.EBusiness.Application集成设置模块

1、先在项目中通过Nuget下载

Volo.Abp.SettingManagement.Application.Contracts

2、然后在EBusinessApplicationModule文件上增加

[DependsOn(
        typeof(AbpSettingManagementApplicationModule)
        )]
 public class EBusinessApplicationContractsModule: AbpModule
 {}

6.EBusiness.HttpApi集成设置模块

1、先在项目中通过Nuget下载

Volo.Abp.SettingManagement.Application.Contracts

2、然后在EBusinessHttpApiModule文件上增加

[DependsOn(
        typeof(AbpSettingManagementHttpApiModule)
 )]
 public class EBusinessHttpApiModule: AbpModule
 {}

三、微信支付使用(默认支付)

1、先在EBusiness.Application.Contracts微信接口

/// <summary>
/// 支付接口
/// </summary>
public interface IPayAppService : IApplicationService
{
    /// <summary>
    /// 支付创建
    /// </summary>
    /// <param name="OrderSn"></param>
    /// <param name="OrderPrice"></param>
    /// <returns></returns>
    public string CreatePay(string productName, string orderSn, string totalPrice);
}

2、EBusiness.Application实现微信支付

/// <summary>
/// 微信支付
/// </summary>
public class WxPayAppService : EBusinessAppService, IPayAppService
{
    public WxPayHttpClient _wxPayHttpClient { set; get; }

    private const string nativeUrl = "https://api.mch.weixin.qq.com/v3/pay/transactions/native";// 支付接口
    private const string mchid = "**888888**8"; // 商户Id
    private const string certpath = @"***********"; // 商户证书路径
    private const string certSerialNo = "***********"; // 证书序列号

    protected WxPayOptions _wxPayOptions { get; }
    public IVirtualFileProvider _virtualFileProvider { set; get; }

    public WxPayAppService(IOptions<WxPayOptions> wxPayOptions)
    {
        _wxPayOptions = wxPayOptions.Value;
    }

    public string CreatePay(string productName, string orderSn, string totalPrice)
    {
        #region 1、默认支付
        {
            //var file = _virtualFileProvider.GetFileInfo("/Pays/certs/apiclient_cert.p12");
            var file = _virtualFileProvider.GetFileInfo("/apiclient_cert.p12");
            _virtualFileProvider.GetDirectoryContents("/");
            // 1、创建支付对象
            NativePay nativePay = new NativePay();
            nativePay.description = productName;
            nativePay.out_trade_no = orderSn;
            nativePay.amount.total = int.Parse(float.Parse(totalPrice) * 100 + "");

            // 2、支付对象转换成json
            string nativePayJson = JsonConvert.SerializeObject(nativePay);

            // 3、创建支付
            string result = _wxPayHttpClient.
                WeChatPostAsync(nativeUrl,
                nativePayJson,
                file.PhysicalPath,
                mchid,
               certSerialNo).Result;
            return result;
        }
        #endregion
    }
}

3、微信支付相关类

/// <summary>
/// 基本参数
/// </summary>
public class NativePay
{
    public string mchid = "1613333188";
    public string appid = "wx31eff1a74e251e9e";
    public string out_trade_no = "native12177525012014070332333";
    public string description = "Image形象店-深圳腾大-QQ公仔";
    public string notify_url = "http://406286l2k9.wicp.vip/WxCallback";

    public NativePayPrice amount { get; } = new NativePayPrice();
}
/// <summary>
/// 支付金额
/// </summary>
public class NativePayPrice
{
    public int total = 1;
    public string currency = "CNY";
   
}
/// <summary>
/// 微信支付核心类
/// </summary>
[Dependency(ServiceLifetime.Transient)]
public class WxPayHttpClient 
{
    private readonly IHttpClientFactory _httpClientFactory;
    public WxPayHttpClient(IHttpClientFactory httpClientFactory)
    {
        _httpClientFactory = httpClientFactory;
    }

    #region //微信支付请求
    /// <summary>
    /// 微信Post请求
    /// </summary>
    /// <param name="url">地址</param>
    /// <param name="requestString">参数</param>
    /// <param name="privateKey">商户证书 p12文件</param>
    /// <param name="merchantId">商户号</param>
    /// <param name="serialNo">商户证书号</param>
    /// <returns></returns>
    public async Task<string> WeChatPostAsync(string url, string requestString, string certPath, string merchantId, string serialNo)
    {
        try
        {
            var client = _httpClientFactory.CreateClient();

            // 1、请求体构造
            var requestContent = new StringContent(requestString);
            requestContent.Headers.ContentType.MediaType = "application/json";

            // 2、请求头构造
            var auth = BuildAuthAsync(url, requestString, certPath, merchantId, serialNo, "POST");
            string value = $"WECHATPAY2-SHA256-RSA2048 {auth}";
            client.DefaultRequestHeaders.Add("Authorization", value);
            client.DefaultRequestHeaders.Add("Accept", "application/json");
            client.DefaultRequestHeaders.Add("User-Agent", "WOW64");
            client.Timeout = TimeSpan.FromSeconds(60);

            // 3、请求
            var response = await client.PostAsync(url, requestContent);
            if (response.IsSuccessStatusCode)
            {
                var result = await response.Content.ReadAsStringAsync();
                return result;
            }
            else
            {
                throw new Exception($"微信支付调用遭遇异常,原因:错误代码{response.StatusCode},错误原因{response.ReasonPhrase}");
            }
        }
        catch (Exception ex)
        {
            throw new Exception($"微信支付调用遭遇异常,原因:" + ex.Message);
        }
    }
    /// <summary>
    /// 微信Get请求
    /// </summary>
    /// <param name="url">地址</param>
    /// <param name="requestString">参数</param>
    /// <param name="privateKey">私有证书 p12文件</param>
    /// <param name="merchantId">商户号</param>
    /// <param name="serialNo">商户证书号</param>
    /// <param name="method">Get或者Post</param>
    /// <returns></returns>
    public async Task<string> WeChatGetAsync(string url, string certPath, string merchantId, string serialNo)
    {
        try
        {
            var client = _httpClientFactory.CreateClient();
            var auth = BuildAuthAsync(url, "", certPath, merchantId, serialNo, "GET");
            string value = $"WECHATPAY2-SHA256-RSA2048 {auth}";
            client.DefaultRequestHeaders.Add("Authorization", value);
            client.DefaultRequestHeaders.Add("Accept", "*/*");
            client.DefaultRequestHeaders.Add("User-Agent", "WOW64");
            client.Timeout = TimeSpan.FromSeconds(60);
            var response = await client.GetAsync(url);
            if (response.IsSuccessStatusCode)
            {
                var result = await response.Content.ReadAsStringAsync();
                return result;
            }
            else
            {
                throw new Exception($"微信支付调用遭遇异常,原因:错误代码{response.StatusCode},错误原因{response.ReasonPhrase}");
            }
        }
        catch (Exception ex)
        {
            throw new Exception($"微信支付调用遭遇异常,原因:" + ex.Message);
        }
    }
    /// <summary>
    /// 1、构造Authorization
    /// </summary>
    /// <param name="url"></param>
    /// <param name="jsonParame"></param>
    /// <param name="certPath"></param>
    /// <param name="merchantId"></param>
    /// <param name="serialNo"></param>
    /// <param name="method"></param>
    /// <returns></returns>
    protected string BuildAuthAsync(string url, string jsonParame, string certPath, string merchantId, string serialNo, string method = "")
    {
        string body = jsonParame;
        var uri = new Uri(url);
        var urlPath = uri.PathAndQuery;
        var timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
        string nonce = Path.GetRandomFileName();

        string message = $"{method}\n{urlPath}\n{timestamp}\n{nonce}\n{body}\n";
        //string signature = Sign(message, privateKey);
       // var path = "apiclient_cert.p12";
        string signature = Sign(message, certPath, merchantId);
        return $"mchid=\"{merchantId}\",nonce_str=\"{nonce}\",timestamp=\"{timestamp}\",serial_no=\"{serialNo}\",signature=\"{signature}\"";
    }
    
    /// <summary>
    //// <summary>
    /// 2、签名
    /// </summary>
    /// <param name="data">要签名的数据</param>
    /// <param name="certPah">证书路径</param>
    /// <param name="certPwd">密码</param>
    /// <returns></returns>
    public string Sign(string data, string certPah, string certPwd)
    {
        var rsa = GetPrivateKey(certPah, certPwd);

        var rsaClear = new RSACryptoServiceProvider();

        var paras = rsa.ExportParameters(true);
        rsaClear.ImportParameters(paras);

        var signData = rsa.SignData(Encoding.UTF8.GetBytes(data), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
        return Convert.ToBase64String(signData);
    }

    
    /// <summary>
    /// 3、获取私钥
    /// </summary>
    /// <param name="priKeyFile">证书文件路径</param>
    /// <param name="keyPwd">密码</param>
    /// <returns></returns>
    private static RSA GetPrivateKey(string priKeyFile, string keyPwd)
    {
        var pc = new X509Certificate2(priKeyFile, keyPwd, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);
        return (RSA)pc.PrivateKey;
    }
    #endregion
}

在这里插入图片描述

四、微信支付使用(选项支付)

1、定义选项支付类

public class WxPayOptions
{
    public string nativeUrl { set; get; }// 支付接口
    public  string mchid { set; get; }// 商户Id
    public  string certpath { set; get; } // 商户证书路径
    public  string certSerialNo { set; get; }// 证书序列号

    public WxPayOptions()
    {
        nativeUrl = "https://api.mch.weixin.qq.com/v3/pay/transactions/native";
        mchid = "1613333188";
        certpath = @"***********";
        certSerialNo = "****8************";
    }
}

2、EBusinessApplicationModule配置选项支付类

//微信支付配置
// 使用configurtion 从配置文件中获取配置值
// appsettings.json配置文件缺点
// 1、无法复用
// 2、维护难度大

Configure<WxPayOptions>(options => {
    options.nativeUrl = "https://api.mch.weixin.qq.com/v3/pay/transactions/native";
    options.mchid = "1613333188";
    options.certpath = @"D:\work\net-project\ABP专题\4、核心项目-电商项目模块原理分析\YDT.EBusiness\src\YDT.EBusiness.Application\Pays\certs\apiclient_cert.p12";
    options.certSerialNo = "6FC4BB506EC38075C5F4F160885ED655A0604DC6";
});

3、EBusiness.Application实现微信支付

/// <summary>
/// 微信支付
/// </summary>
public class WxPayAppService : EBusinessAppService, IPayAppService
{
    public WxPayHttpClient _wxPayHttpClient { set; get; }

    protected WxPayOptions _wxPayOptions { get; }
    public IVirtualFileProvider _virtualFileProvider { set; get; }

    public WxPayAppService(IOptions<WxPayOptions> wxPayOptions)
    {
        _wxPayOptions = wxPayOptions.Value;
    }

    public string CreatePay(string productName, string orderSn, string totalPrice)
    {
        #region 2、选项支付
        {
            // 1、创建支付对象
            NativePay nativePay = new NativePay();
            nativePay.description = productName;
            nativePay.out_trade_no = orderSn;
            nativePay.amount.total = int.Parse(float.Parse(totalPrice) * 100 + "");

            // 2、支付对象转换成json
            string nativePayJson = JsonConvert.SerializeObject(nativePay);

            // 3、创建支付
            string result = _wxPayHttpClient.
                WeChatPostAsync(_wxPayOptions.nativeUrl,
                nativePayJson,
                _wxPayOptions.certpath,
                _wxPayOptions.mchid,
               _wxPayOptions.certSerialNo).Result;

            return result;

        }
        #endregion
    }
}

五、微信支付使用(设置支付)

1.设置定义

1、先在EBusiness.Domain模块中通过nuget引入

Volo.Abp.Settings

2、然后在EBusiness.Domain模块中Settings文件夹中创建EBusinessSettings类

public static class EBusinessSettings
{
    private const string Prefix = "EBusiness";

    /// <summary>
    /// 微信支付设置
    /// </summary>
    public static class WxPay
    {
        public const string Default = Prefix + ".WxPay";
        public const string NativeUrl = Default + ".nativeUrl";
        public const string Mchid = Default + ".mchid";
        public const string Certpath = Default + ".certpath";
        public const string CertSerialNo = Default + ".certSerialNo";
    }
}

3、然后在EBusiness.Domain模块中Settings文件夹中创建EBusinessSettingDefinitionProvider类

实现SettingDefinitionProvider抽象类

public class EBusinessSettingDefinitionProvider : SettingDefinitionProvider
{
    public override void Define(ISettingDefinitionContext context)
    {
        // 1、定义微信支付设置
        context.Add(
            new SettingDefinition(EBusinessSettings.WxPay.NativeUrl),
            new SettingDefinition(EBusinessSettings.WxPay.Mchid),
            new SettingDefinition(EBusinessSettings.WxPay.Certpath),
            new SettingDefinition(EBusinessSettings.WxPay.CertSerialNo));
    }
}

2.设置管理

1、EBusinessSettings接口
在这里插入图片描述
2、使用PUT接口添加设置到数据库
在这里插入图片描述

3.设置取值

1、在EBusiness.Application模块中WxPayAppService类中创建商品使用ISettingProvider获取设置信息

/// <summary>
/// 微信支付
/// </summary>
public class WxPayAppService : EBusinessAppService, IPayAppService
{
    public WxPayHttpClient _wxPayHttpClient { set; get; }

    protected WxPayOptions _wxPayOptions { get; }
    public IVirtualFileProvider _virtualFileProvider { set; get; }

    public WxPayAppService(IOptions<WxPayOptions> wxPayOptions)
    {
        _wxPayOptions = wxPayOptions.Value;
    }

    public string CreatePay(string productName, string orderSn, string totalPrice)
    {
        #region 3、设置支付
        {
            // 1、创建支付对象
            NativePay nativePay = new NativePay();
            nativePay.description = productName;
            nativePay.out_trade_no = orderSn;
            nativePay.amount.total = int.Parse(float.Parse(totalPrice) * 100 + "");

            // 2、支付对象转换成json
            string nativePayJson = JsonConvert.SerializeObject(nativePay);

            // 3、创建支付
            string a1 = SettingProvider.GetOrNullAsync(EBusinessSettings.WxPay.NativeUrl).Result;
            string a2 = SettingProvider.GetOrNullAsync(EBusinessSettings.WxPay.Certpath).Result;
            string a3 = SettingProvider.GetOrNullAsync(EBusinessSettings.WxPay.Mchid).Result;
            string a4 = SettingProvider.GetOrNullAsync(EBusinessSettings.WxPay.CertSerialNo).Result;
            string result = _wxPayHttpClient.
                WeChatPostAsync(SettingProvider.GetOrNullAsync(EBusinessSettings.WxPay.NativeUrl).Result,
                nativePayJson,
                SettingProvider.GetOrNullAsync(EBusinessSettings.WxPay.Certpath).Result,
                SettingProvider.GetOrNullAsync(EBusinessSettings.WxPay.Mchid).Result,
               SettingProvider.GetOrNullAsync(EBusinessSettings.WxPay.CertSerialNo).Result).Result;

            return result;
        }
        #endregion
    }
}

六、设置模块原理

1.设置定义原理

条件

1、Volo.Abp.Settings模块

接口

1、SettingDefinition

2、SettingDefinitionProvider

3、SettingDefinitionManager

说明

1、SettingDefinition执行定义

2、SettingDefinitionProvider提供设置。

3、SettingDefinitionManager 核心执行

2.设置管理原理

条件

1、EBusiness.Application模块

2、Volo.Abp.SettingManagement.Domain模块

接口

1、EBusinessSettingsAppService

2、SettingManager

3、SettingManagementProvider (默认GlobalSettingManagementProvider)

4、SettingManagementStore

说明

1、EBusinessSettingsAppService负责接口入口

2、SettingManager负责客户端调用

3、SettingManagementProvider负责设置扩展

4、SettingManagementStore负责设置取值

3.设置取值原理

条件

1、Volo.Abp.Settings模块

接口

1、SettingProvider

2、SettingValueProviderManager

3、SettingValueProvider(默认:GlobalSettingValueProvider)

4、SettingDefinitionManager

说明

1、SettingProvider负责客户端取值

2、SettingValueProviderManager负责提供设置扩展管理

3、SettingValueProvider负责获取设置值

4、SettingDefinitionManager负责设置定义管理

七、设置模块其他客户端使用

1.EBusiness.Web页面访问设置模块

1、先在EBusiness.Web模块中通过Nuget引入

Volo.Abp.SettingManagement.Web

2、然后在EBusiness.Web模块中EBusinessWebModule类上添加

[DependsOn(
    ....
        typeof(AbpSettingManagementWebModule),
     ....
        )]
    public class EBusinessWebModule : AbpModule
    {}

2.OA系统调用设置模块

1、先在项目中通过Nuget下载

Volo.Abp.SettingManagement.HttpApi.Client

2、然后在YDT.OA文件上增加

 [DependsOn(
	typeof(AbpSettingManagementHttpApiClientModule)
 )]
 public class OAModule: AbpModule
 {}
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。