feat: 数据适配器和接口管理

This commit is contained in:
clay
2024-04-18 15:29:19 +08:00
parent 695d21793e
commit 7f8ceb3e25
39 changed files with 1288 additions and 24 deletions

View File

@@ -59,11 +59,7 @@ public class EncryptAspect {
} else if (arg instanceof List) {
try {
List<String> list = (List<String>) arg;
for (int j = 0; j < list.size(); j++) {
String ciphertext = list.get(j);
String decrypt = encryptService.decrypt(ciphertext);
list.set(j, decrypt);
}
list.replaceAll(encryptService::decrypt);
args[i] = list;
} catch (Exception e) {
throw new CustomException("接受参数类型错误,请使用String类型的泛型参数");
@@ -117,7 +113,9 @@ public class EncryptAspect {
String decrypt = encryptService.encrypt((String) value);
ReflectionUtils.setField(field, data, decrypt);
} else if (field.getType().getName().startsWith(BASE_PACKAGE)) {
if (!value.getClass().isEnum()){
encrypt(value);
}
} else if (value instanceof Collection) {
Collection<Object> collection = (Collection<Object>) value;
for (Object item : collection) {
@@ -148,9 +146,11 @@ public class EncryptAspect {
String decrypt = encryptService.decrypt((String) value);
ReflectionUtils.setField(field, arg, decrypt);
} else if (field.getType().getName().startsWith(BASE_PACKAGE)) {
if (!value.getClass().isEnum()){
decrypt(value);
}
}
}
}
}

View File

@@ -0,0 +1,29 @@
package cn.fateverse.common.decrypt.entity;
import cn.fateverse.common.decrypt.annotation.EncryptField;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author Clay
* @date 2024/4/15 12:23
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class EncryptOption {
/**
* 节点ID
*/
@EncryptField
private String value;
/**
* 节点名称
*/
private String label;
}

View File

@@ -0,0 +1,38 @@
package cn.fateverse.common.decrypt.entity;
import cn.fateverse.common.core.entity.OptionTree;
import cn.fateverse.common.decrypt.annotation.EncryptField;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author Clay
* @date 2024/4/15 12:23
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class EncryptOptionTree {
/**
* 节点ID
*/
@EncryptField
private String value;
/**
* 节点名称
*/
private Object label;
/**
* 子节点
*/
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private List<OptionTree> children;
}

View File

@@ -0,0 +1,41 @@
<?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>
<artifactId>custom-query</artifactId>
<groupId>cn.fateverse</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>custom-query-api</artifactId>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>cn.fateverse</groupId>
<artifactId>common-dubbo</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo.extensions</groupId>
<artifactId>dubbo-cluster-specify-address-dubbo3</artifactId>
<version>1.0.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>cn.fateverse</groupId>
<artifactId>common-dubbo</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -49,9 +49,14 @@
<groupId>cn.fateverse</groupId>
<artifactId>admin-api</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>cn.fateverse</groupId>-->
<!-- <artifactId>common-seata</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>cn.fateverse</groupId>
<artifactId>common-seata</artifactId>
<artifactId>custom-query-api</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>

View File

@@ -0,0 +1,93 @@
package cn.fateverse.query.config;
import cn.fateverse.common.core.exception.CustomException;
import cn.fateverse.query.controller.TestController;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.lang.reflect.Method;
import java.util.Map;
/**
* @author Clay
* @date 2024/4/12 16:56
*/
@Slf4j
@Configuration
public class HandlerMethodConfiguration implements ApplicationContextAware {
public static final String CUSTOM_INTERFACE = "customInterface:";
private RequestMappingHandlerMapping mapping;
private Method mappingMethod;
public HandlerMethodConfiguration() {
Class<TestController> testControllerClass = TestController.class;
Method[] declaredMethods = testControllerClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
if ("mapping".equals(declaredMethod.getName())) {
mappingMethod = declaredMethod;
}
}
if (mappingMethod == null) {
log.error("mappingMethod is null");
}
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
mapping = (RequestMappingHandlerMapping) applicationContext.getBean("requestMappingHandlerMapping");
}
/**
* 注册映射接口
*
* @param path 接口路径
* @param requestMethod 请求方法
*/
public void registerMapping(String path, RequestMethod requestMethod) {
String[] empty = {};
RequestMappingInfo.Builder builder = RequestMappingInfo
.paths(path)
.methods(requestMethod)
.params(empty)
.headers(empty)
.consumes(empty)
.produces(empty)
.mappingName(CUSTOM_INTERFACE + path);
RequestMappingInfo requestMappingInfo = builder.options(mapping.getBuilderConfiguration()).build();
Map<RequestMappingInfo, HandlerMethod> handlerMethods = mapping.getHandlerMethods();
if (handlerMethods.containsKey(requestMappingInfo)) {
throw new CustomException("path is exist");
}
mapping.registerMapping(requestMappingInfo, "testController", mappingMethod);
}
/**
* 卸载映射接口
*
* @param path 接口路径
* @param requestMethod 请求类型
*/
public void unregisterMapping(String path, RequestMethod requestMethod) {
Map<RequestMappingInfo, HandlerMethod> handlerMethods = mapping.getHandlerMethods();
for (RequestMappingInfo mappingInfo : handlerMethods.keySet()) {
if (!ObjectUtils.isEmpty(mappingInfo.getName())
&& (CUSTOM_INTERFACE + path).equals(mappingInfo.getName())
&& mappingInfo.getMethodsCondition().getMethods().contains(requestMethod)) {
mapping.unregisterMapping(mappingInfo);
}
}
}
}

View File

@@ -1,6 +1,9 @@
package cn.fateverse.query.controller;
import cn.fateverse.common.core.exception.CustomException;
import cn.fateverse.common.decrypt.annotation.Encrypt;
import cn.fateverse.common.decrypt.annotation.EncryptField;
import cn.fateverse.common.decrypt.entity.EncryptOption;
import cn.fateverse.common.excel.utils.ExcelUtil;
import cn.fateverse.query.entity.dto.DataAdapterDto;
import cn.fateverse.query.entity.query.DataAdapterQuery;
@@ -39,6 +42,7 @@ public class DataAdapterController {
@ApiOperation("获取数据源适配器列表")
@Encrypt
@GetMapping
@PreAuthorize("@ss.hasPermission('query:adapter:list')")
public Result<TableDataInfo<DataAdapterVo>> list(DataAdapterQuery query) {
@@ -47,9 +51,10 @@ public class DataAdapterController {
}
@ApiOperation("获取校验规则option")
@Encrypt
@GetMapping("/option")
public Result<List<Option>> option() {
List<Option> options = dataAdapterService.searchOptionList();
public Result<List<EncryptOption>> option() {
List<EncryptOption> options = dataAdapterService.searchOptionList();
return Result.ok(options);
}
@@ -62,11 +67,13 @@ public class DataAdapterController {
}
@ApiOperation("获取数据源适配器详细信息")
@Encrypt
@GetMapping("/{adapterId}")
@PreAuthorize("@ss.hasPermission('query:adapter:info')")
public Result<DataAdapterVo> info(@PathVariable Long adapterId) {
public Result<DataAdapterVo> info(@PathVariable @EncryptField String adapterId) {
ObjectUtils.checkPk(adapterId);
DataAdapterVo dataAdapter = dataAdapterService.searchById(adapterId);
Long id = Long.valueOf(adapterId);
DataAdapterVo dataAdapter = dataAdapterService.searchById(id);
return Result.ok(dataAdapter);
}

View File

@@ -0,0 +1,60 @@
package cn.fateverse.query.controller;
import cn.fateverse.common.core.result.Result;
import cn.fateverse.common.core.result.page.TableDataInfo;
import cn.fateverse.common.core.utils.ObjectUtils;
import cn.fateverse.common.decrypt.annotation.Encrypt;
import cn.fateverse.common.decrypt.annotation.EncryptField;
import cn.fateverse.query.entity.query.PortalQuery;
import cn.fateverse.query.entity.vo.PortalVo;
import cn.fateverse.query.entity.vo.SimplePortalVo;
import cn.fateverse.query.service.PortalService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 接口管理表(portal 传送门 接口作为入口 传送到其他类型) Controller
*
* @author clay
* @date 2024-04-15
*/
@Api(value = "接口管理表", tags = "接口管理表")
@RestController
@RequestMapping("/portal")
public class PortalController {
private final PortalService portalService;
public PortalController(PortalService portalService) {
this.portalService = portalService;
}
@ApiOperation("获取接口管理表详细信息")
@Encrypt
@GetMapping("/{portalId}")
@PreAuthorize("@ss.hasPermission('query:portal:info')")
public Result<PortalVo> info(@PathVariable @EncryptField String portalId) {
ObjectUtils.checkPk(portalId);
Long value = Long.valueOf(portalId);
PortalVo portal = portalService.searchById(value);
return Result.ok(portal);
}
@ApiOperation("获取接口管理表列表")
@GetMapping
@Encrypt
@PreAuthorize("@ss.hasPermission('query:portal:list')")
public Result<TableDataInfo<SimplePortalVo>> list(PortalQuery query) {
TableDataInfo<SimplePortalVo> dataInfo = portalService.searchList(query);
return Result.ok(dataInfo);
}
}

View File

@@ -0,0 +1,30 @@
package cn.fateverse.query.controller;
import cn.fateverse.query.service.QueryToolService;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Clay
* @date 2024/4/16 16:10
*/
@Api(tags = "自定义查询工具接口管理")
@RestController
@RequestMapping("/query/tool")
public class QueryToolController {
private final QueryToolService queryToolService;
public QueryToolController(QueryToolService queryToolService) {
this.queryToolService = queryToolService;
}
}

View File

@@ -0,0 +1,47 @@
package cn.fateverse.query.controller;
import cn.fateverse.common.security.annotation.Anonymity;
import cn.fateverse.common.security.configure.properties.PermitAllUrlProperties;
import cn.fateverse.query.config.HandlerMethodConfiguration;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
/**
* @author Clay
* @date 2024/4/12 14:18
*/
@RestController
@RequestMapping("/test")
public class TestController {
@Resource
private HandlerMethodConfiguration configuration;
@Anonymity
@GetMapping("/1")
public String test1() {
configuration.registerMapping("/anonymity/mapping", RequestMethod.GET);
return "1";
}
@Anonymity
@GetMapping("/2")
public String test2() {
configuration.unregisterMapping("/anonymity/mapping", RequestMethod.GET);
return "2";
}
public String mapping(HttpServletRequest request) {
return "mapping";
}
}

View File

@@ -0,0 +1,100 @@
package cn.fateverse.query.entity;
import cn.fateverse.common.core.annotaion.EnableAutoField;
import cn.fateverse.common.core.entity.BaseEntity;
import cn.fateverse.query.enums.PortalEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 接口管理表(portal 传送门 接口作为入口 传送到其他类型)对象 portal
*
* @author clay
* @date 2024-04-15
*/
@Data
@Builder
@EnableAutoField
@AllArgsConstructor
@NoArgsConstructor
public class Portal extends BaseEntity{
/**
* 主键id
*/
private Long portalId;
/**
* 自定义查询id
*/
private Long queryId;
/**
* 数据适配器id
*/
private Long adapterId;
/**
* 接口名称
*/
private String portalName;
/**
* 是否匿名
*/
private Boolean anonymity;
/**
* 接口类型
*/
private PortalEnum type;
/**
* 系统暴露地址
*/
private String path;
/**
* 请求头
*/
private String header;
/**
* 请求参数
*/
private String params;
/**
* 请求体
*/
private String body;
/**
* 第三方接口地址
*/
private String url;
/**
* 第三方接口请求头
*/
private String apiHeader;
/**
* 第三方接口请求参数
*/
private String apiParams;
/**
* 第三方接口请求体
*/
private String apiBody;
/**
* 状态
*/
private Long state;
}

View File

@@ -0,0 +1,46 @@
package cn.fateverse.query.entity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 接口映射表对象 portal_mapping
*
* @author clay
* @date 2024-04-15
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class PortalMapping {
/**
* 条件id
*/
private Long mappingId;
/**
* 自定义接口id
*/
private Long portalId;
/**
* 字段
*/
private String mappingKey;
/**
* 数据类型, 0 param, 1 header, 2 body
*/
private Integer dataType;
/**
* 映射值 自定义查询映射值为查询条件的id 第三方接口则为接口查询的key
*/
private String mappingValue;
}

View File

@@ -0,0 +1,137 @@
package cn.fateverse.query.entity.dto;
import cn.fateverse.query.entity.Portal;
import cn.fateverse.query.enums.PortalEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 接口管理表(portal 传送门 接口作为入口 传送到其他类型)对象 portal
*
* @author clay
* @date 2024-04-15
*/
@Data
@ApiModel("接口管理表(portal 传送门 接口作为入口 传送到其他类型)Dto")
public class PortalDto {
/**
* 主键id
*/
@ApiModelProperty("主键id")
private String portalId;
/**
* 自定义查询id
*/
@ApiModelProperty("自定义查询id")
private Long queryId;
/**
* 数据适配器id
*/
@ApiModelProperty("数据适配器id")
private Long adapterId;
/**
* 接口名称
*/
@ApiModelProperty("接口名称")
private String portalName;
/**
* 是否匿名
*/
@ApiModelProperty("是否匿名")
private Boolean anonymity;
/**
* 接口类型
*/
@ApiModelProperty("接口类型")
private PortalEnum type;
/**
* 系统暴露地址
*/
@ApiModelProperty("系统暴露地址")
private String path;
/**
* 请求头
*/
@ApiModelProperty("请求头")
private String header;
/**
* 请求参数
*/
@ApiModelProperty("请求参数")
private String params;
/**
* 请求体
*/
@ApiModelProperty("请求体")
private String body;
/**
* 第三方接口地址
*/
@ApiModelProperty("第三方接口地址")
private String url;
/**
* 第三方接口请求头
*/
@ApiModelProperty("第三方接口请求头")
private String apiHeader;
/**
* 第三方接口请求参数
*/
@ApiModelProperty("第三方接口请求参数")
private String apiParams;
/**
* 第三方接口请求体
*/
@ApiModelProperty("第三方接口请求体")
private String apiBody;
/**
* 状态
*/
@ApiModelProperty("状态")
private Long state;
/**
* 备注
*/
@ApiModelProperty("备注")
private String remark;
public Portal toPortal() {
Portal portal = Portal.builder()
.queryId(queryId)
.adapterId(adapterId)
.portalName(portalName)
.anonymity(anonymity)
.type(type)
.path(path)
.header(header)
.params(params)
.body(body)
.url(url)
.apiHeader(apiHeader)
.apiParams(apiParams)
.apiBody(apiBody)
.state(state)
.build();
portal.setPortalId(Long.valueOf(portalId));
portal.setRemark(remark);
return portal;
}
}

View File

@@ -0,0 +1,45 @@
package cn.fateverse.query.entity.query;
import cn.fateverse.query.enums.PortalEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 接口管理表(portal 传送门 接口作为入口 传送到其他类型)对象 portal
*
* @author clay
* @date 2024-04-15
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel("接口管理表(portal 传送门 接口作为入口 传送到其他类型)Query")
public class PortalQuery {
/**
* 接口名称
*/
@ApiModelProperty("接口名称")
private String portalName;
/**
* 是否匿名
*/
@ApiModelProperty("是否匿名")
private Boolean anonymity;
/**
* 接口类型
*/
@ApiModelProperty("接口类型")
private PortalEnum type;
/**
* 系统暴露地址
*/
@ApiModelProperty("系统暴露地址")
private String path;
}

View File

@@ -0,0 +1,34 @@
package cn.fateverse.query.entity.vo;
import lombok.Builder;
import lombok.Data;
/**
* @author Clay
* @date 2024/4/15 16:44
*/
@Data
@Builder
public class PortalMappingVo {
/**
* 条件id
*/
private Long mappingId;
/**
* 字段
*/
private String mappingKey;
/**
* 数据类型, 0 param, 1 header, 2 body
*/
private Integer dataType;
/**
* 映射值 自定义查询映射值为查询条件的id 第三方接口则为接口查询的key
*/
private String mappingValue;
}

View File

@@ -0,0 +1,40 @@
package cn.fateverse.query.entity.vo;
import cn.fateverse.query.entity.Portal;
import cn.fateverse.query.entity.PortalMapping;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import org.springframework.beans.BeanUtils;
import org.springframework.util.ObjectUtils;
import java.util.List;
/**
* 接口管理表(portal 传送门 接口作为入口 传送到其他类型)对象 portal
*
* @author clay
* @date 2024-04-15
*/
@Data
@ApiModel("接口详细管理表Vo")
public class PortalVo extends SimplePortalVo {
private List<PortalMapping> mappings;
public static PortalVo toPortalVo(Portal portal) {
return toPortalVo(portal, null);
}
public static PortalVo toPortalVo(Portal portal, List<PortalMapping> mappings) {
SimplePortalVo simplePortalVo = SimplePortalVo.toPortalVo(portal);
PortalVo portalVo = new PortalVo();
BeanUtils.copyProperties(simplePortalVo, portalVo);
if (!ObjectUtils.isEmpty(mappings)) {
portalVo.setMappings(mappings);
}
return portalVo;
}
}

View File

@@ -0,0 +1,148 @@
package cn.fateverse.query.entity.vo;
import cn.fateverse.common.core.annotaion.Excel;
import cn.fateverse.common.decrypt.annotation.EncryptField;
import cn.fateverse.query.entity.Portal;
import cn.fateverse.query.enums.PortalEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.util.ObjectUtils;
import java.util.Date;
/**
* @author Clay
* @date 2024/4/15 10:28
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ApiModel("简单接口管理表")
public class SimplePortalVo {
/**
* 主键id
*/
@ApiModelProperty("主键id")
@EncryptField
private String portalId;
/**
* 自定义查询id
*/
@ApiModelProperty("自定义查询id")
@EncryptField
private String queryId;
/**
* 数据适配器id
*/
@ApiModelProperty("数据适配器id")
@EncryptField
private String adapterId;
/**
* 接口名称
*/
@ApiModelProperty("接口名称")
@Excel("接口名称")
private String portalName;
/**
* 自定查询名称
*/
@ApiModelProperty("自定查询名称")
@Excel("自定查询名称")
private String queryName;
@ApiModelProperty("自定查询类型 1:sql 2:topo图")
private Integer queryType;
/**
* 数据适配器名称
*/
@ApiModelProperty("数据适配器名称")
@Excel("数据适配器名称")
private String adapterName;
/**
* 是否匿名
*/
@ApiModelProperty("是否匿名")
@Excel("是否匿名")
private Boolean anonymity;
/**
* 接口类型
*/
@ApiModelProperty("接口类型")
@Excel("接口类型")
private PortalEnum type;
/**
* 系统暴露地址
*/
@ApiModelProperty("系统暴露地址")
@Excel("系统暴露地址")
private String path;
/**
* 状态
*/
@ApiModelProperty("状态 0: 创建 1: 发布 2:内部使用(例如提供echarts单独使用)")
@Excel("状态")
private Long state;
/**
* 创建时间
*/
@ApiModelProperty("创建时间")
@Excel("创建时间")
private Date createTime;
/**
* 更新者
*/
@ApiModelProperty("更新时间")
@Excel("更新时间")
private Date updateTime;
/**
* 备注
*/
@ApiModelProperty("备注")
@Excel("备注")
private String remark;
public static SimplePortalVo toPortalVo(Portal portal) {
SimplePortalVo portalVo = SimplePortalVo.builder()
.portalId(String.valueOf(portal.getPortalId()))
.portalName(portal.getPortalName())
.anonymity(portal.getAnonymity())
.type(portal.getType())
.path(portal.getPath())
.state(portal.getState())
.createTime(portal.getCreateTime())
.updateTime(portal.getUpdateTime())
.remark(portal.getRemark())
.build();
portalVo.setCreateTime(portal.getCreateTime());
portalVo.setUpdateTime(portal.getUpdateTime());
if (!ObjectUtils.isEmpty(portal.getQueryId())) {
portalVo.setQueryId(String.valueOf(portal.getQueryId()));
}
if (!ObjectUtils.isEmpty(portal.getAdapterId())) {
portalVo.setAdapterId(String.valueOf(portal.getAdapterId()));
}
return portalVo;
}
}

View File

@@ -0,0 +1,23 @@
package cn.fateverse.query.enums;
/**
* @author Clay
* @date 2024/4/15 11:23
*/
public enum PortalEnum {
LOCAL("local"),
EXTERNAL("external")
;
private final String type;
PortalEnum(String type) {
this.type = type;
}
public String getType() {
return type;
}
}

View File

@@ -27,6 +27,9 @@ public class JavaScriptEngineExecuteHandler implements EngineExecuteHandler {
@Override
public Boolean preconditioning(DataAdapter dataAdapter) {
if (DataAdapterType.JAVA_SCRIPT.equals(dataAdapter.getType())){
return Boolean.TRUE;
}
return Boolean.FALSE;
}
}

View File

@@ -29,6 +29,9 @@ public interface DataAdapterMapper {
*/
List<DataAdapter> selectList(DataAdapterQuery query);
List<DataAdapter> selectListByIds(List<Long> adapterIds);
/**
* 新增数据源适配器
*

View File

@@ -0,0 +1,32 @@
package cn.fateverse.query.mapper;
import cn.fateverse.query.entity.Portal;
import cn.fateverse.query.entity.query.PortalQuery;
import java.util.List;
/**
* 接口管理表
*
* @author Clay
* @date 2024/4/15 10:32
*/
public interface PortalMapper {
/**
* 查询接口管理表
*
* @param portalId 接口管理表Id
* @return 接口管理表
*/
Portal selectById(Long portalId);
/**
* 查询接口管理表列表
*
* @param query 接口管理表查询
* @return 接口管理表集合
*/
List<Portal> selectList(PortalQuery query);
}

View File

@@ -0,0 +1,20 @@
package cn.fateverse.query.mapper;
import cn.fateverse.query.entity.PortalMapping;
import java.util.List;
/**
* @author Clay
* @date 2024/4/15 15:20
*/
public interface PortalMappingMapper {
List<PortalMapping> selectByPortalId(Long portalId);
Integer insertBatch(List<PortalMapping> list);
Integer deleteByPortalId(Long portalId);
}

View File

@@ -29,6 +29,9 @@ public interface UniQueryMapper {
*/
UniQuery selectSampleById(Long id);
List<UniQuery> selectListByIds(List<Long> queryIds);
/**
* 查询万能查询列表
*
@@ -69,4 +72,5 @@ public interface UniQueryMapper {
*/
int deleteBatchByIdList(List<Long> idList);
}

View File

@@ -1,5 +1,6 @@
package cn.fateverse.query.service;
import cn.fateverse.common.decrypt.entity.EncryptOption;
import cn.fateverse.query.entity.dto.DataAdapterDto;
import cn.fateverse.query.entity.vo.DataAdapterVo;
import cn.fateverse.query.entity.query.DataAdapterQuery;
@@ -37,7 +38,7 @@ public interface DataAdapterService {
*
* @return 选项集合
*/
List<Option> searchOptionList();
List<EncryptOption> searchOptionList();
/**
* 导出数据源适配器列表

View File

@@ -0,0 +1,21 @@
package cn.fateverse.query.service;
import cn.fateverse.common.core.result.page.TableDataInfo;
import cn.fateverse.query.entity.query.PortalQuery;
import cn.fateverse.query.entity.vo.PortalVo;
import cn.fateverse.query.entity.vo.SimplePortalVo;
/**
* @author Clay
* @date 2024/4/15 10:26
*/
public interface PortalService {
PortalVo searchById(Long portalId);
TableDataInfo<SimplePortalVo> searchList(PortalQuery query);
}

View File

@@ -0,0 +1,8 @@
package cn.fateverse.query.service;
/**
* @author Clay
* @date 2024/4/16 16:17
*/
public interface QueryToolService {
}

View File

@@ -19,7 +19,7 @@ import cn.fateverse.query.mapper.UniColumnMapper;
import cn.fateverse.query.mapper.UniConMapper;
import cn.fateverse.query.mapper.UniQueryMapper;
import cn.fateverse.query.service.impl.SqlSearchServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
//import io.seata.spring.annotation.GlobalTransactional;
import org.apache.dubbo.config.annotation.DubboReference;
import java.util.ArrayList;
@@ -115,7 +115,7 @@ public class SearchService {
*
* @param queryId 自定义查询id
*/
@GlobalTransactional
// @GlobalTransactional
public void cancel(Long queryId) {
UniQuery sample = uniQueryMapper.selectSampleById(queryId);
if (!sample.getPublish()) {

View File

@@ -1,5 +1,6 @@
package cn.fateverse.query.service.impl;
import cn.fateverse.common.decrypt.entity.EncryptOption;
import cn.fateverse.query.entity.DataAdapter;
import cn.fateverse.query.entity.dto.DataAdapterDto;
import cn.fateverse.query.entity.dto.SearchInfo;
@@ -53,11 +54,11 @@ public class DataAdapterServiceImpl implements DataAdapterService {
}
@Override
public List<Option> searchOptionList() {
public List<EncryptOption> searchOptionList() {
DataAdapterQuery query = new DataAdapterQuery();
List<DataAdapter> list = dataAdapterMapper.selectList(query);
return list.stream().map(item -> Option.builder()
.value(item.getAdapterId())
return list.stream().map(item -> EncryptOption.builder()
.value(String.valueOf(item.getAdapterId()))
.label(item.getAdapterName())
.build()).collect(Collectors.toList());
}

View File

@@ -0,0 +1,97 @@
package cn.fateverse.query.service.impl;
import cn.fateverse.common.core.result.page.TableDataInfo;
import cn.fateverse.common.mybatis.utils.PageUtils;
import cn.fateverse.query.entity.DataAdapter;
import cn.fateverse.query.entity.Portal;
import cn.fateverse.query.entity.UniQuery;
import cn.fateverse.query.entity.query.PortalQuery;
import cn.fateverse.query.entity.vo.PortalVo;
import cn.fateverse.query.entity.vo.SimplePortalVo;
import cn.fateverse.query.mapper.DataAdapterMapper;
import cn.fateverse.query.mapper.PortalMapper;
import cn.fateverse.query.mapper.UniQueryMapper;
import cn.fateverse.query.service.PortalService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Clay
* @date 2024/4/15 10:31
*/
@Slf4j
@Service
public class PortalServiceImpl implements PortalService {
private final PortalMapper portalMapper;
private final UniQueryMapper queryMapper;
private final DataAdapterMapper adapterMapper;
public PortalServiceImpl(PortalMapper portalMapper,
UniQueryMapper queryMapper,
DataAdapterMapper adapterMapper) {
this.portalMapper = portalMapper;
this.queryMapper = queryMapper;
this.adapterMapper = adapterMapper;
}
@Override
public PortalVo searchById(Long portalId) {
Portal portal = portalMapper.selectById(portalId);
PortalVo vo = PortalVo.toPortalVo(portal);
// return PortalVo.toPortalVo(portal);
return null;
}
@Override
public TableDataInfo<SimplePortalVo> searchList(PortalQuery query) {
PageUtils.startPage();
List<Portal> list = portalMapper.selectList(query);
if (ObjectUtils.isEmpty(list)) {
return PageUtils.convertDataTable(null, 0L);
}
List<Long> queryIds = new ArrayList<>();
List<Long> adapterIds = new ArrayList<>();
list.forEach(portal -> {
if (!ObjectUtils.isEmpty(portal.getQueryId())) {
queryIds.add(portal.getQueryId());
}
if (!ObjectUtils.isEmpty(portal.getAdapterId())) {
adapterIds.add(portal.getAdapterId());
}
});
Map<Long, UniQuery> queryMap = new HashMap<>();
if (!ObjectUtils.isEmpty(queryIds)) {
List<UniQuery> queryList = queryMapper.selectListByIds(queryIds);
for (UniQuery uniQuery : queryList) {
queryMap.put(uniQuery.getId(), uniQuery);
}
}
Map<Long, String> adapterMap = new HashMap<>();
if (!ObjectUtils.isEmpty(adapterIds)) {
List<DataAdapter> adapterList = adapterMapper.selectListByIds(adapterIds);
for (DataAdapter adapter : adapterList) {
adapterMap.put(adapter.getAdapterId(), adapter.getAdapterName());
}
}
return PageUtils.convertDataTable(list, portal -> {
SimplePortalVo simplePortalVo = SimplePortalVo.toPortalVo(portal);
UniQuery uniQuery = queryMap.getOrDefault(portal.getQueryId(), null);
if (!ObjectUtils.isEmpty(uniQuery)) {
simplePortalVo.setQueryName(uniQuery.getUqName());
simplePortalVo.setQueryType(uniQuery.getType());
}
simplePortalVo.setAdapterName(adapterMap.getOrDefault(portal.getAdapterId(), null));
return simplePortalVo;
});
}
}

View File

@@ -0,0 +1,29 @@
package cn.fateverse.query.service.impl;
import cn.fateverse.query.mapper.UniColumnMapper;
import cn.fateverse.query.mapper.UniConMapper;
import cn.fateverse.query.service.QueryToolService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* @author Clay
* @date 2024/4/16 16:18
*/
@Slf4j
@Service
public class QueryToolServiceImpl implements QueryToolService {
private final UniConMapper uniConMapper;
private final UniColumnMapper uniColumnMapper;
public QueryToolServiceImpl(UniConMapper uniConMapper,
UniColumnMapper uniColumnMapper) {
this.uniConMapper = uniConMapper;
this.uniColumnMapper = uniColumnMapper;
}
}

View File

@@ -19,7 +19,7 @@ import cn.fateverse.query.service.DynamicDataSearchService;
import cn.fateverse.query.service.DynamicDataSourceTableService;
import cn.fateverse.query.service.SearchService;
import cn.fateverse.query.service.SqlSearchService;
import io.seata.spring.annotation.GlobalTransactional;
//import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -121,7 +121,7 @@ public class SqlSearchServiceImpl extends SearchService implements SqlSearchServ
}
@Override
@GlobalTransactional
// @GlobalTransactional
public void publish(SqlDto sqlDto) {
UniQuery query = uniQueryMapper.selectSampleById(sqlDto.getLongQueryId());
if (query.getPublish()) {

View File

@@ -14,7 +14,7 @@ import cn.fateverse.query.entity.dto.TopoDto;
import cn.fateverse.query.entity.dto.UniConDto;
import cn.fateverse.query.entity.topology.TopologyBo;
import com.alibaba.fastjson2.JSON;
import io.seata.spring.annotation.GlobalTransactional;
//import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -131,7 +131,7 @@ public class TopologySearchServiceImpl extends SearchService implements Topology
}
@Override
@GlobalTransactional
// @GlobalTransactional
public void publish(TopoDto topo) {
UniQuery query = uniQueryMapper.selectSampleById(topo.getLongQueryId());
if (query.getPublish()) {

View File

@@ -38,6 +38,14 @@
where adapter_id = #{adapterId}
</select>
<select id="selectListByIds" resultType="cn.fateverse.query.entity.DataAdapter">
<include refid="selectDataAdapterVo"/>
where adapter_id in
<foreach collection="list" item="adapterId" open="(" close=")" separator=",">
#{adapterId}
</foreach>
</select>
<insert id="insert" >
insert into data_adapter
<trim prefix="(" suffix=")" suffixOverrides=",">

View File

@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.fateverse.query.mapper.PortalMapper">
<sql id="selectVo">
select portal_id,
query_id,
adapter_id,
portal_name,
anonymity,
type,
path,
header,
params,
body,
url,
api_header,
api_params,
api_body,
state,
create_by,
create_time,
update_by,
update_time,
remark
from portal
</sql>
<sql id="selectSimpleVo">
select portal_id,
query_id,
adapter_id,
portal_name,
anonymity,
type,
path,
url,
state,
create_time,
update_time,
remark
from portal
</sql>
<select id="selectById" resultType="cn.fateverse.query.entity.Portal">
<include refid="selectVo"/>
where portal_id = #{portalId}
</select>
<select id="selectList" resultType="cn.fateverse.query.entity.Portal">
<include refid="selectSimpleVo"/>
<where>
<if test="portalName != null and portalName != ''"> and portal_name like concat('%', #{portalName}, '%')</if>
<if test="anonymity != null "> and anonymity = #{anonymity}</if>
<if test="type != null"> and type = #{type}</if>
<if test="path != null and path != ''"> and path like concat('%', #{path}, '%')</if>
</where>
</select>
</mapper>

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.fateverse.query.mapper.PortalMappingMapper">
<select id="selectByPortalId" resultType="cn.fateverse.query.entity.PortalMapping">
select mapping_id, portal_id, mapping_key, data_type, mapping_value
from portal_mapping
where portal_id = #{portalId}
</select>
<insert id="insertBatch">
insert into portal_mapping (portal_id, mapping_key, data_type, mapping_value)
values
<foreach collection="list" item="item" separator=",">
(#{item.portalId}, #{item.mappingKey}, #{item.dataType}, #{item.mappingValue})
</foreach>
</insert>
<delete id="deleteByPortalId">
delete
from portal_mapping
where portal_id = #{portalId}
</delete>
</mapper>

View File

@@ -52,6 +52,15 @@
where id = #{id}
</select>
<select id="selectListByIds" resultType="cn.fateverse.query.entity.UniQuery">
select id, data_source_id, uq_name, publish, single, preview, type, create_by, create_time, update_by, update_time
from uni_query
where id in
<foreach collection="list" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</select>
<insert id="insert" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
insert into uni_query
<trim prefix="(" suffix=")" suffixOverrides=",">

View File

@@ -0,0 +1,14 @@
package cn.fateverse.query;
import java.util.*;
import java.util.stream.*;
public class DataAdapter {
public static Object execute(List<Map<String, Object>> data) {
for (Map<String, Object> objectMap : data) {
objectMap.remove("oper_location");
}
return data;
}
}

View File

@@ -23,6 +23,7 @@
<modules>
<module>custom-query-biz</module>
<module>custom-query-submter</module>
<module>custom-query-api</module>
</modules>
</project>

View File

@@ -1,6 +1,6 @@
# Tomcat
server:
port: 8001
port: 8000
swagger:
enabled: true