Merge remote-tracking branch 'origin/master'

This commit is contained in:
zhouhao
2025-01-15 17:19:16 +08:00
7 changed files with 115 additions and 32 deletions

View File

@@ -4,23 +4,44 @@ import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.hswebframework.web.bean.FastBeanCopier;
import org.hswebframework.web.i18n.I18nSupportUtils;
import org.hswebframework.web.i18n.MultipleI18nSupportEntity;
import java.util.List;
import java.util.Collection;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import static org.hswebframework.web.authorization.define.ResourceDefinition.supportLocale;
@Getter
@Setter
@EqualsAndHashCode(of = "id")
public class ResourceActionDefinition {
public class ResourceActionDefinition implements MultipleI18nSupportEntity {
private String id;
private String name;
private String description;
private Map<String, Map<String, String>> i18nMessages;
private DataAccessDefinition dataAccess = new DataAccessDefinition();
public ResourceActionDefinition copy(){
return FastBeanCopier.copy(this,ResourceActionDefinition::new);
private final static String resolveActionPrefix = "hswebframework.web.system.action.";
public ResourceActionDefinition copy() {
return FastBeanCopier.copy(this, ResourceActionDefinition::new);
}
public Map<String, Map<String, String>> getI18nMessages() {
if (org.springframework.util.CollectionUtils.isEmpty(i18nMessages)) {
this.i18nMessages = I18nSupportUtils
.putI18nMessages(
resolveActionPrefix + this.id, "name", supportLocale, null, this.i18nMessages
);
}
return i18nMessages;
}
}

View File

@@ -8,15 +8,16 @@ import lombok.Setter;
import org.apache.commons.collections4.CollectionUtils;
import org.hswebframework.web.authorization.annotation.Logical;
import org.hswebframework.web.bean.FastBeanCopier;
import org.hswebframework.web.i18n.I18nSupportUtils;
import org.hswebframework.web.i18n.MultipleI18nSupportEntity;
import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;
@Getter
@Setter
@EqualsAndHashCode(of = "id")
public class ResourceDefinition {
public class ResourceDefinition implements MultipleI18nSupportEntity {
private String id;
private String name;
@@ -27,6 +28,8 @@ public class ResourceDefinition {
private List<String> group;
private Map<String, Map<String, String>> i18nMessages;
@Setter(value = AccessLevel.PRIVATE)
@JsonIgnore
private volatile Set<String> actionIds;
@@ -35,6 +38,16 @@ public class ResourceDefinition {
private Phased phased = Phased.before;
public final static List<Locale> supportLocale = new ArrayList<>();
static {
supportLocale.add(Locale.CHINESE);
supportLocale.add(Locale.ENGLISH);
}
private final static String resolvePermissionPrefix = "hswebframework.web.system.permission.";
public static ResourceDefinition of(String id, String name) {
ResourceDefinition definition = new ResourceDefinition();
definition.setId(id);
@@ -42,6 +55,16 @@ public class ResourceDefinition {
return definition;
}
public Map<String, Map<String, String>> getI18nMessages() {
if (org.springframework.util.CollectionUtils.isEmpty(i18nMessages)) {
this.i18nMessages = I18nSupportUtils
.putI18nMessages(
resolvePermissionPrefix + this.id, "name", supportLocale, null, this.i18nMessages
);
}
return i18nMessages;
}
public ResourceDefinition copy() {
ResourceDefinition definition = FastBeanCopier.copy(this, ResourceDefinition::new);
definition.setActions(actions.stream().map(ResourceActionDefinition::copy).collect(Collectors.toSet()));
@@ -60,7 +83,7 @@ public class ResourceDefinition {
ResourceActionDefinition old = getAction(action.getId()).orElse(null);
if (old != null) {
old.getDataAccess().getDataAccessTypes()
.addAll(action.getDataAccess().getDataAccessTypes());
.addAll(action.getDataAccess().getDataAccessTypes());
}
actions.add(action);
return this;
@@ -68,8 +91,8 @@ public class ResourceDefinition {
public Optional<ResourceActionDefinition> getAction(String action) {
return actions.stream()
.filter(act -> act.getId().equalsIgnoreCase(action))
.findAny();
.filter(act -> act.getId().equalsIgnoreCase(action))
.findAny();
}
public Set<String> getActionIds() {
@@ -85,13 +108,13 @@ public class ResourceDefinition {
@JsonIgnore
public List<ResourceActionDefinition> getDataAccessAction() {
return actions.stream()
.filter(act -> CollectionUtils.isNotEmpty(act.getDataAccess().getDataAccessTypes()))
.collect(Collectors.toList());
.filter(act -> CollectionUtils.isNotEmpty(act.getDataAccess().getDataAccessTypes()))
.collect(Collectors.toList());
}
public boolean hasDataAccessAction() {
return actions.stream()
.anyMatch(act -> CollectionUtils.isNotEmpty(act.getDataAccess().getDataAccessTypes()));
.anyMatch(act -> CollectionUtils.isNotEmpty(act.getDataAccess().getDataAccessTypes()));
}
public boolean hasAction(Collection<String> actions) {

View File

@@ -4,15 +4,16 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.*;
import org.hswebframework.web.authorization.annotation.*;
import org.hswebframework.web.authorization.define.*;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.util.StringUtils;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import static org.hswebframework.web.authorization.define.ResourceDefinition.supportLocale;
/**
* 默认权限权限定义

View File

@@ -12,6 +12,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.util.StringUtils;

View File

@@ -2,8 +2,14 @@ package org.hswebframework.web.system.authorization.api.entity;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import org.hswebframework.ezorm.rdb.mapping.annotation.ColumnType;
import org.hswebframework.ezorm.rdb.mapping.annotation.JsonCodec;
import org.hswebframework.web.api.crud.entity.Entity;
import org.hswebframework.web.i18n.MultipleI18nSupportEntity;
import org.hswebframework.web.i18n.SingleI18nSupportEntity;
import javax.persistence.Column;
import java.sql.JDBCType;
import java.util.Map;
@Getter
@@ -12,7 +18,7 @@ import java.util.Map;
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(of = "action")
public class ActionEntity implements Entity {
public class ActionEntity implements Entity, MultipleI18nSupportEntity {
@Schema(description = "操作标识,如: add,query")
private String action;
@@ -24,5 +30,15 @@ public class ActionEntity implements Entity {
private String describe;
@Schema(description = "其他配置")
private Map<String,Object> properties;
private Map<String, Object> properties;
@Schema(description = "国际化信息")
private Map<String, Map<String, String>> i18nMessages;
public String getI18nName() {
return getI18nMessage("name", name);
}
public String getI18nDescribe() {
return getI18nMessage("describe", describe);
}
}

View File

@@ -11,6 +11,7 @@ import org.hswebframework.web.api.crud.entity.RecordCreationEntity;
import org.hswebframework.web.api.crud.entity.RecordModifierEntity;
import org.hswebframework.web.bean.FastBeanCopier;
import org.hswebframework.web.crud.generator.Generators;
import org.hswebframework.web.i18n.MultipleI18nSupportEntity;
import org.hswebframework.web.validator.CreateGroup;
import org.springframework.util.CollectionUtils;
@@ -31,7 +32,7 @@ import java.util.stream.Collectors;
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PermissionEntity extends GenericEntity<String> implements RecordCreationEntity, RecordModifierEntity {
public class PermissionEntity extends GenericEntity<String> implements RecordCreationEntity, RecordModifierEntity, MultipleI18nSupportEntity {
@Override
@Pattern(regexp = "^[0-9a-zA-Z_\\-]+$", message = "ID只能由数字,字母,下划线和中划线组成", groups = CreateGroup.class)
@@ -102,6 +103,19 @@ public class PermissionEntity extends GenericEntity<String> implements RecordCre
@Column(length = 64, updatable = false)
private String modifierId;
@Schema(title = "国际化信息定义")
@Column
@JsonCodec
@ColumnType(jdbcType = JDBCType.LONGVARCHAR, javaType = String.class)
private Map<String, Map<String, String>> i18nMessages;
public String getI18nName() {
return getI18nMessage("name", name);
}
public String getI18nDescribe() {
return getI18nMessage("describe", describe);
}
public PermissionEntity copy(Predicate<ActionEntity> actionFilter,
Predicate<OptionalField> fieldFilter) {
PermissionEntity entity = FastBeanCopier.copy(this, new PermissionEntity());

View File

@@ -8,10 +8,10 @@ import org.hswebframework.web.api.crud.entity.Entity;
import org.hswebframework.web.authorization.define.*;
import org.hswebframework.web.crud.web.reactive.ReactiveQueryController;
import org.hswebframework.web.crud.web.reactive.ReactiveServiceQueryController;
import org.hswebframework.web.i18n.LocaleUtils;
import org.hswebframework.web.system.authorization.api.entity.ActionEntity;
import org.hswebframework.web.system.authorization.api.entity.OptionalField;
import org.hswebframework.web.system.authorization.api.entity.PermissionEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.event.EventListener;
import org.springframework.util.CollectionUtils;
@@ -75,15 +75,15 @@ public class PermissionSynchronization implements CommandLineRunner {
}
}
public static PermissionEntity convert(Map<String, PermissionEntity> old, ResourceDefinition definition,Map<String, List<OptionalField>> entityFieldsMapping) {
public static PermissionEntity convert(Map<String, PermissionEntity> old, ResourceDefinition definition, Map<String, List<OptionalField>> entityFieldsMapping) {
PermissionEntity entity = old.getOrDefault(definition.getId(), PermissionEntity.builder()
.name(definition.getName())
.describe(definition.getDescription())
.status((byte) 1)
.build());
.name(definition.getName())
.describe(definition.getDescription())
.i18nMessages(definition.getI18nMessages())
.status((byte) 1)
.build());
entity.setId(definition.getId());
if (CollectionUtils.isEmpty(entity.getOptionalFields())) {
entity.setOptionalFields(entityFieldsMapping.get(entity.getId()));
}
@@ -100,24 +100,31 @@ public class PermissionSynchronization implements CommandLineRunner {
.name(definitionAction.getName())
.describe(definitionAction.getName())
.build());
action.setI18nMessages(definitionAction.getI18nMessages());
Map<String, Object> properties = Optional.ofNullable(action.getProperties()).orElse(new HashMap<>());
@SuppressWarnings("all")
Set<Object> types = (Set)Optional.of(properties.computeIfAbsent("supportDataAccessTypes", t -> new HashSet<>()))
Set<Object> types = (Set) Optional
.of(properties.computeIfAbsent("supportDataAccessTypes", t -> new HashSet<>()))
.filter(Collection.class::isInstance)
.map(Collection.class::cast)
.map(HashSet::new)
.orElseGet(HashSet::new);
types.addAll(definitionAction.getDataAccess().getDataAccessTypes().stream().map(DataAccessTypeDefinition::getId).collect(Collectors.toSet()));
types.addAll(definitionAction
.getDataAccess()
.getDataAccessTypes()
.stream()
.map(DataAccessTypeDefinition::getId)
.collect(Collectors.toSet()));
action.setProperties(properties);
oldAction.put(action.getAction(), action);
}
entity.setActions(new ArrayList<>(oldAction.values()));
return entity;
}
@Override
public void run(String... args) throws Exception {
if (definition.getResources().isEmpty()) {
@@ -130,8 +137,8 @@ public class PermissionSynchronization implements CommandLineRunner {
.fetch()
.collect(Collectors.toMap(PermissionEntity::getId, Function.identity()))
.flatMap(group -> Flux.fromIterable(definition.getResources())
.map(d -> PermissionSynchronization.convert(group, d,entityFieldsMapping))
.as(permissionRepository::save))
.map(d -> PermissionSynchronization.convert(group, d, entityFieldsMapping))
.as(permissionRepository::save))
.doOnError(err -> log.warn("sync permission error", err))
.subscribe(l -> {
log.info("sync permission success:{}", l);