commit:升级到vue3,更新最近工作流技术栈,支持sa-token

This commit is contained in:
Jerry
2024-07-05 22:42:33 +08:00
parent bbcc608584
commit 565ecb6371
1751 changed files with 236790 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
package com.orangeforms.common.swagger.config;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
/**
* 自动加载bean的配置对象。
*
* @author Jerry
* @date 2024-07-02
*/
@EnableConfigurationProperties(SwaggerProperties.class)
@ConditionalOnProperty(prefix = "common-swagger", name = "enabled")
public class SwaggerAutoConfiguration {
@Bean
public GroupedOpenApi upmsApi(SwaggerProperties p) {
String[] paths = {"/admin/upms/**"};
String[] packagedToMatch = {p.getServiceBasePackage() + ".upms.controller"};
return GroupedOpenApi.builder().group("用户权限分组接口")
.pathsToMatch(paths)
.packagesToScan(packagedToMatch).build();
}
@Bean
public GroupedOpenApi bizApi(SwaggerProperties p) {
String[] paths = {"/admin/app/**"};
String[] packagedToMatch = {p.getServiceBasePackage() + ".app.controller"};
return GroupedOpenApi.builder().group("业务应用分组接口")
.pathsToMatch(paths)
.packagesToScan(packagedToMatch).build();
}
@Bean
public GroupedOpenApi workflowApi(SwaggerProperties p) {
String[] paths = {"/admin/flow/**"};
String[] packagedToMatch = {p.getBasePackage() + ".common.flow.controller"};
return GroupedOpenApi.builder().group("工作流通用操作接口")
.pathsToMatch(paths)
.packagesToScan(packagedToMatch).build();
}
@Bean
public GroupedOpenApi onlineApi(SwaggerProperties p) {
String[] paths = {"/admin/online/**"};
String[] packagedToMatch = {p.getBasePackage() + ".common.online.controller"};
return GroupedOpenApi.builder().group("在线表单操作接口")
.pathsToMatch(paths)
.packagesToScan(packagedToMatch).build();
}
@Bean
public GroupedOpenApi reportApi(SwaggerProperties p) {
String[] paths = {"/admin/report/**"};
String[] packagedToMatch = {p.getBasePackage() + ".common.report.controller"};
return GroupedOpenApi.builder().group("报表打印操作接口")
.pathsToMatch(paths)
.packagesToScan(packagedToMatch).build();
}
@Bean
public OpenAPI customOpenApi(SwaggerProperties p) {
Info info = new Info().title(p.getTitle()).version(p.getVersion()).description(p.getDescription());
return new OpenAPI().info(info);
}
}

View File

@@ -0,0 +1,45 @@
package com.orangeforms.common.swagger.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* 配置参数对象。
*
* @author Jerry
* @date 2024-07-02
*/
@Data
@ConfigurationProperties("common-swagger")
public class SwaggerProperties {
/**
* 是否开启Swagger。
*/
private Boolean enabled;
/**
* Swagger解析的基础包路径。
**/
private String basePackage = "";
/**
* Swagger解析的服务包路径。
**/
private String serviceBasePackage = "";
/**
* ApiInfo中的标题。
**/
private String title = "";
/**
* ApiInfo中的描述信息。
**/
private String description = "";
/**
* ApiInfo中的版本信息。
**/
private String version = "";
}

View File

@@ -0,0 +1,194 @@
package com.orangeforms.common.swagger.plugin;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.orangeforms.common.core.annotation.MyRequestBody;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.models.Operation;
import lombok.extern.slf4j.Slf4j;
import org.springdoc.core.customizers.GlobalOperationCustomizer;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import java.lang.annotation.Annotation;
import java.lang.reflect.*;
import java.util.*;
import java.util.stream.Stream;
/**
* @author <a href="xiaoymin@foxmail.com">xiaoymin@foxmail.com</a>
*/
@Slf4j
@Component
public class MyGlobalOperationCustomer implements GlobalOperationCustomizer {
/**
* 注解包路径名称
*/
private static final String REF_KEY = "$ref";
private static final String REF_SCHEMA_PREFIX = "#/components/schemas/";
private final Map<Class<?>, Set<String>> cacheClassProperties = MapUtil.newHashMap();
private static final String EXTENSION_ORANGE_FORM_NAME = "x-orangeforms";
private static final String EXTENSION_ORANGE_FORM_IGNORE_NAME = "x-orangeforms-ignore-parameters";
@Override
public Operation customize(Operation operation, HandlerMethod handlerMethod) {
this.handleSummary(operation, handlerMethod);
if (handlerMethod.getMethod().getParameterCount() <= 0) {
return operation;
}
Parameter[] parameters = handlerMethod.getMethod().getParameters();
if (ArrayUtil.isEmpty(parameters)) {
return operation;
}
Map<String, Object> properties = MapUtil.newHashMap();
Map<String, Object> extensions = MapUtil.newHashMap();
Set<String> ignoreFieldName = CollUtil.newHashSet();
List<String> required = new ArrayList<>();
Map<String, io.swagger.v3.oas.annotations.Parameter> paramMap = getParameterDescription(handlerMethod.getMethod());
for (Parameter parameter : parameters) {
Annotation[] annos = parameter.getAnnotations();
if (ArrayUtil.isEmpty(annos)) {
continue;
}
long count = Stream.of(annos).filter(anno -> anno.annotationType().equals(MyRequestBody.class)).count();
if (count > 0) {
this.handleParameterDetail(parameter, properties, paramMap, ignoreFieldName, required);
}
}
if (!properties.isEmpty()) {
extensions.put("properties", properties);
extensions.put("type", "object");
//required字段
if (!required.isEmpty()) {
extensions.put("required", required);
}
String generateSchemaName = handlerMethod.getMethod().getName() + "DynamicReq";
Map<String, Object> orangeExtensions = MapUtil.newHashMap();
orangeExtensions.put(generateSchemaName, extensions);
//增加扩展属性
operation.addExtension(EXTENSION_ORANGE_FORM_NAME, orangeExtensions);
if (!ignoreFieldName.isEmpty()) {
operation.addExtension(EXTENSION_ORANGE_FORM_IGNORE_NAME, ignoreFieldName);
}
}
return operation;
}
private void handleSummary(Operation operation, HandlerMethod handlerMethod) {
io.swagger.v3.oas.annotations.Operation operationAnno =
handlerMethod.getMethod().getAnnotation(io.swagger.v3.oas.annotations.Operation.class);
if (operationAnno == null || StrUtil.isBlank(operationAnno.summary())) {
operation.setSummary(handlerMethod.getMethod().getName());
}
}
private void handleParameterDetail(
Parameter parameter,
Map<String, Object> properties,
Map<String, io.swagger.v3.oas.annotations.Parameter> paramMap,
Set<String> ignoreFieldName,
List<String> required) {
Class<?> parameterType = parameter.getType();
String schemaName = parameterType.getSimpleName();
//添加忽律参数名称
ignoreFieldName.addAll(getClassFields(parameterType));
//处理schema注解别名的情况
Schema schema = parameterType.getAnnotation(Schema.class);
if (schema != null && StrUtil.isNotBlank(schema.name())) {
schemaName = schema.name();
}
Map<String, Object> value = MapUtil.newHashMap();
//此处需要判断parameter的基础数据类型
if (parameterType.isPrimitive() || parameterType.getName().startsWith("java.lang")) {
//基础数据类型
ignoreFieldName.add(parameter.getName());
value.put("type", parameterType.getSimpleName().toLowerCase());
//判断format
} else if (Collection.class.isAssignableFrom(parameterType)) {
//集合类型
value.put("type", "array");
//获取泛型
getGenericType(parameterType, parameter.getParameterizedType())
.ifPresent(s -> value.put("items", MapUtil.builder(REF_KEY, REF_SCHEMA_PREFIX + s).build()));
} else {
//引用类型
value.put(REF_KEY, REF_SCHEMA_PREFIX + schemaName);
}
//补一个description
io.swagger.v3.oas.annotations.Parameter paramAnnotation = paramMap.get(parameter.getName());
if (paramAnnotation != null) {
//忽略该参数
ignoreFieldName.add(paramAnnotation.name());
value.put("description", paramAnnotation.description());
if (StrUtil.isNotBlank(paramAnnotation.example())) {
value.put("default", paramAnnotation.example());
}
// required参数
if (paramAnnotation.required()) {
required.add(parameter.getName());
}
}
properties.put(parameter.getName(), value);
}
private Optional<String> getGenericType(Class<?> clazz, Type type) {
Type genericSuperclass = clazz.getGenericSuperclass();
if (genericSuperclass instanceof ParameterizedType || type instanceof ParameterizedType) {
if (type instanceof ParameterizedType) {
genericSuperclass = type;
}
ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
return Optional.of(((Class) actualTypeArguments[0]).getSimpleName());
}
return Optional.empty();
}
private Set<String> getClassFields(Class<?> parameterType) {
if (parameterType == null) {
return Collections.emptySet();
}
if (cacheClassProperties.containsKey(parameterType)) {
return cacheClassProperties.get(parameterType);
}
Set<String> fieldNames = new HashSet<>();
try {
Field[] fields = parameterType.getDeclaredFields();
if (fields.length > 0) {
for (Field field : fields) {
fieldNames.add(field.getName());
}
cacheClassProperties.put(parameterType, fieldNames);
return fieldNames;
}
} catch (Exception e) {
//ignore
}
return Collections.emptySet();
}
private Map<String, io.swagger.v3.oas.annotations.Parameter> getParameterDescription(Method method) {
Parameters parameters = method.getAnnotation(Parameters.class);
Map<String, io.swagger.v3.oas.annotations.Parameter> resultMap = MapUtil.newHashMap();
if (parameters != null) {
io.swagger.v3.oas.annotations.Parameter[] parameters1 = parameters.value();
if (parameters1 != null && parameters1.length > 0) {
for (io.swagger.v3.oas.annotations.Parameter parameter : parameters1) {
resultMap.put(parameter.name(), parameter);
}
return resultMap;
}
} else {
io.swagger.v3.oas.annotations.Parameter parameter =
method.getAnnotation(io.swagger.v3.oas.annotations.Parameter.class);
if (parameter != null) {
resultMap.put(parameter.name(), parameter);
}
}
return resultMap;
}
}

View File

@@ -0,0 +1 @@
com.orangeforms.common.swagger.config.SwaggerAutoConfiguration