Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
600766c4a5
|
|
@ -1,5 +1,6 @@
|
|||
package org.jetlinks.community.reactorql.term;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import lombok.Getter;
|
||||
import org.hswebframework.ezorm.core.param.Term;
|
||||
import org.hswebframework.ezorm.rdb.operator.builder.fragments.NativeSql;
|
||||
|
|
@ -106,14 +107,16 @@ public enum FixedTermTypeSupport implements TermTypeSupport {
|
|||
};
|
||||
|
||||
private final String text;
|
||||
private final boolean needValue;
|
||||
private final Set<String> supportTypes;
|
||||
|
||||
private final String function;
|
||||
|
||||
private FixedTermTypeSupport(String text, String function, String... supportTypes) {
|
||||
FixedTermTypeSupport(String text, String function, String... supportTypes) {
|
||||
this.text = text;
|
||||
this.function = function;
|
||||
this.supportTypes = new HashSet<>(Arrays.asList(supportTypes));
|
||||
this.needValue = true;
|
||||
this.supportTypes = Sets.newHashSet(supportTypes);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -140,21 +143,18 @@ public enum FixedTermTypeSupport implements TermTypeSupport {
|
|||
PrepareSqlFragments fragments = PrepareSqlFragments.of();
|
||||
appendFunction(column, fragments);
|
||||
|
||||
if (term.getOptions().contains(OPTIONS_NATIVE_SQL)) {
|
||||
value = NativeSql.of(String.valueOf(value));
|
||||
}
|
||||
|
||||
value = convertValue(value, term);
|
||||
|
||||
if (value instanceof NativeSql) {
|
||||
fragments
|
||||
.addSql(((NativeSql) value).getSql())
|
||||
.addParameter(((NativeSql) value).getParameters());
|
||||
} else {
|
||||
fragments.addSql("?")
|
||||
.addParameter(value);
|
||||
.addParameter(((NativeSql) value).getParameters())
|
||||
.addSql(")");
|
||||
} else if (needValue) {
|
||||
value = convertValue(value, term);
|
||||
fragments
|
||||
.addSql("?")
|
||||
.addParameter(value)
|
||||
.addSql(")");
|
||||
}
|
||||
fragments.addSql(")");
|
||||
return fragments;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -106,7 +106,6 @@ public class DefaultVertxMqttServerProvider implements NetworkProvider<VertxMqtt
|
|||
.add("publicPort", "公网端口", "", new IntType())
|
||||
.add("certId", "证书id", "", new StringType())
|
||||
.add("secure", "开启TSL", "", new BooleanType())
|
||||
.add("secure", "开启TSL", "", new BooleanType())
|
||||
.add("maxMessageSize", "最大消息长度", "", new StringType());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -154,7 +154,14 @@ public class DefaultEmailNotifier extends AbstractNotifier<EmailTemplate> {
|
|||
|
||||
return Flux
|
||||
.fromIterable(template.getAttachments().entrySet())
|
||||
.flatMap(entry -> Mono.zip(Mono.just(entry.getKey()), convertResource(entry.getValue())))
|
||||
.flatMap(entry -> Mono
|
||||
.zip(Mono.just(entry.getKey()), convertResource(entry.getValue()))
|
||||
.onErrorResume(err -> Mono
|
||||
.error(() -> new BusinessException.NoStackTrace("error.load_attachment_failed",
|
||||
500,
|
||||
entry.getKey(),
|
||||
err.getMessage())))
|
||||
)
|
||||
.flatMap(tp2 -> Mono
|
||||
.fromCallable(() -> {
|
||||
//添加附件
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
error.load_attachment_failed=load attachment [{0}] failed:{1}
|
||||
|
|
@ -0,0 +1 @@
|
|||
error.load_attachment_failed=\u52A0\u8F7D\u9644\u4EF6[{0}]\u5931\u8D25\uFF1A{1}
|
||||
|
|
@ -36,8 +36,7 @@ public abstract class AbstractPropertyMetricManager implements PropertyMetricMan
|
|||
private Mono<PropertyMetric> loadFromTemplate(ThingId thingId, String property, String metric) {
|
||||
return registry
|
||||
.getThing(thingId.getType(), thingId.getId())
|
||||
.flatMap(Thing::getTemplate)
|
||||
.flatMap(ThingTemplate::getMetadata)
|
||||
.flatMap(Thing::getMetadata)
|
||||
.flatMap(metadata -> Mono
|
||||
.justOrEmpty(
|
||||
metadata
|
||||
|
|
|
|||
|
|
@ -49,6 +49,14 @@ public class MenuBindEntity extends GenericEntity<String> {
|
|||
@NotBlank
|
||||
private String menuId;
|
||||
|
||||
/**
|
||||
* @since 2.2 此前数据未记录
|
||||
*/
|
||||
@Schema(description = "菜单拥有者")
|
||||
@Column(length = 64, updatable = false)
|
||||
@NotBlank
|
||||
private String owner;
|
||||
|
||||
@Schema(description = "其他配置")
|
||||
@Column
|
||||
@ColumnType(jdbcType = JDBCType.LONGVARCHAR, javaType = String.class)
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ public class UserDetail {
|
|||
@Schema(hidden = true)
|
||||
private UserEntityType type;
|
||||
|
||||
@Schema(description = "用户类型ID")
|
||||
private String typeId;
|
||||
|
||||
@Schema(description = "用户状态。1启用,0禁用")
|
||||
private Byte status;
|
||||
|
||||
|
|
@ -63,6 +66,9 @@ public class UserDetail {
|
|||
@Schema(description = "所在机构(部门)信息")
|
||||
private List<OrganizationInfo> orgList;
|
||||
|
||||
@Schema(description = "创建者ID")
|
||||
private String creatorId;
|
||||
|
||||
private boolean tenantDisabled;
|
||||
|
||||
public static UserDetail of(UserEntity entity) {
|
||||
|
|
@ -118,6 +124,11 @@ public class UserDetail {
|
|||
return this;
|
||||
}
|
||||
|
||||
public UserDetail withType() {
|
||||
this.setType(UserEntityTypes.getType(this.getTypeId()));
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserEntity toUserEntity() {
|
||||
UserEntity userEntity = new UserEntity();
|
||||
userEntity.setId(id);
|
||||
|
|
@ -131,7 +142,7 @@ public class UserDetail {
|
|||
return userEntity;
|
||||
}
|
||||
|
||||
public UserDetailEntity toDetailEntity(){
|
||||
public UserDetailEntity toDetailEntity() {
|
||||
return FastBeanCopier.copy(this, new UserDetailEntity());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package org.jetlinks.community.auth.service;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.hswebframework.ezorm.core.param.TermType;
|
||||
import org.hswebframework.ezorm.rdb.mapping.ReactiveRepository;
|
||||
import org.jetlinks.community.auth.entity.MenuBindEntity;
|
||||
import org.jetlinks.community.auth.entity.MenuEntity;
|
||||
|
|
@ -10,6 +11,8 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class MenuGrantService {
|
||||
|
|
@ -54,4 +57,29 @@ public class MenuGrantService {
|
|||
.then()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空菜单授权
|
||||
* @param targetType 权限类型
|
||||
* @param targetId 权限类型对应的数据ID
|
||||
* @param owner 菜单所有者
|
||||
* @return void
|
||||
*/
|
||||
public Mono<Void> clearGrant(String targetType, String targetId, Set<String> owner) {
|
||||
return this
|
||||
.deleteMenuBind(targetType, targetId, owner)
|
||||
.then();
|
||||
}
|
||||
|
||||
private Mono<Integer> deleteMenuBind(String targetType, String targetId, Set<String> owner) {
|
||||
return bindRepository
|
||||
.createDelete()
|
||||
.where(MenuBindEntity::getTargetKey, MenuBindEntity.generateTargetKey(targetType, targetId))
|
||||
.nest()
|
||||
//兼容之前数据-未记录owner
|
||||
.isNull(MenuBindEntity::getOwner)
|
||||
.when(!owner.isEmpty(), d -> d.or(MenuBindEntity::getOwner, TermType.in, owner))
|
||||
.end()
|
||||
.execute();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,10 @@ package org.jetlinks.community.auth.service;
|
|||
import org.hswebframework.web.api.crud.entity.PagerResult;
|
||||
import org.hswebframework.web.api.crud.entity.QueryParamEntity;
|
||||
import org.hswebframework.web.authorization.Authentication;
|
||||
import org.hswebframework.web.authorization.ReactiveAuthenticationHolder;
|
||||
import org.hswebframework.web.authorization.ReactiveAuthenticationManager;
|
||||
import org.hswebframework.web.bean.FastBeanCopier;
|
||||
import org.hswebframework.web.crud.query.QueryHelper;
|
||||
import org.hswebframework.web.crud.service.GenericReactiveCrudService;
|
||||
import org.hswebframework.web.i18n.LocaleUtils;
|
||||
import org.hswebframework.web.system.authorization.api.entity.UserEntity;
|
||||
|
|
@ -20,13 +22,14 @@ import org.jetlinks.community.auth.service.request.SaveUserRequest;
|
|||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 用户详情管理
|
||||
|
|
@ -44,20 +47,25 @@ public class UserDetailService extends GenericReactiveCrudService<UserDetailEnti
|
|||
private final ReactiveUserService userService;
|
||||
|
||||
private final RoleService roleService;
|
||||
|
||||
private final OrganizationService organizationService;
|
||||
|
||||
private final ReactiveAuthenticationManager authenticationManager;
|
||||
|
||||
private final QueryHelper queryHelper;
|
||||
|
||||
private final static UserDetailEntity emptyDetail = new UserDetailEntity();
|
||||
|
||||
public UserDetailService(ReactiveUserService userService,
|
||||
RoleService roleService,
|
||||
OrganizationService organizationService,
|
||||
ReactiveAuthenticationManager authenticationManager) {
|
||||
ReactiveAuthenticationManager authenticationManager,
|
||||
QueryHelper queryHelper) {
|
||||
this.userService = userService;
|
||||
this.roleService = roleService;
|
||||
this.organizationService = organizationService;
|
||||
this.authenticationManager = authenticationManager;
|
||||
this.queryHelper = queryHelper;
|
||||
// 注册默认用户类型
|
||||
UserEntityTypes.register(Arrays.asList(DefaultUserEntityType.values()));
|
||||
|
||||
|
|
@ -112,33 +120,41 @@ public class UserDetailService extends GenericReactiveCrudService<UserDetailEnti
|
|||
}
|
||||
|
||||
public Mono<PagerResult<UserDetail>> queryUserDetail(QueryParamEntity query) {
|
||||
return Mono
|
||||
.zip(
|
||||
userService.countUser(query),
|
||||
userService.findUser(query).collectList())
|
||||
.flatMap(tp2 -> {
|
||||
List<UserEntity> userList = tp2.getT2();
|
||||
return this.createQuery()
|
||||
.in(UserDetailEntity::getId, userList
|
||||
.stream()
|
||||
.map(UserEntity::getId)
|
||||
.collect(Collectors.toList()))
|
||||
.fetch()
|
||||
.collectMap(UserDetailEntity::getId)
|
||||
.flatMap(userDetailMap -> {
|
||||
List<UserDetail> userDetailList = userList.stream()
|
||||
.map(user -> {
|
||||
UserDetail userDetail = UserDetail.of(user);
|
||||
UserDetailEntity entity = userDetailMap.get(user.getId());
|
||||
if (entity != null) {
|
||||
userDetail = userDetail.with(entity);
|
||||
}
|
||||
return userDetail;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
return Mono.just(PagerResult.of(tp2.getT1(), userDetailList, query));
|
||||
});
|
||||
});
|
||||
return QueryHelper
|
||||
.transformPageResult(
|
||||
queryHelper
|
||||
.select(UserDetail.class)
|
||||
.all(UserDetailEntity.class)
|
||||
.as(UserEntity::getId, UserDetail::setId)
|
||||
.as(UserEntity::getName, UserDetail::setName)
|
||||
.as(UserEntity::getUsername, UserDetail::setUsername)
|
||||
// 兼容之前已有字段
|
||||
.as(UserEntity::getType, UserDetail::setTypeId)
|
||||
.as(UserEntity::getStatus, UserDetail::setStatus)
|
||||
.as(UserEntity::getCreateTime, UserDetail::setCreateTime)
|
||||
.as(UserEntity::getCreatorId, UserDetail::setCreatorId)
|
||||
.from(UserEntity.class)
|
||||
.leftJoin(UserDetailEntity.class, j -> j.is(UserDetailEntity::getId, UserEntity::getId))
|
||||
.where(query)
|
||||
.fetchPaged(),
|
||||
list -> this.fillUserDetail(list).
|
||||
collectList());
|
||||
}
|
||||
|
||||
private Flux<UserDetail> fillUserDetail(List<UserDetail> users) {
|
||||
if (CollectionUtils.isEmpty(users)) {
|
||||
return Flux.empty();
|
||||
}
|
||||
return Flux
|
||||
.fromIterable(users)
|
||||
.flatMap(detail ->
|
||||
//维度信息
|
||||
ReactiveAuthenticationHolder
|
||||
.get(detail.getId())
|
||||
.map(Authentication::getDimensions)
|
||||
.defaultIfEmpty(Collections.emptyList())
|
||||
.map(dimensions -> detail.withDimension(dimensions).withType())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import org.springframework.web.bind.annotation.*;
|
|||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
|
|
@ -183,6 +184,15 @@ public class MenuController implements ReactiveServiceCrudController<MenuEntity,
|
|||
.flatMap(grantService::grant);
|
||||
}
|
||||
|
||||
@PutMapping("/{targetType}/{targetId}/{owner}/clear-grant")
|
||||
@Operation(summary = "清空菜单授权")
|
||||
@ResourceAction(id = "grant", name = "授权")
|
||||
public Mono<Void> cleargrant(@PathVariable String targetType,
|
||||
@PathVariable String targetId,
|
||||
@PathVariable String owner) {
|
||||
return grantService.clearGrant(targetType, targetId, Collections.singleton(owner));
|
||||
}
|
||||
|
||||
@PutMapping("/_batch/_grant")
|
||||
@Operation(summary = "对菜单批量进行授权")
|
||||
@ResourceAction(id = "grant", name = "授权")
|
||||
|
|
|
|||
|
|
@ -5,9 +5,11 @@ import lombok.extern.slf4j.Slf4j;
|
|||
import org.jetlinks.community.rule.engine.entity.RuleInstanceEntity;
|
||||
import org.jetlinks.community.rule.engine.entity.SceneEntity;
|
||||
import org.jetlinks.community.rule.engine.enums.RuleInstanceState;
|
||||
import org.jetlinks.rule.engine.api.RuleEngine;
|
||||
import org.jetlinks.rule.engine.api.model.RuleEngineModelParser;
|
||||
import org.jetlinks.rule.engine.cluster.RuleInstance;
|
||||
import org.jetlinks.rule.engine.cluster.RuleInstanceRepository;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
|
@ -17,13 +19,15 @@ import javax.annotation.Nonnull;
|
|||
@Component
|
||||
@AllArgsConstructor
|
||||
@Slf4j
|
||||
public class LocalRuleInstanceRepository implements RuleInstanceRepository {
|
||||
public class LocalRuleInstanceRepository implements RuleInstanceRepository, CommandLineRunner {
|
||||
private final RuleInstanceService instanceService;
|
||||
|
||||
private final SceneService sceneService;
|
||||
|
||||
private final RuleEngineModelParser parser;
|
||||
|
||||
private final RuleEngine ruleEngine;
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Flux<RuleInstance> findAll() {
|
||||
|
|
@ -71,4 +75,17 @@ public class LocalRuleInstanceRepository implements RuleInstanceRepository {
|
|||
)
|
||||
;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
this
|
||||
.findAll()
|
||||
.flatMap(ruleInstance -> ruleEngine
|
||||
.startRule(ruleInstance.getId(), ruleInstance.getModel())
|
||||
.onErrorResume(err -> {
|
||||
log.warn("启动规则[{}]失败: {}", ruleInstance.getModel().getName(), ruleInstance);
|
||||
return Mono.empty();
|
||||
}))
|
||||
.subscribe();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import org.jetlinks.rule.engine.api.model.RuleEngineModelParser;
|
|||
import org.jetlinks.rule.engine.api.model.RuleModel;
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
|
@ -23,7 +22,7 @@ import reactor.core.publisher.Mono;
|
|||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class RuleInstanceService extends GenericReactiveCrudService<RuleInstanceEntity, String> implements CommandLineRunner {
|
||||
public class RuleInstanceService extends GenericReactiveCrudService<RuleInstanceEntity, String> {
|
||||
|
||||
@Autowired
|
||||
private RuleEngine ruleEngine;
|
||||
|
|
@ -78,18 +77,4 @@ public class RuleInstanceService extends GenericReactiveCrudService<RuleInstance
|
|||
.as(super::deleteById);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(String... args) {
|
||||
createQuery()
|
||||
.where()
|
||||
.is(RuleInstanceEntity::getState, RuleInstanceState.started)
|
||||
.fetch()
|
||||
.flatMap(e -> this
|
||||
.doStart(e)
|
||||
.onErrorResume(err -> {
|
||||
log.warn("启动规则[{}]失败", e.getName(), e);
|
||||
return Mono.empty();
|
||||
}))
|
||||
.subscribe();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue