Compare commits

..

No commits in common. "1b551eeb4c44f4723e91a426a9ab299e660b8dea" and "1611bf38e81b7f3d168d685e5265bd2387f4dd8e" have entirely different histories.

61 changed files with 409 additions and 1175 deletions

View File

@ -4,8 +4,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import xyz.zhouxy.plusone.exception.handler.BaseExceptionHandler.ExceptionInfoHolder;
/** /**
* AllExceptionHandlerConfig * AllExceptionHandlerConfig
*/ */
@ -14,7 +12,7 @@ import xyz.zhouxy.plusone.exception.handler.BaseExceptionHandler.ExceptionInfoHo
public class AllExceptionHandlerConfig { public class AllExceptionHandlerConfig {
@Bean @Bean
AllExceptionHandler getAllExceptionHandler(ExceptionInfoHolder exceptionInfoHolder) { AllExceptionHandler getAllExceptionHandler() {
return new AllExceptionHandler(exceptionInfoHolder); return new AllExceptionHandler(ExceptionInfoHolderFactory.newDefaultExceptionInfoHolder());
} }
} }

View File

@ -40,8 +40,9 @@ import xyz.zhouxy.plusone.util.RestfulResult;
@Order(Ordered.LOWEST_PRECEDENCE - 1) @Order(Ordered.LOWEST_PRECEDENCE - 1)
@Slf4j @Slf4j
public class DefaultExceptionHandler extends BaseExceptionHandler { public class DefaultExceptionHandler extends BaseExceptionHandler {
public DefaultExceptionHandler(ExceptionInfoHolder exceptionInfoHolder) {
super(exceptionInfoHolder); public DefaultExceptionHandler() {
super(ExceptionInfoHolderFactory.newDefaultExceptionInfoHolder());
set(IllegalArgumentException.class, 4010000, "格式错误", HttpStatus.FORBIDDEN); set(IllegalArgumentException.class, 4010000, "格式错误", HttpStatus.FORBIDDEN);
set(DataAccessException.class, 6030000, "数据库错误", HttpStatus.INTERNAL_SERVER_ERROR, true); set(DataAccessException.class, 6030000, "数据库错误", HttpStatus.INTERNAL_SERVER_ERROR, true);
set(MethodArgumentNotValidException.class, set(MethodArgumentNotValidException.class,

View File

@ -31,11 +31,6 @@
<artifactId>spring-webmvc</artifactId> <artifactId>spring-webmvc</artifactId>
</dependency> </dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<dependency> <dependency>
<groupId>xyz.zhouxy.plusone</groupId> <groupId>xyz.zhouxy.plusone</groupId>
<artifactId>plusone-commons</artifactId> <artifactId>plusone-commons</artifactId>

View File

@ -6,7 +6,12 @@ import org.springframework.web.bind.annotation.ResponseStatus;
/** /**
* *
* *
* <p>
*
* </p>
*
* @author <a href="https://gitee.com/zhouxy108">ZhouXY</a> * @author <a href="https://gitee.com/zhouxy108">ZhouXY</a>
* @see xyz.zhouxy.plusone.util.AssertResult
*/ */
@ResponseStatus(HttpStatus.NOT_FOUND) @ResponseStatus(HttpStatus.NOT_FOUND)
public class DataNotExistException extends PlusoneException { public class DataNotExistException extends PlusoneException {

View File

@ -4,7 +4,7 @@ import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.ResponseStatus;
/** /**
* *
* *
* <p> * <p>
* *
@ -14,18 +14,18 @@ import org.springframework.web.bind.annotation.ResponseStatus;
* @see xyz.zhouxy.plusone.util.AssertResult * @see xyz.zhouxy.plusone.util.AssertResult
*/ */
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public class DataOperationResultException extends PlusoneException { public class DataOperationNumberException extends PlusoneException {
@java.io.Serial @java.io.Serial
private static final long serialVersionUID = -9220765735990318186L; private static final long serialVersionUID = -9220765735990318186L;
public static final int ERROR_CODE = 4110200; public static final int ERROR_CODE = 4110200;
public DataOperationResultException() { public DataOperationNumberException() {
super(ERROR_CODE, "数据操作结果不符合预期"); super(ERROR_CODE, "数据操作的行数不符合预期");
} }
public DataOperationResultException(String message) { public DataOperationNumberException(String message) {
super(ERROR_CODE, message); super(ERROR_CODE, message);
} }
} }

View File

@ -1,10 +1,10 @@
package xyz.zhouxy.plusone.util; package xyz.zhouxy.plusone.util;
import xyz.zhouxy.plusone.exception.DataNotExistException; import xyz.zhouxy.plusone.exception.DataNotExistException;
import xyz.zhouxy.plusone.exception.DataOperationResultException; import xyz.zhouxy.plusone.exception.DataOperationNumberException;
import java.util.Objects; import java.util.Objects;
import java.util.function.Supplier;
/** /**
* *
@ -17,34 +17,51 @@ public final class AssertResult {
throw new IllegalStateException("Utility class"); throw new IllegalStateException("Utility class");
} }
public static <E extends Throwable> void isTrue(boolean condition, Supplier<E> e) throws E { public static void update(boolean expression) {
if (!condition) { if (!expression) {
throw e.get(); throw new DataOperationNumberException();
} }
} }
public static <T> void equals(T result, T expectedValue) { public static void update(boolean expression, String message) {
isTrue(Objects.equals(result, expectedValue), DataOperationResultException::new); if (!expression) {
throw new DataOperationNumberException(message);
}
} }
public static <T> void equals(T result, T expectedValue, String msgTemplate, Object... args) { public static void update(Object i, int expectedValue) {
isTrue(!Objects.equals(result, expectedValue), if (!Objects.equals(i, expectedValue)) {
() -> new DataOperationResultException(String.format(msgTemplate, args))); throw new DataOperationNumberException();
}
} }
public static void updateOneRow(int i) { public static void update(Object i, int expectedValue, String format) {
equals(i, 1); if (!Objects.equals(i, expectedValue)) {
throw new DataOperationNumberException(String.format(format, i));
}
} }
public static void updateOneRow(int i, String format, Object... args) { public static void exist(boolean expression) {
equals(i, 1, format, args); if (!expression) {
throw new DataNotExistException();
}
}
public static void exist(boolean expression, String message) {
if (!expression) {
throw new DataNotExistException(message);
}
} }
public static void nonNull(Object obj) { public static void nonNull(Object obj) {
isTrue(Objects.nonNull(obj), DataNotExistException::new); if (Objects.isNull(obj)) {
throw new DataNotExistException();
}
} }
public static void nonNull(Object obj, String message) { public static void nonNull(Object obj, String message) {
isTrue(Objects.nonNull(obj), () -> new DataNotExistException(message)); if (Objects.isNull(obj)) {
throw new DataNotExistException(message);
}
} }
} }

View File

@ -1,7 +1,6 @@
package xyz.zhouxy.plusone.domain; package xyz.zhouxy.plusone.domain;
import java.io.Serializable; import java.io.Serializable;
import java.util.Optional;
/** /**
* Repository * Repository
@ -11,7 +10,7 @@ import java.util.Optional;
*/ */
public interface IRepository<T extends AggregateRoot<ID>, ID extends Serializable> { public interface IRepository<T extends AggregateRoot<ID>, ID extends Serializable> {
Optional<T> find(ID id); T find(ID id);
T save(T entity); T save(T entity);

View File

@ -1,7 +1,5 @@
package xyz.zhouxy.plusone.domain; package xyz.zhouxy.plusone.domain;
import java.util.Optional;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonValue; import com.fasterxml.jackson.annotation.JsonValue;
@ -33,8 +31,4 @@ public abstract class ValidatableStringRecord implements IValueObject {
public String toString() { public String toString() {
return value; return value;
} }
public static String getValueOrNull(Optional<? extends ValidatableStringRecord> s) {
return s.map(ValidatableStringRecord::value).orElse(null);
}
} }

View File

@ -1,7 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" <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">
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> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>xyz.zhouxy</groupId> <groupId>xyz.zhouxy</groupId>
@ -86,11 +84,6 @@
<groupId>com.tencentcloudapi</groupId> <groupId>com.tencentcloudapi</groupId>
<artifactId>tencentcloud-sdk-java-sms</artifactId> <artifactId>tencentcloud-sdk-java-sms</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.csource</groupId>
<artifactId>fastdfs-client-java</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -1,18 +0,0 @@
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);
}
}

View File

@ -0,0 +1,15 @@
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);
}
}

View File

@ -4,61 +4,60 @@ import java.io.Serializable;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.stream.Stream; import java.util.stream.Stream;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import org.springframework.jdbc.core.ResultSetExtractor; import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.RowMapper; 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.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import xyz.zhouxy.plusone.domain.Entity; import xyz.zhouxy.plusone.domain.Entity;
public abstract class JdbcEntityDaoSupport<T extends Entity<ID>, ID extends Serializable> public abstract class JdbcEntityDaoSupport<T extends Entity<ID>, ID extends Serializable> {
extends PlusoneJdbcDaoSupport { protected final NamedParameterJdbcTemplate jdbc;
protected RowMapper<T> rowMapper; protected RowMapper<T> rowMapper;
protected ResultSetExtractor<Optional<T>> resultSetExtractor; protected ResultSetExtractor<T> resultSetExtractor;
protected JdbcEntityDaoSupport(@Nonnull NamedParameterJdbcTemplate namedParameterJdbcTemplate) { protected JdbcEntityDaoSupport(@Nonnull NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
super(namedParameterJdbcTemplate); this.jdbc = namedParameterJdbcTemplate;
this.rowMapper = (ResultSet rs, int rowNum) -> mapRow(rs); this.rowMapper = (ResultSet rs, int rowNum) -> mapRow(rs);
this.resultSetExtractor = (ResultSet rs) -> rs.next() ? Optional.of(mapRow(rs)) : Optional.empty(); this.resultSetExtractor = (ResultSet rs) -> rs.next() ? mapRow(rs) : null;
} }
protected final Optional<T> queryForObject(String sql) { protected final T queryForObject(String sql) {
return queryForObject(sql, this.resultSetExtractor); return this.jdbc.query(sql, this.resultSetExtractor);
} }
protected final Optional<T> queryForObject(String sql, SqlParameterSource paramSource) { protected final T queryForObject(String sql, SqlParameterSource paramSource) {
return queryForObject(sql, paramSource, this.resultSetExtractor); return this.jdbc.query(sql, paramSource, this.resultSetExtractor);
}
protected final Optional<T> queryForObject(String sql, String paramName, Object value) {
return queryForObject(sql, new MapSqlParameterSource(paramName, value), this.resultSetExtractor);
} }
protected final List<T> queryForList(String sql) { protected final List<T> queryForList(String sql) {
return queryForList(sql, this.rowMapper); return this.jdbc.query(sql, this.rowMapper);
} }
protected final List<T> queryForList(String sql, SqlParameterSource parameterSource) { protected final List<T> queryForList(String sql, SqlParameterSource parameterSource) {
return queryForList(sql, parameterSource, this.rowMapper); return this.jdbc.query(sql, parameterSource, this.rowMapper);
}
protected final List<T> queryForList(String sql, String paramName, Object value) {
return queryForList(sql, new MapSqlParameterSource(paramName, value), this.rowMapper);
} }
protected final Stream<T> queryForStream(String sql, SqlParameterSource parameterSource) { protected final Stream<T> queryForStream(String sql, SqlParameterSource parameterSource) {
return queryForStream(sql, parameterSource, this.rowMapper); return this.jdbc.queryForStream(sql, parameterSource, this.rowMapper);
} }
protected final Stream<T> queryForStream(String sql, String paramName, Object value) { protected final <E> Stream<E> queryForStream(String sql, SqlParameterSource parameterSource, Class<E> elementType) {
return queryForStream(sql, new MapSqlParameterSource(paramName, value), this.rowMapper); return this.jdbc.queryForList(sql, parameterSource, 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 int update(String sql, SqlParameterSource parameterSource) {
return this.jdbc.update(sql, parameterSource);
} }
protected abstract T mapRow(ResultSet rs) throws SQLException; protected abstract T mapRow(ResultSet rs) throws SQLException;
@ -67,7 +66,7 @@ public abstract class JdbcEntityDaoSupport<T extends Entity<ID>, ID extends Seri
this.rowMapper = rowMapper; this.rowMapper = rowMapper;
} }
protected void setResultSetExtractor(@Nonnull ResultSetExtractor<Optional<T>> resultSetExtractor) { protected void setResultSetExtractor(@Nonnull ResultSetExtractor<T> resultSetExtractor) {
this.resultSetExtractor = resultSetExtractor; this.resultSetExtractor = resultSetExtractor;
} }
} }

View File

@ -1,6 +1,5 @@
package xyz.zhouxy.plusone.jdbc; package xyz.zhouxy.plusone.jdbc;
import org.springframework.context.ApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
@ -17,17 +16,15 @@ import xyz.zhouxy.plusone.spring.SpringContextHolder;
*/ */
public final class JdbcFactory { public final class JdbcFactory {
private static final ApplicationContext CONTEXT = SpringContextHolder.getContext();
private JdbcFactory() { private JdbcFactory() {
throw new IllegalStateException("Utility class"); throw new IllegalStateException("Utility class");
} }
public static JdbcTemplate getJdbcTemplate() { public static JdbcTemplate getJdbcTemplate() {
return CONTEXT.getBean(JdbcTemplate.class); return SpringContextHolder.getContext().getBean(JdbcTemplate.class);
} }
public static NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() { public static NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() {
return CONTEXT.getBean(NamedParameterJdbcTemplate.class); return SpringContextHolder.getContext().getBean(NamedParameterJdbcTemplate.class);
} }
} }

View File

@ -1,7 +1,6 @@
package xyz.zhouxy.plusone.jdbc; package xyz.zhouxy.plusone.jdbc;
import java.io.Serializable; import java.io.Serializable;
import java.util.Optional;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -21,7 +20,7 @@ public abstract class JdbcRepositorySupport<T extends AggregateRoot<ID>, ID exte
protected abstract void doDelete(@Nonnull T entity); protected abstract void doDelete(@Nonnull T entity);
protected abstract Optional<T> doFindById(@Nonnull ID id); protected abstract T doFindById(@Nonnull ID id);
protected abstract T doInsert(@Nonnull T entity); protected abstract T doInsert(@Nonnull T entity);
@ -36,7 +35,7 @@ public abstract class JdbcRepositorySupport<T extends AggregateRoot<ID>, ID exte
} }
@Override @Override
public final Optional<T> find(ID id) { public final T find(ID id) {
if (id == null) { if (id == null) {
throw new IllegalArgumentException("Id cannot be null."); throw new IllegalArgumentException("Id cannot be null.");
} }

View File

@ -1,172 +0,0 @@
package xyz.zhouxy.plusone.jdbc;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Stream;
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;
import xyz.zhouxy.plusone.exception.DataOperationResultException;
import xyz.zhouxy.plusone.util.NumberUtil;
public abstract class PlusoneJdbcDaoSupport {
protected final NamedParameterJdbcTemplate jdbc;
protected PlusoneJdbcDaoSupport(@Nonnull NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
this.jdbc = namedParameterJdbcTemplate;
}
protected final <T> T queryForObject(String sql, ResultSetExtractor<T> resultSetExtractor) {
return this.jdbc.query(sql, resultSetExtractor);
}
protected final <T> T queryForObject(String sql, SqlParameterSource paramSource,
ResultSetExtractor<T> resultSetExtractor) {
return this.jdbc.query(sql, paramSource, resultSetExtractor);
}
protected final <T> T queryForObject(String sql, String paramName, Object value,
ResultSetExtractor<T> resultSetExtractor) {
return this.jdbc.query(sql, new MapSqlParameterSource(paramName, value), resultSetExtractor);
}
protected final <T> List<T> queryForList(String sql, RowMapper<T> rowMapper) {
return this.jdbc.query(sql, rowMapper);
}
protected final <T> List<T> queryForList(String sql, SqlParameterSource parameterSource, RowMapper<T> rowMapper) {
return this.jdbc.query(sql, parameterSource, rowMapper);
}
protected final <T> List<T> queryForList(String sql, String paramName, Object value, RowMapper<T> rowMapper) {
return this.jdbc.query(sql, new MapSqlParameterSource(paramName, value), rowMapper);
}
protected final <T> Stream<T> queryForStream(String sql, SqlParameterSource parameterSource,
RowMapper<T> rowMapper) {
return this.jdbc.queryForStream(sql, parameterSource, rowMapper);
}
protected final <T> Stream<T> queryForStream(String sql, String paramName, Object value, RowMapper<T> rowMapper) {
return this.jdbc.queryForStream(sql, new MapSqlParameterSource(paramName, value), rowMapper);
}
protected final <T> Stream<T> queryForStream(String sql, SqlParameterSource parameterSource, Class<T> elementType) {
return this.jdbc.queryForList(sql, parameterSource, elementType).stream();
}
protected final <T> Stream<T> queryForStream(String sql, String paramName, Object value, Class<T> elementType) {
return queryForStream(sql, new MapSqlParameterSource(paramName, value), elementType);
}
protected final boolean queryExists(String sql, SqlParameterSource parameterSource) {
Boolean isExists = this.jdbc.queryForObject(sql, parameterSource, Boolean.TYPE);
return Boolean.TRUE.equals(isExists);
}
protected final boolean queryExists(String sql, String paramName, Object value) {
return queryExists(sql, new MapSqlParameterSource(paramName, value));
}
protected final int update(String sql, SqlParameterSource parameterSource) {
return this.jdbc.update(sql, parameterSource);
}
protected final int update(String sql, String paramName, Object value) {
return update(sql, new MapSqlParameterSource(paramName, value));
}
protected final int batchUpdate(String sql, SqlParameterSource[] batchArgs) {
int[] i = this.jdbc.batchUpdate(sql, batchArgs);
return NumberUtil.sum(i);
}
protected final <T> int batchUpdate(String sql, Stream<T> c,
@Nonnull Function<T, SqlParameterSource> paramSourceBuilder) {
int[] i = this.jdbc.batchUpdate(sql, buildSqlParameterSourceArray(c, paramSourceBuilder));
return NumberUtil.sum(i);
}
protected final <T> int batchUpdate(String sql, Collection<T> c,
@Nonnull Function<T, SqlParameterSource> paramSourceBuilder) {
int[] i = this.jdbc.batchUpdate(sql, buildSqlParameterSourceArray(c, paramSourceBuilder));
return NumberUtil.sum(i);
}
protected static final <T> void assertResultEquals(T result, T expectedValue) {
if (!Objects.equals(result, expectedValue)) {
throw new DataOperationResultException();
}
}
protected static final <T> void assertResultEquals(T result, T expectedValue, Function<T, String> errMsg) {
if (!Objects.equals(result, expectedValue)) {
throw new DataOperationResultException(errMsg.apply(result));
}
}
protected static final <T> void assertResultEquals(T result, T expectedValue, String msgTemplate, Object... args) {
if (!Objects.equals(result, expectedValue)) {
throw new DataOperationResultException(String.format(msgTemplate, args));
}
}
protected static final <T, E extends Throwable> void assertResultEqualsOrThrow(T result, T expectedValue,
Function<T, E> e) throws E {
if (!Objects.equals(result, expectedValue)) {
throw e.apply(result);
}
}
protected static final void assertUpdateOneRow(int result) {
assertResultEquals(result, 1);
}
protected static final void assertUpdateOneRow(int result, Function<Integer, String> errMsg) {
assertResultEquals(result, 1, errMsg);
}
protected static final void assertUpdateOneRow(int result, String msgTemplate, Object... args) {
assertResultEquals(result, 1, msgTemplate, args);
}
protected static final <E extends Throwable> void assertUpdateOneRowOrThrow(int result, Function<Integer, E> e)
throws E {
assertResultEqualsOrThrow(result, 1, e);
}
protected static final <T> SqlParameterSource[] buildSqlParameterSourceArray(
T[] c,
@Nonnull Function<T, SqlParameterSource> paramSourceBuilder) {
if (c == null || c.length == 0) {
return new SqlParameterSource[] {};
}
return buildSqlParameterSourceArray(Arrays.stream(c), paramSourceBuilder);
}
protected static final <T> SqlParameterSource[] buildSqlParameterSourceArray(
Collection<T> c,
@Nonnull Function<T, SqlParameterSource> paramSourceBuilder) {
if (c == null || c.isEmpty()) {
return new SqlParameterSource[] {};
}
return buildSqlParameterSourceArray(c.stream(), paramSourceBuilder);
}
protected static final <T> SqlParameterSource[] buildSqlParameterSourceArray(
Stream<T> stream,
@Nonnull Function<T, SqlParameterSource> paramSourceBuilder) {
Objects.requireNonNull(stream);
Objects.requireNonNull(paramSourceBuilder);
return stream.map(paramSourceBuilder).toArray(SqlParameterSource[]::new);
}
}

View File

@ -1,5 +1,6 @@
package xyz.zhouxy.plusone.mail; package xyz.zhouxy.plusone.mail;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
@ -14,10 +15,11 @@ import org.springframework.mail.javamail.JavaMailSender;
@Configuration @Configuration
@EnableConfigurationProperties(PlusoneMailProperties.class) @EnableConfigurationProperties(PlusoneMailProperties.class)
@ConditionalOnClass(MailService.class) @ConditionalOnClass(MailService.class)
@EnableAutoConfiguration
public class PlusoneMailAutoConfiguration { public class PlusoneMailAutoConfiguration {
@Bean @Bean
MailService mailService(JavaMailSender mailSender, PlusoneMailProperties mailProperties) { public MailService mailService(JavaMailSender mailSender, PlusoneMailProperties mailProperties) {
MailMessageFactory mailMessageFactory = new MailMessageFactory(mailProperties); MailMessageFactory mailMessageFactory = new MailMessageFactory(mailProperties);
return new SimpleMailService(mailSender, mailMessageFactory); return new SimpleMailService(mailSender, mailMessageFactory);
} }

View File

@ -1,92 +0,0 @@
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.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)
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);
}
}
}

View File

@ -1,28 +0,0 @@
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);
}
}

View File

@ -1,121 +0,0 @@
package xyz.zhouxy.plusone.oss;
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;
@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;
public Integer getConnectTimeoutInSeconds() {
return connectTimeoutInSeconds;
}
public void setConnectTimeoutInSeconds(Integer connectTimeoutInSeconds) {
this.connectTimeoutInSeconds = connectTimeoutInSeconds;
}
public Integer getNetworkTimeoutInSeconds() {
return networkTimeoutInSeconds;
}
public void setNetworkTimeoutInSeconds(Integer networkTimeoutInSeconds) {
this.networkTimeoutInSeconds = networkTimeoutInSeconds;
}
public String getCharset() {
return charset;
}
public void setCharset(String charset) {
this.charset = charset;
}
public Boolean getHttpAntiStealToken() {
return httpAntiStealToken;
}
public void setHttpAntiStealToken(Boolean httpAntiStealToken) {
this.httpAntiStealToken = httpAntiStealToken;
}
public String getHttpSecretKey() {
return httpSecretKey;
}
public void setHttpSecretKey(String httpSecretKey) {
this.httpSecretKey = httpSecretKey;
}
public Integer getHttpTrackerHttpPort() {
return httpTrackerHttpPort;
}
public void setHttpTrackerHttpPort(Integer httpTrackerHttpPort) {
this.httpTrackerHttpPort = httpTrackerHttpPort;
}
public List<String> getTrackerServers() {
return trackerServers;
}
public void setTrackerServers(List<String> trackerServers) {
this.trackerServers = trackerServers;
}
public ConnectionPool getConnectionPool() {
return connectionPool;
}
public void setConnectionPool(ConnectionPool connectionPool) {
this.connectionPool = connectionPool;
}
public static class ConnectionPool {
private Boolean enabled;
private Integer maxCountPerEntry;
private Integer maxIdleTime;
private Integer maxWaitTimeInMs;
public Boolean getEnabled() {
return enabled;
}
public void setEnabled(Boolean enabled) {
this.enabled = enabled;
}
public Integer getMaxCountPerEntry() {
return maxCountPerEntry;
}
public void setMaxCountPerEntry(Integer maxCountPerEntry) {
this.maxCountPerEntry = maxCountPerEntry;
}
public Integer getMaxIdleTime() {
return maxIdleTime;
}
public void setMaxIdleTime(Integer maxIdleTime) {
this.maxIdleTime = maxIdleTime;
}
public Integer getMaxWaitTimeInMs() {
return maxWaitTimeInMs;
}
public void setMaxWaitTimeInMs(Integer maxWaitTimeInMs) {
this.maxWaitTimeInMs = maxWaitTimeInMs;
}
}
}

View File

@ -1,126 +0,0 @@
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;
}
}
}

View File

@ -11,12 +11,17 @@ import org.springframework.context.annotation.Configuration;
* @author <a href="https://gitee.com/zhouxy108">ZhouXY</a> * @author <a href="https://gitee.com/zhouxy108">ZhouXY</a>
*/ */
@Configuration @Configuration
@EnableConfigurationProperties(SmsProperties.class) @EnableConfigurationProperties(value = {
SmsProperties.class,
SmsCredentialProperties.class,
SmsClientProperties.class,
SmsHttpProperties.class,
SmsProxyProperties.class})
@ConditionalOnClass(SmsService.class) @ConditionalOnClass(SmsService.class)
public class PlusoneSmsAutoConfiguration { public class PlusoneSmsAutoConfiguration {
@Bean @Bean
SmsService smsService(SmsProperties smsProperties) { public SmsService smsService(SmsProperties smsProperties) {
return new TencentSmsServiceImpl(smsProperties); return new TencentSmsServiceImpl(smsProperties);
} }
} }

View File

@ -4,11 +4,14 @@ import java.util.Map;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import lombok.Data;
/** /**
* SMS * SMS
* *
* @author <a href="https://gitee.com/zhouxy108">ZhouXY</a> * @author <a href="https://gitee.com/zhouxy108">ZhouXY</a>
*/ */
@Data
@ConfigurationProperties("plusone.sms") @ConfigurationProperties("plusone.sms")
public class SmsProperties { public class SmsProperties {
private String region; private String region;
@ -16,138 +19,33 @@ public class SmsProperties {
private SmsClientProperties client; private SmsClientProperties client;
private String appId; private String appId;
private Map<String, String> templates; private Map<String, String> templates;
}
public String getRegion() {
return region; @Data
} @ConfigurationProperties("plusone.sms.credential")
class SmsCredentialProperties {
public void setRegion(String region) { private String secretId;
this.region = region; private String secretKey;
} }
public SmsCredentialProperties getCredential() { @Data
return credential; @ConfigurationProperties("plusone.sms.client")
} class SmsClientProperties {
private String signMethod;
public void setCredential(SmsCredentialProperties credential) { private SmsHttpProperties http;
this.credential = credential; }
}
@Data
public SmsClientProperties getClient() { @ConfigurationProperties("plusone.sms.client.http")
return client; class SmsHttpProperties {
} private SmsProxyProperties proxy;
private String reqMethod;
public void setClient(SmsClientProperties client) { private Integer connTimeout;
this.client = client; }
}
@Data
public String getAppId() { @ConfigurationProperties("plusone.sms.client.http.proxy")
return appId; class SmsProxyProperties {
} private String host;
private Integer port;
public void setAppId(String appId) {
this.appId = appId;
}
public Map<String, String> getTemplates() {
return templates;
}
public void setTemplates(Map<String, String> templates) {
this.templates = templates;
}
public static class SmsCredentialProperties {
private String secretId;
private String secretKey;
public String getSecretId() {
return secretId;
}
public void setSecretId(String secretId) {
this.secretId = secretId;
}
public String getSecretKey() {
return secretKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
}
public static class SmsClientProperties {
private String signMethod;
private SmsHttpProperties http;
public String getSignMethod() {
return signMethod;
}
public void setSignMethod(String signMethod) {
this.signMethod = signMethod;
}
public SmsHttpProperties getHttp() {
return http;
}
public void setHttp(SmsHttpProperties http) {
this.http = http;
}
}
public static class SmsHttpProperties {
private SmsProxyProperties proxy;
private String reqMethod;
private Integer connTimeout;
public SmsProxyProperties getProxy() {
return proxy;
}
public void setProxy(SmsProxyProperties proxy) {
this.proxy = proxy;
}
public String getReqMethod() {
return reqMethod;
}
public void setReqMethod(String reqMethod) {
this.reqMethod = reqMethod;
}
public Integer getConnTimeout() {
return connTimeout;
}
public void setConnTimeout(Integer connTimeout) {
this.connTimeout = connTimeout;
}
}
public static class SmsProxyProperties {
private String host;
private Integer port;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public Integer getPort() {
return port;
}
public void setPort(Integer port) {
this.port = port;
}
}
} }

View File

@ -13,9 +13,6 @@ import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import xyz.zhouxy.plusone.constant.ErrorCodeConsts; import xyz.zhouxy.plusone.constant.ErrorCodeConsts;
import xyz.zhouxy.plusone.exception.PlusoneException; import xyz.zhouxy.plusone.exception.PlusoneException;
import xyz.zhouxy.plusone.sms.SmsProperties.SmsCredentialProperties;
import xyz.zhouxy.plusone.sms.SmsProperties.SmsHttpProperties;
import xyz.zhouxy.plusone.sms.SmsProperties.SmsProxyProperties;
/** /**
* 使 SMS * 使 SMS

View File

@ -3,12 +3,13 @@ package xyz.zhouxy.plusone.validator;
import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.bind.annotation.RestControllerAdvice;
import xyz.zhouxy.plusone.exception.handler.BaseExceptionHandler; import xyz.zhouxy.plusone.exception.handler.BaseExceptionHandler;
import xyz.zhouxy.plusone.exception.handler.ExceptionInfoHolderFactory;
@RestControllerAdvice @RestControllerAdvice
public class InvalidInputExceptionHandler extends BaseExceptionHandler { public class InvalidInputExceptionHandler extends BaseExceptionHandler {
public InvalidInputExceptionHandler(ExceptionInfoHolder exceptionInfoHolder) { protected InvalidInputExceptionHandler() {
super(exceptionInfoHolder); super(ExceptionInfoHolderFactory.newDefaultExceptionInfoHolder());
set(InvalidInputException.class, InvalidInputException.ERROR_CODE, "无效的用户输入"); set(InvalidInputException.class, InvalidInputException.ERROR_CODE, "无效的用户输入");
} }
} }

View File

@ -1,4 +0,0 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
xyz.zhouxy.plusone.sms.PlusoneSmsAutoConfiguration,\
xyz.zhouxy.plusone.mail.PlusoneMailAutoConfiguration,\
xyz.zhouxy.plusone.oss.FastDFSAutoConfig

View File

@ -8,7 +8,7 @@ import lombok.NoArgsConstructor;
import xyz.zhouxy.plusone.constant.RegexConsts; import xyz.zhouxy.plusone.constant.RegexConsts;
import xyz.zhouxy.plusone.validator.BaseValidator; import xyz.zhouxy.plusone.validator.BaseValidator;
class BaseValidatorTest { class BaseValidator2Test {
@Test @Test
void testValid() { void testValid() {

View File

@ -1,32 +1,34 @@
{"properties": [ {
{ "properties": [
"name": "plusone.application.name", {
"type": "java.lang.String", "name": "plusone.application.name",
"description": "A description for 'plusone.application.name'" "type": "java.lang.String",
}, "description": "A description for 'plusone.application.name'"
{ },
"name": "plusone.server.port", {
"type": "java.lang.Integer", "name": "plusone.server.port",
"description": "A description for 'plusone.server.port'" "type": "java.lang.Integer",
}, "description": "A description for 'plusone.server.port'"
{ },
"name": "plusone.debug", {
"type": "java.lang.Boolean", "name": "plusone.debug",
"description": "A description for 'plusone.debug'" "type": "java.lang.Boolean",
}, "description": "A description for 'plusone.debug'"
{ },
"name": "plusone.mail.host", {
"type": "java.lang.String", "name": "plusone.mail.host",
"description": "A description for 'plusone.mail.host'" "type": "java.lang.String",
}, "description": "A description for 'plusone.mail.host'"
{ },
"name": "plusone.mail.password", {
"type": "java.lang.String", "name": "plusone.mail.password",
"description": "A description for 'plusone.mail.password'" "type": "java.lang.String",
}, "description": "A description for 'plusone.mail.password'"
{ },
"name": "plusone.exception.handle-all-exception", {
"type": "java.lang.Boolean", "name": "plusone.exception.handle-all-exception",
"description": "A description for 'plusone.exception.handle-all-exception'" "type": "java.lang.Boolean",
} "description": "A description for 'plusone.exception.handle-all-exception'"
]} }
]
}

View File

@ -50,7 +50,7 @@ plusone:
conn-timeout: 60 conn-timeout: 60
app-id: 1111111111 app-id: 1111111111
templates: templates:
'[code]': 0000000 code: 0000000
# 邮件发送相关参数 # 邮件发送相关参数
mail: mail:
@ -63,16 +63,7 @@ plusone:
exception: exception:
handle-all-exception: false handle-all-exception: false
fastdfs: # 日志配置
connect_timeout_in_seconds: 5 logging:
network_timeout_in_seconds: 30 level:
charset: UTF-8 root: debug
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

View File

@ -6,11 +6,6 @@ plusone:
# 邮件发送相关参数 # 邮件发送相关参数
mail: mail:
subject: subject:
'[code]': Plusone code: Plusone
template: template:
'[code]': 【Plusone】验证码%s10分钟内有效请勿泄露。 code: 【Plusone】验证码%s10分钟内有效请勿泄露。
# 日志配置
logging:
level:
root: info
'[xyz.zhouxy.plusone]': debug

View File

@ -1,33 +0,0 @@
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));
}
}
}

View File

@ -1,16 +0,0 @@
spring:
profiles:
active: secret
plusone:
# 邮件发送相关参数
mail:
subject:
'[code]': Plusone
template:
'[code]': 【Plusone】验证码%s10分钟内有效请勿泄露。
# 日志配置
logging:
level:
root: info
'[xyz.zhouxy.plusone]': debug

View File

@ -20,6 +20,7 @@ import xyz.zhouxy.plusone.system.application.query.params.AccountQueryParams;
import xyz.zhouxy.plusone.system.application.service.AccountManagementService; import xyz.zhouxy.plusone.system.application.service.AccountManagementService;
import xyz.zhouxy.plusone.system.application.service.command.CreateAccountCommand; import xyz.zhouxy.plusone.system.application.service.command.CreateAccountCommand;
import xyz.zhouxy.plusone.system.application.service.command.UpdateAccountCommand; import xyz.zhouxy.plusone.system.application.service.command.UpdateAccountCommand;
import xyz.zhouxy.plusone.util.AssertResult;
import xyz.zhouxy.plusone.util.RestfulResult; import xyz.zhouxy.plusone.util.RestfulResult;
/** /**
@ -76,6 +77,7 @@ public class AccountManagementController {
adminAuthLogic.checkLogin(); adminAuthLogic.checkLogin();
adminAuthLogic.checkPermission("sys-account-details"); adminAuthLogic.checkPermission("sys-account-details");
var accountDetails = service.queryAccountDetails(accountId); var accountDetails = service.queryAccountDetails(accountId);
AssertResult.nonNull(accountDetails);
return success("查询成功", accountDetails); return success("查询成功", accountDetails);
} }
} }

View File

@ -21,34 +21,18 @@ public class AccountLoginException extends PlusoneException {
} }
public static AccountLoginException accountNotExistException() { public static AccountLoginException accountNotExistException() {
return accountNotExistException("用户账户不存在"); return new AccountLoginException(4030101, "用户账户不存在");
}
public static AccountLoginException accountNotExistException(String msg) {
return new AccountLoginException(4030101, msg);
} }
public static AccountLoginException otpErrorException() { public static AccountLoginException otpErrorException() {
return otpErrorException("验证码错误"); return new AccountLoginException(4030501, "验证码错误");
}
public static AccountLoginException otpErrorException(String msg) {
return new AccountLoginException(4030501, msg);
} }
public static AccountLoginException otpNotExistsException() { public static AccountLoginException otpNotExistsException() {
return otpNotExistsException("验证码不存在或已过期"); return new AccountLoginException(4030502, "验证码不存在或已过期");
}
public static AccountLoginException otpNotExistsException(String msg) {
return new AccountLoginException(4030502, msg);
} }
public static AccountLoginException passwordErrorException() { public static AccountLoginException passwordErrorException() {
return passwordErrorException("用户密码错误"); return new AccountLoginException(4030200, "用户密码错误");
}
public static AccountLoginException passwordErrorException(String msg) {
return new AccountLoginException(4030200, msg);
} }
} }

View File

@ -7,14 +7,15 @@ import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.bind.annotation.RestControllerAdvice;
import xyz.zhouxy.plusone.exception.handler.BaseExceptionHandler; 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.system.application.exception.AccountLoginException;
import xyz.zhouxy.plusone.util.RestfulResult; import xyz.zhouxy.plusone.util.RestfulResult;
@RestControllerAdvice @RestControllerAdvice
public class AccountLoginExceptionHandler extends BaseExceptionHandler { public class AccountLoginExceptionHandler extends BaseExceptionHandler {
public AccountLoginExceptionHandler(ExceptionInfoHolder exceptionInfoHolder) { protected AccountLoginExceptionHandler() {
super(exceptionInfoHolder); super(ExceptionInfoHolderFactory.newDefaultExceptionInfoHolder());
} }
@ExceptionHandler({ AccountLoginException.class }) @ExceptionHandler({ AccountLoginException.class })

View File

@ -15,6 +15,7 @@ import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.exception.SameTokenInvalidException; import cn.dev33.satoken.exception.SameTokenInvalidException;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import xyz.zhouxy.plusone.exception.handler.BaseExceptionHandler; import xyz.zhouxy.plusone.exception.handler.BaseExceptionHandler;
import xyz.zhouxy.plusone.exception.handler.ExceptionInfoHolderFactory;
import xyz.zhouxy.plusone.util.RestfulResult; import xyz.zhouxy.plusone.util.RestfulResult;
/** /**
@ -26,9 +27,8 @@ import xyz.zhouxy.plusone.util.RestfulResult;
@Slf4j @Slf4j
public class SaTokenExceptionHandler extends BaseExceptionHandler { public class SaTokenExceptionHandler extends BaseExceptionHandler {
public SaTokenExceptionHandler() {
public SaTokenExceptionHandler(ExceptionInfoHolder exceptionInfoHolder) { super(ExceptionInfoHolderFactory.newDefaultExceptionInfoHolder());
super(exceptionInfoHolder);
set(NotPermissionException.class, 4030103, "会话未能通过权限认证", HttpStatus.FORBIDDEN); set(NotPermissionException.class, 4030103, "会话未能通过权限认证", HttpStatus.FORBIDDEN);
set(NotRoleException.class, 4030103, "会话未能通过角色认证", HttpStatus.FORBIDDEN); set(NotRoleException.class, 4030103, "会话未能通过角色认证", HttpStatus.FORBIDDEN);
set(DisableServiceException.class, 4030202, "账号指定服务已被封禁", HttpStatus.FORBIDDEN); set(DisableServiceException.class, 4030202, "账号指定服务已被封禁", HttpStatus.FORBIDDEN);

View File

@ -1,7 +1,8 @@
package xyz.zhouxy.plusone.system.application.service; package xyz.zhouxy.plusone.system.application.service;
import xyz.zhouxy.plusone.system.constant.AuthLogic;
import java.util.List; import java.util.List;
import java.util.Optional;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -9,6 +10,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import cn.dev33.satoken.stp.StpLogic; import cn.dev33.satoken.stp.StpLogic;
import cn.hutool.core.lang.Assert;
import xyz.zhouxy.plusone.system.application.common.util.PrincipalUtil; import xyz.zhouxy.plusone.system.application.common.util.PrincipalUtil;
import xyz.zhouxy.plusone.system.application.exception.AccountLoginException; import xyz.zhouxy.plusone.system.application.exception.AccountLoginException;
import xyz.zhouxy.plusone.system.application.query.AccountQueries; import xyz.zhouxy.plusone.system.application.query.AccountQueries;
@ -17,7 +19,6 @@ import xyz.zhouxy.plusone.system.application.query.result.MenuViewObject;
import xyz.zhouxy.plusone.system.application.service.command.ChangePasswordByOtpCommand; import xyz.zhouxy.plusone.system.application.service.command.ChangePasswordByOtpCommand;
import xyz.zhouxy.plusone.system.application.service.command.ChangePasswordCommand; import xyz.zhouxy.plusone.system.application.service.command.ChangePasswordCommand;
import xyz.zhouxy.plusone.system.application.service.command.ChangePasswordWithoutLoginCommand; import xyz.zhouxy.plusone.system.application.service.command.ChangePasswordWithoutLoginCommand;
import xyz.zhouxy.plusone.system.constant.AuthLogic;
import xyz.zhouxy.plusone.system.domain.model.account.Account; import xyz.zhouxy.plusone.system.domain.model.account.Account;
import xyz.zhouxy.plusone.system.domain.model.account.AccountRepository; import xyz.zhouxy.plusone.system.domain.model.account.AccountRepository;
import xyz.zhouxy.plusone.system.domain.model.account.Email; import xyz.zhouxy.plusone.system.domain.model.account.Email;
@ -33,7 +34,7 @@ import xyz.zhouxy.plusone.validator.InvalidInputException;
@Service @Service
public class AccountContextService { public class AccountContextService {
private static final StpLogic adminAuthLogic = AuthLogic.adminAuthLogic; private final static StpLogic adminAuthLogic = AuthLogic.adminAuthLogic;
@Resource @Resource
private AccountQueries accountQueries; private AccountQueries accountQueries;
@ -64,8 +65,7 @@ public class AccountContextService {
@Transactional @Transactional
public void changePassword(ChangePasswordCommand command) { public void changePassword(ChangePasswordCommand command) {
adminAuthLogic.checkLogin(); adminAuthLogic.checkLogin();
Account account = accountRepository.find(adminAuthLogic.getLoginIdAsLong()) Account account = accountRepository.find(adminAuthLogic.getLoginIdAsLong());
.orElseThrow(() -> AccountLoginException.accountNotExistException("当前所登录的账号不存在"));
account.checkPassword(command.getPassword()); account.checkPassword(command.getPassword());
account.changePassword(command.getNewPassword(), command.getPasswordConfirmation()); account.changePassword(command.getNewPassword(), command.getPasswordConfirmation());
accountRepository.save(account); accountRepository.save(account);
@ -77,10 +77,9 @@ public class AccountContextService {
String principal = command.getAccount(); String principal = command.getAccount();
Principal emailOrMobilePhone = PrincipalUtil.getEmailOrMobilePhone(principal); Principal emailOrMobilePhone = PrincipalUtil.getEmailOrMobilePhone(principal);
Account account = (emailOrMobilePhone instanceof Email Account account = emailOrMobilePhone instanceof Email
? accountRepository.findByEmail((Email) emailOrMobilePhone) ? accountRepository.findByEmail((Email) emailOrMobilePhone)
: accountRepository.findByMobilePhone((MobilePhone) emailOrMobilePhone)) : accountRepository.findByMobilePhone((MobilePhone) emailOrMobilePhone);
.orElseThrow(() -> AccountLoginException.accountNotExistException("当前所登录的账号不存在"));
account.checkPassword(command.getOldPassword()); account.checkPassword(command.getOldPassword());
account.changePassword(command.getNewPassword(), command.getPasswordConfirmation()); account.changePassword(command.getNewPassword(), command.getPasswordConfirmation());
accountRepository.save(account); accountRepository.save(account);
@ -91,12 +90,12 @@ public class AccountContextService {
public void changePasswordByOtp(ChangePasswordByOtpCommand command) { public void changePasswordByOtp(ChangePasswordByOtpCommand command) {
var principal = command.getAccount(); var principal = command.getAccount();
Optional<Account> account = switch (command.getPrincipalType()) { Account account = switch (command.getPrincipalType()) {
case EMAIL -> accountRepository.findByEmail(Email.of(principal)); case EMAIL -> accountRepository.findByEmail(Email.of(principal));
case MOBILE_PHONE -> accountRepository.findByMobilePhone(MobilePhone.of(principal)); case MOBILE_PHONE -> accountRepository.findByMobilePhone(MobilePhone.of(principal));
default -> throw InvalidInputException.unsupportedPrincipalTypeException("输入邮箱地址或手机号"); default -> throw InvalidInputException.unsupportedPrincipalTypeException("输入邮箱地址或手机号");
}; };
account.orElseThrow(AccountLoginException::accountNotExistException); Assert.notNull(account, () -> AccountLoginException.accountNotExistException());
mailAndSmsVerifyService.checkOtp(principal, command.getOtp()); mailAndSmsVerifyService.checkOtp(principal, command.getOtp());
} }

View File

@ -14,7 +14,6 @@ import org.springframework.util.Assert;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import xyz.zhouxy.plusone.exception.DataNotExistException;
import xyz.zhouxy.plusone.system.application.exception.AccountRegisterException; import xyz.zhouxy.plusone.system.application.exception.AccountRegisterException;
import xyz.zhouxy.plusone.system.application.query.AccountQueries; import xyz.zhouxy.plusone.system.application.query.AccountQueries;
import xyz.zhouxy.plusone.system.application.query.params.AccountQueryParams; import xyz.zhouxy.plusone.system.application.query.params.AccountQueryParams;
@ -77,16 +76,16 @@ public class AccountManagementService {
public void deleteAccounts(List<Long> ids) { public void deleteAccounts(List<Long> ids) {
Account accountToDelete; Account accountToDelete;
for (var id : ids) { for (var id : ids) {
accountToDelete = accountRepository.find(id) accountToDelete = accountRepository.find(id);
.orElseThrow(() -> new DataNotExistException("该账号不存在")); AssertResult.nonNull(accountToDelete);
accountRepository.delete(accountToDelete); accountRepository.delete(accountToDelete);
} }
} }
public void updateAccountInfo(Long id, @Valid UpdateAccountCommand command) { public void updateAccountInfo(Long id, @Valid UpdateAccountCommand command) {
Assert.isTrue(Objects.equals(id, command.getId()), "参数错误: id 不匹配"); Assert.isTrue(Objects.equals(id, command.getId()), "参数错误: id 不匹配");
Account account = accountRepository.find(id) Account account = accountRepository.find(id);
.orElseThrow(() -> new DataNotExistException("该账号不存在")); AssertResult.nonNull(account, "该账号不存在");
account.setAccountInfo(command.getNickname(), command.getAvatar(), command.getSex()); account.setAccountInfo(command.getNickname(), command.getAvatar(), command.getSex());
account.setUpdatedBy(adminAuthLogic.getLoginIdAsLong()); account.setUpdatedBy(adminAuthLogic.getLoginIdAsLong());
accountRepository.save(account); accountRepository.save(account);
@ -97,13 +96,6 @@ public class AccountManagementService {
return accountQueries.queryAccountOverviewPage(queryParams); return accountQueries.queryAccountOverviewPage(queryParams);
} }
/**
* {@link DataNotExistException}
*
* @param accountId id
* @return
* @throws DataNotExistException
*/
@Transactional(propagation = Propagation.SUPPORTS) @Transactional(propagation = Propagation.SUPPORTS)
public AccountDetails queryAccountDetails(@PathVariable("accountId") Long accountId) { public AccountDetails queryAccountDetails(@PathVariable("accountId") Long accountId) {
var accountDetails = accountQueries.queryAccountDetails(accountId); var accountDetails = accountQueries.queryAccountDetails(accountId);

View File

@ -44,13 +44,14 @@ public class AdminLoginService {
@ValidateDto @ValidateDto
public LoginInfoViewObject loginByPassword(LoginByPasswordCommand command) { public LoginInfoViewObject loginByPassword(LoginByPasswordCommand command) {
var principal = command.getPrincipal(); var principal = command.getPrincipal();
Account account = (switch (command.getPrincipalType()) { Account account = switch (command.getPrincipalType()) {
case USERNAME -> accountRepository.findByUsername(Username.of(principal)); case USERNAME -> accountRepository.findByUsername(Username.of(principal));
case EMAIL -> accountRepository.findByEmail(Email.of(principal)); case EMAIL -> accountRepository.findByEmail(Email.of(principal));
case MOBILE_PHONE -> accountRepository.findByMobilePhone(MobilePhone.of(principal)); case MOBILE_PHONE -> accountRepository.findByMobilePhone(MobilePhone.of(principal));
}).orElseThrow(AccountLoginException::accountNotExistException); };
Assert.notNull(account, () -> AccountLoginException.accountNotExistException());
var isPasswordCorrect = account.checkPassword(command.getPassword()); var isPasswordCorrect = account.checkPassword(command.getPassword());
Assert.isTrue(isPasswordCorrect, AccountLoginException::passwordErrorException); Assert.isTrue(isPasswordCorrect, () -> AccountLoginException.passwordErrorException());
adminAuthLogic.login(account.getId().orElseThrow(), command.isRememberMe()); adminAuthLogic.login(account.getId().orElseThrow(), command.isRememberMe());
var accountDetails = accountQueries.queryAccountDetails(account.getId().orElseThrow()); var accountDetails = accountQueries.queryAccountDetails(account.getId().orElseThrow());
@ -60,11 +61,12 @@ public class AdminLoginService {
@ValidateDto @ValidateDto
public LoginInfoViewObject loginByOtp(LoginByOtpCommand command) { public LoginInfoViewObject loginByOtp(LoginByOtpCommand command) {
var principal = command.getPrincipal(); var principal = command.getPrincipal();
Account account = (switch (command.getPrincipalType()) { Account account = switch (command.getPrincipalType()) {
case EMAIL -> accountRepository.findByEmail(Email.of(principal)); case EMAIL -> accountRepository.findByEmail(Email.of(principal));
case MOBILE_PHONE -> accountRepository.findByMobilePhone(MobilePhone.of(principal)); case MOBILE_PHONE -> accountRepository.findByMobilePhone(MobilePhone.of(principal));
default -> throw InvalidInputException.unsupportedPrincipalTypeException("输入邮箱地址或手机号"); default -> throw InvalidInputException.unsupportedPrincipalTypeException("输入邮箱地址或手机号");
}).orElseThrow(AccountLoginException::accountNotExistException); };
Assert.notNull(account, () -> AccountLoginException.accountNotExistException());
mailAndSmsVerifyService.checkOtp(principal, command.getOtp()); mailAndSmsVerifyService.checkOtp(principal, command.getOtp());

View File

@ -10,7 +10,6 @@ import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import xyz.zhouxy.plusone.exception.DataNotExistException;
import xyz.zhouxy.plusone.system.application.query.DictQueries; import xyz.zhouxy.plusone.system.application.query.DictQueries;
import xyz.zhouxy.plusone.system.application.query.params.DictQueryParams; import xyz.zhouxy.plusone.system.application.query.params.DictQueryParams;
import xyz.zhouxy.plusone.system.application.query.result.DictOverview; import xyz.zhouxy.plusone.system.application.query.result.DictOverview;
@ -46,21 +45,21 @@ public class DictManagementService {
public void deleteDicts(List<Long> ids) { public void deleteDicts(List<Long> ids) {
Dict dictToDelete; Dict dictToDelete;
for (Long id : ids) { for (Long id : ids) {
dictToDelete = dictRepository.find(id).orElseThrow(DataNotExistException::new); dictToDelete = dictRepository.find(id);
dictRepository.delete(dictToDelete); dictRepository.delete(dictToDelete);
} }
} }
public void updateDict(Long id, @Valid UpdateDictCommand command) { public void updateDict(Long id, @Valid UpdateDictCommand command) {
Assert.isTrue(Objects.equals(id, command.getId()), "id 不匹配"); Assert.isTrue(Objects.equals(id, command.getId()), "id 不匹配");
Dict dictToUpdate = dictRepository.find(command.getId()).orElseThrow(DataNotExistException::new); Dict dictToUpdate = dictRepository.find(command.getId());
dictToUpdate.updateDict(command.getDictType(), command.getDictLabel(), command.getKeyLabelMap()); dictToUpdate.updateDict(command.getDictType(), command.getDictLabel(), command.getKeyLabelMap());
dictRepository.save(dictToUpdate); dictRepository.save(dictToUpdate);
} }
@Transactional(propagation = Propagation.SUPPORTS) @Transactional(propagation = Propagation.SUPPORTS)
public Dict findDictDetails(Long dictId) { public Dict findDictDetails(Long dictId) {
return dictRepository.find(dictId).orElseThrow(DataNotExistException::new); return dictRepository.find(dictId);
} }
@Transactional(propagation = Propagation.SUPPORTS) @Transactional(propagation = Propagation.SUPPORTS)

View File

@ -14,7 +14,6 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import xyz.zhouxy.plusone.domain.IWithOrderNumber; import xyz.zhouxy.plusone.domain.IWithOrderNumber;
import xyz.zhouxy.plusone.exception.DataNotExistException;
import xyz.zhouxy.plusone.system.application.exception.UnsupportedMenuTypeException; import xyz.zhouxy.plusone.system.application.exception.UnsupportedMenuTypeException;
import xyz.zhouxy.plusone.system.application.query.result.MenuViewObject; import xyz.zhouxy.plusone.system.application.query.result.MenuViewObject;
import xyz.zhouxy.plusone.system.application.service.command.CreateMenuCommand; import xyz.zhouxy.plusone.system.application.service.command.CreateMenuCommand;
@ -23,6 +22,7 @@ import xyz.zhouxy.plusone.system.domain.model.menu.Menu;
import xyz.zhouxy.plusone.system.domain.model.menu.MenuConstructor; import xyz.zhouxy.plusone.system.domain.model.menu.MenuConstructor;
import xyz.zhouxy.plusone.system.domain.model.menu.MenuRepository; import xyz.zhouxy.plusone.system.domain.model.menu.MenuRepository;
import xyz.zhouxy.plusone.system.domain.service.MenuService; import xyz.zhouxy.plusone.system.domain.service.MenuService;
import xyz.zhouxy.plusone.util.AssertResult;
/** /**
* *
@ -88,16 +88,15 @@ public class MenuManagementService {
// ==================== delete ==================== // ==================== delete ====================
public void deleteMenu(Long id) { public void deleteMenu(Long id) {
Menu menuToDelete = menuRepository.find(id) Menu menuToDelete = menuRepository.find(id);
.orElseThrow(DataNotExistException::new); AssertResult.nonNull(menuToDelete);
menuRepository.delete(menuToDelete); menuRepository.delete(menuToDelete);
} }
// ==================== update ==================== // ==================== update ====================
public void updateMenu(Long id, @Valid UpdateMenuCommand command) { public void updateMenu(Long id, @Valid UpdateMenuCommand command) {
Assert.isTrue(Objects.equals(id, command.getId()), "id 不匹配"); Assert.isTrue(Objects.equals(id, command.getId()), "id 不匹配");
Menu menuToUpdate = menuRepository.find(command.getId()) Menu menuToUpdate = menuRepository.find(command.getId());
.orElseThrow(DataNotExistException::new);
menuToUpdate.updateMenuInfo( menuToUpdate.updateMenuInfo(
command.getMenuType(), command.getMenuType(),
command.getParentId(), command.getParentId(),
@ -119,7 +118,7 @@ public class MenuManagementService {
@Transactional(propagation = Propagation.SUPPORTS) @Transactional(propagation = Propagation.SUPPORTS)
public MenuViewObject findById(Long id) { public MenuViewObject findById(Long id) {
var menu = menuRepository.find(id); var menu = menuRepository.find(id);
return MenuViewObject.of(menu.orElseThrow(DataNotExistException::new)); return MenuViewObject.of(menu);
} }
@Transactional(propagation = Propagation.SUPPORTS) @Transactional(propagation = Propagation.SUPPORTS)

View File

@ -10,7 +10,6 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import xyz.zhouxy.plusone.exception.DataNotExistException;
import xyz.zhouxy.plusone.system.application.query.RoleQueries; import xyz.zhouxy.plusone.system.application.query.RoleQueries;
import xyz.zhouxy.plusone.system.application.query.params.RoleQueryParams; import xyz.zhouxy.plusone.system.application.query.params.RoleQueryParams;
import xyz.zhouxy.plusone.system.application.query.result.RoleOverview; import xyz.zhouxy.plusone.system.application.query.result.RoleOverview;
@ -63,7 +62,7 @@ public class RoleManagementService {
public void updateRole(@Valid UpdateRoleCommand command) { public void updateRole(@Valid UpdateRoleCommand command) {
Long roleId = command.getId(); Long roleId = command.getId();
Role roleToUpdate = _roleRepository.find(roleId).orElseThrow(DataNotExistException::new); Role roleToUpdate = _roleRepository.find(roleId);
roleToUpdate.update( roleToUpdate.update(
command.getName(), command.getName(),
command.getIdentifier(), command.getIdentifier(),
@ -75,7 +74,7 @@ public class RoleManagementService {
} }
public void delete(Long id) { public void delete(Long id) {
Role role = _roleRepository.find(id).orElseThrow(DataNotExistException::new); Role role = _roleRepository.find(id);
_roleRepository.delete(role); _roleRepository.delete(role);
} }
@ -86,7 +85,7 @@ public class RoleManagementService {
@Transactional(propagation = Propagation.SUPPORTS) @Transactional(propagation = Propagation.SUPPORTS)
public Role findById(Long id) { public Role findById(Long id) {
return _roleRepository.find(id).orElseThrow(DataNotExistException::new); return _roleRepository.find(id);
} }
@Transactional(propagation = Propagation.SUPPORTS) @Transactional(propagation = Propagation.SUPPORTS)

View File

@ -27,7 +27,7 @@ public class AccountCreated extends DomainEvent {
public AccountCreated(Account account) { public AccountCreated(Account account) {
this.username = account.getUsername(); this.username = account.getUsername();
this.email = account.getEmail().orElse(null); this.email = account.getEmail();
this.mobilePhone = account.getMobilePhone().orElse(null); this.mobilePhone = account.getMobilePhone();
} }
} }

View File

@ -27,7 +27,7 @@ public class AccountLocked extends DomainEvent {
public AccountLocked(Account account) { public AccountLocked(Account account) {
this.username = account.getUsername(); this.username = account.getUsername();
this.email = account.getEmail().orElse(null); this.email = account.getEmail();
this.mobilePhone = account.getMobilePhone().orElse(null); this.mobilePhone = account.getMobilePhone();
} }
} }

View File

@ -27,8 +27,8 @@ public class AccountPasswordChanged extends DomainEvent {
public AccountPasswordChanged(Account account) { public AccountPasswordChanged(Account account) {
this.username = account.getUsername(); this.username = account.getUsername();
this.email = account.getEmail().orElse(null); this.email = account.getEmail();
this.mobilePhone = account.getMobilePhone().orElse(null); this.mobilePhone = account.getMobilePhone();
} }
} }

View File

@ -25,6 +25,6 @@ public class EmailChanged extends DomainEvent {
public EmailChanged(Account account) { public EmailChanged(Account account) {
this.username = account.getUsername(); this.username = account.getUsername();
this.email = account.getEmail().orElse(null); this.email = account.getEmail();
} }
} }

View File

@ -25,6 +25,6 @@ public class MobilePhoneChanged extends DomainEvent {
public MobilePhoneChanged(Account account) { public MobilePhoneChanged(Account account) {
this.username = account.getUsername(); this.username = account.getUsername();
this.mobilePhone = account.getMobilePhone().orElse(null); this.mobilePhone = account.getMobilePhone();
} }
} }

View File

@ -27,7 +27,7 @@ public class UsernameChanged extends DomainEvent {
public UsernameChanged(Account account) { public UsernameChanged(Account account) {
this.username = account.getUsername(); this.username = account.getUsername();
this.email = account.getEmail().orElse(null); this.email = account.getEmail();
this.mobilePhone = account.getMobilePhone().orElse(null); this.mobilePhone = account.getMobilePhone();
} }
} }

View File

@ -5,6 +5,8 @@ import java.util.HashSet;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import xyz.zhouxy.plusone.domain.AggregateRoot; import xyz.zhouxy.plusone.domain.AggregateRoot;
import xyz.zhouxy.plusone.domain.IWithVersion; import xyz.zhouxy.plusone.domain.IWithVersion;
@ -28,17 +30,17 @@ public class Account extends AggregateRoot<Long> implements IWithVersion {
// ===================== 字段 ==================== // ===================== 字段 ====================
private Long id; private Long id;
private Username username; private @Getter Username username;
private Email email; private @Getter Email email;
private MobilePhone mobilePhone; private @Getter MobilePhone mobilePhone;
private Password password; private Password password;
private AccountStatus status; private @Getter AccountStatus status;
private AccountInfo accountInfo; private @Getter AccountInfo accountInfo;
private Set<Long> roleRefs = new HashSet<>(); private Set<Long> roleRefs = new HashSet<>();
private Long createdBy; private @Getter Long createdBy;
private Long updatedBy; private @Getter @Setter Long updatedBy;
private long version; private @Getter long version;
public void setUsername(Username username) { public void setUsername(Username username) {
this.username = username; this.username = username;
@ -221,48 +223,11 @@ public class Account extends AggregateRoot<Long> implements IWithVersion {
return Optional.ofNullable(id); return Optional.ofNullable(id);
} }
public Username getUsername() { public Set<Long> getRoleIds() {
return username; return Set.copyOf(this.roleRefs);
}
public Optional<Email> getEmail() {
return Optional.ofNullable(email);
}
public Optional<MobilePhone> getMobilePhone() {
return Optional.ofNullable(mobilePhone);
} }
Password getPassword() { Password getPassword() {
return password; return password;
} }
public AccountStatus getStatus() {
return status;
}
public AccountInfo getAccountInfo() {
return accountInfo;
}
public Set<Long> getRoleIds() {
return Set.copyOf(roleRefs);
}
public Optional<Long> getCreatedBy() {
return Optional.ofNullable(createdBy);
}
public Optional<Long> getUpdatedBy() {
return Optional.ofNullable(updatedBy);
}
public void setUpdatedBy(long updatedBy) {
this.updatedBy = updatedBy;
}
@Override
public long getVersion() {
return this.version;
}
} }

View File

@ -3,7 +3,6 @@ package xyz.zhouxy.plusone.system.domain.model.account;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
import lombok.Getter; import lombok.Getter;
import lombok.ToString; import lombok.ToString;
@ -14,12 +13,13 @@ import xyz.zhouxy.plusone.domain.IValueObject;
* *
* @author <a href="https://gitee.com/zhouxy108">ZhouXY</a> * @author <a href="https://gitee.com/zhouxy108">ZhouXY</a>
*/ */
@Getter
@ToString @ToString
public class AccountInfo implements IValueObject { public class AccountInfo implements IValueObject {
private final Nickname nickname; private final Nickname nickname;
private final URL avatar; private final URL avatar;
private final @Getter Sex sex; private final Sex sex;
private AccountInfo(Nickname nickname, URL avatar, Sex sex) { private AccountInfo(Nickname nickname, URL avatar, Sex sex) {
this.nickname = nickname; this.nickname = nickname;
@ -40,12 +40,4 @@ public class AccountInfo implements IValueObject {
} }
return new AccountInfo(Nickname.ofNullable(nickname), avatarURL, sex); return new AccountInfo(Nickname.ofNullable(nickname), avatarURL, sex);
} }
public Optional<Nickname> getNickname() {
return Optional.ofNullable(nickname);
}
public Optional<URL> getAvatar() {
return Optional.ofNullable(avatar);
}
} }

View File

@ -1,7 +1,6 @@
package xyz.zhouxy.plusone.system.domain.model.account; package xyz.zhouxy.plusone.system.domain.model.account;
import java.util.Collection; import java.util.Collection;
import java.util.Optional;
import xyz.zhouxy.plusone.domain.IRepository; import xyz.zhouxy.plusone.domain.IRepository;
@ -15,11 +14,11 @@ public interface AccountRepository extends IRepository<Account, Long> {
Collection<Account> findByRoleId(Long roleId); Collection<Account> findByRoleId(Long roleId);
Optional<Account> findByEmail(Email email); Account findByEmail(Email email);
Optional<Account> findByMobilePhone(MobilePhone mobilePhone); Account findByMobilePhone(MobilePhone mobilePhone);
Optional<Account> findByUsername(Username username); Account findByUsername(Username username);
boolean existsUsername(Username username); boolean existsUsername(Username username);

View File

@ -6,6 +6,7 @@ import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import lombok.ToString; import lombok.ToString;
import xyz.zhouxy.plusone.domain.AggregateRoot; import xyz.zhouxy.plusone.domain.AggregateRoot;
@ -114,7 +115,7 @@ public class Dict extends AggregateRoot<Long> implements IWithLabel, IWithVersio
} }
public Set<DictValue> getValues() { public Set<DictValue> getValues() {
return Set.copyOf(this.values.values()); return this.values.values().stream().collect(Collectors.toSet());
} }
@Override @Override

View File

@ -4,7 +4,7 @@ import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Collection; import java.util.Collection;
import java.util.Optional; import java.util.Objects;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -14,8 +14,8 @@ import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import static xyz.zhouxy.plusone.domain.ValidatableStringRecord.getValueOrNull;
import xyz.zhouxy.plusone.jdbc.JdbcRepositorySupport; import xyz.zhouxy.plusone.jdbc.JdbcRepositorySupport;
import xyz.zhouxy.plusone.util.AssertResult;
/** /**
* AccountRepository * AccountRepository
@ -41,11 +41,11 @@ public class AccountRepositoryImpl extends JdbcRepositorySupport<Account, Long>
new MapSqlParameterSource() new MapSqlParameterSource()
.addValue("id", entity.getId().orElseThrow()) .addValue("id", entity.getId().orElseThrow())
.addValue("version", entity.getVersion())); .addValue("version", entity.getVersion()));
assertUpdateOneRow(i); AssertResult.update(i, 1);
} }
@Override @Override
protected final Optional<Account> doFindById(@Nonnull Long id) { protected final Account doFindById(@Nonnull Long id) {
return queryForObject(""" return queryForObject("""
SELECT SELECT
id, email, mobile_phone, username, "password", salt, avatar, sex, nickname, status, id, email, mobile_phone, username, "password", salt, avatar, sex, nickname, status,
@ -53,11 +53,11 @@ public class AccountRepositoryImpl extends JdbcRepositorySupport<Account, Long>
FROM sys_account FROM sys_account
WHERE id = :id AND deleted = 0 WHERE id = :id AND deleted = 0
""", """,
"id", id); new MapSqlParameterSource("id", id));
} }
@Override @Override
public Optional<Account> findByEmail(Email email) { public Account findByEmail(Email email) {
return queryForObject(""" return queryForObject("""
SELECT SELECT
id, email, mobile_phone, username, "password", salt, avatar, sex, nickname, status, id, email, mobile_phone, username, "password", salt, avatar, sex, nickname, status,
@ -65,11 +65,11 @@ public class AccountRepositoryImpl extends JdbcRepositorySupport<Account, Long>
FROM sys_account FROM sys_account
WHERE email = :email AND deleted = 0 WHERE email = :email AND deleted = 0
""", """,
"email", email.value()); new MapSqlParameterSource("email", email.value()));
} }
@Override @Override
public Optional<Account> findByMobilePhone(MobilePhone mobilePhone) { public Account findByMobilePhone(MobilePhone mobilePhone) {
return queryForObject(""" return queryForObject("""
SELECT SELECT
id, email, mobile_phone, username, "password", salt, avatar, sex, nickname, status, id, email, mobile_phone, username, "password", salt, avatar, sex, nickname, status,
@ -77,11 +77,11 @@ public class AccountRepositoryImpl extends JdbcRepositorySupport<Account, Long>
FROM sys_account FROM sys_account
WHERE mobile_phone = :mobilePhone AND deleted = 0 WHERE mobile_phone = :mobilePhone AND deleted = 0
""", """,
"mobilePhone", mobilePhone.value()); new MapSqlParameterSource("mobilePhone", mobilePhone.value()));
} }
@Override @Override
public Optional<Account> findByUsername(Username username) { public Account findByUsername(Username username) {
return queryForObject(""" return queryForObject("""
SELECT SELECT
id, email, mobile_phone, username, "password", salt, avatar, sex, nickname, status, id, email, mobile_phone, username, "password", salt, avatar, sex, nickname, status,
@ -89,33 +89,31 @@ public class AccountRepositoryImpl extends JdbcRepositorySupport<Account, Long>
FROM sys_account FROM sys_account
WHERE username = :username AND deleted = 0 WHERE username = :username AND deleted = 0
""", """,
"username", username.value()); new MapSqlParameterSource("username", username.value()));
} }
@Override @Override
public boolean exists(Long id) { public boolean exists(Long id) {
return queryExists("SELECT EXISTS (SELECT 1 FROM sys_account WHERE id = :id AND deleted = 0 LIMIT 1)", return queryExists("SELECT 1 FROM sys_account WHERE id = :id AND deleted = 0 LIMIT 1",
"id", id); new MapSqlParameterSource("id", id));
} }
@Override @Override
public boolean existsUsername(Username username) { public boolean existsUsername(Username username) {
return queryExists( return queryExists("SELECT 1 FROM sys_account WHERE username = :username AND deleted = 0 LIMIT 1",
"SELECT EXISTS (SELECT 1 FROM sys_account WHERE username = :username AND deleted = 0 LIMIT 1)", new MapSqlParameterSource("username", username.value()));
"username", username.value());
} }
@Override @Override
public boolean existsEmail(Email email) { public boolean existsEmail(Email email) {
return queryExists("SELECT EXISTS (SELECT 1 FROM sys_account WHERE email = :email AND deleted = 0 LIMIT 1)", return queryExists("SELECT 1 FROM sys_account WHERE email = :email AND deleted = 0 LIMIT 1",
"email", email.value()); new MapSqlParameterSource("email", email.value()));
} }
@Override @Override
public boolean existsMobilePhone(MobilePhone mobilePhone) { public boolean existsMobilePhone(MobilePhone mobilePhone) {
return queryExists( return queryExists("SELECT 1 FROM sys_account WHERE mobile_phone = :mobile_phone AND deleted = 0 LIMIT 1",
"SELECT EXISTS (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 @Override
@ -129,7 +127,7 @@ public class AccountRepositoryImpl extends JdbcRepositorySupport<Account, Long>
LEFT JOIN sys_account_role ar ON a.id = ar.account_id LEFT JOIN sys_account_role ar ON a.id = ar.account_id
WHERE ar.role_id = :roleId AND a.deleted = 0 WHERE ar.role_id = :roleId AND a.deleted = 0
""", """,
"roleId", roleId); new MapSqlParameterSource("roleId", roleId));
} }
@Override @Override
@ -144,9 +142,9 @@ public class AccountRepositoryImpl extends JdbcRepositorySupport<Account, Long>
:createdBy, :createTime) :createdBy, :createTime)
""", """,
generateParamSource(id, entity)); generateParamSource(id, entity));
assertUpdateOneRow(i); AssertResult.update(i, 1);
this.accountRoleDAO.insertAccountRoleRefs(id, entity.getRoleIds()); this.accountRoleDAO.insertAccountRoleRefs(id, entity.getRoleIds());
return find(id).orElseThrow(); return entity;
} }
@Override @Override
@ -168,9 +166,9 @@ public class AccountRepositoryImpl extends JdbcRepositorySupport<Account, Long>
WHERE id = :id AND deleted = 0 AND "version" = :version WHERE id = :id AND deleted = 0 AND "version" = :version
""", """,
generateParamSource(entity)); generateParamSource(entity));
assertUpdateOneRow(i); AssertResult.update(i, 1);
this.accountRoleDAO.saveAccountRoleRefs(entity); this.accountRoleDAO.saveAccountRoleRefs(entity);
return find(entity.getId().orElseThrow()).orElseThrow(); return entity;
} }
@Override @Override
@ -200,14 +198,16 @@ public class AccountRepositoryImpl extends JdbcRepositorySupport<Account, Long>
AccountInfo accountInfo = entity.getAccountInfo(); AccountInfo accountInfo = entity.getAccountInfo();
return new MapSqlParameterSource() return new MapSqlParameterSource()
.addValue("id", id) .addValue("id", id)
.addValue("email", getValueOrNull(entity.getEmail())) .addValue("email", Objects.nonNull(entity.getEmail()) ? entity.getEmail().value() : null)
.addValue("mobilePhone", getValueOrNull(entity.getMobilePhone())) .addValue("mobilePhone",
Objects.nonNull(entity.getMobilePhone()) ? entity.getMobilePhone().value() : null)
.addValue("username", entity.getUsername().value()) .addValue("username", entity.getUsername().value())
.addValue("password", entity.getPassword().value()) .addValue("password", entity.getPassword().value())
.addValue("salt", entity.getPassword().getSalt()) .addValue("salt", entity.getPassword().getSalt())
.addValue("avatar", accountInfo.getAvatar().toString()) .addValue("avatar", accountInfo.getAvatar().toString())
.addValue("sex", accountInfo.getSex().getValue()) .addValue("sex", accountInfo.getSex().getValue())
.addValue("nickname", getValueOrNull(accountInfo.getNickname())) .addValue("nickname",
Objects.nonNull(accountInfo.getNickname()) ? accountInfo.getNickname().value() : null)
.addValue("status", entity.getStatus().getValue()) .addValue("status", entity.getStatus().getValue())
.addValue("createdBy", entity.getCreatedBy()) .addValue("createdBy", entity.getCreatedBy())
.addValue("createTime", now) .addValue("createTime", now)

View File

@ -1,43 +1,47 @@
package xyz.zhouxy.plusone.system.domain.model.account; package xyz.zhouxy.plusone.system.domain.model.account;
import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import xyz.zhouxy.plusone.jdbc.PlusoneJdbcDaoSupport; import xyz.zhouxy.plusone.util.AssertResult;
import xyz.zhouxy.plusone.util.NumberUtil;
class AccountRoleRefDAO extends PlusoneJdbcDaoSupport { class AccountRoleRefDAO {
private final NamedParameterJdbcTemplate jdbc;
AccountRoleRefDAO(@Nonnull NamedParameterJdbcTemplate jdbc) { AccountRoleRefDAO(NamedParameterJdbcTemplate jdbc) {
super(jdbc); this.jdbc = jdbc;
} }
Set<Long> selectRoleIdsByAccountId(Long accountId) { Set<Long> selectRoleIdsByAccountId(Long accountId) {
return queryForStream(""" List<Long> roleRefs = this.jdbc.queryForList("""
SELECT r.id FROM sys_role r RIGHT JOIN sys_account_role ar ON r.id = ar.role_id SELECT r.id FROM sys_role r RIGHT JOIN sys_account_role ar ON r.id = ar.role_id
WHERE r.deleted = 0 AND ar.account_id = :accountId; WHERE r.deleted = 0 AND ar.account_id = :accountId;
""", """,
"accountId", accountId, new MapSqlParameterSource("accountId", accountId),
Long.TYPE) Long.TYPE);
.collect(Collectors.toSet()); return new HashSet<>(roleRefs);
} }
void clearAccountRoleRefs(Account entity) { void clearAccountRoleRefs(Account entity) {
update("DELETE FROM sys_account_role WHERE account_id = :accountId", "accountId", entity.getId().orElseThrow()); var param = new MapSqlParameterSource("accountId", entity.getId().orElseThrow());
this.jdbc.update("DELETE FROM sys_account_role WHERE account_id = :accountId", param);
} }
void insertAccountRoleRefs(Long accountId, Set<Long> roleRefs) { void insertAccountRoleRefs(Long accountId, Set<Long> roleRefs) {
int i = batchUpdate( String sql = "INSERT INTO sys_account_role (account_id, role_id) VALUES (:accountId, :roleId)";
"INSERT INTO sys_account_role (account_id, role_id) VALUES (:accountId, :roleId)", MapSqlParameterSource[] batchArgs = roleRefs
roleRefs, .stream()
(Long roleId) -> new MapSqlParameterSource() .map((Long roleId) -> new MapSqlParameterSource()
.addValue("accountId", accountId) .addValue("accountId", accountId)
.addValue("roleId", roleId)); .addValue("roleId", roleId))
assertResultEquals(i, roleRefs.size()); .toArray(MapSqlParameterSource[]::new);
int[] i = this.jdbc.batchUpdate(sql, batchArgs);
AssertResult.update(roleRefs.size(), NumberUtil.sum(i));
} }
void saveAccountRoleRefs(Account entity) { void saveAccountRoleRefs(Account entity) {

View File

@ -6,7 +6,6 @@ import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import java.util.Optional;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -16,7 +15,6 @@ import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import xyz.zhouxy.plusone.exception.DataNotExistException;
import xyz.zhouxy.plusone.jdbc.JdbcRepositorySupport; import xyz.zhouxy.plusone.jdbc.JdbcRepositorySupport;
import xyz.zhouxy.plusone.util.AssertResult; import xyz.zhouxy.plusone.util.AssertResult;
@ -36,9 +34,9 @@ public class DictRepositoryImpl extends JdbcRepositorySupport<Dict, Long> implem
} }
@Override @Override
public Optional<Dict> doFindById(@Nonnull Long id) { public Dict doFindById(@Nonnull Long id) {
return queryForObject("SELECT id, dict_type, dict_label, \"version\" WHERE id = :id AND deleted = 0", return queryForObject("SELECT id, dict_type, dict_label, \"version\" WHERE id = :id AND deleted = 0",
"id", id); new MapSqlParameterSource("id", id));
} }
@Override @Override
@ -49,9 +47,9 @@ public class DictRepositoryImpl extends JdbcRepositorySupport<Dict, Long> implem
VALUES (:dictType, :dictLabel, :createTime, :createdBy) VALUES (:dictType, :dictLabel, :createTime, :createdBy)
""", """,
generateParamSource(id, entity)); generateParamSource(id, entity));
AssertResult.updateOneRow(i); AssertResult.update(i, 1);
this.dictValueDAO.insertDictValues(id, entity); this.dictValueDAO.insertDictValues(id, entity);
return find(id).orElseThrow(DataNotExistException::new); return find(id);
} }
@Override @Override
@ -66,9 +64,9 @@ public class DictRepositoryImpl extends JdbcRepositorySupport<Dict, Long> implem
WHERE id = :id AND deleted = 0 AND "version" = :version WHERE id = :id AND deleted = 0 AND "version" = :version
""", """,
generateParamSource(entity)); generateParamSource(entity));
AssertResult.updateOneRow(i); AssertResult.update(i, 1);
this.dictValueDAO.updateDictValues(entity); this.dictValueDAO.updateDictValues(entity);
return find(entity.getId().orElseThrow()).orElseThrow(DataNotExistException::new); return find(entity.getId().orElseThrow());
} }
@Override @Override
@ -78,12 +76,12 @@ public class DictRepositoryImpl extends JdbcRepositorySupport<Dict, Long> implem
WHERE id = :id AND deleted = 0 AND "version" = :version WHERE id = :id AND deleted = 0 AND "version" = :version
""", """,
generateParamSource(entity)); generateParamSource(entity));
AssertResult.updateOneRow(i); AssertResult.update(i, 1);
} }
@Override @Override
public boolean exists(Long id) { public boolean exists(Long id) {
return queryExists("SELECT EXISTS (SELECT 1 FROM sys_dict_type WHERE id = :id AND deleted = 0 LIMIT 1)", return queryExists("SELECT 1 FROM sys_dict_type WHERE id = :id AND deleted = 0 LIMIT 1",
new MapSqlParameterSource("id", id)); new MapSqlParameterSource("id", id));
} }

View File

@ -4,45 +4,48 @@ import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import xyz.zhouxy.plusone.jdbc.PlusoneJdbcDaoSupport; import xyz.zhouxy.plusone.util.AssertResult;
import xyz.zhouxy.plusone.util.NumberUtil;
class DictValueDAO extends PlusoneJdbcDaoSupport { class DictValueDAO {
private final NamedParameterJdbcTemplate jdbc;
DictValueDAO(@Nonnull NamedParameterJdbcTemplate jdbc) { DictValueDAO(NamedParameterJdbcTemplate jdbc) {
super(jdbc); this.jdbc = jdbc;
} }
void updateDictValues(Dict entity) { void updateDictValues(Dict entity) {
update("DELETE FROM sys_dict_value WHERE dict_type = :dictType", MapSqlParameterSource deleteParam = new MapSqlParameterSource("dictType", entity.getId().orElseThrow());
"dictType", entity.getId().orElseThrow()); this.jdbc.update("DELETE FROM sys_dict_value WHERE dict_type = :dictType", deleteParam);
int i = insertDictValues(entity.getId().orElseThrow(), entity); int i = insertDictValues(entity.getId().orElseThrow(), entity);
assertResultEquals(i, entity.count()); AssertResult.update(i, entity.count());
} }
int insertDictValues(Long dictId, Dict entity) { int insertDictValues(Long dictId, Dict entity) {
if (Objects.isNull(dictId) || Objects.isNull(entity) || CollectionUtils.isEmpty(entity.getValues())) { if (Objects.isNull(dictId) || Objects.isNull(entity) || CollectionUtils.isEmpty(entity.getValues())) {
return 0; return 0;
} }
return batchUpdate( int[] i = this.jdbc.batchUpdate(
"INSERT INTO sys_dict_value (dict_type, dict_key, label) VALUES (:dictType, :dictKey, :label)", "INSERT INTO sys_dict_value (dict_type, dict_key, label) VALUES (:dictType, :dictKey, :label)",
entity.getValues(), entity.getValues().stream()
dictValue -> new MapSqlParameterSource() .map(dictValue -> new MapSqlParameterSource()
.addValue("dictType", dictId) .addValue("dictType", dictId)
.addValue("dictKey", dictValue.getKey()) .addValue("dictKey", dictValue.getKey())
.addValue("label", dictValue.getLabel())); .addValue("label", dictValue.getLabel()))
.toArray(SqlParameterSource[]::new));
return NumberUtil.sum(i);
} }
Set<DictValue> selectDictValuesByDictId(long id) { Set<DictValue> selectDictValuesByDictId(long id) {
return queryForStream( return this.jdbc.queryForStream("""
"SELECT dict_key, label FROM sys_dict_value WHERE dict_type = :dictType", SELECT dict_key, label FROM sys_dict_value WHERE dict_type = :dictType
"dictType", id, """, new MapSqlParameterSource("dictType", id),
(rs, i) -> DictValue.of(rs.getInt("dict_key"), rs.getString("label"))) (rs, rowNum) -> DictValue.of(rs.getInt("dict_key"), rs.getString("label")))
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
} }

View File

@ -39,14 +39,15 @@ class ActionDAO extends JdbcEntityDaoSupport<Action, Long> {
.map(action -> action.getId().orElseThrow()) .map(action -> action.getId().orElseThrow())
.collect(Collectors.toSet()); .collect(Collectors.toSet());
if (!ids.isEmpty()) { if (!ids.isEmpty()) {
update("UPDATE sys_action SET deleted = id WHERE resource = :resource AND id NOT IN (:ids) AND deleted = 0", this.jdbc.update(
"UPDATE sys_action SET deleted = id WHERE resource = :resource AND id NOT IN (:ids) AND deleted = 0",
new MapSqlParameterSource() new MapSqlParameterSource()
.addValue("resource", menuId) .addValue("resource", menuId)
.addValue("ids", ids)); .addValue("ids", ids));
} }
// 更新存在的数据 // 更新存在的数据
batchUpdate(""" this.jdbc.batchUpdate("""
UPDATE sys_action UPDATE sys_action
SET resource = :resource, SET resource = :resource,
identifier = :identifier, identifier = :identifier,
@ -55,18 +56,22 @@ class ActionDAO extends JdbcEntityDaoSupport<Action, Long> {
updated_by = :updatedBy updated_by = :updatedBy
WHERE id = :id AND deleted = 0 WHERE id = :id AND deleted = 0
""", """,
actions.stream().filter(action -> action.getId().isPresent()), actions.stream()
action -> generateParamSource(menuId, action)); .filter(action -> action.getId().isPresent())
.map(action -> generateParamSource(menuId, action))
.toArray(MapSqlParameterSource[]::new));
// 插入新添加的数据 // 插入新添加的数据
batchUpdate(""" this.jdbc.batchUpdate("""
INSERT INTO sys_action INSERT INTO sys_action
(id, resource, identifier, "label", create_time, created_by) (id, resource, identifier, "label", create_time, created_by)
VALUES VALUES
(:id, :resource, :identifier, :label, :createTime, :createdBy) (:id, :resource, :identifier, :label, :createTime, :createdBy)
""", """,
actions.stream().filter(action -> action.getId().isEmpty()), actions.stream()
action -> generateParamSource(menuId, IdUtil.getSnowflakeNextId(), action)); .filter(action -> action.getId().isEmpty())
.map(action -> generateParamSource(menuId, IdUtil.getSnowflakeNextId(), action))
.toArray(MapSqlParameterSource[]::new));
} }
List<Action> selectActionsByMenuId(long menuId) { List<Action> selectActionsByMenuId(long menuId) {
@ -75,8 +80,7 @@ class ActionDAO extends JdbcEntityDaoSupport<Action, Long> {
FROM sys_action a FROM sys_action a
JOIN (SELECT id, resource FROM sys_menu WHERE id = :menuId AND deleted = 0) m ON a.resource = m.id JOIN (SELECT id, resource FROM sys_menu WHERE id = :menuId AND deleted = 0) m ON a.resource = m.id
WHERE a.deleted = 0 WHERE a.deleted = 0
""", """, new MapSqlParameterSource("menuId", menuId));
"menuId", menuId);
} }
Collection<Action> selectActionsByIdIn(Collection<Long> actionIds) { Collection<Action> selectActionsByIdIn(Collection<Long> actionIds) {
@ -88,8 +92,7 @@ class ActionDAO extends JdbcEntityDaoSupport<Action, Long> {
FROM sys_action a FROM sys_action a
LEFT JOIN sys_menu m ON a.resource = m.id LEFT JOIN sys_menu m ON a.resource = m.id
WHERE a.id IN (:actionIds) AND a.deleted = 0 WHERE a.id IN (:actionIds) AND a.deleted = 0
""", """, new MapSqlParameterSource("actionIds", actionIds));
"actionIds", actionIds);
} }
private SqlParameterSource generateParamSource(Long menuId, Action action) { private SqlParameterSource generateParamSource(Long menuId, Action action) {

View File

@ -8,7 +8,6 @@ import java.time.LocalDateTime;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -18,7 +17,6 @@ import org.springframework.stereotype.Repository;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import xyz.zhouxy.plusone.constant.EntityStatus; import xyz.zhouxy.plusone.constant.EntityStatus;
import xyz.zhouxy.plusone.exception.DataNotExistException;
import xyz.zhouxy.plusone.jdbc.JdbcRepositorySupport; import xyz.zhouxy.plusone.jdbc.JdbcRepositorySupport;
import xyz.zhouxy.plusone.system.domain.model.menu.Menu.MenuType; import xyz.zhouxy.plusone.system.domain.model.menu.Menu.MenuType;
import xyz.zhouxy.plusone.util.AssertResult; import xyz.zhouxy.plusone.util.AssertResult;
@ -40,7 +38,7 @@ public class MenuRepositoryImpl extends JdbcRepositorySupport<Menu, Long> implem
} }
@Override @Override
protected final Optional<Menu> doFindById(@Nonnull Long id) { protected final Menu doFindById(@Nonnull Long id) {
return queryForObject(""" return queryForObject("""
SELECT SELECT
id, parent_id, "type", "name", "path", title, icon, hidden, order_number, status, remarks, id, parent_id, "type", "name", "path", title, icon, hidden, order_number, status, remarks,
@ -48,7 +46,7 @@ public class MenuRepositoryImpl extends JdbcRepositorySupport<Menu, Long> implem
FROM sys_menu FROM sys_menu
WHERE id = :id AND deleted = 0 WHERE id = :id AND deleted = 0
""", """,
"id", id); new MapSqlParameterSource("id", id));
} }
@Override @Override
@ -64,9 +62,9 @@ public class MenuRepositoryImpl extends JdbcRepositorySupport<Menu, Long> implem
"""; """;
MapSqlParameterSource paramSource = generateParamSource(id, entity); MapSqlParameterSource paramSource = generateParamSource(id, entity);
int i = update(sql, paramSource); int i = update(sql, paramSource);
AssertResult.updateOneRow(i); AssertResult.update(i, 1);
this.actionDAO.saveActions(id, entity.getActions()); this.actionDAO.saveActions(id, entity.getActions());
return find(id).orElseThrow(DataNotExistException::new); return entity;
} }
@Override @Override
@ -94,12 +92,12 @@ public class MenuRepositoryImpl extends JdbcRepositorySupport<Menu, Long> implem
// 更新菜单 // 更新菜单
int i = update(sql, generateParamSource(entity)); int i = update(sql, generateParamSource(entity));
AssertResult.updateOneRow(i); AssertResult.update(i, 1);
// 保存权限 // 保存权限
Long id = entity.getId().orElseThrow(); Long id = entity.getId().orElseThrow();
this.actionDAO.saveActions(id, entity.getActions()); this.actionDAO.saveActions(id, entity.getActions());
return find(entity.getId().orElseThrow()).orElseThrow(DataNotExistException::new); return entity;
} }
@Override @Override
@ -110,13 +108,13 @@ public class MenuRepositoryImpl extends JdbcRepositorySupport<Menu, Long> implem
""", """,
new MapSqlParameterSource("id", entity.getId().orElseThrow()) new MapSqlParameterSource("id", entity.getId().orElseThrow())
.addValue("version", entity.getVersion())); .addValue("version", entity.getVersion()));
AssertResult.updateOneRow(i); AssertResult.update(i, 1);
} }
@Override @Override
public boolean exists(Long id) { public boolean exists(Long id) {
return queryExists("SELECT EXISTS (SELECT 1 FROM sys_menu WHERE id = :id AND deleted = 0 LIMIT 1)", return queryExists("SELECT 1 FROM sys_menu WHERE id = :id AND deleted = 0 LIMIT 1",
"id", id); new MapSqlParameterSource("id", id));
} }
@Override @Override
@ -131,7 +129,7 @@ public class MenuRepositoryImpl extends JdbcRepositorySupport<Menu, Long> implem
FROM sys_menu FROM sys_menu
WHERE id IN (:ids) AND deleted = 0 WHERE id IN (:ids) AND deleted = 0
""", """,
"ids", ids); new MapSqlParameterSource("ids", ids));
} }
@Override @Override
@ -149,7 +147,7 @@ public class MenuRepositoryImpl extends JdbcRepositorySupport<Menu, Long> implem
LEFT JOIN sys_role_menu AS rm ON m.id = rm.menu_id LEFT JOIN sys_role_menu AS rm ON m.id = rm.menu_id
WHERE rm.role_id = :roleId AND r.deleted = 0 WHERE rm.role_id = :roleId AND r.deleted = 0
""", """,
"roleId", roleId); new MapSqlParameterSource("roleId", roleId));
} }
@Override @Override

View File

@ -3,38 +3,43 @@ package xyz.zhouxy.plusone.system.domain.model.role;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import xyz.zhouxy.plusone.jdbc.PlusoneJdbcDaoSupport; import xyz.zhouxy.plusone.util.AssertResult;
import xyz.zhouxy.plusone.util.NumberUtil;
class RoleMenuRefDAO extends PlusoneJdbcDaoSupport { class RoleMenuRefDAO {
public RoleMenuRefDAO(@Nonnull NamedParameterJdbcTemplate jdbc) { private final NamedParameterJdbcTemplate jdbc;
super(jdbc);
public RoleMenuRefDAO(NamedParameterJdbcTemplate jdbc) {
this.jdbc = jdbc;
} }
Set<MenuRef> selectMenuRefsByRoleId(long roleId) { Set<MenuRef> selectMenuRefsByRoleId(long roleId) {
return queryForStream("SELECT menu_id FROM sys_role_menu WHERE role_id = :roleId", return this.jdbc.queryForList("SELECT menu_id FROM sys_role_menu WHERE role_id = :roleId",
"roleId", roleId, new MapSqlParameterSource("roleId", roleId),
Long.TYPE) Long.TYPE)
.stream()
.map(MenuRef::of) .map(MenuRef::of)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
void clearRoleMenuRefs(Role entity) { void clearRoleMenuRefs(Role entity) {
update("DELETE FROM sys_role_menu WHERE role_id = :roleId", "roleId", entity.getId().orElseThrow()); MapSqlParameterSource param = new MapSqlParameterSource("roleId", entity.getId().orElseThrow());
this.jdbc.update("DELETE FROM sys_role_menu WHERE role_id = :roleId", param);
} }
void saveRoleMenuRefs(Long roleId, Role entity) { void saveRoleMenuRefs(Long roleId, Role entity) {
int i = batchUpdate( String sql = "INSERT INTO sys_role_menu(role_id, menu_id) VALUES (:roleId, :menuId)";
"INSERT INTO sys_role_menu(role_id, menu_id) VALUES (:roleId, :menuId)", MapSqlParameterSource[] batchArgs = entity.getMenus()
entity.getMenus(), .stream()
menuRef -> new MapSqlParameterSource() .map(menuRef -> new MapSqlParameterSource()
.addValue("roleId", roleId) .addValue("roleId", roleId)
.addValue("menuId", menuRef.menuId())); .addValue("menuId", menuRef.menuId()))
assertResultEquals(i, entity.getMenus().size()); .toArray(MapSqlParameterSource[]::new);
int[] i = this.jdbc.batchUpdate(sql, batchArgs);
AssertResult.update(entity.getMenus().size(), NumberUtil.sum(i));
} }
} }

View File

@ -3,39 +3,43 @@ package xyz.zhouxy.plusone.system.domain.model.role;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import xyz.zhouxy.plusone.jdbc.PlusoneJdbcDaoSupport; import xyz.zhouxy.plusone.util.AssertResult;
import xyz.zhouxy.plusone.util.NumberUtil;
class RolePermissionRefDAO extends PlusoneJdbcDaoSupport { class RolePermissionRefDAO {
private final NamedParameterJdbcTemplate jdbc;
protected RolePermissionRefDAO(@Nonnull NamedParameterJdbcTemplate jdbc) { public RolePermissionRefDAO(NamedParameterJdbcTemplate jdbc) {
super(jdbc); this.jdbc = jdbc;
} }
Set<ActionRef> selectPermissionRefsByRoleId(long roleId) { Set<ActionRef> selectPermissionRefsByRoleId(long roleId) {
return queryForStream("SELECT permission_id FROM sys_role_permission WHERE role_id = :roleId", return this.jdbc.queryForList("SELECT permission_id FROM sys_role_permission WHERE role_id = :roleId",
"roleId", roleId, new MapSqlParameterSource("roleId", roleId),
Long.TYPE) Long.TYPE)
.stream()
.map(ActionRef::of) .map(ActionRef::of)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
void clearRolePermissionRefs(Role entity) { void clearRolePermissionRefs(Role entity) {
update("DELETE FROM sys_role_permission WHERE role_id = :roleId", MapSqlParameterSource param = new MapSqlParameterSource("roleId", entity.getId().orElseThrow());
"roleId", entity.getId().orElseThrow()); this.jdbc.update("DELETE FROM sys_role_permission WHERE role_id = :roleId", param);
} }
void saveRolePermissionRefs(Long roleId, Role entity) { void saveRolePermissionRefs(Long roleId, Role entity) {
int i = batchUpdate( String sql = "INSERT INTO sys_role_permission(role_id, permission_id) VALUES (:roleId, :permissionId)";
"INSERT INTO sys_role_permission(role_id, permission_id) VALUES (:roleId, :permissionId)", SqlParameterSource[] batchArgs = entity.getPermissions()
entity.getPermissions(), .stream()
actionRef -> new MapSqlParameterSource() .map(menuRef -> new MapSqlParameterSource()
.addValue("roleId", roleId) .addValue("roleId", roleId)
.addValue("permissionId", actionRef.actionId())); .addValue("permissionId", menuRef.actionId()))
assertResultEquals(i, entity.getMenus().size()); .toArray(MapSqlParameterSource[]::new);
int[] i = this.jdbc.batchUpdate(sql, batchArgs);
AssertResult.update(entity.getMenus().size(), NumberUtil.sum(i));
} }
} }

View File

@ -6,7 +6,6 @@ import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Collection; import java.util.Collection;
import java.util.Optional;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -16,7 +15,6 @@ import org.springframework.stereotype.Repository;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import xyz.zhouxy.plusone.constant.EntityStatus; import xyz.zhouxy.plusone.constant.EntityStatus;
import xyz.zhouxy.plusone.exception.DataNotExistException;
import xyz.zhouxy.plusone.jdbc.JdbcRepositorySupport; import xyz.zhouxy.plusone.jdbc.JdbcRepositorySupport;
import xyz.zhouxy.plusone.util.AssertResult; import xyz.zhouxy.plusone.util.AssertResult;
@ -38,13 +36,12 @@ public class RoleRepositoryImpl extends JdbcRepositorySupport<Role, Long> implem
} }
@Override @Override
protected final Optional<Role> doFindById(@Nonnull Long id) { protected final Role doFindById(@Nonnull Long id) {
return queryForObject(""" return queryForObject("""
SELECT "id","name","identifier","status","remarks","version" SELECT "id","name","identifier","status","remarks","version"
FROM "sys_role" FROM "sys_role"
WHERE id = :id AND deleted = 0 WHERE id = :id AND deleted = 0
""", """, new MapSqlParameterSource("id", id));
"id", id);
} }
@Override @Override
@ -55,13 +52,13 @@ public class RoleRepositoryImpl extends JdbcRepositorySupport<Role, Long> implem
""", """,
new MapSqlParameterSource("id", entity.getId().orElseThrow()) new MapSqlParameterSource("id", entity.getId().orElseThrow())
.addValue("version", entity.getVersion())); .addValue("version", entity.getVersion()));
AssertResult.updateOneRow(i); AssertResult.update(i, 1);
} }
@Override @Override
public boolean exists(Long id) { public boolean exists(Long id) {
return queryExists("SELECT EXISTS (SELECT 1 FROM sys_role WHERE id = :id AND deleted = 0 LIMIT 1)", return queryExists("SELECT 1 FROM sys_role WHERE id = :id AND deleted = 0 LIMIT 1",
"id", id); new MapSqlParameterSource("id", id));
} }
@Override @Override
@ -73,10 +70,10 @@ public class RoleRepositoryImpl extends JdbcRepositorySupport<Role, Long> implem
VALUES VALUES
(:id, :name, :identifier, :status, :remarks, :createTime, :createdBy) (:id, :name, :identifier, :status, :remarks, :createTime, :createdBy)
""", generateParamSource(id, entity)); """, generateParamSource(id, entity));
AssertResult.updateOneRow(i); AssertResult.update(i, 1);
this.roleMenuRefDAO.saveRoleMenuRefs(id, entity); this.roleMenuRefDAO.saveRoleMenuRefs(id, entity);
this.rolePermissionRefDAO.saveRolePermissionRefs(id, entity); this.rolePermissionRefDAO.saveRolePermissionRefs(id, entity);
return find(id).orElseThrow(DataNotExistException::new); return entity;
} }
@Override @Override
@ -92,14 +89,14 @@ public class RoleRepositoryImpl extends JdbcRepositorySupport<Role, Long> implem
"version" = "version" + 1 "version" = "version" + 1
WHERE id = :id AND deleted = 0 AND "version" = :version WHERE id = :id AND deleted = 0 AND "version" = :version
""", generateParamSource(entity)); """, generateParamSource(entity));
AssertResult.updateOneRow(i); AssertResult.update(i, 1);
Long id = entity.getId().orElseThrow(); Long id = entity.getId().orElseThrow();
this.roleMenuRefDAO.clearRoleMenuRefs(entity); this.roleMenuRefDAO.clearRoleMenuRefs(entity);
this.roleMenuRefDAO.saveRoleMenuRefs(id, entity); this.roleMenuRefDAO.saveRoleMenuRefs(id, entity);
this.rolePermissionRefDAO.clearRolePermissionRefs(entity); this.rolePermissionRefDAO.clearRolePermissionRefs(entity);
this.rolePermissionRefDAO.saveRolePermissionRefs(id, entity); this.rolePermissionRefDAO.saveRolePermissionRefs(id, entity);
return find(entity.getId().orElseThrow()).orElseThrow(DataNotExistException::new); return entity;
} }
@Override @Override
@ -109,8 +106,7 @@ public class RoleRepositoryImpl extends JdbcRepositorySupport<Role, Long> implem
FROM sys_role AS r FROM sys_role AS r
LEFT JOIN sys_account_role AS ar ON r.id = ar.role_id LEFT JOIN sys_account_role AS ar ON r.id = ar.role_id
WHERE ar.account_id = :accountId AND r.deleted = 0 WHERE ar.account_id = :accountId AND r.deleted = 0
""", """, new MapSqlParameterSource("accountId", accountId));
"accountId", accountId);
} }
@Override @Override

View File

@ -40,7 +40,7 @@
<commons-math3.version>3.6.1</commons-math3.version> <commons-math3.version>3.6.1</commons-math3.version>
<commons-pool2.version>2.11.1</commons-pool2.version> <commons-pool2.version>2.11.1</commons-pool2.version>
<tencentcloud-sdk.version>3.1.681</tencentcloud-sdk.version> <tencentcloud-sdk.version>3.1.681</tencentcloud-sdk.version>
<fastdfs.version>1.30-SNAPSHOT</fastdfs.version> <fastdfs.version>1.29-SNAPSHOT</fastdfs.version>
<okio.version>3.0.0</okio.version> <okio.version>3.0.0</okio.version>
<okhttp.version>4.10.0</okhttp.version> <okhttp.version>4.10.0</okhttp.version>
@ -197,10 +197,6 @@
<artifactId>jsr305</artifactId> <artifactId>jsr305</artifactId>
<version>3.0.2</version> <version>3.0.2</version>
</dependency> </dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
</dependencies> </dependencies>
<repositories> <repositories>