钉钉群机器人发送消息;
This commit is contained in:
parent
046527c76e
commit
35b5798f9b
221
msgdispatcher/pom.xml
Normal file
221
msgdispatcher/pom.xml
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
<?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.msgdispatcher</groupId>
|
||||||
|
<artifactId>msgdispatcher</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>3.3.0</version>
|
||||||
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<hutool.version>5.8.18</hutool.version>
|
||||||
|
<maven.plugin.version>3.8.1</maven.plugin.version>
|
||||||
|
<mybatis.plus.spring.boot>3.5.5</mybatis.plus.spring.boot>
|
||||||
|
|
||||||
|
<hutool.version>5.8.25</hutool.version>
|
||||||
|
<postgresql.version>42.7.3</postgresql.version>
|
||||||
|
<easyexcel.version>3.2.1</easyexcel.version>
|
||||||
|
<annotations.version>4.8.6</annotations.version>
|
||||||
|
<undertow.version>2.3.14.Final</undertow.version>
|
||||||
|
<apache.poi>5.3.0</apache.poi>
|
||||||
|
<taosdata.verson>3.2.10</taosdata.verson>
|
||||||
|
<disruptor.version>3.4.4</disruptor.version>
|
||||||
|
<aviator.version>5.4.3</aviator.version>
|
||||||
|
<alibaba-dingtalk-service-sdk.version>2.0.0</alibaba-dingtalk-service-sdk.version>
|
||||||
|
<commons-codec.version>1.11</commons-codec.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- web 容器使用 undertow 代替 tomcat-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-undertow</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 定时任务支持-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-quartz</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!--spring 配置支持-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.postgresql</groupId>
|
||||||
|
<artifactId>postgresql</artifactId>
|
||||||
|
<version>${postgresql.version}</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.poi</groupId>
|
||||||
|
<artifactId>poi-ooxml</artifactId>
|
||||||
|
<version>${apache.poi}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-poi</artifactId>
|
||||||
|
<version>${hutool.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.taosdata.jdbc</groupId>
|
||||||
|
<artifactId>taos-jdbcdriver</artifactId>
|
||||||
|
<version>${taosdata.verson}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 提供Redis连接池 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-pool2</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!--mybatis-plus-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
|
||||||
|
<version>${mybatis.plus.spring.boot}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- hutool 的依赖配置-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-core</artifactId>
|
||||||
|
<version>${hutool.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-crypto</artifactId>
|
||||||
|
<version>${hutool.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-captcha</artifactId>
|
||||||
|
<version>${hutool.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-validation</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<!--redis 操作-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.lmax</groupId>
|
||||||
|
<artifactId>disruptor</artifactId>
|
||||||
|
<version>${disruptor.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.googlecode.aviator</groupId>
|
||||||
|
<artifactId>aviator</artifactId>
|
||||||
|
<version>${aviator.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!--aop切面-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-aop</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 临时修复MAYBE枚举量未定义问题,等待Spring6.2正式发行-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.spotbugs</groupId>
|
||||||
|
<artifactId>spotbugs-annotations</artifactId>
|
||||||
|
<version>${annotations.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>easyexcel</artifactId>
|
||||||
|
<version>${easyexcel.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.apache.poi</groupId>
|
||||||
|
<artifactId>poi-ooxml-schemas</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.aliyun</groupId>
|
||||||
|
<artifactId>alibaba-dingtalk-service-sdk</artifactId>
|
||||||
|
<version>2.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-codec</groupId>
|
||||||
|
<artifactId>commons-codec</artifactId>
|
||||||
|
<version>1.11</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.msgdispatcher.common.config;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ConfigurationProperties(prefix = "dingtalk.webhook")
|
||||||
|
public class DingTalkProperties {
|
||||||
|
|
||||||
|
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
private String token;
|
||||||
|
|
||||||
|
private String secret;
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.msgdispatcher.common.config;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ConfigurationProperties(prefix = "dingtalk-user")
|
||||||
|
public class DingTalkUserProperties {
|
||||||
|
|
||||||
|
|
||||||
|
private String getTokenUrl;
|
||||||
|
|
||||||
|
private String getUserUrl;
|
||||||
|
|
||||||
|
private String appKey;
|
||||||
|
|
||||||
|
private String appSecret;
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package com.msgdispatcher.common.config;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ConfigurationProperties(prefix = "msg-file")
|
||||||
|
public class MsgFileProperties {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息文件目录
|
||||||
|
*/
|
||||||
|
private String directoryPath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基础备份目录
|
||||||
|
*/
|
||||||
|
private String baseBackupDir;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package com.msgdispatcher.common.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class RestTemplateConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RestTemplate restTemplate() {
|
||||||
|
return new RestTemplate();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package com.msgdispatcher.common.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author chenhaojie
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface AdminConstant {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基础包路径
|
||||||
|
*/
|
||||||
|
String BASE_PACKAGE = "com.msgdispatcher";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
package com.msgdispatcher.common.exceptions;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import com.msgdispatcher.common.result.IResultCode;
|
||||||
|
import com.msgdispatcher.common.result.ResultCode;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author chenhaojie
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class BusinessException extends RuntimeException {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private int code = ResultCode.CLIENT_UN_AUTHORIZED.getCode();
|
||||||
|
|
||||||
|
private String msg = ResultCode.CLIENT_UN_AUTHORIZED.getMessage();
|
||||||
|
|
||||||
|
public BusinessException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BusinessException(String msg) {
|
||||||
|
super(msg);
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BusinessException(IResultCode resultCode, String msg) {
|
||||||
|
super(msg);
|
||||||
|
this.code = resultCode.getCode();
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BusinessException(String msg, Throwable cause) {
|
||||||
|
super(msg, cause);
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BusinessException(IResultCode resultCode, String msg, Throwable cause) {
|
||||||
|
super(msg, cause);
|
||||||
|
this.code = resultCode.getCode();
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BusinessException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(int code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMsg() {
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMsg(String msg) {
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
package com.msgdispatcher.common.exceptions;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import com.msgdispatcher.common.result.IResultCode;
|
||||||
|
import com.msgdispatcher.common.result.ResultCode;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author chenhaojie
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class EasyExcelException extends RuntimeException {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private int code = ResultCode.FAILURE.getCode();
|
||||||
|
|
||||||
|
private String msg = ResultCode.FAILURE.getMessage();
|
||||||
|
|
||||||
|
public EasyExcelException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public EasyExcelException(String msg) {
|
||||||
|
super(msg);
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EasyExcelException(IResultCode resultCode, String msg) {
|
||||||
|
super(msg);
|
||||||
|
this.code = resultCode.getCode();
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EasyExcelException(String msg, Throwable cause) {
|
||||||
|
super(msg, cause);
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EasyExcelException(IResultCode resultCode, String msg, Throwable cause) {
|
||||||
|
super(msg, cause);
|
||||||
|
this.code = resultCode.getCode();
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EasyExcelException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(int code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMsg() {
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMsg(String msg) {
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,69 @@
|
|||||||
|
package com.msgdispatcher.common.exceptions;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import com.msgdispatcher.common.result.IResultCode;
|
||||||
|
import com.msgdispatcher.common.result.ResultCode;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author chenhaojie
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class OssException extends RuntimeException {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private int code = ResultCode.FAILURE.getCode();
|
||||||
|
|
||||||
|
private String msg = ResultCode.FAILURE.getMessage();
|
||||||
|
|
||||||
|
public OssException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public OssException(String msg) {
|
||||||
|
super(msg);
|
||||||
|
this.setMsg(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OssException(IResultCode resultCode, String msg) {
|
||||||
|
super(msg);
|
||||||
|
this.setCode(resultCode.getCode());
|
||||||
|
this.setMsg(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OssException(String msg, Throwable cause) {
|
||||||
|
super(msg, cause);
|
||||||
|
this.setMsg(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OssException(IResultCode resultCode, String msg, Throwable cause) {
|
||||||
|
super(msg, cause);
|
||||||
|
this.setCode(resultCode.getCode());
|
||||||
|
this.setMsg(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OssException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(int code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMsg(String msg) {
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMsg() {
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
package com.msgdispatcher.common.exceptions;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import com.msgdispatcher.common.result.IResultCode;
|
||||||
|
import com.msgdispatcher.common.result.ResultCode;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author chenhaojie
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public class RateLimiterException extends RuntimeException {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private int code = ResultCode.FAILURE.getCode();
|
||||||
|
|
||||||
|
private String msg = ResultCode.FAILURE.getMessage();
|
||||||
|
|
||||||
|
public RateLimiterException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public RateLimiterException(String msg) {
|
||||||
|
super(msg);
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RateLimiterException(IResultCode resultCode, String msg) {
|
||||||
|
super(msg);
|
||||||
|
this.code = resultCode.getCode();
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RateLimiterException(String msg, Throwable cause) {
|
||||||
|
super(msg, cause);
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RateLimiterException(IResultCode resultCode, String msg, Throwable cause) {
|
||||||
|
super(msg, cause);
|
||||||
|
this.code = resultCode.getCode();
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RateLimiterException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(int code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMsg(String msg) {
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
package com.msgdispatcher.common.exceptions;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import com.msgdispatcher.common.result.IResultCode;
|
||||||
|
import com.msgdispatcher.common.result.ResultCode;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author chenhaojie
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public class RepeatSubmitException extends RuntimeException {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private int code = ResultCode.FAILURE.getCode();
|
||||||
|
|
||||||
|
private String msg = ResultCode.FAILURE.getMessage();
|
||||||
|
|
||||||
|
public RepeatSubmitException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public RepeatSubmitException(String msg) {
|
||||||
|
super(msg);
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RepeatSubmitException(IResultCode resultCode, String msg) {
|
||||||
|
super(msg);
|
||||||
|
this.code = resultCode.getCode();
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RepeatSubmitException(String msg, Throwable cause) {
|
||||||
|
super(msg, cause);
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RepeatSubmitException(IResultCode resultCode, String msg, Throwable cause) {
|
||||||
|
super(msg, cause);
|
||||||
|
this.code = resultCode.getCode();
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RepeatSubmitException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(int code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMsg(String msg) {
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
package com.msgdispatcher.common.exceptions;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import com.msgdispatcher.common.result.IResultCode;
|
||||||
|
import com.msgdispatcher.common.result.ResultCode;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author chenhaojie
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ServiceException extends RuntimeException {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private int code = ResultCode.FAILURE.getCode();
|
||||||
|
|
||||||
|
private String msg = ResultCode.FAILURE.getMessage();
|
||||||
|
|
||||||
|
public ServiceException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServiceException(String msg) {
|
||||||
|
super(msg);
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServiceException(IResultCode resultCode, String msg) {
|
||||||
|
super(msg);
|
||||||
|
this.code = resultCode.getCode();
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServiceException(String msg, Throwable cause) {
|
||||||
|
super(msg, cause);
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServiceException(IResultCode resultCode, String msg, Throwable cause) {
|
||||||
|
super(msg, cause);
|
||||||
|
this.code = resultCode.getCode();
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServiceException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(int code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMsg() {
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMsg(String msg) {
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,172 @@
|
|||||||
|
package com.msgdispatcher.common.handler;
|
||||||
|
|
||||||
|
|
||||||
|
import com.msgdispatcher.common.constant.AdminConstant;
|
||||||
|
import com.msgdispatcher.common.exceptions.*;
|
||||||
|
import com.msgdispatcher.common.exceptions.*;
|
||||||
|
import com.msgdispatcher.common.result.R;
|
||||||
|
import jakarta.validation.ConstraintViolation;
|
||||||
|
import jakarta.validation.ConstraintViolationException;
|
||||||
|
import jakarta.validation.ValidationException;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.validation.BindException;
|
||||||
|
import org.springframework.validation.BindingResult;
|
||||||
|
import org.springframework.validation.FieldError;
|
||||||
|
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||||
|
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||||
|
import org.springframework.web.bind.MissingServletRequestParameterException;
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
import org.springframework.web.servlet.NoHandlerFoundException;
|
||||||
|
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author chenhaojie
|
||||||
|
* <p>
|
||||||
|
* 如果我同时捕获了父类和子类,那么到底能够被那个异常处理器捕获呢?比如 Exception 和 BusinessException
|
||||||
|
* 当然是 BusinessException 的异常处理器捕获了,精确匹配,如果没有 BusinessException 的异常处理器才会轮到它的 父亲 ,
|
||||||
|
* 父亲 没有才会到 祖父 。总之一句话, 精准匹配,找那个关系最近的
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RestControllerAdvice
|
||||||
|
public class GlobalExceptionHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param businessException 业务异常
|
||||||
|
* @return @ResponseBody
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(BusinessException.class)
|
||||||
|
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||||
|
public R handle(BusinessException businessException) {
|
||||||
|
// 获取指定包名前缀的异常信息,减少不必要的日志
|
||||||
|
String stackTraceByPn = getStackTraceByPn(businessException, AdminConstant.BASE_PACKAGE);
|
||||||
|
log.error("记录业务异常信息, 消息:{} 编码:{} {}", businessException.getMessage(), businessException.getCode(), stackTraceByPn);
|
||||||
|
return R.fail(businessException.getCode(), businessException.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拦截限流异常信息
|
||||||
|
* */
|
||||||
|
@ExceptionHandler(RateLimiterException.class)
|
||||||
|
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||||
|
public R handle(RateLimiterException rateLimiterException) {
|
||||||
|
// 获取指定包名前缀的异常信息,减少不必要的日志
|
||||||
|
// String stackTraceByPn = getStackTraceByPn(rateLimiterException, AdminConstant.BASE_PACKAGE);
|
||||||
|
log.error("拦截限流异常信息, 消息:{} 编码:{}", rateLimiterException.getMessage(), rateLimiterException.getCode());
|
||||||
|
return R.fail(rateLimiterException.getCode(), rateLimiterException.getMessage());
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 重复提交异常信息
|
||||||
|
* */
|
||||||
|
@ExceptionHandler(RepeatSubmitException.class)
|
||||||
|
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||||
|
public R handle(RepeatSubmitException repeatSubmitException) {
|
||||||
|
// 获取指定包名前缀的异常信息,减少不必要的日志
|
||||||
|
// String stackTraceByPn = getStackTraceByPn(rateLimiterException, AdminConstant.BASE_PACKAGE);
|
||||||
|
log.error("重复提交异常信息, 消息:{} 编码:{}", repeatSubmitException.getMessage(), repeatSubmitException.getCode());
|
||||||
|
return R.fail(repeatSubmitException.getCode(), repeatSubmitException.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(ServiceException.class)
|
||||||
|
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||||
|
public R handle(ServiceException serviceException) {
|
||||||
|
// 这里记录所有堆栈信息
|
||||||
|
log.error("记录业务异常信息, 消息:{} 编码:{}", serviceException.getMessage(), serviceException.getCode(), serviceException);
|
||||||
|
return R.fail(serviceException.getCode(), serviceException.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(OssException.class)
|
||||||
|
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||||
|
public R handle(OssException ossException) {
|
||||||
|
// 这里记录所有堆栈信息
|
||||||
|
log.error("oss异常信息, 消息:{} 编码:{}", ossException.getMessage(), ossException.getCode(), ossException);
|
||||||
|
return R.fail(ossException.getCode(), ossException.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getStackTraceByPn(Throwable e, String packagePrefix) {
|
||||||
|
StringBuilder append = new StringBuilder("\n").append(e);
|
||||||
|
for (StackTraceElement stackTraceElement : e.getStackTrace()) {
|
||||||
|
if (stackTraceElement.getClassName().startsWith(packagePrefix)) {
|
||||||
|
append.append("\n\tat ").append(stackTraceElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return append.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(value = {BindException.class, ValidationException.class, MethodArgumentNotValidException.class})
|
||||||
|
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||||
|
public R handleValidatedException(Exception exception) {
|
||||||
|
BindingResult bindingResult = null;
|
||||||
|
if (exception instanceof MethodArgumentNotValidException e){
|
||||||
|
bindingResult = e.getBindingResult();
|
||||||
|
if (bindingResult.hasErrors()) {
|
||||||
|
FieldError fieldError = bindingResult.getFieldError();
|
||||||
|
if (fieldError != null) {
|
||||||
|
return R.fail(fieldError.getField()+ ":" + fieldError.getDefaultMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else if (exception instanceof ConstraintViolationException e){
|
||||||
|
String collect = e.getConstraintViolations().stream()
|
||||||
|
.map(ConstraintViolation::getMessage)
|
||||||
|
.collect(Collectors.joining(";"));
|
||||||
|
return R.fail(collect);
|
||||||
|
}else if (exception instanceof BindException e){
|
||||||
|
bindingResult = e.getBindingResult();
|
||||||
|
if (bindingResult.hasErrors()) {
|
||||||
|
FieldError fieldError = bindingResult.getFieldError();
|
||||||
|
if (fieldError != null) {
|
||||||
|
return R.fail(fieldError.getField()+ ":" + fieldError.getDefaultMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return R.fail(exception.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(value = {MissingServletRequestParameterException.class})
|
||||||
|
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||||
|
public R handlerMissingServletRequestParameterException(MissingServletRequestParameterException exception) {
|
||||||
|
String message = exception.getMessage();
|
||||||
|
log.error("全局捕获MissingServletRequestParameterException错误信息: {}", message, exception);
|
||||||
|
return R.fail("缺少必要参数");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 捕获空指针异常
|
||||||
|
**/
|
||||||
|
@ExceptionHandler(value = NullPointerException.class)
|
||||||
|
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||||
|
public R handlerNullPointException(NullPointerException exception) {
|
||||||
|
String message = exception.getMessage();
|
||||||
|
log.error("全局捕获null错误信息", exception);
|
||||||
|
return R.fail(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 捕获 404 异常
|
||||||
|
* @param exception 异常
|
||||||
|
* @return R
|
||||||
|
*/
|
||||||
|
@ExceptionHandler({NoHandlerFoundException.class, HttpRequestMethodNotSupportedException.class})
|
||||||
|
@ResponseStatus(HttpStatus.NOT_FOUND)
|
||||||
|
public R handle(Exception exception) {
|
||||||
|
String message = exception.getMessage();
|
||||||
|
log.error("404捕获错误信息: {}", message);
|
||||||
|
return R.fail("找不到对应资源");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 捕获最大异常
|
||||||
|
**/
|
||||||
|
@ExceptionHandler(value = Throwable.class)
|
||||||
|
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||||
|
public R handlerBindException(Exception exception) {
|
||||||
|
String message = exception.getMessage();
|
||||||
|
log.error("全局捕获错误信息", exception);
|
||||||
|
return R.fail(message);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package com.msgdispatcher.common.result;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author chenhaojie
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface IResultCode extends Serializable {
|
||||||
|
/**
|
||||||
|
* 获取结果消息
|
||||||
|
* @return 结果消息
|
||||||
|
*/
|
||||||
|
String getMessage();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取返回状态码
|
||||||
|
* @return 结果状态码
|
||||||
|
*/
|
||||||
|
int getCode();
|
||||||
|
}
|
@ -0,0 +1,133 @@
|
|||||||
|
package com.msgdispatcher.common.result;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author chenhaojie
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
public class R<T> implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态码
|
||||||
|
*/
|
||||||
|
private int code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否成功
|
||||||
|
*/
|
||||||
|
private boolean success;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 承载数据
|
||||||
|
*/
|
||||||
|
private T data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回消息
|
||||||
|
*/
|
||||||
|
private String msg;
|
||||||
|
|
||||||
|
private R(IResultCode resultCode) {
|
||||||
|
this(resultCode, null, resultCode.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
private R(IResultCode resultCode, String msg) {
|
||||||
|
this(resultCode, null, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private R(IResultCode resultCode, T data) {
|
||||||
|
this(resultCode, data, resultCode.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
private R(IResultCode resultCode, T data, String msg) {
|
||||||
|
this(resultCode.getCode(), data, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private R(int code, T data, String msg) {
|
||||||
|
this.code = code;
|
||||||
|
this.data = data;
|
||||||
|
this.msg = msg;
|
||||||
|
this.success = ResultCode.SUCCESS.code == code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isSuccess(@Nullable R<?> result) {
|
||||||
|
return Optional.ofNullable(result).map((x) -> ResultCode.SUCCESS.code == x.code).orElse(Boolean.FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isNotSuccess(@Nullable R<?> result) {
|
||||||
|
return !isSuccess(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> R<T> data(T data) {
|
||||||
|
return data(data, "操作成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> R<T> data(T data, String msg) {
|
||||||
|
return data(200, data, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> R<T> data(int code, T data, String msg) {
|
||||||
|
return new R(code, data, data == null ? "暂无承载数据" : msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> R<T> success(String msg) {
|
||||||
|
return new R(ResultCode.SUCCESS, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> R<T> success(T data) {
|
||||||
|
return new R(ResultCode.SUCCESS, data,"操作成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> R<T> success() {
|
||||||
|
return new R(ResultCode.SUCCESS,null, "操作成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> R<T> success(IResultCode resultCode) {
|
||||||
|
return new R(resultCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> R<T> success(IResultCode resultCode, String msg) {
|
||||||
|
return new R(resultCode, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> R<T> fail(String msg) {
|
||||||
|
return new R(ResultCode.FAILURE, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> R<T> fail(int code, String msg) {
|
||||||
|
return new R(code, null, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> R<T> fail(IResultCode resultCode) {
|
||||||
|
return new R(resultCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> R<T> fail(IResultCode resultCode, String msg) {
|
||||||
|
return new R(resultCode, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> R<T> status(boolean flag) {
|
||||||
|
return flag ? success("操作成功") : fail("操作失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "R(code=" + this.getCode() + ", success=" + this.isSuccess() + ", data=" + this.getData() + ", msg=" + this.getMsg() + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
public R() {
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package com.msgdispatcher.common.result;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author chenhaojie
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public enum ResultCode implements IResultCode {
|
||||||
|
/**
|
||||||
|
* 返回状态码,以及返回消息
|
||||||
|
*/
|
||||||
|
SUCCESS(200, "操作成功"),
|
||||||
|
FAILURE(400, "业务异常"),
|
||||||
|
UN_AUTHORIZED(401, "请求未授权"),
|
||||||
|
CLIENT_UN_AUTHORIZED(401, "客户端请求未授权"),
|
||||||
|
NOT_FOUND(404, "404 没找到请求"),
|
||||||
|
MSG_NOT_READABLE(400, "消息不能读取"),
|
||||||
|
METHOD_NOT_SUPPORTED(405, "不支持当前请求方法"),
|
||||||
|
MEDIA_TYPE_NOT_SUPPORTED(415, "不支持当前媒体类型"),
|
||||||
|
REQ_REJECT(403, "请求被拒绝"),
|
||||||
|
INTERNAL_SERVER_ERROR(500, "服务器异常"),
|
||||||
|
PARAM_MISS(400, "缺少必要的请求参数"),
|
||||||
|
PARAM_TYPE_ERROR(400, "请求参数类型错误"),
|
||||||
|
PARAM_BIND_ERROR(400, "请求参数绑定错误"),
|
||||||
|
PARAM_VALID_ERROR(400, "参数校验失败");
|
||||||
|
|
||||||
|
final int code;
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCode() {
|
||||||
|
return this.code;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMessage() {
|
||||||
|
return this.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultCode(final int code, final String message) {
|
||||||
|
this.code = code;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package com.msgdispatcher.modules.ddsend.controller;
|
||||||
|
|
||||||
|
import com.msgdispatcher.common.result.R;
|
||||||
|
import com.msgdispatcher.modules.ddsend.job.SendDingTalkMsgJob;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RequestMapping("/api/dingTalk")
|
||||||
|
@RestController
|
||||||
|
public class DingTalkController {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SendDingTalkMsgJob sendDingTalkMsgJob;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 钉钉机器人,发送消息
|
||||||
|
*/
|
||||||
|
@GetMapping("/sendMessage")
|
||||||
|
public R<String> sendMessage() {
|
||||||
|
sendDingTalkMsgJob.sendMessage();
|
||||||
|
return R.success("发送成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.msgdispatcher.modules.ddsend.domain.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class MsgFileDto {
|
||||||
|
/**
|
||||||
|
* 文件路径
|
||||||
|
*/
|
||||||
|
private String filePath;
|
||||||
|
/**
|
||||||
|
* 消息内容
|
||||||
|
*/
|
||||||
|
private List<Map<String, Object>> mgsList;
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
package com.msgdispatcher.modules.ddsend.job;
|
||||||
|
|
||||||
|
import com.msgdispatcher.modules.ddsend.domain.dto.MsgFileDto;
|
||||||
|
import com.msgdispatcher.modules.ddsend.service.DingTalkService;
|
||||||
|
import com.msgdispatcher.modules.ddsend.service.ParseFileService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
public class SendDingTalkMsgJob {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DingTalkService dingTalkService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ParseFileService parseFileService;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//@Scheduled(cron = "0 0/10 * * * ?")
|
||||||
|
public void sendMessage() {
|
||||||
|
//获取目录下所有文件的解析结果
|
||||||
|
List<MsgFileDto> msgFileList= null;
|
||||||
|
try {
|
||||||
|
msgFileList = parseFileService.scanAndParseAllFiles();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("解析文件错误:"+e.getMessage());
|
||||||
|
}
|
||||||
|
if (msgFileList ==null){
|
||||||
|
log.info("目录中没有文件,无需发送消息");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//发送消息
|
||||||
|
for (MsgFileDto msgFileDto : msgFileList) {
|
||||||
|
String filePath = null;
|
||||||
|
try {
|
||||||
|
filePath = msgFileDto.getFilePath();
|
||||||
|
List<Map<String, Object>> mgsList = msgFileDto.getMgsList();
|
||||||
|
for (Map<String, Object> map : mgsList) {
|
||||||
|
String phone = (String) map.get("接收人手机号");
|
||||||
|
String msgContent = (String) map.get("消息内容");
|
||||||
|
String wind = (String) map.get("风机");
|
||||||
|
StringBuilder stb = new StringBuilder();
|
||||||
|
stb.append(wind).append("风机,").append(msgContent);
|
||||||
|
String user =null;
|
||||||
|
if (phone !=null){
|
||||||
|
stb.append(" @").append(phone);
|
||||||
|
user = dingTalkService.getUserIdByMobile(phone);
|
||||||
|
}
|
||||||
|
dingTalkService.sendMessage(stb.toString(),user);
|
||||||
|
}
|
||||||
|
//文件发送成功后,把文件移动到备份文件夹
|
||||||
|
parseFileService.moveFileToBackupDirectory(filePath);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("发送消息错误:{},文件路径:{}",e,filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,112 @@
|
|||||||
|
package com.msgdispatcher.modules.ddsend.service;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.dingtalk.api.DefaultDingTalkClient;
|
||||||
|
import com.dingtalk.api.DingTalkClient;
|
||||||
|
import com.dingtalk.api.request.OapiRobotSendRequest;
|
||||||
|
import com.dingtalk.api.response.OapiRobotSendResponse;
|
||||||
|
import com.msgdispatcher.common.config.DingTalkProperties;
|
||||||
|
import com.msgdispatcher.common.config.DingTalkUserProperties;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.client.RestClientException;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
import javax.crypto.Mac;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class DingTalkService {
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DingTalkProperties dingTalkProperties;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DingTalkUserProperties dingTalkUserProperties;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RestTemplate restTemplate;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送钉钉消息
|
||||||
|
* @param message 内容
|
||||||
|
*/
|
||||||
|
public void sendMessage(String message,String user) {
|
||||||
|
try {
|
||||||
|
Long timestamp = System.currentTimeMillis();
|
||||||
|
String secret = dingTalkProperties.getSecret();
|
||||||
|
String stringToSign = timestamp + "\n" + secret;
|
||||||
|
Mac mac = Mac.getInstance("HmacSHA256");
|
||||||
|
mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256"));
|
||||||
|
byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
|
||||||
|
String sign = URLEncoder.encode(new String(Base64.encodeBase64(signData)), "UTF-8");
|
||||||
|
//sign字段和timestamp字段必须拼接到请求URL上,否则会出现 310000 的错误信息
|
||||||
|
String serverUrl = String.format("%s%s%s%s", dingTalkProperties.getUrl(), sign, "×tamp=", timestamp);
|
||||||
|
DingTalkClient client = new DefaultDingTalkClient(serverUrl);
|
||||||
|
OapiRobotSendRequest req = new OapiRobotSendRequest();
|
||||||
|
//定义文本内容
|
||||||
|
OapiRobotSendRequest.Text text = new OapiRobotSendRequest.Text();
|
||||||
|
text.setContent(message);
|
||||||
|
//定义 @ 对象
|
||||||
|
OapiRobotSendRequest.At at = new OapiRobotSendRequest.At();
|
||||||
|
at.setAtUserIds(Arrays.asList(user));
|
||||||
|
//设置消息类型
|
||||||
|
req.setMsgtype("text");
|
||||||
|
req.setText(text);
|
||||||
|
req.setAt(at);
|
||||||
|
OapiRobotSendResponse rsp = client.execute(req, dingTalkProperties.getToken());
|
||||||
|
log.info("rsp:"+rsp.getBody());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("机器人发送消息错误"+e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据手机号获取用户ID
|
||||||
|
* @param mobile
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getUserIdByMobile(String mobile) {
|
||||||
|
try {
|
||||||
|
String accessToken = getAccessToken();
|
||||||
|
String url = String.format("%s%s&mobile=%s",dingTalkUserProperties.getGetUserUrl(),accessToken,mobile);
|
||||||
|
JSONObject response = restTemplate.getForObject(url, JSONObject.class);
|
||||||
|
if (response != null && response.getIntValue("errcode") == 0) {
|
||||||
|
return response.getString("userid");
|
||||||
|
} else {
|
||||||
|
log.info("无法获取访问令牌"+ response.toJSONString());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("根据手机号获取用户ID失败"+ e.getMessage());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取AccessToken
|
||||||
|
* @return access_token
|
||||||
|
*/
|
||||||
|
public String getAccessToken() {;
|
||||||
|
String url = String.format("%s%s&appsecret=%s",dingTalkUserProperties.getGetTokenUrl(),
|
||||||
|
dingTalkUserProperties.getAppKey(),dingTalkUserProperties.getAppSecret());
|
||||||
|
JSONObject response = restTemplate.getForObject(url, JSONObject.class);
|
||||||
|
if (response != null && response.getIntValue("errcode") == 0) {
|
||||||
|
return response.getString("access_token");
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("无法获取访问令牌: " + response.toJSONString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,157 @@
|
|||||||
|
package com.msgdispatcher.modules.ddsend.service;
|
||||||
|
|
||||||
|
import com.msgdispatcher.common.config.MsgFileProperties;
|
||||||
|
import com.msgdispatcher.modules.ddsend.domain.dto.MsgFileDto;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ParseFileService {
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MsgFileProperties msgFileProperties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 扫描目录下的所有.e文件并解析E语言格式文件
|
||||||
|
*
|
||||||
|
* @return 所有文件的解析结果
|
||||||
|
* @throws IOException 如果读取过程中出现错误
|
||||||
|
*/
|
||||||
|
public List<MsgFileDto> scanAndParseAllFiles() throws IOException {
|
||||||
|
File directory = new File(msgFileProperties.getDirectoryPath());
|
||||||
|
if (!directory.exists()) {
|
||||||
|
throw new RuntimeException("目录不存在: " + msgFileProperties.getDirectoryPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
File[] files = directory.listFiles((dir, name) -> name.toLowerCase().endsWith(".e")); // 过滤出.e文件
|
||||||
|
if (files == null || files.length == 0) {
|
||||||
|
throw new RuntimeException("目录中找不到 .e 文件,目录: " + msgFileProperties.getDirectoryPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
List<MsgFileDto> listData = new ArrayList<>();
|
||||||
|
for (File file : files) {
|
||||||
|
// 获取文件的路径名
|
||||||
|
String filePath = file.getPath();
|
||||||
|
List<Map<String, Object>> fileData = parseELanguageFile(file);
|
||||||
|
MsgFileDto msgFileDto = new MsgFileDto();
|
||||||
|
msgFileDto.setFilePath(filePath);
|
||||||
|
msgFileDto.setMgsList(fileData);
|
||||||
|
listData.add(msgFileDto);
|
||||||
|
}
|
||||||
|
return listData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析E语言格式文件并返回List<Map<String, Object>>
|
||||||
|
*
|
||||||
|
* @param file 文件对象
|
||||||
|
* @return 解析后的数据
|
||||||
|
* @throws IOException 如果读取过程中出现错误
|
||||||
|
*/
|
||||||
|
private List<Map<String, Object>> parseELanguageFile(File file) throws IOException {
|
||||||
|
List<Map<String, Object>> result = new ArrayList<>();
|
||||||
|
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
|
||||||
|
String line;
|
||||||
|
boolean isDataSection = false;
|
||||||
|
List<String> headers = new ArrayList<>();
|
||||||
|
|
||||||
|
while ((line = br.readLine()) != null) {
|
||||||
|
if (line.startsWith("<!")) {
|
||||||
|
// 跳过头部信息
|
||||||
|
continue;
|
||||||
|
} else if (line.startsWith("@")) {
|
||||||
|
// 解析表头
|
||||||
|
headers = Arrays.asList(line.substring(1).trim().split("\t"));
|
||||||
|
isDataSection = true;
|
||||||
|
continue;
|
||||||
|
} else if (line.startsWith("#") && isDataSection) {
|
||||||
|
// 解析数据行
|
||||||
|
String[] values = line.substring(1).trim().split("\t");
|
||||||
|
Map<String, Object> row = new HashMap<>();
|
||||||
|
for (int i = 0; i < headers.size(); i++) {
|
||||||
|
row.put(headers.get(i), values[i]);
|
||||||
|
}
|
||||||
|
result.add(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移动文件到指定目录
|
||||||
|
*
|
||||||
|
* @param sourcePath 源文件路径
|
||||||
|
* @throws IOException 如果移动过程中出现错误
|
||||||
|
*/
|
||||||
|
public void moveFileToBackupDirectory(String sourcePath) throws IOException {
|
||||||
|
Path source = Paths.get(sourcePath);
|
||||||
|
if (!Files.exists(source)) {
|
||||||
|
throw new IOException("Source file does not exist: " + sourcePath);
|
||||||
|
}
|
||||||
|
//获取备份目录路径
|
||||||
|
String backupDir = createBackupDirectory();
|
||||||
|
Path target = Paths.get(backupDir, source.getFileName().toString());
|
||||||
|
|
||||||
|
Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据当前日期创建备份目录(1个月一个目录)
|
||||||
|
*
|
||||||
|
* @return 备份目录路径
|
||||||
|
* @throws IOException 如果创建目录过程中出现错误
|
||||||
|
*/
|
||||||
|
private String createBackupDirectory() throws IOException {
|
||||||
|
LocalDate now = LocalDate.now();
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
|
||||||
|
String backupDirName = now.format(formatter);
|
||||||
|
Path backupDirPath = Paths.get(msgFileProperties.getBaseBackupDir(), backupDirName);
|
||||||
|
|
||||||
|
if (!Files.exists(backupDirPath)) {
|
||||||
|
Files.createDirectories(backupDirPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return backupDirPath.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移动文件到指定目录
|
||||||
|
*
|
||||||
|
* @param sourcePath 源文件路径
|
||||||
|
* @param targetDir 目标目录路径
|
||||||
|
* @throws IOException 如果移动过程中出现错误
|
||||||
|
*/
|
||||||
|
public void moveFile(String sourcePath, String targetDir) throws IOException {
|
||||||
|
Path source = Paths.get(sourcePath);
|
||||||
|
Path target = Paths.get(targetDir, source.getFileName().toString());
|
||||||
|
|
||||||
|
if (!Files.exists(source)) {
|
||||||
|
throw new IOException("Source file does not exist: " + sourcePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Files.exists(target.getParent())) {
|
||||||
|
Files.createDirectories(target.getParent());
|
||||||
|
}
|
||||||
|
Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
83
msgdispatcher/src/main/resources/application-dev.yml
Normal file
83
msgdispatcher/src/main/resources/application-dev.yml
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
server:
|
||||||
|
port: 8081
|
||||||
|
# SpringBoot中我们既可以使用Tomcat作为Http服务,也可以用Undertow来代替。Undertow在高并发业务场景中,性能优于Tomcat
|
||||||
|
undertow:
|
||||||
|
threads:
|
||||||
|
# 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程
|
||||||
|
io: 16
|
||||||
|
# 阻塞任务线程池, 当执行类似servlet请求阻塞操作, undertow会从这个线程池中取得线程,它的值设置取决于系统的负载
|
||||||
|
worker: 400
|
||||||
|
# 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理
|
||||||
|
# 每块buffer的空间大小,越小的空间被利用越充分
|
||||||
|
buffer-size: 1024
|
||||||
|
# HTTP post内容的最大大小。当值为-1时,默认值为大小是无限的
|
||||||
|
max-http-post-size: -1
|
||||||
|
# 是否分配的直接内存
|
||||||
|
direct-buffers: true
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: msgdispatcher
|
||||||
|
#json格式化全局配置,相当于@JsonFormat
|
||||||
|
jackson:
|
||||||
|
time-zone: GMT+8
|
||||||
|
date-format: yyyy-MM-dd HH:mm:ss
|
||||||
|
# 指定默认包含的熟悉,NON_NULL表示只序列化非空属性
|
||||||
|
default-property-inclusion: non_null
|
||||||
|
# 配置文件上传大小限制
|
||||||
|
servlet:
|
||||||
|
multipart:
|
||||||
|
# 单个文件最大大小
|
||||||
|
max-file-size: 1024MB
|
||||||
|
# 多个文件总大小
|
||||||
|
max-request-size: 2048MB
|
||||||
|
datasource:
|
||||||
|
url: jdbc:postgresql://192.168.109.102:5432/das
|
||||||
|
username: das
|
||||||
|
password: qwaszx12
|
||||||
|
# # redis相关配置
|
||||||
|
data:
|
||||||
|
redis:
|
||||||
|
host: 192.168.109.195
|
||||||
|
database: 0
|
||||||
|
port: 6379
|
||||||
|
password:
|
||||||
|
client-type: lettuce
|
||||||
|
|
||||||
|
|
||||||
|
# 配置 xml 文件所在位置 配置全局的 主键策略,默认为 ASSIGN_ID 默认为 【雪花算法】 , auto 自增
|
||||||
|
mybatis-plus:
|
||||||
|
mapper-locations: classpath*:/mapper/**/*.xml
|
||||||
|
# 搜索指定包别名
|
||||||
|
typeAliasesPackage: com.das.**.entity
|
||||||
|
global-config:
|
||||||
|
# 关闭MP3.0自带的banner
|
||||||
|
banner: false
|
||||||
|
db-config:
|
||||||
|
id-type: ASSIGN_ID
|
||||||
|
# 逻辑删除
|
||||||
|
logic-not-delete-value: 0
|
||||||
|
logic-delete-value: 1
|
||||||
|
#字段策略
|
||||||
|
insert-strategy: not_null
|
||||||
|
update-strategy: not_null
|
||||||
|
where-strategy: not_empty
|
||||||
|
#驼峰下划线转换
|
||||||
|
table-underline: true
|
||||||
|
# 开启驼峰命名 默认开启驼峰命名
|
||||||
|
# mybatis-plus配置控制台打印完整带参数SQL语句
|
||||||
|
configuration:
|
||||||
|
map-underscore-to-camel-case: true
|
||||||
|
cache-enabled: false
|
||||||
|
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||||
|
|
||||||
|
|
||||||
|
logging:
|
||||||
|
level:
|
||||||
|
com:
|
||||||
|
das: DEBUG
|
||||||
|
|
||||||
|
tdengine:
|
||||||
|
password: taosdata
|
||||||
|
url: jdbc:TAOS-RS://192.168.109.160:6041/das
|
||||||
|
username: root
|
106
msgdispatcher/src/main/resources/application.yml
Normal file
106
msgdispatcher/src/main/resources/application.yml
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
server:
|
||||||
|
port: 8087
|
||||||
|
# SpringBoot中我们既可以使用Tomcat作为Http服务,也可以用Undertow来代替。Undertow在高并发业务场景中,性能优于Tomcat
|
||||||
|
undertow:
|
||||||
|
threads:
|
||||||
|
# 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程
|
||||||
|
io: 16
|
||||||
|
# 阻塞任务线程池, 当执行类似servlet请求阻塞操作, undertow会从这个线程池中取得线程,它的值设置取决于系统的负载
|
||||||
|
worker: 400
|
||||||
|
# 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理
|
||||||
|
# 每块buffer的空间大小,越小的空间被利用越充分
|
||||||
|
buffer-size: 1024
|
||||||
|
# HTTP post内容的最大大小。当值为-1时,默认值为大小是无限的
|
||||||
|
max-http-post-size: -1
|
||||||
|
# 是否分配的直接内存
|
||||||
|
direct-buffers: true
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: msgdispatcher
|
||||||
|
#json格式化全局配置,相当于@JsonFormat
|
||||||
|
jackson:
|
||||||
|
time-zone: GMT+8
|
||||||
|
date-format: yyyy-MM-dd HH:mm:ss
|
||||||
|
# 指定默认包含的熟悉,NON_NULL表示只序列化非空属性
|
||||||
|
default-property-inclusion: non_null
|
||||||
|
# 配置文件上传大小限制
|
||||||
|
servlet:
|
||||||
|
multipart:
|
||||||
|
# 单个文件最大大小
|
||||||
|
max-file-size: 1024MB
|
||||||
|
# 多个文件总大小
|
||||||
|
max-request-size: 2048MB
|
||||||
|
datasource:
|
||||||
|
url: jdbc:postgresql://192.168.109.102:5432/das
|
||||||
|
username: das
|
||||||
|
password: qwaszx12
|
||||||
|
# # redis相关配置
|
||||||
|
data:
|
||||||
|
redis:
|
||||||
|
host: 127.0.0.1
|
||||||
|
database: 0
|
||||||
|
port: 6379
|
||||||
|
password:
|
||||||
|
client-type: lettuce
|
||||||
|
|
||||||
|
|
||||||
|
# 配置 xml 文件所在位置 配置全局的 主键策略,默认为 ASSIGN_ID 默认为 【雪花算法】 , auto 自增
|
||||||
|
mybatis-plus:
|
||||||
|
mapper-locations: classpath*:/mapper/**/*.xml
|
||||||
|
# 搜索指定包别名
|
||||||
|
typeAliasesPackage: com.msgdispatcher.**.entity
|
||||||
|
global-config:
|
||||||
|
# 关闭MP3.0自带的banner
|
||||||
|
banner: false
|
||||||
|
db-config:
|
||||||
|
id-type: ASSIGN_ID
|
||||||
|
# 逻辑删除
|
||||||
|
logic-not-delete-value: 0
|
||||||
|
logic-delete-value: 1
|
||||||
|
#字段策略
|
||||||
|
insert-strategy: not_null
|
||||||
|
update-strategy: not_null
|
||||||
|
where-strategy: not_empty
|
||||||
|
#驼峰下划线转换
|
||||||
|
table-underline: true
|
||||||
|
# 开启驼峰命名 默认开启驼峰命名
|
||||||
|
# mybatis-plus配置控制台打印完整带参数SQL语句
|
||||||
|
configuration:
|
||||||
|
map-underscore-to-camel-case: true
|
||||||
|
cache-enabled: false
|
||||||
|
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||||
|
|
||||||
|
|
||||||
|
logging:
|
||||||
|
level:
|
||||||
|
root: ERROR
|
||||||
|
com:
|
||||||
|
das: ERROR
|
||||||
|
|
||||||
|
tdengine:
|
||||||
|
password: taosdata
|
||||||
|
url: jdbc:TAOS-RS://192.168.109.160:6041/das
|
||||||
|
username: root
|
||||||
|
|
||||||
|
|
||||||
|
dingtalk:
|
||||||
|
webhook:
|
||||||
|
url: https://oapi.dingtalk.com/robot/send?sign=
|
||||||
|
token: 5d3897e1b170ff89b641d136e96582931374b6dbc39e333ffc54d4d5c735b879
|
||||||
|
secret: SECc871ad4be9c0f5f5b72f8a1519a196185d3bcc865ef9d1f184c9cb1a6d9f4649
|
||||||
|
|
||||||
|
dingtalk-user :
|
||||||
|
#获取token接口
|
||||||
|
getTokenUrl: https://oapi.dingtalk.com/gettoken?appkey=
|
||||||
|
#获取用户信息接口
|
||||||
|
getUserUrl: https://oapi.dingtalk.com/user/get?access_token=
|
||||||
|
#开发者中心-应用列表中,应用的AppKey和AppSecret
|
||||||
|
appKey:
|
||||||
|
appSecret:
|
||||||
|
|
||||||
|
msg-file:
|
||||||
|
#消息文件目录
|
||||||
|
directoryPath: /home/dingding
|
||||||
|
#备份目录
|
||||||
|
baseBackupDir: /home/dingding/bak
|
Loading…
Reference in New Issue
Block a user