Compare commits
9 Commits
6d7517f778
...
1dbd00ccef
Author | SHA1 | Date |
---|---|---|
ZhouXY108 | 1dbd00ccef | |
ZhouXY108 | 44f2067f20 | |
ZhouXY108 | cc44c3ddbd | |
ZhouXY108 | 2de86dcc4a | |
ZhouXY108 | 7c522cae1d | |
ZhouXY108 | 117390c5ae | |
ZhouXY108 | cec72ba7f9 | |
ZhouXY108 | d01db60309 | |
ZhouXY108 | 151a33cad4 |
|
@ -4,6 +4,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
|||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import xyz.zhouxy.plusone.exception.handler.BaseExceptionHandler.ExceptionInfoHolder;
|
||||
|
||||
/**
|
||||
* AllExceptionHandlerConfig
|
||||
*/
|
||||
|
@ -12,7 +14,7 @@ import org.springframework.context.annotation.Configuration;
|
|||
public class AllExceptionHandlerConfig {
|
||||
|
||||
@Bean
|
||||
AllExceptionHandler getAllExceptionHandler() {
|
||||
return new AllExceptionHandler(ExceptionInfoHolderFactory.newDefaultExceptionInfoHolder());
|
||||
AllExceptionHandler getAllExceptionHandler(ExceptionInfoHolder exceptionInfoHolder) {
|
||||
return new AllExceptionHandler(exceptionInfoHolder);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,9 +40,8 @@ import xyz.zhouxy.plusone.util.RestfulResult;
|
|||
@Order(Ordered.LOWEST_PRECEDENCE - 1)
|
||||
@Slf4j
|
||||
public class DefaultExceptionHandler extends BaseExceptionHandler {
|
||||
|
||||
public DefaultExceptionHandler() {
|
||||
super(ExceptionInfoHolderFactory.newDefaultExceptionInfoHolder());
|
||||
public DefaultExceptionHandler(ExceptionInfoHolder exceptionInfoHolder) {
|
||||
super(exceptionInfoHolder);
|
||||
set(IllegalArgumentException.class, 4010000, "格式错误", HttpStatus.FORBIDDEN);
|
||||
set(DataAccessException.class, 6030000, "数据库错误", HttpStatus.INTERNAL_SERVER_ERROR, true);
|
||||
set(MethodArgumentNotValidException.class,
|
||||
|
|
|
@ -31,6 +31,11 @@
|
|||
<artifactId>spring-webmvc</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>xyz.zhouxy.plusone</groupId>
|
||||
<artifactId>plusone-commons</artifactId>
|
||||
|
|
|
@ -41,6 +41,14 @@ public final class AssertResult {
|
|||
}
|
||||
}
|
||||
|
||||
public static void updateOneRow(int i) {
|
||||
update(i, 1);
|
||||
}
|
||||
|
||||
public static void updateOneRow(Object i, String format) {
|
||||
update(i, 1, format);
|
||||
}
|
||||
|
||||
public static void exist(boolean expression) {
|
||||
if (!expression) {
|
||||
throw new DataNotExistException();
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?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">
|
||||
<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>xyz.zhouxy</groupId>
|
||||
|
@ -84,6 +86,11 @@
|
|||
<groupId>com.tencentcloudapi</groupId>
|
||||
<artifactId>tencentcloud-sdk-java-sms</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.csource</groupId>
|
||||
<artifactId>fastdfs-client-java</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
package xyz.zhouxy.plusone.exception.config;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import xyz.zhouxy.plusone.constant.ErrorCodeConsts;
|
||||
import xyz.zhouxy.plusone.exception.handler.BaseExceptionHandler.ExceptionInfoHolder;
|
||||
|
||||
@Configuration
|
||||
public class PlusoneExceptionHandlerConfig {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
ExceptionInfoHolder exceptionInfoHolder() {
|
||||
return new ExceptionInfoHolder(ErrorCodeConsts.DEFAULT_ERROR_CODE);
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
package xyz.zhouxy.plusone.exception.handler;
|
||||
|
||||
import xyz.zhouxy.plusone.constant.ErrorCodeConsts;
|
||||
import xyz.zhouxy.plusone.exception.handler.BaseExceptionHandler.ExceptionInfoHolder;
|
||||
|
||||
public class ExceptionInfoHolderFactory {
|
||||
|
||||
private ExceptionInfoHolderFactory() {
|
||||
throw new IllegalStateException("Utility class");
|
||||
}
|
||||
|
||||
public static ExceptionInfoHolder newDefaultExceptionInfoHolder() {
|
||||
return new ExceptionInfoHolder(ErrorCodeConsts.DEFAULT_ERROR_CODE);
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ import javax.annotation.Nonnull;
|
|||
|
||||
import org.springframework.jdbc.core.ResultSetExtractor;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
|
||||
|
||||
|
@ -35,6 +36,10 @@ public abstract class JdbcEntityDaoSupport<T extends Entity<ID>, ID extends Seri
|
|||
return this.jdbc.query(sql, paramSource, this.resultSetExtractor);
|
||||
}
|
||||
|
||||
protected final T queryForObject(String sql, String paramName, Object value) {
|
||||
return this.jdbc.query(sql, new MapSqlParameterSource(paramName, value), this.resultSetExtractor);
|
||||
}
|
||||
|
||||
protected final List<T> queryForList(String sql) {
|
||||
return this.jdbc.query(sql, this.rowMapper);
|
||||
}
|
||||
|
@ -43,19 +48,36 @@ public abstract class JdbcEntityDaoSupport<T extends Entity<ID>, ID extends Seri
|
|||
return this.jdbc.query(sql, parameterSource, this.rowMapper);
|
||||
}
|
||||
|
||||
protected final List<T> queryForList(String sql, String paramName, Object value) {
|
||||
return this.jdbc.query(sql, new MapSqlParameterSource(paramName, value), this.rowMapper);
|
||||
}
|
||||
|
||||
protected final Stream<T> queryForStream(String sql, SqlParameterSource parameterSource) {
|
||||
return this.jdbc.queryForStream(sql, parameterSource, this.rowMapper);
|
||||
}
|
||||
|
||||
protected final Stream<T> queryForStream(String sql, String paramName, Object value) {
|
||||
return this.jdbc.queryForStream(sql, new MapSqlParameterSource(paramName, value), this.rowMapper);
|
||||
}
|
||||
|
||||
protected final <E> Stream<E> queryForStream(String sql, SqlParameterSource parameterSource, Class<E> elementType) {
|
||||
return this.jdbc.queryForList(sql, parameterSource, elementType).stream();
|
||||
}
|
||||
|
||||
protected final <E> Stream<E> queryForStream(String sql, String paramName, Object value, Class<E> elementType) {
|
||||
return this.jdbc.queryForList(sql, new MapSqlParameterSource(paramName, value), elementType).stream();
|
||||
}
|
||||
|
||||
protected final boolean queryExists(String sql, SqlParameterSource parameterSource) {
|
||||
Boolean isExists = this.jdbc.query(sql, parameterSource, ResultSet::next);
|
||||
return Boolean.TRUE.equals(isExists);
|
||||
}
|
||||
|
||||
protected final boolean queryExists(String sql, String paramName, Object value) {
|
||||
Boolean isExists = this.jdbc.query(sql, new MapSqlParameterSource(paramName, value), ResultSet::next);
|
||||
return Boolean.TRUE.equals(isExists);
|
||||
}
|
||||
|
||||
protected final int update(String sql, SqlParameterSource parameterSource) {
|
||||
return this.jdbc.update(sql, parameterSource);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
package xyz.zhouxy.plusone.oss;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.csource.common.MyException;
|
||||
import org.csource.fastdfs.ClientGlobal;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import xyz.zhouxy.plusone.oss.FastDFSProperties.ConnectionPool;
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(FastDFSProperties.class)
|
||||
@ConditionalOnClass(FastDFSUtil.class)
|
||||
@EnableAutoConfiguration
|
||||
public class FastDFSAutoConfig {
|
||||
|
||||
@Bean
|
||||
@SuppressWarnings("all")
|
||||
FastDFSUtil fastDFSUtil(FastDFSProperties props) throws IOException, FastDFSException {
|
||||
|
||||
List<String> trackerServerStrList = props.getTrackerServers();
|
||||
if (CollectionUtils.isEmpty(trackerServerStrList)) {
|
||||
throw new FastDFSException(
|
||||
String.format("configure item %s is required - ", ClientGlobal.PROP_KEY_TRACKER_SERVERS));
|
||||
}
|
||||
try {
|
||||
InetSocketAddress[] trackerServers = trackerServerStrList.stream()
|
||||
.map(trackerServer -> {
|
||||
String[] hostPort = trackerServer.trim().split(":");
|
||||
String host = hostPort[0].trim();
|
||||
int port = Integer.parseInt(hostPort[1].trim());
|
||||
return new InetSocketAddress(host, port);
|
||||
})
|
||||
.toArray(InetSocketAddress[]::new);
|
||||
ClientGlobal.initByTrackers(trackerServers);
|
||||
|
||||
var connectTimeoutInSecondsConf = props.getConnectTimeoutInSeconds();
|
||||
if (connectTimeoutInSecondsConf != null) {
|
||||
ClientGlobal.setG_connect_timeout(connectTimeoutInSecondsConf * 1000);
|
||||
}
|
||||
var networkTimeoutInSecondsConf = props.getNetworkTimeoutInSeconds();
|
||||
if (networkTimeoutInSecondsConf != null) {
|
||||
ClientGlobal.setG_network_timeout(networkTimeoutInSecondsConf * 1000);
|
||||
}
|
||||
var charsetConf = props.getCharset();
|
||||
if (StringUtils.hasText(charsetConf)) {
|
||||
ClientGlobal.setG_charset(charsetConf);
|
||||
}
|
||||
var httpAntiStealTokenConf = props.getHttpAntiStealToken();
|
||||
if (httpAntiStealTokenConf != null) {
|
||||
ClientGlobal.setG_anti_steal_token(httpAntiStealTokenConf);
|
||||
}
|
||||
var httpSecretKeyConf = props.getHttpSecretKey();
|
||||
if (StringUtils.hasText(httpSecretKeyConf)) {
|
||||
ClientGlobal.setG_secret_key(httpSecretKeyConf);
|
||||
}
|
||||
var httpTrackerHttpPortConf = props.getHttpTrackerHttpPort();
|
||||
if (httpTrackerHttpPortConf != null) {
|
||||
ClientGlobal.setG_tracker_http_port(httpTrackerHttpPortConf);
|
||||
}
|
||||
|
||||
ConnectionPool connectionPool = props.getConnectionPool();
|
||||
var poolEnabled = Objects.nonNull(connectionPool)
|
||||
&& Boolean.TRUE.equals(connectionPool.getEnabled());
|
||||
|
||||
if (poolEnabled) {
|
||||
var poolMaxCountPerEntry = connectionPool.getMaxCountPerEntry();
|
||||
if (poolMaxCountPerEntry != null) {
|
||||
ClientGlobal.g_connection_pool_max_count_per_entry = poolMaxCountPerEntry;
|
||||
}
|
||||
var poolMaxIdleTime = connectionPool.getMaxIdleTime();
|
||||
if (poolMaxIdleTime != null) {
|
||||
ClientGlobal.g_connection_pool_max_idle_time = poolMaxIdleTime * 1000;
|
||||
}
|
||||
var poolMaxWaitTimeInMS = connectionPool.getMaxWaitTimeInMs();
|
||||
if (poolMaxWaitTimeInMS != null) {
|
||||
ClientGlobal.g_connection_pool_max_wait_time_in_ms = poolMaxWaitTimeInMS;
|
||||
}
|
||||
}
|
||||
return new FastDFSUtil();
|
||||
} catch (MyException e) {
|
||||
throw new FastDFSException(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package xyz.zhouxy.plusone.oss;
|
||||
|
||||
/**
|
||||
* 封装 FastDFS 的 {@link org.csource.common.MyException}
|
||||
*
|
||||
* @author <a href="https://gitee.com/zhouxy108">ZhouXY</a>
|
||||
*/
|
||||
public class FastDFSException extends Exception {
|
||||
|
||||
public FastDFSException() {
|
||||
}
|
||||
|
||||
public FastDFSException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public FastDFSException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public FastDFSException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public FastDFSException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package xyz.zhouxy.plusone.oss;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@ConfigurationProperties("fastdfs")
|
||||
public class FastDFSProperties {
|
||||
private Integer connectTimeoutInSeconds;
|
||||
private Integer networkTimeoutInSeconds;
|
||||
private String charset;
|
||||
private Boolean httpAntiStealToken;
|
||||
private String httpSecretKey;
|
||||
private Integer httpTrackerHttpPort;
|
||||
private List<String> trackerServers;
|
||||
|
||||
private ConnectionPool connectionPool;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public static class ConnectionPool {
|
||||
private Boolean enabled;
|
||||
private Integer maxCountPerEntry;
|
||||
private Integer maxIdleTime;
|
||||
private Integer maxWaitTimeInMs;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
package xyz.zhouxy.plusone.oss;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.csource.common.MyException;
|
||||
import org.csource.common.NameValuePair;
|
||||
import org.csource.fastdfs.FileInfo;
|
||||
import org.csource.fastdfs.StorageClient;
|
||||
import org.csource.fastdfs.StorageServer;
|
||||
import org.csource.fastdfs.TrackerClient;
|
||||
import org.csource.fastdfs.TrackerServer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
public class FastDFSUtil {
|
||||
|
||||
private final TrackerServer trackerServer;
|
||||
private final StorageServer storageServer;
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(FastDFSUtil.class);
|
||||
|
||||
FastDFSUtil() throws IOException, MyException {
|
||||
TrackerClient trackerClient = new TrackerClient();
|
||||
this.trackerServer = trackerClient.getTrackerServer();
|
||||
this.storageServer = trackerClient.getStoreStorage(trackerServer);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件到 Fast DFS,失败将抛异常
|
||||
*
|
||||
* @param file 文件信息
|
||||
* @return 2 elements string array if success:<br>
|
||||
* <ul>
|
||||
* <li>results[0]: the group name to store the file</li>
|
||||
* </ul>
|
||||
* <ul>
|
||||
* <li>results[1]: the new created filename</li>
|
||||
* </ul>
|
||||
* return null if fail
|
||||
* @throws FastDFSException
|
||||
*/
|
||||
public String[] upload(FastDFSFile file) throws FastDFSException {
|
||||
logger.info("File Name: {}, File Length: {}", file.getName(), file.getContent().length);
|
||||
|
||||
NameValuePair[] metaList = new NameValuePair[1];
|
||||
metaList[0] = new NameValuePair("author", file.getAuthor());
|
||||
|
||||
long startTime = System.currentTimeMillis();
|
||||
StorageClient storageClient = null;
|
||||
String[] uploadResults = null;
|
||||
try {
|
||||
storageClient = new StorageClient(this.trackerServer, this.storageServer);
|
||||
uploadResults = storageClient.upload_file(file.getContent(), file.getExt(), metaList);
|
||||
|
||||
if (uploadResults == null) {
|
||||
throw new FastDFSException("upload file fail, error code: " + storageClient.getErrorCode());
|
||||
}
|
||||
logger.info("Upload file successfully!!! group_name: {}, remoteFileName: {}, time used: {} ms",
|
||||
uploadResults[0], uploadResults[1], System.currentTimeMillis() - startTime);
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new FastDFSException("IO Exception when uploadind the file:" + file.getName(), e);
|
||||
} catch (MyException e) {
|
||||
throw new FastDFSException(e);
|
||||
}
|
||||
|
||||
return uploadResults;
|
||||
}
|
||||
|
||||
public FileInfo getFile(String groupName, String remoteFileName) throws FastDFSException {
|
||||
try {
|
||||
StorageClient storageClient = new StorageClient(this.trackerServer, this.storageServer);
|
||||
return storageClient.get_file_info(groupName, remoteFileName);
|
||||
} catch (IOException e) {
|
||||
throw new FastDFSException("IO Exception: Get File from Fast DFS failed", e);
|
||||
} catch (Exception e) {
|
||||
throw new FastDFSException("Non IO Exception: Get File from Fast DFS failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
public InputStream downFile(String groupName, String remoteFileName) throws FastDFSException {
|
||||
try {
|
||||
StorageClient storageClient = new StorageClient(this.trackerServer, this.storageServer);
|
||||
byte[] fileByte = storageClient.download_file(groupName, remoteFileName);
|
||||
InputStream ins = new ByteArrayInputStream(fileByte);
|
||||
return ins;
|
||||
} catch (IOException e) {
|
||||
throw new FastDFSException("IO Exception: Get File from Fast DFS failed", e);
|
||||
} catch (Exception e) {
|
||||
throw new FastDFSException("Non IO Exception: Get File from Fast DFS failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteFile(String groupName, String remoteFileName) throws FastDFSException {
|
||||
StorageClient storageClient = new StorageClient(this.trackerServer, this.storageServer);
|
||||
try {
|
||||
int i = storageClient.delete_file(groupName, remoteFileName);
|
||||
if (i == 0) {
|
||||
logger.info("Delete file SUCCESSFULLY!!!");
|
||||
} else {
|
||||
throw new FastDFSException("Delete file failed, error code is: " + i);
|
||||
}
|
||||
} catch (IOException | MyException e) {
|
||||
throw new FastDFSException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
public static final class FastDFSFile {
|
||||
private String name;
|
||||
private byte[] content;
|
||||
private String ext;
|
||||
private String md5;
|
||||
private String author;
|
||||
|
||||
public FastDFSFile(String name, byte[] content, String ext) {
|
||||
this.name = name;
|
||||
this.content = content;
|
||||
this.ext = ext;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,13 +3,12 @@ package xyz.zhouxy.plusone.validator;
|
|||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
|
||||
import xyz.zhouxy.plusone.exception.handler.BaseExceptionHandler;
|
||||
import xyz.zhouxy.plusone.exception.handler.ExceptionInfoHolderFactory;
|
||||
|
||||
@RestControllerAdvice
|
||||
public class InvalidInputExceptionHandler extends BaseExceptionHandler {
|
||||
|
||||
protected InvalidInputExceptionHandler() {
|
||||
super(ExceptionInfoHolderFactory.newDefaultExceptionInfoHolder());
|
||||
public InvalidInputExceptionHandler(ExceptionInfoHolder exceptionInfoHolder) {
|
||||
super(exceptionInfoHolder);
|
||||
set(InvalidInputException.class, InvalidInputException.ERROR_CODE, "无效的用户输入");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import lombok.NoArgsConstructor;
|
|||
import xyz.zhouxy.plusone.constant.RegexConsts;
|
||||
import xyz.zhouxy.plusone.validator.BaseValidator;
|
||||
|
||||
class BaseValidator2Test {
|
||||
class BaseValidatorTest {
|
||||
|
||||
@Test
|
||||
void testValid() {
|
|
@ -1,34 +1,57 @@
|
|||
{
|
||||
"properties": [
|
||||
{
|
||||
"name": "plusone.application.name",
|
||||
"type": "java.lang.String",
|
||||
"description": "A description for 'plusone.application.name'"
|
||||
},
|
||||
{
|
||||
"name": "plusone.server.port",
|
||||
"type": "java.lang.Integer",
|
||||
"description": "A description for 'plusone.server.port'"
|
||||
},
|
||||
{
|
||||
"name": "plusone.debug",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "A description for 'plusone.debug'"
|
||||
},
|
||||
{
|
||||
"name": "plusone.mail.host",
|
||||
"type": "java.lang.String",
|
||||
"description": "A description for 'plusone.mail.host'"
|
||||
},
|
||||
{
|
||||
"name": "plusone.mail.password",
|
||||
"type": "java.lang.String",
|
||||
"description": "A description for 'plusone.mail.password'"
|
||||
},
|
||||
{
|
||||
"name": "plusone.exception.handle-all-exception",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "A description for 'plusone.exception.handle-all-exception'"
|
||||
}
|
||||
]
|
||||
}
|
||||
{"properties": [
|
||||
{
|
||||
"name": "plusone.application.name",
|
||||
"type": "java.lang.String",
|
||||
"description": "A description for 'plusone.application.name'"
|
||||
},
|
||||
{
|
||||
"name": "plusone.server.port",
|
||||
"type": "java.lang.Integer",
|
||||
"description": "A description for 'plusone.server.port'"
|
||||
},
|
||||
{
|
||||
"name": "plusone.debug",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "A description for 'plusone.debug'"
|
||||
},
|
||||
{
|
||||
"name": "plusone.mail.host",
|
||||
"type": "java.lang.String",
|
||||
"description": "A description for 'plusone.mail.host'"
|
||||
},
|
||||
{
|
||||
"name": "plusone.mail.password",
|
||||
"type": "java.lang.String",
|
||||
"description": "A description for 'plusone.mail.password'"
|
||||
},
|
||||
{
|
||||
"name": "plusone.exception.handle-all-exception",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "A description for 'plusone.exception.handle-all-exception'"
|
||||
},
|
||||
{
|
||||
"name": "fastdfs.http_anti_steal_token",
|
||||
"type": "java.lang.String",
|
||||
"description": "A description for 'fastdfs.http_anti_steal_token'"
|
||||
},
|
||||
{
|
||||
"name": "fastdfs.http_secret_key",
|
||||
"type": "java.lang.String",
|
||||
"description": "A description for 'fastdfs.http_secret_key'"
|
||||
},
|
||||
{
|
||||
"name": "fastdfs.http_tracker_http_port",
|
||||
"type": "java.lang.String",
|
||||
"description": "A description for 'fastdfs.http_tracker_http_port'"
|
||||
},
|
||||
{
|
||||
"name": "fastdfs.network_timeout_in_seconds",
|
||||
"type": "java.lang.String",
|
||||
"description": "A description for 'fastdfs.network_timeout_in_seconds'"
|
||||
},
|
||||
{
|
||||
"name": "fastdfs.tracker_servers",
|
||||
"type": "java.util.List",
|
||||
"description": "A description for 'fastdfs.tracker_servers'"
|
||||
}
|
||||
]}
|
||||
|
|
|
@ -63,7 +63,16 @@ plusone:
|
|||
exception:
|
||||
handle-all-exception: false
|
||||
|
||||
# 日志配置
|
||||
logging:
|
||||
level:
|
||||
root: debug
|
||||
fastdfs:
|
||||
connect_timeout_in_seconds: 5
|
||||
network_timeout_in_seconds: 30
|
||||
charset: UTF-8
|
||||
http_anti_steal_token: false
|
||||
http_secret_key: FastDFS1234567890
|
||||
http_tracker_http_port: 80
|
||||
tracker_servers: 10.0.11.201:22122,10.0.11.202:22122,10.0.11.203:22122
|
||||
connection_pool:
|
||||
enabled: true
|
||||
max_count_per_entry: 500
|
||||
max_idle_time: 3600
|
||||
max_wait_time_in_ms: 1000
|
||||
|
|
|
@ -9,3 +9,8 @@ plusone:
|
|||
code: Plusone
|
||||
template:
|
||||
code: 【Plusone】验证码:%s,10分钟内有效,请勿泄露。
|
||||
# 日志配置
|
||||
logging:
|
||||
level:
|
||||
root: info
|
||||
'[xyz.zhouxy.plusone]': debug
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package xyz.zhouxy.plusone;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import xyz.zhouxy.plusone.oss.FastDFSException;
|
||||
import xyz.zhouxy.plusone.oss.FastDFSUtil;
|
||||
import xyz.zhouxy.plusone.oss.FastDFSUtil.FastDFSFile;
|
||||
|
||||
@SpringBootTest(classes = PlusoneApplication.class)
|
||||
@Slf4j
|
||||
class FastDFSTests {
|
||||
|
||||
@Resource
|
||||
FastDFSUtil fastDFSUtil;
|
||||
|
||||
@Test
|
||||
void testOSS() throws FileNotFoundException, IOException, FastDFSException {
|
||||
try (FileInputStream in = new FileInputStream("D:\\ZhouXY\\Desktop\\666.png");) {
|
||||
byte[] content = IOUtils.toByteArray(in);
|
||||
String[] upload = fastDFSUtil.upload(new FastDFSFile("666.png", content, "png"));
|
||||
log.info(String.join("/", upload));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
spring:
|
||||
profiles:
|
||||
active: secret
|
||||
|
||||
plusone:
|
||||
# 邮件发送相关参数
|
||||
mail:
|
||||
subject:
|
||||
code: Plusone
|
||||
template:
|
||||
code: 【Plusone】验证码:%s,10分钟内有效,请勿泄露。
|
||||
# 日志配置
|
||||
logging:
|
||||
level:
|
||||
root: info
|
||||
'[xyz.zhouxy.plusone]': debug
|
|
@ -7,15 +7,14 @@ import org.springframework.web.bind.annotation.ExceptionHandler;
|
|||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
|
||||
import xyz.zhouxy.plusone.exception.handler.BaseExceptionHandler;
|
||||
import xyz.zhouxy.plusone.exception.handler.ExceptionInfoHolderFactory;
|
||||
import xyz.zhouxy.plusone.system.application.exception.AccountLoginException;
|
||||
import xyz.zhouxy.plusone.util.RestfulResult;
|
||||
|
||||
@RestControllerAdvice
|
||||
public class AccountLoginExceptionHandler extends BaseExceptionHandler {
|
||||
|
||||
protected AccountLoginExceptionHandler() {
|
||||
super(ExceptionInfoHolderFactory.newDefaultExceptionInfoHolder());
|
||||
public AccountLoginExceptionHandler(ExceptionInfoHolder exceptionInfoHolder) {
|
||||
super(exceptionInfoHolder);
|
||||
}
|
||||
|
||||
@ExceptionHandler({ AccountLoginException.class })
|
||||
|
|
|
@ -15,7 +15,6 @@ import cn.dev33.satoken.exception.SaTokenException;
|
|||
import cn.dev33.satoken.exception.SameTokenInvalidException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import xyz.zhouxy.plusone.exception.handler.BaseExceptionHandler;
|
||||
import xyz.zhouxy.plusone.exception.handler.ExceptionInfoHolderFactory;
|
||||
import xyz.zhouxy.plusone.util.RestfulResult;
|
||||
|
||||
/**
|
||||
|
@ -27,8 +26,9 @@ import xyz.zhouxy.plusone.util.RestfulResult;
|
|||
@Slf4j
|
||||
public class SaTokenExceptionHandler extends BaseExceptionHandler {
|
||||
|
||||
public SaTokenExceptionHandler() {
|
||||
super(ExceptionInfoHolderFactory.newDefaultExceptionInfoHolder());
|
||||
|
||||
public SaTokenExceptionHandler(ExceptionInfoHolder exceptionInfoHolder) {
|
||||
super(exceptionInfoHolder);
|
||||
set(NotPermissionException.class, 4030103, "会话未能通过权限认证", HttpStatus.FORBIDDEN);
|
||||
set(NotRoleException.class, 4030103, "会话未能通过角色认证", HttpStatus.FORBIDDEN);
|
||||
set(DisableServiceException.class, 4030202, "账号指定服务已被封禁", HttpStatus.FORBIDDEN);
|
||||
|
|
|
@ -34,7 +34,7 @@ import xyz.zhouxy.plusone.validator.InvalidInputException;
|
|||
@Service
|
||||
public class AccountContextService {
|
||||
|
||||
private final static StpLogic adminAuthLogic = AuthLogic.adminAuthLogic;
|
||||
private static final StpLogic adminAuthLogic = AuthLogic.adminAuthLogic;
|
||||
|
||||
@Resource
|
||||
private AccountQueries accountQueries;
|
||||
|
@ -95,7 +95,7 @@ public class AccountContextService {
|
|||
case MOBILE_PHONE -> accountRepository.findByMobilePhone(MobilePhone.of(principal));
|
||||
default -> throw InvalidInputException.unsupportedPrincipalTypeException("输入邮箱地址或手机号");
|
||||
};
|
||||
Assert.notNull(account, () -> AccountLoginException.accountNotExistException());
|
||||
Assert.notNull(account, AccountLoginException::accountNotExistException);
|
||||
|
||||
mailAndSmsVerifyService.checkOtp(principal, command.getOtp());
|
||||
}
|
||||
|
|
|
@ -49,9 +49,9 @@ public class AdminLoginService {
|
|||
case EMAIL -> accountRepository.findByEmail(Email.of(principal));
|
||||
case MOBILE_PHONE -> accountRepository.findByMobilePhone(MobilePhone.of(principal));
|
||||
};
|
||||
Assert.notNull(account, () -> AccountLoginException.accountNotExistException());
|
||||
Assert.notNull(account, AccountLoginException::accountNotExistException);
|
||||
var isPasswordCorrect = account.checkPassword(command.getPassword());
|
||||
Assert.isTrue(isPasswordCorrect, () -> AccountLoginException.passwordErrorException());
|
||||
Assert.isTrue(isPasswordCorrect, AccountLoginException::passwordErrorException);
|
||||
|
||||
adminAuthLogic.login(account.getId().orElseThrow(), command.isRememberMe());
|
||||
var accountDetails = accountQueries.queryAccountDetails(account.getId().orElseThrow());
|
||||
|
@ -66,7 +66,7 @@ public class AdminLoginService {
|
|||
case MOBILE_PHONE -> accountRepository.findByMobilePhone(MobilePhone.of(principal));
|
||||
default -> throw InvalidInputException.unsupportedPrincipalTypeException("输入邮箱地址或手机号");
|
||||
};
|
||||
Assert.notNull(account, () -> AccountLoginException.accountNotExistException());
|
||||
Assert.notNull(account, AccountLoginException::accountNotExistException);
|
||||
|
||||
mailAndSmsVerifyService.checkOtp(principal, command.getOtp());
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ public class AccountRepositoryImpl extends JdbcRepositorySupport<Account, Long>
|
|||
new MapSqlParameterSource()
|
||||
.addValue("id", entity.getId().orElseThrow())
|
||||
.addValue("version", entity.getVersion()));
|
||||
AssertResult.update(i, 1);
|
||||
AssertResult.updateOneRow(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -53,7 +53,7 @@ public class AccountRepositoryImpl extends JdbcRepositorySupport<Account, Long>
|
|||
FROM sys_account
|
||||
WHERE id = :id AND deleted = 0
|
||||
""",
|
||||
new MapSqlParameterSource("id", id));
|
||||
"id", id);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -65,7 +65,7 @@ public class AccountRepositoryImpl extends JdbcRepositorySupport<Account, Long>
|
|||
FROM sys_account
|
||||
WHERE email = :email AND deleted = 0
|
||||
""",
|
||||
new MapSqlParameterSource("email", email.value()));
|
||||
"email", email.value());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -77,7 +77,7 @@ public class AccountRepositoryImpl extends JdbcRepositorySupport<Account, Long>
|
|||
FROM sys_account
|
||||
WHERE mobile_phone = :mobilePhone AND deleted = 0
|
||||
""",
|
||||
new MapSqlParameterSource("mobilePhone", mobilePhone.value()));
|
||||
"mobilePhone", mobilePhone.value());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -89,31 +89,31 @@ public class AccountRepositoryImpl extends JdbcRepositorySupport<Account, Long>
|
|||
FROM sys_account
|
||||
WHERE username = :username AND deleted = 0
|
||||
""",
|
||||
new MapSqlParameterSource("username", username.value()));
|
||||
"username", username.value());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists(Long id) {
|
||||
return queryExists("SELECT 1 FROM sys_account WHERE id = :id AND deleted = 0 LIMIT 1",
|
||||
new MapSqlParameterSource("id", id));
|
||||
"id", id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean existsUsername(Username username) {
|
||||
return queryExists("SELECT 1 FROM sys_account WHERE username = :username AND deleted = 0 LIMIT 1",
|
||||
new MapSqlParameterSource("username", username.value()));
|
||||
"username", username.value());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean existsEmail(Email email) {
|
||||
return queryExists("SELECT 1 FROM sys_account WHERE email = :email AND deleted = 0 LIMIT 1",
|
||||
new MapSqlParameterSource("email", email.value()));
|
||||
"email", email.value());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean existsMobilePhone(MobilePhone mobilePhone) {
|
||||
return queryExists("SELECT 1 FROM sys_account WHERE mobile_phone = :mobile_phone AND deleted = 0 LIMIT 1",
|
||||
new MapSqlParameterSource("mobile_phone", mobilePhone.value()));
|
||||
"mobile_phone", mobilePhone.value());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -127,7 +127,7 @@ public class AccountRepositoryImpl extends JdbcRepositorySupport<Account, Long>
|
|||
LEFT JOIN sys_account_role ar ON a.id = ar.account_id
|
||||
WHERE ar.role_id = :roleId AND a.deleted = 0
|
||||
""",
|
||||
new MapSqlParameterSource("roleId", roleId));
|
||||
"roleId", roleId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -142,7 +142,7 @@ public class AccountRepositoryImpl extends JdbcRepositorySupport<Account, Long>
|
|||
:createdBy, :createTime)
|
||||
""",
|
||||
generateParamSource(id, entity));
|
||||
AssertResult.update(i, 1);
|
||||
AssertResult.updateOneRow(i);
|
||||
this.accountRoleDAO.insertAccountRoleRefs(id, entity.getRoleIds());
|
||||
return entity;
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ public class AccountRepositoryImpl extends JdbcRepositorySupport<Account, Long>
|
|||
WHERE id = :id AND deleted = 0 AND "version" = :version
|
||||
""",
|
||||
generateParamSource(entity));
|
||||
AssertResult.update(i, 1);
|
||||
AssertResult.updateOneRow(i);
|
||||
this.accountRoleDAO.saveAccountRoleRefs(entity);
|
||||
return entity;
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ public class DictRepositoryImpl extends JdbcRepositorySupport<Dict, Long> implem
|
|||
@Override
|
||||
public Dict doFindById(@Nonnull Long id) {
|
||||
return queryForObject("SELECT id, dict_type, dict_label, \"version\" WHERE id = :id AND deleted = 0",
|
||||
new MapSqlParameterSource("id", id));
|
||||
"id", id);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -47,7 +47,7 @@ public class DictRepositoryImpl extends JdbcRepositorySupport<Dict, Long> implem
|
|||
VALUES (:dictType, :dictLabel, :createTime, :createdBy)
|
||||
""",
|
||||
generateParamSource(id, entity));
|
||||
AssertResult.update(i, 1);
|
||||
AssertResult.updateOneRow(i);
|
||||
this.dictValueDAO.insertDictValues(id, entity);
|
||||
return find(id);
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ public class DictRepositoryImpl extends JdbcRepositorySupport<Dict, Long> implem
|
|||
WHERE id = :id AND deleted = 0 AND "version" = :version
|
||||
""",
|
||||
generateParamSource(entity));
|
||||
AssertResult.update(i, 1);
|
||||
AssertResult.updateOneRow(i);
|
||||
this.dictValueDAO.updateDictValues(entity);
|
||||
return find(entity.getId().orElseThrow());
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ public class DictRepositoryImpl extends JdbcRepositorySupport<Dict, Long> implem
|
|||
WHERE id = :id AND deleted = 0 AND "version" = :version
|
||||
""",
|
||||
generateParamSource(entity));
|
||||
AssertResult.update(i, 1);
|
||||
AssertResult.updateOneRow(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -46,7 +46,7 @@ public class MenuRepositoryImpl extends JdbcRepositorySupport<Menu, Long> implem
|
|||
FROM sys_menu
|
||||
WHERE id = :id AND deleted = 0
|
||||
""",
|
||||
new MapSqlParameterSource("id", id));
|
||||
"id", id);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -62,7 +62,7 @@ public class MenuRepositoryImpl extends JdbcRepositorySupport<Menu, Long> implem
|
|||
""";
|
||||
MapSqlParameterSource paramSource = generateParamSource(id, entity);
|
||||
int i = update(sql, paramSource);
|
||||
AssertResult.update(i, 1);
|
||||
AssertResult.updateOneRow(i);
|
||||
this.actionDAO.saveActions(id, entity.getActions());
|
||||
return entity;
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ public class MenuRepositoryImpl extends JdbcRepositorySupport<Menu, Long> implem
|
|||
|
||||
// 更新菜单
|
||||
int i = update(sql, generateParamSource(entity));
|
||||
AssertResult.update(i, 1);
|
||||
AssertResult.updateOneRow(i);
|
||||
|
||||
// 保存权限
|
||||
Long id = entity.getId().orElseThrow();
|
||||
|
@ -108,13 +108,13 @@ public class MenuRepositoryImpl extends JdbcRepositorySupport<Menu, Long> implem
|
|||
""",
|
||||
new MapSqlParameterSource("id", entity.getId().orElseThrow())
|
||||
.addValue("version", entity.getVersion()));
|
||||
AssertResult.update(i, 1);
|
||||
AssertResult.updateOneRow(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists(Long id) {
|
||||
return queryExists("SELECT 1 FROM sys_menu WHERE id = :id AND deleted = 0 LIMIT 1",
|
||||
new MapSqlParameterSource("id", id));
|
||||
"id", id);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -129,7 +129,7 @@ public class MenuRepositoryImpl extends JdbcRepositorySupport<Menu, Long> implem
|
|||
FROM sys_menu
|
||||
WHERE id IN (:ids) AND deleted = 0
|
||||
""",
|
||||
new MapSqlParameterSource("ids", ids));
|
||||
"ids", ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -147,7 +147,7 @@ public class MenuRepositoryImpl extends JdbcRepositorySupport<Menu, Long> implem
|
|||
LEFT JOIN sys_role_menu AS rm ON m.id = rm.menu_id
|
||||
WHERE rm.role_id = :roleId AND r.deleted = 0
|
||||
""",
|
||||
new MapSqlParameterSource("roleId", roleId));
|
||||
"roleId", roleId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -41,7 +41,8 @@ public class RoleRepositoryImpl extends JdbcRepositorySupport<Role, Long> implem
|
|||
SELECT "id","name","identifier","status","remarks","version"
|
||||
FROM "sys_role"
|
||||
WHERE id = :id AND deleted = 0
|
||||
""", new MapSqlParameterSource("id", id));
|
||||
""",
|
||||
"id", id);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -52,13 +53,13 @@ public class RoleRepositoryImpl extends JdbcRepositorySupport<Role, Long> implem
|
|||
""",
|
||||
new MapSqlParameterSource("id", entity.getId().orElseThrow())
|
||||
.addValue("version", entity.getVersion()));
|
||||
AssertResult.update(i, 1);
|
||||
AssertResult.updateOneRow(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists(Long id) {
|
||||
return queryExists("SELECT 1 FROM sys_role WHERE id = :id AND deleted = 0 LIMIT 1",
|
||||
new MapSqlParameterSource("id", id));
|
||||
"id", id);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -70,7 +71,7 @@ public class RoleRepositoryImpl extends JdbcRepositorySupport<Role, Long> implem
|
|||
VALUES
|
||||
(:id, :name, :identifier, :status, :remarks, :createTime, :createdBy)
|
||||
""", generateParamSource(id, entity));
|
||||
AssertResult.update(i, 1);
|
||||
AssertResult.updateOneRow(i);
|
||||
this.roleMenuRefDAO.saveRoleMenuRefs(id, entity);
|
||||
this.rolePermissionRefDAO.saveRolePermissionRefs(id, entity);
|
||||
return entity;
|
||||
|
@ -89,7 +90,7 @@ public class RoleRepositoryImpl extends JdbcRepositorySupport<Role, Long> implem
|
|||
"version" = "version" + 1
|
||||
WHERE id = :id AND deleted = 0 AND "version" = :version
|
||||
""", generateParamSource(entity));
|
||||
AssertResult.update(i, 1);
|
||||
AssertResult.updateOneRow(i);
|
||||
|
||||
Long id = entity.getId().orElseThrow();
|
||||
this.roleMenuRefDAO.clearRoleMenuRefs(entity);
|
||||
|
@ -106,7 +107,8 @@ public class RoleRepositoryImpl extends JdbcRepositorySupport<Role, Long> implem
|
|||
FROM sys_role AS r
|
||||
LEFT JOIN sys_account_role AS ar ON r.id = ar.role_id
|
||||
WHERE ar.account_id = :accountId AND r.deleted = 0
|
||||
""", new MapSqlParameterSource("accountId", accountId));
|
||||
""",
|
||||
"accountId", accountId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue