diff --git a/src/Shentun.Sms.Application/Jobs/SmsSendJob.cs b/src/Shentun.Sms.Application/Jobs/SmsSendJob.cs index ecce2cb..8cac135 100644 --- a/src/Shentun.Sms.Application/Jobs/SmsSendJob.cs +++ b/src/Shentun.Sms.Application/Jobs/SmsSendJob.cs @@ -12,6 +12,8 @@ using Volo.Abp.Domain.Repositories; using Volo.Abp; using Microsoft.Extensions.Configuration; using Shentun.Sms.Service.Sms; +using Volo.Abp.Caching; +using Microsoft.Extensions.Logging; namespace Shentun.Sms.Jobs { @@ -21,24 +23,32 @@ namespace Shentun.Sms.Jobs [RemoteService(false)] public class SmsSendJob : ApplicationService, ISmsSendJob { + + //private readonly IServiceProvider _service; + private readonly IRepository _smsSendRepository; private readonly IRepository _smsTaskRepository; private readonly SmsSendManager _smsSendManager; - private readonly IConfiguration _tencentSmsConfig; + private readonly IConfiguration _configuration; + private readonly SmsFactory _smsFactory; + + private readonly ILogger _logger; public SmsSendJob( SmsSendManager smsSendManager, IRepository smsSendRepository, - IConfiguration tencentSmsConfig, - IRepository smsTaskRepository - ) + IConfiguration configuration, + IRepository smsTaskRepository, + ILogger logger, + SmsFactory smsFactory) { _smsSendManager = smsSendManager; _smsSendRepository = smsSendRepository; - _tencentSmsConfig = tencentSmsConfig; + _configuration = configuration; _smsTaskRepository = smsTaskRepository; + _logger = logger; + _smsFactory = smsFactory; } - public async Task DoWork() { try @@ -49,7 +59,8 @@ namespace Shentun.Sms.Jobs select new { a, - CountryCode = b.CountryCode + CountryCode = b.CountryCode, + Content = b.Content }; @@ -58,15 +69,18 @@ namespace Shentun.Sms.Jobs foreach (var item in smsSendQuery.ToList()) { string CountryCode = item.CountryCode; - SmsSendAsync(item.a, CountryCode); + string Content = item.Content; + SmsSendAsync(item.a, CountryCode, Content); smsSendUpdateList.Add(item.a); } await _smsSendRepository.UpdateManyAsync(smsSendUpdateList); + + _logger.LogInformation($"------扫描处理了【{smsSendUpdateList.Count}】条SmsSend记录------当前时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}"); } catch (Exception ex) { - + _logger.LogInformation(ex.ToString()); } } @@ -76,25 +90,18 @@ namespace Shentun.Sms.Jobs /// /// /// - public void SmsSendAsync(SmsSend smsSend, string CountryCode) + public void SmsSendAsync(SmsSend smsSend, string CountryCode, string Content) { - SmsFactory smsFactory = new SmsFactory(_tencentSmsConfig); - - SmsBase smsBase = smsFactory.CreateSms(); - - Random rd = new Random(); - - string[] phoneNumber = { $"+{CountryCode}{smsSend.MobileTelephone}" }; - string[] templateParam = { rd.Next(1000, 9999).ToString(), "10" }; - - + if (!string.IsNullOrEmpty(CountryCode) && !string.IsNullOrEmpty(smsSend.MobileTelephone)) + { + SmsBase smsBase = _smsFactory.CreateSms(); - //phoneNumber.Append($"+{CountryCode}{smsSend.MobileTelephone}"); - //templateParam.Append(rd.Next(1000, 9999).ToString()); - //templateParam.Append("10"); + string[] phoneNumber = { $"+{CountryCode}{smsSend.MobileTelephone}" }; - smsBase.Send(phoneNumber, templateParam); + string[] templateParam = Content.Trim('|').Split("|", StringSplitOptions.RemoveEmptyEntries); + smsBase.Send(phoneNumber, templateParam); + } smsSend.IsActive = 'N'; smsSend.IsComplete = 'Y'; } diff --git a/src/Shentun.Sms.Application/Jobs/SmsTaskJob.cs b/src/Shentun.Sms.Application/Jobs/SmsTaskJob.cs index 631c5c3..fd97da9 100644 --- a/src/Shentun.Sms.Application/Jobs/SmsTaskJob.cs +++ b/src/Shentun.Sms.Application/Jobs/SmsTaskJob.cs @@ -1,6 +1,8 @@ using Cronos; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; using Shentun.Sms.Enums; +using Shentun.Sms.Service.Sms; using Shentun.Sms.SmsApps; using Shentun.Sms.SmsSends; using Shentun.Sms.SmsTasks; @@ -9,8 +11,10 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using TencentCloud.Ic.V20190307.Models; using Volo.Abp; using Volo.Abp.Application.Services; +using Volo.Abp.Caching; using Volo.Abp.Domain.Repositories; using Volo.Abp.Identity; @@ -21,53 +25,72 @@ namespace Shentun.Sms.Jobs /// public class SmsTaskJob : ApplicationService, ISmsTaskJob { + + private readonly IRepository _smsTaskRepository; private readonly IRepository _smsSendRepository; + private readonly SmsSendManager _smsSendManager; private readonly IConfiguration _configuration; + + private readonly ILogger _logger; + + private readonly SmsFactory _smsFactory; public SmsTaskJob( IRepository smsTaskRepository, SmsSendManager smsSendManager, IConfiguration configuration, - IRepository smsSendRepository - ) + IRepository smsSendRepository, + SmsFactory smsFactory, + ILogger logger) { _smsTaskRepository = smsTaskRepository; _smsSendManager = smsSendManager; _configuration = configuration; _smsSendRepository = smsSendRepository; + _smsFactory = smsFactory; + _logger = logger; } - [RemoteService(false)] + //[RemoteService(false)] public async Task DoWork() { - var smsTaskList = (from a in await _smsTaskRepository.GetQueryableAsync() - join b in await _smsSendRepository.GetQueryableAsync() on a.Id equals b.SmsTaskId into bb - from ab in bb.DefaultIfEmpty() - where a.IsActive == 'Y' && ab == null - select a).ToList(); + try + { + _logger.LogInformation("测试"); + var smsTaskList = (from a in await _smsTaskRepository.GetQueryableAsync() + join b in await _smsSendRepository.GetQueryableAsync() on a.Id equals b.SmsTaskId into bb + from ab in bb.DefaultIfEmpty() + where a.IsActive == 'Y' && ab == null + select a).ToList(); - List smsSendList = new List(); + List smsSendList = new List(); - foreach (var smsTask in smsTaskList) - { - CreateSmsSendAsync(smsTask, smsSendList); - } + foreach (var smsTask in smsTaskList) + { + CreateSmsSendAsync(smsTask, smsSendList); + } - if (smsSendList.Any()) - { - await _smsSendRepository.InsertManyAsync(smsSendList); - } + if (smsSendList.Any()) + { + await _smsSendRepository.InsertManyAsync(smsSendList); + } - if (smsTaskList.Any()) + if (smsTaskList.Any()) + { + await _smsTaskRepository.UpdateManyAsync(smsTaskList); + } + + _logger.LogInformation($"------扫描处理了【{smsTaskList.Count}】条SmsTask记录,生成了【{smsSendList.Count}】条短信记录------当前时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}"); + } + catch (Exception ex) { - await _smsTaskRepository.UpdateManyAsync(smsTaskList); + _logger.LogInformation(ex.ToString()); } - } /// @@ -80,17 +103,13 @@ namespace Shentun.Sms.Jobs public void CreateSmsSendAsync(SmsTask smsTask, List smsSendList) { string SmsInterfaceId = _configuration.GetValue("Sms:SmsInterfaceId"); - if (string.IsNullOrEmpty(SmsInterfaceId)) - { - SmsInterfaceId = "001"; - } if (smsTask.TaskCycleType == TaskCycleTypeFlag.TimelySend) { var smsSendEntity = new SmsSend(GuidGenerator.Create()) { Content = smsTask.Content, - IsActive = 'Y', - IsComplete = 'N', + IsActive = 'N', + IsComplete = 'Y', SmsInterfaceId = SmsInterfaceId, SmsTaskId = smsTask.Id, PlanSendTime = DateTime.Now @@ -98,6 +117,17 @@ namespace Shentun.Sms.Jobs _smsSendManager.CreateAsync(smsSendEntity); + //发送短信 + // SmsFactory smsFactory = new SmsFactory(_configuration); + + SmsBase smsBase = _smsFactory.CreateSms(); + + string[] phoneNumber = { $"+{smsTask.CountryCode}{smsTask.MobileTelephone}" }; + string[] templateParam = smsTask.Content.Trim('|').Split("|", StringSplitOptions.RemoveEmptyEntries); + + + smsBase.Send(phoneNumber, templateParam); + smsSendList.Add(smsSendEntity); } @@ -109,24 +139,40 @@ namespace Shentun.Sms.Jobs #region 解析Cron表达式 - var schedule = CronExpression.Parse(taskCorn, CronFormat.IncludeSeconds); - var occurrences = schedule.GetOccurrences(DateTime.UtcNow, smsTask.StopTime.Value.ToUniversalTime()); //获取截止时间前所有的计划时间 - foreach (var occurrence in occurrences) + try { - var smsSendEntity = new SmsSend(GuidGenerator.Create()) + var schedule = CronExpression.Parse(taskCorn, CronFormat.IncludeSeconds); + var occurrences = schedule.GetOccurrences(DateTime.UtcNow, smsTask.StopTime.Value.ToUniversalTime()); //获取截止时间前所有的计划时间 + + if (occurrences.Count() < 10) { - Content = smsTask.Content, - IsActive = 'Y', - IsComplete = 'N', - SmsInterfaceId = SmsInterfaceId, - SmsTaskId = smsTask.Id, - MobileTelephone = smsTask.MobileTelephone, - PlanSendTime = occurrence - }; - - _smsSendManager.CreateAsync(smsSendEntity); - - smsSendList.Add(smsSendEntity); + foreach (var occurrence in occurrences) + { + var smsSendEntity = new SmsSend(GuidGenerator.Create()) + { + Content = smsTask.Content, + IsActive = 'Y', + IsComplete = 'N', + SmsInterfaceId = SmsInterfaceId, + SmsTaskId = smsTask.Id, + MobileTelephone = smsTask.MobileTelephone, + PlanSendTime = occurrence + }; + + _smsSendManager.CreateAsync(smsSendEntity); + + smsSendList.Add(smsSendEntity); + + } + } + else + { + _logger.LogInformation($"------Id为【{smsTask.Id}】的SmsTask记录,Corn表达式记录超出10条,已跳过------当前时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}"); + } + } + catch (Exception ex) + { + _logger.LogInformation($"------处理Corn表达式异常------,{ex.ToString()}"); } diff --git a/src/Shentun.Sms.EntityFrameworkCore/EntityFrameworkCore/SmsDbContext.cs b/src/Shentun.Sms.EntityFrameworkCore/EntityFrameworkCore/SmsDbContext.cs index 9891e61..a70682a 100644 --- a/src/Shentun.Sms.EntityFrameworkCore/EntityFrameworkCore/SmsDbContext.cs +++ b/src/Shentun.Sms.EntityFrameworkCore/EntityFrameworkCore/SmsDbContext.cs @@ -1,11 +1,13 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.ChangeTracking; +using Microsoft.Extensions.Logging; using Shentun.Sms.DbMapping; using Shentun.Sms.SmsApps; using Shentun.Sms.SmsInterfaces; using Shentun.Sms.SmsSends; using Shentun.Sms.SmsTasks; using Shentun.Sms.SmsTypes; +using System; using Volo.Abp.AuditLogging; using Volo.Abp.AuditLogging.EntityFrameworkCore; using Volo.Abp.BackgroundJobs; @@ -165,4 +167,12 @@ public class SmsDbContext : base.ApplyAbpConceptsForAddedEntity(entry); SetModificationAuditProperties(entry); } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + ////日志输出SQL语句 + //optionsBuilder.LogTo(Console.WriteLine, LogLevel.Information) + // .EnableSensitiveDataLogging(); + base.OnConfiguring(optionsBuilder); + } } diff --git a/src/Shentun.Sms.HttpApi.Host/Logger/CustomLogger.cs b/src/Shentun.Sms.HttpApi.Host/Logger/CustomLogger.cs new file mode 100644 index 0000000..82e3c79 --- /dev/null +++ b/src/Shentun.Sms.HttpApi.Host/Logger/CustomLogger.cs @@ -0,0 +1,52 @@ +using Microsoft.Extensions.Logging; +using System; +using System.IO; + +namespace Shentun.Sms.Logger +{ + public class CustomLogger : ILogger + { + private string _categoryName; + + public CustomLogger(string categoryName) + { + _categoryName = categoryName; + } + + + + public IDisposable BeginScope(TState state) + { + return null; + } + + public bool IsEnabled(LogLevel logLevel) + { + return true; + } + + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) + { + string message = $"{DateTime.Now} - {logLevel} - {_categoryName} - {formatter(state, exception)}"; + File.AppendAllText("job_log.txt", message); + } + + //public static void LogInformation(this ILogger logger, string? message, params object?[] args) + //{ + // logger.Log(LogLevel.Information, message, args); + //} + + } + + public class CustomLoggerProvider : ILoggerProvider + { + public ILogger CreateLogger(string categoryName) + { + return new CustomLogger(categoryName); + } + + public void Dispose() + { + } + } +} diff --git a/src/Shentun.Sms.HttpApi.Host/Program.cs b/src/Shentun.Sms.HttpApi.Host/Program.cs index 7cb5a3e..ae20bb9 100644 --- a/src/Shentun.Sms.HttpApi.Host/Program.cs +++ b/src/Shentun.Sms.HttpApi.Host/Program.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using Hangfire; using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Serilog; @@ -14,23 +15,38 @@ public class Program { public async static Task Main(string[] args) { + // Log.Logger = new LoggerConfiguration() + //#if DEBUG + // .MinimumLevel.Debug() + //#else + // .MinimumLevel.Information() + //#endif + // .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + // .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning) + // .Enrich.FromLogContext() + // .WriteTo.Async(c => c.File("Logs/logs.txt")) + // .WriteTo.Async(c => c.Console()) + // .CreateLogger(); + Log.Logger = new LoggerConfiguration() #if DEBUG - .MinimumLevel.Debug() + .MinimumLevel.Debug() #else .MinimumLevel.Information() #endif .MinimumLevel.Override("Microsoft", LogEventLevel.Information) .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning) .Enrich.FromLogContext() - .WriteTo.Async(c => c.File("Logs/logs.txt")) + .WriteTo.Async(c => c.File("Logs/logs.txt", rollingInterval: RollingInterval.Day)) +#if DEBUG .WriteTo.Async(c => c.Console()) +#endif .CreateLogger(); try { - + Log.Information("Starting Shentun.Sms.HttpApi.Host."); var builder = WebApplication.CreateBuilder(args); builder.Host.AddAppSettingsSecretsJson() @@ -40,17 +56,18 @@ public class Program var app = builder.Build(); await app.InitializeApplicationAsync(); - var TaskCron = builder.Configuration["JobCron:TaskCron"]; - if (!string.IsNullOrWhiteSpace(TaskCron)) - { - RecurringJob.AddOrUpdate("扫描短信计划", o => o.DoWork(), TaskCron); - } + //var TaskCron = builder.Configuration["JobCron:TaskCron"]; + //if (!string.IsNullOrWhiteSpace(TaskCron)) + //{ + // RecurringJob.AddOrUpdate("扫描短信计划", o => o.DoWork(), TaskCron); + //} + + //var SendCron = builder.Configuration["JobCron:SendCron"]; + //if (!string.IsNullOrWhiteSpace(SendCron)) + //{ + // RecurringJob.AddOrUpdate("执行发送短信扫描", o => o.DoWork(), SendCron); + //} - var SendCron = builder.Configuration["JobCron:SendCron"]; - if (!string.IsNullOrWhiteSpace(SendCron)) - { - RecurringJob.AddOrUpdate("执行发送短信扫描", o => o.DoWork(), SendCron); - } await app.RunAsync(); diff --git a/src/Shentun.Sms.HttpApi.Host/SmsHttpApiHostModule.cs b/src/Shentun.Sms.HttpApi.Host/SmsHttpApiHostModule.cs index cde81c7..8ca2b76 100644 --- a/src/Shentun.Sms.HttpApi.Host/SmsHttpApiHostModule.cs +++ b/src/Shentun.Sms.HttpApi.Host/SmsHttpApiHostModule.cs @@ -12,10 +12,13 @@ using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; using Microsoft.OpenApi.Models; using OpenIddict.Validation.AspNetCore; using Shentun.Sms.EntityFrameworkCore; +using Shentun.Sms.Logger; using Shentun.Sms.MultiTenancy; +using Shentun.Sms.Service.Sms; using System; using System.Collections.Generic; using System.Globalization; @@ -135,12 +138,29 @@ public class SmsHttpApiHostModule : AbpModule #endregion - ///解除https限制 + #region 解除https限制 + context.Services.AddOpenIddict() .AddServer(option => { option.UseAspNetCore().DisableTransportSecurityRequirement(); }); + #endregion + + #region 本地日志 + + context.Services.AddLogging(builder => + { + builder.AddProvider(new CustomLoggerProvider()); + }); + #endregion + + #region 注册服务 + + context.Services.AddSingleton(); + context.Services.AddSingleton(); + + #endregion } /// @@ -150,14 +170,16 @@ public class SmsHttpApiHostModule : AbpModule /// private void ConfigureHangfire(ServiceConfigurationContext context, IConfiguration configuration) { + context.Services.AddHangfire(config => { + //TimeZoneInfo.Local + config.UsePostgreSqlStorage(configuration.GetConnectionString("Default"), new PostgreSqlStorageOptions { - QueuePollInterval = TimeSpan.FromSeconds(30), + QueuePollInterval = TimeSpan.FromSeconds(30) }); - //config.UseDashboardMetric(DashboardMetrics.ServerCount) // .UseDashboardMetric(DashboardMetrics.RecurringJobCount) // .UseDashboardMetric(DashboardMetrics.RetriesCount) @@ -356,7 +378,7 @@ public class SmsHttpApiHostModule : AbpModule } - // app.UseHangfireDashboard(); + app.UseHangfireDashboard(); // app.UseHangfireDashboard("/hangfire", new DashboardOptions // { diff --git a/src/Shentun.Sms.HttpApi.Host/appsettings.json b/src/Shentun.Sms.HttpApi.Host/appsettings.json index 0ebcac7..eb055da 100644 --- a/src/Shentun.Sms.HttpApi.Host/appsettings.json +++ b/src/Shentun.Sms.HttpApi.Host/appsettings.json @@ -26,11 +26,10 @@ "Sms": { "SmsInterfaceId": "001", "Platform": "Tencent" - }, "JobCron": { - "TaskCron": "0 0 */2 * * ?", /*扫描Task 10分钟一次*/ - "SendCron": "0 */2 * * * ?" /*扫描Send 1小时一次*/ + "TaskCron": "0 0,30 */1 * * ?", /*扫描Task 1小时二次(0分、30分执行)*/ + "SendCron": "0 10 */1 * * ?" /*扫描Send 1小时一次(每小时10分执行)*/ }, "AspNetCore": { "ConventionalControllers": { @@ -51,4 +50,5 @@ "Timeout": 60 //超时 秒 } + } diff --git a/src/Shentun.Sms.Service/Shentun.Sms.Service.csproj b/src/Shentun.Sms.Service/Shentun.Sms.Service.csproj index 0e2d6ef..3f9f558 100644 --- a/src/Shentun.Sms.Service/Shentun.Sms.Service.csproj +++ b/src/Shentun.Sms.Service/Shentun.Sms.Service.csproj @@ -9,6 +9,7 @@ + diff --git a/src/Shentun.Sms.Service/Sms/SmsFactory.cs b/src/Shentun.Sms.Service/Sms/SmsFactory.cs index 4da7afc..b32a429 100644 --- a/src/Shentun.Sms.Service/Sms/SmsFactory.cs +++ b/src/Shentun.Sms.Service/Sms/SmsFactory.cs @@ -1,4 +1,5 @@ using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Linq; @@ -10,13 +11,17 @@ namespace Shentun.Sms.Service.Sms public class SmsFactory { private readonly IConfiguration _tencentSmsConfig; + private readonly TencentSms _tencentSms; + public SmsFactory( - IConfiguration tencentSmsConfig + IConfiguration tencentSmsConfig, + TencentSms tencentSms ) { _tencentSmsConfig = tencentSmsConfig; + _tencentSms = tencentSms; } - + public SmsBase CreateSms() { @@ -25,9 +30,10 @@ namespace Shentun.Sms.Service.Sms switch (platform) { case "Tencent": - sms = new TencentSms(_tencentSmsConfig); + // sms = new TencentSms(_tencentSmsConfig); + sms = _tencentSms; break; - + default: throw new ArgumentException("不支持的短信驱动"); } return sms; diff --git a/src/Shentun.Sms.Service/Sms/TencentSms.cs b/src/Shentun.Sms.Service/Sms/TencentSms.cs index 645d486..db9d85a 100644 --- a/src/Shentun.Sms.Service/Sms/TencentSms.cs +++ b/src/Shentun.Sms.Service/Sms/TencentSms.cs @@ -8,6 +8,8 @@ using TencentCloud.Common; using Microsoft.Extensions.Configuration; using TencentCloud.Sms.V20210111; using TencentCloud.Sms.V20210111.Models; +using Microsoft.Extensions.Logging; +using TencentCloud.Tsf.V20180326.Models; namespace Shentun.Sms.Service.Sms { @@ -15,12 +17,14 @@ namespace Shentun.Sms.Service.Sms { private readonly IConfiguration _tencentSmsConfig; + private readonly ILogger _logger; public TencentSms( - IConfiguration tencentSmsConfig - ) + IConfiguration tencentSmsConfig, + ILogger logger) { _tencentSmsConfig = tencentSmsConfig; + _logger = logger; } /// @@ -127,6 +131,9 @@ namespace Shentun.Sms.Service.Sms SendSmsResponse resp = client.SendSmsSync(req); + + _logger.LogInformation($"------短信发送记录=>{AbstractModel.ToJsonString(resp)}------当前时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}"); + // 输出json格式的字符串回包 Console.WriteLine(AbstractModel.ToJsonString(resp));