回调管理

This commit is contained in:
六如
2025-11-03 07:56:35 +08:00
parent 9d8a04b702
commit 5001809fef
75 changed files with 2828 additions and 56 deletions

24
sop-notify/pom.xml Normal file
View File

@@ -0,0 +1,24 @@
<?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.gitee.sop</groupId>
<artifactId>sop-parent</artifactId>
<version>5.0.0-SNAPSHOT</version>
</parent>
<artifactId>sop-notify</artifactId>
<packaging>pom</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<modules>
<module>sop-notify-api</module>
<module>sop-notify-service</module>
</modules>
</project>

View 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>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-notify-api</artifactId>
<version>5.0.0-SNAPSHOT</version>
<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>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.36</version>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,29 @@
package com.gitee.sop.notify.api;
import com.gitee.sop.notify.api.req.NotifyRequest;
import com.gitee.sop.notify.api.resp.NotifyResponse;
/**
* 回调接口
*
* @author 六如
*/
public interface NotifyService {
/**
* 回调
*
* @param request 参数
* @return 返回结果
*/
NotifyResponse notify(NotifyRequest request);
/**
* 回调立即发送
*
* @param notifyId notifyId
* @return 返回结果
*/
NotifyResponse notifyImmediately(Long notifyId);
}

View File

@@ -0,0 +1,66 @@
package com.gitee.sop.notify.api.req;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.Map;
/**
* @author 六如
*/
@Data
public class NotifyRequest implements Serializable {
private static final long serialVersionUID = -4018307141661725928L;
/**
* appId
*/
@NotBlank(message = "appId必填")
private String appId;
/**
* apiName
*/
@NotBlank(message = "apiName必填")
private String apiName;
/**
* version
*/
@NotBlank(message = "version必填")
private String version;
/**
* 编码
*/
@NotBlank(message = "charset必填")
private String charset;
/**
* token,没有返回null
*/
private String appAuthToken;
/**
* 客户端ip
*/
private String clientIp;
/**
* 回调地址
*/
private String notifyUrl;
/**
* 业务参数
*/
@NotNull(message = "bizParams必填")
private Map<String, Object> bizParams;
/**
* 备注
*/
private String remark;
}

View File

@@ -0,0 +1,39 @@
package com.gitee.sop.notify.api.resp;
import lombok.Data;
import java.io.Serializable;
/**
* @author 六如
*/
@Data
public class NotifyResponse implements Serializable {
private static final long serialVersionUID = 5813802354743928430L;
/**
* 返回请求id
*/
private Long notifyId;
private Boolean success = true;
private String msg;
public static NotifyResponse success(Long notifyId) {
NotifyResponse notifyResponse = new NotifyResponse();
notifyResponse.setNotifyId(notifyId);
notifyResponse.setSuccess(true);
notifyResponse.setMsg("");
return notifyResponse;
}
public static NotifyResponse error(String msg) {
NotifyResponse notifyResponse = new NotifyResponse();
notifyResponse.setNotifyId(null);
notifyResponse.setSuccess(false);
notifyResponse.setMsg(msg);
return notifyResponse;
}
}

View File

@@ -0,0 +1,154 @@
<?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.gitee.sop</groupId>
<artifactId>sop-notify</artifactId>
<version>5.0.0-SNAPSHOT</version>
</parent>
<artifactId>sop-notify-service</artifactId>
<version>5.0.0-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
<!-- dubbo版本 -->
<dubbo.version>3.2.16</dubbo.version>
</properties>
<dependencies>
<dependency>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-notify-api</artifactId>
<version>5.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.gitee.sop</groupId>
<artifactId>sdk-java</artifactId>
<version>5.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.gitee.durcframework</groupId>
<artifactId>fastmybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>net.oschina.durcframework</groupId>
<artifactId>http-helper</artifactId>
</dependency>
<!-- sop接入依赖 -->
<dependency>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-spring-boot-starter</artifactId>
<version>5.0.0-SNAPSHOT</version>
</dependency>
<!-- nacos注册中心 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-nacos-spring-boot-starter</artifactId>
</dependency>
<!-- zookeeper注册中心 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-zookeeper-curator5-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.34</version>
<scope>provided</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-bom</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<!-- 打包时跳过测试 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>UTF-8</encoding>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
<!-- 文档推送 -->
<plugin>
<groupId>com.ly.smart-doc</groupId>
<artifactId>smart-doc-maven-plugin</artifactId>
<version>3.0.9</version>
<configuration>
<!--指定生成文档的使用的配置文件-->
<configFile>./src/main/resources/smart-doc.json</configFile>
<!--指定项目名称-->
<projectName>${project.artifactId}</projectName>
</configuration>
<dependencies>
<dependency>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-service-support</artifactId>
<version>5.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
<repository>
<id>maven_central</id>
<name>Maven Central</name>
<url>https://repo.maven.apache.org/maven2/</url>
</repository>
</repositories>
</project>

View File

@@ -0,0 +1,18 @@
package com.gitee.sop.notify;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableDubbo
@EnableScheduling
public class SopNotifyApplication {
public static void main(String[] args) {
SpringApplication.run(SopNotifyApplication.class, args);
}
}

View File

@@ -0,0 +1,99 @@
package com.gitee.sop.notify.dao.entity;
import java.time.LocalDateTime;
import com.gitee.fastmybatis.annotation.Pk;
import com.gitee.fastmybatis.annotation.PkStrategy;
import com.gitee.fastmybatis.annotation.Table;
import lombok.Data;
/**
* 表名notify_info
* 备注:回调信息
*
* @author 六如
*/
@Table(name = "notify_info", pk = @Pk(name = "id", strategy = PkStrategy.INCREMENT))
@Data
public class NotifyInfo {
private Long id;
/**
* app_id
*/
private String appId;
/**
* api_name
*/
private String apiName;
/**
* api_version
*/
private String apiVersion;
/**
* 回调url
*/
private String notifyUrl;
/**
* 最近一次发送时间
*/
private LocalDateTime lastSendTime;
/**
* 下一次发送时间
*/
private LocalDateTime nextSendTime;
/**
* 已发送次数
*/
private Integer sendCnt;
/**
* 发送内容
*/
private String content;
/**
* 状态,1-发送成功,2-发送失败,3-重试结束
*/
private Integer notifyStatus;
/**
* 失败原因
*/
private String errorMsg;
/**
* 返回结果
*/
private String resultContent;
/**
* 备注
*/
private String remark;
private LocalDateTime addTime;
private LocalDateTime updateTime;
/**
* 创建人id
*/
private Long addBy;
/**
* 修改人id
*/
private Long updateBy;
}

View File

@@ -0,0 +1,14 @@
package com.gitee.sop.notify.dao.mapper;
import org.apache.ibatis.annotations.Mapper;
/**
* @author 六如
*/
@Mapper
public interface IsvMapper {
String getPrivatePlatformKey(String appId);
String getNotifyUrl(String appId);
}

View File

@@ -0,0 +1,13 @@
package com.gitee.sop.notify.dao.mapper;
import com.gitee.fastmybatis.core.mapper.BaseMapper;
import com.gitee.sop.notify.dao.entity.NotifyInfo;
import org.apache.ibatis.annotations.Mapper;
/**
* @author 六如
*/
@Mapper
public interface NotifyInfoMapper extends BaseMapper<NotifyInfo> {
}

View File

@@ -0,0 +1,48 @@
package com.gitee.sop.notify.dubbo;
import com.gitee.sop.notify.api.NotifyService;
import com.gitee.sop.notify.api.req.NotifyRequest;
import com.gitee.sop.notify.api.resp.NotifyResponse;
import com.gitee.sop.notify.service.NotifyBizService;
import com.gitee.sop.notify.service.bo.NotifyBO;
import com.gitee.sop.sdk.sign.SopSignException;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @author 六如
*/
@DubboService(validation = "true")
@Slf4j
public class NotifyServiceImpl implements NotifyService {
@Autowired
private NotifyBizService notifyBizService;
@Override
public NotifyResponse notify(NotifyRequest request) {
NotifyBO notifyBO = new NotifyBO();
BeanUtils.copyProperties(request, notifyBO);
try {
Long notifyId = notifyBizService.notify(notifyBO);
return NotifyResponse.success(notifyId);
} catch (SopSignException e) {
log.error("回调异常,服务端签名失败, request={}", request, e);
return NotifyResponse.error(e.getErrMsg());
}
}
@Override
public NotifyResponse notifyImmediately(Long notifyId) {
try {
notifyBizService.notifyImmediately(notifyId);
return NotifyResponse.success(notifyId);
} catch (Exception e) {
log.error("回调异常, notifyId={}", notifyId, e);
return NotifyResponse.error(e.getMessage());
}
}
}

View File

@@ -0,0 +1,22 @@
package com.gitee.sop.notify.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author 六如
*/
@AllArgsConstructor
@Getter
public enum NotifyStatusEnum {
// 状态,1-发送成功,2-发送失败,3-重试结束
SEND_SUCCESS(1, "发送成功"),
SEND_FAIL(2, "发送失败"),
RETRY_OVER(3, "重试结束");
private final Integer value;
private final String description;
}

View File

@@ -0,0 +1,27 @@
package com.gitee.sop.notify.schedule;
import com.gitee.sop.notify.service.NotifyBizService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
/**
* @author 六如
*/
@Component
public class NotifySchedule {
@Autowired
private NotifyBizService notifyBizService;
/**
* 每分钟执行一次
*/
@Scheduled(cron = "0 0/1 * * * ?")
public void run() {
notifyBizService.retry(LocalDateTime.now());
}
}

View File

@@ -0,0 +1,24 @@
package com.gitee.sop.notify.service;
import com.gitee.sop.notify.dao.mapper.IsvMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author 六如
*/
@Service
public class IsvService {
@Autowired
private IsvMapper isvMapper;
public String getPrivatePlatformKey(String appId) {
return isvMapper.getPrivatePlatformKey(appId);
}
public String getNotifyUrl(String appId) {
return isvMapper.getNotifyUrl(appId);
}
}

View File

@@ -0,0 +1,243 @@
package com.gitee.sop.notify.service;
import com.alibaba.fastjson.JSON;
import com.gitee.fastmybatis.core.support.LambdaService;
import com.gitee.httphelper.HttpHelper;
import com.gitee.httphelper.result.ResponseResult;
import com.gitee.sop.notify.dao.entity.NotifyInfo;
import com.gitee.sop.notify.dao.mapper.NotifyInfoMapper;
import com.gitee.sop.notify.enums.NotifyStatusEnum;
import com.gitee.sop.notify.service.bo.NotifyBO;
import com.gitee.sop.sdk.sign.SignUtil;
import com.gitee.sop.sdk.sign.SopSignException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.http.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* 回调业务逻辑处理
*
* @author 六如
*/
@Service
@Slf4j
public class NotifyBizService implements LambdaService<NotifyInfo, NotifyInfoMapper> {
// 对应第123...次尝试
// 即1分钟后进行第一次尝试如果失败5分钟后进行第二次尝试
@Value("${sop.notify.time-level:1m,5m,10m,30m,1h,2h,5h}")
private String timeLevel;
@Autowired
private IsvService isvService;
/**
* 第一次发送
*
* @param notifyBO 回调内容
* @return 返回回调id
* @throws SopSignException 异常处理
*/
public Long notify(NotifyBO notifyBO) throws SopSignException {
NotifyInfo notifyInfo = buildRecord(notifyBO);
return doNotify(notifyBO, notifyInfo);
}
public void notifyImmediately(Long notifyId) throws SopSignException {
NotifyInfo notifyInfo = this.getById(notifyId);
String content = notifyInfo.getContent();
NotifyBO notifyBO = JSON.parseObject(content, NotifyBO.class);
// 发送请求
doNotify(notifyBO, notifyInfo);
}
/**
* 重试
*
* @param now 当前时间
*/
public void retry(LocalDateTime now) {
LocalDateTime nextTime = now.withSecond(0).withNano(0);
List<NotifyInfo> list = this.query()
.eq(NotifyInfo::getNextSendTime, nextTime)
.eq(NotifyInfo::getNotifyStatus, NotifyStatusEnum.SEND_FAIL.getValue())
.list();
if (list.isEmpty()) {
log.info("[notify]无重试记录");
return;
}
for (NotifyInfo notifyInfo : list) {
retry(notifyInfo);
}
}
private void retry(NotifyInfo notifyInfo) {
String content = notifyInfo.getContent();
NotifyBO notifyBO = JSON.parseObject(content, NotifyBO.class);
try {
log.info("[notify]开始重试, notifyId={}", notifyInfo.getId());
if (Objects.equals(notifyInfo.getNotifyStatus(), NotifyStatusEnum.RETRY_OVER.getValue())) {
log.warn("重试次数已用尽, notifyId={}", notifyInfo.getId());
return;
}
// 发送请求
doNotify(notifyBO, notifyInfo);
} catch (SopSignException e) {
log.error("[notify]重试签名错误notifyId={}", notifyInfo.getId(), e);
throw new RuntimeException("重试失败,签名错误");
}
}
/**
* 构建下一次重试时间
*
* @param currentSendCnt 当前发送次数
* @return 返回null表示重试次数用完
*/
private LocalDateTime buildNextSendTime(Integer currentSendCnt) {
String[] split = timeLevel.split(",");
if (currentSendCnt >= split.length) {
return null;
}
// 1m
String exp = split[currentSendCnt - 1];
// 秒,毫秒归零f
LocalDateTime time = LocalDateTime.now().withSecond(0).withNano(0);
// 最后一个字符m,h,d
char ch = exp.charAt(exp.length() - 1);
int value = NumberUtils.toInt(exp.substring(0, exp.length() - 1));
switch (String.valueOf(ch).toLowerCase()) {
case "m":
return time.plusMinutes(value);
case "h":
return time.plusHours(value);
case "d":
return time.plusDays(value);
default:
return null;
}
}
private Long doNotify(NotifyBO notifyBO, NotifyInfo notifyInfo) throws SopSignException {
notifyInfo.setSendCnt(notifyInfo.getSendCnt() + 1);
notifyInfo.setLastSendTime(LocalDateTime.now());
notifyInfo.setNotifyUrl(buildNotifyUrl(notifyBO, notifyInfo));
String notifyUrl = notifyInfo.getNotifyUrl();
// 构建请求参数
Map<String, String> params = buildParams(notifyBO);
try {
if (StringUtils.isBlank(notifyUrl)) {
throw new RuntimeException("回调接口不能为空");
}
String json = JSON.toJSONString(params);
log.info("发送回调请求notifyUrl={}, content={}", notifyUrl, json);
ResponseResult responseResult = HttpHelper.postJson(notifyUrl, json)
.execute();
// 这里判断收到200认为请求成功
int status = responseResult.getStatus();
String resultContent = responseResult.asString();
notifyInfo.setResultContent(resultContent);
if (status == HttpStatus.SC_OK) {
// 更新状态
notifyInfo.setNotifyStatus(NotifyStatusEnum.SEND_SUCCESS.getValue());
notifyInfo.setErrorMsg("");
} else {
// 回调失败
log.error("回调状态非200:{}, result={}", status, resultContent);
throw new RuntimeException(resultContent);
}
} catch (Exception e) {
log.error("回调请求失败, notifyUrl={}, params={}, notifyBO={}", notifyUrl, params, notifyBO, e);
notifyInfo.setNotifyStatus(NotifyStatusEnum.SEND_FAIL.getValue());
notifyInfo.setErrorMsg(e.getMessage());
LocalDateTime nextSendTime = buildNextSendTime(notifyInfo.getSendCnt());
notifyInfo.setNextSendTime(nextSendTime);
if (nextSendTime == null) {
log.error("回调请求次数达到上线, notifyUrl={}, params={}", notifyUrl, params);
notifyInfo.setNotifyStatus(NotifyStatusEnum.RETRY_OVER.getValue());
}
}
this.saveOrUpdate(notifyInfo);
return notifyInfo.getId();
}
private Map<String, String> buildParams(NotifyBO notifyBO) throws SopSignException {
// 公共请求参数
Map<String, String> params = new HashMap<>();
String appId = notifyBO.getAppId();
params.put("app_id", appId);
params.put("method", notifyBO.getApiName());
params.put("format", "json");
params.put("charset", notifyBO.getCharset());
params.put("sign_type", "RSA2");
params.put("timestamp", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
params.put("version", notifyBO.getVersion());
// 业务参数
Map<String, Object> bizContent = notifyBO.getBizParams();
params.put("biz_content", JSON.toJSONString(bizContent));
String content = SignUtil.getSignContent(params);
String privateKey = isvService.getPrivatePlatformKey(appId);
String sign = SignUtil.rsa256Sign(content, privateKey, notifyBO.getCharset());
params.put("sign", sign);
return params;
}
private String buildNotifyUrl(NotifyBO notifyBO, NotifyInfo notifyInfo) {
String savedUrl = notifyInfo.getNotifyUrl();
if (StringUtils.isNotBlank(savedUrl)) {
return savedUrl;
}
String notifyUrl = notifyBO.getNotifyUrl();
if (StringUtils.isBlank(notifyUrl)) {
notifyUrl = isvService.getNotifyUrl(notifyBO.getAppId());
}
return notifyUrl;
}
private NotifyInfo buildRecord(NotifyBO notifyBO) {
NotifyInfo notifyInfo = new NotifyInfo();
notifyInfo.setAppId(notifyBO.getAppId());
notifyInfo.setApiName(notifyBO.getApiName());
notifyInfo.setApiVersion(notifyBO.getVersion());
notifyInfo.setSendCnt(0);
notifyInfo.setContent(JSON.toJSONString(notifyBO));
notifyInfo.setNotifyStatus(0);
notifyInfo.setErrorMsg("");
notifyInfo.setRemark(notifyBO.getRemark());
notifyInfo.setAddTime(LocalDateTime.now());
notifyInfo.setUpdateTime(LocalDateTime.now());
notifyInfo.setAddBy(0L);
notifyInfo.setUpdateBy(0L);
return notifyInfo;
}
}

View File

@@ -0,0 +1,64 @@
package com.gitee.sop.notify.service.bo;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.util.Map;
/**
* @author 六如
*/
@Data
public class NotifyBO {
/**
* appId
*/
@NotBlank(message = "appId必填")
private String appId;
/**
* apiName
*/
@NotBlank(message = "apiName必填")
private String apiName;
/**
* version
*/
@NotBlank(message = "version必填")
private String version;
/**
* token,没有返回null
*/
private String appAuthToken;
/**
* 客户端ip
*/
private String clientIp;
/**
* 回调地址
*/
@NotBlank(message = "notifyUrl必填")
private String notifyUrl;
/**
* 编码
*/
private String charset;
/**
* 业务参数
*/
@NotBlank(message = "bizParams必填")
private Map<String, Object> bizParams;
/**
* 备注
*/
private String remark;
}

View File

@@ -0,0 +1,7 @@
mybatis.print-sql=true
# mysql config
mysql.host=127.0.0.1:3306
mysql.db=sop
mysql.username=root
mysql.password=12345678

View File

@@ -0,0 +1,9 @@
dubbo.registry.address=nacos://localhost:8848
mybatis.print-sql=true
# mysql config
mysql.host=127.0.0.1:3306
mysql.db=sop
mysql.username=root
mysql.password=root

View File

@@ -0,0 +1,47 @@
server.port=8085
spring.profiles.active=dev
spring.application.name=sop-notify
dubbo.protocol.name=dubbo
dubbo.protocol.port=-1
dubbo.application.qos-enable=false
dubbo.consumer.check=false
# ### register config see:https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/registry/overview/
# ------
# nacos://localhost:8848 Cluster config:nacos://localhost:8848?backup=localshot:8846,localshot:8847
# zookeeper://localhost:2181 Cluster config:zookeeper://10.20.153.10:2181?backup=10.20.153.11:2181,10.20.153.12:2181
# redis://localhost:6379 Cluster config:redis://10.20.153.10:6379?backup=10.20.153.11:6379,10.20.153.12:6379
# ------
dubbo.registry.address=zookeeper://localhost:2181
####### mysql config #######
mysql.host=127.0.0.1:3306
mysql.db=sop
mysql.username=
mysql.password=
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://${mysql.host}/${mysql.db}?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai
spring.datasource.username=${mysql.username}
spring.datasource.password=${mysql.password}
####### mybatis config #######
mybatis.fill.com.gitee.fastmybatis.core.support.LocalDateTimeFillInsert=add_time
mybatis.fill.com.gitee.fastmybatis.core.support.LocalDateTimeFillUpdate=update_time
# mybatis config file
mybatis.config-location=classpath:mybatis/mybatisConfig.xml
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
# log level
logging.level.com.gitee.sop=info
# log path
logging.file.name=logs/sop-notify.log
# print SQL
logging.level.com.gitee.sop.notify.dao=error
logging.level.com.gitee.fastmybatis=info
mybatis.print-sql=false
# \u5BF9\u5E94\u7B2C1\uFF0C2\uFF0C3...\u6B21\u5C1D\u8BD5
# \u53731\u5206\u949F\u540E\u8FDB\u884C\u7B2C\u4E00\u6B21\u5C1D\u8BD5\uFF0C\u5982\u679C\u5931\u8D25\uFF0C5\u5206\u949F\u540E\u8FDB\u884C\u7B2C\u4E8C\u6B21\u5C1D\u8BD5
sop.notify.time-level:1m,5m,10m,30m,1h,2h,5h

View File

@@ -0,0 +1,19 @@
<?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.gitee.sop.notify.dao.mapper.IsvMapper">
<select id="getPrivatePlatformKey" resultType="String">
select t2.private_key_platform
from isv_info t inner join isv_keys t2 on t.id = t2.isv_id
where app_id=#{appId}
limit 1
</select>
<select id="getNotifyUrl" resultType="String">
select t.notify_url
from isv_info t
where app_id=#{appId}
limit 1
</select>
</mapper>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!-- 全局映射器启用缓存 -->
<setting name="cacheEnabled" value="true" />
<!-- 查询时,关闭关联对象即时加载以提高性能 -->
<setting name="lazyLoadingEnabled" value="true" />
<!-- 对于未知的SQL查询允许返回不同的结果集以达到通用的效果 -->
<setting name="multipleResultSetsEnabled" value="true" />
<!-- 允许使用列标签代替列名 -->
<setting name="useColumnLabel" value="true" />
<!-- 允许使用自定义的主键值(比如由程序生成的UUID 32位编码作为键值)数据表的PK生成策略将被覆盖 -->
<setting name="useGeneratedKeys" value="false" />
<!-- 对于批量更新操作缓存SQL以提高性能:BATCH -->
<setting name="defaultExecutorType" value="SIMPLE" />
<!-- 超时设置 -->
<setting name="defaultStatementTimeout" value="25000" />
</settings>
<plugins>
<plugin interceptor="com.gitee.fastmybatis.core.support.plugin.SqlFormatterPlugin">
</plugin>
</plugins>
</configuration>