Parcourir la source

团组短信提醒、阿里云SDK

jiangjc il y a 1 an
Parent
commit
74ca5f4045

+ 3 - 2
OASystem/EntitySync/Program.cs

@@ -97,7 +97,8 @@ db.CodeFirst.SetStringDefaultLength(50).BackupTable().InitTables(new Type[]
     //typeof(Grp_GroupCostParameter)
     //typeof(Grp_TeamRate)
     //typeof(Grp_DecreasePayments)
-    typeof(Grp_InvitationOfficialActivities),
-    typeof(Res_InvitationOfficialActivityData),
+    //typeof(Grp_InvitationOfficialActivities),
+    //typeof(Res_InvitationOfficialActivityData),
+    typeof(Bus_MsgPostInfo),
 });
 Console.WriteLine("数据库结构同步完成!");

+ 20 - 0
OASystem/OASystem.Api/Controllers/BusinessController.cs

@@ -1,4 +1,6 @@
 using Microsoft.AspNetCore.Mvc;
+using NPOI.SS.Formula.Functions;
+using OASystem.API.OAMethodLib.ALiYun;
 using OASystem.API.OAMethodLib.ExcelOutput;
 using OASystem.Domain.Common;
 using OASystem.Domain.Dtos.Business;
@@ -163,5 +165,23 @@ Where c.ConfListId = {0}", ConfId);
 
         #endregion
 
+        #region 阿里云短信测试
+
+        /// <summary>
+        /// 编辑物料采购清单
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> AliMessageTest(string mobile)
+        {
+
+            string add2dayZH = DateTime.Now.AddDays(2).ToString("yyyy年MM月dd日");
+            string templateParam = JsonConvert.SerializeObject(new { teams = "测试团组", date = add2dayZH });
+            AliMessagePost.PostMessage(mobile, "泛美国际团组", "SMS_461575447", templateParam);
+            return Ok(JsonView(true));
+        }
+
+        #endregion
     }
 }

+ 70 - 0
OASystem/OASystem.Api/OAMethodLib/ALiYun/AliMessagePost.cs

@@ -0,0 +1,70 @@
+using Tea;
+
+namespace OASystem.API.OAMethodLib.ALiYun
+{
+    public class AliMessagePost
+    {
+        private static string accessKeyId { get; set; } = "LTAI5t982d4MQ8FqswNt3qkf";
+        private static string accessKeySecret { get; set; } = "VsDBzZI4O6IEli7NgdWHoZviHgYgYB";
+
+        /**
+         * 使用AK&SK初始化账号Client
+         * @param accessKeyId
+         * @param accessKeySecret
+         * @return Client
+         * @throws Exception
+         */
+        public static AlibabaCloud.SDK.Dysmsapi20170525.Client CreateClient(string accessKeyId, string accessKeySecret)
+        {
+            AlibabaCloud.OpenApiClient.Models.Config config = new AlibabaCloud.OpenApiClient.Models.Config
+            {
+                // 必填,您的 AccessKey ID
+                AccessKeyId = accessKeyId,
+                // 必填,您的 AccessKey Secret
+                AccessKeySecret = accessKeySecret,
+            };
+            // 访问的域名
+            config.Endpoint = "dysmsapi.aliyuncs.com";
+            return new AlibabaCloud.SDK.Dysmsapi20170525.Client(config);
+        }
+
+        public static string PostMessage(string phoneNumber, string signName,string templateCode,string templateParam)
+        {
+            // 请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID 和 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
+            // 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例使用环境变量获取 AccessKey 的方式进行调用,仅供参考,建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378671.html
+            AlibabaCloud.SDK.Dysmsapi20170525.Client client = CreateClient(accessKeyId, accessKeySecret);
+            AlibabaCloud.SDK.Dysmsapi20170525.Models.SendSmsRequest sendSmsRequest = new AlibabaCloud.SDK.Dysmsapi20170525.Models.SendSmsRequest
+            {
+                PhoneNumbers = phoneNumber,
+                SignName = signName,
+                TemplateCode = templateCode,
+                TemplateParam = templateParam
+            };
+
+            string result = "发送失败,未知错误";
+            try
+            {
+                // 复制代码运行请自行打印 API 的返回值
+                var suc = client.SendSmsWithOptions(sendSmsRequest, new AlibabaCloud.TeaUtil.Models.RuntimeOptions());
+                result = JsonConvert.SerializeObject(suc);
+            }
+            catch (TeaException error)
+            {
+                // 如有需要,请打印 error
+                result = AlibabaCloud.TeaUtil.Common.AssertAsString(error.Message);
+            }
+            catch (Exception _error)
+            {
+                TeaException error = new TeaException(new Dictionary<string, object>
+                {
+                    { "message", _error.Message }
+                });
+                // 如有需要,请打印 error
+                result = AlibabaCloud.TeaUtil.Common.AssertAsString(error.Message);
+            }
+
+            return result;
+        }
+
+    }
+}

+ 8 - 0
OASystem/OASystem.Api/OAMethodLib/AutofacRegister.cs

@@ -1,5 +1,6 @@
 using Microsoft.Extensions.Configuration.Json;
 using OASystem.Domain.Dtos.Groups;
+using OASystem.Domain.Dtos.Business;
 
 namespace OASystem.API.OAMethodLib
 {
@@ -24,6 +25,13 @@ namespace OASystem.API.OAMethodLib
             builder.RegisterInstance<GroupsConfig>(_groupsConfig);
             #endregion
 
+            #region 团组结束通知短信
+            DeleReminderConfig _deleReminderConfig = new DeleReminderConfig();
+            _deleReminderConfig.Test= AppSettingsHelper.Get(DeleReminderConfig.KEY, "Test");
+            _deleReminderConfig.PhoneNumber= AppSettingsHelper.Get(DeleReminderConfig.KEY, "PhoneNumber");
+            builder.RegisterInstance<DeleReminderConfig>(_deleReminderConfig);
+            #endregion
+
         }
     }
 }

+ 75 - 0
OASystem/OASystem.Api/OAMethodLib/Quartz/Business/DeleReminderMessage.cs

@@ -0,0 +1,75 @@
+using OASystem.API.OAMethodLib.ALiYun;
+using OASystem.Domain.Dtos.Business;
+using OASystem.Domain.Entities.Business;
+using OASystem.Domain.Entities.Groups;
+using OASystem.Infrastructure.Repositories.Groups;
+
+namespace OASystem.API.OAMethodLib.Quartz.Business
+{
+    public static class DeleReminderMessage
+    {
+        private readonly static DelegationInfoRepository _grpDeleRep = AutofacIocManager.Instance.GetService<DelegationInfoRepository>();
+
+        /// <summary>
+        /// 检查团组结束日期,将当天和2天后的团组整理并发送短信提醒
+        /// </summary>
+        public static async void PostMessage()
+        {
+            DeleReminderConfig _deleReminderConfig = AutofacIocManager.Instance.GetService<DeleReminderConfig>();
+            string postPhoneNumber = string.IsNullOrEmpty(_deleReminderConfig.PhoneNumber) ? _deleReminderConfig.Test : _deleReminderConfig.PhoneNumber;
+
+            //sqladd2day查询0A2014数据库,正式使用新OA后将两次查询合并
+            DateTime dtNow = DateTime.Now;
+            string today = dtNow.ToString("yyyy-MM-dd");
+            string add2day = dtNow.AddDays(2).ToString("yyyy-MM-dd");
+
+            _grpDeleRep.ChangeDataBase(DBEnum.OA2014DB);
+            string sql = string.Format(@" Select * From DelegationInfo With(Nolock) Where IsdDel=0 And VisitEndDate in ('{0}','{1}') ", today, add2day);
+            List<Grp_DelegationInfo> list_source = _grpDeleRep._sqlSugar.SqlQueryable<Grp_DelegationInfo>(sql).ToList();
+
+            _grpDeleRep.ChangeDataBase(DBEnum.OA2023DB);
+            if (list_source.Count > 0)
+            {
+                List<Grp_DelegationInfo> listToday = list_source.Where(s => s.VisitEndDate.Equals(today)).ToList();
+                List<Grp_DelegationInfo> listAdd2day = list_source.Where(s => s.VisitEndDate.Equals(add2day)).ToList();
+
+                if (listToday.Count > 0)
+                {
+                    string teamNames = "";
+                    listToday.ForEach(s => teamNames += s.TeamName + "、");
+                    teamNames = teamNames.TrimEnd('、');
+                    //发送短信
+                    string templateParam = JsonConvert.SerializeObject(new { teams = teamNames, date = "今日" });
+                    string postResult = AliMessagePost.PostMessage(postPhoneNumber, "泛美国际团组", "SMS_461575447", templateParam);
+                    Bus_MsgPostInfo _entity = new Bus_MsgPostInfo();
+                    _entity.Source = "ALiYun";
+                    _entity.TeamNames = teamNames;
+                    _entity.PostType = "Dele2";
+                    _entity.PhoneNumber = postPhoneNumber;
+                    _entity.PostResult = postResult;
+                    _grpDeleRep.AddAsync(_entity);
+                }
+
+                if (listAdd2day.Count > 0)
+                {
+                    string teamNames = "";
+                    listAdd2day.ForEach(s => teamNames += s.TeamName + "、");
+                    teamNames = teamNames.TrimEnd('、');
+                    //发送短信
+                    string add2dayZH = dtNow.AddDays(2).ToString("yyyy年MM月dd日");
+                    string templateParam = JsonConvert.SerializeObject(new { teams = teamNames, date = add2dayZH });
+                    string postResult = AliMessagePost.PostMessage(postPhoneNumber, "泛美国际团组", "SMS_461575447", templateParam);
+                    Bus_MsgPostInfo _entity = new Bus_MsgPostInfo();
+                    _entity.Source = "ALiYun";
+                    _entity.TeamNames = teamNames;
+                    _entity.PostType = "Dele1";
+                    _entity.PhoneNumber = postPhoneNumber;
+                    _entity.PostResult = postResult;
+                    _grpDeleRep.AddAsync(_entity);
+
+                }
+            }
+
+        }
+    }
+}

+ 26 - 0
OASystem/OASystem.Api/OAMethodLib/Quartz/IOCJobFactory.cs

@@ -0,0 +1,26 @@
+using Quartz;
+using Quartz.Spi;
+
+namespace QuzrtzJob.Factory
+{
+    public class IOCJobFactory : IJobFactory
+    {
+        private readonly IServiceProvider _serviceProvider;
+        public IOCJobFactory(IServiceProvider serviceProvider)
+        {
+            _serviceProvider = serviceProvider;
+        }
+        public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
+        {
+            return _serviceProvider.GetService(bundle.JobDetail.JobType) as IJob;
+
+        }
+
+        public void ReturnJob(IJob job)
+        {
+            var disposable = job as IDisposable;
+            disposable?.Dispose();
+
+        }
+    }
+}

+ 23 - 0
OASystem/OASystem.Api/OAMethodLib/Quartz/Jobs/ALiYunPostMessageJob.cs

@@ -0,0 +1,23 @@
+using OASystem.API.OAMethodLib.Quartz.Business;
+using Quartz;
+
+namespace QuzrtzJob.Factory
+{
+    public class ALiYunPostMessageJob : IJob
+    {
+        private readonly ILogger<ALiYunPostMessageJob> _logger;
+        public ALiYunPostMessageJob(ILogger<ALiYunPostMessageJob> logger)
+        {
+            _logger = logger;
+        }
+
+        public Task Execute(IJobExecutionContext context)
+        {
+            _logger.LogInformation("调用阿里云短信接口 " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
+            //在此处编写任务业务代码
+            DeleReminderMessage.PostMessage();
+
+            return Task.CompletedTask;
+        }
+    }
+}

+ 40 - 0
OASystem/OASystem.Api/OAMethodLib/Quartz/QuartzFactory.cs

@@ -0,0 +1,40 @@
+using OASystem.API.OAMethodLib.Quartz;
+using Quartz;
+using Quartz.Spi;
+
+namespace QuzrtzJob.Factory
+{
+    public class QuartzFactory
+    {
+        //1、声明一个调度工厂
+        private ISchedulerFactory _schedulerFactory;
+        private IScheduler _scheduler = default;
+        private IJobFactory _IOCjobFactory;
+        public QuartzFactory(ISchedulerFactory schedulerFactory, IJobFactory jobFactory)
+        {
+            _schedulerFactory = schedulerFactory;
+            _IOCjobFactory = jobFactory;
+        }
+        public async Task<string> Start()
+        {
+            //2、通过调度工厂获得调度器
+            _scheduler = await _schedulerFactory.GetScheduler();
+            //这里是指定容器仓库
+            _scheduler.JobFactory = _IOCjobFactory;
+            //3、开启调度器
+            await _scheduler.Start();
+            //4、创建一个触发器
+            var trigger = TriggerBuilder.Create()
+                            //.WithSimpleSchedule(x => x.WithIntervalInSeconds(2).RepeatForever())//每两秒执行一次
+                            .WithCronSchedule("0 15 9 * * ?")
+                            .Build();
+            //5、创建任务
+            var jobDetail = JobBuilder.Create<ALiYunPostMessageJob>()
+                            .WithIdentity("job", "group")
+                            .Build();
+            //6、将触发器和任务器绑定到调度器中
+            await _scheduler.ScheduleJob(jobDetail, trigger);
+            return await Task.FromResult("将触发器和任务器绑定到调度器中完成");
+        }
+    }
+}

+ 2 - 0
OASystem/OASystem.Api/OASystem.API.csproj

@@ -20,6 +20,7 @@
   </ItemGroup>
 
   <ItemGroup>
+    <PackageReference Include="AlibabaCloud.SDK.Dysmsapi20170525" Version="2.0.23" />
     <PackageReference Include="Aspose.Cells" Version="23.4.0" />
     <PackageReference Include="Autofac" Version="6.4.0" />
     <PackageReference Include="Autofac.Extensions.DependencyInjection" Version="8.0.0" />
@@ -30,6 +31,7 @@
     <PackageReference Include="Flurl.Http" Version="3.2.4" />
     <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.11" />
     <PackageReference Include="QRCoder" Version="1.4.1" />
+    <PackageReference Include="Quartz" Version="3.6.2" />
     <PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
     <PackageReference Include="SqlSugarCore" Version="5.1.3.35" />
     <PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />

+ 37 - 1
OASystem/OASystem.Api/Program.cs

@@ -9,6 +9,10 @@ using Microsoft.AspNetCore.Http.Features;
 using Microsoft.AspNetCore.Server.Kestrel.Core;
 using OASystem.API.OAMethodLib.JuHeAPI;
 using OASystem.API.OAMethodLib.YouDaoAPI;
+using Quartz.Impl;
+using Quartz.Spi;
+using Quartz;
+using QuzrtzJob.Factory;
 
 var builder = WebApplication.CreateBuilder(args);
 var basePath = AppContext.BaseDirectory;
@@ -88,7 +92,12 @@ builder.Services.AddScoped(options =>
         new ConnectionConfig() {
             ConfigId = DBEnum.OA2023DB,
             ConnectionString = _config.GetConnectionString("OA2023DB"),
-            DbType = DbType.SqlServer, IsAutoCloseConnection = true }
+            DbType = DbType.SqlServer, IsAutoCloseConnection = true },
+        new ConnectionConfig()
+        {
+            ConfigId = DBEnum.OA2014DB,
+            ConnectionString = _config.GetConnectionString("OA2014DB"),
+            DbType = DbType.SqlServer, IsAutoCloseConnection = true },
     });
 });
 #endregion
@@ -242,6 +251,16 @@ builder.Services.AddHttpClient("PublicJuHeApi", c => c.BaseAddress = new Uri("ht
 //builder.Services.AddHttpClient("PublicYouDaoApi", c => c.BaseAddress = new Uri("https://openapi.youdao.com"));
 #endregion
 
+#region Quartz
+
+builder.Services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();
+builder.Services.AddSingleton<QuartzFactory>();
+builder.Services.AddSingleton<ALiYunPostMessageJob>();
+//# new business
+builder.Services.AddSingleton<IJobFactory, IOCJobFactory>();
+
+#endregion
+
 var app = builder.Build();
 AutofacIocManager.Instance.Container = app.UseHostFiltering().ApplicationServices.GetAutofacRoot();//AutofacIocManager
 
@@ -276,6 +295,23 @@ if (AppSettingsHelper.Get("UseSwagger").ToBool())
 }
 #endregion
 
+#region Quartz
+
+//»ñÈ¡ÈÝÆ÷ÖеÄQuartzFactory
+var quartz = app.Services.GetRequiredService<QuartzFactory>();
+app.Lifetime.ApplicationStarted.Register(async () =>
+{
+    await quartz.Start();
+});
+
+app.Lifetime.ApplicationStopped.Register(() =>
+{
+    //Quzrtz¹Ø±Õ·½·¨
+    //quartz.Stop();
+});
+
+#endregion
+
 
 app.MapControllerRoute(
     name: "default",

+ 6 - 1
OASystem/OASystem.Api/appsettings.json

@@ -1,6 +1,7 @@
 {
   "ConnectionStrings": {
-    "OA2023DB": "server=132.232.92.186;uid=sa;pwd=Yjx@158291;database=OA2023DB;"
+    "OA2023DB": "server=132.232.92.186;uid=sa;pwd=Yjx@158291;database=OA2023DB;",
+    "OA2014DB": "server=132.232.92.186;uid=sa;pwd=Yjx@158291;database=OA2014;"
   },
   "JwtSecurityKey": "48d3f4fe770940a1068052f581536b81", //jwt密钥
   "UseSwagger": "true", //启用Swagger
@@ -13,6 +14,10 @@
     "Boss": "21",
     "FilterUser": "51,180"
   },
+  "DeleReminderConfig": {
+    "PhoneNumber": "17380669807",
+    "Test": "18477317582"
+  },
   "RateCurrency": [
     {
       "CurrencyName": "人民币",

+ 26 - 0
OASystem/OASystem.Domain/Dtos/Business/DeleReminderConfig.cs

@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace OASystem.Domain.Dtos.Business
+{
+    /// <summary>
+    /// appsettings.json配置对应实体类(团组结束日期短信通知配置)
+    /// </summary>
+    public class DeleReminderConfig
+    {
+        public const string KEY = "DeleReminderConfig";
+
+        /// <summary>
+        /// 财务经理手机号码
+        /// </summary>
+        public string PhoneNumber { get; set; }
+
+        /// <summary>
+        /// 测试号码
+        /// </summary>
+        public string Test { get; set; }
+    }
+}

+ 42 - 0
OASystem/OASystem.Domain/Entities/Business/Bus_MsgPostInfo.cs

@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace OASystem.Domain.Entities.Business
+{
+    [SugarTable("Bus_MsgPost")]
+    public class Bus_MsgPostInfo : EntityBase
+    {
+        /// <summary>
+        /// 发送平台
+        /// </summary>
+        [SugarColumn(ColumnDescription = "发送平台", IsNullable = false, ColumnDataType = "varchar(30)")]
+        public string Source { get; set; }
+
+        /// <summary>
+        /// 团组名称
+        /// </summary>
+        [SugarColumn(ColumnDescription = "团组名称", IsNullable = false, ColumnDataType = "nvarchar(200)")]
+        public string TeamNames { get; set; }
+
+        /// <summary>
+        /// 短信类型,Dele1:团组结束日期提前2天通知,Dele2:团组结束当天通知
+        /// </summary>
+        [SugarColumn(ColumnDescription = "短信类型", IsNullable = false, ColumnDataType = "varchar(30)")]
+        public string PostType { get; set; }
+
+        /// <summary>
+        /// 目标手机号码
+        /// </summary>
+        [SugarColumn(ColumnDescription = "目标手机号码", IsNullable = false, ColumnDataType = "varchar(30)")]
+        public string PhoneNumber { get; set; }
+
+        /// <summary>
+        /// 发送结果
+        /// </summary>
+        [SugarColumn(ColumnDescription = "发送结果", IsNullable = false, ColumnDataType = "nvarchar(500)")]
+        public string PostResult { get; set; }
+    }
+}

+ 2 - 1
OASystem/OASystem.Domain/Enums/DBEnum.cs

@@ -2,6 +2,7 @@
 {
     public enum DBEnum : int
     {
-        OA2023DB = 1
+        OA2023DB = 1,
+        OA2014DB = 2
     }
 }