瀏覽代碼

Merge branch 'test' of http://110.188.24.182:10023/Fengwo/hotline into test

tangjiang 1 周之前
父節點
當前提交
825cddad5d

+ 412 - 10
src/Hotline.Api/Controllers/FwThirdController.cs

@@ -7,6 +7,7 @@ using Hotline.Caching.Interfaces;
 using Hotline.Configurations;
 using Hotline.KnowledgeBase;
 using Hotline.Orders;
+using Hotline.Push.Notifies;
 using Hotline.Repository.SqlSugar.Extensions;
 using Hotline.Settings;
 using Hotline.Settings.Hotspots;
@@ -16,6 +17,8 @@ using Hotline.Share.Dtos.Schedulings;
 using Hotline.Share.Dtos.WebPortal;
 using Hotline.Share.Enums.KnowledgeBase;
 using Hotline.Share.Enums.Order;
+using Hotline.Share.Enums.Push;
+using Hotline.Share.Tools;
 using Hotline.Tools;
 using Hotline.Users;
 using Hotline.WebPortal;
@@ -26,6 +29,10 @@ using Microsoft.AspNetCore.Mvc;
 using Microsoft.Extensions.Options;
 using NPOI.XWPF.UserModel;
 using SqlSugar;
+using System;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Text;
 using XF.Domain.Authentications;
 using XF.Domain.Cache;
 using XF.Domain.Exceptions;
@@ -44,6 +51,7 @@ namespace Hotline.Api.Controllers
         private readonly IRepository<WebUserRegister> _webUserRegisterRepository;
         private readonly IRepository<WebUserAuth> _webUserAuthRepository;
         private readonly IRepository<WebFlowAccept> _webFlowAcceptRepository;
+        private readonly ITypedCache<VerificationPic> _verificationPic;
         private readonly ITypedCache<WriteLettersSendSmsDto> _writeLettersSendSms;
         private readonly IRepository<Hotspot> _hotspotRepository;
         private readonly ISystemSettingCacheManager _systemSettingCacheManager;
@@ -73,6 +81,7 @@ namespace Hotline.Api.Controllers
             IRepository<WebUserRegister> webUserRegisterRepository,
             IRepository<WebUserAuth> webUserAuthRepository,
             IRepository<WebFlowAccept> webFlowAcceptRepository,
+            ITypedCache<VerificationPic> verificationPic,
             ITypedCache<WriteLettersSendSmsDto> writeLettersSendSms,
             IRepository<Hotspot> hotspotRepository,
             ISystemSettingCacheManager systemSettingCacheManager,
@@ -103,6 +112,7 @@ namespace Hotline.Api.Controllers
             _webUserRegisterRepository = webUserRegisterRepository;
             _webUserAuthRepository = webUserAuthRepository;
             _webFlowAcceptRepository = webFlowAcceptRepository;
+            _verificationPic = verificationPic;
             _writeLettersSendSms = writeLettersSendSms;
             _hotspotRepository = hotspotRepository;
             _systemSettingCacheManager = systemSettingCacheManager;
@@ -143,9 +153,9 @@ namespace Hotline.Api.Controllers
 
         #region 自贡门户查询接口
 
-        #region 受理统计
+        #region 4.2 受理统计
 
-        /// <summary>getacceptancetypestatisticsbymonth
+        /// <summary>
         /// 受理统计
         /// </summary>
         /// <param name="dto"></param>
@@ -199,7 +209,7 @@ namespace Hotline.Api.Controllers
 
         #endregion
 
-        #region 办理统计
+        #region 4.3 办理统计
 
         /// <summary>
         /// 办理统计
@@ -253,7 +263,7 @@ namespace Hotline.Api.Controllers
 
         #endregion
 
-        #region 公告通知、工作简报
+        #region 4.4~5 公告通知、工作简报
 
         /// <summary>
         /// 公告通知、工作简报
@@ -327,7 +337,7 @@ namespace Hotline.Api.Controllers
 
         #endregion
 
-        #region 信件选登
+        #region 4.6 信件选登
 
         /// <summary>
         /// 查询工单发布后公开的数据
@@ -457,7 +467,7 @@ namespace Hotline.Api.Controllers
 
         #endregion
 
-        #region 知识库
+        #region 4.7 知识库
 
         #region 知识库分类
 
@@ -563,7 +573,7 @@ namespace Hotline.Api.Controllers
 
         #endregion
 
-        #region 工单写信
+        #region 4.8.1 工单写信(老版)
 
         /// <summary>
         /// 工单写信
@@ -655,13 +665,12 @@ namespace Hotline.Api.Controllers
             else
                 returnDto.State = "0";
 
-
             return OpenResponse.Ok(WebPortalDeResponse<OrderAcceptanceReturnDto>.Success(returnDto));
         }
 
         #endregion
 
-        #region 附件上传
+        #region 4.8.2 附件上传
 
         /// <summary>
         /// 附件上传
@@ -710,7 +719,101 @@ namespace Hotline.Api.Controllers
 
         #endregion
 
-        #region 工单查询
+        #region 4.8.3 工单写信(带验证码)
+
+        /// <summary>
+        /// 工单写信
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("orderacceptancesms")]
+        public async Task<OrderAcceptanceReturnDto> OrderAcceptanceSms([FromBody] WebFlowAcceptSmsDto dto)
+        {
+            //电话号码去空格
+            if (!string.IsNullOrEmpty(dto.Mobile))
+                dto.Mobile = dto.Mobile.Trim();
+
+            string strResult = dto.ValidateObject();
+            if (!string.IsNullOrEmpty(strResult))
+            {
+                throw UserFriendlyException.SameMessage("数据验证不通过");
+            }
+
+            if (dto.Mobile.IsPhoneNumber() == false)
+            {
+                throw UserFriendlyException.SameMessage("请输入正确的手机号");
+            }
+
+            string keyTokenSms = "SmsUserWriteKey_" + dto.Mobile + "_" + DateTime.Now.ToString("yyyyMMdd");
+            var dataSms = await _writeLettersSendSms.GetAsync(keyTokenSms, HttpContext.RequestAborted);
+            if (dataSms != null)
+            {
+                if (dataSms.SmsCode != dto.SmsCode)
+                    throw UserFriendlyException.SameMessage("短信验证码错误!");
+            }
+            else
+            {
+                throw UserFriendlyException.SameMessage("短信验证码错误!");
+            }
+
+            var order = _orderListRepository.Queryable()
+                            .Where(x => x.Title == dto.Title)
+                            .Where(x => x.SourceChannelCode == "YTW")
+                            .Where(x => x.Contact == dto.Mobile)
+                            .Select(x => new
+                            {
+                                No = x.No,
+                                Second = SqlFunc.DateDiff(DateType.Second, x.CreationTime, DateTime.Now)
+                            }).MergeTable()
+                            .Where(x => x.Second < 180)
+                            .Any();
+            if (order)
+            {
+                throw UserFriendlyException.SameMessage("3分钟内,请勿重复提交工单!");
+            }
+
+            var data = _mapper.Map<Hotline.Share.Dtos.Order.AddOrderDto>(dto);
+            data.Source = ESource.WebPortal;
+            data.SourceChannel = "因特网";
+            data.SourceChannelCode = "YTW";
+
+            if (!string.IsNullOrEmpty(data.LicenceNo))
+            {
+                data.LicenceTypeCode = "10";
+                data.LicenceType = "中华人民共和国居民身份证";
+            }
+            data.ExternalId = Guid.NewGuid().ToString();
+
+            data.IdentityType = dto.IdentityType;
+            data.Transpond = false;
+            data.IsEnforcementOrder = false;
+
+
+            var result = await _orderApplication.ReceiveOrderFromExternalAsync(data, HttpContext.RequestAborted);
+
+            OrderAcceptanceReturnDto returnDto = new();
+            if (result != null)
+            {
+                returnDto.PWD = result.Password;
+                returnDto.Code = result.No;
+                returnDto.State = "1";
+
+                dto.Pwd = result.Password;
+                dto.Code = result.No;
+                dto.OrderId = result.Id;
+                var dtoData = _mapper.Map<WebFlowAccept>(dto);
+                await _webFlowAcceptRepository.AddAsync(dtoData, HttpContext.RequestAborted);
+
+            }
+            else
+                returnDto.State = "0";
+
+            return returnDto;
+        }
+
+        #endregion
+
+        #region 4.9 工单查询
 
         /// <summary>
         /// 根据编号和密码查询信件ID
@@ -767,10 +870,125 @@ namespace Hotline.Api.Controllers
         }
 
 
+        #endregion
+
+        #region 4.10 图片验证码
+
+        /// <summary>
+        /// 图片验证码
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("getverificationcodebypic")]
+        public async Task<VerificationPic> GetVerificationCodeByPic()
+        {
+            var verifyCode = GetVerifyCodeText(5, true, false);                // 验证码
+            var base64String = CreateImageAndConvertToBase64(verifyCode);      // 图片Base64
+            var guidString = Guid.NewGuid().ToString();                        // Guid
+
+            var data = new VerificationPic()
+            {
+                base64 = base64String,
+                guid = guidString
+            };
+
+            // 保存数据到Readis
+            string keyToken = "PicUserWriteKey_" + guidString + "_" + verifyCode + "_" + DateTime.Now.ToString("yyyyMMdd");
+            await _verificationPic.SetAsync(keyToken, data, TimeSpan.FromHours(1), HttpContext.RequestAborted);
+
+            return data;
+        }
+
+        #endregion
+
+        #region 4.11 短信验证码
+
+        /// <summary>
+        /// 短信验证码
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost("getverificationcodebysms")]
+        public async Task<VerificationSms> GetVerificationCodeBySms([FromBody] VerificationPicDto dto)
+        {
+            if (dto.TelNum.IsPhoneNumber() == false)
+            {
+                throw UserFriendlyException.SameMessage("请输入正确的手机号");
+            }
+
+            // 验证图片验证码是否对
+            string keyToken = "PicUserWriteKey_" + dto.guid + "_" + dto.verCode + "_" + DateTime.Now.ToString("yyyyMMdd");
+            var data = await _verificationPic.GetAsync(keyToken, HttpContext.RequestAborted);
+            if (data == null)
+            {
+                throw UserFriendlyException.SameMessage("验证码错误");
+            }
+
+            var SmsCodeRand = RandomNum();
+
+            // 发送短信验证码
+            string keyTokenSms = "SmsUserWriteKey_" + dto.TelNum + "_" + DateTime.Now.ToString("yyyyMMdd");
+            var dataSms = await _writeLettersSendSms.GetAsync(keyTokenSms, HttpContext.RequestAborted);
+            if (dataSms != null)//已经发过短信
+            {
+                //是否可以继续发送短信(10次)
+                if (dataSms.SendCount > 10)
+                    //短信发送超过10条
+                    throw UserFriendlyException.SameMessage("短信发送超过10条");
+
+                // 验证是否在两分钟之内
+                TimeSpan duration = DateTime.Now - dataSms.AddTime; // 计算时间差
+                if ((int)duration.TotalSeconds < 120)
+                    // 距离上次发送时间不足两分钟
+                    throw UserFriendlyException.SameMessage("距离上次发送时间不足两分钟");
+
+                //修改缓存信息
+                dataSms.SendCount++;
+                dataSms.SmsCode = SmsCodeRand;
+                dataSms.AddTime = DateTime.Now;
+            }
+            else
+            {
+                //没有发过短信,直接写入数据
+                dataSms = new WriteLettersSendSmsDto
+                {
+                    AddTime = DateTime.Now,
+                    SmsCode = SmsCodeRand,
+                    MobileNum = dto.TelNum,
+                    SendCount = 1
+                };
+            }
+            //这里发送短信
+            var messageDto = new Share.Dtos.Push.MessageDto
+            {
+                PushBusiness = EPushBusiness.MsgCode,
+                ExternalId = "",
+                OrderId = "",
+                PushPlatform = EPushPlatform.Web,
+                Remark = "",
+                Name = dto.TelNum,
+                TemplateCode = "1008",
+                Params = new List<string>() { SmsCodeRand },
+                TelNumber = dto.TelNum,
+
+            };
+            await _mediator.Publish(new PushMessageNotify(messageDto), HttpContext.RequestAborted);
+
+            //保存短信
+            await _writeLettersSendSms.SetAsync(keyTokenSms, dataSms, TimeSpan.FromDays(1), HttpContext.RequestAborted);
+
+            return new VerificationSms()
+            {
+                TelNum = dto.TelNum,
+                SmsCode = SmsCodeRand
+            };
+        }
+
         #endregion
 
         #region 私有方法
 
+        #region 将文件转化为文件流
+
         /// <summary>
         /// 将文件转化为文件流
         /// </summary>
@@ -787,6 +1005,190 @@ namespace Hotline.Api.Controllers
 
         #endregion
 
+        #region 获取验证码字符串
+        /// <summary>
+        /// 获取验证码字符串
+        /// </summary>
+        /// <param name="codeLen">验证码长度</param>
+        /// <param name="addUpper">是否添加大写</param>
+        /// <param name="addLower">是否添加小写</param>
+        /// <returns></returns>
+        private string GetVerifyCodeText(int codeLen = 4, bool addUpper = true, bool addLower = true)
+        {
+            // 返回对象
+            string codeText = "";
+            if (codeLen < 4)
+            {
+                codeLen = 4;
+            }
+            StringBuilder objChars = new StringBuilder();
+            StringBuilder objNums = new StringBuilder();
+            // 加入数字1-9
+            for (int i = 1; i <= 9; i++)
+            {
+                objNums.Append(i.ToString());
+            }
+            List<char> notExists = new List<char>();
+            notExists.Add('O');
+            notExists.Add('o');
+            notExists.Add('I');
+            notExists.Add('i');
+            notExists.Add('L');
+            notExists.Add('l');
+            notExists.Add('J');
+            notExists.Add('j');
+            notExists.Add('P');
+            notExists.Add('p');
+            notExists.Add('G');
+            notExists.Add('g');
+            // 加入大写字母A-Z,不包括O
+            if (addUpper == true)
+            {
+                char temp = ' ';
+
+                for (int i = 0; i < 26; i++)
+                {
+                    temp = Convert.ToChar(i + 65);
+
+                    // 如果生成的字母不是'O','o','I','i','L','l','J','j'
+                    if (notExists.Contains(temp) == false)
+                    {
+                        objChars.Append(temp);
+                    }
+                }
+            }
+
+            // 加入小写字母a-z,不包括o
+            if (addLower == true)
+            {
+                char temp = ' ';
+
+                for (int i = 0; i < 26; i++)
+                {
+                    temp = Convert.ToChar(i + 97);
+
+                    // 如果生成的字母不是'O','o','I','i','L','l','J','j'
+                    if (notExists.Contains(temp) == false)
+                    {
+                        objChars.Append(temp);
+                    }
+                }
+            }
+            // 生成验证码字符串
+            {
+                int index = 0;
+                Random objRandom = new Random();
+                StringBuilder objCodes = new StringBuilder();
+                for (int i = 0; i < 2; i++)
+                {
+                    index = objRandom.Next(0, objNums.Length);
+                    objCodes.Append(objNums[index]);
+                    objNums.Remove(index, 1);
+                }
+                for (int i = 0; i < codeLen - 2; i++)
+                {
+                    index = objRandom.Next(0, objChars.Length);
+                    objCodes.Append(objChars[index]);
+                    objChars.Remove(index, 1);
+                }
+                for (int i = 0; i < codeLen; i++)
+                {
+                    index = objRandom.Next(0, objCodes.Length);
+                    codeText += objCodes[index];
+                    objCodes.Remove(index, 1);
+                }
+            }
+            return codeText;
+        }
+        #endregion
+
+        #region 创建图片并且转换成base64
+
+        /// <summary>
+        /// 创建图片并且转换成base64
+        /// </summary>
+        /// <param name="verifyCode"></param>
+        /// <returns></returns>
+        private string CreateImageAndConvertToBase64(string verifyCode)
+        {
+            var base64String = "";
+            try
+            {
+                // 1. 创建一个新的位图 (100x100像素)
+                using (var bitmap = new Bitmap((int)Math.Ceiling((verifyCode.Length * 16.5)), 25))
+                {
+                    // 2. 使用Graphics对象绘制内容
+                    using (var graphics = Graphics.FromImage(bitmap))
+                    {
+                        Random random = new Random();
+
+                        graphics.Clear(Color.White);
+
+                        for (int i = 0; i < 25; i++)
+                        {
+                            int x1 = random.Next(bitmap.Width);
+                            int x2 = random.Next(bitmap.Width);
+                            int y1 = random.Next(bitmap.Height);
+                            int y2 = random.Next(bitmap.Height);
+                            graphics.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2);
+                        }
+
+                        // 添加一些文本
+                        var font = new Font("Arial", 14, (FontStyle.Bold | FontStyle.Italic));
+                        System.Drawing.Drawing2D.LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(0, 0, bitmap.Width, bitmap.Height), Color.Blue, Color.DarkRed, 1.2f, true);
+                        graphics.DrawString(verifyCode, font, brush, 10, 0);
+
+                        for (int i = 0; i < 100; i++)
+                        {
+                            int x = random.Next(bitmap.Width);
+                            int y = random.Next(bitmap.Height);
+
+                            bitmap.SetPixel(x, y, Color.FromArgb(random.Next()));
+                        }
+
+                        graphics.DrawRectangle(new Pen(Color.Silver), 0, 0, bitmap.Width - 1, bitmap.Height - 1);
+                    }
+
+                    // 保存图片
+                    //bitmap.Save("C:\\Users\\PC\\Desktop\\1x1.png", ImageFormat.Png);
+
+                    // 3. 将图像保存到内存流
+                    using (var memoryStream = new MemoryStream())
+                    {
+                        bitmap.Save(memoryStream, ImageFormat.Png);
+
+                        // 4. 将内存流转换为字节数组
+                        byte[] imageBytes = memoryStream.ToArray();
+
+                        // 5. 将字节数组转换为Base64字符串
+                        base64String = Convert.ToBase64String(imageBytes);
+                    }
+                }
+            }
+            catch (Exception)
+            {
+            }
+            return base64String;
+        }
+
+        #endregion
+
+        #region 随机生成6位数字
+
+        /// <summary>
+        /// 随机生成6位数字
+        /// </summary>
+        /// <returns></returns>
+        private string RandomNum()
+        {
+            var random = new Random();
+            return random.Next(100000, 999999).ToString();
+        }
+
+        #endregion
+
+        #endregion
+
         #endregion
 
         #region 泸州电信查询接口

+ 43 - 0
src/Hotline.Share/Dtos/WebPortal/GetOrderCodePwd.cs

@@ -633,4 +633,47 @@ namespace Hotline.Share.Dtos.WebPortal
         public string? Name { get; set; }
     }
 
+    public class VerificationPic
+    {
+        /// <summary>
+        /// 图片
+        /// </summary>
+        public string? base64 { get; set; }
+
+        /// <summary>
+        /// Guid
+        /// </summary>
+        public string? guid { get; set; }
+    }
+
+    public class VerificationPicDto
+    {
+        /// <summary>
+        /// 验证码
+        /// </summary>
+        public string verCode { get; set; }
+
+        /// <summary>
+        /// Guid
+        /// </summary>
+        public string guid { get; set; }
+
+        /// <summary>
+        /// 号码
+        /// </summary>
+        public string TelNum { get; set; }
+    }
+
+    public class VerificationSms
+    {
+        /// <summary>
+        /// 号码
+        /// </summary>
+        public string TelNum { get; set; }
+
+        /// <summary>
+        /// 验证码
+        /// </summary>
+        public string SmsCode { get; set; }
+    }
 }

+ 8 - 0
src/Hotline.Share/Dtos/WebPortal/WebFlowAcceptDto.cs

@@ -137,4 +137,12 @@ namespace Hotline.Share.Dtos.WebPortal
         /// </summary>
         public string? AreaCode { get; set; }
     }
+
+    public class WebFlowAcceptSmsDto : WebFlowAcceptDto
+    {
+        /// <summary>
+        /// 短信验证码
+        /// </summary>
+        public string SmsCode { get; set; }
+    }
 }