diff --git a/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/ResourceActionDefinition.java b/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/ResourceActionDefinition.java index 2b257cbff..b09339916 100644 --- a/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/ResourceActionDefinition.java +++ b/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/ResourceActionDefinition.java @@ -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> 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> getI18nMessages() { + if (org.springframework.util.CollectionUtils.isEmpty(i18nMessages)) { + this.i18nMessages = I18nSupportUtils + .putI18nMessages( + resolveActionPrefix + this.id, "name", supportLocale, null, this.i18nMessages + ); + } + return i18nMessages; + } } diff --git a/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/ResourceDefinition.java b/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/ResourceDefinition.java index 3fe66eb35..815116669 100644 --- a/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/ResourceDefinition.java +++ b/hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/ResourceDefinition.java @@ -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 group; + private Map> i18nMessages; + @Setter(value = AccessLevel.PRIVATE) @JsonIgnore private volatile Set actionIds; @@ -35,6 +38,16 @@ public class ResourceDefinition { private Phased phased = Phased.before; + public final static List 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> 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 getAction(String action) { return actions.stream() - .filter(act -> act.getId().equalsIgnoreCase(action)) - .findAny(); + .filter(act -> act.getId().equalsIgnoreCase(action)) + .findAny(); } public Set getActionIds() { @@ -85,13 +108,13 @@ public class ResourceDefinition { @JsonIgnore public List 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 actions) { diff --git a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/DefaultBasicAuthorizeDefinition.java b/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/DefaultBasicAuthorizeDefinition.java index dd334acf8..624261eee 100644 --- a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/DefaultBasicAuthorizeDefinition.java +++ b/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/DefaultBasicAuthorizeDefinition.java @@ -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; /** * 默认权限权限定义 diff --git a/hsweb-starter/src/main/java/org/hswebframework/web/starter/i18n/I18nConfiguration.java b/hsweb-starter/src/main/java/org/hswebframework/web/starter/i18n/I18nConfiguration.java index 6b888f12f..c18e19d3c 100644 --- a/hsweb-starter/src/main/java/org/hswebframework/web/starter/i18n/I18nConfiguration.java +++ b/hsweb-starter/src/main/java/org/hswebframework/web/starter/i18n/I18nConfiguration.java @@ -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; diff --git a/hsweb-system/hsweb-system-authorization/hsweb-system-authorization-api/src/main/java/org/hswebframework/web/system/authorization/api/entity/ActionEntity.java b/hsweb-system/hsweb-system-authorization/hsweb-system-authorization-api/src/main/java/org/hswebframework/web/system/authorization/api/entity/ActionEntity.java index f468dd118..415565f07 100644 --- a/hsweb-system/hsweb-system-authorization/hsweb-system-authorization-api/src/main/java/org/hswebframework/web/system/authorization/api/entity/ActionEntity.java +++ b/hsweb-system/hsweb-system-authorization/hsweb-system-authorization-api/src/main/java/org/hswebframework/web/system/authorization/api/entity/ActionEntity.java @@ -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 properties; + private Map properties; + + @Schema(description = "国际化信息") + private Map> i18nMessages; + + public String getI18nName() { + return getI18nMessage("name", name); + } + public String getI18nDescribe() { + return getI18nMessage("describe", describe); + } } diff --git a/hsweb-system/hsweb-system-authorization/hsweb-system-authorization-api/src/main/java/org/hswebframework/web/system/authorization/api/entity/PermissionEntity.java b/hsweb-system/hsweb-system-authorization/hsweb-system-authorization-api/src/main/java/org/hswebframework/web/system/authorization/api/entity/PermissionEntity.java index dd596d6fa..f60c25634 100644 --- a/hsweb-system/hsweb-system-authorization/hsweb-system-authorization-api/src/main/java/org/hswebframework/web/system/authorization/api/entity/PermissionEntity.java +++ b/hsweb-system/hsweb-system-authorization/hsweb-system-authorization-api/src/main/java/org/hswebframework/web/system/authorization/api/entity/PermissionEntity.java @@ -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 implements RecordCreationEntity, RecordModifierEntity { +public class PermissionEntity extends GenericEntity 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 implements RecordCre @Column(length = 64, updatable = false) private String modifierId; + @Schema(title = "国际化信息定义") + @Column + @JsonCodec + @ColumnType(jdbcType = JDBCType.LONGVARCHAR, javaType = String.class) + private Map> i18nMessages; + + + public String getI18nName() { + return getI18nMessage("name", name); + } + public String getI18nDescribe() { + return getI18nMessage("describe", describe); + } public PermissionEntity copy(Predicate actionFilter, Predicate fieldFilter) { PermissionEntity entity = FastBeanCopier.copy(this, new PermissionEntity()); diff --git a/hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/main/java/org/hswebframework/web/system/authorization/defaults/service/PermissionSynchronization.java b/hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/main/java/org/hswebframework/web/system/authorization/defaults/service/PermissionSynchronization.java index d0a2a0795..a091a9720 100644 --- a/hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/main/java/org/hswebframework/web/system/authorization/defaults/service/PermissionSynchronization.java +++ b/hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/main/java/org/hswebframework/web/system/authorization/defaults/service/PermissionSynchronization.java @@ -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 old, ResourceDefinition definition,Map> entityFieldsMapping) { + public static PermissionEntity convert(Map old, ResourceDefinition definition, Map> 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 properties = Optional.ofNullable(action.getProperties()).orElse(new HashMap<>()); @SuppressWarnings("all") - Set types = (Set)Optional.of(properties.computeIfAbsent("supportDataAccessTypes", t -> new HashSet<>())) + Set 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);