chore: initialize qiming workspace repository
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>com.xspaceagi</groupId>
|
||||
<artifactId>platform-system</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>system-spec</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.tika</groupId>
|
||||
<artifactId>tika-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.tika</groupId>
|
||||
<artifactId>tika-parsers-standard-package</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.sun.mail</groupId>
|
||||
<artifactId>javax.mail</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.fastjson2</groupId>
|
||||
<artifactId>fastjson2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 密钥工具 -->
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk18on</artifactId>
|
||||
</dependency>
|
||||
<!-- 加密 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-crypto</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--缓存-->
|
||||
<dependency>
|
||||
<groupId>com.github.ben-manes.caffeine</groupId>
|
||||
<artifactId>caffeine</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- hutool工具类 -->
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- hutool拼音功能依赖的底层引擎(用于中文转拼音首字母) -->
|
||||
<dependency>
|
||||
<groupId>com.belerweb</groupId>
|
||||
<artifactId>pinyin4j</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.xspaceagi.sandbox;
|
||||
|
||||
/**
|
||||
* Sandbox 相关的attribute key
|
||||
*/
|
||||
public class SandboxRequestAttributes {
|
||||
|
||||
private SandboxRequestAttributes() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 原始请求 URI(形如:/api/v1/4sandbox/{module}/...)
|
||||
* 鉴权拦截器需要基于这个值做白名单/AKTargetType 判断。
|
||||
*/
|
||||
public static final String ORIGINAL_REQUEST_URI = "ORIGINAL_REQUEST_URI";
|
||||
|
||||
/**
|
||||
* 请求来源(用于 controller 做沙箱/前端差异处理)
|
||||
*/
|
||||
public static final String REQUEST_SOURCE = "REQUEST_SOURCE";
|
||||
|
||||
/**
|
||||
* sandbox 来源标记值
|
||||
*/
|
||||
public static final String SOURCE_SANDBOX = "sandbox";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.xspaceagi.system.spec.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 执行后清除所有用户权限缓存
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface ClearAllUserPermissionCache {
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.xspaceagi.system.spec.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 执行后按用户ID列表清理权限缓存
|
||||
*
|
||||
* 通过 userIdParamIndexes 指定方法参数中哪些位置包含用户ID或用户ID集合:
|
||||
* - 如果参数类型是 Long,则视为单个 userId
|
||||
* - 如果是 Collection<Long> / List<Long>,则视为用户ID列表
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface ClearUserPermissionCacheByUserIds {
|
||||
|
||||
/**
|
||||
* 方法参数中,包含用户ID或用户ID集合的参数下标(从 0 开始)
|
||||
*/
|
||||
int[] userIdParamIndexes();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.xspaceagi.system.spec.annotation;
|
||||
|
||||
import jakarta.validation.Constraint;
|
||||
import jakarta.validation.Payload;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
@Documented
|
||||
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
|
||||
@Retention(RUNTIME)
|
||||
@Repeatable(EnumValidation.List.class) // 允许在同一元素上多次使用该注解
|
||||
@Constraint(validatedBy = {EnumValidator.class})
|
||||
public @interface EnumValidation {
|
||||
|
||||
String message() default "{*.validation.constraint.Enum.message}";
|
||||
|
||||
Class<?>[] groups() default {};
|
||||
|
||||
Class<? extends Payload>[] payload() default {};
|
||||
|
||||
Class<?> clazz();
|
||||
|
||||
String method() default "ordinal";
|
||||
|
||||
@Documented
|
||||
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
|
||||
@Retention(RUNTIME)
|
||||
@interface List {
|
||||
EnumValidation[] value();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.xspaceagi.system.spec.annotation;
|
||||
|
||||
import jakarta.validation.ConstraintValidator;
|
||||
import jakarta.validation.ConstraintValidatorContext;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* @desc: 枚举验证器
|
||||
*/
|
||||
public class EnumValidator implements ConstraintValidator<EnumValidation, Object> {
|
||||
|
||||
private EnumValidation annotation;
|
||||
|
||||
@Override
|
||||
public void initialize(EnumValidation constraintAnnotation) {
|
||||
this.annotation = constraintAnnotation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(Object value, ConstraintValidatorContext context) {
|
||||
if (value == null) {
|
||||
return false;
|
||||
}
|
||||
Object[] objects = annotation.clazz().getEnumConstants();
|
||||
try {
|
||||
Method method = annotation.clazz().getMethod(annotation.method());
|
||||
for (Object o : objects) {
|
||||
if (value.equals(method.invoke(o))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.xspaceagi.system.spec.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface I18n {
|
||||
String module() default "";
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.xspaceagi.system.spec.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface I18nField {
|
||||
|
||||
String field() default "";
|
||||
|
||||
boolean subObj() default false;
|
||||
|
||||
boolean id() default false;
|
||||
|
||||
boolean keyPrefix() default false;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.xspaceagi.system.spec.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 请求参数,不需要解析转换到QueryMap的字段
|
||||
*/
|
||||
@Inherited
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.FIELD, ElementType.TYPE})
|
||||
public @interface NoParseRequestParam {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.xspaceagi.system.spec.annotation;
|
||||
|
||||
import com.xspaceagi.system.spec.enums.ResourceEnum;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 资源权限注解,支持方法级别和类级别
|
||||
* - 方法级别:仅该方法的接口受此注解限制
|
||||
* - 类级别:该类的所有接口方法都受此注解限制,方法上的注解优先于类上的
|
||||
* 支持传入多个资源码
|
||||
*/
|
||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface RequireResource {
|
||||
|
||||
/**
|
||||
* 资源枚举(支持多个,用户拥有任意一个即可)
|
||||
*/
|
||||
ResourceEnum[] value() default {};
|
||||
|
||||
/**
|
||||
* 资源码(支持多个,用户拥有任意一个即可)
|
||||
* 当 value 与 codes 同时指定时,会合并校验
|
||||
*/
|
||||
String[] codes() default {};
|
||||
|
||||
/**
|
||||
* 权限描述信息
|
||||
*/
|
||||
String description() default "需要资源权限";
|
||||
|
||||
/**
|
||||
* 是否允许跳过权限检查(用于测试等场景)
|
||||
*/
|
||||
boolean skipCheck() default false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.xspaceagi.system.spec.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface SaasAdmin {
|
||||
|
||||
boolean skipCheck() default false;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.xspaceagi.system.spec.annotation;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 敏感字段权限过滤, 目前自己从权限系统里获取,如有无成本权限,售价权限等
|
||||
* <p>后续完善中,看实际情况,会继续增加敏感类型的区分和过滤</p>
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class SensitiveAuthParam {
|
||||
|
||||
/**
|
||||
* 用户密码权限
|
||||
*/
|
||||
private Boolean userPasswordFlag;
|
||||
|
||||
|
||||
|
||||
public static SensitiveAuthParam passwordAuthBuild(Boolean userPasswordFlag) {
|
||||
SensitiveAuthParam sensitiveAuthParam = new SensitiveAuthParam();
|
||||
sensitiveAuthParam.setUserPasswordFlag(userPasswordFlag);
|
||||
return sensitiveAuthParam;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.xspaceagi.system.spec.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 敏感字段处理
|
||||
*/
|
||||
@Inherited
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.FIELD, ElementType.TYPE})
|
||||
public @interface SensitiveField {
|
||||
|
||||
/**
|
||||
* 参考:SensitiveFieldEnum 枚举
|
||||
*/
|
||||
SensitiveFieldEnum type();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.xspaceagi.system.spec.annotation;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum SensitiveFieldEnum {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
USER_PASSWORD("用户密码");
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String desc;
|
||||
|
||||
SensitiveFieldEnum(String desc) {
|
||||
this.desc = desc;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.xspaceagi.system.spec.auth;
|
||||
|
||||
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties({UserAuthProperties.class,UserJwtProperties.class})
|
||||
public class AuthWebConfiguration {
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.xspaceagi.system.spec.auth;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import lombok.Data;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户鉴权相关配置
|
||||
*/
|
||||
@Data
|
||||
@ConfigurationProperties(prefix = "auth")
|
||||
public class UserAuthProperties {
|
||||
|
||||
|
||||
/**
|
||||
* 不需要鉴权的uri
|
||||
*/
|
||||
private List<String> excludePath = Lists.newArrayList("/login", "/health", "/ready");
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.xspaceagi.system.spec.auth;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
@Data
|
||||
@ConfigurationProperties(prefix = "auth.jwt")
|
||||
public class UserJwtProperties {
|
||||
|
||||
|
||||
/**
|
||||
* jwt 密钥
|
||||
*/
|
||||
private String secretKey;
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
package com.xspaceagi.system.spec.cache;
|
||||
|
||||
import jakarta.annotation.PreDestroy;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class SimpleJvmHashCache {
|
||||
|
||||
public static final long DEFAULT_EXPIRE_AFTER_SECONDS = 86400;
|
||||
|
||||
private static final Map<String, Map<String, CacheItem<Object>>> cache;
|
||||
private static final ScheduledExecutorService cleanupExecutor;
|
||||
|
||||
static {
|
||||
cache = new ConcurrentHashMap<>();
|
||||
cleanupExecutor = Executors.newSingleThreadScheduledExecutor();
|
||||
// 每5秒清理一次过期缓存
|
||||
cleanupExecutor.scheduleAtFixedRate(SimpleJvmHashCache::cleanupExpiredItems, 5, 5, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加Hash缓存项,指定过期时间(单位:秒)
|
||||
*/
|
||||
public static void putHash(String key, String field, Object value, long expireAfterSeconds, Consumer<Object> expireListener) {
|
||||
if (key == null) {
|
||||
return;
|
||||
}
|
||||
long expireTime = System.currentTimeMillis() + expireAfterSeconds * 1000;
|
||||
cache.computeIfAbsent(key, k -> new ConcurrentHashMap<>())
|
||||
.put(field, new CacheItem<>(value, expireTime, expireListener));
|
||||
}
|
||||
|
||||
public static void putHash(String key, String field, Object value, long expireAfterSeconds) {
|
||||
if (key == null) {
|
||||
return;
|
||||
}
|
||||
long expireTime = System.currentTimeMillis() + expireAfterSeconds * 1000;
|
||||
cache.computeIfAbsent(key, k -> new ConcurrentHashMap<>())
|
||||
.put(field, new CacheItem<>(value, expireTime));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Hash缓存项,如果已过期则返回null
|
||||
*/
|
||||
public static Object getHash(String key, String field) {
|
||||
if (key == null) {
|
||||
return null;
|
||||
}
|
||||
Map<String, CacheItem<Object>> fieldMap = cache.get(key);
|
||||
if (fieldMap == null) return null;
|
||||
|
||||
CacheItem<Object> item = fieldMap.get(field);
|
||||
if (item == null || item.isExpired()) {
|
||||
fieldMap.remove(field);
|
||||
return null;
|
||||
}
|
||||
return item.getValue();
|
||||
}
|
||||
|
||||
//getHashAll
|
||||
public static Map<String, Object> getHashAll(String key) {
|
||||
if (key == null) {
|
||||
return null;
|
||||
}
|
||||
Map<String, CacheItem<Object>> fieldMap = cache.get(key);
|
||||
if (fieldMap == null) return null;
|
||||
|
||||
Map<String, Object> result = new ConcurrentHashMap<>();
|
||||
fieldMap.forEach((field, item) -> {
|
||||
if (item != null && !item.isExpired() && item.getValue() != null) {
|
||||
result.put(field, item.getValue());
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除Hash缓存项
|
||||
*/
|
||||
public static Object removeHash(String key, String field) {
|
||||
if (key == null) {
|
||||
return null;
|
||||
}
|
||||
Map<String, CacheItem<Object>> fieldMap = cache.get(key);
|
||||
if (fieldMap != null) {
|
||||
CacheItem<Object> item = fieldMap.remove(field);
|
||||
if (item != null) {
|
||||
return item.getValue();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//删除
|
||||
public static void removeHashAll(String key) {
|
||||
if (key == null) {
|
||||
return;
|
||||
}
|
||||
cache.remove(key);
|
||||
}
|
||||
|
||||
private static void cleanupExpiredItems() {
|
||||
try {
|
||||
cleanupExpiredItems0();
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
log.error("cleanupExpiredItems error", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理所有过期的缓存项
|
||||
*/
|
||||
private static void cleanupExpiredItems0() {
|
||||
List<String> toRemove = new ArrayList<>();
|
||||
cache.forEach((key, fieldMap) -> {
|
||||
fieldMap.entrySet().removeIf(entry -> {
|
||||
if (entry.getValue().isExpired()) {
|
||||
if (entry.getValue().expireListener != null) {
|
||||
try {
|
||||
entry.getValue().expireListener.accept(entry.getValue().getValue());
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if (fieldMap.isEmpty()) {
|
||||
toRemove.add(key);
|
||||
}
|
||||
});
|
||||
toRemove.forEach(cache::remove);
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭缓存清理任务
|
||||
*/
|
||||
@PreDestroy
|
||||
public void shutdown() {
|
||||
cleanupExecutor.shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存项包装类,记录过期时间
|
||||
*/
|
||||
private static class CacheItem<V> {
|
||||
private final V value;
|
||||
private final long expireTime;
|
||||
|
||||
private Consumer<V> expireListener;
|
||||
|
||||
CacheItem(V value, long expireTime) {
|
||||
this.value = value;
|
||||
this.expireTime = expireTime;
|
||||
}
|
||||
|
||||
CacheItem(V value, long expireTime, Consumer<V> expireListener) {
|
||||
this.value = value;
|
||||
this.expireTime = expireTime;
|
||||
this.expireListener = expireListener;
|
||||
}
|
||||
|
||||
V getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
boolean isExpired() {
|
||||
return System.currentTimeMillis() > expireTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.xspaceagi.system.spec.common;
|
||||
|
||||
import com.xspaceagi.system.spec.jackson.JsonSerializeUtil;
|
||||
import org.apache.ibatis.type.BaseTypeHandler;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Objects;
|
||||
|
||||
public class JsonTypeHandler extends BaseTypeHandler<Object> {
|
||||
|
||||
@Override
|
||||
public void setNonNullParameter(PreparedStatement preparedStatement, int i, Object object, JdbcType jdbcType) throws SQLException {
|
||||
if (Objects.nonNull(object)) {
|
||||
preparedStatement.setString(i, JsonSerializeUtil.toJSONStringGeneric(object));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getNullableResult(ResultSet resultSet, String s) throws SQLException {
|
||||
if (null != resultSet.getString(s)) {
|
||||
return JsonSerializeUtil.parseObjectGeneric(resultSet.getString(s));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getNullableResult(ResultSet resultSet, int i) throws SQLException {
|
||||
if (null != resultSet.getString(i)) {
|
||||
return JsonSerializeUtil.parseObjectGeneric(resultSet.getString(i));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
|
||||
if (null != callableStatement.getString(i)) {
|
||||
return JsonSerializeUtil.parseObjectGeneric(callableStatement.getString(i));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
package com.xspaceagi.system.spec.common;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.ibatis.type.BaseTypeHandler;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.StreamReadConstraints;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
|
||||
/**
|
||||
* 不包含类型信息的 JsonTypeHandler
|
||||
* 专门用于序列化不包含 @class 类型信息的 JSON 数据
|
||||
*/
|
||||
public class JsonTypeHandlerWithoutType extends BaseTypeHandler<Object> {
|
||||
|
||||
private static final ObjectMapper objectMapper;
|
||||
|
||||
/**
|
||||
* 最大序列化大小限制:100MB
|
||||
* 超过此大小会抛出明确的异常,而不是导致 OOM
|
||||
*/
|
||||
private static final long MAX_SERIALIZATION_SIZE = 100 * 1024 * 1024L;
|
||||
|
||||
static {
|
||||
objectMapper = new ObjectMapper();
|
||||
// 配置不包含类型信息
|
||||
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
|
||||
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
|
||||
// 配置 StreamReadConstraints 以支持更大的字符串长度
|
||||
// 设置最大字符串长度为 100MB (100 * 1024 * 1024 字符)
|
||||
StreamReadConstraints constraints = StreamReadConstraints.builder()
|
||||
.maxStringLength(100 * 1024 * 1024)
|
||||
.build();
|
||||
JsonFactory factory = objectMapper.getFactory();
|
||||
factory.setStreamReadConstraints(constraints);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNonNullParameter(PreparedStatement preparedStatement, int i, Object object, JdbcType jdbcType)
|
||||
throws SQLException {
|
||||
if (Objects.nonNull(object)) {
|
||||
try {
|
||||
// 使用 ByteArrayOutputStream 来限制内存使用并检查大小
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
try (JsonGenerator generator = objectMapper.getFactory().createGenerator(outputStream)) {
|
||||
objectMapper.writeValue(generator, object);
|
||||
}
|
||||
|
||||
// 检查序列化后的大小
|
||||
byte[] bytes = outputStream.toByteArray();
|
||||
if (bytes.length > MAX_SERIALIZATION_SIZE) {
|
||||
throw new SQLException(String.format(
|
||||
"序列化后的数据大小超过限制: %d bytes > %d bytes (%.2f MB)。请减少数据量或分批处理。",
|
||||
bytes.length, MAX_SERIALIZATION_SIZE, bytes.length / (1024.0 * 1024.0)));
|
||||
}
|
||||
|
||||
String jsonString = outputStream.toString("UTF-8");
|
||||
// 确保 JSON 字符串以正确的字符集传递给 MySQL
|
||||
preparedStatement.setObject(i, jsonString, java.sql.Types.VARCHAR);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new SQLException("序列化失败: " + e.getMessage(), e);
|
||||
} catch (IOException e) {
|
||||
throw new SQLException("序列化IO失败: " + e.getMessage(), e);
|
||||
} catch (OutOfMemoryError e) {
|
||||
throw new SQLException("序列化时内存溢出,请减少数据量或增加JVM堆内存。", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getNullableResult(ResultSet resultSet, String s) throws SQLException {
|
||||
if (null != resultSet.getString(s)) {
|
||||
try {
|
||||
return objectMapper.readValue(resultSet.getString(s), Object.class);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new SQLException("反序列化失败", e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getNullableResult(ResultSet resultSet, int i) throws SQLException {
|
||||
if (null != resultSet.getString(i)) {
|
||||
try {
|
||||
return objectMapper.readValue(resultSet.getString(i), Object.class);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new SQLException("反序列化失败", e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
|
||||
if (null != callableStatement.getString(i)) {
|
||||
try {
|
||||
return objectMapper.readValue(callableStatement.getString(i), Object.class);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new SQLException("反序列化失败", e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
package com.xspaceagi.system.spec.common;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.ibatis.type.BaseTypeHandler;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.StreamReadConstraints;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
|
||||
/**
|
||||
* 支持泛型 List 的 JSON TypeHandler
|
||||
*/
|
||||
public abstract class ListJsonTypeHandler<T> extends BaseTypeHandler<List<T>> {
|
||||
|
||||
private static final ObjectMapper objectMapper;
|
||||
|
||||
/**
|
||||
* 最大序列化大小限制:100MB
|
||||
* 超过此大小会抛出明确的异常,而不是导致 OOM
|
||||
*/
|
||||
private static final long MAX_SERIALIZATION_SIZE = 100 * 1024 * 1024L;
|
||||
|
||||
/**
|
||||
* 最大列表元素数量限制:10000
|
||||
* 超过此数量会抛出明确的异常
|
||||
*/
|
||||
private static final int MAX_LIST_SIZE = 10000;
|
||||
|
||||
static {
|
||||
objectMapper = new ObjectMapper();
|
||||
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
|
||||
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
|
||||
// 配置 StreamReadConstraints 以支持更大的字符串长度
|
||||
// 设置最大字符串长度为 100MB (100 * 1024 * 1024 字符)
|
||||
StreamReadConstraints constraints = StreamReadConstraints.builder()
|
||||
.maxStringLength(100 * 1024 * 1024)
|
||||
.build();
|
||||
JsonFactory factory = objectMapper.getFactory();
|
||||
factory.setStreamReadConstraints(constraints);
|
||||
}
|
||||
|
||||
/**
|
||||
* 子类需要提供 TypeReference 以支持正确的泛型反序列化
|
||||
*/
|
||||
protected abstract TypeReference<List<T>> getTypeReference();
|
||||
|
||||
@Override
|
||||
public void setNonNullParameter(PreparedStatement preparedStatement, int i, List<T> list, JdbcType jdbcType)
|
||||
throws SQLException {
|
||||
if (Objects.nonNull(list)) {
|
||||
// 检查列表大小
|
||||
if (list.size() > MAX_LIST_SIZE) {
|
||||
throw new SQLException(String.format(
|
||||
"列表大小超过限制: %d > %d,无法序列化。请减少数据量或分批处理。",
|
||||
list.size(), MAX_LIST_SIZE));
|
||||
}
|
||||
|
||||
try {
|
||||
// 使用 ByteArrayOutputStream 来限制内存使用并检查大小
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
try (JsonGenerator generator = objectMapper.getFactory().createGenerator(outputStream)) {
|
||||
objectMapper.writeValue(generator, list);
|
||||
}
|
||||
|
||||
// 检查序列化后的大小
|
||||
byte[] bytes = outputStream.toByteArray();
|
||||
if (bytes.length > MAX_SERIALIZATION_SIZE) {
|
||||
throw new SQLException(String.format(
|
||||
"序列化后的数据大小超过限制: %d bytes > %d bytes (%.2f MB)。请减少数据量或分批处理。",
|
||||
bytes.length, MAX_SERIALIZATION_SIZE, bytes.length / (1024.0 * 1024.0)));
|
||||
}
|
||||
|
||||
String jsonString = outputStream.toString("UTF-8");
|
||||
// 确保 JSON 字符串以正确的字符集传递给 MySQL
|
||||
preparedStatement.setObject(i, jsonString, java.sql.Types.VARCHAR);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new SQLException("序列化失败: " + e.getMessage(), e);
|
||||
} catch (IOException e) {
|
||||
throw new SQLException("序列化IO失败: " + e.getMessage(), e);
|
||||
} catch (OutOfMemoryError e) {
|
||||
throw new SQLException(String.format(
|
||||
"序列化时内存溢出。列表大小: %d,请减少数据量或增加JVM堆内存。", list.size()), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> getNullableResult(ResultSet resultSet, String columnName) throws SQLException {
|
||||
String json = resultSet.getString(columnName);
|
||||
if (json != null && !json.isEmpty()) {
|
||||
try {
|
||||
return objectMapper.readValue(json, getTypeReference());
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new SQLException("反序列化失败: columnName=" + columnName + ", json=" + json, e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> getNullableResult(ResultSet resultSet, int columnIndex) throws SQLException {
|
||||
String json = resultSet.getString(columnIndex);
|
||||
if (json != null && !json.isEmpty()) {
|
||||
try {
|
||||
return objectMapper.readValue(json, getTypeReference());
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new SQLException("反序列化失败: columnIndex=" + columnIndex + ", json=" + json, e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> getNullableResult(CallableStatement callableStatement, int columnIndex) throws SQLException {
|
||||
String json = callableStatement.getString(columnIndex);
|
||||
if (json != null && !json.isEmpty()) {
|
||||
try {
|
||||
return objectMapper.readValue(json, getTypeReference());
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new SQLException("反序列化失败: columnIndex=" + columnIndex + ", json=" + json, e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.xspaceagi.system.spec.common;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.context.annotation.ScopedProxyMode;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
|
||||
@Getter
|
||||
@Setter
|
||||
public class LoginWrapper {
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 是否登录
|
||||
*/
|
||||
private boolean isLogin;
|
||||
|
||||
/**
|
||||
* 用户信息
|
||||
*/
|
||||
private UserContext user;
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.xspaceagi.system.spec.common;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 操作日志(SysOperatorLog)实体类
|
||||
*
|
||||
* @author p1
|
||||
* @since 2024-11-01 11:16:02
|
||||
*/
|
||||
@Schema(description = "操作日志")
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class OperatorLogContext {
|
||||
|
||||
private Long tenantId;
|
||||
/**
|
||||
* 客户端请求时间
|
||||
*/
|
||||
private Long clientTime;
|
||||
|
||||
/**
|
||||
* 客户端ip
|
||||
*/
|
||||
private String ip;
|
||||
|
||||
@Schema(description = "1:操作类型;2:访问日志")
|
||||
private Long operateType;
|
||||
|
||||
@Schema(description = "系统编码")
|
||||
private String systemCode;
|
||||
|
||||
@Schema(description = "系统名称")
|
||||
private String systemName;
|
||||
|
||||
@Schema(description = "操作对象,比如:用户表,角色表,菜单表")
|
||||
private String object;
|
||||
|
||||
@Schema(description = "操作动作,比如:新增,删除,修改,查看")
|
||||
private String action;
|
||||
|
||||
@Schema(description = "操作内容,比如评估页面")
|
||||
private String operateContent;
|
||||
|
||||
@Schema(description = "额外的操作内容信息记录,比如:更新提交的数据内容")
|
||||
private String extraContent;
|
||||
|
||||
@Schema(description = "操作人所属机构id")
|
||||
private Long orgId;
|
||||
|
||||
@Schema(description = "操作人所属机构名称")
|
||||
private String orgName;
|
||||
|
||||
@Schema(description = "创建人id")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "创建人名称")
|
||||
private String creator;
|
||||
|
||||
|
||||
@Schema(description = "操作状态,成功;失败")
|
||||
private String status;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package com.xspaceagi.system.spec.common;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.context.annotation.ScopedProxyMode;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
@Slf4j
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Component
|
||||
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
|
||||
@Getter
|
||||
@Setter
|
||||
public class RequestContext<T> implements Serializable {
|
||||
|
||||
private static ThreadLocal<RequestContext> threadLocal = new ThreadLocal<>();
|
||||
private static ThreadLocal<Set<String>> tenantIgnoreTablesLocal = new ThreadLocal<>();
|
||||
|
||||
private Long userId;
|
||||
private Long tenantId;
|
||||
private Object tenantConfig;
|
||||
private String clientIp;
|
||||
private String clientLang;
|
||||
private String clientCookieLang;
|
||||
private String lang;//最终的语言
|
||||
private Map<String, String> langMap;
|
||||
private boolean isLogin;
|
||||
private T user;
|
||||
private UserContext userContext;
|
||||
private String token;
|
||||
private String requestId;
|
||||
private Object akTarget;
|
||||
private Object userAccessKey;
|
||||
|
||||
public static <T> void set(RequestContext<T> requestContext) {
|
||||
requestContext.setRequestId(UUID.randomUUID().toString().replace("-", ""));
|
||||
threadLocal.set(requestContext);
|
||||
log.debug("RequestContext set, userId:{}, tenantId: {}", requestContext.getUserId(), requestContext.getTenantId());
|
||||
}
|
||||
|
||||
public static <T> RequestContext<T> get() {
|
||||
return threadLocal.get();
|
||||
}
|
||||
|
||||
public static <T> void remove() {
|
||||
RequestContext requestContext = get();
|
||||
log.debug("RequestContext remove, userId:{}, tenantId: {}", requestContext == null ? null : requestContext.getUserId(),
|
||||
requestContext == null ? null : requestContext.getTenantId());
|
||||
threadLocal.remove();
|
||||
tenantIgnoreTablesLocal.remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* 跨线程运行,设置一个新的租户ID,用于数据库租户隔离使用
|
||||
*
|
||||
* @param tenantId 租户ID
|
||||
*/
|
||||
public static void setThreadTenantId(Long tenantId) {
|
||||
log.debug("RequestContext setThreadTenantId, tenantId: {}", tenantId);
|
||||
RequestContext<?> requestContext = new RequestContext<>();
|
||||
requestContext.setTenantId(tenantId);
|
||||
threadLocal.set(requestContext);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取租户忽略表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static Set<String> getTenantIgnoreTables() {
|
||||
Set<String> tenantIgnoreTables = RequestContext.tenantIgnoreTablesLocal.get();
|
||||
if (tenantIgnoreTables == null) {
|
||||
RequestContext.tenantIgnoreTablesLocal.set(new HashSet<>());
|
||||
}
|
||||
return tenantIgnoreTables == null ? RequestContext.tenantIgnoreTablesLocal.get() : tenantIgnoreTables;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加忽略表
|
||||
*
|
||||
* @param clazz
|
||||
*/
|
||||
public static void addTenantIgnoreEntity(Class<?> clazz) {
|
||||
TableName tableName = clazz.getAnnotation(TableName.class);
|
||||
if (tableName != null) {
|
||||
getTenantIgnoreTables().add(tableName.value());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除忽略表
|
||||
*
|
||||
* @param clazz
|
||||
*/
|
||||
public static void removeTenantIgnoreEntity(Class<?> clazz) {
|
||||
TableName tableName = clazz.getAnnotation(TableName.class);
|
||||
if (tableName != null) {
|
||||
getTenantIgnoreTables().remove(tableName.value());
|
||||
}
|
||||
}
|
||||
|
||||
public void setUserId(Long userId) {
|
||||
log.debug("RequestContext setUserId, userId: {}", userId);
|
||||
this.userId = userId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.xspaceagi.system.spec.common;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 用户信息,从拦截器里获取到的用户信息
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class UserContext {
|
||||
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
@Schema(description = "用户ID")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "用户唯一标识,部分租户会有值")
|
||||
private String uid;
|
||||
|
||||
@Schema(description = "头像")
|
||||
private String avatar;
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
@Schema(description = "用户名")
|
||||
private String userName;
|
||||
|
||||
@Schema(description = "用户昵称")
|
||||
private String nickName;
|
||||
|
||||
@Schema(description = "管理员邮箱,密文")
|
||||
private String email;
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
@Schema(description = "手机号")
|
||||
private String phone;
|
||||
|
||||
@Schema(description = "用户状态,1:启用;-1:禁用")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "所属机构ID")
|
||||
private Long orgId;
|
||||
|
||||
@Schema(description = "所属机构名称")
|
||||
private String orgName;
|
||||
|
||||
@Schema(description = "角色类型,1:管理员角色;2:普通角色")
|
||||
private Integer roleType;
|
||||
|
||||
@Schema(description = "所属租户ID")
|
||||
private Long tenantId;
|
||||
|
||||
@Schema(description = "所属租户名称")
|
||||
private String tenantName;
|
||||
|
||||
private Object tenantConfig;
|
||||
|
||||
@Schema(description = "语言环境")
|
||||
private Map<String, String> langMap;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.xspaceagi.system.spec.config;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* EventBus配置类
|
||||
* 用于管理Guava EventBus实例
|
||||
*/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
public class EventBusConfig {
|
||||
|
||||
@Bean
|
||||
public EventBus eventBus() {
|
||||
EventBus eventBus = new EventBus();
|
||||
log.info("EventBus配置初始化完成");
|
||||
return eventBus;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.xspaceagi.system.spec.constants;
|
||||
|
||||
/**
|
||||
* i18n 内置 JSON 导出目录与命名(与 classpath {@code i18n/} 下资源一致)。
|
||||
*/
|
||||
public final class I18nSyncConstants {
|
||||
|
||||
private I18nSyncConstants() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出 i18n JSON 的默认基础路径(相对项目根目录,与权限导出同级约定)。
|
||||
*/
|
||||
public static final String I18N_JSON_EXPORT_BASE_PATH =
|
||||
"app-platform-modules/platform-system/system-application/src/main/resources/i18n";
|
||||
|
||||
/**
|
||||
* classpath 下语言列表:{@code i18n/i18n-lang-{version}.json}
|
||||
*/
|
||||
public static String buildI18nLangClasspathPath(String version) {
|
||||
return "i18n/i18n-lang-" + version + ".json";
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出文件名:{@code i18n-config-{version}.json}
|
||||
*/
|
||||
public static String buildI18nConfigExportFileName(String version) {
|
||||
return "i18n-config-" + version + ".json";
|
||||
}
|
||||
|
||||
/**
|
||||
* classpath 配置项:{@code i18n/i18n-config-{version}.json}
|
||||
*/
|
||||
public static String buildI18nConfigClasspathPath(String version) {
|
||||
return "i18n/" + buildI18nConfigExportFileName(version);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增差异文件名:{@code i18n-config-{version}-add.json}
|
||||
*/
|
||||
public static String buildI18nConfigAddFileName(String version) {
|
||||
return "i18n-config-" + version + "-add.json";
|
||||
}
|
||||
|
||||
/**
|
||||
* classpath 新增差异配置:{@code i18n/i18n-config-{version}-add.json}
|
||||
*/
|
||||
public static String buildI18nConfigAddClasspathPath(String version) {
|
||||
return "i18n/" + buildI18nConfigAddFileName(version);
|
||||
}
|
||||
|
||||
/**
|
||||
* 变更差异文件名:{@code i18n-config-{version}-update.json}
|
||||
*/
|
||||
public static String buildI18nConfigUpdateFileName(String version) {
|
||||
return "i18n-config-" + version + "-update.json";
|
||||
}
|
||||
|
||||
/**
|
||||
* classpath 变更差异配置:{@code i18n/i18n-config-{version}-update.json}
|
||||
*/
|
||||
public static String buildI18nConfigUpdateClasspathPath(String version) {
|
||||
return "i18n/" + buildI18nConfigUpdateFileName(version);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.xspaceagi.system.spec.constants;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.xspaceagi.system.spec.enums.MenuEnum.ROLE_MANAGE;
|
||||
import static com.xspaceagi.system.spec.enums.ResourceEnum.ROLE_MANAGE_BIND_MENU;
|
||||
import static com.xspaceagi.system.spec.enums.ResourceEnum.ROLE_MANAGE_QUERY;
|
||||
|
||||
public class PermissionConstants {
|
||||
private PermissionConstants() {
|
||||
}
|
||||
|
||||
// 超管必须具备的菜单
|
||||
public static Set<String> superAdminNecessaryMenus = Set.of(
|
||||
ROLE_MANAGE.getCode()
|
||||
);
|
||||
|
||||
// 超管必须具备的资源
|
||||
public static Set<String> superAdminNecessaryResources = Set.of(
|
||||
ROLE_MANAGE_QUERY.getCode(),
|
||||
ROLE_MANAGE_BIND_MENU.getCode()
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.xspaceagi.system.spec.constants;
|
||||
|
||||
/**
|
||||
* 权限同步 JSON 文件路径常量
|
||||
* <p>
|
||||
* 导出与导入使用同一目录:{@code system-application/src/main/resources/permission/}
|
||||
* 文件命名:{@code permission-{version}.json}
|
||||
* </p>
|
||||
*/
|
||||
public class PermissionSyncConstants {
|
||||
|
||||
private PermissionSyncConstants() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入权限 JSON 的 classpath 路径前缀
|
||||
* 完整路径:{@code permission/permission-{version}.json}
|
||||
*/
|
||||
public static final String PERMISSION_JSON_CLASSPATH_PREFIX = "permission/permission-";
|
||||
|
||||
/**
|
||||
* 导出权限 JSON 的默认基础路径(相对项目根目录)
|
||||
* 完整路径:{@code {basePath}/permission-{version}.json}
|
||||
*/
|
||||
public static final String PERMISSION_JSON_EXPORT_BASE_PATH = "app-platform-modules/platform-system/system-application/src/main/resources/permission";
|
||||
|
||||
/**
|
||||
* 根据版本构建 classpath 路径(导入权限用)
|
||||
*/
|
||||
public static String buildClasspathPath(String version) {
|
||||
return PERMISSION_JSON_CLASSPATH_PREFIX + version + ".json";
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据版本构建导出文件路径(导出权限用,需拼接 basePath)
|
||||
*/
|
||||
public static String buildExportFileName(String version) {
|
||||
return "permission-" + version + ".json";
|
||||
}
|
||||
|
||||
/**
|
||||
* 差异 JSON 的 classpath 路径前缀
|
||||
* 完整路径:{@code permission/permission-{toVersion}-diff.json}
|
||||
*/
|
||||
public static String buildDiffClasspathPath(String toVersion) {
|
||||
return "permission/permission-" + toVersion + "-diff.json";
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据目标版本构建差异文件名
|
||||
*/
|
||||
public static String buildDiffFileName(String toVersion) {
|
||||
return "permission-" + toVersion + "-diff.json";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package com.xspaceagi.system.spec.constants;
|
||||
|
||||
/**
|
||||
* Redis Key 常量统一管理
|
||||
* <p>
|
||||
* 系统为租户隔离架构,所有 Redis 缓存 key 均需动态加上 tenantId 实现租户隔离。
|
||||
* 格式示例:{prefix}:{tenantId}:{businessId}
|
||||
* </p>
|
||||
*/
|
||||
public class RedisKeyConstants {
|
||||
|
||||
private RedisKeyConstants() {
|
||||
// 工具类,禁止实例化
|
||||
}
|
||||
|
||||
// ==================== 权限相关缓存 ====================
|
||||
|
||||
/**
|
||||
* 用户权限缓存 key 前缀(使用Hash存储)
|
||||
* 完整 key 格式:user:permission:{tenantId}:{userId}
|
||||
*/
|
||||
public static final String USER_PERMISSION_CACHE_KEY = "user:permission:";
|
||||
|
||||
/**
|
||||
* 权限最新生效时间 key 前缀(按租户隔离,用于判断缓存是否失效)
|
||||
* 完整 key 格式:permission:latest:time:{tenantId}
|
||||
*/
|
||||
public static final String PERMISSION_LATEST_TIME_KEY = "permission:latest:time:";
|
||||
|
||||
/**
|
||||
* 构建用户权限缓存 key(租户隔离)
|
||||
*
|
||||
* @param tenantId 租户ID
|
||||
* @param userId 用户ID
|
||||
* @return user:permission:{tenantId}:{userId}
|
||||
*/
|
||||
public static String buildUserPermissionCacheKey(Long tenantId, Long userId) {
|
||||
return USER_PERMISSION_CACHE_KEY + tenantId + ":" + userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建权限最新生效时间 key(租户隔离)
|
||||
*
|
||||
* @param tenantId 租户ID
|
||||
* @return permission:latest:time:{tenantId}
|
||||
*/
|
||||
public static String buildPermissionLatestTimeKey(Long tenantId) {
|
||||
return PERMISSION_LATEST_TIME_KEY + tenantId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash存储字段名:菜单树
|
||||
*/
|
||||
public static final String HASH_FIELD_MENU_TREE = "menuTree";
|
||||
|
||||
/**
|
||||
* Hash存储字段名:资源码集合
|
||||
*/
|
||||
public static final String HASH_FIELD_RESOURCE_CODES = "resourceCodes";
|
||||
|
||||
/**
|
||||
* Hash存储字段名:数据权限
|
||||
*/
|
||||
public static final String HASH_FIELD_DATA_PERMISSION = "dataPermission";
|
||||
|
||||
/**
|
||||
* Hash存储字段名:用户角色ID集合
|
||||
*/
|
||||
public static final String HASH_FIELD_ROLE_IDS = "roleIds";
|
||||
|
||||
/**
|
||||
* Hash存储字段名:用户组ID集合
|
||||
*/
|
||||
public static final String HASH_FIELD_GROUP_IDS = "groupIds";
|
||||
|
||||
/**
|
||||
* Hash存储字段名:缓存生成时间(毫秒时间戳)
|
||||
*/
|
||||
public static final String HASH_FIELD_CACHE_TIME = "cacheTime";
|
||||
|
||||
/**
|
||||
* 用户权限相关缓存过期时间(秒)
|
||||
*/
|
||||
public static final long USER_PERMISSION_CACHE_EXPIRE_SECONDS = 24 * 60 * 60L; // 24小时
|
||||
|
||||
/**
|
||||
* 按用户清除缓存的阈值:超过此数量的用户时,改为清除全部缓存(避免大量定向删除占用资源)
|
||||
*/
|
||||
public static final int CLEAR_CACHE_BY_USER_IDS_THRESHOLD = 500;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.xspaceagi.system.spec.dto;
|
||||
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 分页查询VO
|
||||
* </p>
|
||||
*
|
||||
*/
|
||||
@Schema(description = "分页查询VO")
|
||||
public class PageQueryVo<T> {
|
||||
|
||||
@Schema(description = "分页查询过滤条件")
|
||||
private T queryFilter;
|
||||
|
||||
@NotNull(message = "pageNo is required")
|
||||
@Schema(description = "分页pageNo", required = true, example = "1")
|
||||
private Long pageNo;
|
||||
|
||||
@NotNull(message = "pageSize is required")
|
||||
@Schema(description = "分页pageSize", required = true, example = "10")
|
||||
private Long pageSize;
|
||||
|
||||
public T getQueryFilter() {
|
||||
return queryFilter;
|
||||
}
|
||||
|
||||
public void setQueryFilter(T queryFilter) {
|
||||
this.queryFilter = queryFilter;
|
||||
}
|
||||
|
||||
public Long getPageNo() {
|
||||
return pageNo;
|
||||
}
|
||||
|
||||
public void setPageNo(Long pageNo) {
|
||||
this.pageNo = pageNo;
|
||||
}
|
||||
|
||||
public Long getPageSize() {
|
||||
return pageSize;
|
||||
}
|
||||
|
||||
public void setPageSize(Long pageSize) {
|
||||
this.pageSize = pageSize;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package com.xspaceagi.system.spec.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
@Schema(description = "请求响应信息")
|
||||
public class ReqResult<T> implements Serializable {
|
||||
|
||||
public static final String SUCCESS = "0000";
|
||||
|
||||
@Schema(description = "业务状态码,0000 表示成功,其余失败", example = "0000")
|
||||
private String code = SUCCESS;
|
||||
|
||||
@Schema(description = "源系统状态码,用于问题跟踪", example = "0000")
|
||||
private String displayCode;
|
||||
|
||||
@Schema(description = "错误描述信息")
|
||||
private String message;
|
||||
|
||||
@Schema(description = "返回的具体业务数据")
|
||||
private T data = null;
|
||||
|
||||
@Schema(description = "跟踪唯一标识")
|
||||
private String tid;
|
||||
|
||||
|
||||
public ReqResult(final String code, final String displayCode, final String message) {
|
||||
this.code = code;
|
||||
this.displayCode = displayCode;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public ReqResult(String code, String message, T data) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
|
||||
public ReqResult(String code, String displayCode, String message, T data) {
|
||||
this.code = code;
|
||||
this.displayCode = displayCode;
|
||||
this.message = message;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
|
||||
public boolean isSuccess() {
|
||||
return "0000".equals(this.code);
|
||||
}
|
||||
|
||||
public static <T> ReqResult<T> success() {
|
||||
return create("0000", "成功", null);
|
||||
}
|
||||
|
||||
public static <T> ReqResult<T> success(T obj) {
|
||||
return create("0000", "success", obj);
|
||||
}
|
||||
|
||||
public static <Void> ReqResult<Void> error(String msg) {
|
||||
return create("0001", msg, null);
|
||||
}
|
||||
|
||||
public static <Void> ReqResult<Void> error(String code, String displayCode, String msg) {
|
||||
return create(code, displayCode, msg, null);
|
||||
}
|
||||
|
||||
public static <Void> ReqResult<Void> error(String code, String msg) {
|
||||
return create(code, code, msg, null);
|
||||
}
|
||||
|
||||
public static <T> ReqResult<T> create(String code, String msg, T data) {
|
||||
|
||||
return new ReqResult(code, code, msg, data);
|
||||
}
|
||||
|
||||
|
||||
public static <T> ReqResult<T> create(String displayCode, String code, String msg, T data) {
|
||||
return new ReqResult(code, displayCode, msg, data);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.xspaceagi.system.spec.enums;
|
||||
|
||||
public enum AuthTypeEnum {
|
||||
|
||||
PHONE(1, "手机"),
|
||||
EMAIL(3, "邮箱"),
|
||||
CAS(2, "CAS");
|
||||
|
||||
private int code;
|
||||
|
||||
private String description;
|
||||
|
||||
AuthTypeEnum(int code, String description) {
|
||||
this.code = code;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.xspaceagi.system.spec.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 绑定类型枚举
|
||||
*/
|
||||
@Getter
|
||||
public enum BindTypeEnum {
|
||||
|
||||
NONE(0, "NONE"),// 未绑定
|
||||
ALL(1, "ALL"),// 全部绑定
|
||||
PART( 2, "PART");//部分绑定
|
||||
|
||||
private final Integer code;
|
||||
private final String desc;
|
||||
|
||||
BindTypeEnum(Integer code, String desc) {
|
||||
this.code = code;
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public static BindTypeEnum getByCode(Integer code) {
|
||||
if (code == null) {
|
||||
return null;
|
||||
}
|
||||
for (BindTypeEnum typeEnum : values()) {
|
||||
if (typeEnum.getCode().equals(code)) {
|
||||
return typeEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isValid(Integer code) {
|
||||
return getByCode(code) != null;
|
||||
}
|
||||
|
||||
public static boolean isInValid(Integer code) {
|
||||
return !isValid(code);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.xspaceagi.system.spec.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 分类类型枚举
|
||||
*/
|
||||
@Getter
|
||||
public enum CategoryTypeEnum {
|
||||
|
||||
AGENT("Agent", "智能体"),
|
||||
PAGE_APP("PageApp", "网页应用"),
|
||||
COMPONENT("Component", "组件");
|
||||
|
||||
private final String code;
|
||||
private final String description;
|
||||
|
||||
CategoryTypeEnum(String code, String description) {
|
||||
this.code = code;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public static CategoryTypeEnum fromCode(String code) {
|
||||
for (CategoryTypeEnum type : values()) {
|
||||
if (type.getCode().equals(code)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isValid(String code) {
|
||||
return fromCode(code) != null;
|
||||
}
|
||||
|
||||
public static boolean isInValid(String code) {
|
||||
return !isValid(code);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.xspaceagi.system.spec.enums;
|
||||
|
||||
public enum CodeTypeEnum {
|
||||
LOGIN_OR_REGISTER,
|
||||
RESET_PASSWORD,
|
||||
BIND_EMAIL,
|
||||
|
||||
VERIFY_CODE
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.xspaceagi.system.spec.enums;
|
||||
|
||||
public enum ErrorCodeEnum {
|
||||
|
||||
SUCCESS("0000", "请求成功"),
|
||||
ERROR_REQUEST("0001", "请求失败"),
|
||||
INVALID_PARAM("4000", "参数错误"),
|
||||
|
||||
INVALID_INVITE_CODE("4001", "邀请码错误"),
|
||||
|
||||
PERMISSION_DENIED("4030", "无权限"),
|
||||
RESOURCE_PERMISSION_DENIED("4033", "无此资源权限"),
|
||||
UNAUTHORIZED("4010", "未登录或登录超时"),
|
||||
UNAUTHORIZED_REDIRECT("4011", "未登录或登录超时"),
|
||||
API_NOT_FOUND("4040", "接口不存在"),
|
||||
METHOD_NOT_ALLOWED("4050", "未登录或登录超时"),
|
||||
SYS_ERROR("5000", "系统异常"),
|
||||
|
||||
PROJECT_STARTING("6001", "项目启动中,请稍等"),
|
||||
|
||||
/** License 文件内容解析失败(与历史契约码 0400 对齐) */
|
||||
LICENSE_CONTENT_INVALID("0400", "许可证内容无效");
|
||||
|
||||
private String code;
|
||||
private String msg;
|
||||
|
||||
/**
|
||||
* @param code
|
||||
* @param msg
|
||||
*/
|
||||
ErrorCodeEnum(String code, String msg) {
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the code
|
||||
*/
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param code the code to set
|
||||
*/
|
||||
|
||||
/**
|
||||
* @return the msg
|
||||
*/
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.xspaceagi.system.spec.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 系统内置用户组
|
||||
*/
|
||||
@Getter
|
||||
public enum GroupEnum {
|
||||
|
||||
DEFAULT_GROUP("default_group", "默认用户组");
|
||||
|
||||
|
||||
private final String code;
|
||||
private final String name;
|
||||
|
||||
GroupEnum(String code, String name) {
|
||||
this.code = code;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public static GroupEnum getByCode(String code) {
|
||||
if (code == null) {
|
||||
return null;
|
||||
}
|
||||
for (GroupEnum resourceEnum : values()) {
|
||||
if (resourceEnum.getCode().equals(code)) {
|
||||
return resourceEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
package com.xspaceagi.system.spec.enums;
|
||||
|
||||
public enum HttpStatusEnum {
|
||||
|
||||
CONTINUE(100, "Continue", "请继续发送请求的剩余部分"),
|
||||
SWITCHING_PROTOCOLS(101, "Switching Protocols", "协议切换"),
|
||||
PROCESSING(102, "Processing", "请求将继续执行"),
|
||||
// for 103 https://news.ycombinator.com/item?id=15590049
|
||||
CHECKPOINT(103, "Checkpoint", "可以预加载"),
|
||||
OK(200, "OK", "请求已经成功处理"),
|
||||
CREATED(201, "Created", "请求已经成功处理,并创建了资源"),
|
||||
ACCEPTED(202, "Accepted", "请求已经接受,等待执行"),
|
||||
NON_AUTHORITATIVE_INFORMATION(203, "Non-Authoritative Information", "请求已经成功处理,但是信息不是原始的"),
|
||||
NO_CONTENT(204, "No Content", "请求已经成功处理,没有内容需要返回"),
|
||||
RESET_CONTENT(205, "Reset Content", "请求已经成功处理,请重置视图"),
|
||||
PARTIAL_CONTENT(206, "Partial Content", "部分Get请求已经成功处理"),
|
||||
MULTI_STATUS(207, "Multi-Status", "请求已经成功处理,将返回XML消息体"),
|
||||
ALREADY_REPORTED(208, "Already Reported", "请求已经成功处理,一个DAV的绑定成员被前一个请求枚举,并且没有被再一次包括"),
|
||||
IM_USED(226, "IM Used", "请求已经成功处理,将响应一个或者多个实例"),
|
||||
MULTIPLE_CHOICES(300, "Multiple Choices", "提供可供选择的回馈"),
|
||||
MOVED_PERMANENTLY(301, "Moved Permanently", "请求的资源已经永久转移"),
|
||||
FOUND(302, "Found", "请重新发送请求"),
|
||||
// MOVED_TEMPORARILY(302, "Moved Temporarily", "") 已经过时
|
||||
SEE_OTHER(303, "See Other", "请以Get方式请求另一个URI"),
|
||||
NOT_MODIFIED(304, "Not Modified", "资源未改变"),
|
||||
USE_PROXY(305, "Use Proxy", "请通过Location域中的代理进行访问"),
|
||||
// 306在新版本的规范中被弃用
|
||||
TEMPORARY_REDIRECT(307, "Temporary Redirect", "请求的资源临时从不同的URI响应请求"),
|
||||
RESUME_INCOMPLETE(308, "Resume Incomplete", "请求的资源已经永久转移"),
|
||||
BAD_REQUEST(400, "Bad Request", "请求错误,请修正请求"),
|
||||
UNAUTHORIZED(401, "Unauthorized", "没有被授权或者授权已经失效"),
|
||||
PAYMENT_REQUIRED(402, "Payment Required", "预留状态"),
|
||||
FORBIDDEN(403, "Forbidden", "请求被理解,但是拒绝执行"),
|
||||
NOT_FOUND(404, "Not Found", "资源未找到"),
|
||||
METHOD_NOT_ALLOWED(405, "Method Not Allowed", "请求方法不允许被执行"),
|
||||
NOT_ACCEPTABLE(406, "Not Acceptable", "请求的资源不满足请求者要求"),
|
||||
PROXY_AUTHENTICATION_REQUIRED(407, "Proxy Authentication Required", "请通过代理进行身份验证"),
|
||||
REQUEST_TIMEOUT(408, "Request Timeout", "请求超时"),
|
||||
CONFLICT(409, "Conflict", "请求冲突"),
|
||||
GONE(410, "Gone", "请求的资源不可用"),
|
||||
LENGTH_REQUIRED(411, "Length Required", "Content-Length未定义"),
|
||||
PRECONDITION_FAILED(412, "Precondition Failed", "不满足请求的先决条件"),
|
||||
REQUEST_ENTITY_TOO_LARGE(413, "Request Entity Too Large", "请求发送的实体太大"),
|
||||
REQUEST_URI_TOO_LONG(414, "Request-URI Too Long", "请求的URI超长"),
|
||||
UNSUPPORTED_MEDIA_TYPE(415, "Unsupported Media Type", "请求发送的实体类型不受支持"),
|
||||
REQUESTED_RANGE_NOT_SATISFIABLE(416, "Requested range not satisfiable", "Range指定的范围与当前资源可用范围不一致"),
|
||||
EXPECTATION_FAILED(417, "Expectation Failed", "请求头Expect中指定的预期内容无法被服务器满足"),
|
||||
// I_AM_A_TEAPOT(418, "I'm a teapot", ""), 该代码没有被服务器实现
|
||||
|
||||
// INSUFFICIENT_SPACE_ON_RESOURCE(419, "Insufficient Space On Resource", ""), 已经过时
|
||||
|
||||
// METHOD_FAILURE(420, "Method Failure", ""), 已经过时
|
||||
|
||||
// DESTINATION_LOCKED(421, "Destination Locked", ""), 已经过时
|
||||
UNPROCESSABLE_ENTITY(422, "Unprocessable Entity", "请求格式正确,但是由于含有语义错误,无法响应"),
|
||||
LOCKED(423, "Locked", "当前资源被锁定"),
|
||||
FAILED_DEPENDENCY(424, "Failed Dependency", "由于之前的请求发生错误,导致当前请求失败"),
|
||||
UPGRADE_REQUIRED(426, "Upgrade Required", "客户端需要切换到TLS1.0"),
|
||||
PRECONDITION_REQUIRED(428, "Precondition Required", "请求需要提供前置条件"),
|
||||
TOO_MANY_REQUESTS(429, "Too Many Requests", "请求过多"),
|
||||
REQUEST_HEADER_FIELDS_TOO_LARGE(431, "Request Header Fields Too Large", "请求头超大,拒绝请求"),
|
||||
INTERNAL_SERVER_ERROR(500, "Internal Server Error", "服务器内部错误"),
|
||||
NOT_IMPLEMENTED(501, "Not Implemented", "服务器不支持当前请求的部分功能"),
|
||||
BAD_GATEWAY(502, "Bad Gateway", "响应无效"),
|
||||
SERVICE_UNAVAILABLE(503, "Service Unavailable", "服务器维护或者过载,拒绝服务"),
|
||||
GATEWAY_TIMEOUT(504, "Gateway Timeout", "上游服务器超时"),
|
||||
HTTP_VERSION_NOT_SUPPORTED(505, "HTTP Version not supported", "不支持的HTTP版本"),
|
||||
VARIANT_ALSO_NEGOTIATES(506, "Variant Also Negotiates", "服务器内部配置错误"),
|
||||
INSUFFICIENT_STORAGE(507, "Insufficient Storage", "服务器无法完成存储请求所需的内容"),
|
||||
LOOP_DETECTED(508, "Loop Detected", "服务器处理请求时发现死循环"),
|
||||
BANDWIDTH_LIMIT_EXCEEDED(509, "Bandwidth Limit Exceeded", "服务器达到带宽限制"),
|
||||
NOT_EXTENDED(510, "Not Extended", "获取资源所需的策略没有被满足"),
|
||||
NETWORK_AUTHENTICATION_REQUIRED(511, "Network Authentication Required", "需要进行网络授权");
|
||||
|
||||
private final int code;
|
||||
private final String reasonPhraseUS;
|
||||
private final String reasonPhraseCN;
|
||||
|
||||
private static final int
|
||||
INFORMATIONAL = 1,
|
||||
successFUL = 2,
|
||||
REDIRECTION = 3,
|
||||
CLIENT_ERROR = 4,
|
||||
SERVER_ERROR = 5;
|
||||
|
||||
HttpStatusEnum(int code, String reasonPhraseUS, String reasonPhraseCN) {
|
||||
this.code = code;
|
||||
this.reasonPhraseUS = reasonPhraseUS;
|
||||
this.reasonPhraseCN = reasonPhraseCN;
|
||||
}
|
||||
|
||||
public int code() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String reasonPhraseUS() {
|
||||
return reasonPhraseUS;
|
||||
}
|
||||
|
||||
public String reasonPhraseCN() {
|
||||
return reasonPhraseCN;
|
||||
}
|
||||
|
||||
public static HttpStatusEnum valueOf(int code) {
|
||||
for (HttpStatusEnum httpStatus : values()) {
|
||||
if (httpStatus.code() == code) {
|
||||
return httpStatus;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("No matching constant for [" + code + "]");
|
||||
}
|
||||
|
||||
public boolean is1xxInformational() {
|
||||
return type() == INFORMATIONAL;
|
||||
}
|
||||
|
||||
public boolean is2xxSuccessful() {
|
||||
return type() == successFUL;
|
||||
}
|
||||
|
||||
public boolean is3xxRedirection() {
|
||||
return type() == REDIRECTION;
|
||||
}
|
||||
|
||||
public boolean is4xxClientError() {
|
||||
return type() == CLIENT_ERROR;
|
||||
}
|
||||
|
||||
public boolean is5xxServerError() {
|
||||
return type() == SERVER_ERROR;
|
||||
}
|
||||
|
||||
private int type() {
|
||||
return (int) code / 100;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.xspaceagi.system.spec.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 时段类型枚举
|
||||
*/
|
||||
@Getter
|
||||
public enum I18nSideEnum {
|
||||
|
||||
PC("PC", "pc"),
|
||||
Mobile("Mobile", "h5"),
|
||||
Claw("Claw", "qiming claw"),
|
||||
Backend("Backend", "backend notice");
|
||||
|
||||
private final String side;
|
||||
private final String desc;
|
||||
|
||||
I18nSideEnum(String side, String desc) {
|
||||
this.side = side;
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public static I18nSideEnum fromSide(String side) {
|
||||
if (side == null) {
|
||||
return null;
|
||||
}
|
||||
for (I18nSideEnum type : I18nSideEnum.values()) {
|
||||
if (type.getSide().equals(side)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isValid(String side) {
|
||||
return fromSide(side) != null;
|
||||
}
|
||||
|
||||
public static boolean isInValid(String code) {
|
||||
return !isValid(code);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.xspaceagi.system.spec.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 系统内置菜单(部分)特殊用到的定义到这里
|
||||
*/
|
||||
@Getter
|
||||
public enum MenuEnum {
|
||||
ROOT("root", "根节点", "根节点"),
|
||||
|
||||
ECO_MARKET("eco_market", "生态市场", "root"),
|
||||
SYSTEM_MANAGE("system_manage", "系统管理", "root"),
|
||||
|
||||
|
||||
PERMISSION_MANAGE("permission_manage", "权限管理", "system_manage"),
|
||||
RESOURCE_MANAGE("resource_manage", "资源管理", "permission_manage"),
|
||||
MENU_MANAGE("menu_manage", "菜单管理", "permission_manage"),
|
||||
ROLE_MANAGE("role_manage", "角色管理", "permission_manage"),
|
||||
USER_GROUP_MANAGE("user_group_manage", "用户组管理", "permission_manage");
|
||||
|
||||
private final String code;
|
||||
private final String name;
|
||||
private final String parentCode;
|
||||
|
||||
MenuEnum(String code, String name, String parentCode) {
|
||||
this.code = code;
|
||||
this.name = name;
|
||||
this.parentCode = parentCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据code获取枚举
|
||||
*/
|
||||
public static MenuEnum getByCode(String code) {
|
||||
if (code == null) {
|
||||
return null;
|
||||
}
|
||||
for (MenuEnum resourceEnum : values()) {
|
||||
if (resourceEnum.getCode().equals(code)) {
|
||||
return resourceEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.xspaceagi.system.spec.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 打开方式
|
||||
*/
|
||||
@Getter
|
||||
public enum OpenTypeEnum {
|
||||
|
||||
CURRENT_TAB(1, "当前标签页打开"),
|
||||
NEW_TAB(2, "新标签页打开");
|
||||
|
||||
private final Integer code;
|
||||
private final String desc;
|
||||
|
||||
OpenTypeEnum(Integer code, String desc) {
|
||||
this.code = code;
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public static OpenTypeEnum getByCode(Integer code) {
|
||||
if (code == null) {
|
||||
return null;
|
||||
}
|
||||
for (OpenTypeEnum typeEnum : values()) {
|
||||
if (typeEnum.getCode().equals(code)) {
|
||||
return typeEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isValid(Integer code) {
|
||||
return getByCode(code) != null;
|
||||
}
|
||||
|
||||
public static boolean isInValid(Integer code) {
|
||||
return !isValid(code);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.xspaceagi.system.spec.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 时段类型枚举
|
||||
*/
|
||||
@Getter
|
||||
public enum PeriodTypeEnum {
|
||||
|
||||
YEAR("YEAR", "年"),
|
||||
MONTH("MONTH", "月"),
|
||||
DAY("DAY", "天"),
|
||||
HOUR("HOUR", "时");
|
||||
|
||||
private final String code;
|
||||
private final String desc;
|
||||
|
||||
PeriodTypeEnum(String code, String desc) {
|
||||
this.code = code;
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public static PeriodTypeEnum fromCode(String code) {
|
||||
if (code == null) {
|
||||
return null;
|
||||
}
|
||||
for (PeriodTypeEnum type : PeriodTypeEnum.values()) {
|
||||
if (type.getCode().equals(code)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isValid(String code) {
|
||||
return fromCode(code) != null;
|
||||
}
|
||||
|
||||
public static boolean isInValid(String code) {
|
||||
return !isValid(code);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.xspaceagi.system.spec.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 权限主体类型枚举
|
||||
*/
|
||||
@Getter
|
||||
public enum PermissionSubjectTypeEnum {
|
||||
|
||||
MODEL(1, "模型"),
|
||||
AGENT(2, "通用智能体"),
|
||||
PAGE(3, "应用页面"),
|
||||
OPEN_API(4, "开放API"),
|
||||
KNOWLEDGE(5, "知识库");
|
||||
|
||||
private final Integer code;
|
||||
private final String desc;
|
||||
|
||||
PermissionSubjectTypeEnum(Integer code, String desc) {
|
||||
this.code = code;
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public static PermissionSubjectTypeEnum getByCode(Integer code) {
|
||||
if (code == null) {
|
||||
return null;
|
||||
}
|
||||
for (PermissionSubjectTypeEnum typeEnum : values()) {
|
||||
if (typeEnum.getCode().equals(code)) {
|
||||
return typeEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isValid(Integer code) {
|
||||
return getByCode(code) != null;
|
||||
}
|
||||
|
||||
public static boolean isInValid(Integer code) {
|
||||
return !isValid(code);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.xspaceagi.system.spec.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 来源枚举
|
||||
*/
|
||||
@Getter
|
||||
public enum PermissionTargetTypeEnum {
|
||||
|
||||
USER(1, "用户"),
|
||||
ROLE(2, "角色"),
|
||||
GROUP(3, "用户组");
|
||||
|
||||
private final Integer code;
|
||||
private final String desc;
|
||||
|
||||
PermissionTargetTypeEnum(Integer code, String desc) {
|
||||
this.code = code;
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public static PermissionTargetTypeEnum getByCode(Integer code) {
|
||||
if (code == null) {
|
||||
return null;
|
||||
}
|
||||
for (PermissionTargetTypeEnum typeEnum : values()) {
|
||||
if (typeEnum.getCode().equals(code)) {
|
||||
return typeEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isValid(Integer code) {
|
||||
return getByCode(code) != null;
|
||||
}
|
||||
|
||||
public static boolean isInValid(Integer code) {
|
||||
return !isValid(code);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,462 @@
|
||||
package com.xspaceagi.system.spec.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 系统内置资源
|
||||
*/
|
||||
@Getter
|
||||
public enum ResourceEnum {
|
||||
|
||||
ROOT(ResourceTypeEnum.MODULE, "root", "根节点", "根节点"),
|
||||
|
||||
// ================== 主页模块 ==================
|
||||
// HOMEPAGE(ResourceTypeEnum.MODULE, "homepage", "主页模块", "root"),
|
||||
|
||||
// ================== 生态市场模块 ==================
|
||||
// ECO_MARKET(ResourceTypeEnum.MODULE, "eco_market", "生态市场模块", "root"),
|
||||
|
||||
// ================== 空间模块 ==================
|
||||
SPACE(ResourceTypeEnum.MODULE, "space", "空间模块", "root"),
|
||||
// SPACE_QUERY_LIST(ResourceTypeEnum.OPERATION, "space_query_list", "查询空间列表", "space"),
|
||||
// SPACE_QUERY_DETAIL(ResourceTypeEnum.OPERATION, "space_query_detail", "查询空间详情", "space"),
|
||||
SPACE_CREATE(ResourceTypeEnum.OPERATION, "space_create", "创建团队空间", "space"),
|
||||
SPACE_MODIFY(ResourceTypeEnum.OPERATION, "space_modify", "编辑", "space"),
|
||||
SPACE_DELETE(ResourceTypeEnum.OPERATION, "space_delete", "删除空间", "space"),
|
||||
SPACE_TRANSFER(ResourceTypeEnum.OPERATION, "space_transfer", "转让空间", "space"),
|
||||
SPACE_QUERY_USER_LIST(ResourceTypeEnum.OPERATION, "space_query_user_list", "查询成员列表", "space"),
|
||||
SPACE_ADD_USER(ResourceTypeEnum.OPERATION, "space_add_user", "添加成员", "space"),
|
||||
SPACE_DELETE_USER(ResourceTypeEnum.OPERATION, "space_delete_user", "删除成员", "space"),
|
||||
|
||||
|
||||
// ================== 智能体开发模块 ==================
|
||||
AGENT_DEV(ResourceTypeEnum.MODULE, "agent_dev", "智能体开发模块", "root"),
|
||||
|
||||
AGENT_CREATE_CHAT_BOT(ResourceTypeEnum.OPERATION, "agent_create_chat_bot", "创建智能体-问答型", "agent_dev"),
|
||||
AGENT_CREATE_TASK_AGENT(ResourceTypeEnum.OPERATION, "agent_create_task_agent", "创建智能体-通用型", "agent_dev"),
|
||||
AGENT_PUBLISH(ResourceTypeEnum.OPERATION, "agent_publish", "发布", "agent_dev"),
|
||||
AGENT_IMPORT(ResourceTypeEnum.OPERATION, "agent_import", "导入配置", "agent_dev"),
|
||||
AGENT_QUERY_LIST(ResourceTypeEnum.OPERATION, "agent_query_list", "查询列表", "agent_dev"),
|
||||
AGENT_QUERY_DETAIL(ResourceTypeEnum.OPERATION, "agent_query_detail", "查询详情", "agent_dev"),
|
||||
AGENT_COLLECT(ResourceTypeEnum.OPERATION, "agent_collect", "收藏", "agent_dev"),
|
||||
AGENT_MODIFY(ResourceTypeEnum.OPERATION, "agent_modify", "编辑", "agent_dev"),
|
||||
AGENT_COPY_TO_SPACE(ResourceTypeEnum.OPERATION, "agent_copy_to_space", "复制到空间", "agent_dev"),
|
||||
AGENT_MIGRATE(ResourceTypeEnum.OPERATION, "agent_migrate", "迁移", "agent_dev"),
|
||||
AGENT_API_KEY(ResourceTypeEnum.OPERATION, "agent_api_key", "API Key", "agent_dev"),
|
||||
AGENT_EXPORT(ResourceTypeEnum.OPERATION, "agent_export", "导出配置", "agent_dev"),
|
||||
// AGENT_LOG(ResourceTypeEnum.OPERATION, "agent_log", "日志", "agent_dev"),
|
||||
AGENT_DELETE(ResourceTypeEnum.OPERATION, "agent_delete", "删除", "agent_dev"),
|
||||
//AGENT_ANALYSE(ResourceTypeEnum.OPERATION, "agent_analyse", "分析", "agent_dev"),
|
||||
AGENT_TEMP_CONVERSATION(ResourceTypeEnum.OPERATION, "agent_temp_conversation", "创建临时会话", "agent_dev"),
|
||||
|
||||
// ================== 网页应用开发模块 ==================
|
||||
PAGE_APP_DEV(ResourceTypeEnum.MODULE, "page_app_dev", "网页应用开发模块", "root"),
|
||||
|
||||
PAGE_APP_CREATE(ResourceTypeEnum.OPERATION, "page_app_create", "创建", "page_app_dev"),
|
||||
PAGE_APP_QUERY_LIST(ResourceTypeEnum.OPERATION, "page_app_query_list", "查询列表", "page_app_dev"),
|
||||
PAGE_APP_QUERY_DETAIL(ResourceTypeEnum.OPERATION, "page_app_query_detail", "查询详情", "page_app_dev"),
|
||||
PAGE_APP_MODIFY(ResourceTypeEnum.OPERATION, "page_app_modify", "编辑", "page_app_dev"),
|
||||
PAGE_APP_CONFIG_PROXY(ResourceTypeEnum.OPERATION, "page_app_config_proxy", "反向代理配置", "page_app_dev"),
|
||||
PAGE_APP_CONFIG_PATH(ResourceTypeEnum.OPERATION, "page_app_config_path", "路径参数配置", "page_app_dev"),
|
||||
//PAGE_APP_CONFIG_AUTH(ResourceTypeEnum.OPERATION, "page_app_config_auth", "认证配置", "page_app_dev"),
|
||||
PAGE_APP_COPY_TO_SPACE(ResourceTypeEnum.OPERATION, "page_app_copy_to_space", "复制到空间", "page_app_dev"),
|
||||
PAGE_APP_BIND_DOMAIN(ResourceTypeEnum.OPERATION, "page_app_bind_domain", "绑定域名", "page_app_dev"),
|
||||
PAGE_APP_IMPORT(ResourceTypeEnum.OPERATION, "page_app_import", "导入项目", "page_app_dev"),
|
||||
PAGE_APP_EXPORT(ResourceTypeEnum.OPERATION, "page_app_export", "导出项目", "page_app_dev"),
|
||||
PAGE_APP_RESTART_SERVER(ResourceTypeEnum.OPERATION, "page_app_restart_server", "重启服务器", "page_app_dev"),
|
||||
PAGE_APP_PUBLISH(ResourceTypeEnum.OPERATION, "page_app_publish", "发布", "page_app_dev"),
|
||||
PAGE_APP_DELETE(ResourceTypeEnum.OPERATION, "page_app_delete", "删除", "page_app_dev"),
|
||||
PAGE_APP_AI_CHAT(ResourceTypeEnum.OPERATION, "page_app_ai_chat", "AI对话", "page_app_dev"),
|
||||
PAGE_APP_MODIFY_FILE(ResourceTypeEnum.OPERATION, "page_app_modify_file", "修改文件", "page_app_dev"),
|
||||
PAGE_APP_UPLOAD_FILE(ResourceTypeEnum.OPERATION, "page_app_upload_file", "上传文件", "page_app_dev"),
|
||||
PAGE_APP_ROLLBACK_VERSION(ResourceTypeEnum.OPERATION, "page_app_rollback_version", "回滚版本", "page_app_dev"),
|
||||
|
||||
// ================== 组件资源模块 ==================
|
||||
COMPONENT_LIB_DEV(ResourceTypeEnum.MODULE, "component_lib_dev", "组件资源模块", "root"),
|
||||
|
||||
COMPONENT_LIB_CREATE(ResourceTypeEnum.OPERATION, "component_lib_create", "创建", "component_lib_dev"),
|
||||
COMPONENT_LIB_PUBLISH(ResourceTypeEnum.OPERATION, "component_lib_publish", "发布", "component_lib_dev"),
|
||||
COMPONENT_LIB_QUERY_LIST(ResourceTypeEnum.OPERATION, "component_lib_query_list", "查询列表", "component_lib_dev"),
|
||||
COMPONENT_LIB_QUERY_DETAIL(ResourceTypeEnum.OPERATION, "component_lib_query_detail", "查询详情", "component_lib_dev"),
|
||||
COMPONENT_LIB_MODIFY(ResourceTypeEnum.OPERATION, "component_lib_modify", "编辑", "component_lib_dev"),
|
||||
COMPONENT_LIB_COPY_TO_SPACE(ResourceTypeEnum.OPERATION, "component_lib_copy_to_space", "复制到空间", "component_lib_dev"),
|
||||
COMPONENT_LIB_COPY(ResourceTypeEnum.OPERATION, "component_lib_copy", "复制", "component_lib_dev"),
|
||||
COMPONENT_LIB_IMPORT(ResourceTypeEnum.OPERATION, "component_lib_import", "导入配置", "component_lib_dev"),
|
||||
COMPONENT_LIB_EXPORT(ResourceTypeEnum.OPERATION, "component_lib_export", "导出配置", "component_lib_dev"),
|
||||
COMPONENT_LIB_DELETE(ResourceTypeEnum.OPERATION, "component_lib_delete", "删除", "component_lib_dev"),
|
||||
|
||||
/**
|
||||
* 以下注释的插件、工作流、知识库、数据表、模型,暂时不用这么细分的控制,后续如果要区分的时候再放开
|
||||
*/
|
||||
// // ================== 插件模块 ==================
|
||||
// PLUGIN_DEV(ResourceTypeEnum.MODULE, "plugin_dev", "插件模块", "root"),
|
||||
//
|
||||
// PLUGIN_DEV_CREATE(ResourceTypeEnum.OPERATION, "plugin_dev_create", "创建", "plugin_dev"),
|
||||
// PLUGIN_DEV_PUBLISH(ResourceTypeEnum.OPERATION, "plugin_dev_publish", "发布", "plugin_dev"),
|
||||
// PLUGIN_DEV_QUERY_LIST(ResourceTypeEnum.OPERATION, "plugin_dev_query_list", "查询列表", "plugin_dev"),
|
||||
// PLUGIN_DEV_QUERY_DETAIL(ResourceTypeEnum.OPERATION, "plugin_dev_query_detail", "查询详情", "plugin_dev"),
|
||||
// PLUGIN_DEV_MODIFY(ResourceTypeEnum.OPERATION, "plugin_dev_modify", "编辑", "plugin_dev"),
|
||||
// PLUGIN_DEV_COPY_TO_SPACE(ResourceTypeEnum.OPERATION, "plugin_dev_copy_to_space", "复制到空间", "plugin_dev"),
|
||||
// PLUGIN_DEV_COPY(ResourceTypeEnum.OPERATION, "plugin_dev_copy", "复制", "plugin_dev"),
|
||||
// PLUGIN_DEV_IMPORT(ResourceTypeEnum.OPERATION, "plugin_dev_import", "导入配置", "plugin_dev"),
|
||||
// PLUGIN_DEV_EXPORT(ResourceTypeEnum.OPERATION, "plugin_dev_export", "导出配置", "plugin_dev"),
|
||||
// PLUGIN_DEV_DELETE(ResourceTypeEnum.OPERATION, "plugin_dev_delete", "删除", "plugin_dev"),
|
||||
//
|
||||
// // ================== 工作流模块 ==================
|
||||
// WORKFLOW_DEV(ResourceTypeEnum.MODULE, "workflow_dev", "插件模块", "root"),
|
||||
//
|
||||
// WORKFLOW_DEV_CREATE(ResourceTypeEnum.OPERATION, "workflow_dev_create", "创建", "workflow_dev"),
|
||||
// WORKFLOW_DEV_PUBLISH(ResourceTypeEnum.OPERATION, "workflow_dev_publish", "发布", "workflow_dev"),
|
||||
// WORKFLOW_DEV_QUERY_LIST(ResourceTypeEnum.OPERATION, "workflow_dev_query_list", "查询列表", "workflow_dev"),
|
||||
// WORKFLOW_DEV_QUERY_DETAIL(ResourceTypeEnum.OPERATION, "workflow_dev_query_detail", "查询详情", "workflow_dev"),
|
||||
// WORKFLOW_DEV_MODIFY(ResourceTypeEnum.OPERATION, "workflow_dev_modify", "编辑", "workflow_dev"),
|
||||
// WORKFLOW_DEV_COPY_TO_SPACE(ResourceTypeEnum.OPERATION, "workflow_dev_copy_to_space", "复制到空间", "workflow_dev"),
|
||||
// WORKFLOW_DEV_COPY(ResourceTypeEnum.OPERATION, "workflow_dev_copy", "复制", "workflow_dev"),
|
||||
// WORKFLOW_DEV_IMPORT(ResourceTypeEnum.OPERATION, "workflow_dev_import", "导入配置", "workflow_dev"),
|
||||
// WORKFLOW_DEV_EXPORT(ResourceTypeEnum.OPERATION, "workflow_dev_export", "导出配置", "workflow_dev"),
|
||||
// WORKFLOW_DEV_DELETE(ResourceTypeEnum.OPERATION, "workflow_dev_delete", "删除", "workflow_dev"),
|
||||
//
|
||||
// // ================== 知识库模块 ==================
|
||||
// KNOWLEDGE_DEV(ResourceTypeEnum.MODULE, "knowledge_dev", "知识库模块", "root"),
|
||||
// KNOWLEDGE_DEV_CREATE(ResourceTypeEnum.OPERATION, "knowledge_dev_create", "创建", "knowledge_dev"),
|
||||
// KNOWLEDGE_DEV_QUERY_DETAIL(ResourceTypeEnum.OPERATION, "knowledge_dev_query_detail", "查询详情", "knowledge_dev"),
|
||||
// KNOWLEDGE_DEV_MODIFY(ResourceTypeEnum.OPERATION, "knowledge_dev_modify", "编辑", "knowledge_dev"),
|
||||
// KNOWLEDGE_DEV_IMPORT(ResourceTypeEnum.OPERATION, "knowledge_dev_import", "导入配置", "knowledge_dev"),
|
||||
// KNOWLEDGE_DEV_DELETE(ResourceTypeEnum.OPERATION, "knowledge_dev_delete", "删除", "knowledge_dev"),
|
||||
//
|
||||
// // ================== 数据表模块 ==================
|
||||
// DATATABLE_DEV(ResourceTypeEnum.MODULE, "datatable_dev", "数据表模块", "root"),
|
||||
// DATATABLE_DEV_CREATE(ResourceTypeEnum.OPERATION, "datatable_dev_create", "创建", "datatable_dev"),
|
||||
// DATATABLE_DEV_QUERY_LIST(ResourceTypeEnum.OPERATION, "datatable_dev_query_list", "查询列表", "datatable_dev"),
|
||||
// DATATABLE_DEV_QUERY_DETAIL(ResourceTypeEnum.OPERATION, "datatable_dev_query_detail", "查询详情", "datatable_dev"),
|
||||
// DATATABLE_DEV_MODIFY(ResourceTypeEnum.OPERATION, "datatable_dev_modify", "编辑", "datatable_dev"),
|
||||
// DATATABLE_DEV_COPY(ResourceTypeEnum.OPERATION, "datatable_dev_copy", "复制", "datatable_dev"),
|
||||
// DATATABLE_DEV_IMPORT(ResourceTypeEnum.OPERATION, "datatable_dev_import", "导入配置", "datatable_dev"),
|
||||
// DATATABLE_DEV_EXPORT(ResourceTypeEnum.OPERATION, "datatable_dev_export", "导出配置", "datatable_dev"),
|
||||
// DATATABLE_DEV_DELETE(ResourceTypeEnum.OPERATION, "datatable_dev_delete", "删除", "datatable_dev"),
|
||||
//
|
||||
// // ================== 模型管理模块 ==================
|
||||
// MODEL_DEV(ResourceTypeEnum.MODULE, "model_dev", "模型管理模块", "root"),
|
||||
// MODEL_DEV_CREATE(ResourceTypeEnum.OPERATION, "model_dev_create", "创建", "model_dev"),
|
||||
// MODEL_DEV_QUERY_LIST(ResourceTypeEnum.OPERATION, "model_dev_query_list", "查询列表", "model_dev"),
|
||||
// MODEL_DEV_QUERY_DETAIL(ResourceTypeEnum.OPERATION, "model_dev_query_detail", "查询详情", "model_dev"),
|
||||
// MODEL_DEV_MODIFY(ResourceTypeEnum.OPERATION, "model_dev_modify", "编辑", "model_dev"),
|
||||
// MODEL_DEV_DELETE(ResourceTypeEnum.OPERATION, "model_dev_delete", "删除", "model_dev"),
|
||||
|
||||
// ================== 技能开发模块 ==================
|
||||
SKILL_DEV(ResourceTypeEnum.MODULE, "skill_dev", "技能开发模块", "root"),
|
||||
|
||||
SKILL_CREATE(ResourceTypeEnum.OPERATION, "skill_create", "创建技能", "skill_dev"),
|
||||
SKILL_QUERY_LIST(ResourceTypeEnum.OPERATION, "skill_query_list", "查询列表", "skill_dev"),
|
||||
SKILL_QUERY_DETAIL(ResourceTypeEnum.OPERATION, "skill_query_detail", "查询详情", "skill_dev"),
|
||||
SKILL_MODIFY(ResourceTypeEnum.OPERATION, "skill_modify", "编辑", "skill_dev"),
|
||||
SKILL_IMPORT(ResourceTypeEnum.OPERATION, "skill_import", "导入技能", "skill_dev"),
|
||||
SKILL_EXPORT(ResourceTypeEnum.OPERATION, "skill_export", "导出技能", "skill_dev"),
|
||||
SKILL_COPY_TO_SPACE(ResourceTypeEnum.OPERATION, "skill_copy_to_space", "复制到空间", "skill_dev"),
|
||||
SKILL_PUBLISH(ResourceTypeEnum.OPERATION, "skill_publish", "发布", "skill_dev"),
|
||||
SKILL_DELETE(ResourceTypeEnum.OPERATION, "skill_delete", "删除", "skill_dev"),
|
||||
|
||||
// ================== MCP管理模块 ==================
|
||||
MCP_DEV(ResourceTypeEnum.MODULE, "mcp_dev", "MCP管理模块", "root"),
|
||||
|
||||
MCP_CREATE(ResourceTypeEnum.OPERATION, "mcp_create", "创建MCP服务", "mcp_dev"),
|
||||
MCP_QUERY_LIST(ResourceTypeEnum.OPERATION, "mcp_query_list", "查询列表", "mcp_dev"),
|
||||
MCP_QUERY_DETAIL(ResourceTypeEnum.OPERATION, "mcp_query_detail", "查询详情", "mcp_dev"),
|
||||
MCP_SAVE(ResourceTypeEnum.OPERATION, "mcp_save", "保存", "mcp_dev"),
|
||||
MCP_EXPORT(ResourceTypeEnum.OPERATION, "mcp_export", "导出", "mcp_dev"),
|
||||
// MCP_LOG(ResourceTypeEnum.OPERATION, "mcp_log", "日志", "mcp_dev"),
|
||||
MCP_DELETE(ResourceTypeEnum.OPERATION, "mcp_delete", "删除", "mcp_dev"),
|
||||
MCP_STOP(ResourceTypeEnum.OPERATION, "mcp_stop", "停止服务", "mcp_dev"),
|
||||
|
||||
// ================== IM渠道 ==================
|
||||
IM_CONFIG(ResourceTypeEnum.MODULE, "im_config", "IM渠道配置模块", "root"),
|
||||
IM_CONFIG_QUERY_LIST(ResourceTypeEnum.MODULE, "im_config_query_list", "查询配置列表", "im_config"),
|
||||
IM_CONFIG_QUERY_DETAIL(ResourceTypeEnum.MODULE, "im_config_query_detail", "查询配置详情", "im_config"),
|
||||
IM_CONFIG_ADD(ResourceTypeEnum.MODULE, "im_config_add", "添加配置", "im_config"),
|
||||
IM_CONFIG_MODIFY(ResourceTypeEnum.MODULE, "im_config_modify", "编辑配置", "im_config"),
|
||||
IM_CONFIG_DELETE(ResourceTypeEnum.MODULE, "im_config_delete", "删除配置", "im_config"),
|
||||
// IM_CONFIG_ENABLE(ResourceTypeEnum.MODULE, "im_config_enable", "启用/禁用配置", "im_config"),
|
||||
|
||||
// ================== 任务中心模块 ==================
|
||||
SPACE_TASK_DEV(ResourceTypeEnum.MODULE, "space_task_dev", "任务中心模块", "root"),
|
||||
|
||||
SPACE_TASK_CREATE(ResourceTypeEnum.OPERATION, "space_task_create", "创建任务", "space_task_dev"),
|
||||
SPACE_TASK_QUERY_LIST(ResourceTypeEnum.OPERATION, "space_task_query_list", "查询列表", "space_task_dev"),
|
||||
SPACE_TASK_EXECUTE_MANUAL(ResourceTypeEnum.OPERATION, "space_task_execute_manual", "手动执行", "space_task_dev"),
|
||||
SPACE_TASK_CANCEL(ResourceTypeEnum.OPERATION, "space_task_cancel", "取消任务", "space_task_dev"),
|
||||
SPACE_TASK_ENABLE(ResourceTypeEnum.OPERATION, "space_task_enable", "启用", "space_task_dev"),
|
||||
// SPACE_TASK_EXECUTE_RECORD(ResourceTypeEnum.OPERATION, "space_task_execute_record", "执行记录", "space_task_dev"),
|
||||
SPACE_TASK_MODIFY(ResourceTypeEnum.OPERATION, "space_task_modify", "编辑", "space_task_dev"),
|
||||
SPACE_TASK_DELETE(ResourceTypeEnum.OPERATION, "space_task_delete", "删除", "space_task_dev"),
|
||||
|
||||
// ================== 空间日志查询模块 ==================
|
||||
SPACE_LOG_QUERY(ResourceTypeEnum.MODULE, "space_log_query", "空间日志查询模块", "root"),
|
||||
|
||||
SPACE_LOG_QUERY_LIST(ResourceTypeEnum.OPERATION, "space_log_query_list", "查询列表", "space_log_query"),
|
||||
SPACE_LOG_QUERY_DETAIL(ResourceTypeEnum.OPERATION, "space_log_query_detail", "详情", "space_log_query"),
|
||||
|
||||
// ================== 广场模块 ==================
|
||||
// SQUARE(ResourceTypeEnum.MODULE, "space_square", "空间广场模块", "root"),
|
||||
//
|
||||
// SQUARE_QUERY_LIST(ResourceTypeEnum.OPERATION, "square_query_list", "查询列表", "space_square"),
|
||||
// SQUARE_QUERY_DETAIL(ResourceTypeEnum.OPERATION, "square_query_detail", "查询详情", "space_square"),
|
||||
// SQUARE_OFFLINE(ResourceTypeEnum.OPERATION, "square_offline", "下架", "space_square"),
|
||||
// SQUARE_COLLECT(ResourceTypeEnum.OPERATION, "square_collect", "收藏", "space_square"),
|
||||
// SQUARE_COPY_TEMPLATE(ResourceTypeEnum.OPERATION, "square_copy_template", "复制模板(智能体、插件、工作流)", "space_square"),
|
||||
// SQUARE_EXPORT(ResourceTypeEnum.OPERATION, "square_export", "导出", "space_square"),
|
||||
|
||||
// ================== 用户管理模块 ==================
|
||||
USER_MANAGE(ResourceTypeEnum.MODULE, "user_manage", "用户管理模块", "root"),
|
||||
|
||||
USER_MANAGE_QUERY(ResourceTypeEnum.OPERATION, "user_manage_query", "查询用户", "user_manage"),
|
||||
USER_MANAGE_ADD(ResourceTypeEnum.OPERATION, "user_manage_add", "添加用户", "user_manage"),
|
||||
USER_MANAGE_SEND_MESSAGE(ResourceTypeEnum.OPERATION, "user_manage_send_message", "消息发送", "user_manage"),
|
||||
USER_MANAGE_ENABLE(ResourceTypeEnum.OPERATION, "user_manage_enable", "启用", "user_manage"),
|
||||
USER_MANAGE_DISABLE(ResourceTypeEnum.OPERATION, "user_manage_disable", "禁用", "user_manage"),
|
||||
USER_MANAGE_MODIFY(ResourceTypeEnum.OPERATION, "user_manage_modify", "修改", "user_manage"),
|
||||
USER_MANAGE_BIND_ROLE(ResourceTypeEnum.OPERATION, "user_manage_bind_role", "绑定角色", "user_manage"),
|
||||
USER_MANAGE_BIND_GROUP(ResourceTypeEnum.OPERATION, "user_manage_bind_group", "绑定用户组", "user_manage"),
|
||||
USER_MANAGE_QUERY_MENU_PERMISSION(ResourceTypeEnum.OPERATION, "user_manage_query_menu_permission", "查看权限", "user_manage"),
|
||||
USER_MANAGE_QUERY_DATA_PERMISSION(ResourceTypeEnum.OPERATION, "user_manage_query_data_permission", "数据权限", "user_manage"),
|
||||
|
||||
|
||||
// ================== 发布审核模块 ==================
|
||||
PUBLISH_AUDIT(ResourceTypeEnum.MODULE, "publish_audit", "发布审核模块", "root"),
|
||||
|
||||
PUBLISH_AUDIT_QUERY_LIST(ResourceTypeEnum.OPERATION, "publish_audit_query_list", "查询列表", "publish_audit"),
|
||||
PUBLISH_AUDIT_PASS(ResourceTypeEnum.OPERATION, "publish_audit_pass", "通过", "publish_audit"),
|
||||
PUBLISH_AUDIT_REJECT(ResourceTypeEnum.OPERATION, "publish_audit_reject", "拒绝", "publish_audit"),
|
||||
PUBLISH_AUDIT_QUERY_DETAIL(ResourceTypeEnum.OPERATION, "publish_audit_query_detail", "查看", "publish_audit"),
|
||||
|
||||
// ================== 已发布管理模块 ==================
|
||||
PUBLISHED_MANAGE(ResourceTypeEnum.MODULE, "published_manage", "已发布管理模块", "root"),
|
||||
|
||||
PUBLISHED_MANAGE_QUERY_LIST(ResourceTypeEnum.OPERATION, "published_manage_query_list", "查询列表", "published_manage"),
|
||||
PUBLISHED_MANAGE_OFFLINE(ResourceTypeEnum.OPERATION, "published_manage_offline", "下架", "published_manage"),
|
||||
PUBLISHED_MANAGE_QUERY_DETAIL(ResourceTypeEnum.OPERATION, "published_manage_query_detail", "查看", "published_manage"),
|
||||
|
||||
// ================== 模型管理模块 ==================
|
||||
MODEL_MANAGE(ResourceTypeEnum.MODULE, "model_manage", "模型管理模块", "root"),
|
||||
|
||||
MODEL_MANAGE_QUERY_LIST(ResourceTypeEnum.OPERATION, "model_manage_query_list", "查询列表", "model_manage"),
|
||||
MODEL_MANAGE_ADD(ResourceTypeEnum.OPERATION, "model_manage_add", "添加模型", "model_manage"),
|
||||
MODEL_MANAGE_MODIFY(ResourceTypeEnum.OPERATION, "model_manage_modify", "编辑", "model_manage"),
|
||||
MODEL_MANAGE_DELETE(ResourceTypeEnum.OPERATION, "model_manage_delete", "删除", "model_manage"),
|
||||
MODEL_MANAGE_ACCESS_CONTROL(ResourceTypeEnum.OPERATION, "model_manage_access_control", "访问授权", "model_manage"),
|
||||
|
||||
// ================== 系统设置模块 ==================
|
||||
SYSTEM_SETTING(ResourceTypeEnum.MODULE, "system_setting", "系统设置模块", "root"),
|
||||
|
||||
SYSTEM_SETTING_BASIC(ResourceTypeEnum.MODULE, "system_setting_basic", "基础配置", "system_setting"),
|
||||
SYSTEM_SETTING_MODEL_DEFAULT(ResourceTypeEnum.MODULE, "system_setting_model_default", "默认模型配置", "system_setting"),
|
||||
SYSTEM_SETTING_SITE_AGENT(ResourceTypeEnum.MODULE, "system_setting_site_agent", "站点智能体设置", "system_setting"),
|
||||
SYSTEM_SETTING_SAVE(ResourceTypeEnum.OPERATION, "system_setting_save", "保存", "system_setting"),
|
||||
|
||||
// ================== 主题配置模块 ==================
|
||||
SYSTEM_THEME_CONFIG(ResourceTypeEnum.MODULE, "system_theme_config", "主题配置模块", "root"),
|
||||
|
||||
SYSTEM_THEME_CONFIG_SAVE(ResourceTypeEnum.OPERATION, "system_theme_config_save", "保存配置", "system_theme_config"),
|
||||
|
||||
// ================== 沙盒配置模块 ==================
|
||||
SANDBOX_CONFIG(ResourceTypeEnum.MODULE, "sandbox_config", "沙盒配置模块", "root"),
|
||||
|
||||
SANDBOX_CONFIG_QUERY(ResourceTypeEnum.OPERATION, "sandbox_config_query", "查询", "sandbox_config"),
|
||||
SANDBOX_CONFIG_ADD(ResourceTypeEnum.OPERATION, "sandbox_config_add", "添加", "sandbox_config"),
|
||||
SANDBOX_CONFIG_MODIFY(ResourceTypeEnum.OPERATION, "sandbox_config_modify", "编辑", "sandbox_config"),
|
||||
SANDBOX_CONFIG_SAVE(ResourceTypeEnum.OPERATION, "sandbox_config_save", "保存", "sandbox_config"),
|
||||
SANDBOX_CONFIG_DELETE(ResourceTypeEnum.OPERATION, "sandbox_config_delete", "删除", "sandbox_config"),
|
||||
// SANDBOX_CONFIG_ENABLE(ResourceTypeEnum.OPERATION, "sandbox_config_enable", "启用/禁用", "sandbox_config"),
|
||||
|
||||
// ================== 分类管理模块 ==================
|
||||
CATEGORY_CONFIG(ResourceTypeEnum.MODULE, "category_config", "分类管理模块", "root"),
|
||||
|
||||
CATEGORY_CONFIG_QUERY(ResourceTypeEnum.OPERATION, "category_config_query", "查询", "category_config"),
|
||||
CATEGORY_CONFIG_ADD(ResourceTypeEnum.OPERATION, "category_config_add", "添加", "category_config"),
|
||||
CATEGORY_CONFIG_MODIFY(ResourceTypeEnum.OPERATION, "category_config_modify", "编辑", "category_config"),
|
||||
CATEGORY_CONFIG_DELETE(ResourceTypeEnum.OPERATION, "category_config_delete", "删除", "category_config"),
|
||||
|
||||
// ================== 系统概览模块 ==================
|
||||
SYSTEM_DASHBOARD(ResourceTypeEnum.MODULE, "system_dashboard", "系统概览查询", "root"),
|
||||
|
||||
// ================== 系统任务管理模块 ==================
|
||||
SYSTEM_TASK_MANAGE(ResourceTypeEnum.MODULE, "system_task_manage", "系统任务管理模块", "root"),
|
||||
|
||||
TASK_MANAGE_QUERY_LIST(ResourceTypeEnum.OPERATION, "task_manage_query_list", "查询列表", "system_task_manage"),
|
||||
TASK_MANAGE_EXECUTE_MANUAL(ResourceTypeEnum.OPERATION, "task_manage_execute_manual", "手动执行", "system_task_manage"),
|
||||
TASK_MANAGE_ENABLE(ResourceTypeEnum.OPERATION, "task_manage_enable", "启用", "system_task_manage"),
|
||||
TASK_MANAGE_CANCEL(ResourceTypeEnum.OPERATION, "task_manage_cancel", "停用", "system_task_manage"),
|
||||
TASK_MANAGE_EXECUTE_RECORD(ResourceTypeEnum.OPERATION, "task_manage_execute_record", "执行记录", "system_task_manage"),
|
||||
TASK_MANAGE_MODIFY(ResourceTypeEnum.OPERATION, "task_manage_modify", "编辑", "system_task_manage"),
|
||||
TASK_MANAGE_DELETE(ResourceTypeEnum.OPERATION, "task_manage_delete", "删除", "system_task_manage"),
|
||||
|
||||
// ================== 权限管理模块 ==================
|
||||
// 1级模块
|
||||
PERMISSION_MANAGE(ResourceTypeEnum.MODULE, "permission_manage", "权限管理模块", "root"),
|
||||
|
||||
// 2级模块 - 资源管理模块
|
||||
RESOURCE_MANAGE(ResourceTypeEnum.MODULE, "resource_manage", "资源管理模块", "permission_manage"),
|
||||
|
||||
RESOURCE_MANAGE_QUERY(ResourceTypeEnum.OPERATION, "resource_manage_query", "查询", "resource_manage"),
|
||||
RESOURCE_MANAGE_ADD(ResourceTypeEnum.OPERATION, "resource_manage_add", "新增", "resource_manage"),
|
||||
RESOURCE_MANAGE_MODIFY(ResourceTypeEnum.OPERATION, "resource_manage_modify", "编辑", "resource_manage"),
|
||||
RESOURCE_MANAGE_DELETE(ResourceTypeEnum.OPERATION, "resource_manage_delete", "删除", "resource_manage"),
|
||||
|
||||
// 2级模块 - 菜单管理模块
|
||||
MENU_MANAGE(ResourceTypeEnum.MODULE, "menu_manage", "菜单管理模块", "permission_manage"),
|
||||
|
||||
MENU_MANAGE_QUERY(ResourceTypeEnum.OPERATION, "menu_manage_query", "查询", "menu_manage"),
|
||||
MENU_MANAGE_ADD(ResourceTypeEnum.OPERATION, "menu_manage_add", "新增", "menu_manage"),
|
||||
MENU_MANAGE_MODIFY(ResourceTypeEnum.OPERATION, "menu_manage_modify", "编辑", "menu_manage"),
|
||||
MENU_MANAGE_DELETE(ResourceTypeEnum.OPERATION, "menu_manage_delete", "删除", "menu_manage"),
|
||||
|
||||
// 2级模块 - 角色管理模块
|
||||
ROLE_MANAGE(ResourceTypeEnum.MODULE, "role_manage", "角色管理模块", "permission_manage"),
|
||||
|
||||
ROLE_MANAGE_QUERY(ResourceTypeEnum.OPERATION, "role_manage_query", "查询", "role_manage"),
|
||||
ROLE_MANAGE_ADD(ResourceTypeEnum.OPERATION, "role_manage_add", "新增", "role_manage"),
|
||||
ROLE_MANAGE_MODIFY(ResourceTypeEnum.OPERATION, "role_manage_modify", "编辑", "role_manage"),
|
||||
ROLE_MANAGE_DELETE(ResourceTypeEnum.OPERATION, "role_manage_delete", "删除", "role_manage"),
|
||||
ROLE_MANAGE_BIND_MENU(ResourceTypeEnum.OPERATION, "role_manage_bind_menu", "菜单权限", "role_manage"),
|
||||
ROLE_MANAGE_BIND_USER(ResourceTypeEnum.OPERATION, "role_manage_bind_user", "绑定用户", "role_manage"),
|
||||
ROLE_MANAGE_BIND_DATA(ResourceTypeEnum.OPERATION, "role_manage_bind_data", "数据权限", "role_manage"),
|
||||
|
||||
// 2级模块 - 用户组管理模块
|
||||
USER_GROUP_MANAGE(ResourceTypeEnum.MODULE, "user_group_manage", "用户组管理模块", "permission_manage"),
|
||||
|
||||
USER_GROUP_MANAGE_QUERY(ResourceTypeEnum.OPERATION, "user_group_manage_query", "查询", "user_group_manage"),
|
||||
USER_GROUP_MANAGE_ADD(ResourceTypeEnum.OPERATION, "user_group_manage_add", "新增", "user_group_manage"),
|
||||
USER_GROUP_MANAGE_MODIFY(ResourceTypeEnum.OPERATION, "user_group_manage_modify", "编辑", "user_group_manage"),
|
||||
USER_GROUP_MANAGE_DELETE(ResourceTypeEnum.OPERATION, "user_group_manage_delete", "删除", "user_group_manage"),
|
||||
USER_GROUP_MANAGE_BIND_MENU(ResourceTypeEnum.OPERATION, "user_group_manage_bind_menu", "菜单权限", "user_group_manage"),
|
||||
USER_GROUP_MANAGE_BIND_USER(ResourceTypeEnum.OPERATION, "user_group_manage_bind_user", "绑定用户", "user_group_manage"),
|
||||
USER_GROUP_MANAGE_BIND_DATA(ResourceTypeEnum.OPERATION, "user_group_manage_bind_data", "数据权限", "user_group_manage"),
|
||||
|
||||
|
||||
// ================== 系统运行日志模块 ==================
|
||||
// 1级模块
|
||||
SYSTEM_LOG(ResourceTypeEnum.MODULE, "system_log", "系统日志模块", "root"),
|
||||
// 2级模块 - 系统运行日志
|
||||
SYSTEM_RUNNING_LOG(ResourceTypeEnum.MODULE, "system_running_log", "系统运行日志模块", "system_log"),
|
||||
|
||||
SYSTEM_RUNNING_LOG_QUERY_LIST(ResourceTypeEnum.OPERATION, "system_running_log_query_list", "查询列表", "system_running_log"),
|
||||
SYSTEM_RUNNING_LOG_QUERY_DETAIL(ResourceTypeEnum.OPERATION, "system_running_log_query_detail", "查询详情", "system_running_log"),
|
||||
|
||||
|
||||
// ================== 内容管理模块 ==================
|
||||
// 1级模块
|
||||
CONTENT_MANAGE(ResourceTypeEnum.MODULE, "content_manage", "内容管理模块", "root"),
|
||||
|
||||
// 2级模块 - 空间管理
|
||||
CONTENT_SPACE(ResourceTypeEnum.MODULE, "content_space", "空间管理", "content_manage"),
|
||||
|
||||
CONTENT_SPACE_QUERY_LIST(ResourceTypeEnum.OPERATION, "content_space_query_list", "查询列表", "content_space"),
|
||||
CONTENT_SPACE_QUERY_DETAIL(ResourceTypeEnum.OPERATION, "content_space_query_detail", "查询详情", "content_space"),
|
||||
CONTENT_SPACE_DELETE(ResourceTypeEnum.OPERATION, "content_space_delete", "删除", "content_space"),
|
||||
|
||||
// 2级模块 - 智能体管理
|
||||
CONTENT_AGENT(ResourceTypeEnum.MODULE, "content_agent", "智能体管理", "content_manage"),
|
||||
|
||||
CONTENT_AGENT_QUERY_LIST(ResourceTypeEnum.OPERATION, "content_agent_query_list", "查询列表", "content_agent"),
|
||||
CONTENT_AGENT_QUERY_DETAIL(ResourceTypeEnum.OPERATION, "content_agent_query_detail", "查询详情", "content_agent"),
|
||||
CONTENT_AGENT_DELETE(ResourceTypeEnum.OPERATION, "content_agent_delete", "删除", "content_agent"),
|
||||
CONTENT_AGENT_ACCESS_CONTROL(ResourceTypeEnum.OPERATION, "content_agent_access_control", "访问授权", "content_agent"),
|
||||
|
||||
// 2级模块 - 网页应用管理
|
||||
CONTENT_PAGE_APP(ResourceTypeEnum.MODULE, "content_page_app", "网页应用管理", "content_manage"),
|
||||
|
||||
CONTENT_PAGE_APP_QUERY_LIST(ResourceTypeEnum.OPERATION, "content_page_app_query_list", "查询列表", "content_page_app"),
|
||||
CONTENT_PAGE_APP_QUERY_DETAIL(ResourceTypeEnum.OPERATION, "content_page_app_query_detail", "查询详情", "content_page_app"),
|
||||
CONTENT_PAGE_APP_DELETE(ResourceTypeEnum.OPERATION, "content_page_app_delete", "删除", "content_page_app"),
|
||||
CONTENT_PAGE_APP_ACCESS_CONTROL(ResourceTypeEnum.OPERATION, "content_page_app_access_control", "访问授权", "content_page_app"),
|
||||
|
||||
// 2级模块 - 知识库管理
|
||||
CONTENT_KNOWLEDGE(ResourceTypeEnum.MODULE, "content_knowledge", "知识库管理", "content_manage"),
|
||||
|
||||
CONTENT_KNOWLEDGE_QUERY_LIST(ResourceTypeEnum.OPERATION, "content_knowledge_query_list", "查询列表", "content_knowledge"),
|
||||
CONTENT_KNOWLEDGE_QUERY_DETAIL(ResourceTypeEnum.OPERATION, "content_knowledge_query_detail", "查询详情", "content_knowledge"),
|
||||
CONTENT_KNOWLEDGE_DELETE(ResourceTypeEnum.OPERATION, "content_knowledge_delete", "删除", "content_knowledge"),
|
||||
CONTENT_KNOWLEDGE_ACCESS_CONTROL(ResourceTypeEnum.OPERATION, "content_knowledge_access_control", "访问授权", "content_knowledge"),
|
||||
|
||||
// 2级模块 - 数据表管理
|
||||
CONTENT_DATATABLE(ResourceTypeEnum.MODULE, "content_datatable", "数据表管理", "content_manage"),
|
||||
|
||||
CONTENT_DATATABLE_QUERY_LIST(ResourceTypeEnum.OPERATION, "content_datatable_query_list", "查询列表", "content_datatable"),
|
||||
CONTENT_DATATABLE_QUERY_DETAIL(ResourceTypeEnum.OPERATION, "content_datatable_query_detail", "查询详情", "content_datatable"),
|
||||
CONTENT_DATATABLE_DELETE(ResourceTypeEnum.OPERATION, "content_datatable_delete", "删除", "content_datatable"),
|
||||
|
||||
// 2级模块 - 工作流管理
|
||||
CONTENT_WORKFLOW(ResourceTypeEnum.MODULE, "content_workflow", "工作流管理", "content_manage"),
|
||||
|
||||
CONTENT_WORKFLOW_QUERY_LIST(ResourceTypeEnum.OPERATION, "content_workflow_query_list", "查询列表", "content_workflow"),
|
||||
CONTENT_WORKFLOW_QUERY_DETAIL(ResourceTypeEnum.OPERATION, "content_workflow_query_detail", "查询详情", "content_workflow"),
|
||||
CONTENT_WORKFLOW_DELETE(ResourceTypeEnum.OPERATION, "content_workflow_delete", "删除", "content_workflow"),
|
||||
|
||||
// 2级模块 - 插件管理
|
||||
CONTENT_PLUGIN(ResourceTypeEnum.MODULE, "content_plugin", "插件管理", "content_manage"),
|
||||
|
||||
CONTENT_PLUGIN_QUERY_LIST(ResourceTypeEnum.OPERATION, "content_plugin_query_list", "查询列表", "content_plugin"),
|
||||
CONTENT_PLUGIN_QUERY_DETAIL(ResourceTypeEnum.OPERATION, "content_plugin_query_detail", "查询详情", "content_plugin"),
|
||||
CONTENT_PLUGIN_DELETE(ResourceTypeEnum.OPERATION, "content_plugin_delete", "删除", "content_plugin"),
|
||||
|
||||
// 2级模块 - MCP管理
|
||||
CONTENT_MCP(ResourceTypeEnum.MODULE, "content_mcp", "MCP管理", "content_manage"),
|
||||
|
||||
CONTENT_MCP_QUERY_LIST(ResourceTypeEnum.OPERATION, "content_mcp_query_list", "查询列表", "content_mcp"),
|
||||
CONTENT_MCP_QUERY_DETAIL(ResourceTypeEnum.OPERATION, "content_mcp_query_detail", "查询详情", "content_mcp"),
|
||||
CONTENT_MCP_DELETE(ResourceTypeEnum.OPERATION, "content_mcp_delete", "删除", "content_mcp"),
|
||||
|
||||
// 2级模块 - 技能管理
|
||||
CONTENT_SKILL(ResourceTypeEnum.MODULE, "content_skill", "技能管理", "content_manage"),
|
||||
|
||||
CONTENT_SKILL_QUERY_LIST(ResourceTypeEnum.OPERATION, "content_skill_query_list", "查询列表", "content_skill"),
|
||||
CONTENT_SKILL_QUERY_DETAIL(ResourceTypeEnum.OPERATION, "content_skill_query_detail", "查询详情", "content_skill"),
|
||||
CONTENT_SKILL_DELETE(ResourceTypeEnum.OPERATION, "content_skill_delete", "删除", "content_skill"),
|
||||
|
||||
// ================== 多语言管理模块 ==================
|
||||
I18N_LANG_MANAGE(ResourceTypeEnum.MODULE, "i18n_lang_manage", "多语言管理模块", "root"),
|
||||
I18N_LANG_QUERY(ResourceTypeEnum.OPERATION, "i18n_lang_query", "查询", "i18n_lang_manage"),
|
||||
I18N_LANG_ADD(ResourceTypeEnum.OPERATION, "i18n_lang_add", "新增", "i18n_lang_manage"),
|
||||
I18N_LANG_MODIFY(ResourceTypeEnum.OPERATION, "i18n_lang_modify", "编辑", "i18n_lang_manage"),
|
||||
I18N_LANG_DELETE(ResourceTypeEnum.OPERATION, "i18n_lang_delete", "删除", "i18n_lang_manage"),
|
||||
I18N_LANG_TRANSLATE(ResourceTypeEnum.OPERATION, "i18n_lang_translate", "翻译", "i18n_lang_manage"),
|
||||
|
||||
// ================== 订阅与积分模块 ==================
|
||||
SUBSCRIPTION_POINTS(ResourceTypeEnum.MODULE, "subscription_points", "订阅与积分模块", "root"),
|
||||
SUBSCRIPTION_POINTS_QUERY(ResourceTypeEnum.OPERATION, "subscription_points_query", "查询", "subscription_points"),
|
||||
SUBSCRIPTION_POINTS_MODIFY(ResourceTypeEnum.OPERATION, "subscription_points_modify", "编辑", "subscription_points"),
|
||||
SUBSCRIPTION_POINTS_DELETE(ResourceTypeEnum.OPERATION, "subscription_points_delete", "删除", "subscription_points"),
|
||||
|
||||
// ================== 支付与收益模块 ==================
|
||||
PAY_EARNINGS(ResourceTypeEnum.MODULE, "pay_earnings", "支付与收益模块", "root"),
|
||||
PAY_EARNINGS_QUERY(ResourceTypeEnum.OPERATION, "pay_earnings_query", "查询", "pay_earnings"),
|
||||
PAY_EARNINGS_MODIFY(ResourceTypeEnum.OPERATION, "pay_earnings_modify", "编辑", "pay_earnings"),
|
||||
MERCHANT_ONBOARDING_AUDIT(ResourceTypeEnum.OPERATION, "merchant_onboarding_audit", "进件审核", "pay_earnings"),
|
||||
WITHDRAW_AUDIT(ResourceTypeEnum.OPERATION, "withdraw_audit", "提现审核", "pay_earnings");
|
||||
|
||||
private final ResourceTypeEnum type;
|
||||
private final String code;
|
||||
private final String name;
|
||||
private final String parentCode;
|
||||
|
||||
ResourceEnum(ResourceTypeEnum type, String code, String name, String parentCode) {
|
||||
this.type = type;
|
||||
this.code = code;
|
||||
this.name = name;
|
||||
this.parentCode = parentCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据code获取枚举
|
||||
*/
|
||||
public static ResourceEnum getByCode(String code) {
|
||||
if (code == null) {
|
||||
return null;
|
||||
}
|
||||
for (ResourceEnum resourceEnum : values()) {
|
||||
if (resourceEnum.getCode().equals(code)) {
|
||||
return resourceEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.xspaceagi.system.spec.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 资源类型枚举
|
||||
*/
|
||||
@Getter
|
||||
public enum ResourceTypeEnum {
|
||||
|
||||
MODULE(1, "模块"),
|
||||
OPERATION(2, "组件");
|
||||
|
||||
private final Integer code;
|
||||
private final String desc;
|
||||
|
||||
ResourceTypeEnum(Integer code, String desc) {
|
||||
this.code = code;
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public static ResourceTypeEnum getByCode(Integer code) {
|
||||
if (code == null) {
|
||||
return null;
|
||||
}
|
||||
for (ResourceTypeEnum typeEnum : values()) {
|
||||
if (typeEnum.getCode().equals(code)) {
|
||||
return typeEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isValid(Integer code) {
|
||||
return getByCode(code) != null;
|
||||
}
|
||||
|
||||
public static boolean isInValid(Integer code) {
|
||||
return !isValid(code);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.xspaceagi.system.spec.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 重试进度
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum RetryProgress {
|
||||
|
||||
INIT(1, "初次上报"),
|
||||
OVERFLOW(2, "重试超过最大次数"),
|
||||
SUCCESS(3, "成功"),
|
||||
;
|
||||
|
||||
private Integer value;
|
||||
private String desc;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.xspaceagi.system.spec.enums;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IEnum;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 状态,1待重试,2重试成功,3重试失败,4禁止重试
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum RetryStatusEnum implements IEnum<Integer> {
|
||||
|
||||
WAIT(1, "待重试"),
|
||||
SUCCESS(2, "重试成功"),
|
||||
FAIL(3, "重试失败"),
|
||||
BAN(4, "禁止重试"),
|
||||
;
|
||||
|
||||
private final Integer value;
|
||||
|
||||
private final String desc;
|
||||
|
||||
public static boolean canRetry(RetryStatusEnum status) {
|
||||
return WAIT.equals(status);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.xspaceagi.system.spec.enums;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IEnum;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 重试类型,1 异常数据需要重试 2 正常数据不需要重试
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum RetryTypeEnum implements IEnum<Integer> {
|
||||
|
||||
Y(1, "异常数据需要重试"),
|
||||
N(2, "正常数据不需要重试"),
|
||||
;
|
||||
|
||||
private final Integer value;
|
||||
|
||||
private final String desc;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.xspaceagi.system.spec.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 系统内置角色
|
||||
*/
|
||||
@Getter
|
||||
public enum RoleEnum {
|
||||
|
||||
SUPER_ADMIN("super_admin", "超级管理员");
|
||||
|
||||
|
||||
private final String code;
|
||||
private final String name;
|
||||
|
||||
RoleEnum(String code, String name) {
|
||||
this.code = code;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public static RoleEnum getByCode(String code) {
|
||||
if (code == null) {
|
||||
return null;
|
||||
}
|
||||
for (RoleEnum resourceEnum : values()) {
|
||||
if (resourceEnum.getCode().equals(code)) {
|
||||
return resourceEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.xspaceagi.system.spec.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 来源枚举
|
||||
*/
|
||||
@Getter
|
||||
public enum SourceEnum {
|
||||
|
||||
SYSTEM(1, "系统内置"),
|
||||
CUSTOM(2, "用户自定义");
|
||||
|
||||
private final Integer code;
|
||||
private final String desc;
|
||||
|
||||
SourceEnum(Integer code, String desc) {
|
||||
this.code = code;
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public static SourceEnum getByCode(Integer code) {
|
||||
if (code == null) {
|
||||
return null;
|
||||
}
|
||||
for (SourceEnum typeEnum : values()) {
|
||||
if (typeEnum.getCode().equals(code)) {
|
||||
return typeEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isValid(Integer code) {
|
||||
return getByCode(code) != null;
|
||||
}
|
||||
|
||||
public static boolean isInValid(Integer code) {
|
||||
return !isValid(code);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.xspaceagi.system.spec.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 状态枚举
|
||||
*/
|
||||
@Getter
|
||||
public enum StatusEnum {
|
||||
|
||||
DISABLED(0, "禁用"),
|
||||
ENABLED(1, "启用");
|
||||
|
||||
private final Integer code;
|
||||
private final String desc;
|
||||
|
||||
StatusEnum(Integer code, String desc) {
|
||||
this.code = code;
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public static StatusEnum getByCode(Integer code) {
|
||||
if (code == null) {
|
||||
return null;
|
||||
}
|
||||
for (StatusEnum statusEnum : values()) {
|
||||
if (statusEnum.getCode().equals(code)) {
|
||||
return statusEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isEnabled(Integer code) {
|
||||
return ENABLED.getCode().equals(code);
|
||||
}
|
||||
|
||||
public static boolean isValid(Integer code) {
|
||||
return getByCode(code) != null;
|
||||
}
|
||||
|
||||
public static boolean isInValid(Integer code) {
|
||||
return !isValid(code);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
//package com.xspaceagi.system.spec.enums;
|
||||
//
|
||||
//import lombok.Getter;
|
||||
//
|
||||
///**
|
||||
// * 系统内置用户组
|
||||
// */
|
||||
//@Getter
|
||||
//public enum SysBuiltinGroupEnum {
|
||||
//
|
||||
// DEFAULT_GROUP("default_group", "默认用户组", "系统默认用户组", 1);
|
||||
//
|
||||
// /**
|
||||
// * 用户组编码
|
||||
// */
|
||||
// private final String code;
|
||||
//
|
||||
// /**
|
||||
// * 用户组名称
|
||||
// */
|
||||
// private final String name;
|
||||
//
|
||||
// /**
|
||||
// * 用户组描述
|
||||
// */
|
||||
// private final String description;
|
||||
//
|
||||
// /**
|
||||
// * 排序索引
|
||||
// */
|
||||
// private final Integer sortIndex;
|
||||
//
|
||||
// SysBuiltinGroupEnum(String code, String name, String description, Integer sortIndex) {
|
||||
// this.code = code;
|
||||
// this.name = name;
|
||||
// this.description = description;
|
||||
// this.sortIndex = sortIndex;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 根据code获取枚举
|
||||
// */
|
||||
// public static SysBuiltinGroupEnum getByCode(String code) {
|
||||
// if (code == null) {
|
||||
// return null;
|
||||
// }
|
||||
// for (SysBuiltinGroupEnum groupEnum : values()) {
|
||||
// if (groupEnum.getCode().equals(code)) {
|
||||
// return groupEnum;
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,52 @@
|
||||
//package com.xspaceagi.system.spec.enums;
|
||||
//
|
||||
//import lombok.Getter;
|
||||
//
|
||||
//import java.util.Arrays;
|
||||
//import java.util.List;
|
||||
//import java.util.stream.Collectors;
|
||||
//
|
||||
///**
|
||||
// * 系统内置用户组-菜单关联
|
||||
// */
|
||||
//@Getter
|
||||
//public enum SysBuiltinGroupMenuEnum {
|
||||
//
|
||||
// GROUP_MENU_EXAMPLE("default_group", "root", BindTypeEnum.ALL);
|
||||
//
|
||||
// //PLACEHOLDER("__PLACEHOLDER__", "__PLACEHOLDER__", BindTypeEnum.NONE, BindTypeEnum.NONE);
|
||||
//
|
||||
// /**
|
||||
// * 用户组编码
|
||||
// */
|
||||
// private final String groupCode;
|
||||
//
|
||||
// /**
|
||||
// * 菜单编码
|
||||
// */
|
||||
// private final String menuCode;
|
||||
//
|
||||
// /**
|
||||
// * 子菜单绑定类型
|
||||
// */
|
||||
// private final BindTypeEnum menuBindType;
|
||||
//
|
||||
// SysBuiltinGroupMenuEnum(String groupCode, String menuCode, BindTypeEnum menuBindType) {
|
||||
// this.groupCode = groupCode;
|
||||
// this.menuCode = menuCode;
|
||||
// this.menuBindType = menuBindType;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 根据用户组编码获取关联的菜单列表
|
||||
// */
|
||||
// public static List<SysBuiltinGroupMenuEnum> getByGroupCode(String groupCode) {
|
||||
// if (groupCode == null) {
|
||||
// return List.of();
|
||||
// }
|
||||
// return Arrays.stream(values())
|
||||
// .filter(enumItem -> enumItem.getGroupCode().equals(groupCode))
|
||||
// .filter(enumItem -> !"__PLACEHOLDER__".equals(enumItem.getGroupCode()))
|
||||
// .collect(Collectors.toList());
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,121 @@
|
||||
//package com.xspaceagi.system.spec.enums;
|
||||
//
|
||||
//import lombok.Getter;
|
||||
//
|
||||
///**
|
||||
// * 系统内置菜单枚举
|
||||
// */
|
||||
//@Getter
|
||||
//public enum SysBuiltinMenuEnum {
|
||||
//
|
||||
// ROOT("root", "根菜单", "根菜单", null, null, "https://avatars.githubusercontent.com/u/41285659", 0),
|
||||
//
|
||||
// // 系统管理
|
||||
// SYS_MANAGE("sys_manage", "系统管理", "系统管理", "root", null, "https://avatars.githubusercontent.com/u/41285659", 0),
|
||||
//
|
||||
// // 用户管理
|
||||
// SYS_USER_MANAGE("sys_user_manage", "用户管理", "用户管理", "sys_manage", null, "https://avatars.githubusercontent.com/u/41285659", 0),
|
||||
//
|
||||
// // 发布管理
|
||||
// SYS_PUBLISH_MANAGE("sys_publish_manage", "发布管理", "发布管理", "sys_manage", null, "https://avatars.githubusercontent.com/u/41285659", 0),
|
||||
// SYS_PUBLISH_APPROVE("sys_publish_approve", "发布审核", "发布审核", "sys_publish_manage", null, "https://avatars.githubusercontent.com/u/41285659", 0),
|
||||
// SYS_PUBLISHED("sys_published", "已发布管理", "已发布管理", "sys_publish_manage", null, "https://avatars.githubusercontent.com/u/41285659", 0),
|
||||
//
|
||||
// // 模型管理
|
||||
// SYS_MODEL_MANAGE("sys_model_manage", "模型管理", "模型管理", "sys_manage", null, "https://avatars.githubusercontent.com/u/41285659", 0),
|
||||
//
|
||||
// // 系统配置
|
||||
//
|
||||
// // 主题配置
|
||||
//
|
||||
// // 系统概览
|
||||
//
|
||||
// // 菜单权限
|
||||
// SYS_MENU_MANAGE("sys_menu_manage", "菜单权限", "菜单权限", "sys_manage", null, "https://avatars.githubusercontent.com/u/41285659", 0),
|
||||
// SYS_RESOURCE("sys_resource", "权限资源", "权限资源", "sys_manage", null, "https://avatars.githubusercontent.com/u/41285659", 0),
|
||||
//
|
||||
// // 日志查询
|
||||
//
|
||||
// // 内容管理
|
||||
//
|
||||
// // 首页
|
||||
// HOMEPAGE("homepage", "首页", "首页", "root", null, "https://avatars.githubusercontent.com/u/41285659", 0),
|
||||
//
|
||||
// // 工作空间
|
||||
// WORKSPACE("workspace", "工作空间", "工作空间", "root", null, "https://avatars.githubusercontent.com/u/41285659", 0),
|
||||
//
|
||||
// AGENT_DEV("agent_dev", "智能体开发", "智能体开发", "workspace", null, "https://avatars.githubusercontent.com/u/41285659", 0),
|
||||
// PAGE_APP_DEV("page_app_dev", "网页应用开发", "网页应用开发", "workspace", null, "https://avatars.githubusercontent.com/u/41285659", 0),
|
||||
// COMPONENT_DEV("component_dev", "组件库", "组件库", "workspace", null, "https://avatars.githubusercontent.com/u/41285659", 0),
|
||||
// SKILL_DEV("skill_dev", "技能管理", "技能管理", "workspace", null, "https://avatars.githubusercontent.com/u/41285659", 0),
|
||||
// MCP_DEV("mcp_dev", "MCP管理", "MCP管理", "workspace", null, "https://avatars.githubusercontent.com/u/41285659", 0),
|
||||
// TASK_MANAGE("task_manage", "任务中心", "任务中心", "workspace", null, "https://avatars.githubusercontent.com/u/41285659", 0),
|
||||
// LOG_MANAGE("log_manage", "日志查询", "日志查询", "workspace", null, "https://avatars.githubusercontent.com/u/41285659", 0),
|
||||
// SPACE_SQUARE("space_square", "空间广场", "空间广场", "workspace", null, "https://avatars.githubusercontent.com/u/41285659", 0),
|
||||
//
|
||||
// SQUARE("square", "广场", "广场", "root", null, "https://avatars.githubusercontent.com/u/41285659", 0),
|
||||
//
|
||||
// ECO_MARKET("eco_market", "生态市场", "生态市场", "root", null, "https://avatars.githubusercontent.com/u/41285659", 0);
|
||||
//
|
||||
// //PLACEHOLDER("__PLACEHOLDER__", "__占位符__", "__占位符__", null, "", "", 0);
|
||||
//
|
||||
// /**
|
||||
// * 菜单编码
|
||||
// */
|
||||
// private final String code;
|
||||
//
|
||||
// /**
|
||||
// * 菜单名称
|
||||
// */
|
||||
// private final String name;
|
||||
//
|
||||
// /**
|
||||
// * 菜单描述
|
||||
// */
|
||||
// private final String description;
|
||||
//
|
||||
// /**
|
||||
// * 父级菜单编码(如果为 null 或空字符串,则表示根菜单)
|
||||
// */
|
||||
// private final String parentCode;
|
||||
//
|
||||
// /**
|
||||
// * 访问路径/路由地址
|
||||
// */
|
||||
// private final String path;
|
||||
//
|
||||
// /**
|
||||
// * 图标
|
||||
// */
|
||||
// private final String icon;
|
||||
//
|
||||
// /**
|
||||
// * 排序索引
|
||||
// */
|
||||
// private final Integer sortIndex;
|
||||
//
|
||||
// SysBuiltinMenuEnum(String code, String name, String description, String parentCode, String path, String icon, Integer sortIndex) {
|
||||
// this.code = code;
|
||||
// this.name = name;
|
||||
// this.description = description;
|
||||
// this.parentCode = parentCode;
|
||||
// this.path = path;
|
||||
// this.icon = icon;
|
||||
// this.sortIndex = sortIndex;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 根据code获取枚举
|
||||
// */
|
||||
// public static SysBuiltinMenuEnum getByCode(String code) {
|
||||
// if (code == null) {
|
||||
// return null;
|
||||
// }
|
||||
// for (SysBuiltinMenuEnum menuEnum : values()) {
|
||||
// if (menuEnum.getCode().equals(code)) {
|
||||
// return menuEnum;
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,143 @@
|
||||
//package com.xspaceagi.system.spec.enums;
|
||||
//
|
||||
//import java.util.Arrays;
|
||||
//import java.util.List;
|
||||
//import java.util.stream.Collectors;
|
||||
//
|
||||
//import lombok.Getter;
|
||||
//
|
||||
///**
|
||||
// * 系统内置菜单-资源关联
|
||||
// */
|
||||
//@Getter
|
||||
//public enum SysBuiltinMenuResourceEnum {
|
||||
//
|
||||
// ROOT(SysBuiltinMenuEnum.ROOT.getCode(), SysBuiltinResourceEnum.ROOT.getCode(), BindTypeEnum.ALL),
|
||||
//
|
||||
// // 系统管理
|
||||
// //SYS_MANAGE_RESOURCE("sys_manage", "sys_manage", BindTypeEnum.ALL),
|
||||
//
|
||||
// // 用户管理
|
||||
// SYS_USER_MANAGE_RESOURCE(SysBuiltinMenuEnum.SYS_USER_MANAGE.getCode(), SysBuiltinResourceEnum.SYS_USER_MANAGE.getCode(), BindTypeEnum.ALL),
|
||||
//// SYS_USER_MANAGE_QUERY(SysBuiltinMenuEnum.SYS_USER_MANAGE.getCode(), SysBuiltinResourceEnum.SYS_USER_QUERY.getCode(), BindTypeEnum.ALL),
|
||||
//// SYS_USER_MANAGE_ADD(SysBuiltinMenuEnum.SYS_USER_MANAGE.getCode(), SysBuiltinResourceEnum.SYS_USER_ADD.getCode(), BindTypeEnum.ALL),
|
||||
//// SYS_USER_MANAGE_EDIT(SysBuiltinMenuEnum.SYS_USER_MANAGE.getCode(), SysBuiltinResourceEnum.SYS_USER_EDIT.getCode(), BindTypeEnum.ALL),
|
||||
//// SYS_USER_MANAGE_DELETE(SysBuiltinMenuEnum.SYS_USER_MANAGE.getCode(), SysBuiltinResourceEnum.SYS_USER_DELETE.getCode(), BindTypeEnum.ALL),
|
||||
//// SYS_USER_MANAGE_ENABLE(SysBuiltinMenuEnum.SYS_USER_MANAGE.getCode(), SysBuiltinResourceEnum.SYS_USER_ENABLE.getCode(), BindTypeEnum.ALL),
|
||||
//
|
||||
// // 发布管理
|
||||
// SYS_PUBLISH_MANAGE(SysBuiltinMenuEnum.SYS_PUBLISH_MANAGE.getCode(), SysBuiltinResourceEnum.SYS_PUBLISH_MANAGE.getCode(), BindTypeEnum.ALL),
|
||||
//
|
||||
// // 发布审核
|
||||
//// SYS_PUBLISH_APPROVE_RESOURCE(SysBuiltinMenuEnum.SYS_PUBLISH_APPROVE.getCode(), SysBuiltinResourceEnum.SYS_PUBLISH_APPROVE.getCode(), BindTypeEnum.ALL),
|
||||
//// SYS_PUBLISH_APPROVE_QUERY(SysBuiltinMenuEnum.SYS_PUBLISH_APPROVE.getCode(), SysBuiltinResourceEnum.SYS_PUBLISH_APPROVE_QUERY.getCode(), BindTypeEnum.ALL),
|
||||
//// SYS_PUBLISH_APPROVE_SUBMIT(SysBuiltinMenuEnum.SYS_PUBLISH_APPROVE.getCode(), SysBuiltinResourceEnum.SYS_PUBLISH_APPROVE_SUBMIT.getCode(), BindTypeEnum.ALL),
|
||||
//
|
||||
// // 已发布管理
|
||||
//// SYS_PUBLISHED_RESOURCE(SysBuiltinMenuEnum.SYS_PUBLISHED.getCode(), SysBuiltinResourceEnum.SYS_PUBLISHED.getCode(), BindTypeEnum.ALL),
|
||||
//
|
||||
// // 模型管理
|
||||
// SYS_MODEL_MANAGE_RESOURCE(SysBuiltinMenuEnum.SYS_MODEL_MANAGE.getCode(), SysBuiltinResourceEnum.SYS_MODEL_MANAGE.getCode(), BindTypeEnum.ALL),
|
||||
//
|
||||
// // 首页
|
||||
// HOMEPAGE_RESOURCE(SysBuiltinMenuEnum.HOMEPAGE.getCode(), SysBuiltinResourceEnum.HOMEPAGE.getCode(), BindTypeEnum.ALL),
|
||||
//
|
||||
// // 工作空间
|
||||
// WORKSPACE_RESOURCE(SysBuiltinMenuEnum.WORKSPACE.getCode(), SysBuiltinResourceEnum.WORKSPACE.getCode(), BindTypeEnum.ALL),
|
||||
//
|
||||
// // 智能体开发
|
||||
// AGENT_DEV_RESOURCE(SysBuiltinMenuEnum.AGENT_DEV.getCode(), SysBuiltinResourceEnum.AGENT_DEV.getCode(), BindTypeEnum.ALL),
|
||||
//// AGENT_DEV_ADD(SysBuiltinMenuEnum.AGENT_DEV.getCode(), SysBuiltinResourceEnum.AGENT_ADD.getCode(), BindTypeEnum.ALL),
|
||||
//// AGENT_DEV_EDIT(SysBuiltinMenuEnum.AGENT_DEV.getCode(), SysBuiltinResourceEnum.AGENT_EDIT.getCode(), BindTypeEnum.ALL),
|
||||
//// AGENT_DEV_DELETE(SysBuiltinMenuEnum.AGENT_DEV.getCode(), SysBuiltinResourceEnum.AGENT_DELETE.getCode(), BindTypeEnum.ALL),
|
||||
//// AGENT_DEV_IMPORT(SysBuiltinMenuEnum.AGENT_DEV.getCode(), SysBuiltinResourceEnum.AGENT_IMPORT.getCode(), BindTypeEnum.ALL),
|
||||
//// AGENT_DEV_EXPORT(SysBuiltinMenuEnum.AGENT_DEV.getCode(), SysBuiltinResourceEnum.AGENT_EXPORT.getCode(), BindTypeEnum.ALL),
|
||||
//// AGENT_DEV_PUBLISH(SysBuiltinMenuEnum.AGENT_DEV.getCode(), SysBuiltinResourceEnum.AGENT_PUBLISH.getCode(), BindTypeEnum.ALL),
|
||||
//// AGENT_DEV_COPY(SysBuiltinMenuEnum.AGENT_DEV.getCode(), SysBuiltinResourceEnum.AGENT_COPY.getCode(), BindTypeEnum.ALL),
|
||||
//// AGENT_DEV_MIGRATE(SysBuiltinMenuEnum.AGENT_DEV.getCode(), SysBuiltinResourceEnum.AGENT_MIGRATE.getCode(), BindTypeEnum.ALL),
|
||||
//
|
||||
// // 网页应用开发
|
||||
// PAGE_APP_DEV_RESOURCE(SysBuiltinMenuEnum.PAGE_APP_DEV.getCode(), SysBuiltinResourceEnum.PAGE_APP_DEV.getCode(), BindTypeEnum.ALL),
|
||||
//// PAGE_APP_DEV_ADD(SysBuiltinMenuEnum.PAGE_APP_DEV.getCode(), SysBuiltinResourceEnum.PAGE_APP_ADD.getCode(), BindTypeEnum.ALL),
|
||||
//// PAGE_APP_DEV_EDIT(SysBuiltinMenuEnum.PAGE_APP_DEV.getCode(), SysBuiltinResourceEnum.PAGE_APP_EDIT.getCode(), BindTypeEnum.ALL),
|
||||
//// PAGE_APP_DEV_DELETE(SysBuiltinMenuEnum.PAGE_APP_DEV.getCode(), SysBuiltinResourceEnum.PAGE_APP_DELETE.getCode(), BindTypeEnum.ALL),
|
||||
//// PAGE_APP_DEV_IMPORT(SysBuiltinMenuEnum.PAGE_APP_DEV.getCode(), SysBuiltinResourceEnum.PAGE_APP_IMPORT.getCode(), BindTypeEnum.ALL),
|
||||
//// PAGE_APP_DEV_EXPORT(SysBuiltinMenuEnum.PAGE_APP_DEV.getCode(), SysBuiltinResourceEnum.PAGE_APP_EXPORT.getCode(), BindTypeEnum.ALL),
|
||||
//// PAGE_APP_DEV_PUBLISH(SysBuiltinMenuEnum.PAGE_APP_DEV.getCode(), SysBuiltinResourceEnum.PAGE_APP_PUBLISH.getCode(), BindTypeEnum.ALL),
|
||||
//// PAGE_APP_DEV_COPY(SysBuiltinMenuEnum.PAGE_APP_DEV.getCode(), SysBuiltinResourceEnum.PAGE_APP_COPY.getCode(), BindTypeEnum.ALL),
|
||||
//// PAGE_APP_DEV_CONFIG(SysBuiltinMenuEnum.PAGE_APP_DEV.getCode(), SysBuiltinResourceEnum.PAGE_APP_CONFIG.getCode(), BindTypeEnum.ALL),
|
||||
//
|
||||
// // 组件库
|
||||
// COMPONENT_DEV_RESOURCE(SysBuiltinMenuEnum.COMPONENT_DEV.getCode(), SysBuiltinResourceEnum.COMPONENT_DEV.getCode(), BindTypeEnum.ALL),
|
||||
//// COMPONENT_DEV_ADD(SysBuiltinMenuEnum.COMPONENT_DEV.getCode(), SysBuiltinResourceEnum.COMPONENT_ADD.getCode(), BindTypeEnum.ALL),
|
||||
//// COMPONENT_DEV_EDIT(SysBuiltinMenuEnum.COMPONENT_DEV.getCode(), SysBuiltinResourceEnum.COMPONENT_EDIT.getCode(), BindTypeEnum.ALL),
|
||||
//// COMPONENT_DEV_DELETE(SysBuiltinMenuEnum.COMPONENT_DEV.getCode(), SysBuiltinResourceEnum.COMPONENT_DELETE.getCode(), BindTypeEnum.ALL),
|
||||
//// COMPONENT_DEV_IMPORT(SysBuiltinMenuEnum.COMPONENT_DEV.getCode(), SysBuiltinResourceEnum.COMPONENT_IMPORT.getCode(), BindTypeEnum.ALL),
|
||||
//// COMPONENT_DEV_EXPORT(SysBuiltinMenuEnum.COMPONENT_DEV.getCode(), SysBuiltinResourceEnum.COMPONENT_EXPORT.getCode(), BindTypeEnum.ALL),
|
||||
//// COMPONENT_DEV_PUBLISH(SysBuiltinMenuEnum.COMPONENT_DEV.getCode(), SysBuiltinResourceEnum.COMPONENT_PUBLISH.getCode(), BindTypeEnum.ALL),
|
||||
//// COMPONENT_DEV_COPY(SysBuiltinMenuEnum.COMPONENT_DEV.getCode(), SysBuiltinResourceEnum.COMPONENT_COPY.getCode(), BindTypeEnum.ALL),
|
||||
//
|
||||
// // 技能管理
|
||||
// SKILL_DEV_RESOURCE(SysBuiltinMenuEnum.SKILL_DEV.getCode(), SysBuiltinResourceEnum.SKILL_DEV.getCode(), BindTypeEnum.ALL),
|
||||
//// SKILL_DEV_ADD(SysBuiltinMenuEnum.SKILL_DEV.getCode(), SysBuiltinResourceEnum.SKILL_ADD.getCode(), BindTypeEnum.ALL),
|
||||
//// SKILL_DEV_EDIT(SysBuiltinMenuEnum.SKILL_DEV.getCode(), SysBuiltinResourceEnum.SKILL_EDIT.getCode(), BindTypeEnum.ALL),
|
||||
//// SKILL_DEV_DELETE(SysBuiltinMenuEnum.SKILL_DEV.getCode(), SysBuiltinResourceEnum.SKILL_DELETE.getCode(), BindTypeEnum.ALL),
|
||||
//// SKILL_DEV_IMPORT(SysBuiltinMenuEnum.SKILL_DEV.getCode(), SysBuiltinResourceEnum.SKILL_IMPORT.getCode(), BindTypeEnum.ALL),
|
||||
//// SKILL_DEV_EXPORT(SysBuiltinMenuEnum.SKILL_DEV.getCode(), SysBuiltinResourceEnum.SKILL_EXPORT.getCode(), BindTypeEnum.ALL),
|
||||
//// SKILL_DEV_PUBLISH(SysBuiltinMenuEnum.SKILL_DEV.getCode(), SysBuiltinResourceEnum.SKILL_PUBLISH.getCode(), BindTypeEnum.ALL),
|
||||
//// SKILL_DEV_COPY(SysBuiltinMenuEnum.SKILL_DEV.getCode(), SysBuiltinResourceEnum.SKILL_COPY.getCode(), BindTypeEnum.ALL),
|
||||
//
|
||||
// // MCP管理
|
||||
// MCP_DEV_RESOURCE(SysBuiltinMenuEnum.MCP_DEV.getCode(), SysBuiltinResourceEnum.MCP_DEV.getCode(), BindTypeEnum.ALL),
|
||||
//
|
||||
// // 任务中心
|
||||
// TASK_MANAGE_RESOURCE(SysBuiltinMenuEnum.TASK_MANAGE.getCode(), SysBuiltinResourceEnum.TASK_MANAGE.getCode(), BindTypeEnum.ALL),
|
||||
//
|
||||
// // 日志查询
|
||||
// LOG_MANAGE_RESOURCE(SysBuiltinMenuEnum.LOG_MANAGE.getCode(), SysBuiltinResourceEnum.LOG_MANAGE.getCode(), BindTypeEnum.ALL),
|
||||
//
|
||||
// // 空间广场
|
||||
// SPACE_SQUARE_RESOURCE(SysBuiltinMenuEnum.SPACE_SQUARE.getCode(), SysBuiltinResourceEnum.SPACE_SQUARE.getCode(), BindTypeEnum.ALL),
|
||||
//
|
||||
// // 广场
|
||||
// SQUARE_RESOURCE(SysBuiltinMenuEnum.SQUARE.getCode(), SysBuiltinResourceEnum.SQUARE.getCode(), BindTypeEnum.ALL),
|
||||
//
|
||||
// // 生态市场
|
||||
// ECO_MARKET_RESOURCE(SysBuiltinMenuEnum.ECO_MARKET.getCode(), SysBuiltinResourceEnum.ECO_MARKET.getCode(), BindTypeEnum.ALL);
|
||||
//
|
||||
// //PLACEHOLDER("__PLACEHOLDER__", "__PLACEHOLDER__", BindTypeEnum.NONE);
|
||||
//
|
||||
// /**
|
||||
// * 菜单编码
|
||||
// */
|
||||
// private final String menuCode;
|
||||
//
|
||||
// /**
|
||||
// * 资源编码
|
||||
// */
|
||||
// private final String resourceCode;
|
||||
//
|
||||
// /**
|
||||
// * 资源绑定类型
|
||||
// */
|
||||
// private final BindTypeEnum resourceBindType;
|
||||
//
|
||||
// SysBuiltinMenuResourceEnum(String menuCode, String resourceCode, BindTypeEnum resourceBindType) {
|
||||
// this.menuCode = menuCode;
|
||||
// this.resourceCode = resourceCode;
|
||||
// this.resourceBindType = resourceBindType;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 根据菜单编码获取关联的资源列表
|
||||
// */
|
||||
// public static List<SysBuiltinMenuResourceEnum> getByMenuCode(String menuCode) {
|
||||
// if (menuCode == null) {
|
||||
// return List.of();
|
||||
// }
|
||||
// return Arrays.stream(values())
|
||||
// .filter(enumItem -> enumItem.getMenuCode().equals(menuCode))
|
||||
// .filter(enumItem -> !"__PLACEHOLDER__".equals(enumItem.getMenuCode()))
|
||||
// .collect(Collectors.toList());
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,55 @@
|
||||
//package com.xspaceagi.system.spec.enums;
|
||||
//
|
||||
//import lombok.Getter;
|
||||
//
|
||||
///**
|
||||
// * 系统内置角色
|
||||
// */
|
||||
//@Getter
|
||||
//public enum SysBuiltinRoleEnum {
|
||||
//
|
||||
// SUPER_ADMIN("super_admin", "超级管理员", "系统超级管理员,拥有所有权限", 1),
|
||||
// NORMAL_USER("normal_user", "普通用户", "系统普通用户", 2);
|
||||
//
|
||||
// /**
|
||||
// * 角色编码
|
||||
// */
|
||||
// private final String code;
|
||||
//
|
||||
// /**
|
||||
// * 角色名称
|
||||
// */
|
||||
// private final String name;
|
||||
//
|
||||
// /**
|
||||
// * 角色描述
|
||||
// */
|
||||
// private final String description;
|
||||
//
|
||||
// /**
|
||||
// * 排序索引
|
||||
// */
|
||||
// private final Integer sortIndex;
|
||||
//
|
||||
// SysBuiltinRoleEnum(String code, String name, String description, Integer sortIndex) {
|
||||
// this.code = code;
|
||||
// this.name = name;
|
||||
// this.description = description;
|
||||
// this.sortIndex = sortIndex;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 根据code获取枚举
|
||||
// */
|
||||
// public static SysBuiltinRoleEnum getByCode(String code) {
|
||||
// if (code == null) {
|
||||
// return null;
|
||||
// }
|
||||
// for (SysBuiltinRoleEnum roleEnum : values()) {
|
||||
// if (roleEnum.getCode().equals(code)) {
|
||||
// return roleEnum;
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,53 @@
|
||||
//package com.xspaceagi.system.spec.enums;
|
||||
//
|
||||
//import java.util.Arrays;
|
||||
//import java.util.List;
|
||||
//import java.util.stream.Collectors;
|
||||
//
|
||||
//import lombok.Getter;
|
||||
//
|
||||
///**
|
||||
// * 系统内置角色-菜单关联
|
||||
// */
|
||||
//@Getter
|
||||
//public enum SysBuiltinRoleMenuEnum {
|
||||
//
|
||||
// SUPER_ADMIN("super_admin", "root", BindTypeEnum.ALL),
|
||||
// NORMAL_USER("normal_user", "root", BindTypeEnum.ALL);
|
||||
//
|
||||
// //PLACEHOLDER("__PLACEHOLDER__", "__PLACEHOLDER__", BindTypeEnum.NONE, BindTypeEnum.NONE);
|
||||
//
|
||||
// /**
|
||||
// * 角色编码
|
||||
// */
|
||||
// private final String roleCode;
|
||||
//
|
||||
// /**
|
||||
// * 菜单编码
|
||||
// */
|
||||
// private final String menuCode;
|
||||
//
|
||||
// /**
|
||||
// * 子菜单绑定类型
|
||||
// */
|
||||
// private final BindTypeEnum menuBindType;
|
||||
//
|
||||
// SysBuiltinRoleMenuEnum(String roleCode, String menuCode, BindTypeEnum menuBindType) {
|
||||
// this.roleCode = roleCode;
|
||||
// this.menuCode = menuCode;
|
||||
// this.menuBindType = menuBindType;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 根据角色编码获取关联的菜单列表
|
||||
// */
|
||||
// public static List<SysBuiltinRoleMenuEnum> getByRoleCode(String roleCode) {
|
||||
// if (roleCode == null) {
|
||||
// return List.of();
|
||||
// }
|
||||
// return Arrays.stream(values())
|
||||
// .filter(enumItem -> enumItem.getRoleCode().equals(roleCode))
|
||||
// .filter(enumItem -> !"__PLACEHOLDER__".equals(enumItem.getRoleCode()))
|
||||
// .collect(Collectors.toList());
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.xspaceagi.system.spec.enums;
|
||||
|
||||
public enum TenantStatus {
|
||||
Pending, Enabled, Disabled // 确保枚举值与数据库中的ENUM值匹配
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.xspaceagi.system.spec.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 角色类型,1:管理员角色;2:普通角色
|
||||
*/
|
||||
@Getter
|
||||
public enum UserRoleTypeEnum {
|
||||
|
||||
|
||||
Manager(1, "管理员角色"),
|
||||
|
||||
Normal(2, "普通角色");
|
||||
|
||||
|
||||
private final int key;
|
||||
|
||||
private final String value;
|
||||
|
||||
UserRoleTypeEnum(int key, String value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
public static UserRoleTypeEnum getUserRoleTypeEnum(Integer key) {
|
||||
if (Objects.isNull(key)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (UserRoleTypeEnum userRoleTypeEnum : UserRoleTypeEnum.values()) {
|
||||
if (userRoleTypeEnum.getKey() == key) {
|
||||
return userRoleTypeEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.xspaceagi.system.spec.enums;
|
||||
|
||||
public enum UserStatus {
|
||||
Enabled, Disabled // 确保枚举值与数据库中的ENUM值匹配
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.xspaceagi.system.spec.enums;
|
||||
|
||||
public enum UserTypeEnum {
|
||||
Admin, User
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.xspaceagi.system.spec.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
public enum YesOrNoEnum {
|
||||
N(0, "无效"),
|
||||
Y(1, "有效");
|
||||
@Getter
|
||||
private final Integer key;
|
||||
private final String value;
|
||||
|
||||
YesOrNoEnum(Integer key, String value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static boolean isValid(Integer key) {
|
||||
for (YesOrNoEnum value : YesOrNoEnum.values()) {
|
||||
if (value.getKey().equals(key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isInValid(Integer key) {
|
||||
return !isValid(key);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.xspaceagi.system.spec.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 逻辑删除标记
|
||||
*/
|
||||
|
||||
@Getter
|
||||
public enum YnEnum {
|
||||
N(-1, "无效"), Y(1, "有效");
|
||||
|
||||
private final Integer key;
|
||||
|
||||
private final String value;
|
||||
|
||||
YnEnum(Integer key, String value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static boolean isY(Integer key) {
|
||||
return Y.getKey().equals(key);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.xspaceagi.system.spec.event;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 消息拉取事件
|
||||
* 用于EventBus事件传递
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class PullMessageEvent implements Serializable{
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 租户ID
|
||||
*/
|
||||
private Long tenantId;
|
||||
|
||||
/**
|
||||
* 客户端ID
|
||||
*/
|
||||
private String clientId;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.xspaceagi.system.spec.exception;
|
||||
|
||||
/**
|
||||
* AI Agent 异常
|
||||
*/
|
||||
public class AgentException extends KindlyException {
|
||||
|
||||
/**
|
||||
* 默认配置前缀
|
||||
*/
|
||||
private static final String DISPLAY_CODE = "Agent";
|
||||
|
||||
|
||||
public AgentException(String code, String message) {
|
||||
super(code, message);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据定义好的异常枚举,构建异常信息
|
||||
*
|
||||
* @param codeEnum 异常枚举
|
||||
* @param params 占位参数
|
||||
* @return 异常
|
||||
*/
|
||||
public static AgentException build(BizExceptionCodeEnum codeEnum, Object... params) {
|
||||
String errorMessage = codeEnum.formatMessage(params);
|
||||
return new AgentException(codeEnum.getCode(), errorMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModule() {
|
||||
return DISPLAY_CODE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.xspaceagi.system.spec.exception;
|
||||
|
||||
/**
|
||||
* agent执行中断
|
||||
*/
|
||||
public class AgentInterruptException extends RuntimeException {
|
||||
|
||||
public AgentInterruptException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public AgentInterruptException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public AgentInterruptException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public AgentInterruptException() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
package com.xspaceagi.system.spec.exception;
|
||||
|
||||
import com.xspaceagi.system.spec.enums.ErrorCodeEnum;
|
||||
import com.xspaceagi.system.spec.enums.HttpStatusEnum;
|
||||
|
||||
/**
|
||||
* 业务异常
|
||||
*/
|
||||
public class BizException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private int status;
|
||||
|
||||
private String code = "0001";
|
||||
|
||||
private String msg;
|
||||
|
||||
/**
|
||||
* {@link BizExceptionCodeEnum} 常量名({@link Enum#name()},小驼峰),用于响应阶段按语言重算文案。
|
||||
* 对外 JSON 的 {@link #getCode()} 可能为 4000/4030 等,与本字段独立。
|
||||
*/
|
||||
private String msgName;
|
||||
|
||||
/**
|
||||
* 与 {@link IBizExceptionCodeEnum#formatMessage(Object...)} 一致的占位参数,供全局异常处理按 {@code RequestContext.lang} 重算中英文。
|
||||
*/
|
||||
private Object[] messageFormatArgs;
|
||||
|
||||
public BizException(String msg) {
|
||||
super(msg);
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public BizException(String code, String msg) {
|
||||
this(code, msg, null);
|
||||
}
|
||||
|
||||
public BizException(String code, String msg, String msgName) {
|
||||
this(code, msg, msgName, null);
|
||||
}
|
||||
|
||||
public BizException(String code, String msg, String msgName, Object[] messageFormatArgs) {
|
||||
super(msg);
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
this.msgName = msgName;
|
||||
this.messageFormatArgs = messageFormatArgs == null ? null : messageFormatArgs.clone();
|
||||
this.status = HttpStatusEnum.OK.code();
|
||||
}
|
||||
|
||||
public BizException(HttpStatusEnum status, ErrorCodeEnum code) {
|
||||
super(code.getMsg());
|
||||
this.code = code.getCode();
|
||||
this.msg = code.getMsg();
|
||||
this.status = status.code();
|
||||
}
|
||||
|
||||
public BizException(HttpStatusEnum status, ErrorCodeEnum code, String message) {
|
||||
super(message);
|
||||
this.code = code.getCode();
|
||||
this.msg = message;
|
||||
this.status = status.code();
|
||||
}
|
||||
|
||||
/**
|
||||
* 对外契约码 + i18n msgName,且保留 {@link HttpStatusEnum}(如 401)供需要读取 {@link #getStatus()} 的场景。
|
||||
*/
|
||||
private BizException(HttpStatusEnum httpStatus, String apiCode, String message, String msgName,
|
||||
Object[] messageFormatArgs) {
|
||||
super(message);
|
||||
this.code = apiCode;
|
||||
this.msg = message;
|
||||
this.msgName = msgName;
|
||||
this.messageFormatArgs = messageFormatArgs == null ? null : messageFormatArgs.clone();
|
||||
this.status = httpStatus.code();
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用业务细分错误码(见 {@link BizExceptionCodeEnum})构造异常;响应中的 code 为枚举自带编码。
|
||||
* 若对外必须固定为 4000/4011/4030 等,请使用 {@link #of(ErrorCodeEnum, IBizExceptionCodeEnum, Object...)}。
|
||||
*/
|
||||
public static BizException of(IBizExceptionCodeEnum codeEnum, Object... params) {
|
||||
String message = codeEnum.formatMessage(params);
|
||||
return new BizException(codeEnum.getCode(), message, ((Enum<?>) codeEnum).name(), params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用对外统一错误码(须保留如 {@link ErrorCodeEnum#INVALID_PARAM 4000}、
|
||||
* {@link ErrorCodeEnum#UNAUTHORIZED_REDIRECT 4011}、{@link ErrorCodeEnum#PERMISSION_DENIED 4030} 等契约)
|
||||
* + 业务文案枚举构造异常;响应 code 取 {@code apiCode},message 取枚举模板(便于 i18n)。
|
||||
*/
|
||||
public static BizException of(ErrorCodeEnum apiCode, IBizExceptionCodeEnum messageEnum, Object... params) {
|
||||
String message = messageEnum.formatMessage(params);
|
||||
return new BizException(apiCode.getCode(), message, ((Enum<?>) messageEnum).name(), params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 同 {@link #of(ErrorCodeEnum, IBizExceptionCodeEnum, Object...)},额外指定 HTTP 语义状态(如 {@link HttpStatusEnum#UNAUTHORIZED}),
|
||||
* 不改变对外 JSON 中的业务 {@code code}(仍取 {@code apiCode})。
|
||||
*/
|
||||
public static BizException of(HttpStatusEnum httpStatus, ErrorCodeEnum apiCode, IBizExceptionCodeEnum messageEnum,
|
||||
Object... params) {
|
||||
String message = messageEnum.formatMessage(params);
|
||||
return new BizException(httpStatus, apiCode.getCode(), message, ((Enum<?>) messageEnum).name(), params);
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* 业务枚举常量名(用于 i18n);未通过 {@link #of} 系列工厂构造时可能为 null。
|
||||
*/
|
||||
public String getMsgName() {
|
||||
return msgName;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link #of(IBizExceptionCodeEnum, Object...)} 传入的占位参数副本;无则 null。
|
||||
*/
|
||||
public Object[] getMessageFormatArgs() {
|
||||
return messageFormatArgs == null ? null : messageFormatArgs.clone();
|
||||
}
|
||||
|
||||
public int getStatus() {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,589 @@
|
||||
package com.xspaceagi.system.spec.exception;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 异常枚举
|
||||
*/
|
||||
@Getter
|
||||
public enum BizExceptionCodeEnum implements IBizExceptionCodeEnum {
|
||||
|
||||
|
||||
/**
|
||||
* 系统异常
|
||||
*/
|
||||
systemUnexpectedError("1000", "系统异常,请稍后再试", "A system error occurred. Please try again later.", "系统未预料统一捕获的异常,例如空指针、数组越界等"),
|
||||
systemMissingRequiredParameter("1010", "系统异常,请稍后再试", "A system error occurred. Please try again later.", "参数异常,必填参数未传递"),
|
||||
systemInternalRpcFailure("1020", "系统异常,请稍后再试", "A system error occurred. Please try again later.", "依赖服务(内部系统RPC)调用异常,超时、服务不可用等"),
|
||||
systemExternalHttpFailure("1030", "系统异常,请稍后再试", "A system error occurred. Please try again later.", "三方服务(外部系统HTTP)调用异常,超时、对方系统异常等"),
|
||||
systemDataLayerFailure("1040", "系统异常,请稍后再试", "A system error occurred. Please try again later.", "数据层(MYSQL、ES等)异常,主键冲突、超时等"),
|
||||
systemCacheFailure("1050", "系统异常,请稍后再试", "A system error occurred. Please try again later.", "缓存异常"),
|
||||
|
||||
|
||||
//参数缺失:统一用「参数'xx'不能为空」,具体名称由调用方传入(与 i18n key fieldRequiredButEmpty 对应)
|
||||
validationFailedWithDetail("2006", "%s", "%s", "参数校验失败"),
|
||||
fieldRequiredButEmpty("2007", "参数'%s'不能为空", "Parameter '%s' is required.", "通用:必填项"),
|
||||
/** 通用:数据/记录不存在(知识库、Compose、自定义页等共用) */
|
||||
resourceDataNotFound("5001", "数据不存在", "Data does not exist.", "通用"),
|
||||
/** 通用:配置记录不存在(IM、沙箱、生态市场、Agent 组件等共用) */
|
||||
configNotFound("8001", "配置不存在", "Configuration does not exist.", "通用"),
|
||||
/** 通用:需要登录态 */
|
||||
userNotLoggedIn("3177", "用户未登录", "User is not signed in.", "认证"),
|
||||
/** 通用:物理表不存在(Compose DDL、助手查询等共用) */
|
||||
tableNotFound("6013", "表不存在", "Table does not exist.", "通用"),
|
||||
/** 通用:无权限(合并原 systemOperationDenied / systemOperationPermissionDenied / systemPermissionDeniedShort) */
|
||||
permissionDenied("3020", "无权限", "Permission denied.", "通用"),
|
||||
|
||||
//系统管理
|
||||
systemGetTenantFailed("3202", "获取租户信息失败", "Failed to fetch tenant information.", "IM"),
|
||||
systemUserNotFound("3001", "用户不存在", "User does not exist.", "用户不存在"),
|
||||
systemUserStatusInvalid("3002", "用户启用状态标记异常", "Invalid user enabled status flag.", "用户启用状态标记异常"),
|
||||
systemLoginCredentialsInvalid("3003", "用户或密码错误", "Invalid username or password.", "用户或密码错误"),
|
||||
systemUserOrPhoneAlreadyExists("3004", "用户或手机号已存在", "Username or phone number already exists.", "用户或手机号已存在"),
|
||||
systemOrgNotFound("3005", "机构不存在", "Organization does not exist.", "机构不存在"),
|
||||
systemBackupFileNotFound("3006", "备份文件不存在,文件=%s", "Backup file not found, file=%s", "备份文件不存在"),
|
||||
systemBackupRecordNotFound("3007", "备份记录不存在", "Backup record does not exist.", "备份记录不存在"),
|
||||
systemBackupFileAlreadyExists("3008", "备份文件已存在,为避免覆盖文件,请重试备份操作", "Backup file already exists. Retry the backup to avoid overwriting.", "备份文件已存在,为避免覆盖文件,请重试备份操作"),
|
||||
systemBackupDownloadIoError("3009", "下载备份文件时发生IO异常,%s", "I/O error while downloading backup file: %s", ""),
|
||||
systemPasswordIncorrect("3010", "密码错误", "Incorrect password.", ""),
|
||||
systemNewPasswordSameAsOld("3011", "新密码不能和旧密码相同", "New password must differ from the old password.", ""),
|
||||
systemMenuNotFound("3012", "菜单不存在,KEY=%s", "Menu not found, KEY=%s", ""),
|
||||
systemRegistrationClosed("3013", "注册已关闭", "Registration is disabled.", "认证"),
|
||||
systemAccountDisabled("3014", "账号已被禁用", "Account has been disabled.", "认证"),
|
||||
systemLoginIdentifierOrPasswordWrong("3015", "用户不存在或密码错误", "User does not exist or password is incorrect.", "认证"),
|
||||
systemUserNotLoggedInWeb("3016", "用户未登陆", "User is not signed in.", "认证"),
|
||||
systemMenuCodeAlreadyExists("3018", "已存在此菜单编码", "This menu code already exists.", "菜单"),
|
||||
systemPersonalSpaceDeleteForbidden("3021", "个人空间不允许删除", "Personal space cannot be deleted.", "空间"),
|
||||
systemParamRequired("3022", "参数不能为空", "Parameter cannot be empty.", "参数"),
|
||||
systemCannotAddOwner("3023", "不能添加Owner", "Cannot add Owner.", "空间成员"),
|
||||
systemCannotUpdateToOwner("3024", "不能更新为Owner", "Cannot change role to Owner.", "空间成员"),
|
||||
systemCannotDeleteSelf("3025", "不能删除自己", "You cannot delete yourself.", "空间成员"),
|
||||
systemSpaceNotFound("3026", "空间不存在", "Space does not exist.", "空间"),
|
||||
systemCannotDeleteSpaceCreator("3027", "不能删除创建者", "Cannot remove the space creator.", "空间成员"),
|
||||
systemEmailFormatInvalid("3028", "邮箱格式不正确", "Invalid email format.", "用户"),
|
||||
systemEmailAlreadyInUse("3029", "邮箱已被占用", "Email is already in use.", "用户"),
|
||||
systemPhoneAlreadyInUse("3030", "手机号已被占用", "Phone number is already in use.", "用户"),
|
||||
systemSmsNotConfiguredDevHint("3031", "系统未配置短信服务,请直接输出本次验证码:%s", "SMS is not configured. Use this verification code: %s", "验证码"),
|
||||
systemMailNotConfiguredDevHint("3032", "系统未配置邮件服务,请直接输出本次验证码:%s", "Mail is not configured. Use this verification code: %s", "验证码"),
|
||||
systemApiKeyRateLimitPerMinute("4290", "每分钟请求次数超限", "Exceeded per-minute request frequency limit.", "API Key"),
|
||||
systemApiKeyRateLimitPerDay("4290", "每日请求次数超限", "Exceeded daily request frequency limit.", "API Key"),
|
||||
systemMailServiceNotConfigured("3033", "请在系统管理中配置邮件服务", "Configure mail service in system administration.", "邮件"),
|
||||
systemMailSendFailed("3034", "邮件发送异常,请检查邮件服务配置", "Failed to send email. Check mail service configuration.", "邮件"),
|
||||
systemSmsServiceNotConfigured("3035", "请在系统管理中配置短信服务", "Configure SMS service in system administration.", "短信"),
|
||||
systemIdGenerateRetryFailed("3036", "%s失败,请重试", "%s failed. Please try again.", "ID生成"),
|
||||
/** 与 UNAUTHORIZED 契约一致;建议 {@code BizException.of(HttpStatusEnum.UNAUTHORIZED, ErrorCodeEnum.UNAUTHORIZED, …)} */
|
||||
systemUnauthorizedOrSessionExpired("3037", "未登录或登录超时", "Not signed in or session expired.", "认证"),
|
||||
|
||||
/** RBAC:角色 / 资源 / 用户组 domain 共用 */
|
||||
systemRbacCodeFormatInvalid("3080", "编码只能包含字母、数字和下划线,且必须以字母开头", "Code may only contain letters, digits and underscores, and must start with a letter.", "RBAC"),
|
||||
systemRbacResourceCodeFormatInvalid("3081", "资源码只能包含字母、数字和下划线,且必须以字母开头", "Resource code may only contain letters, digits and underscores, and must start with a letter.", "RBAC"),
|
||||
systemRbacCodeLengthExceeded("3082", "编码长度不能超过100", "Code length cannot exceed 100.", "RBAC"),
|
||||
systemRbacNameLengthExceeded("3083", "名称长度不能超过50", "Name length cannot exceed 50.", "RBAC"),
|
||||
systemRbacDescLengthExceeded("3084", "描述长度不能超过500", "Description length cannot exceed 500.", "RBAC"),
|
||||
systemRbacPathLengthExceeded("3085", "路径长度不能超过500", "Path length cannot exceed 500.", "RBAC"),
|
||||
systemRoleCodeDuplicate("3086", "已存在此角色编码", "This role code already exists.", "RBAC"),
|
||||
systemGroupCodeDuplicate("3087", "已存在此用户组编码", "This group code already exists.", "RBAC"),
|
||||
systemResourceCodeDuplicate("3088", "已存在此资源编码", "This resource code already exists.", "RBAC"),
|
||||
systemRbacSaveFailed("3089", "保存失败", "Save failed.", "RBAC"),
|
||||
systemRoleNotFound("3090", "角色不存在", "Role does not exist.", "RBAC"),
|
||||
systemResourceNotFound("3091", "资源不存在", "Resource does not exist.", "RBAC"),
|
||||
systemGroupNotFound("3092", "用户组不存在", "User group does not exist.", "RBAC"),
|
||||
systemBuiltinRoleCodeImmutable("3093", "系统内置角色编码不能修改", "Built-in role code cannot be changed.", "RBAC"),
|
||||
systemBuiltinRoleNameImmutable("3094", "系统内置角色名称不能修改", "Built-in role name cannot be changed.", "RBAC"),
|
||||
systemBuiltinRoleCannotDisable("3095", "系统内置角色不能禁用", "Built-in role cannot be disabled.", "RBAC"),
|
||||
systemBuiltinResourceCodeImmutable("3096", "系统内置资源编码不能修改", "Built-in resource code cannot be changed.", "RBAC"),
|
||||
systemBuiltinResourceNameImmutable("3097", "系统内置资源名称不能修改", "Built-in resource name cannot be changed.", "RBAC"),
|
||||
systemBuiltinResourceCannotDisable("3098", "系统内置资源不能禁用", "Built-in resource cannot be disabled.", "RBAC"),
|
||||
systemBuiltinGroupCodeImmutable("3099", "系统内置用户组编码不能修改", "Built-in group code cannot be changed.", "RBAC"),
|
||||
systemBuiltinGroupNameImmutable("3100", "系统内置用户组名称不能修改", "Built-in group name cannot be changed.", "RBAC"),
|
||||
systemBuiltinGroupCannotDisable("3101", "系统内置用户组不能禁用", "Built-in group cannot be disabled.", "RBAC"),
|
||||
systemRbacDataPermissionRequired("3102", "数据权限配置不能为空", "Data permission configuration is required.", "RBAC"),
|
||||
systemRbacTokenLimitMinInvalid("3103", "最大Token不能小于-1", "Max tokens cannot be less than -1.", "RBAC"),
|
||||
systemRoleBindRequiresAdminUser("3104", "仅管理员类型用户才可以绑定角色 [%s]", "Only admin-type users may bind role [%s].", "RBAC"),
|
||||
systemSuperAdminRequiresRoleMenuResources("3105", "超级管理员角色必须绑定必要 菜单[角色管理] 和 资源[查询、菜单权限]", "Super admin role must bind required menu [Role management] and resources [Query, menu permission].", "RBAC"),
|
||||
systemRbacMenuIdNotFound("3106", "菜单ID[%s]不存在", "Menu ID [%s] does not exist.", "RBAC"),
|
||||
systemSuperAdminRequiresRoleMenuResourcesAlt("3107", "超级管理员角色必须绑定必要 菜单[角色管理] 及资源 [查询、菜单权限]", "Super admin role must bind required menu [Role management] and resources [Query, menu permission].", "RBAC"),
|
||||
systemSuperAdminRequiresMenuByName("3108", "超级管理员角色必须绑定必要菜单 [%s]", "Super admin role must bind required menu [%s].", "RBAC"),
|
||||
systemSuperAdminResourceCodeMissing("3109", "超级管理员角色必须绑定必要菜单 [角色管理] 及资源 [查询、菜单权限],系统未找到资源[%s],请联系管理员检查配置", "Super admin must bind menu [Role management] and resources [Query, menu permission]. Resource [%s] not found. Contact an administrator.", "RBAC"),
|
||||
systemSuperAdminResourceMenuOrphan("3110", "超级管理员角色必须绑定必要菜单 [角色管理] 及资源 [查询、菜单权限],资源[%s]未关联菜单,请联系管理员检查配置", "Super admin must bind menu [Role management] and resources [Query, menu permission]. Resource [%s] is not linked to a menu. Contact an administrator.", "RBAC"),
|
||||
systemSuperAdminBindIncomplete("3111", "超级管理员角色必须绑定必要菜单 [角色管理] 及资源 [查询、菜单权限]", "Super admin role must bind menu [Role management] and resources [Query, menu permission].", "RBAC"),
|
||||
systemRbacParentIdInvalid("3112", "父级ID无效", "Invalid parent ID.", "RBAC"),
|
||||
systemRbacParentResourceNotFoundWithParentId("3113", "父级资源不存在,parentId=%s", "Parent resource not found, parentId=%s", "RBAC"),
|
||||
systemRbacParentNameNotModule("3114", "[%s]不是模块,不能作为父级", "[%s] is not a module and cannot be used as a parent.", "RBAC"),
|
||||
systemRbacParentSelfReferenceForbidden("3115", "父级节点不能是自身 [id:%s]", "Parent node cannot be itself [id:%s].", "RBAC"),
|
||||
systemRbacParentResourceNotFound("3116", "父级资源不存在", "Parent resource does not exist.", "RBAC"),
|
||||
systemRbacParentIdInvalidForResource("3117", "父级ID无效: resourceId=%s", "Invalid parent ID: resourceId=%s", "RBAC"),
|
||||
systemRbacParentNodeNotFound("3118", "父级节点不存在 [parentId:%s]", "Parent node does not exist [parentId:%s].", "RBAC"),
|
||||
systemResourceTreeJsonInvalid("3119", "resourceTreeJson 反序列化失败", "Failed to deserialize resourceTreeJson.", "RBAC"),
|
||||
systemRoleNotFoundWithRowId("3120", "角色不存在: id=%s", "Role does not exist: id=%s", "RBAC"),
|
||||
systemRbacUserNotFoundWithId("3121", "用户不存在,id=%s", "User does not exist, id=%s", "RBAC"),
|
||||
systemRoleNotFoundWithRoleId("3122", "角色不存在,id=%s", "Role does not exist, id=%s", "RBAC"),
|
||||
systemGroupMaxUsersBelowBound("3123", "最大用户数不能小于已绑定用户数,当前已绑定%s人", "Max users cannot be below the number already bound; currently %s user(s) bound.", "RBAC"),
|
||||
systemGroupUserLimitExceeded("3124", "组用户数量超出限制", "Group user count exceeds the limit.", "RBAC"),
|
||||
systemGroupNotFoundWithRowId("3125", "用户组不存在: id=%s", "User group does not exist: id=%s", "RBAC"),
|
||||
systemGroupNotFoundWithGroupId("3126", "组不存在,id=%s", "Group does not exist, id=%s", "RBAC"),
|
||||
systemGroupNotFoundWithGroupIdAlt("3127", "用户组不存在,id=%s", "User group does not exist, id=%s", "RBAC"),
|
||||
systemDataPermissionTargetTypeInvalid("3128", "数据权限目标类型错误", "Invalid data permission target type.", "数据权限"),
|
||||
systemDataPermissionTargetIdInvalid("3129", "数据权限目标ID错误", "Invalid data permission target ID.", "数据权限"),
|
||||
systemMenuBindResourceNotFound("3130", "资源ID[%s]不存在", "Resource ID [%s] does not exist.", "菜单绑定"),
|
||||
systemMenuBindResourceOutOfScope("3131", "资源ID[%s]不在菜单ID[%s]的绑定资源范围内", "Resource ID [%s] is outside the bound resources for menu ID [%s].", "菜单绑定"),
|
||||
systemMenuBindResourceBindTypeInvalid("3132", "资源ID[%s]的绑定类型[%s]无效,只能是0(NONE)、1(ALL)或2(PART)", "For resource ID [%s], bind type [%s] is invalid; must be 0 (NONE), 1 (ALL), or 2 (PART).", "菜单绑定"),
|
||||
systemRbacResourceCodeLengthExceeded("3133", "资源码长度不能超过100", "Resource code length cannot exceed 100.", "RBAC"),
|
||||
systemGroupCannotBindForbiddenMenu("3134", "用户组不能绑定「%s」菜单", "User group cannot bind menu \"%s\".", "RBAC"),
|
||||
systemVerifyCodeIncorrect("3135", "验证码错误", "Incorrect verification code.", "验证码"),
|
||||
systemVerifyParamInvalid("3136", "校验参数异常", "Invalid verification parameters.", "验证码"),
|
||||
systemVerifyCodeCheckFailed("3137", "验证码校验失败", "Verification code check failed.", "验证码"),
|
||||
systemUsernameDigitsOnlyForbidden("3138", "用户名不能为纯数字", "Username cannot be all digits.", "用户"),
|
||||
systemUsernameAlreadyInUse("3139", "用户名已被占用", "Username is already taken.", "用户"),
|
||||
systemUsernameFormatInvalid("3140", "用户名不符合规范", "Username does not meet the rules.", "用户"),
|
||||
systemUsernameChangeDisallowedInCurrentAuthMode("3141", "当前认证模式不允许修改用户名", "Username cannot be changed in the current auth mode.", "用户"),
|
||||
systemNicknameDigitsOnlyForbidden("3142", "昵称不能为纯数字", "Nickname cannot be all digits.", "用户"),
|
||||
systemWeChatAccessTokenFetchFailed("3143", "获取微信 access_token 失败", "Failed to obtain WeChat access_token.", "微信"),
|
||||
systemWeChatApiReturnedError("3144", "%s", "%s", "微信"),
|
||||
systemWeChatPhoneNumberFetchFailed("3145", "获取微信手机号失败", "Failed to obtain WeChat phone number.", "微信"),
|
||||
systemTenantDomainAlreadyInUse("3146", "域名%s已被占用", "Domain %s is already in use.", "租户"),
|
||||
systemUserIdInvalid("3147", "错误的用户ID", "Invalid user ID.", "用户"),
|
||||
systemMenuPermissionImportTenantInvalid("3148", "菜单权限导入失败,租户ID无效", "Menu permission import failed: invalid tenant ID.", "权限"),
|
||||
systemMenuPermissionDiffImportTenantInvalid("3149", "菜单权限差异导入失败,租户ID无效", "Menu permission diff import failed: invalid tenant ID.", "权限"),
|
||||
systemCategoryOperationDenied("3150", "无权限操作该分类", "No permission to operate this category.", "分类"),
|
||||
systemMenuIdNullWithNodeName("3151", "菜单id不能为null,name:%s", "Menu id cannot be null, name:%s", "菜单"),
|
||||
systemI18nExportRowCountExceeded("3152", "导出行数(%d)超过上限(%d),请缩小筛选条件后重试", "Export row count (%d) exceeds the limit (%d). Narrow filters and try again.", "i18n"),
|
||||
systemI18nTranslationFailedTargetLang("3153", "翻译失败。目标语言:%s", "Translation failed. Target language: %s", "i18n"),
|
||||
systemI18nBatchTranslationSizeMismatch("3154", "批量翻译返回条数不匹配。目标语言:%s,分块起始:%s", "Batch translation count mismatch. Target language: %s, chunk start: %s", "i18n"),
|
||||
systemI18nBatchTranslationResultEmpty("3155", "批量翻译结果为空。Key = %s,目标语言 = %s", "Batch translation result is empty. Key = %s, target language = %s", "i18n"),
|
||||
systemI18nLangTagInvalid("3156", "语言标识格式不正确,请使用合法的语言标签,如 zh-CN、en-US、zh-Hans-CN", "Invalid language tag. Use a valid BCP 47 tag such as zh-CN, en-US, or zh-Hans-CN.", "i18n"),
|
||||
systemI18nLangTagDuplicate("3157", "该语言标签已存在,不允许重复", "This language tag already exists; duplicates are not allowed.", "i18n"),
|
||||
systemI18nBatchTranslationNotJson("3158", "批量翻译返回非 JSON 对象:%s", "Batch translation returned a non-JSON object: %s", "i18n"),
|
||||
systemI18nBatchTranslationKeyOrValueMissing("3159", "批量翻译缺少 key 或值为空: %s", "Batch translation missing key or empty value: %s", "i18n"),
|
||||
systemI18nTranslationEmpty("3160", "翻译返回空结果", "Translation returned empty.", "i18n"),
|
||||
systemI18nTranslationModelAuthFailed("3161", "翻译失败:模型鉴权失败,请检查默认模型的 API Key/鉴权配置。", "Translation failed: model authentication error. Check default model API key and auth settings.", "i18n"),
|
||||
systemI18nTranslationFailedWithReason("3162", "翻译失败: %s", "Translation failed: %s", "i18n"),
|
||||
systemI18nOriginalRecordNotFound("3163", "原始记录不存在", "The original record does not exist.", "i18n"),
|
||||
|
||||
bootstrapAuthRedirectUrl("3164", "%s", "%s", "登录跳转"),
|
||||
bootstrapLicenseContentInvalid("3165", "许可证内容无效", "Invalid license content.", "License"),
|
||||
systemNoPermissionForSystemApi("3166", "你没有权限", "You do not have permission.", "权限"),
|
||||
apiKeyInvalid("3167", "无效的 API Key", "Invalid API Key.", "API Key"),
|
||||
apiKeyExpired("3168", "API Key 已过期", "API Key expired.", "API Key"),
|
||||
apiKeyAccessDenied("3169", "API Key 无访问权限", "API Key does not have access permissions.", "API Key"),
|
||||
apiKeyMissing("3170", "缺少 API Key", "Missing API Key.", "API Key"),
|
||||
apiKeyUserDisabled("3171", "用户已停用", "User disabled.", "API Key"),
|
||||
apiKeyAgentApiDisabled("3172", "当前已禁用 API 调用", "The API calls are currently disabled.", "API Key"),
|
||||
apiKeyOpenApiNotFound("3173", "API 不存在或无权限", "API not found or permission denied.", "API Key"),
|
||||
apiKeyPermissionDenied("3174", "无权限", "Permission denied.", "API Key"),
|
||||
|
||||
imFeishuWebhookMissingAppId("3178", "飞书 Webhook 缺少必要参数: appId", "Feishu Webhook is missing required parameter: appId.", "IM"),
|
||||
imFeishuBotNotBound("3179", "飞书机器人未绑定", "Feishu bot is not bound.", "IM"),
|
||||
imDingtalkWebhookMissingRobotCode("3180", "钉钉 Webhook 缺少必要参数: robotCode", "DingTalk Webhook is missing required parameter: robotCode.", "IM"),
|
||||
imDingtalkBotNotBound("3181", "钉钉机器人未绑定", "DingTalk bot is not bound.", "IM"),
|
||||
imWechatQrFetchFailed("3182", "获取微信二维码失败: %s", "Failed to fetch WeChat QR code: %s", "IM"),
|
||||
imWechatQrSessionExpired("3183", "扫码会话已过期或不存在", "Scan session has expired or does not exist.", "IM"),
|
||||
imWechatQrSessionDataInvalid("3184", "会话数据异常", "Session data is invalid.", "IM"),
|
||||
imWechatQrQueryStatusFailed("3185", "查询扫码状态失败: %s", "Failed to query scan status: %s", "IM"),
|
||||
imWechatIlinkChannelOnly("3188", "仅支持微信 iLink 渠道配置", "Only WeChat iLink channel configuration is supported.", "IM"),
|
||||
imWechatIlinkConfigDisabled("3189", "当前微信 iLink 配置未启用", "WeChat iLink configuration is not enabled.", "IM"),
|
||||
imWechatIlinkConfigMissing("3190", "微信 iLink 配置缺失", "WeChat iLink configuration is missing.", "IM"),
|
||||
imWechatIlinkBotTokenMissing("3191", "微信 iLink 配置缺少 botToken", "WeChat iLink configuration is missing botToken.", "IM"),
|
||||
imWechatIlinkUserIdMissing("3192", "微信 iLink 配置缺少 ilinkUserId", "WeChat iLink configuration is missing ilinkUserId.", "IM"),
|
||||
imWechatIlinkPushFailed("3193", "推送失败: %s", "Push failed: %s", "IM"),
|
||||
imChannelConfigInvalidOrUnavailable("3194", "指定的 im_channel_config 不存在、未启用或不是当前空间下可用的微信 iLink 渠道", "The specified im_channel_config does not exist, is disabled, or is not an available WeChat iLink channel in this space.", "IM"),
|
||||
imNoWechatIlinkInSpace("3195", "当前空间未配置可用的微信 iLink 渠道", "No available WeChat iLink channel is configured for this space.", "IM"),
|
||||
imMultipleWechatIlinkNeedExplicitId("3196", "存在多条启用的微信 iLink 配置,主动/定时任务须显式指定 im_channel_config.id(对齐 openclaw-weixin 1.0.3 delivery.accountId)", "Multiple enabled WeChat iLink configs exist; proactive/scheduled tasks must specify im_channel_config.id explicitly (aligned with openclaw-weixin 1.0.3 delivery.accountId).", "IM"),
|
||||
imTenantOrUserMissing("3197", "租户或用户信息缺失", "Tenant or user information is missing.", "IM"),
|
||||
imWechatChannelNotFoundForBot("3198", "未找到与该 botId 对应的微信渠道配置", "No WeChat channel configuration found for this botId.", "IM"),
|
||||
imWechatChannelNotFoundForUser("3199", "未找到当前用户的微信渠道配置", "No WeChat channel configuration found for the current user.", "IM"),
|
||||
imWechatChannelDisabled("3200", "微信渠道配置已禁用", "WeChat channel configuration is disabled.", "IM"),
|
||||
imWechatIlinkParseFailed("3201", "微信 iLink 配置解析失败", "Failed to parse WeChat iLink configuration.", "IM"),
|
||||
imCannotResolveTargetId("3207", "无法从配置数据中解析目标唯一标识", "Cannot resolve target unique identifier from configuration data.", "IM"),
|
||||
imChannelConfigDuplicate("3208", "该渠道配置已存在", "This channel configuration already exists.", "IM"),
|
||||
imChannelConfigDuplicateDetail("3209", "该渠道配置已存在: %s %s %s", "This channel configuration already exists: %s %s %s", "IM"),
|
||||
customPageMultimodalModelUnavailable("3212", "当前多模态模型不可用:%s", "Multimodal model is unavailable: %s", "自定义页面"),
|
||||
customPageModelNotMultimodal("3213", "当前模型不支持多模态,无法解析图片,模型 id=%s", "This model does not support multimodal input; cannot parse images. Model id=%s", "自定义页面"),
|
||||
customPageChatModelUnavailable("3214", "当前聊天模型不可用:%s", "Chat model is unavailable: %s", "自定义页面"),
|
||||
customPageProxyProjectBuildNotFound("3215", "未找到项目构建信息", "Project build information not found.", "自定义页面"),
|
||||
customPageProxyDevServerNotStarted("3216", "项目未启动开发服务器", "Dev server has not been started for this project.", "自定义页面"),
|
||||
customPageProxyAuthFailed("3217", "认证失败", "Authentication failed.", "自定义页面"),
|
||||
customPageProxyNoSpace("3218", "无空间信息", "No space information.", "自定义页面"),
|
||||
customPageProxyNoAgentPermission("3219", "无Agent权限", "No Agent permission.", "自定义页面"),
|
||||
customPageProxyNoAgentOrchestrationPermission("3220", "无Agent编排权限", "No Agent orchestration permission.", "自定义页面"),
|
||||
|
||||
sandboxClientAddressUnavailable("3222", "无法获取客户端服务地址", "Unable to obtain client service address.", "沙盒"),
|
||||
sandboxUserProxyCreateFailed("3223", "创建用户沙盒代理失败", "Failed to create user sandbox proxy.", "沙盒"),
|
||||
sandboxDeployFailedWithHelp("3225", "%s", "%s", "沙盒"),
|
||||
sandboxConfigKeyDuplicate("3226", "配置键已存在,请使用其他配置键", "Configuration key already exists; use another key.", "沙盒"),
|
||||
|
||||
mcpNotFound("3227", "MCP不存在", "MCP does not exist.", "MCP"),
|
||||
mcpServiceConfigJsonInvalid("3228", "服务配置格式错误,请填写正确的JSON数据", "Invalid service configuration format; provide valid JSON.", "MCP"),
|
||||
mcpNpxConfigInvalid("3229", "请输入正确的npx配置", "Enter a valid npx configuration.", "MCP"),
|
||||
mcpUvxConfigInvalid("3230", "请输入正确的uvx配置", "Enter a valid uvx configuration.", "MCP"),
|
||||
mcpStreamableHttpConfigInvalid("3231", "请输入正确的streamableHTTP配置", "Enter a valid streamable HTTP configuration.", "MCP"),
|
||||
mcpSseConfigInvalid("3232", "请输入正确的sse配置", "Enter a valid SSE configuration.", "MCP"),
|
||||
/** MCP / 插件参数校验共用 */
|
||||
paramArgTypeInvalid("3234", "参数[%s]类型错误", "Parameter [%s] has an invalid type.", "参数"),
|
||||
mcpDeployResponseNull("3235", "McpDeployStatusResponse 为空", "McpDeployStatusResponse is null.", "MCP"),
|
||||
remoteServiceMessage("3236", "%s", "%s", "远程调用"),
|
||||
|
||||
customPageDomainBindPermissionDenied("3237", "无权限操作该域名绑定", "No permission to manage this domain binding.", "自定义页面"),
|
||||
customPageProxyEnvPathExists("3238", "指定环境和路径的代理配置已存在,无法添加", "Proxy config for this environment and path already exists; cannot add.", "自定义页面"),
|
||||
customPageProxyEnvPathNotFoundForEdit("3239", "指定环境和路径的代理配置不存在,无法编辑", "Proxy config for this environment and path does not exist; cannot edit.", "自定义页面"),
|
||||
customPageProxyEnvPathNotFoundForDelete("3240", "指定环境和路径的代理配置不存在,无法删除", "Proxy config for this environment and path does not exist; cannot delete.", "自定义页面"),
|
||||
customPagePathConfigExists("3241", "指定路径的配置已存在,无法添加", "Configuration for this path already exists; cannot add.", "自定义页面"),
|
||||
customPagePathConfigNotFoundForEdit("3242", "指定路径的配置不存在,无法编辑", "Configuration for this path does not exist; cannot edit.", "自定义页面"),
|
||||
customPagePathConfigNotFoundForDelete("3243", "指定路径的配置不存在,无法删除", "Configuration for this path does not exist; cannot delete.", "自定义页面"),
|
||||
customPageProjectConfigNotFound("3244", "项目配置不存在", "Project configuration does not exist.", "自定义页面"),
|
||||
customPageDuplicatePathConfig("3245", "存在重复的路径配置: %s:%s", "Duplicate path configuration: %s:%s", "自定义页面"),
|
||||
customPageBackendListEmpty("3246", "后端地址列表不能为空: %s:%s", "Backend address list cannot be empty: %s:%s", "自定义页面"),
|
||||
customPageBackendAddressEmpty("3247", "后端地址不能为空: %s:%s", "Backend address cannot be empty: %s:%s", "自定义页面"),
|
||||
customPagePluginQueryFailed("3248", "查询插件失败,插件[%s:%s]", "Failed to query plugin [%s:%s]", "自定义页面"),
|
||||
customPageWorkflowQueryFailed("3249", "查询工作流失败,工作流[%s:%s]", "Failed to query workflow [%s:%s]", "自定义页面"),
|
||||
customPageDatasourceParamNameDuplicate("3251", "存在重复的参数名称: %s", "Duplicate parameter name: %s", "自定义页面"),
|
||||
customPageConfigFileParseFailed("3252", "配置文件解析失败: %s", "Failed to parse configuration file: %s", "自定义页面"),
|
||||
customPageWebAppCountExceeded("3253", "你的网页应用数量已经达到上限,网页应用上限数为%s", "You have reached the web app limit; maximum is %s.", "自定义页面"),
|
||||
customPageCreateConfigFailed("3254", "创建自定义页面(config)失败: %s", "Failed to create custom page (config): %s", "自定义页面"),
|
||||
customPageCreateBuildFailed("3255", "创建自定义页面(build)失败: %s", "Failed to create custom page (build): %s", "自定义页面"),
|
||||
customPageCreateAgentFailed("3256", "创建智能体失败: %s", "Failed to create agent: %s", "自定义页面"),
|
||||
customPageBindAgentFailed("3257", "绑定智能体到项目失败: %s", "Failed to bind agent to project: %s", "自定义页面"),
|
||||
customPageCreateReverseProxyFailed("3258", "创建反向代理项目失败: %s", "Failed to create reverse proxy project: %s", "自定义页面"),
|
||||
customPageDeleteReverseProxyFailed("3259", "删除反向代理配置失败: %s", "Failed to delete reverse proxy configuration: %s", "自定义页面"),
|
||||
customPageConfigPageParamsFailed("3260", "配置页面参数失败: %s", "Failed to configure page parameters: %s", "自定义页面"),
|
||||
customPageAddPathConfigFailed("3261", "添加路径配置失败: %s", "Failed to add path configuration: %s", "自定义页面"),
|
||||
customPageEditPathConfigFailed("3262", "编辑路径配置失败: %s", "Failed to edit path configuration: %s", "自定义页面"),
|
||||
customPageDeletePathConfigFailed("3263", "删除路径配置失败: %s", "Failed to delete path configuration: %s", "自定义页面"),
|
||||
customPageBatchReverseProxyFailed("3264", "批量配置反向代理失败: %s", "Failed to batch configure reverse proxy: %s", "自定义页面"),
|
||||
customPageSaveDataSourceFailed("3265", "保存数据源失败: %s", "Failed to save data source: %s", "自定义页面"),
|
||||
customPageUnbindDataSourceFailed("3266", "解绑数据源失败: %s", "Failed to unbind data source: %s", "自定义页面"),
|
||||
customPageUpdateProjectFailed("3267", "修改项目失败: %s", "Failed to update project: %s", "自定义页面"),
|
||||
customPageUpdateAgentFailed("3268", "更新智能体失败: %s", "Failed to update agent: %s", "自定义页面"),
|
||||
customPageUpdateProjectException("3269", "修改项目异常: %s", "Error while updating project: %s", "自定义页面"),
|
||||
customPageDeleteProjectFailed("3270", "删除项目失败: %s", "Failed to delete project: %s", "自定义页面"),
|
||||
customPageDeleteAgentFailed("3271", "删除智能体失败: %s", "Failed to delete agent: %s", "自定义页面"),
|
||||
customPageDeleteProjectException("3272", "删除项目异常: %s", "Error while deleting project: %s", "自定义页面"),
|
||||
customPageCopyPluginFailed("3273", "复制插件失败: %s", "Failed to copy plugin: %s", "自定义页面"),
|
||||
customPageCopyWorkflowFailed("3274", "复制工作流失败: %s", "Failed to copy workflow: %s", "自定义页面"),
|
||||
customPageProxyPathLoadFailed("3275", "获取页面配置失败", "Failed to load page configuration.", "自定义页面"),
|
||||
customPageProxyPathNoAgent("3277", "页面没有绑定智能体", "No agent is bound to this page.", "自定义页面"),
|
||||
customPageKeepAliveDbUpdateFailed("3278", "KeepAlive更新库表失败", "KeepAlive failed to update database tables.", "自定义页面"),
|
||||
|
||||
//加密解密异常
|
||||
cipherDecryptFailed("4001", "解密失败", "Decryption failed.", "解密失败"),
|
||||
cipherEncryptFailed("4002", "加密失败", "Encryption failed.", "加密失败"),
|
||||
|
||||
//知识库
|
||||
knowledgeTemplateDirectiveTypeNotFound("5002", "模板指令类型不存在", "Template directive type does not exist.", "模板指令类型不存在"),
|
||||
knowledgeUnknownAnalysisDimension("5005", "未识别的分析维度类型[%s]", "Unknown analysis dimension type [%s].", "未识别的分析维度类型"),
|
||||
knowledgeDataMappingFailed("5006", "数据映射识别,异常=%s", "Data mapping failed, error=%s", "excel数据映射记录"),
|
||||
knowledgeExcelDataRequired("5007", "Excel相关数据不能为空", "Excel-related data cannot be empty.", "Excel相关数据不能为空"),
|
||||
knowledgeExcelHeaderRequired("5008", "Excel抬头字段信息不能为空", "Excel header field information cannot be empty.", "Excel抬头字段信息不能为空"),
|
||||
knowledgeVectorDatabaseNotFound("5011", "向量数据库[{}]不存在", "Vector database [{}] does not exist.", ""),
|
||||
knowledgeFileIdNotFound("5012", "文件ID不存在", "File ID does not exist.", ""),
|
||||
knowledgeDocumentParseFailed("5014", "解析文档失败", "Failed to parse document.", ""),
|
||||
knowledgeDocumentUnsupportedType("5015", "解析文档失败,错误:不支持的文件类型", "Failed to parse document: unsupported file type.", ""),
|
||||
knowledgeLlmAnswerEmpty("5016", "大模型返回的答案为空,分段id=%s", "The model returned an empty answer, segment id=%s", ""),
|
||||
knowledgeLlmQuestionEmpty("5017", "大模型返回的问题为空,分段id=%s", "The model returned an empty question, segment id=%s", ""),
|
||||
knowledgeImportFileFailed("5019", "导入文件失败,%s", "Failed to import file, %s", ""),
|
||||
knowledgeGenerateTemplateFailed("5020", "生成模板失败:,%s", "Failed to generate template: %s", ""),
|
||||
knowledgeKbNotFoundById("5021", "知识库不存在,知识库ID=%s", "Knowledge base does not exist, id=%s", ""),
|
||||
knowledgeVectorizationFailed("5022", "向量化失败,%s", "Vectorization failed, %s", ""),
|
||||
knowledgeDeleteKbFulltextFailed("5023", "删除知识库全文检索数据失败", "Failed to delete knowledge base full-text index data.", ""),
|
||||
knowledgeDeleteDocFulltextFailed("5024", "删除文档全文检索数据失败", "Failed to delete document full-text index data.", ""),
|
||||
knowledgeDeleteSegmentFulltextFailed("5025", "删除原始分段全文检索数据失败", "Failed to delete original segment full-text index data.", ""),
|
||||
knowledgeJsonParseUnsupported("5026", "解析JSON文档失败,JSON格式不支持,期望JSON数组或JSON对象", "Failed to parse JSON document: unsupported format; expected a JSON array or object.", ""),
|
||||
knowledgeQaGenerationBusy("5027", "操作失败:当前数据正在生成问答,请稍后重试!", "Operation failed: Q&A generation is in progress for this data. Please try again later.", "知识库"),
|
||||
knowledgeStorageUpperBound("5028", "操作失败,已超过知识库的存储上限!(最大%sGB)", "Operation failed: knowledge base storage limit exceeded (max %s GB).", "知识库"),
|
||||
knowledgeKbCreateCountExceeded("5029", "操作失败,添加的知识库数量超过上限(%s)", "Operation failed: number of knowledge bases exceeds the limit (%s).", "知识库"),
|
||||
knowledgeNotFoundSimple("5030", "知识库不存在", "Knowledge base does not exist.", "知识库"),
|
||||
memoryUnitNotFound("5031", "记忆单元不存在: %s", "Memory unit does not exist: %s", "记忆"),
|
||||
modelProxyTokenLimitExceeded("5032", "超出 token 限制", "Token limit exceeded.", "模型代理"),
|
||||
|
||||
//组件模块
|
||||
composeCannotGetCreateTableDdl("6002", "无法获取建表DDL语句", "Unable to obtain CREATE TABLE DDL.", ""),
|
||||
composeDorisDbNameParseFailed("6003", "解析Doris数据库名称失败: %s", "Failed to parse Doris database name: %s", ""),
|
||||
composeSqlOnlyDmlAllowed("6004", "只允许执行 SELECT/INSERT/UPDATE/DELETE 查询语句", "Only SELECT, INSERT, UPDATE, or DELETE statements are allowed.", ""),
|
||||
composeSqlEmpty("6005", "执行的SQL语句不能为空", "SQL statement cannot be empty.", ""),
|
||||
composeSqlExecuteFailed("6006", "执行SQL失败,%s", "SQL execution failed, %s", ""),
|
||||
composeCreateTableFailed("6008", "创建表失败", "Failed to create table.", ""),
|
||||
composeCannotBuildUpdateSet("6010", "无法构建更新的 SET 子句", "Unable to build UPDATE SET clause.", ""),
|
||||
composeUpdateDataEmpty("6011", "更新的数据不能为空", "Update data cannot be empty.", ""),
|
||||
composeSqlParseFailed("6015", "SQL解析失败,%s", "SQL parse failed, %s", ""),
|
||||
composeSqlOnlyDdl("6016", "只允许DDL语句,sql=%s", "Only DDL statements are allowed, sql=%s", ""),
|
||||
composeQueryAllDataFailed("6017", "查询全部数据失败", "Failed to query all data.", ""),
|
||||
composeCannotDropFieldWithData("6018", "表中已有数据,不允许删除字段", "Cannot drop column: table already contains data.", ""),
|
||||
composeCannotChangeUniqueWithData("6019", "字段[%s]已有数据,不允许修改唯一性约束", "Cannot change unique constraint on field [%s]: data already exists.", ""),
|
||||
composeCannotChangeNullableWithData("6020", "字段[%s]已有数据,不允许修改非空约束", "Cannot change nullability on field [%s]: data already exists.", ""),
|
||||
composeDbTypeNotConfigured("6021", "未配置数据库类型,配置:spring.datasource.sql-generator.type", "Database type not configured; set spring.datasource.sql-generator.type.", ""),
|
||||
composeUnsupportedDbType("6022", "不支持的数据库类型: %s, 仅支持 mysql 或 doris", "Unsupported database type: %s; only mysql or doris is supported.", ""),
|
||||
composeDorisUrlNotConfigured("6023", "未配置Doris数据源URL,配置:spring.datasource.dynamic.datasource.doris.url", "Doris datasource URL not configured; set spring.datasource.dynamic.datasource.doris.url.", ""),
|
||||
composeInsertDataEmpty("6024", "插入的数据不能为空", "Insert data cannot be empty.", ""),
|
||||
composeTableDefinitionNotFound("6025", "表定义不存在", "Table definition does not exist.", ""),
|
||||
composeCreateIndexFailed("6026", "创建索引失败", "Failed to create index.", ""),
|
||||
composeFieldNameTooLong("6028", "字段名长度不能超过64字符", "Field name cannot exceed 64 characters.", ""),
|
||||
composeFieldNameMustStartWithLetter("6029", "字段名必须以英文字母开头", "Field name must start with a letter.", ""),
|
||||
composeFieldNameInvalidChars("6030", "字段名只能包含字母、数字和下划线", "Field name may only contain letters, digits, and underscores.", ""),
|
||||
composeCheckTableExistsFailed("6031", "检查表是否存在时发生错误,数据库,%s", "Error while checking if table exists, database %s", ""),
|
||||
composeTruncateTableFailed("6032", "清空表数据时发生错误,数据库,%s", "Error while truncating table, database %s", ""),
|
||||
composeGetTableDefinitionFailed("6033", "获取表定义信息时发生错误,数据库,%s", "Error while fetching table definition, database %s", ""),
|
||||
composeRawSqlExecuteFailed("6034", "执行原始管理/DML/DDL的SQL异常,%s", "Error executing raw admin/DML/DDL SQL, %s", ""),
|
||||
composeUnsupportedSqlType("6035", "不支持的SQL类型,SqlType=%s", "Unsupported SQL type, SqlType=%s", ""),
|
||||
composeBuildConditionFailed("6036", "创建条件表达式失败,%s", "Failed to build condition expression, %s", ""),
|
||||
composeDefaultValueMustBeNumber("6037", "字段[%s]的默认值必须为数值", "Default value for field [%s] must be numeric.", ""),
|
||||
composeDefaultValueMustBeBoolean("6038", "字段[%s]的默认值必须为布尔值", "Default value for field [%s] must be boolean.", ""),
|
||||
composeDefaultValueTooLong("6039", "字段[%s]的默认值长度不能超过255字符", "Default value for field [%s] cannot exceed 255 characters.", ""),
|
||||
composeMediumtextNoDefault("6040", "MEDIUMTEXT类型字段[%s]不允许设置默认值", "MEDIUMTEXT field [%s] cannot have a default value.", "MEDIUMTEXT类型字段不允许设置默认值"),
|
||||
composeExcelRowCountExceeded("6041", "Excel数据行数超过限制,最大支持[%s]行", "Excel row count exceeds limit; maximum [%s] rows.", ""),
|
||||
composeTableRowCountExceeded("6042", "表总行数超过限制,最大支持[%s]行", "Total table row count exceeds limit; maximum [%s] rows.", ""),
|
||||
composeTableDefMissingFields("6043", "表定义缺少字段定义", "Table definition is missing field definitions.", ""),
|
||||
composeFieldAlreadyExists("6044", "字段[%s]已存在", "Field [%s] already exists.", ""),
|
||||
composeDefaultValueOutOfRange("6045", "字段[%s]的默认值超出范围,范围区间:[%s,%s]", "Default value for field [%s] is out of range [%s, %s].", ""),
|
||||
composeGenericMessage("6047", "%s", "%s", ""),
|
||||
|
||||
|
||||
|
||||
//日志平台
|
||||
logPlatformSearchFailed("7001", "搜索失败,%s", "Search failed, %s", "搜索失败"),
|
||||
logPlatformInsertFailed("7002", "新增失败,%s", "Insert failed, %s", "新增失败"),
|
||||
logPlatformBatchInsertFailed("7003", "批量新增失败,%s", "Batch insert failed, %s", "批量新增失败"),
|
||||
|
||||
//生态市场
|
||||
ecoMarketGetConfigFailed("8002", "获取配置异常,%s", "Failed to fetch configuration, %s", "获取配置详情异常"),
|
||||
ecoMarketPublishConfigFailed("8003", "发布配置异常,%s", "Failed to publish configuration, %s", "发布配置异常"),
|
||||
ecoMarketOfflineConfigFailed("8004", "下线配置异常,%s", "Failed to offline configuration, %s", "下线配置异常"),
|
||||
ecoMarketQueryConfigStatusFailed("8005", "查询配置状态异常,%s", "Failed to query configuration status, %s", "查询配置状态异常"),
|
||||
ecoMarketQueryPublishedDetailFailed("8006", "查询发布配置详情异常,%s", "Failed to query published configuration detail, %s", "查询发布配置详情异常"),
|
||||
ecoMarketCannotDeleteRemotePublished("8010", "远程生态市场已上架的配置不能删除", "Cannot delete configuration that is listed on the remote marketplace.", ""),
|
||||
ecoMarketClientSecretFetchFailed("8011", "获取客户端密钥失败,请稍后重试", "Failed to fetch client secret. Please try again later.", "获取客户端密钥失败"),
|
||||
ecoMarketUpdateOnlyDraftOrRejected("8012", "只能更新草稿或被驳回状态的配置", "Only draft or rejected configurations can be updated.", "只能更新草稿或被驳回状态的配置"),
|
||||
ecoMarketNoPermissionToUpdate("8013", "无权更新此配置", "No permission to update this configuration.", "无权更新此配置"),
|
||||
ecoMarketConfigInfoNotFound("8014", "未找到对应的配置信息", "Configuration not found.", "未找到对应的配置信息"),
|
||||
ecoMarketModelAndUidRequired("8016", "配置模型不能为空且UID必须指定", "Model is required and UID must be specified.", "配置模型不能为空且UID必须指定"),
|
||||
ecoMarketPublishedConfigNotFound("8017", "未找到对应的发布配置信息", "Published configuration not found.", "未找到对应的发布配置信息"),
|
||||
ecoMarketUnsupportedDataType("8019", "不支持的数据类型", "Unsupported data type.", ""),
|
||||
ecoMarketReleaseFailed("8020", "发版失败,%s", "Release failed, %s", ""),
|
||||
ecoMarketSaveConfigFailed("8021", "保存配置异常,%s", "Failed to save configuration, %s", ""),
|
||||
ecoMarketEnableConfigFailed("8023", "启用配置失败", "Failed to enable configuration.", ""),
|
||||
ecoMarketDuplicateShareNotAllowed("8025", "已有重复的配置,不允许新建我的分享", "Duplicate configuration exists; cannot create a new share.", ""),
|
||||
ecoMarketCenterUpgrading("8026", "生态市场中心服务升级中,请稍后再试", "Eco marketplace center is upgrading. Please try again later.", ""),
|
||||
ecoMarketConfigResultBodyEmpty("8027", "获取配置结果失败,Body为空", "Failed to get configuration result: empty body.", ""),
|
||||
ecoMarketDeployMcpFailed("8030", "部署MCP失败", "Failed to deploy MCP.", "部署MCP失败"),
|
||||
ecoMarketStopMcpFailed("8031", "停止MCP失败", "Failed to stop MCP.", "停止MCP失败"),
|
||||
ecoMarketMcpConfigParseFailed("8032", "MCP配置解析失败", "Failed to parse MCP configuration.", "MCP配置解析失败"),
|
||||
ecoMarketDisableConfigFailed("8033", "禁用配置失败", "Failed to disable configuration.", ""),
|
||||
ecoMarketOfflineOnlyPublishedOrReviewing("8034", "只有已发布/审核中状态的配置可以下线", "Only published or under-review configurations can be taken offline.", ""),
|
||||
ecoMarketOfflineServerConfigFailed("8035", "下线服务器配置失败,请稍后重试", "Failed to offline server configuration. Please try again later.", ""),
|
||||
ecoMarketNotPublishedNoOffline("8036", "未发布,无需下线", "Not published; no need to offline.", ""),
|
||||
ecoMarketRevokeOnlyReviewing("8037", "只有审核中状态的配置可以撤销发布", "Only under-review configurations can be revoked from publication.", ""),
|
||||
ecoMarketCannotShareFromMarket("8038", "禁止分享生态市场获取的配置", "Sharing configurations obtained from the marketplace is not allowed.", ""),
|
||||
ecoMarketAgentPageRequiredForShare("8039", "智能体未绑定页面,不能分享为应用页面", "Agent is not bound to a page; cannot share as an app page.", ""),
|
||||
ecoMarketPageExportFailed("8040", "页面导出失败", "Failed to export page.", ""),
|
||||
ecoMarketPageArchiveDownloadFailed("8042", "下载页面压缩包失败", "Failed to download page archive.", ""),
|
||||
ecoMarketPageProjectCreateFailed("8043", "创建页面项目失败", "Failed to create page project.", ""),
|
||||
ecoMarketPageArchiveUploadFailed("8044", "上传页面压缩包失败", "Failed to upload page archive.", ""),
|
||||
ecoMarketPagePublishFailed("8045", "发布页面失败", "Failed to publish page.", ""),
|
||||
ecoMarketAppPageEnableFailed("8046", "应用页面启用失败", "Failed to enable app page.", ""),
|
||||
ecoMarketDeleteOnlyOwnShare("8047", "只能删除自己分享的配置", "You can only delete configurations you shared.", ""),
|
||||
|
||||
|
||||
//AI 开发自定义页面
|
||||
customPageAgentTaskInProgress("9010", "Agent正在执行任务,请等待当前任务完成后再发送新请求", "Agent is running a task; wait for it to finish before sending another request.", "Agent正在执行任务,请等待当前任务完成后再发送新请求;前端全局处理了这个错误码"),
|
||||
|
||||
/** 智能体模块内部/防御性:仅英文提示,不做多语言业务文案 */
|
||||
agentDependencyServiceError("9198", "依赖服务返回错误", "The dependency service returned an error.", "RPC/内部透传"),
|
||||
|
||||
// 智能体 Agent 模块(9200–9499)
|
||||
agentWorkflowIdInvalid("9201", "workflowId错误", "Invalid workflowId.", "参数"),
|
||||
agentWorkflowHasInvalidNodesForPublish("9202", "工作流存在错误节点,不允许发布,请重新试运行", "Workflow has invalid nodes; publishing is not allowed. Re-run and fix.", "工作流"),
|
||||
agentWorkflowCyclicDependency("9203", "你添加的节点存在工作流循环依赖,请重新选择", "The nodes you added create a cyclic dependency; choose again.", "工作流"),
|
||||
agentTableIdInvalid("9204", "表ID错误", "Invalid table ID.", "参数"),
|
||||
agentKnowledgeBaseRemovedOrMissing("9205", "知识库[%s]不存在或已删除,请移除", "Knowledge base [%s] does not exist or was removed; remove it.", "工作流/知识库"),
|
||||
agentWorkflowNodeIdInvalid("9206", "节点ID错误", "Invalid node ID.", "参数"),
|
||||
agentWorkflowNotFound("9207", "Workflow不存在", "Workflow does not exist.", "工作流"),
|
||||
agentIdInvalid("9208", "agentId错误", "Invalid agentId.", "参数"),
|
||||
agentModelComponentCannotAddManually("9209", "模型组件配置不能手动添加", "Model component cannot be added manually.", "智能体组件"),
|
||||
agentPluginNotFoundOrUnpublished("9210", "插件不存在或未发布", "Plugin does not exist or is not published.", "组件"),
|
||||
agentWorkflowNotFoundOrUnpublished("9211", "工作流不存在或未发布", "Workflow does not exist or is not published.", "组件"),
|
||||
agentMcpConfigIncomplete("9213", "MCP缺少必要配置参数", "MCP is missing required configuration.", "组件"),
|
||||
agentSkillNotFoundOrUnpublished("9214", "技能不存在或未发布", "Skill does not exist or is not published.", "组件"),
|
||||
agentModelComponentCannotDelete("9216", "模型组件配置不能删除", "Model component cannot be deleted.", "组件"),
|
||||
agentBoundModelOffline("9217", "智能体关联大模型已下线,请重新配置", "The bound LLM is offline; reconfigure the agent.", "智能体"),
|
||||
agentNotPublishedOrOffline("9218", "该智能体未发布或已下架", "This agent is not published or has been taken offline.", "发布"),
|
||||
agentDataNotFoundWithId("9219", "数据不存在,id=%s", "Data does not exist, id=%s", "数据"),
|
||||
agentPluginNotFound("9220", "插件不存在", "Plugin does not exist.", "通用"),
|
||||
agentWorkflowNotFoundSimple("9221", "工作流不存在", "Workflow does not exist.", "通用"),
|
||||
agentNotFound("9222", "智能体不存在", "Agent does not exist.", "通用"),
|
||||
agentTableSchemaQueryFailed("9223", "查询表结构定义失败", "Failed to query table schema.", "表结构"),
|
||||
agentTemplateConfigInvalid("9224", "该模版配置异常,暂时不可用", "This template configuration is invalid and temporarily unavailable.", "模版"),
|
||||
agentSandboxServerStoppedOrRemoved("9225", "关联的agent服务器已停止或已删除", "The associated agent server has stopped or been removed.", "沙箱/电脑"),
|
||||
agentSandboxNotFound("9226", "未找到沙盒服务器", "Sandbox server not found.", "沙箱/电脑"),
|
||||
agentPrivateComputerDeleteForbidden("9227", "私有电脑的智能体不允许在此删除", "Agents on a private computer cannot be deleted here.", "智能体"),
|
||||
agentKnowledgeIdInvalid("9228", "知识ID错误", "Invalid knowledge ID.", "参数"),
|
||||
agentPageIdInvalid("9229", "页面ID错误", "Invalid page ID.", "参数"),
|
||||
agentArgBooleanDefaultInvalid("9230", "参数[%s]类型为Boolean,默认值只能为true或false", "Parameter [%s] is Boolean; default must be true or false.", "变量"),
|
||||
agentArgIntegerDefaultInvalid("9231", "参数[%s]类型为Integer,默认值只能为整数", "Parameter [%s] is Integer; default must be an integer.", "变量"),
|
||||
agentArgNumberDefaultInvalid("9232", "参数[%s]类型为Number,默认值只能为数字", "Parameter [%s] is Number; default must be numeric.", "变量"),
|
||||
agentVariableNameDuplicated("9233", "变量名[%s]重复", "Duplicate variable name [%s].", "变量"),
|
||||
agentVariableSelectOptionsRequired("9234", "变量[%s]的输入类型为下拉选项,请设置下拉参数配置", "Variable [%s] uses a select input; configure dropdown options.", "变量"),
|
||||
agentVariablePluginOffline("9235", "变量[%s]引用的插件不存在或已下线", "Plugin referenced by variable [%s] does not exist or is offline.", "变量"),
|
||||
agentVariablePluginDataInvalid("9236", "变量[%s]引用的插件数据结构异常", "Invalid plugin data structure for variable [%s].", "变量"),
|
||||
agentVariablePluginOutputEmpty("9237", "变量[%s]引用的插件[%s]的输出参数为空", "For variable [%s], output parameters of referenced plugin [%s] are empty.", "变量"),
|
||||
agentVariablePluginOptionsMissing("9238", "变量[%s]引用的插件数据结构不符合规,缺少options", "Plugin data for variable [%s] is invalid: missing options.", "变量"),
|
||||
agentVariableWorkflowNotFound("9239", "变量[%s]引用的工作流不存在", "Workflow referenced by variable [%s] does not exist.", "变量"),
|
||||
agentVariableWorkflowNoOutput("9240", "变量[%s]引用的工作流没有输出参数", "Workflow referenced by variable [%s] has no output parameters.", "变量"),
|
||||
agentVariableWorkflowOptionsMissing("9241", "变量[%s]引用的工作流输出数据结构不符合规,缺少options", "Workflow output data for variable [%s] is invalid: missing options.", "变量"),
|
||||
agentVariableOptionsMissing("9242", "变量[%s]缺少选项", "Variable [%s] is missing options.", "变量"),
|
||||
agentComponentNotFoundOrRemoved("9243", "组件不存在或已删除", "Component does not exist or was removed.", "组件"),
|
||||
agentComponentTypeInvalid("9244", "组件类型错误,请检查是否使用了正确的接口", "Invalid component type; verify you are using the correct API.", "组件"),
|
||||
agentNotFoundAlt("9245", "Agent不存在", "Agent does not exist.", "智能体"),
|
||||
agentPublishedOffline("9246", "智能体未发布或已下架", "Agent is not published or has been taken offline.", "发布"),
|
||||
agentPluginOffline("9247", "插件不存在或已下架", "Plugin does not exist or has been taken offline.", "发布"),
|
||||
agentWorkflowOffline("9248", "工作流不存在或已下架", "Workflow does not exist or has been taken offline.", "发布"),
|
||||
agentSkillOffline("9249", "技能不存在或已下架", "Skill does not exist or has been taken offline.", "发布"),
|
||||
agentSkillDownloadDenied("9250", "无技能下载权限", "No permission to download skills.", "权限"),
|
||||
agentUnpublishFailedNotPublished("9251", "下架失败,未发布", "Unpublish failed: not published.", "发布"),
|
||||
agentViewDenied("9252", "无查看权限", "No permission to view.", "权限"),
|
||||
agentConversationNotFound("9253", "会话不存在", "Conversation does not exist.", "会话"),
|
||||
agentConversationPermissionDenied("9254", "无智能体会话权限", "No permission for this agent conversation.", "权限"),
|
||||
agentOfflineOrNotFound("9255", "智能体不存在或已下架", "Agent does not exist or has been taken offline.", "会话"),
|
||||
agentSelectedNotFound("9256", "选择的智能体不存在", "Selected agent does not exist.", "会话"),
|
||||
agentScheduledTaskLimitExceeded("9257", "用户在每个智能体进行中的定时任务不能超过%s个", "In-progress scheduled tasks per agent cannot exceed %s.", "定时任务"),
|
||||
agentOperationDenied("9258", "无操作权限", "Operation not permitted.", "权限"),
|
||||
agentWebAppNotFound("9259", "网页应用不存在", "Web app does not exist.", "自定义页"),
|
||||
agentEmbeddingModelDeleteForbidden("9260", "嵌入模型不允许删除", "Embedding model cannot be deleted.", "模型"),
|
||||
agentApplyIdInvalid("9261", "applyId错误", "Invalid applyId.", "参数"),
|
||||
agentPublishScopeNotSelected("9262", "未选择发布范围", "Publish scope not selected.", "发布"),
|
||||
agentPrivateCannotPublishToSquare("9263", "私有电脑的智能体不允许发布到广场", "Agents on a private computer cannot be published to the square.", "发布"),
|
||||
agentSpaceNotFound("9264", "空间[%s]不存在", "Space [%s] does not exist.", "发布"),
|
||||
agentSpacePublishDenied("9265", "无空间[%s]发布权限", "No permission to publish to space [%s].", "发布"),
|
||||
agentSpacePublishReceivingDisabled("9266", "空间[%s]未开启接收发布功能", "Space [%s] has not enabled receiving publications.", "发布"),
|
||||
agentSkillConfigParseFailed("9267", "技能配置解析失败", "Failed to parse skill configuration.", "技能"),
|
||||
agentUnpublishFailedAlreadyOffline("9268", "下架失败,未发布或已下架", "Unpublish failed: not published or already offline.", "发布"),
|
||||
agentUserSpacePublishDenied("9269", "用户无空间发布权限", "User has no permission to publish to spaces.", "发布"),
|
||||
agentUserPublishDenied("9270", "用户无发布权限", "User has no publish permission.", "发布"),
|
||||
agentUserNoPersonalSpace("9271", "用户没有个人空间", "User has no personal space.", "发布"),
|
||||
agentPluginIdInvalid("9272", "pluginId错误", "Invalid pluginId.", "参数"),
|
||||
agentPluginIdError("9273", "插件ID错误", "Invalid plugin ID.", "参数"),
|
||||
agentPageIdError("9274", "页面Id错误", "Invalid page ID.", "页面"),
|
||||
agentPageAgentIdError("9275", "智能体Id错误", "Invalid agent ID.", "页面"),
|
||||
agentPageEnvInvalid("9276", "环境错误", "Invalid environment.", "页面"),
|
||||
agentPageDatasourceInvalid("9277", "页面数据源错误", "Invalid page data source.", "页面"),
|
||||
agentAppAccessDenied("9279", "无应用访问权限", "No permission to access the app.", "权限"),
|
||||
agentPageSpacePermissionDenied("9280", "用户无页面所在空间权限", "User has no permission for the page's space.", "权限"),
|
||||
agentAgentPermissionDenied("9281", "用户无智能体权限", "User has no permission for this agent.", "权限"),
|
||||
agentPageNotBoundToAgent("9282", "调用的智能体未绑定对应页面", "The invoked agent is not bound to the corresponding page.", "页面"),
|
||||
agentPageDatasourceNotFound("9283", "请求的数据源不存在", "Requested data source does not exist.", "页面"),
|
||||
agentPluginNotPublished("9284", "插件ID错误或未发布", "Invalid plugin ID or plugin not published.", "页面"),
|
||||
agentPluginExecuteDenied("9285", "无插件执行权限", "No permission to execute plugin.", "权限"),
|
||||
agentExportFileGenerationFailed("9286", "生成导出文件失败", "Failed to generate export file.", "导入导出"),
|
||||
agentPermissionDeniedGeneric("9287", "没有权限", "Permission denied.", "权限"),
|
||||
agentRelatedOfflineOrNotFound("9288", "相关智能体不存在或已下架", "Related agent does not exist or is offline.", "API"),
|
||||
agentConversationIdInvalid("9289", "错误的conversationId", "Invalid conversationId.", "API"),
|
||||
agentTempConversationNotFound("9290", "临时会话不存在", "Temporary conversation does not exist.", "临时会话"),
|
||||
agentTempConversationExpired("9291", "临时会话已过期", "Temporary conversation has expired.", "临时会话"),
|
||||
agentClientDisabled("9292", "智能体客户端已停用", "Agent client is disabled.", "沙箱"),
|
||||
agentComputerServerDisabled("9293", "会话所在智能体电脑服务端已停用", "Agent computer server for this session is disabled.", "沙箱"),
|
||||
agentClientOffline("9294", "智能体客户端已离线", "Agent client is offline.", "沙箱"),
|
||||
agentSandboxCapacityExceeded("9295", "当前过于火爆,请稍后再试", "Service is busy. Please try again later.", "沙箱"),
|
||||
agentNotPublishedOrOfflineAlt("9296", "未发布或已下架", "Not published or offline.", "收藏"),
|
||||
agentPublishIdInvalid("9297", "发布ID错误", "Invalid publish ID.", "发布"),
|
||||
agentMcpServiceNotFoundOrDenied("9298", "选择的MCP服务不存在或没有权限", "Selected MCP service does not exist or access denied.", "MCP"),
|
||||
agentMcpToolNotFoundOrDenied("9299", "选择的工具不存在或没有权限", "Selected tool does not exist or access denied.", "MCP"),
|
||||
agentPluginRequiredParamMissing("9300", "请填写必要参数[%s],便于获取返回参数", "Fill required parameter [%s] to obtain return values.", "插件"),
|
||||
agentPluginOfflineReplaceRequired("9303", "插件[%s]未发布或已下线,请更换其他适合的插件", "Plugin [%s] is not published or is offline; choose another plugin.", "插件"),
|
||||
agentPluginOfflineSimple("9304", "该插件未发布或已下线", "This plugin is not published or is offline.", "插件"),
|
||||
agentPluginSpacePermissionDenied("9305", "当前空间没有插件权限", "No plugin permission in this space.", "插件"),
|
||||
agentSessionNotFound("9306", "未找到当前会话", "Current session not found.", "文件"),
|
||||
agentResourceAccessDenied("9307", "无权访问当前资源", "No permission to access this resource.", "文件"),
|
||||
agentRequiredParamEmpty("9308", "必传参数为空", "Required parameter is empty.", "参数"),
|
||||
agentContainerServiceCallFailed("9309", "容器服务调用失败", "Container service call failed.", "容器"),
|
||||
agentWorkflowMissingStartNode("9313", "工作流缺少开始节点", "Workflow is missing a start node.", "工作流"),
|
||||
agentWorkflowMissingEndNode("9314", "工作流缺少结束节点", "Workflow is missing an end node.", "工作流"),
|
||||
agentWorkflowSelfReference("9315", "工作流不能引用自己", "Workflow cannot reference itself.", "工作流"),
|
||||
agentWorkflowNotPublished("9316", "工作流未发布", "Workflow is not published.", "工作流"),
|
||||
agentWorkflowPluginPermissionDenied("9317", "没有插件权限", "No plugin permission.", "工作流"),
|
||||
agentWorkflowCannotDeleteTerminalNodes("9319", "不能删除起始节点和结束节点", "Cannot delete start or end nodes.", "工作流"),
|
||||
agentWorkflowCannotDeleteLoopTerminalNodes("9320", "不能删除循环起始节点和结束节点", "Cannot delete loop start or end nodes.", "工作流"),
|
||||
agentWorkflowStartNodeNotFound("9321", "未找到起始节点", "Start node not found.", "工作流"),
|
||||
agentWorkflowCannotCopyTerminalNodes("9322", "不能复制起始节点和结束节点", "Cannot copy start or end nodes.", "工作流"),
|
||||
agentWorkflowSpacePermissionDenied("9323", "当前空间没有工作流[%s]的权限", "No permission for workflow [%s] in this space.", "工作流"),
|
||||
agentWorkflowNodeCycleEdge("9367", "节点<%s>与节点<%s>存在循环连线", "Cycle edge between node <%s> and node <%s>.", "工作流"),
|
||||
agentSkillUploadFileRequired("9327", "请选择要上传的文件", "Please select a file to upload.", "技能"),
|
||||
agentSkillFileFormatInvalid("9329", "文件必须是zip/.skill格式,或者为SKILL.md文件", "File must be .zip/.skill or SKILL.md.", "技能"),
|
||||
agentSkillTargetSpaceRequired("9330", "请选择目标空间", "Please select a target space.", "技能"),
|
||||
agentSkillZipFormatInvalid("9331", "ZIP 文件格式错误或不兼容,请使用标准的 ZIP 压缩格式重新打包文件。错误详情: %s", "Invalid or incompatible ZIP; repack with standard ZIP. Details: %s", "技能"),
|
||||
agentSkillFileFormatError("9332", "文件格式错误,请上传正确的技能文件。错误详情: %s", "Invalid file format; upload a valid skill file. Details: %s", "技能"),
|
||||
agentSkillFileSizeExceeded100m("9333", "文件大小不能超过 100M", "File size cannot exceed 100 MB.", "技能"),
|
||||
agentSkillReadSkillMdFailed("9334", "读取 SKILL.md 文件失败", "Failed to read SKILL.md.", "技能"),
|
||||
agentSkillMdRequired("9335", "技能包中缺少必需的 SKILL.md 文件", "Required SKILL.md is missing from the skill package.", "技能"),
|
||||
agentSkillMdNameDescRequired("9336", "SKILL.md 文件中必须包含 name 和 description 信息", "SKILL.md must include name and description.", "技能"),
|
||||
agentSkillTemplateReadFailed("9337", "读取技能模板失败: %s", "Failed to read skill template: %s", "技能"),
|
||||
agentSkillNotFoundOrDenied("9338", "技能不存在或无权限使用", "Skill does not exist or access denied.", "技能"),
|
||||
agentSkillFilePathInvalid("9339", "filePath 无效", "Invalid filePath.", "技能"),
|
||||
agentSkillUploadProcessFailed("9340", "处理上传文件失败: %s", "Failed to process uploaded file: %s", "技能"),
|
||||
agentSkillMdDeleteForbidden("9343", "SKILL.md 文件不允许删除", "SKILL.md cannot be deleted.", "技能"),
|
||||
agentSkillDirRenameFailed("9344", "目录重命名失败,源目录不存在或为空", "Failed to rename directory: source missing or empty.", "技能"),
|
||||
agentSkillFileRenameFailed("9345", "文件重命名失败,源文件不存在", "Failed to rename file: source does not exist.", "技能"),
|
||||
agentSkillRenameSourceMissing("9346", "缺少文件重命名的源文件名", "Source file name for rename is missing.", "技能"),
|
||||
agentSkillUnknownFileOperation("9347", "未知的文件操作类型", "Unknown file operation type.", "技能"),
|
||||
agentSkillSingleFileSizeExceeded("9348", "单个文件大小不能超过 100M", "Single file size cannot exceed 100 MB.", "技能"),
|
||||
agentSkillExportFailed("9349", "导出技能失败", "Failed to export skill.", "技能"),
|
||||
agentDefaultModelDeleteForbidden("9350", "默认模型不允许删除", "Default model cannot be deleted.", "模型"),
|
||||
agentModelNotFound("9351", "模型不存在", "Model does not exist.", "模型"),
|
||||
agentModelJsonInvalid("9352", "模型返回的JSON格式不正确,请检查提示词", "Invalid JSON from model; check your prompt.", "模型"),
|
||||
agentWorkspaceCreateFailed("9353", "创建工作空间失败", "Failed to create workspace.", "工作空间"),
|
||||
agentSkillZipPackFailed("9354", "打包技能 zip 失败", "Failed to pack skill zip.", "工作空间"),
|
||||
agentSkillFilePushFailed("9355", "推送技能文件失败", "Failed to push skill files.", "工作空间"),
|
||||
agentSkillAgentPackFailed("9356", "打包 skill/agent 失败", "Failed to pack skill/agent.", "工作空间"),
|
||||
agentCodeExecuteUnavailable("9357", "代码执行接口暂不可用,请稍后再试", "Code execution is temporarily unavailable. Try again later.", "代码执行"),
|
||||
agentPluginTypeInvalid("9358", "插件类型错误", "Invalid plugin type.", "插件执行"),
|
||||
agentSkillNotFound("9359", "技能不存在", "Skill does not exist.", "技能"),
|
||||
agentOpenapiPluginIdInvalid("9360", "pluginId 错误", "Invalid pluginId.", "OpenAPI 英文"),
|
||||
agentOpenapiExecutePermissionDenied("9361", "无执行权限", "Execute permission denied.", "OpenAPI 英文"),
|
||||
agentOpenapiModelIdInvalid("9362", "model id 错误", "Invalid model id.", "OpenAPI 英文"),
|
||||
agentOpenapiConversationIdInvalid("9363", "conversationId 错误", "Invalid conversationId.", "OpenAPI 英文"),
|
||||
agentOpenapiPluginNotFound("9364", "Plugin不存在", "Plugin does not exist.", "英文资源名"),
|
||||
agentOpenapiSkillNotFound("9366", "Skill不存在", "Skill does not exist.", "英文资源名"),
|
||||
|
||||
/** 沙箱 / 电脑连接与状态 */
|
||||
agentComputerConnectFailed("9371", "智能体电脑连接失败", "Failed to connect to agent computer.", "沙箱"),
|
||||
agentStatusQueryResponseInvalid("9372", "状态查询返回数据结构异常", "Invalid status query response structure.", "沙箱"),
|
||||
agentComputerStartupFailed("9373", "智能体电脑启动失败,请重试", "Failed to start agent computer. Please retry.", "沙箱"),
|
||||
|
||||
/** 助手 / 表查询(与「表结构定义」文案区分) */
|
||||
agentAssistantTableSchemaQueryFailed("9375", "查询表结构失败", "Failed to query table schema.", "助手"),
|
||||
|
||||
/** 工作流节点执行 */
|
||||
agentWorkflowMcpReferenceRemoved("9377", "节点引用的MCP服务已被删除", "MCP service referenced by the node has been deleted.", "工作流"),
|
||||
agentWorkflowLoopNotFullyConnected("9378", "循环节点未完整连接", "Loop nodes are not fully connected.", "工作流"),
|
||||
agentWorkflowLoopMaxCountInvalid("9379", "循环节点最大循环次数不能小于等于0", "Loop max iterations must be greater than 0.", "工作流"),
|
||||
agentWorkflowConditionBranchesEmpty("9380", "条件分支列表不能为空", "Condition branch list cannot be empty.", "工作流"),
|
||||
|
||||
|
||||
pay_order_not_found("9381", "支付订单不存在", "Payment order not found", "支付"),
|
||||
|
||||
pay_developer_account_not_found("9382", "开发者账户信息不存在", "Developer account not found", "支付");
|
||||
|
||||
/**
|
||||
* 错误码
|
||||
*/
|
||||
private final String code;
|
||||
/**
|
||||
* 中文提示模板(与 {@link String#format} 占位一致)
|
||||
*/
|
||||
private final String messageZh;
|
||||
/**
|
||||
* 英文提示模板
|
||||
*/
|
||||
private final String messageEn;
|
||||
/**
|
||||
* 分类备注,方便看异常定义,不参与错误提示
|
||||
*/
|
||||
private final String remark;
|
||||
|
||||
|
||||
BizExceptionCodeEnum(String code, String messageZh, String messageEn, String remark) {
|
||||
this.code = code;
|
||||
this.messageZh = messageZh;
|
||||
this.messageEn = messageEn;
|
||||
this.remark = remark;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.xspaceagi.system.spec.exception;
|
||||
|
||||
/**
|
||||
* 知识库异常
|
||||
*/
|
||||
|
||||
public class ComposeException extends KindlyException {
|
||||
|
||||
/**
|
||||
* 默认配置前缀
|
||||
*/
|
||||
private static final String DISPLAY_CODE = "Compose";
|
||||
|
||||
|
||||
public ComposeException(String code, String message) {
|
||||
super(code, message);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据定义好的异常枚举,构建异常信息
|
||||
*
|
||||
* @param codeEnum 异常枚举
|
||||
* @param params 占位参数
|
||||
* @return 异常
|
||||
*/
|
||||
public static ComposeException build(BizExceptionCodeEnum codeEnum, Object... params) {
|
||||
String errorMessage = codeEnum.formatMessage(params);
|
||||
return new ComposeException(codeEnum.getCode(), errorMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModule() {
|
||||
return DISPLAY_CODE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.xspaceagi.system.spec.exception;
|
||||
|
||||
/**
|
||||
* 知识库异常
|
||||
*/
|
||||
|
||||
public class CustomPageException extends KindlyException {
|
||||
|
||||
/**
|
||||
* 默认配置前缀
|
||||
*/
|
||||
private static final String DISPLAY_CODE = "CustomPage";
|
||||
|
||||
|
||||
public CustomPageException(String code, String message) {
|
||||
super(code, message);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据定义好的异常枚举,构建异常信息
|
||||
*
|
||||
* @param codeEnum 异常枚举
|
||||
* @param params 占位参数
|
||||
* @return 异常
|
||||
*/
|
||||
public static CustomPageException build(BizExceptionCodeEnum codeEnum, Object... params) {
|
||||
String errorMessage = codeEnum.formatMessage(params);
|
||||
return new CustomPageException(codeEnum.getCode(), errorMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModule() {
|
||||
return DISPLAY_CODE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.xspaceagi.system.spec.exception;
|
||||
|
||||
/**
|
||||
* 生态市场异常
|
||||
*/
|
||||
|
||||
public class EcoMarketException extends KindlyException {
|
||||
|
||||
/**
|
||||
* 默认配置前缀
|
||||
*/
|
||||
private static final String DISPLAY_CODE = "EcoMarket";
|
||||
|
||||
|
||||
public EcoMarketException(String code, String message) {
|
||||
super(code, message);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据定义好的异常枚举,构建异常信息
|
||||
*
|
||||
* @param codeEnum 异常枚举
|
||||
* @param params 占位参数
|
||||
* @return 异常
|
||||
*/
|
||||
public static EcoMarketException build(BizExceptionCodeEnum codeEnum, Object... params) {
|
||||
String errorMessage = codeEnum.formatMessage(params);
|
||||
return new EcoMarketException(codeEnum.getCode(), errorMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModule() {
|
||||
return DISPLAY_CODE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.xspaceagi.system.spec.exception;
|
||||
|
||||
import com.xspaceagi.system.spec.common.RequestContext;
|
||||
|
||||
public interface IBizExceptionCodeEnum {
|
||||
|
||||
String getCode();
|
||||
|
||||
/**
|
||||
* 中文错误信息模板(与 {@link String#format} 占位一致)
|
||||
*/
|
||||
String getMessageZh();
|
||||
|
||||
/**
|
||||
* 英文错误信息模板
|
||||
*/
|
||||
String getMessageEn();
|
||||
|
||||
/**
|
||||
* 分类备注,方便看异常定义,不参与错误提示
|
||||
*/
|
||||
String getRemark();
|
||||
|
||||
/**
|
||||
* 按当前请求 {@link RequestContext#getLang()} 选择模板:仅 {@code zh-CN}(忽略大小写)使用中文,其余(含未设置 lang)使用英文。
|
||||
*/
|
||||
default String pickMessageTemplateForRequest() {
|
||||
RequestContext<?> ctx = RequestContext.get();
|
||||
if (ctx != null) {
|
||||
String lang = ctx.getLang();
|
||||
if (lang != null && !lang.isBlank() && "zh-CN".equalsIgnoreCase(lang.trim())) {
|
||||
return getMessageZh();
|
||||
}
|
||||
}
|
||||
return getMessageEn();
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用 {@link #pickMessageTemplateForRequest()} 的模板做 {@link String#format}。
|
||||
*/
|
||||
default String formatMessage(Object... params) {
|
||||
String tpl = pickMessageTemplateForRequest();
|
||||
if (params == null || params.length == 0) {
|
||||
return tpl;
|
||||
}
|
||||
return String.format(tpl, params);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.xspaceagi.system.spec.exception;
|
||||
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 通用抽象
|
||||
*/
|
||||
public abstract class KindlyException extends RuntimeException {
|
||||
|
||||
@Getter
|
||||
private final String code;
|
||||
|
||||
private String displayCode;
|
||||
|
||||
|
||||
public KindlyException(String code, String message) {
|
||||
super(message);
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public KindlyException(String code, String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
|
||||
public String getDisplayCode() {
|
||||
if (null == getModule()) {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
return getModule() + this.code;
|
||||
}
|
||||
|
||||
/**
|
||||
* 模块名称简拼
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public abstract String getModule();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.xspaceagi.system.spec.exception;
|
||||
|
||||
/**
|
||||
* 知识库异常
|
||||
*/
|
||||
|
||||
public class KnowledgeException extends KindlyException {
|
||||
|
||||
/**
|
||||
* 默认配置前缀
|
||||
*/
|
||||
private static final String DISPLAY_CODE = "Knowledge";
|
||||
|
||||
|
||||
public KnowledgeException(String code, String message) {
|
||||
super(code, message);
|
||||
}
|
||||
|
||||
public KnowledgeException(String code, String message, Throwable cause) {
|
||||
super(code, message, cause);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据定义好的异常枚举,构建异常信息
|
||||
*
|
||||
* @param codeEnum 异常枚举
|
||||
* @param params 占位参数
|
||||
* @return 异常
|
||||
*/
|
||||
public static KnowledgeException build(BizExceptionCodeEnum codeEnum, Object... params) {
|
||||
String errorMessage = codeEnum.formatMessage(params);
|
||||
return new KnowledgeException(codeEnum.getCode(), errorMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据定义好的异常枚举,构建异常信息(带原始异常)
|
||||
*
|
||||
* @param codeEnum 异常枚举
|
||||
* @param cause 原始异常
|
||||
* @return 异常
|
||||
*/
|
||||
public static KnowledgeException build(BizExceptionCodeEnum codeEnum, Throwable cause) {
|
||||
return new KnowledgeException(codeEnum.getCode(), codeEnum.formatMessage(), cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModule() {
|
||||
return DISPLAY_CODE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.xspaceagi.system.spec.exception;
|
||||
|
||||
/**
|
||||
* 日志平台异常
|
||||
*/
|
||||
|
||||
public class LogPlatformException extends KindlyException {
|
||||
|
||||
/**
|
||||
* 默认配置前缀
|
||||
*/
|
||||
private static final String DISPLAY_CODE = "LogPlatform";
|
||||
|
||||
|
||||
public LogPlatformException(String code, String message) {
|
||||
super(code, message);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据定义好的异常枚举,构建异常信息
|
||||
*
|
||||
* @param codeEnum 异常枚举
|
||||
* @param params 占位参数
|
||||
* @return 异常
|
||||
*/
|
||||
public static LogPlatformException build(BizExceptionCodeEnum codeEnum, Object... params) {
|
||||
String errorMessage = codeEnum.formatMessage(params);
|
||||
return new LogPlatformException(codeEnum.getCode(), errorMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModule() {
|
||||
return DISPLAY_CODE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.xspaceagi.system.spec.exception;
|
||||
|
||||
/**
|
||||
* 资源权限异常
|
||||
*/
|
||||
public class ResourcePermissionException extends RuntimeException {
|
||||
|
||||
public ResourcePermissionException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ResourcePermissionException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.xspaceagi.system.spec.exception;
|
||||
|
||||
import com.xspaceagi.system.spec.enums.ErrorCodeEnum;
|
||||
import lombok.Getter;
|
||||
|
||||
public class SpacePermissionException extends RuntimeException {
|
||||
|
||||
@Getter
|
||||
private String code = ErrorCodeEnum.PERMISSION_DENIED.getCode();
|
||||
|
||||
public SpacePermissionException() {
|
||||
super("您没有此空间数据的访问权限!");
|
||||
}
|
||||
|
||||
public SpacePermissionException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public SpacePermissionException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public SpacePermissionException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.xspaceagi.system.spec.exception;
|
||||
|
||||
/**
|
||||
* 系统管理异常,如人员,机构,角色等管理异常
|
||||
*/
|
||||
public class SystemManagerException extends KindlyException {
|
||||
|
||||
/**
|
||||
* 默认配置前缀
|
||||
*/
|
||||
private static final String DISPLAY_CODE = "SystemManager";
|
||||
|
||||
|
||||
public SystemManagerException(String code, String message) {
|
||||
super(code, message);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据定义好的异常枚举,构建异常信息
|
||||
*
|
||||
* @param codeEnum 异常枚举
|
||||
* @param params 占位参数
|
||||
* @return 异常
|
||||
*/
|
||||
public static SystemManagerException build(BizExceptionCodeEnum codeEnum, Object... params) {
|
||||
String errorMessage = codeEnum.formatMessage(params);
|
||||
return new SystemManagerException(codeEnum.getCode(), errorMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModule() {
|
||||
return DISPLAY_CODE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.xspaceagi.system.spec.file;
|
||||
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class FileSystemMultipartFile implements MultipartFile {
|
||||
private final File file;
|
||||
private final String name;
|
||||
private final String contentType;
|
||||
|
||||
public FileSystemMultipartFile(File file, String name, String contentType) {
|
||||
this.file = file;
|
||||
this.name = name;
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOriginalFilename() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return file.length() == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSize() {
|
||||
return file.length();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBytes() throws IOException {
|
||||
return java.nio.file.Files.readAllBytes(file.toPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return new FileInputStream(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.springframework.core.io.Resource getResource() {
|
||||
return new FileSystemResource(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transferTo(File dest) throws IOException, IllegalStateException {
|
||||
java.nio.file.Files.copy(file.toPath(), dest.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.xspaceagi.system.spec.file;
|
||||
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
|
||||
public class InMemoryMultipartFile implements MultipartFile {
|
||||
|
||||
private final String name;
|
||||
private final String originalFilename;
|
||||
private final String contentType;
|
||||
private final byte[] content;
|
||||
|
||||
public InMemoryMultipartFile(String name, String originalFilename, String contentType, byte[] content) {
|
||||
this.name = name;
|
||||
this.originalFilename = originalFilename;
|
||||
this.contentType = contentType;
|
||||
this.content = (content != null ? content : new byte[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOriginalFilename() {
|
||||
return originalFilename;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return content.length == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSize() {
|
||||
return content.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBytes() {
|
||||
return content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() {
|
||||
return new ByteArrayInputStream(content);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transferTo(java.io.File dest) throws IOException {
|
||||
try (java.io.FileOutputStream fos = new java.io.FileOutputStream(dest)) {
|
||||
fos.write(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.xspaceagi.system.spec.id;
|
||||
|
||||
/**
|
||||
* ID生成器
|
||||
*/
|
||||
public interface IdGenerator {
|
||||
|
||||
/**
|
||||
* 生成唯一ID
|
||||
*/
|
||||
long nextId();
|
||||
|
||||
/**
|
||||
* 生成唯一ID,指定位数
|
||||
*/
|
||||
long nextId(int digits);
|
||||
|
||||
/**
|
||||
* 生成唯一ID(字符串)
|
||||
*/
|
||||
String nextIdStr();
|
||||
|
||||
/**
|
||||
* 生成唯一ID(字符串),指定位数
|
||||
*/
|
||||
String nextIdStr(int digits);
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.xspaceagi.system.spec.id;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import cn.hutool.core.lang.Snowflake;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
|
||||
/**
|
||||
* 基于雪花算法的分布式ID生成器
|
||||
*/
|
||||
@Component
|
||||
public class SnowflakeIdGenerator implements IdGenerator {
|
||||
|
||||
// 数据中心ID,目前单实例,不配置,直接写死
|
||||
// @Value("${id.snowflake.datacenter-id:1}")
|
||||
private long datacenterId = 1L;
|
||||
|
||||
// 数据中心内的机器/实例ID,目前单实例,不配置,直接写死
|
||||
// @Value("${id.snowflake.worker-id:1}")
|
||||
private long workerId = 1L;
|
||||
|
||||
private Snowflake snowflake;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
this.snowflake = IdUtil.getSnowflake(workerId, datacenterId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long nextId() {
|
||||
return snowflake.nextId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成指定位数的ID
|
||||
* 注意:位数越少,重复风险越高!
|
||||
*
|
||||
* 建议:
|
||||
* - 19位:完全不重复(原始雪花ID)
|
||||
* - 16-18位:截取后N位,基本不重复
|
||||
* - 13-15位:中等并发场景可用,有一定重复风险
|
||||
* - ≤12位:高并发场景下重复概率较高,不推荐
|
||||
*/
|
||||
@Override
|
||||
public long nextId(int digits) {
|
||||
if (digits < 1 || digits > 19) {
|
||||
throw new IllegalArgumentException("Bit count must be between 1 and 19");
|
||||
}
|
||||
|
||||
long id = snowflake.nextId();
|
||||
|
||||
if (digits >= 19) {
|
||||
return id;
|
||||
}
|
||||
|
||||
id = Math.abs(id);
|
||||
|
||||
String idStr = String.valueOf(id);
|
||||
|
||||
// 如果本身不足指定位数,直接返回
|
||||
if (idStr.length() <= digits) {
|
||||
return id;
|
||||
}
|
||||
|
||||
// 截取后N位(保留时间戳的后部分+序列号)
|
||||
String truncated = idStr.substring(idStr.length() - digits);
|
||||
|
||||
return Long.parseLong(truncated);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String nextIdStr() {
|
||||
return snowflake.nextIdStr();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String nextIdStr(int digits) {
|
||||
long id = nextId(digits);
|
||||
return String.valueOf(id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.xspaceagi.system.spec.jackson;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.DateTimeException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
public class FixedLocalDateTimeDeserializer extends LocalDateTimeDeserializer {
|
||||
private static final DateTimeFormatter DEFAULT_FORMATTER;
|
||||
|
||||
public FixedLocalDateTimeDeserializer(DateTimeFormatter formatter) {
|
||||
super(formatter);
|
||||
}
|
||||
|
||||
protected LocalDateTime _fromString(JsonParser p, DeserializationContext ctxt, String string0) throws IOException {
|
||||
String string = string0.trim();
|
||||
if (string.length() == 0) {
|
||||
return (LocalDateTime)this._fromEmptyString(p, ctxt, string);
|
||||
} else {
|
||||
try {
|
||||
return string.length() > 10 && string.charAt(10) == 'T' ? LocalDateTime.parse(string, DEFAULT_FORMATTER) : LocalDateTime.parse(string, this._formatter);
|
||||
} catch (DateTimeException var6) {
|
||||
return (LocalDateTime)this._handleDateTimeException(ctxt, var6, string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
DEFAULT_FORMATTER = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.xspaceagi.system.spec.jackson;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.ser.std.StdKeySerializers;
|
||||
import java.io.IOException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class FixedNumberKeySerializer extends StdKeySerializers.Default {
|
||||
private static final Logger log = LoggerFactory.getLogger(FixedNumberKeySerializer.class);
|
||||
private Class<?> cls;
|
||||
|
||||
public FixedNumberKeySerializer(int typeId, Class<?> type) {
|
||||
super(typeId, type);
|
||||
this.cls = type;
|
||||
}
|
||||
|
||||
public void serialize(Object value, JsonGenerator g, SerializerProvider provider) throws IOException {
|
||||
if (this.isNumber() && !(value instanceof Number)) {
|
||||
log.warn("javaType:{},valueType:{} 不匹配,请检查!", this.cls.getName(), value.getClass().getName());
|
||||
g.writeFieldName(value.toString());
|
||||
} else {
|
||||
super.serialize(value, g, provider);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isNumber() {
|
||||
return this._typeId == 5 || this._typeId == 6;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package com.xspaceagi.system.spec.jackson;
|
||||
|
||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.Module;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping;
|
||||
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.fasterxml.jackson.databind.ser.DefaultSerializerProvider;
|
||||
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
public class JacksonBuilder {
|
||||
private ObjectMapper objectMapper;
|
||||
private final JacksonProperties jacksonProperties;
|
||||
private final SimpleModule customModule;
|
||||
|
||||
private JacksonBuilder() {
|
||||
this(new JacksonProperties());
|
||||
}
|
||||
|
||||
private JacksonBuilder(JacksonProperties jacksonProperties) {
|
||||
this.jacksonProperties = jacksonProperties;
|
||||
this.customModule = new SimpleModule();
|
||||
this.defaultObjectMapper();
|
||||
}
|
||||
|
||||
private void defaultObjectMapper() {
|
||||
DefaultSerializerProvider provider = new DefaultSerializerProvider.Impl();
|
||||
provider.setNullKeySerializer(new NullKeySerializer());
|
||||
this.customModule.addKeySerializer(Integer.class, new FixedNumberKeySerializer(5, Integer.class));
|
||||
this.customModule.addKeySerializer(Long.class, new FixedNumberKeySerializer(6, Integer.class));
|
||||
this.objectMapper = (new ObjectMapper()).setSerializationInclusion(Include.NON_NULL).configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false).setVisibility(PropertyAccessor.ALL, Visibility.ANY).registerModule(this.javaTimeModule()).registerModule(new Jdk8Module());
|
||||
String utilDateFormat = this.jacksonProperties.getUtilDateFormat();
|
||||
if (!ObjectUtils.isEmpty(utilDateFormat)) {
|
||||
this.objectMapper.setDateFormat(new SimpleDateFormat(utilDateFormat));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Module javaTimeModule() {
|
||||
JavaTimeModule module = new JavaTimeModule();
|
||||
module.addSerializer(this.localDateTimeSerializer());
|
||||
module.addSerializer(this.localDateSerializer());
|
||||
module.addSerializer(this.localTimeSerializer());
|
||||
module.addDeserializer(LocalDateTime.class, this.fixedLocalDateTimeDeserializer());
|
||||
module.addDeserializer(LocalDate.class, this.localDateDeserializer());
|
||||
module.addDeserializer(LocalTime.class, this.localTimeDeserializer());
|
||||
return module;
|
||||
}
|
||||
|
||||
private LocalDateTimeSerializer localDateTimeSerializer() {
|
||||
return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(this.jacksonProperties.getDateTimeFormat()));
|
||||
}
|
||||
|
||||
private FixedLocalDateTimeDeserializer fixedLocalDateTimeDeserializer() {
|
||||
return new FixedLocalDateTimeDeserializer(DateTimeFormatter.ofPattern(this.jacksonProperties.getDateTimeFormat()));
|
||||
}
|
||||
|
||||
private LocalDateSerializer localDateSerializer() {
|
||||
return new LocalDateSerializer(DateTimeFormatter.ofPattern(this.jacksonProperties.getDateFormat()));
|
||||
}
|
||||
|
||||
private LocalTimeSerializer localTimeSerializer() {
|
||||
return new LocalTimeSerializer(DateTimeFormatter.ofPattern(this.jacksonProperties.getTimeFormat()));
|
||||
}
|
||||
|
||||
private LocalDateTimeDeserializer localDateTimeDeserializer() {
|
||||
return new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(this.jacksonProperties.getDateTimeFormat()));
|
||||
}
|
||||
|
||||
private LocalDateDeserializer localDateDeserializer() {
|
||||
return new LocalDateDeserializer(DateTimeFormatter.ofPattern(this.jacksonProperties.getDateFormat()));
|
||||
}
|
||||
|
||||
private LocalTimeDeserializer localTimeDeserializer() {
|
||||
return new LocalTimeDeserializer(DateTimeFormatter.ofPattern(this.jacksonProperties.getTimeFormat()));
|
||||
}
|
||||
|
||||
public JacksonBuilder writeNull() {
|
||||
this.objectMapper.setSerializationInclusion(Include.ALWAYS);
|
||||
return this;
|
||||
}
|
||||
|
||||
public JacksonBuilder withJavaType() {
|
||||
this.objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, DefaultTyping.NON_FINAL, As.PROPERTY);
|
||||
return this;
|
||||
}
|
||||
|
||||
public JacksonBuilder addSerializer(JsonSerializer<?> ser) {
|
||||
this.customModule.addSerializer(ser);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ObjectMapper build() {
|
||||
this.objectMapper.registerModule(this.customModule);
|
||||
return this.objectMapper;
|
||||
}
|
||||
|
||||
public static JacksonBuilder builder() {
|
||||
return new JacksonBuilder();
|
||||
}
|
||||
|
||||
public static JacksonBuilder builder(JacksonProperties jacksonProperties) {
|
||||
return new JacksonBuilder(jacksonProperties);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.xspaceagi.system.spec.jackson;
|
||||
|
||||
public class JacksonProperties {
|
||||
private String dateTimeFormat = "yyyy-MM-dd HH:mm:ss";
|
||||
private String dateFormat = "yyyy-MM-dd";
|
||||
private String timeFormat = "HH:mm:ss";
|
||||
private String utilDateFormat;
|
||||
|
||||
public JacksonProperties() {
|
||||
}
|
||||
|
||||
public String getDateTimeFormat() {
|
||||
return this.dateTimeFormat;
|
||||
}
|
||||
|
||||
public void setDateTimeFormat(String dateTimeFormat) {
|
||||
this.dateTimeFormat = dateTimeFormat;
|
||||
}
|
||||
|
||||
public String getDateFormat() {
|
||||
return this.dateFormat;
|
||||
}
|
||||
|
||||
public void setDateFormat(String dateFormat) {
|
||||
this.dateFormat = dateFormat;
|
||||
}
|
||||
|
||||
public String getTimeFormat() {
|
||||
return this.timeFormat;
|
||||
}
|
||||
|
||||
public void setTimeFormat(String timeFormat) {
|
||||
this.timeFormat = timeFormat;
|
||||
}
|
||||
|
||||
public String getUtilDateFormat() {
|
||||
return this.utilDateFormat;
|
||||
}
|
||||
|
||||
public void setUtilDateFormat(String utilDateFormat) {
|
||||
this.utilDateFormat = utilDateFormat;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
package com.xspaceagi.system.spec.jackson;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class JsonSerializeUtil {
|
||||
|
||||
// 包含类型信息的ObjectMapper
|
||||
private static ObjectMapper objectMapper;
|
||||
|
||||
// 不包含类型信息的ObjectMapper
|
||||
private static ObjectMapper objectMapperWithoutType;
|
||||
|
||||
private static final LinkedHashMap<String, String> PACKAGE_MAP = new LinkedHashMap<String, String>() {{
|
||||
put("com.xspaceagi.platform.ui.web.dto", "com.xspaceagi.system.web.dto");
|
||||
put("com.xspaceagi.domain.log", "com.xspaceagi.system.domain.log");
|
||||
put("com.xspaceagi.platform", "com.xspaceagi.system");
|
||||
}};
|
||||
|
||||
static {
|
||||
objectMapper = JacksonBuilder.builder(new JacksonProperties()).withJavaType().build();
|
||||
objectMapperWithoutType = JacksonBuilder.builder(new JacksonProperties()).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 反序列化JSON字符串为对象,包含类型信息(@class字段)
|
||||
*/
|
||||
public static Object parseObjectGeneric(String json) {
|
||||
if (json == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return objectMapper.readValue(json, Object.class);
|
||||
} catch (IOException e) {
|
||||
try {
|
||||
String newJson = json;
|
||||
for (Map.Entry<String, String> entry : PACKAGE_MAP.entrySet()) {
|
||||
newJson = newJson.replace(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return objectMapper.readValue(newJson, Object.class);
|
||||
} catch (IOException retryException) {
|
||||
throw new RuntimeException("反序列化失败,原始异常: " + e.getMessage() +
|
||||
", 迁移后异常: " + retryException.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 序列化对象为JSON字符串,包含类型信息(@class字段)
|
||||
*/
|
||||
public static String toJSONStringGeneric(Object obj) {
|
||||
try {
|
||||
return objectMapper.writeValueAsString(obj);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 序列化对象为JSON字符串,不包含类型信息(@class字段)
|
||||
*/
|
||||
public static String toJSONString(Object obj) {
|
||||
if (obj == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return objectMapperWithoutType.writeValueAsString(obj);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException("序列化失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 反序列化JSON字符串为指定类型的对象,用于不包含类型信息的JSON
|
||||
*/
|
||||
public static <T> T parseObject(String json, Class<T> clazz) {
|
||||
if (json == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return objectMapperWithoutType.readValue(json, clazz);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException("反序列化失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 反序列化JSON字符串为指定类型的对象,用于不包含类型信息的JSON(支持泛型)
|
||||
*/
|
||||
public static <T> T parseObject(String json, TypeReference<T> typeReference) {
|
||||
if (json == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return objectMapperWithoutType.readValue(json, typeReference);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException("反序列化失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Object deepCopy(Object obj) {
|
||||
return parseObjectGeneric(toJSONStringGeneric(obj));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.xspaceagi.system.spec.jackson;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser.NumberType;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.ser.std.NumberSerializers;
|
||||
import java.io.IOException;
|
||||
|
||||
public class LongToStringSerializer extends NumberSerializers.Base<Object> {
|
||||
public LongToStringSerializer() {
|
||||
super(Long.class, NumberType.LONG, "number");
|
||||
}
|
||||
|
||||
public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
|
||||
long number = (Long)value;
|
||||
if (number >= 10000000000000000L) {
|
||||
gen.writeString(number + "");
|
||||
} else {
|
||||
gen.writeNumber(number);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// Source code recreated from a .class file by IntelliJ IDEA
|
||||
// (powered by FernFlower decompiler)
|
||||
//
|
||||
|
||||
package com.xspaceagi.system.spec.jackson;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
public class NullKeySerializer extends JsonSerializer {
|
||||
public NullKeySerializer() {
|
||||
}
|
||||
|
||||
public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
|
||||
if (Objects.isNull(value)) {
|
||||
gen.writeFieldName("null");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.xspaceagi.system.spec.mail;
|
||||
|
||||
import com.xspaceagi.system.spec.enums.ErrorCodeEnum;
|
||||
import com.xspaceagi.system.spec.exception.BizException;
|
||||
import com.xspaceagi.system.spec.exception.BizExceptionCodeEnum;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.mail.*;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import java.util.Properties;
|
||||
|
||||
public class MailSender {
|
||||
|
||||
public static void sendEmail(String host, String port, String username, String password, String toAddress, String subject, String message) {
|
||||
if (StringUtils.isBlank(host)) {
|
||||
throw BizException.of(ErrorCodeEnum.INVALID_PARAM, BizExceptionCodeEnum.systemMailServiceNotConfigured);
|
||||
}
|
||||
// 设置邮件服务器属性
|
||||
Properties properties = new Properties();
|
||||
properties.put("mail.smtp.host", host);
|
||||
properties.put("mail.smtp.port", port);
|
||||
properties.put("mail.smtp.auth", "true");
|
||||
properties.put("mail.smtp.ssl.enable", "true");
|
||||
|
||||
// 创建会话对象
|
||||
Session session = Session.getInstance(properties, new Authenticator() {
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
return new PasswordAuthentication(username, password);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
// 创建邮件消息
|
||||
Message msg = new MimeMessage(session);
|
||||
msg.setFrom(new InternetAddress(username));
|
||||
InternetAddress[] toAddresses = {new InternetAddress(toAddress)};
|
||||
msg.setRecipients(Message.RecipientType.TO, toAddresses);
|
||||
msg.setSubject(subject);
|
||||
msg.setSentDate(new java.util.Date());
|
||||
msg.setText(message);
|
||||
// 发送邮件
|
||||
Transport.send(msg);
|
||||
} catch (MessagingException e) {
|
||||
throw BizException.of(ErrorCodeEnum.INVALID_PARAM, BizExceptionCodeEnum.systemMailSendFailed);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.xspaceagi.system.spec.page;
|
||||
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class ColumnExt implements Serializable {
|
||||
|
||||
/**
|
||||
* 列固定设置
|
||||
*/
|
||||
private String fixed;
|
||||
/**
|
||||
* 是否可见
|
||||
*/
|
||||
private boolean visible = true;
|
||||
/**
|
||||
* 列的副标题
|
||||
*/
|
||||
private String subLabel;
|
||||
/**
|
||||
* 列宽
|
||||
*/
|
||||
private String width;
|
||||
/**
|
||||
* 列宽最小值
|
||||
*/
|
||||
private String minWidth;
|
||||
/**
|
||||
* 是否允许自定义
|
||||
*/
|
||||
private boolean settable = true;
|
||||
/**
|
||||
* 对齐 'left' | 'center' | 'right'
|
||||
*/
|
||||
private String align;
|
||||
/**
|
||||
* 组件格式化类型:日期(dateTime)、数量(quantity)、单价(unitPrice)、金额(amount)
|
||||
*/
|
||||
private String formatter;
|
||||
|
||||
|
||||
/**
|
||||
* 字段提示信息
|
||||
*/
|
||||
private String tips;
|
||||
|
||||
/**
|
||||
* 超长则自动省略号隐藏,hover提示
|
||||
*/
|
||||
private Boolean ellipsis;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.xspaceagi.system.spec.page;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 筛选字段
|
||||
*
|
||||
* @author soddy
|
||||
*/
|
||||
@Data
|
||||
public class ComparisonExpression implements Serializable {
|
||||
|
||||
|
||||
/**
|
||||
* 字段
|
||||
*/
|
||||
private String column;
|
||||
|
||||
/**
|
||||
* 筛选方式 ,比如: "=",">"
|
||||
*/
|
||||
private String operator;
|
||||
|
||||
/**
|
||||
* 字段值
|
||||
*/
|
||||
private Object value;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
package com.xspaceagi.system.spec.page;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.OrderItem;
|
||||
import com.xspaceagi.system.spec.utils.Pojo2MapUtil;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 列表查询参数
|
||||
*
|
||||
* @author soddy
|
||||
*/
|
||||
@Data
|
||||
@Slf4j
|
||||
public class PageQueryParamVo implements Serializable {
|
||||
|
||||
/**
|
||||
* 租户id,显示传递
|
||||
*/
|
||||
private Long tenantId;
|
||||
/**
|
||||
* 是否查询明细表
|
||||
*/
|
||||
private boolean queryDetailFlag = false;
|
||||
/**
|
||||
* 排序字段
|
||||
*/
|
||||
private List<OrderItem> orderItemList;
|
||||
|
||||
/**
|
||||
* 列筛选字段条件,不是查询条件
|
||||
*/
|
||||
private List<ComparisonExpression> comparisonExpressionList;
|
||||
|
||||
|
||||
/**
|
||||
* 页码,页大小,位置偏移定义
|
||||
*/
|
||||
private PageQueryDto pageQueryDto;
|
||||
|
||||
/**
|
||||
* 抬头筛选条件
|
||||
*/
|
||||
private Map<String, Object> queryMap = new HashMap<>(0);
|
||||
|
||||
public PageQueryParamVo(long pageNo, long pageSize) {
|
||||
this.pageQueryDto = new PageQueryDto(pageNo, pageSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* request请求条件,转换为后端查询对象map
|
||||
* <p>和前端对象隔离开,参数(名称)等字段定义互不影响</p>
|
||||
*
|
||||
* @param superPage 公共属性
|
||||
*/
|
||||
public <T> PageQueryParamVo(PageQueryVo<T> superPage) {
|
||||
PageQueryParamVo pageQueryParamVo = new PageQueryParamVo(superPage.getCurrent(), superPage.getPageSize());
|
||||
pageQueryParamVo.setComparisonExpressionList(superPage.getFilters());
|
||||
pageQueryParamVo.setOrderItemList(superPage.getOrders());
|
||||
|
||||
Map<String, Object> queryMap = Pojo2MapUtil.object2Map(superPage.getQueryFilter());
|
||||
pageQueryParamVo.setQueryMap(queryMap);
|
||||
|
||||
this.pageQueryDto = new PageQueryDto(superPage.getCurrent(), superPage.getPageSize());
|
||||
this.comparisonExpressionList = superPage.getFilters();
|
||||
this.orderItemList = superPage.getOrders();
|
||||
this.queryMap = queryMap;
|
||||
|
||||
}
|
||||
|
||||
public Long getPageNo() {
|
||||
return this.pageQueryDto.pageNo;
|
||||
}
|
||||
|
||||
public Long getPageSize() {
|
||||
return this.pageQueryDto.pageSize;
|
||||
}
|
||||
|
||||
public Long getStartIndex() {
|
||||
return this.pageQueryDto.startIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为查询条件mapper
|
||||
* <p>不使用operator来动态控制,后端</p>
|
||||
*
|
||||
* @return 查询条件
|
||||
*/
|
||||
public Map<String, Object> convertQueryFilterParamMap() {
|
||||
Map<String, Object> queryMap = new HashMap<>(8);
|
||||
if (null == comparisonExpressionList || comparisonExpressionList.isEmpty()) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("列筛选条件为空,继续组装抬头查询条件");
|
||||
}
|
||||
} else {
|
||||
//列筛选条件
|
||||
queryMap = new HashMap<>(this.comparisonExpressionList.size());
|
||||
for (ComparisonExpression item : this.comparisonExpressionList) {
|
||||
queryMap.put(item.getColumn(), item.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
//抬头查询条件,追加到map里
|
||||
queryMap.putAll(this.queryMap);
|
||||
return queryMap;
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public static class PageQueryDto {
|
||||
|
||||
/**
|
||||
* 当前页码
|
||||
*/
|
||||
private final Long pageNo;
|
||||
|
||||
/**
|
||||
* 页大小
|
||||
*/
|
||||
private Long pageSize;
|
||||
|
||||
/**
|
||||
* 偏移位置
|
||||
*/
|
||||
private Long startIndex;
|
||||
|
||||
public PageQueryDto(long pageNo, long pageSize) {
|
||||
if (pageNo <= 0) {
|
||||
this.pageNo = 1L;
|
||||
} else {
|
||||
this.pageNo = pageNo;
|
||||
}
|
||||
this.pageSize = pageSize;
|
||||
|
||||
this.startIndex = (this.pageNo - 1) * this.pageSize;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.xspaceagi.system.spec.page;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.OrderItem;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 分页查询VO
|
||||
* </p>
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Schema(description = "分页查询VO")
|
||||
public class PageQueryVo<T> {
|
||||
|
||||
@Schema(description = "分页查询过滤条件", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
|
||||
private T queryFilter;
|
||||
|
||||
@Schema(description = "当前页", requiredMode = Schema.RequiredMode.NOT_REQUIRED, defaultValue = "1", example = "1")
|
||||
private Long current = 1L;
|
||||
|
||||
@Schema(description = "分页pageSize", requiredMode = Schema.RequiredMode.NOT_REQUIRED, defaultValue = "10", example = "10")
|
||||
private Long pageSize = 10L;
|
||||
|
||||
|
||||
/**
|
||||
* 排序字段信息,可空,一般没有默认为创建时间排序
|
||||
*/
|
||||
@Schema(description = "排序字段信息,可空,一般没有默认为创建时间排序", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
|
||||
private List<OrderItem> orders = new ArrayList<>();
|
||||
|
||||
|
||||
/**
|
||||
* 列的筛选条件,可空
|
||||
*/
|
||||
@Schema(description = "列的筛选条件,可空", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
|
||||
private List<ComparisonExpression> filters = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 表格的列信息,可空
|
||||
*/
|
||||
@Schema(description = "表格的列信息,可空", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
|
||||
private List<SuperTableColumn> columns = new ArrayList<>();
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.xspaceagi.system.spec.page;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 给页码,页大小,计算开始索引,结束索引,用于mysql查询limit使用
|
||||
*/
|
||||
public class PageUtils {
|
||||
|
||||
/**
|
||||
* 获取开始索引
|
||||
*
|
||||
* @param pageNum 页码
|
||||
* @param pageSize 页大小
|
||||
* @return 开始索引
|
||||
*/
|
||||
public static long getStartIndex(long pageNum, long pageSize) {
|
||||
if (Objects.isNull(pageNum) || pageNum < 1) {
|
||||
pageNum = 1;
|
||||
}
|
||||
if (Objects.isNull(pageSize) || pageSize < 1) {
|
||||
pageSize = 100;
|
||||
}
|
||||
return (pageNum - 1) * pageSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取结束索引
|
||||
*
|
||||
* @param pageNum 页码
|
||||
* @param pageSize 页大小
|
||||
* @return 结束索引
|
||||
*/
|
||||
public static long getEndIndex(long pageNum, long pageSize) {
|
||||
if (Objects.isNull(pageNum) || pageNum < 1) {
|
||||
pageNum = 1;
|
||||
}
|
||||
if (Objects.isNull(pageSize) || pageSize < 1) {
|
||||
pageSize = 100;
|
||||
}
|
||||
return (pageNum - 1) * pageSize + pageSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据总条数,和页大小,获取 页数 pages
|
||||
*
|
||||
* @param total 总条数
|
||||
* @param pageSize 页大小
|
||||
* @return 页数
|
||||
*/
|
||||
public static int getPages(long total, long pageSize) {
|
||||
if (Objects.isNull(total) || total < 1) {
|
||||
return 1;
|
||||
}
|
||||
if (Objects.isNull(pageSize) || pageSize < 1) {
|
||||
pageSize = 100;
|
||||
}
|
||||
return (int) Math.ceil((double) total / pageSize);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.xspaceagi.system.spec.page;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* 时间范围对象,承接前端一个范围时间的数值
|
||||
*
|
||||
* @author soddy
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
public class RangeTimeVo extends ArrayList<String> implements Serializable {
|
||||
|
||||
/**
|
||||
* 开始时间
|
||||
*/
|
||||
private LocalDateTime startTime;
|
||||
|
||||
/**
|
||||
* 结束时间
|
||||
*/
|
||||
private LocalDateTime endTime;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.xspaceagi.system.spec.page;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.metadata.OrderItem;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 前端list交互规范结构
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
public class SuperPage<T> extends Page<T> implements Serializable {
|
||||
|
||||
|
||||
/**
|
||||
* 表格的列定义
|
||||
*/
|
||||
private List<SuperTableColumn> columns = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* @param current 当前页
|
||||
* @param size 每页显示条数
|
||||
*/
|
||||
public SuperPage(long current, long size) {
|
||||
super(current, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param current 当前页
|
||||
* @param size 每页显示条数
|
||||
* @param orders 排序字段
|
||||
*/
|
||||
public SuperPage(long current, long size, List<OrderItem> orders) {
|
||||
super(current, size);
|
||||
if (!CollectionUtils.isEmpty(orders)) {
|
||||
this.addOrder(orders);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param pageNo 当前页
|
||||
* @param pageSize 页大小
|
||||
* @param total 总条数
|
||||
*/
|
||||
public SuperPage(long pageNo, long pageSize, long total) {
|
||||
super(pageNo, pageSize, total);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param pageNo 当前页
|
||||
* @param pageSize 页大小
|
||||
* @param total 总条数
|
||||
* @param records 数据
|
||||
*/
|
||||
public SuperPage(long pageNo, long pageSize, long total, List<T> records) {
|
||||
super(pageNo, pageSize, total);
|
||||
this.setRecords(records);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 替换 IPage 的对象类型
|
||||
*/
|
||||
public static <O> SuperPage<O> build(IPage<?> in, List<O> records) {
|
||||
return new SuperPage<>(in.getCurrent(), in.getSize(), in.getTotal(), records);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package com.xspaceagi.system.spec.page;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
public class SuperTableColumn implements Serializable {
|
||||
|
||||
/**
|
||||
* 序号
|
||||
*/
|
||||
private int serialNumber;
|
||||
|
||||
/**
|
||||
* 列的标题
|
||||
*/
|
||||
private String label;
|
||||
/**
|
||||
* 列字段名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 是否开启列排序
|
||||
*/
|
||||
private boolean sortable;
|
||||
/**
|
||||
* 列提示
|
||||
*/
|
||||
private String tips;
|
||||
/**
|
||||
* 列扩展信息
|
||||
*/
|
||||
private ColumnExt ext;
|
||||
|
||||
|
||||
private List<SuperTableColumn> children = Collections.emptyList();
|
||||
|
||||
|
||||
public SuperTableColumn(String label, String name, boolean sortable) {
|
||||
this.label = label;
|
||||
this.name = name;
|
||||
this.sortable = sortable;
|
||||
}
|
||||
|
||||
public SuperTableColumn(String label, String name) {
|
||||
this.label = label;
|
||||
this.name = name;
|
||||
this.sortable = false;
|
||||
}
|
||||
|
||||
|
||||
public SuperTableColumn(int serialNumber, String label, String name) {
|
||||
this.serialNumber = serialNumber;
|
||||
this.label = label;
|
||||
this.name = name;
|
||||
this.sortable = false;
|
||||
}
|
||||
|
||||
public SuperTableColumn(String label, String name, boolean sortable, ColumnExt ext) {
|
||||
this.label = label;
|
||||
this.name = name;
|
||||
this.sortable = sortable;
|
||||
this.ext = ext;
|
||||
}
|
||||
|
||||
public SuperTableColumn(int serialNumber, String label, String name, boolean sortable, ColumnExt ext) {
|
||||
this.serialNumber = serialNumber;
|
||||
this.label = label;
|
||||
this.name = name;
|
||||
this.sortable = sortable;
|
||||
this.ext = ext;
|
||||
}
|
||||
|
||||
public SuperTableColumn(String label, String name, ColumnExt ext) {
|
||||
this.label = label;
|
||||
this.name = name;
|
||||
this.sortable = false;
|
||||
this.ext = ext;
|
||||
}
|
||||
|
||||
public SuperTableColumn(int serialNumber, String label, String name, ColumnExt ext) {
|
||||
this.serialNumber = serialNumber;
|
||||
this.label = label;
|
||||
this.name = name;
|
||||
this.sortable = false;
|
||||
this.ext = ext;
|
||||
}
|
||||
|
||||
public SuperTableColumn() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user