大声道撒旦
This commit is contained in:
parent
53c61ad0c8
commit
bfb7c7b6da
@ -0,0 +1,44 @@
|
||||
package com.qqchen.deploy.backend.deploy.api;
|
||||
|
||||
import com.qqchen.deploy.backend.deploy.dto.BuildConfigDefinedDTO;
|
||||
import com.qqchen.deploy.backend.deploy.dto.DeployAppConfigDTO;
|
||||
import com.qqchen.deploy.backend.deploy.entity.DeployAppConfig;
|
||||
import com.qqchen.deploy.backend.deploy.query.DeployAppConfigQuery;
|
||||
import com.qqchen.deploy.backend.deploy.service.IDeployAppConfigService;
|
||||
import com.qqchen.deploy.backend.framework.api.Response;
|
||||
import com.qqchen.deploy.backend.framework.controller.BaseController;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 应用配置控制器
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/deploy-app-config")
|
||||
@Tag(name = "应用配置管理", description = "应用配置管理相关接口")
|
||||
public class DeployAppConfigApiController extends BaseController<DeployAppConfig, DeployAppConfigDTO, Long, DeployAppConfigQuery> {
|
||||
|
||||
|
||||
@Resource
|
||||
private IDeployAppConfigService deployAppConfigService;
|
||||
|
||||
@Operation(summary = "获取构建类型Schema定义")
|
||||
@GetMapping("/defined")
|
||||
public Response<List<BuildConfigDefinedDTO>> defined() {
|
||||
return Response.success(deployAppConfigService.defined());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void exportData(HttpServletResponse response, List<DeployAppConfigDTO> data) {
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
package com.qqchen.deploy.backend.deploy.converter;
|
||||
|
||||
import com.qqchen.deploy.backend.deploy.dto.DeployAppConfigDTO;
|
||||
import com.qqchen.deploy.backend.deploy.entity.DeployAppConfig;
|
||||
import com.qqchen.deploy.backend.framework.converter.BaseConverter;
|
||||
import org.mapstruct.Mapper;
|
||||
|
||||
/**
|
||||
* 应用配置转换器
|
||||
*/
|
||||
@Mapper(config = BaseConverter.class)
|
||||
public interface DeployAppConfigConverter extends BaseConverter<DeployAppConfig, DeployAppConfigDTO> {
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package com.qqchen.deploy.backend.deploy.dto;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.qqchen.deploy.backend.deploy.enums.BuildTypeEnum;
|
||||
import com.qqchen.deploy.backend.deploy.enums.DevelopmentLanguageTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Schema(description = "部署配置定义")
|
||||
public class BuildConfigDefinedDTO {
|
||||
|
||||
@Schema(description = "编码")
|
||||
private String code;
|
||||
|
||||
@Schema(description = "名称")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "部署类型类型")
|
||||
private BuildTypeEnum buildType;
|
||||
|
||||
private DevelopmentLanguageTypeEnum languageType;
|
||||
|
||||
@Schema(description = "JSON SCHEMA")
|
||||
private JsonNode buildVariablesSchema;
|
||||
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package com.qqchen.deploy.backend.deploy.dto;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.qqchen.deploy.backend.deploy.enums.BuildTypeEnum;
|
||||
import com.qqchen.deploy.backend.framework.dto.BaseDTO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 应用配置DTO
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "应用配置")
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class DeployAppConfigDTO extends BaseDTO {
|
||||
|
||||
@Schema(description = "环境ID")
|
||||
private Long environmentId;
|
||||
|
||||
@Schema(description = "应用ID")
|
||||
private Long applicationId;
|
||||
|
||||
@Schema(description = "构建类型")
|
||||
private BuildTypeEnum buildType;
|
||||
|
||||
@Schema(description = "构建变量")
|
||||
private JsonNode buildVariables;
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package com.qqchen.deploy.backend.deploy.dto.variables;
|
||||
|
||||
import com.qqchen.deploy.backend.workflow.annotation.SchemaProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Jenkins构建变量
|
||||
*/
|
||||
@Data
|
||||
public class JenkinsBaseBuildVariables {
|
||||
|
||||
@SchemaProperty(
|
||||
title = "分支名称",
|
||||
description = "Git分支名称",
|
||||
required = true
|
||||
)
|
||||
private String branch;
|
||||
|
||||
}
|
||||
@ -1,4 +0,0 @@
|
||||
package com.qqchen.deploy.backend.deploy.dto.variables;
|
||||
|
||||
public class JenkinsBuildVariables {
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package com.qqchen.deploy.backend.deploy.dto.variables;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Jenkins构建变量
|
||||
*/
|
||||
@Data
|
||||
public class JenkinsJavaBuildVariables extends JenkinsBaseBuildVariables {
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package com.qqchen.deploy.backend.deploy.dto.variables;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Jenkins构建变量
|
||||
*/
|
||||
@Data
|
||||
public class JenkinsNodeJsBuildVariables extends JenkinsBaseBuildVariables {
|
||||
|
||||
}
|
||||
@ -1,5 +1,7 @@
|
||||
package com.qqchen.deploy.backend.deploy.enums;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
import com.qqchen.deploy.backend.deploy.dto.variables.JenkinsJavaBuildVariables;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
@ -8,13 +10,70 @@ import lombok.Getter;
|
||||
@Getter
|
||||
public enum BuildTypeEnum {
|
||||
|
||||
JENKINS("Jenkins构建"),
|
||||
GITLAB_RUNNER("GitLab Runner构建"),
|
||||
GITHUB_ACTION("GitHub Action构建");
|
||||
JENKINS(
|
||||
"JENKINS",
|
||||
"Jenkins构建",
|
||||
new DevelopmentLanguageTypeEnum[] {
|
||||
DevelopmentLanguageTypeEnum.JAVA,
|
||||
DevelopmentLanguageTypeEnum.NODE_JS,
|
||||
DevelopmentLanguageTypeEnum.GO,
|
||||
DevelopmentLanguageTypeEnum.PYTHON
|
||||
},
|
||||
new Class[] {
|
||||
JenkinsJavaBuildVariables.class,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
},
|
||||
"Jenkins构建"
|
||||
),
|
||||
GITLAB_RUNNER(
|
||||
"GITLAB_RUNNER",
|
||||
"GitLab Runner构建",
|
||||
null,
|
||||
null,
|
||||
"GitLab Runner构建"
|
||||
),
|
||||
GITHUB_ACTION(
|
||||
"GITHUB_ACTION",
|
||||
"GitHub Action构建",
|
||||
null,
|
||||
null,
|
||||
"GitHub Action构建"
|
||||
);
|
||||
|
||||
@JsonValue
|
||||
private final String code;
|
||||
|
||||
private final String name;
|
||||
|
||||
private final DevelopmentLanguageTypeEnum[] supportedLanguages;
|
||||
|
||||
private final Class<?>[] buildVariables;
|
||||
|
||||
private final String description;
|
||||
|
||||
BuildTypeEnum(String description) {
|
||||
BuildTypeEnum(String code, String name, DevelopmentLanguageTypeEnum[] supportedLanguages, Class<?>[] buildVariables, String description) {
|
||||
this.code = code;
|
||||
this.name = name;
|
||||
this.supportedLanguages = supportedLanguages;
|
||||
this.buildVariables = buildVariables;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据编码查找对应的枚举
|
||||
*
|
||||
* @param code 构建类型编码
|
||||
* @return 对应的枚举实例
|
||||
* @throws IllegalArgumentException 当找不到对应的枚举值时抛出
|
||||
*/
|
||||
public static BuildTypeEnum fromValue(String code) {
|
||||
for (BuildTypeEnum type : values()) {
|
||||
if (type.code.equals(code)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown BuildType code: " + code);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package com.qqchen.deploy.backend.deploy.query;
|
||||
|
||||
import com.qqchen.deploy.backend.deploy.enums.BuildTypeEnum;
|
||||
import com.qqchen.deploy.backend.framework.annotation.QueryField;
|
||||
import com.qqchen.deploy.backend.framework.query.BaseQuery;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 应用配置查询对象
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "应用配置查询")
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class DeployAppConfigQuery extends BaseQuery {
|
||||
|
||||
@Schema(description = "环境ID")
|
||||
@QueryField(field = "environmentId")
|
||||
private Long environmentId;
|
||||
|
||||
@Schema(description = "应用ID")
|
||||
@QueryField(field = "applicationId")
|
||||
private Long applicationId;
|
||||
|
||||
@Schema(description = "构建类型")
|
||||
@QueryField(field = "buildType")
|
||||
private BuildTypeEnum buildType;
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
package com.qqchen.deploy.backend.deploy.repository;
|
||||
|
||||
import com.qqchen.deploy.backend.deploy.entity.DeployAppConfig;
|
||||
import com.qqchen.deploy.backend.framework.repository.IBaseRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* 应用配置仓库接口
|
||||
*/
|
||||
@Repository
|
||||
public interface IDeployAppConfigRepository extends IBaseRepository<DeployAppConfig, Long> {
|
||||
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.qqchen.deploy.backend.deploy.service;
|
||||
|
||||
import com.qqchen.deploy.backend.deploy.dto.BuildConfigDefinedDTO;
|
||||
import com.qqchen.deploy.backend.deploy.dto.DeployAppConfigDTO;
|
||||
import com.qqchen.deploy.backend.deploy.entity.DeployAppConfig;
|
||||
import com.qqchen.deploy.backend.deploy.query.DeployAppConfigQuery;
|
||||
import com.qqchen.deploy.backend.framework.service.IBaseService;
|
||||
import com.qqchen.deploy.backend.workflow.dto.WorkflowNodeTypeDefinedDTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 应用配置服务接口
|
||||
*/
|
||||
public interface IDeployAppConfigService extends IBaseService<DeployAppConfig, DeployAppConfigDTO, DeployAppConfigQuery, Long> {
|
||||
|
||||
/**
|
||||
* 获取构建类型Schema定义
|
||||
*
|
||||
* @return Schema定义列表
|
||||
*/
|
||||
List<BuildConfigDefinedDTO> defined();
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
package com.qqchen.deploy.backend.deploy.service.impl;
|
||||
|
||||
import com.qqchen.deploy.backend.deploy.dto.BuildConfigDefinedDTO;
|
||||
import com.qqchen.deploy.backend.deploy.dto.DeployAppConfigDTO;
|
||||
import com.qqchen.deploy.backend.deploy.entity.DeployAppConfig;
|
||||
import com.qqchen.deploy.backend.deploy.enums.BuildTypeEnum;
|
||||
import com.qqchen.deploy.backend.deploy.enums.DevelopmentLanguageTypeEnum;
|
||||
import com.qqchen.deploy.backend.deploy.query.DeployAppConfigQuery;
|
||||
import com.qqchen.deploy.backend.deploy.service.IDeployAppConfigService;
|
||||
import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.qqchen.deploy.backend.workflow.util.GenerateSchemaUtils.generateSchema;
|
||||
|
||||
/**
|
||||
* 应用配置服务实现类
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class DeployAppConfigServiceImpl extends BaseServiceImpl<DeployAppConfig, DeployAppConfigDTO, DeployAppConfigQuery, Long> implements IDeployAppConfigService {
|
||||
|
||||
|
||||
@Override
|
||||
public List<BuildConfigDefinedDTO> defined() {
|
||||
List<BuildConfigDefinedDTO> result = new ArrayList<>();
|
||||
|
||||
for (BuildTypeEnum buildType : BuildTypeEnum.values()) {
|
||||
try {
|
||||
BuildConfigDefinedDTO definedDTO = new BuildConfigDefinedDTO();
|
||||
definedDTO.setCode(buildType.getCode());
|
||||
definedDTO.setName(buildType.getName());
|
||||
// 获取支持的语言和对应的构建变量类
|
||||
DevelopmentLanguageTypeEnum[] languages = buildType.getSupportedLanguages();
|
||||
Class<?>[] buildVariablesClasses = buildType.getBuildVariables();
|
||||
definedDTO.setBuildType(buildType);
|
||||
// 如果支持的语言不为空,则处理每种语言对应的Schema
|
||||
if (languages != null && buildVariablesClasses != null) {
|
||||
for (int i = 0; i < languages.length; i++) {
|
||||
if (buildVariablesClasses[i] != null) {
|
||||
definedDTO.setLanguageType(languages[i]);
|
||||
definedDTO.setBuildVariablesSchema(generateSchema(buildVariablesClasses[i]));
|
||||
result.add(definedDTO);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Error processing build type: " + buildType, e);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -30,6 +30,8 @@ import com.qqchen.deploy.backend.workflow.annotation.SchemaProperty;
|
||||
import com.qqchen.deploy.backend.workflow.annotation.SchemaPropertyDataSource;
|
||||
import com.qqchen.deploy.backend.workflow.annotation.SchemaPropertyDataSourceParam;
|
||||
|
||||
import static com.qqchen.deploy.backend.workflow.util.GenerateSchemaUtils.generateSchema;
|
||||
|
||||
/**
|
||||
* 工作流节点定义服务实现
|
||||
*/
|
||||
@ -125,184 +127,4 @@ public class WorkflowNodeDefinitionServiceImpl extends BaseServiceImpl<WorkflowN
|
||||
return result;
|
||||
}
|
||||
|
||||
private ObjectNode generateSchema(Class<?> cls) {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
ObjectNode schema = mapper.createObjectNode();
|
||||
schema.put("type", "object");
|
||||
|
||||
// 处理属性
|
||||
ObjectNode properties = schema.putObject("properties");
|
||||
List<String> required = new ArrayList<>();
|
||||
|
||||
// 获取所有字段,包括父类的字段
|
||||
List<Field> allFields = getAllFields(cls);
|
||||
|
||||
// 遍历所有字段
|
||||
for (Field field : allFields) {
|
||||
SchemaProperty annotation = field.getAnnotation(SchemaProperty.class);
|
||||
if (annotation != null) {
|
||||
ObjectNode property = properties.putObject(field.getName());
|
||||
|
||||
// 设置基本属性
|
||||
String jsonType = getJsonSchemaType(field.getType());
|
||||
property.put("type", jsonType);
|
||||
|
||||
// 从注解中获取属性
|
||||
if (!annotation.title().isEmpty()) {
|
||||
property.put("title", annotation.title());
|
||||
}
|
||||
if (!annotation.description().isEmpty()) {
|
||||
property.put("description", annotation.description());
|
||||
}
|
||||
if (!annotation.format().isEmpty()) {
|
||||
property.put("format", annotation.format());
|
||||
}
|
||||
if (annotation.required()) {
|
||||
required.add(field.getName());
|
||||
}
|
||||
if (annotation.defaultValue().length() > 0) {
|
||||
if (jsonType.equals("integer")) {
|
||||
property.put("default", Integer.parseInt(annotation.defaultValue()));
|
||||
} else if (jsonType.equals("number")) {
|
||||
property.put("default", Double.parseDouble(annotation.defaultValue()));
|
||||
} else {
|
||||
property.put("default", annotation.defaultValue());
|
||||
}
|
||||
}
|
||||
|
||||
// 处理枚举
|
||||
if (annotation.enumValues().length > 0) {
|
||||
ArrayNode enumNode = property.putArray("enum");
|
||||
for (String value : annotation.enumValues()) {
|
||||
enumNode.add(value);
|
||||
}
|
||||
|
||||
if (annotation.enumNames().length > 0) {
|
||||
ArrayNode enumNamesNode = property.putArray("enumNames");
|
||||
for (String name : annotation.enumNames()) {
|
||||
enumNamesNode.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理数组类型
|
||||
if (List.class.isAssignableFrom(field.getType())) {
|
||||
ObjectNode items = property.putObject("items");
|
||||
items.put("type", "string");
|
||||
}
|
||||
|
||||
// 处理Map类型
|
||||
if (Map.class.isAssignableFrom(field.getType())) {
|
||||
ObjectNode additionalProperties = property.putObject("additionalProperties");
|
||||
additionalProperties.put("type", "string");
|
||||
}
|
||||
|
||||
// 处理嵌套对象
|
||||
if (property.get("type").asText().equals("object")
|
||||
&& !Map.class.isAssignableFrom(field.getType())
|
||||
&& !field.getType().getName().startsWith("java.")) {
|
||||
ObjectNode nestedSchema = generateSchema(field.getType());
|
||||
if (nestedSchema.has("properties")) {
|
||||
property.set("properties", nestedSchema.get("properties"));
|
||||
}
|
||||
if (nestedSchema.has("required")) {
|
||||
property.set("required", nestedSchema.get("required"));
|
||||
}
|
||||
}
|
||||
|
||||
// 处理数据源
|
||||
SchemaPropertyDataSource dataSource = annotation.dataSource();
|
||||
if (dataSource != null && !dataSource.type().isEmpty()) {
|
||||
processDataSource(property, dataSource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 添加required字段
|
||||
if (!required.isEmpty()) {
|
||||
ArrayNode requiredNode = schema.putArray("required");
|
||||
required.forEach(requiredNode::add);
|
||||
}
|
||||
return schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理SchemaPropertyDataSource注解,生成数据源配置
|
||||
*
|
||||
* @param property 当前属性节点
|
||||
* @param dataSource 数据源注解
|
||||
*/
|
||||
private void processDataSource(ObjectNode property, SchemaPropertyDataSource dataSource) {
|
||||
ObjectNode dataSourceNode = property.putObject("dataSource");
|
||||
|
||||
// 处理基本属性
|
||||
dataSourceNode.put("type", dataSource.type());
|
||||
dataSourceNode.put("url", dataSource.url());
|
||||
dataSourceNode.put("valueField", dataSource.valueField());
|
||||
dataSourceNode.put("labelField", dataSource.labelField());
|
||||
|
||||
// 处理依赖字段
|
||||
String[] dependsOn = dataSource.dependsOn();
|
||||
if (dependsOn != null && dependsOn.length > 0) {
|
||||
ArrayNode dependsOnNode = dataSourceNode.putArray("dependsOn");
|
||||
for (String depend : dependsOn) {
|
||||
dependsOnNode.add(depend);
|
||||
}
|
||||
}
|
||||
|
||||
// 处理请求参数
|
||||
SchemaPropertyDataSourceParam[] params = dataSource.params();
|
||||
if (params != null && params.length > 0) {
|
||||
ObjectNode paramsNode = dataSourceNode.putObject("params");
|
||||
for (SchemaPropertyDataSourceParam param : params) {
|
||||
paramsNode.put(param.name(), param.value());
|
||||
}
|
||||
}
|
||||
|
||||
// // 处理其他可选属性
|
||||
// if (!dataSource.method().isEmpty()) {
|
||||
// dataSourceNode.put("method", dataSource.method());
|
||||
// }
|
||||
// if (!dataSource.searchField().isEmpty()) {
|
||||
// dataSourceNode.put("searchField", dataSource.searchField());
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取类的所有字段,包括父类的字段
|
||||
*/
|
||||
private List<Field> getAllFields(Class<?> clazz) {
|
||||
List<Field> fields = new ArrayList<>();
|
||||
Class<?> currentClass = clazz;
|
||||
|
||||
// 遍历类的继承层次
|
||||
while (currentClass != null && !currentClass.equals(Object.class)) {
|
||||
// 添加当前类的字段
|
||||
fields.addAll(Arrays.asList(currentClass.getDeclaredFields()));
|
||||
// 获取父类
|
||||
currentClass = currentClass.getSuperclass();
|
||||
}
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
private String getJsonSchemaType(Class<?> type) {
|
||||
if (String.class.equals(type)) {
|
||||
return "string";
|
||||
} else if (Integer.class.equals(type) || int.class.equals(type)
|
||||
|| Long.class.equals(type) || long.class.equals(type)) {
|
||||
return "integer";
|
||||
} else if (Double.class.equals(type) || double.class.equals(type)
|
||||
|| Float.class.equals(type) || float.class.equals(type)) {
|
||||
return "number";
|
||||
} else if (Boolean.class.equals(type) || boolean.class.equals(type)) {
|
||||
return "boolean";
|
||||
} else if (List.class.isAssignableFrom(type)) {
|
||||
return "array";
|
||||
} else if (Map.class.isAssignableFrom(type)) {
|
||||
return "object";
|
||||
} else {
|
||||
return "object";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,194 @@
|
||||
package com.qqchen.deploy.backend.workflow.util;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.qqchen.deploy.backend.workflow.annotation.SchemaProperty;
|
||||
import com.qqchen.deploy.backend.workflow.annotation.SchemaPropertyDataSource;
|
||||
import com.qqchen.deploy.backend.workflow.annotation.SchemaPropertyDataSourceParam;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class GenerateSchemaUtils {
|
||||
|
||||
public static ObjectNode generateSchema(Class<?> cls) {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
ObjectNode schema = mapper.createObjectNode();
|
||||
schema.put("type", "object");
|
||||
|
||||
// 处理属性
|
||||
ObjectNode properties = schema.putObject("properties");
|
||||
List<String> required = new ArrayList<>();
|
||||
|
||||
// 获取所有字段,包括父类的字段
|
||||
List<Field> allFields = getAllFields(cls);
|
||||
|
||||
// 遍历所有字段
|
||||
for (Field field : allFields) {
|
||||
SchemaProperty annotation = field.getAnnotation(SchemaProperty.class);
|
||||
if (annotation != null) {
|
||||
ObjectNode property = properties.putObject(field.getName());
|
||||
|
||||
// 设置基本属性
|
||||
String jsonType = getJsonSchemaType(field.getType());
|
||||
property.put("type", jsonType);
|
||||
|
||||
// 从注解中获取属性
|
||||
if (!annotation.title().isEmpty()) {
|
||||
property.put("title", annotation.title());
|
||||
}
|
||||
if (!annotation.description().isEmpty()) {
|
||||
property.put("description", annotation.description());
|
||||
}
|
||||
if (!annotation.format().isEmpty()) {
|
||||
property.put("format", annotation.format());
|
||||
}
|
||||
if (annotation.required()) {
|
||||
required.add(field.getName());
|
||||
}
|
||||
if (annotation.defaultValue().length() > 0) {
|
||||
if (jsonType.equals("integer")) {
|
||||
property.put("default", Integer.parseInt(annotation.defaultValue()));
|
||||
} else if (jsonType.equals("number")) {
|
||||
property.put("default", Double.parseDouble(annotation.defaultValue()));
|
||||
} else {
|
||||
property.put("default", annotation.defaultValue());
|
||||
}
|
||||
}
|
||||
|
||||
// 处理枚举
|
||||
if (annotation.enumValues().length > 0) {
|
||||
ArrayNode enumNode = property.putArray("enum");
|
||||
for (String value : annotation.enumValues()) {
|
||||
enumNode.add(value);
|
||||
}
|
||||
|
||||
if (annotation.enumNames().length > 0) {
|
||||
ArrayNode enumNamesNode = property.putArray("enumNames");
|
||||
for (String name : annotation.enumNames()) {
|
||||
enumNamesNode.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理数组类型
|
||||
if (List.class.isAssignableFrom(field.getType())) {
|
||||
ObjectNode items = property.putObject("items");
|
||||
items.put("type", "string");
|
||||
}
|
||||
|
||||
// 处理Map类型
|
||||
if (Map.class.isAssignableFrom(field.getType())) {
|
||||
ObjectNode additionalProperties = property.putObject("additionalProperties");
|
||||
additionalProperties.put("type", "string");
|
||||
}
|
||||
|
||||
// 处理嵌套对象
|
||||
if (property.get("type").asText().equals("object") && !Map.class.isAssignableFrom(field.getType()) && !field.getType().getName().startsWith("java.")) {
|
||||
ObjectNode nestedSchema = generateSchema(field.getType());
|
||||
if (nestedSchema.has("properties")) {
|
||||
property.set("properties", nestedSchema.get("properties"));
|
||||
}
|
||||
if (nestedSchema.has("required")) {
|
||||
property.set("required", nestedSchema.get("required"));
|
||||
}
|
||||
}
|
||||
|
||||
// 处理数据源
|
||||
SchemaPropertyDataSource dataSource = annotation.dataSource();
|
||||
if (dataSource != null && !dataSource.type().isEmpty()) {
|
||||
processDataSource(property, dataSource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 添加required字段
|
||||
if (!required.isEmpty()) {
|
||||
ArrayNode requiredNode = schema.putArray("required");
|
||||
required.forEach(requiredNode::add);
|
||||
}
|
||||
return schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理SchemaPropertyDataSource注解,生成数据源配置
|
||||
*
|
||||
* @param property 当前属性节点
|
||||
* @param dataSource 数据源注解
|
||||
*/
|
||||
private static void processDataSource(ObjectNode property, SchemaPropertyDataSource dataSource) {
|
||||
ObjectNode dataSourceNode = property.putObject("dataSource");
|
||||
|
||||
// 处理基本属性
|
||||
dataSourceNode.put("type", dataSource.type());
|
||||
dataSourceNode.put("url", dataSource.url());
|
||||
dataSourceNode.put("valueField", dataSource.valueField());
|
||||
dataSourceNode.put("labelField", dataSource.labelField());
|
||||
|
||||
// 处理依赖字段
|
||||
String[] dependsOn = dataSource.dependsOn();
|
||||
if (dependsOn != null && dependsOn.length > 0) {
|
||||
ArrayNode dependsOnNode = dataSourceNode.putArray("dependsOn");
|
||||
for (String depend : dependsOn) {
|
||||
dependsOnNode.add(depend);
|
||||
}
|
||||
}
|
||||
|
||||
// 处理请求参数
|
||||
SchemaPropertyDataSourceParam[] params = dataSource.params();
|
||||
if (params != null && params.length > 0) {
|
||||
ObjectNode paramsNode = dataSourceNode.putObject("params");
|
||||
for (SchemaPropertyDataSourceParam param : params) {
|
||||
paramsNode.put(param.name(), param.value());
|
||||
}
|
||||
}
|
||||
|
||||
// // 处理其他可选属性
|
||||
// if (!dataSource.method().isEmpty()) {
|
||||
// dataSourceNode.put("method", dataSource.method());
|
||||
// }
|
||||
// if (!dataSource.searchField().isEmpty()) {
|
||||
// dataSourceNode.put("searchField", dataSource.searchField());
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取类的所有字段,包括父类的字段
|
||||
*/
|
||||
private static List<Field> getAllFields(Class<?> clazz) {
|
||||
List<Field> fields = new ArrayList<>();
|
||||
Class<?> currentClass = clazz;
|
||||
|
||||
// 遍历类的继承层次
|
||||
while (currentClass != null && !currentClass.equals(Object.class)) {
|
||||
// 添加当前类的字段
|
||||
fields.addAll(Arrays.asList(currentClass.getDeclaredFields()));
|
||||
// 获取父类
|
||||
currentClass = currentClass.getSuperclass();
|
||||
}
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
private static String getJsonSchemaType(Class<?> type) {
|
||||
if (String.class.equals(type)) {
|
||||
return "string";
|
||||
} else if (Integer.class.equals(type) || int.class.equals(type) || Long.class.equals(type) || long.class.equals(type)) {
|
||||
return "integer";
|
||||
} else if (Double.class.equals(type) || double.class.equals(type) || Float.class.equals(type) || float.class.equals(type)) {
|
||||
return "number";
|
||||
} else if (Boolean.class.equals(type) || boolean.class.equals(type)) {
|
||||
return "boolean";
|
||||
} else if (List.class.isAssignableFrom(type)) {
|
||||
return "array";
|
||||
} else if (Map.class.isAssignableFrom(type)) {
|
||||
return "object";
|
||||
} else {
|
||||
return "object";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -78,6 +78,8 @@ VALUES
|
||||
(202, '应用管理', '/deploy/applications', '/src/pages/Deploy/Application/List/index', 'AppstoreOutlined', 2, 200, 2, FALSE, TRUE, 'system', '2024-01-01 00:00:00', 0, FALSE),
|
||||
|
||||
(203, '环境管理', '/deploy/environments', '/src/pages/Deploy/Environment/List/index', 'CloudOutlined', 2, 200, 3, FALSE, TRUE, 'system', '2024-01-01 00:00:00', 0, FALSE),
|
||||
|
||||
(204, '部署配置管理', '/deploy/deployment', '/src/pages/Deploy/Deployment/List/index', 'CloudOutlined', 2, 200, 3, FALSE, TRUE, 'system', '2024-01-01 00:00:00', 0, FALSE),
|
||||
-- 三方系统
|
||||
(205, '三方系统管理', '/deploy/external', '/src/pages/Deploy/external/index', 'ApiOutlined', 2, 200, 70, FALSE, TRUE, 'system', '2024-01-01 00:00:00', 0, FALSE);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user