/*********************************************************************** * Project: baifenBinfa * ProjectName: 百分兵法管理系统 * Web: http://chuanyin.com * Author: * Email: * CreateTime: 202403/02 * Description: 暂无 ***********************************************************************/ using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Threading.Tasks; using CoreCms.Net.Configuration; using CoreCms.Net.IRepository; using CoreCms.Net.IRepository.UnitOfWork; using CoreCms.Net.IServices; using CoreCms.Net.Loging; using CoreCms.Net.Model.Entities; using CoreCms.Net.Model.ViewModels.Sms; using CoreCms.Net.Model.ViewModels.UI; using CoreCms.Net.Utility.Extensions; using CoreCms.Net.Utility.Helper; using Flurl.Http; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using SqlSugar; using static SKIT.FlurlHttpClient.Wechat.Api.Models.ComponentTCBBatchCreateContainerServiceVersionResponse.Types; using static SKIT.FlurlHttpClient.Wechat.Api.Models.WxaApiUserLogSearchResponse.Types.Data.Types.RealtimeLog.Types; namespace CoreCms.Net.Services { /// /// 短信发送日志 接口实现 /// public class CoreCmsSmsServices : BaseServices, ICoreCmsSmsServices { private readonly ICoreCmsSmsRepository _dal; private readonly ICoreCmsSettingServices _settingServices; private readonly IUnitOfWork _unitOfWork; private readonly IHttpContextAccessor _httpContextAccessor; public CoreCmsSmsServices(IUnitOfWork unitOfWork , ICoreCmsSmsRepository dal , IHttpContextAccessor httpContextAccessor, ICoreCmsSettingServices settingServices) { this._dal = dal; base.BaseDal = dal; _unitOfWork = unitOfWork; _httpContextAccessor = httpContextAccessor; _settingServices = settingServices; } #region 发送短信(验证码) /// /// 发送短信(验证码) /// /// /// /// public async Task DoSendSms(string type, string mobile) { var jm = new WebApiCallBack(); var smsOptions = await _settingServices.GetSmsOptions(); if (smsOptions.Enabled == false) { jm.msg = "短信功能未开启"; return jm; } Random rd = new Random(); int codeNumber = rd.Next(100000, 999999); var dt = DateTime.Now; //获取当前ip今日的发送记录 var ip = _httpContextAccessor.HttpContext?.Connection.RemoteIpAddress != null ? _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString() : "127.0.0.1"; if (string.IsNullOrEmpty(ip)) { jm.msg = "短信发送IP获取失败"; return jm; } var black = smsOptions.SmsIpSendBlackList.Split('|').ToList(); if (black.Count > 0 && black.Contains(ip)) { jm.msg = "此IP被禁止短信业务"; return jm; } var white = smsOptions.SmsIpSendWhiteList.Split('|').ToList(); if (white.Count <= 0 || !white.Contains(ip)) { var startDateTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 0, DateTimeKind.Utc); var endDateTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 23, 59, 59, DateTimeKind.Utc); var sendCount = await _dal.GetCountAsync(p => p.ip.Equals(ip) && p.createTime > startDateTime && p.createTime < endDateTime); if (smsOptions.SmsIpSendNumber > 0 && sendCount > smsOptions.SmsIpSendNumber) { jm.msg = "此IP被已超过每日短信发送限额。"; return jm; } } //获取是否存在 var endDt = dt.AddMinutes(10); var oldLog = await _dal.QueryByClauseAsync(p => p.code == type && p.mobile == mobile && p.createTime > dt && p.createTime < endDt, p => p.id, OrderByType.Desc); if (oldLog == null) { oldLog = new CoreCmsSms(); oldLog.code = type; oldLog.createTime = dt; oldLog.mobile = mobile; oldLog.ip = ip; oldLog.isUsed = false; var obj = new { code = codeNumber }; switch (type) { case "login": oldLog.contentBody = "您正在登陆账号,验证码是" + codeNumber + ",请勿告诉他人。";//您本次登陆的验证码是:" + codeNumber + ",请不要将验证码泄露给他人!" oldLog.parameters = JsonConvert.SerializeObject(obj); break; default: oldLog.contentBody = "您的验证码是" + codeNumber + ",请勿告诉他人。"; //"您验证码是:" + codeNumber + ",请不要将验证码泄露给他人!"; oldLog.parameters = JsonConvert.SerializeObject(obj); break; } await _dal.InsertAsync(oldLog); } var result = await SendSms(oldLog.mobile, oldLog.contentBody, smsOptions); jm.status = result.IsSuccess; jm.msg = result.IsSuccess ? "发送成功" : result.Message; jm.otherData = result; return jm; } #endregion #region 校验短信验证码 /// /// 校验短信验证码 /// /// /// /// /// public async Task Check(string phone, string verCode, string code) { var smsInfo = await _dal.QueryByClauseAsync(p => p.mobile == phone && p.code == code && p.createTime < DateTime.Now && p.isUsed == false, p => p.createTime, OrderByType.Desc); if (smsInfo != null) { var parameters = JObject.Parse(smsInfo.parameters); if (parameters.ContainsKey("code")) { var dataCode = parameters["code"]?.ToString(); if (dataCode != verCode) return false; smsInfo.isUsed = true; await _dal.UpdateAsync(smsInfo); return true; } return false; } return false; } #endregion #region 接口通道发送短信 /// /// 接口通道发送短信 /// /// /// /// 配置文件 public async Task SendSms(string mobile, string contentBody, SmsOptions smsOptions) { if (smsOptions.Enabled) { var result = new SMSReturnData() { ReturnStatus = "faild", Message = "短信发送失败", RemainPoint = 0, TaskID = 0, SuccessCounts = 0 }; string url = smsOptions.ApiUrl; string data = "CorpID="+ smsOptions.Account + "&Pwd="+ smsOptions.Password + "&Mobile=" + mobile + "&Content=" + contentBody + "【"+smsOptions.Signature+"】&SendTime="; //退订回N string ssss = await HttpClientPostGB2312Async(url, "POST", data); int aaaa = 0; if (int.TryParse(ssss, out aaaa) && aaaa > 0) { result = new SMSReturnData() { ReturnStatus = "success", Message = "短信发送成功", RemainPoint = 0, TaskID = 0, SuccessCounts = 1, IsSuccess = true, }; } //var result = await smsOptions.ApiUrl.PostUrlEncodedAsync(new //{ // action = "send", // userid = smsOptions.UserId, // account = smsOptions.Account, // password = smsOptions.Password, // mobile, // content = "【" + smsOptions.Signature + "】" + contentBody, // rt = "json" //}).ReceiveJson(); //result.IsSuccess = result.ReturnStatus.ToLowerInvariant() == "success"; return result; } else { var result = new SMSReturnData() { ReturnStatus = "faild", Message = "短信功能未开启", RemainPoint = 0, TaskID = 0, SuccessCounts = 0 }; return result; } } #endregion #region 发送短信统一方法 /// /// 发送短信统一方法 /// /// 接受者手机号码 /// 模板编码 /// 参数 /// public async Task Send(string mobile, string code, JObject parameters) { var jm = new WebApiCallBack(); var smsOptions = await _settingServices.GetSmsOptions(); if (smsOptions.Enabled == false) { jm.msg = "短信功能未开启"; return jm; } var dt = DateTime.Now; //获取当前ip今日的发送记录 var ip = _httpContextAccessor.HttpContext?.Connection.RemoteIpAddress != null ? _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString() : ""; if (string.IsNullOrEmpty(ip)) { jm.msg = "短信发送IP获取失败"; return jm; } var black = smsOptions.SmsIpSendBlackList.Split('|').ToList(); if (black.Count > 0 && black.Contains(ip)) { jm.msg = "此IP被禁止短信业务"; return jm; } var white = smsOptions.SmsIpSendWhiteList.Split('|').ToList(); if (white.Count <= 0 || !white.Contains(ip)) { var startDateTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 0, DateTimeKind.Utc); var endDateTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 23, 59, 59, DateTimeKind.Utc); var sendCount = await _dal.GetCountAsync(p => p.ip.Equals(ip) && p.createTime > startDateTime && p.createTime < endDateTime); if (smsOptions.SmsIpSendNumber > 0 && sendCount > smsOptions.SmsIpSendNumber) { jm.msg = "此IP被已超过每日短信发送限额。"; return jm; } } if (string.IsNullOrEmpty(mobile)) { jm.msg = GlobalErrorCodeVars.Code11051; return jm; } var isUsed = false; if (code == GlobalEnumVars.SmsMessageTypes.Reg.ToString() || code == GlobalEnumVars.SmsMessageTypes.Login.ToString() || code == GlobalEnumVars.SmsMessageTypes.Veri.ToString()) { var newCreateTime = DateTime.Now.AddSeconds(-60); var smsInfo = await _dal.QueryByClauseAsync(p => p.mobile == mobile && p.code == code && p.createTime < newCreateTime && p.isUsed == false); if (smsInfo != null) { var ts = dt - smsInfo.createTime; if (ts.Seconds < 60) { jm.msg = "两次发送时间间隔小于60秒"; return jm; } parameters = JObject.Parse(smsInfo.parameters); } else { Random rd = new Random(); int codeNumber = rd.Next(100000, 999999); if (parameters.ContainsKey("code")) { parameters.Remove("code"); } parameters.Add("code", codeNumber); } isUsed = false; } else { isUsed = true; } var str = string.Empty; var allConfigs = await _settingServices.GetConfigDictionaries(); if (code == GlobalEnumVars.SmsMessageTypes.Reg.ToString()) { // 账户注册 var msg = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.SmsTplForReg); if (!string.IsNullOrEmpty(msg)) { var sendCode = string.Empty; if (parameters.ContainsKey("code")) { sendCode = parameters["code"]?.ToString(); } str = msg.Replace("{code}", sendCode); } } else if (code == GlobalEnumVars.SmsMessageTypes.Login.ToString()) { // 账户登录 var msg = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.SmsTplForLogin); if (!string.IsNullOrEmpty(msg)) { var sendCode = string.Empty; if (parameters.ContainsKey("code")) { sendCode = parameters["code"]?.ToString(); } str = msg.Replace("{code}", sendCode); } } else if (code == GlobalEnumVars.SmsMessageTypes.Veri.ToString()) { // 验证验证码 var msg = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.SmsTplForVeri); if (!string.IsNullOrEmpty(msg)) { var sendCode = string.Empty; if (parameters.ContainsKey("code")) { sendCode = parameters["code"]?.ToString(); } str = msg.Replace("{code}", sendCode); } } else if (code == GlobalEnumVars.PlatformMessageTypes.CreateOrder.ToString()) { // 订单创建 var msg = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.SmsTplForCreateOrder); str = !string.IsNullOrEmpty(msg) ? msg : string.Empty; } else if (code == GlobalEnumVars.PlatformMessageTypes.OrderPayed.ToString()) { // 订单支付通知买家 var msg = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.SmsTplForOrderPayed); str = !string.IsNullOrEmpty(msg) ? msg : string.Empty; } else if (code == GlobalEnumVars.PlatformMessageTypes.RemindOrderPay.ToString()) { // 未支付催单 var msg = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.SmsTplForRemindOrderPay); str = !string.IsNullOrEmpty(msg) ? msg : string.Empty; } else if (code == GlobalEnumVars.PlatformMessageTypes.DeliveryNotice.ToString()) { // 订单发货 var msg = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.SmsTplForDeliveryNotice); str = !string.IsNullOrEmpty(msg) ? msg : string.Empty; } else if (code == GlobalEnumVars.PlatformMessageTypes.AfterSalesPass.ToString()) { // 售后审核通过 var msg = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.SmsTplForAfterSalesPass); str = !string.IsNullOrEmpty(msg) ? msg : string.Empty; } else if (code == GlobalEnumVars.PlatformMessageTypes.RefundSuccess.ToString()) { // 退款已处理 var msg = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.SmsTplForRefundSuccess); str = !string.IsNullOrEmpty(msg) ? msg : string.Empty; } else if (code == GlobalEnumVars.PlatformMessageTypes.SellerOrderNotice.ToString()) { // 订单支付通知卖家 var msg = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.SmsTplForSellerOrderNotice); str = !string.IsNullOrEmpty(msg) ? msg : string.Empty; } else if (code == GlobalEnumVars.PlatformMessageTypes.Common.ToString()) { //通用类型 var tpl = string.Empty; if (parameters.ContainsKey("tpl")) { tpl = parameters["tpl"]?.ToString(); } str = tpl; if (string.IsNullOrEmpty(str)) { var msg = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.SmsTplForCommon); str = !string.IsNullOrEmpty(msg) ? msg : string.Empty; } } if (string.IsNullOrEmpty(str)) { jm.msg = GlobalErrorCodeVars.Code10009; return jm; } var oldLog = new CoreCmsSms(); oldLog.mobile = mobile; oldLog.code = code; oldLog.parameters = JsonConvert.SerializeObject(parameters); oldLog.contentBody = str; oldLog.createTime = dt; oldLog.ip = ip; oldLog.isUsed = isUsed; await _dal.InsertAsync(oldLog); var result = await SendSms(oldLog.mobile, oldLog.contentBody, smsOptions); jm.status = result.IsSuccess; jm.msg = result.IsSuccess ? "发送成功" : result.Message; return jm; } #endregion public async Task HttpClientPostGB2312Async(string url, string Method, string data = "") { string _url = url;// "http://localhost:65022/login/getaa"; string jsonParam = data;// "{\"a\":\"aa\",\"b\":\"bb\",\"c\":\"cc\"}"; var request = (HttpWebRequest)WebRequest.Create(_url); request.Method = Method;//"POST"; request.ContentType = "application/x-www-form-urlencoded;charset=GB2312"; var byteData = Encoding.GetEncoding("GB2312").GetBytes(jsonParam); var length = byteData.Length; request.ContentLength = length; request.ServicePoint.Expect100Continue = false; //ServicePointManager.Expect100Continue = false; request.Timeout = 5000; //是进行后续同步请求时使用 GetResponse 方法等待响应以及 GetRequestStream 方法等待流所允许的毫秒数 var writer = request.GetRequestStream(); await writer.WriteAsync(byteData, 0, length); writer.Close(); //接收响应内容 var response = (HttpWebResponse)request.GetResponse(); var responseString = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("utf-8")).ReadToEnd(); return responseString.ToString(); } } }