feat: 接口管理新增完成

This commit is contained in:
clay
2024-04-18 23:29:47 +08:00
parent 7f8ceb3e25
commit ab8e2f7b87
39 changed files with 645 additions and 223 deletions

View File

@@ -228,4 +228,24 @@ public class JavaCodeEngine {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
/**
* 删除类
* @param className 删除类
* @return 删除结果
*/
public Boolean remove(String className) {
return SegmentLock.lock(className, () -> {
classCache.remove(className);
File javaFile = new File(CLASS_PATH + className + JAVA_SUFFIX);
if (javaFile.exists()) {
javaFile.delete();
}
File classFile = new File(CLASS_PATH + className + CLASS_SUFFIX);
if (classFile.exists()) {
classFile.delete();
}
return true;
});
}
} }

View File

@@ -9,4 +9,6 @@ public class QueryConstant {
public static final String PERMISSIONS_KEY = "custom:query:online:"; public static final String PERMISSIONS_KEY = "custom:query:online:";
public static final String PORTAL_KEY = "custom:query:portal:";
} }

View File

@@ -10,7 +10,6 @@ import cn.fateverse.query.entity.query.DataAdapterQuery;
import cn.fateverse.query.entity.vo.DataAdapterVo; import cn.fateverse.query.entity.vo.DataAdapterVo;
import cn.fateverse.query.service.DataAdapterService; import cn.fateverse.query.service.DataAdapterService;
import cn.fateverse.common.core.result.Result; import cn.fateverse.common.core.result.Result;
import cn.fateverse.common.core.entity.Option;
import cn.fateverse.common.core.result.page.TableDataInfo; import cn.fateverse.common.core.result.page.TableDataInfo;
import cn.fateverse.common.core.utils.ObjectUtils; import cn.fateverse.common.core.utils.ObjectUtils;
import cn.fateverse.common.log.annotation.Log; import cn.fateverse.common.log.annotation.Log;

View File

@@ -5,6 +5,7 @@ import cn.fateverse.common.core.result.page.TableDataInfo;
import cn.fateverse.common.core.utils.ObjectUtils; import cn.fateverse.common.core.utils.ObjectUtils;
import cn.fateverse.common.decrypt.annotation.Encrypt; import cn.fateverse.common.decrypt.annotation.Encrypt;
import cn.fateverse.common.decrypt.annotation.EncryptField; import cn.fateverse.common.decrypt.annotation.EncryptField;
import cn.fateverse.query.entity.dto.PortalDto;
import cn.fateverse.query.entity.query.PortalQuery; import cn.fateverse.query.entity.query.PortalQuery;
import cn.fateverse.query.entity.vo.PortalVo; import cn.fateverse.query.entity.vo.PortalVo;
import cn.fateverse.query.entity.vo.SimplePortalVo; import cn.fateverse.query.entity.vo.SimplePortalVo;
@@ -12,10 +13,8 @@ import cn.fateverse.query.service.PortalService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/** /**
* 接口管理表(portal 传送门 接口作为入口 传送到其他类型) Controller * 接口管理表(portal 传送门 接口作为入口 传送到其他类型) Controller
@@ -56,5 +55,22 @@ public class PortalController {
return Result.ok(dataInfo); return Result.ok(dataInfo);
} }
@ApiOperation("新增接口")
@PostMapping
@PreAuthorize("@ss.hasPermission('query:portal:add')")
public Result<Void> add(@RequestBody @Validated PortalDto portalDto) {
portalService.save(portalDto);
return Result.ok();
}
@ApiOperation("修改接口")
@PutMapping
@PreAuthorize("@ss.hasPermission('query:portal:edit')")
public Result<Void> edit(@RequestBody @Validated PortalDto portalDto) {
ObjectUtils.checkPk(portalDto.getPortalId());
portalService.edit(portalDto);
return Result.ok();
}
} }

View File

@@ -1,17 +1,25 @@
package cn.fateverse.query.controller; package cn.fateverse.query.controller;
import cn.fateverse.common.core.entity.Option;
import cn.fateverse.common.core.result.Result;
import cn.fateverse.query.entity.vo.UniConVo;
import cn.fateverse.query.service.QueryToolService; import cn.fateverse.query.service.QueryToolService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/** /**
* @author Clay * @author Clay
* @date 2024/4/16 16:10 * @date 2024/4/16 16:10
*/ */
@Api(tags = "自定义查询工具接口管理") @Api(tags = "自定义查询工具接口管理")
@RestController @RestController
@RequestMapping("/query/tool") @RequestMapping("/tool")
public class QueryToolController { public class QueryToolController {
@@ -22,9 +30,26 @@ public class QueryToolController {
this.queryToolService = queryToolService; this.queryToolService = queryToolService;
} }
@ApiOperation("根据查询类型获取自定义查询")
@GetMapping("/option/{type}")
public Result<List<Option>> option(@PathVariable Integer type) {
if (type == null) {
return Result.error("查询类型不能为空");
}
List<Option> optionList = queryToolService.searchQueryOption(type);
return Result.ok(optionList);
}
@ApiOperation("根据自定义查询id获取查询条件")
@GetMapping("/con/{queryId}")
public Result<List<Option>> con(@PathVariable Long queryId) {
if (queryId == null) {
return Result.error("查询条件不能为空");
}
List<Option> optionList = queryToolService.searchQueryCon(queryId);
return Result.ok(optionList);
}
} }

View File

@@ -85,7 +85,7 @@ public class SqlSearchController {
@Encrypt @Encrypt
@PostMapping("/preview/data") @PostMapping("/preview/data")
public Result<TableDataInfo<Map<String, Object>>> previewData(@RequestBody @Validated SearchInfo searchInfo) { public Result<TableDataInfo<Map<String, Object>>> previewData(@RequestBody @Validated SearchInfo searchInfo) {
TableDataInfo<Map<String, Object>> tableDataInfo = sqlSearchService.previewData(searchInfo.getList(), searchInfo.getQueryId()); TableDataInfo<Map<String, Object>> tableDataInfo = sqlSearchService.previewData(searchInfo.getList(), searchInfo.getLongQueryId());
return Result.ok(tableDataInfo); return Result.ok(tableDataInfo);
} }

View File

@@ -1,9 +1,7 @@
package cn.fateverse.query.controller; package cn.fateverse.query.controller;
import cn.fateverse.common.security.annotation.Anonymity; import cn.fateverse.common.security.annotation.Anonymity;
import cn.fateverse.common.security.configure.properties.PermitAllUrlProperties; import cn.fateverse.query.portal.config.HandlerMethodService;
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.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
@@ -11,7 +9,6 @@ import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
/** /**
* @author Clay * @author Clay
@@ -22,19 +19,19 @@ import java.util.ArrayList;
public class TestController { public class TestController {
@Resource @Resource
private HandlerMethodConfiguration configuration; private HandlerMethodService methodService;
@Anonymity @Anonymity
@GetMapping("/1") @GetMapping("/1")
public String test1() { public String test1() {
configuration.registerMapping("/anonymity/mapping", RequestMethod.GET); methodService.registerMapping("/anonymity/mapping", RequestMethod.GET);
return "1"; return "1";
} }
@Anonymity @Anonymity
@GetMapping("/2") @GetMapping("/2")
public String test2() { public String test2() {
configuration.unregisterMapping("/anonymity/mapping", RequestMethod.GET); methodService.unregisterMapping("/anonymity/mapping", RequestMethod.GET);
return "2"; return "2";
} }

View File

@@ -78,7 +78,7 @@ public class TopologySearchController {
@Encrypt @Encrypt
@PostMapping("/preview/data") @PostMapping("/preview/data")
public Result<TableDataInfo<Map<String, Object>>> previewData(@RequestBody @Validated SearchInfo searchInfo) { public Result<TableDataInfo<Map<String, Object>>> previewData(@RequestBody @Validated SearchInfo searchInfo) {
TableDataInfo<Map<String, Object>> tableDataInfo = topologySearchService.previewData(searchInfo.getList(), searchInfo.getQueryId()); TableDataInfo<Map<String, Object>> tableDataInfo = topologySearchService.previewData(searchInfo.getList(), searchInfo.getLongQueryId());
return Result.ok(tableDataInfo); return Result.ok(tableDataInfo);
} }

View File

@@ -2,6 +2,7 @@ package cn.fateverse.query.entity;
import cn.fateverse.common.core.annotaion.EnableAutoField; import cn.fateverse.common.core.annotaion.EnableAutoField;
import cn.fateverse.common.core.entity.BaseEntity; import cn.fateverse.common.core.entity.BaseEntity;
import cn.fateverse.common.core.exception.CustomException;
import cn.fateverse.query.enums.DataAdapterSource; import cn.fateverse.query.enums.DataAdapterSource;
import cn.fateverse.query.enums.DataAdapterType; import cn.fateverse.query.enums.DataAdapterType;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
@@ -28,11 +29,6 @@ public class DataAdapter extends BaseEntity {
*/ */
private Long adapterId; private Long adapterId;
/**
* 数据源id,数据源可以是 topo自定义查询,sql自定义查询,api请求
*/
private Long dataSourceId;
/** /**
* 适配器名称 * 适配器名称
*/ */
@@ -43,6 +39,11 @@ public class DataAdapter extends BaseEntity {
*/ */
private DataAdapterType type; private DataAdapterType type;
/**
* 是否通用
*/
private Boolean common;
/** /**
* 适配器代码 * 适配器代码
*/ */
@@ -53,14 +54,31 @@ public class DataAdapter extends BaseEntity {
*/ */
private String executeCode; private String executeCode;
/**
* 适配器来源,数据源 自定义创建 自定义查询 sql 自定义查询 echart编辑器
*/
private DataAdapterSource source;
/** /**
* 模拟数据 strng类型的json字符串 * 模拟数据 strng类型的json字符串
*/ */
private String mockData; private String mockData;
public void init() {
if (type == null) {
throw new CustomException("数据适配器类型为空");
}
if (DataAdapterType.JAVA.equals(type)) {
//Java代码初始化
this.code = "\n" +
"import java.util.*;\n" +
"import java.util.stream.*;\n" +
"\n" +
"public class DataAdapter {\n" +
"\n" +
" public static Object execute(List<Map<String, Object>> data) {\n" +
" return data;\n" +
" }\n" +
"}\n";
} else if (DataAdapterType.JAVA_SCRIPT.equals(type)) {
//JavaScript代码初始化
}
}
} }

View File

@@ -1,4 +1,4 @@
package cn.fateverse.query.entity; package cn.fateverse.query.entity;
import cn.fateverse.common.core.annotaion.EnableAutoField; import cn.fateverse.common.core.annotaion.EnableAutoField;
import cn.fateverse.common.core.entity.BaseEntity; import cn.fateverse.common.core.entity.BaseEntity;
@@ -7,6 +7,7 @@ import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.springframework.web.bind.annotation.RequestMethod;
/** /**
@@ -20,7 +21,7 @@ import lombok.NoArgsConstructor;
@EnableAutoField @EnableAutoField
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
public class Portal extends BaseEntity{ public class Portal extends BaseEntity {
/** /**
* 主键id * 主键id
@@ -52,49 +53,28 @@ public class Portal extends BaseEntity{
*/ */
private PortalEnum type; private PortalEnum type;
/**
* 请求类型
*/
private String requestMethod;
private Boolean createDataAdapter;
/** /**
* 系统暴露地址 * 系统暴露地址
*/ */
private String path; private String path;
/**
* 请求头
*/
private String header;
/**
* 请求参数
*/
private String params;
/**
* 请求体
*/
private String body;
/** /**
* 第三方接口地址 * 第三方接口地址
*/ */
private String url; private String url;
/**
* 第三方接口请求头
*/
private String apiHeader;
/**
* 第三方接口请求参数
*/
private String apiParams;
/**
* 第三方接口请求体
*/
private String apiBody;
/** /**
* 状态 * 状态
*/ */
private Long state; private Integer state;
} }

View File

@@ -4,6 +4,7 @@ import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.springframework.util.ObjectUtils;
/** /**
@@ -36,11 +37,20 @@ public class PortalMapping {
/** /**
* 数据类型, 0 param, 1 header, 2 body * 数据类型, 0 param, 1 header, 2 body
*/ */
private Integer dataType; private Integer mappingType;
/** /**
* 映射值 自定义查询映射值为查询条件的id 第三方接口则为接口查询的key * 映射值 自定义查询映射值为查询条件的id 第三方接口则为接口查询的key
*/ */
private String mappingValue; private String mappingValue;
public Boolean check() {
if (ObjectUtils.isEmpty(mappingKey)
|| ObjectUtils.isEmpty(mappingValue)
|| ObjectUtils.isEmpty(mappingType)){
return Boolean.FALSE;
}
return Boolean.TRUE;
}
} }

View File

@@ -41,12 +41,6 @@ public class DataAdapterDto {
@ApiModelProperty("适配器代码") @ApiModelProperty("适配器代码")
private String code; private String code;
/**
* 适配器来源,数据源 自定义创建 自定义查询 sql 自定义查询 echart编辑器
*/
@ApiModelProperty("适配器来源,数据源 自定义创建 自定义查询 sql 自定义查询 echart编辑器")
private DataAdapterSource source;
/** /**
* 模拟数据 strng类型的json字符串 * 模拟数据 strng类型的json字符串
*/ */
@@ -59,7 +53,6 @@ public class DataAdapterDto {
.adapterName(adapterName) .adapterName(adapterName)
.type(type) .type(type)
.code(code) .code(code)
.source(source)
.mockData(mockData) .mockData(mockData)
.build(); .build();
} }

View File

@@ -1,10 +1,17 @@
package cn.fateverse.query.entity.dto; package cn.fateverse.query.entity.dto;
import cn.fateverse.common.core.utils.ObjectUtils;
import cn.fateverse.query.entity.Portal; import cn.fateverse.query.entity.Portal;
import cn.fateverse.query.entity.PortalMapping;
import cn.fateverse.query.enums.PortalEnum; import cn.fateverse.query.enums.PortalEnum;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;
/** /**
* 接口管理表(portal 传送门 接口作为入口 传送到其他类型)对象 portal * 接口管理表(portal 传送门 接口作为入口 传送到其他类型)对象 portal
@@ -31,80 +38,57 @@ public class PortalDto {
/** /**
* 数据适配器id * 数据适配器id
*/ */
@ApiModelProperty("数据适配器id") @ApiModelProperty("数据适配器id 为-1 代表需要创建数据适配器")
private Long adapterId; private Long adapterId;
/** /**
* 接口名称 * 接口名称
*/ */
@ApiModelProperty("接口名称") @ApiModelProperty("接口名称")
@NotBlank(message = "接口名称不能为空")
private String portalName; private String portalName;
/** /**
* 是否匿名 * 是否匿名
*/ */
@ApiModelProperty("是否匿名") @ApiModelProperty("是否匿名")
@NotNull(message = "是否匿名不能为空")
private Boolean anonymity; private Boolean anonymity;
/** /**
* 接口类型 * 接口类型
*/ */
@ApiModelProperty("接口类型") @ApiModelProperty("接口类型")
@NotNull(message = "接口类型不能为空")
private PortalEnum type; private PortalEnum type;
@ApiModelProperty("请求类型")
@NotBlank(message = "请求类型不能为空")
private String requestMethod;
@NotNull(message = "是否创建数据适配器不能为空!")
private Boolean createDataAdapter;
/** /**
* 系统暴露地址 * 系统暴露地址
*/ */
@ApiModelProperty("系统暴露地址") @ApiModelProperty("系统暴露地址")
@NotBlank(message = "系统暴露地址不能为空")
private String path; private String path;
/**
* 请求头
*/
@ApiModelProperty("请求头")
private String header;
/**
* 请求参数
*/
@ApiModelProperty("请求参数")
private String params;
/**
* 请求体
*/
@ApiModelProperty("请求体")
private String body;
/** /**
* 第三方接口地址 * 第三方接口地址
*/ */
@ApiModelProperty("第三方接口地址") @ApiModelProperty("第三方接口地址")
private String url; private String url;
/**
* 第三方接口请求头
*/
@ApiModelProperty("第三方接口请求头")
private String apiHeader;
/**
* 第三方接口请求参数
*/
@ApiModelProperty("第三方接口请求参数")
private String apiParams;
/**
* 第三方接口请求体
*/
@ApiModelProperty("第三方接口请求体")
private String apiBody;
/** /**
* 状态 * 状态
*/ */
@ApiModelProperty("状态") @ApiModelProperty("状态")
private Long state; private Integer state;
/** /**
* 备注 * 备注
@@ -113,24 +97,42 @@ public class PortalDto {
private String remark; private String remark;
@ApiModelProperty("数据适配器信息")
private DataAdapterDto dataAdapter;
@ApiModelProperty("映射关系")
private List<PortalMapping> mappings;
public Portal toPortal() { public Portal toPortal() {
Portal portal = Portal.builder() Portal portal = Portal.builder()
.queryId(queryId) .queryId(queryId)
.adapterId(adapterId) .adapterId(adapterId)
.portalName(portalName) .portalName(portalName)
.anonymity(anonymity) .anonymity(anonymity)
.createDataAdapter(createDataAdapter)
.requestMethod(requestMethod)
.type(type) .type(type)
.path(path) .path(path)
.header(header)
.params(params)
.body(body)
.url(url) .url(url)
.apiHeader(apiHeader)
.apiParams(apiParams)
.apiBody(apiBody)
.state(state) .state(state)
.build(); .build();
portal.setPortalId(Long.valueOf(portalId)); try {
RequestMethod.valueOf(requestMethod);
}catch (Exception e){
throw new RuntimeException("请求类型不支持!");
}
if (!ObjectUtils.isEmpty(portalId)) {
portal.setPortalId(Long.valueOf(portalId));
}
if (!ObjectUtils.isEmpty(mappings)) {
for (PortalMapping mapping : mappings) {
if (!mapping.check()) {
throw new RuntimeException("映射关系不完全,请检查映射关系");
}
}
}
portal.setRemark(remark); portal.setRemark(remark);
return portal; return portal;
} }

View File

@@ -20,7 +20,7 @@ public class SearchInfo {
@EncryptField @EncryptField
private String queryId; private String queryId;
public Long getQueryId() { public Long getLongQueryId() {
return Long.parseLong(queryId); return Long.parseLong(queryId);
} }
} }

View File

@@ -1,6 +1,5 @@
package cn.fateverse.query.entity.query; package cn.fateverse.query.entity.query;
import cn.fateverse.query.enums.DataAdapterSource;
import cn.fateverse.query.enums.DataAdapterType; import cn.fateverse.query.enums.DataAdapterType;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
@@ -32,9 +31,7 @@ public class DataAdapterQuery {
@ApiModelProperty("数据适配器代码类型 Java or Js") @ApiModelProperty("数据适配器代码类型 Java or Js")
private DataAdapterType type; private DataAdapterType type;
/** @ApiModelProperty("是否通用")
* 适配器来源,数据源 自定义创建 自定义查询 sql 自定义查询 echarts编辑器 private Boolean common;
*/
@ApiModelProperty("适配器来源,数据源 自定义创建 自定义查询 sql 自定义查询 echarts编辑器")
private DataAdapterSource source;
} }

View File

@@ -55,13 +55,6 @@ public class DataAdapterVo {
@Excel("适配器代码") @Excel("适配器代码")
private String code; private String code;
/**
* 适配器来源,数据源 自定义创建 自定义查询 sql 自定义查询 echarts编辑器
*/
@ApiModelProperty("适配器来源,数据源 自定义创建 自定义查询 sql 自定义查询 echarts编辑器")
@Excel("适配器来源,数据源 自定义创建 自定义查询 sql 自定义查询 echarts编辑器")
private DataAdapterSource source;
/** /**
* 模拟数据 strng类型的json字符串 * 模拟数据 strng类型的json字符串
*/ */
@@ -75,7 +68,6 @@ public class DataAdapterVo {
.adapterName(dataAdapter.getAdapterName()) .adapterName(dataAdapter.getAdapterName())
.type(dataAdapter.getType()) .type(dataAdapter.getType())
.code(dataAdapter.getCode()) .code(dataAdapter.getCode())
.source(dataAdapter.getSource())
.mockData(dataAdapter.getMockData()) .mockData(dataAdapter.getMockData())
.build(); .build();
} }

View File

@@ -20,8 +20,11 @@ import java.util.List;
@ApiModel("接口详细管理表Vo") @ApiModel("接口详细管理表Vo")
public class PortalVo extends SimplePortalVo { public class PortalVo extends SimplePortalVo {
private List<PortalMapping> mappings; private Integer queryType;
private Boolean createDataAdapter;
private List<PortalMapping> mappings;
public static PortalVo toPortalVo(Portal portal) { public static PortalVo toPortalVo(Portal portal) {
return toPortalVo(portal, null); return toPortalVo(portal, null);

View File

@@ -99,7 +99,7 @@ public class SimplePortalVo {
*/ */
@ApiModelProperty("状态 0: 创建 1: 发布 2:内部使用(例如提供echarts单独使用)") @ApiModelProperty("状态 0: 创建 1: 发布 2:内部使用(例如提供echarts单独使用)")
@Excel("状态") @Excel("状态")
private Long state; private Integer state;
/** /**
* 创建时间 * 创建时间

View File

@@ -1,6 +1,7 @@
package cn.fateverse.query.handler.adapter; package cn.fateverse.query.handler.adapter;
import cn.fateverse.query.entity.DataAdapter; import cn.fateverse.query.entity.DataAdapter;
import cn.fateverse.query.entity.Portal;
/** /**
* @author Clay * @author Clay
@@ -12,16 +13,18 @@ public interface DataAdapterHandler {
* 模拟执行 * 模拟执行
* *
* @param dataAdapter 数据适配器信息 * @param dataAdapter 数据适配器信息
* @param portal
* @return 执行结果 * @return 执行结果
*/ */
Object mockExecute(DataAdapter dataAdapter, Object param); Object mockExecute(DataAdapter dataAdapter, Portal portal, Object param);
/** /**
* 真实执行 * 真实执行
* *
* @param dataAdapter 数据适配器信息 * @param dataAdapter 数据适配器信息
* @param portal
* @return 执行结果 * @return 执行结果
*/ */
Object execute(DataAdapter dataAdapter, Object param); Object execute(DataAdapter dataAdapter, Portal portal, Object param);
} }

View File

@@ -3,9 +3,10 @@ package cn.fateverse.query.handler.adapter.impl;
import cn.fateverse.common.core.exception.CustomException; import cn.fateverse.common.core.exception.CustomException;
import cn.fateverse.common.core.result.page.TableDataInfo; import cn.fateverse.common.core.result.page.TableDataInfo;
import cn.fateverse.query.entity.DataAdapter; import cn.fateverse.query.entity.DataAdapter;
import cn.fateverse.query.entity.Portal;
import cn.fateverse.query.entity.UniQuery; import cn.fateverse.query.entity.UniQuery;
import cn.fateverse.query.entity.dto.SearchInfo; import cn.fateverse.query.entity.dto.SearchInfo;
import cn.fateverse.query.enums.DataAdapterSource; import cn.fateverse.query.enums.PortalEnum;
import cn.fateverse.query.handler.adapter.DataAdapterHandler; import cn.fateverse.query.handler.adapter.DataAdapterHandler;
import cn.fateverse.query.handler.reader.EngineExecuteHandlerReader; import cn.fateverse.query.handler.reader.EngineExecuteHandlerReader;
import cn.fateverse.query.mapper.UniQueryMapper; import cn.fateverse.query.mapper.UniQueryMapper;
@@ -24,7 +25,7 @@ import java.util.Map;
*/ */
@Slf4j @Slf4j
@Service @Service
public class CustomQueryDataAdapterHandler implements DataAdapterHandler { public class LocalDataAdapterHandler implements DataAdapterHandler {
private final UniQueryMapper uniQueryMapper; private final UniQueryMapper uniQueryMapper;
@@ -33,9 +34,9 @@ public class CustomQueryDataAdapterHandler implements DataAdapterHandler {
private final DynamicDataSearchService dynamicDataSearchService; private final DynamicDataSearchService dynamicDataSearchService;
public CustomQueryDataAdapterHandler(UniQueryMapper uniQueryMapper, public LocalDataAdapterHandler(UniQueryMapper uniQueryMapper,
EngineExecuteHandlerReader handlerReader, EngineExecuteHandlerReader handlerReader,
DynamicDataSearchService dynamicDataSearchService) { DynamicDataSearchService dynamicDataSearchService) {
this.uniQueryMapper = uniQueryMapper; this.uniQueryMapper = uniQueryMapper;
this.handlerReader = handlerReader; this.handlerReader = handlerReader;
this.dynamicDataSearchService = dynamicDataSearchService; this.dynamicDataSearchService = dynamicDataSearchService;
@@ -43,8 +44,8 @@ public class CustomQueryDataAdapterHandler implements DataAdapterHandler {
@Override @Override
public Object mockExecute(DataAdapter dataAdapter, Object param) { public Object mockExecute(DataAdapter dataAdapter, Portal portal, Object param) {
if (!(dataAdapter.getSource() == DataAdapterSource.TOPO_QUERY || dataAdapter.getSource() == DataAdapterSource.SQL_QUERY)) { if (portal.getType() != PortalEnum.LOCAL) {
return null; return null;
} }
handlerReader.preconditioning(dataAdapter); handlerReader.preconditioning(dataAdapter);
@@ -55,7 +56,7 @@ public class CustomQueryDataAdapterHandler implements DataAdapterHandler {
throw new CustomException("数据类型不匹配"); throw new CustomException("数据类型不匹配");
} }
SearchInfo info = (SearchInfo) param; SearchInfo info = (SearchInfo) param;
UniQuery query = uniQueryMapper.selectSampleById(dataAdapter.getDataSourceId()); UniQuery query = uniQueryMapper.selectSampleById(portal.getQueryId());
if (null == query) { if (null == query) {
throw new CustomException("数据源为空!"); throw new CustomException("数据源为空!");
} }
@@ -66,8 +67,8 @@ public class CustomQueryDataAdapterHandler implements DataAdapterHandler {
@Override @Override
public Object execute(DataAdapter dataAdapter, Object param) { public Object execute(DataAdapter dataAdapter, Portal portal, Object param) {
if (!(dataAdapter.getSource() == DataAdapterSource.TOPO_QUERY || dataAdapter.getSource() == DataAdapterSource.SQL_QUERY)) { if (portal.getType() != PortalEnum.LOCAL) {
return null; return null;
} }
handlerReader.preconditioning(dataAdapter); handlerReader.preconditioning(dataAdapter);

View File

@@ -23,4 +23,10 @@ public interface EngineExecuteHandler {
Boolean preconditioning(DataAdapter dataAdapter); Boolean preconditioning(DataAdapter dataAdapter);
/**
* 删除数据适配器
* @param dataAdapter 数据适配器
* @return 删除结果
*/
Boolean remove(DataAdapter dataAdapter);
} }

View File

@@ -25,10 +25,6 @@ public class JavaEngineExecuteHandler implements EngineExecuteHandler {
private final JavaCodeEngine javaCodeEngine; private final JavaCodeEngine javaCodeEngine;
private final String IMPORT_CODE =
"import java.util.*;\n" +
"import java.util.stream.*;\n";
public JavaEngineExecuteHandler(JavaCodeEngine javaCodeEngine) { public JavaEngineExecuteHandler(JavaCodeEngine javaCodeEngine) {
this.javaCodeEngine = javaCodeEngine; this.javaCodeEngine = javaCodeEngine;
} }
@@ -55,11 +51,21 @@ public class JavaEngineExecuteHandler implements EngineExecuteHandler {
} }
String modifiedCode = modifiedCode(dataAdapter.getCode()); String modifiedCode = modifiedCode(dataAdapter.getCode());
String replacedCode = replacedClass(modifiedCode, getClassName(dataAdapter)); String replacedCode = replacedClass(modifiedCode, getClassName(dataAdapter));
String IMPORT_CODE = "import java.util.*;\n" +
"import java.util.stream.*;\n";
dataAdapter.setExecuteCode(IMPORT_CODE + replacedCode); dataAdapter.setExecuteCode(IMPORT_CODE + replacedCode);
return Boolean.TRUE; return Boolean.TRUE;
} }
@Override
public Boolean remove(DataAdapter dataAdapter) {
if (dataAdapter.getType() != DataAdapterType.JAVA) {
return Boolean.FALSE;
}
return javaCodeEngine.remove(getClassName(dataAdapter));
}
/** /**
* 替换类定义 * 替换类定义
* *

View File

@@ -19,7 +19,7 @@ public class JavaScriptEngineExecuteHandler implements EngineExecuteHandler {
@Override @Override
public Object execute(DataAdapter dataAdapter, Object data, boolean development) { public Object execute(DataAdapter dataAdapter, Object data, boolean development) {
if (!DataAdapterType.JAVA_SCRIPT.equals(dataAdapter.getType())){ if (!DataAdapterType.JAVA_SCRIPT.equals(dataAdapter.getType())) {
return null; return null;
} }
return JavaScriptEngine.executeScript(dataAdapter.getExecuteCode(), "execute", data); return JavaScriptEngine.executeScript(dataAdapter.getExecuteCode(), "execute", data);
@@ -27,9 +27,14 @@ public class JavaScriptEngineExecuteHandler implements EngineExecuteHandler {
@Override @Override
public Boolean preconditioning(DataAdapter dataAdapter) { public Boolean preconditioning(DataAdapter dataAdapter) {
if (DataAdapterType.JAVA_SCRIPT.equals(dataAdapter.getType())){ if (DataAdapterType.JAVA_SCRIPT.equals(dataAdapter.getType())) {
return Boolean.TRUE; return Boolean.TRUE;
} }
return Boolean.FALSE; return Boolean.FALSE;
} }
@Override
public Boolean remove(DataAdapter dataAdapter) {
return Boolean.FALSE;
}
} }

View File

@@ -3,6 +3,7 @@ package cn.fateverse.query.handler.reader;
import cn.fateverse.common.core.exception.CustomException; import cn.fateverse.common.core.exception.CustomException;
import cn.fateverse.query.entity.DataAdapter; import cn.fateverse.query.entity.DataAdapter;
import cn.fateverse.query.entity.Portal;
import cn.fateverse.query.handler.adapter.DataAdapterHandler; import cn.fateverse.query.handler.adapter.DataAdapterHandler;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -27,9 +28,9 @@ public class DataAdapterHandlerReader {
} }
public Object mockExecute(DataAdapter dataAdapter, Object params) { public Object mockExecute(DataAdapter dataAdapter, Portal portal, Object params) {
for (DataAdapterHandler dataAdapterHandler : handlerList) { for (DataAdapterHandler dataAdapterHandler : handlerList) {
Object result = dataAdapterHandler.mockExecute(dataAdapter, params); Object result = dataAdapterHandler.mockExecute(dataAdapter,portal , params);
if (result != null) { if (result != null) {
return result; return result;
} }
@@ -38,9 +39,9 @@ public class DataAdapterHandlerReader {
} }
public Object execute(DataAdapter dataAdapter, Object params) { public Object execute(DataAdapter dataAdapter,Portal portal, Object params) {
for (DataAdapterHandler dataAdapterHandler : handlerList) { for (DataAdapterHandler dataAdapterHandler : handlerList) {
Object result = dataAdapterHandler.execute(dataAdapter, params); Object result = dataAdapterHandler.execute(dataAdapter, portal, params);
if (result != null) { if (result != null) {
return result; return result;
} }

View File

@@ -61,4 +61,18 @@ public class EngineExecuteHandlerReader {
} }
public Boolean remove(DataAdapter dataAdapter) {
// 遍历引擎执行处理器列表
for (EngineExecuteHandler engineExecuteHandler : handlerList) {
// 执行数据适配器的处理方法
Boolean result = engineExecuteHandler.remove(dataAdapter);
if (result) {
return true;
}
}
// 若未找到匹配的数据适配器处理器则返回null
return false;
}
} }

View File

@@ -2,6 +2,8 @@ package cn.fateverse.query.mapper;
import cn.fateverse.query.entity.Portal; import cn.fateverse.query.entity.Portal;
import cn.fateverse.query.entity.query.PortalQuery; import cn.fateverse.query.entity.query.PortalQuery;
import org.apache.ibatis.annotations.Param;
import org.springframework.web.bind.annotation.RequestMethod;
import java.util.List; import java.util.List;
@@ -22,6 +24,15 @@ public interface PortalMapper {
*/ */
Portal selectById(Long portalId); Portal selectById(Long portalId);
/**
* 根据请求路径查询
*
* @param path 路径
* @return 查询结果
*/
Portal selectByPath(@Param("path") String path, @Param("requestMethod") String requestMethod);
/** /**
* 查询接口管理表列表 * 查询接口管理表列表
* *
@@ -29,4 +40,12 @@ public interface PortalMapper {
* @return 接口管理表集合 * @return 接口管理表集合
*/ */
List<Portal> selectList(PortalQuery query); List<Portal> selectList(PortalQuery query);
/**
* 新增接口
*
* @param portal 接口对象
* @return 更新数量
*/
int insert(Portal portal);
} }

View File

@@ -10,10 +10,28 @@ import java.util.List;
*/ */
public interface PortalMappingMapper { public interface PortalMappingMapper {
/**
* 根据portalId查询
*
* @param portalId 接口模块id
* @return 映射key
*/
List<PortalMapping> selectByPortalId(Long portalId); List<PortalMapping> selectByPortalId(Long portalId);
/**
* 批量插入
*
* @param list 映射关系
* @return 插入数量
*/
Integer insertBatch(List<PortalMapping> list); Integer insertBatch(List<PortalMapping> list);
/**
* 根据portalId删除
*
* @param portalId 接口模块id
* @return 删除数量
*/
Integer deleteByPortalId(Long portalId); Integer deleteByPortalId(Long portalId);

View File

@@ -1,5 +1,6 @@
package cn.fateverse.query.mapper; package cn.fateverse.query.mapper;
import cn.fateverse.common.core.entity.Option;
import cn.fateverse.query.entity.UniQuery; import cn.fateverse.query.entity.UniQuery;
import cn.fateverse.query.entity.query.UniQueryQuery; import cn.fateverse.query.entity.query.UniQueryQuery;
@@ -40,6 +41,7 @@ public interface UniQueryMapper {
*/ */
List<UniQuery> selectList(UniQueryQuery query); List<UniQuery> selectList(UniQueryQuery query);
/** /**
* 新增万能查询 * 新增万能查询
* *

View File

@@ -0,0 +1,83 @@
package cn.fateverse.query.portal;
import cn.fateverse.query.entity.DataAdapter;
import cn.fateverse.query.entity.Portal;
import cn.fateverse.query.entity.PortalMapping;
import cn.fateverse.query.entity.dto.SearchInfo;
import cn.fateverse.query.entity.dto.UniConDto;
import cn.fateverse.query.handler.reader.DataAdapterHandlerReader;
import cn.fateverse.query.mapper.DataAdapterMapper;
import cn.fateverse.query.mapper.PortalMapper;
import cn.fateverse.query.mapper.PortalMappingMapper;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
/**
* @author Clay
* @date 2024/4/18 21:42
*/
@Component
public class PortalDispatchServlet {
private final PortalMapper portalMapper;
private final DataAdapterMapper dataAdapterMapper;
private final PortalMappingMapper portalMappingMapper;
private final DataAdapterHandlerReader dataAdapterHandler;
public PortalDispatchServlet(PortalMapper portalMapper,
DataAdapterMapper dataAdapterMapper,
PortalMappingMapper portalMappingMapper,
DataAdapterHandlerReader dataAdapterHandler) {
this.portalMapper = portalMapper;
this.dataAdapterMapper = dataAdapterMapper;
this.portalMappingMapper = portalMappingMapper;
this.dataAdapterHandler = dataAdapterHandler;
}
private void doDispatch(HttpServletRequest request, HttpServletResponse response) {
String path = request.getServletPath();
String method = request.getMethod();
Portal portal = portalMapper.selectByPath(path, method);
if (portal == null) {
response.setStatus(HttpStatus.NOT_FOUND.value());
return;
}
List<PortalMapping> portalMappings = portalMappingMapper.selectByPortalId(portal.getPortalId());
SearchInfo searchInfo = new SearchInfo();
List<UniConDto> uniConList = new ArrayList<>();
for (PortalMapping portalMapping : portalMappings) {
UniConDto uniCon = new UniConDto();
String mappingValue = portalMapping.getMappingValue();
uniCon.setUcId(Long.parseLong(mappingValue));
if (portalMapping.getMappingType() == 0) {
uniCon.setQuery(request.getParameter(mappingValue));
} else if (portalMapping.getMappingType() == 1) {
uniCon.setQuery(request.getHeaders(mappingValue));
} else {
uniCon.setQuery(request.getParameter(mappingValue));
}
uniConList.add(uniCon);
}
searchInfo.setList(uniConList);
DataAdapter dataAdapter = dataAdapterMapper.selectById(portal.getAdapterId());
if (portal.getState() == 1 || portal.getState() == 2) {
Object execute = dataAdapterHandler.execute(dataAdapter, portal, searchInfo);
} else {
Object mockExecute = dataAdapterHandler.mockExecute(dataAdapter, portal, searchInfo);
}
}
}

View File

@@ -1,12 +1,12 @@
package cn.fateverse.query.config; package cn.fateverse.query.portal.config;
import cn.fateverse.common.core.exception.CustomException; import cn.fateverse.common.core.exception.CustomException;
import cn.fateverse.query.controller.TestController; import cn.fateverse.query.portal.PortalDispatchServlet;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.method.HandlerMethod; import org.springframework.web.method.HandlerMethod;
@@ -21,8 +21,8 @@ import java.util.Map;
* @date 2024/4/12 16:56 * @date 2024/4/12 16:56
*/ */
@Slf4j @Slf4j
@Configuration @Component
public class HandlerMethodConfiguration implements ApplicationContextAware { public class HandlerMethodService implements ApplicationContextAware {
public static final String CUSTOM_INTERFACE = "customInterface:"; public static final String CUSTOM_INTERFACE = "customInterface:";
@@ -30,22 +30,24 @@ public class HandlerMethodConfiguration implements ApplicationContextAware {
private Method mappingMethod; private Method mappingMethod;
public HandlerMethodConfiguration() { public HandlerMethodService() {
Class<TestController> testControllerClass = TestController.class; Class<PortalDispatchServlet> portalDispatchServletClass = PortalDispatchServlet.class;
Method[] declaredMethods = testControllerClass.getDeclaredMethods(); Method[] declaredMethods = portalDispatchServletClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) { for (Method declaredMethod : declaredMethods) {
if ("mapping".equals(declaredMethod.getName())) { if ("doDispatch".equals(declaredMethod.getName())) {
mappingMethod = declaredMethod; mappingMethod = declaredMethod;
} }
} }
if (mappingMethod == null) { if (mappingMethod == null) {
log.error("mappingMethod is null"); log.error("mappingMethod is null");
} }
mappingMethod.setAccessible(Boolean.TRUE);
} }
@Override @Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
mapping = (RequestMappingHandlerMapping) applicationContext.getBean("requestMappingHandlerMapping"); mapping = (RequestMappingHandlerMapping) applicationContext.getBean("requestMappingHandlerMapping");
registerMapping("/anonymity/mapping",RequestMethod.GET);
} }
/** /**
@@ -69,7 +71,7 @@ public class HandlerMethodConfiguration implements ApplicationContextAware {
if (handlerMethods.containsKey(requestMappingInfo)) { if (handlerMethods.containsKey(requestMappingInfo)) {
throw new CustomException("path is exist"); throw new CustomException("path is exist");
} }
mapping.registerMapping(requestMappingInfo, "testController", mappingMethod); mapping.registerMapping(requestMappingInfo, "portalDispatchServlet", mappingMethod);
} }
/** /**

View File

@@ -1,6 +1,7 @@
package cn.fateverse.query.service; package cn.fateverse.query.service;
import cn.fateverse.common.core.result.page.TableDataInfo; import cn.fateverse.common.core.result.page.TableDataInfo;
import cn.fateverse.query.entity.dto.PortalDto;
import cn.fateverse.query.entity.query.PortalQuery; import cn.fateverse.query.entity.query.PortalQuery;
import cn.fateverse.query.entity.vo.PortalVo; import cn.fateverse.query.entity.vo.PortalVo;
import cn.fateverse.query.entity.vo.SimplePortalVo; import cn.fateverse.query.entity.vo.SimplePortalVo;
@@ -11,11 +12,18 @@ import cn.fateverse.query.entity.vo.SimplePortalVo;
*/ */
public interface PortalService { public interface PortalService {
/**
* 根据id查询
* @param portalId id
* @return 结果
*/
PortalVo searchById(Long portalId); PortalVo searchById(Long portalId);
TableDataInfo<SimplePortalVo> searchList(PortalQuery query); TableDataInfo<SimplePortalVo> searchList(PortalQuery query);
void save(PortalDto portalDto);
void edit(PortalDto portalDto);
} }

View File

@@ -1,8 +1,17 @@
package cn.fateverse.query.service; package cn.fateverse.query.service;
import cn.fateverse.common.core.entity.Option;
import java.util.List;
/** /**
* @author Clay * @author Clay
* @date 2024/4/16 16:17 * @date 2024/4/16 16:17
*/ */
public interface QueryToolService { public interface QueryToolService {
List<Option> searchQueryOption(Integer type);
List<Option> searchQueryCon(Long queryId);
} }

View File

@@ -35,7 +35,8 @@ public class DataAdapterServiceImpl implements DataAdapterService {
private final DataAdapterHandlerReader handlerReader; private final DataAdapterHandlerReader handlerReader;
public DataAdapterServiceImpl(DataAdapterMapper dataAdapterMapper, DataAdapterHandlerReader handlerReader) { public DataAdapterServiceImpl(DataAdapterMapper dataAdapterMapper,
DataAdapterHandlerReader handlerReader) {
this.dataAdapterMapper = dataAdapterMapper; this.dataAdapterMapper = dataAdapterMapper;
this.handlerReader = handlerReader; this.handlerReader = handlerReader;
} }
@@ -77,8 +78,9 @@ public class DataAdapterServiceImpl implements DataAdapterService {
//后续可以添加对应的查询条件 //后续可以添加对应的查询条件
searchInfo.setList(new ArrayList<>()); searchInfo.setList(new ArrayList<>());
DataAdapter dbData = dataAdapterMapper.selectById(dto.getAdapterId()); DataAdapter dbData = dataAdapterMapper.selectById(dto.getAdapterId());
dataAdapter.setDataSourceId(dbData.getDataSourceId()); // dataAdapter.setDataSourceId(dbData.getDataSourceId());
return handlerReader.mockExecute(dataAdapter, searchInfo); // return handlerReader.mockExecute(dataAdapter, searchInfo);
return null;
} }
@Override @Override

View File

@@ -134,8 +134,8 @@ public class PageServiceImpl implements PageService {
@Override @Override
public TableDataInfo<Map<String, Object>> searchQueryData(SearchInfo searchInfo) { public TableDataInfo<Map<String, Object>> searchQueryData(SearchInfo searchInfo) {
checkPermissions(searchInfo.getQueryId()); checkPermissions(searchInfo.getLongQueryId());
UniQuery query = uniQueryMapper.selectSampleById(searchInfo.getQueryId()); UniQuery query = uniQueryMapper.selectSampleById(searchInfo.getLongQueryId());
if (!query.getPublish()) { if (!query.getPublish()) {
throw new CustomException("当前状态有误!"); throw new CustomException("当前状态有误!");
} }

View File

@@ -1,21 +1,33 @@
package cn.fateverse.query.service.impl; package cn.fateverse.query.service.impl;
import cn.fateverse.common.core.exception.CustomException;
import cn.fateverse.common.core.result.page.TableDataInfo; import cn.fateverse.common.core.result.page.TableDataInfo;
import cn.fateverse.common.mybatis.utils.PageUtils; import cn.fateverse.common.mybatis.utils.PageUtils;
import cn.fateverse.query.portal.config.HandlerMethodService;
import cn.fateverse.query.constant.QueryConstant;
import cn.fateverse.query.entity.DataAdapter; import cn.fateverse.query.entity.DataAdapter;
import cn.fateverse.query.entity.Portal; import cn.fateverse.query.entity.Portal;
import cn.fateverse.query.entity.PortalMapping;
import cn.fateverse.query.entity.UniQuery; import cn.fateverse.query.entity.UniQuery;
import cn.fateverse.query.entity.dto.DataAdapterDto;
import cn.fateverse.query.entity.dto.PortalDto;
import cn.fateverse.query.entity.query.PortalQuery; import cn.fateverse.query.entity.query.PortalQuery;
import cn.fateverse.query.entity.vo.PortalVo; import cn.fateverse.query.entity.vo.PortalVo;
import cn.fateverse.query.entity.vo.SimplePortalVo; import cn.fateverse.query.entity.vo.SimplePortalVo;
import cn.fateverse.query.enums.PortalEnum;
import cn.fateverse.query.mapper.DataAdapterMapper; import cn.fateverse.query.mapper.DataAdapterMapper;
import cn.fateverse.query.mapper.PortalMapper; import cn.fateverse.query.mapper.PortalMapper;
import cn.fateverse.query.mapper.PortalMappingMapper;
import cn.fateverse.query.mapper.UniQueryMapper; import cn.fateverse.query.mapper.UniQueryMapper;
import cn.fateverse.query.service.PortalService; import cn.fateverse.query.service.PortalService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.annotation.Resource;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@@ -29,27 +41,45 @@ import java.util.Map;
@Service @Service
public class PortalServiceImpl implements PortalService { public class PortalServiceImpl implements PortalService {
@Resource
private RedisTemplate<String, Portal> redisTemplate;
@Resource
private HandlerMethodService methodService;
private final PortalMapper portalMapper; private final PortalMapper portalMapper;
private final UniQueryMapper queryMapper; private final UniQueryMapper queryMapper;
private final DataAdapterMapper adapterMapper; private final DataAdapterMapper adapterMapper;
private final PortalMappingMapper portalMappingMapper;
public PortalServiceImpl(PortalMapper portalMapper, public PortalServiceImpl(PortalMapper portalMapper,
UniQueryMapper queryMapper, UniQueryMapper queryMapper,
DataAdapterMapper adapterMapper) { DataAdapterMapper adapterMapper,
PortalMappingMapper portalMappingMapper) {
this.portalMapper = portalMapper; this.portalMapper = portalMapper;
this.queryMapper = queryMapper; this.queryMapper = queryMapper;
this.adapterMapper = adapterMapper; this.adapterMapper = adapterMapper;
this.portalMappingMapper = portalMappingMapper;
} }
@Override @Override
public PortalVo searchById(Long portalId) { public PortalVo searchById(Long portalId) {
Portal portal = portalMapper.selectById(portalId); Portal portal = portalMapper.selectById(portalId);
PortalVo vo = PortalVo.toPortalVo(portal); PortalVo portalVo = PortalVo.toPortalVo(portal);
List<PortalMapping> portalMappings = portalMappingMapper.selectByPortalId(portalId);
// return PortalVo.toPortalVo(portal); if (ObjectUtils.isEmpty(portalMappings)) {
return null; portalMappings = new ArrayList<>();
}
if (PortalEnum.LOCAL.equals(portal.getType())) {
UniQuery uniQuery = queryMapper.selectById(portal.getQueryId());
portalVo.setQueryType(uniQuery.getType());
}
portalVo.setMappings(portalMappings);
return portalVo;
} }
@Override @Override
@@ -94,4 +124,105 @@ public class PortalServiceImpl implements PortalService {
return simplePortalVo; return simplePortalVo;
}); });
} }
@Override
@Transactional(rollbackFor = Exception.class)
public void save(PortalDto portalDto) {
Portal portal = portalDto.toPortal();
checkPortalType(portal);
Portal old = portalMapper.selectByPath(portal.getPath(), portal.getRequestMethod());
if (!ObjectUtils.isEmpty(old)) {
throw new CustomException("系统中存在当前请求路径");
}
UniQuery uniQuery = queryMapper.selectById(portal.getQueryId());
if (ObjectUtils.isEmpty(uniQuery)) {
throw new CustomException("未找到对应的查询接口!");
}
portal.setState(0);
// 判断是否需要创建数据适配器
if (portal.getCreateDataAdapter()) {
createDataAdapter(portalDto, portal);
} else {
DataAdapter dataAdapter = adapterMapper.selectById(portal.getAdapterId());
if (ObjectUtils.isEmpty(dataAdapter)) {
throw new CustomException("未找到对应的数据适配器!");
}
}
portalMapper.insert(portal);
List<PortalMapping> mappings = portalDto.getMappings();
if (!ObjectUtils.isEmpty(mappings)) {
for (PortalMapping mapping : mappings) {
mapping.setPortalId(portal.getPortalId());
}
portalMappingMapper.insertBatch(mappings);
}
publishPortal(portal);
}
@Override
public void edit(PortalDto portalDto) {
Portal portal = portalDto.toPortal();
checkPortalType(portal);
Portal old = portalMapper.selectByPath(portal.getPath(), portal.getRequestMethod());
if (!ObjectUtils.isEmpty(old) && !old.getPortalId().equals(portal.getPortalId())) {
throw new CustomException("系统中存在当前请求路径");
}
if (!old.getPath().equals(portal.getPath())) {
unpublishPortal(old);
publishPortal(portal);
}
if (portal.getCreateDataAdapter() != old.getCreateDataAdapter()) {
if (portal.getCreateDataAdapter()) {
createDataAdapter(portalDto, portal);
} else {
adapterMapper.deleteById(old.getAdapterId());
}
}
}
private void publishPortal(Portal portal) {
methodService.registerMapping(portal.getPath(), RequestMethod.valueOf(portal.getRequestMethod()));
redisTemplate.opsForValue().set(QueryConstant.PORTAL_KEY + portal.getPortalId(), portal);
}
private void unpublishPortal(Portal portal) {
methodService.unregisterMapping(portal.getPath(), RequestMethod.valueOf(portal.getRequestMethod()));
redisTemplate.delete(QueryConstant.PORTAL_KEY + portal.getPortalId());
}
private void createDataAdapter(PortalDto portalDto, Portal portal) {
DataAdapterDto dataAdapterDto = portalDto.getDataAdapter();
if (ObjectUtils.isEmpty(dataAdapterDto)) {
throw new CustomException("数据适配器为空!");
}
DataAdapter dataAdapter = dataAdapterDto.toDataAdapter();
if (ObjectUtils.isEmpty(dataAdapter.getType())) {
throw new CustomException("请选择数据适配器类型!");
}
dataAdapter.setAdapterName(portal.getPortalName() + "专用数据适配器!");
dataAdapter.setCommon(Boolean.FALSE);
dataAdapter.init();
adapterMapper.insert(dataAdapter);
portal.setAdapterId(dataAdapter.getAdapterId());
}
private void checkPortalType(Portal portal) {
if (PortalEnum.LOCAL.equals(portal.getType())) {
if (ObjectUtils.isEmpty(portal.getQueryId())) {
throw new CustomException("请选择查询接口!");
}
portal.setUrl(null);
} else if (PortalEnum.EXTERNAL.equals(portal.getType())) {
if (ObjectUtils.isEmpty(portal.getUrl())) {
throw new CustomException("第三方接口地址不能为空!");
}
} else {
throw new CustomException("当前类型不支持");
}
}
} }

View File

@@ -1,10 +1,19 @@
package cn.fateverse.query.service.impl; package cn.fateverse.query.service.impl;
import cn.fateverse.query.mapper.UniColumnMapper; import cn.fateverse.common.core.entity.Option;
import cn.fateverse.query.entity.UniCon;
import cn.fateverse.query.entity.UniQuery;
import cn.fateverse.query.entity.query.UniQueryQuery;
import cn.fateverse.query.mapper.UniConMapper; import cn.fateverse.query.mapper.UniConMapper;
import cn.fateverse.query.mapper.UniQueryMapper;
import cn.fateverse.query.service.QueryToolService; import cn.fateverse.query.service.QueryToolService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/** /**
* @author Clay * @author Clay
@@ -14,16 +23,44 @@ import org.springframework.stereotype.Service;
@Service @Service
public class QueryToolServiceImpl implements QueryToolService { public class QueryToolServiceImpl implements QueryToolService {
private final UniConMapper uniConMapper; private final UniConMapper conMapper;
private final UniColumnMapper uniColumnMapper; private final UniQueryMapper queryMapper;
public QueryToolServiceImpl(UniConMapper uniConMapper, public QueryToolServiceImpl(UniConMapper conMapper,
UniColumnMapper uniColumnMapper) { UniQueryMapper queryMapper) {
this.uniConMapper = uniConMapper; this.conMapper = conMapper;
this.uniColumnMapper = uniColumnMapper; this.queryMapper = queryMapper;
} }
@Override
public List<Option> searchQueryOption(Integer type) {
UniQueryQuery query = new UniQueryQuery();
query.setType(type);
query.setPreview(Boolean.TRUE);
List<UniQuery> queryList = queryMapper.selectList(query);
if (ObjectUtils.isEmpty(queryList)) {
return new ArrayList<>();
}
return queryList.stream().map(uniQuery -> Option.builder()
.value(uniQuery.getId())
.label(uniQuery.getUqName())
.build()).collect(Collectors.toList());
}
@Override
public List<Option> searchQueryCon(Long queryId) {
List<UniCon> uniCons = conMapper.selectByQueryId(queryId);
if (ObjectUtils.isEmpty(uniCons)) {
return new ArrayList<>();
}
return uniCons.stream()
.map(uniCon -> Option.builder()
.value(uniCon.getUcId())
.label(uniCon.getUcName())
.build()).collect(Collectors.toList());
}
} }

View File

@@ -8,8 +8,8 @@
<id column="adapter_id" property="adapterId"/> <id column="adapter_id" property="adapterId"/>
<result column="adapter_name" property="adapterName"/> <result column="adapter_name" property="adapterName"/>
<result column="type" property="type"/> <result column="type" property="type"/>
<result column="common" property="common"/>
<result column="code" property="code"/> <result column="code" property="code"/>
<result column="source" property="source"/>
<result column="mock_data" property="mockData"/> <result column="mock_data" property="mockData"/>
<result column="create_by" property="createBy"/> <result column="create_by" property="createBy"/>
<result column="create_time" property="createTime"/> <result column="create_time" property="createTime"/>
@@ -18,18 +18,26 @@
</resultMap> </resultMap>
<sql id="selectDataAdapterVo"> <sql id="selectDataAdapterVo">
select adapter_id, data_source_id, adapter_name, `type`, code, `source`, mock_data, create_by, create_time, update_by, update_time select adapter_id,
adapter_name,
`type`,
common,
code,
mock_data,
create_by,
create_time,
update_by,
update_time
from data_adapter from data_adapter
</sql> </sql>
<select id="selectList" resultMap="DataAdapterResult"> <select id="selectList" resultMap="DataAdapterResult">
<include refid="selectDataAdapterVo"/> <include refid="selectDataAdapterVo"/>
<where> <where>
<if test="adapterName != null and adapterName != ''"> and adapter_name like concat('%', #{adapterName}, '%')</if> <if test="adapterName != null and adapterName != ''">and adapter_name like concat('%', #{adapterName}, '%')</if>
<if test="type != null"> and `type` = #{type}</if> <if test="type != null">and `type` = #{type}</if>
<if test="source != null "> and `source` = #{source}</if> <if test="common != null">and common = #{common}</if>
</where> </where>
</select> </select>
@@ -46,24 +54,22 @@
</foreach> </foreach>
</select> </select>
<insert id="insert" > <insert id="insert" useGeneratedKeys="true" keyProperty="adapterId" keyColumn="adapter_id">
insert into data_adapter insert into data_adapter
<trim prefix="(" suffix=")" suffixOverrides=","> <trim prefix="(" suffix=")" suffixOverrides=",">
<if test="dataSourceId != null">data_source_id,</if>
<if test="adapterName != null">adapter_name,</if> <if test="adapterName != null">adapter_name,</if>
<if test="type != null">`type`,</if> <if test="type != null">`type`,</if>
<if test="common != null">common,</if>
<if test="code != null">code,</if> <if test="code != null">code,</if>
<if test="source != null">`source`,</if>
<if test="mockData != null">mock_data,</if> <if test="mockData != null">mock_data,</if>
<if test="createBy != null and createBy != ''">create_by,</if> <if test="createBy != null and createBy != ''">create_by,</if>
<if test="createTime != null ">create_time,</if> <if test="createTime != null ">create_time,</if>
</trim> </trim>
<trim prefix="values (" suffix=")" suffixOverrides=","> <trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="dataSourceId != null">#{dataSourceId},</if>
<if test="adapterName != null">#{adapterName},</if> <if test="adapterName != null">#{adapterName},</if>
<if test="type != null">#{type},</if> <if test="type != null">#{type},</if>
<if test="common != null">#{common},</if>
<if test="code != null">#{code},</if> <if test="code != null">#{code},</if>
<if test="source != null">#{source},</if>
<if test="mockData != null">#{mockData},</if> <if test="mockData != null">#{mockData},</if>
<if test="createBy != null and createBy != ''">#{createBy},</if> <if test="createBy != null and createBy != ''">#{createBy},</if>
<if test="createTime != null ">#{createTime},</if> <if test="createTime != null ">#{createTime},</if>
@@ -73,11 +79,9 @@
<update id="update"> <update id="update">
update data_adapter update data_adapter
<set> <set>
<if test="dataSourceId != null">data_source_id = #{dataSourceId},</if>
<if test="adapterName != null">adapter_name = #{adapterName},</if> <if test="adapterName != null">adapter_name = #{adapterName},</if>
<if test="type != null">`type` = #{type},</if> <if test="type != null">`type` = #{type},</if>
<if test="code != null">code = #{code},</if> <if test="code != null">code = #{code},</if>
<if test="source != null">`source` = #{source},</if>
<if test="mockData != null">mock_data = #{mockData},</if> <if test="mockData != null">mock_data = #{mockData},</if>
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if> <if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
<if test="updateTime != null ">update_time = #{updateTime},</if> <if test="updateTime != null ">update_time = #{updateTime},</if>
@@ -86,7 +90,8 @@
</update> </update>
<delete id="deleteById"> <delete id="deleteById">
delete from data_adapter delete
from data_adapter
where adapter_id = #{adapterId} where adapter_id = #{adapterId}
</delete> </delete>

View File

@@ -11,14 +11,10 @@
portal_name, portal_name,
anonymity, anonymity,
type, type,
request_method,
create_data_adapter,
path, path,
header,
params,
body,
url, url,
api_header,
api_params,
api_body,
state, state,
create_by, create_by,
create_time, create_time,
@@ -28,35 +24,55 @@
from portal from portal
</sql> </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"> <select id="selectById" resultType="cn.fateverse.query.entity.Portal">
<include refid="selectVo"/> <include refid="selectVo"/>
where portal_id = #{portalId} where portal_id = #{portalId}
</select> </select>
<select id="selectList" resultType="cn.fateverse.query.entity.Portal"> <select id="selectList" resultType="cn.fateverse.query.entity.Portal">
<include refid="selectSimpleVo"/> <include refid="selectVo"/>
<where> <where>
<if test="portalName != null and portalName != ''"> and portal_name like concat('%', #{portalName}, '%')</if> <if test="portalName != null and portalName != ''">and portal_name like concat('%', #{portalName}, '%') </if>
<if test="anonymity != null "> and anonymity = #{anonymity}</if> <if test="anonymity != null ">and anonymity = #{anonymity}</if>
<if test="type != null"> and type = #{type}</if> <if test="type != null">and type = #{type}</if>
<if test="path != null and path != ''"> and path like concat('%', #{path}, '%')</if> <if test="path != null and path != ''">and path like concat('%', #{path}, '%')</if>
</where> </where>
</select> </select>
<select id="selectByPath" resultType="cn.fateverse.query.entity.Portal">
<include refid="selectVo"/>
where path = #{path} and request_method = #{requestMethod} limit 1
</select>
<insert id="insert" useGeneratedKeys="true" keyColumn="portal_id" keyProperty="portalId">
insert into portal
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="queryId != null">query_id,</if>
<if test="adapterId != null">adapter_id,</if>
<if test="portalName != null">portal_name,</if>
<if test="anonymity != null">anonymity,</if>
<if test="type != null">type,</if>
<if test="requestMethod != null">request_method,</if>
<if test="createDataAdapter != null">create_data_adapter,</if>
<if test="path != null">path,</if>
<if test="url != null">url,</if>
<if test="state != null">state,</if>
<if test="createBy != null and createBy != ''">create_by,</if>
<if test="createTime != null ">create_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="queryId != null">#{queryId},</if>
<if test="adapterId != null">#{adapterId},</if>
<if test="portalName != null">#{portalName},</if>
<if test="anonymity != null">#{anonymity},</if>
<if test="type != null">#{type},</if>
<if test="requestMethod != null">#{requestMethod},</if>
<if test="createDataAdapter != null">#{createDataAdapter},</if>
<if test="path != null">#{path},</if>
<if test="url != null">#{url},</if>
<if test="state != null">#{state},</if>
<if test="createBy != null and createBy != ''">#{createBy},</if>
<if test="createTime != null ">#{createTime},</if>
</trim>
</insert>
</mapper> </mapper>

View File

@@ -5,17 +5,17 @@
<mapper namespace="cn.fateverse.query.mapper.PortalMappingMapper"> <mapper namespace="cn.fateverse.query.mapper.PortalMappingMapper">
<select id="selectByPortalId" resultType="cn.fateverse.query.entity.PortalMapping"> <select id="selectByPortalId" resultType="cn.fateverse.query.entity.PortalMapping">
select mapping_id, portal_id, mapping_key, data_type, mapping_value select mapping_id, portal_id, mapping_key, mapping_type, mapping_value
from portal_mapping from portal_mapping
where portal_id = #{portalId} where portal_id = #{portalId}
</select> </select>
<insert id="insertBatch"> <insert id="insertBatch">
insert into portal_mapping (portal_id, mapping_key, data_type, mapping_value) insert into portal_mapping (portal_id, mapping_key, mapping_type, mapping_value)
values values
<foreach collection="list" item="item" separator=","> <foreach collection="list" item="item" separator=",">
(#{item.portalId}, #{item.mappingKey}, #{item.dataType}, #{item.mappingValue}) (#{item.portalId}, #{item.mappingKey}, #{item.mappingType}, #{item.mappingValue})
</foreach> </foreach>
</insert> </insert>