282 lines
7.5 KiB
C#
282 lines
7.5 KiB
C#
using AutoMapper;
|
||
|
||
using ChouBox.Code.TencentCloudExtend.Model;
|
||
using ChouBox.Model.Entities;
|
||
|
||
using HuanMeng.DotNetCore.Base;
|
||
using HuanMeng.DotNetCore.Extensions;
|
||
|
||
using Microsoft.AspNetCore.Http;
|
||
using Microsoft.EntityFrameworkCore;
|
||
using Microsoft.Extensions.Configuration;
|
||
using Microsoft.Extensions.DependencyInjection;
|
||
using Microsoft.Extensions.Logging;
|
||
|
||
using Newtonsoft.Json;
|
||
|
||
using StackExchange.Redis;
|
||
|
||
using System.Threading.Tasks;
|
||
|
||
namespace ChouBox.Code.AppExtend;
|
||
|
||
/// <summary>
|
||
/// bll 基础类
|
||
/// </summary>
|
||
public class ChouBoxCodeBase
|
||
{
|
||
/// <summary>
|
||
/// _serviceProvider,提供基本依赖注入支持
|
||
/// </summary>
|
||
protected readonly IServiceProvider _serviceProvider;
|
||
/// <summary>
|
||
/// 构造函数
|
||
/// </summary>
|
||
/// <param name="serviceProvider"></param>
|
||
public ChouBoxCodeBase(IServiceProvider serviceProvider)
|
||
{
|
||
_serviceProvider = serviceProvider;
|
||
}
|
||
|
||
private EfCoreDaoBase<YoudaContext>? _dao;
|
||
/// <summary>
|
||
/// 数据库,
|
||
/// 更新删除,尽量只操作本bll实例dao获取到的对象,取和存要同一个dao
|
||
/// </summary>
|
||
public EfCoreDaoBase<YoudaContext> Dao
|
||
{
|
||
get
|
||
{
|
||
if (_dao == null)
|
||
{
|
||
_dao = new EfCoreDaoBase<YoudaContext>(_serviceProvider.GetRequiredService<YoudaContext>());
|
||
|
||
}
|
||
return _dao;
|
||
}
|
||
}
|
||
|
||
#region 映射
|
||
private IMapper _mapper;
|
||
/// <summary>
|
||
/// DTO 映射
|
||
/// </summary>
|
||
public virtual IMapper Mapper
|
||
{
|
||
get
|
||
{
|
||
if (_mapper == null)
|
||
{
|
||
_mapper = _serviceProvider.GetRequiredService<IMapper>();
|
||
}
|
||
return _mapper;
|
||
}
|
||
set
|
||
{
|
||
_mapper = value;
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region 请求信息
|
||
private IHttpContextAccessor _httpContextAccessor;
|
||
/// <summary>
|
||
/// HttpContextAccessor
|
||
/// </summary>
|
||
public IHttpContextAccessor HttpContextAccessor
|
||
{
|
||
get
|
||
{
|
||
if (_httpContextAccessor == null)
|
||
{
|
||
_httpContextAccessor = _serviceProvider.GetRequiredService<IHttpContextAccessor>();
|
||
|
||
}
|
||
return _httpContextAccessor;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取客户端真实IP地址,考虑Nginx等代理情况
|
||
/// </summary>
|
||
/// <returns>客户端真实IP地址</returns>
|
||
protected string GetRealIpAddress()
|
||
{
|
||
var context = HttpContextAccessor.HttpContext;
|
||
if (context == null)
|
||
return "unknown";
|
||
|
||
// 尝试从X-Forwarded-For获取真实IP
|
||
string ip = context.Request.Headers["X-Forwarded-For"].FirstOrDefault();
|
||
|
||
// 如果X-Forwarded-For为空,尝试X-Real-IP
|
||
if (string.IsNullOrEmpty(ip))
|
||
{
|
||
ip = context.Request.Headers["X-Real-IP"].FirstOrDefault();
|
||
}
|
||
|
||
// 尝试其他可能包含真实IP的头
|
||
if (string.IsNullOrEmpty(ip))
|
||
{
|
||
ip = context.Request.Headers["Proxy-Client-IP"].FirstOrDefault();
|
||
}
|
||
|
||
if (string.IsNullOrEmpty(ip))
|
||
{
|
||
ip = context.Request.Headers["WL-Proxy-Client-IP"].FirstOrDefault();
|
||
}
|
||
|
||
if (string.IsNullOrEmpty(ip))
|
||
{
|
||
ip = context.Request.Headers["HTTP_CLIENT_IP"].FirstOrDefault();
|
||
}
|
||
|
||
if (string.IsNullOrEmpty(ip))
|
||
{
|
||
ip = context.Request.Headers["HTTP_X_FORWARDED_FOR"].FirstOrDefault();
|
||
}
|
||
|
||
// 如果还是获取不到,则使用RemoteIpAddress
|
||
if (string.IsNullOrEmpty(ip))
|
||
{
|
||
ip = context.Connection.RemoteIpAddress?.ToString();
|
||
}
|
||
|
||
// 如果X-Forwarded-For包含多个IP,取第一个非内网IP
|
||
if (!string.IsNullOrEmpty(ip) && ip.Contains(","))
|
||
{
|
||
ip = ip.Split(',')[0].Trim();
|
||
}
|
||
|
||
return ip ?? "unknown";
|
||
}
|
||
#endregion
|
||
|
||
#region 日志
|
||
private ILogger<ChouBoxCodeBase> _logger;
|
||
/// <summary>
|
||
/// 日志
|
||
/// </summary>
|
||
public ILogger<ChouBoxCodeBase> Logger
|
||
{
|
||
get
|
||
{
|
||
if (_logger == null)
|
||
{
|
||
_logger = _serviceProvider.GetRequiredService<ILogger<ChouBoxCodeBase>>();
|
||
}
|
||
return _logger;
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
public IConfiguration Configuration()
|
||
{
|
||
return _serviceProvider.GetRequiredService<IConfiguration>();
|
||
}
|
||
|
||
#region Redis
|
||
private IDatabase _redis;
|
||
/// <summary>
|
||
/// Redis 缓存
|
||
/// </summary>
|
||
public IDatabase RedisCache
|
||
{
|
||
get
|
||
{
|
||
if (_redis == null)
|
||
{
|
||
var connectionMultiplexer = _serviceProvider.GetRequiredService<IConnectionMultiplexer>();
|
||
_redis = connectionMultiplexer.GetDatabase();
|
||
}
|
||
return _redis;
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
/// <summary>
|
||
/// 获取腾讯云短信配置
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public async Task<TencentSMSConfig> GetTencentSMSConfigAsync()
|
||
{
|
||
var config = await this.GetConfigAsync<TencentSMSConfig>("tencent_sms_config");
|
||
if (config == null)
|
||
{
|
||
config = new TencentSMSConfig()
|
||
{
|
||
SecretId = "AKIDLbhdP0Vs57yd7QZWu8A2jFbno8JKBUp6",
|
||
SecretKey = "",
|
||
ReqMethod = "POST",
|
||
Timeout = 30,
|
||
SmsSdkAppId = "1400923253",
|
||
SignName = "上海寰梦科技发展",
|
||
TemplateId = "2209122"
|
||
|
||
};
|
||
}
|
||
return config;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取系统配置
|
||
/// </summary>
|
||
/// <param name="type">配置关键词</param>
|
||
/// <returns>配置信息</returns>
|
||
public Dictionary<string, object> GetConfig(string type)
|
||
{
|
||
// 生成缓存键
|
||
string cacheKey = $"config:{type}";
|
||
|
||
// 尝试从缓存获取数据
|
||
var cachedData = RedisCache.StringGet<Dictionary<string, object>>(cacheKey);
|
||
if (cachedData != null)
|
||
{
|
||
return cachedData;
|
||
}
|
||
|
||
// 从数据库查询
|
||
var content = Dao.Context.Config.Where(it => it.Key == type).FirstOrDefault();
|
||
Dictionary<string, object> config = null;
|
||
|
||
if (content != null)
|
||
{
|
||
|
||
var d = JsonConvert.DeserializeObject<Dictionary<string, object>>(content.Value);
|
||
RedisCache.StringSet(cacheKey, content.Value, TimeSpan.FromMinutes(10));
|
||
return d;
|
||
}
|
||
return null;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取系统配置
|
||
/// </summary>
|
||
/// <typeparam name="T">实体类</typeparam>
|
||
/// <param name="type">配置key</param>
|
||
/// <returns></returns>
|
||
public async Task<T?> GetConfigAsync<T>(string type) where T : class
|
||
{
|
||
// 生成缓存键
|
||
string cacheKey = $"config:{type}";
|
||
|
||
// 尝试从缓存获取数据
|
||
var cachedData = RedisCache.StringGet<T>(cacheKey);
|
||
if (cachedData != null)
|
||
{
|
||
return cachedData;
|
||
}
|
||
// 从数据库查询
|
||
var content = await Dao.Context.Config.Where(it => it.Key == type).FirstOrDefaultAsync();
|
||
|
||
if (content != null && !string.IsNullOrEmpty(content.Value))
|
||
{
|
||
var d = JsonConvert.DeserializeObject<T>(content.Value);
|
||
RedisCache.StringSet(cacheKey, content.Value, TimeSpan.FromMinutes(10));
|
||
return d;
|
||
}
|
||
return null;
|
||
}
|
||
}
|