724 lines
34 KiB
C#
724 lines
34 KiB
C#
using System.Security.Cryptography;
|
||
using System.Text;
|
||
using System.Web;
|
||
using JNPF.Common.Core.Manager;
|
||
using JNPF.Common.Dtos.Message;
|
||
using JNPF.Common.Enums;
|
||
using JNPF.Common.Extension;
|
||
using JNPF.Common.Filter;
|
||
using JNPF.Common.Options;
|
||
using JNPF.Common.Security;
|
||
using JNPF.DependencyInjection;
|
||
using JNPF.DynamicApiController;
|
||
using JNPF.Extras.Thirdparty.DingDing;
|
||
using JNPF.Extras.Thirdparty.Email;
|
||
using JNPF.Extras.Thirdparty.Sms;
|
||
using JNPF.Extras.Thirdparty.WeChat;
|
||
using JNPF.FriendlyException;
|
||
using JNPF.Message.Entitys.Dto.MessageTemplate;
|
||
using JNPF.Message.Entitys.Dto.SendMessage;
|
||
using JNPF.Message.Entitys.Entity;
|
||
using JNPF.Message.Entitys.Model.MessageTemplate;
|
||
using JNPF.Message.Interfaces.Message;
|
||
using JNPF.RemoteRequest.Extensions;
|
||
using JNPF.Systems.Entitys.Permission;
|
||
using JNPF.Systems.Interfaces.Permission;
|
||
using JNPF.Systems.Interfaces.System;
|
||
using JNPF.WorkFlow.Entitys.Entity;
|
||
using Mapster;
|
||
using Microsoft.AspNetCore.Mvc;
|
||
using Senparc.Weixin.MP.AdvancedAPIs.TemplateMessage;
|
||
using SqlSugar;
|
||
|
||
namespace JNPF.Message.Service;
|
||
|
||
/// <summary>
|
||
/// 发送配置
|
||
/// 版 本:V3.2
|
||
/// 版 权:拓通智联科技有限公司(http://www.tuotong-tech.com)
|
||
/// 日 期:2021-06-01.
|
||
/// </summary>
|
||
[ApiDescriptionSettings(Tag = "Message", Name = "SendMessage", Order = 240)]
|
||
[Route("api/message/SendMessageConfig")]
|
||
public class SendMessageService : ISendMessageService, IDynamicApiController, ITransient
|
||
{
|
||
private readonly ISqlSugarRepository<MessageSendEntity> _repository;
|
||
private readonly IUsersService _usersService;
|
||
private readonly IMessageService _messageService;
|
||
private readonly ISynThirdInfoService _synThirdInfoService;
|
||
private readonly IShortLinkService _shortLinkService;
|
||
private readonly MessageOptions _messageOptions = App.GetConfig<MessageOptions>("Message", true);
|
||
private readonly IUserManager _userManager;
|
||
|
||
public SendMessageService(
|
||
ISqlSugarRepository<MessageSendEntity> repository,
|
||
IUsersService usersService,
|
||
IMessageService messageService,
|
||
ISynThirdInfoService synThirdInfoService,
|
||
IShortLinkService shortLinkService,
|
||
IUserManager userManager)
|
||
{
|
||
_repository = repository;
|
||
_usersService = usersService;
|
||
_messageService = messageService;
|
||
_synThirdInfoService = synThirdInfoService;
|
||
_shortLinkService = shortLinkService;
|
||
_userManager = userManager;
|
||
}
|
||
|
||
#region Get
|
||
/// <summary>
|
||
/// 列表.
|
||
/// </summary>
|
||
/// <param name="input">请求参数.</param>
|
||
/// <returns></returns>
|
||
[HttpGet("")]
|
||
public async Task<dynamic> GetList([FromQuery] MessageTemplateQuery input)
|
||
{
|
||
var list = await _repository.AsSugarClient().Queryable<MessageSendEntity>()
|
||
.Where(a => a.DeleteMark == null)
|
||
.WhereIF(input.messageSource.IsNotEmptyOrNull(), a => a.MessageSource == input.messageSource)
|
||
.WhereIF(input.templateType.IsNotEmptyOrNull(), a => a.TemplateType == input.templateType)
|
||
.WhereIF(input.enabledMark.IsNotEmptyOrNull(), a => a.EnabledMark == input.enabledMark)
|
||
.WhereIF(input.keyword.IsNotEmptyOrNull(), a => a.FullName.Contains(input.keyword) || a.EnCode.Contains(input.keyword))
|
||
.OrderBy(a => a.SortCode)
|
||
.OrderBy(a => a.CreatorTime, OrderByType.Desc)
|
||
.OrderBy(a => a.LastModifyTime, OrderByType.Desc)
|
||
.Select(a => new SendMessageListOutput
|
||
{
|
||
id = a.Id,
|
||
fullName = a.FullName,
|
||
enCode = a.EnCode,
|
||
templateType = a.TemplateType,
|
||
messageSource = SqlFunc.Subqueryable<MessageDataTypeEntity>().Where(u => u.Type == "4" && u.EnCode == a.MessageSource).Select(u => u.FullName),
|
||
creatorUser = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == a.CreatorUserId).Select(u => SqlFunc.MergeString(u.RealName, "/", u.Account)),
|
||
creatorTime = a.CreatorTime,
|
||
lastModifyTime = a.LastModifyTime,
|
||
sortCode = a.SortCode,
|
||
enabledMark = a.EnabledMark,
|
||
}).ToPagedListAsync(input.currentPage, input.pageSize);
|
||
foreach (var item in list.list)
|
||
{
|
||
item.messageType = await _repository.AsSugarClient()
|
||
.Queryable<MessageSendTemplateEntity, MessageDataTypeEntity>((a, b) => new JoinQueryInfos(JoinType.Left, a.MessageType == b.EnCode && b.Type == "1"))
|
||
.Where((a, b) => a.SendConfigId == item.id && a.DeleteMark == null)
|
||
.Select((a, b) => new MessageTypeModel
|
||
{
|
||
fullName = b.FullName,
|
||
type = a.MessageType,
|
||
}).Distinct().ToListAsync();
|
||
}
|
||
return PageResult<SendMessageListOutput>.SqlSugarPageResult(list);
|
||
}
|
||
|
||
[HttpGet("getSendConfigList")]
|
||
public async Task<dynamic> GetSendList([FromQuery] MessageTemplateQuery input)
|
||
{
|
||
var list = await _repository.AsSugarClient().Queryable<MessageSendEntity>()
|
||
.Where(a => a.DeleteMark == null && a.EnabledMark == 1 && a.TemplateType == "0")
|
||
.WhereIF(input.messageSource.IsNotEmptyOrNull(), a => a.MessageSource == input.messageSource)
|
||
.WhereIF(input.keyword.IsNotEmptyOrNull(), a => a.FullName.Contains(input.keyword) || a.EnCode.Contains(input.keyword))
|
||
.OrderBy(a => a.SortCode)
|
||
.OrderBy(a => a.CreatorTime, OrderByType.Desc)
|
||
.OrderBy(a => a.LastModifyTime, OrderByType.Desc)
|
||
.Select(a => new SendMessageListOutput
|
||
{
|
||
id = a.Id,
|
||
fullName = a.FullName,
|
||
enCode = a.EnCode,
|
||
}).ToPagedListAsync(input.currentPage, input.pageSize);
|
||
foreach (var item in list.list)
|
||
{
|
||
item.templateJson = await SendTest(item.id);
|
||
}
|
||
return PageResult<SendMessageListOutput>.SqlSugarPageResult(list);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 详情.
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
[HttpGet("{id}")]
|
||
public async Task<dynamic> GetInfo(string id)
|
||
{
|
||
var output = (await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null)).Adapt<SendMessageInfoOutput>();
|
||
output.sendConfigTemplateList = await _repository.AsSugarClient().Queryable<MessageSendTemplateEntity, MessageTemplateEntity, MessageAccountEntity>((a, b, c) => new JoinQueryInfos(JoinType.Left, a.TemplateId == b.Id, JoinType.Left, a.AccountConfigId == c.Id))
|
||
.Where(a => a.SendConfigId == id && a.DeleteMark == null)
|
||
.Select((a, b, c) => new SendTemplateModel
|
||
{
|
||
id = a.Id,
|
||
messageType = a.MessageType,
|
||
sendConfigId = a.SendConfigId,
|
||
templateId = a.TemplateId,
|
||
accountConfigId = a.AccountConfigId,
|
||
templateCode = b.EnCode,
|
||
templateName = b.FullName,
|
||
accountCode = c.EnCode,
|
||
accountName = c.FullName,
|
||
enabledMark = a.EnabledMark,
|
||
sortCode = a.SortCode,
|
||
description = a.Description
|
||
}).ToListAsync();
|
||
return output;
|
||
}
|
||
#endregion
|
||
|
||
#region POST
|
||
|
||
/// <summary>
|
||
/// 新建.
|
||
/// </summary>
|
||
/// <param name="input">实体对象.</param>
|
||
/// <returns></returns>
|
||
[HttpPost("")]
|
||
public async Task Create([FromBody] SendMessageInfoOutput input)
|
||
{
|
||
if (await _repository.IsAnyAsync(x => (x.EnCode == input.enCode || x.FullName == input.fullName) && x.DeleteMark == null))
|
||
throw Oops.Oh(ErrorCode.COM1004);
|
||
var entity = input.Adapt<MessageSendEntity>();
|
||
var result = await _repository.AsInsertable(entity).IgnoreColumns(ignoreNullColumn: true).CallEntityMethod(m => m.Creator()).ExecuteReturnEntityAsync();
|
||
if (input.sendConfigTemplateList.Any())
|
||
{
|
||
foreach (var item in input.sendConfigTemplateList)
|
||
{
|
||
var sendTemplateEntity = item.Adapt<MessageSendTemplateEntity>();
|
||
sendTemplateEntity.SendConfigId = result.Id;
|
||
await _repository.AsSugarClient().Insertable(sendTemplateEntity).IgnoreColumns(ignoreNullColumn: true).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
|
||
}
|
||
}
|
||
if (result.IsNullOrEmpty())
|
||
throw Oops.Oh(ErrorCode.COM1000);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 修改.
|
||
/// </summary>
|
||
/// <param name="id">主键值.</param>
|
||
/// <param name="input">实体对象.</param>
|
||
/// <returns></returns>
|
||
[HttpPut("{id}")]
|
||
public async Task Update(string id, [FromBody] SendMessageInfoOutput input)
|
||
{
|
||
if (await _repository.IsAnyAsync(x => x.Id != id && (x.EnCode == input.enCode || x.FullName == input.fullName) && x.DeleteMark == null))
|
||
throw Oops.Oh(ErrorCode.COM1004);
|
||
var entity = input.Adapt<MessageSendEntity>();
|
||
await _repository.AsSugarClient().Deleteable<MessageSendTemplateEntity>(x => x.SendConfigId == id).ExecuteCommandAsync();
|
||
if (input.sendConfigTemplateList.Any())
|
||
{
|
||
foreach (var item in input.sendConfigTemplateList)
|
||
{
|
||
var sendTemplateEntity = item.Adapt<MessageSendTemplateEntity>();
|
||
sendTemplateEntity.SendConfigId = id;
|
||
await _repository.AsSugarClient().Insertable(sendTemplateEntity).IgnoreColumns(ignoreNullColumn: true).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
|
||
}
|
||
}
|
||
var isOk = await _repository.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandHasChangeAsync();
|
||
if (!isOk)
|
||
throw Oops.Oh(ErrorCode.COM1001);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 删除.
|
||
/// </summary>
|
||
/// <param name="id">主键.</param>
|
||
/// <returns></returns>
|
||
[HttpDelete("{id}")]
|
||
public async Task Delete(string id)
|
||
{
|
||
var entity = await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null);
|
||
if (entity == null)
|
||
throw Oops.Oh(ErrorCode.COM1005);
|
||
if (await _repository.AsSugarClient().Queryable<FlowEngineEntity>().AnyAsync(x => x.FlowTemplateJson.Contains(id)))
|
||
throw Oops.Oh(ErrorCode.D1007);
|
||
await _repository.AsSugarClient().Deleteable<MessageSendTemplateEntity>(x => x.SendConfigId == id).ExecuteCommandAsync();
|
||
var isOk = await _repository.AsUpdateable(entity).CallEntityMethod(m => m.Delete()).UpdateColumns(it => new { it.DeleteMark, it.DeleteTime, it.DeleteUserId }).ExecuteCommandHasChangeAsync();
|
||
if (!isOk)
|
||
throw Oops.Oh(ErrorCode.COM1002);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 复制.
|
||
/// </summary>
|
||
/// <param name="id">主键值.</param>
|
||
/// <returns></returns>
|
||
[HttpPost("copy/{id}")]
|
||
public async Task ActionsCopy(string id)
|
||
{
|
||
var entity = await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null);
|
||
var random = RandomExtensions.NextLetterAndNumberString(new Random(), 5).ToLower();
|
||
entity.FullName = string.Format("{0}副本{1}", entity.FullName, random);
|
||
entity.EnCode = string.Format("{0}{1}", entity.EnCode, random);
|
||
entity.Id = SnowflakeIdHelper.NextId();
|
||
entity.EnabledMark = 0;
|
||
entity.TemplateType = "0";
|
||
entity.LastModifyTime = null;
|
||
entity.LastModifyUserId = null;
|
||
if (entity.FullName.Length >= 50 || entity.EnCode.Length >= 50)
|
||
throw Oops.Oh(ErrorCode.COM1009);
|
||
var sendTemplateList = await _repository.AsSugarClient().Queryable<MessageSendTemplateEntity>().Where(x => x.SendConfigId == id && x.DeleteMark == null).ToListAsync();
|
||
foreach (var item in sendTemplateList)
|
||
{
|
||
var sendTemplateEntity = item.Adapt<MessageSendTemplateEntity>();
|
||
sendTemplateEntity.SendConfigId = entity.Id;
|
||
await _repository.AsSugarClient().Insertable(sendTemplateEntity).IgnoreColumns(ignoreNullColumn: true).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
|
||
}
|
||
var isOk = await _repository.AsInsertable(entity).IgnoreColumns(ignoreNullColumn: true).CallEntityMethod(m => m.Create()).ExecuteCommandAsync();
|
||
if (isOk < 1)
|
||
throw Oops.Oh(ErrorCode.COM1008);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 测试发送.
|
||
/// </summary>
|
||
/// <param name="id">主键值.</param>
|
||
/// <returns></returns>
|
||
[HttpPost("getTestConfig/{id}")]
|
||
public async Task<dynamic> SendTest(string id)
|
||
{
|
||
var list = await _repository.AsSugarClient().Queryable<MessageSendTemplateEntity, MessageTemplateEntity>((a, b) => new JoinQueryInfos(JoinType.Left, a.TemplateId == b.Id))
|
||
.Where((a, b) => a.SendConfigId == id && a.DeleteMark == null && b.DeleteMark == null)
|
||
.Select((a, b) => new MessageSendModel
|
||
{
|
||
accountConfigId = a.AccountConfigId,
|
||
id = a.Id,
|
||
messageType = SqlFunc.Subqueryable<MessageDataTypeEntity>().Where(u => u.Type == "1" && u.EnCode == a.MessageType).Select(u => u.FullName),
|
||
msgTemplateName = b.FullName,
|
||
sendConfigId = a.SendConfigId,
|
||
templateId = a.TemplateId,
|
||
}).ToListAsync();
|
||
foreach (var item in list)
|
||
{
|
||
// 是否存在参数.
|
||
var flag = await _repository.AsSugarClient().Queryable<MessageSmsFieldEntity>().AnyAsync(x => x.TemplateId == item.templateId && x.DeleteMark == null);
|
||
if (flag)
|
||
{
|
||
item.paramJson = await _repository.AsSugarClient().Queryable<MessageTemplateParamEntity, MessageTemplateEntity, MessageSmsFieldEntity>((a, b, c) => new JoinQueryInfos(JoinType.Left, a.TemplateId == b.Id, JoinType.Left, a.TemplateId == c.TemplateId))
|
||
.Where((a, b, c) => a.TemplateId == item.templateId && a.DeleteMark == null && b.DeleteMark == null && a.Field == c.Field && a.Field != "@flowLink")
|
||
.Select((a, b) => new MessageSendParam
|
||
{
|
||
field = a.Field,
|
||
fieldName = a.FieldName,
|
||
id = a.Id,
|
||
templateCode = b.TemplateCode,
|
||
templateId = a.TemplateId,
|
||
templateName = b.FullName,
|
||
templateType = b.TemplateType
|
||
}).ToListAsync();
|
||
}
|
||
else
|
||
{
|
||
item.paramJson = await _repository.AsSugarClient().Queryable<MessageTemplateParamEntity, MessageTemplateEntity>((a, b) => new JoinQueryInfos(JoinType.Left, a.TemplateId == b.Id))
|
||
.Where((a, b) => a.TemplateId == item.templateId && a.DeleteMark == null && b.DeleteMark == null && a.Field != "@flowLink")
|
||
.Where((a, b) => b.Title.Contains(a.Field) || b.Content.Contains(a.Field))
|
||
.Select((a, b) => new MessageSendParam
|
||
{
|
||
field = a.Field,
|
||
fieldName = a.FieldName,
|
||
id = a.Id,
|
||
templateCode = b.TemplateCode,
|
||
templateId = a.TemplateId,
|
||
templateName = b.FullName,
|
||
templateType = b.TemplateType
|
||
}).ToListAsync();
|
||
}
|
||
}
|
||
return list;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 测试发送.
|
||
/// </summary>
|
||
/// <param name="id">主键值.</param>
|
||
/// <returns></returns>
|
||
[HttpPost("testSendConfig")]
|
||
public async Task<dynamic> SendTest([FromBody] List<MessageSendModel> input)
|
||
{
|
||
var resultList = new List<object>();
|
||
foreach (var item in input)
|
||
{
|
||
var result = await SendMessage(item, new Dictionary<string, object>());
|
||
if (result.IsNullOrEmpty())
|
||
{
|
||
resultList.Add(new { isSuccess = "1", messageType = string.Format("消息类型:{0}", item.messageType) });
|
||
}
|
||
else
|
||
{
|
||
resultList.Add(new { isSuccess = "0", messageType = string.Format("消息类型:{0}", item.messageType), result = string.Format("发送{0}失败,失败原因:{1}", item.messageType, result) });
|
||
}
|
||
}
|
||
return resultList;
|
||
}
|
||
#endregion
|
||
|
||
#region PublicMethod
|
||
[NonAction]
|
||
public async Task<string> SendMessage(MessageSendModel messageSendModel, Dictionary<string, object> bodyDic)
|
||
{
|
||
var errorList = new List<string>();
|
||
var messageTemplateEntity = await _repository.AsSugarClient().Queryable<MessageTemplateEntity>().FirstAsync(x => x.Id == messageSendModel.templateId && x.DeleteMark == null);
|
||
var messageAccountEntity = await _repository.AsSugarClient().Queryable<MessageAccountEntity>().FirstAsync(x => x.Id == messageSendModel.accountConfigId && x.DeleteMark == null);
|
||
var paramsDic = messageSendModel.paramJson.ToDictionary(x => x.field, y => y.value);//参数
|
||
var title = messageTemplateEntity.Title;
|
||
var content = messageTemplateEntity.Content;
|
||
if (messageTemplateEntity.MessageType=="6")
|
||
{
|
||
try
|
||
{
|
||
messageTemplateEntity.Title = MessageTemplateManage(messageTemplateEntity.Title, paramsDic);
|
||
messageTemplateEntity.Content = MessageTemplateManage(messageTemplateEntity.Content, paramsDic);
|
||
await WebHookSend(messageTemplateEntity, messageAccountEntity);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
|
||
errorList.Add(string.Format("【{0}】", ex.Message));
|
||
}
|
||
var messageMonitorEntity = new MessageMonitorEntity();
|
||
messageMonitorEntity.MessageType = messageTemplateEntity.MessageType;
|
||
messageMonitorEntity.MessageSource = messageTemplateEntity.MessageSource;
|
||
messageMonitorEntity.SendTime = DateTime.Now;
|
||
messageMonitorEntity.MessageTemplateId = messageTemplateEntity.Id;
|
||
messageMonitorEntity.Title = messageTemplateEntity.Title;
|
||
await _repository.AsSugarClient().Insertable(messageMonitorEntity).IgnoreColumns(ignoreNullColumn: true).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
|
||
}
|
||
foreach (var item in messageSendModel.toUser)
|
||
{
|
||
var userId = item.Replace("-delegate", string.Empty);
|
||
var userName = await _usersService.GetUserName(userId);
|
||
try
|
||
{
|
||
if (bodyDic.IsNotEmptyOrNull() && bodyDic.ContainsKey(item))
|
||
{
|
||
var shortLinkEntity = await _shortLinkService.Create(userId, bodyDic[item].ToJsonString());
|
||
var shortLink = string.Format("{0}/dev/api/message/ShortLink/{1}", _messageOptions.DoMainPc, shortLinkEntity.ShortLink);
|
||
paramsDic["@flowLink"] = shortLink;
|
||
}
|
||
messageTemplateEntity.Title = MessageTemplateManage(title, paramsDic);
|
||
messageTemplateEntity.Content = MessageTemplateManage(content, paramsDic);
|
||
switch (messageTemplateEntity.MessageType)
|
||
{
|
||
case "1"://站内信
|
||
await _messageService.SentMessage(new List<string>() { item }, messageTemplateEntity.Title, messageTemplateEntity.Content, bodyDic);
|
||
break;
|
||
case "2"://邮件
|
||
EmailSend(new List<string>() { userId }, messageTemplateEntity, messageAccountEntity);
|
||
break;
|
||
case "3"://短信
|
||
SmsSend(new List<string>() { userId }, messageTemplateEntity, messageAccountEntity, paramsDic);
|
||
break;
|
||
case "4"://钉钉
|
||
var dingIds = await _synThirdInfoService.GetThirdIdList(new List<string>() { userId }, 2, 3);
|
||
if (dingIds.Count > 0)
|
||
{
|
||
var dingMsg = new { msgtype = "text", text = new { content = messageTemplateEntity.Content } }.ToJsonString();
|
||
DingWorkMessageParameter dingWorkMsgModel = new DingWorkMessageParameter()
|
||
{
|
||
toUsers = string.Join(",", dingIds),
|
||
agentId = messageAccountEntity.AgentId,
|
||
msg = dingMsg
|
||
};
|
||
new DingUtil(messageAccountEntity.AppId, messageAccountEntity.AppSecret).SendWorkMsg(dingWorkMsgModel);
|
||
}
|
||
else
|
||
{
|
||
throw Oops.Oh(ErrorCode.D7015);
|
||
}
|
||
break;
|
||
case "5"://企业微信
|
||
var qyIds = await _synThirdInfoService.GetThirdIdList(new List<string>() { userId }, 1, 3);
|
||
var weChat = new WeChatUtil(messageAccountEntity.EnterpriseId, messageAccountEntity.AppSecret);
|
||
if (qyIds.Count > 0)
|
||
{
|
||
await weChat.SendText(messageAccountEntity.AppId, messageTemplateEntity.Content, string.Join(",", qyIds));
|
||
}
|
||
else
|
||
{
|
||
throw Oops.Oh(ErrorCode.D7015);
|
||
}
|
||
break;
|
||
case "7"://微信公众号
|
||
var body = bodyDic.ContainsKey(item) ? bodyDic[item].ToJsonString() : string.Empty;
|
||
WeChatMpSend(userId, messageTemplateEntity, messageAccountEntity, paramsDic, body);
|
||
break;
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
errorList.Add(string.Format("用户{0}【{1}】", userName, ex.Message));
|
||
}
|
||
|
||
#region 消息监控
|
||
var messageMonitorEntity = new MessageMonitorEntity();
|
||
messageMonitorEntity.MessageType = messageTemplateEntity.MessageType;
|
||
messageMonitorEntity.MessageSource = messageTemplateEntity.MessageSource;
|
||
messageMonitorEntity.SendTime = DateTime.Now;
|
||
messageMonitorEntity.MessageTemplateId = messageTemplateEntity.Id;
|
||
messageMonitorEntity.Title = messageTemplateEntity.Title;
|
||
messageMonitorEntity.Content = messageTemplateEntity.Content;
|
||
messageMonitorEntity.ReceiveUser = userId;
|
||
await _repository.AsSugarClient().Insertable(messageMonitorEntity).IgnoreColumns(ignoreNullColumn: true).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
|
||
#endregion
|
||
}
|
||
return errorList.Any() ? string.Join(",", errorList) : string.Empty;
|
||
}
|
||
|
||
public async Task SendMessageDefult(string enCode, List<string> toUser,string creatorUser, string flowName, Dictionary<string, object> bodyDic)
|
||
{
|
||
var msgTemplateEntity= await _repository.AsSugarClient().Queryable<MessageTemplateEntity>().FirstAsync(x => x.EnCode == enCode && x.TemplateType=="1" && x.DeleteMark == null);
|
||
msgTemplateEntity.Title = msgTemplateEntity.Title.Replace("@流程发起人", creatorUser).Replace("@流程名称", flowName);
|
||
msgTemplateEntity.Content = msgTemplateEntity.Content.Replace("@流程发起人", creatorUser).Replace("@流程名称", flowName);
|
||
await _messageService.SentMessage(toUser, msgTemplateEntity.Title, msgTemplateEntity.Content, bodyDic);
|
||
#region 消息监控
|
||
foreach (var item in toUser)
|
||
{
|
||
var userId = item.Replace("-delegate", string.Empty);
|
||
var messageMonitorEntity = new MessageMonitorEntity();
|
||
messageMonitorEntity.MessageType = msgTemplateEntity.MessageType;
|
||
messageMonitorEntity.MessageSource = msgTemplateEntity.MessageSource;
|
||
messageMonitorEntity.SendTime = DateTime.Now;
|
||
messageMonitorEntity.MessageTemplateId = msgTemplateEntity.Id;
|
||
messageMonitorEntity.Title = msgTemplateEntity.Title;
|
||
messageMonitorEntity.Content = msgTemplateEntity.Content;
|
||
messageMonitorEntity.ReceiveUser = item;
|
||
await _repository.AsSugarClient().Insertable(messageMonitorEntity).IgnoreColumns(ignoreNullColumn: true).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
|
||
}
|
||
#endregion
|
||
}
|
||
public async Task SendMessageDelegate(string delegateType, string ToUserId, string flowName)
|
||
{
|
||
var title = string.Format("{0}已{1}您的{2}流程!", _userManager.User.RealName, delegateType, flowName);
|
||
var parameter = new { type = "1" };
|
||
var bodyDic = new Dictionary<string, object>();
|
||
bodyDic.Add(ToUserId, parameter);
|
||
await _messageService.SentMessage(new List<string>() { ToUserId }, title, null, bodyDic, 2, "2");
|
||
}
|
||
public async Task SendMessageSystem(string enCode)
|
||
{
|
||
var msgTemplateEntity = await _repository.AsSugarClient().Queryable<MessageTemplateEntity>().FirstAsync(x => x.EnCode == enCode && x.TemplateType == "1" && x.DeleteMark == null);
|
||
var bodyDic = new Dictionary<string, object>();
|
||
bodyDic.Add(_userManager.UserId, msgTemplateEntity.Content);
|
||
await _messageService.SentMessage(new List<string>() { _userManager.UserId }, msgTemplateEntity.Title, msgTemplateEntity.Content, bodyDic, 3);
|
||
}
|
||
#endregion
|
||
|
||
#region PrivateMethod
|
||
|
||
/// <summary>
|
||
/// 邮箱.
|
||
/// </summary>
|
||
/// <param name="titile"></param>
|
||
/// <param name="userList"></param>
|
||
/// <param name="context"></param>
|
||
/// <param name="sysconfig"></param>
|
||
/// <returns></returns>
|
||
private void EmailSend(List<string> userList, MessageTemplateEntity messageTemplateEntity, MessageAccountEntity messageAccountEntity)
|
||
{
|
||
var emailList = new List<string>();
|
||
foreach (var item in userList)
|
||
{
|
||
var user = _usersService.GetInfoByUserId(item);
|
||
if (user.IsNotEmptyOrNull() && user.Email.IsNotEmptyOrNull())
|
||
{
|
||
emailList.Add(user.Email);
|
||
}
|
||
}
|
||
var mailModel = new MailInfo();
|
||
mailModel.To = string.Join(",", emailList);
|
||
mailModel.Subject = messageTemplateEntity.Title;
|
||
mailModel.BodyText = HttpUtility.HtmlDecode(messageTemplateEntity.Content);
|
||
MailUtil.Send(
|
||
new MailParameterInfo
|
||
{
|
||
AccountName = messageAccountEntity.AddressorName,
|
||
Account = messageAccountEntity.SmtpUser,
|
||
Password = messageAccountEntity.SmtpPassword,
|
||
SMTPHost = messageAccountEntity.SmtpServer,
|
||
SMTPPort = messageAccountEntity.SmtpPort.ParseToInt(),
|
||
Ssl=messageAccountEntity.SslLink.Equals("1")
|
||
}, mailModel);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 短信.
|
||
/// </summary>
|
||
/// <param name="messageTemplateEntity"></param>
|
||
/// <param name="userList"></param>
|
||
/// <param name="parameters"></param>
|
||
/// <param name="sysconfig"></param>
|
||
private void SmsSend(List<string> userList, MessageTemplateEntity messageTemplateEntity, MessageAccountEntity messageAccountEntity, Dictionary<string, string> smsParams)
|
||
{
|
||
var phoneList = new List<string>();//电话号码
|
||
foreach (var item in userList)
|
||
{
|
||
var user = _usersService.GetInfoByUserId(item);
|
||
if (user.IsNotEmptyOrNull() && user.MobilePhone.IsNotEmptyOrNull())
|
||
{
|
||
phoneList.Add("+86" + user.MobilePhone);
|
||
}
|
||
}
|
||
var smsModel = new SmsParameterInfo()
|
||
{
|
||
keyId = messageAccountEntity.AppId,
|
||
keySecret = messageAccountEntity.AppSecret,
|
||
region = messageAccountEntity.ZoneParam,
|
||
domain = messageAccountEntity.Channel.Equals("1") ? messageAccountEntity.EndPoint : messageAccountEntity.ZoneName,
|
||
templateId = messageTemplateEntity.TemplateCode,
|
||
signName = messageAccountEntity.SmsSignature,
|
||
appId = messageAccountEntity.SdkAppId
|
||
};
|
||
var smsFieldList = _repository.AsSugarClient().Queryable<MessageSmsFieldEntity>().Where(x => x.TemplateId == messageTemplateEntity.Id).ToDictionary(x => x.SmsField, y => y.Field);
|
||
foreach (var item in smsFieldList.Keys)
|
||
{
|
||
if (smsParams.Keys.Contains(smsFieldList[item].ToString()))
|
||
{
|
||
smsFieldList[item] = smsParams[smsFieldList[item].ToString()];
|
||
}
|
||
}
|
||
if (messageAccountEntity.Channel.Equals("1"))
|
||
{
|
||
smsModel.mobileAli = string.Join(",", phoneList);
|
||
smsModel.templateParamAli = smsFieldList.ToJsonString();
|
||
SmsUtil.SendSmsByAli(smsModel);
|
||
}
|
||
else
|
||
{
|
||
smsModel.mobileTx = phoneList.ToArray();
|
||
List<string> mList = new List<string>();
|
||
var fields = SmsUtil.GetTemplateByTencent(smsModel);
|
||
foreach (string item in fields)
|
||
{
|
||
if (smsFieldList.ContainsKey(item))
|
||
mList.Add(smsFieldList[item].ToString());
|
||
}
|
||
|
||
smsModel.templateParamTx = mList.ToArray();
|
||
SmsUtil.SendSmsByTencent(smsModel);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// webhook.
|
||
/// </summary>
|
||
/// <param name="messageTemplateEntity"></param>
|
||
/// <param name="messageAccountEntity"></param>
|
||
/// <param name="messageSendModel"></param>
|
||
/// <returns></returns>
|
||
private async Task WebHookSend(MessageTemplateEntity messageTemplateEntity, MessageAccountEntity messageAccountEntity)
|
||
{
|
||
// 钉钉
|
||
if (messageAccountEntity.WebhookType == "1")
|
||
{
|
||
// 认证
|
||
if (messageAccountEntity.ApproveType == "2") SignWebhook(messageAccountEntity);
|
||
new DingUtil().SendGroupMsg(messageAccountEntity.WebhookAddress, messageTemplateEntity.Content);
|
||
}
|
||
// 企业微信
|
||
if (messageAccountEntity.WebhookType == "2")
|
||
{
|
||
var bodyDic = new Dictionary<string, object>();
|
||
bodyDic.Add("msgtype", "text");
|
||
bodyDic.Add("text", new { content = messageTemplateEntity.Content });
|
||
await messageAccountEntity.WebhookAddress.SetBody(bodyDic).PostAsStringAsync();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// webhook签名.
|
||
/// </summary>
|
||
/// <param name="messageAccountEntity"></param>
|
||
private void SignWebhook(MessageAccountEntity messageAccountEntity)
|
||
{
|
||
// webhook加签密钥
|
||
var secret = messageAccountEntity.Bearer;
|
||
|
||
// 获取时间戳
|
||
var timestamp = DateTime.Now.ParseToUnixTime();
|
||
|
||
var signature = string.Empty;
|
||
using (var hmac = new HMACSHA256(secret.ToBase64String().ToBytes()))
|
||
{
|
||
byte[] hashmessage = hmac.ComputeHash(timestamp.ToString().ToBytes(Encoding.UTF8));
|
||
signature = hashmessage.ToHexString();
|
||
}
|
||
|
||
messageAccountEntity.WebhookAddress = string.Format("{0}×tamp={1}&signature={2}", messageAccountEntity.WebhookAddress, timestamp, signature);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 公众号.
|
||
/// </summary>
|
||
/// <param name="userId"></param>
|
||
/// <param name="messageTemplateEntity"></param>
|
||
/// <param name="messageAccountEntity"></param>
|
||
/// <param name="paramDic"></param>
|
||
/// <param name="bodyDic"></param>
|
||
private void WeChatMpSend(string userId, MessageTemplateEntity messageTemplateEntity, MessageAccountEntity messageAccountEntity, Dictionary<string, string> paramDic, string bodyDic)
|
||
{
|
||
var weChatMP = new WeChatMPUtil(messageAccountEntity.AppId, messageAccountEntity.AppSecret);
|
||
var wechatUser = _repository.AsSugarClient().Queryable<MessageWechatUserEntity>().Single(x => userId == x.UserId);
|
||
if (wechatUser == null) throw Oops.Oh(ErrorCode.D7016);
|
||
var openId = wechatUser.IsNotEmptyOrNull() ? wechatUser.OpenId : string.Empty;
|
||
var mpFieldList = _repository.AsSugarClient().Queryable<MessageSmsFieldEntity>().Where(x => x.TemplateId == messageTemplateEntity.Id).ToList();
|
||
var mpTempDic = new Dictionary<string, object>();
|
||
foreach (var item in mpFieldList)
|
||
{
|
||
if (paramDic.Keys.Contains(item.Field))
|
||
{
|
||
mpTempDic[item.SmsField] = new { value = paramDic[item.Field] };
|
||
}
|
||
}
|
||
var url = paramDic.ContainsKey("@flowLink") ? paramDic["@flowLink"] : string.Empty;
|
||
// 跳转小程序
|
||
if (messageTemplateEntity.WxSkip == "1")
|
||
{
|
||
var config = bodyDic.ToBase64String();
|
||
var token = _shortLinkService.CreateToken(userId);
|
||
var miniProgram = new TemplateModel_MiniProgram
|
||
{
|
||
appid = messageTemplateEntity.XcxAppId,
|
||
pagepath = "/pages/workFlow/flowBefore/index?config=" + config + "&token=" + token
|
||
};
|
||
weChatMP.SendTemplateMessage(openId, messageTemplateEntity.TemplateCode, url, mpTempDic, miniProgram);
|
||
}
|
||
else
|
||
{
|
||
weChatMP.SendTemplateMessage(openId, messageTemplateEntity.TemplateCode, url, mpTempDic);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 参数处理.
|
||
/// </summary>
|
||
/// <param name="text"></param>
|
||
/// <param name="paramDic"></param>
|
||
/// <returns></returns>
|
||
private string MessageTemplateManage(string text, Dictionary<string, string> paramDic, bool isGzh = false)
|
||
{
|
||
if (text.IsNotEmptyOrNull())
|
||
{
|
||
// 默认站内信
|
||
if (paramDic.ContainsKey("@flowFullName"))
|
||
{
|
||
text = text.Replace("@流程名称", paramDic["@flowFullName"]);
|
||
}
|
||
if (paramDic.ContainsKey("@launchUserName"))
|
||
{
|
||
text = text.Replace("@流程发起人", paramDic["@launchUserName"]);
|
||
}
|
||
foreach (var item in paramDic.Keys)
|
||
{
|
||
if (isGzh)
|
||
{
|
||
text = text.Replace(item, paramDic[item]);
|
||
}
|
||
else
|
||
{
|
||
text = text.Replace("{" + item + "}", paramDic[item]);
|
||
}
|
||
}
|
||
}
|
||
return text;
|
||
}
|
||
#endregion
|
||
}
|