diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/controller/OpenApiAuthController.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/controller/OpenApiAuthController.java new file mode 100644 index 000000000..fec2ec755 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/controller/OpenApiAuthController.java @@ -0,0 +1,112 @@ +package org.jeecg.modules.openapi.controller; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.system.base.controller.JeecgController; +import org.jeecg.common.system.query.QueryGenerator; +import org.jeecg.modules.openapi.entity.OpenApiAuth; +import org.jeecg.modules.openapi.generator.AKSKGenerator; +import org.jeecg.modules.openapi.service.OpenApiAuthService; +import org.springframework.web.bind.annotation.*; + +import jakarta.servlet.http.HttpServletRequest; +import java.util.Arrays; + +/** + * @date 2024/12/10 9:54 + */ +@RestController +@RequestMapping("/openapi/auth") +public class OpenApiAuthController extends JeecgController { + + /** + * 分页列表查询 + * + * @param openApiAuth + * @param pageNo + * @param pageSize + * @param req + * @return + */ + @GetMapping(value = "/list") + public Result queryPageList(OpenApiAuth openApiAuth, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) { + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(openApiAuth, req.getParameterMap()); + Page page = new Page<>(pageNo, pageSize); + IPage pageList = service.page(page, queryWrapper); + return Result.ok(pageList); + } + + /** + * 添加 + * + * @param openApiAuth + * @return + */ + @PostMapping(value = "/add") + public Result add(@RequestBody OpenApiAuth openApiAuth) { + service.save(openApiAuth); + return Result.ok("添加成功!"); + } + + /** + * 编辑 + * + * @param openApiAuth + * @return + */ + @PutMapping(value = "/edit") + public Result edit(@RequestBody OpenApiAuth openApiAuth) { + service.updateById(openApiAuth); + return Result.ok("修改成功!"); + + } + + /** + * 通过id删除 + * + * @param id + * @return + */ + @DeleteMapping(value = "/delete") + public Result delete(@RequestParam(name = "id", required = true) String id) { + service.removeById(id); + return Result.ok("删除成功!"); + } + + /** + * 批量删除 + * + * @param ids + * @return + */ + @DeleteMapping(value = "/deleteBatch") + public Result deleteBatch(@RequestParam(name = "ids", required = true) String ids) { + + this.service.removeByIds(Arrays.asList(ids.split(","))); + return Result.ok("批量删除成功!"); + } + + /** + * 通过id查询 + * + * @param id + * @return + */ + @GetMapping(value = "/queryById") + public Result queryById(@RequestParam(name = "id", required = true) String id) { + OpenApiAuth openApiAuth = service.getById(id); + return Result.ok(openApiAuth); + } + + /** + * 生成AKSK + * @return + */ + @GetMapping("genAKSK") + public Result genAKSK() { + return Result.ok(AKSKGenerator.genAKSKPair()); + } +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/controller/OpenApiController.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/controller/OpenApiController.java new file mode 100644 index 000000000..671798be5 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/controller/OpenApiController.java @@ -0,0 +1,415 @@ +package org.jeecg.modules.openapi.controller; + +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.google.common.collect.Lists; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.constant.CommonConstant; +import org.jeecg.common.system.base.controller.JeecgController; +import org.jeecg.common.system.query.QueryGenerator; +import org.jeecg.common.system.util.JwtUtil; +import org.jeecg.common.util.RedisUtil; +import org.jeecg.common.util.RestUtil; +import org.jeecg.modules.openapi.entity.OpenApi; +import org.jeecg.modules.openapi.entity.OpenApiAuth; +import org.jeecg.modules.openapi.entity.OpenApiHeader; +import org.jeecg.modules.openapi.entity.OpenApiParam; +import org.jeecg.modules.openapi.generator.PathGenerator; +import org.jeecg.modules.openapi.service.OpenApiAuthService; +import org.jeecg.modules.openapi.service.OpenApiService; +import org.jeecg.modules.openapi.swagger.*; +import org.jeecg.modules.system.entity.SysUser; +import org.jeecg.modules.system.service.ISysUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponentsBuilder; + +import jakarta.servlet.http.HttpServletRequest; +import java.net.URI; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @date 2024/12/10 9:11 + */ +@RestController +@RequestMapping("/openapi") +public class OpenApiController extends JeecgController { + + @Autowired + private RestTemplate restTemplate; + @Autowired + private RedisUtil redisUtil; + @Autowired + private ISysUserService sysUserService; + @Autowired + private OpenApiAuthService openApiAuthService; + + /** + * 分页列表查询 + * + * @param openApi + * @param pageNo + * @param pageSize + * @param req + * @return + */ + @GetMapping(value = "/list") + public Result queryPageList(OpenApi openApi, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) { + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(openApi, req.getParameterMap()); + Page page = new Page<>(pageNo, pageSize); + IPage pageList = service.page(page, queryWrapper); + return Result.ok(pageList); + } + + /** + * 添加 + * + * @param openApi + * @return + */ + @PostMapping(value = "/add") + public Result add(@RequestBody OpenApi openApi) { + service.save(openApi); + return Result.ok("添加成功!"); + } + + /** + * 编辑 + * + * @param openApi + * @return + */ + @PutMapping(value = "/edit") + public Result edit(@RequestBody OpenApi openApi) { + service.updateById(openApi); + return Result.ok("修改成功!"); + + } + + /** + * 通过id删除 + * + * @param id + * @return + */ + @DeleteMapping(value = "/delete") + public Result delete(@RequestParam(name = "id", required = true) String id) { + service.removeById(id); + return Result.ok("删除成功!"); + } + + /** + * 批量删除 + * + * @param ids + * @return + */ + @DeleteMapping(value = "/deleteBatch") + public Result deleteBatch(@RequestParam(name = "ids", required = true) String ids) { + + this.service.removeByIds(Arrays.asList(ids.split(","))); + return Result.ok("批量删除成功!"); + } + + /** + * 通过id查询 + * + * @param id + * @return + */ + @GetMapping(value = "/queryById") + public Result queryById(@RequestParam(name = "id", required = true) String id) { + OpenApi OpenApi = service.getById(id); + return Result.ok(OpenApi); + } + + /** + * 接口调用 + * @param path + * @return + */ + @RequestMapping(value = "/call/{path}", method = {RequestMethod.GET,RequestMethod.POST}) + public Result call(@PathVariable String path, @RequestBody(required = false) String json, HttpServletRequest request) { + OpenApi openApi = service.findByPath(path); + if (Objects.isNull(openApi)) { + Map result = new HashMap<>(); + result.put("code", 404); + result.put("data", null); + return Result.error("失败", result); + } + HttpHeaders httpHeaders = new HttpHeaders(); + if (StrUtil.isNotEmpty(openApi.getHeadersJson())) { + List headers = JSON.parseArray(openApi.getHeadersJson(),OpenApiHeader.class); + if (headers.size()>0) { + for (OpenApiHeader header : headers) { + httpHeaders.put(header.getHeaderKey(), Lists.newArrayList(request.getHeader(header.getHeaderKey()))); + } + } + } + + String url = openApi.getOriginUrl(); + String method = openApi.getRequestMethod(); + String appkey = request.getHeader("appkey"); + OpenApiAuth openApiAuth = openApiAuthService.getByAppkey(appkey); + SysUser systemUser = sysUserService.getById(openApiAuth.getSystemUserId()); + String token = this.getToken(systemUser.getUsername(), systemUser.getPassword()); + httpHeaders.put("X-Access-Token", Lists.newArrayList(token)); + httpHeaders.put("Content-Type",Lists.newArrayList("application/json")); + HttpEntity httpEntity = new HttpEntity<>(json, httpHeaders); + url = RestUtil.getBaseUrl() + url; + UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url); + if (HttpMethod.GET.matches(method) + || HttpMethod.DELETE.matches(method) + || HttpMethod.OPTIONS.matches(method) + || HttpMethod.TRACE.matches(method)) { + //拼接参数 + if (!request.getParameterMap().isEmpty()) { + if (StrUtil.isNotEmpty(openApi.getParamsJson())) { + List params = JSON.parseArray(openApi.getParamsJson(),OpenApiParam.class); + if (params.size()>0) { + Map openApiParamMap = params.stream().collect(Collectors.toMap(p -> p.getParamKey(), p -> p, (e, r) -> e)); + request.getParameterMap().forEach((k, v) -> { + OpenApiParam openApiParam = openApiParamMap.get(k); + if (Objects.nonNull(openApiParam)) { + if(v==null&&StrUtil.isNotEmpty(openApiParam.getDefaultValue())){ + builder.queryParam(openApiParam.getParamKey(), openApiParam.getDefaultValue()); + } + if (v!=null){ + builder.queryParam(openApiParam.getParamKey(), v); + } + } + }); + } + } + + } + } + URI targetUrl = builder.build().encode().toUri(); + return restTemplate.exchange(targetUrl.toString(), Objects.requireNonNull(HttpMethod.resolve(method)), httpEntity, Result.class, request.getParameterMap()).getBody(); + } + + /** + * 生成接口访问令牌 Token + * + * @param USERNAME + * @param PASSWORD + * @return + */ + private String getToken(String USERNAME, String PASSWORD) { + String token = JwtUtil.sign(USERNAME, PASSWORD); + redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token); + redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, 60); + return token; + } + + + @GetMapping("/json") + public SwaggerModel swaggerModel() { + + SwaggerModel swaggerModel = new SwaggerModel(); + swaggerModel.setSwagger("2.0"); + swaggerModel.setInfo(swaggerInfo()); + swaggerModel.setHost("jeecg.com"); + swaggerModel.setBasePath("/jeecg-boot"); + swaggerModel.setSchemes(Lists.newArrayList("http", "https")); + + SwaggerTag swaggerTag = new SwaggerTag(); + swaggerTag.setName("openapi"); + swaggerModel.setTags(Lists.newArrayList(swaggerTag)); + + pathsAndDefinitions(swaggerModel); + + return swaggerModel; + } + + private void pathsAndDefinitions(SwaggerModel swaggerModel) { + Map> paths = new HashMap<>(); + Map definitions = new HashMap<>(); + List openapis = service.list(); + for (OpenApi openApi : openapis) { + Map operations = new HashMap<>(); + SwaggerOperation operation = new SwaggerOperation(); + operation.setTags(Lists.newArrayList("openapi")); + operation.setSummary(openApi.getName()); + operation.setDescription(openApi.getName()); + operation.setOperationId(openApi.getRequestUrl()+"Using"+openApi.getRequestMethod()); + operation.setProduces(Lists.newArrayList("application/json")); + parameters(operation, openApi); + + // body入参 + if (StringUtils.hasText(openApi.getBody())) { + SwaggerDefinition definition = new SwaggerDefinition(); + definition.setType("object"); + Map definitionProperties = new HashMap<>(); + definition.setProperties(definitionProperties); + if (openApi.getBody()!=null){ + JSONObject jsonObject = JSONObject.parseObject(openApi.getBody()); + if (jsonObject.size()>0){ + for (Map.Entry properties : jsonObject.entrySet()) { + SwaggerDefinitionProperties swaggerDefinitionProperties = new SwaggerDefinitionProperties(); + swaggerDefinitionProperties.setType("string"); + swaggerDefinitionProperties.setDescription(properties.getValue()+""); + definitionProperties.put(properties.getKey(), swaggerDefinitionProperties); + } + } + } + // body的definition构建完成 + definitions.put(openApi.getRequestUrl()+"Using"+openApi.getRequestMethod()+"body", definition); + + SwaggerOperationParameter bodyParameter = new SwaggerOperationParameter(); + bodyParameter.setDescription(openApi.getName() + " body"); + bodyParameter.setIn("body"); + bodyParameter.setName(openApi.getName() + " body"); + bodyParameter.setRequired(true); + + Map bodySchema = new HashMap<>(); + bodySchema.put("$ref", "#/definitions/" + openApi.getRequestUrl()+"Using"+openApi.getRequestMethod()+"body"); + bodyParameter.setSchema(bodySchema); + + // 构建参数构建完成 + operation.getParameters().add(bodyParameter); + + } + + // 响应 + Map responses = new HashMap<>(); + SwaggerOperationResponse resp200 = new SwaggerOperationResponse(); + resp200.setDescription("OK"); + Map respSchema = new HashMap<>(); + respSchema.put("$ref", "#/definitions/OpenApiResult"); + resp200.setSchema(respSchema); + + responses.put("200", resp200); + + Map emptySchema = new HashMap<>(); + SwaggerOperationResponse resp201 = new SwaggerOperationResponse(); + resp201.setDescription("Created"); + resp201.setSchema(emptySchema); + responses.put("201", resp201); + SwaggerOperationResponse resp401 = new SwaggerOperationResponse(); + resp401.setDescription("Unauthorized"); + resp401.setSchema(emptySchema); + responses.put("401", resp401); + SwaggerOperationResponse resp403 = new SwaggerOperationResponse(); + resp403.setDescription("Forbidden"); + resp403.setSchema(emptySchema); + responses.put("403", resp403); + SwaggerOperationResponse resp404 = new SwaggerOperationResponse(); + resp404.setDescription("Not Found"); + resp404.setSchema(emptySchema); + responses.put("404", resp404); + + // 构建响应definition + SwaggerDefinition respDefinition = new SwaggerDefinition(); + respDefinition.setType("object"); + + Map definitionProperties = new HashMap<>(); + respDefinition.setProperties(definitionProperties); + + SwaggerDefinitionProperties codeProperties = new SwaggerDefinitionProperties(); + codeProperties.setType("integer"); + codeProperties.setDescription("返回代码"); + definitionProperties.put("code", codeProperties); + SwaggerDefinitionProperties messageProperties = new SwaggerDefinitionProperties(); + messageProperties.setType("string"); + messageProperties.setDescription("返回处理消息"); + definitionProperties.put("message", messageProperties); + SwaggerDefinitionProperties resultProperties = new SwaggerDefinitionProperties(); + resultProperties.setType("object"); + resultProperties.setDescription("返回数据对象"); + definitionProperties.put("result", resultProperties); + SwaggerDefinitionProperties successProperties = new SwaggerDefinitionProperties(); + successProperties.setType("boolean"); + successProperties.setDescription("成功标志"); + definitionProperties.put("success", successProperties); + SwaggerDefinitionProperties timestampProperties = new SwaggerDefinitionProperties(); + timestampProperties.setType("integer"); + timestampProperties.setDescription("时间戳"); + definitionProperties.put("timestamp", timestampProperties); + + definitions.put("OpenApiResult", respDefinition); + + + operation.setResponses(responses); + operations.put(openApi.getRequestMethod().toLowerCase(), operation); + paths.put("/openapi/call/"+openApi.getRequestUrl(), operations); + } + + swaggerModel.setDefinitions(definitions); + swaggerModel.setPaths(paths); + + } + + private void parameters(SwaggerOperation operation, OpenApi openApi) { + List parameters = new ArrayList<>(); + if (openApi.getParamsJson()!=null) { + List openApiParams = JSON.parseArray(openApi.getParamsJson(), OpenApiParam.class); + for (OpenApiParam openApiParam : openApiParams) { + SwaggerOperationParameter parameter = new SwaggerOperationParameter(); + parameter.setIn("path"); + parameter.setName(openApiParam.getParamKey()); + parameter.setRequired(openApiParam.getRequired() == 1); + parameter.setDescription(openApiParam.getNote()); + parameters.add(parameter); + } + } + if (openApi.getHeadersJson()!=null) { + List openApiHeaders = JSON.parseArray(openApi.getHeadersJson(), OpenApiHeader.class); + for (OpenApiHeader openApiHeader : openApiHeaders) { + SwaggerOperationParameter parameter = new SwaggerOperationParameter(); + parameter.setIn("header"); + parameter.setName(openApiHeader.getHeaderKey()); + parameter.setRequired(openApiHeader.getRequired() == 1); + parameter.setDescription(openApiHeader.getNote()); + parameters.add(parameter); + } + } + operation.setParameters(parameters); + } + + private SwaggerInfo swaggerInfo() { + SwaggerInfo info = new SwaggerInfo(); + + info.setDescription("OpenAPI 接口列表"); + info.setVersion("3.8.0"); + info.setTitle("OpenAPI 接口列表"); + info.setTermsOfService("https://jeecg.com"); + + SwaggerInfoContact contact = new SwaggerInfoContact(); + contact.setName("jeecg@qq.com"); + + info.setContact(contact); + + SwaggerInfoLicense license = new SwaggerInfoLicense(); + license.setName("Apache 2.0"); + license.setUrl("http://www.apache.org/licenses/LICENSE-2.0.html"); + + info.setLicense(license); + + return info; + } + + /** + * 生成接口路径 + * @return + */ + @GetMapping("genPath") + public Result genPath() { + Result r = new Result(); + r.setSuccess(true); + r.setCode(CommonConstant.SC_OK_200); + r.setResult(PathGenerator.genPath()); + return r; + } +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/controller/OpenApiIndexController.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/controller/OpenApiIndexController.java new file mode 100644 index 000000000..36fcba8ab --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/controller/OpenApiIndexController.java @@ -0,0 +1,26 @@ +package org.jeecg.modules.openapi.controller; + +import org.jeecg.common.api.vo.Result; +import org.jeecg.config.shiro.IgnoreAuth; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.HashMap; +import java.util.Map; + +/** + * @date 2024/12/20 14:04 + */ +@RestController +@RequestMapping("/openapi/demo") +public class OpenApiIndexController { + + @GetMapping("index") + @IgnoreAuth + public Result> index() { + Map result = new HashMap<>(); + result.put("first", "Hello World"); + return Result.ok(result); + } +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/controller/OpenApiLogController.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/controller/OpenApiLogController.java new file mode 100644 index 000000000..6ca5e0315 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/controller/OpenApiLogController.java @@ -0,0 +1,102 @@ +package org.jeecg.modules.openapi.controller; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.system.base.controller.JeecgController; +import org.jeecg.common.system.query.QueryGenerator; +import org.jeecg.modules.openapi.entity.OpenApiLog; +import org.jeecg.modules.openapi.service.OpenApiLogService; +import org.springframework.web.bind.annotation.*; + +import jakarta.servlet.http.HttpServletRequest; +import java.util.Arrays; + +/** + * @date 2024/12/10 9:57 + */ +@RestController +@RequestMapping("/openapi/record") +public class OpenApiLogController extends JeecgController { + + /** + * 分页列表查询 + * + * @param OpenApiLog + * @param pageNo + * @param pageSize + * @param req + * @return + */ + @GetMapping(value = "/list") + public Result queryPageList(OpenApiLog OpenApiLog, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) { + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(OpenApiLog, req.getParameterMap()); + Page page = new Page<>(pageNo, pageSize); + IPage pageList = service.page(page, queryWrapper); + return Result.ok(pageList); + } + + /** + * 添加 + * + * @param OpenApiLog + * @return + */ + @PostMapping(value = "/add") + public Result add(@RequestBody OpenApiLog OpenApiLog) { + service.save(OpenApiLog); + return Result.ok("添加成功!"); + } + + /** + * 编辑 + * + * @param OpenApiLog + * @return + */ + @PutMapping(value = "/edit") + public Result edit(@RequestBody OpenApiLog OpenApiLog) { + service.updateById(OpenApiLog); + return Result.ok("修改成功!"); + + } + + /** + * 通过id删除 + * + * @param id + * @return + */ + @DeleteMapping(value = "/delete") + public Result delete(@RequestParam(name = "id", required = true) String id) { + service.removeById(id); + return Result.ok("删除成功!"); + } + + /** + * 批量删除 + * + * @param ids + * @return + */ + @DeleteMapping(value = "/deleteBatch") + public Result deleteBatch(@RequestParam(name = "ids", required = true) String ids) { + + this.service.removeByIds(Arrays.asList(ids.split(","))); + return Result.ok("批量删除成功!"); + } + + /** + * 通过id查询 + * + * @param id + * @return + */ + @GetMapping(value = "/queryById") + public Result queryById(@RequestParam(name = "id", required = true) String id) { + OpenApiLog OpenApiLog = service.getById(id); + return Result.ok(OpenApiLog); + } +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/controller/OpenApiPermissionController.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/controller/OpenApiPermissionController.java new file mode 100644 index 000000000..6d3324dfa --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/controller/OpenApiPermissionController.java @@ -0,0 +1,35 @@ +package org.jeecg.modules.openapi.controller; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.system.base.controller.JeecgController; +import org.jeecg.modules.openapi.entity.OpenApiPermission; +import org.jeecg.modules.openapi.service.OpenApiPermissionService; +import org.springframework.web.bind.annotation.*; + +import java.util.Arrays; +import java.util.List; + +@RestController +@RequestMapping("/openapi/permission") +public class OpenApiPermissionController extends JeecgController { + + @PostMapping("add") + public Result add(@RequestBody OpenApiPermission openApiPermission) { + List list = Arrays.asList(openApiPermission.getApiId().split(",")); + if (CollectionUtil.isNotEmpty(list)) { + list.forEach(l->{ + OpenApiPermission saveApiPermission = new OpenApiPermission(); + saveApiPermission.setApiId(l); + saveApiPermission.setApiAuthId(openApiPermission.getApiAuthId()); + service.save(saveApiPermission); + }); + } + return Result.ok("保存成功"); + } + @GetMapping("/list") + public Result list( String apiAuthId) { + return Result.ok(service.list(Wrappers.lambdaQuery().eq(OpenApiPermission::getApiAuthId,apiAuthId))); + } +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/entity/OpenApi.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/entity/OpenApi.java new file mode 100644 index 000000000..92c62386a --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/entity/OpenApi.java @@ -0,0 +1,98 @@ +package org.jeecg.modules.openapi.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.Date; + +/** + * 接口表 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +public class OpenApi implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId(type = IdType.ASSIGN_ID) + private String id; + + /** + * 接口名称 + */ + private String name; + + /** + * 请求方式,如POST、GET + */ + private String requestMethod; + + /** + * 对外开放的相对接口路径 + */ + private String requestUrl; + + /** + * IP 黑名单 + */ + private String blackList; + /** + * 请求头json + */ + private String headersJson; + /** + * 请求参数json + */ + private String paramsJson; + + + /** + * 目前仅支持json + */ + private String body; + + /** + * 原始接口路径 + */ + private String originUrl; + + /** + * 状态(1:正常 2:废弃 ) + */ + private Integer status; + + /** + * 删除状态(0,正常,1已删除) + */ + @TableLogic + private Integer delFlag; + + /** + * 创建人 + */ + private String createBy; + + /** + * 创建时间 + */ + private Date createTime; + + /** + * 更新人 + */ + private String updateBy; + + /** + * 更新时间 + */ + private Date updateTime; +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/entity/OpenApiAuth.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/entity/OpenApiAuth.java new file mode 100644 index 000000000..c95963adb --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/entity/OpenApiAuth.java @@ -0,0 +1,70 @@ +package org.jeecg.modules.openapi.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.jeecg.common.aspect.annotation.Dict; + +import java.io.Serializable; +import java.util.Date; + +/** + * 权限表 + * @date 2024/12/10 9:38 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +public class OpenApiAuth implements Serializable { + + private static final long serialVersionUID = -5933153354153738498L; + + /** + * id + */ + @TableId(type = IdType.ASSIGN_ID) + private String id; + + /** + * 受权名称 + */ + private String name; + + /** + * access key + */ + private String ak; + + /** + * secret key + */ + private String sk; + + /** + * 系统用户ID + */ + @Dict(dictTable = "sys_user",dicCode = "id",dicText = "username") + private String systemUserId; + + /** + * 创建人 + */ + private String createBy; + + /** + * 创建时间 + */ + private Date createTime; + + /** + * 更新人 + */ + private String updateBy; + + /** + * 更新时间 + */ + private Date updateTime; +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/entity/OpenApiHeader.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/entity/OpenApiHeader.java new file mode 100644 index 000000000..48ec9a05f --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/entity/OpenApiHeader.java @@ -0,0 +1,39 @@ +package org.jeecg.modules.openapi.entity; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + * 请求头表 + * @date 2024/12/10 14:37 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +public class OpenApiHeader implements Serializable { + private static final long serialVersionUID = 5032708503120184683L; + + + /** + * key + */ + private String headerKey; + + /** + * 是否必填(0:否,1:是) + */ + private Integer required; + + /** + * 默认值 + */ + private String defaultValue; + + /** + * 说明 + */ + private String note; +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/entity/OpenApiLog.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/entity/OpenApiLog.java new file mode 100644 index 000000000..80d2c2607 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/entity/OpenApiLog.java @@ -0,0 +1,52 @@ +package org.jeecg.modules.openapi.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.Date; + +/** + * 调用记录表 + * @date 2024/12/10 9:41 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +public class OpenApiLog implements Serializable { + private static final long serialVersionUID = -5870384488947863579L; + + /** + * id + */ + @TableId(type = IdType.ASSIGN_ID) + private String id; + + /** + * 接口ID + */ + private String apiId; + + /** + * 调用ID + */ + private String callAuthId; + + /** + * 调用时间 + */ + private Date callTime; + + /** + * 耗时 + */ + private Long usedTime; + + /** + * 响应时间 + */ + private Date responseTime; +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/entity/OpenApiParam.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/entity/OpenApiParam.java new file mode 100644 index 000000000..cd042b4df --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/entity/OpenApiParam.java @@ -0,0 +1,38 @@ +package org.jeecg.modules.openapi.entity; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + * query部分参数表 + * @date 2024/12/10 14:37 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +public class OpenApiParam implements Serializable { + private static final long serialVersionUID = -6174831468578022357L; + + /** + * key + */ + private String paramKey; + + /** + * 是否必填(0:否,1:是) + */ + private Integer required; + + /** + * 默认值 + */ + private String defaultValue; + + /** + * 说明 + */ + private String note; +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/entity/OpenApiPermission.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/entity/OpenApiPermission.java new file mode 100644 index 000000000..661b14940 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/entity/OpenApiPermission.java @@ -0,0 +1,55 @@ +package org.jeecg.modules.openapi.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.Date; + +/** + * + * @date 2024/12/19 17:41 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +public class OpenApiPermission implements Serializable { + /** + * id + */ + @TableId(type = IdType.ASSIGN_ID) + private String id; + + /** + * 接口ID + */ + private String apiId; + + /** + * 认证ID + */ + private String apiAuthId; + + /** + * 创建人 + */ + private String createBy; + + /** + * 创建时间 + */ + private Date createTime; + + /** + * 更新人 + */ + private String updateBy; + + /** + * 更新时间 + */ + private Date updateTime; +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/filter/ApiAuthFilter.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/filter/ApiAuthFilter.java new file mode 100644 index 000000000..a301d13b6 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/filter/ApiAuthFilter.java @@ -0,0 +1,204 @@ +package org.jeecg.modules.openapi.filter; + +import jakarta.servlet.*; +import jakarta.servlet.http.HttpServletRequest; +import lombok.extern.slf4j.Slf4j; +import org.jeecg.common.exception.JeecgBootException; +import org.jeecg.modules.openapi.entity.OpenApi; +import org.jeecg.modules.openapi.entity.OpenApiAuth; +import org.jeecg.modules.openapi.entity.OpenApiLog; +import org.jeecg.modules.openapi.entity.OpenApiPermission; +import org.jeecg.modules.openapi.service.OpenApiAuthService; +import org.jeecg.modules.openapi.service.OpenApiLogService; +import org.jeecg.modules.openapi.service.OpenApiPermissionService; +import org.jeecg.modules.openapi.service.OpenApiService; +import org.springframework.util.StringUtils; +import org.springframework.web.context.WebApplicationContext; + +import java.io.IOException; +import java.security.MessageDigest; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +/** + * @date 2024/12/19 16:55 + */ +@Slf4j +public class ApiAuthFilter implements Filter { + + private OpenApiLogService openApiLogService; + private OpenApiAuthService openApiAuthService; + private OpenApiPermissionService openApiPermissionService; + private OpenApiService openApiService; + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + long startTime = System.currentTimeMillis(); + Date callTime = new Date(); + + HttpServletRequest request = (HttpServletRequest)servletRequest; + String ip = request.getRemoteAddr(); + + String appkey = request.getHeader("appkey"); + String signature = request.getHeader("signature"); + String timestamp = request.getHeader("timestamp"); + + OpenApi openApi = findOpenApi(request); + + // IP 黑名单核验 + checkBlackList(openApi, ip); + + // 签名核验 + checkSignValid(appkey, signature, timestamp); + + OpenApiAuth openApiAuth = openApiAuthService.getByAppkey(appkey); + // 认证信息核验 + checkSignature(appkey, signature, timestamp, openApiAuth); + // 业务核验 + checkPermission(openApi, openApiAuth); + + filterChain.doFilter(servletRequest, servletResponse); + long endTime = System.currentTimeMillis(); + + OpenApiLog openApiLog = new OpenApiLog(); + openApiLog.setApiId(openApi.getId()); + openApiLog.setCallAuthId(openApiAuth.getId()); + openApiLog.setCallTime(callTime); + openApiLog.setUsedTime(endTime - startTime); + openApiLog.setResponseTime(new Date()); + openApiLogService.save(openApiLog); + } + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + ServletContext servletContext = filterConfig.getServletContext(); + WebApplicationContext applicationContext = (WebApplicationContext)servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); + this.openApiService = applicationContext.getBean(OpenApiService.class); + this.openApiLogService = applicationContext.getBean(OpenApiLogService.class); + this.openApiAuthService = applicationContext.getBean(OpenApiAuthService.class); + this.openApiPermissionService = applicationContext.getBean(OpenApiPermissionService.class); + } + + /** + * IP 黑名单核验 + * @param openApi + * @param ip + */ + protected void checkBlackList(OpenApi openApi, String ip) { + if (!StringUtils.hasText(openApi.getBlackList())) { + return; + } + + List blackList = Arrays.asList(openApi.getBlackList().split(",")); + if (blackList.contains(ip)) { + throw new JeecgBootException("目标接口限制IP[" + ip + "]进行访问,IP已记录,请停止访问"); + } + } + + /** + * 签名验证 + * @param appkey + * @param signature + * @param timestamp + * @return + */ + protected void checkSignValid(String appkey, String signature, String timestamp) { + if (!StringUtils.hasText(appkey)) { + throw new JeecgBootException("appkey为空"); + } + if (!StringUtils.hasText(signature)) { + throw new JeecgBootException("signature为空"); + } + if (!StringUtils.hasText(timestamp)) { + throw new JeecgBootException("timastamp时间戳为空"); + } + if (!timestamp.matches("[0-9]*")) { + throw new JeecgBootException("timastamp时间戳不合法"); + } + if (System.currentTimeMillis() - Long.parseLong(timestamp) > 5 * 60 * 1000) { + throw new JeecgBootException("signature签名已过期(超过五分钟)"); + } + } + + /** + * 认证信息核验 + * @param appKey + * @param signature + * @param timestamp + * @param openApiAuth + * @return + * @throws Exception + */ + protected void checkSignature(String appKey, String signature, String timestamp, OpenApiAuth openApiAuth) { + if(openApiAuth==null){ + throw new JeecgBootException("不存在认证信息"); + } + + if(!appKey.equals(openApiAuth.getAk())){ + throw new JeecgBootException("appkey错误"); + } + + if (!signature.equals(md5(appKey + openApiAuth.getSk() + timestamp))) { + throw new JeecgBootException("signature签名错误"); + } + } + + protected void checkPermission(OpenApi openApi, OpenApiAuth openApiAuth) { + List permissionList = openApiPermissionService.findByAuthId(openApiAuth.getId()); + + boolean hasPermission = false; + for (OpenApiPermission permission : permissionList) { + if (permission.getApiId().equals(openApi.getId())) { + hasPermission = true; + break; + } + } + + if (!hasPermission) { + throw new JeecgBootException("该appKey未授权当前接口"); + } + } + + /** + * @return String 返回类型 + * @Title: MD5 + * @Description: 【MD5加密】 + */ + protected static String md5(String sourceStr) { + String result = ""; + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + md.update(sourceStr.getBytes("utf-8")); + byte[] hash = md.digest(); + int i; + StringBuffer buf = new StringBuffer(32); + for (int offset = 0; offset < hash.length; offset++) { + i = hash[offset]; + if (i < 0) { + i += 256; + } + if (i < 16) { + buf.append("0"); + } + buf.append(Integer.toHexString(i)); + } + result = buf.toString(); + } catch (Exception e) { + log.error("sign签名错误", e); + } + return result; + } + + protected OpenApi findOpenApi(HttpServletRequest request) { + String uri = request.getRequestURI(); + String path = uri.substring(uri.lastIndexOf("/") + 1); + return openApiService.findByPath(path); + } + + public static void main(String[] args) { + long timestamp = System.currentTimeMillis(); + System.out.println("timestamp:" + timestamp); + System.out.println("signature:" + md5("ak-eAU25mrMxhtaZsyS" + "rjxMqB6YyUXpSHAz4DCIz8vZ5aozQQiV" + timestamp)); + } +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/filter/ApiFilterConfig.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/filter/ApiFilterConfig.java new file mode 100644 index 000000000..bac823fe1 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/filter/ApiFilterConfig.java @@ -0,0 +1,25 @@ +package org.jeecg.modules.openapi.filter; + +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @date 2024/12/19 17:09 + */ +@Configuration +public class ApiFilterConfig { + + /** + * + * @Description: 【注册api加密过滤器】 + */ + @Bean + public FilterRegistrationBean authFilter() { + FilterRegistrationBean registration = new FilterRegistrationBean<>(); + registration.setFilter(new ApiAuthFilter()); + registration.setName("apiAuthFilter"); + registration.addUrlPatterns("/openapi/call/*"); + return registration; + } +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/generator/AKSKGenerator.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/generator/AKSKGenerator.java new file mode 100644 index 000000000..c93069c09 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/generator/AKSKGenerator.java @@ -0,0 +1,36 @@ +package org.jeecg.modules.openapi.generator; + +import java.security.SecureRandom; + +/** + * AK/SK生成器 + */ +public class AKSKGenerator { + private static final String CHAR_POOL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + private static final int AK_LENGTH = 16; // Adjust as per requirements + private static final int SK_LENGTH = 32; + + public static String[] genAKSKPair() { + return new String[]{genAK(), genSK()}; + } + + public static String genAK() { + return "ak-" + generateRandomString(AK_LENGTH); + } + + public static String genSK() { + return generateRandomString(SK_LENGTH); + } + + + private static String generateRandomString(int length) { + SecureRandom random = new SecureRandom(); + StringBuilder sb = new StringBuilder(length); + + for (int i = 0; i < length; i++) { + sb.append(CHAR_POOL.charAt(random.nextInt(CHAR_POOL.length()))); + } + + return sb.toString(); + } +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/generator/PathGenerator.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/generator/PathGenerator.java new file mode 100644 index 000000000..eaf5e5327 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/generator/PathGenerator.java @@ -0,0 +1,28 @@ +package org.jeecg.modules.openapi.generator; + +import lombok.experimental.UtilityClass; + +import java.util.Random; + +/** + * @date 2024/12/10 10:00 + */ +@UtilityClass +public class PathGenerator { + + // Base62字符集 + private static final String BASE62 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + + /** + * 生成随机路径 + * @return + */ + public static String genPath() { + StringBuilder result = new StringBuilder(); + Random random = new Random(); + for (int i=0; i<8; i++) { + result.append(BASE62.charAt(random.nextInt(62))); + } + return result.toString(); + } +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/mapper/OpenApiAuthMapper.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/mapper/OpenApiAuthMapper.java new file mode 100644 index 000000000..4ec70f132 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/mapper/OpenApiAuthMapper.java @@ -0,0 +1,12 @@ +package org.jeecg.modules.openapi.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.jeecg.modules.openapi.entity.OpenApiAuth; + +/** + * @date 2024/12/10 9:49 + */ +@Mapper +public interface OpenApiAuthMapper extends BaseMapper { +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/mapper/OpenApiLogMapper.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/mapper/OpenApiLogMapper.java new file mode 100644 index 000000000..8035085e0 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/mapper/OpenApiLogMapper.java @@ -0,0 +1,12 @@ +package org.jeecg.modules.openapi.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.jeecg.modules.openapi.entity.OpenApiLog; + +/** + * @date 2024/12/10 9:50 + */ +@Mapper +public interface OpenApiLogMapper extends BaseMapper { +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/mapper/OpenApiMapper.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/mapper/OpenApiMapper.java new file mode 100644 index 000000000..f9a4b6758 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/mapper/OpenApiMapper.java @@ -0,0 +1,9 @@ +package org.jeecg.modules.openapi.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.jeecg.modules.openapi.entity.OpenApi; + +@Mapper +public interface OpenApiMapper extends BaseMapper { +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/mapper/OpenApiPermissionMapper.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/mapper/OpenApiPermissionMapper.java new file mode 100644 index 000000000..18f246c72 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/mapper/OpenApiPermissionMapper.java @@ -0,0 +1,12 @@ +package org.jeecg.modules.openapi.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.jeecg.modules.openapi.entity.OpenApiPermission; + +/** + * @date 2024/12/19 17:43 + */ +@Mapper +public interface OpenApiPermissionMapper extends BaseMapper { +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/OpenApiAuthService.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/OpenApiAuthService.java new file mode 100644 index 000000000..011513f35 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/OpenApiAuthService.java @@ -0,0 +1,11 @@ +package org.jeecg.modules.openapi.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import org.jeecg.modules.openapi.entity.OpenApiAuth; + +/** + * @date 2024/12/10 9:50 + */ +public interface OpenApiAuthService extends IService { + OpenApiAuth getByAppkey(String appkey); +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/OpenApiLogService.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/OpenApiLogService.java new file mode 100644 index 000000000..929d5095d --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/OpenApiLogService.java @@ -0,0 +1,10 @@ +package org.jeecg.modules.openapi.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import org.jeecg.modules.openapi.entity.OpenApiLog; + +/** + * @date 2024/12/10 9:51 + */ +public interface OpenApiLogService extends IService { +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/OpenApiPermissionService.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/OpenApiPermissionService.java new file mode 100644 index 000000000..af541639e --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/OpenApiPermissionService.java @@ -0,0 +1,13 @@ +package org.jeecg.modules.openapi.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import org.jeecg.modules.openapi.entity.OpenApiPermission; + +import java.util.List; + +/** + * @date 2024/12/19 17:44 + */ +public interface OpenApiPermissionService extends IService { + List findByAuthId(String authId); +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/OpenApiService.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/OpenApiService.java new file mode 100644 index 000000000..8b58889f7 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/OpenApiService.java @@ -0,0 +1,8 @@ +package org.jeecg.modules.openapi.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import org.jeecg.modules.openapi.entity.OpenApi; + +public interface OpenApiService extends IService { + OpenApi findByPath(String path); +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/impl/OpenApiAuthServiceImpl.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/impl/OpenApiAuthServiceImpl.java new file mode 100644 index 000000000..549994a73 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/impl/OpenApiAuthServiceImpl.java @@ -0,0 +1,19 @@ +package org.jeecg.modules.openapi.service.impl; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.jeecg.modules.openapi.entity.OpenApiAuth; +import org.jeecg.modules.openapi.mapper.OpenApiAuthMapper; +import org.jeecg.modules.openapi.service.OpenApiAuthService; +import org.springframework.stereotype.Service; + +/** + * @date 2024/12/10 9:51 + */ +@Service +public class OpenApiAuthServiceImpl extends ServiceImpl implements OpenApiAuthService { + @Override + public OpenApiAuth getByAppkey(String appkey) { + return baseMapper.selectOne(Wrappers.lambdaUpdate(OpenApiAuth.class).eq(OpenApiAuth::getAk, appkey), false); + } +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/impl/OpenApiLogServiceImpl.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/impl/OpenApiLogServiceImpl.java new file mode 100644 index 000000000..c723b7fcd --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/impl/OpenApiLogServiceImpl.java @@ -0,0 +1,14 @@ +package org.jeecg.modules.openapi.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.jeecg.modules.openapi.entity.OpenApiLog; +import org.jeecg.modules.openapi.mapper.OpenApiLogMapper; +import org.jeecg.modules.openapi.service.OpenApiLogService; +import org.springframework.stereotype.Service; + +/** + * @date 2024/12/10 9:53 + */ +@Service +public class OpenApiLogServiceImpl extends ServiceImpl implements OpenApiLogService { +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/impl/OpenApiPermissionServiceImpl.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/impl/OpenApiPermissionServiceImpl.java new file mode 100644 index 000000000..34dcce092 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/impl/OpenApiPermissionServiceImpl.java @@ -0,0 +1,21 @@ +package org.jeecg.modules.openapi.service.impl; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.jeecg.modules.openapi.entity.OpenApiPermission; +import org.jeecg.modules.openapi.mapper.OpenApiPermissionMapper; +import org.jeecg.modules.openapi.service.OpenApiPermissionService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @date 2024/12/19 17:44 + */ +@Service +public class OpenApiPermissionServiceImpl extends ServiceImpl implements OpenApiPermissionService { + @Override + public List findByAuthId(String authId) { + return baseMapper.selectList(Wrappers.lambdaQuery(OpenApiPermission.class).eq(OpenApiPermission::getApiAuthId, authId)); + } +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/impl/OpenApiServiceImpl.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/impl/OpenApiServiceImpl.java new file mode 100644 index 000000000..7c72d528c --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/service/impl/OpenApiServiceImpl.java @@ -0,0 +1,16 @@ +package org.jeecg.modules.openapi.service.impl; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.jeecg.modules.openapi.entity.OpenApi; +import org.jeecg.modules.openapi.mapper.OpenApiMapper; +import org.jeecg.modules.openapi.service.OpenApiService; +import org.springframework.stereotype.Service; + +@Service +public class OpenApiServiceImpl extends ServiceImpl implements OpenApiService { + @Override + public OpenApi findByPath(String path) { + return baseMapper.selectOne(Wrappers.lambdaQuery(OpenApi.class).eq(OpenApi::getRequestUrl, path), false); + } +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerDefinition.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerDefinition.java new file mode 100644 index 000000000..eaf9e156f --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerDefinition.java @@ -0,0 +1,14 @@ +package org.jeecg.modules.openapi.swagger; + +import lombok.Data; + +import java.util.Map; + +/** + * @date 2025/1/26 11:17 + */ +@Data +public class SwaggerDefinition { + private String type; + private Map properties; +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerDefinitionProperties.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerDefinitionProperties.java new file mode 100644 index 000000000..51ac51426 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerDefinitionProperties.java @@ -0,0 +1,13 @@ +package org.jeecg.modules.openapi.swagger; + +import lombok.Data; + +/** + * @date 2025/1/26 13:54 + */ +@Data +public class SwaggerDefinitionProperties { + private String type; + private String example; + private String description; +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerInfo.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerInfo.java new file mode 100644 index 000000000..e2ca84693 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerInfo.java @@ -0,0 +1,16 @@ +package org.jeecg.modules.openapi.swagger; + +import lombok.Data; + +/** + * @date 2025/1/26 11:05 + */ +@Data +public class SwaggerInfo { + private String description; + private String version; + private String title; + private String termsOfService; + private SwaggerInfoContact contact; + private SwaggerInfoLicense license; +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerInfoContact.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerInfoContact.java new file mode 100644 index 000000000..c46d17c10 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerInfoContact.java @@ -0,0 +1,11 @@ +package org.jeecg.modules.openapi.swagger; + +import lombok.Data; + +/** + * @date 2025/1/26 11:08 + */ +@Data +public class SwaggerInfoContact { + private String name; +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerInfoLicense.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerInfoLicense.java new file mode 100644 index 000000000..fc4b68b69 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerInfoLicense.java @@ -0,0 +1,12 @@ +package org.jeecg.modules.openapi.swagger; + +import lombok.Data; + +/** + * @date 2025/1/26 11:09 + */ +@Data +public class SwaggerInfoLicense { + private String name; + private String url; +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerModel.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerModel.java new file mode 100644 index 000000000..dd0b732e2 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerModel.java @@ -0,0 +1,21 @@ +package org.jeecg.modules.openapi.swagger; + +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @date 2025/1/26 11:05 + */ +@Data +public class SwaggerModel { + private String swagger; + private SwaggerInfo info; + private String host; + private String basePath; + private List tags; + private List schemes; + private Map> paths; + private Map definitions; +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerOperation.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerOperation.java new file mode 100644 index 000000000..3fe6f8924 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerOperation.java @@ -0,0 +1,20 @@ +package org.jeecg.modules.openapi.swagger; + +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @date 2025/1/26 11:16 + */ +@Data +public class SwaggerOperation { + private List tags; + private String summary; + private String description; + private String operationId; + private List produces; + private List parameters; + private Map responses; +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerOperationParameter.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerOperationParameter.java new file mode 100644 index 000000000..dac52a978 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerOperationParameter.java @@ -0,0 +1,17 @@ +package org.jeecg.modules.openapi.swagger; + +import lombok.Data; + +import java.util.Map; + +/** + * @date 2025/1/26 11:43 + */ +@Data +public class SwaggerOperationParameter { + private String name; + private String in; + private String description; + private Boolean required; + private Map schema; +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerOperationResponse.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerOperationResponse.java new file mode 100644 index 000000000..cb749d374 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerOperationResponse.java @@ -0,0 +1,14 @@ +package org.jeecg.modules.openapi.swagger; + +import lombok.Data; + +import java.util.Map; + +/** + * @date 2025/1/26 11:47 + */ +@Data +public class SwaggerOperationResponse { + private String description; + private Map schema; +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerSchema.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerSchema.java new file mode 100644 index 000000000..ef9a0d00e --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerSchema.java @@ -0,0 +1,16 @@ +package org.jeecg.modules.openapi.swagger; + +/** + * @date 2025/1/26 11:51 + */ +public class SwaggerSchema { + private String $ref; + + public String get$ref() { + return $ref; + } + + public void set$ref(String $ref) { + this.$ref = $ref; + } +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerTag.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerTag.java new file mode 100644 index 000000000..f0281e5ba --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/openapi/swagger/SwaggerTag.java @@ -0,0 +1,11 @@ +package org.jeecg.modules.openapi.swagger; + +import lombok.Data; + +/** + * @date 2025/1/26 11:15 + */ +@Data +public class SwaggerTag { + private String name; +}