浏览代码

新增短信模板接口

TANG JIANG 1 年之前
父节点
当前提交
e33af024c5

+ 1 - 1
src/Hotline.Api/Controllers/KnowledgeApplyController.cs

@@ -79,7 +79,7 @@ namespace Hotline.Api.Controllers
         [HttpPut("update")]
         public async Task UpdateApply([FromBody] UpdateKnowledgeApplyDto dto)
         {
-            var ka = _mapper.Map<KnowledgeApply>(dto); 
+            var ka = _mapper.Map<KnowledgeApply>(dto);
             ka.Status = EKnowledgeApplyStatus.Handling;
             await _knowledgeApplyRepository.UpdateAsync(ka, HttpContext.RequestAborted);
         }

+ 51 - 0
src/Hotline.Api/Controllers/PushMessageController.cs

@@ -0,0 +1,51 @@
+using Hotline.Push;
+using Hotline.Repository.SqlSugar.Extensions;
+using Hotline.Share.Dtos;
+using Hotline.Share.Dtos.Push;
+using MapsterMapper;
+using Microsoft.AspNetCore.Mvc;
+
+namespace Hotline.Api.Controllers
+{
+    public class PushMessageController : BaseController
+    {
+        private readonly IMessageRepository _messageRepository;
+        private readonly IMapper _mapper;
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="messageRepository"></param>
+        /// <param name="mapper"></param>
+        public PushMessageController(IMessageRepository messageRepository, IMapper mapper)
+        {
+            _messageRepository = messageRepository;
+            _mapper = mapper;
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="pagedDto"></param>
+        /// <returns></returns>
+        [HttpGet("getlist")]
+        public async Task<PagedDto<MessageDataDto>> AllMessage([FromQuery] MessagePagedDto pagedDto)
+        {
+            var (total, items) = await _messageRepository
+                    .Queryable()
+                    .Includes(it => it.User)
+                    .Includes(it => it.SystemOrganize)
+                    .Includes(it => it.Order)
+                    .WhereIF(pagedDto.PushBusiness.HasValue, d => d.PushBusiness == pagedDto.PushBusiness)
+                    .WhereIF(pagedDto.Status.HasValue, d => d.Status == pagedDto.Status)
+                    .WhereIF(!string.IsNullOrEmpty(pagedDto.Keyword), d => d.Name.Contains(pagedDto.Keyword!) || d.Content.Contains(pagedDto.Keyword!) || d.TelNumber.Contains(pagedDto.Keyword!) || d.User.Name.Contains(pagedDto.Keyword!) || d.SystemOrganize.OrgName.Contains(pagedDto.Keyword!))
+                    .WhereIF(pagedDto.StartTime.HasValue, d => d.SendTime >= pagedDto.StartTime)
+                    .WhereIF(pagedDto.EndTime.HasValue, d => d.SendTime <= pagedDto.EndTime)
+                    .OrderByDescending(it => it.CreationTime)
+                    .ToPagedListAsync(pagedDto.PageIndex, pagedDto.PageSize, HttpContext.RequestAborted);
+
+            return new PagedDto<MessageDataDto>(total, _mapper.Map<IReadOnlyList<MessageDataDto>>(items));
+
+        }
+    }
+}

+ 104 - 0
src/Hotline.Api/Controllers/TemplateDomainController.cs

@@ -0,0 +1,104 @@
+using Hotline.Push;
+using Hotline.Repository.SqlSugar.Extensions;
+using Hotline.Share.Dtos;
+using Hotline.Share.Dtos.Push;
+using MapsterMapper;
+using Microsoft.AspNetCore.Mvc;
+using XF.Domain.Exceptions;
+
+namespace Hotline.Api.Controllers
+{
+    public class TemplateDomainController : BaseController
+    {
+        private readonly IMessageTemplateRepository _messageTemplateRepository;
+        private readonly IMapper _mapper;
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="messageTemplateRepository"></param>
+        public TemplateDomainController(IMessageTemplateRepository messageTemplateRepository, IMapper mapper)
+        {
+            _messageTemplateRepository = messageTemplateRepository;
+            _mapper = mapper;
+        }
+
+        /// <summary>
+        /// 新增
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPut("add")]
+        public async Task<string> AddTemplate([FromBody] TemplateDto dto)
+        {
+            var template = _mapper.Map<MessageTemplate>(dto);
+
+            var data = await _messageTemplateRepository.GetAsync(p => p.Code == template.Code, HttpContext.RequestAborted);
+            if (data != null)
+                throw UserFriendlyException.SameMessage("存在相同Code!");
+
+            return await _messageTemplateRepository.AddAsync(template, HttpContext.RequestAborted);
+        }
+
+        /// <summary>
+        /// 修改
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPut("update")]
+        public async Task UpdateTemplate([FromBody] UpdateTemplateDto dto)
+        {
+            var template = _mapper.Map<MessageTemplate>(dto);
+
+            var data = await _messageTemplateRepository.GetAsync(p => p.Code == template.Code && p.Id != template.Id, HttpContext.RequestAborted);
+            if (data != null)
+                throw UserFriendlyException.SameMessage("存在相同Code!");
+
+            await _messageTemplateRepository.UpdateAsync(template, HttpContext.RequestAborted);
+        }
+
+        /// <summary>
+        /// 删除
+        /// </summary>
+        /// <param name="Id"></param>
+        /// <returns></returns>
+        [HttpDelete("remove")]
+        public async Task RemoveType(string Id)
+        {
+            await _messageTemplateRepository.RemoveAsync(Id, false, HttpContext.RequestAborted);
+        }
+
+        /// <summary>
+        /// 查询详情
+        /// </summary>
+        /// <param name="Id"></param>
+        /// <returns></returns>
+        [HttpGet("info/{Id}")]
+        public async Task<UpdateTemplateDto> Info(string Id)
+        {
+            var template = await _messageTemplateRepository.GetAsync(Id, HttpContext.RequestAborted);
+            if (template is null)
+                throw UserFriendlyException.SameMessage("查询失败!");
+            return _mapper.Map<UpdateTemplateDto>(template);
+        }
+
+        /// <summary>
+        /// 查询列表
+        /// </summary>
+        /// <param name="pagedDto"></param>
+        /// <returns></returns>
+        [HttpGet("getlist")]
+        public async Task<PagedDto<TemplateDataDto>> GetList([FromQuery] TemplatePagedDto pagedDto)
+        {
+            var (total, items) = await _messageTemplateRepository
+                    .Queryable()
+                    .WhereIF(!string.IsNullOrEmpty(pagedDto.Keyword), d => d.Code.Contains(pagedDto.Keyword!) || d.Content.Contains(pagedDto.Keyword!))
+                    .WhereIF(pagedDto.PushBusiness.HasValue, d => d.PushBusiness == pagedDto.PushBusiness)
+                    .OrderByDescending(it => it.CreationTime)
+                    .ToPagedListAsync(pagedDto.PageIndex, pagedDto.PageSize, HttpContext.RequestAborted);
+
+            return new PagedDto<TemplateDataDto>(total, _mapper.Map<IReadOnlyList<TemplateDataDto>>(items));
+
+        }
+    }
+}

+ 17 - 0
src/Hotline.Application.Contracts/Validators/Push/TemplateDtoValidator.cs

@@ -0,0 +1,17 @@
+using FluentValidation;
+using Hotline.Share.Dtos.Push;
+
+namespace Hotline.Application.Contracts.Validators.Push
+{
+    public class TemplateDtoValidator : AbstractValidator<TemplateDto>
+    {
+        /// <summary>
+        /// 
+        /// </summary>
+        public TemplateDtoValidator()
+        {
+            RuleFor(d => d.Code).NotEmpty();
+            RuleFor(d => d.Content).NotEmpty();
+        }
+    }
+}

+ 18 - 0
src/Hotline.Application.Contracts/Validators/Push/UpdateTemplateDtoValidator.cs

@@ -0,0 +1,18 @@
+using FluentValidation;
+using Hotline.Share.Dtos.Push;
+
+namespace Hotline.Application.Contracts.Validators.Push
+{
+    public class UpdateTemplateDtoValidator : AbstractValidator<UpdateTemplateDto>
+    {
+        /// <summary>
+        /// 
+        /// </summary>
+        public UpdateTemplateDtoValidator()
+        {
+            RuleFor(d => d.Id).NotEmpty();
+            RuleFor(d => d.Code).NotEmpty();
+            RuleFor(d => d.Content).NotEmpty();
+        }
+    }
+}

+ 7 - 0
src/Hotline.Application/Mappers/MapperConfigs.cs

@@ -8,6 +8,7 @@ using Hotline.Share.Dtos.CallCenter;
 using Hotline.Share.Dtos.FlowEngine;
 using Hotline.Share.Dtos.Knowledge;
 using Hotline.Share.Dtos.Order;
+using Hotline.Share.Dtos.Push;
 using Hotline.Share.Dtos.Roles;
 using Hotline.Share.Dtos.Users;
 using Hotline.Users;
@@ -180,6 +181,12 @@ namespace Hotline.Application.Mappers
                 .Map(d => d.OrderReport.Id, x => x.Id);
 
             #endregion
+
+            config.ForType<Hotline.Push.Message, MessageDataDto>()
+               .Map(d => d.SendUser, x => x.User.Name)
+               .Map(d => d.SendOrganize, x => x.SystemOrganize.OrgName)
+               .Map(d => d.OrderId, x => x.Order.Id)
+               .Map(d => d.OrderNo, x => x.Order.No);
         }
     }
 }

+ 16 - 0
src/Hotline.Repository.SqlSugar/Push/MessageRepository.cs

@@ -0,0 +1,16 @@
+using Hotline.KnowledgeBase;
+using Hotline.Push;
+using Hotline.Repository.SqlSugar.DataPermissions;
+using SqlSugar;
+using XF.Domain.Dependency;
+
+namespace Hotline.Repository.SqlSugar.Push
+{
+    public class MessageRepository : BaseRepository<Message>, IMessageRepository, IScopeDependency
+    {
+        public MessageRepository(ISugarUnitOfWork<HotlineDbContext> uow, IDataPermissionFilterBuilder dataPermissionFilterBuilder) : base(uow, dataPermissionFilterBuilder)
+        {
+
+        }
+    }
+}

+ 15 - 0
src/Hotline.Repository.SqlSugar/Push/MessageTemplateRepository.cs

@@ -0,0 +1,15 @@
+using Hotline.Push;
+using Hotline.Repository.SqlSugar.DataPermissions;
+using SqlSugar;
+using XF.Domain.Dependency;
+
+namespace Hotline.Repository.SqlSugar.Push
+{
+    public class MessageTemplateRepository : BaseRepository<MessageTemplate>, IMessageTemplateRepository, IScopeDependency
+    {
+        public MessageTemplateRepository(ISugarUnitOfWork<HotlineDbContext> uow, IDataPermissionFilterBuilder dataPermissionFilterBuilder) : base(uow, dataPermissionFilterBuilder)
+        {
+
+        }
+    }
+}

+ 67 - 0
src/Hotline.Share/Dtos/Push/MessageDataDto.cs

@@ -0,0 +1,67 @@
+using Hotline.Share.Enums.Push;
+
+namespace Hotline.Share.Dtos.Push
+{
+    public record MessageDataDto
+    {
+        /// <summary>
+        /// 消息推送业务
+        /// </summary>
+        public EPushBusiness PushBusiness { get; set; }
+
+        /// <summary>
+        /// 接收姓名
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 接收手机号码
+        /// </summary>
+        public string TelNumber { get; set; }
+
+        /// <summary>
+        /// 内容
+        /// </summary>
+        public string Content { get; set; }
+
+        /// <summary>
+        /// 创建时间
+        /// </summary>
+        public DateTime CreationTime { get; set; }
+
+        /// <summary>
+        /// 发送时间
+        /// </summary>
+        public DateTime? SendTime { get; set; }
+
+        /// <summary>
+        /// 发送人
+        /// </summary>
+        public string SendUser { get; set; }
+
+        /// <summary>
+        /// 发送部门
+        /// </summary>
+        public string SendOrganize { get; set; }
+
+        /// <summary>
+        /// 备注
+        /// </summary>
+        public string? Remark { get; set; }
+
+        /// <summary>
+        /// 关联工单编号
+        /// </summary>
+        public string? OrderNo { get; set; }
+
+        /// <summary>
+        /// 关联工单ID
+        /// </summary>
+        public string? OrderId { get; set; }
+
+        /// <summary>
+        /// 推送状态
+        /// </summary>
+        public EPushStatus Status { get; set; }
+    }
+}

+ 13 - 0
src/Hotline.Share/Dtos/Push/MessagePagedDto.cs

@@ -0,0 +1,13 @@
+using Hotline.Share.Enums.Push;
+using Hotline.Share.Requests;
+
+namespace Hotline.Share.Dtos.Push
+{
+
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="PushBusiness"></param>
+    /// <param name="Status"></param>
+    public record MessagePagedDto(EPushBusiness? PushBusiness, EPushStatus? Status, DateTime? StartTime, DateTime? EndTime) : PagedKeywordRequest;
+}

+ 37 - 0
src/Hotline.Share/Dtos/Push/TemplateDataDto.cs

@@ -0,0 +1,37 @@
+using Hotline.Share.Enums.Push;
+
+namespace Hotline.Share.Dtos.Push
+{
+    public record TemplateDataDto
+    {
+        /// <summary>
+        /// ID
+        /// </summary>
+        public string Id { get; set; }
+
+        /// <summary>
+        /// 短信类型
+        /// </summary>
+        public EPushBusiness PushBusiness { get; set; }
+
+        /// <summary>
+        /// 短信Code
+        /// </summary>
+        public string Code { get; set; }
+
+        /// <summary>
+        /// 内容
+        /// </summary>
+        public string Content { get; set; }
+
+        /// <summary>
+        /// 备注
+        /// </summary>
+        public string? Remark { get; set; }
+
+        /// <summary>
+        /// 模板状态
+        /// </summary>
+        public bool Status { get; set; }
+    }
+}

+ 47 - 0
src/Hotline.Share/Dtos/Push/TemplateDto.cs

@@ -0,0 +1,47 @@
+using Hotline.Share.Enums.Push;
+
+namespace Hotline.Share.Dtos.Push
+{
+    /// <summary>
+    /// 
+    /// </summary>
+    public record TemplateDto
+    {
+        /// <summary>
+        /// 短信类型
+        /// </summary>
+        public EPushBusiness PushBusiness { get; set; }
+
+        /// <summary>
+        /// 短信Code
+        /// </summary>
+        public string Code { get; set; }
+
+        /// <summary>
+        /// 内容
+        /// </summary>
+        public string Content { get; set; }
+
+        /// <summary>
+        /// 备注
+        /// </summary>
+        public string? Remark { get; set; }
+
+        /// <summary>
+        /// 模板状态
+        /// </summary>
+        public bool Status { get; set; }
+    }
+
+    /// <summary>
+    /// 编辑
+    /// </summary>
+    public record UpdateTemplateDto : TemplateDto
+    {
+        /// <summary>
+        /// ID
+        /// </summary>
+        public string Id { get; set; }
+    }
+
+}

+ 11 - 0
src/Hotline.Share/Dtos/Push/TemplatePagedDto.cs

@@ -0,0 +1,11 @@
+using Hotline.Share.Enums.Push;
+using Hotline.Share.Requests;
+
+namespace Hotline.Share.Dtos.Push
+{
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="PushBusiness"></param>
+    public record TemplatePagedDto(EPushBusiness? PushBusiness) : PagedKeywordRequest;
+}

+ 19 - 1
src/Hotline.Share/Enums/Push/EPushStatus.cs

@@ -1,9 +1,27 @@
-namespace Hotline.Share.Enums.Push;
+using System.ComponentModel;
+
+namespace Hotline.Share.Enums.Push;
 
 /// <summary>
 /// 推送状态
 /// </summary>
 public enum EPushStatus
 {
+    /// <summary>
+    /// 
+    /// </summary>
+    [Description("推送中")]
+    Pushing =0,
+
+    /// <summary>
+    /// 
+    /// </summary>
+    [Description("推送成功")]
+    Success =1,
 
+    /// <summary>
+    /// 
+    /// </summary>
+    [Description("推送失败")]
+    Failed =2
 }

+ 8 - 0
src/Hotline/Push/IMessageRepository.cs

@@ -0,0 +1,8 @@
+using XF.Domain.Repository;
+
+namespace Hotline.Push
+{
+    public interface IMessageRepository : IRepository<Message>
+    {
+    }
+}

+ 8 - 0
src/Hotline/Push/IMessageTemplateRepository.cs

@@ -0,0 +1,8 @@
+using XF.Domain.Repository;
+
+namespace Hotline.Push
+{
+    public interface IMessageTemplateRepository : IRepository<MessageTemplate>
+    {
+    }
+}

+ 2 - 8
src/Hotline/Push/IPushDomainService.cs

@@ -1,13 +1,7 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Hotline.Push
+namespace Hotline.Push
 {
     public interface IPushDomainService
     {
-        Task PushAsync(Message message, CancellationToken cancellation);
+        Task PushAsync(Message message, List<string> Params, CancellationToken cancellation);
     }
 }

+ 57 - 6
src/Hotline/Push/Message.cs

@@ -1,9 +1,7 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using Hotline.Orders;
+using Hotline.Settings;
 using Hotline.Share.Enums.Push;
+using Hotline.Users;
 using SqlSugar;
 using XF.Domain.Repository;
 
@@ -14,6 +12,9 @@ namespace Hotline.Push
     /// </summary>
     public class Message : CreationEntity
     {
+        /// <summary>
+        /// 消息推送业务
+        /// </summary>
         public EPushBusiness PushBusiness { get; set; }
 
         /// <summary>
@@ -45,6 +46,56 @@ namespace Hotline.Push
         /// <summary>
         /// 备注
         /// </summary>
-        public string Remark { get; set; }
+        [SugarColumn(IsNullable = true)]
+        public string? Remark { get; set; }
+
+        /// <summary>
+        /// 接收姓名
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 接收手机号码
+        /// </summary>
+        public string TelNumber { get; set; }
+
+        /// <summary>
+        /// 发送时间
+        /// </summary>
+        public DateTime? SendTime { get; set; }
+
+        /// <summary>
+        /// 发送人ID
+        /// </summary>
+        public string UserID { get; set; }
+
+        /// <summary>
+        /// 发送人部门ID
+        /// </summary>
+        public string SendDepartment { get; set; }
+
+        /// <summary>
+        /// 关联工单编号
+        /// </summary>
+        [SugarColumn(IsNullable = true)]
+        public string? OrderId { get; set; }
+
+        /// <summary>
+        /// 发送人
+        /// </summary>
+        [Navigate(NavigateType.OneToOne, nameof(UserID))]//
+        public User User { get; set; }
+
+        /// <summary>
+        /// 发送部门
+        /// </summary>
+        [Navigate(NavigateType.OneToOne, nameof(SendDepartment))]//
+        public SystemOrganize SystemOrganize { get; set; }
+
+        /// <summary>
+        /// 关联工单信息
+        /// </summary>
+        [Navigate(NavigateType.OneToOne, nameof(OrderId))]//
+        public Order Order { get; set; }
     }
 }

+ 35 - 0
src/Hotline/Push/MessageTemplate.cs

@@ -0,0 +1,35 @@
+using Hotline.Share.Enums.Push;
+using SqlSugar;
+using XF.Domain.Repository;
+
+namespace Hotline.Push
+{
+    public class MessageTemplate : CreationModificationEntity
+    {
+        /// <summary>
+        /// 短信类型
+        /// </summary>
+        public EPushBusiness PushBusiness { get; set; }
+
+        /// <summary>
+        /// 短信Code
+        /// </summary>
+        public string Code { get; set; }
+
+        /// <summary>
+        /// 内容
+        /// </summary>
+        public string Content { get; set; }
+
+        /// <summary>
+        /// 备注
+        /// </summary>
+        [SugarColumn(IsNullable = true)]
+        public string? Remark { get; set; }
+
+        /// <summary>
+        /// 模板状态
+        /// </summary>
+        public bool Status { get; set; }
+    }
+}

+ 55 - 3
src/Hotline/Push/PushDomainService.cs

@@ -1,11 +1,63 @@
-using XF.Domain.Dependency;
+using System.Text.RegularExpressions;
+using XF.Domain.Dependency;
+using XF.Domain.Exceptions;
 
 namespace Hotline.Push;
 
 public class PushDomainService : IPushDomainService, IScopeDependency
 {
-    public async Task PushAsync(Message message, CancellationToken cancellation)
+
+    private readonly IMessageRepository _messageRepository;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="messageRepository"></param>
+    public PushDomainService(IMessageRepository messageRepository)
+    {
+        _messageRepository = messageRepository;
+    }
+
+    /// <summary>
+    /// 业务处理
+    /// </summary>
+    /// <param name="message"></param>
+    /// <param name="Params"></param>
+    /// <param name="cancellation"></param>
+    /// <returns></returns>
+    public async Task PushAsync(Message message, List<string> Params, CancellationToken cancellation)
     {
-        throw new NotImplementedException();
+        if (message == null)
+        {
+            throw UserFriendlyException.SameMessage("消息不能为空!");
+        }
+
+        //如果模板为空,参数为空则直接用短信内容
+        if (!string.IsNullOrEmpty(message.Template) && Params.Count > 0)
+        {
+            string Template = message.Template;
+            //正则查询模板中需要替换的内容
+            Regex regex = new(@"\{[a-zA-Z0-9]{1,}\}");
+            var matches = regex.Matches(Template);
+            if (matches != null && matches.Count != Params.Count)
+            {
+                //参数与需要替换的字符数不匹配
+                //throw UserFriendlyException.SameMessage("模板需要参数与实际传递参数个数不匹配!");
+                message.Remark = "模板需要参数与实际传递参数个数不匹配!";
+            }
+
+            //根据正则查询出来的匹配项替换内容
+            for (int i = 0; i < matches.Count; i++)
+            {
+                var strTemp = matches[i].ToString();
+                Template = Template.Replace(strTemp, Params[i]);
+            }
+
+            message.Content = Template;
+        }
+        //写入本地数据库
+        var id = await _messageRepository.AddAsync(message);
+
+        //调用短信发送业务
     }
 }