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; /// /// 发送配置 /// 版 本:V3.2 /// 版 权:拓通智联科技有限公司(http://www.tuotong-tech.com) /// 日 期:2021-06-01. /// [ApiDescriptionSettings(Tag = "Message", Name = "SendMessage", Order = 240)] [Route("api/message/SendMessageConfig")] public class SendMessageService : ISendMessageService, IDynamicApiController, ITransient { private readonly ISqlSugarRepository _repository; private readonly IUsersService _usersService; private readonly IMessageService _messageService; private readonly ISynThirdInfoService _synThirdInfoService; private readonly IShortLinkService _shortLinkService; private readonly MessageOptions _messageOptions = App.GetConfig("Message", true); private readonly IUserManager _userManager; public SendMessageService( ISqlSugarRepository 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 /// /// 列表. /// /// 请求参数. /// [HttpGet("")] public async Task GetList([FromQuery] MessageTemplateQuery input) { var list = await _repository.AsSugarClient().Queryable() .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().Where(u => u.Type == "4" && u.EnCode == a.MessageSource).Select(u => u.FullName), creatorUser = SqlFunc.Subqueryable().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((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.SqlSugarPageResult(list); } [HttpGet("getSendConfigList")] public async Task GetSendList([FromQuery] MessageTemplateQuery input) { var list = await _repository.AsSugarClient().Queryable() .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.SqlSugarPageResult(list); } /// /// 详情. /// /// [HttpGet("{id}")] public async Task GetInfo(string id) { var output = (await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null)).Adapt(); output.sendConfigTemplateList = await _repository.AsSugarClient().Queryable((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 /// /// 新建. /// /// 实体对象. /// [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(); 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(); 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); } /// /// 修改. /// /// 主键值. /// 实体对象. /// [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(); await _repository.AsSugarClient().Deleteable(x => x.SendConfigId == id).ExecuteCommandAsync(); if (input.sendConfigTemplateList.Any()) { foreach (var item in input.sendConfigTemplateList) { var sendTemplateEntity = item.Adapt(); 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); } /// /// 删除. /// /// 主键. /// [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().AnyAsync(x => x.FlowTemplateJson.Contains(id))) throw Oops.Oh(ErrorCode.D1007); await _repository.AsSugarClient().Deleteable(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); } /// /// 复制. /// /// 主键值. /// [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().Where(x => x.SendConfigId == id && x.DeleteMark == null).ToListAsync(); foreach (var item in sendTemplateList) { var sendTemplateEntity = item.Adapt(); 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); } /// /// 测试发送. /// /// 主键值. /// [HttpPost("getTestConfig/{id}")] public async Task SendTest(string id) { var list = await _repository.AsSugarClient().Queryable((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().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().AnyAsync(x => x.TemplateId == item.templateId && x.DeleteMark == null); if (flag) { item.paramJson = await _repository.AsSugarClient().Queryable((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((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; } /// /// 测试发送. /// /// 主键值. /// [HttpPost("testSendConfig")] public async Task SendTest([FromBody] List input) { var resultList = new List(); foreach (var item in input) { var result = await SendMessage(item, new Dictionary()); 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 SendMessage(MessageSendModel messageSendModel, Dictionary bodyDic) { var errorList = new List(); var messageTemplateEntity = await _repository.AsSugarClient().Queryable().FirstAsync(x => x.Id == messageSendModel.templateId && x.DeleteMark == null); var messageAccountEntity = await _repository.AsSugarClient().Queryable().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() { item }, messageTemplateEntity.Title, messageTemplateEntity.Content, bodyDic); break; case "2"://邮件 EmailSend(new List() { userId }, messageTemplateEntity, messageAccountEntity); break; case "3"://短信 SmsSend(new List() { userId }, messageTemplateEntity, messageAccountEntity, paramsDic); break; case "4"://钉钉 var dingIds = await _synThirdInfoService.GetThirdIdList(new List() { 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() { 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 toUser, string creatorUser, string flowName, Dictionary bodyDic) { var msgTemplateEntity = await _repository.AsSugarClient().Queryable().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(); bodyDic.Add(ToUserId, parameter); await _messageService.SentMessage(new List() { ToUserId }, title, null, bodyDic, 2, "2"); } public async Task SendMessageSystem(string enCode) { var msgTemplateEntity = await _repository.AsSugarClient().Queryable().FirstAsync(x => x.EnCode == enCode && x.TemplateType == "1" && x.DeleteMark == null); var bodyDic = new Dictionary(); bodyDic.Add(_userManager.UserId, msgTemplateEntity.Content); await _messageService.SentMessage(new List() { _userManager.UserId }, msgTemplateEntity.Title, msgTemplateEntity.Content, bodyDic, 3); } #endregion #region PrivateMethod /// /// 邮箱. /// /// /// /// /// /// private void EmailSend(List userList, MessageTemplateEntity messageTemplateEntity, MessageAccountEntity messageAccountEntity) { var emailList = new List(); 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); } /// /// 短信. /// /// /// /// /// private void SmsSend(List userList, MessageTemplateEntity messageTemplateEntity, MessageAccountEntity messageAccountEntity, Dictionary smsParams) { var phoneList = new List();//电话号码 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().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 mList = new List(); 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); } } /// /// webhook. /// /// /// /// /// 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(); bodyDic.Add("msgtype", "text"); bodyDic.Add("text", new { content = messageTemplateEntity.Content }); await messageAccountEntity.WebhookAddress.SetBody(bodyDic).PostAsStringAsync(); } } /// /// webhook签名. /// /// 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); } /// /// 公众号. /// /// /// /// /// /// private void WeChatMpSend(string userId, MessageTemplateEntity messageTemplateEntity, MessageAccountEntity messageAccountEntity, Dictionary paramDic, string bodyDic) { var weChatMP = new WeChatMPUtil(messageAccountEntity.AppId, messageAccountEntity.AppSecret); var wechatUser = _repository.AsSugarClient().Queryable().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().Where(x => x.TemplateId == messageTemplateEntity.Id).ToList(); var mpTempDic = new Dictionary(); 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); } } /// /// 参数处理. /// /// /// /// private string MessageTemplateManage(string text, Dictionary 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 }