feat: 框架代码全面升级webflux,兼容原

This commit is contained in:
wangyu 2021-12-07 17:02:56 +08:00
parent 5ef117cfae
commit b83b7edaa3
61 changed files with 918 additions and 295 deletions

View File

@ -23,6 +23,11 @@
<artifactId>spring-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>

View File

@ -1,6 +1,6 @@
package com.flyfish.framework.annotations;
import com.flyfish.framework.repository.impl.DefaultRepositoryFactoryBean;
import com.flyfish.framework.repository.factory.DefaultRepositoryFactoryBean;
import com.flyfish.framework.repository.impl.DefaultRepositoryImpl;
import org.springframework.core.annotation.AliasFor;
import org.springframework.data.mongodb.config.EnableMongoAuditing;

View File

@ -0,0 +1,29 @@
package com.flyfish.framework.annotations;
import com.flyfish.framework.repository.factory.DefaultReactiveRepositoryFactoryBean;
import com.flyfish.framework.repository.impl.DefaultReactiveRepositoryImpl;
import org.springframework.core.annotation.AliasFor;
import org.springframework.data.mongodb.config.EnableReactiveMongoAuditing;
import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories;
import java.lang.annotation.*;
@EnableReactiveMongoRepositories(
repositoryFactoryBeanClass = DefaultReactiveRepositoryFactoryBean.class,
repositoryBaseClass = DefaultReactiveRepositoryImpl.class
)
@EnableReactiveMongoAuditing
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface EnableReactiveMongoRepo {
/**
* 扫描的基本路径
*
* @return 结果
*/
@AliasFor(annotation = EnableReactiveMongoRepositories.class)
String[] basePackages() default "com.flyfish.framework";
}

View File

@ -10,6 +10,6 @@ import org.springframework.data.repository.NoRepositoryBean;
* @param <T> 泛型
*/
@NoRepositoryBean
public interface DefaultReactiveRepository<T> extends ReactiveMongoRepository<T, String> {
public interface DefaultReactiveRepository<T> extends ReactiveMongoRepository<T, String>, ReactiveQueryModelExecutor<T> {
}

View File

@ -80,7 +80,7 @@ public interface QueryModelExecutor<T> {
* @param values 集合
* @return 结果
*/
List<T> findAllByValues(String key, List<Object> values);
List<T> findAllByValues(String key, List<?> values);
/**
* Checks whether the data store contains elements that match the given {@link Qo}.

View File

@ -65,7 +65,7 @@ public interface ReactiveQueryModelExecutor<T> {
* @param pageable may be {@link Pageable#unpaged()}, must not be {@literal null}.
* @return a {@link Page} of entities matching the given {@link Qo}.
*/
Page<T> findAll(Qo<T> query, Pageable pageable);
Mono<Page<T>> findAll(Qo<T> query, Pageable pageable);
/**
* Returns the number of instances matching the given {@link Qo}.
@ -73,7 +73,7 @@ public interface ReactiveQueryModelExecutor<T> {
* @param query the {@link Qo} to count instances for, must not be {@literal null}.
* @return the number of instances matching the {@link Qo}.
*/
long count(Qo<T> query);
Mono<Long> count(Qo<T> query);
/**
* 通过特定键的集合查询
@ -82,7 +82,7 @@ public interface ReactiveQueryModelExecutor<T> {
* @param values 集合
* @return 结果
*/
List<T> findAllByValues(String key, List<Object> values);
Flux<T> findAllByValues(String key, List<?> values);
/**
* Checks whether the data store contains elements that match the given {@link Qo}.
@ -90,5 +90,13 @@ public interface ReactiveQueryModelExecutor<T> {
* @param query the {@link Qo} to use for the existence check, must not be {@literal null}.
* @return {@literal true} if the data store contains elements that match the given {@link Qo}.
*/
boolean exists(Qo<T> query);
Mono<Boolean> exists(Qo<T> query);
/**
* 删除全部
*
* @param qo 查询实体
* @return 结果
*/
Mono<Void> deleteAll(Qo<T> qo);
}

View File

@ -0,0 +1,26 @@
package com.flyfish.framework.repository.factory;
import com.flyfish.framework.repository.impl.DefaultReactiveRepositoryImpl;
import org.springframework.data.mongodb.core.ReactiveMongoOperations;
import org.springframework.data.mongodb.repository.support.ReactiveMongoRepositoryFactory;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.lang.NonNull;
public class DefaultReactiveRepositoryFactory extends ReactiveMongoRepositoryFactory {
/**
* Creates a new {@link ReactiveMongoRepositoryFactory} with the given {@link ReactiveMongoOperations}.
*
* @param mongoOperations must not be {@literal null}.
*/
public DefaultReactiveRepositoryFactory(ReactiveMongoOperations mongoOperations) {
super(mongoOperations);
this.setRepositoryBaseClass(DefaultReactiveRepositoryImpl.class);
}
@Override
@NonNull
protected Class<?> getRepositoryBaseClass(@NonNull RepositoryMetadata metadata) {
return DefaultReactiveRepositoryImpl.class;
}
}

View File

@ -0,0 +1,26 @@
package com.flyfish.framework.repository.factory;
import org.springframework.data.mongodb.core.ReactiveMongoOperations;
import org.springframework.data.mongodb.repository.support.ReactiveMongoRepositoryFactoryBean;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
import org.springframework.lang.NonNull;
public class DefaultReactiveRepositoryFactoryBean<T extends Repository<S, String>, S>
extends ReactiveMongoRepositoryFactoryBean<T, S, String> {
/**
* Creates a new {@link ReactiveMongoRepositoryFactoryBean} for the given repository interface.
*
* @param repositoryInterface must not be {@literal null}.
*/
public DefaultReactiveRepositoryFactoryBean(Class<? extends T> repositoryInterface) {
super(repositoryInterface);
}
@Override
@NonNull
protected RepositoryFactorySupport getFactoryInstance(@NonNull ReactiveMongoOperations operations) {
return new DefaultReactiveRepositoryFactory(operations);
}
}

View File

@ -1,8 +1,10 @@
package com.flyfish.framework.repository.impl;
package com.flyfish.framework.repository.factory;
import com.flyfish.framework.repository.impl.DefaultRepositoryImpl;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.repository.support.MongoRepositoryFactory;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.lang.NonNull;
public class DefaultRepositoryFactory extends MongoRepositoryFactory {
@ -13,11 +15,12 @@ public class DefaultRepositoryFactory extends MongoRepositoryFactory {
*/
public DefaultRepositoryFactory(MongoOperations mongoOperations) {
super(mongoOperations);
this.setRepositoryBaseClass(DefaultRepositoryFactory.class);
this.setRepositoryBaseClass(DefaultRepositoryImpl.class);
}
@Override
protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
return DefaultRepositoryFactory.class;
@NonNull
protected Class<?> getRepositoryBaseClass(@NonNull RepositoryMetadata metadata) {
return DefaultRepositoryImpl.class;
}
}

View File

@ -1,9 +1,10 @@
package com.flyfish.framework.repository.impl;
package com.flyfish.framework.repository.factory;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.repository.support.MongoRepositoryFactoryBean;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
import org.springframework.lang.NonNull;
public class DefaultRepositoryFactoryBean<T extends Repository<S, java.lang.String>, S>
extends MongoRepositoryFactoryBean<T, S, String> {
@ -18,7 +19,8 @@ public class DefaultRepositoryFactoryBean<T extends Repository<S, java.lang.Stri
}
@Override
protected RepositoryFactorySupport getFactoryInstance(MongoOperations operations) {
@NonNull
protected RepositoryFactorySupport getFactoryInstance(@NonNull MongoOperations operations) {
return new DefaultRepositoryFactory(operations);
}
}

View File

@ -1,4 +1,180 @@
package com.flyfish.framework.repository.impl;
public class DefaultReactiveRepositoryImpl {
import com.flyfish.framework.domain.base.Domain;
import com.flyfish.framework.domain.base.Qo;
import com.flyfish.framework.repository.DefaultReactiveRepository;
import lombok.NonNull;
import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.ReactiveMongoOperations;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
import org.springframework.data.mongodb.repository.support.SimpleReactiveMongoRepository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.Optional;
/**
* 默认的异步仓库实现
*
* @param <T> 泛型
*/
public class DefaultReactiveRepositoryImpl<T extends Domain> extends SimpleReactiveMongoRepository<T, String>
implements DefaultReactiveRepository<T> {
private final MongoEntityInformation<T, String> entityInformation;
private final ReactiveMongoOperations mongoOperations;
public DefaultReactiveRepositoryImpl(@NonNull MongoEntityInformation<T, String> entityInformation,
@NonNull ReactiveMongoOperations mongoOperations) {
super(entityInformation, mongoOperations);
this.mongoOperations = mongoOperations;
this.entityInformation = entityInformation;
}
/**
* 通过名称查找一个
*
* @param name 名称
* @return 结果
*/
@Override
public Mono<T> findByName(String name) {
if (StringUtils.isNotBlank(name)) {
return mongoOperations.findOne(Query.query(Criteria.where("name").is(name)),
entityInformation.getJavaType(), entityInformation.getCollectionName());
}
return Mono.empty();
}
/**
* Returns a single entity matching the given {@link Qo} or {@link Optional#empty()} if none was found.
*
* @param query must not be {@literal null}.
* @return a single entity matching the given {@link Qo} or {@link Optional#empty()} if none was found.
* @throws IncorrectResultSizeDataAccessException if the Qo yields more than one
* result.
*/
@Override
public Mono<T> findOne(Qo<T> query) {
return Mono.justOrEmpty(QueryBuildUtils.getQuery(query))
.flatMap(querying -> mongoOperations.findOne(querying, entityInformation.getJavaType(),
entityInformation.getCollectionName()));
}
/**
* Returns all entities matching the given {@link Qo}. In case no match could be found an empty
* {@link Iterable} is returned.
*
* @param query must not be {@literal null}.
* @return all entities matching the given {@link Qo}.
*/
@Override
public Flux<T> findAll(Qo<T> query) {
return Mono.justOrEmpty(QueryBuildUtils.getQuery(query))
.flatMapMany(querying -> mongoOperations.find(querying,
entityInformation.getJavaType(),
entityInformation.getCollectionName()));
}
/**
* Returns all entities matching the given {@link Qo} applying the given {@link Sort}. In case no match could
* be found an empty {@link Iterable} is returned.
*
* @param query must not be {@literal null}.
* @param sort the {@link Sort} specification to sort the results by, may be {@link Sort#empty()}, must not be
* {@literal null}.
* @return all entities matching the given {@link Qo}.
* @since 1.10
*/
@Override
public Flux<T> findAll(Qo<T> query, Sort sort) {
return Mono.justOrEmpty(QueryBuildUtils.getQuery(query))
.flatMapMany(querying -> mongoOperations.find(querying.with(sort),
entityInformation.getJavaType(),
entityInformation.getCollectionName()));
}
/**
* Returns a {@link Page} of entities matching the given {@link Qo}. In case no match could be found, an empty
* {@link Page} is returned.
*
* @param query must not be {@literal null}.
* @param pageable may be {@link Pageable#unpaged()}, must not be {@literal null}.
* @return a {@link Page} of entities matching the given {@link Qo}.
*/
@Override
public Mono<Page<T>> findAll(Qo<T> query, Pageable pageable) {
return Mono.justOrEmpty(QueryBuildUtils.getQuery(query))
.flatMap(querying -> mongoOperations.find(querying.with(pageable),
entityInformation.getJavaType(), entityInformation.getCollectionName())
.collectList()
.flatMap(list -> ReactivePageableExecutionUtils.getPage(list, pageable, this.count(query))))
.defaultIfEmpty(Page.empty());
}
/**
* Returns the number of instances matching the given {@link Qo}.
*
* @param query the {@link Qo} to count instances for, must not be {@literal null}.
* @return the number of instances matching the {@link Qo}.
*/
@Override
public Mono<Long> count(Qo<T> query) {
return Mono.justOrEmpty(QueryBuildUtils.getQuery(query))
.flatMap(querying -> this.mongoOperations.count(querying, entityInformation.getJavaType(),
entityInformation.getCollectionName()))
.defaultIfEmpty(0L);
}
/**
* 通过特定键的集合查询
*
* @param key
* @param values 集合
* @return 结果
*/
@Override
public Flux<T> findAllByValues(String key, List<?> values) {
Criteria criteria = Criteria.where(key).in(values);
Query query = new Query(criteria);
return mongoOperations.find(query,
entityInformation.getJavaType(),
entityInformation.getCollectionName());
}
/**
* Checks whether the data store contains elements that match the given {@link Qo}.
*
* @param query the {@link Qo} to use for the existence check, must not be {@literal null}.
* @return {@literal true} if the data store contains elements that match the given {@link Qo}.
*/
@Override
public Mono<Boolean> exists(Qo<T> query) {
return Mono.justOrEmpty(QueryBuildUtils.getQuery(query))
.flatMap(querying -> mongoOperations.exists(querying,
entityInformation.getJavaType(), entityInformation.getCollectionName()))
.defaultIfEmpty(false);
}
/**
* 删除全部
*
* @param qo 查询实体
* @return 结果
*/
@Override
public Mono<Void> deleteAll(Qo<T> qo) {
return Mono.justOrEmpty(QueryBuildUtils.getQuery(qo))
.flatMap(querying -> mongoOperations.remove(querying, entityInformation.getJavaType(),
entityInformation.getCollectionName()))
.then(Mono.empty());
}
}

View File

@ -3,10 +3,8 @@ package com.flyfish.framework.repository.impl;
import com.flyfish.framework.domain.base.Domain;
import com.flyfish.framework.domain.base.Qo;
import com.flyfish.framework.repository.DefaultRepository;
import com.flyfish.framework.utils.CopyUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
@ -16,7 +14,7 @@ import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
import org.springframework.data.mongodb.repository.support.SimpleMongoRepository;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.data.support.PageableExecutionUtils;
import java.util.Collections;
import java.util.List;
@ -71,14 +69,10 @@ public class DefaultRepositoryImpl<T extends Domain> extends SimpleMongoReposito
*/
@Override
public Optional<T> findOne(Qo<T> query) {
Query querying = getQuery(query);
if (null != querying) {
return Optional
.ofNullable(mongoOperations.findOne(querying,
entityInformation.getJavaType(),
entityInformation.getCollectionName()));
}
return Optional.empty();
return QueryBuildUtils.getQuery(query)
.map(querying -> mongoOperations.findOne(querying,
entityInformation.getJavaType(),
entityInformation.getCollectionName()));
}
/**
@ -90,13 +84,11 @@ public class DefaultRepositoryImpl<T extends Domain> extends SimpleMongoReposito
*/
@Override
public Iterable<T> findAll(Qo<T> query) {
Query querying = getQuery(query);
if (null != querying) {
return mongoOperations.find(querying,
entityInformation.getJavaType(),
entityInformation.getCollectionName());
}
return Collections.emptyList();
return QueryBuildUtils.getQuery(query)
.map(querying -> mongoOperations.find(querying,
entityInformation.getJavaType(),
entityInformation.getCollectionName()))
.orElse(Collections.emptyList());
}
/**
@ -111,7 +103,11 @@ public class DefaultRepositoryImpl<T extends Domain> extends SimpleMongoReposito
*/
@Override
public Iterable<T> findAll(Qo<T> query, Sort sort) {
return Collections.emptyList();
return QueryBuildUtils.getQuery(query)
.map(querying -> mongoOperations.find(querying.with(sort),
entityInformation.getJavaType(),
entityInformation.getCollectionName()))
.orElse(Collections.emptyList());
}
/**
@ -124,14 +120,11 @@ public class DefaultRepositoryImpl<T extends Domain> extends SimpleMongoReposito
*/
@Override
public Page<T> findAll(Qo<T> query, Pageable pageable) {
Query querying = getQuery(query);
if (null != querying) {
querying.with(pageable);
List<T> queryResult = mongoOperations.find(querying,
return QueryBuildUtils.getQuery(query).map(querying -> {
List<T> queryResult = mongoOperations.find(querying.with(pageable),
entityInformation.getJavaType(), entityInformation.getCollectionName());
return PageableExecutionUtils.getPage(queryResult, pageable, () -> count(query));
}
return Page.empty();
}).orElse(Page.empty());
}
/**
@ -142,8 +135,9 @@ public class DefaultRepositoryImpl<T extends Domain> extends SimpleMongoReposito
*/
@Override
public long count(Qo<T> query) {
Query q = getQuery(query);
return this.mongoOperations.count(q, entityInformation.getJavaType(), entityInformation.getCollectionName());
return QueryBuildUtils.getQuery(query)
.map(q -> this.mongoOperations.count(q, entityInformation.getJavaType(), entityInformation.getCollectionName()))
.orElse(0L);
}
/**
@ -154,7 +148,7 @@ public class DefaultRepositoryImpl<T extends Domain> extends SimpleMongoReposito
* @return 结果
*/
@Override
public List<T> findAllByValues(String key, List<Object> values) {
public List<T> findAllByValues(String key, List<?> values) {
Criteria criteria = Criteria.where(key).in(values);
Query query = new Query(criteria);
return mongoOperations.find(query,
@ -170,38 +164,9 @@ public class DefaultRepositoryImpl<T extends Domain> extends SimpleMongoReposito
*/
@Override
public boolean exists(Qo<T> query) {
return false;
}
/**
* 从查询实体抽取内部查询信息
*
* @param qo 查询实体
* @return 结果
*/
private Query getQuery(Qo<T> qo) {
Criteria criteria = null;
if (null != qo.getCriteria()) {
criteria = qo.getCriteria();
} else if (null != qo.getExample()) {
criteria = new Criteria().alike(qo.getExample());
} else {
Class<T> type = qo.pojoType();
if (null != type && !Object.class.equals(type)) {
try {
T pojo = CopyUtils.copyQueryProps(qo, qo.pojoType().newInstance());
criteria = new Criteria().alike(Example.of(pojo));
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
if (criteria != null) {
// 针对删除状态全局筛选
return new Query(Criteria.where("delete").ne(true).andOperator(criteria))
.with(qo.sorts());
}
return null;
return QueryBuildUtils.getQuery(query).map(querying -> mongoOperations.exists(querying,
entityInformation.getJavaType(), entityInformation.getCollectionName()))
.orElse(false);
}
}

View File

@ -0,0 +1,43 @@
package com.flyfish.framework.repository.impl;
import com.flyfish.framework.domain.base.Qo;
import com.flyfish.framework.utils.CopyUtils;
import org.springframework.data.domain.Example;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import java.util.Optional;
abstract class QueryBuildUtils {
/**
* 从查询实体抽取内部查询信息
*
* @param qo 查询实体
* @return 结果
*/
static <T> Optional<Query> getQuery(Qo<T> qo) {
Criteria criteria = null;
if (null != qo.getCriteria()) {
criteria = qo.getCriteria();
} else if (null != qo.getExample()) {
criteria = new Criteria().alike(qo.getExample());
} else {
Class<T> type = qo.pojoType();
if (null != type && !Object.class.equals(type)) {
try {
T pojo = CopyUtils.copyQueryProps(qo, qo.pojoType().newInstance());
criteria = new Criteria().alike(Example.of(pojo));
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
if (criteria != null) {
// 针对删除状态全局筛选
return Optional.of(new Query(Criteria.where("delete").ne(true).andOperator(criteria))
.with(qo.sorts()));
}
return Optional.empty();
}
}

View File

@ -0,0 +1,69 @@
/*
* Copyright 2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.flyfish.framework.repository.impl;
import reactor.core.publisher.Mono;
import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.util.Assert;
/**
* Support for query execution using {@link Pageable}. Using {@link ReactivePageableExecutionUtils} assumes that data
* queries are cheaper than {@code COUNT} queries and so some cases can take advantage of optimizations.
*
* @author Mark Paluch
* @since 3.3
*/
abstract class ReactivePageableExecutionUtils {
private ReactivePageableExecutionUtils() {}
/**
* Constructs a {@link Page} based on the given {@code content}, {@link Pageable} and {@link Mono} applying
* optimizations. The construction of {@link Page} omits a count query if the total can be determined based on the
* result size and {@link Pageable}.
*
* @param content must not be {@literal null}.
* @param pageable must not be {@literal null}.
* @param totalSupplier must not be {@literal null}.
* @return the {@link Page}.
*/
public static <T> Mono<Page<T>> getPage(List<T> content, Pageable pageable, Mono<Long> totalSupplier) {
Assert.notNull(content, "Content must not be null!");
Assert.notNull(pageable, "Pageable must not be null!");
Assert.notNull(totalSupplier, "TotalSupplier must not be null!");
if (pageable.isUnpaged() || pageable.getOffset() == 0) {
if (pageable.isUnpaged() || pageable.getPageSize() > content.size()) {
return Mono.just(new PageImpl<>(content, pageable, content.size()));
}
return totalSupplier.map(total -> new PageImpl<>(content, pageable, total));
}
if (!content.isEmpty() && pageable.getPageSize() > content.size()) {
return Mono.just(new PageImpl<>(content, pageable, pageable.getOffset() + content.size()));
}
return totalSupplier.map(total -> new PageImpl<>(content, pageable, total));
}
}

View File

@ -11,7 +11,7 @@ import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.reflections.Reflections;
import org.reflections.scanners.FieldAnnotationsScanner;
import org.reflections.scanners.Scanners;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import org.springframework.beans.factory.InitializingBean;
@ -45,7 +45,7 @@ public class DictionaryProcessor implements InitializingBean {
.collect(Collectors.toList());
Reflections reflections = new Reflections(new ConfigurationBuilder()
.setUrls(urls)
.setScanners(new FieldAnnotationsScanner()));
.setScanners(Scanners.FieldsAnnotated));
Set<Field> fields = reflections.getFieldsAnnotatedWith(DictValue.class);
if (CollectionUtils.isNotEmpty(fields)) {
// 查找是否存在不存在插入存在无视

View File

@ -1,10 +1,10 @@
package com.flyfish.framework.dict.controller;
import com.flyfish.framework.beans.annotations.RestMapping;
import com.flyfish.framework.controller.BaseController;
import com.flyfish.framework.controller.ReactiveBaseController;
import com.flyfish.framework.dict.domain.AutoComplete;
import com.flyfish.framework.domain.base.NameLikeQo;
@RestMapping("auto-completes")
public class AutoCompleteController extends BaseController<AutoComplete, NameLikeQo<AutoComplete>> {
public class AutoCompleteController extends ReactiveBaseController<AutoComplete, NameLikeQo<AutoComplete>> {
}

View File

@ -2,7 +2,7 @@ package com.flyfish.framework.dict.controller;
import com.flyfish.framework.beans.annotations.RestMapping;
import com.flyfish.framework.controller.BaseController;
import com.flyfish.framework.controller.ReactiveBaseController;
import com.flyfish.framework.dict.domain.Dictionary;
import com.flyfish.framework.dict.domain.DictionaryQo;
@ -12,6 +12,6 @@ import com.flyfish.framework.dict.domain.DictionaryQo;
* @author wangyu
*/
@RestMapping("dictionaries")
public class DictionaryController extends BaseController<Dictionary, DictionaryQo> {
public class DictionaryController extends ReactiveBaseController<Dictionary, DictionaryQo> {
}

View File

@ -1,7 +1,7 @@
package com.flyfish.framework.dict.repository;
import com.flyfish.framework.dict.domain.AutoComplete;
import com.flyfish.framework.repository.DefaultRepository;
import com.flyfish.framework.repository.DefaultReactiveRepository;
public interface AutoCompleteRepository extends DefaultRepository<AutoComplete> {
public interface AutoCompleteRepository extends DefaultReactiveRepository<AutoComplete> {
}

View File

@ -1,7 +1,7 @@
package com.flyfish.framework.dict.repository;
import com.flyfish.framework.dict.domain.Dictionary;
import com.flyfish.framework.repository.DefaultRepository;
import com.flyfish.framework.repository.DefaultReactiveRepository;
import java.util.Optional;
@ -10,7 +10,7 @@ import java.util.Optional;
*
* @author wangyu
*/
public interface DictionaryRepository extends DefaultRepository<Dictionary> {
public interface DictionaryRepository extends DefaultReactiveRepository<Dictionary> {
/**
* 通过code查找

View File

@ -1,9 +1,9 @@
package com.flyfish.framework.dict.service;
import com.flyfish.framework.dict.domain.AutoComplete;
import com.flyfish.framework.service.impl.BaseServiceImpl;
import com.flyfish.framework.service.impl.BaseReactiveServiceImpl;
import org.springframework.stereotype.Service;
@Service
public class AutoCompleteService extends BaseServiceImpl<AutoComplete> {
public class AutoCompleteService extends BaseReactiveServiceImpl<AutoComplete> {
}

View File

@ -3,7 +3,8 @@ package com.flyfish.framework.dict.service;
import com.flyfish.framework.dict.domain.Dictionary;
import com.flyfish.framework.dict.repository.DictionaryRepository;
import com.flyfish.framework.service.impl.BaseServiceImpl;
import com.flyfish.framework.service.impl.BaseReactiveServiceImpl;
import com.flyfish.framework.service.impl.BaseReactiveServiceImpl;
import org.springframework.stereotype.Service;
import java.util.Optional;
@ -14,7 +15,7 @@ import java.util.Optional;
* @author wangyu
*/
@Service
public class DictionaryService extends BaseServiceImpl<Dictionary> {
public class DictionaryService extends BaseReactiveServiceImpl<Dictionary> {
/**
* 通过code查询

View File

@ -1,7 +1,7 @@
package com.flyfish.framework.file.controller;
import com.flyfish.framework.controller.BaseController;
import com.flyfish.framework.controller.ReactiveBaseController;
import com.flyfish.framework.file.domain.Attachment;
import com.flyfish.framework.file.domain.AttachmentQo;
import org.springframework.web.bind.annotation.RequestMapping;
@ -9,6 +9,6 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/attachments")
public class AttachmentController extends BaseController<Attachment, AttachmentQo> {
public class AttachmentController extends ReactiveBaseController<Attachment, AttachmentQo> {
}

View File

@ -57,7 +57,7 @@ public class AttachmentUploadController {
@GetMapping("/downloads/{id}")
public Mono<Void> downloadAttachment(@PathVariable String id, ServerHttpResponse response) {
return Mono.justOrEmpty(attachmentService.getById(id))
return attachmentService.getById(id)
.flatMap(attachment -> DownloadUtils.download(configuration.getLocalPath() +
attachment.getPath(), response));
}

View File

@ -2,7 +2,7 @@ package com.flyfish.framework.file.repository;
import com.flyfish.framework.file.domain.Attachment;
import com.flyfish.framework.repository.DefaultRepository;
import com.flyfish.framework.repository.DefaultReactiveRepository;
public interface AttachmentRepository extends DefaultRepository<Attachment> {
public interface AttachmentRepository extends DefaultReactiveRepository<Attachment> {
}

View File

@ -3,7 +3,7 @@ package com.flyfish.framework.file.service;
import com.flyfish.framework.file.domain.Attachment;
import com.flyfish.framework.file.utils.FileSizeUtils;
import com.flyfish.framework.service.impl.BaseServiceImpl;
import com.flyfish.framework.service.impl.BaseReactiveServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.codec.multipart.FilePart;
import org.springframework.stereotype.Service;
@ -12,7 +12,7 @@ import reactor.core.publisher.Mono;
import javax.annotation.Resource;
@Service
public class AttachmentService extends BaseServiceImpl<Attachment> {
public class AttachmentService extends BaseReactiveServiceImpl<Attachment> {
private static String URL = "/api/attachment/";
@Resource
@ -36,7 +36,7 @@ public class AttachmentService extends BaseServiceImpl<Attachment> {
*/
public Mono<Attachment> upload(FilePart part, String name) {
return fileService.saveLocal(part)
.map(path -> {
.flatMap(path -> {
Attachment attachment = Attachment.builder()
.size(FileSizeUtils.size(part.headers().getContentLength()))
.path(path)

View File

@ -1,6 +1,6 @@
package com.flyfish.framework.form.controller;
import com.flyfish.framework.controller.BaseController;
import com.flyfish.framework.controller.ReactiveBaseController;
import com.flyfish.framework.domain.base.NameLikeQo;
import com.flyfish.framework.form.domain.OnlineForm;
import org.springframework.web.bind.annotation.RequestMapping;
@ -13,5 +13,5 @@ import org.springframework.web.bind.annotation.RestController;
*/
@RestController
@RequestMapping("online-forms")
public class OnlineFormController extends BaseController<OnlineForm, NameLikeQo<OnlineForm>> {
public class OnlineFormController extends ReactiveBaseController<OnlineForm, NameLikeQo<OnlineForm>> {
}

View File

@ -1,10 +1,10 @@
package com.flyfish.framework.form.repository;
import com.flyfish.framework.form.domain.OnlineForm;
import com.flyfish.framework.repository.DefaultRepository;
import com.flyfish.framework.repository.DefaultReactiveRepository;
/**
* 在线表单
*/
public interface OnlineFormRepository extends DefaultRepository<OnlineForm> {
public interface OnlineFormRepository extends DefaultReactiveRepository<OnlineForm> {
}

View File

@ -1,7 +1,7 @@
package com.flyfish.framework.form.service;
import com.flyfish.framework.form.domain.OnlineForm;
import com.flyfish.framework.service.impl.BaseServiceImpl;
import com.flyfish.framework.service.impl.BaseReactiveServiceImpl;
import org.springframework.stereotype.Service;
/**
@ -9,5 +9,5 @@ import org.springframework.stereotype.Service;
* @author wangyu
*/
@Service
public class OnlineFormService extends BaseServiceImpl<OnlineForm> {
public class OnlineFormService extends BaseReactiveServiceImpl<OnlineForm> {
}

View File

@ -1,7 +1,7 @@
package com.flyfish.framework.logging.controller;
import com.flyfish.framework.beans.annotations.RestMapping;
import com.flyfish.framework.controller.BaseController;
import com.flyfish.framework.controller.ReactiveBaseController;
import com.flyfish.framework.logging.domain.Log;
import com.flyfish.framework.logging.domain.LogQo;
@ -11,6 +11,6 @@ import com.flyfish.framework.logging.domain.LogQo;
* @author wangyu
*/
@RestMapping("logs")
public class LogController extends BaseController<Log, LogQo> {
public class LogController extends ReactiveBaseController<Log, LogQo> {
}

View File

@ -1,11 +1,11 @@
package com.flyfish.framework.logging.repository;
import com.flyfish.framework.logging.domain.Log;
import com.flyfish.framework.repository.DefaultRepository;
import com.flyfish.framework.repository.DefaultReactiveRepository;
/**
* 日志仓库
* @author wangyu
*/
public interface LogRepository extends DefaultRepository<Log> {
public interface LogRepository extends DefaultReactiveRepository<Log> {
}

View File

@ -1,7 +1,7 @@
package com.flyfish.framework.logging.service;
import com.flyfish.framework.logging.domain.Log;
import com.flyfish.framework.service.impl.BaseServiceImpl;
import com.flyfish.framework.service.impl.BaseReactiveServiceImpl;
import org.springframework.stereotype.Service;
/**
@ -9,7 +9,7 @@ import org.springframework.stereotype.Service;
* @author wangyu
*/
@Service
public class LogService extends BaseServiceImpl<Log> {
public class LogService extends BaseReactiveServiceImpl<Log> {
}

View File

@ -6,13 +6,12 @@ import com.flyfish.framework.logging.config.LoggingTextRegistry;
import com.flyfish.framework.logging.domain.Log;
import com.flyfish.framework.logging.domain.LogType;
import com.flyfish.framework.service.AuthenticationLogger;
import com.flyfish.framework.service.UserFindService;
import com.flyfish.framework.utils.AuthenticationMessages;
import com.flyfish.framework.utils.UserUtils;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;
import reactor.core.publisher.Mono;
import javax.annotation.Resource;
import java.util.Date;
@ -29,8 +28,6 @@ public class SimpleAuthenticationLogger implements AuthenticationLogger {
@Resource
private LogService logService;
@Resource
private UserFindService userService;
@Resource
private LoggingTextRegistry registry;
/**
@ -39,19 +36,19 @@ public class SimpleAuthenticationLogger implements AuthenticationLogger {
* @param user 用户
*/
@Override
public void success(UserDetails user) {
saveSuccess("LOGIN", "登录成功", user);
public Mono<Void> success(UserDetails user) {
return saveSuccess("LOGIN", "登录成功", user);
}
/**
* 记录失败
*
* @param form 表单
* @param user 表单用户
* @param exception 错误异常
*/
@Override
public void failure(MultiValueMap<String, String> form, AuthenticationException exception) {
saveError("LOGIN", "登录失败", form.getFirst("username"), AuthenticationMessages.message(exception));
public Mono<Void> failure(User user, AuthenticationException exception) {
return saveError("LOGIN", "登录失败", user, AuthenticationMessages.message(exception));
}
/**
@ -60,8 +57,8 @@ public class SimpleAuthenticationLogger implements AuthenticationLogger {
* @param user 用户
*/
@Override
public void logout(UserDetails user) {
saveSuccess("LOGOUT", "退出成功", user);
public Mono<Void> logout(UserDetails user) {
return saveSuccess("LOGOUT", "退出成功", user);
}
/**
@ -71,7 +68,7 @@ public class SimpleAuthenticationLogger implements AuthenticationLogger {
* @param message 信息
* @param user 用户
*/
private void saveSuccess(String business, String message, UserDetails user) {
private Mono<Void> saveSuccess(String business, String message, UserDetails user) {
User raw = UserUtils.toUser(user);
Log log = new Log();
log.setType(LogType.AUTHENTICATION);
@ -85,7 +82,7 @@ public class SimpleAuthenticationLogger implements AuthenticationLogger {
log.setPeriod(0L);
log.setStartTime(new Date());
// 写入日志
logService.create(log);
return logService.create(log).then();
}
/**
@ -93,24 +90,23 @@ public class SimpleAuthenticationLogger implements AuthenticationLogger {
*
* @param business 业务
* @param message 消息
* @param username 用户名
* @param error 错误
*/
private void saveError(String business, String message, String username, String error) {
private Mono<Void> saveError(String business, String message, User user, String error) {
Log log = new Log();
log.setType(LogType.AUTHENTICATION);
log.setSignature(business);
log.setSuccess(false);
log.setBody("某人尝试使用用户名'" + username + "',密码:******,进行登录");
log.setBody("某人尝试使用用户名'" + user.getUsername() + "',密码:******,进行登录");
log.setModule("登录模块");
log.setBusiness(registry.text(business));
log.setError(error);
log.setResponse(message);
log.setOperator(userService.findByUsername(username).map(Domain::getName).orElse("未知"));
log.setOperator(user.getName());
log.setPeriod(0L);
log.setStartTime(new Date());
// 写入日志
logService.create(log);
return logService.create(log).then();
}
}

View File

@ -16,7 +16,7 @@ import java.lang.annotation.*;
@Target({ElementType.TYPE})
@Documented
@Import(WebSecurityConfig.class)
@EnableReactiveMongoRepositories(basePackages = "com.flyfish.framework")
@EnableReactiveMongoRepo
@EnableReactiveRedis
public @interface EnableAutoSecurity {
}

View File

@ -40,8 +40,7 @@ public class AuthenticationAuditorImpl extends ResultDataTransformer implements
updating.setId(details.getId());
updating.setErrorCount(0);
updating.setLastTime(new Date());
return reactiveUserService.updateSelectiveById(updating)
.then(Mono.fromRunnable(() -> authenticationLogger.success(user)));
return reactiveUserService.updateSelectiveById(updating).then(authenticationLogger.success(user));
}
/**
@ -56,27 +55,40 @@ public class AuthenticationAuditorImpl extends ResultDataTransformer implements
return webFilterExchange.getExchange()
.getFormData()
.flatMap(data -> {
String username = data.getFirst("username");
Mono<User> userMono = reactiveUserService.findByUsername(username).defaultIfEmpty(emptyUser(username));
// 当且仅当为凭据错误尝试
if (exception instanceof BadCredentialsException) {
return reactiveUserService.findByUsername(data.getFirst("username"))
.flatMap(user -> {
User updating = new User();
updating.setId(user.getId());
updating.setErrorCount(user.getErrorCount() + 1);
if (updating.getErrorCount() >= 5) {
updating.setStatus(UserStatus.LOCKED);
}
return reactiveUserService.updateSelectiveById(updating);
})
.map(user -> data);
userMono = userMono.flatMap(user -> {
User updating = new User();
updating.setId(user.getId());
updating.setErrorCount(user.getErrorCount() + 1);
if (updating.getErrorCount() >= 5) {
updating.setStatus(UserStatus.LOCKED);
}
return reactiveUserService.updateSelectiveById(updating);
});
}
return Mono.just(data);
})
.flatMap(data -> Mono.fromRunnable(() -> authenticationLogger.failure(data, exception)));
return userMono.flatMap(user -> authenticationLogger.failure(user, exception));
});
}
@Override
public Mono<Void> logout(UserDetails userDetails) {
return Mono.fromRunnable(() -> authenticationLogger.logout(userDetails));
return authenticationLogger.logout(userDetails);
}
/**
* 构造空用户
*
* @param username 用户名
* @return 结果
*/
private User emptyUser(String username) {
User user = new User();
user.setUsername(username);
user.setName("未知");
return user;
}
}

View File

@ -36,7 +36,7 @@ import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.authentication.HttpStatusServerEntryPoint;
import org.springframework.security.web.server.context.ServerSecurityContextRepository;
import org.springframework.security.web.server.context.WebSessionServerSecurityContextRepository;
import org.springframework.util.MultiValueMap;
import reactor.core.publisher.Mono;
import java.util.stream.Stream;
@ -74,18 +74,18 @@ public class WebSecurityConfig {
public AuthenticationLogger authenticationLogger() {
return new AuthenticationLogger() {
@Override
public void success(UserDetails user) {
public Mono<Void> success(UserDetails user) {
return Mono.empty();
}
@Override
public void failure(MultiValueMap<String, String> form, AuthenticationException exception) {
public Mono<Void> failure(User user, AuthenticationException exception) {
return Mono.empty();
}
@Override
public void logout(UserDetails user) {
public Mono<Void> logout(UserDetails user) {
return Mono.empty();
}
};
}

View File

@ -0,0 +1,33 @@
package com.flyfish.framework.config.audit;
import com.flyfish.framework.domain.base.Domain;
import com.flyfish.framework.utils.UserUtils;
import org.springframework.data.domain.ReactiveAuditorAware;
import org.springframework.lang.NonNull;
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
/**
* 用户上下文审查工具
*
* @author wangyu
*/
@Component
public class ReactiveUserAuditor implements ReactiveAuditorAware<String> {
/**
* 在异步上下文中获取结果
*
* @return 结果
*/
@Override
@NonNull
public Mono<String> getCurrentAuditor() {
return ReactiveSecurityContextHolder.getContext()
.map(UserUtils::extractUser)
.map(Domain::getName)
.defaultIfEmpty("匿名用户");
}
}

View File

@ -1,4 +1,4 @@
package com.flyfish.framework.auditor;
package com.flyfish.framework.config.audit;
import com.flyfish.framework.context.UserContext;
import com.flyfish.framework.domain.base.Domain;

View File

@ -12,6 +12,6 @@ import org.springframework.web.bind.annotation.RestController;
*/
@RestController
@RequestMapping("/roles")
public class RoleController extends BaseController<Role, RoleQo> {
public class RoleController extends ReactiveBaseController<Role, RoleQo> {
}

View File

@ -10,7 +10,6 @@ import com.flyfish.framework.domain.po.Role;
import com.flyfish.framework.domain.po.User;
import com.flyfish.framework.enums.UserStatus;
import com.flyfish.framework.service.ReactiveUserService;
import com.flyfish.framework.service.UserService;
import com.flyfish.framework.utils.Assert;
import com.flyfish.framework.utils.StrengthUtils;
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
@ -24,7 +23,7 @@ import java.util.Optional;
@RestController
@RequestMapping("/users")
public class UserController extends BaseController<User, UserQo> {
public class UserController extends ReactiveBaseController<User, UserQo> {
@Resource
private PasswordEncoder passwordEncoder;
@ -38,7 +37,7 @@ public class UserController extends BaseController<User, UserQo> {
*/
@PutMapping("{id}/passwords")
@Operation("重置密码")
public Result<Void> resetPassword(@PathVariable String id, @RequestBody User body, @CurrentUser User user) {
public Mono<Result<Void>> resetPassword(@PathVariable String id, @RequestBody User body, @CurrentUser User user) {
Assert.hasText(body.getPassword(), "重置密码必需携带密码!");
Assert.isTrue(Optional.ofNullable(user.getRoles()).map(roles -> roles.stream().anyMatch(Role::getAdmin))
.orElse(false), "您没有管理员权限,无法重置密码!");
@ -48,8 +47,7 @@ public class UserController extends BaseController<User, UserQo> {
updating.setStatus(UserStatus.NORMAL);
updating.setErrorCount(0);
updating.setPassword(passwordEncoder.encode(body.getPassword()));
service.updateSelectiveById(updating);
return Result.ok();
return reactiveService.updateSelectiveById(updating).thenReturn(Result.ok());
}
/**
@ -61,7 +59,7 @@ public class UserController extends BaseController<User, UserQo> {
*/
@PutMapping("/passwords")
@Operation("修改密码")
public Result<Void> changePassword(@Valid @RequestBody UserPasswordDto passwordDto, @CurrentUser User user) {
public Mono<Result<Void>> changePassword(@Valid @RequestBody UserPasswordDto passwordDto, @CurrentUser User user) {
// 检查原密码
Assert.isTrue(passwordEncoder.matches(passwordDto.getOldPassword(), user.getPassword()), "原密码不正确!");
Assert.isTrue(!passwordEncoder.matches(passwordDto.getPassword(), user.getPassword()), "新密码和旧密码一致,输入个新的吧!");
@ -70,8 +68,7 @@ public class UserController extends BaseController<User, UserQo> {
User updating = new User();
updating.setId(user.getId());
updating.setPassword(passwordEncoder.encode(passwordDto.getPassword()));
service.updateSelectiveById(updating);
return Result.ok();
return reactiveService.updateSelectiveById(updating).thenReturn(Result.ok());
}
/**
@ -81,12 +78,17 @@ public class UserController extends BaseController<User, UserQo> {
*/
@GetMapping("/current")
public Mono<Result<IUser>> getCurrentUser() {
UserService userService = getService();
return ReactiveSecurityContextHolder.getContext()
.map(context -> (IUser) context.getAuthentication().getPrincipal())
.map(Result::ok);
}
/**
* 更新用户状态主要更新部门
*
* @param authorize 鉴权
* @return 结果
*/
@PatchMapping("/status")
public Mono<Result<User>> updateStatus(String authorize) {
ReactiveUserService reactiveService = (ReactiveUserService) this.reactiveService;

View File

@ -7,5 +7,5 @@ import com.flyfish.framework.domain.po.Department;
*
* @author wybab
*/
public interface DepartmentRepository extends DefaultRepository<Department> {
public interface DepartmentRepository extends DefaultReactiveRepository<Department> {
}

View File

@ -8,5 +8,5 @@ import com.flyfish.framework.domain.po.Permission;
*
* @author wybab
*/
public interface PermissionRepository extends DefaultRepository<Permission> {
public interface PermissionRepository extends DefaultReactiveRepository<Permission> {
}

View File

@ -7,5 +7,5 @@ import com.flyfish.framework.domain.po.Role;
*
* @author wybab
*/
public interface RoleRepository extends DefaultRepository<Role> {
public interface RoleRepository extends DefaultReactiveRepository<Role> {
}

View File

@ -1,7 +1,7 @@
package com.flyfish.framework.service;
import com.flyfish.framework.domain.po.Department;
import com.flyfish.framework.service.impl.BaseServiceImpl;
import com.flyfish.framework.service.impl.BaseReactiveServiceImpl;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
@ -17,7 +17,7 @@ import java.util.stream.Collectors;
* @author wangyu
*/
@Service
public class DepartmentService extends BaseServiceImpl<Department> {
public class DepartmentService extends BaseReactiveServiceImpl<Department> {
@Resource
private MongoOperations mongoOperations;

View File

@ -80,7 +80,7 @@ public class MongoUserDetailsServiceImpl implements MongoUserDetailsService {
public Mono<UserDetails> findByUsername(String s) {
String key = UserCacheKeys.get(s);
// 优先从缓存读取如果缓存不存在查询转换后放入缓存
return reactiveRedisOperations.hasKey(key).flatMap(exists -> exists ? reactiveRedisOperations.get(key) :
return reactiveRedisOperations.hasKey(key).flatMap(exists -> Boolean.TRUE.equals(exists) ? reactiveRedisOperations.get(key) :
userService.findByUsername(s).flatMap(this::validate).map(this::mapToUserDetails)
.flatMap(detail -> reactiveRedisOperations.set(key, detail).thenReturn(detail))
)

View File

@ -2,10 +2,10 @@ package com.flyfish.framework.service;
import com.flyfish.framework.domain.po.Permission;
import com.flyfish.framework.service.impl.BaseServiceImpl;
import com.flyfish.framework.service.impl.BaseReactiveServiceImpl;
import org.springframework.stereotype.Service;
@Service
public class PermissionService extends BaseServiceImpl<Permission> {
public class PermissionService extends BaseReactiveServiceImpl<Permission> {
}

View File

@ -12,7 +12,7 @@ import reactor.core.publisher.Mono;
* @author wangyu
*/
@Service
public class ReactiveUserService extends BaseReactiveServiceImpl<User> {
public class ReactiveUserService extends BaseReactiveServiceImpl<User> implements UserFindService {
/**
* 获取用户数据
@ -20,6 +20,7 @@ public class ReactiveUserService extends BaseReactiveServiceImpl<User> {
* @param username 用户
* @return 结果
*/
@Override
public Mono<User> findByUsername(String username) {
return ((ReactiveUserRepository) repository).findByUsername(username);
}

View File

@ -5,39 +5,45 @@ import com.flyfish.framework.domain.PermissionQo;
import com.flyfish.framework.domain.po.Permission;
import com.flyfish.framework.domain.po.Role;
import com.flyfish.framework.enums.RoleType;
import com.flyfish.framework.service.impl.BaseServiceImpl;
import com.flyfish.framework.service.impl.BaseReactiveServiceImpl;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.Collections;
@Service
@RequiredArgsConstructor
public class RoleService extends BaseServiceImpl<Role> {
public class RoleService extends BaseReactiveServiceImpl<Role> {
private final PermissionService permissionService;
/**
* 如果是管理员设置拥有所有权限
*
* @param entity 实体
* @param role 实体
* @return 结果
*/
@Override
public Role create(Role entity) {
if (entity.isSystem()) {
entity.setPermissions(permissionService.getAll());
} else if (BooleanUtils.isTrue(entity.getAdmin())) {
// 如果是管理员拥有所有权限
PermissionQo qo = new PermissionQo();
qo.setAdmin(false);
List<Permission> permissions = permissionService.getList(qo);
entity.setPermissions(permissions);
}
if (null == entity.getType()) {
entity.setType(RoleType.PC);
}
return super.create(entity);
public Mono<Role> create(Role role) {
return Mono.defer(() -> {
if (role.isSystem()) {
return permissionService.getAll().collectList();
} else if (BooleanUtils.isTrue(role.getAdmin())) {
// 如果是管理员拥有所有权限
PermissionQo qo = new PermissionQo();
qo.setAdmin(false);
return permissionService.getList(qo).collectList();
}
return Mono.just(Collections.<Permission>emptyList());
})
.flatMap(permissions -> {
role.setPermissions(permissions);
if (null == role.getType()) {
role.setType(RoleType.PC);
}
return super.create(role);
});
}
}

View File

@ -1,24 +1,10 @@
package com.flyfish.framework.service;
import com.flyfish.framework.domain.po.User;
import com.flyfish.framework.repository.UserRepository;
import com.flyfish.framework.service.impl.BaseServiceImpl;
import org.springframework.stereotype.Service;
import java.util.Optional;
@Service
public class UserService extends BaseServiceImpl<User> implements UserFindService {
public class UserService extends BaseServiceImpl<User> {
/**
* 获取用户数据
*
* @param username 用户
* @return 结果
*/
@Override
public Optional<User> findByUsername(String username) {
return ((UserRepository) repository).findByUsername(username);
}
}

View File

@ -2,6 +2,7 @@ package com.flyfish.framework.beans.excel;
import com.flyfish.framework.controller.BaseController;
import com.flyfish.framework.controller.ReactiveBaseController;
import com.flyfish.framework.domain.base.NameLikeQo;
import com.flyfish.framework.domain.po.ExcelMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@ -13,5 +14,5 @@ import org.springframework.web.bind.annotation.RestController;
*/
@RestController
@RequestMapping("/excel-mappings")
public class ExcelMappingController extends BaseController<ExcelMapping, NameLikeQo<ExcelMapping>> {
public class ExcelMappingController extends ReactiveBaseController<ExcelMapping, NameLikeQo<ExcelMapping>> {
}

View File

@ -1,13 +1,13 @@
package com.flyfish.framework.beans.excel;
import com.flyfish.framework.domain.po.ExcelMapping;
import com.flyfish.framework.repository.DefaultRepository;
import com.flyfish.framework.repository.DefaultReactiveRepository;
/**
* excel导入方案
*
* @author wangyu
*/
public interface ExcelMappingRepository extends DefaultRepository<ExcelMapping> {
public interface ExcelMappingRepository extends DefaultReactiveRepository<ExcelMapping> {
}

View File

@ -1,9 +1,9 @@
package com.flyfish.framework.beans.excel;
import com.flyfish.framework.domain.po.ExcelMapping;
import com.flyfish.framework.service.impl.BaseServiceImpl;
import com.flyfish.framework.service.impl.BaseReactiveServiceImpl;
import org.springframework.stereotype.Service;
@Service
public class ExcelMappingService extends BaseServiceImpl<ExcelMapping> {
public class ExcelMappingService extends BaseReactiveServiceImpl<ExcelMapping> {
}

View File

@ -1,13 +1,13 @@
package com.flyfish.framework.beans.meta;
import com.flyfish.framework.controller.BaseController;
import com.flyfish.framework.controller.ReactiveBaseController;
import com.flyfish.framework.controller.SafeController;
import com.flyfish.framework.domain.base.NameLikeQo;
import com.flyfish.framework.domain.base.Qo;
import com.flyfish.framework.domain.base.Vo;
import com.flyfish.framework.repository.DefaultRepository;
import com.flyfish.framework.service.BaseService;
import com.flyfish.framework.service.impl.BaseServiceImpl;
import com.flyfish.framework.repository.DefaultReactiveRepository;
import com.flyfish.framework.service.BaseReactiveService;
import com.flyfish.framework.service.impl.BaseReactiveServiceImpl;
import org.springframework.core.annotation.AliasFor;
import org.springframework.data.mongodb.core.mapping.Document;
@ -79,19 +79,19 @@ public @interface RestBean {
*
* @return 结果
*/
Class<? extends DefaultRepository> repoClass() default DefaultRepository.class;
Class<? extends DefaultReactiveRepository> repoClass() default DefaultReactiveRepository.class;
/**
* 服务类动态生成服务
*
* @return 结果
*/
Class<? extends BaseService> serviceClass() default BaseServiceImpl.class;
Class<? extends BaseReactiveService> serviceClass() default BaseReactiveServiceImpl.class;
/**
* controller的类支持自定义
*
* @return 结果
*/
Class<? extends SafeController> controllerClass() default BaseController.class;
Class<? extends SafeController> controllerClass() default ReactiveBaseController.class;
}

View File

@ -114,20 +114,6 @@ public abstract class BaseController<T extends Domain, Q extends Qo<T>> implemen
return Result.accept(service.getList(qo));
}
/**
* reactive接口
*/
@PostMapping(value = "", headers = ReactiveConstants.USE_REACTIVE)
public Mono<Result<T>> reactiveCreate(@ValidRequestBody T entity) {
return reactiveService.create(entity).map(Result::accept);
}
@GetMapping(value = "{id}", headers = ReactiveConstants.USE_REACTIVE)
public Mono<Result<T>> reactiveGet(@PathVariable String id) {
return reactiveService.getById(id)
.map(Result::accept)
.defaultIfEmpty(Result.notFound());
}
@PutMapping(value = "{id}", headers = ReactiveConstants.USE_REACTIVE)
public Mono<Result<T>> reactiveUpdate(@ValidRequestBody T entity) {
@ -136,29 +122,4 @@ public abstract class BaseController<T extends Domain, Q extends Qo<T>> implemen
.defaultIfEmpty(Result.notFound());
}
@DeleteMapping(value = "{id}", headers = ReactiveConstants.USE_REACTIVE)
public Mono<Result<T>> reactiveRemove(@PathVariable String id) {
return reactiveService.deleteById(id).map(item -> Result.ok());
}
@GetMapping(value = "/all", headers = ReactiveConstants.USE_REACTIVE)
public Mono<Result<List<T>>> reactiveAll() {
return reactiveService.getAll()
.collectList()
.map(Result::accept)
.defaultIfEmpty(Result.emptyList());
}
@GetMapping(value = "", headers = ReactiveConstants.USE_REACTIVE)
public Mono<Result<List<T>>> reactiveList(@PagedQuery Q qo) {
if (null != qo.getPageable()) {
return reactiveService.getPageList(qo)
.map(Result::accept)
.defaultIfEmpty(Result.emptyPage());
}
return reactiveService.getList(qo).collectList()
.map(Result::accept)
.defaultIfEmpty(Result.emptyList());
}
}

View File

@ -0,0 +1,103 @@
package com.flyfish.framework.controller;
import com.flyfish.framework.annotations.Operation;
import com.flyfish.framework.bean.Result;
import com.flyfish.framework.bean.SyncVo;
import com.flyfish.framework.configuration.annotations.PagedQuery;
import com.flyfish.framework.configuration.annotations.ValidRequestBody;
import com.flyfish.framework.context.UserContext;
import com.flyfish.framework.domain.base.Domain;
import com.flyfish.framework.domain.base.Qo;
import com.flyfish.framework.service.BaseReactiveService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.util.CastUtils;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;
import java.util.List;
/**
* 通用RESTful的控制器用于动态提供基础的RESTful接口
* 基于最新知识架构出品
*
* @author wangyu
* @create 2021-12-7
*/
public abstract class ReactiveBaseController<T extends Domain, Q extends Qo<T>> implements SafeController {
@Autowired
protected BaseReactiveService<T> reactiveService;
@Autowired
protected UserContext userContext;
public <S extends BaseReactiveService<T>> S getService() {
return CastUtils.cast(reactiveService);
}
@GetMapping("/exists")
public Mono<Result<Boolean>> exists(@PagedQuery Q qo) {
return reactiveService.exists(qo).map(Result::accept);
}
@GetMapping("/count")
public Mono<Result<Long>> count(@PagedQuery Q qo) {
return reactiveService.count(qo).map(Result::accept);
}
@PostMapping("")
@Operation.Create
public Mono<Result<T>> create(@ValidRequestBody T entity) {
return reactiveService.create(entity).map(Result::accept);
}
@GetMapping("{id}")
public Mono<Result<T>> get(@PathVariable String id) {
return reactiveService.getById(id).map(Result::accept).defaultIfEmpty(Result.notFound());
}
@PutMapping("{id}")
@Operation.Update
public Mono<Result<T>> update(@ValidRequestBody T entity) {
return reactiveService.updateSelectiveById(entity).map(Result::accept).defaultIfEmpty(Result.notFound());
}
@PatchMapping("{id}")
@Operation.Update
public Mono<Result<T>> patch(@RequestBody T entity) {
return reactiveService.updateSelectiveById(entity).map(Result::accept).defaultIfEmpty(Result.notFound());
}
@PutMapping("")
@Operation.UpdateAll
public Mono<Result<List<T>>> updateList(@RequestBody List<T> list) {
return reactiveService.updateBatch(list).collectList().map(Result::accept).defaultIfEmpty(Result.emptyList());
}
@PutMapping("/sync")
@Operation.Sync
public Mono<Result<SyncVo<T>>> syncList(@RequestBody List<T> list) {
return reactiveService.sync(list).map(Result::accept).defaultIfEmpty(Result.accept(SyncVo.<T>builder().build()));
}
@DeleteMapping("{id}")
@Operation.Delete
public Mono<Result<T>> remove(@PathVariable List<String> id) {
return reactiveService.deleteBatchByIds(id).thenReturn(Result.ok());
}
@GetMapping("/all")
public Mono<Result<List<T>>> all(@PagedQuery Q qo) {
if (qo.isEmpty()) {
return reactiveService.getAll().collectList().map(Result::accept).defaultIfEmpty(Result.emptyList());
}
return reactiveService.getList(qo).collectList().map(Result::accept).defaultIfEmpty(Result.emptyList());
}
@GetMapping("")
public Mono<Result<List<T>>> list(@PagedQuery Q qo) {
if (null != qo.getPageable() && qo.getPageable().isPaged()) {
return reactiveService.getPageList(qo).map(Result::accept).defaultIfEmpty(Result.emptyPage());
}
return reactiveService.getList(qo).collectList().map(Result::accept).defaultIfEmpty(Result.emptyList());
}
}

View File

@ -1,8 +1,9 @@
package com.flyfish.framework.service;
import com.flyfish.framework.domain.po.User;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.util.MultiValueMap;
import reactor.core.publisher.Mono;
/**
* 认证日志者
@ -16,20 +17,20 @@ public interface AuthenticationLogger {
*
* @param user 用户
*/
void success(UserDetails user);
Mono<Void> success(UserDetails user);
/**
* 记录失败
*
* @param form 表单
* @param user 表单
* @param exception 错误异常
*/
void failure(MultiValueMap<String, String> form, AuthenticationException exception);
Mono<Void> failure(User user, AuthenticationException exception);
/**
* 记录退出
*
* @param user 用户
*/
void logout(UserDetails user);
Mono<Void> logout(UserDetails user);
}

View File

@ -1,5 +1,7 @@
package com.flyfish.framework.service;
import com.flyfish.framework.bean.SyncVo;
import com.flyfish.framework.domain.base.Domain;
import com.flyfish.framework.domain.base.Qo;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
@ -14,7 +16,7 @@ import java.util.List;
*
* @author wybab
*/
public interface BaseReactiveService<T> {
public interface BaseReactiveService<T extends Domain> {
/**
* 查询
@ -40,6 +42,14 @@ public interface BaseReactiveService<T> {
*/
Mono<T> getById(String id);
/**
* 通过实体名称访问
*
* @param name 名称
* @return 结果
*/
Mono<T> getByName(String name);
/**
* 根据ID集合来查询
*
@ -48,6 +58,15 @@ public interface BaseReactiveService<T> {
*/
Flux<T> getByIds(List<String> ids);
/**
* 通过某个字段的集合包含查询
*
* @param key
* @param values
* @return 结果
*/
<K> Flux<T> getByValues(String key, List<K> values);
/**
* 查询列表
*
@ -102,6 +121,22 @@ public interface BaseReactiveService<T> {
*/
Mono<Long> count(T entity);
/**
* 查询总记录数
*
* @param query 查询实体
* @return 结果
*/
Mono<Long> count(Qo<T> query);
/**
* 查询是否存在
*
* @param query 查询
* @return 结果
*/
Mono<Boolean> exists(Qo<T> query);
/**
* 插入新记录
*
@ -151,10 +186,37 @@ public interface BaseReactiveService<T> {
*/
Mono<Void> deleteBatchByIds(List<String> ids);
/**
* 通过某一个键删除所有
*
* @param qo 查询实体
*/
Mono<Void> deleteAll(Qo<T> qo);
/**
* 通过某一个键删除所有
*
* @param entity 查询
*/
Mono<Void> deleteAll(T entity);
/**
* 删除全部实体危险
*/
Mono<Void> deleteAll();
/**
* 批量更新
*
* @param entities 要批量更新的集合
*/
Flux<T> updateBatch(List<T> entities);
/**
* 同步数据
*
* @param entities 数据们
* @return 结果
*/
Mono<SyncVo<T>> sync(List<T> entities);
}

View File

@ -2,6 +2,7 @@ package com.flyfish.framework.service;
import com.flyfish.framework.domain.po.User;
import reactor.core.publisher.Mono;
import java.util.Optional;
@ -16,5 +17,5 @@ public interface UserFindService {
* @param username 用户名
* @return 结果
*/
Optional<User> findByUsername(String username);
Mono<User> findByUsername(String username);
}

View File

@ -2,13 +2,16 @@ package com.flyfish.framework.service.impl;
import com.flyfish.framework.auditor.BeanAuditor;
import com.flyfish.framework.auditor.BeanPoster;
import com.flyfish.framework.bean.SyncVo;
import com.flyfish.framework.domain.base.AuditDomain;
import com.flyfish.framework.domain.base.Domain;
import com.flyfish.framework.domain.base.Qo;
import com.flyfish.framework.exception.biz.InvalidBusinessException;
import com.flyfish.framework.repository.DefaultReactiveRepository;
import com.flyfish.framework.service.BaseReactiveService;
import com.flyfish.framework.utils.Assert;
import com.flyfish.framework.utils.CopyUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
@ -20,10 +23,11 @@ import reactor.core.publisher.Mono;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* 基础的Service继承常用的全部Crud操作基于JPARepository
* TODO 此方法在更新和查询存在不完善后续完善底层支持用于性能优
* 已完全实现全部webflux功能提供全异步支持系统性能最大
*
* @param <T> 实体泛型
*/
@ -38,7 +42,6 @@ public class BaseReactiveServiceImpl<T extends Domain> implements BaseReactiveSe
@Autowired
private BeanAuditor<AuditDomain> operationAuditor;
/**
* 查询
*
@ -58,7 +61,7 @@ public class BaseReactiveServiceImpl<T extends Domain> implements BaseReactiveSe
*/
@Override
public Mono<T> getOne(Qo<T> query) {
return Mono.empty();
return repository.findOne(query);
}
/**
@ -72,6 +75,17 @@ public class BaseReactiveServiceImpl<T extends Domain> implements BaseReactiveSe
return repository.findById(id);
}
/**
* 通过实体名称访问
*
* @param name 名称
* @return 结果
*/
@Override
public Mono<T> getByName(String name) {
return repository.findByName(name);
}
/**
* 根据ID集合来查询
*
@ -83,6 +97,18 @@ public class BaseReactiveServiceImpl<T extends Domain> implements BaseReactiveSe
return repository.findAllById(ids);
}
/**
* 通过某个字段的集合包含查询
*
* @param key
* @param values
* @return 结果
*/
@Override
public <K> Flux<T> getByValues(String key, List<K> values) {
return repository.findAllByValues(key, values);
}
/**
* 查询列表
*
@ -102,7 +128,7 @@ public class BaseReactiveServiceImpl<T extends Domain> implements BaseReactiveSe
*/
@Override
public Flux<T> getList(Qo<T> query) {
return Flux.empty();
return repository.findAll(query);
}
/**
@ -131,7 +157,7 @@ public class BaseReactiveServiceImpl<T extends Domain> implements BaseReactiveSe
*/
@Override
public Mono<Page<T>> getPageList(Qo<T> query) {
return Mono.empty();
return repository.findAll(query, query.getPageable());
}
/**
@ -165,6 +191,28 @@ public class BaseReactiveServiceImpl<T extends Domain> implements BaseReactiveSe
return repository.count(Example.of(entity));
}
/**
* 查询总记录数
*
* @param query 查询实体
* @return 结果
*/
@Override
public Mono<Long> count(Qo<T> query) {
return repository.count(query);
}
/**
* 查询是否存在
*
* @param query 查询
* @return 结果
*/
@Override
public Mono<Boolean> exists(Qo<T> query) {
return repository.exists(query);
}
/**
* 插入新记录
*
@ -172,7 +220,7 @@ public class BaseReactiveServiceImpl<T extends Domain> implements BaseReactiveSe
*/
@Override
public Mono<T> create(T entity) {
return repository.insert(entity);
return repository.insert(audit(entity)).map(this::post);
}
/**
@ -182,7 +230,7 @@ public class BaseReactiveServiceImpl<T extends Domain> implements BaseReactiveSe
*/
@Override
public Mono<T> createSelective(T entity) {
return repository.insert(entity);
return repository.insert(audit(entity)).map(this::post);
}
/**
@ -212,7 +260,7 @@ public class BaseReactiveServiceImpl<T extends Domain> implements BaseReactiveSe
*/
@Override
public Mono<T> updateById(T entity) {
return repository.save(entity);
return repository.save(audit(entity)).map(this::post);
}
/**
@ -225,7 +273,8 @@ public class BaseReactiveServiceImpl<T extends Domain> implements BaseReactiveSe
Assert.hasText(entity.getId(), "更新的主键不可为空!");
return repository.findById(entity.getId())
.map(saved -> CopyUtils.copyProps(entity, saved))
.flatMap(this::updateById);
.flatMap(this::updateById)
.switchIfEmpty(Mono.defer(() -> Mono.error(new InvalidBusinessException("要更新的信息不存在"))));
}
/**
@ -240,6 +289,34 @@ public class BaseReactiveServiceImpl<T extends Domain> implements BaseReactiveSe
.single();
}
/**
* 通过某一个键删除所有
*
* @param qo 查询实体
*/
@Override
public Mono<Void> deleteAll(Qo<T> qo) {
return repository.deleteAll(qo);
}
/**
* 通过某一个键删除所有
*
* @param entity 查询
*/
@Override
public Mono<Void> deleteAll(T entity) {
return repository.delete(entity);
}
/**
* 删除全部实体危险
*/
@Override
public Mono<Void> deleteAll() {
return repository.deleteAll();
}
/**
* 批量更新
*
@ -247,17 +324,42 @@ public class BaseReactiveServiceImpl<T extends Domain> implements BaseReactiveSe
*/
@Override
public Flux<T> updateBatch(List<T> entities) {
// Assert.notEmpty(entities, "数据不可为空!");
// entities.forEach(item -> Assert.hasText(item.getId(), "每个对象的id必须附带"));
// // 过滤不存在的记录
// Map<String, T> savedMap = ((List<T>) repository.findAllById(entities.stream()
// .map(Domain::getId).collect(Collectors.toList()))).stream()
// .collect(Collectors.toMap(Domain::getId, t -> t));
// List<T> updating = entities.stream()
// .filter(t -> savedMap.containsKey(t.getId()))
// .map(t -> CopyUtils.copyProps(savedMap.get(t.getId()), t))
// .collect(Collectors.toList());
return repository.saveAll(entities);
if (CollectionUtils.isNotEmpty(entities)) {
// 带有id的集合
List<String> ids = entities.stream()
.filter(Objects::nonNull)
.map(Domain::getId)
.filter(Objects::nonNull)
.collect(Collectors.toList());
return Mono.just(ids)
.filter(CollectionUtils::isNotEmpty)
.flatMapMany(list -> repository.findAllById(list))
.collectMap(Domain::getId, t -> t)
.map(map -> entities.stream()
// 补全已保存信息
.map(t -> map.containsKey(t.getId()) ? CopyUtils.copyProps(t, map.get(t.getId())) : t)
.map(this::audit)
.collect(Collectors.toList()))
.flatMapMany(list -> repository.saveAll(list))
.map(this::post);
}
return Flux.fromIterable(entities);
}
/**
* 同步数据
*
* @param entities 数据们
* @return 结果
*/
@Override
public Mono<SyncVo<T>> sync(List<T> entities) {
return this.updateBatch(entities)
.collectList()
.map(list -> SyncVo.<T>builder()
.success(list.size())
.list(list)
.build());
}
/**
@ -265,7 +367,7 @@ public class BaseReactiveServiceImpl<T extends Domain> implements BaseReactiveSe
*
* @param entity 实体
*/
protected void audit(T entity) {
protected T audit(T entity) {
// 用户审查
if (entity instanceof AuditDomain) {
operationAuditor.audit((AuditDomain) entity);
@ -274,6 +376,7 @@ public class BaseReactiveServiceImpl<T extends Domain> implements BaseReactiveSe
if (auditor != null) {
auditor.audit(entity);
}
return entity;
}
/**
@ -289,5 +392,9 @@ public class BaseReactiveServiceImpl<T extends Domain> implements BaseReactiveSe
return entity;
}
@SuppressWarnings("unchecked")
public <R extends DefaultReactiveRepository<T>> R getRepository() {
return (R) repository;
}
}

View File

@ -6,6 +6,7 @@ import com.flyfish.framework.bean.SyncVo;
import com.flyfish.framework.domain.base.AuditDomain;
import com.flyfish.framework.domain.base.Domain;
import com.flyfish.framework.domain.base.Qo;
import com.flyfish.framework.repository.DefaultReactiveRepository;
import com.flyfish.framework.repository.DefaultRepository;
import com.flyfish.framework.service.BaseService;
import com.flyfish.framework.utils.Assert;
@ -91,9 +92,8 @@ public class BaseServiceImpl<T extends Domain> implements BaseService<T> {
}
@Override
@SuppressWarnings("unchecked")
public <K> List<T> getByValues(String key, List<K> values) {
return repository.findAllByValues(key, (List<Object>) values);
return repository.findAllByValues(key, values);
}
/**
@ -276,8 +276,7 @@ public class BaseServiceImpl<T extends Domain> implements BaseService<T> {
*/
@Override
public void deleteAll(T entity) {
Iterable<T> list = repository.findAll(Example.of(entity));
repository.deleteAll(list);
repository.delete(entity);
}
/**
@ -366,7 +365,7 @@ public class BaseServiceImpl<T extends Domain> implements BaseService<T> {
}
@SuppressWarnings("unchecked")
public <R extends DefaultRepository<T>> R getRepository() {
public <R extends DefaultReactiveRepository<T>> R getRepository() {
return (R) repository;
}
}

View File

@ -3,8 +3,8 @@ package com.flyfish.framework.utils;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.CollectionUtils;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -71,13 +71,12 @@ public class RedisOperations {
*
* @param key 可以传一个值 或多个
*/
@SuppressWarnings("unchecked")
public void del(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete(CollectionUtils.arrayToList(key));
redisTemplate.delete(Arrays.asList(key));
}
}
}
@ -175,7 +174,7 @@ public class RedisOperations {
* 递增
*
* @param key
* @param by 要增加几(大于0)
* @param delta 要增加几(大于0)
* @return
*/
public long incr(String key, long delta) {
@ -189,7 +188,7 @@ public class RedisOperations {
* 递减
*
* @param key
* @param by 要减少几(小于0)
* @param delta 要减少几(小于0)
* @return
*/
public long decr(String key, long delta) {

View File

@ -12,7 +12,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.4.RELEASE</version>
<version>2.6.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
@ -25,7 +25,7 @@
<jasypt.version>3.0.3</jasypt.version>
<spring-cloud.version>Finchley.SR1</spring-cloud.version>
<jjwt.version>0.11.0</jjwt.version>
<reflection.version>0.9.11</reflection.version>
<reflection.version>0.10.2</reflection.version>
</properties>
<developers>