New file |
| | |
| | | // Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。 |
| | | // |
| | | // 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。 |
| | | // |
| | | // 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! |
| | | |
| | | using Admin.NET.Core.Service; |
| | | using Admin.NET.Core; |
| | | using Furion.DependencyInjection; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | using Microsoft.Extensions.Options; |
| | | using Dm.util; |
| | | using Aop.Api.Domain; |
| | | using Furion.FriendlyException; |
| | | using Furion.DataValidation; |
| | | using static QRCoder.PayloadGenerator; |
| | | using System.Net; |
| | | using Org.BouncyCastle.Asn1.Ocsp; |
| | | using Microsoft.AspNetCore.Mvc; |
| | | using Microsoft.AspNetCore.Authorization; |
| | | using Furion.DynamicApiController; |
| | | using System.ComponentModel; |
| | | using System.ComponentModel.DataAnnotations; |
| | | using Yitter.IdGenerator; |
| | | using Lazy.Captcha.Core; |
| | | using Furion; |
| | | using NewLife; |
| | | |
| | | namespace FZCZTB.NET.SYSService.MSM; |
| | | /// <summary> |
| | | /// 政采短信服务 |
| | | /// </summary> |
| | | [AllowAnonymous] |
| | | [ApiDescriptionSettings("FZCAPISYS",Order = 149)] |
| | | public class ZCSMSService : IDynamicApiController,ITransient |
| | | { |
| | | private readonly SMSConfigOptions _smsOptions; |
| | | private readonly SysCacheService _sysCacheService; |
| | | private readonly ICaptcha _captcha; |
| | | public ZCSMSService(IOptions<SMSConfigOptions> smsOptions, |
| | | SysCacheService sysCacheService, |
| | | ICaptcha captcha |
| | | ) |
| | | { |
| | | |
| | | _smsOptions = smsOptions.Value; |
| | | _sysCacheService = sysCacheService; |
| | | |
| | | _captcha = captcha; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 根据藏用模版格式化短信内容 会自动贴上标签 |
| | | /// </summary> |
| | | /// <param name="Code"> 需要替换的内容,用于替换末班内容的code部分</param> |
| | | /// <param name="Key"></param> |
| | | [NonAction] |
| | | public string FormartMessage(string? Code, string Key = "VCode") |
| | | { |
| | | var Temp= _smsOptions.lingKai.Templates.Where(x => x.TemplateCode == Key).FirstOrDefault(); |
| | | if ( Temp != null ) |
| | | { |
| | | if(Code != null) |
| | | { |
| | | |
| | | return Temp.Content.replace("${code}", Code) + Temp.SignName; |
| | | |
| | | } |
| | | |
| | | else |
| | | return Temp.Content+Temp.SignName; |
| | | } |
| | | if (Code == null) |
| | | throw Oops.Oh("短信内容为空"); |
| | | return Code; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 发送短信 |
| | | /// </summary> |
| | | /// <param name="Content">要替换的内容</param> |
| | | [NonAction] |
| | | public async Task SendSMSAsync(string Content,string Phone) |
| | | { |
| | | if (!Phone.TryValidate(ValidationTypes.PhoneNumber).IsValid) throw Oops.Oh("请正确填写手机号码"); |
| | | |
| | | if( string.IsNullOrEmpty(Content)) throw Oops.Oh("请填写正确的手机号码"); |
| | | |
| | | string postdata1 = "CorpID=" + _smsOptions.lingKai.Number + "&Pwd=" + _smsOptions.lingKai.AccountPassPassword + "&Mobile=" + Phone + "&Content="+ Content + "&SendTime="; |
| | | string code = (string)await HttpPost(_smsOptions.lingKai.Url, postdata1); |
| | | |
| | | var data = Convert.ToInt64(code); |
| | | if (data > 0) |
| | | { |
| | | return ; |
| | | } |
| | | Oops.Oh($"发送短信失败,错误码{data}"); |
| | | |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 获取验证码 🔖 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | [AllowAnonymous] |
| | | [SuppressMonitor] |
| | | [DisplayName("获取验证码")] |
| | | public dynamic GetCaptcha() |
| | | { |
| | | var codeId = YitIdHelper.NextId().ToString(); |
| | | var captcha = _captcha.Generate(codeId); |
| | | var expirySeconds = App.GetOptions<CaptchaOptions>()?.ExpirySeconds ?? 60; |
| | | return new { Id = codeId, Img = captcha.Base64, ExpirySeconds = expirySeconds }; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 校验短信验证码 |
| | | /// </summary> |
| | | /// <param name="input"></param> |
| | | /// <returns></returns> |
| | | [AllowAnonymous] |
| | | [DisplayName("校验短信验证码")] |
| | | public bool VerifyCode(SmsVerifyCodeInput input) |
| | | { |
| | | var verifyCode = _sysCacheService.Get<string>($"{CacheConst.KeyPhoneVerCode}{input.Phone}"); |
| | | |
| | | if (string.IsNullOrWhiteSpace(verifyCode)) throw Oops.Oh("验证码不存在或已失效,请重新获取!"); |
| | | |
| | | if (verifyCode != input.Code) throw Oops.Oh("验证码错误!"); |
| | | _sysCacheService.Remove($"{CacheConst.KeyPhoneVerCode}{input.Phone}"); |
| | | return true; |
| | | } |
| | | /// <summary> |
| | | /// 发送验证短信,要要验证码 需要输入校验,避免电脑攻击 |
| | | /// </summary> |
| | | /// <param name="phoneNumber"> 电话号码</param> |
| | | /// <param name="VerifyCode">图片校验数据</param> |
| | | /// <param name="VerifyCodeId">检验的ID</param> |
| | | /// <returns></returns> |
| | | [AllowAnonymous] |
| | | [DisplayName("发送验证码")] |
| | | public async Task SendSMS([Required] string phoneNumber , [Required] string VerifyCode, [Required] string VerifyCodeId) |
| | | { |
| | | if (!phoneNumber.TryValidate(ValidationTypes.PhoneNumber).IsValid) throw Oops.Oh("请正确填写手机号码"); |
| | | |
| | | // 校验验证码 |
| | | if (!_captcha.Validate(VerifyCodeId, VerifyCode)) throw Oops.Oh(ErrorCodeEnum.D0008); |
| | | _captcha.Generate(VerifyCodeId); |
| | | |
| | | // 生成随机验证码 |
| | | var random = new Random(); |
| | | var verifyCode = random.Next(100000, 999999); |
| | | |
| | | var templateParam = new |
| | | { |
| | | code = verifyCode |
| | | }; |
| | | var code= FormartMessage(verifyCode.toString()); |
| | | |
| | | await SendSMSAsync(code, phoneNumber); |
| | | |
| | | _sysCacheService.Set($"{CacheConst.KeyPhoneVerCode}{phoneNumber}", verifyCode, TimeSpan.FromSeconds(_smsOptions.lingKai.VerifyTimeOut.ToInt())); |
| | | |
| | | |
| | | |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 发送验证码 |
| | | /// </summary> |
| | | /// <param name="Url"> 链接</param> |
| | | /// <param name="postDataStr"> 验证码</param> |
| | | /// <returns></returns> |
| | | private async Task<string> HttpPost(string Url, string postDataStr) |
| | | { |
| | | //HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url); |
| | | //request.Method = "POST"; |
| | | //request.ContentType = "application/x-www-form-urlencoded;charset=gb2312"; |
| | | |
| | | //byte[] postData = Encoding.GetEncoding("gb2312").GetBytes(postDataStr); |
| | | //request.ContentLength = postData.Length; |
| | | //Stream myRequestStream = request.GetRequestStream(); |
| | | //myRequestStream.Write(postData, 0, postData.Length); |
| | | //myRequestStream.Close(); |
| | | //HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync(); |
| | | //Stream myResponseStream = response.GetResponseStream(); |
| | | //StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("gb2312")); |
| | | //string retString = myStreamReader.ReadToEnd(); |
| | | //myStreamReader.Close(); |
| | | //myResponseStream.Close(); |
| | | |
| | | //return retString; |
| | | // 创建 HttpClient 实例 |
| | | using var httpClient = new HttpClient(); |
| | | // 准备要发送的内容,设置编码和内容类型 |
| | | var content = new StringContent(postDataStr, Encoding.GetEncoding("gb2312"), "application/x-www-form-urlencoded"); |
| | | // 发送 POST 请求 |
| | | var response = await httpClient.PostAsync(Url, content); |
| | | // 确保请求成功,若失败则抛出异常 |
| | | response.EnsureSuccessStatusCode(); |
| | | // 读取响应内容 |
| | | return await response.Content.ReadAsStringAsync(); |
| | | } |
| | | |
| | | } |