第一次提交
This commit is contained in:
75
fastbee-notify/fastbee-notify-core/pom.xml
Normal file
75
fastbee-notify/fastbee-notify-core/pom.xml
Normal file
@ -0,0 +1,75 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.fastbee</groupId>
|
||||
<artifactId>fastbee-notify</artifactId>
|
||||
<version>3.8.5</version>
|
||||
</parent>
|
||||
|
||||
<description>通知核心发送模块</description>
|
||||
<artifactId>fastbee-notify-core</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.fastbee</groupId>
|
||||
<artifactId>fastbee-common</artifactId>
|
||||
</dependency>
|
||||
<!-- 通知配置 -->
|
||||
<dependency>
|
||||
<groupId>com.fastbee</groupId>
|
||||
<artifactId>fastbee-notify-web</artifactId>
|
||||
</dependency>
|
||||
<!-- 微信 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fastbee</groupId>
|
||||
<artifactId>fastbee-iot-service</artifactId>
|
||||
</dependency>
|
||||
<!-- 阿里云语音 -->
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>dyvmsapi20170525</artifactId>
|
||||
<version>2.1.4</version>
|
||||
</dependency>
|
||||
<!-- 腾讯云语音 -->
|
||||
<dependency>
|
||||
<groupId>com.tencentcloudapi</groupId>
|
||||
<artifactId>tencentcloud-sdk-java</artifactId>
|
||||
<version>3.1.952</version>
|
||||
</dependency>
|
||||
<!-- 邮箱快捷包 -->
|
||||
<dependency>
|
||||
<groupId>org.dromara.sms4j</groupId>
|
||||
<artifactId>sms4j-Email-core</artifactId>
|
||||
<version>3.1.0</version>
|
||||
</dependency>
|
||||
<!-- 钉钉官方包 -->
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>dingtalk</artifactId>
|
||||
<version>1.1.32</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>alibaba-dingtalk-service-sdk</artifactId>
|
||||
<version>2.0.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -0,0 +1,87 @@
|
||||
package com.fastbee.notify.core.controller;
|
||||
|
||||
import com.fastbee.common.core.domain.AjaxResult;
|
||||
import com.fastbee.notify.core.service.NotifySendService;
|
||||
import com.fastbee.notify.core.vo.SendParams;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author fastb
|
||||
* @version 1.0
|
||||
* @description: 通知控制器
|
||||
* @date 2023-12-15 11:44
|
||||
*/
|
||||
@Api(tags = "通知发送")
|
||||
@RestController
|
||||
@RequestMapping("/notify")
|
||||
public class NotifyController {
|
||||
|
||||
@Resource
|
||||
private NotifySendService notifySendService;
|
||||
|
||||
/**
|
||||
* @description: 通知测试发送接口
|
||||
* @param: sendParams 发送参数
|
||||
* @return: com.fastbee.common.core.domain.AjaxResult
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('notify:template:send')")
|
||||
@PostMapping("/send")
|
||||
@ApiOperation("通知模版测试发送接口")
|
||||
public AjaxResult send(@RequestBody SendParams sendParams){
|
||||
return notifySendService.send(sendParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 短信登录获取验证码
|
||||
* @param: phoneNumber 手机号
|
||||
* @return: com.fastbee.common.core.domain.AjaxResult
|
||||
*/
|
||||
@GetMapping("/smsLoginCaptcha")
|
||||
@ApiOperation("短信登录获取验证码")
|
||||
public AjaxResult smsLoginCaptcha(String phoneNumber){
|
||||
return notifySendService.smsLoginCaptcha(phoneNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业微信验证url有效性
|
||||
* @param msgSignature
|
||||
* @param: timestamp
|
||||
* @param: nonce
|
||||
* @param: echostr
|
||||
* @param: response
|
||||
* @return void
|
||||
*/
|
||||
@ApiOperation("企业微信验证url有效性")
|
||||
@GetMapping("/weComVerifyUrl")
|
||||
public void weComVerifyUrl(@RequestParam(value = "msg_signature") String msgSignature,
|
||||
@RequestParam(value = "timestamp") String timestamp,
|
||||
@RequestParam(value = "nonce") String nonce,
|
||||
@RequestParam(value = "echostr") String echostr,
|
||||
HttpServletResponse response) {
|
||||
String msg = notifySendService.weComVerifyUrl(msgSignature, timestamp, nonce, echostr);
|
||||
try {
|
||||
response.getWriter().print(msg);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 短信注册获取验证码
|
||||
* @param: phoneNumber 手机号
|
||||
* @return: com.fastbee.common.core.domain.AjaxResult
|
||||
*/
|
||||
@GetMapping("/smsRegisterCaptcha")
|
||||
@ApiOperation("短信登录获取验证码")
|
||||
public AjaxResult smsRegisterCaptcha(String phoneNumber){
|
||||
return notifySendService.smsRegisterCaptcha(phoneNumber);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.fastbee.notify.core.dingtalk.service;
|
||||
|
||||
import com.fastbee.common.core.notify.NotifySendResponse;
|
||||
import com.fastbee.notify.vo.NotifyVO;
|
||||
|
||||
/**
|
||||
* 钉钉通知服务类
|
||||
* @author fastb
|
||||
* @date 2024-01-12 17:57
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface DingTalkService {
|
||||
|
||||
/**
|
||||
* 钉钉统一发送方法
|
||||
* @param notifyVO 通知参数
|
||||
* @return com.fastbee.common.core.notify.NotifySendResponse
|
||||
*/
|
||||
NotifySendResponse send(NotifyVO notifyVO);
|
||||
|
||||
}
|
@ -0,0 +1,225 @@
|
||||
package com.fastbee.notify.core.dingtalk.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.aliyun.dingtalkoauth2_1_0.Client;
|
||||
import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest;
|
||||
import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenResponse;
|
||||
import com.aliyun.tea.TeaException;
|
||||
import com.aliyun.teaopenapi.models.Config;
|
||||
import com.aliyun.teautil.Common;
|
||||
import com.dingtalk.api.DefaultDingTalkClient;
|
||||
import com.dingtalk.api.DingTalkClient;
|
||||
import com.dingtalk.api.request.OapiMessageCorpconversationAsyncsendV2Request;
|
||||
import com.dingtalk.api.request.OapiRobotSendRequest;
|
||||
import com.dingtalk.api.response.OapiMessageCorpconversationAsyncsendV2Response;
|
||||
import com.dingtalk.api.response.OapiRobotSendResponse;
|
||||
import com.fastbee.common.core.notify.NotifySendResponse;
|
||||
import com.fastbee.common.core.notify.config.DingTalkConfigParams;
|
||||
import com.fastbee.common.core.notify.msg.DingTalkMsgParams;
|
||||
import com.fastbee.common.enums.NotifyChannelProviderEnum;
|
||||
import com.fastbee.common.utils.StringUtils;
|
||||
import com.fastbee.notify.core.dingtalk.service.DingTalkService;
|
||||
import com.fastbee.notify.domain.NotifyChannel;
|
||||
import com.fastbee.notify.domain.NotifyTemplate;
|
||||
import com.fastbee.notify.vo.NotifyVO;
|
||||
import com.taobao.api.ApiException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author fastb
|
||||
* @version 1.0
|
||||
* @description: 钉钉通知服务类
|
||||
* @date 2024-01-12 17:58
|
||||
*/
|
||||
@Service
|
||||
public class DingTalkServiceImpl implements DingTalkService {
|
||||
|
||||
|
||||
@Override
|
||||
public NotifySendResponse send(NotifyVO notifyVO) {
|
||||
NotifySendResponse notifySendResponse = new NotifySendResponse();
|
||||
NotifyChannel notifyChannel = notifyVO.getNotifyChannel();
|
||||
NotifyTemplate notifyTemplate = notifyVO.getNotifyTemplate();
|
||||
String content = JSONObject.parseObject(notifyTemplate.getMsgParams()).get("content").toString();
|
||||
String sendContent = StringUtils.strReplaceVariable("${", "}", content, notifyVO.getMap());
|
||||
DingTalkMsgParams dingTalkMsgParams = JSONObject.parseObject(notifyTemplate.getMsgParams(), DingTalkMsgParams.class);
|
||||
// 获取AppKey和AppSecret
|
||||
DingTalkConfigParams dingTalkConfigParams = JSONObject.parseObject(notifyChannel.getConfigContent(), DingTalkConfigParams.class);
|
||||
if (NotifyChannelProviderEnum.DING_TALK_WORK.equals(notifyVO.getNotifyChannelProviderEnum())) {
|
||||
notifySendResponse = this.workSend(dingTalkConfigParams, dingTalkMsgParams, notifyVO.getSendAccount(), sendContent);
|
||||
} else if (NotifyChannelProviderEnum.DING_TALK_GROUP_ROBOT.equals(notifyVO.getNotifyChannelProviderEnum())) {
|
||||
notifySendResponse = this.customizeRobotSend(dingTalkConfigParams, dingTalkMsgParams, sendContent);
|
||||
}
|
||||
return notifySendResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义机器人发送
|
||||
* @param dingTalkConfigParams 渠道配置参数
|
||||
* @param: dingTalkMsgParams 模版配置参数
|
||||
* @param: sendContent 发送内容
|
||||
* @return com.fastbee.common.core.notify.NotifySendResponse
|
||||
*/
|
||||
private NotifySendResponse customizeRobotSend(DingTalkConfigParams dingTalkConfigParams, DingTalkMsgParams dingTalkMsgParams, String sendContent) {
|
||||
NotifySendResponse notifySendResponse = new NotifySendResponse();
|
||||
DefaultDingTalkClient client = new DefaultDingTalkClient(dingTalkConfigParams.getWebHook());
|
||||
OapiRobotSendRequest request = this.createOapiRobotMsg(dingTalkMsgParams, sendContent);
|
||||
try {
|
||||
OapiRobotSendResponse execute = client.execute(request);
|
||||
notifySendResponse.setStatus("0".equals(execute.getErrorCode()) ? 1 : 0);
|
||||
notifySendResponse.setResultContent(JSON.toJSONString(execute));
|
||||
} catch (ApiException e) {
|
||||
notifySendResponse.setStatus(0);
|
||||
notifySendResponse.setResultContent(e.toString());
|
||||
}
|
||||
return notifySendResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* 工作通知发送
|
||||
* @param dingTalkConfigParams 渠道配置参数
|
||||
* @param: dingTalkMsgParams 模版配置参数
|
||||
* @param: sendAccount 发送账号,多个以,隔开
|
||||
* @param: sendContent 发送内容
|
||||
* @return com.fastbee.common.core.notify.NotifySendResponse
|
||||
*/
|
||||
private NotifySendResponse workSend(DingTalkConfigParams dingTalkConfigParams, DingTalkMsgParams dingTalkMsgParams, String sendAccount, String sendContent) {
|
||||
NotifySendResponse notifySendResponse = new NotifySendResponse();
|
||||
notifySendResponse.setSendContent(sendContent);
|
||||
notifySendResponse.setStatus(1);
|
||||
// 发送
|
||||
try {
|
||||
// 获取应用访问凭证accessToken
|
||||
Config config = new Config();
|
||||
config.protocol = "https";
|
||||
config.regionId = "central";
|
||||
Client client = new Client(config);
|
||||
GetAccessTokenRequest accessTokenRequest = new GetAccessTokenRequest();
|
||||
accessTokenRequest.setAppKey(dingTalkConfigParams.getAppKey());
|
||||
accessTokenRequest.setAppSecret(dingTalkConfigParams.getAppSecret());
|
||||
GetAccessTokenResponse accessTokenResponse = client.getAccessToken(accessTokenRequest);
|
||||
String accessToken = accessTokenResponse.getBody().getAccessToken();
|
||||
DingTalkClient dingTalkClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");
|
||||
OapiMessageCorpconversationAsyncsendV2Request req = new OapiMessageCorpconversationAsyncsendV2Request();
|
||||
req.setAgentId(Long.valueOf(dingTalkConfigParams.getAgentId()));
|
||||
// 优先取发送账号、然后是部门、然后是所有人
|
||||
if (StringUtils.isNotEmpty(sendAccount)) {
|
||||
// 根据手机号获取钉钉userid
|
||||
// DingTalkClient dingTalkClientUser = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/getbymobile");
|
||||
// OapiV2UserGetbymobileRequest phoneReq = new OapiV2UserGetbymobileRequest();
|
||||
// phoneReq.setMobile(sendAccount);
|
||||
// OapiV2UserGetbymobileResponse rsp = dingTalkClientUser.execute(phoneReq, accessToken);
|
||||
// userId = rsp.getResult().getUserid();
|
||||
req.setUseridList(sendAccount);
|
||||
} else if (StringUtils.isNotEmpty(dingTalkMsgParams.getDeptId())) {
|
||||
req.setDeptIdList(dingTalkMsgParams.getDeptId());
|
||||
notifySendResponse.setOtherSendAccount(dingTalkMsgParams.getDeptId());
|
||||
} else if (Boolean.TRUE.toString().equals(dingTalkMsgParams.getSendAllEnable())) {
|
||||
req.setToAllUser(Boolean.TRUE);
|
||||
notifySendResponse.setOtherSendAccount("allUser");
|
||||
}
|
||||
OapiMessageCorpconversationAsyncsendV2Request.Msg msg = this.createOapiMessageMsg(dingTalkMsgParams, sendContent);
|
||||
req.setMsg(msg);
|
||||
OapiMessageCorpconversationAsyncsendV2Response rsp = dingTalkClient.execute(req, accessToken);
|
||||
notifySendResponse.setStatus(0 == rsp.getErrcode() ? 1 : 0);
|
||||
notifySendResponse.setResultContent(JSON.toJSONString(rsp));
|
||||
} catch (Exception e) {
|
||||
notifySendResponse.setStatus(0);
|
||||
notifySendResponse.setResultContent(e.toString());
|
||||
}
|
||||
return notifySendResponse;
|
||||
}
|
||||
|
||||
private OapiRobotSendRequest createOapiRobotMsg(DingTalkMsgParams dingTalkMsgParams, String sendContent) {
|
||||
OapiRobotSendRequest request = new OapiRobotSendRequest();
|
||||
request.setMsgtype(dingTalkMsgParams.getMsgType());
|
||||
switch (request.getMsgtype()) {
|
||||
case "text":
|
||||
OapiRobotSendRequest.Text text = new OapiRobotSendRequest.Text();
|
||||
text.setContent(sendContent);
|
||||
request.setText(text);
|
||||
break;
|
||||
case "link":
|
||||
OapiRobotSendRequest.Link link = new OapiRobotSendRequest.Link();
|
||||
link.setTitle(dingTalkMsgParams.getTitle());
|
||||
link.setText(sendContent);
|
||||
link.setMessageUrl(dingTalkMsgParams.getMessageUrl());
|
||||
link.setPicUrl(dingTalkMsgParams.getPicUrl());
|
||||
request.setLink(link);
|
||||
break;
|
||||
case "markdown":
|
||||
OapiRobotSendRequest.Markdown markdown = new OapiRobotSendRequest.Markdown();
|
||||
markdown.setText(sendContent);
|
||||
markdown.setTitle(dingTalkMsgParams.getTitle());
|
||||
request.setMarkdown(markdown);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建钉钉发送消息
|
||||
* @param msgParams 消息参数
|
||||
* @return
|
||||
*/
|
||||
private OapiMessageCorpconversationAsyncsendV2Request.Msg createOapiMessageMsg(DingTalkMsgParams msgParams, String content) {
|
||||
OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
|
||||
msg.setMsgtype(msgParams.getMsgType());
|
||||
switch (msg.getMsgtype()) {
|
||||
case "text":
|
||||
msg.setText(new OapiMessageCorpconversationAsyncsendV2Request.Text());
|
||||
msg.getText().setContent(content);
|
||||
break;
|
||||
case "link":
|
||||
msg.setLink(new OapiMessageCorpconversationAsyncsendV2Request.Link());
|
||||
msg.getLink().setTitle(msgParams.getTitle());
|
||||
msg.getLink().setText(content);
|
||||
msg.getLink().setMessageUrl(msgParams.getMessageUrl());
|
||||
msg.getLink().setPicUrl(msgParams.getPicUrl());
|
||||
break;
|
||||
case "markdown":
|
||||
msg.setMarkdown(new OapiMessageCorpconversationAsyncsendV2Request.Markdown());
|
||||
msg.getMarkdown().setText(content);
|
||||
msg.getMarkdown().setTitle(msgParams.getTitle());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取AccessToken
|
||||
* @param appKey
|
||||
* @param: appSecret
|
||||
* @return java.lang.String
|
||||
*/
|
||||
private String getAccessToken(String appKey, String appSecret) {
|
||||
try {
|
||||
Config config = new Config();
|
||||
config.protocol = "https";
|
||||
config.regionId = "central";
|
||||
Client client = new Client(config);
|
||||
GetAccessTokenRequest accessTokenRequest = new GetAccessTokenRequest();
|
||||
accessTokenRequest.setAppKey(appKey);
|
||||
accessTokenRequest.setAppSecret(appSecret);
|
||||
GetAccessTokenResponse accessToken = client.getAccessToken(accessTokenRequest);
|
||||
return accessToken.getBody().getAccessToken();
|
||||
} catch (TeaException err) {
|
||||
if (!Common.empty(err.code) && !Common.empty(err.message)) {
|
||||
// err 中含有 code 和 message 属性,可帮助开发定位问题
|
||||
}
|
||||
} catch (Exception _err) {
|
||||
TeaException err = new TeaException(_err.getMessage(), _err);
|
||||
if (!Common.empty(err.code) && !Common.empty(err.message)) {
|
||||
// err 中含有 code 和 message 属性,可帮助开发定位问题
|
||||
}
|
||||
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.fastbee.notify.core.email.config;
|
||||
|
||||
import com.fastbee.common.core.notify.config.EmailConfigParams;
|
||||
import org.dromara.email.api.MailClient;
|
||||
import org.dromara.email.comm.config.MailSmtpConfig;
|
||||
import org.dromara.email.core.factory.MailFactory;
|
||||
|
||||
/**
|
||||
* @author fastb
|
||||
* @version 1.0
|
||||
* @description: 邮箱获取发送配置类
|
||||
* @date 2023-12-20 10:23
|
||||
*/
|
||||
public class EmailNotifyConfig {
|
||||
|
||||
public static MailClient create(String mailClientKey, EmailConfigParams emailNotifyConfig) {
|
||||
MailSmtpConfig config = MailSmtpConfig.builder()
|
||||
.smtpServer(emailNotifyConfig.getSmtpServer())
|
||||
.port(emailNotifyConfig.getPort())
|
||||
.fromAddress(emailNotifyConfig.getUsername())
|
||||
.username(emailNotifyConfig.getUsername())
|
||||
.password(emailNotifyConfig.getPassword())
|
||||
.isSSL(emailNotifyConfig.getSslEnable().toString())
|
||||
.isAuth(emailNotifyConfig.getAuthEnable().toString())
|
||||
.retryInterval(emailNotifyConfig.getRetryInterval())
|
||||
.maxRetries(emailNotifyConfig.getMaxRetries())
|
||||
.build();
|
||||
MailFactory.put(mailClientKey, config);
|
||||
return MailFactory.createMailClient(mailClientKey);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.fastbee.notify.core.email.service;
|
||||
|
||||
import com.fastbee.common.core.notify.NotifySendResponse;
|
||||
import com.fastbee.notify.vo.NotifyVO;
|
||||
|
||||
/**
|
||||
* @description: 邮箱发送业务类
|
||||
* @author fastb
|
||||
* @date 2023-12-29 16:20
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface EmailService {
|
||||
|
||||
/**
|
||||
* @description: 邮件简要内容发送
|
||||
* @param: notifyVO 发送VO类
|
||||
* @return: void
|
||||
*/
|
||||
NotifySendResponse send(NotifyVO notifyVO);
|
||||
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
package com.fastbee.notify.core.email.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.fastbee.common.core.notify.NotifySendResponse;
|
||||
import com.fastbee.common.core.notify.config.EmailConfigParams;
|
||||
import com.fastbee.common.core.notify.msg.EmailMsgParams;
|
||||
import com.fastbee.common.utils.StringUtils;
|
||||
import com.fastbee.notify.core.email.config.EmailNotifyConfig;
|
||||
import com.fastbee.notify.core.email.service.EmailService;
|
||||
import com.fastbee.notify.domain.NotifyChannel;
|
||||
import com.fastbee.notify.domain.NotifyTemplate;
|
||||
import com.fastbee.notify.vo.NotifyVO;
|
||||
import org.dromara.email.api.MailClient;
|
||||
import org.dromara.email.comm.entity.MailMessage;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author fastb
|
||||
* @version 1.0
|
||||
* @description: 邮箱发送业务类
|
||||
* @date 2023-12-20 10:21
|
||||
*/
|
||||
@Service
|
||||
public class EmailServiceImpl implements EmailService {
|
||||
|
||||
|
||||
public MailClient createMailClient(NotifyChannel notifyChannel, NotifyTemplate notifyTemplate) {
|
||||
// 构建邮箱配置对象,key为 provider_id
|
||||
String mailClientKey = notifyChannel.getProvider() + "_" + notifyTemplate.getId();
|
||||
EmailConfigParams emailNotifyConfig = JSONObject.parseObject(notifyChannel.getConfigContent(), EmailConfigParams.class);
|
||||
return EmailNotifyConfig.create(mailClientKey, emailNotifyConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NotifySendResponse send(NotifyVO notifyVO) {
|
||||
NotifySendResponse notifySendResponse = new NotifySendResponse();
|
||||
if (StringUtils.isEmpty(notifyVO.getSendAccount())) {
|
||||
notifySendResponse.setStatus(0);
|
||||
notifySendResponse.setResultContent("发送邮箱号为空,请先配置发送邮箱号!");
|
||||
return notifySendResponse;
|
||||
}
|
||||
MailClient mailClient;
|
||||
try {
|
||||
mailClient = this.createMailClient(notifyVO.getNotifyChannel(), notifyVO.getNotifyTemplate());
|
||||
} catch (Exception e) {
|
||||
notifySendResponse.setStatus(0);
|
||||
notifySendResponse.setResultContent("获取邮箱发送类失败," + e);
|
||||
return notifySendResponse;
|
||||
}
|
||||
NotifyTemplate notifyTemplate = notifyVO.getNotifyTemplate();
|
||||
EmailMsgParams emailMsgParams = JSONObject.parseObject(notifyTemplate.getMsgParams(), EmailMsgParams.class);
|
||||
// 目前附件就支持一个
|
||||
Map<String, String> filesMap = new HashMap<>(2);
|
||||
if (StringUtils.isNotEmpty(emailMsgParams.getAttachment())) {
|
||||
String fileName = emailMsgParams.getAttachment().substring(emailMsgParams.getAttachment().lastIndexOf("/"));
|
||||
filesMap.put(fileName, emailMsgParams.getAttachment());
|
||||
}
|
||||
// 多个邮箱以,分隔
|
||||
List<String> mailList = StringUtils.str2List(notifyVO.getSendAccount(), ",", true, true);
|
||||
MailMessage mailMessage = MailMessage.Builder()
|
||||
.mailAddress(mailList)
|
||||
.title(emailMsgParams.getTitle())
|
||||
.html(new ByteArrayInputStream(emailMsgParams.getContent().getBytes()))
|
||||
.htmlValues(notifyVO.getMap())
|
||||
.files(filesMap)
|
||||
.build();
|
||||
try {
|
||||
mailClient.send(mailMessage);
|
||||
} catch (Exception e) {
|
||||
notifySendResponse.setStatus(0);
|
||||
notifySendResponse.setResultContent("邮箱发送失败," + e);
|
||||
return notifySendResponse;
|
||||
}
|
||||
String sendContent = StringUtils.strReplaceVariable("#{", "}", emailMsgParams.getContent(), notifyVO.getMap());
|
||||
notifySendResponse.setSendContent(sendContent);
|
||||
notifySendResponse.setStatus(1);
|
||||
return notifySendResponse;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
package com.fastbee.notify.core.service;
|
||||
|
||||
import com.fastbee.common.core.domain.AjaxResult;
|
||||
import com.fastbee.common.core.notify.AlertPushParams;
|
||||
import com.fastbee.notify.core.vo.SendParams;
|
||||
import com.fastbee.notify.vo.NotifyVO;
|
||||
|
||||
/**
|
||||
* @description: 所有通知发送入口
|
||||
* 以后有通知业务可写在这里
|
||||
* @author fastb
|
||||
* @date 2023-12-26 15:47
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface NotifySendService {
|
||||
|
||||
/**
|
||||
* @description: 通知测试发送接口
|
||||
* @param: sendParams
|
||||
* @return: void
|
||||
*/
|
||||
AjaxResult send(SendParams sendParams);
|
||||
|
||||
/**
|
||||
* @description: 通知统一发送方法
|
||||
* @param: notifyVO 通知发送参数VO
|
||||
* @return: void
|
||||
*/
|
||||
AjaxResult notifySend(NotifyVO notifyVO);
|
||||
|
||||
/**
|
||||
* 告警通知统一推送
|
||||
* @param alertPushParams 告警推送参数
|
||||
* @return void
|
||||
*/
|
||||
void alertSend(AlertPushParams alertPushParams);
|
||||
|
||||
/**
|
||||
* @description: 发送短信验证码
|
||||
* @author fastb
|
||||
* @date 2023-12-26 15:49
|
||||
* @version 1.0
|
||||
*/
|
||||
void sendCaptchaSms(String phone, String captcha);
|
||||
|
||||
/**
|
||||
* @description: 根据业务编码、渠道、服务商获取唯一启用通知配置信息
|
||||
* @param serviceCode 业务编码,一定传
|
||||
* @param channelType 渠道类型 一定传
|
||||
* @param provider 钉钉和微信渠道 一定传
|
||||
* @author fastb
|
||||
* @date 2024-01-02 11:13
|
||||
*/
|
||||
NotifyVO selectOnlyEnable(String serviceCode, String channelType, String provider, Long tenantId);
|
||||
|
||||
/**
|
||||
* @description: 短信登录获取验证码
|
||||
* @param: phoneNumber
|
||||
* @return: com.fastbee.common.core.domain.AjaxResult
|
||||
*/
|
||||
AjaxResult smsLoginCaptcha(String phoneNumber);
|
||||
|
||||
/**
|
||||
* 企业微信验证url有效性
|
||||
* @param msgSignature
|
||||
* @param: timestamp
|
||||
* @param: nonce
|
||||
* @param: echostr
|
||||
* @param: response
|
||||
* @return void
|
||||
*/
|
||||
String weComVerifyUrl(String msgSignature, String timestamp, String nonce, String echostr);
|
||||
|
||||
/**
|
||||
* @description: 短信注册获取验证码
|
||||
* @param: phoneNumber 手机号
|
||||
* @return: com.fastbee.common.core.domain.AjaxResult
|
||||
*/
|
||||
AjaxResult smsRegisterCaptcha(String phoneNumber);
|
||||
}
|
@ -0,0 +1,333 @@
|
||||
package com.fastbee.notify.core.service.impl;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.fastbee.common.constant.CacheConstants;
|
||||
import com.fastbee.common.core.domain.AjaxResult;
|
||||
import com.fastbee.common.core.notify.AlertPushParams;
|
||||
import com.fastbee.common.core.notify.NotifySendResponse;
|
||||
import com.fastbee.common.core.redis.RedisCache;
|
||||
import com.fastbee.common.enums.NotifyChannelEnum;
|
||||
import com.fastbee.common.enums.NotifyChannelProviderEnum;
|
||||
import com.fastbee.common.enums.NotifyServiceCodeEnum;
|
||||
import com.fastbee.common.exception.ServiceException;
|
||||
import com.fastbee.common.utils.StringUtils;
|
||||
import com.fastbee.common.utils.ValidationUtils;
|
||||
import com.fastbee.common.utils.VerifyCodeUtils;
|
||||
import com.fastbee.common.utils.wechat.AesException;
|
||||
import com.fastbee.common.utils.wechat.WXBizMsgCrypt;
|
||||
import com.fastbee.notify.core.dingtalk.service.DingTalkService;
|
||||
import com.fastbee.notify.core.email.service.EmailService;
|
||||
import com.fastbee.notify.core.service.NotifySendService;
|
||||
import com.fastbee.notify.core.sms.service.ISmsService;
|
||||
import com.fastbee.notify.core.vo.SendParams;
|
||||
import com.fastbee.notify.core.voice.service.VoiceService;
|
||||
import com.fastbee.notify.core.wechat.service.WeChatPushService;
|
||||
import com.fastbee.notify.domain.NotifyChannel;
|
||||
import com.fastbee.notify.domain.NotifyLog;
|
||||
import com.fastbee.notify.domain.NotifyTemplate;
|
||||
import com.fastbee.notify.service.INotifyChannelService;
|
||||
import com.fastbee.notify.service.INotifyLogService;
|
||||
import com.fastbee.notify.service.INotifyTemplateService;
|
||||
import com.fastbee.notify.vo.NotifyVO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.checkerframework.checker.units.qual.C;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author fastb
|
||||
* @version 1.0
|
||||
* @description: 通知业务类
|
||||
* @date 2023-12-26 10:38
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class NotifySendServiceImpl implements NotifySendService {
|
||||
|
||||
@Resource
|
||||
private INotifyChannelService notifyChannelService;
|
||||
@Resource
|
||||
private INotifyTemplateService notifyTemplateService;
|
||||
@Resource
|
||||
private INotifyLogService notifyLogService;
|
||||
@Resource
|
||||
private ISmsService smsService;
|
||||
@Resource
|
||||
private VoiceService voiceService;
|
||||
@Resource
|
||||
private EmailService emailService;
|
||||
@Resource
|
||||
private WeChatPushService weChatPushService;
|
||||
@Resource
|
||||
private RedisCache redisCache;
|
||||
@Resource
|
||||
private DingTalkService dingTalkService;
|
||||
|
||||
@Override
|
||||
public AjaxResult send(SendParams sendParams) {
|
||||
// 获取配置参数
|
||||
NotifyTemplate notifyTemplate = notifyTemplateService.selectNotifyTemplateById(sendParams.getId());
|
||||
NotifyChannel notifyChannel = notifyChannelService.selectNotifyChannelById(notifyTemplate.getChannelId());
|
||||
LinkedHashMap<String,String> map = new LinkedHashMap<>();
|
||||
if (StringUtils.isNotEmpty(sendParams.getVariables())) {
|
||||
map = JSONObject.parseObject(sendParams.getVariables(), LinkedHashMap.class);
|
||||
}
|
||||
NotifyChannelProviderEnum notifyChannelProviderEnum = NotifyChannelProviderEnum.getByChannelTypeAndProvider(notifyChannel.getChannelType(), notifyChannel.getProvider());
|
||||
NotifyVO notifyVO = new NotifyVO();
|
||||
notifyVO.setNotifyChannel(notifyChannel).setNotifyTemplate(notifyTemplate)
|
||||
.setSendAccount(sendParams.getSendAccount()).setMap(map).setNotifyChannelProviderEnum(notifyChannelProviderEnum);
|
||||
return this.notifySend(notifyVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AjaxResult notifySend(NotifyVO notifyVO) {
|
||||
// 获取发送参数
|
||||
NotifyChannel notifyChannel = notifyVO.getNotifyChannel();
|
||||
NotifyTemplate notifyTemplate = notifyVO.getNotifyTemplate();
|
||||
String sendAccount = notifyVO.getSendAccount();
|
||||
if (StringUtils.isNotEmpty(notifyVO.getSendAccount())) {
|
||||
String s = notifyVO.getSendAccount().replaceAll(",", ",");
|
||||
sendAccount = s;
|
||||
notifyVO.setSendAccount(s);
|
||||
}
|
||||
NotifyChannelEnum notifyChannelEnum = NotifyChannelEnum.getNotifyChannelEnum(notifyChannel.getChannelType());
|
||||
// 组装模板内容参数,发送通知
|
||||
NotifySendResponse notifySendResponse = new NotifySendResponse();
|
||||
switch (Objects.requireNonNull(notifyChannelEnum)) {
|
||||
case SMS:
|
||||
notifySendResponse = smsService.send(notifyVO);
|
||||
break;
|
||||
case EMAIL:
|
||||
notifySendResponse = emailService.send(notifyVO);
|
||||
break;
|
||||
case VOICE:
|
||||
notifySendResponse = voiceService.send(notifyVO);
|
||||
break;
|
||||
case WECHAT:
|
||||
notifySendResponse = weChatPushService.send(notifyVO);
|
||||
break;
|
||||
case DING_TALK:
|
||||
notifySendResponse = dingTalkService.send(notifyVO);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// 保存日志
|
||||
NotifyLog notifyLog = new NotifyLog();
|
||||
notifyLog.setChannelId(notifyChannel.getId()).setNotifyTemplateId(notifyTemplate.getId())
|
||||
.setSendAccount(StringUtils.isNotEmpty(notifySendResponse.getOtherSendAccount()) ? notifySendResponse.getOtherSendAccount() : sendAccount)
|
||||
.setServiceCode(notifyTemplate.getServiceCode())
|
||||
.setMsgContent(notifySendResponse.getSendContent())
|
||||
.setSendStatus(notifySendResponse.getStatus()).setResultContent(notifySendResponse.getResultContent())
|
||||
.setTenantId(notifyTemplate.getTenantId()).setTenantName(notifyTemplate.getTenantName());
|
||||
notifyLogService.insertNotifyLog(notifyLog);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void alertSend(AlertPushParams alertPushParams) {
|
||||
// 获取发送模版
|
||||
NotifyTemplate notifyTemplate = notifyTemplateService.selectNotifyTemplateById(alertPushParams.getNotifyTemplateId());
|
||||
if (Objects.isNull(notifyTemplate) || 0 == notifyTemplate.getStatus()) {
|
||||
log.info("告警关联通知模版未启用,模版编号:{}", alertPushParams.getNotifyTemplateId());
|
||||
return;
|
||||
}
|
||||
NotifyChannel notifyChannel = notifyChannelService.selectNotifyChannelById(notifyTemplate.getChannelId());
|
||||
NotifyChannelProviderEnum notifyChannelProviderEnum = NotifyChannelProviderEnum.getByChannelTypeAndProvider(notifyChannel.getChannelType(), notifyChannel.getProvider());
|
||||
NotifyVO notifyVO = new NotifyVO();
|
||||
notifyVO.setNotifyChannel(notifyChannel).setNotifyTemplate(notifyTemplate).setNotifyChannelProviderEnum(notifyChannelProviderEnum);
|
||||
// 获取模版参数
|
||||
JSONObject jsonMsgParams = JSONObject.parseObject(notifyVO.getNotifyTemplate().getMsgParams());
|
||||
String content = jsonMsgParams.get("content").toString();
|
||||
List<String> variables = notifyTemplateService.listVariables(content, notifyChannelProviderEnum);
|
||||
// 获取模版变量
|
||||
assert notifyChannelProviderEnum != null;
|
||||
NotifyChannelEnum notifyChannelEnum = NotifyChannelEnum.getNotifyChannelEnum(notifyChannelProviderEnum.getChannelType());
|
||||
LinkedHashMap<String, String> map = new LinkedHashMap<>();
|
||||
switch (Objects.requireNonNull(notifyChannelEnum)) {
|
||||
// 示例内容变量顺序:您的设备:${name},设备编号:${serialnumber},在${address}发生${alert}告警; 可自行修改
|
||||
case SMS:
|
||||
case EMAIL:
|
||||
case WECHAT:
|
||||
case DING_TALK:
|
||||
// 按顺序依次替换变量信息
|
||||
for (int i = 0; i < variables.size(); i++) {
|
||||
if (i == 0) {
|
||||
map.put(variables.get(i), alertPushParams.getDeviceName());
|
||||
} else if (i == 1) {
|
||||
map.put(variables.get(i), alertPushParams.getSerialNumber());
|
||||
} else if (i == 2) {
|
||||
map.put(variables.get(i), alertPushParams.getAddress());
|
||||
} else {
|
||||
map.put(variables.get(i), alertPushParams.getAlertName());
|
||||
}
|
||||
}
|
||||
break;
|
||||
// 示例内容变量顺序:您的设备:${name},在${address}发生告警,请尽快处理;
|
||||
// 阿里云语音模版只支持两个变量,所有语音统一使用两个变量,可自行修改
|
||||
case VOICE:
|
||||
// 按顺序依次替换变量信息
|
||||
for (int i = 0; i < variables.size(); i++) {
|
||||
if (i == 0) {
|
||||
map.put(variables.get(i), alertPushParams.getDeviceName());
|
||||
} else {
|
||||
map.put(variables.get(i), alertPushParams.getAddress());
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// 获取发送账号
|
||||
Object sendAccountObject = jsonMsgParams.get("sendAccount");
|
||||
Set<String> sendAccountSet = new HashSet<>();
|
||||
if (ObjectUtil.isNotEmpty(sendAccountObject)) {
|
||||
Collections.addAll(sendAccountSet, sendAccountObject.toString());
|
||||
}
|
||||
// 短信、语音、微信小程序需要取设备所属及分享用户信息+模版配置账号,其余使用模版配置的账号
|
||||
if (NotifyChannelEnum.SMS.equals(notifyChannelEnum) || NotifyChannelEnum.VOICE.equals(notifyChannelEnum)) {
|
||||
if (CollectionUtils.isNotEmpty(alertPushParams.getUserPhoneSet())) {
|
||||
sendAccountSet.addAll(alertPushParams.getUserPhoneSet());
|
||||
}
|
||||
}
|
||||
if (NotifyChannelProviderEnum.WECHAT_MINI_PROGRAM.equals(notifyChannelProviderEnum)
|
||||
|| NotifyChannelProviderEnum.WECHAT_PUBLIC_ACCOUNT.equals(notifyChannelProviderEnum)) {
|
||||
if (CollectionUtils.isNotEmpty(alertPushParams.getUserIdSet())) {
|
||||
for (Long userId : alertPushParams.getUserIdSet()) {
|
||||
sendAccountSet.add(userId.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
notifyVO.setSendAccount(StringUtils.join(sendAccountSet, ","));
|
||||
// 发送
|
||||
notifyVO.setMap(map);
|
||||
this.notifySend(notifyVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendCaptchaSms(String phone, String captcha) {
|
||||
NotifyVO notifyVO = this.selectOnlyEnable(NotifyServiceCodeEnum.CAPTCHA.getServiceCode(), NotifyChannelEnum.SMS.getType(), null, 1L);
|
||||
NotifyChannelProviderEnum notifyChannelProviderEnum = notifyVO.getNotifyChannelProviderEnum();
|
||||
// 获取模板参数
|
||||
JSONObject jsonMsgParams = JSONObject.parseObject(notifyVO.getNotifyTemplate().getMsgParams());
|
||||
String content = jsonMsgParams.get("content").toString();
|
||||
// 从模板内容中获取 占位符 关键字
|
||||
LinkedHashMap<String, String> map = new LinkedHashMap<>();
|
||||
List<String> variables = new ArrayList<>();
|
||||
if (NotifyChannelProviderEnum.SMS_ALIBABA.equals(notifyChannelProviderEnum)) {
|
||||
variables = StringUtils.getVariables("${}", content);
|
||||
} else if (NotifyChannelProviderEnum.SMS_TENCENT.equals(notifyChannelProviderEnum)) {
|
||||
variables = StringUtils.getVariables("{}", content);
|
||||
}
|
||||
map.put(variables.get(0), captcha);
|
||||
notifyVO.setSendAccount(phone);
|
||||
notifyVO.setMap(map);
|
||||
this.notifySend(notifyVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NotifyVO selectOnlyEnable(String serviceCode, String channelType, String provider, Long tenantId) {
|
||||
// 获取查询条件
|
||||
NotifyTemplate enableQueryCondition = notifyTemplateService.getEnableQueryCondition(serviceCode, channelType, provider, tenantId);
|
||||
NotifyTemplate notifyTemplate = notifyTemplateService.selectOnlyEnable(enableQueryCondition);
|
||||
if (Objects.isNull(notifyTemplate)) {
|
||||
throw new ServiceException("查询不到启用的通知模板");
|
||||
}
|
||||
NotifyChannel notifyChannel = notifyChannelService.selectNotifyChannelById(notifyTemplate.getChannelId());
|
||||
if (Objects.isNull(notifyChannel)) {
|
||||
throw new ServiceException("查询不到通知渠道");
|
||||
}
|
||||
NotifyVO notifyVO = new NotifyVO();
|
||||
notifyVO.setNotifyChannel(notifyChannel);
|
||||
notifyVO.setNotifyTemplate(notifyTemplate);
|
||||
NotifyChannelProviderEnum notifyChannelProviderEnum = NotifyChannelProviderEnum.getByChannelTypeAndProvider(notifyVO.getNotifyChannel().getChannelType(), notifyVO.getNotifyChannel().getProvider());
|
||||
notifyVO.setNotifyChannelProviderEnum(notifyChannelProviderEnum);
|
||||
return notifyVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AjaxResult smsLoginCaptcha(String phoneNumber) {
|
||||
String userIdKey = CacheConstants.LOGIN_SMS_CAPTCHA_PHONE + phoneNumber;
|
||||
String captcha = VerifyCodeUtils.generateVerifyCode(6, "0123456789");
|
||||
this.sendCaptchaSms(phoneNumber, captcha);
|
||||
redisCache.setCacheObject(userIdKey, captcha, 5, TimeUnit.MINUTES);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String weComVerifyUrl(String msgSignature, String timestamp, String nonce, String echostr) {
|
||||
// 因为只用验证一次,下面三个参数就不写在配置文件里了,需要验证的可以把下面的验证参数改为自己公司的,然后部署到服务器验证就行
|
||||
//token
|
||||
String token = "pr77kdcA5mzJwNeAwV86UcIS";
|
||||
// encodingAESKey
|
||||
String encodingAesKey = "efNILsQxM6wOCsrNPiBeuLOBDgDSnNtOVFBbtf6jwTe";
|
||||
//企业ID
|
||||
String corpId = "ww4761023a5d81550f";
|
||||
// 通过检验msg_signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
|
||||
String result = null;
|
||||
try {
|
||||
WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(token, encodingAesKey, corpId);
|
||||
result = wxcpt.VerifyURL(msgSignature, timestamp, nonce, echostr);
|
||||
} catch (AesException e) {
|
||||
log.error("企业微信验证url错误,error:{}", e.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AjaxResult smsRegisterCaptcha(String phoneNumber) {
|
||||
String userIdKey = CacheConstants.REGISTER_SMS_CAPTCHA_PHONE + phoneNumber;
|
||||
Object cacheObject = redisCache.getCacheObject(userIdKey);
|
||||
if (ObjectUtil.isNotNull(cacheObject)) {
|
||||
return AjaxResult.error("验证码已发送,请稍后重试!");
|
||||
}
|
||||
// String captcha = VerifyCodeUtils.generateVerifyCode(6, "0123456789");
|
||||
// this.sendCaptchaSms(phoneNumber, captcha);
|
||||
String captcha = "123456";
|
||||
redisCache.setCacheObject(userIdKey, captcha, 1, TimeUnit.MINUTES);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验发送账号格式
|
||||
* @param sendAccount 发送账号
|
||||
* @param: notifyChannelEnum 通知枚举
|
||||
* @return java.lang.String
|
||||
*/
|
||||
private String checkSendAccountMsg(String sendAccount, NotifyChannelProviderEnum notifyChannelProviderEnum) {
|
||||
boolean matches;
|
||||
switch (Objects.requireNonNull(notifyChannelProviderEnum)) {
|
||||
case SMS_ALIBABA:
|
||||
case SMS_TENCENT:
|
||||
case VOICE_ALIBABA:
|
||||
case DING_TALK_WORK:
|
||||
case WECHAT_WECOM_APPLY:
|
||||
matches = ValidationUtils.isMobile(sendAccount);
|
||||
if (!matches) {
|
||||
return "请输入正确的电话号码!";
|
||||
}
|
||||
break;
|
||||
case EMAIL_QQ:
|
||||
case EMAIL_163:
|
||||
matches = ValidationUtils.isEmail(sendAccount);
|
||||
if (!matches) {
|
||||
return "请输入正确的邮箱地址!";
|
||||
}
|
||||
break;
|
||||
case WECHAT_MINI_PROGRAM:
|
||||
if (!StringUtils.isNumeric(sendAccount)) {
|
||||
return "请输入正确的用户id";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package com.fastbee.notify.core.sms.config;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.bean.copier.CopyOptions;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.fastbee.common.enums.NotifyChannelEnum;
|
||||
import com.fastbee.common.enums.NotifyChannelProviderEnum;
|
||||
import com.fastbee.notify.domain.NotifyChannel;
|
||||
import com.fastbee.notify.domain.NotifyTemplate;
|
||||
import com.fastbee.notify.service.INotifyChannelService;
|
||||
import com.fastbee.notify.service.INotifyTemplateService;
|
||||
import org.dromara.sms4j.core.datainterface.SmsReadConfig;
|
||||
import org.dromara.sms4j.provider.config.BaseConfig;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author gsb
|
||||
* @date 2023/12/14 17:10
|
||||
*/
|
||||
@Component
|
||||
public class ReadConfig implements SmsReadConfig {
|
||||
|
||||
@Resource
|
||||
private INotifyChannelService notifyChannelService;
|
||||
@Resource
|
||||
private INotifyTemplateService notifyTemplateService;
|
||||
|
||||
@Override
|
||||
public BaseConfig getSupplierConfig(String notifyTemplateId) {
|
||||
NotifyTemplate notifyTemplate = notifyTemplateService.selectNotifyTemplateById(Long.valueOf(notifyTemplateId));
|
||||
NotifyChannel notifyChannel = notifyChannelService.selectNotifyChannelById(notifyTemplate.getChannelId());
|
||||
NotifyChannelProviderEnum notifyChannelProviderEnum = NotifyChannelProviderEnum.getByChannelTypeAndProvider(notifyChannel.getChannelType(), notifyChannel.getProvider());
|
||||
// 注意:因为配置参数是分开渠道和模版配的,所以这里需要先转换,再copy一下
|
||||
BaseConfig baseConfig = (BaseConfig) JSONObject.parseObject(notifyChannel.getConfigContent(), notifyChannelProviderEnum.getConfigContentClass());
|
||||
CopyOptions copyOptions = CopyOptions.create(null, true);
|
||||
BeanUtil.copyProperties(JSONObject.parseObject(notifyTemplate.getMsgParams(), notifyChannelProviderEnum.getMsgParamsClass()), baseConfig, copyOptions);
|
||||
return baseConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BaseConfig> getSupplierConfigList() {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package com.fastbee.notify.core.sms.service;
|
||||
|
||||
import com.fastbee.common.core.notify.NotifySendResponse;
|
||||
import com.fastbee.notify.vo.NotifyVO;
|
||||
import org.dromara.sms4j.api.SmsBlend;
|
||||
import org.dromara.sms4j.api.entity.SmsResponse;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 短信发送接口
|
||||
* @author gsb
|
||||
* @date 2023/12/15 11:01
|
||||
*/
|
||||
public interface ISmsService {
|
||||
|
||||
/**
|
||||
* 根据模版统一发送短信
|
||||
* @param notifyVO 发送类
|
||||
* @return com.fastbee.common.core.notify.NotifySendResponse
|
||||
*/
|
||||
NotifySendResponse send(NotifyVO notifyVO);
|
||||
|
||||
|
||||
/**
|
||||
* 单个电话发送短信
|
||||
* @param phone 电话
|
||||
* @param message 模板内容
|
||||
* @return 结果
|
||||
*/
|
||||
SmsResponse sendMessage(SmsBlend smsBlend, String phone, String message);
|
||||
|
||||
/**
|
||||
* 根据模板id发送 --多参数
|
||||
* @param phone 电话
|
||||
* @param templateId 模板id
|
||||
* @param messages 内容集合
|
||||
* @return 结果
|
||||
*/
|
||||
SmsResponse sendMessage(SmsBlend smsBlend, String phone, String templateId, LinkedHashMap<String,String> messages);
|
||||
|
||||
/**
|
||||
* 群发短信
|
||||
* @param phones 电话集合
|
||||
* @param templateId 模板id
|
||||
* @param messages 内容集合
|
||||
* @return 结果
|
||||
*/
|
||||
SmsResponse massTexting(SmsBlend smsBlend, List<String> phones, String templateId, LinkedHashMap<String,String> messages);
|
||||
|
||||
/**
|
||||
* 延迟发送
|
||||
* @param phone 电话
|
||||
* @param message 模板内容
|
||||
* @param delayedTime 延迟时间
|
||||
*/
|
||||
void delayedMessage(SmsBlend smsBlend,String phone ,String message,Long delayedTime);
|
||||
|
||||
/**
|
||||
* 根据模板延迟发送
|
||||
* @param phone 电话
|
||||
* @param messages 模板内容集合
|
||||
* @param delayedTime 延迟时间
|
||||
*/
|
||||
void delayedMessage(SmsBlend smsBlend, String phone ,String templateId, LinkedHashMap<String,String> messages,Long delayedTime);
|
||||
|
||||
}
|
@ -0,0 +1,139 @@
|
||||
package com.fastbee.notify.core.sms.service.Impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.bean.copier.CopyOptions;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.fastbee.common.core.notify.NotifySendResponse;
|
||||
import com.fastbee.common.utils.StringUtils;
|
||||
import com.fastbee.notify.core.sms.config.ReadConfig;
|
||||
import com.fastbee.notify.core.sms.service.ISmsService;
|
||||
import com.fastbee.notify.vo.NotifyVO;
|
||||
import org.dromara.sms4j.api.SmsBlend;
|
||||
import org.dromara.sms4j.api.entity.SmsResponse;
|
||||
import org.dromara.sms4j.core.factory.SmsFactory;
|
||||
import org.dromara.sms4j.provider.config.BaseConfig;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author gsb
|
||||
* @date 2023/12/15 11:03
|
||||
*/
|
||||
@Service
|
||||
public class SmsServiceImpl implements ISmsService {
|
||||
|
||||
@Resource
|
||||
private ReadConfig config;
|
||||
|
||||
@Override
|
||||
public NotifySendResponse send(NotifyVO notifyVO) {
|
||||
NotifySendResponse notifySendResponse = new NotifySendResponse();
|
||||
// 注意:因为配置参数是分开渠道和模版配的,所以这里需要先转换,再copy一下
|
||||
BaseConfig baseConfig = (BaseConfig) JSONObject.parseObject(notifyVO.getNotifyChannel().getConfigContent(), notifyVO.getNotifyChannelProviderEnum().getConfigContentClass());
|
||||
CopyOptions copyOptions = CopyOptions.create(null, true);
|
||||
BeanUtil.copyProperties(JSONObject.parseObject(notifyVO.getNotifyTemplate().getMsgParams(), notifyVO.getNotifyChannelProviderEnum().getMsgParamsClass()), baseConfig, copyOptions);
|
||||
JSONObject jsonMsgParams = JSONObject.parseObject(notifyVO.getNotifyTemplate().getMsgParams());
|
||||
String content = jsonMsgParams.get("content").toString();
|
||||
LinkedHashMap<String, String> map = notifyVO.getMap();
|
||||
String sendContent = "";
|
||||
switch (notifyVO.getNotifyChannelProviderEnum()) {
|
||||
case SMS_ALIBABA:
|
||||
sendContent = StringUtils.strReplaceVariable("${", "}", content, map);
|
||||
break;
|
||||
case SMS_TENCENT:
|
||||
sendContent = StringUtils.strReplaceVariable("{", "}", content, map);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
notifySendResponse.setSendContent(sendContent);
|
||||
SmsBlend smsBlend = this.getSmsInstance(notifyVO.getNotifyTemplate().getId().toString());
|
||||
List<String> phoneList = StringUtils.str2List(notifyVO.getSendAccount(), ",", true, true);
|
||||
SmsResponse smsResponse = this.massTexting(smsBlend, phoneList, baseConfig.getTemplateId(), map);
|
||||
notifySendResponse.setStatus(smsResponse.isSuccess() ? 1 : 0);
|
||||
notifySendResponse.setResultContent(JSON.toJSONString(smsResponse.getData()));
|
||||
return notifySendResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取短信实例
|
||||
* @return
|
||||
*/
|
||||
private SmsBlend getSmsInstance(String configId){
|
||||
SmsBlend smsBlend = SmsFactory.getSmsBlend(configId);
|
||||
if (Objects.isNull(smsBlend)){
|
||||
//如果没有初始化,则先进行初始化
|
||||
SmsFactory.createSmsBlend(config, configId);
|
||||
return SmsFactory.getSmsBlend(configId);
|
||||
}
|
||||
return smsBlend;
|
||||
}
|
||||
|
||||
/**
|
||||
* 单个电话发送短信
|
||||
*
|
||||
* @param phone 电话
|
||||
* @param message 模板内容
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public SmsResponse sendMessage(SmsBlend smsBlend, String phone, String message) {
|
||||
return smsBlend.sendMessage(phone, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据模板id发送 --多参数
|
||||
*
|
||||
* @param phone 电话
|
||||
* @param templateId 模板id
|
||||
* @param messages 内容集合
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public SmsResponse sendMessage(SmsBlend smsBlend, String phone, String templateId, LinkedHashMap<String, String> messages) {
|
||||
return smsBlend.sendMessage(phone, templateId, messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* 群发短信
|
||||
*
|
||||
* @param phones 电话集合
|
||||
* @param templateId 模板id
|
||||
* @param messages 内容集合
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public SmsResponse massTexting(SmsBlend smsBlend, List<String> phones, String templateId, LinkedHashMap<String,String> messages) {
|
||||
return smsBlend.massTexting(phones, templateId, messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* 延迟发送
|
||||
*
|
||||
* @param phone 电话
|
||||
* @param message 模板内容
|
||||
* @param delayedTime 延迟时间
|
||||
*/
|
||||
@Override
|
||||
public void delayedMessage(SmsBlend smsBlend, String phone, String message, Long delayedTime) {
|
||||
smsBlend.delayedMessage(phone, message, delayedTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据模板延迟发送
|
||||
*
|
||||
* @param phone 电话
|
||||
* @param messages 模板内容集合
|
||||
* @param delayedTime 延迟时间
|
||||
*/
|
||||
@Override
|
||||
public void delayedMessage(SmsBlend smsBlend, String phone, String templateId, LinkedHashMap<String, String> messages, Long delayedTime) {
|
||||
smsBlend.delayedMessage(phone, templateId, messages, delayedTime);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.fastbee.notify.core.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author fastb
|
||||
* @version 1.0
|
||||
* @description: 通知测试传参
|
||||
* @date 2023-12-28 15:15
|
||||
*/
|
||||
@Data
|
||||
public class SendParams {
|
||||
|
||||
/**
|
||||
* 模板编号
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 发送账号:手机号、邮箱、用户id
|
||||
*/
|
||||
private String sendAccount;
|
||||
/**
|
||||
* 模板内容变量json字符串
|
||||
*/
|
||||
private String variables;
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package com.fastbee.notify.core.voice.config;
|
||||
|
||||
import com.aliyun.dyvmsapi20170525.Client;
|
||||
import com.aliyun.teaopenapi.models.Config;
|
||||
|
||||
/**
|
||||
* @author fastb
|
||||
* @version 1.0
|
||||
* @description: 语音配置类
|
||||
* @date 2024-01-11 16:06
|
||||
*/
|
||||
public class VoiceConfig {
|
||||
|
||||
/**
|
||||
* 使用AK&SK初始化账号Client
|
||||
* @param accessKeyId
|
||||
* @param accessKeySecret
|
||||
* @return Client
|
||||
* @throws Exception
|
||||
*/
|
||||
public static Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
|
||||
Config config = new Config()
|
||||
// 必填,您的 AccessKey ID
|
||||
.setAccessKeyId(accessKeyId)
|
||||
// 必填,您的 AccessKey Secret
|
||||
.setAccessKeySecret(accessKeySecret);
|
||||
// Endpoint 请参考 https://api.aliyun.com/product/Dyvmsapi
|
||||
config.endpoint = "dyvmsapi.aliyuncs.com";
|
||||
return new Client(config);
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.fastbee.notify.core.voice.service;
|
||||
|
||||
import com.fastbee.common.core.notify.NotifySendResponse;
|
||||
import com.fastbee.notify.vo.NotifyVO;
|
||||
|
||||
/**
|
||||
* @description: 语音通知服务类
|
||||
* @author fastb
|
||||
* @date 2023-12-15 11:05
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface VoiceService {
|
||||
|
||||
/**
|
||||
* 语音发送
|
||||
* @param notifyVO 发送参数
|
||||
* @return
|
||||
*/
|
||||
NotifySendResponse send(NotifyVO notifyVO);
|
||||
}
|
@ -0,0 +1,212 @@
|
||||
package com.fastbee.notify.core.voice.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.aliyun.dyvmsapi20170525.Client;
|
||||
import com.aliyun.dyvmsapi20170525.models.SingleCallByTtsRequest;
|
||||
import com.aliyun.dyvmsapi20170525.models.SingleCallByTtsResponse;
|
||||
import com.aliyun.teautil.models.RuntimeOptions;
|
||||
import com.fastbee.common.core.notify.NotifySendResponse;
|
||||
import com.fastbee.common.core.notify.config.VoiceConfigParams;
|
||||
import com.fastbee.common.core.notify.msg.VoiceMsgParams;
|
||||
import com.fastbee.common.enums.NotifyChannelProviderEnum;
|
||||
import com.fastbee.common.utils.StringUtils;
|
||||
import com.fastbee.notify.core.voice.config.VoiceConfig;
|
||||
import com.fastbee.notify.core.voice.service.VoiceService;
|
||||
import com.fastbee.notify.vo.NotifyVO;
|
||||
import com.tencentcloudapi.common.Credential;
|
||||
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
||||
import com.tencentcloudapi.common.profile.ClientProfile;
|
||||
import com.tencentcloudapi.common.profile.HttpProfile;
|
||||
import com.tencentcloudapi.vms.v20200902.VmsClient;
|
||||
import com.tencentcloudapi.vms.v20200902.models.SendTtsVoiceRequest;
|
||||
import com.tencentcloudapi.vms.v20200902.models.SendTtsVoiceResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author fastb
|
||||
* @version 1.0
|
||||
* @description: 语音通知发送业务类
|
||||
* @date 2023-12-26 9:54
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class VoiceServiceImpl implements VoiceService {
|
||||
|
||||
@Override
|
||||
public NotifySendResponse send(NotifyVO notifyVO) {
|
||||
NotifySendResponse notifySendResponse = new NotifySendResponse();
|
||||
VoiceConfigParams configParams = JSONObject.parseObject(notifyVO.getNotifyChannel().getConfigContent(), VoiceConfigParams.class);
|
||||
VoiceMsgParams msgParams = JSONObject.parseObject(notifyVO.getNotifyTemplate().getMsgParams(), VoiceMsgParams.class);
|
||||
LinkedHashMap<String, String> map = notifyVO.getMap();
|
||||
NotifyChannelProviderEnum notifyChannelProviderEnum = notifyVO.getNotifyChannelProviderEnum();
|
||||
if (StringUtils.isEmpty(notifyVO.getSendAccount())) {
|
||||
notifySendResponse.setStatus(0);
|
||||
notifySendResponse.setResultContent("发送电话不能为空,请先配置!");
|
||||
return notifySendResponse;
|
||||
}
|
||||
String phoneStr = notifyVO.getSendAccount();
|
||||
List<String> phoneList = StringUtils.str2List(phoneStr, ",", true, true);
|
||||
String sendContent = "";
|
||||
List<String> resultList = new ArrayList<>();
|
||||
for (String phone : phoneList) {
|
||||
switch (notifyChannelProviderEnum) {
|
||||
case VOICE_ALIBABA:
|
||||
sendContent = StringUtils.strReplaceVariable("${", "}", msgParams.getContent(), map);
|
||||
try {
|
||||
notifySendResponse = singleCallByTts(configParams, msgParams, map, phone);
|
||||
} catch (Exception e) {
|
||||
log.error("阿里云语音通知异常,phone:{}, exception:{}", phone, e.toString());
|
||||
}
|
||||
break;
|
||||
case VOICE_TENCENT:
|
||||
sendContent = StringUtils.strReplaceVariable("{", "}", msgParams.getContent(), map);
|
||||
notifySendResponse = this.sendTtsVoice(configParams, msgParams, map, phone);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
resultList.add("phone:[" + phone + "],status:[" + notifySendResponse.getStatus() + "],resultContent:[" + notifySendResponse.getResultContent() + "]");
|
||||
}
|
||||
notifySendResponse.setSendContent(sendContent);
|
||||
notifySendResponse.setResultContent(StringUtils.join(resultList, "; "));
|
||||
return notifySendResponse;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @description: 阿里云文本转语音通知
|
||||
* @param: configParams 渠道服务商配置参数
|
||||
* @param: msgParams 模版通知内容
|
||||
* @param: map 变量参数
|
||||
* @param: phone 通知电话
|
||||
* @return: com.aliyun.dyvmsapi20170525.models.SingleCallByTtsResponse
|
||||
*/
|
||||
public NotifySendResponse singleCallByTts(VoiceConfigParams configParams, VoiceMsgParams msgParams, LinkedHashMap<String, String> map, String phone) throws Exception {
|
||||
NotifySendResponse notifySendResponse = new NotifySendResponse();
|
||||
try {
|
||||
Client client = VoiceConfig.createClient(configParams.getAccessKeyId(), configParams.getAccessKeySecret());
|
||||
SingleCallByTtsRequest singleCallByTtsRequest = new SingleCallByTtsRequest()
|
||||
.setTtsCode(msgParams.getTemplateId())
|
||||
.setCalledNumber(phone)
|
||||
.setTtsParam(JSON.toJSONString(map))
|
||||
.setPlayTimes(StringUtils.isNotEmpty(msgParams.getPlayTimes()) ? Integer.parseInt(msgParams.getPlayTimes()) : 1)
|
||||
.setVolume(StringUtils.isNotEmpty(msgParams.getVolume()) ? Integer.parseInt(msgParams.getVolume()) : 50)
|
||||
.setSpeed(StringUtils.isNotEmpty(msgParams.getSpeed()) ? Integer.parseInt(msgParams.getSpeed()) : 0);
|
||||
RuntimeOptions runtimeOptions = new RuntimeOptions();
|
||||
SingleCallByTtsResponse singleCallByTtsResponse = client.singleCallByTtsWithOptions(singleCallByTtsRequest, runtimeOptions);
|
||||
notifySendResponse.setStatus("OK".equals(singleCallByTtsResponse.getBody().getCode()) ? 1 : 0);
|
||||
notifySendResponse.setResultContent(JSON.toJSONString(singleCallByTtsResponse.getBody()));
|
||||
} catch (Exception e) {
|
||||
notifySendResponse.setStatus(0);
|
||||
notifySendResponse.setResultContent(e.toString());
|
||||
}
|
||||
return notifySendResponse;
|
||||
}
|
||||
|
||||
public NotifySendResponse sendTtsVoice(VoiceConfigParams configParams, VoiceMsgParams msgParams, LinkedHashMap<String, String> map, String phone) {
|
||||
NotifySendResponse notifySendResponse = new NotifySendResponse();
|
||||
try {
|
||||
/* 必要步骤:
|
||||
* 实例化一个认证对象,入参需要传入腾讯云账户密钥对secretId,secretKey。
|
||||
* 这里采用的是从环境变量读取的方式,需要在环境变量中先设置这两个值。
|
||||
* 您也可以直接在代码中写死密钥对,但是小心不要将代码复制、上传或者分享给他人,
|
||||
* 以免泄露密钥对危及您的财产安全。
|
||||
* CAM密匙查询: https://console.cloud.tencent.com/cam/capi*/
|
||||
Credential cred = new Credential(configParams.getAccessKeyId(), configParams.getAccessKeySecret());
|
||||
|
||||
|
||||
// 实例化一个http选项,可选,没有特殊需求可以跳过
|
||||
HttpProfile httpProfile = new HttpProfile();
|
||||
// 设置代理
|
||||
// httpProfile.setProxyHost("host");
|
||||
// httpProfile.setProxyPort(port);
|
||||
// SDK默认使用POST方法。
|
||||
// 如果您一定要使用GET方法,可以在这里设置。GET方法无法处理一些较大的请求
|
||||
httpProfile.setReqMethod("POST");
|
||||
/* SDK有默认的超时时间,非必要请不要进行调整
|
||||
* 如有需要请在代码中查阅以获取最新的默认值 */
|
||||
httpProfile.setConnTimeout(60);
|
||||
/* SDK会自动指定域名。通常是不需要特地指定域名的,但是如果您访问的是金融区的服务
|
||||
* 则必须手动指定域名,例如vms的上海金融区域名: vms.ap-shanghai-fsi.tencentcloudapi.com */
|
||||
httpProfile.setEndpoint("vms.tencentcloudapi.com");
|
||||
|
||||
|
||||
/* 非必要步骤:
|
||||
* 实例化一个客户端配置对象,可以指定超时时间等配置 */
|
||||
ClientProfile clientProfile = new ClientProfile();
|
||||
/* SDK默认用TC3-HMAC-SHA256进行签名
|
||||
* 非必要请不要修改这个字段 */
|
||||
clientProfile.setSignMethod("TC3-HMAC-SHA256");
|
||||
clientProfile.setHttpProfile(httpProfile);
|
||||
/* 实例化要请求产品(以vms为例)的client对象
|
||||
* 第二个参数是地域信息,可以直接填写字符串ap-guangzhou,或者引用预设的常量 */
|
||||
VmsClient client = new VmsClient(cred, "ap-guangzhou", clientProfile);
|
||||
/* 实例化一个请求对象,根据调用的接口和实际情况,可以进一步设置请求参数
|
||||
* 您可以直接查询SDK源码确定接口有哪些属性可以设置
|
||||
* 属性可能是基本类型,也可能引用了另一个数据结构
|
||||
* 推荐使用IDE进行开发,可以方便的跳转查阅各个接口和数据结构的文档说明 */
|
||||
SendTtsVoiceRequest req = new SendTtsVoiceRequest();
|
||||
|
||||
|
||||
/* 填充请求参数,这里request对象的成员变量即对应接口的入参
|
||||
* 您可以通过官网接口文档或跳转到request对象的定义处查看请求参数的定义
|
||||
* 基本类型的设置:
|
||||
* 帮助链接:
|
||||
* 语音消息控制台:https://console.cloud.tencent.com/vms
|
||||
* vms helper:https://cloud.tencent.com/document/product/1128/37720 */
|
||||
|
||||
|
||||
// 模板 ID,必须填写在控制台审核通过的模板 ID,可登录 [语音消息控制台] 查看模板 ID
|
||||
String templateId = msgParams.getTemplateId();
|
||||
req.setTemplateId(templateId);
|
||||
|
||||
|
||||
// 模板参数,若模板没有参数,请提供为空数组
|
||||
String[] templateParamSet = map.values().toArray(new String[0]);;
|
||||
req.setTemplateParamSet(templateParamSet);
|
||||
|
||||
|
||||
/* 被叫手机号码,采用 e.164 标准,格式为+[国家或地区码][用户号码]
|
||||
* 例如:+8613711112222,其中前面有一个+号,86为国家码,13711112222为手机号 */
|
||||
String calledNumber = "+86" + phone;
|
||||
req.setCalledNumber(calledNumber);
|
||||
|
||||
|
||||
// 在 [语音控制台] 添加应用后生成的实际SdkAppid,示例如1400006666
|
||||
String voiceSdkAppid = msgParams.getSdkAppId();
|
||||
req.setVoiceSdkAppid(voiceSdkAppid);
|
||||
|
||||
|
||||
// 播放次数,可选,最多3次,默认2次
|
||||
Long playTimes = 2L;
|
||||
req.setPlayTimes(playTimes);
|
||||
|
||||
|
||||
// 用户的 session 内容,腾讯 server 回包中会原样返回
|
||||
String sessionContext = phone;
|
||||
req.setSessionContext(sessionContext);
|
||||
|
||||
|
||||
/* 通过 client 对象调用 SendTtsVoice 方法发起请求。注意请求方法名与请求对象是对应的
|
||||
* 返回的 res 是一个 SendTtsVoiceResponse 类的实例,与请求对象对应 */
|
||||
SendTtsVoiceResponse response = client.SendTtsVoice(req);
|
||||
notifySendResponse.setStatus(1);
|
||||
notifySendResponse.setResultContent(JSON.toJSONString(response));
|
||||
|
||||
|
||||
} catch (TencentCloudSDKException e) {
|
||||
// log.error("腾讯云语音通知异常,phone:{}, exception:{}", phone, e.toString());
|
||||
notifySendResponse.setStatus(0);
|
||||
notifySendResponse.setResultContent(e.toString());
|
||||
}
|
||||
return notifySendResponse;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package com.fastbee.notify.core.wechat.service;
|
||||
|
||||
import com.fastbee.common.core.notify.NotifySendResponse;
|
||||
import com.fastbee.notify.core.wechat.vo.WeChatMiniPushVO;
|
||||
import com.fastbee.notify.core.wechat.vo.WxMssVo;
|
||||
import com.fastbee.notify.domain.NotifyChannel;
|
||||
import com.fastbee.notify.domain.NotifyTemplate;
|
||||
import com.fastbee.notify.vo.NotifyVO;
|
||||
|
||||
/**
|
||||
* @description: 微信通知推送业务类
|
||||
* @author fastb
|
||||
* @date 2023-12-29 16:39
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface WeChatPushService {
|
||||
|
||||
/**
|
||||
* 统一发送接口
|
||||
* @param notifyVO 发送参数
|
||||
* @return
|
||||
*/
|
||||
NotifySendResponse send(NotifyVO notifyVO);
|
||||
|
||||
/**
|
||||
* @description: 推送消息给指定的用户 --微信小程序服务号推送
|
||||
* @param: wxMssVo
|
||||
* @param: url
|
||||
* @return: java.lang.String
|
||||
*/
|
||||
NotifySendResponse weChatPostPush(String json, String url);
|
||||
|
||||
/**
|
||||
* @description: 生成微信小程序基本推送参数
|
||||
* @param: notifyTemplateId
|
||||
* @return: com.fastbee.notify.core.wechat.vo.WeChatMiniPushVO
|
||||
*/
|
||||
WeChatMiniPushVO createWeChatMiniPushVO(NotifyChannel notifyChannel, NotifyTemplate notifyTemplate, Long userId);
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,399 @@
|
||||
package com.fastbee.notify.core.wechat.service.impl;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.fastbee.common.constant.FastBeeConstant;
|
||||
import com.fastbee.common.core.notify.NotifySendResponse;
|
||||
import com.fastbee.common.core.notify.config.WeChatConfigParams;
|
||||
import com.fastbee.common.core.notify.msg.WeComMsgParams;
|
||||
import com.fastbee.common.core.notify.msg.WechatMsgParams;
|
||||
import com.fastbee.common.core.redis.RedisCache;
|
||||
import com.fastbee.common.enums.NotifyChannelProviderEnum;
|
||||
import com.fastbee.common.enums.SocialPlatformType;
|
||||
import com.fastbee.common.utils.StringUtils;
|
||||
import com.fastbee.common.utils.http.HttpUtils;
|
||||
import com.fastbee.common.utils.wechat.WechatUtils;
|
||||
import com.fastbee.common.wechat.WeChatAppResult;
|
||||
import com.fastbee.iot.domain.SocialUser;
|
||||
import com.fastbee.iot.service.ISocialUserService;
|
||||
import com.fastbee.notify.core.wechat.service.WeChatPushService;
|
||||
import com.fastbee.notify.core.wechat.vo.TemplateDataVo;
|
||||
import com.fastbee.notify.core.wechat.vo.WeChatMiniPushVO;
|
||||
import com.fastbee.notify.core.wechat.vo.WeChatPublicAccountPushVO;
|
||||
import com.fastbee.notify.core.wechat.vo.WxMssVo;
|
||||
import com.fastbee.notify.domain.NotifyChannel;
|
||||
import com.fastbee.notify.domain.NotifyTemplate;
|
||||
import com.fastbee.notify.vo.NotifyVO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author fastb
|
||||
* @version 1.0
|
||||
* @description: 微信相关发送服务类
|
||||
* @date 2023-12-26 17:15
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class WeChatPushServiceImpl implements WeChatPushService {
|
||||
|
||||
@Resource
|
||||
private ISocialUserService socialUserService;
|
||||
private static RestTemplate restTemplate;
|
||||
@Resource
|
||||
private RedisCache redisCache;
|
||||
|
||||
|
||||
@Override
|
||||
public NotifySendResponse send(NotifyVO notifyVO) {
|
||||
NotifySendResponse notifySendResponse = new NotifySendResponse();
|
||||
NotifyChannelProviderEnum notifyChannelProviderEnum = notifyVO.getNotifyChannelProviderEnum();
|
||||
switch (notifyChannelProviderEnum) {
|
||||
case WECHAT_MINI_PROGRAM:
|
||||
notifySendResponse = this.weChatMiniSend(notifyVO);
|
||||
break;
|
||||
case WECHAT_WECOM_ROBOT:
|
||||
notifySendResponse = this.weComRobotSend(notifyVO);
|
||||
break;
|
||||
case WECHAT_WECOM_APPLY:
|
||||
notifySendResponse = this.weComApplySend(notifyVO);
|
||||
break;
|
||||
case WECHAT_PUBLIC_ACCOUNT:
|
||||
notifySendResponse = this.weChatPublicAccountSend(notifyVO);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return notifySendResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信公众号发送
|
||||
* @param notifyVO 通知参数
|
||||
* @return com.fastbee.common.core.notify.NotifySendResponse
|
||||
*/
|
||||
private NotifySendResponse weChatPublicAccountSend(NotifyVO notifyVO) {
|
||||
NotifySendResponse notifySendResponse = new NotifySendResponse();
|
||||
if (StringUtils.isEmpty(notifyVO.getSendAccount())) {
|
||||
notifySendResponse.setStatus(0);
|
||||
notifySendResponse.setResultContent("发送用户id为空,请先配置发送用户id!");
|
||||
return notifySendResponse;
|
||||
}
|
||||
LinkedHashMap<String, String> map = notifyVO.getMap();
|
||||
LinkedHashMap<String,String> mapVariable = new LinkedHashMap<>();
|
||||
Map<String, Object> sendMap = new HashMap<>(5);
|
||||
for (Map.Entry<String, String> m : map.entrySet()) {
|
||||
sendMap.put(m.getKey(), new TemplateDataVo(m.getValue()));
|
||||
mapVariable.put(m.getKey() + ".DATA", m.getValue());
|
||||
}
|
||||
NotifyChannel notifyChannel = notifyVO.getNotifyChannel();
|
||||
NotifyTemplate notifyTemplate = notifyVO.getNotifyTemplate();
|
||||
WeChatConfigParams weChatConfigParams = JSONObject.parseObject(notifyChannel.getConfigContent(), WeChatConfigParams.class);
|
||||
WechatMsgParams wechatMsgParams = JSONObject.parseObject(notifyTemplate.getMsgParams(), WechatMsgParams.class);
|
||||
// 获取accessToken
|
||||
if (StringUtils.isEmpty(weChatConfigParams.getAppId()) || StringUtils.isEmpty(weChatConfigParams.getAppSecret())) {
|
||||
notifySendResponse.setStatus(0);
|
||||
notifySendResponse.setResultContent("通知渠道配置参数为空,请先配置!");
|
||||
return notifySendResponse;
|
||||
}
|
||||
WeChatAppResult weChatAppResult = WechatUtils.getAccessToken(weChatConfigParams.getAppId(), weChatConfigParams.getAppSecret());
|
||||
if (ObjectUtil.isNull(weChatAppResult) || StringUtils.isEmpty(weChatAppResult.getAccessToken())) {
|
||||
notifySendResponse.setStatus(0);
|
||||
notifySendResponse.setResultContent("获取AccessToken失败,原因:" + JSON.toJSONString(weChatAppResult));
|
||||
return notifySendResponse;
|
||||
}
|
||||
String pushUrl = FastBeeConstant.URL.WX_PUBLIC_ACCOUNT_TEMPLATE_SEND_URL_PREFIX + weChatAppResult.getAccessToken();
|
||||
|
||||
// 组装发送参数
|
||||
WeChatPublicAccountPushVO weChatPublicAccountPushVO = new WeChatPublicAccountPushVO();
|
||||
weChatPublicAccountPushVO.setData(sendMap);
|
||||
weChatPublicAccountPushVO.setTemplateId(wechatMsgParams.getTemplateId());
|
||||
if (StringUtils.isNotEmpty(wechatMsgParams.getRedirectUrl())) {
|
||||
weChatPublicAccountPushVO.setUrl(wechatMsgParams.getRedirectUrl());
|
||||
}
|
||||
if (StringUtils.isNotEmpty(wechatMsgParams.getPagePath())) {
|
||||
WeChatPublicAccountPushVO.MiniProgram miniProgram = new WeChatPublicAccountPushVO.MiniProgram();
|
||||
miniProgram.setAppId(wechatMsgParams.getAppid());
|
||||
miniProgram.setPagePath(wechatMsgParams.getPagePath());
|
||||
weChatPublicAccountPushVO.setMiniProgram(miniProgram);
|
||||
}
|
||||
// 获取用户id
|
||||
List<String> userIdList = StringUtils.str2List(notifyVO.getSendAccount(), ",", true, true);
|
||||
List<SocialUser> socialUserList = socialUserService.listWechatPublicAccountOpenId(userIdList);
|
||||
Map<Long, String> userMap = socialUserList.stream().collect(Collectors.toMap(SocialUser::getSysUserId, SocialUser::getOpenId, (o, n) -> n));
|
||||
|
||||
List<String> resultContentList = new ArrayList<>();
|
||||
for (String userId : userIdList) {
|
||||
String openId = userMap.get(Long.valueOf(userId));
|
||||
if (StringUtils.isEmpty(openId)) {
|
||||
resultContentList.add("userId:[" + userId + "],status:[0],resultContent:[该用户未绑定微信,请先绑定后重试!]");
|
||||
notifySendResponse.setStatus(0);
|
||||
continue;
|
||||
}
|
||||
weChatPublicAccountPushVO.setTouser(openId);
|
||||
notifySendResponse = this.weChatPostPush(JSON.toJSONString(weChatPublicAccountPushVO), pushUrl);
|
||||
resultContentList.add("userId:[" + userId + "],status:[" + notifySendResponse.getStatus() +"],resultContent:[" + notifySendResponse.getResultContent() + "]");
|
||||
}
|
||||
String content = JSONObject.parseObject(notifyVO.getNotifyTemplate().getMsgParams()).get("content").toString();
|
||||
String sendContent = StringUtils.strReplaceVariable("{{", "}}", content, mapVariable);
|
||||
notifySendResponse.setSendContent(sendContent);
|
||||
notifySendResponse.setResultContent(StringUtils.join(resultContentList, "; "));
|
||||
return notifySendResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业微信应用消息发送
|
||||
* @param notifyVO 发送vo类
|
||||
* @return com.fastbee.common.core.notify.NotifySendResponse
|
||||
*/
|
||||
private NotifySendResponse weComApplySend(NotifyVO notifyVO) {
|
||||
NotifySendResponse notifySendResponse = new NotifySendResponse();
|
||||
if (StringUtils.isEmpty(notifyVO.getSendAccount())) {
|
||||
notifySendResponse.setStatus(0);
|
||||
notifySendResponse.setResultContent("发送成员账号为空,请先配置!");
|
||||
return notifySendResponse;
|
||||
}
|
||||
WeChatConfigParams weChatConfigParams = JSONObject.parseObject(notifyVO.getNotifyChannel().getConfigContent(), WeChatConfigParams.class);
|
||||
if (StringUtils.isEmpty(weChatConfigParams.getCorpId()) || StringUtils.isEmpty(weChatConfigParams.getCorpSecret())) {
|
||||
notifySendResponse.setStatus(0);
|
||||
notifySendResponse.setResultContent("企业微信应用消息渠道配置信息为空,请先配置!");
|
||||
return notifySendResponse;
|
||||
}
|
||||
WeComMsgParams weComMsgParams = JSONObject.parseObject(notifyVO.getNotifyTemplate().getMsgParams(), WeComMsgParams.class);
|
||||
// 获取accessToken,优先从缓存获取,不能频繁的获取
|
||||
String accessToken;
|
||||
Object accessTokenRedis = redisCache.getCacheObject(FastBeeConstant.REDIS.NOTIFY_WECOM_APPLY_ACCESSTOKEN + weChatConfigParams.getAgentId());
|
||||
if (Objects.nonNull(accessTokenRedis)) {
|
||||
accessToken = accessTokenRedis.toString();
|
||||
} else {
|
||||
String s = HttpUtils.sendGet(FastBeeConstant.URL.WECOM_GET_ACCESSTOKEN + "?corpid=" + weChatConfigParams.getCorpId() + "&corpsecret=" + weChatConfigParams.getCorpSecret());
|
||||
JSONObject accessTokenJson = JSONObject.parseObject(s);
|
||||
if (!"0".equals(accessTokenJson.get("errcode").toString())) {
|
||||
notifySendResponse.setStatus(0);
|
||||
notifySendResponse.setResultContent(s);
|
||||
return notifySendResponse;
|
||||
}
|
||||
accessToken = accessTokenJson.get("access_token").toString();
|
||||
redisCache.setCacheObject(FastBeeConstant.REDIS.NOTIFY_WECOM_APPLY_ACCESSTOKEN + weChatConfigParams.getAgentId(), accessToken, 2, TimeUnit.HOURS);
|
||||
}
|
||||
// 通过手机号获取企业微信用户名
|
||||
// JSONObject phoneReq = new JSONObject();
|
||||
// phoneReq.put("mobile", notifyVO.getSendAccount());
|
||||
// String phoneRes = HttpUtils.sendPost("https://qyapi.weixin.qq.com/cgi-bin/user/getuserid?access_token=" + accessToken, phoneReq.toString());
|
||||
// JSONObject phoneResJson = JSONObject.parseObject(phoneRes);
|
||||
// if (!"0".equals(phoneResJson.get("errcode").toString())) {
|
||||
// notifySendResponse.setStatus(0);
|
||||
// notifySendResponse.setResultContent(phoneRes);
|
||||
// return notifySendResponse;
|
||||
// }
|
||||
// String userid = phoneResJson.get("userid").toString();
|
||||
// 构建消息内容
|
||||
String sendContent = StringUtils.strReplaceVariable("${", "}", weComMsgParams.getContent(), notifyVO.getMap());
|
||||
notifySendResponse.setSendContent(sendContent);
|
||||
JSONObject msg = this.createWeComMsg(weComMsgParams, sendContent);
|
||||
// 多个用户用|分隔
|
||||
List<String> userIdList = StringUtils.str2List(notifyVO.getSendAccount(), ",", true, true);
|
||||
String userIdStr = String.join("|", userIdList);
|
||||
msg.put("touser", userIdStr);
|
||||
msg.put("agentid", weChatConfigParams.getAgentId());
|
||||
// 发送
|
||||
String sendUrl = FastBeeConstant.URL.WECOM_APPLY_SEND + accessToken;
|
||||
String result = HttpUtils.sendPost(sendUrl, msg.toString());
|
||||
notifySendResponse.setStatus("0".equals(JSONObject.parseObject(result).get("errcode").toString()) ? 1 : 0);
|
||||
notifySendResponse.setResultContent(result);
|
||||
return notifySendResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业微信群机器人发送
|
||||
* @param notifyVO 发送配置类
|
||||
* @return com.fastbee.common.core.notify.NotifySendResponse
|
||||
*/
|
||||
private NotifySendResponse weComRobotSend(NotifyVO notifyVO) {
|
||||
NotifySendResponse notifySendResponse = new NotifySendResponse();
|
||||
NotifyChannel notifyChannel = notifyVO.getNotifyChannel();
|
||||
NotifyTemplate notifyTemplate = notifyVO.getNotifyTemplate();
|
||||
WeChatConfigParams weChatConfigParams = JSONObject.parseObject(notifyChannel.getConfigContent(), WeChatConfigParams.class);
|
||||
if (StringUtils.isEmpty(weChatConfigParams.getWebHook())) {
|
||||
notifySendResponse.setStatus(0);
|
||||
notifySendResponse.setResultContent("企业微信群机器人webHook为空,请先去通知渠道下配置!");
|
||||
return notifySendResponse;
|
||||
}
|
||||
WeComMsgParams weComMsgParams = JSONObject.parseObject(notifyTemplate.getMsgParams(), WeComMsgParams.class);
|
||||
String sendContent = StringUtils.strReplaceVariable("${", "}", weComMsgParams.getContent(), notifyVO.getMap());
|
||||
JSONObject sendJson = this.createWeComMsg(weComMsgParams, sendContent);
|
||||
String s = HttpUtils.sendPost(weChatConfigParams.getWebHook(), sendJson.toString());
|
||||
notifySendResponse.setSendContent(sendJson.toJSONString());
|
||||
notifySendResponse.setStatus("0".equals(JSONObject.parseObject(s).get("errcode").toString()) ? 1 : 0);
|
||||
notifySendResponse.setResultContent(s);
|
||||
return notifySendResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建企业微信发送参数
|
||||
* @param weComMsgParams 消息配置参数
|
||||
* @param: sendContent
|
||||
* @return java.lang.String
|
||||
*/
|
||||
private JSONObject createWeComMsg(WeComMsgParams weComMsgParams, String sendContent) {
|
||||
JSONObject req = new JSONObject();
|
||||
String msgType = weComMsgParams.getMsgType();
|
||||
req.put("msgtype", msgType);
|
||||
switch (msgType) {
|
||||
case "text":
|
||||
JSONObject text = new JSONObject();
|
||||
text.put("content", sendContent);
|
||||
req.put("text", text);
|
||||
break;
|
||||
case "markdown":
|
||||
JSONObject markdown = new JSONObject();
|
||||
markdown.put("content", sendContent);
|
||||
req.put("markdown", markdown);
|
||||
break;
|
||||
case "news":
|
||||
JSONObject articles = new JSONObject();
|
||||
articles.put("title", weComMsgParams.getTitle());
|
||||
articles.put("description", sendContent);
|
||||
articles.put("url", weComMsgParams.getUrl());
|
||||
articles.put("picurl", weComMsgParams.getPicUrl());
|
||||
JSONObject news = new JSONObject();
|
||||
news.put("articles", articles);
|
||||
req.put("news", news);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return req;
|
||||
}
|
||||
|
||||
/**
|
||||
* 小程序发送
|
||||
* @param notifyVO 发送vo类
|
||||
* @return com.fastbee.common.core.notify.NotifySendResponse
|
||||
*/
|
||||
private NotifySendResponse weChatMiniSend(NotifyVO notifyVO) {
|
||||
// 微信小程序
|
||||
NotifySendResponse notifySendResponse = new NotifySendResponse();
|
||||
if (StringUtils.isEmpty(notifyVO.getSendAccount())) {
|
||||
notifySendResponse.setStatus(0);
|
||||
notifySendResponse.setResultContent("发送用户id为空,请先配置发送用户id!");
|
||||
return notifySendResponse;
|
||||
}
|
||||
LinkedHashMap<String, String> map = notifyVO.getMap();
|
||||
LinkedHashMap<String,String> mapVariable = new LinkedHashMap<>();
|
||||
Map<String, Object> sendMap = new HashMap<>(5);
|
||||
for (Map.Entry<String, String> m : map.entrySet()) {
|
||||
sendMap.put(m.getKey(), new TemplateDataVo(m.getValue()));
|
||||
mapVariable.put(m.getKey() + ".DATA", m.getValue());
|
||||
}
|
||||
List<String> userIdList = StringUtils.str2List(notifyVO.getSendAccount(), ",", true, true);
|
||||
List<String> resultContentList = new ArrayList<>();
|
||||
for (String userId : userIdList) {
|
||||
WeChatMiniPushVO weChatMiniPushVO = this.createWeChatMiniPushVO(notifyVO.getNotifyChannel(), notifyVO.getNotifyTemplate(), Long.valueOf(userId));
|
||||
if (Objects.isNull(weChatMiniPushVO)) {
|
||||
resultContentList.add("userId:[" + userId + "],status:[0],resultContent:[获取微信小程序推送配置信息失败!]");
|
||||
notifySendResponse.setStatus(0);
|
||||
continue;
|
||||
}
|
||||
if (StringUtils.isNotEmpty(weChatMiniPushVO.getErrorMsg())) {
|
||||
resultContentList.add("userId:[" + userId + "],status:[0],resultContent:[" + weChatMiniPushVO.getErrorMsg() + "]");
|
||||
notifySendResponse.setStatus(0);
|
||||
continue;
|
||||
}
|
||||
WxMssVo wxMssVo = weChatMiniPushVO.getWxMssVo();
|
||||
wxMssVo.setData(sendMap);
|
||||
notifySendResponse = this.weChatPostPush(JSON.toJSONString(wxMssVo), weChatMiniPushVO.getUrl());
|
||||
resultContentList.add("userId:[" + userId + "],status:[" + notifySendResponse.getStatus() +"],resultContent:[" + notifySendResponse.getResultContent() + "]");
|
||||
}
|
||||
String content = JSONObject.parseObject(notifyVO.getNotifyTemplate().getMsgParams()).get("content").toString();
|
||||
String sendContent = StringUtils.strReplaceVariable("{{", "}}", content, mapVariable);
|
||||
notifySendResponse.setSendContent(sendContent);
|
||||
notifySendResponse.setResultContent(StringUtils.join(resultContentList, "; "));
|
||||
return notifySendResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* 推送消息给指定的用户 --微信小程序服务号推送
|
||||
* @param json 推送参数
|
||||
* @return 推送结果
|
||||
*/
|
||||
@Override
|
||||
public NotifySendResponse weChatPostPush(String json, String url) {
|
||||
NotifySendResponse notifySendResponse = new NotifySendResponse();
|
||||
if(restTemplate==null){
|
||||
restTemplate = new RestTemplate();
|
||||
}
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
|
||||
headers.setContentType(type);
|
||||
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
|
||||
HttpEntity<String> httpEntity = new HttpEntity<>(json, headers);
|
||||
ResponseEntity<String> responseEntity =
|
||||
restTemplate.postForEntity(url, httpEntity, String.class);
|
||||
log.warn("小程序推送结果={}", responseEntity.getBody());
|
||||
String response = responseEntity.getBody();
|
||||
notifySendResponse.setStatus("0".equals(JSONObject.parseObject(response).get("errcode").toString()) ? 1 : 0);
|
||||
notifySendResponse.setResultContent(response);
|
||||
return notifySendResponse;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WeChatMiniPushVO createWeChatMiniPushVO(NotifyChannel notifyChannel, NotifyTemplate notifyTemplate, Long userId) {
|
||||
WeChatMiniPushVO weChatMiniPushVO = new WeChatMiniPushVO();
|
||||
//获取微信与用户关联信息
|
||||
SocialUser socialUser = socialUserService.selectByUserIdAndSourceClient(userId, SocialPlatformType.WECHAT_OPEN_MINI_PROGRAM.sourceClient);
|
||||
if (Objects.isNull(socialUser) || StringUtils.isEmpty(socialUser.getOpenId())) {
|
||||
weChatMiniPushVO.setErrorMsg("该用户未绑定微信小程序,请先绑定后重试");
|
||||
return weChatMiniPushVO;
|
||||
}
|
||||
//获取openId
|
||||
String openId = socialUser.getOpenId();
|
||||
//拼接推送的模版
|
||||
WxMssVo wxMssVo = new WxMssVo();
|
||||
//用户openid
|
||||
wxMssVo.setTouser(openId);
|
||||
if (notifyTemplate == null) {
|
||||
weChatMiniPushVO.setErrorMsg("推送模板为空,请先配置微信小程序推送模板");
|
||||
return weChatMiniPushVO;
|
||||
}
|
||||
//获取微信服务号推送的配置参数
|
||||
if (notifyChannel == null) {
|
||||
weChatMiniPushVO.setErrorMsg("推送渠道为空,请检查微信小程序推送渠道");
|
||||
return weChatMiniPushVO;
|
||||
}
|
||||
WeChatConfigParams weChatConfigParams = JSONObject.parseObject(notifyChannel.getConfigContent(), WeChatConfigParams.class);
|
||||
if (StringUtils.isEmpty(weChatConfigParams.getAppId()) || StringUtils.isEmpty(weChatConfigParams.getAppSecret())) {
|
||||
weChatMiniPushVO.setErrorMsg("微信小程序渠道配置信息为空,请先配置!");
|
||||
return weChatMiniPushVO;
|
||||
}
|
||||
//获取access_token
|
||||
WeChatAppResult weChatAppResult = WechatUtils.getAccessToken(weChatConfigParams.getAppId(), weChatConfigParams.getAppSecret());
|
||||
if (weChatAppResult == null || StringUtils.isEmpty(weChatAppResult.getAccessToken())) {
|
||||
weChatMiniPushVO.setErrorMsg("获取用户调用凭据失败,请重新登录!");
|
||||
return weChatMiniPushVO;
|
||||
}
|
||||
//微信推送URL
|
||||
String url = FastBeeConstant.URL.WX_MINI_PROGRAM_PUSH_URL_PREFIX + "?access_token=" + weChatAppResult.getAccessToken();
|
||||
WechatMsgParams msgParams = JSONObject.parseObject(notifyTemplate.getMsgParams(), WechatMsgParams.class);
|
||||
//模版id
|
||||
wxMssVo.setTemplateId(msgParams.getTemplateId());
|
||||
//推送路径
|
||||
if (StringUtils.isNotEmpty(msgParams.getRedirectUrl())){
|
||||
wxMssVo.setPage(msgParams.getRedirectUrl());
|
||||
}
|
||||
weChatMiniPushVO.setWxMssVo(wxMssVo);
|
||||
weChatMiniPushVO.setUrl(url);
|
||||
return weChatMiniPushVO;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.fastbee.notify.core.wechat.vo;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class TemplateDataVo {
|
||||
|
||||
/*微信文档中要求的格式 "data": { "name01": {"value": "某某"},"thing01": {"value": "广州至北京"
|
||||
} ,"date01": {"value": "2018-01-01"}
|
||||
}*/
|
||||
@JSONField(name = "value")
|
||||
private String value;
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.fastbee.notify.core.wechat.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author fastb
|
||||
* @version 1.0
|
||||
* @description: 获取微信小程序服务通知推送类,推送内容变量参数需自己组装
|
||||
* @date 2023-12-28 16:38
|
||||
*/
|
||||
@Data
|
||||
public class WeChatMiniPushVO {
|
||||
|
||||
private WxMssVo wxMssVo;
|
||||
|
||||
private String url;
|
||||
|
||||
private String errorMsg;
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
package com.fastbee.notify.core.wechat.vo;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author fastb
|
||||
* @version 1.0
|
||||
* @description: 微信公众号推送参数
|
||||
* @date 2024-03-09 14:10
|
||||
*/
|
||||
@Data
|
||||
public class WeChatPublicAccountPushVO {
|
||||
/**
|
||||
* 接收者(用户)的 openid
|
||||
*/
|
||||
@JSONField(name = "touser")
|
||||
private String touser;
|
||||
/**
|
||||
* 所需下发的订阅模板id
|
||||
*/
|
||||
@JSONField(name = "template_id")
|
||||
private String templateId;
|
||||
/**
|
||||
* 模板跳转链接(海外账号没有跳转能力)
|
||||
*/
|
||||
@JSONField(name = "url")
|
||||
private String url;
|
||||
/**
|
||||
* 跳小程序所需数据,不需跳小程序可不用传该数据
|
||||
*/
|
||||
@JSONField(name = "miniprogram")
|
||||
private MiniProgram miniProgram;
|
||||
/**
|
||||
* 防重入id。对于同一个openid + client_msg_id, 只发送一条消息,10分钟有效,超过10分钟不保证效果。若无防重入需求,可不填
|
||||
*/
|
||||
@JSONField(name = "client_msg_id")
|
||||
private String clientMsgId;
|
||||
/**
|
||||
* 模板内容,格式形如 { "key1": { "value": any }, "key2": { "value": any } }
|
||||
*/
|
||||
@JSONField(name = "data")
|
||||
private Map<String, Object> data;
|
||||
|
||||
@Data
|
||||
public static class MiniProgram {
|
||||
|
||||
/**
|
||||
* 所需跳转到的小程序appid
|
||||
*/
|
||||
@JSONField(name = "appid")
|
||||
private String appId;
|
||||
|
||||
/**
|
||||
* 所需跳转到小程序的具体页面路径,支持带参数,(示例index?foo=bar),要求该小程序已发布,暂不支持小游戏
|
||||
*/
|
||||
@JSONField(name = "pagepath")
|
||||
private String pagePath;
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package com.fastbee.notify.core.wechat.vo;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/*
|
||||
* 小程序推送所需数据
|
||||
* */
|
||||
@Data
|
||||
public class WxMssVo {
|
||||
/**
|
||||
* 接收者(用户)的 openid
|
||||
*/
|
||||
@JSONField(name = "touser")
|
||||
private String touser;
|
||||
/**
|
||||
* 所需下发的订阅模板id
|
||||
*/
|
||||
@JSONField(name = "template_id")
|
||||
private String templateId;
|
||||
/**
|
||||
* 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转。
|
||||
*/
|
||||
@JSONField(name = "page")
|
||||
private String page = "pages/index/index";
|
||||
/**
|
||||
* 模板内容,格式形如 { "key1": { "value": any }, "key2": { "value": any } }
|
||||
*/
|
||||
@JSONField(name = "data")
|
||||
private Map<String, Object> data;
|
||||
/**
|
||||
* 跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版
|
||||
*/
|
||||
@JSONField(name = "miniprogram_state")
|
||||
private String miniprogramState;
|
||||
/**
|
||||
* 进入小程序查看”的语言类型,支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),默认为zh_CN
|
||||
*/
|
||||
@JSONField(name = "lang")
|
||||
private String lang;
|
||||
/**
|
||||
* 默认正式版 和 简体中文
|
||||
*/
|
||||
public WxMssVo() {
|
||||
this.miniprogramState = "formal";
|
||||
this.lang = "zh_CN";
|
||||
}
|
||||
}
|
31
fastbee-notify/fastbee-notify-web/pom.xml
Normal file
31
fastbee-notify/fastbee-notify-web/pom.xml
Normal file
@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.fastbee</groupId>
|
||||
<artifactId>fastbee-notify</artifactId>
|
||||
<version>3.8.5</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>fastbee-notify-web</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.fastbee</groupId>
|
||||
<artifactId>fastbee-common</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fastbee</groupId>
|
||||
<artifactId>fastbee-system-service</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -0,0 +1,129 @@
|
||||
package com.fastbee.notify.controller;
|
||||
|
||||
import com.fastbee.common.annotation.Log;
|
||||
import com.fastbee.common.core.controller.BaseController;
|
||||
import com.fastbee.common.core.domain.AjaxResult;
|
||||
import com.fastbee.common.core.page.TableDataInfo;
|
||||
import com.fastbee.common.enums.BusinessType;
|
||||
import com.fastbee.common.utils.poi.ExcelUtil;
|
||||
import com.fastbee.notify.domain.NotifyChannel;
|
||||
import com.fastbee.notify.service.INotifyChannelService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 通知渠道Controller
|
||||
*
|
||||
* @author kerwincui
|
||||
* @date 2023-12-01
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/notify/channel")
|
||||
@Api(tags = "通知渠道")
|
||||
public class NotifyChannelController extends BaseController
|
||||
{
|
||||
@Resource
|
||||
private INotifyChannelService notifyChannelService;
|
||||
|
||||
/**
|
||||
* 查询通知渠道列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('notify:channel:list')")
|
||||
@GetMapping("/list")
|
||||
@ApiOperation(value = "查询通知渠道列表")
|
||||
public TableDataInfo list(NotifyChannel notifyChannel)
|
||||
{
|
||||
startPage();
|
||||
List<NotifyChannel> list = notifyChannelService.selectNotifyChannelList(notifyChannel);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出通知渠道列表
|
||||
*/
|
||||
@ApiOperation(value = "导出通知渠道列表")
|
||||
@PreAuthorize("@ss.hasPermi('notify:channel:export')")
|
||||
@Log(title = "通知渠道", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, NotifyChannel notifyChannel)
|
||||
{
|
||||
List<NotifyChannel> list = notifyChannelService.selectNotifyChannelList(notifyChannel);
|
||||
ExcelUtil<NotifyChannel> util = new ExcelUtil<NotifyChannel>(NotifyChannel.class);
|
||||
util.exportExcel(response, list, "通知渠道数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取通知渠道详细信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('notify:channel:query')")
|
||||
@GetMapping(value = "/{id}")
|
||||
@ApiOperation(value = "获取通知渠道详细信息")
|
||||
public AjaxResult getInfo(@PathVariable("id") Long id)
|
||||
{
|
||||
return success(notifyChannelService.selectNotifyChannelById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增通知渠道
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('notify:channel:add')")
|
||||
@Log(title = "通知渠道", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
@ApiOperation(value = "新增通知渠道")
|
||||
public AjaxResult add(@RequestBody NotifyChannel notifyChannel)
|
||||
{
|
||||
return toAjax(notifyChannelService.insertNotifyChannel(notifyChannel));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改通知渠道
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('notify:channel:edit')")
|
||||
@Log(title = "通知渠道", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
@ApiOperation(value = "修改通知渠道")
|
||||
public AjaxResult edit(@RequestBody NotifyChannel notifyChannel)
|
||||
{
|
||||
return toAjax(notifyChannelService.updateNotifyChannel(notifyChannel));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除通知渠道
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('notify:channel:remove')")
|
||||
@Log(title = "通知渠道", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
@ApiOperation(value = "删除通知渠道")
|
||||
public AjaxResult remove(@PathVariable Long[] ids)
|
||||
{
|
||||
return toAjax(notifyChannelService.deleteNotifyChannelByIds(ids));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询通知渠道和服务商
|
||||
* @return 结果
|
||||
*/
|
||||
@GetMapping("/listChannel")
|
||||
@ApiOperation(value = "查询通知渠道和服务商")
|
||||
public AjaxResult listChannel() {
|
||||
return AjaxResult.success(notifyChannelService.listChannel());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取消息通知渠道参数信息
|
||||
* @param channelType 渠道类型
|
||||
* @param: provider 服务商
|
||||
* @return com.fastbee.common.core.domain.AjaxResult
|
||||
*/
|
||||
@GetMapping(value = "/getConfigContent")
|
||||
@ApiOperation("获取渠道参数配置")
|
||||
public AjaxResult msgParams(String channelType, String provider) {
|
||||
return success(notifyChannelService.getConfigContent(channelType, provider));
|
||||
}
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
package com.fastbee.notify.controller;
|
||||
|
||||
import com.fastbee.common.annotation.Log;
|
||||
import com.fastbee.common.core.controller.BaseController;
|
||||
import com.fastbee.common.core.domain.AjaxResult;
|
||||
import com.fastbee.common.core.page.TableDataInfo;
|
||||
import com.fastbee.common.enums.BusinessType;
|
||||
import com.fastbee.common.utils.poi.ExcelUtil;
|
||||
import com.fastbee.notify.domain.NotifyLog;
|
||||
import com.fastbee.notify.service.INotifyLogService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 通知日志Controller
|
||||
*
|
||||
* @author fastbee
|
||||
* @date 2023-12-16
|
||||
*/
|
||||
@Api(tags = "通知日志")
|
||||
@RestController
|
||||
@RequestMapping("/notify/log")
|
||||
public class NotifyLogController extends BaseController
|
||||
{
|
||||
@Resource
|
||||
private INotifyLogService notifyLogService;
|
||||
|
||||
/**
|
||||
* 查询通知日志列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('notify:log:list')")
|
||||
@ApiOperation(value = "查询通知日志列表")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(NotifyLog notifyLog)
|
||||
{
|
||||
startPage();
|
||||
List<NotifyLog> list = notifyLogService.selectNotifyLogList(notifyLog);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出通知日志列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('notify:log:export')")
|
||||
@Log(title = "通知日志", businessType = BusinessType.EXPORT)
|
||||
@ApiOperation(value = "导出通知日志列表")
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, NotifyLog notifyLog)
|
||||
{
|
||||
List<NotifyLog> list = notifyLogService.selectNotifyLogList(notifyLog);
|
||||
ExcelUtil<NotifyLog> util = new ExcelUtil<NotifyLog>(NotifyLog.class);
|
||||
util.exportExcel(response, list, "通知日志数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取通知日志详细信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('notify:log:query')")
|
||||
@ApiOperation(value = "获取通知日志详细信息")
|
||||
@GetMapping(value = "/{id}")
|
||||
public AjaxResult getInfo(@PathVariable("id") Long id)
|
||||
{
|
||||
return success(notifyLogService.selectNotifyLogById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增通知日志
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('notify:log:add')")
|
||||
@Log(title = "通知日志", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody NotifyLog notifyLog)
|
||||
{
|
||||
return toAjax(notifyLogService.insertNotifyLog(notifyLog));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改通知日志
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('notify:log:edit')")
|
||||
@Log(title = "通知日志", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody NotifyLog notifyLog)
|
||||
{
|
||||
return toAjax(notifyLogService.updateNotifyLog(notifyLog));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除通知日志
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('notify:log:remove')")
|
||||
@Log(title = "通知日志", businessType = BusinessType.DELETE)
|
||||
@ApiOperation(value = "批量删除通知日志")
|
||||
@DeleteMapping("/{ids}")
|
||||
public AjaxResult remove(@PathVariable Long[] ids)
|
||||
{
|
||||
return toAjax(notifyLogService.deleteNotifyLogByIds(ids));
|
||||
}
|
||||
}
|
@ -0,0 +1,187 @@
|
||||
package com.fastbee.notify.controller;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.fastbee.common.annotation.Log;
|
||||
import com.fastbee.common.core.controller.BaseController;
|
||||
import com.fastbee.common.core.domain.AjaxResult;
|
||||
import com.fastbee.common.core.domain.entity.SysUser;
|
||||
import com.fastbee.common.core.page.TableDataInfo;
|
||||
import com.fastbee.common.enums.BusinessType;
|
||||
import com.fastbee.common.enums.NotifyChannelProviderEnum;
|
||||
import com.fastbee.common.utils.MessageUtils;
|
||||
import com.fastbee.common.utils.poi.ExcelUtil;
|
||||
import com.fastbee.notify.domain.NotifyTemplate;
|
||||
import com.fastbee.notify.service.INotifyTemplateService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 通知模版Controller
|
||||
*
|
||||
* @author kerwincui
|
||||
* @date 2023-12-01
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/notify/template")
|
||||
@Api(tags = "通知模板配置")
|
||||
public class NotifyTemplateController extends BaseController {
|
||||
|
||||
@Resource
|
||||
private INotifyTemplateService notifyTemplateService;
|
||||
|
||||
/**
|
||||
* 查询通知模版列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('notify:template:list')")
|
||||
@GetMapping("/list")
|
||||
@ApiOperation("查询通知模版列表")
|
||||
public TableDataInfo list(NotifyTemplate notifyTemplate) {
|
||||
startPage();
|
||||
List<NotifyTemplate> list = notifyTemplateService.selectNotifyTemplateList(notifyTemplate);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出通知模版列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('notify:template:export')")
|
||||
@Log(title = "通知模版", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
@ApiOperation("导出通知模版列表")
|
||||
public void export(HttpServletResponse response, NotifyTemplate notifyTemplate) {
|
||||
List<NotifyTemplate> list = notifyTemplateService.selectNotifyTemplateList(notifyTemplate);
|
||||
ExcelUtil<NotifyTemplate> util = new ExcelUtil<NotifyTemplate>(NotifyTemplate.class);
|
||||
util.exportExcel(response, list, "通知模版数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取通知模版详细信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('notify:template:query')")
|
||||
@GetMapping(value = "/{id}")
|
||||
@ApiOperation("获取通知模版详细信息")
|
||||
public AjaxResult getInfo(@PathVariable("id") Long id) {
|
||||
return success(notifyTemplateService.selectNotifyTemplateById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增通知模版
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('notify:template:add')")
|
||||
@Log(title = "通知模版", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
@ApiOperation("新增通知模版")
|
||||
public AjaxResult add(@RequestBody NotifyTemplate notifyTemplate) {
|
||||
return notifyTemplateService.insertNotifyTemplate(notifyTemplate);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改通知模版
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('notify:template:edit')")
|
||||
@Log(title = "通知模版", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
@ApiOperation("修改通知模版")
|
||||
public AjaxResult edit(@RequestBody NotifyTemplate notifyTemplate) {
|
||||
return notifyTemplateService.updateNotifyTemplate(notifyTemplate);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除通知模版
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('notify:template:remove')")
|
||||
@Log(title = "通知模版", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
@ApiOperation("删除通知模版")
|
||||
public AjaxResult remove(@PathVariable Long[] ids) {
|
||||
return toAjax(notifyTemplateService.deleteNotifyTemplateByIds(ids));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取消息通知模版参数信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('notify:template:query')")
|
||||
@GetMapping(value = "/msgParams")
|
||||
@ApiOperation("获取模板参数配置")
|
||||
public AjaxResult msgParams(Long channelId, String msgType) {
|
||||
return success(notifyTemplateService.getNotifyMsgParams(channelId, msgType));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取通知模版详细信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('notify:template:query')")
|
||||
@GetMapping(value = "/getUsable")
|
||||
@ApiOperation("获取同一业务的模板是否有可用的")
|
||||
public AjaxResult getUsable(NotifyTemplate notifyTemplate) {
|
||||
return success(notifyTemplateService.countNormalTemplate(notifyTemplate));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 修改通知模版-更新选择的为可用,其他为不可用
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('notify:template:edit')")
|
||||
@PostMapping("/updateState")
|
||||
@ApiOperation("修改模版启用状态")
|
||||
public AjaxResult updateState(@RequestBody NotifyTemplate notifyTemplate) {
|
||||
notifyTemplateService.updateTemplateStatus(notifyTemplate);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取消息通知模版参数变量
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('notify:template:query')")
|
||||
@GetMapping(value = "/listVariables")
|
||||
@ApiOperation("获取模板内容变量")
|
||||
public AjaxResult listVariables(Long id, String channelType, String provider) {
|
||||
NotifyTemplate notifyTemplate = notifyTemplateService.selectNotifyTemplateById(id);
|
||||
if (Objects.isNull(notifyTemplate)) {
|
||||
return success();
|
||||
}
|
||||
String content = JSONObject.parseObject(notifyTemplate.getMsgParams()).get("content").toString();
|
||||
Object account = JSONObject.parseObject(notifyTemplate.getMsgParams()).get("sendAccount");
|
||||
NotifyChannelProviderEnum notifyChannelProviderEnum = NotifyChannelProviderEnum.getByChannelTypeAndProvider(channelType, provider);
|
||||
List<String> variables = notifyTemplateService.listVariables(content, notifyChannelProviderEnum);
|
||||
LinkedHashMap<String, String> map = new LinkedHashMap<>();
|
||||
for (String variable : variables) {
|
||||
map.put(variable, "");
|
||||
}
|
||||
JSONObject resultData = new JSONObject();
|
||||
// 企业微信、钉钉机器人没有发送账号
|
||||
if (NotifyChannelProviderEnum.WECHAT_WECOM_ROBOT == notifyChannelProviderEnum ||
|
||||
NotifyChannelProviderEnum.DING_TALK_GROUP_ROBOT == notifyChannelProviderEnum) {
|
||||
if (MapUtils.isEmpty(map)) {
|
||||
return AjaxResult.success(MessageUtils.message("operate.success"), "");
|
||||
} else {
|
||||
resultData.put("variables", JSON.toJSONString(map));
|
||||
return success(resultData);
|
||||
}
|
||||
}
|
||||
resultData.put("sendAccount", Objects.isNull(account) ? "" : account.toString());
|
||||
resultData.put("variables", MapUtils.isNotEmpty(map) ? JSON.toJSONString(map) : "");
|
||||
return success(resultData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取告警微信小程序模板id
|
||||
*/
|
||||
@GetMapping(value = "/getAlertWechatMini")
|
||||
@ApiOperation("获取告警微信小程序模板id")
|
||||
public AjaxResult getAlertWechatMini() {
|
||||
return success(notifyTemplateService.getAlertWechatMini());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package com.fastbee.notify.domain;
|
||||
|
||||
import com.fastbee.common.annotation.Excel;
|
||||
import com.fastbee.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 通知渠道对象 notify_channel
|
||||
*
|
||||
* @author kerwincui
|
||||
* @date 2023-12-01
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class NotifyChannel extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 编号 */
|
||||
private Long id;
|
||||
|
||||
/** 通知名称 */
|
||||
@Excel(name = "通知名称")
|
||||
private String name;
|
||||
|
||||
/** 发送渠道类型 */
|
||||
@Excel(name = "发送渠道类型")
|
||||
private String channelType;
|
||||
|
||||
/** 服务商 */
|
||||
@Excel(name = "服务商")
|
||||
private String provider;
|
||||
|
||||
/** 配置内容 */
|
||||
@Excel(name = "配置内容")
|
||||
private String configContent;
|
||||
|
||||
/** 租户id */
|
||||
private Long tenantId;
|
||||
|
||||
/** 租户名称 */
|
||||
private String tenantName;
|
||||
|
||||
/** 逻辑删除标识 */
|
||||
private Integer delFlag;
|
||||
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package com.fastbee.notify.domain;
|
||||
|
||||
import com.fastbee.common.annotation.Excel;
|
||||
import com.fastbee.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 通知日志对象 notify_log
|
||||
*
|
||||
* @author fastbee
|
||||
* @date 2023-12-16
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class NotifyLog extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 编号 */
|
||||
private Long id;
|
||||
|
||||
/** 通知模版编号 */
|
||||
@Excel(name = "通知模版编号")
|
||||
private Long notifyTemplateId;
|
||||
|
||||
/** 渠道编号 */
|
||||
@Excel(name = "渠道编号")
|
||||
private Long channelId;
|
||||
|
||||
/** 消息内容 */
|
||||
@Excel(name = "消息内容")
|
||||
private String msgContent;
|
||||
|
||||
/** 发送账号 */
|
||||
@Excel(name = "发送账号")
|
||||
private String sendAccount;
|
||||
|
||||
/** 发送状态 */
|
||||
@Excel(name = "发送状态")
|
||||
private Integer sendStatus;
|
||||
|
||||
/** 返回内容 */
|
||||
@Excel(name = "返回内容")
|
||||
private String resultContent;
|
||||
|
||||
/** 逻辑删除标识 */
|
||||
private Integer delFlag;
|
||||
|
||||
/** 渠道名称 */
|
||||
private String channelName;
|
||||
|
||||
/** 模板名称 */
|
||||
private String templateName;
|
||||
|
||||
/** 租户id */
|
||||
private Long tenantId;
|
||||
|
||||
/** 租户名称 */
|
||||
private String tenantName;
|
||||
/** 业务编码 */
|
||||
@Excel(name = "业务编码")
|
||||
private String serviceCode;
|
||||
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package com.fastbee.notify.domain;
|
||||
|
||||
import com.fastbee.common.annotation.Excel;
|
||||
import com.fastbee.common.core.domain.BaseEntity;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 通知模版对象 notify_template
|
||||
*
|
||||
* @author kerwincui
|
||||
* @date 2023-12-01
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class NotifyTemplate extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 编号 */
|
||||
private Long id;
|
||||
|
||||
/** 模版名称 */
|
||||
@Excel(name = "模版名称")
|
||||
private String name;
|
||||
|
||||
/** 通知渠道 */
|
||||
@Excel(name = "通知渠道")
|
||||
private Long channelId;
|
||||
|
||||
/** 业务编码 */
|
||||
@Excel(name = "业务编码")
|
||||
private String serviceCode;
|
||||
|
||||
@ApiModelProperty("模版配置参数")
|
||||
private String msgParams;
|
||||
|
||||
/** 发送账号 */
|
||||
@Excel(name = "是否启用,0-否 1-是")
|
||||
private Integer status;
|
||||
|
||||
/** 逻辑删除标识 */
|
||||
private Integer delFlag;
|
||||
|
||||
private String channelName;
|
||||
|
||||
/** 发送渠道类型 */
|
||||
@Excel(name = "发送渠道类型")
|
||||
private String channelType;
|
||||
|
||||
/** 服务商 */
|
||||
@Excel(name = "服务商")
|
||||
private String provider;
|
||||
|
||||
/** 租户id */
|
||||
private Long tenantId;
|
||||
|
||||
/** 租户名称 */
|
||||
private String tenantName;
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package com.fastbee.notify.mapper;
|
||||
|
||||
import com.fastbee.notify.domain.NotifyChannel;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 通知渠道Mapper接口
|
||||
*
|
||||
* @author kerwincui
|
||||
* @date 2023-12-01
|
||||
*/
|
||||
public interface NotifyChannelMapper
|
||||
{
|
||||
/**
|
||||
* 查询通知渠道
|
||||
*
|
||||
* @param id 通知渠道主键
|
||||
* @return 通知渠道
|
||||
*/
|
||||
public NotifyChannel selectNotifyChannelById(Long id);
|
||||
|
||||
/**
|
||||
* 查询通知渠道列表
|
||||
*
|
||||
* @param notifyChannel 通知渠道
|
||||
* @return 通知渠道集合
|
||||
*/
|
||||
public List<NotifyChannel> selectNotifyChannelList(NotifyChannel notifyChannel);
|
||||
|
||||
/**
|
||||
* 新增通知渠道
|
||||
*
|
||||
* @param notifyChannel 通知渠道
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertNotifyChannel(NotifyChannel notifyChannel);
|
||||
|
||||
/**
|
||||
* 修改通知渠道
|
||||
*
|
||||
* @param notifyChannel 通知渠道
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateNotifyChannel(NotifyChannel notifyChannel);
|
||||
|
||||
/**
|
||||
* 删除通知渠道
|
||||
*
|
||||
* @param id 通知渠道主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteNotifyChannelById(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除通知渠道
|
||||
*
|
||||
* @param ids 需要删除的数据主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteNotifyChannelByIds(Long[] ids);
|
||||
|
||||
/**
|
||||
* 批量查询通知渠道
|
||||
* @param idList 主键id集合
|
||||
* @return java.util.List<com.fastbee.notify.domain.NotifyChannel>
|
||||
*/
|
||||
List<NotifyChannel> selectNotifyChannelByIds(@Param("idList") List<Long> idList);
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
package com.fastbee.notify.mapper;
|
||||
|
||||
import com.fastbee.notify.domain.NotifyLog;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 通知日志Mapper接口
|
||||
*
|
||||
* @author fastbee
|
||||
* @date 2023-12-16
|
||||
*/
|
||||
public interface NotifyLogMapper
|
||||
{
|
||||
/**
|
||||
* 查询通知日志
|
||||
*
|
||||
* @param id 通知日志主键
|
||||
* @return 通知日志
|
||||
*/
|
||||
public NotifyLog selectNotifyLogById(Long id);
|
||||
|
||||
/**
|
||||
* 查询通知日志列表
|
||||
*
|
||||
* @param notifyLog 通知日志
|
||||
* @return 通知日志集合
|
||||
*/
|
||||
public List<NotifyLog> selectNotifyLogList(NotifyLog notifyLog);
|
||||
|
||||
/**
|
||||
* 新增通知日志
|
||||
*
|
||||
* @param notifyLog 通知日志
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertNotifyLog(NotifyLog notifyLog);
|
||||
|
||||
/**
|
||||
* 修改通知日志
|
||||
*
|
||||
* @param notifyLog 通知日志
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateNotifyLog(NotifyLog notifyLog);
|
||||
|
||||
/**
|
||||
* 删除通知日志
|
||||
*
|
||||
* @param id 通知日志主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteNotifyLogById(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除通知日志
|
||||
*
|
||||
* @param ids 需要删除的数据主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteNotifyLogByIds(Long[] ids);
|
||||
}
|
@ -0,0 +1,112 @@
|
||||
package com.fastbee.notify.mapper;
|
||||
|
||||
import com.fastbee.notify.domain.NotifyTemplate;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 通知模版Mapper接口
|
||||
*
|
||||
* @author kerwincui
|
||||
* @date 2023-12-01
|
||||
*/
|
||||
public interface NotifyTemplateMapper
|
||||
{
|
||||
/**
|
||||
* 查询通知模版
|
||||
*
|
||||
* @param id 通知模版主键
|
||||
* @return 通知模版
|
||||
*/
|
||||
public NotifyTemplate selectNotifyTemplateById(Long id);
|
||||
|
||||
/**
|
||||
* 查询通知模版列表
|
||||
*
|
||||
* @param notifyTemplate 通知模版
|
||||
* @return 通知模版集合
|
||||
*/
|
||||
public List<NotifyTemplate> selectNotifyTemplateList(NotifyTemplate notifyTemplate);
|
||||
|
||||
/**
|
||||
* 查询同一业务已启用的模板
|
||||
* @param notifyTemplate
|
||||
* @return
|
||||
*/
|
||||
public Integer selectEnableNotifyTemplateCount(NotifyTemplate notifyTemplate);
|
||||
|
||||
/**
|
||||
* 新增通知模版
|
||||
*
|
||||
* @param notifyTemplate 通知模版
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertNotifyTemplate(NotifyTemplate notifyTemplate);
|
||||
|
||||
/**
|
||||
* 修改通知模版
|
||||
*
|
||||
* @param notifyTemplate 通知模版
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateNotifyTemplate(NotifyTemplate notifyTemplate);
|
||||
|
||||
/**
|
||||
* 批量更新渠道状态
|
||||
* @param ids ids
|
||||
* @return
|
||||
*/
|
||||
public int updateNotifyBatch(@Param("ids") List<Long> ids, @Param("status") Integer status);
|
||||
|
||||
/**
|
||||
* 删除通知模版
|
||||
*
|
||||
* @param id 通知模版主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteNotifyTemplateById(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除通知模版
|
||||
*
|
||||
* @param ids 需要删除的数据主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteNotifyTemplateByIds(Long[] ids);
|
||||
|
||||
/**
|
||||
* 根据业务编码查询启用模板
|
||||
* @param notifyTemplate 通知模板
|
||||
* @return com.fastbee.notify.domain.NotifyTemplate
|
||||
*/
|
||||
NotifyTemplate selectOnlyEnable(NotifyTemplate notifyTemplate);
|
||||
|
||||
/**
|
||||
* @description: 批量删除通知模板
|
||||
* @param: ids 渠道id数组
|
||||
* @return: void
|
||||
*/
|
||||
void deleteNotifyTemplateByChannelIds(Long[] channelIds);
|
||||
|
||||
/**
|
||||
* @description: 查询通知模板
|
||||
* @param: templateIdList
|
||||
* @return: java.util.List<com.fastbee.notify.domain.NotifyTemplate>
|
||||
*/
|
||||
List<NotifyTemplate> selectNotifyTemplateByIds(@Param("idList") List<Long> idList);
|
||||
|
||||
/**
|
||||
* 根据渠道id查询模板
|
||||
* @param channelId 渠道id
|
||||
* @return java.util.List<com.fastbee.notify.domain.NotifyTemplate>
|
||||
*/
|
||||
List<NotifyTemplate> selectNotifyTemplateByChannelId(Long channelId);
|
||||
|
||||
/**
|
||||
* 根据场景ID批量删除告警场景
|
||||
* @param notifyTemplateIds
|
||||
* @return
|
||||
*/
|
||||
public int deleteAlertNotifyTemplateByNotifyTemplateIds(Long[] notifyTemplateIds);
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
package com.fastbee.notify.service;
|
||||
|
||||
import com.fastbee.common.core.notify.NotifyConfigVO;
|
||||
import com.fastbee.notify.domain.NotifyChannel;
|
||||
import com.fastbee.notify.vo.ChannelProviderVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 通知渠道Service接口
|
||||
*
|
||||
* @author kerwincui
|
||||
* @date 2023-12-01
|
||||
*/
|
||||
public interface INotifyChannelService
|
||||
{
|
||||
/**
|
||||
* 查询通知渠道
|
||||
*
|
||||
* @param id 通知渠道主键
|
||||
* @return 通知渠道
|
||||
*/
|
||||
public NotifyChannel selectNotifyChannelById(Long id);
|
||||
|
||||
/**
|
||||
* 查询通知渠道列表
|
||||
*
|
||||
* @param notifyChannel 通知渠道
|
||||
* @return 通知渠道集合
|
||||
*/
|
||||
public List<NotifyChannel> selectNotifyChannelList(NotifyChannel notifyChannel);
|
||||
|
||||
/**
|
||||
* 新增通知渠道
|
||||
*
|
||||
* @param notifyChannel 通知渠道
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertNotifyChannel(NotifyChannel notifyChannel);
|
||||
|
||||
/**
|
||||
* 修改通知渠道
|
||||
*
|
||||
* @param notifyChannel 通知渠道
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateNotifyChannel(NotifyChannel notifyChannel);
|
||||
|
||||
/**
|
||||
* 批量删除通知渠道
|
||||
*
|
||||
* @param ids 需要删除的通知渠道主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteNotifyChannelByIds(Long[] ids);
|
||||
|
||||
/**
|
||||
* 删除通知渠道信息
|
||||
*
|
||||
* @param id 通知渠道主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteNotifyChannelById(Long id);
|
||||
|
||||
/**
|
||||
* 查询通知渠道和服务商
|
||||
* @return
|
||||
*/
|
||||
List<ChannelProviderVO> listChannel();
|
||||
|
||||
/**
|
||||
* 获取消息通知渠道参数信息
|
||||
* @param channelType 渠道类型
|
||||
* @param: provider 服务商
|
||||
* @return 结果集
|
||||
*/
|
||||
List<NotifyConfigVO> getConfigContent(String channelType, String provider);
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
package com.fastbee.notify.service;
|
||||
|
||||
import com.fastbee.notify.domain.NotifyLog;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 通知日志Service接口
|
||||
*
|
||||
* @author kerwincui
|
||||
* @date 2023-12-16
|
||||
*/
|
||||
public interface INotifyLogService
|
||||
{
|
||||
/**
|
||||
* 查询通知日志
|
||||
*
|
||||
* @param id 通知日志主键
|
||||
* @return 通知日志
|
||||
*/
|
||||
public NotifyLog selectNotifyLogById(Long id);
|
||||
|
||||
/**
|
||||
* 查询通知日志列表
|
||||
*
|
||||
* @param notifyLog 通知日志
|
||||
* @return 通知日志集合
|
||||
*/
|
||||
public List<NotifyLog> selectNotifyLogList(NotifyLog notifyLog);
|
||||
|
||||
/**
|
||||
* 新增通知日志
|
||||
*
|
||||
* @param notifyLog 通知日志
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertNotifyLog(NotifyLog notifyLog);
|
||||
|
||||
/**
|
||||
* 修改通知日志
|
||||
*
|
||||
* @param notifyLog 通知日志
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateNotifyLog(NotifyLog notifyLog);
|
||||
|
||||
/**
|
||||
* 批量删除通知日志
|
||||
*
|
||||
* @param ids 需要删除的通知日志主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteNotifyLogByIds(Long[] ids);
|
||||
|
||||
/**
|
||||
* 删除通知日志信息
|
||||
*
|
||||
* @param id 通知日志主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteNotifyLogById(Long id);
|
||||
}
|
@ -0,0 +1,117 @@
|
||||
package com.fastbee.notify.service;
|
||||
|
||||
import com.fastbee.common.core.domain.AjaxResult;
|
||||
import com.fastbee.common.core.notify.NotifyConfigVO;
|
||||
import com.fastbee.common.enums.NotifyChannelProviderEnum;
|
||||
import com.fastbee.notify.domain.NotifyTemplate;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 通知模版Service接口
|
||||
*
|
||||
* @author kerwincui
|
||||
* @date 2023-12-01
|
||||
*/
|
||||
public interface INotifyTemplateService
|
||||
{
|
||||
/**
|
||||
* 查询通知模版
|
||||
*
|
||||
* @param id 通知模版主键
|
||||
* @return 通知模版
|
||||
*/
|
||||
public NotifyTemplate selectNotifyTemplateById(Long id);
|
||||
|
||||
/**
|
||||
* 查询通知模版列表
|
||||
*
|
||||
* @param notifyTemplate 通知模版
|
||||
* @return 通知模版集合
|
||||
*/
|
||||
public List<NotifyTemplate> selectNotifyTemplateList(NotifyTemplate notifyTemplate);
|
||||
|
||||
/**
|
||||
* 新增通知模版
|
||||
*
|
||||
* @param notifyTemplate 通知模版
|
||||
* @return 结果
|
||||
*/
|
||||
public AjaxResult insertNotifyTemplate(NotifyTemplate notifyTemplate);
|
||||
|
||||
/**
|
||||
* 修改通知模版
|
||||
*
|
||||
* @param notifyTemplate 通知模版
|
||||
* @return 结果
|
||||
*/
|
||||
public AjaxResult updateNotifyTemplate(NotifyTemplate notifyTemplate);
|
||||
|
||||
/**
|
||||
* 批量删除通知模版
|
||||
*
|
||||
* @param ids 需要删除的通知模版主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteNotifyTemplateByIds(Long[] ids);
|
||||
|
||||
/**
|
||||
* 删除通知模版信息
|
||||
*
|
||||
* @param id 通知模版主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteNotifyTemplateById(Long id);
|
||||
|
||||
/**
|
||||
* 查询某一业务通知通道是否有启动的(业务编码唯一启用一个模板)
|
||||
* @param notifyTemplate 通知模板
|
||||
*/
|
||||
public Integer countNormalTemplate(NotifyTemplate notifyTemplate);
|
||||
|
||||
/**
|
||||
* 更新某一类型为不可用状态,选中的为可用状态
|
||||
* @param notifyTemplate 通知模板
|
||||
*/
|
||||
public void updateTemplateStatus(NotifyTemplate notifyTemplate);
|
||||
|
||||
/**
|
||||
* @description: 查询启用通知模板
|
||||
* @param: serviceCode 业务编码
|
||||
* @return: com.fastbee.notify.domain.NotifyTemplate
|
||||
*/
|
||||
NotifyTemplate selectOnlyEnable(NotifyTemplate notifyTemplate);
|
||||
|
||||
/**
|
||||
* @description: 获取消息通知模版参数信息
|
||||
* @author fastb
|
||||
* @date 2023-12-22 11:01
|
||||
* @version 1.0
|
||||
*/
|
||||
List<NotifyConfigVO> getNotifyMsgParams(Long channelId, String msgType);
|
||||
|
||||
/**
|
||||
* @description: 统一获取模板参数内容变量,调用这个方法
|
||||
* @param: channelId
|
||||
* @return: java.lang.String
|
||||
*/
|
||||
List<String> listVariables(String content, NotifyChannelProviderEnum notifyChannelProviderEnum);
|
||||
|
||||
/**
|
||||
* @description: 获取告警微信小程序模板id
|
||||
* @param:
|
||||
* @return: java.lang.String
|
||||
*/
|
||||
String getAlertWechatMini();
|
||||
|
||||
/**
|
||||
* 获取唯一启用模版查询条件
|
||||
* 短信、语音、邮箱以业务编码+渠道保证唯一启用,微信、钉钉以业务编码+渠道+服务商保证唯一启用
|
||||
* @param: serviceCode
|
||||
* @param: channelType
|
||||
* @param: provider
|
||||
* @return com.fastbee.notify.domain.NotifyTemplate
|
||||
*/
|
||||
NotifyTemplate getEnableQueryCondition(String serviceCode, String channelType, String provider, Long tenantId);
|
||||
|
||||
}
|
@ -0,0 +1,196 @@
|
||||
package com.fastbee.notify.service.impl;
|
||||
|
||||
import com.fastbee.common.core.domain.entity.SysDictData;
|
||||
import com.fastbee.common.core.domain.entity.SysRole;
|
||||
import com.fastbee.common.core.domain.entity.SysUser;
|
||||
import com.fastbee.common.core.notify.NotifyConfigVO;
|
||||
import com.fastbee.common.enums.NotifyChannelProviderEnum;
|
||||
import com.fastbee.common.exception.ServiceException;
|
||||
import com.fastbee.common.utils.DateUtils;
|
||||
import com.fastbee.notify.domain.NotifyChannel;
|
||||
import com.fastbee.notify.domain.NotifyTemplate;
|
||||
import com.fastbee.notify.mapper.NotifyChannelMapper;
|
||||
import com.fastbee.notify.mapper.NotifyTemplateMapper;
|
||||
import com.fastbee.notify.service.INotifyChannelService;
|
||||
import com.fastbee.notify.vo.ChannelProviderVO;
|
||||
import com.fastbee.system.service.ISysDictDataService;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.dromara.sms4j.core.factory.SmsFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.fastbee.common.utils.SecurityUtils.getLoginUser;
|
||||
|
||||
/**
|
||||
* 通知渠道Service业务层处理
|
||||
*
|
||||
* @author kerwincui
|
||||
* @date 2023-12-01
|
||||
*/
|
||||
@Service
|
||||
public class NotifyChannelServiceImpl implements INotifyChannelService
|
||||
{
|
||||
@Resource
|
||||
private NotifyChannelMapper notifyChannelMapper;
|
||||
@Resource
|
||||
private ISysDictDataService sysDictDataService;
|
||||
@Resource
|
||||
private NotifyTemplateMapper notifyTemplateMapper;
|
||||
|
||||
/**
|
||||
* 查询通知渠道
|
||||
*
|
||||
* @param id 通知渠道主键
|
||||
* @return 通知渠道
|
||||
*/
|
||||
@Override
|
||||
public NotifyChannel selectNotifyChannelById(Long id)
|
||||
{
|
||||
return notifyChannelMapper.selectNotifyChannelById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询通知渠道列表
|
||||
*
|
||||
* @param notifyChannel 通知渠道
|
||||
* @return 通知渠道
|
||||
*/
|
||||
@Override
|
||||
public List<NotifyChannel> selectNotifyChannelList(NotifyChannel notifyChannel)
|
||||
{
|
||||
SysUser user = getLoginUser().getUser();
|
||||
// List<SysRole> roles=user.getRoles();
|
||||
// // 租户
|
||||
// if(roles.stream().anyMatch(a-> "tenant".equals(a.getRoleKey()))){
|
||||
// notifyChannel.setTenantId(user.getUserId());
|
||||
// }
|
||||
// 查询所属机构
|
||||
if (null != user.getDeptId()) {
|
||||
notifyChannel.setTenantId(user.getDept().getDeptUserId());
|
||||
} else {
|
||||
notifyChannel.setTenantId(user.getUserId());
|
||||
}
|
||||
return notifyChannelMapper.selectNotifyChannelList(notifyChannel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增通知渠道
|
||||
*
|
||||
* @param notifyChannel 通知渠道
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int insertNotifyChannel(NotifyChannel notifyChannel)
|
||||
{
|
||||
SysUser user = getLoginUser().getUser();
|
||||
if (null == user.getDeptId()) {
|
||||
throw new ServiceException("只允许租户配置");
|
||||
}
|
||||
notifyChannel.setTenantId(user.getDept().getDeptUserId());
|
||||
notifyChannel.setTenantName(user.getDept().getDeptUserName());
|
||||
return notifyChannelMapper.insertNotifyChannel(notifyChannel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改通知渠道
|
||||
*
|
||||
* @param notifyChannel 通知渠道
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int updateNotifyChannel(NotifyChannel notifyChannel)
|
||||
{
|
||||
notifyChannel.setUpdateTime(DateUtils.getNowDate());
|
||||
List<NotifyTemplate> notifyTemplateList = notifyTemplateMapper.selectNotifyTemplateByChannelId(notifyChannel.getId());
|
||||
for (NotifyTemplate notifyTemplate : notifyTemplateList) {
|
||||
SmsFactory.unregister(notifyTemplate.getId().toString());
|
||||
}
|
||||
return notifyChannelMapper.updateNotifyChannel(notifyChannel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除通知渠道
|
||||
*
|
||||
* @param ids 需要删除的通知渠道主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteNotifyChannelByIds(Long[] ids)
|
||||
{
|
||||
int result = notifyChannelMapper.deleteNotifyChannelByIds(ids);
|
||||
// 删除渠道下的模板
|
||||
if (result > 0) {
|
||||
notifyTemplateMapper.deleteNotifyTemplateByChannelIds(ids);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除通知渠道信息
|
||||
*
|
||||
* @param id 通知渠道主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteNotifyChannelById(Long id)
|
||||
{
|
||||
int result = notifyChannelMapper.deleteNotifyChannelById(id);
|
||||
// 删除渠道下的模板
|
||||
if (result > 0) {
|
||||
notifyTemplateMapper.deleteNotifyTemplateByChannelIds(new Long[]{id});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ChannelProviderVO> listChannel() {
|
||||
SysDictData sysDictData = new SysDictData();
|
||||
sysDictData.setDictType("notify_channel_type");
|
||||
sysDictData.setStatus("0");
|
||||
List<SysDictData> parentDataList = sysDictDataService.selectDictDataList(sysDictData);
|
||||
if (CollectionUtils.isEmpty(parentDataList)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<String> dictValueList = parentDataList.stream().map(SysDictData::getDictValue).collect(Collectors.toList());
|
||||
List<String> dictTypeList = new ArrayList<>();
|
||||
for (String s : dictValueList) {
|
||||
dictTypeList.add("notify_channel_" + s + "_provider");
|
||||
}
|
||||
List<SysDictData> childerDataList = sysDictDataService.selectDictDataListByDictTypes(dictTypeList);
|
||||
Map<String, List<SysDictData>> map = childerDataList.stream().collect(Collectors.groupingBy(SysDictData::getDictType));
|
||||
List<ChannelProviderVO> result = new ArrayList<>();
|
||||
for (SysDictData dictData : parentDataList) {
|
||||
ChannelProviderVO channelProviderVO = new ChannelProviderVO();
|
||||
channelProviderVO.setChannelType(dictData.getDictValue());
|
||||
channelProviderVO.setChannelName(dictData.getDictLabel());
|
||||
String key = "notify_channel_" + dictData.getDictValue() + "_provider";
|
||||
if (!map.containsKey(key)) {
|
||||
result.add(channelProviderVO);
|
||||
continue;
|
||||
}
|
||||
List<SysDictData> dataList = map.get(key);
|
||||
List<ChannelProviderVO.Provider> providerList = new ArrayList<>();
|
||||
for (SysDictData data : dataList) {
|
||||
ChannelProviderVO.Provider provider = new ChannelProviderVO.Provider();
|
||||
provider.setProvider(data.getDictValue());
|
||||
provider.setProviderName(data.getDictLabel());
|
||||
provider.setCategory(dictData.getDictValue());
|
||||
providerList.add(provider);
|
||||
}
|
||||
channelProviderVO.setProviderList(providerList);
|
||||
result.add(channelProviderVO);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NotifyConfigVO> getConfigContent(String channelType, String provider) {
|
||||
return NotifyChannelProviderEnum.getConfigContent(Objects.requireNonNull(NotifyChannelProviderEnum.getByChannelTypeAndProvider(channelType, provider)));
|
||||
}
|
||||
}
|
@ -0,0 +1,143 @@
|
||||
package com.fastbee.notify.service.impl;
|
||||
|
||||
import com.fastbee.common.core.domain.entity.SysRole;
|
||||
import com.fastbee.common.core.domain.entity.SysUser;
|
||||
import com.fastbee.common.utils.DateUtils;
|
||||
import com.fastbee.notify.domain.NotifyChannel;
|
||||
import com.fastbee.notify.domain.NotifyLog;
|
||||
import com.fastbee.notify.domain.NotifyTemplate;
|
||||
import com.fastbee.notify.mapper.NotifyChannelMapper;
|
||||
import com.fastbee.notify.mapper.NotifyLogMapper;
|
||||
import com.fastbee.notify.mapper.NotifyTemplateMapper;
|
||||
import com.fastbee.notify.service.INotifyLogService;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.fastbee.common.utils.SecurityUtils.getLoginUser;
|
||||
|
||||
/**
|
||||
* 通知日志Service业务层处理
|
||||
*
|
||||
* @author fastbee
|
||||
* @date 2023-12-16
|
||||
*/
|
||||
@Service
|
||||
public class NotifyLogServiceImpl implements INotifyLogService
|
||||
{
|
||||
@Resource
|
||||
private NotifyLogMapper notifyLogMapper;
|
||||
@Resource
|
||||
private NotifyChannelMapper notifyChannelMapper;
|
||||
@Resource
|
||||
private NotifyTemplateMapper notifyTemplateMapper;
|
||||
|
||||
/**
|
||||
* 查询通知日志
|
||||
*
|
||||
* @param id 通知日志主键
|
||||
* @return 通知日志
|
||||
*/
|
||||
@Override
|
||||
public NotifyLog selectNotifyLogById(Long id)
|
||||
{
|
||||
return notifyLogMapper.selectNotifyLogById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询通知日志列表
|
||||
*
|
||||
* @param notifyLog 通知日志
|
||||
* @return 通知日志
|
||||
*/
|
||||
@Override
|
||||
public List<NotifyLog> selectNotifyLogList(NotifyLog notifyLog)
|
||||
{
|
||||
SysUser user = getLoginUser().getUser();
|
||||
// List<SysRole> roles=user.getRoles();
|
||||
// // 租户
|
||||
// if(roles.stream().anyMatch(a->a.getRoleKey().equals("tenant"))){
|
||||
// notifyLog.setTenantId(user.getUserId());
|
||||
// }
|
||||
// 查询所属机构
|
||||
if (null != user.getDeptId()) {
|
||||
notifyLog.setTenantId(user.getDept().getDeptUserId());
|
||||
} else {
|
||||
notifyLog.setTenantId(user.getUserId());
|
||||
}
|
||||
List<NotifyLog> notifyLogs = notifyLogMapper.selectNotifyLogList(notifyLog);
|
||||
if (CollectionUtils.isEmpty(notifyLogs)) {
|
||||
return notifyLogs;
|
||||
}
|
||||
List<Long> channelIdList = notifyLogs.stream().map(NotifyLog::getChannelId).collect(Collectors.toList());
|
||||
List<NotifyChannel> notifyChannelList = notifyChannelMapper.selectNotifyChannelByIds(channelIdList);
|
||||
Map<Long, NotifyChannel> notifyChannelMap = notifyChannelList.stream().collect(Collectors.toMap(NotifyChannel::getId, Function.identity()));
|
||||
List<Long> templateIdList = notifyLogs.stream().map(NotifyLog::getNotifyTemplateId).collect(Collectors.toList());
|
||||
List<NotifyTemplate> notifyTemplateList = notifyTemplateMapper.selectNotifyTemplateByIds(templateIdList);
|
||||
Map<Long, NotifyTemplate> notifyTemplateMap = notifyTemplateList.stream().collect(Collectors.toMap(NotifyTemplate::getId, Function.identity()));
|
||||
for (NotifyLog log : notifyLogs) {
|
||||
if (notifyChannelMap.containsKey(log.getChannelId())) {
|
||||
log.setChannelName(notifyChannelMap.get(log.getChannelId()).getName());
|
||||
}
|
||||
if (notifyTemplateMap.containsKey(log.getNotifyTemplateId())) {
|
||||
log.setTemplateName(notifyTemplateMap.get(log.getNotifyTemplateId()).getName());
|
||||
}
|
||||
}
|
||||
return notifyLogs;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增通知日志
|
||||
*
|
||||
* @param notifyLog 通知日志
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int insertNotifyLog(NotifyLog notifyLog)
|
||||
{
|
||||
notifyLog.setCreateTime(DateUtils.getNowDate());
|
||||
return notifyLogMapper.insertNotifyLog(notifyLog);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改通知日志
|
||||
*
|
||||
* @param notifyLog 通知日志
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int updateNotifyLog(NotifyLog notifyLog)
|
||||
{
|
||||
notifyLog.setUpdateTime(DateUtils.getNowDate());
|
||||
return notifyLogMapper.updateNotifyLog(notifyLog);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除通知日志
|
||||
*
|
||||
* @param ids 需要删除的通知日志主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteNotifyLogByIds(Long[] ids)
|
||||
{
|
||||
return notifyLogMapper.deleteNotifyLogByIds(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除通知日志信息
|
||||
*
|
||||
* @param id 通知日志主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteNotifyLogById(Long id)
|
||||
{
|
||||
return notifyLogMapper.deleteNotifyLogById(id);
|
||||
}
|
||||
}
|
@ -0,0 +1,288 @@
|
||||
package com.fastbee.notify.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.fastbee.common.core.domain.AjaxResult;
|
||||
import com.fastbee.common.core.domain.entity.SysRole;
|
||||
import com.fastbee.common.core.domain.entity.SysUser;
|
||||
import com.fastbee.common.core.domain.model.LoginUser;
|
||||
import com.fastbee.common.core.notify.NotifyConfigVO;
|
||||
import com.fastbee.common.enums.NotifyChannelEnum;
|
||||
import com.fastbee.common.enums.NotifyChannelProviderEnum;
|
||||
import com.fastbee.common.enums.NotifyServiceCodeEnum;
|
||||
import com.fastbee.common.exception.ServiceException;
|
||||
import com.fastbee.common.utils.DateUtils;
|
||||
import com.fastbee.common.utils.StringUtils;
|
||||
import com.fastbee.notify.domain.NotifyChannel;
|
||||
import com.fastbee.notify.domain.NotifyTemplate;
|
||||
import com.fastbee.notify.mapper.NotifyChannelMapper;
|
||||
import com.fastbee.notify.mapper.NotifyTemplateMapper;
|
||||
import com.fastbee.notify.service.INotifyTemplateService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.sms4j.core.factory.SmsFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.fastbee.common.utils.SecurityUtils.getLoginUser;
|
||||
|
||||
/**
|
||||
* 通知模版Service业务层处理
|
||||
*
|
||||
* @author kerwincui
|
||||
* @date 2023-12-01
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class NotifyTemplateServiceImpl implements INotifyTemplateService {
|
||||
@Resource
|
||||
private NotifyTemplateMapper notifyTemplateMapper;
|
||||
@Resource
|
||||
private NotifyChannelMapper notifyChannelMapper;
|
||||
|
||||
|
||||
/**
|
||||
* 查询通知模版
|
||||
*
|
||||
* @param id 通知模版主键
|
||||
* @return 通知模版
|
||||
*/
|
||||
@Override
|
||||
public NotifyTemplate selectNotifyTemplateById(Long id) {
|
||||
return notifyTemplateMapper.selectNotifyTemplateById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询通知模版列表
|
||||
*
|
||||
* @param notifyTemplate 通知模版
|
||||
* @return 通知模版
|
||||
*/
|
||||
@Override
|
||||
public List<NotifyTemplate> selectNotifyTemplateList(NotifyTemplate notifyTemplate) {
|
||||
SysUser user = getLoginUser().getUser();
|
||||
// List<SysRole> roles=user.getRoles();
|
||||
// // 租户
|
||||
// if(roles.stream().anyMatch(a-> "tenant".equals(a.getRoleKey()))){
|
||||
// notifyTemplate.setTenantId(user.getUserId());
|
||||
// }
|
||||
// 查询所属机构
|
||||
if (null != user.getDeptId()) {
|
||||
notifyTemplate.setTenantId(user.getDept().getDeptUserId());
|
||||
} else {
|
||||
notifyTemplate.setTenantId(user.getUserId());
|
||||
}
|
||||
List<NotifyTemplate> notifyTemplates = notifyTemplateMapper.selectNotifyTemplateList(notifyTemplate);
|
||||
if (org.apache.commons.collections4.CollectionUtils.isEmpty(notifyTemplates)) {
|
||||
return notifyTemplates;
|
||||
}
|
||||
List<Long> collect = notifyTemplates.stream().map(NotifyTemplate::getChannelId).collect(Collectors.toList());
|
||||
List<NotifyChannel> notifyChannelList = notifyChannelMapper.selectNotifyChannelByIds(collect);
|
||||
Map<Long, NotifyChannel> notifyChannelMap = notifyChannelList.stream().collect(Collectors.toMap(NotifyChannel::getId, Function.identity()));
|
||||
for (NotifyTemplate template : notifyTemplates) {
|
||||
if (notifyChannelMap.containsKey(template.getChannelId())) {
|
||||
NotifyChannel notifyChannel = notifyChannelMap.get(template.getChannelId());
|
||||
template.setChannelName(notifyChannel.getName());
|
||||
}
|
||||
}
|
||||
return notifyTemplates;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增通知模版
|
||||
*
|
||||
* @param notifyTemplate 通知模版
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public AjaxResult insertNotifyTemplate(NotifyTemplate notifyTemplate) {
|
||||
SysUser user = getLoginUser().getUser();
|
||||
if (null == user.getDeptId()) {
|
||||
throw new ServiceException("只允许租户配置");
|
||||
}
|
||||
notifyTemplate.setTenantId(user.getDept().getDeptUserId());
|
||||
notifyTemplate.setTenantName(user.getDept().getDeptUserName());
|
||||
notifyTemplate.setCreateTime(DateUtils.getNowDate());
|
||||
return notifyTemplateMapper.insertNotifyTemplate(notifyTemplate) > 0 ? AjaxResult.success() : AjaxResult.error();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改通知模版
|
||||
*
|
||||
* @param notifyTemplate 通知模版
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public AjaxResult updateNotifyTemplate(NotifyTemplate notifyTemplate) {
|
||||
notifyTemplate.setUpdateTime(DateUtils.getNowDate());
|
||||
if (NotifyChannelEnum.SMS.getType().equals(notifyTemplate.getChannelType())) {
|
||||
SmsFactory.unregister(notifyTemplate.getId().toString());
|
||||
}
|
||||
return notifyTemplateMapper.updateNotifyTemplate(notifyTemplate) > 0 ? AjaxResult.success() : AjaxResult.error();
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除通知模版
|
||||
*
|
||||
* @param ids 需要删除的通知模版主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteNotifyTemplateByIds(Long[] ids) {
|
||||
int i = notifyTemplateMapper.deleteNotifyTemplateByIds(ids);
|
||||
if (i > 0) {
|
||||
notifyTemplateMapper.deleteAlertNotifyTemplateByNotifyTemplateIds(ids);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除通知模版信息
|
||||
*
|
||||
* @param id 通知模版主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteNotifyTemplateById(Long id) {
|
||||
int i = notifyTemplateMapper.deleteNotifyTemplateById(id);
|
||||
if (i > 0) {
|
||||
notifyTemplateMapper.deleteAlertNotifyTemplateByNotifyTemplateIds(new Long[]{id});
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询某一业务通知通道是否有启动的(业务编码唯一启用一个模板)
|
||||
* @param notifyTemplate 通知模板
|
||||
*/
|
||||
@Override
|
||||
public Integer countNormalTemplate(NotifyTemplate notifyTemplate){
|
||||
LoginUser loginUser = getLoginUser();
|
||||
assert !Objects.isNull(notifyTemplate.getServiceCode()) : "业务编码不能为空";
|
||||
NotifyTemplate selectOne = this.getEnableQueryCondition(notifyTemplate.getServiceCode(), notifyTemplate.getChannelType(), notifyTemplate.getProvider(), loginUser.getUser().getDept().getDeptUserId());
|
||||
selectOne.setId(notifyTemplate.getId());
|
||||
return notifyTemplateMapper.selectEnableNotifyTemplateCount(selectOne);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取唯一启用模版查询条件
|
||||
* 唯一启用条件:同一业务编码的模板短信、语音、邮箱渠道分别可以启用一个,微信、钉钉渠道下不同服务商分别可以启用一个
|
||||
* @param: serviceCode
|
||||
* @param: channelType
|
||||
* @param: provider
|
||||
* @return com.fastbee.notify.domain.NotifyTemplate
|
||||
*/
|
||||
@Override
|
||||
public NotifyTemplate getEnableQueryCondition(String serviceCode, String channelType, String provider, Long tenantId) {
|
||||
NotifyTemplate notifyTemplate = new NotifyTemplate();
|
||||
notifyTemplate.setServiceCode(serviceCode);
|
||||
notifyTemplate.setStatus(1);
|
||||
notifyTemplate.setTenantId(tenantId);
|
||||
NotifyChannelEnum notifyChannelEnum = NotifyChannelEnum.getNotifyChannelEnum(channelType);
|
||||
switch (Objects.requireNonNull(notifyChannelEnum)) {
|
||||
case SMS:
|
||||
case VOICE:
|
||||
case EMAIL:
|
||||
notifyTemplate.setChannelType(channelType);
|
||||
break;
|
||||
case WECHAT:
|
||||
case DING_TALK:
|
||||
notifyTemplate.setChannelType(channelType);
|
||||
notifyTemplate.setProvider(provider);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return notifyTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新某一类型为不可用状态,选中的为可用状态
|
||||
* @param notifyTemplate 通知模板
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateTemplateStatus(NotifyTemplate notifyTemplate){
|
||||
LoginUser loginUser = getLoginUser();
|
||||
// 查询所有统一类型可用的渠道
|
||||
NotifyTemplate selectEnable = this.getEnableQueryCondition(notifyTemplate.getServiceCode(), notifyTemplate.getChannelType(), notifyTemplate.getProvider(), loginUser.getUser().getDept().getDeptUserId());
|
||||
selectEnable.setId(notifyTemplate.getId());
|
||||
List<NotifyTemplate> notifyTemplateList = this.selectNotifyTemplateList(selectEnable);
|
||||
if (!CollectionUtils.isEmpty(notifyTemplateList)){
|
||||
//如果有同一类型的渠道为可用,要先将更新为不可用
|
||||
List<Long> ids = notifyTemplateList.stream().map(NotifyTemplate::getId).filter(id -> !Objects.equals(id, notifyTemplate.getId())).collect(Collectors.toList());
|
||||
if (!CollectionUtils.isEmpty(ids)) {
|
||||
notifyTemplateMapper.updateNotifyBatch(ids, 0);
|
||||
}
|
||||
}
|
||||
//更新选中的为可用状态
|
||||
NotifyTemplate updateBo = new NotifyTemplate();
|
||||
updateBo.setStatus(1);
|
||||
updateBo.setId(notifyTemplate.getId());
|
||||
notifyTemplateMapper.updateNotifyTemplate(updateBo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NotifyTemplate selectOnlyEnable(NotifyTemplate notifyTemplate) {
|
||||
return notifyTemplateMapper.selectOnlyEnable(notifyTemplate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NotifyConfigVO> getNotifyMsgParams(Long channelId, String msgType) {
|
||||
NotifyChannel notifyChannel = notifyChannelMapper.selectNotifyChannelById(channelId);
|
||||
if (Objects.isNull(notifyChannel)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
NotifyChannelProviderEnum notifyChannelProviderEnum = NotifyChannelProviderEnum.getByChannelTypeAndProvider(notifyChannel.getChannelType(), notifyChannel.getProvider());
|
||||
return NotifyChannelProviderEnum.getMsgParams(notifyChannelProviderEnum, msgType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> listVariables(String content, NotifyChannelProviderEnum notifyChannelProviderEnum) {
|
||||
List<String> variables;
|
||||
switch (Objects.requireNonNull(notifyChannelProviderEnum)) {
|
||||
case WECHAT_MINI_PROGRAM:
|
||||
case WECHAT_PUBLIC_ACCOUNT:
|
||||
variables = StringUtils.getWeChatMiniVariables(content);
|
||||
break;
|
||||
case SMS_TENCENT:
|
||||
case VOICE_TENCENT:
|
||||
variables = StringUtils.getVariables("{}", content);
|
||||
break;
|
||||
case EMAIL_QQ:
|
||||
case EMAIL_163:
|
||||
variables = StringUtils.getVariables("#{}", content);
|
||||
break;
|
||||
default:
|
||||
variables = StringUtils.getVariables("${}", content);
|
||||
break;
|
||||
}
|
||||
return variables;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAlertWechatMini() {
|
||||
NotifyTemplate selectOne = new NotifyTemplate();
|
||||
selectOne.setServiceCode(NotifyServiceCodeEnum.ALERT.getServiceCode()).setChannelType(NotifyChannelProviderEnum.WECHAT_MINI_PROGRAM.getChannelType()).setProvider(NotifyChannelProviderEnum.WECHAT_MINI_PROGRAM.getProvider()).setStatus(1);
|
||||
SysUser user = getLoginUser().getUser();
|
||||
if (null != user.getDeptId()) {
|
||||
selectOne.setTenantId(user.getDept().getDeptUserId());
|
||||
} else {
|
||||
selectOne.setTenantId(1L);
|
||||
}
|
||||
NotifyTemplate notifyTemplate = notifyTemplateMapper.selectOnlyEnable(selectOne);
|
||||
if (notifyTemplate == null || StringUtils.isEmpty(notifyTemplate.getMsgParams())) {
|
||||
return "";
|
||||
}
|
||||
JSONObject jsonObject = JSONObject.parseObject(notifyTemplate.getMsgParams());
|
||||
return jsonObject.get("templateId").toString();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package com.fastbee.notify.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 渠道服务商VO类
|
||||
* @author fastb
|
||||
* @date 2023-12-01 14:06
|
||||
*/
|
||||
@Data
|
||||
public class ChannelProviderVO {
|
||||
|
||||
/**
|
||||
* 渠道类型
|
||||
*/
|
||||
private String channelType;
|
||||
|
||||
/**
|
||||
* 渠道名称
|
||||
*/
|
||||
private String channelName;
|
||||
|
||||
/**
|
||||
* 服务商集合
|
||||
*/
|
||||
private List<Provider> providerList;
|
||||
|
||||
/**
|
||||
* 服务商
|
||||
*/
|
||||
@Data
|
||||
public static class Provider{
|
||||
|
||||
/**
|
||||
* 服务商英文标识
|
||||
*/
|
||||
private String provider;
|
||||
|
||||
/**
|
||||
* 服务商名称
|
||||
*/
|
||||
private String providerName;
|
||||
|
||||
/**
|
||||
* 所属渠道标识
|
||||
*/
|
||||
private String category;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,33 @@
|
||||
package com.fastbee.notify.vo;
|
||||
|
||||
import com.fastbee.common.enums.NotifyChannelProviderEnum;
|
||||
import com.fastbee.notify.domain.NotifyChannel;
|
||||
import com.fastbee.notify.domain.NotifyTemplate;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
/**
|
||||
* @author fastb
|
||||
* @version 1.0
|
||||
* @description: 通知发送参数
|
||||
* @date 2024-01-02 11:10
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class NotifyVO {
|
||||
|
||||
private NotifyChannel notifyChannel;
|
||||
|
||||
private NotifyTemplate notifyTemplate;
|
||||
|
||||
/**
|
||||
* 多个账号用英文逗号隔开 例如:21,51
|
||||
*/
|
||||
private String sendAccount;
|
||||
|
||||
private LinkedHashMap<String,String> map;
|
||||
|
||||
private NotifyChannelProviderEnum notifyChannelProviderEnum;
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.fastbee.notify.mapper.NotifyChannelMapper">
|
||||
|
||||
<resultMap type="NotifyChannel" id="NotifyChannelResult">
|
||||
<result property="id" column="id" />
|
||||
<result property="name" column="name" />
|
||||
<result property="channelType" column="channel_type" />
|
||||
<result property="provider" column="provider" />
|
||||
<result property="configContent" column="config_content" />
|
||||
<result property="tenantId" column="tenant_id" />
|
||||
<result property="tenantName" column="tenant_name" />
|
||||
<result property="createBy" column="create_by" />
|
||||
<result property="createTime" column="create_time" />
|
||||
<result property="updateBy" column="update_by" />
|
||||
<result property="updateTime" column="update_time" />
|
||||
<result property="delFlag" column="del_flag" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectNotifyChannelVo">
|
||||
select id, name, channel_type, provider, config_content, tenant_id, tenant_name, create_by, create_time, update_by, update_time, del_flag from notify_channel
|
||||
</sql>
|
||||
|
||||
<select id="selectNotifyChannelList" parameterType="NotifyChannel" resultMap="NotifyChannelResult">
|
||||
<include refid="selectNotifyChannelVo"/>
|
||||
<where>
|
||||
<if test="name != null and name != ''"> and name like concat('%', #{name}, '%')</if>
|
||||
<if test="channelType != null "> and channel_type = #{channelType}</if>
|
||||
<if test="provider != null and provider != ''"> and provider = #{provider}</if>
|
||||
<if test="configContent != null and configContent != ''"> and config_content = #{configContent}</if>
|
||||
<if test="tenantId != null "> and tenant_id = #{tenantId}</if>
|
||||
</where>
|
||||
order by create_time desc
|
||||
</select>
|
||||
|
||||
<select id="selectNotifyChannelById" parameterType="Long" resultMap="NotifyChannelResult">
|
||||
<include refid="selectNotifyChannelVo"/>
|
||||
where id = #{id}
|
||||
</select>
|
||||
|
||||
<select id="selectNotifyChannelByIds" resultType="com.fastbee.notify.domain.NotifyChannel">
|
||||
<include refid="selectNotifyChannelVo"/>
|
||||
where id in
|
||||
<foreach item="id" collection="idList" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
<insert id="insertNotifyChannel" parameterType="NotifyChannel" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into notify_channel
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="name != null and name != ''">name,</if>
|
||||
<if test="channelType != null">channel_type,</if>
|
||||
<if test="provider != null and provider != ''">provider,</if>
|
||||
<if test="configContent != null and configContent != ''">config_content,</if>
|
||||
<if test="tenantId != null">tenant_id,</if>
|
||||
<if test="tenantName != null and tenantName != ''">tenant_name,</if>
|
||||
<if test="createBy != null">create_by,</if>
|
||||
<if test="createTime != null">create_time,</if>
|
||||
<if test="updateBy != null">update_by,</if>
|
||||
<if test="updateTime != null">update_time,</if>
|
||||
<if test="delFlag != null">del_flag,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="name != null and name != ''">#{name},</if>
|
||||
<if test="channelType != null">#{channelType},</if>
|
||||
<if test="provider != null and provider != ''">#{provider},</if>
|
||||
<if test="configContent != null and configContent != ''">#{configContent},</if>
|
||||
<if test="tenantId != null">#{tenantId},</if>
|
||||
<if test="tenantName != null and tenantName != ''">#{tenantName},</if>
|
||||
<if test="createBy != null">#{createBy},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
<if test="updateBy != null">#{updateBy},</if>
|
||||
<if test="updateTime != null">#{updateTime},</if>
|
||||
<if test="delFlag != null">#{delFlag},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
<update id="updateNotifyChannel" parameterType="NotifyChannel">
|
||||
update notify_channel
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
<if test="name != null and name != ''">name = #{name},</if>
|
||||
<if test="channelType != null">channel_type = #{channelType},</if>
|
||||
<if test="provider != null and provider != ''">provider = #{provider},</if>
|
||||
<if test="configContent != null and configContent != ''">config_content = #{configContent},</if>
|
||||
<if test="tenantId != null">tenant_id = #{tenantId},</if>
|
||||
<if test="tenantName != null and tenantName != ''">tenant_name = #{tenantName},</if>
|
||||
<if test="createBy != null">create_by = #{createBy},</if>
|
||||
<if test="createTime != null">create_time = #{createTime},</if>
|
||||
<if test="updateBy != null">update_by = #{updateBy},</if>
|
||||
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||
<if test="delFlag != null">del_flag = #{delFlag},</if>
|
||||
</trim>
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
||||
<delete id="deleteNotifyChannelById" parameterType="Long">
|
||||
delete from notify_channel where id = #{id}
|
||||
</delete>
|
||||
|
||||
<delete id="deleteNotifyChannelByIds" parameterType="String">
|
||||
delete from notify_channel where id in
|
||||
<foreach item="id" collection="array" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</delete>
|
||||
</mapper>
|
@ -0,0 +1,122 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.fastbee.notify.mapper.NotifyLogMapper">
|
||||
|
||||
<resultMap type="NotifyLog" id="NotifyLogResult">
|
||||
<result property="id" column="id" />
|
||||
<result property="notifyTemplateId" column="notify_template_id" />
|
||||
<result property="channelId" column="channel_id" />
|
||||
<result property="msgContent" column="msg_content" />
|
||||
<result property="sendAccount" column="send_account" />
|
||||
<result property="sendStatus" column="send_status" />
|
||||
<result property="resultContent" column="result_content" />
|
||||
<result property="createBy" column="create_by" />
|
||||
<result property="createTime" column="create_time" />
|
||||
<result property="updateBy" column="update_by" />
|
||||
<result property="updateTime" column="update_time" />
|
||||
<result property="delFlag" column="del_flag" />
|
||||
<result property="tenantId" column="tenant_id" />
|
||||
<result property="tenantName" column="tenant_name" />
|
||||
<result property="serviceCode" column="service_code" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectNotifyLogVo">
|
||||
select id, notify_template_id, channel_id, msg_content, send_account, send_status, result_content,service_code, create_by, create_time, update_by, update_time, del_flag, tenant_id, tenant_name from notify_log
|
||||
</sql>
|
||||
|
||||
<select id="selectNotifyLogList" parameterType="NotifyLog" resultMap="NotifyLogResult">
|
||||
<include refid="selectNotifyLogVo"/>
|
||||
<where>
|
||||
<if test="notifyTemplateId != null "> and notify_template_id = #{notifyTemplateId}</if>
|
||||
<if test="channelId != null "> and channel_id = #{channelId}</if>
|
||||
<if test="msgContent != null and msgContent != ''"> and msg_content = #{msgContent}</if>
|
||||
<if test="sendAccount != null and sendAccount != ''"> and send_account like concat("%", #{sendAccount}, "%")</if>
|
||||
<if test="sendStatus != null "> and send_status = #{sendStatus}</if>
|
||||
<if test="resultContent != null and resultContent != ''"> and result_content = #{resultContent}</if>
|
||||
<if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
|
||||
and date_format(create_time,'%y%m%d') >= date_format(#{params.beginTime},'%y%m%d')
|
||||
</if>
|
||||
<if test="params.endTime != null and params.endTime != ''"><!-- 结束时间检索 -->
|
||||
and date_format(create_time,'%y%m%d') <= date_format(#{params.endTime},'%y%m%d')
|
||||
</if>
|
||||
<if test="serviceCode != null and serviceCode != ''"> and service_code = #{serviceCode}</if>
|
||||
<if test="tenantId != null "> and tenant_id = #{tenantId}</if>
|
||||
</where>
|
||||
order by id desc
|
||||
</select>
|
||||
|
||||
<select id="selectNotifyLogById" parameterType="Long" resultMap="NotifyLogResult">
|
||||
<include refid="selectNotifyLogVo"/>
|
||||
where id = #{id}
|
||||
</select>
|
||||
|
||||
<insert id="insertNotifyLog" parameterType="NotifyLog" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into notify_log
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="notifyTemplateId != null">notify_template_id,</if>
|
||||
<if test="channelId != null">channel_id,</if>
|
||||
<if test="msgContent != null">msg_content,</if>
|
||||
<if test="sendAccount != null">send_account,</if>
|
||||
<if test="sendStatus != null">send_status,</if>
|
||||
<if test="resultContent != null">result_content,</if>
|
||||
<if test="createBy != null">create_by,</if>
|
||||
<if test="createTime != null">create_time,</if>
|
||||
<if test="updateBy != null">update_by,</if>
|
||||
<if test="updateTime != null">update_time,</if>
|
||||
<if test="delFlag != null">del_flag,</if>
|
||||
<if test="tenantId != null">tenant_id,</if>
|
||||
<if test="tenantName != null and tenantName != ''">tenant_name,</if>
|
||||
<if test="serviceCode != null">service_code,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="notifyTemplateId != null">#{notifyTemplateId},</if>
|
||||
<if test="channelId != null">#{channelId},</if>
|
||||
<if test="msgContent != null">#{msgContent},</if>
|
||||
<if test="sendAccount != null">#{sendAccount},</if>
|
||||
<if test="sendStatus != null">#{sendStatus},</if>
|
||||
<if test="resultContent != null">#{resultContent},</if>
|
||||
<if test="createBy != null">#{createBy},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
<if test="updateBy != null">#{updateBy},</if>
|
||||
<if test="updateTime != null">#{updateTime},</if>
|
||||
<if test="delFlag != null">#{delFlag},</if>
|
||||
<if test="tenantId != null">#{tenantId},</if>
|
||||
<if test="tenantName != null and tenantName != ''">#{tenantName},</if>
|
||||
<if test="serviceCode != null">#{serviceCode},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
<update id="updateNotifyLog" parameterType="NotifyLog">
|
||||
update notify_log
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
<if test="notifyTemplateId != null">notify_template_id = #{notifyTemplateId},</if>
|
||||
<if test="channelId != null">channel_id = #{channelId},</if>
|
||||
<if test="msgContent != null">msg_content = #{msgContent},</if>
|
||||
<if test="sendAccount != null">send_account = #{sendAccount},</if>
|
||||
<if test="sendStatus != null">send_status = #{sendStatus},</if>
|
||||
<if test="resultContent != null">result_content = #{resultContent},</if>
|
||||
<if test="createBy != null">create_by = #{createBy},</if>
|
||||
<if test="createTime != null">create_time = #{createTime},</if>
|
||||
<if test="updateBy != null">update_by = #{updateBy},</if>
|
||||
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||
<if test="delFlag != null">del_flag = #{delFlag},</if>
|
||||
<if test="tenantId != null">tenant_id = #{tenantId},</if>
|
||||
<if test="tenantName != null and tenantName != ''">tenant_name = #{tenantName},</if>
|
||||
<if test="serviceCode != null">service_code = #{serviceCode},</if>
|
||||
</trim>
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
||||
<delete id="deleteNotifyLogById" parameterType="Long">
|
||||
delete from notify_log where id = #{id}
|
||||
</delete>
|
||||
|
||||
<delete id="deleteNotifyLogByIds" parameterType="String">
|
||||
delete from notify_log where id in
|
||||
<foreach item="id" collection="array" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</delete>
|
||||
</mapper>
|
@ -0,0 +1,175 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.fastbee.notify.mapper.NotifyTemplateMapper">
|
||||
|
||||
<resultMap type="com.fastbee.notify.domain.NotifyTemplate" id="NotifyTemplateResult">
|
||||
<result property="id" column="id" />
|
||||
<result property="serviceCode" column="service_code" />
|
||||
<result property="msgParams" column="msg_params"/>
|
||||
<result property="status" column="status" />
|
||||
<result property="name" column="name" />
|
||||
<result property="channelId" column="channel_id" />
|
||||
<result property="channelType" column="channel_type" />
|
||||
<result property="provider" column="provider" />
|
||||
<result property="createBy" column="create_by" />
|
||||
<result property="createTime" column="create_time" />
|
||||
<result property="updateBy" column="update_by" />
|
||||
<result property="updateTime" column="update_time" />
|
||||
<result property="delFlag" column="del_flag" />
|
||||
<result property="tenantId" column="tenant_id" />
|
||||
<result property="tenantName" column="tenant_name" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectNotifyTemplateVo">
|
||||
select id, service_code,msg_params,status, name, channel_id, channel_type, provider, create_by, create_time, update_by, update_time, del_flag, tenant_id, tenant_name from notify_template
|
||||
</sql>
|
||||
|
||||
<select id="selectNotifyTemplateList" parameterType="NotifyTemplate" resultMap="NotifyTemplateResult">
|
||||
<include refid="selectNotifyTemplateVo"/>
|
||||
<where>
|
||||
<if test="serviceCode != null and serviceCode != ''"> and service_code = #{serviceCode}</if>
|
||||
<if test="name != null and name != ''"> and name like concat('%', #{name}, '%')</if>
|
||||
<if test="channelId != null "> and channel_id = #{channelId}</if>
|
||||
<if test="channelType != null "> and channel_type = #{channelType}</if>
|
||||
<if test="provider != null and provider != ''"> and provider = #{provider}</if>
|
||||
<if test="status != null"> and status = #{status}</if>
|
||||
<if test="tenantId != null "> and tenant_id = #{tenantId}</if>
|
||||
</where>
|
||||
order by status desc, create_time desc
|
||||
</select>
|
||||
|
||||
<select id="selectEnableNotifyTemplateCount" parameterType="NotifyTemplate" resultType="java.lang.Integer">
|
||||
select count(*) from notify_template t
|
||||
where t.service_code = #{serviceCode}
|
||||
and t.status = #{status} and t.id != #{id}
|
||||
and t.channel_type = #{channelType}
|
||||
and t.tenant_id = #{tenantId}
|
||||
<if test="provider != null and provider != ''">
|
||||
and t.provider = #{provider}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="selectNotifyTemplateById" parameterType="Long" resultMap="NotifyTemplateResult">
|
||||
<include refid="selectNotifyTemplateVo"/>
|
||||
where id = #{id}
|
||||
</select>
|
||||
|
||||
<select id="selectOnlyEnable" parameterType="NotifyTemplate" resultType="com.fastbee.notify.domain.NotifyTemplate">
|
||||
<include refid="selectNotifyTemplateVo"/>
|
||||
where service_code = #{serviceCode}
|
||||
and status = 1
|
||||
and channel_type = #{channelType}
|
||||
and tenant_id = #{tenantId}
|
||||
<if test="provider != null and provider != ''">
|
||||
and provider = #{provider}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="selectNotifyTemplateByIds" resultType="com.fastbee.notify.domain.NotifyTemplate">
|
||||
<include refid="selectNotifyTemplateVo"/>
|
||||
where id in
|
||||
<foreach item="id" collection="idList" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
<select id="selectNotifyTemplateByChannelId" resultType="com.fastbee.notify.domain.NotifyTemplate">
|
||||
<include refid="selectNotifyTemplateVo"/>
|
||||
where channel_id = #{channelId}
|
||||
</select>
|
||||
|
||||
<insert id="insertNotifyTemplate" parameterType="NotifyTemplate" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into notify_template
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="serviceCode != null">service_code,</if>
|
||||
<if test="name != null and name != ''">name,</if>
|
||||
<if test="channelId != null">channel_id,</if>
|
||||
<if test="channelType != null">channel_type,</if>
|
||||
<if test="provider != null and provider != ''">provider,</if>
|
||||
<if test="createBy != null">create_by,</if>
|
||||
<if test="createTime != null">create_time,</if>
|
||||
<if test="updateBy != null">update_by,</if>
|
||||
<if test="updateTime != null">update_time,</if>
|
||||
<if test="delFlag != null">del_flag,</if>
|
||||
<if test="msgParams != null">msg_params,</if>
|
||||
<if test="status != null">status,</if>
|
||||
<if test="tenantId != null">tenant_id,</if>
|
||||
<if test="tenantName != null and tenantName != ''">tenant_name,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="serviceCode != null">#{serviceCode},</if>
|
||||
<if test="name != null and name != ''">#{name},</if>
|
||||
<if test="channelId != null">#{channelId},</if>
|
||||
<if test="channelType != null">#{channelType},</if>
|
||||
<if test="provider != null and provider != ''">#{provider},</if>
|
||||
<if test="createBy != null">#{createBy},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
<if test="updateBy != null">#{updateBy},</if>
|
||||
<if test="updateTime != null">#{updateTime},</if>
|
||||
<if test="delFlag != null">#{delFlag},</if>
|
||||
<if test="msgParams != null">#{msgParams},</if>
|
||||
<if test="status != null">#{status},</if>
|
||||
<if test="tenantId != null">#{tenantId},</if>
|
||||
<if test="tenantName != null and tenantName != ''">#{tenantName},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
<update id="updateNotifyTemplate" parameterType="NotifyTemplate">
|
||||
update notify_template
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
<if test="serviceCode != null">service_code = #{serviceCode},</if>
|
||||
<if test="name != null and name != ''">name = #{name},</if>
|
||||
<if test="channelId != null">channel_id = #{channelId},</if>
|
||||
<if test="channelType != null">channel_type = #{channelType},</if>
|
||||
<if test="provider != null and provider != ''">provider = #{provider},</if>
|
||||
<if test="createBy != null">create_by = #{createBy},</if>
|
||||
<if test="createTime != null">create_time = #{createTime},</if>
|
||||
<if test="updateBy != null">update_by = #{updateBy},</if>
|
||||
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||
<if test="delFlag != null">del_flag = #{delFlag},</if>
|
||||
<if test="msgParams != null">msg_params = #{msgParams},</if>
|
||||
<if test="status != null">status = #{status},</if>
|
||||
<if test="tenantId != null">tenant_id = #{tenantId},</if>
|
||||
<if test="tenantName != null and tenantName != ''">tenant_name = #{tenantName},</if>
|
||||
</trim>
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
||||
<update id="updateNotifyBatch" >
|
||||
update notify_template
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
<if test="status != null">status = #{status},</if>
|
||||
</trim>
|
||||
where id in
|
||||
<foreach collection="ids" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
</update>
|
||||
|
||||
<delete id="deleteNotifyTemplateById" parameterType="Long">
|
||||
delete from notify_template where id = #{id}
|
||||
</delete>
|
||||
|
||||
<delete id="deleteNotifyTemplateByIds" parameterType="String">
|
||||
delete from notify_template where id in
|
||||
<foreach item="id" collection="array" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<delete id="deleteNotifyTemplateByChannelIds">
|
||||
delete from notify_template where channel_id in
|
||||
<foreach item="channelId" collection="array" open="(" separator="," close=")">
|
||||
#{channelId}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<delete id="deleteAlertNotifyTemplateByNotifyTemplateIds">
|
||||
delete from iot_alert_notify_template where notify_template_id in
|
||||
<foreach item="notifyTemplateId" collection="array" open="(" separator="," close=")">
|
||||
#{notifyTemplateId}
|
||||
</foreach>
|
||||
</delete>
|
||||
</mapper>
|
27
fastbee-notify/pom.xml
Normal file
27
fastbee-notify/pom.xml
Normal file
@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.fastbee</groupId>
|
||||
<artifactId>fastbee</artifactId>
|
||||
<version>3.8.5</version>
|
||||
</parent>
|
||||
|
||||
<packaging>pom</packaging>
|
||||
<artifactId>fastbee-notify</artifactId>
|
||||
<description>通知模块整合</description>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
<module>fastbee-notify-web</module>
|
||||
<module>fastbee-notify-core</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
Reference in New Issue
Block a user