username@email.com
4 天以前 4008c7e22c9c01eb653b04f934990486df622654
Admin.NET/FZCZTB.NET.SYSService/MSM/ZCSMSService.cs
New file
@@ -0,0 +1,216 @@
// 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();
    }
}