diff --git a/czsj-admin/src/main/java/com/czsj/web/controller/flink/api/UploadApiController.java b/czsj-admin/src/main/java/com/czsj/web/controller/flink/api/UploadApiController.java index 7410509..dd60361 100644 --- a/czsj-admin/src/main/java/com/czsj/web/controller/flink/api/UploadApiController.java +++ b/czsj-admin/src/main/java/com/czsj/web/controller/flink/api/UploadApiController.java @@ -3,7 +3,7 @@ package com.czsj.web.controller.flink.api; import com.czsj.bigdata.entity.BaseResource; import com.czsj.bigdata.mapper.BaseResourceMapper; -import com.czsj.common.config.czsjConfig; +import com.czsj.common.config.CzsjConfig; import com.czsj.common.utils.ReadYmlUtil; import com.czsj.common.utils.file.FileUploadUtils; import com.czsj.common.utils.file.FileUtils; @@ -58,7 +58,7 @@ public class UploadApiController extends BaseController { @RequestMapping(value = "/upload", method = RequestMethod.POST, consumes = "multipart/form-data") public RestResult upload(HttpServletRequest request, @RequestParam(value="resourceId") String resourceId,@RequestParam(value="remarks") String remarks,@RequestParam("file") MultipartFile file) { try { - String uploadPath = czsjConfig.getUploadPath(); + String uploadPath = CzsjConfig.getUploadPath(); //通过ID查资源服务器信息 BaseResource baseResource = baseResourceMapper.getById(Integer.parseInt(resourceId)); log.info("uploadPath={}", uploadPath); @@ -92,7 +92,7 @@ public class UploadApiController extends BaseController { public RestResult deleteFile(Long id) { try { UploadFileDTO uploadFileById = uploadFileService.getUploadFileById(id); - String uploadPath = czsjConfig.getUploadPath(); + String uploadPath = CzsjConfig.getUploadPath(); // String[] split = uploadFileById.getDownloadJarHttp().split("/"); // String filePath = uploadPath + "/" + split[split.length-4] + "/" + split[split.length-3] + "/" + split[split.length-2] + "/" + uploadFileById.getFilePath(); String filePath = uploadPath + "/" + uploadFileById.getFilePath(); diff --git a/czsj-admin/src/main/java/com/czsj/web/controller/market/ApiLogController.java b/czsj-admin/src/main/java/com/czsj/web/controller/market/ApiLogController.java new file mode 100644 index 0000000..97501ef --- /dev/null +++ b/czsj-admin/src/main/java/com/czsj/web/controller/market/ApiLogController.java @@ -0,0 +1,135 @@ +package com.czsj.web.controller.market; + +import cn.hutool.core.util.StrUtil; +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.czsj.common.core.controller.BaseController; +import com.czsj.common.core.domain.AjaxResult; +import com.czsj.core.database.core.JsonPage; +import com.czsj.market.dto.ApiLogDto; +import com.czsj.market.entity.ApiLogEntity; +import com.czsj.market.mapstruct.ApiLogMapper; +import com.czsj.market.query.ApiLogQuery; +import com.czsj.market.service.ApiLogService; +import com.czsj.market.vo.ApiLogVo; +import com.czsj.metadata.validate.ValidationGroups; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.stream.Collectors; + +/** + *

+ * api调用日志信息表 前端控制器 + *

+ * + * @author yuwei + * @since 2020-08-21 + */ +@Api(tags = {"api调用日志信息表"}) +@RestController +@RequestMapping("market/apiLogs") +public class ApiLogController extends BaseController { + + @Autowired + private ApiLogService apiLogService; + + @Autowired + private ApiLogMapper apiLogMapper; + + /** + * 通过ID查询信息 + * + * @param id + * @return + */ + @ApiOperation(value = "获取详细信息", notes = "根据url的id来获取详细信息") + @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path") + @GetMapping("/{id}") + public AjaxResult getApiLogById(@PathVariable String id) { + ApiLogEntity apiLogEntity = apiLogService.getApiLogById(id); + return AjaxResult.success(apiLogMapper.toVO(apiLogEntity)); + } + + /** + * 分页查询信息 + * + * @param apiLogQuery + * @return + */ + @ApiOperation(value = "分页查询", notes = "") + @ApiImplicitParams({ + @ApiImplicitParam(name = "apiLogQuery", value = "查询实体apiLogQuery", required = true, dataTypeClass = ApiLogQuery.class) + }) + @GetMapping("/page") + public AjaxResult getApiLogPage(ApiLogQuery apiLogQuery) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.like(StrUtil.isNotBlank(apiLogQuery.getApiName()), "api.api_name", apiLogQuery.getApiName()); + IPage page = apiLogService.page(new Page<>(apiLogQuery.getPageNum(), apiLogQuery.getPageSize()), queryWrapper); + List collect = page.getRecords().stream().map(apiLogMapper::toVO).collect(Collectors.toList()); + JsonPage jsonPage = new JsonPage<>(page.getCurrent(), page.getSize(), page.getTotal(), collect); + return AjaxResult.success(jsonPage); + } + + /** + * 添加 + * @param apiLog + * @return + */ + @ApiOperation(value = "添加信息", notes = "根据apiLog对象添加信息") + @ApiImplicitParam(name = "apiLog", value = "详细实体apiLog", required = true, dataType = "ApiLogDto") + @PostMapping() + public AjaxResult saveApiLog(@RequestBody @Validated({ValidationGroups.Insert.class}) ApiLogDto apiLog) { + ApiLogEntity apiLogEntity = apiLogService.saveApiLog(apiLog); + return AjaxResult.success(apiLogMapper.toVO(apiLogEntity)); + } + + /** + * 修改 + * @param apiLog + * @return + */ + @ApiOperation(value = "修改信息", notes = "根据url的id来指定修改对象,并根据传过来的信息来修改详细信息") + @ApiImplicitParams({ + @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path"), + @ApiImplicitParam(name = "apiLog", value = "详细实体apiLog", required = true, dataType = "ApiLogDto") + }) + @PutMapping("/{id}") + public AjaxResult updateApiLog(@PathVariable String id, @RequestBody @Validated({ValidationGroups.Update.class}) ApiLogDto apiLog) { + ApiLogEntity apiLogEntity = apiLogService.updateApiLog(apiLog); + return AjaxResult.success(apiLogMapper.toVO(apiLogEntity)); + } + + /** + * 删除 + * @param id + * @return + */ + @ApiOperation(value = "删除", notes = "根据url的id来指定删除对象") + @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path") + @DeleteMapping("/{id}") + public AjaxResult deleteApiLogById(@PathVariable String id) { + apiLogService.deleteApiLogById(id); + return AjaxResult.success(); + } + + /** + * 批量删除 + * @param ids + * @return + */ + @ApiOperation(value = "批量删除角色", notes = "根据url的ids来批量删除对象") + @ApiImplicitParam(name = "ids", value = "ID集合", required = true, dataType = "List", paramType = "path") + @DeleteMapping("/batch/{ids}") + public AjaxResult deleteApiLogBatch(@PathVariable List ids) { + apiLogService.deleteApiLogBatch(ids); + return AjaxResult.success(); + } +} diff --git a/czsj-admin/src/main/java/com/czsj/web/controller/market/ApiMaskController.java b/czsj-admin/src/main/java/com/czsj/web/controller/market/ApiMaskController.java new file mode 100644 index 0000000..773927b --- /dev/null +++ b/czsj-admin/src/main/java/com/czsj/web/controller/market/ApiMaskController.java @@ -0,0 +1,145 @@ +package com.czsj.web.controller.market; + + +import cn.hutool.core.util.StrUtil; +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.czsj.common.core.controller.BaseController; +import com.czsj.common.core.domain.AjaxResult; +import com.czsj.core.database.core.JsonPage; +import com.czsj.market.dto.ApiMaskDto; +import com.czsj.market.entity.ApiMaskEntity; +import com.czsj.market.mapstruct.ApiMaskMapper; +import com.czsj.market.query.ApiMaskQuery; +import com.czsj.market.service.ApiMaskService; +import com.czsj.market.vo.ApiMaskVo; +import com.czsj.metadata.validate.ValidationGroups; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.stream.Collectors; + +/** + *

+ * 数据API脱敏信息表 前端控制器 + *

+ * + * @author yuwei + * @since 2020-04-14 + */ +@Api(tags = {"数据API脱敏信息表"}) +@RestController +@RequestMapping("market/apiMasks") +public class ApiMaskController extends BaseController { + + @Autowired + private ApiMaskService apiMaskService; + + @Autowired + private ApiMaskMapper apiMaskMapper; + + /** + * 通过ID查询信息 + * + * @param id + * @return + */ + @ApiOperation(value = "获取详细信息", notes = "根据url的id来获取详细信息") + @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path") + @GetMapping("/{id}") + public AjaxResult getApiMaskById(@PathVariable String id) { + ApiMaskEntity apiMaskEntity = apiMaskService.getApiMaskById(id); + return AjaxResult.success(apiMaskMapper.toVO(apiMaskEntity)); + } + + /** + * 通过ID查询信息 + * + * @param id + * @return + */ + @ApiOperation(value = "获取详细信息", notes = "根据url的id来获取详细信息") + @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path") + @GetMapping("/api/{id}") + public AjaxResult getApiMaskByApiId(@PathVariable String id) { + ApiMaskEntity apiMaskEntity = apiMaskService.getApiMaskByApiId(id); + return AjaxResult.success(apiMaskMapper.toVO(apiMaskEntity)); + } + + /** + * 分页查询信息 + * + * @param apiMaskQuery + * @return + */ + @ApiOperation(value = "分页查询", notes = "") + @ApiImplicitParams({ + @ApiImplicitParam(name = "apiMaskQuery", value = "查询实体apiMaskQuery", required = true, dataTypeClass = ApiMaskQuery.class) + }) + @GetMapping("/page") + public AjaxResult getApiMaskPage(ApiMaskQuery apiMaskQuery) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.like(StrUtil.isNotBlank(apiMaskQuery.getMaskName()), "mask_name", apiMaskQuery.getMaskName()); + IPage page = apiMaskService.page(new Page<>(apiMaskQuery.getPageNum(), apiMaskQuery.getPageSize()), queryWrapper); + List collect = page.getRecords().stream().map(apiMaskMapper::toVO).collect(Collectors.toList()); + JsonPage jsonPage = new JsonPage<>(page.getCurrent(), page.getSize(), page.getTotal(), collect); + return AjaxResult.success(jsonPage); + } + + /** + * 添加 + * @param apiMask + * @return + */ + @ApiOperation(value = "添加信息", notes = "根据apiMask对象添加信息") + @ApiImplicitParam(name = "apiMask", value = "详细实体apiMask", required = true, dataType = "ApiMaskDto") + @PostMapping() + public AjaxResult saveApiMask(@RequestBody @Validated({ValidationGroups.Insert.class}) ApiMaskDto apiMask) { + apiMaskService.saveApiMask(apiMask); + return AjaxResult.success(); + } + + /** + * 修改 + * @param apiMask + * @return + */ + @ApiOperation(value = "修改信息", notes = "根据url的id来指定修改对象,并根据传过来的信息来修改详细信息") + @ApiImplicitParams({ + @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path"), + @ApiImplicitParam(name = "apiMask", value = "详细实体apiMask", required = true, dataType = "ApiMaskDto") + }) + @PutMapping("/{id}") + public AjaxResult updateApiMask(@PathVariable String id, @RequestBody @Validated({ValidationGroups.Update.class}) ApiMaskDto apiMask) { + apiMaskService.updateApiMask(apiMask); + return AjaxResult.success(); + } + + /** + * 删除 + * @param id + * @return + */ + @ApiOperation(value = "删除", notes = "根据url的id来指定删除对象") + @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path") + @DeleteMapping("/{id}") + public AjaxResult deleteApiMaskById(@PathVariable String id) { + apiMaskService.deleteApiMaskById(id); + return AjaxResult.success(); + } + + @ApiOperation(value = "批量删除", notes = "根据url的ids来批量删除对象") + @ApiImplicitParam(name = "ids", value = "ID集合", required = true, dataType = "List", paramType = "path") + @DeleteMapping("/batch/{ids}") + public AjaxResult deleteApiMaskBatch(@PathVariable List ids) { + apiMaskService.deleteApiMaskBatch(ids); + return AjaxResult.success(); + } +} diff --git a/czsj-admin/src/main/java/com/czsj/web/controller/market/DataApiController.java b/czsj-admin/src/main/java/com/czsj/web/controller/market/DataApiController.java new file mode 100644 index 0000000..9398e0e --- /dev/null +++ b/czsj-admin/src/main/java/com/czsj/web/controller/market/DataApiController.java @@ -0,0 +1,218 @@ +package com.czsj.web.controller.market; + +import cn.hutool.core.util.StrUtil; +import com.aspose.words.Document; +import com.aspose.words.SaveFormat; +import com.aspose.words.SaveOptions; +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.czsj.common.core.controller.BaseController; +import com.czsj.common.core.domain.AjaxResult; +import com.czsj.core.database.core.JsonPage; +import com.czsj.market.dto.DataApiDto; +import com.czsj.market.dto.SqlParseDto; +import com.czsj.market.entity.DataApiEntity; +import com.czsj.market.mapstruct.DataApiMapper; +import com.czsj.market.query.DataApiQuery; +import com.czsj.market.service.DataApiService; +import com.czsj.market.vo.DataApiVo; +import com.czsj.market.vo.SqlParseVo; +import com.czsj.metadata.validate.ValidationGroups; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import net.sf.jsqlparser.JSQLParserException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.io.OutputStream; +import java.sql.SQLException; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + *

+ * 数据API信息表 前端控制器 + *

+ * + * @author yuwei + * @since 2020-03-31 + */ +@Api(tags = {"数据API信息表"}) +@RestController +@RequestMapping("market/dataApis") +public class DataApiController extends BaseController { + + @Autowired + private DataApiService dataApiService; + + @Autowired + private DataApiMapper dataApiMapper; + + /** + * 通过ID查询信息 + * + * @param id + * @return + */ + @ApiOperation(value = "获取详细信息", notes = "根据url的id来获取详细信息") + @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path") + @GetMapping("/{id}") + public AjaxResult getDataApiById(@PathVariable String id) { + DataApiEntity dataApiEntity = dataApiService.getDataApiById(id); + return AjaxResult.success(dataApiMapper.toVO(dataApiEntity)); + } + + @ApiOperation(value = "获取列表", notes = "") + @GetMapping("/list") + public AjaxResult getDataApiList() { + QueryWrapper queryWrapper = new QueryWrapper<>(); + List list = dataApiService.list(queryWrapper); + List collect = list.stream().map(dataApiMapper::toVO).collect(Collectors.toList()); + return AjaxResult.success(collect); + } + + /** + * 分页查询信息 + * + * @param dataApiQuery + * @return + */ + @ApiOperation(value = "分页查询", notes = "") + @ApiImplicitParams({ + @ApiImplicitParam(name = "dataApiQuery", value = "查询实体dataApiQuery", required = true, dataTypeClass = DataApiQuery.class) + }) + @GetMapping("/page") + public AjaxResult getDataApiPage(DataApiQuery dataApiQuery) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.like(StrUtil.isNotBlank(dataApiQuery.getApiName()), "api_name", dataApiQuery.getApiName()); + IPage page = dataApiService.page(new Page<>(dataApiQuery.getPageNum(), dataApiQuery.getPageSize()), queryWrapper); + List collect = page.getRecords().stream().map(dataApiMapper::toVO).collect(Collectors.toList()); + JsonPage jsonPage = new JsonPage<>(page.getCurrent(), page.getSize(), page.getTotal(), collect); + return AjaxResult.success(jsonPage); + } + + /** + * 添加 + * @param dataApi + * @return + */ + @ApiOperation(value = "添加信息", notes = "根据dataApi对象添加信息") + @ApiImplicitParam(name = "dataApi", value = "详细实体dataApi", required = true, dataType = "DataApiDto") + @PostMapping() + public AjaxResult saveDataApi(@RequestBody @Validated({ValidationGroups.Insert.class}) DataApiDto dataApi) { + dataApiService.saveDataApi(dataApi); + return AjaxResult.success(); + } + + /** + * 修改 + * @param dataApi + * @return + */ + @ApiOperation(value = "修改信息", notes = "根据url的id来指定修改对象,并根据传过来的信息来修改详细信息") + @ApiImplicitParams({ + @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path"), + @ApiImplicitParam(name = "dataApi", value = "详细实体dataApi", required = true, dataType = "DataApiDto") + }) + @PutMapping("/{id}") + public AjaxResult updateDataApi(@PathVariable String id, @RequestBody @Validated({ValidationGroups.Update.class}) DataApiDto dataApi) { + dataApiService.updateDataApi(dataApi); + return AjaxResult.success(); + } + + /** + * 删除 + * @param id + * @return + */ + @ApiOperation(value = "删除", notes = "根据url的id来指定删除对象") + @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path") + @DeleteMapping("/{id}") + public AjaxResult deleteDataApiById(@PathVariable String id) { + dataApiService.deleteDataApiById(id); + return AjaxResult.success(); + } + + @ApiOperation(value = "批量删除", notes = "根据url的ids来批量删除对象") + @ApiImplicitParam(name = "ids", value = "ID集合", required = true, dataType = "List", paramType = "path") + @DeleteMapping("/batch/{ids}") + public AjaxResult deleteDataApiBatch(@PathVariable List ids) { + dataApiService.deleteDataApiBatch(ids); + return AjaxResult.success(); + } + + /** + * SQL解析 + * @param sqlParseDto + * @return + */ + @ApiOperation(value = "SQL解析") + @ApiImplicitParam(name = "sqlParseDto", value = "SQL解析实体sqlParseDto", required = true, dataType = "SqlParseDto") + @PostMapping("/sql/parse") + public AjaxResult sqlParse(@RequestBody @Validated SqlParseDto sqlParseDto) throws SQLException, JSQLParserException { + SqlParseVo sqlParseVo = dataApiService.sqlParse(sqlParseDto); + return AjaxResult.success(sqlParseVo); + } + + /** + * 拷贝接口 + * @param id + * @return + */ + @PostMapping("/{id}/copy") + public AjaxResult copyDataApi(@PathVariable String id) { + dataApiService.copyDataApi(id); + return AjaxResult.success(); + } + + /** + * 发布接口 + * @param id + * @return + */ + @PostMapping(value = "/{id}/release") + public AjaxResult releaseDataApi(@PathVariable String id){ + dataApiService.releaseDataApi(id); + return AjaxResult.success(); + } + + /** + * 注销接口 + * @param id + * @return + */ + @PostMapping(value = "/{id}/cancel") + public AjaxResult cancelDataApi(@PathVariable String id){ + dataApiService.cancelDataApi(id); + return AjaxResult.success(); + } + + @ApiOperation(value = "接口文档", notes = "根据url的id来指定生成接口文档对象") + @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path") + @PostMapping("/word/{id}") + public void wordDataApi(@PathVariable String id, HttpServletResponse response) throws Exception { + // 清空response + response.reset(); + // 设置response的Header + response.setContentType("application/octet-stream;charset=utf-8"); + // 设置content-disposition响应头控制浏览器以下载的形式打开文件 + response.addHeader("Content-Disposition", "attachment;filename=" + new String("接口文档.docx".getBytes())); + Document doc = dataApiService.wordDataApi(id); + OutputStream out = response.getOutputStream(); + doc.save(out, SaveOptions.createSaveOptions(SaveFormat.DOCX)); + out.flush(); + out.close(); + } + + @GetMapping("/detail/{id}") + public AjaxResult getDataApiDetailById(@PathVariable String id) { + Map map = dataApiService.getDataApiDetailById(id); + return AjaxResult.success(map); + } +} diff --git a/czsj-admin/src/main/java/com/czsj/web/controller/market/GetApiLogAspect.java b/czsj-admin/src/main/java/com/czsj/web/controller/market/GetApiLogAspect.java new file mode 100644 index 0000000..1d62f4f --- /dev/null +++ b/czsj-admin/src/main/java/com/czsj/web/controller/market/GetApiLogAspect.java @@ -0,0 +1,119 @@ +package com.czsj.web.controller.market; + + +import cn.hutool.core.map.MapUtil; +import com.alibaba.fastjson.JSON; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.czsj.async.AsyncTask; +import com.czsj.common.core.data.R; +import com.czsj.core.database.core.DataConstant; +import com.czsj.core.database.core.PageResult; +import com.czsj.core.util.IPUtil; +import com.czsj.core.util.RequestHolder; +import com.czsj.market.dto.ApiLogDto; +import com.czsj.market.utils.MD5Util; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.Map; + +@Slf4j +@Aspect +@Component +public class GetApiLogAspect { + + @Autowired + private AsyncTask asyncTask; + + @Pointcut("execution(* com.czsj.web.controller.market.marketInnerController.getApiMaskByApiId(..))") + public void logPointCut() { + System.out.println(1111); + } + + /** + * 通知方法会将目标方法封装起来 + * + * @param joinPoint 切点 + */ + @Around(value = "logPointCut()") + public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable { + long startTime = System.currentTimeMillis(); + Object result = joinPoint.proceed(); + long endTime = System.currentTimeMillis(); + ApiLogDto log = getLog(); + log.setTime(endTime - startTime); + R r = JSON.parseObject(JSON.toJSONString(result), R.class); + if (r != null) { + log.setCallerSize(JSON.parseObject(JSON.toJSONString(r.getData()), PageResult.class).getData().size()); + } + handleLog(joinPoint,log); + return result; + } + + /** + * 通知方法会在目标方法抛出异常后执行 + * + * @param joinPoint + * @param e + */ + @AfterThrowing(value = "logPointCut()", throwing = "e") + public void doAfterThrowing(JoinPoint joinPoint, Exception e) { + log.error("出错{}", e.getMessage()); + ApiLogDto log = getLog(); + log.setStatus(DataConstant.EnableState.DISABLE.getKey()); + log.setMsg(e.getMessage()); + handleLog(joinPoint, log); + } + + private ApiLogDto getLog() { + ApiLogDto log = new ApiLogDto(); + HttpServletRequest request = RequestHolder.getHttpServletRequest(); + String apiKey = request.getHeader("api_key"); + String secretKey = request.getHeader("secret_key"); + try { + MD5Util mt = MD5Util.getInstance(); + String apiId = mt.decode(apiKey); + String userId = mt.decode(secretKey); + log.setCallerId(userId); + log.setApiId(apiId); + } catch (Exception e) {} + String uri = request.getRequestURI(); + log.setCallerUrl(uri); + String ipAddr = IPUtil.getIpAddr(request); + log.setCallerIp(ipAddr); + log.setCallerDate(LocalDateTime.now()); + log.setStatus(DataConstant.EnableState.ENABLE.getKey()); + return log; + } + + protected void handleLog(final JoinPoint joinPoint, ApiLogDto log) { + Map pathVariables = (Map) joinPoint.getArgs()[2]; + Map requestParams = (Map) joinPoint.getArgs()[3]; + Map requestBodys = (Map) joinPoint.getArgs()[4]; + Map params = new HashMap<>(); + if (MapUtil.isNotEmpty(pathVariables)) { + params.putAll(pathVariables); + } + if (MapUtil.isNotEmpty(requestParams)) { + params.putAll(requestParams); + } + if (MapUtil.isNotEmpty(requestBodys)) { + params.putAll(requestBodys); + } + try { + log.setCallerParams(new ObjectMapper().writeValueAsString(params)); + } catch (JsonProcessingException e) {} + asyncTask.doTask(log); + } +} diff --git a/czsj-admin/src/main/java/com/czsj/web/controller/market/PostApiLogAspect.java b/czsj-admin/src/main/java/com/czsj/web/controller/market/PostApiLogAspect.java new file mode 100644 index 0000000..7766c35 --- /dev/null +++ b/czsj-admin/src/main/java/com/czsj/web/controller/market/PostApiLogAspect.java @@ -0,0 +1,119 @@ +package com.czsj.web.controller.market; + + +import cn.hutool.core.map.MapUtil; +import com.alibaba.fastjson.JSON; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.czsj.async.AsyncTask; +import com.czsj.common.core.data.R; +import com.czsj.core.database.core.DataConstant; +import com.czsj.core.database.core.PageResult; +import com.czsj.core.util.IPUtil; +import com.czsj.core.util.RequestHolder; +import com.czsj.market.dto.ApiLogDto; +import com.czsj.market.utils.MD5Util; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.Map; + +@Slf4j +@Aspect +@Component +public class PostApiLogAspect { + + @Autowired + private AsyncTask asyncTask; + + @Pointcut("execution(* com.czsj.web.controller.market.marketInnerController.postApiMaskByApiId(..))") + public void logPointCut() { + System.out.println(1111); + } + + /** + * 通知方法会将目标方法封装起来 + * + * @param joinPoint 切点 + */ + @Around(value = "logPointCut()") + public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable { + long startTime = System.currentTimeMillis(); + Object result = joinPoint.proceed(); + long endTime = System.currentTimeMillis(); + ApiLogDto log = getLog(); + log.setTime(endTime - startTime); + R r = JSON.parseObject(JSON.toJSONString(result), R.class); + if (r != null) { + log.setCallerSize(JSON.parseObject(JSON.toJSONString(r.getData()), PageResult.class).getData().size()); + } + handleLog(joinPoint,log); + return result; + } + + /** + * 通知方法会在目标方法抛出异常后执行 + * + * @param joinPoint + * @param e + */ + @AfterThrowing(value = "logPointCut()", throwing = "e") + public void doAfterThrowing(JoinPoint joinPoint, Exception e) { + log.error("出错{}", e.getMessage()); + ApiLogDto log = getLog(); + log.setStatus(DataConstant.EnableState.DISABLE.getKey()); + log.setMsg(e.getMessage()); + handleLog(joinPoint, log); + } + + private ApiLogDto getLog() { + ApiLogDto log = new ApiLogDto(); + HttpServletRequest request = RequestHolder.getHttpServletRequest(); + String apiKey = request.getHeader("api_key"); + String secretKey = request.getHeader("secret_key"); + try { + MD5Util mt = MD5Util.getInstance(); + String apiId = mt.decode(apiKey); + String userId = mt.decode(secretKey); + log.setCallerId(userId); + log.setApiId(apiId); + } catch (Exception e) {} + String uri = request.getRequestURI(); + log.setCallerUrl(uri); + String ipAddr = IPUtil.getIpAddr(request); + log.setCallerIp(ipAddr); + log.setCallerDate(LocalDateTime.now()); + log.setStatus(DataConstant.EnableState.ENABLE.getKey()); + return log; + } + + protected void handleLog(final JoinPoint joinPoint, ApiLogDto log) { + Map pathVariables = (Map) joinPoint.getArgs()[2]; + Map requestParams = (Map) joinPoint.getArgs()[3]; + Map requestBodys = (Map) joinPoint.getArgs()[4]; + Map params = new HashMap<>(); + if (MapUtil.isNotEmpty(pathVariables)) { + params.putAll(pathVariables); + } + if (MapUtil.isNotEmpty(requestParams)) { + params.putAll(requestParams); + } + if (MapUtil.isNotEmpty(requestBodys)) { + params.putAll(requestBodys); + } + try { + log.setCallerParams(new ObjectMapper().writeValueAsString(params)); + } catch (JsonProcessingException e) {} + asyncTask.doTask(log); + } +} diff --git a/czsj-admin/src/main/java/com/czsj/web/controller/market/marketInnerController.java b/czsj-admin/src/main/java/com/czsj/web/controller/market/marketInnerController.java new file mode 100644 index 0000000..56b3c65 --- /dev/null +++ b/czsj-admin/src/main/java/com/czsj/web/controller/market/marketInnerController.java @@ -0,0 +1,128 @@ +package com.czsj.web.controller.market; + +import cn.hutool.core.map.MapUtil; +import com.aspose.words.net.System.Data.DataException; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.czsj.common.core.controller.BaseController; +import com.czsj.common.core.domain.AjaxResult; +import com.czsj.core.database.core.DataConstant; +import com.czsj.core.database.core.PageResult; +import com.czsj.market.entity.ApiMaskEntity; +import com.czsj.market.entity.DataApiEntity; +import com.czsj.market.handler.MappingHandlerMapping; +import com.czsj.market.handler.RequestHandler; +import com.czsj.market.service.ApiMaskService; +import com.czsj.market.service.DataApiService; +import lombok.SneakyThrows; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("/inner") +public class marketInnerController extends BaseController { + + @Autowired + private DataApiService dataApiService; + + @Autowired + private ApiMaskService apiMaskService; + + @Autowired + private RequestHandler requestHandler; + + + @GetMapping("/apis/{id}") + public DataApiEntity getDataApiById(@PathVariable("id") String id) { + DataApiEntity dataApiEntity = dataApiService.getDataApiById(id); + return dataApiEntity; + } + + @GetMapping("/apis/release/list") + public List getReleaseDataApiList() { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("status", DataConstant.ApiState.RELEASE.getKey()); + List dataApiEntityList = dataApiService.list(queryWrapper); + return dataApiEntityList; + } + + @GetMapping("/apiMasks/api/{id}") + public ApiMaskEntity getApiMaskByApiId(@PathVariable("id") String id) { + ApiMaskEntity apiMaskEntity = apiMaskService.getApiMaskByApiId(id); + return apiMaskEntity; + } + + @SneakyThrows + @ResponseBody + @GetMapping("/data/api") + public Object getApiMaskByApiId(HttpServletRequest request, HttpServletResponse response, + @PathVariable(required = false) Map pathVariables, + @RequestParam(required = false) Map requestParams, + @RequestBody(required = false) Map requestBodys) { + + DataApiEntity api; + Map params = new HashMap<>(); + if (MapUtil.isNotEmpty(pathVariables)) { + params.putAll(pathVariables); + } + if (MapUtil.isNotEmpty(requestParams)) { + params.putAll(requestParams); + } + if (MapUtil.isNotEmpty(requestBodys)) { + params.putAll(requestBodys); + } + api = MappingHandlerMapping.getMappingApiInfoA(params.get("apiCode").toString()); + params.remove("apiCode"); + if(null == api){ + throw new DataException("api接口未发布或不存在!"); + } + // 序列化 + api = requestHandler.getObjectMapper().readValue(requestHandler.getObjectMapper().writeValueAsString(api), DataApiEntity.class); + // 执行前置拦截器 + requestHandler.getRequestInterceptor().preHandle(request, response, api, params); + PageResult> value = requestHandler.getApiMappingEngine().execute(api, params); + // 执行后置拦截器 + requestHandler.getRequestInterceptor().postHandle(request, response, api, params, value); + return AjaxResult.success(value); + } + + @SneakyThrows + @ResponseBody + @PostMapping("/data/api") + public Object postApiMaskByApiId(HttpServletRequest request, HttpServletResponse response, + @PathVariable(required = false) Map pathVariables, + @RequestParam(required = false) Map requestParams, + @RequestBody(required = false) Map requestBodys) { + + DataApiEntity api; + Map params = new HashMap<>(); + if (MapUtil.isNotEmpty(pathVariables)) { + params.putAll(pathVariables); + } + if (MapUtil.isNotEmpty(requestParams)) { + params.putAll(requestParams); + } + if (MapUtil.isNotEmpty(requestBodys)) { + params.putAll(requestBodys); + } + api = MappingHandlerMapping.getMappingApiInfoA(params.get("apiCode").toString()); + params.remove("apiCode"); + if(null == api){ + throw new DataException("api接口未发布或不存在!"); + } + // 序列化 + api = requestHandler.getObjectMapper().readValue(requestHandler.getObjectMapper().writeValueAsString(api), DataApiEntity.class); + // 执行前置拦截器 + requestHandler.getRequestInterceptor().preHandle(request, response, api, params); + PageResult> value = requestHandler.getApiMappingEngine().execute(api, params); + // 执行后置拦截器 + requestHandler.getRequestInterceptor().postHandle(request, response, api, params, value); + return AjaxResult.success(value); + } + +} diff --git a/czsj-admin/src/main/java/com/czsj/web/controller/metadata/MetadataChangeRecordController.java b/czsj-admin/src/main/java/com/czsj/web/controller/metadata/MetadataChangeRecordController.java new file mode 100644 index 0000000..e384518 --- /dev/null +++ b/czsj-admin/src/main/java/com/czsj/web/controller/metadata/MetadataChangeRecordController.java @@ -0,0 +1,137 @@ +package com.czsj.web.controller.metadata; + + +import cn.hutool.core.util.StrUtil; +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.czsj.common.core.controller.BaseController; +import com.czsj.common.core.domain.AjaxResult; +import com.czsj.core.database.core.JsonPage; +import com.czsj.metadata.dto.MetadataChangeRecordDto; +import com.czsj.metadata.entity.MetadataChangeRecordEntity; +import com.czsj.metadata.mapstruct.MetadataChangeRecordMapper; +import com.czsj.metadata.query.MetadataChangeRecordQuery; +import com.czsj.metadata.service.MetadataChangeRecordService; +import com.czsj.metadata.validate.ValidationGroups; +import com.czsj.metadata.vo.MetadataChangeRecordVo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.stream.Collectors; + +/** + *

+ * 元数据变更记录表 前端控制器 + *

+ * + * @author yuwei + * @since 2020-07-30 + */ +@Api(tags = {"元数据变更记录表"}) +@RestController +@RequestMapping("/changeRecords") +public class MetadataChangeRecordController extends BaseController { + + @Autowired + private MetadataChangeRecordService metadataChangeRecordService; + + @Autowired + private MetadataChangeRecordMapper metadataChangeRecordMapper; + + /** + * 通过ID查询信息 + * + * @param id + * @return + */ + @ApiOperation(value = "获取详细信息", notes = "根据url的id来获取详细信息") + @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path") + @GetMapping("/{id}") + public AjaxResult getMetadataChangeRecordById(@PathVariable String id) { + MetadataChangeRecordEntity metadataChangeRecordEntity = metadataChangeRecordService.getMetadataChangeRecordById(id); + return AjaxResult.success(metadataChangeRecordMapper.toVO(metadataChangeRecordEntity)); + } + + /** + * 分页查询信息 + * + * @param metadataChangeRecordQuery + * @return + */ + @ApiOperation(value = "分页查询", notes = "") + @ApiImplicitParams({ + @ApiImplicitParam(name = "metadataChangeRecordQuery", value = "查询实体metadataChangeRecordQuery", required = true, dataTypeClass = MetadataChangeRecordQuery.class) + }) + @GetMapping("/page") + public AjaxResult getMetadataChangeRecordPage(MetadataChangeRecordQuery metadataChangeRecordQuery) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(StrUtil.isNotBlank(metadataChangeRecordQuery.getObjectId()), "r.object_id", metadataChangeRecordQuery.getObjectId()); + queryWrapper.like(StrUtil.isNotBlank(metadataChangeRecordQuery.getFieldName()), "r.field_name", metadataChangeRecordQuery.getFieldName()); + IPage page = metadataChangeRecordService.page(new Page<>(metadataChangeRecordQuery.getPageNum(), metadataChangeRecordQuery.getPageSize()), queryWrapper); + List collect = page.getRecords().stream().map(metadataChangeRecordMapper::toVO).collect(Collectors.toList()); + JsonPage jsonPage = new JsonPage<>(page.getCurrent(), page.getSize(), page.getTotal(), collect); + return AjaxResult.success(jsonPage); + } + + /** + * 添加 + * @param metadataChangeRecord + * @return + */ + @ApiOperation(value = "添加信息", notes = "根据metadataChangeRecord对象添加信息") + @ApiImplicitParam(name = "metadataChangeRecord", value = "详细实体metadataChangeRecord", required = true, dataType = "MetadataChangeRecordDto") + @PostMapping() + public AjaxResult saveMetadataChangeRecord(@RequestBody @Validated({ValidationGroups.Insert.class}) MetadataChangeRecordDto metadataChangeRecord) { + MetadataChangeRecordEntity metadataChangeRecordEntity = metadataChangeRecordService.saveMetadataChangeRecord(metadataChangeRecord); + return AjaxResult.success(metadataChangeRecordMapper.toVO(metadataChangeRecordEntity)); + } + + /** + * 修改 + * @param metadataChangeRecord + * @return + */ + @ApiOperation(value = "修改信息", notes = "根据url的id来指定修改对象,并根据传过来的信息来修改详细信息") + @ApiImplicitParams({ + @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path"), + @ApiImplicitParam(name = "metadataChangeRecord", value = "详细实体metadataChangeRecord", required = true, dataType = "MetadataChangeRecordDto") + }) + @PutMapping("/{id}") + public AjaxResult updateMetadataChangeRecord(@PathVariable String id, @RequestBody @Validated({ValidationGroups.Update.class}) MetadataChangeRecordDto metadataChangeRecord) { + MetadataChangeRecordEntity metadataChangeRecordEntity = metadataChangeRecordService.updateMetadataChangeRecord(metadataChangeRecord); + return AjaxResult.success(metadataChangeRecordMapper.toVO(metadataChangeRecordEntity)); + } + + /** + * 删除 + * @param id + * @return + */ + @ApiOperation(value = "删除", notes = "根据url的id来指定删除对象") + @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path") + @DeleteMapping("/{id}") + public AjaxResult deleteMetadataChangeRecordById(@PathVariable String id) { + metadataChangeRecordService.deleteMetadataChangeRecordById(id); + return AjaxResult.success(); + } + + /** + * 批量删除 + * @param ids + * @return + */ + @ApiOperation(value = "批量删除角色", notes = "根据url的ids来批量删除对象") + @ApiImplicitParam(name = "ids", value = "ID集合", required = true, dataType = "List", paramType = "path") + @DeleteMapping("/batch/{ids}") + public AjaxResult deleteMetadataChangeRecordBatch(@PathVariable List ids) { + metadataChangeRecordService.deleteMetadataChangeRecordBatch(ids); + return AjaxResult.success(); + } +} diff --git a/czsj-admin/src/main/java/com/czsj/web/controller/metadata/MetadataColumnController.java b/czsj-admin/src/main/java/com/czsj/web/controller/metadata/MetadataColumnController.java new file mode 100644 index 0000000..adc72c3 --- /dev/null +++ b/czsj-admin/src/main/java/com/czsj/web/controller/metadata/MetadataColumnController.java @@ -0,0 +1,162 @@ +package com.czsj.web.controller.metadata; + +import cn.hutool.core.util.StrUtil; +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.czsj.common.core.controller.BaseController; +import com.czsj.common.core.domain.AjaxResult; +import com.czsj.core.database.core.JsonPage; +import com.czsj.metadata.dto.MetadataColumnDto; +import com.czsj.metadata.entity.MetadataColumnEntity; +import com.czsj.metadata.query.MetadataColumnQuery; +import com.czsj.metadata.service.MetadataColumnMapper; +import com.czsj.metadata.service.MetadataColumnService; +import com.czsj.metadata.validate.ValidationGroups; +import com.czsj.metadata.vo.MetadataColumnVo; +import com.czsj.metadata.vo.MetadataTreeVo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.stream.Collectors; + +/** + *

+ * 元数据信息表 前端控制器 + *

+ * + * @author yuwei + * @since 2020-07-29 + */ +@Api(tags = {"元数据信息表"}) +@RestController +@RequestMapping("/columns") +public class MetadataColumnController extends BaseController { + + @Autowired + private MetadataColumnService metadataColumnService; + + @Autowired + private MetadataColumnMapper metadataColumnMapper; + + /** + * 通过ID查询信息 + * + * @param id + * @return + */ + @ApiOperation(value = "获取详细信息", notes = "根据url的id来获取详细信息") + @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path") + @GetMapping("/{id}") + public AjaxResult getDataMetadataColumnById(@PathVariable String id) { + MetadataColumnEntity metadataColumnEntity = metadataColumnService.getMetadataColumnById(id); + return AjaxResult.success(metadataColumnMapper.toVO(metadataColumnEntity)); + } + + @ApiOperation(value = "获取列表", notes = "") + @GetMapping("/list") + public AjaxResult getDataMetadataColumnList(MetadataColumnQuery metadataColumnQuery) { + List list = metadataColumnService.getDataMetadataColumnList(metadataColumnQuery); + List collect = list.stream().map(metadataColumnMapper::toVO).collect(Collectors.toList()); + return AjaxResult.success(collect); + } + + /** + * 分页查询信息 + * + * @param metadataColumnQuery + * @return + */ + @ApiOperation(value = "分页查询", notes = "") + @ApiImplicitParams({ + @ApiImplicitParam(name = "dataMetadataColumnQuery", value = "查询实体dataMetadataColumnQuery", required = true, dataTypeClass = MetadataColumnQuery.class) + }) + @GetMapping("/page") + public AjaxResult getDataMetadataColumnPage(MetadataColumnQuery metadataColumnQuery) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.like(StrUtil.isNotBlank(metadataColumnQuery.getColumnName()), "c.column_name", metadataColumnQuery.getColumnName()); + queryWrapper.eq(StrUtil.isNotBlank(metadataColumnQuery.getSourceId()), "c.source_id", metadataColumnQuery.getSourceId()); + queryWrapper.eq(StrUtil.isNotBlank(metadataColumnQuery.getTableId()), "c.table_id", metadataColumnQuery.getTableId()); + IPage page = metadataColumnService.pageWithAuth(new Page<>(metadataColumnQuery.getPageNum(), metadataColumnQuery.getPageSize()), queryWrapper); + List collect = page.getRecords().stream().map(metadataColumnMapper::toVO).collect(Collectors.toList()); + JsonPage jsonPage = new JsonPage<>(page.getCurrent(), page.getSize(), page.getTotal(), collect); + return AjaxResult.success(jsonPage); + } + + /** + * 添加 + * @param dataMetadataColumn + * @return + */ + @ApiOperation(value = "添加信息", notes = "根据dataMetadataColumn对象添加信息") + @ApiImplicitParam(name = "dataMetadataColumn", value = "详细实体dataMetadataColumn", required = true, dataType = "DataMetadataColumnDto") + @PostMapping() + public AjaxResult saveDataMetadataColumn(@RequestBody @Validated({ValidationGroups.Insert.class}) MetadataColumnDto dataMetadataColumn) { + MetadataColumnEntity metadataColumnEntity = metadataColumnService.saveMetadataColumn(dataMetadataColumn); + return AjaxResult.success(metadataColumnMapper.toVO(metadataColumnEntity)); + } + + /** + * 修改 + * @param dataMetadataColumn + * @return + */ + @ApiOperation(value = "修改信息", notes = "根据url的id来指定修改对象,并根据传过来的信息来修改详细信息") + @ApiImplicitParams({ + @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path"), + @ApiImplicitParam(name = "dataMetadataColumn", value = "详细实体dataMetadataColumn", required = true, dataType = "DataMetadataColumnDto") + }) + @PutMapping("/{id}") + public AjaxResult updateDataMetadataColumn(@PathVariable String id, @RequestBody @Validated({ValidationGroups.Update.class}) MetadataColumnDto dataMetadataColumn) { + MetadataColumnEntity metadataColumnEntity = metadataColumnService.updateMetadataColumn(dataMetadataColumn); + return AjaxResult.success(metadataColumnMapper.toVO(metadataColumnEntity)); + } + + /** + * 删除 + * @param id + * @return + */ + @ApiOperation(value = "删除", notes = "根据url的id来指定删除对象") + @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path") + @DeleteMapping("/{id}") + public AjaxResult deleteDataMetadataColumnById(@PathVariable String id) { + metadataColumnService.deleteMetadataColumnById(id); + return AjaxResult.success(); + } + + /** + * 批量删除 + * @param ids + * @return + */ + @ApiOperation(value = "批量删除角色", notes = "根据url的ids来批量删除对象") + @ApiImplicitParam(name = "ids", value = "ID集合", required = true, dataType = "List", paramType = "path") + @DeleteMapping("/batch/{ids}") + public AjaxResult deleteDataMetadataColumnBatch(@PathVariable List ids) { + metadataColumnService.deleteMetadataColumnBatch(ids); + return AjaxResult.success(); + } + + /** + * 获取层级树 + * @param level 层级database、table、column + * @return + */ + @ApiOperation(value = "获取层级树", notes = "根据url的层级来获取树对象") + @ApiImplicitParams({ + @ApiImplicitParam(name = "level", value = "层级", required = true, dataType = "String", paramType = "path"), + @ApiImplicitParam(name = "metadataColumnQuery", value = "查询实体metadataColumnQuery", required = false, dataType = "MetadataColumnQuery") + }) + @GetMapping("/tree/{level}") + public AjaxResult getDataMetadataTree(@PathVariable String level, MetadataColumnQuery metadataColumnQuery) { + List list = metadataColumnService.getDataMetadataTree(level, metadataColumnQuery); + return AjaxResult.success(list); + } +} diff --git a/czsj-admin/src/main/java/com/czsj/web/controller/metadata/MetadataSourceController.java b/czsj-admin/src/main/java/com/czsj/web/controller/metadata/MetadataSourceController.java new file mode 100644 index 0000000..7fedcf6 --- /dev/null +++ b/czsj-admin/src/main/java/com/czsj/web/controller/metadata/MetadataSourceController.java @@ -0,0 +1,254 @@ +package com.czsj.web.controller.metadata; + + +import cn.hutool.core.util.StrUtil; +import com.aspose.words.Document; +import com.aspose.words.SaveFormat; +import com.aspose.words.SaveOptions; +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.czsj.common.core.controller.BaseController; +import com.czsj.common.core.domain.AjaxResult; +import com.czsj.common.database.service.DbQuery; +import com.czsj.core.database.core.DbColumn; +import com.czsj.core.database.core.DbTable; +import com.czsj.core.database.core.JsonPage; +import com.czsj.core.database.core.PageResult; +import com.czsj.metadata.dto.MetadataSourceDto; +import com.czsj.metadata.entity.MetadataSourceEntity; +import com.czsj.metadata.query.DbDataQuery; +import com.czsj.metadata.query.MetadataSourceQuery; +import com.czsj.metadata.service.MetadataSourceMapper; +import com.czsj.metadata.service.MetadataSourceService; +import com.czsj.metadata.validate.ValidationGroups; +import com.czsj.metadata.vo.MetadataSourceVo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.io.OutputStream; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + *

+ * 数据源信息表 前端控制器 + *

+ * + * @author yuwei + * @since 2020-03-14 + */ +@Api(tags = {"数据源信息表"}) +@RestController +@RequestMapping("/sources") +public class MetadataSourceController extends BaseController { + + @Autowired + private MetadataSourceService metadataSourceService; + + @Autowired + private MetadataSourceMapper metadataSourceMapper; + + /** + * 通过ID查询信息 + * + * @param id + * @return + */ + @ApiOperation(value = "获取详细信息", notes = "根据url的id来获取详细信息") + @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path") + @GetMapping("/{id}") + public AjaxResult getMetadataSourceById(@PathVariable String id) { + MetadataSourceEntity metadataSourceEntity = metadataSourceService.getMetadataSourceById(id); + return AjaxResult.success(metadataSourceMapper.toVO(metadataSourceEntity)); + } + + @ApiOperation(value = "获取列表", notes = "") + @GetMapping("/list") + public AjaxResult getMetadataSourceList() { + List list = metadataSourceService.getMetadataSourceList(); + List collect = list.stream().map(metadataSourceMapper::toVO).collect(Collectors.toList()); + return AjaxResult.success(collect); + } + + /** + * 分页查询信息 + * + * @param metadataSourceQuery + * @return + */ + @ApiOperation(value = "分页查询", notes = "") + @ApiImplicitParams({ + @ApiImplicitParam(name = "metadataSourceQuery", value = "查询实体metadataSourceQuery", required = true, dataTypeClass = MetadataSourceQuery.class) + }) + @GetMapping("/page") + public AjaxResult getMetadataSourcePage(MetadataSourceQuery metadataSourceQuery) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.like(StrUtil.isNotBlank(metadataSourceQuery.getSourceName()), "s.source_name", metadataSourceQuery.getSourceName()); + IPage page = metadataSourceService.pageWithAuth(new Page<>(metadataSourceQuery.getPageNum(), metadataSourceQuery.getPageSize()), queryWrapper); + List collect = page.getRecords().stream().map(metadataSourceMapper::toVO).collect(Collectors.toList()); + JsonPage jsonPage = new JsonPage<>(page.getCurrent(), page.getSize(), page.getTotal(), collect); + return AjaxResult.success(jsonPage); + } + + /** + * 添加 + * @param metadataSourceDto + * @return + */ + @ApiOperation(value = "添加信息", notes = "根据metadataSourceDto对象添加信息") + @ApiImplicitParam(name = "metadataSourceDto", value = "详细实体metadataSourceDto", required = true, dataType = "MetadataSourceDto") + @PostMapping() + public AjaxResult saveMetadataSource(@RequestBody @Validated({ValidationGroups.Insert.class}) MetadataSourceDto metadataSourceDto) { + metadataSourceDto.setUser(getUsername()); + metadataSourceService.saveMetadataSource(metadataSourceDto); + return AjaxResult.success(); + } + + /** + * 修改 + * @param metadataSourceDto + * @return + */ + @ApiOperation(value = "修改信息", notes = "根据url的id来指定修改对象,并根据传过来的信息来修改详细信息") + @ApiImplicitParams({ + @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path"), + @ApiImplicitParam(name = "metadataSourceDto", value = "详细实体metadataSourceDto", required = true, dataType = "MetadataSourceDto") + }) + @PutMapping("/{id}") + public AjaxResult updateMetadataSource(@PathVariable String id, @RequestBody @Validated({ValidationGroups.Update.class}) MetadataSourceDto metadataSourceDto) { + metadataSourceDto.setUser(getUsername()); + metadataSourceService.updateMetadataSource(metadataSourceDto); + return AjaxResult.success(); + } + + /** + * 删除 + * @param id + * @return + */ + @ApiOperation(value = "删除", notes = "根据url的id来指定删除对象") + @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path") + @DeleteMapping("/{id}") + public AjaxResult deleteMetadataSourceById(@PathVariable String id) { + metadataSourceService.deleteMetadataSourceById(id); + return AjaxResult.success(); + } + + @ApiOperation(value = "批量删除", notes = "根据url的ids来批量删除对象") + @ApiImplicitParam(name = "ids", value = "ID集合", required = true, dataType = "List", paramType = "path") + @DeleteMapping("/batch/{ids}") + public AjaxResult deleteMetadataSourceBatch(@PathVariable List ids) { + metadataSourceService.deleteMetadataSourceBatch(ids); + return AjaxResult.success(); + } + + /** + * 检测数据库连通性 + * @param metadataSourceDto + * @return + */ + @ApiOperation(value = "数据库连通性", notes = "根据数据库配置信息检测数据库连通性") + @ApiImplicitParam(name = "dataSource", value = "详细实体dataSource", required = true, dataType = "DataSourceDto") + @PostMapping("/checkConnection") + public AjaxResult checkConnection(@RequestBody @Validated({ValidationGroups.Insert.class}) MetadataSourceDto metadataSourceDto) { + DbQuery dbQuery = metadataSourceService.checkConnection(metadataSourceDto); + Boolean valid = dbQuery.valid(); + return valid ? AjaxResult.success("数据库连接成功") : AjaxResult.error("数据库连接有误,请检查数据库配置是否正确"); + } + + /** + * 数据库表 + * @param id + * @return + */ + @ApiOperation(value = "数据库表", notes = "根据数据源的id来获取指定数据库表") + @ApiImplicitParams({ + @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path") + }) + @GetMapping("/{id}/tables") + public AjaxResult getDbTables(@PathVariable String id) { + List tables = metadataSourceService.getDbTables(id); + return AjaxResult.success(tables); + } + + /** + * 数据库表结构 + * @param id + * @return + */ + @ApiOperation(value = "数据库表结构", notes = "根据数据源的id来获取指定数据库表的表结构") + @ApiImplicitParams({ + @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path"), + @ApiImplicitParam(name = "tableName", value = "数据库表", required = true, dataType = "String", paramType = "path") + }) + @GetMapping("/{id}/{tableName}/columns") + public AjaxResult getDbTableColumns(@PathVariable String id, @PathVariable String tableName) { + List columns = metadataSourceService.getDbTableColumns(id, tableName); + return AjaxResult.success(columns); + } + + @ApiOperation(value = "获取SQL结果", notes = "根据数据源的id来获取SQL结果") + @ApiImplicitParam(name = "dbDataQuery", value = "详细实体dbDataQuery", required = true, dataType = "DbDataQuery") + @PostMapping("/queryList") + public AjaxResult queryList(@RequestBody @Validated DbDataQuery dbDataQuery) { + DbQuery dbQuery = metadataSourceService.getDbQuery(dbDataQuery.getDataSourceId()); + List> list = dbQuery.queryList(dbDataQuery.getSql()); + return AjaxResult.success(list); + } + + @ApiOperation(value = "分页获取SQL结果", notes = "根据数据源的id来分页获取SQL结果") + @ApiImplicitParam(name = "dbDataQuery", value = "详细实体dbDataQuery", required = true, dataType = "DbDataQuery") + @PostMapping("/queryByPage") + public AjaxResult queryByPage(@RequestBody @Validated DbDataQuery dbDataQuery) { + DbQuery dbQuery = metadataSourceService.getDbQuery(dbDataQuery.getDataSourceId()); + PageResult> page = dbQuery.queryByPage(dbDataQuery.getSql(), dbDataQuery.getOffset(), dbDataQuery.getPageSize()); + page.setPageNum(dbDataQuery.getPageNum()).setPageSize(dbDataQuery.getPageSize()); + return AjaxResult.success(page); + } + + @ApiOperation(value = "同步", notes = "根据url的id来指定同步对象") + @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path") + @PostMapping("/sync/{id}") + public AjaxResult syncMetadata(@PathVariable String id) { + metadataSourceService.syncMetadata(id); + return AjaxResult.success(); + } + + @ApiOperation(value = "数据库设计文档", notes = "根据url的id来指定生成数据库设计文档对象") + @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path") + @PostMapping("/word/{id}") + public void wordMetadata(@PathVariable String id, HttpServletResponse response) throws Exception { + // 清空response + response.reset(); + // 设置response的Header + response.setContentType("application/octet-stream;charset=utf-8"); + // 设置content-disposition响应头控制浏览器以下载的形式打开文件 + response.addHeader("Content-Disposition", "attachment;filename=" + new String("数据库设计文档.doc".getBytes())); + Document doc = metadataSourceService.wordMetadata(id); + OutputStream out = response.getOutputStream(); + doc.save(out, SaveOptions.createSaveOptions(SaveFormat.DOC)); + out.flush(); + out.close(); + } + + /** + * 刷新参数缓存 + * + * @return + */ + @GetMapping("/refresh") + public AjaxResult refreshMetadata() { + metadataSourceService.refreshMetadata(); + return AjaxResult.success(); + } + + +} diff --git a/czsj-admin/src/main/java/com/czsj/web/controller/metadata/MetadataTableController.java b/czsj-admin/src/main/java/com/czsj/web/controller/metadata/MetadataTableController.java new file mode 100644 index 0000000..a7ab271 --- /dev/null +++ b/czsj-admin/src/main/java/com/czsj/web/controller/metadata/MetadataTableController.java @@ -0,0 +1,151 @@ +package com.czsj.web.controller.metadata; + + +import cn.hutool.core.util.StrUtil; +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.czsj.common.core.controller.BaseController; +import com.czsj.common.core.domain.AjaxResult; +import com.czsj.core.database.core.JsonPage; +import com.czsj.metadata.dto.MetadataTableDto; +import com.czsj.metadata.entity.MetadataTableEntity; +import com.czsj.metadata.mapstruct.MetadataTableMapper; +import com.czsj.metadata.query.MetadataTableQuery; +import com.czsj.metadata.service.MetadataTableService; +import com.czsj.metadata.validate.ValidationGroups; +import com.czsj.metadata.vo.MetadataTableVo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.stream.Collectors; + +/** + *

+ * 数据库表信息表 前端控制器 + *

+ * + * @author yuwei + * @since 2020-07-29 + */ +@Api(tags = {"数据库表信息表"}) +@RestController +@RequestMapping("/tables") +public class MetadataTableController extends BaseController { + + @Autowired + private MetadataTableService metadataTableService; + + @Autowired + private MetadataTableMapper metadataTableMapper; + + /** + * 通过ID查询信息 + * + * @param id + * @return + */ + @ApiOperation(value = "获取详细信息", notes = "根据url的id来获取详细信息") + @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path") + @GetMapping("/{id}") + public AjaxResult getDataMetadataTableById(@PathVariable String id) { + MetadataTableEntity metadataTableEntity = metadataTableService.getMetadataTableById(id); + return AjaxResult.success(metadataTableMapper.toVO(metadataTableEntity)); + } + + @ApiOperation(value = "获取列表", notes = "") + @GetMapping("/list") + @PreAuthorize("@ss.hasPermi('metadata:tables:list')") + public AjaxResult getDataMetadataTableList(MetadataTableQuery metadataTableQuery) { + List list = metadataTableService.getDataMetadataTableList(metadataTableQuery); + List collect = list.stream().map(metadataTableMapper::toVO).collect(Collectors.toList()); + return AjaxResult.success(collect); + } + + /** + * 分页查询信息 + * + * @param metadataTableQuery + * @return + */ + @ApiOperation(value = "分页查询", notes = "") + @ApiImplicitParams({ + @ApiImplicitParam(name = "dataMetadataTableQuery", value = "查询实体dataMetadataTableQuery", required = true, dataTypeClass = MetadataTableQuery.class) + }) + @GetMapping("/page") + public AjaxResult getDataMetadataTablePage(MetadataTableQuery metadataTableQuery) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.like(StrUtil.isNotBlank(metadataTableQuery.getTableName()), "t.table_name", metadataTableQuery.getTableName()); + queryWrapper.eq(StrUtil.isNotBlank(metadataTableQuery.getSourceId()), "t.source_id", metadataTableQuery.getSourceId()); + IPage page = metadataTableService.pageWithAuth(new Page<>(metadataTableQuery.getPageNum(), metadataTableQuery.getPageSize()), queryWrapper); + List collect = page.getRecords().stream().map(metadataTableMapper::toVO).collect(Collectors.toList()); + JsonPage jsonPage = new JsonPage<>(page.getCurrent(), page.getSize(), page.getTotal(), collect); + return AjaxResult.success(jsonPage); + } + + /** + * 添加 + * @param dataMetadataTable + * @return + */ + @ApiOperation(value = "添加信息", notes = "根据dataMetadataTable对象添加信息") + @ApiImplicitParam(name = "dataMetadataTable", value = "详细实体dataMetadataTable", required = true, dataType = "DataMetadataTableDto") + @PostMapping() + @PreAuthorize("@ss.hasPermi('metadata:tables:add')") + public AjaxResult saveDataMetadataTable(@RequestBody @Validated({ValidationGroups.Insert.class}) MetadataTableDto dataMetadataTable) { + MetadataTableEntity metadataTableEntity = metadataTableService.saveMetadataTable(dataMetadataTable); + return AjaxResult.success(metadataTableMapper.toVO(metadataTableEntity)); + } + + /** + * 修改 + * @param dataMetadataTable + * @return + */ + @ApiOperation(value = "修改信息", notes = "根据url的id来指定修改对象,并根据传过来的信息来修改详细信息") + @ApiImplicitParams({ + @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path"), + @ApiImplicitParam(name = "dataMetadataTable", value = "详细实体dataMetadataTable", required = true, dataType = "DataMetadataTableDto") + }) + @PutMapping("/{id}") + @PreAuthorize("@ss.hasPermi('metadata:tables:edit')") + public AjaxResult updateDataMetadataTable(@PathVariable String id, @RequestBody @Validated({ValidationGroups.Update.class}) MetadataTableDto dataMetadataTable) { + MetadataTableEntity metadataTableEntity = metadataTableService.updateMetadataTable(dataMetadataTable); + return AjaxResult.success(metadataTableMapper.toVO(metadataTableEntity)); + } + + /** + * 删除 + * @param id + * @return + */ + @ApiOperation(value = "删除", notes = "根据url的id来指定删除对象") + @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path") + @DeleteMapping("/{id}") + @PreAuthorize("@ss.hasPermi('metadata:tables:remove')") + public AjaxResult deleteDataMetadataTableById(@PathVariable String id) { + metadataTableService.deleteMetadataTableById(id); + return AjaxResult.success(); + } + + /** + * 批量删除 + * @param ids + * @return + */ + @ApiOperation(value = "批量删除角色", notes = "根据url的ids来批量删除对象") + @ApiImplicitParam(name = "ids", value = "ID集合", required = true, dataType = "List", paramType = "path") + @DeleteMapping("/batch/{ids}") + @PreAuthorize("@ss.hasPermi('metadata:tables:remove')") + public AjaxResult deleteDataMetadataTableBatch(@PathVariable List ids) { + metadataTableService.deleteMetadataTableBatch(ids); + return AjaxResult.success(); + } +} diff --git a/czsj-admin/src/main/java/com/czsj/web/controller/metadata/SqlConsoleController.java b/czsj-admin/src/main/java/com/czsj/web/controller/metadata/SqlConsoleController.java new file mode 100644 index 0000000..70dc000 --- /dev/null +++ b/czsj-admin/src/main/java/com/czsj/web/controller/metadata/SqlConsoleController.java @@ -0,0 +1,38 @@ +package com.czsj.web.controller.metadata; + + +import com.czsj.common.core.controller.BaseController; +import com.czsj.common.core.domain.AjaxResult; +import com.czsj.metadata.dto.SqlConsoleDto; +import com.czsj.metadata.service.SqlConsoleService; +import com.czsj.metadata.validate.ValidationGroups; +import com.czsj.metadata.vo.SqlConsoleVo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.sql.SQLException; +import java.util.List; + +@RestController +@RequestMapping("/sql") +public class SqlConsoleController extends BaseController { + + @Autowired + private SqlConsoleService sqlConsoleService; + + @PostMapping("/run") + public AjaxResult sqlRun(@RequestBody @Validated SqlConsoleDto sqlConsoleDto) throws SQLException { + List list = sqlConsoleService.sqlRun(sqlConsoleDto); + return AjaxResult.success(list); + } + + @PostMapping("/stop") + public AjaxResult sqlStop(@RequestBody @Validated({ValidationGroups.Other.class}) SqlConsoleDto sqlConsoleDto){ + sqlConsoleService.sqlStop(sqlConsoleDto); + return AjaxResult.success(); + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/config/CzsjConfig.java b/czsj-common/src/main/java/com/czsj/common/config/CzsjConfig.java index 89222bc..b6116e4 100644 --- a/czsj-common/src/main/java/com/czsj/common/config/CzsjConfig.java +++ b/czsj-common/src/main/java/com/czsj/common/config/CzsjConfig.java @@ -119,4 +119,12 @@ public class CzsjConfig { return getProfile() + "/upload"; } + + /** + * 获取临时上传路径 + */ + public static String getTemporaryUploadPath() + { + return getProfile() + "/temporary"; + } } diff --git a/czsj-common/src/main/java/com/czsj/common/core/data/R.java b/czsj-common/src/main/java/com/czsj/common/core/data/R.java new file mode 100644 index 0000000..07fc679 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/core/data/R.java @@ -0,0 +1,88 @@ +package com.czsj.common.core.data; + +import lombok.Getter; + +import java.io.Serializable; + +@Getter +public class R implements Serializable { + + private static final long serialVersionUID = 1L; + + private boolean success; + private int code; + private String msg; + private Object data; + private long timestamp; + + private R() {} + + public static R error() { + return error(null); + } + + public static R error(String message) { + return error(null, message); + } + + public static R error(Integer code, String message) { + if(code == null) { + code = 500; + } + if(message == null) { + message = "服务器内部错误"; + } + return build(code, false, message); + } + + public static R ok() { + return ok(null); + } + + public static R ok(String message) { + return ok(null, message); + } + + public static R ok(Integer code, String message) { + if(code == null) { + code = 200; + } + if(message == null) { + message = "操作成功"; + } + return build(code, true, message); + } + + public static R build(int code, boolean success, String message) { + return new R() + .setCode(code) + .setSuccess(success) + .setMessage(message) + .setTimestamp(System.currentTimeMillis()); + } + + public R setCode(int code) { + this.code = code; + return this; + } + + public R setSuccess(boolean success) { + this.success = success; + return this; + } + public R setMessage(String msg) { + this.msg = msg; + return this; + } + + public R setData(Object data) { + this.data = data; + return this; + } + + public R setTimestamp(long timestamp) { + this.timestamp = timestamp; + return this; + } + +} diff --git a/czsj-common/src/main/java/com/czsj/common/core/redis/RedisCache.java b/czsj-common/src/main/java/com/czsj/common/core/redis/RedisCache.java index 0c304ee..903c89b 100644 --- a/czsj-common/src/main/java/com/czsj/common/core/redis/RedisCache.java +++ b/czsj-common/src/main/java/com/czsj/common/core/redis/RedisCache.java @@ -1,11 +1,5 @@ package com.czsj.common.core.redis; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.TimeUnit; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.BoundSetOperations; import org.springframework.data.redis.core.HashOperations; @@ -13,6 +7,10 @@ import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ValueOperations; import org.springframework.stereotype.Component; +import javax.annotation.Resource; +import java.util.*; +import java.util.concurrent.TimeUnit; + /** * spring redis 工具类 * @@ -265,4 +263,55 @@ public class RedisCache { return redisTemplate.keys(pattern); } + + + /** + * 普通缓存获取 + * + * @param key 键 + * @return 值 + */ + public Object get(String key) { + return key == null ? null : redisTemplate.opsForValue().get(key); + } + + + /** + * HashGet + * + * @param key 键 不能为 null + * @param map 项 不能为 null + * @return 值 + */ + public void putAll(String key, Map map) { + redisTemplate.opsForHash().putAll(key, map); + } + + + + /** + * HashGet + * + * @param key 键 不能为 null + * @param item 项 不能为 null + * @return 值 + */ + public Object hget(String key, String item) { + return redisTemplate.opsForHash().get(key, item); + } + + /** + * 删除缓存 + * + * @param key 可以传一个值 或多个 + */ + public void del(String... key) { + if (key != null && key.length > 0) { + if (key.length == 1) { + redisTemplate.delete(key[0]); + } else { + redisTemplate.delete(Arrays.asList(key)); + } + } + } } diff --git a/czsj-common/src/main/java/com/czsj/common/utils/ListUtils.java b/czsj-common/src/main/java/com/czsj/common/utils/ListUtils.java new file mode 100644 index 0000000..123ee99 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/utils/ListUtils.java @@ -0,0 +1,100 @@ +package com.czsj.common.utils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +public class ListUtils { + private static void stupidMethod2(List listA, List listB) { + System.out.println("数量级为 " + listA.size() + "集合的不同元素为"); + List differList = new ArrayList<>(); + long startTime = System.currentTimeMillis(); + for (String str : listB) { + if (!listA.contains(str)) { + differList.add(str); + } + } + traverse(differList); + long endTime = System.currentTimeMillis(); + System.out.println("使用双层遍历方法 对比耗时: " + (endTime - startTime)); + } + + /** + * 遍历集合,打印出每个元素 + * + * @param list List集合 + */ + private static void traverse(List list) { + for (String str : list) { + System.out.print(str + " "); + } + System.out.println(); + } + + private static void stupidMethod(List listA, List listB) { + System.out.println("数量级为 " + listA.size() + "集合的不同元素为"); + List listABak = new ArrayList<>(listA); // 复制A集合作为备份 + long startTime = System.currentTimeMillis(); + listB.removeAll(listA); // B集合与A集合的不同元素 + traverse(listB); + long endTime = System.currentTimeMillis(); + System.out.println("直接调用java api 方法 对比耗时: " + (endTime - startTime)); +// listABak.removeAll(listB); // A集合与B集合的相同元素 +// listA.removeAll(listABak); // A集合与B集合的不同元素 + } + + /** + * 制造任意个元素的的List集合 + * + * @param size List集合的size + * @return List + */ + private static List dataList(int size) { + List dataList = new ArrayList<>(); + for (int i = 0; i < size; i++) { + dataList.add("" + i); + } + return dataList; + } + + + /** + * 借助Map来获取listA、listB的不同元素集合 + * + * @param listA 集合A + * @param listB 集合B + * @return list + */ + public static List getDifferListByMap(List listA, List listB) { + System.out.println("数量级为 " + listA.size() + "集合的不同元素为"); + List differList = new ArrayList<>(); + Map map = new HashMap<>(); + long beginTime = System.currentTimeMillis(); + for (String strA : listA) { + map.put(strA, 1); + } + for (String strB : listB) { + Integer value = map.get(strB); + if (value != null) { + map.put(strB, ++value); + continue; + } + map.put(strB, 1); + } + + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue() == 1) { //获取不同元素集合 + differList.add(entry.getKey()); + } + } + traverse(differList); + long endTime = System.currentTimeMillis(); + System.out.println("使用map方式遍历, 对比耗时: " + (endTime - beginTime)); + return differList; + } + + } + + diff --git a/czsj-common/src/main/java/com/czsj/common/utils/ReadYmlUtil.java b/czsj-common/src/main/java/com/czsj/common/utils/ReadYmlUtil.java new file mode 100644 index 0000000..f263784 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/utils/ReadYmlUtil.java @@ -0,0 +1,157 @@ +package com.czsj.common.utils; + +import org.yaml.snakeyaml.Yaml; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @Deacription 支持读取${}占位符中的内容 + * @Author levi + * @Date 2022/06/16 9:43 + * @Version 1.0 + **/ +public class ReadYmlUtil { + private static String DATAX_HOME; + + + // ${} 占位符 正则表达式 + private static Pattern p1 = Pattern.compile("\\$\\{.*?\\}"); + + private ReadYmlUtil(){ + throw new AssertionError(); + } + + /** + * key:文件索引名 + * value:配置文件内容 + */ + private static Map ymls = new HashMap<>(); + /** + * String:当前线程需要查询的文件名 + */ + private static ThreadLocal nowFileName = new InheritableThreadLocal<>(); + + private static ThreadLocal profileLocal = new InheritableThreadLocal<>(); + + /** + * 主动设置,初始化当前线程的环境 + * @param profile + */ + public static void setProfile(String profile) { + profileLocal.set(profile); + } + + /** + * 加载配置文件 + * @param fileName + */ + private static void loadYml(String fileName){ + nowFileName.set(fileName); + if (!ymls.containsKey(fileName)){ + ymls.put(fileName , new Yaml().loadAs(ReadYmlUtil.class.getResourceAsStream("/" + fileName),LinkedHashMap.class)); + } + } + + /** + * 读取yml文件中的某个value。 + * 支持解析 yml文件中的 ${} 占位符 + * @param key + * @return Object + */ + private static Object getValue(String key){ + String[] keys = key.split("[.]"); + Map ymlInfo = (Map) ymls.get(nowFileName.get()).clone(); + for (int i = 0; i < keys.length; i++) { + Object value = ymlInfo.get(keys[i]); + if (i < keys.length - 1){ + ymlInfo = (Map) value; + }else if (value == null){ + throw new RuntimeException("key不存在"); + }else { + String g; + String keyChild; + String v1 = value+""; + for(Matcher m = p1.matcher(v1); m.find(); value = v1.replace(g, (String)getValue(keyChild))) { + g = m.group(); + keyChild = g.replaceAll("\\$\\{", "").replaceAll("\\}", ""); + } + return value; + } + } + return ""; + } + + /** + * 读取yml文件中的某个value + * @param fileName yml名称 + * @param key + * @return Object + */ + public static Object getValue(String fileName , String key){ + loadYml(fileName); + return getValue(key); + } + + /** + * 框架私有方法,非通用。 + * 获取 spring.profiles.active的值: test/prod 测试环境/生成环境 + * @return + */ + public static String getProfiles(){ + if (profileLocal.get() == null) { + String value = (String) getValue("application.yml", "spring.profiles.active"); + setProfile(value); + } + return profileLocal.get(); + } + + /** + * 读取yml文件中的某个value,返回String + * @param fileName + * @param key + * @return String + */ + public static String getValueToString(String fileName , String key){ + return (String)getValue(fileName , key); + } + + /** + * 获取 application.yml 的配置 + * @param key + * @return + */ + public static String getValueToString(String key){ + return String.valueOf(getValue("application.yml" , key)); + } + + /** + * 获取 application-test/prod.yml 的配置 + * @param key + * @return + */ + public static String getProfileValueToString(String key){ + String fileName = "application-" + getProfiles() + ".yml"; + return (String)getValue(fileName , key); + } + + /** + * Test + * @param args + */ + public static void main(String[] args) { + // System.out.println(getProfiles()); + //System.out.println(ReadYmlUtil.getValueToString("server.port"));//get application.yml + +// System.out.println(ReadYmlUtil.getValueToString("application.yml", "server.port"));//get other yml +// System.out.println(ReadYmlUtil.getProfileValueToString("Ignite-addr"));// get application-${profile}.yml +// +// ReadYmlUtil.setProfile("test"); //主动修改环境配置 +// System.out.println(ReadYmlUtil.getProfileValueToString("Ignite-addr"));// get application-${profile}.yml + } + + +} diff --git a/czsj-common/src/main/java/com/czsj/common/utils/ThrowableUtil.java b/czsj-common/src/main/java/com/czsj/common/utils/ThrowableUtil.java new file mode 100644 index 0000000..47eedd6 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/utils/ThrowableUtil.java @@ -0,0 +1,26 @@ +package com.czsj.common.utils; + +import java.io.PrintWriter; +import java.io.StringWriter; + +/** + * 异常工具 + */ +public class ThrowableUtil { + + /** + * 获取堆栈信息 + * @param throwable + * @return + */ + public static String getStackTrace(Throwable throwable){ + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + try { + throwable.printStackTrace(pw); + return sw.toString(); + } finally { + pw.close(); + } + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/utils/file/FileUploadUtils.java b/czsj-common/src/main/java/com/czsj/common/utils/file/FileUploadUtils.java index 25e4a8e..6edc314 100644 --- a/czsj-common/src/main/java/com/czsj/common/utils/file/FileUploadUtils.java +++ b/czsj-common/src/main/java/com/czsj/common/utils/file/FileUploadUtils.java @@ -1,11 +1,5 @@ package com.czsj.common.utils.file; -import java.io.File; -import java.io.IOException; -import java.nio.file.Paths; -import java.util.Objects; -import org.apache.commons.io.FilenameUtils; -import org.springframework.web.multipart.MultipartFile; import com.czsj.common.config.CzsjConfig; import com.czsj.common.constant.Constants; import com.czsj.common.exception.file.FileNameLengthLimitExceededException; @@ -14,6 +8,13 @@ import com.czsj.common.exception.file.InvalidExtensionException; import com.czsj.common.utils.DateUtils; import com.czsj.common.utils.StringUtils; import com.czsj.common.utils.uuid.Seq; +import org.apache.commons.io.FilenameUtils; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Paths; +import java.util.Objects; /** * 文件上传工具类 @@ -23,9 +24,9 @@ import com.czsj.common.utils.uuid.Seq; public class FileUploadUtils { /** - * 默认大小 50M + * 默认大小 500M */ - public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024L; + public static final long DEFAULT_MAX_SIZE = 500 * 1024 * 1024; /** * 默认的文件名最大长度 100 @@ -66,6 +67,8 @@ public class FileUploadUtils } } + + /** * 根据文件路径上传 * @@ -86,6 +89,26 @@ public class FileUploadUtils } } + /** + * 根据文件路径上传 + * + * @param baseDir 相对应用的基目录 + * @param file 上传的文件 + * @return 文件名称 + * @throws IOException + */ + public static final String flnkJarupload(String baseDir, MultipartFile file) throws IOException + { + try + { + return flinkJarupload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); + } + catch (Exception e) + { + throw new IOException(e.getMessage(), e); + } + } + /** * 文件上传 * @@ -117,6 +140,37 @@ public class FileUploadUtils return getPathFileName(baseDir, fileName); } + /** + * flink文件上传 + * + * @param baseDir 相对应用的基目录 + * @param file 上传的文件 + * @param allowedExtension 上传文件类型 + * @return 返回上传成功的文件名 + * @throws FileSizeLimitExceededException 如果超出最大大小 + * @throws FileNameLengthLimitExceededException 文件名太长 + * @throws IOException 比如读写文件出错时 + * @throws InvalidExtensionException 文件校验异常 + */ + public static final String flinkJarupload(String baseDir, MultipartFile file, String[] allowedExtension) + throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException, + InvalidExtensionException + { + int fileNamelength = Objects.requireNonNull(file.getOriginalFilename()).length(); + if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH) + { + throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH); + } + + assertAllowed(file, allowedExtension); + + String fileName = file.getOriginalFilename(); + + String absPath = getAbsoluteFile(baseDir, fileName).getAbsolutePath(); + file.transferTo(Paths.get(absPath)); + return getPathFileName(baseDir, fileName); + } + /** * 编码文件名 */ @@ -144,6 +198,9 @@ public class FileUploadUtils { int dirLastIndex = CzsjConfig.getProfile().length() + 1; String currentDir = StringUtils.substring(uploadDir, dirLastIndex); + if("".equals(currentDir)||null==currentDir){ + return Constants.RESOURCE_PREFIX + "/" + fileName; + } return Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + fileName; } @@ -193,6 +250,7 @@ public class FileUploadUtils throw new InvalidExtensionException(allowedExtension, extension, fileName); } } + } /** diff --git a/czsj-common/src/main/java/com/czsj/common/utils/uuid/UUID.java b/czsj-common/src/main/java/com/czsj/common/utils/uuid/UUID.java index dedfde3..db15208 100644 --- a/czsj-common/src/main/java/com/czsj/common/utils/uuid/UUID.java +++ b/czsj-common/src/main/java/com/czsj/common/utils/uuid/UUID.java @@ -1,11 +1,12 @@ package com.czsj.common.utils.uuid; +import com.czsj.common.exception.UtilException; + import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Random; import java.util.concurrent.ThreadLocalRandom; -import com.czsj.common.exception.UtilException; /** * 提供通用唯一识别码(universally unique identifier)(UUID)实现 @@ -66,7 +67,7 @@ public final class UUID implements java.io.Serializable, Comparable } /** - * 获取类型 4(伪随机生成的)UUID 的静态工厂。 + * 获取类型 4(伪随机生成的)UUID 的静态工厂。 使用加密的本地线程伪随机数生成器生成该 UUID。 * * @return 随机生成的 {@code UUID} */ @@ -150,15 +151,15 @@ public final class UUID implements java.io.Serializable, Comparable components[i] = "0x" + components[i]; } - long mostSigBits = Long.decode(components[0]).longValue(); + long mostSigBits = Long.decode(components[0]); mostSigBits <<= 16; - mostSigBits |= Long.decode(components[1]).longValue(); + mostSigBits |= Long.decode(components[1]); mostSigBits <<= 16; - mostSigBits |= Long.decode(components[2]).longValue(); + mostSigBits |= Long.decode(components[2]); - long leastSigBits = Long.decode(components[3]).longValue(); + long leastSigBits = Long.decode(components[3]); leastSigBits <<= 48; - leastSigBits |= Long.decode(components[4]).longValue(); + leastSigBits |= Long.decode(components[4]); return new UUID(mostSigBits, leastSigBits); } diff --git a/czsj-flink-web-common/src/main/java/com/czsj/flink/streaming/web/common/util/UrlUtil.java b/czsj-flink-web-common/src/main/java/com/czsj/flink/streaming/web/common/util/UrlUtil.java index 2881552..56e4bc1 100644 --- a/czsj-flink-web-common/src/main/java/com/czsj/flink/streaming/web/common/util/UrlUtil.java +++ b/czsj-flink-web-common/src/main/java/com/czsj/flink/streaming/web/common/util/UrlUtil.java @@ -1,7 +1,7 @@ package com.czsj.flink.streaming.web.common.util; import ch.ethz.ssh2.Connection; -import com.czsj.common.config.czsjConfig; +import com.czsj.common.config.CzsjConfig; import lombok.extern.slf4j.Slf4j; import com.czsj.common.utils.file.FileUtils; @@ -68,7 +68,7 @@ public class UrlUtil { InputStream inputStream = conn.getInputStream(); //获取自己数组 byte[] getData = readInputStream(inputStream); - String uploadPath = czsjConfig.getTemporaryUploadPath(); + String uploadPath = CzsjConfig.getTemporaryUploadPath(); //文件保存位置 File saveDir = new File(uploadPath); if (!saveDir.exists()) { diff --git a/czsj-framework/src/main/java/com/czsj/framework/config/ServerConfig.java b/czsj-framework/src/main/java/com/czsj/framework/config/ServerConfig.java index 186dc5f..1524db0 100644 --- a/czsj-framework/src/main/java/com/czsj/framework/config/ServerConfig.java +++ b/czsj-framework/src/main/java/com/czsj/framework/config/ServerConfig.java @@ -1,8 +1,16 @@ package com.czsj.framework.config; -import javax.servlet.http.HttpServletRequest; -import org.springframework.stereotype.Component; import com.czsj.common.utils.ServletUtils; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import java.net.URI; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static java.util.regex.Pattern.compile; /** * 服务相关配置 @@ -29,4 +37,37 @@ public class ServerConfig String contextPath = request.getServletContext().getContextPath(); return url.delete(url.length() - request.getRequestURI().length(), url.length()).append(contextPath).toString(); } + + public Map getIpAndPort(String url) { + Map map = new HashMap<>(); + Pattern p = compile("(\\d+\\.\\d+\\.\\d+\\.\\d+)\\:(\\d+)?"); + Matcher m = p.matcher(url); + String ip = ""; + String port = ""; + while (m.find()) { + ip = m.group(1); + port = m.group(2); + } + map.put("ip",ip); + map.put("port",port); + return map; + } + + + public static Map getIpAndPort1(String url) { + Map map = new HashMap<>(); + URI uri = URI.create(url); + String host = uri.getHost(); + int port = uri.getPort(); + map.put("ip",host); + map.put("port", String.valueOf(port)); + return map; + } + + public static void main(String[] arg){ + + } + + + } diff --git a/czsj-system/src/main/java/com/czsj/async/AsyncTask.java b/czsj-system/src/main/java/com/czsj/async/AsyncTask.java new file mode 100644 index 0000000..f087421 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/async/AsyncTask.java @@ -0,0 +1,158 @@ +package com.czsj.async; + + +import cn.hutool.core.collection.CollUtil; +import com.czsj.common.database.constants.DbQueryProperty; +import com.czsj.common.database.service.DataSourceFactory; +import com.czsj.common.database.service.DbQuery; +import com.czsj.common.utils.ListUtils; +import com.czsj.core.database.core.DbColumn; +import com.czsj.core.database.core.DbTable; +import com.czsj.market.dto.ApiLogDto; +import com.czsj.market.service.ApiLogService; +import com.czsj.metadata.dto.DbSchema; +import com.czsj.metadata.entity.MetadataColumnEntity; +import com.czsj.metadata.entity.MetadataSourceEntity; +import com.czsj.metadata.entity.MetadataTableEntity; +import com.czsj.metadata.enums.SyncStatus; +import com.czsj.metadata.mapper.MetadataColumnDao; +import com.czsj.metadata.mapper.MetadataSourceDao; +import com.czsj.metadata.mapper.MetadataTableDao; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 异步处理 + */ +@Slf4j +@Component +public class AsyncTask { + + @Autowired + private ApiLogService apiLogService; + + @Autowired + private DataSourceFactory dataSourceFactory; + + @Autowired + private MetadataSourceDao metadataSourceDao; + + @Autowired + private MetadataTableDao metadataTableDao; + + @Autowired + private MetadataColumnDao metadataColumnDao; + + @Async("taskExecutor") + public void doTask(ApiLogDto apiLogDto) { + + apiLogService.saveApiLog(apiLogDto); + } + + @Async("taskExecutor") + public void doTask(MetadataSourceEntity dataSource) { + Boolean completed = false; + try { + long start = System.currentTimeMillis(); + DbSchema dbSchema = dataSource.getDbSchema(); + DbQueryProperty dbQueryProperty = new DbQueryProperty(dataSource.getDbType(), dbSchema.getHost(),dbSchema.getUsername(), dbSchema.getPassword(), dbSchema.getPort(), dbSchema.getDbName(), dbSchema.getSid()); + DbQuery dbQuery = dataSourceFactory.createDbQuery(dbQueryProperty); + List tables = dbQuery.getTables(dbSchema.getDbName()); + List SourcetablesList = new ArrayList<>(); + List SourcecolumnsList = new ArrayList<>(); + if (CollUtil.isNotEmpty(tables)) { + List metadataTableEntityList = tables.stream().map(table -> { + MetadataTableEntity metadataTable = new MetadataTableEntity(); + metadataTable.setSourceId(dataSource.getId()); + metadataTable.setTableName(table.getTableName()); + metadataTable.setTableComment(table.getTableComment()); + SourcetablesList.add(table.getTableName()); + return metadataTable; + }).collect(Collectors.toList()); + List tableList = metadataTableDao.selectTableBySourceId(dataSource.getId()); + + if(null != tableList && null != SourcetablesList && tableList.size() > SourcetablesList.size()){ + List differListByMap = ListUtils.getDifferListByMap(tableList, SourcetablesList); + System.out.println("集合A和集合B不同的元素:"+differListByMap); + for(String tablename : differListByMap) { + metadataTableDao.deleteBysourceId(dataSource.getId(), tablename); + } + } + + if (CollUtil.isNotEmpty(metadataTableEntityList)) { + metadataTableEntityList.stream().forEach(table -> { + Integer tablenumber = metadataTableDao.countByTableName(table.getTableName(),table.getSourceId()); + if(tablenumber == 0){ + metadataTableDao.insert(table); + }else{ + String id = metadataTableDao.selectIdByTableName(table.getTableName(),table.getSourceId()); + table.setId(id); + metadataTableDao.updateById(table); + } + List columns = dbQuery.getTableColumns(dbSchema.getDbName(), table.getTableName()); + if (CollUtil.isNotEmpty(columns)) { + List metadataColumnEntityList = columns.stream().map(column -> { + MetadataColumnEntity metadataColumn = new MetadataColumnEntity(); + metadataColumn.setSourceId(dataSource.getId()); + metadataColumn.setTableId(table.getId()); + metadataColumn.setColumnName(column.getColName()); + metadataColumn.setColumnComment(column.getColComment()); + metadataColumn.setColumnKey(column.getColKey() ? "1" : "0"); + metadataColumn.setColumnNullable(column.getNullable() ? "1" : "0"); + metadataColumn.setColumnPosition(column.getColPosition()); + metadataColumn.setDataType(column.getDataType()); + metadataColumn.setDataLength(column.getDataLength()); + metadataColumn.setDataPrecision(column.getDataPrecision()); + metadataColumn.setDataScale(column.getDataScale()); + metadataColumn.setDataDefault(column.getDataDefault()); + SourcecolumnsList.add(column.getColName()); + return metadataColumn; + }).collect(Collectors.toList()); + + + List columnsList = metadataColumnDao.selectColumnNameByTableId(table.getId(),table.getSourceId()); + if(null != tableList && null != SourcecolumnsList && columnsList.size() > SourcecolumnsList.size()){ + List differListByMap = ListUtils.getDifferListByMap(columnsList, SourcecolumnsList); + for(String columnName : differListByMap) { + metadataColumnDao.deleteBysourceIdAndTidAndColName(table.getId(),table.getSourceId(),columnName); + } + } + + + if (CollUtil.isNotEmpty(metadataColumnEntityList)) { + metadataColumnEntityList.stream().forEach(column -> + { + Integer Columnnumber = metadataColumnDao.countByColumnName(column.getColumnName(),column.getTableId(),column.getSourceId()); + if(Columnnumber == 0){ + metadataColumnDao.insert(column); + }else{ + String id = metadataColumnDao.selectIdByColumnName(column.getColumnName(),column.getTableId(),column.getSourceId()); + column.setId(id); + metadataColumnDao.updateById(column); + } + }); + } + } + }); + } + } + dataSource.setIsSync(SyncStatus.IsSync.getKey()); + metadataSourceDao.updateById(dataSource); + completed = true; + log.info("异步任务执行完成!耗时{}秒", (System.currentTimeMillis() - start / 1000)); + }finally { + if(!completed){ + dataSource.setIsSync(SyncStatus.ErrSync.getKey()); + metadataSourceDao.updateById(dataSource); + log.info("异步任务执行失败!"); + } + } + + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/config/ApiMappingConfig.java b/czsj-system/src/main/java/com/czsj/market/config/ApiMappingConfig.java new file mode 100644 index 0000000..169643f --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/config/ApiMappingConfig.java @@ -0,0 +1,36 @@ +package com.czsj.market.config; + + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.czsj.market.handler.MappingHandlerMapping; +import com.czsj.market.handler.RequestHandler; +import com.czsj.market.handler.RequestInterceptor; +import com.czsj.market.service.impl.ApiMappingEngine; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; + +@Configuration +public class ApiMappingConfig { + + @Bean + public MappingHandlerMapping mappingHandlerMapping(RequestMappingHandlerMapping requestMappingHandlerMapping, + ApiMappingEngine apiMappingEngine, + RedisTemplate redisTemplate, + ObjectMapper objectMapper) { + MappingHandlerMapping mappingHandlerMapping = new MappingHandlerMapping(); + mappingHandlerMapping.setHandler(requestHandler(apiMappingEngine, redisTemplate, objectMapper)); + mappingHandlerMapping.setRequestMappingHandlerMapping(requestMappingHandlerMapping); + return mappingHandlerMapping; + } + + @Bean + public RequestHandler requestHandler(ApiMappingEngine apiMappingEngine, RedisTemplate redisTemplate, ObjectMapper objectMapper) { + RequestHandler handler = new RequestHandler(); + handler.setApiMappingEngine(apiMappingEngine); + handler.setObjectMapper(objectMapper); + handler.setRequestInterceptor(new RequestInterceptor(redisTemplate)); + return handler; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/config/StartedUpRunner.java b/czsj-system/src/main/java/com/czsj/market/config/StartedUpRunner.java new file mode 100644 index 0000000..40eaff1 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/config/StartedUpRunner.java @@ -0,0 +1,52 @@ +package com.czsj.market.config; + + +import cn.hutool.core.collection.CollUtil; +import com.czsj.core.database.core.DataConstant; +import com.czsj.market.entity.DataApiEntity; +import com.czsj.market.handler.MappingHandlerMapping; +import com.czsj.market.service.DataApiService; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + +@Component +@RequiredArgsConstructor +public class StartedUpRunner implements ApplicationRunner { + + private final ConfigurableApplicationContext context; + private final Environment environment; + + + @Autowired + private MappingHandlerMapping mappingHandlerMapping; + + @Autowired + private DataApiService dataApiService; + + @Override + public void run(ApplicationArguments args) { + if (context.isActive()) { + String banner = "-----------------------------------------\n" + + "服务启动成功,时间:" + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now()) + "\n" + + "服务名称:" + environment.getProperty("czsj.name") + "\n" + + "端口号:" + environment.getProperty("server.port") + "\n" + + "-----------------------------------------"; + System.out.println(banner); + + // 项目启动时,初始化已发布的接口 + List releaseDataApiList = dataApiService.getDataApiEntityList(DataConstant.ApiState.RELEASE.getKey()); + if (CollUtil.isNotEmpty(releaseDataApiList)) { + releaseDataApiList.stream().forEach(api -> mappingHandlerMapping.registerMapping(api)); + } + } + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/dto/ApiLogDto.java b/czsj-system/src/main/java/com/czsj/market/dto/ApiLogDto.java new file mode 100644 index 0000000..6ae9b3c --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/dto/ApiLogDto.java @@ -0,0 +1,24 @@ +package com.czsj.market.dto; + +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +@Data +public class ApiLogDto implements Serializable { + + private static final long serialVersionUID=1L; + + private String id; + private String apiId; + private String callerId; + private String callerIp; + private String callerUrl; + private String callerParams; + private Integer callerSize; + private LocalDateTime callerDate; + private Long time; + private String msg; + private String status; +} diff --git a/czsj-system/src/main/java/com/czsj/market/dto/ApiMaskDto.java b/czsj-system/src/main/java/com/czsj/market/dto/ApiMaskDto.java new file mode 100644 index 0000000..69edcac --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/dto/ApiMaskDto.java @@ -0,0 +1,49 @@ +package com.czsj.market.dto; + +import com.czsj.metadata.validate.ValidationGroups; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.io.Serializable; +import java.util.List; + +/** + *

+ * 数据API脱敏信息表 实体DTO + *

+ * + * @author yuwei + * @since 2020-04-14 + */ +@ApiModel(value = "数据API脱敏信息表Model") +@Data +public class ApiMaskDto implements Serializable { + + private static final long serialVersionUID=1L; + + @ApiModelProperty(value = "主键ID") + @NotBlank(message = "主键ID不能为空", groups = {ValidationGroups.Update.class}) + private String id; + @ApiModelProperty(value = "数据API") + @NotBlank(message = "数据API不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String apiId; + @ApiModelProperty(value = "脱敏名称") + @NotBlank(message = "脱敏名称不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String maskName; + @ApiModelProperty(value = "脱敏字段规则配置") + @Valid + @NotEmpty(message = "脱敏字段规则配置不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + @Size(min = 1, message="脱敏字段规则配置长度不能少于{min}位") + private List rules; + @ApiModelProperty(value = "状态") + @NotNull(message = "状态不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String status; + @ApiModelProperty(value = "备注") + private String remark; +} diff --git a/czsj-system/src/main/java/com/czsj/market/dto/DataApiDto.java b/czsj-system/src/main/java/com/czsj/market/dto/DataApiDto.java new file mode 100644 index 0000000..1b48a6c --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/dto/DataApiDto.java @@ -0,0 +1,73 @@ +package com.czsj.market.dto; + +import com.czsj.metadata.validate.ValidationGroups; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.io.Serializable; +import java.util.List; + +/** + *

+ * 数据API信息表 实体DTO + *

+ * + * @author yuwei + * @since 2020-03-31 + */ +@ApiModel(value = "数据API信息表Model") +@Data +public class DataApiDto implements Serializable { + + private static final long serialVersionUID=1L; + + @ApiModelProperty(value = "主键ID") + @NotBlank(message = "主键ID不能为空", groups = {ValidationGroups.Update.class}) + private String id; + @ApiModelProperty(value = "API名称") + @NotBlank(message = "API名称不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String apiName; + @ApiModelProperty(value = "API版本") + @NotBlank(message = "API版本不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String apiVersion; + @ApiModelProperty(value = "API路径") + @NotBlank(message = "API路径不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String apiUrl; + @ApiModelProperty(value = "请求方式") + @NotBlank(message = "请求方式不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String reqMethod; + @ApiModelProperty(value = "返回格式") + @NotBlank(message = "返回格式不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String resType; + @ApiModelProperty(value = "IP黑名单多个用英文,隔开") + private String deny; + @ApiModelProperty(value = "限流配置") + @Valid + private RateLimit rateLimit; + @ApiModelProperty(value = "执行配置") + @Valid + private ExecuteConfig executeConfig; + @ApiModelProperty(value = "请求参数") + @Valid + @NotEmpty(message = "请求参数不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + @Size(min = 1, message="请求参数长度不能少于{min}位") + private List reqParams; + @ApiModelProperty(value = "返回参数") + @Valid + @NotEmpty(message = "返回字段不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + @Size(min = 1, message="返回字段长度不能少于{min}位") + private List resParams; + @ApiModelProperty(value = "状态") + @NotNull(message = "状态不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String status; + @ApiModelProperty(value = "备注") + private String remark; + @ApiModelProperty(value = "接口编码") + private String apiCode; +} diff --git a/czsj-system/src/main/java/com/czsj/market/dto/ExecuteConfig.java b/czsj-system/src/main/java/com/czsj/market/dto/ExecuteConfig.java new file mode 100644 index 0000000..d24f13b --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/dto/ExecuteConfig.java @@ -0,0 +1,40 @@ +package com.czsj.market.dto; + +import com.czsj.metadata.validate.ValidationGroups; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.List; + +@ApiModel(value = "执行配置信息Model") +@Data +public class ExecuteConfig implements Serializable { + + private static final long serialVersionUID=1L; + + @ApiModelProperty(value = "数据源") + @NotBlank(message = "数据源不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String sourceId; + + @ApiModelProperty(value = "配置方式") + @NotNull(message = "配置方式不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String configType; + + @ApiModelProperty(value = "数据库表主键") + private String tableId; + + @ApiModelProperty(value = "数据库表") + private String tableName; + + @ApiModelProperty(value = "表字段列表") + @Valid + private List fieldParams; + + @ApiModelProperty(value = "解析SQL") + private String sqlText; +} diff --git a/czsj-system/src/main/java/com/czsj/market/dto/FieldParam.java b/czsj-system/src/main/java/com/czsj/market/dto/FieldParam.java new file mode 100644 index 0000000..0e35818 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/dto/FieldParam.java @@ -0,0 +1,73 @@ +package com.czsj.market.dto; + +import io.swagger.annotations.ApiModel; +import lombok.Data; + +import java.io.Serializable; + +@ApiModel(value = "字段信息Model") +@Data +public class FieldParam implements Serializable { + + private static final long serialVersionUID=1L; + + /** + * 列名 + */ + private String columnName; + + /** + * 数据类型 + */ + private String dataType; + + /** + * 数据长度 + */ + private Integer dataLength; + + /** + * 数据精度 + */ + private Integer dataPrecision; + + /** + * 数据小数位 + */ + private Integer dataScale; + + /** + * 是否主键 + */ + private String columnKey; + + /** + * 是否允许为空 + */ + private String columnNullable; + + /** + * 列的序号 + */ + private Integer columnPosition; + + /** + * 列默认值 + */ + private String dataDefault; + + /** + * 列注释 + */ + private String columnComment; + + /** + * 作为请求参数 + */ + private String reqable; + + /** + * 作为返回参数 + */ + private String resable; +} diff --git a/czsj-system/src/main/java/com/czsj/market/dto/FieldRule.java b/czsj-system/src/main/java/com/czsj/market/dto/FieldRule.java new file mode 100644 index 0000000..77cc196 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/dto/FieldRule.java @@ -0,0 +1,27 @@ +package com.czsj.market.dto; + +import com.czsj.metadata.validate.ValidationGroups; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +@ApiModel(value = "字段信息Model") +@Data +public class FieldRule implements Serializable { + + private static final long serialVersionUID=1L; + + @ApiModelProperty(value = "字段名称") + @NotBlank(message = "字段名称不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String fieldName; + @ApiModelProperty(value = "脱敏类型") + @NotNull(message = "脱敏类型不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String cipherType; + @ApiModelProperty(value = "规则类型") + @NotNull(message = "规则类型不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String cryptType; +} diff --git a/czsj-system/src/main/java/com/czsj/market/dto/HttpService.java b/czsj-system/src/main/java/com/czsj/market/dto/HttpService.java new file mode 100644 index 0000000..515c3fe --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/dto/HttpService.java @@ -0,0 +1,23 @@ +package com.czsj.market.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +@ApiModel(value = "http接口Model") +@Data +public class HttpService implements Serializable { + + private static final long serialVersionUID=1L; + + @ApiModelProperty(value = "请求地址") + private String url; + @ApiModelProperty(value = "请求头") + private String header; + @ApiModelProperty(value = "请求参数") + private String param; + @ApiModelProperty(value = "请求方式") + private String httpMethod; +} diff --git a/czsj-system/src/main/java/com/czsj/market/dto/RateLimit.java b/czsj-system/src/main/java/com/czsj/market/dto/RateLimit.java new file mode 100644 index 0000000..ce4b84e --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/dto/RateLimit.java @@ -0,0 +1,24 @@ +package com.czsj.market.dto; + +import com.czsj.metadata.validate.ValidationGroups; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +@ApiModel(value = "限流信息Model") +@Data +public class RateLimit implements Serializable { + + private static final long serialVersionUID=1L; + + @ApiModelProperty(value = "是否限流:0:否,1:是") + @NotNull(message = "是否限流不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String enable; + @ApiModelProperty(value = "请求次数默认5次") + private Integer times = 5; + @ApiModelProperty(value = "请求时间范围默认60秒") + private Integer seconds = 60; +} diff --git a/czsj-system/src/main/java/com/czsj/market/dto/ReqParam.java b/czsj-system/src/main/java/com/czsj/market/dto/ReqParam.java new file mode 100644 index 0000000..c8a78c6 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/dto/ReqParam.java @@ -0,0 +1,54 @@ +package com.czsj.market.dto; + +import com.czsj.metadata.validate.ValidationGroups; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +@ApiModel(value = "请求参数信息Model") +@Data +public class ReqParam implements Serializable { + + private static final long serialVersionUID=1L; + + @ApiModelProperty(value = "参数名称") + @NotBlank(message = "参数名称不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String paramName; + + @ApiModelProperty(value = "是否为空") + @NotNull(message = "是否为空不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String nullable; + + @ApiModelProperty(value = "描述") + @NotBlank(message = "描述不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String paramComment; + + @ApiModelProperty(value = "操作符") + @NotNull(message = "操作符不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String whereType; + + @ApiModelProperty(value = "参数类型") + @NotNull(message = "参数类型不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String paramType; + + @ApiModelProperty(value = "开始时间") + private String startValue; + + @ApiModelProperty(value = "结束时间") + private String endValue; + + @ApiModelProperty(value = "示例值") + @NotBlank(message = "示例值不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String exampleValue; + + @ApiModelProperty(value = "默认值") + @NotBlank(message = "默认值不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String defaultValue; + + + +} diff --git a/czsj-system/src/main/java/com/czsj/market/dto/ResParam.java b/czsj-system/src/main/java/com/czsj/market/dto/ResParam.java new file mode 100644 index 0000000..5755100 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/dto/ResParam.java @@ -0,0 +1,36 @@ +package com.czsj.market.dto; + +import com.czsj.metadata.validate.ValidationGroups; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +@ApiModel(value = "返回参数信息Model") +@Data +public class ResParam implements Serializable { + + private static final long serialVersionUID=1L; + + @ApiModelProperty(value = "字段名称") + @NotBlank(message = "字段名称不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String fieldName; + + @ApiModelProperty(value = "描述") + @NotBlank(message = "描述不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String fieldComment; + + @ApiModelProperty(value = "数据类型") + @NotNull(message = "数据类型不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String dataType; + + @ApiModelProperty(value = "示例值") + @NotBlank(message = "示例值不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String exampleValue; + + @ApiModelProperty(value = "字段别名") + private String fieldAliasName; +} diff --git a/czsj-system/src/main/java/com/czsj/market/dto/ServiceExecuteDto.java b/czsj-system/src/main/java/com/czsj/market/dto/ServiceExecuteDto.java new file mode 100644 index 0000000..7743c27 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/dto/ServiceExecuteDto.java @@ -0,0 +1,25 @@ +package com.czsj.market.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +@ApiModel(value = "服务调用Model") +@Data +public class ServiceExecuteDto implements Serializable { + + private static final long serialVersionUID=1L; + + @ApiModelProperty(value = "服务编号") + private String serviceNo; + + @ApiModelProperty(value = "http服务请求头") + private String header; + @ApiModelProperty(value = "http服务请求参数") + private String param; + + @ApiModelProperty(value = "webservice服务请求报文") + private String soap; +} diff --git a/czsj-system/src/main/java/com/czsj/market/dto/ServiceIntegrationDto.java b/czsj-system/src/main/java/com/czsj/market/dto/ServiceIntegrationDto.java new file mode 100644 index 0000000..61c8594 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/dto/ServiceIntegrationDto.java @@ -0,0 +1,46 @@ +package com.czsj.market.dto; + +import com.czsj.metadata.validate.ValidationGroups; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +/** + *

+ * 服务集成表 实体DTO + *

+ * + * @author yuwei + * @since 2020-08-20 + */ +@ApiModel(value = "服务集成表Model") +@Data +public class ServiceIntegrationDto implements Serializable { + + private static final long serialVersionUID=1L; + + @ApiModelProperty(value = "主键ID") + @NotBlank(message = "主键ID不能为空", groups = {ValidationGroups.Update.class}) + private String id; + @ApiModelProperty(value = "服务名称") + @NotBlank(message = "服务名称不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String serviceName; + @ApiModelProperty(value = "服务类型(1http接口,2webservice接口)") + private String serviceType; + @ApiModelProperty(value = "http接口") + @Valid + private HttpService httpService; + @ApiModelProperty(value = "webservice接口") + @Valid + private WebService webService; + @ApiModelProperty(value = "状态") + @NotNull(message = "状态不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String status; + @ApiModelProperty(value = "备注") + private String remark; +} diff --git a/czsj-system/src/main/java/com/czsj/market/dto/ServiceLogDto.java b/czsj-system/src/main/java/com/czsj/market/dto/ServiceLogDto.java new file mode 100644 index 0000000..115f663 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/dto/ServiceLogDto.java @@ -0,0 +1,49 @@ +package com.czsj.market.dto; + +import com.czsj.metadata.validate.ValidationGroups; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 服务集成调用日志表 实体DTO + *

+ * + * @author yuwei + * @since 2020-08-20 + */ +@ApiModel(value = "服务集成调用日志表Model") +@Data +public class ServiceLogDto implements Serializable { + + private static final long serialVersionUID=1L; + + @ApiModelProperty(value = "主键ID") + @NotBlank(message = "主键ID不能为空", groups = {ValidationGroups.Update.class}) + private String id; + @ApiModelProperty(value = "服务id") + private String serviceId; + @ApiModelProperty(value = "调用者id") + private String callerId; + @ApiModelProperty(value = "调用者ip") + private String callerIp; + @ApiModelProperty(value = "调用时间") + private LocalDateTime callerDate; + @ApiModelProperty(value = "调用请求头") + private String callerHeader; + @ApiModelProperty(value = "调用请求参数") + private String callerParam; + @ApiModelProperty(value = "调用报文") + private String callerSoap; + @ApiModelProperty(value = "调用耗时") + private Long time; + @ApiModelProperty(value = "信息记录") + private String msg; + @ApiModelProperty(value = "状态:0:失败,1:成功") + private String status; +} diff --git a/czsj-system/src/main/java/com/czsj/market/dto/SqlParseDto.java b/czsj-system/src/main/java/com/czsj/market/dto/SqlParseDto.java new file mode 100644 index 0000000..c818aea --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/dto/SqlParseDto.java @@ -0,0 +1,21 @@ +package com.czsj.market.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.io.Serializable; + +@Data +public class SqlParseDto implements Serializable { + + private static final long serialVersionUID=1L; + + @ApiModelProperty(value = "数据源") + @NotBlank(message = "数据源不能为空") + private String sourceId; + + @ApiModelProperty(value = "SQL文本") + @NotBlank(message = "SQL不能为空") + private String sqlText; +} diff --git a/czsj-system/src/main/java/com/czsj/market/dto/TryParam.java b/czsj-system/src/main/java/com/czsj/market/dto/TryParam.java new file mode 100644 index 0000000..b534443 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/dto/TryParam.java @@ -0,0 +1,22 @@ +package com.czsj.market.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.io.Serializable; + +@ApiModel(value = "API调用参数信息Model") +@Data +public class TryParam implements Serializable { + + private static final long serialVersionUID=1L; + + @ApiModelProperty(value = "参数名称") + @NotBlank(message = "参数名称不能为空") + private String paramName; + + @ApiModelProperty(value = "参数值") + private Object paramValue; +} diff --git a/czsj-system/src/main/java/com/czsj/market/dto/WebService.java b/czsj-system/src/main/java/com/czsj/market/dto/WebService.java new file mode 100644 index 0000000..0405480 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/dto/WebService.java @@ -0,0 +1,23 @@ +package com.czsj.market.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +@ApiModel(value = "webservice接口Model") +@Data +public class WebService implements Serializable { + + private static final long serialVersionUID=1L; + + @ApiModelProperty(value = "wsdl地址") + private String wsdl; + @ApiModelProperty(value = "命名空间") + private String targetNamespace; + @ApiModelProperty(value = "请求报文") + private String soap; + @ApiModelProperty(value = "调用方法") + private String method; +} diff --git a/czsj-system/src/main/java/com/czsj/market/entity/ApiLogEntity.java b/czsj-system/src/main/java/com/czsj/market/entity/ApiLogEntity.java new file mode 100644 index 0000000..adb3ecb --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/entity/ApiLogEntity.java @@ -0,0 +1,72 @@ +package com.czsj.market.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.time.LocalDateTime; + +@Data +@Accessors(chain = true) +@TableName("market_api_log") +public class ApiLogEntity implements Serializable { + + private static final long serialVersionUID=1L; + + /** + * 主键 + */ + @TableId(value = "id", type = IdType.ASSIGN_ID) + private String id; + /** + * 调用api + */ + private String apiId; + /** + * api名称 + */ + @TableField(exist = false) + private String apiName; + /** + * 调用者id + */ + private String callerId; + /** + * 调用者ip + */ + private String callerIp; + /** + * 调用url + */ + private String callerUrl; + /** + * 调用参数 + */ + private String callerParams; + /** + * 调用数据量 + */ + private Integer callerSize; + /** + * 调用耗时 + */ + private Long time; + /** + * 信息记录 + */ + private String msg; + /** + * 状态:0:失败,1:成功 + */ + private String status; + /** + * 调用时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private LocalDateTime callerDate; +} diff --git a/czsj-system/src/main/java/com/czsj/market/entity/ApiMaskEntity.java b/czsj-system/src/main/java/com/czsj/market/entity/ApiMaskEntity.java new file mode 100644 index 0000000..ff49592 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/entity/ApiMaskEntity.java @@ -0,0 +1,65 @@ +package com.czsj.market.entity; + + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.czsj.core.database.base.DataScopeBaseEntity; +import com.czsj.market.dto.FieldRule; + +import java.util.List; + +/** + *

+ * 数据API脱敏信息表 + *

+ * + * @author yuwei + * @since 2020-04-14 + */ + +@TableName(value = "market_api_mask", autoResultMap = true) +public class ApiMaskEntity extends DataScopeBaseEntity { + + private static final long serialVersionUID=1L; + + /** + * 数据API + */ + private String apiId; + + /** + * 脱敏名称 + */ + private String maskName; + + /** + * 脱敏字段规则配置 + */ + @TableField(value = "config_json", typeHandler = JacksonTypeHandler.class) + private List rules; + + public String getApiId() { + return apiId; + } + + public void setApiId(String apiId) { + this.apiId = apiId; + } + + public String getMaskName() { + return maskName; + } + + public void setMaskName(String maskName) { + this.maskName = maskName; + } + + public List getRules() { + return rules; + } + + public void setRules(List rules) { + this.rules = rules; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/entity/DataApiEntity.java b/czsj-system/src/main/java/com/czsj/market/entity/DataApiEntity.java new file mode 100644 index 0000000..227e9de --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/entity/DataApiEntity.java @@ -0,0 +1,94 @@ +package com.czsj.market.entity; + + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.czsj.core.database.base.DataScopeBaseEntity; +import com.czsj.market.dto.ExecuteConfig; +import com.czsj.market.dto.RateLimit; +import com.czsj.market.dto.ReqParam; +import com.czsj.market.dto.ResParam; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.util.List; + +/** + *

+ * 数据API信息表 + *

+ * + * @author yuwei + * @since 2020-03-31 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@Accessors(chain = true) +@TableName(value = "market_api", autoResultMap = true) +public class DataApiEntity extends DataScopeBaseEntity { + + private static final long serialVersionUID=1L; + + /** + * API名称 + */ + private String apiName; + + /** + * API版本 + */ + private String apiVersion; + + /** + * API路径 + */ + private String apiUrl; + + /** + * 请求类型 + */ + private String reqMethod; + + /** + * 返回格式 + */ + private String resType; + + /** + * IP黑名单多个,隔开 + */ + private String deny; + + /** + * 限流配置 + */ + @TableField(value = "limit_json", typeHandler = JacksonTypeHandler.class) + private RateLimit rateLimit; + + /** + * 执行配置 + */ + @TableField(value = "config_json", typeHandler = JacksonTypeHandler.class) + private ExecuteConfig executeConfig; + + /** + * 请求参数 + */ + @TableField(value = "req_json", typeHandler = JacksonTypeHandler.class) + private List reqParams; + + /** + * 返回字段 + */ + @TableField(value = "res_json", typeHandler = JacksonTypeHandler.class) + private List resParams; + + + /** + * 返回字段 + */ + private String apiCode; + +} diff --git a/czsj-system/src/main/java/com/czsj/market/entity/ServiceIntegrationEntity.java b/czsj-system/src/main/java/com/czsj/market/entity/ServiceIntegrationEntity.java new file mode 100644 index 0000000..0b33260 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/entity/ServiceIntegrationEntity.java @@ -0,0 +1,56 @@ +package com.czsj.market.entity; + + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.czsj.core.database.base.DataScopeBaseEntity; +import com.czsj.market.dto.HttpService; +import com.czsj.market.dto.WebService; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + *

+ * 服务集成表 + *

+ * + * @author yuwei + * @since 2020-08-20 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@Accessors(chain = true) +@TableName(value = "market_service_integration", autoResultMap = true) +public class ServiceIntegrationEntity extends DataScopeBaseEntity { + + private static final long serialVersionUID=1L; + + /** + * 服务编号 + */ + private String serviceNo; + + /** + * 服务名称 + */ + private String serviceName; + + /** + * 服务类型(1http接口,2webservice接口) + */ + private String serviceType; + + /** + * http接口 + */ + @TableField(value = "httpservice_json", typeHandler = JacksonTypeHandler.class) + private HttpService httpService; + + /** + * webservice接口 + */ + @TableField(value = "webservice_json", typeHandler = JacksonTypeHandler.class) + private WebService webService; +} diff --git a/czsj-system/src/main/java/com/czsj/market/entity/ServiceLogEntity.java b/czsj-system/src/main/java/com/czsj/market/entity/ServiceLogEntity.java new file mode 100644 index 0000000..5baa532 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/entity/ServiceLogEntity.java @@ -0,0 +1,91 @@ +package com.czsj.market.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 服务集成调用日志表 + *

+ * + * @author yuwei + * @since 2020-08-20 + */ +@Data +@Accessors(chain = true) +@TableName("market_service_log") +public class ServiceLogEntity implements Serializable { + + private static final long serialVersionUID=1L; + + /** + * 主键 + */ + @TableId(value = "id", type = IdType.ASSIGN_ID) + private String id; + + /** + * 服务id + */ + private String serviceId; + + /** + * 服务名称 + */ + @TableField(exist = false) + private String serviceName; + + /** + * 调用者id + */ + private String callerId; + + /** + * 调用者ip + */ + private String callerIp; + + /** + * 调用时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private LocalDateTime callerDate; + + /** + * 调用请求头 + */ + private String callerHeader; + + /** + * 调用请求参数 + */ + private String callerParam; + + /** + * 调用报文 + */ + private String callerSoap; + + /** + * 调用耗时 + */ + private Long time; + + /** + * 信息记录 + */ + private String msg; + + /** + * 状态:0:失败,1:成功 + */ + private String status; +} diff --git a/czsj-system/src/main/java/com/czsj/market/enums/AlgorithmCrypto.java b/czsj-system/src/main/java/com/czsj/market/enums/AlgorithmCrypto.java new file mode 100644 index 0000000..41164fc --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/enums/AlgorithmCrypto.java @@ -0,0 +1,37 @@ +package com.czsj.market.enums; + +public enum AlgorithmCrypto { + + BASE64("1", "BASE64加密"), + MD5("2", "MD5加密"), + SHA_1("3", "SHA_1加密"), + SHA_256("4", "SHA_256加密"), + AES("5", "AES加密"), + DES("6", "DES加密"); + + private final String key; + + private final String val; + + AlgorithmCrypto(String key, String val) { + this.key = key; + this.val = val; + } + + public String getKey() { + return key; + } + + public String getVal() { + return val; + } + + public static AlgorithmCrypto getAlgorithmCrypto(String algorithmCrypt) { + for (AlgorithmCrypto type : AlgorithmCrypto.values()) { + if (type.key.equals(algorithmCrypt)) { + return type; + } + } + return BASE64; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/enums/CipherType.java b/czsj-system/src/main/java/com/czsj/market/enums/CipherType.java new file mode 100644 index 0000000..5ec0da5 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/enums/CipherType.java @@ -0,0 +1,33 @@ +package com.czsj.market.enums; + +public enum CipherType { + + REGEX("1", "正则替换"), + ALGORITHM("2", "加密算法"); + + private final String key; + + private final String val; + + CipherType(String key, String val) { + this.key = key; + this.val = val; + } + + public String getKey() { + return key; + } + + public String getVal() { + return val; + } + + public static CipherType getCipherType(String cipherType) { + for (CipherType type : CipherType.values()) { + if (type.key.equals(cipherType)) { + return type; + } + } + return REGEX; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/enums/ConfigType.java b/czsj-system/src/main/java/com/czsj/market/enums/ConfigType.java new file mode 100644 index 0000000..b25c2e7 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/enums/ConfigType.java @@ -0,0 +1,24 @@ +package com.czsj.market.enums; + +public enum ConfigType { + + FORM("1", "表引导模式"), + SCRIPT("2", "脚本模式"); + + private final String key; + + private final String val; + + ConfigType(String key, String val) { + this.key = key; + this.val = val; + } + + public String getKey() { + return key; + } + + public String getVal() { + return val; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/enums/ParamType.java b/czsj-system/src/main/java/com/czsj/market/enums/ParamType.java new file mode 100644 index 0000000..05d7474 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/enums/ParamType.java @@ -0,0 +1,85 @@ +package com.czsj.market.enums; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; +import com.aspose.words.net.System.Data.DataException; + +import java.math.BigDecimal; + +public enum ParamType { + + String("1", "字符串"), + Integer("2", "整型"), + Float("3", "浮点型"), + Date("4", "时间"), + List("5", "集合"); + + private final String key; + + private final String val; + + ParamType(String key, String val) { + this.key = key; + this.val = val; + } + + public String getKey() { + return key; + } + + public String getVal() { + return val; + } + + public static Object parse(ParamType paramType, Object obj) { + if (ObjectUtil.isEmpty(obj)) { + return null; + } + switch (paramType) { + case String: + try { + return (java.lang.String)obj; + } catch (Exception e) { + throw new DataException("参数值[" + obj + "]不是" + String.getVal() + "数据类型]"); + } + case Float: + try { + return new BigDecimal(obj.toString()).doubleValue(); + } catch (Exception e) { + throw new DataException("参数值[" + obj + "]不是" + Float.getVal() + "数据类型]"); + } + case Integer: + try { + return (java.lang.Integer)obj; + } catch (Exception e) { + throw new DataException("参数值[" + obj + "]不是" + Integer.getVal() + "数据类型]"); + } + case List: + try { + return (java.util.List)obj; + } catch (Exception e) { + throw new DataException("参数值[" + obj + "]不是" + List.getVal() + "数据类型]"); + } + case Date: + try { + return DateUtil.parse(obj.toString(), "yyyy-MM-dd HH:mm:ss"); + } catch (Exception e) { + try { + return DateUtil.parse(obj.toString(), "yyyy-MM-dd"); + } catch (Exception ex) { + throw new DataException("参数值[" + obj + "]不是" + Date.getVal() + "数据类型]"); + } + } + } + return null; + } + + public static ParamType getParamType(String paramType) { + for (ParamType type : ParamType.values()) { + if (type.key.equals(paramType)) { + return type; + } + } + return String; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/enums/RegexCrypto.java b/czsj-system/src/main/java/com/czsj/market/enums/RegexCrypto.java new file mode 100644 index 0000000..042f8d5 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/enums/RegexCrypto.java @@ -0,0 +1,39 @@ +package com.czsj.market.enums; + +public enum RegexCrypto { + + CHINESE_NAME("1", "中文姓名"), + ID_CARD("2", "身份证号"), + FIXED_PHONE("3", "固定电话"), + MOBILE_PHONE("4", "手机号码"), + ADDRESS("5", "地址"), + EMAIL("6", "电子邮箱"), + BANK_CARD("7", "银行卡号"), + CNAPS_CODE("8", "公司开户银行联号"); + + private final String key; + + private final String val; + + RegexCrypto(String key, String val) { + this.key = key; + this.val = val; + } + + public String getKey() { + return key; + } + + public String getVal() { + return val; + } + + public static RegexCrypto getRegexCrypto(String regexCrypt) { + for (RegexCrypto type : RegexCrypto.values()) { + if (type.key.equals(regexCrypt)) { + return type; + } + } + return CHINESE_NAME; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/enums/ReqMethod.java b/czsj-system/src/main/java/com/czsj/market/enums/ReqMethod.java new file mode 100644 index 0000000..95d0706 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/enums/ReqMethod.java @@ -0,0 +1,17 @@ +package com.czsj.market.enums; + +public enum ReqMethod { + + GET("GET"), + POST("POST"); + + private String desc; + + ReqMethod(String desc) { + this.desc = desc; + } + + public String getDesc() { + return desc; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/enums/ResType.java b/czsj-system/src/main/java/com/czsj/market/enums/ResType.java new file mode 100644 index 0000000..ad59188 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/enums/ResType.java @@ -0,0 +1,17 @@ +package com.czsj.market.enums; + +public enum ResType { + + JSON("JSON"), + XML("XML"); + + private String desc; + + ResType(String desc) { + this.desc = desc; + } + + public String getDesc() { + return desc; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/enums/ServiceType.java b/czsj-system/src/main/java/com/czsj/market/enums/ServiceType.java new file mode 100644 index 0000000..66ca923 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/enums/ServiceType.java @@ -0,0 +1,24 @@ +package com.czsj.market.enums; + +public enum ServiceType { + + HTTP("1", "http接口"), + WEBSERVICE("2", "webservice接口"); + + private final String key; + + private final String val; + + ServiceType(String key, String val) { + this.key = key; + this.val = val; + } + + public String getKey() { + return key; + } + + public String getVal() { + return val; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/enums/WhereType.java b/czsj-system/src/main/java/com/czsj/market/enums/WhereType.java new file mode 100644 index 0000000..f378efc --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/enums/WhereType.java @@ -0,0 +1,51 @@ +package com.czsj.market.enums; + +public enum WhereType { + + EQUALS("1", "=", "等于"), + NOT_EQUALS("2", "!=", "不等于"), + LIKE("3", "LIKE", "全模糊查询"), + LIKE_LEFT("4", "LIKE", "左模糊查询"), + LIKE_RIGHT("5", "LIKE", "右模糊查询"), + GREATER_THAN("6", ">", "大于"), + GREATER_THAN_EQUALS("7", ">=", "大于等于"), + LESS_THAN("8", "<", "小于"), + LESS_THAN_EQUALS("9", "<=", "小于等于"), + NULL("10", "IS NULL", "是否为空"), + NOT_NULL("11", "IS NOT NULL", "是否不为空"), + IN("12", "IN", "IN"), + BETWEEN("13", "BETWEEN", "BETWEEN"); + + private final String type; + + private final String key; + + private final String desc; + + WhereType(String type, String key, String desc) { + this.type = type; + this.key = key; + this.desc = desc; + } + + public String getType() { + return type; + } + + public String getKey() { + return key; + } + + public String getDesc() { + return desc; + } + + public static WhereType getWhereType(String whereType) { + for (WhereType type : WhereType.values()) { + if (type.type.equals(whereType)) { + return type; + } + } + return EQUALS; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/factory/AbstractFactory.java b/czsj-system/src/main/java/com/czsj/market/factory/AbstractFactory.java new file mode 100644 index 0000000..d903918 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/factory/AbstractFactory.java @@ -0,0 +1,8 @@ +package com.czsj.market.factory; + +import com.czsj.market.factory.crypto.Crypto; + +public abstract class AbstractFactory { + + public abstract Crypto getCrypto(String type); +} diff --git a/czsj-system/src/main/java/com/czsj/market/factory/AlgorithmFactory.java b/czsj-system/src/main/java/com/czsj/market/factory/AlgorithmFactory.java new file mode 100644 index 0000000..c0efffb --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/factory/AlgorithmFactory.java @@ -0,0 +1,17 @@ +package com.czsj.market.factory; + + +import com.czsj.market.enums.AlgorithmCrypto; +import com.czsj.market.factory.crypto.AlgorithmRegistry; +import com.czsj.market.factory.crypto.Crypto; + +public class AlgorithmFactory extends AbstractFactory { + + private static final AlgorithmRegistry ALGORITHM_REGISTRY = new AlgorithmRegistry(); + + @Override + public Crypto getCrypto(String type) { + AlgorithmCrypto crypto = AlgorithmCrypto.getAlgorithmCrypto(type); + return ALGORITHM_REGISTRY.getAlgorithm(crypto); + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/factory/FactoryProducer.java b/czsj-system/src/main/java/com/czsj/market/factory/FactoryProducer.java new file mode 100644 index 0000000..eb697fd --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/factory/FactoryProducer.java @@ -0,0 +1,18 @@ +package com.czsj.market.factory; + + +import com.czsj.market.enums.CipherType; + +public class FactoryProducer { + + public static AbstractFactory getFactory(String type){ + CipherType cipherType = CipherType.getCipherType(type); + switch (cipherType) { + case REGEX: + return new RegexFactory(); + case ALGORITHM: + return new AlgorithmFactory(); + } + return null; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/factory/RegexFactory.java b/czsj-system/src/main/java/com/czsj/market/factory/RegexFactory.java new file mode 100644 index 0000000..567724e --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/factory/RegexFactory.java @@ -0,0 +1,18 @@ +package com.czsj.market.factory; + + +import com.czsj.market.enums.RegexCrypto; +import com.czsj.market.factory.crypto.Crypto; +import com.czsj.market.factory.crypto.RegexRegistry; + + +public class RegexFactory extends AbstractFactory { + + private static final RegexRegistry REGEX_REGISTRY = new RegexRegistry(); + + @Override + public Crypto getCrypto(String type) { + RegexCrypto crypto = RegexCrypto.getRegexCrypto(type); + return REGEX_REGISTRY.getRegex(crypto); + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/factory/crypto/ADDRESSCrypto.java b/czsj-system/src/main/java/com/czsj/market/factory/crypto/ADDRESSCrypto.java new file mode 100644 index 0000000..1721955 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/factory/crypto/ADDRESSCrypto.java @@ -0,0 +1,22 @@ +package com.czsj.market.factory.crypto; + +import org.apache.commons.lang3.StringUtils; + +/** + * [地址] 只显示前六位,不显示详细地址;我们要对个人信息增强保护<例子:北京市海淀区****> + */ +public class ADDRESSCrypto implements Crypto { + + @Override + public String encrypt(String content) { + if (StringUtils.isBlank(content)) { + return null; + } + return StringUtils.rightPad(StringUtils.left(content, 6), StringUtils.length(content), "*"); + } + + @Override + public String decrypt(String content) { + return null; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/factory/crypto/AESCrypto.java b/czsj-system/src/main/java/com/czsj/market/factory/crypto/AESCrypto.java new file mode 100644 index 0000000..47c2d62 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/factory/crypto/AESCrypto.java @@ -0,0 +1,73 @@ +package com.czsj.market.factory.crypto; + +import cn.hutool.core.util.StrUtil; +import org.apache.commons.lang3.StringUtils; + +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import java.security.SecureRandom; +import java.util.Base64; + +public class AESCrypto implements Crypto { + + @Override + public String encrypt(String content) { + if (StrUtil.isBlank(content)) { + return null; + } + try { + //1.构造密钥生成器,指定为AES算法,不区分大小写 + KeyGenerator kGen = KeyGenerator.getInstance("AES"); + //2.根据 RULES 规则初始化密钥生成器,根据传入的字节数组生成一个128位的随机源 + kGen.init(128, new SecureRandom(SLAT.getBytes(CHARSET_UTF8))); + //3.产生原始对称密钥 + SecretKey secretKey = kGen.generateKey(); + //4.获得原始对称密钥的字节数组 + byte[] enCodeFormat = secretKey.getEncoded(); + //5.根据字节数组生成AES密钥 + SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES"); + //6.根据指定算法AES生成密码器 + Cipher cipher = Cipher.getInstance("AES"); + //7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作,第二个参数为使用的KEY + cipher.init(Cipher.ENCRYPT_MODE, key); + //8.根据密码器的初始化方式--加密:将数据加密 + byte[] AES_encrypt = cipher.doFinal(content.getBytes(CHARSET_UTF8)); + //9.将字符串返回 + return Base64.getEncoder().encodeToString(AES_encrypt); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + @Override + public String decrypt(String content) { + if (StringUtils.isBlank(content)) { + return null; + } + try { + //1.构造密钥生成器,指定为AES算法,不区分大小写 + KeyGenerator kGen = KeyGenerator.getInstance("AES"); + //2.根据 RULES 规则初始化密钥生成器,根据传入的字节数组生成一个128位的随机源 + kGen.init(128, new SecureRandom(SLAT.getBytes(CHARSET_UTF8))); + //3.产生原始对称密钥 + SecretKey secretKey = kGen.generateKey(); + //4.获得原始对称密钥的字节数组 + byte[] enCodeFormat = secretKey.getEncoded(); + //5.根据字节数组生成AES密钥 + SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES"); + //6.根据指定算法AES生成密码器 + Cipher cipher = Cipher.getInstance("AES"); + //7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作,第二个参数为使用的KEY + cipher.init(Cipher.DECRYPT_MODE, key);// 初始化 + //8.根据密码器的初始化方式--加密:将数据加密 + byte[] AES_decode = cipher.doFinal(Base64.getDecoder().decode(content)); + return new String(AES_decode, CHARSET_UTF8); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/factory/crypto/AlgorithmRegistry.java b/czsj-system/src/main/java/com/czsj/market/factory/crypto/AlgorithmRegistry.java new file mode 100644 index 0000000..47f6812 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/factory/crypto/AlgorithmRegistry.java @@ -0,0 +1,24 @@ +package com.czsj.market.factory.crypto; + +import com.czsj.market.enums.AlgorithmCrypto; + +import java.util.EnumMap; +import java.util.Map; + +public class AlgorithmRegistry { + + private final Map algorithm_enum_map = new EnumMap<>(AlgorithmCrypto.class); + + public AlgorithmRegistry() { + algorithm_enum_map.put(AlgorithmCrypto.BASE64, new BASE64Crypto()); + algorithm_enum_map.put(AlgorithmCrypto.AES, new AESCrypto()); + algorithm_enum_map.put(AlgorithmCrypto.DES, new DESCrypto()); + algorithm_enum_map.put(AlgorithmCrypto.MD5, new MD5Crypto()); + algorithm_enum_map.put(AlgorithmCrypto.SHA_1, new SHA1Crypto()); + algorithm_enum_map.put(AlgorithmCrypto.SHA_256, new SHA256Crypto()); + } + + public Crypto getAlgorithm(AlgorithmCrypto crypto) { + return algorithm_enum_map.get(crypto); + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/factory/crypto/BANKCARDCrypto.java b/czsj-system/src/main/java/com/czsj/market/factory/crypto/BANKCARDCrypto.java new file mode 100644 index 0000000..29f8cf9 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/factory/crypto/BANKCARDCrypto.java @@ -0,0 +1,22 @@ +package com.czsj.market.factory.crypto; + +import org.apache.commons.lang3.StringUtils; + +/** + * [银行卡号] 前六位,后四位,其他用星号隐藏每位1个星号<例子:6222600**********1234> + */ +public class BANKCARDCrypto implements Crypto { + + @Override + public String encrypt(String content) { + if (StringUtils.isBlank(content)) { + return null; + } + return StringUtils.left(content, 6).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(content, 4), StringUtils.length(content), "*"), "******")); + } + + @Override + public String decrypt(String content) { + return null; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/factory/crypto/BASE64Crypto.java b/czsj-system/src/main/java/com/czsj/market/factory/crypto/BASE64Crypto.java new file mode 100644 index 0000000..6d20816 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/factory/crypto/BASE64Crypto.java @@ -0,0 +1,34 @@ +package com.czsj.market.factory.crypto; + +import org.apache.commons.lang3.StringUtils; + +import java.util.Base64; + +public class BASE64Crypto implements Crypto { + + @Override + public String encrypt(String content) { + if (StringUtils.isBlank(content)) { + return null; + } + try { + byte[] encode = Base64.getEncoder().encode(content.getBytes(CHARSET_UTF8)); + return new String(encode, CHARSET_UTF8); + } catch (Exception e) { + } + return null; + } + + @Override + public String decrypt(String content) { + if (StringUtils.isBlank(content)) { + return null; + } + try { + byte[] decode = Base64.getDecoder().decode(content.getBytes(CHARSET_UTF8)); + return new String(decode, CHARSET_UTF8); + } catch (Exception e) { + } + return null; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/factory/crypto/CHINESENAMECrypto.java b/czsj-system/src/main/java/com/czsj/market/factory/crypto/CHINESENAMECrypto.java new file mode 100644 index 0000000..8b2acc0 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/factory/crypto/CHINESENAMECrypto.java @@ -0,0 +1,22 @@ +package com.czsj.market.factory.crypto; + +import org.apache.commons.lang3.StringUtils; + +/** + * [中文姓名] 只显示第一个汉字,其他隐藏为星号<例子:李**> + */ +public class CHINESENAMECrypto implements Crypto { + + @Override + public String encrypt(String content) { + if (StringUtils.isBlank(content)) { + return null; + } + return StringUtils.rightPad(StringUtils.left(content, 1), StringUtils.length(content), "*"); + } + + @Override + public String decrypt(String content) { + return null; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/factory/crypto/CNAPSCODECrypto.java b/czsj-system/src/main/java/com/czsj/market/factory/crypto/CNAPSCODECrypto.java new file mode 100644 index 0000000..faeca42 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/factory/crypto/CNAPSCODECrypto.java @@ -0,0 +1,22 @@ +package com.czsj.market.factory.crypto; + +import org.apache.commons.lang3.StringUtils; + +/** + * [公司开户银行联号] 公司开户银行联行号,显示前四位,其他用星号隐藏,每位1个星号<例子:1234********> + */ +public class CNAPSCODECrypto implements Crypto { + + @Override + public String encrypt(String content) { + if (StringUtils.isBlank(content)) { + return null; + } + return StringUtils.rightPad(StringUtils.left(content, 4), StringUtils.length(content), "*"); + } + + @Override + public String decrypt(String content) { + return null; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/factory/crypto/Crypto.java b/czsj-system/src/main/java/com/czsj/market/factory/crypto/Crypto.java new file mode 100644 index 0000000..acd70ad --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/factory/crypto/Crypto.java @@ -0,0 +1,17 @@ +package com.czsj.market.factory.crypto; + +public interface Crypto { + + /** + * 字符编码 + */ + String CHARSET_UTF8 = "UTF-8"; + /** + * 密码盐 + */ + String SLAT = "DATAX:20200101"; + + String encrypt(String content); + + String decrypt(String content); +} diff --git a/czsj-system/src/main/java/com/czsj/market/factory/crypto/DESCrypto.java b/czsj-system/src/main/java/com/czsj/market/factory/crypto/DESCrypto.java new file mode 100644 index 0000000..08ccf5a --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/factory/crypto/DESCrypto.java @@ -0,0 +1,54 @@ +package com.czsj.market.factory.crypto; + +import org.apache.commons.lang3.StringUtils; + +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import java.security.SecureRandom; +import java.util.Base64; + +public class DESCrypto implements Crypto { + + @Override + public String encrypt(String content) { + if (StringUtils.isBlank(content)) { + return null; + } + try { + KeyGenerator kGen = KeyGenerator.getInstance("DES"); + kGen.init(56, new SecureRandom(SLAT.getBytes(CHARSET_UTF8))); + SecretKey secretKey = kGen.generateKey(); + byte[] enCodeFormat = secretKey.getEncoded(); + SecretKeySpec key = new SecretKeySpec(enCodeFormat, "DES"); + Cipher cipher = Cipher.getInstance("DES"); + cipher.init(Cipher.ENCRYPT_MODE, key); + byte[] DES_encrypt = cipher.doFinal(content.getBytes(CHARSET_UTF8)); + return Base64.getEncoder().encodeToString(DES_encrypt); + } catch (Exception e) { + } + return null; + } + + @Override + public String decrypt(String content) { + if (StringUtils.isBlank(content)) { + return null; + } + try { + KeyGenerator kGen = KeyGenerator.getInstance("DES"); + kGen.init(56, new SecureRandom(SLAT.getBytes(CHARSET_UTF8))); + SecretKey secretKey = kGen.generateKey(); + byte[] enCodeFormat = secretKey.getEncoded(); + SecretKeySpec key = new SecretKeySpec(enCodeFormat, "DES"); + Cipher cipher = Cipher.getInstance("DES"); + cipher.init(Cipher.DECRYPT_MODE, key); + byte[] DES_decrypt = cipher.doFinal(Base64.getDecoder().decode(content)); + return new String(DES_decrypt, CHARSET_UTF8); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/factory/crypto/EMAILCrypto.java b/czsj-system/src/main/java/com/czsj/market/factory/crypto/EMAILCrypto.java new file mode 100644 index 0000000..5d8fb28 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/factory/crypto/EMAILCrypto.java @@ -0,0 +1,22 @@ +package com.czsj.market.factory.crypto; + +import org.apache.commons.lang3.StringUtils; + +/** + * [电子邮箱] 只显示前三后显示邮箱后缀,其他隐藏为星号<例子:312****@qq.com> + */ +public class EMAILCrypto implements Crypto { + + @Override + public String encrypt(String content) { + if (StringUtils.isBlank(content)) { + return null; + } + return content.replaceAll("(\\w{3}).*@(\\w+)", "$1****@$2"); + } + + @Override + public String decrypt(String content) { + return null; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/factory/crypto/FIXEDPHONECrypto.java b/czsj-system/src/main/java/com/czsj/market/factory/crypto/FIXEDPHONECrypto.java new file mode 100644 index 0000000..bf5d3f4 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/factory/crypto/FIXEDPHONECrypto.java @@ -0,0 +1,22 @@ +package com.czsj.market.factory.crypto; + +import org.apache.commons.lang3.StringUtils; + +/** + * [固定电话] 后四位,其他隐藏<例子:****1234> + */ +public class FIXEDPHONECrypto implements Crypto { + + @Override + public String encrypt(String content) { + if (StringUtils.isBlank(content)) { + return null; + } + return StringUtils.leftPad(StringUtils.right(content, 4), StringUtils.length(content), "*"); + } + + @Override + public String decrypt(String content) { + return null; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/factory/crypto/IDCARDCrypto.java b/czsj-system/src/main/java/com/czsj/market/factory/crypto/IDCARDCrypto.java new file mode 100644 index 0000000..35318a0 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/factory/crypto/IDCARDCrypto.java @@ -0,0 +1,22 @@ +package com.czsj.market.factory.crypto; + +import org.apache.commons.lang3.StringUtils; + +/** + * [身份证号] 显示最后四位,其他隐藏。共计18位或者15位。<例子:*************5762> + */ +public class IDCARDCrypto implements Crypto { + + @Override + public String encrypt(String content) { + if (StringUtils.isBlank(content)) { + return null; + } + return StringUtils.leftPad(StringUtils.right(content, 4), StringUtils.length(content), "*"); + } + + @Override + public String decrypt(String content) { + return null; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/factory/crypto/MD5Crypto.java b/czsj-system/src/main/java/com/czsj/market/factory/crypto/MD5Crypto.java new file mode 100644 index 0000000..f19ef06 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/factory/crypto/MD5Crypto.java @@ -0,0 +1,29 @@ +package com.czsj.market.factory.crypto; + +import org.apache.commons.lang3.StringUtils; + +import java.security.MessageDigest; +import java.util.Base64; + +public class MD5Crypto implements Crypto { + + @Override + public String encrypt(String content) { + if (StringUtils.isBlank(content)) { + return null; + } + MessageDigest md5 = null; + try { + md5 = MessageDigest.getInstance("MD5"); + md5.update(content.getBytes(CHARSET_UTF8)); + md5.update(SLAT.getBytes(CHARSET_UTF8)); + } catch (Exception e) { + } + return Base64.getEncoder().encodeToString(md5.digest()); + } + + @Override + public String decrypt(String content) { + return null; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/factory/crypto/MOBILEPHONECrypto.java b/czsj-system/src/main/java/com/czsj/market/factory/crypto/MOBILEPHONECrypto.java new file mode 100644 index 0000000..69b2287 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/factory/crypto/MOBILEPHONECrypto.java @@ -0,0 +1,22 @@ +package com.czsj.market.factory.crypto; + +import org.apache.commons.lang3.StringUtils; + +/** + * [手机号码] 前三位,后四位,其他隐藏<例子:138******1234> + */ +public class MOBILEPHONECrypto implements Crypto { + + @Override + public String encrypt(String content) { + if (StringUtils.isBlank(content)) { + return null; + } + return StringUtils.left(content, 3).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(content, 4), StringUtils.length(content), "*"), "***")); + } + + @Override + public String decrypt(String content) { + return null; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/factory/crypto/RegexRegistry.java b/czsj-system/src/main/java/com/czsj/market/factory/crypto/RegexRegistry.java new file mode 100644 index 0000000..3cf5db0 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/factory/crypto/RegexRegistry.java @@ -0,0 +1,26 @@ +package com.czsj.market.factory.crypto; + +import com.czsj.market.enums.RegexCrypto; + +import java.util.EnumMap; +import java.util.Map; + +public class RegexRegistry { + + private final Map regex_enum_map = new EnumMap<>(RegexCrypto.class); + + public RegexRegistry() { + regex_enum_map.put(RegexCrypto.CHINESE_NAME, new CHINESENAMECrypto()); + regex_enum_map.put(RegexCrypto.ID_CARD, new IDCARDCrypto()); + regex_enum_map.put(RegexCrypto.FIXED_PHONE, new FIXEDPHONECrypto()); + regex_enum_map.put(RegexCrypto.MOBILE_PHONE, new MOBILEPHONECrypto()); + regex_enum_map.put(RegexCrypto.ADDRESS, new ADDRESSCrypto()); + regex_enum_map.put(RegexCrypto.EMAIL, new EMAILCrypto()); + regex_enum_map.put(RegexCrypto.BANK_CARD, new BANKCARDCrypto()); + regex_enum_map.put(RegexCrypto.CNAPS_CODE, new CNAPSCODECrypto()); + } + + public Crypto getRegex(RegexCrypto crypto) { + return regex_enum_map.get(crypto); + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/factory/crypto/SHA1Crypto.java b/czsj-system/src/main/java/com/czsj/market/factory/crypto/SHA1Crypto.java new file mode 100644 index 0000000..b019893 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/factory/crypto/SHA1Crypto.java @@ -0,0 +1,29 @@ +package com.czsj.market.factory.crypto; + +import org.apache.commons.lang3.StringUtils; + +import java.security.MessageDigest; +import java.util.Base64; + +public class SHA1Crypto implements Crypto { + + @Override + public String encrypt(String content) { + if (StringUtils.isBlank(content)) { + return null; + } + MessageDigest md5 = null; + try { + md5 = MessageDigest.getInstance("SHA-1"); + md5.update(content.getBytes(CHARSET_UTF8)); + md5.update(SLAT.getBytes(CHARSET_UTF8)); + } catch (Exception e) { + } + return Base64.getEncoder().encodeToString(md5.digest()); + } + + @Override + public String decrypt(String content) { + return null; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/factory/crypto/SHA256Crypto.java b/czsj-system/src/main/java/com/czsj/market/factory/crypto/SHA256Crypto.java new file mode 100644 index 0000000..032d9d5 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/factory/crypto/SHA256Crypto.java @@ -0,0 +1,29 @@ +package com.czsj.market.factory.crypto; + +import org.apache.commons.lang3.StringUtils; + +import java.security.MessageDigest; +import java.util.Base64; + +public class SHA256Crypto implements Crypto { + + @Override + public String encrypt(String content) { + if (StringUtils.isBlank(content)) { + return null; + } + MessageDigest md5 = null; + try { + md5 = MessageDigest.getInstance("SHA-256"); + md5.update(content.getBytes(CHARSET_UTF8)); + md5.update(SLAT.getBytes(CHARSET_UTF8)); + } catch (Exception e) { + } + return Base64.getEncoder().encodeToString(md5.digest()); + } + + @Override + public String decrypt(String content) { + return null; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/handler/MappingHandlerMapping.java b/czsj-system/src/main/java/com/czsj/market/handler/MappingHandlerMapping.java new file mode 100644 index 0000000..566e128 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/handler/MappingHandlerMapping.java @@ -0,0 +1,121 @@ +package com.czsj.market.handler; + +import com.czsj.market.entity.DataApiEntity; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.ServletWebRequest; +import org.springframework.web.servlet.HandlerMapping; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.lang.reflect.Method; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +@Slf4j +public class MappingHandlerMapping { + + private static Map mappings = new ConcurrentHashMap<>(); + private RequestMappingHandlerMapping requestMappingHandlerMapping; + private RequestHandler handler; + private Method method; + + { + try { + method = RequestHandler.class.getDeclaredMethod("invoke", HttpServletRequest.class, HttpServletResponse.class, Map.class, Map.class, Map.class); + } catch (NoSuchMethodException e) { + } + } + + private String ignore = "services"; + private String prefix = "v1.0.0"; + private String separator = "/"; + + public MappingHandlerMapping() {} + + public void setRequestMappingHandlerMapping(RequestMappingHandlerMapping requestMappingHandlerMapping) { + this.requestMappingHandlerMapping = requestMappingHandlerMapping; + } + + public void setHandler(RequestHandler handler) { + this.handler = handler; + } + + public static DataApiEntity getMappingApiInfo(HttpServletRequest request,String url) { + NativeWebRequest webRequest = new ServletWebRequest(request); + String requestMapping = (String) webRequest.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE, RequestAttributes.SCOPE_REQUEST); + return getMappingApiInfo(buildMappingKey(request.getMethod(), url)); + } + + public static DataApiEntity getMappingApiInfoA(String apicode) { + return getMappingApiInfo(apicode); + } + + public static DataApiEntity getMappingApiInfo(String key) { + return mappings.get(key); + } + + public static String buildMappingKey(String requestMethod, String requestMapping) { + return requestMethod.toUpperCase() + ":" + requestMapping; + } + + /** + * 注册请求映射 + * + * @param api + */ + public static void registerMapping(DataApiEntity api) { + String mappingKey = api.getApiCode(); + //String mappingKey = getMappingKey(api); + if (mappings.containsKey(mappingKey)) { + // 取消注册 + mappings.remove(mappingKey); + //requestMappingHandlerMapping.unregisterMapping(getRequestMapping(api)); + } + log.info("注册接口:{}", api.getApiName()); + //RequestMappingInfo requestMapping = getRequestMapping(api); + mappings.put(mappingKey, api); + //requestMappingHandlerMapping.registerMapping(requestMapping, handler, method); + } + + /** + * 取消注册请求映射 + * + * @param api + */ + public static void unregisterMapping(DataApiEntity api) { + log.info("取消注册接口:{}", api.getApiName()); + String mappingKey = api.getApiCode(); + //String mappingKey = getMappingKey(api); + if (mappings.containsKey(mappingKey)) { + // 取消注册 + mappings.remove(mappingKey); + //requestMappingHandlerMapping.unregisterMapping(getRequestMapping(api)); + } + } + + private String getMappingKey(DataApiEntity api) { + return buildMappingKey(api.getReqMethod().toUpperCase(), getRequestPath(api.getApiVersion(), api.getApiUrl())); + } + + private RequestMappingInfo getRequestMapping(DataApiEntity api) { + return RequestMappingInfo.paths(getRequestPath(api.getApiVersion(), api.getApiUrl())).methods(RequestMethod.valueOf(api.getReqMethod().toUpperCase())).build(); + } + + /** + * 调用接口 /services/v1.0.0/user/1 + * @param version + * @param path + * @return + */ + private String getRequestPath(String version, String path) { + if (version != null) { + prefix = version; + } + return separator + ignore + separator + prefix + (path.startsWith(separator) ? path : (separator + path)); + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/handler/RequestHandler.java b/czsj-system/src/main/java/com/czsj/market/handler/RequestHandler.java new file mode 100644 index 0000000..fe9b221 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/handler/RequestHandler.java @@ -0,0 +1,41 @@ +package com.czsj.market.handler; + + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.czsj.market.service.impl.ApiMappingEngine; +import lombok.extern.slf4j.Slf4j; + + +@Slf4j +public class RequestHandler { + + private RequestInterceptor requestInterceptor; + + private ApiMappingEngine apiMappingEngine; + + private ObjectMapper objectMapper; + + public void setRequestInterceptor(RequestInterceptor requestInterceptor) { + this.requestInterceptor = requestInterceptor; + } + + public void setApiMappingEngine(ApiMappingEngine apiMappingEngine) { + this.apiMappingEngine = apiMappingEngine; + } + + public void setObjectMapper(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + public RequestInterceptor getRequestInterceptor() { + return requestInterceptor; + } + + public ApiMappingEngine getApiMappingEngine() { + return apiMappingEngine; + } + + public ObjectMapper getObjectMapper() { + return objectMapper; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/handler/RequestInterceptor.java b/czsj-system/src/main/java/com/czsj/market/handler/RequestInterceptor.java new file mode 100644 index 0000000..800f638 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/handler/RequestInterceptor.java @@ -0,0 +1,114 @@ +package com.czsj.market.handler; + + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.StrUtil; +import com.aspose.words.net.System.Data.DataException; +import com.czsj.core.database.core.DataConstant; +import com.czsj.core.util.IPUtil; +import com.czsj.market.dto.RateLimit; +import com.czsj.market.entity.DataApiEntity; +import com.czsj.market.enums.ParamType; +import com.czsj.market.utils.MD5Util; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.RedisTemplate; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.TimeUnit; + +@Slf4j +public class RequestInterceptor { + + private RedisTemplate redisTemplate; + + public RequestInterceptor(RedisTemplate redisTemplate) { + this.redisTemplate = redisTemplate; + } + + /** + * 请求之前执行 + * + * @return 当返回对象时,直接将此对象返回到页面,返回null时,继续执行后续操作 + * @throws Exception + */ + public void preHandle(HttpServletRequest request, HttpServletResponse response, DataApiEntity api, Map params) throws Exception { + System.out.println("************ApiInterceptor preHandle executed**********"); + String uri = request.getRequestURI(); + log.info("getRequestURI的值:" + uri); + String ipAddr = IPUtil.getIpAddr(request); + log.info("ipAddr的值:" + ipAddr); + + // 密钥校验 + String apiKey = request.getHeader("api_key"); + String secretKey = request.getHeader("secret_key"); + if (StrUtil.isBlank(apiKey) || StrUtil.isBlank(secretKey)) { + throw new DataException("api_key或secret_key空"); + } + MD5Util mt = MD5Util.getInstance(); + String apiId = mt.decode(apiKey); + String userId = mt.decode(secretKey); + + // 黑名单校验 + String deny = api.getDeny(); + if (StrUtil.isNotBlank(deny)) { + List denyList = Arrays.asList(deny.split(",")); + if (CollUtil.isNotEmpty(denyList)) { + for (String ip : denyList) { + if(ip.equals(ipAddr)){ + throw new DataException(ip + "已被加入IP黑名单"); + } + } + } + } + + // 参数校验 + if (MapUtil.isNotEmpty(params)) { + if(null == api.getReqParams()||api.getReqParams().size() == 0){ + throw new DataException("API请求参数与系统参数不匹配!"); + } + api.getReqParams().stream().forEach(param -> { + if (params.containsKey(param.getParamName())) { + // 参数类型是否正确 + ParamType.parse(ParamType.getParamType(param.getParamType()), params.get(param.getParamName())); + } + }); + } + + // 限流校验 + RateLimit rateLimit = api.getRateLimit(); + if (DataConstant.TrueOrFalse.TRUE.getKey().equals(rateLimit.getEnable())) { + Integer times = rateLimit.getTimes(); + Integer seconds = rateLimit.getSeconds(); + // 请求次数 + times = Optional.ofNullable(times).orElse(5); + // 请求时间范围60秒 + seconds = Optional.ofNullable(seconds).orElse(60); + // 根据 USER + API 限流 + String key = "user:" + userId + ":api:" + apiId; + // 根据key获取已请求次数 + Integer maxTimes = (Integer) redisTemplate.opsForValue().get(key); + if (maxTimes == null) { + // set时一定要加过期时间 + redisTemplate.opsForValue().set(key, 1, seconds, TimeUnit.SECONDS); + } else if (maxTimes < times) { + redisTemplate.opsForValue().set(key, maxTimes + 1, seconds, TimeUnit.SECONDS); + } else { + throw new DataException("API调用过于频繁"); + } + } + } + + /** + * 执行完毕之后执行 + * + * @throws Exception + */ + public void postHandle(HttpServletRequest request, HttpServletResponse response, DataApiEntity api, Map params, Object value) throws Exception { + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/mapper/ApiLogDao.java b/czsj-system/src/main/java/com/czsj/market/mapper/ApiLogDao.java new file mode 100644 index 0000000..8229966 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/mapper/ApiLogDao.java @@ -0,0 +1,22 @@ +package com.czsj.market.mapper; + + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.czsj.core.database.base.BaseDao; +import com.czsj.market.entity.ApiLogEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.io.Serializable; + +@Mapper +public interface ApiLogDao extends BaseDao { + + @Override + ApiLogEntity selectById(Serializable id); + + @Override + > E selectPage(E page, @Param(Constants.WRAPPER) Wrapper queryWrapper); +} diff --git a/czsj-system/src/main/java/com/czsj/market/mapper/ApiMaskDao.java b/czsj-system/src/main/java/com/czsj/market/mapper/ApiMaskDao.java new file mode 100644 index 0000000..10ab8cd --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/mapper/ApiMaskDao.java @@ -0,0 +1,30 @@ +package com.czsj.market.mapper; + + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.czsj.core.database.base.BaseDao; +import com.czsj.market.entity.ApiMaskEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.io.Serializable; + +/** + *

+ * 数据API脱敏信息表 Mapper 接口 + *

+ * + * @author yuwei + * @since 2020-04-14 + */ +@Mapper +public interface ApiMaskDao extends BaseDao { + + @Override + ApiMaskEntity selectById(Serializable id); + + @Override + > E selectPage(E page, @Param(Constants.WRAPPER) Wrapper queryWrapper); +} diff --git a/czsj-system/src/main/java/com/czsj/market/mapper/DataApiDao.java b/czsj-system/src/main/java/com/czsj/market/mapper/DataApiDao.java new file mode 100644 index 0000000..9de6cc8 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/mapper/DataApiDao.java @@ -0,0 +1,36 @@ +package com.czsj.market.mapper; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.czsj.core.database.base.BaseDao; +import com.czsj.market.entity.DataApiEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.io.Serializable; +import java.util.List; + +/** + *

+ * 数据API信息表 Mapper 接口 + *

+ * + * @author yuwei + * @since 2020-03-31 + */ +@Mapper +public interface DataApiDao extends BaseDao { + + @Override + DataApiEntity selectById(Serializable id); + + @Override + List selectList(@Param(Constants.WRAPPER) Wrapper queryWrapper); + + @Override + > E selectPage(E page, @Param(Constants.WRAPPER) Wrapper queryWrapper); + + List getDataApiEntityList(String status); + +} diff --git a/czsj-system/src/main/java/com/czsj/market/mapstruct/ApiLogMapper.java b/czsj-system/src/main/java/com/czsj/market/mapstruct/ApiLogMapper.java new file mode 100644 index 0000000..60fb92d --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/mapstruct/ApiLogMapper.java @@ -0,0 +1,12 @@ +package com.czsj.market.mapstruct; + + +import com.czsj.market.dto.ApiLogDto; +import com.czsj.market.entity.ApiLogEntity; +import com.czsj.market.vo.ApiLogVo; +import com.czsj.metadata.mapstruct.EntityMapper; +import org.mapstruct.Mapper; + +@Mapper(componentModel = "spring") +public interface ApiLogMapper extends EntityMapper { +} diff --git a/czsj-system/src/main/java/com/czsj/market/mapstruct/ApiMaskMapper.java b/czsj-system/src/main/java/com/czsj/market/mapstruct/ApiMaskMapper.java new file mode 100644 index 0000000..a3622be --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/mapstruct/ApiMaskMapper.java @@ -0,0 +1,21 @@ +package com.czsj.market.mapstruct; + + +import com.czsj.market.dto.ApiMaskDto; +import com.czsj.market.entity.ApiMaskEntity; +import com.czsj.market.vo.ApiMaskVo; +import com.czsj.metadata.mapstruct.EntityMapper; +import org.mapstruct.Mapper; + +/** + *

+ * 数据API脱敏信息表 Mapper 实体映射 + *

+ * + * @author yuwei + * @since 2020-04-14 + */ +@Mapper(componentModel = "spring") +public interface ApiMaskMapper extends EntityMapper { + +} diff --git a/czsj-system/src/main/java/com/czsj/market/mapstruct/DataApiMapper.java b/czsj-system/src/main/java/com/czsj/market/mapstruct/DataApiMapper.java new file mode 100644 index 0000000..e6bd6e9 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/mapstruct/DataApiMapper.java @@ -0,0 +1,22 @@ +package com.czsj.market.mapstruct; + + +import com.czsj.market.dto.DataApiDto; +import com.czsj.market.entity.DataApiEntity; +import com.czsj.market.vo.DataApiVo; +import com.czsj.metadata.mapstruct.EntityMapper; +import org.mapstruct.Mapper; + +/** + *

+ * 数据API信息表 Mapper 实体映射 + *

+ * + * @author yuwei + * @since 2020-03-31 + */ +@Mapper(componentModel = "spring") +public interface DataApiMapper extends EntityMapper { + + +} diff --git a/czsj-system/src/main/java/com/czsj/market/mapstruct/impl/ApiLogMapperImpl.java b/czsj-system/src/main/java/com/czsj/market/mapstruct/impl/ApiLogMapperImpl.java new file mode 100644 index 0000000..b5437e2 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/mapstruct/impl/ApiLogMapperImpl.java @@ -0,0 +1,126 @@ +package com.czsj.market.mapstruct.impl; + +import com.czsj.market.dto.ApiLogDto; +import com.czsj.market.entity.ApiLogEntity; +import com.czsj.market.mapstruct.ApiLogMapper; +import com.czsj.market.vo.ApiLogVo; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +@Component +public class ApiLogMapperImpl implements ApiLogMapper { + + @Override + public ApiLogDto toDTO(ApiLogEntity e) { + if ( e == null ) { + return null; + } + + ApiLogDto apiLogDto = new ApiLogDto(); + + apiLogDto.setId( e.getId() ); + apiLogDto.setApiId( e.getApiId() ); + apiLogDto.setCallerId( e.getCallerId() ); + apiLogDto.setCallerIp( e.getCallerIp() ); + apiLogDto.setCallerUrl( e.getCallerUrl() ); + apiLogDto.setCallerParams( e.getCallerParams() ); + apiLogDto.setCallerSize( e.getCallerSize() ); + apiLogDto.setCallerDate( e.getCallerDate() ); + apiLogDto.setTime( e.getTime() ); + apiLogDto.setMsg( e.getMsg() ); + apiLogDto.setStatus( e.getStatus() ); + + return apiLogDto; + } + + @Override + public List toDTO(List es) { + if ( es == null ) { + return null; + } + + List list = new ArrayList( es.size() ); + for ( ApiLogEntity apiLogEntity : es ) { + list.add( toDTO( apiLogEntity ) ); + } + + return list; + } + + @Override + public ApiLogVo toVO(ApiLogEntity e) { + if ( e == null ) { + return null; + } + + ApiLogVo apiLogVo = new ApiLogVo(); + + apiLogVo.setId( e.getId() ); + apiLogVo.setApiId( e.getApiId() ); + apiLogVo.setApiName( e.getApiName() ); + apiLogVo.setCallerId( e.getCallerId() ); + apiLogVo.setCallerIp( e.getCallerIp() ); + apiLogVo.setCallerUrl( e.getCallerUrl() ); + apiLogVo.setCallerSize( e.getCallerSize() ); + apiLogVo.setCallerParams( e.getCallerParams() ); + apiLogVo.setCallerDate( e.getCallerDate() ); + apiLogVo.setTime( e.getTime() ); + apiLogVo.setMsg( e.getMsg() ); + apiLogVo.setStatus( e.getStatus() ); + + return apiLogVo; + } + + @Override + public List toVO(List es) { + if ( es == null ) { + return null; + } + + List list = new ArrayList( es.size() ); + for ( ApiLogEntity apiLogEntity : es ) { + list.add( toVO( apiLogEntity ) ); + } + + return list; + } + + @Override + public ApiLogEntity toEntity(ApiLogDto d) { + if ( d == null ) { + return null; + } + + ApiLogEntity apiLogEntity = new ApiLogEntity(); + + apiLogEntity.setId( d.getId() ); + apiLogEntity.setApiId( d.getApiId() ); + apiLogEntity.setCallerId( d.getCallerId() ); + apiLogEntity.setCallerIp( d.getCallerIp() ); + apiLogEntity.setCallerUrl( d.getCallerUrl() ); + apiLogEntity.setCallerParams( d.getCallerParams() ); + apiLogEntity.setCallerSize( d.getCallerSize() ); + apiLogEntity.setTime( d.getTime() ); + apiLogEntity.setMsg( d.getMsg() ); + apiLogEntity.setStatus( d.getStatus() ); + apiLogEntity.setCallerDate( d.getCallerDate() ); + + return apiLogEntity; + } + + @Override + public List toEntity(List ds) { + if ( ds == null ) { + return null; + } + + List list = new ArrayList( ds.size() ); + for ( ApiLogDto apiLogDto : ds ) { + list.add( toEntity( apiLogDto ) ); + } + + return list; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/mapstruct/impl/ApiMaskMapperImpl.java b/czsj-system/src/main/java/com/czsj/market/mapstruct/impl/ApiMaskMapperImpl.java new file mode 100644 index 0000000..81fda04 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/mapstruct/impl/ApiMaskMapperImpl.java @@ -0,0 +1,123 @@ +package com.czsj.market.mapstruct.impl; + + +import com.czsj.market.dto.ApiMaskDto; +import com.czsj.market.dto.FieldRule; +import com.czsj.market.entity.ApiMaskEntity; +import com.czsj.market.mapstruct.ApiMaskMapper; +import com.czsj.market.vo.ApiMaskVo; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + + +@Component +public class ApiMaskMapperImpl implements ApiMaskMapper { + + @Override + public ApiMaskDto toDTO(ApiMaskEntity e) { + if ( e == null ) { + return null; + } + + ApiMaskDto apiMaskDto = new ApiMaskDto(); + + apiMaskDto.setId( e.getId() ); + apiMaskDto.setApiId( e.getApiId() ); + apiMaskDto.setMaskName( e.getMaskName() ); + List list = e.getRules(); + if ( list != null ) { + apiMaskDto.setRules( new ArrayList( list ) ); + } + apiMaskDto.setStatus( e.getStatus() ); + apiMaskDto.setRemark( e.getRemark() ); + + return apiMaskDto; + } + + @Override + public List toDTO(List es) { + if ( es == null ) { + return null; + } + + List list = new ArrayList( es.size() ); + for ( ApiMaskEntity apiMaskEntity : es ) { + list.add( toDTO( apiMaskEntity ) ); + } + + return list; + } + + @Override + public ApiMaskVo toVO(ApiMaskEntity e) { + if ( e == null ) { + return null; + } + + ApiMaskVo apiMaskVo = new ApiMaskVo(); + + apiMaskVo.setId( e.getId() ); + apiMaskVo.setStatus( e.getStatus() ); + apiMaskVo.setCreateTime( e.getCreateTime() ); + apiMaskVo.setRemark( e.getRemark() ); + apiMaskVo.setApiId( e.getApiId() ); + apiMaskVo.setMaskName( e.getMaskName() ); + List list = e.getRules(); + if ( list != null ) { + apiMaskVo.setRules( new ArrayList( list ) ); + } + + return apiMaskVo; + } + + @Override + public List toVO(List es) { + if ( es == null ) { + return null; + } + + List list = new ArrayList( es.size() ); + for ( ApiMaskEntity apiMaskEntity : es ) { + list.add( toVO( apiMaskEntity ) ); + } + + return list; + } + + @Override + public ApiMaskEntity toEntity(ApiMaskDto d) { + if ( d == null ) { + return null; + } + + ApiMaskEntity apiMaskEntity = new ApiMaskEntity(); + + apiMaskEntity.setId( d.getId() ); + apiMaskEntity.setStatus( d.getStatus() ); + apiMaskEntity.setRemark( d.getRemark() ); + apiMaskEntity.setApiId( d.getApiId() ); + apiMaskEntity.setMaskName( d.getMaskName() ); + List list = d.getRules(); + if ( list != null ) { + apiMaskEntity.setRules( new ArrayList( list ) ); + } + + return apiMaskEntity; + } + + @Override + public List toEntity(List ds) { + if ( ds == null ) { + return null; + } + + List list = new ArrayList( ds.size() ); + for ( ApiMaskDto apiMaskDto : ds ) { + list.add( toEntity( apiMaskDto ) ); + } + + return list; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/mapstruct/impl/DataApiMapperImpl.java b/czsj-system/src/main/java/com/czsj/market/mapstruct/impl/DataApiMapperImpl.java new file mode 100644 index 0000000..c5ed648 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/mapstruct/impl/DataApiMapperImpl.java @@ -0,0 +1,155 @@ +package com.czsj.market.mapstruct.impl; + +import com.czsj.market.dto.DataApiDto; +import com.czsj.market.dto.ReqParam; +import com.czsj.market.dto.ResParam; +import com.czsj.market.entity.DataApiEntity; +import com.czsj.market.mapstruct.DataApiMapper; +import com.czsj.market.vo.DataApiVo; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +@Component +public class DataApiMapperImpl implements DataApiMapper { + + @Override + public DataApiDto toDTO(DataApiEntity e) { + if ( e == null ) { + return null; + } + + DataApiDto dataApiDto = new DataApiDto(); + + dataApiDto.setId( e.getId() ); + dataApiDto.setApiName( e.getApiName() ); + dataApiDto.setApiVersion( e.getApiVersion() ); + dataApiDto.setApiUrl( e.getApiUrl() ); + dataApiDto.setReqMethod( e.getReqMethod() ); + dataApiDto.setResType( e.getResType() ); + dataApiDto.setDeny( e.getDeny() ); + dataApiDto.setRateLimit( e.getRateLimit() ); + dataApiDto.setExecuteConfig( e.getExecuteConfig() ); + dataApiDto.setApiCode(e.getApiCode()); + + List list = e.getReqParams(); + if ( list != null ) { + dataApiDto.setReqParams( new ArrayList( list ) ); + } + List list1 = e.getResParams(); + if ( list1 != null ) { + dataApiDto.setResParams( new ArrayList( list1 ) ); + } + dataApiDto.setStatus( e.getStatus() ); + dataApiDto.setRemark( e.getRemark() ); + + return dataApiDto; + } + + @Override + public List toDTO(List es) { + if ( es == null ) { + return null; + } + + List list = new ArrayList( es.size() ); + for ( DataApiEntity dataApiEntity : es ) { + list.add( toDTO( dataApiEntity ) ); + } + + return list; + } + + @Override + public DataApiVo toVO(DataApiEntity e) { + if ( e == null ) { + return null; + } + + DataApiVo dataApiVo = new DataApiVo(); + + dataApiVo.setId( e.getId() ); + dataApiVo.setStatus( e.getStatus() ); + dataApiVo.setCreateTime( e.getCreateTime() ); + dataApiVo.setRemark( e.getRemark() ); + dataApiVo.setApiName( e.getApiName() ); + dataApiVo.setApiVersion( e.getApiVersion() ); + dataApiVo.setApiUrl( e.getApiUrl() ); + dataApiVo.setReqMethod( e.getReqMethod() ); + dataApiVo.setDeny( e.getDeny() ); + dataApiVo.setResType( e.getResType() ); + dataApiVo.setRateLimit( e.getRateLimit() ); + dataApiVo.setExecuteConfig( e.getExecuteConfig() ); + dataApiVo.setApiCode(e.getApiCode()); + List list = e.getReqParams(); + if ( list != null ) { + dataApiVo.setReqParams( new ArrayList( list ) ); + } + List list1 = e.getResParams(); + if ( list1 != null ) { + dataApiVo.setResParams( new ArrayList( list1 ) ); + } + + return dataApiVo; + } + + @Override + public List toVO(List es) { + if ( es == null ) { + return null; + } + + List list = new ArrayList( es.size() ); + for ( DataApiEntity dataApiEntity : es ) { + list.add( toVO( dataApiEntity ) ); + } + + return list; + } + + @Override + public DataApiEntity toEntity(DataApiDto d) { + if ( d == null ) { + return null; + } + + DataApiEntity dataApiEntity = new DataApiEntity(); + dataApiEntity.setApiCode(d.getApiCode()); + dataApiEntity.setId( d.getId() ); + dataApiEntity.setStatus( d.getStatus() ); + dataApiEntity.setRemark( d.getRemark() ); + dataApiEntity.setApiName( d.getApiName() ); + dataApiEntity.setApiVersion( d.getApiVersion() ); + dataApiEntity.setApiUrl( d.getApiUrl() ); + dataApiEntity.setReqMethod( d.getReqMethod() ); + dataApiEntity.setResType( d.getResType() ); + dataApiEntity.setDeny( d.getDeny() ); + dataApiEntity.setRateLimit( d.getRateLimit() ); + dataApiEntity.setExecuteConfig( d.getExecuteConfig() ); + List list = d.getReqParams(); + if ( list != null ) { + dataApiEntity.setReqParams( new ArrayList( list ) ); + } + List list1 = d.getResParams(); + if ( list1 != null ) { + dataApiEntity.setResParams( new ArrayList( list1 ) ); + } + + return dataApiEntity; + } + + @Override + public List toEntity(List ds) { + if ( ds == null ) { + return null; + } + + List list = new ArrayList( ds.size() ); + for ( DataApiDto dataApiDto : ds ) { + list.add( toEntity( dataApiDto ) ); + } + + return list; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/query/ApiLogQuery.java b/czsj-system/src/main/java/com/czsj/market/query/ApiLogQuery.java new file mode 100644 index 0000000..27e099d --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/query/ApiLogQuery.java @@ -0,0 +1,22 @@ +package com.czsj.market.query; + +import com.czsj.core.database.base.BaseQueryParams; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * api调用日志信息表 查询实体 + *

+ * + * @author yuwei + * @since 2020-08-21 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class ApiLogQuery extends BaseQueryParams { + + private static final long serialVersionUID=1L; + + private String apiName; +} diff --git a/czsj-system/src/main/java/com/czsj/market/query/ApiMaskQuery.java b/czsj-system/src/main/java/com/czsj/market/query/ApiMaskQuery.java new file mode 100644 index 0000000..e4747ca --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/query/ApiMaskQuery.java @@ -0,0 +1,22 @@ +package com.czsj.market.query; + +import com.czsj.core.database.base.BaseQueryParams; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * 数据API脱敏信息表 查询实体 + *

+ * + * @author yuwei + * @since 2020-04-14 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class ApiMaskQuery extends BaseQueryParams { + + private static final long serialVersionUID=1L; + + private String maskName; +} diff --git a/czsj-system/src/main/java/com/czsj/market/query/DataApiQuery.java b/czsj-system/src/main/java/com/czsj/market/query/DataApiQuery.java new file mode 100644 index 0000000..6d7c7c0 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/query/DataApiQuery.java @@ -0,0 +1,22 @@ +package com.czsj.market.query; + +import com.czsj.core.database.base.BaseQueryParams; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * 数据API信息表 查询实体 + *

+ * + * @author yuwei + * @since 2020-03-31 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class DataApiQuery extends BaseQueryParams { + + private static final long serialVersionUID=1L; + + private String apiName; +} diff --git a/czsj-system/src/main/java/com/czsj/market/query/ServiceIntegrationQuery.java b/czsj-system/src/main/java/com/czsj/market/query/ServiceIntegrationQuery.java new file mode 100644 index 0000000..37875c1 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/query/ServiceIntegrationQuery.java @@ -0,0 +1,23 @@ +package com.czsj.market.query; + +import com.czsj.core.database.base.BaseQueryParams; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * 服务集成表 查询实体 + *

+ * + * @author yuwei + * @since 2020-08-20 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class ServiceIntegrationQuery extends BaseQueryParams { + + private static final long serialVersionUID=1L; + + private String serviceName; + private String serviceType; +} diff --git a/czsj-system/src/main/java/com/czsj/market/query/ServiceLogQuery.java b/czsj-system/src/main/java/com/czsj/market/query/ServiceLogQuery.java new file mode 100644 index 0000000..0a4e0fe --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/query/ServiceLogQuery.java @@ -0,0 +1,22 @@ +package com.czsj.market.query; + +import com.czsj.core.database.base.BaseQueryParams; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * 服务集成调用日志表 查询实体 + *

+ * + * @author yuwei + * @since 2020-08-20 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class ServiceLogQuery extends BaseQueryParams { + + private static final long serialVersionUID=1L; + + private String serviceName; +} diff --git a/czsj-system/src/main/java/com/czsj/market/service/ApiLogService.java b/czsj-system/src/main/java/com/czsj/market/service/ApiLogService.java new file mode 100644 index 0000000..9f58360 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/service/ApiLogService.java @@ -0,0 +1,22 @@ +package com.czsj.market.service; + + + +import com.czsj.core.database.base.BaseService; +import com.czsj.market.dto.ApiLogDto; +import com.czsj.market.entity.ApiLogEntity; + +import java.util.List; + +public interface ApiLogService extends BaseService { + + ApiLogEntity saveApiLog(ApiLogDto apiLog); + + ApiLogEntity updateApiLog(ApiLogDto apiLog); + + ApiLogEntity getApiLogById(String id); + + void deleteApiLogById(String id); + + void deleteApiLogBatch(List ids); +} diff --git a/czsj-system/src/main/java/com/czsj/market/service/ApiMaskService.java b/czsj-system/src/main/java/com/czsj/market/service/ApiMaskService.java new file mode 100644 index 0000000..aa21c7c --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/service/ApiMaskService.java @@ -0,0 +1,31 @@ +package com.czsj.market.service; + + +import com.czsj.core.database.base.BaseService; +import com.czsj.market.dto.ApiMaskDto; +import com.czsj.market.entity.ApiMaskEntity; + +import java.util.List; + +/** + *

+ * 数据API脱敏信息表 服务类 + *

+ * + * @author yuwei + * @since 2020-04-14 + */ +public interface ApiMaskService extends BaseService { + + void saveApiMask(ApiMaskDto dataApiMask); + + void updateApiMask(ApiMaskDto dataApiMask); + + ApiMaskEntity getApiMaskById(String id); + + ApiMaskEntity getApiMaskByApiId(String apiId); + + void deleteApiMaskById(String id); + + void deleteApiMaskBatch(List ids); +} diff --git a/czsj-system/src/main/java/com/czsj/market/service/DataApiService.java b/czsj-system/src/main/java/com/czsj/market/service/DataApiService.java new file mode 100644 index 0000000..7dd32d6 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/service/DataApiService.java @@ -0,0 +1,49 @@ +package com.czsj.market.service; + + +import com.aspose.words.Document; +import com.czsj.core.database.base.BaseService; +import com.czsj.market.dto.DataApiDto; +import com.czsj.market.dto.SqlParseDto; +import com.czsj.market.entity.DataApiEntity; +import com.czsj.market.vo.SqlParseVo; +import net.sf.jsqlparser.JSQLParserException; + +import java.sql.SQLException; +import java.util.List; +import java.util.Map; + +/** + *

+ * 数据API信息表 服务类 + *

+ * + * @author yuwei + * @since 2020-03-31 + */ +public interface DataApiService extends BaseService { + + void saveDataApi(DataApiDto dataApi); + + void updateDataApi(DataApiDto dataApi); + + DataApiEntity getDataApiById(String id); + + void deleteDataApiById(String id); + + void deleteDataApiBatch(List ids); + + SqlParseVo sqlParse(SqlParseDto sqlParseDto) throws SQLException, JSQLParserException; + + void copyDataApi(String id); + + void releaseDataApi(String id); + + void cancelDataApi(String id); + + Document wordDataApi(String id) throws Exception; + + Map getDataApiDetailById(String id); + + List getDataApiEntityList(String status); +} diff --git a/czsj-system/src/main/java/com/czsj/market/service/impl/ApiLogServiceImpl.java b/czsj-system/src/main/java/com/czsj/market/service/impl/ApiLogServiceImpl.java new file mode 100644 index 0000000..6f436ba --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/service/impl/ApiLogServiceImpl.java @@ -0,0 +1,60 @@ +package com.czsj.market.service.impl; + + +import com.czsj.core.database.base.BaseServiceImpl; +import com.czsj.market.dto.ApiLogDto; +import com.czsj.market.entity.ApiLogEntity; +import com.czsj.market.mapper.ApiLogDao; +import com.czsj.market.mapstruct.ApiLogMapper; +import com.czsj.market.service.ApiLogService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class) +public class ApiLogServiceImpl extends BaseServiceImpl implements ApiLogService { + + @Autowired + private ApiLogDao apiLogDao; + + @Autowired + private ApiLogMapper apiLogMapper; + + @Override + @Transactional(rollbackFor = Exception.class) + public ApiLogEntity saveApiLog(ApiLogDto apiLogDto) { + ApiLogEntity apiLog = apiLogMapper.toEntity(apiLogDto); + apiLogDao.insert(apiLog); + return apiLog; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public ApiLogEntity updateApiLog(ApiLogDto apiLogDto) { + ApiLogEntity apiLog = apiLogMapper.toEntity(apiLogDto); + apiLogDao.updateById(apiLog); + return apiLog; + } + + @Override + public ApiLogEntity getApiLogById(String id) { + ApiLogEntity apiLogEntity = super.getById(id); + return apiLogEntity; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteApiLogById(String id) { + apiLogDao.deleteById(id); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteApiLogBatch(List ids) { + apiLogDao.deleteBatchIds(ids); + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/service/impl/ApiMappingEngine.java b/czsj-system/src/main/java/com/czsj/market/service/impl/ApiMappingEngine.java new file mode 100644 index 0000000..8b01e25 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/service/impl/ApiMappingEngine.java @@ -0,0 +1,112 @@ +package com.czsj.market.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; +import com.aspose.words.net.System.Data.DataException; +import com.czsj.common.database.constants.DbQueryProperty; +import com.czsj.common.database.service.DataSourceFactory; +import com.czsj.common.database.service.DbQuery; +import com.czsj.common.utils.ThrowableUtil; +import com.czsj.core.database.core.PageResult; +import com.czsj.core.util.PageUtil; +import com.czsj.market.dto.FieldRule; +import com.czsj.market.entity.ApiMaskEntity; +import com.czsj.market.entity.DataApiEntity; +import com.czsj.market.factory.AbstractFactory; +import com.czsj.market.factory.FactoryProducer; +import com.czsj.market.factory.crypto.Crypto; +import com.czsj.market.service.ApiMaskService; +import com.czsj.market.utils.SqlBuilderUtil; +import com.czsj.metadata.dto.DbSchema; +import com.czsj.metadata.entity.MetadataSourceEntity; +import com.czsj.metadata.service.MetadataSourceService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +@Slf4j +@Service +public class ApiMappingEngine { + + @Autowired + private DataSourceFactory dataSourceFactory; + + @Autowired + private MetadataSourceService metadataSourceService; + + @Autowired + private ApiMaskService apiMaskService; + + public PageResult> execute(DataApiEntity dataApi, Map params) { + MetadataSourceEntity dataSource = Optional.ofNullable(metadataSourceService.getMetadataSourceById(dataApi.getExecuteConfig().getSourceId())).orElseThrow(() -> new DataException("API调用查询数据源出错")); + DbSchema dbSchema = dataSource.getDbSchema(); + DbQueryProperty dbQueryProperty = new DbQueryProperty(dataSource.getDbType(), dbSchema.getHost(), + dbSchema.getUsername(), dbSchema.getPassword(), dbSchema.getPort(), dbSchema.getDbName(), dbSchema.getSid()); + DbQuery dbQuery = Optional.ofNullable(dataSourceFactory.createDbQuery(dbQueryProperty)).orElseThrow(() -> new DataException("创建数据查询接口出错")); + // 参数 + Integer pageNum = Integer.parseInt(String.valueOf( params.getOrDefault("pageNum", 1))); + Integer pageSize = Integer.parseInt(String.valueOf(params.getOrDefault("pageSize", 20))); + PageUtil pageUtil = new PageUtil(pageNum, pageSize); + Integer offset = pageUtil.getOffset(); + SqlBuilderUtil.SqlFilterResult sqlFilterResult; + try { + sqlFilterResult = SqlBuilderUtil.getInstance().applyFilters(dataApi.getExecuteConfig().getSqlText(), params); + } catch (Exception e) { + log.error("全局异常信息ex={}, StackTrace={}", e.getMessage(), ThrowableUtil.getStackTrace(e)); + throw new DataException("API调用动态构造SQL语句出错"); + } + Map acceptedFilters = sqlFilterResult.getAcceptedFilters(); + // 数据脱敏 + List rules = null; + + ApiMaskEntity apiMaskEntity = apiMaskService.getApiMaskByApiId(dataApi.getId()); + if (apiMaskEntity != null) { + rules = apiMaskEntity.getRules(); + } + PageResult> pageResult; + try { + pageResult = dbQuery.queryByPage(sqlFilterResult.getSql(), acceptedFilters, offset, pageSize); + } catch (Exception e) { + log.error("全局异常信息ex={}, StackTrace={}", e.getMessage(), ThrowableUtil.getStackTrace(e)); + throw new DataException("API调用查询结果集出错"); + } finally { + dbQuery.close(); + } + try { + if (CollUtil.isNotEmpty(rules)){ + System.out.println(rules.toString()); + // 并行流处理脱敏 + List finalRules = new ArrayList<>(); + for(int i=0;i ruless = (Map)rules.get(i); + FieldRule fieldRule = BeanUtil.fillBeanWithMap(ruless, new FieldRule(), false); + finalRules.add(fieldRule); + } + + pageResult.getData().parallelStream().forEach(m -> { + finalRules.stream().forEach(r -> { + if (m.containsKey(r.getFieldName())) { + Object obj = m.get(r.getFieldName()); + if (null != obj){ + AbstractFactory factory = FactoryProducer.getFactory(r.getCipherType()); + Crypto crypto = factory.getCrypto(r.getCryptType()); + String encrypt = crypto.encrypt(String.valueOf(obj)); + m.put(r.getFieldName(), encrypt); + } + } + }); + }); + } + } catch (Exception e) { + log.error("全局异常信息ex={}, StackTrace={}", e.getMessage(), ThrowableUtil.getStackTrace(e)); + throw new DataException("API调用数据脱敏出错"); + } + pageResult.setPageNum(pageNum).setPageSize(pageSize); + return pageResult; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/service/impl/ApiMaskServiceImpl.java b/czsj-system/src/main/java/com/czsj/market/service/impl/ApiMaskServiceImpl.java new file mode 100644 index 0000000..a398c93 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/service/impl/ApiMaskServiceImpl.java @@ -0,0 +1,80 @@ +package com.czsj.market.service.impl; + + +import com.aspose.words.net.System.Data.DataException; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.czsj.core.database.base.BaseServiceImpl; +import com.czsj.market.dto.ApiMaskDto; +import com.czsj.market.entity.ApiMaskEntity; +import com.czsj.market.mapper.ApiMaskDao; +import com.czsj.market.mapstruct.ApiMaskMapper; +import com.czsj.market.service.ApiMaskService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + *

+ * 数据API脱敏信息表 服务实现类 + *

+ * + * @author yuwei + * @since 2020-04-14 + */ +@Service +@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class) +public class ApiMaskServiceImpl extends BaseServiceImpl implements ApiMaskService { + + @Autowired + private ApiMaskDao apiMaskDao; + + @Autowired + private ApiMaskMapper apiMaskMapper; + + @Override + @Transactional(rollbackFor = Exception.class) + public void saveApiMask(ApiMaskDto apiMaskDto) { + ApiMaskEntity apiMask = apiMaskMapper.toEntity(apiMaskDto); + // 校验api唯一 + int n = apiMaskDao.selectCount(Wrappers.lambdaQuery().eq(ApiMaskEntity::getApiId, apiMask.getApiId())); + if(n > 0){ + throw new DataException("该api已进行过脱敏配置"); + } + apiMaskDao.insert(apiMask); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateApiMask(ApiMaskDto apiMaskDto) { + ApiMaskEntity apiMask = apiMaskMapper.toEntity(apiMaskDto); + apiMaskDao.updateById(apiMask); + } + + @Override + public ApiMaskEntity getApiMaskById(String id) { + ApiMaskEntity apiMaskEntity = super.getById(id); + return apiMaskEntity; + } + + @Override + public ApiMaskEntity getApiMaskByApiId(String apiId) { + ApiMaskEntity apiMaskEntity = apiMaskDao.selectOne(new QueryWrapper().eq("api_id", apiId)); + return apiMaskEntity; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteApiMaskById(String id) { + apiMaskDao.deleteById(id); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteApiMaskBatch(List ids) { + apiMaskDao.deleteBatchIds(ids); + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/service/impl/DataApiServiceImpl.java b/czsj-system/src/main/java/com/czsj/market/service/impl/DataApiServiceImpl.java new file mode 100644 index 0000000..5460b5a --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/service/impl/DataApiServiceImpl.java @@ -0,0 +1,527 @@ +package com.czsj.market.service.impl; + + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import com.aspose.words.Document; +import com.aspose.words.MailMerge; +import com.aspose.words.net.System.Data.DataException; +import com.aspose.words.net.System.Data.DataRow; +import com.aspose.words.net.System.Data.DataTable; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.czsj.common.core.domain.AjaxResult; +import com.czsj.common.core.redis.RedisCache; +import com.czsj.common.database.utils.SecurityUtil; +import com.czsj.common.database.utils.WordUtil; +import com.czsj.common.utils.ThrowableUtil; +import com.czsj.core.database.base.BaseServiceImpl; +import com.czsj.core.database.core.DataConstant; +import com.czsj.market.dto.DataApiDto; +import com.czsj.market.dto.ReqParam; +import com.czsj.market.dto.ResParam; +import com.czsj.market.dto.SqlParseDto; +import com.czsj.market.entity.DataApiEntity; +import com.czsj.market.enums.ConfigType; +import com.czsj.market.handler.MappingHandlerMapping; +import com.czsj.market.mapper.DataApiDao; +import com.czsj.market.mapstruct.DataApiMapper; +import com.czsj.market.service.DataApiService; +import com.czsj.market.utils.MD5Util; +import com.czsj.market.utils.SqlBuilderUtil; +import com.czsj.market.vo.ApiHeader; +import com.czsj.market.vo.SqlParseVo; +import com.czsj.metadata.service.SqlConsoleService; +import lombok.extern.slf4j.Slf4j; +import net.sf.jsqlparser.JSQLParserException; +import net.sf.jsqlparser.expression.ExpressionVisitorAdapter; +import net.sf.jsqlparser.expression.Function; +import net.sf.jsqlparser.expression.JdbcNamedParameter; +import net.sf.jsqlparser.parser.CCJSqlParserUtil; +import net.sf.jsqlparser.schema.Column; +import net.sf.jsqlparser.schema.Table; +import net.sf.jsqlparser.statement.Statement; +import net.sf.jsqlparser.statement.StatementVisitorAdapter; +import net.sf.jsqlparser.statement.select.*; +import net.sf.jsqlparser.util.SelectUtils; +import net.sf.jsqlparser.util.TablesNamesFinder; +import net.sf.jsqlparser.util.deparser.ExpressionDeParser; +import net.sf.jsqlparser.util.deparser.SelectDeParser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.ClassPathResource; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; +import com.czsj.common.utils.uuid.UUID; + +import java.io.InputStream; +import java.sql.SQLException; +import java.time.LocalDateTime; +import java.util.*; +import java.util.stream.Collectors; + +/** + *

+ * 数据API信息表 服务实现类 + *

+ * + * @author yuwei + * @since 2020-03-31 + */ +@Slf4j +@Service +@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class) +public class DataApiServiceImpl extends BaseServiceImpl implements DataApiService { + + @Autowired + private DataApiDao dataApiDao; + + @Autowired + private DataApiMapper dataApiMapper; + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private RedisCache redisService; + + @Autowired + private SqlConsoleService sqlConsoleService; + + @Override + @Transactional(rollbackFor = Exception.class) + public void saveDataApi(DataApiDto dataApiDto) { + String uuid = UUID.randomUUID(true).toString(); + dataApiDto.setApiCode(uuid); + DataApiEntity dataApi = shareCode(dataApiDto); + dataApiDao.insert(dataApi); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateDataApi(DataApiDto dataApiDto) { + DataApiEntity dataApi = shareCode(dataApiDto); + dataApiDao.updateById(dataApi); + } + + private DataApiEntity shareCode(DataApiDto dataApiDto) { + DataApiEntity dataApi = dataApiMapper.toEntity(dataApiDto); + String configType = dataApi.getExecuteConfig().getConfigType(); + if (ConfigType.FORM.getKey().equals(configType)) { + try { + dataApi.getExecuteConfig().setSqlText(sqlJdbcNamedParameterBuild(dataApi)); + } catch (JSQLParserException e) { + log.error("全局异常信息ex={}, StackTrace={}", e.getMessage(), ThrowableUtil.getStackTrace(e)); + throw new DataException("SQL语法有问题,解析出错"); + } + } else if (ConfigType.SCRIPT.getKey().equals(configType)) {} + return dataApi; + } + + @Override + public DataApiEntity getDataApiById(String id) { + DataApiEntity dataApiEntity = super.getById(id); + return dataApiEntity; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteDataApiById(String id) { + dataApiDao.deleteById(id); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteDataApiBatch(List ids) { + dataApiDao.deleteBatchIds(ids); + } + + @Override + public SqlParseVo sqlParse(SqlParseDto sqlParseDto) throws SQLException, JSQLParserException { + String sourceId = sqlParseDto.getSourceId(); + String sql = sqlParseDto.getSqlText(); + sql = sql.replace(SqlBuilderUtil.getInstance().MARK_KEY_START, ""); + sql = sql.replace(SqlBuilderUtil.getInstance().MARK_KEY_END, ""); + Statement stmt; + try { + stmt = CCJSqlParserUtil.parse(sql); + } catch (JSQLParserException e) { + log.error("全局异常信息ex={}, StackTrace={}", e.getMessage(), ThrowableUtil.getStackTrace(e)); + throw new DataException("SQL语法有问题,解析出错"); + } + // 维护元数据缓存数据 + TablesNamesFinder tablesNamesFinder = new TablesNamesFinder(); + List tables = tablesNamesFinder.getTableList(stmt); + // 查询字段 + final List> cols = new ArrayList<>(); + // 查询参数 + final List vars = new ArrayList<>(); + if (tables.size() == 1) { + // 单表解析 + singleSqlParse(stmt, cols, vars, tables.get(0)); + } else if (tables.size() > 1) { + // 多表解析 + multipleSqlParse(stmt, cols, vars); + } + SqlParseVo sqlParseVo = new SqlParseVo(); + List reqParams = vars.stream().map(s -> { + ReqParam reqParam = new ReqParam(); + reqParam.setParamName(s); + reqParam.setNullable(DataConstant.TrueOrFalse.FALSE.getKey()); + return reqParam; + }).collect(Collectors.toList()); + sqlParseVo.setReqParams(reqParams); + + + final List resParams = new ArrayList<>(); + parseFields(sqlParseDto.getSqlText()).forEach((column, alias) -> { + ResParam resParam = new ResParam(); + if(alias.isEmpty()){ + resParam.setFieldName(column); + }else { + resParam.setFieldName(alias); + } + resParams.add(resParam); + }); + +// List sourceEntityList = (List) redisService.get(RedisConstant.METADATA_SOURCE_KEY); +// MetadataSourceEntity sourceEntity = sourceEntityList.stream().filter(s -> sourceId.equals(s.getId())).findFirst().orElse(null); +// if (sourceEntity != null) { +// List tableEntityList = (List) redisService.hget(RedisConstant.METADATA_TABLE_KEY, sourceEntity.getId()); +// Map>> map = cols.stream().collect(Collectors.groupingBy(e -> e.get("tableName").toString())); +// for (Map.Entry>> entry : map.entrySet()) { +// String entryKey = entry.getKey().toLowerCase(); +// List> entryValue = entry.getValue(); +// MetadataTableEntity tableEntity = tableEntityList.stream().filter(t -> entryKey.equals(t.getTableName().toLowerCase())).findFirst().orElse(null); +// if (tableEntity != null) { +// List columnEntityList = (List) redisService.hget(RedisConstant.METADATA_COLUMN_KEY, tableEntity.getId()); +// entryValue.stream().forEach(m -> { +// String columnName = m.get("columnName").toLowerCase(); +// String columnAliasName = m.get("columnAliasName"); +// Stream stream = columnEntityList.stream().filter(c -> columnName.equals(c.getColumnName().toLowerCase())); +// MetadataColumnEntity columnEntity = stream.findFirst().orElse(null); +// ResParam resParam = new ResParam(); +// if (columnEntity != null) { +// resParam.setFieldName(columnEntity.getColumnName()); +// resParam.setFieldComment(StrUtil.isNotBlank(columnEntity.getColumnComment()) ? columnEntity.getColumnComment() : ""); +// resParam.setDataType(StrUtil.isNotBlank(columnEntity.getDataType()) ? columnEntity.getDataType() : ""); +// resParam.setFieldAliasName(StrUtil.isNotBlank(columnAliasName) ? columnAliasName : ""); +// }else{ +// resParam.setFieldName(columnName); +// } +// resParams.add(resParam); +// }); +// } +// } +// } + sqlParseVo.setResParams(resParams); + return sqlParseVo; + } + + private void singleSqlParse(Statement stmt, List> cols, List vars, String tableName) { + stmt.accept(new StatementVisitorAdapter() { + @Override + public void visit(Select select) { + select.getSelectBody().accept(new SelectVisitorAdapter() { + @Override + public void visit(PlainSelect plainSelect) { + plainSelect.getSelectItems().forEach(selectItem -> { + selectItem.accept(new SelectItemVisitorAdapter() { + @Override + public void visit(SelectExpressionItem item) { + Map map = new HashMap<>(); + String columnName; + Object expression = item.getExpression(); + + if (expression instanceof Column) { + Column column = (Column) expression; + columnName = column.getColumnName(); + if (item.getAlias() != null) { + map.put("columnAliasName", item.getAlias().getName()); + } + } else if (expression instanceof Function) { + columnName = expression.toString(); + } else { + // 增加对select 'aaa' from table; 的支持 + columnName = String.valueOf(expression); + columnName = columnName.replace("'", "").replace("\"", "").replace("`", ""); + } + columnName = columnName.replace("'", "").replace("\"", "").replace("`", ""); + map.put("tableName", tableName); + map.put("columnName", columnName); + cols.add(map); + } + }); + }); + if (plainSelect.getWhere() != null) { + plainSelect.getWhere().accept(new ExpressionVisitorAdapter() { + @Override + public void visit(JdbcNamedParameter jdbcNamedParameter) { + vars.add(jdbcNamedParameter.getName()); + } + }); + } + } + }); + } + }); + } + + private void multipleSqlParse(Statement stmt, List> cols, List vars) { + stmt.accept(new StatementVisitorAdapter() { + @Override + public void visit(Select select) { + select.getSelectBody().accept(new SelectVisitorAdapter() { + @Override + public void visit(PlainSelect plainSelect) { + // 存储表名 + Map map = new HashMap<>(); + Table table = (Table) plainSelect.getFromItem(); + if (table.getAlias() != null) { + map.put(table.getName(), table.getAlias().getName()); + } + for (Join join : plainSelect.getJoins()) { + Table table1 = (Table) join.getRightItem(); + if (table1.getAlias() != null) { + map.put(table1.getName(), table1.getAlias().getName()); + } + } + plainSelect.getSelectItems().forEach(selectItem -> { + selectItem.accept(new SelectItemVisitorAdapter() { + @Override + public void visit(SelectExpressionItem item) { + Map m = new HashMap<>(); + String tableName = "", columnName; + Object expression = item.getExpression(); + if (expression instanceof Column) { + Column column = (Column) expression; + Table table = column.getTable(); + if (table != null) { + for (Map.Entry entry : map.entrySet()) { + if (table.getName().equals(entry.getValue())) { + tableName = entry.getKey(); + break; + } + } + } + columnName = column.getColumnName(); + if (item.getAlias() != null) { + m.put("columnAliasName", item.getAlias().getName()); + } + } else if (expression instanceof Function) { + columnName = expression.toString(); + } else { + // 增加对select 'aaa' from table; 的支持 + columnName = String.valueOf(expression); + columnName = columnName.replace("'", "").replace("\"", "").replace("`", ""); + } + columnName = columnName.replace("'", "").replace("\"", "").replace("`", ""); + m.put("tableName", tableName); + m.put("columnName", columnName); + cols.add(m); + } + }); + }); + if (plainSelect.getWhere() != null) { + plainSelect.getWhere().accept(new ExpressionVisitorAdapter() { + @Override + public void visit(JdbcNamedParameter jdbcNamedParameter) { + vars.add(jdbcNamedParameter.getName()); + } + }); + } + } + }); + } + }); + } + + private String sqlJdbcNamedParameterBuild(DataApiEntity dataApi) throws JSQLParserException { + Table table = new Table(dataApi.getExecuteConfig().getTableName()); + String[] resParams = dataApi.getResParams().stream().map(s -> s.getFieldName()).toArray(String[]::new); + Select select = SelectUtils.buildSelectFromTableAndExpressions(table, resParams); + return SqlBuilderUtil.getInstance().buildHql(select.toString(), dataApi.getReqParams()); + } + + private String sqlJdbcNamedParameterParse(String sqlText) throws JSQLParserException { + final StringBuilder buffer = new StringBuilder(); + ExpressionDeParser expressionDeParser = new ExpressionDeParser() { + @Override + public void visit(JdbcNamedParameter jdbcNamedParameter) { + this.getBuffer().append("?"); + } + }; + SelectDeParser deparser = new SelectDeParser(expressionDeParser, buffer); + expressionDeParser.setSelectVisitor(deparser); + expressionDeParser.setBuffer(buffer); + Statement stmt = CCJSqlParserUtil.parse(sqlText); + stmt.accept(new StatementVisitorAdapter() { + @Override + public void visit(Select select) { + select.getSelectBody().accept(deparser); + } + }); + return buffer.toString(); + } + + @Override + public void copyDataApi(String id) { + DataApiEntity dataApiEntity = Optional.ofNullable(super.getById(id)).orElseThrow(() -> new DataException("获取失败")); + DataApiEntity copy = new DataApiEntity(); + copy.setApiName(dataApiEntity.getApiName() + "_副本" + DateUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_PATTERN)); + copy.setApiVersion(dataApiEntity.getApiVersion()); + copy.setApiUrl(dataApiEntity.getApiUrl() + "/copy" + DateUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_PATTERN)); + copy.setReqMethod(dataApiEntity.getReqMethod()); + copy.setResType(dataApiEntity.getResType()); + copy.setDeny(dataApiEntity.getDeny()); + copy.setRateLimit(dataApiEntity.getRateLimit()); + copy.setExecuteConfig(dataApiEntity.getExecuteConfig()); + copy.setReqParams(dataApiEntity.getReqParams()); + copy.setResParams(dataApiEntity.getResParams()); + copy.setStatus(DataConstant.ApiState.WAIT.getKey()); + dataApiDao.insert(copy); + } + + @Override + public void releaseDataApi(String id) { + Map map = new HashMap<>(2); + map.put("id", id); + map.put("type", "1"); + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.set(DataApiEntity::getStatus, DataConstant.ApiState.RELEASE.getKey()); + updateWrapper.eq(DataApiEntity::getId, id); + dataApiDao.update(null, updateWrapper); + DataApiEntity dataApiEntity = dataApiDao.selectById(id); + MappingHandlerMapping.registerMapping(dataApiEntity); + } + + @Override + public void cancelDataApi(String id) { + Map map = new HashMap<>(2); + map.put("id", id); + map.put("type", "2"); + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.set(DataApiEntity::getStatus, DataConstant.ApiState.CANCEL.getKey()); + updateWrapper.eq(DataApiEntity::getId, id); + dataApiDao.update(null, updateWrapper); + DataApiEntity dataApiEntity = dataApiDao.selectById(id); + MappingHandlerMapping.unregisterMapping(dataApiEntity); + } + + @Override + public Document wordDataApi(String id) throws Exception { + //注册编码提供程序 + DataApiEntity dataApiEntity = super.getById(id); + // 合并模版 + ClassPathResource classPathResource = new ClassPathResource("templates/api_1.0.0.docx"); + InputStream inputStream = classPathResource.getInputStream(); + Document doc = WordUtil.getInstance().getDocument(inputStream); + // 提供字段 + MD5Util mt = MD5Util.getInstance(); + String apiKey = mt.encode(id); + String secretkey = mt.encode(SecurityUtil.getUserId()); + String[] fieldNames = new String[] {"apiName", "apiVersion", "reqMethod", "resType", "apiUrl", "remark", "apiKey", "secretkey","apiCode"}; + Object[] fieldValues = new Object[] {dataApiEntity.getApiName(), dataApiEntity.getApiVersion(), dataApiEntity.getReqMethod(), dataApiEntity.getResType(), dataApiEntity.getApiUrl(), dataApiEntity.getRemark(), apiKey, secretkey,dataApiEntity.getApiCode()}; + MailMerge mailMerge = doc.getMailMerge(); + mailMerge.execute(fieldNames, fieldValues); + // 请求参数 TableStart:ReqParamList TableEnd:ReqParamList + DataTable reqParamTable = new DataTable("ReqParamList"); + reqParamTable.getColumns().add("paramName"); + reqParamTable.getColumns().add("paramComment"); + reqParamTable.getColumns().add("paramType"); + reqParamTable.getColumns().add("nullable"); + reqParamTable.getColumns().add("exampleValue"); + List reqParamList = objectMapper.convertValue(dataApiEntity.getReqParams(), new TypeReference>() {}); + ReqParam reqparam = new ReqParam(); + reqparam.setParamName("apiCode"); + reqparam.setParamComment("接口key"); + reqparam.setParamType("String"); + reqparam.setNullable("N"); + reqparam.setExampleValue(dataApiEntity.getApiCode()); + reqParamList.add(reqparam); + for (int i = 0; i < reqParamList.size(); i++) { + DataRow row = reqParamTable.newRow(); + ReqParam param = reqParamList.get(i); + row.set(0, param.getParamName()); + row.set(1, param.getParamComment()); + row.set(2, param.getParamType()); + row.set(3, "1".equals(param.getNullable()) ? "Y" : "N"); + row.set(4, param.getExampleValue()); + reqParamTable.getRows().add(row); + } + mailMerge.executeWithRegions(reqParamTable); + // 返回字段 TableStart:ResParamList TableEnd:ResParamList + DataTable resParamTable = new DataTable("ResParamList"); + resParamTable.getColumns().add("fieldName"); + resParamTable.getColumns().add("dataType"); + resParamTable.getColumns().add("fieldComment"); + resParamTable.getColumns().add("exampleValue"); + List resParamList = objectMapper.convertValue(dataApiEntity.getResParams(), new TypeReference>() {}); + for (int i = 0; i < resParamList.size(); i++) { + DataRow row = resParamTable.newRow(); + ResParam param = resParamList.get(i); + row.set(0, param.getFieldName()); + row.set(1, param.getDataType()); + row.set(2, param.getFieldComment()); + row.set(3, param.getExampleValue()); + resParamTable.getRows().add(row); + } + mailMerge.executeWithRegions(resParamTable); + // 返回示例 reqExample resExample + ObjectNode objectNode = objectMapper.createObjectNode(); + for (int i = 0; i < resParamList.size(); i++) { + ResParam param = resParamList.get(i); + objectNode.put(param.getFieldName(), param.getExampleValue()); + } + mailMerge.execute(new String[] {"reqExample", "resExample"}, new Object[] {objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(AjaxResult.success(new LinkedList(){{add(objectNode);}})), objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(AjaxResult.error("返回失败"))}); + WordUtil.getInstance().insertWatermarkText(doc, SecurityUtil.getUserName()); + return doc; + } + + @Override + public Map getDataApiDetailById(String id) { + DataApiEntity dataApiEntity = super.getById(id); + ApiHeader apiHeader = new ApiHeader(); + MD5Util mt = null; + try { + mt = MD5Util.getInstance(); + apiHeader.setApiKey(mt.encode(id)); + apiHeader.setSecretKey(mt.encode(SecurityUtil.getUserId())); + } catch (Exception e) { + e.printStackTrace(); + } + Map map = new HashMap<>(2); + map.put("data", dataApiMapper.toVO(dataApiEntity)); + map.put("header", apiHeader); + return map; + } + + @Override + public List getDataApiEntityList(String status) { + return dataApiDao.getDataApiEntityList(status); + } + + public static Map parseFields(String sql) throws JSQLParserException { + // Remove placeholders + sql = sql.replaceAll("\\$\\{.*?\\}", ""); + + Map fields = new HashMap<>(); + Select select = (Select) CCJSqlParserUtil.parse(sql); + PlainSelect plainSelect = (PlainSelect) select.getSelectBody(); + List selectItems = plainSelect.getSelectItems(); + + for (SelectItem selectItem : selectItems) { + selectItem.accept(new SelectItemVisitorAdapter() { + @Override + public void visit(SelectExpressionItem item) { + String columnName = item.getExpression().toString().replaceAll("^[a-zA-Z]+\\.", ""); + String alias = item.getAlias() != null ? item.getAlias().getName().replaceAll("^[a-zA-Z]+\\.", "") : columnName; + fields.put(columnName, alias); + } + }); + } + return fields; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/utils/MD5Util.java b/czsj-system/src/main/java/com/czsj/market/utils/MD5Util.java new file mode 100644 index 0000000..1e605fe --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/utils/MD5Util.java @@ -0,0 +1,123 @@ +package com.czsj.market.utils; + +import javax.crypto.Cipher; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.DESKeySpec; +import javax.crypto.spec.IvParameterSpec; +import java.security.Key; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.spec.AlgorithmParameterSpec; +import java.util.Base64; + +public class MD5Util { + + /** 向量(同时拥有向量和密匙才能解密),此向量必须是8byte,多少都报错 */ + private final byte[] DESIV = new byte[] { 0x22, 0x54, 0x36, 110, 0x40, (byte) 0xac, (byte) 0xad, (byte) 0xdf }; + /** 自定义密钥,个数不能太短,太短报错,过长,它默认只取前N位(N的具体值,大家另行查找资料) */ + private final String deSkey = "datax-cloud"; + /** 加密算法的参数接口 */ + private AlgorithmParameterSpec iv = null; + private Key key = null; + private String charset = "UTF-8"; + + private static volatile MD5Util instance; + + /** + * 构造函数 + * @throws Exception + */ + private MD5Util() throws Exception { + // 设置密钥参数 + DESKeySpec keySpec = new DESKeySpec(deSkey.getBytes(this.charset)); + // 设置向量 + iv = new IvParameterSpec(DESIV); + // 获得密钥工厂 + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); + // 得到密钥对象 + key = keyFactory.generateSecret(keySpec); + } + + public static MD5Util getInstance() throws Exception { + if(instance == null) { + synchronized (MD5Util.class) { + if(instance == null) { + instance = new MD5Util(); + } + } + } + return instance; + } + + public static void main(String[] args) { + try { + String value = "1246656415670484994"; + MD5Util mt = new MD5Util(); + System.out.println("加密前的字符:" + value); + System.out.println("加密后的字符:" + mt.encode(value)); + System.out.println("解密后的字符:" + mt.decode(mt.encode(value))); + System.out.println("字符串的MD5值:"+ getMD5Value(value)); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 加密 + * @param data + * @return + * @throws Exception + */ + public String encode(String data) throws Exception { + // 得到加密对象Cipher + Cipher enCipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); + // 设置工作模式为加密模式,给出密钥和向量 + enCipher.init(Cipher.ENCRYPT_MODE, key, iv); + byte[] pasByte = enCipher.doFinal(data.getBytes(this.charset)); + return Base64.getEncoder().encodeToString(pasByte); + } + + /** + * 解密 + * @param data + * @return + * @throws Exception + */ + public String decode(String data) throws Exception { + Cipher deCipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); + deCipher.init(Cipher.DECRYPT_MODE, key, iv); + //此处注意doFinal()的参数的位数必须是8的倍数,否则会报错(通过encode加密的字符串读出来都是8的倍数位,但写入文件再读出来,就可能因为读取的方式的问题,导致最后此处的doFinal()的参数的位数不是8的倍数) + //此处必须用base64Decoder,若用data。getBytes()则获取的字符串的byte数组的个数极可能不是8的倍数,而且不与上面的BASE64Encoder对应(即使解密不报错也不会得到正确结果) + byte[] pasByte = deCipher.doFinal(Base64.getDecoder().decode(data)); + return new String(pasByte, this.charset); + } + + /** + * 获取MD5的值,可用于对比校验 + * @param sourceStr + * @return + */ + private static String getMD5Value(String sourceStr) { + String result = ""; + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + md.update(sourceStr.getBytes()); + byte b[] = md.digest(); + int i; + StringBuffer buf = new StringBuffer(""); + for (int offset = 0; offset < b.length; offset++) { + i = b[offset]; + if (i < 0) { + i += 256; + } + if (i < 16) { + buf.append("0"); + } + buf.append(Integer.toHexString(i)); + } + result = buf.toString(); + } catch (NoSuchAlgorithmException e) { + } + return result; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/utils/NamedParameterUtil.java b/czsj-system/src/main/java/com/czsj/market/utils/NamedParameterUtil.java new file mode 100644 index 0000000..7d0c266 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/utils/NamedParameterUtil.java @@ -0,0 +1,147 @@ +package com.czsj.market.utils; + +import com.aspose.words.net.System.Data.DataException; +import org.springframework.util.Assert; + +import java.util.*; + +/** + * 带参数sql处理工具类 + */ +public class NamedParameterUtil { + +// public static void main(String[] args) { +// String sql = "select * from user where 1 = 1 ${ and id = :id } ${and name = :name}"; +// int start = sql.indexOf("${"); +// int end = sql.indexOf("}", start); +// String key = sql.substring(start + 2, end); +// System.out.println(key); +// Map params = new HashMap<>(); +// params.put("name", "yuwei"); +// params.put("id", "123"); +// params.put("age", 12); +// ParsedSql parsedSql = NamedParameterUtil.parseSqlStatement(key); +// System.out.println(parsedSql); +// String actualSql = NamedParameterUtil.substituteNamedParams(parsedSql, params); +// Map acceptedFilters = NamedParameterUtil.buildValueArray(parsedSql, params); +// System.out.println(actualSql); +// System.out.println(acceptedFilters); +// SqlBuilderUtil.SqlFilterResult sqlFilterResult = SqlBuilderUtil.getInstance().applyFilters(sql, params); +// System.out.println(sqlFilterResult.getSql()); +// Object[] array = new Object[] {}; +// array = sqlFilterResult.getAcceptedFilters().values().toArray(); +// Arrays.stream(array).forEach(s -> System.out.println(s)); +// } + + private NamedParameterUtil() {} + + /** + * 定义特殊字符(增加最后的自定义的'}') + */ + private static final char[] PARAMETER_SEPARATORS = + new char[] {'"', '\'', ':', '&', ',', ';', '(', ')', '|', '=', '+', '-', '*', '%', '/', '\\', '<', '>', '^', '}'}; + + /** + * 对带参数sql的统计式封装,便于后续肢解拼装 + * @param originalSql + * @return + */ + public static ParsedSql parseSqlStatement(String originalSql) { + Assert.notNull(originalSql, "SQL must not be null"); + ParsedSql parsedSql = new ParsedSql(originalSql); + Set namedParameters = new HashSet(); + char[] sqlchars = originalSql.toCharArray(); + int namedParamCount = 0; + int unNamedParamCount = 0; + int totalParamCount = 0; + int i = 0; + while (i < sqlchars.length) { + char statement = sqlchars[i]; + if (statement == ':') { + int j = i + 1; + while (j < sqlchars.length && !isSeparatorsChar(sqlchars[j])) { + j++; + } + if (j - i > 1) { + String paramName = originalSql.substring(i + 1, j); + if (!namedParameters.contains(paramName)) { + namedParameters.add(paramName); + namedParamCount++; + } + parsedSql.addParamNames(paramName, i, j); + totalParamCount++; + } + i = j - 1; + } else if (statement == '?') { + unNamedParamCount++; + totalParamCount++; + } + i++; + } + parsedSql.setNamedParamCount(namedParamCount); + parsedSql.setUnnamedParamCount(unNamedParamCount); + parsedSql.setTotalParamCount(totalParamCount); + return parsedSql; + } + + /** + * 获得不带参数的sql,即替换参数为? + * @param parsedSql + * @param params + * @return + */ + public static String substituteNamedParams(ParsedSql parsedSql, Map params){ + String original = parsedSql.getOriginalSql(); + StringBuffer actual = new StringBuffer(""); + int lastIndex = 0; + List paramNames = parsedSql.getParamNames(); + for (int i = 0; i < paramNames.size(); i++) { + int[] indexs = parsedSql.getParamIndexs(i); + int startIndex = indexs[0]; + int endIndex = indexs[1]; + String paramName = paramNames.get(i); + actual.append(original.substring(lastIndex, startIndex)); + if (params != null && params.containsKey(paramName)) { + actual.append("?"); + } else{ + actual.append("?"); + } + lastIndex = endIndex; + } + actual.append(original.subSequence(lastIndex, original.length())); + return actual.toString(); + } + + /** + * 获得sql所需参数K,V + * @param parsedSql + * @param params + * @return + */ + public static LinkedHashMap buildValueArray(ParsedSql parsedSql, Map params){ + List paramNames = parsedSql.getParamNames(); + LinkedHashMap acceptedFilters = new LinkedHashMap<>(parsedSql.getTotalParamCount()); + if (parsedSql.getNamedParamCount() > 0 && parsedSql.getUnnamedParamCount() > 0) { + throw new DataException("parameter方式与?方式不能混合!"); + } + for (int i = 0; i < paramNames.size(); i++) { + String keyName = paramNames.get(i); + if (params.containsKey(keyName)) { + acceptedFilters.put(keyName, params.get(keyName)); + } + } + return acceptedFilters; + } + + private static boolean isSeparatorsChar(char statement){ + if (Character.isWhitespace(statement)) { + return true; + } + for (int i = 0; i < PARAMETER_SEPARATORS.length; i++) { + if (statement == PARAMETER_SEPARATORS[i]) { + return true; + } + } + return false; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/utils/ParsedSql.java b/czsj-system/src/main/java/com/czsj/market/utils/ParsedSql.java new file mode 100644 index 0000000..4a50e5c --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/utils/ParsedSql.java @@ -0,0 +1,82 @@ +package com.czsj.market.utils; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * 此类封装NamedParameterSql + */ +public class ParsedSql implements Serializable { + + private static final long serialVersionUID=1L; + + private String originalSql; + //参数名 + private List paramNames = new ArrayList<>(); + //参数在sql中对应的位置 + private List paramIndexs = new ArrayList<>(); + //统计参数个数(不包含重复) + private int namedParamCount; + //统计sql中?的个数 + private int unnamedParamCount; + + private int totalParamCount; + + public ParsedSql(String originalSql){ + this.originalSql = originalSql; + } + + public List getParamNames() { + return paramNames; + } + + public void addParamNames(String paramName,int startIndex,int endIndex) { + paramNames.add(paramName); + paramIndexs.add(new int[]{startIndex,endIndex}); + } + + public int[] getParamIndexs(int position) { + return paramIndexs.get(position); + } + + public String getOriginalSql() { + return originalSql; + } + + public int getNamedParamCount() { + return namedParamCount; + } + + public void setNamedParamCount(int namedParamCount) { + this.namedParamCount = namedParamCount; + } + + public int getUnnamedParamCount() { + return unnamedParamCount; + } + + public void setUnnamedParamCount(int unnamedParamCount) { + this.unnamedParamCount = unnamedParamCount; + } + + public int getTotalParamCount() { + return totalParamCount; + } + + public void setTotalParamCount(int totalParamCount) { + this.totalParamCount = totalParamCount; + } + + @Override + public String toString() { + return "ParsedSql{" + + "originalSql='" + originalSql + '\'' + + ", paramNames=" + paramNames + + ", paramIndexs=" + paramIndexs + + ", namedParamCount=" + namedParamCount + + ", unnamedParamCount=" + unnamedParamCount + + ", totalParamCount=" + totalParamCount + + '}'; + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/utils/SqlBuilderUtil.java b/czsj-system/src/main/java/com/czsj/market/utils/SqlBuilderUtil.java new file mode 100644 index 0000000..9d3543f --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/utils/SqlBuilderUtil.java @@ -0,0 +1,319 @@ +package com.czsj.market.utils; + + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ObjectUtil; +import com.czsj.market.dto.ReqParam; +import com.czsj.market.enums.WhereType; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.Assert; + +import java.io.Serializable; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * 用于动态构造sql语句 + * ${ segment... } 为一个条件代码块 + * + * String sql = "select * from user where 1=1 + * ${ and username = :username } + * ${ and password = :password } + * ${ and age = :age }" + * + * Map filters = new HashMap(); + * filters.put("username", "yuwei"); + * filters.put("age", "12"); + * filters.put("id", "123"); + * + * SqlFilterResult result = SqlBuilderUtil.applyFilters(sql, filters); + * + * result.getSql()结果 + * select * from user where 1=1 and username=:username and age=:age + * + * result.getAcceptedFilters()结果 + * {username=yuwei} + * {age=12} + */ +@Slf4j +public class SqlBuilderUtil { + + private SqlBuilderUtil() {} + + private static volatile SqlBuilderUtil instance; + + public static SqlBuilderUtil getInstance() { + if(instance == null) { + synchronized (SqlBuilderUtil.class) { + if(instance == null) { + instance = new SqlBuilderUtil(); + } + } + } + return instance; + } + + /** + * 空格 + */ + private final String SPACE = " "; + /** + * 冒号占位符 + */ + private final String COLON = ":"; + /** + * 问号占位符 + */ + private final String MARK = "?"; + /** + * where关键字 + */ + private final String WHERE_SQL = "WHERE"; + /** + * AND连接符 + */ + private final String WHERE_AND = "AND"; + /** + * where 1=1条件 + */ + private final String WHERE_INIT = WHERE_SQL + " 1 = 1"; + /** + * 左括号 + */ + private final String LEFT_BRACKET = "("; + /** + * 右括号 + */ + private final String RIGHT_BRACKET = ")"; + /** + * 百分号% + */ + private final String PERCENT_SIGN = "%"; + /** + * 单引号 ' + */ + private final String SINGLE_QUOTE = "'"; + /** + * 条件代码块标记开始 + */ + public final String MARK_KEY_START = "${"; + /** + * 条件代码块标记结束 + */ + public final String MARK_KEY_END = "}"; + + /** + * <= + */ + private final String LET = "<="; + + /** + * >= + */ + private final String GET = ">="; + + private final String START = "_Start"; + + private final String END = "_End"; + + + /** + * 拼接命名参数sql + * @param sql + * @param params + * @return + */ + public String buildHql(String sql, List params){ + Assert.notNull(sql, "SQL must not be null"); + return buildHql(new StringBuffer(sql), params); + } + + private String buildHql(StringBuffer sql, List params){ + if(CollUtil.isEmpty(params)){ + return sql.toString(); + } + sql.append(SPACE).append(WHERE_INIT); + for (int i = 0; i < params.size(); i++) { + ReqParam reqParam = params.get(i); + sql.append(SPACE).append(MARK_KEY_START).append(WHERE_AND).append(SPACE).append(reqParam.getParamName()); + if (WhereType.LIKE.getType().equals(reqParam.getWhereType()) ) { + // LIKE :username 把%带到参数里面去 + sql.append(SPACE).append(WhereType.getWhereType(reqParam.getWhereType()).getKey()) + .append(SPACE) + .append(COLON).append(reqParam.getParamName()) + .append(SPACE).append(MARK_KEY_END); + } else if(WhereType.LIKE_LEFT.getType().equals(reqParam.getWhereType())) { + sql.append(SPACE).append(WhereType.getWhereType(reqParam.getWhereType()).getKey()) + .append(SPACE).append(SINGLE_QUOTE).append(PERCENT_SIGN).append(SINGLE_QUOTE).append(SPACE) + .append(COLON).append(reqParam.getParamName()).append(MARK_KEY_END); + } else if(WhereType.LIKE_RIGHT.getType().equals(reqParam.getWhereType())) { + sql.append(SPACE).append(WhereType.getWhereType(reqParam.getWhereType()).getKey()) + .append(SPACE).append(COLON).append(reqParam.getParamName()) + .append(SPACE).append(SINGLE_QUOTE).append(PERCENT_SIGN).append(SINGLE_QUOTE).append(MARK_KEY_END); + } else if(WhereType.NULL.getType().equals(reqParam.getWhereType()) || WhereType.NOT_NULL.getType().equals(reqParam.getWhereType())){ + // is null或is not null不需要参数值 + sql.append(SPACE).append(WhereType.getWhereType(reqParam.getWhereType()).getKey()).append(MARK_KEY_END); + } else if(WhereType.IN.getType().equals(reqParam.getWhereType())){ + // in (:ids) + sql.append(SPACE).append(WhereType.getWhereType(reqParam.getWhereType()).getKey()) + .append(SPACE).append(LEFT_BRACKET) + .append(COLON).append(reqParam.getParamName()) + .append(RIGHT_BRACKET).append(MARK_KEY_END); + } else if(WhereType.BETWEEN.getType().equals(reqParam.getWhereType())){ + sql.append(SPACE).append(SPACE).append(GET) + .append(COLON).append(reqParam.getParamName()).append(START) + .append(SPACE).append(WHERE_AND).append(SPACE) + .append(reqParam.getParamName()) + .append(SPACE).append(LET) + .append(COLON).append(reqParam.getParamName()).append(END) + .append(MARK_KEY_END); + }else { + sql.append(SPACE).append(WhereType.getWhereType(reqParam.getWhereType()).getKey()) + .append(SPACE).append(COLON).append(reqParam.getParamName()).append(MARK_KEY_END); + } + } + return sql.toString(); + } + + /** + * 根据入参动态构造sql语句 + * @param sql + * @param filters + * @return + */ + public SqlFilterResult applyFilters(String sql, Map filters){ + Assert.notNull(sql, "SQL must not be null"); + return applyFilters(new StringBuffer(sql), filters); + } + + private SqlFilterResult applyFilters(StringBuffer sql, Map filters){ + LinkedHashMap acceptedFilters = new LinkedHashMap<>(); + for (int i = 0, end = 0, start = sql.indexOf(MARK_KEY_START); ((start = sql.indexOf(MARK_KEY_START, end)) >= 0); i++) { + end = sql.indexOf(MARK_KEY_END, start); + // 封装该条件代码块中的NamedParameterSql + ParsedSql parsedSql = getSegmentParsedSql(sql, start, end); + if (CollUtil.isEmpty(parsedSql.getParamNames())){ + throw new IllegalArgumentException("Not key found in segment=" + sql.substring(start, end + MARK_KEY_END.length())); + } + // 判断输入参数filters中是否存在查询参数 + if (isAcceptedKeys(filters, parsedSql.getParamNames())) { + // 动态构造可执行的sql语句,去掉条件代码块两边的${ }标记符 + if (log.isDebugEnabled()) { + log.debug("The filter namedParameters=" + parsedSql.getParamNames() + " is accepted on segment=" + sql.substring(start, end + MARK_KEY_END.length())); + } + // 下面方法2选1可以获取条件代码块 + // select id, name from user where 1 = 1 and id = :id +// String segment = sql.substring(start + MARK_KEY_START.length(), end); + String segment = parsedSql.getOriginalSql(); + // 转换命名参数:为? + // select id, name from user where 1 = 1 and id = ? +// String segment = NamedParameterUtil.substituteNamedParams(parsedSql, filters); + // 获取传参中包含命名参数的数据 + LinkedHashMap linkAcceptedFilters = NamedParameterUtil.buildValueArray(parsedSql, filters); + acceptedFilters.putAll(linkAcceptedFilters); + sql.replace(start, end + MARK_KEY_END.length(), segment); + end = start + segment.length(); + } else { + // 抛弃该条件代码块 + if (log.isDebugEnabled()) { + log.debug("The filter namedParameters=" + parsedSql.getParamNames() + " is removed from the query on segment=" + sql.substring(start, end + MARK_KEY_END.length())); + } + sql.replace(start, end + MARK_KEY_END.length(), ""); + end = start; + } + } + return new SqlFilterResult(sql.toString(), acceptedFilters); + } + + /** + * 验证入参,并过滤值为空的入参 + */ + private boolean isAcceptedKeys(Map filters, List keys) { + for (int i = 0; i < keys.size(); i++) { + String key = keys.get(i); + Object value = getProperty(filters, key); + if (!isValuePopulated(value, true)) { + return false; + } + } + return true; + } + + /** + * 封装该条件代码块中的NamedParameterSql + */ + private ParsedSql getSegmentParsedSql(StringBuffer sql, int start, int end) { + String segment = sql.substring(start + MARK_KEY_START.length(), end); + ParsedSql parsedSql = NamedParameterUtil.parseSqlStatement(segment); + return parsedSql; + } + + /** + * 获取参数值 + * @param filters + * @param key + * @return + */ + private Object getProperty(Map filters, String key) { + if (MapUtil.isEmpty(filters)) + return null; + return filters.get(key); + } + + /** + * 验证参数值是否空 + * @param value + * @param isRemoveEmpty + * @return + */ + private boolean isValuePopulated(Object value, boolean isRemoveEmpty) { + if (value == null) { + return false; + } + if (isRemoveEmpty) { + return ObjectUtil.isNotEmpty(value); + } else { + return true; + } + } + + public class SqlFilterResult implements Serializable { + + private static final long serialVersionUID=1L; + + private String sql; + + private Map acceptedFilters; + + public SqlFilterResult(String sql, Map acceptedFilters) { + this.setSql(sql); + this.setAcceptedFilters(acceptedFilters); + } + + public String getSql() { + return sql; + } + + public void setSql(String sql) { + this.sql = sql; + } + + public Map getAcceptedFilters() { + return acceptedFilters; + } + + public void setAcceptedFilters(Map acceptedFilters) { + this.acceptedFilters = acceptedFilters; + } + + @Override + public String toString() { + return "SqlFilterResult{" + + "sql='" + sql + '\'' + + ", acceptedFilters=" + acceptedFilters + + '}'; + } + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/utils/ThreadUtil.java b/czsj-system/src/main/java/com/czsj/market/utils/ThreadUtil.java new file mode 100644 index 0000000..1d8ce64 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/utils/ThreadUtil.java @@ -0,0 +1,36 @@ +package com.czsj.market.utils; + + +import com.czsj.market.dto.ApiLogDto; + +public class ThreadUtil { + + private ThreadUtil() {} + + private static volatile ThreadUtil instance; + + public static ThreadUtil getInstance() { + if(instance == null) { + synchronized (ThreadUtil.class) { + if(instance == null) { + instance = new ThreadUtil(); + } + } + } + return instance; + } + + private final static ThreadLocal logHolder = new ThreadLocal<>(); + + public void set(ApiLogDto log){ + logHolder.set(log); + } + + public void remove(){ + logHolder.remove(); + } + + public ApiLogDto get(){ + return logHolder.get(); + } +} diff --git a/czsj-system/src/main/java/com/czsj/market/vo/ApiHeader.java b/czsj-system/src/main/java/com/czsj/market/vo/ApiHeader.java new file mode 100644 index 0000000..f7b3fa9 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/vo/ApiHeader.java @@ -0,0 +1,14 @@ +package com.czsj.market.vo; + +import lombok.Data; + +import java.io.Serializable; + +@Data +public class ApiHeader implements Serializable { + + private static final long serialVersionUID=1L; + + private String apiKey; + private String secretKey; +} diff --git a/czsj-system/src/main/java/com/czsj/market/vo/ApiLogVo.java b/czsj-system/src/main/java/com/czsj/market/vo/ApiLogVo.java new file mode 100644 index 0000000..94a251f --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/vo/ApiLogVo.java @@ -0,0 +1,27 @@ +package com.czsj.market.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +@Data +public class ApiLogVo implements Serializable { + + private static final long serialVersionUID=1L; + + private String id; + private String apiId; + private String apiName; + private String callerId; + private String callerIp; + private String callerUrl; + private Integer callerSize; + private String callerParams; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private LocalDateTime callerDate; + private Long time; + private String msg; + private String status; +} diff --git a/czsj-system/src/main/java/com/czsj/market/vo/ApiMaskVo.java b/czsj-system/src/main/java/com/czsj/market/vo/ApiMaskVo.java new file mode 100644 index 0000000..9249b65 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/vo/ApiMaskVo.java @@ -0,0 +1,32 @@ +package com.czsj.market.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.czsj.market.dto.FieldRule; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +/** + *

+ * 数据API脱敏信息表 实体VO + *

+ * + * @author yuwei + * @since 2020-04-14 + */ +@Data +public class ApiMaskVo implements Serializable { + + private static final long serialVersionUID=1L; + + private String id; + private String status; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date createTime; + private String remark; + private String apiId; + private String maskName; + private List rules; +} diff --git a/czsj-system/src/main/java/com/czsj/market/vo/DataApiVo.java b/czsj-system/src/main/java/com/czsj/market/vo/DataApiVo.java new file mode 100644 index 0000000..ad259fb --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/vo/DataApiVo.java @@ -0,0 +1,44 @@ +package com.czsj.market.vo; + + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.czsj.market.dto.ExecuteConfig; +import com.czsj.market.dto.RateLimit; +import com.czsj.market.dto.ReqParam; +import com.czsj.market.dto.ResParam; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +/** + *

+ * 数据API信息表 实体VO + *

+ * + * @author yuwei + * @since 2020-03-31 + */ +@Data +public class DataApiVo implements Serializable { + + private static final long serialVersionUID=1L; + + private String id; + private String status; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date createTime; + private String remark; + private String apiName; + private String apiVersion; + private String apiUrl; + private String reqMethod; + private String deny; + private String resType; + private String apiCode; + private RateLimit rateLimit; + private ExecuteConfig executeConfig; + private List reqParams; + private List resParams; +} diff --git a/czsj-system/src/main/java/com/czsj/market/vo/ServiceHeader.java b/czsj-system/src/main/java/com/czsj/market/vo/ServiceHeader.java new file mode 100644 index 0000000..1eebe5f --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/vo/ServiceHeader.java @@ -0,0 +1,14 @@ +package com.czsj.market.vo; + +import lombok.Data; + +import java.io.Serializable; + +@Data +public class ServiceHeader implements Serializable { + + private static final long serialVersionUID=1L; + + private String serviceKey; + private String secretKey; +} diff --git a/czsj-system/src/main/java/com/czsj/market/vo/ServiceIntegrationVo.java b/czsj-system/src/main/java/com/czsj/market/vo/ServiceIntegrationVo.java new file mode 100644 index 0000000..dcc8fa4 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/vo/ServiceIntegrationVo.java @@ -0,0 +1,33 @@ +package com.czsj.market.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.czsj.market.dto.HttpService; +import com.czsj.market.dto.WebService; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 服务集成表 实体VO + *

+ * + * @author yuwei + * @since 2020-08-20 + */ +@Data +public class ServiceIntegrationVo implements Serializable { + + private static final long serialVersionUID=1L; + + private String id; + private String status; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private LocalDateTime createTime; + private String serviceNo; + private String serviceName; + private String serviceType; + private HttpService httpService; + private WebService webService; +} diff --git a/czsj-system/src/main/java/com/czsj/market/vo/ServiceLogVo.java b/czsj-system/src/main/java/com/czsj/market/vo/ServiceLogVo.java new file mode 100644 index 0000000..cff10be --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/vo/ServiceLogVo.java @@ -0,0 +1,35 @@ +package com.czsj.market.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 服务集成调用日志表 实体VO + *

+ * + * @author yuwei + * @since 2020-08-20 + */ +@Data +public class ServiceLogVo implements Serializable { + + private static final long serialVersionUID=1L; + + private String id; + private String status; + private String serviceId; + private String serviceName; + private String callerId; + private String callerIp; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private LocalDateTime callerDate; + private String callerHeader; + private String callerParam; + private String callerSoap; + private Long time; + private String msg; +} diff --git a/czsj-system/src/main/java/com/czsj/market/vo/SqlParseVo.java b/czsj-system/src/main/java/com/czsj/market/vo/SqlParseVo.java new file mode 100644 index 0000000..6d5cf4f --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/market/vo/SqlParseVo.java @@ -0,0 +1,17 @@ +package com.czsj.market.vo; + +import com.czsj.market.dto.ReqParam; +import com.czsj.market.dto.ResParam; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +@Data +public class SqlParseVo implements Serializable { + + private static final long serialVersionUID=1L; + + private List reqParams; + private List resParams; +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/concurrent/CallableTemplate.java b/czsj-system/src/main/java/com/czsj/metadata/concurrent/CallableTemplate.java new file mode 100644 index 0000000..b7029d5 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/concurrent/CallableTemplate.java @@ -0,0 +1,40 @@ +package com.czsj.metadata.concurrent; + +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.Callable; + +/** + * 多线程模板类 + */ +@Slf4j +public abstract class CallableTemplate implements Callable { + + /** + * 前置处理,子类可以Override该方法 + */ + public void beforeProcess() { + log.info("before process...."); + } + + /** + * 处理业务逻辑的方法,需要子类去Override + * @return + */ + public abstract V process(); + + /** + * 后置处理,子类可以Override该方法 + */ + public void afterProcess() { + log.info("after process...."); + } + + @Override + public V call() { + beforeProcess(); + V result = process(); + afterProcess(); + return result; + } +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/concurrent/DateHander.java b/czsj-system/src/main/java/com/czsj/metadata/concurrent/DateHander.java new file mode 100644 index 0000000..af48441 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/concurrent/DateHander.java @@ -0,0 +1,169 @@ +package com.czsj.metadata.concurrent; + +import com.czsj.metadata.vo.SqlConsoleVo; +import lombok.extern.slf4j.Slf4j; + +import java.sql.*; +import java.util.*; +import java.util.concurrent.CountDownLatch; + +@Slf4j +public class DateHander extends CallableTemplate { + + private CountDownLatch latch; + + private Connection conn; + + private String sql; + + public DateHander(CountDownLatch latch, Connection conn, String sql) { + this.latch = latch; + this.conn = conn; + this.sql = sql; + } + + @Override + public SqlConsoleVo process() { + log.info("执行sql:" + sql); + long start = System.currentTimeMillis(); + Statement stmt = null; + ResultSet rs = null; + // 将查询数据存储到数据中 + List> dataList = new ArrayList<>(); + // 存储列名的数组 + List columnList = new LinkedList<>(); + // 新增、修改、删除受影响行数 + Integer updateCount = null; + SqlConsoleVo sqlConsoleVo = new SqlConsoleVo(); + sqlConsoleVo.setSuccess(true); + try { + // 为了设置fetchSize,必须设置为false + conn.setAutoCommit(false); + stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); + stmt.setFetchSize(200); + // 是否查询操作 + boolean execute = stmt.execute(sql); + if (execute) { + // 限制下最大数量 + stmt.setMaxRows(1000); + rs = stmt.getResultSet(); + // 获取结果集的元数据信息 + ResultSetMetaData rsmd = rs.getMetaData(); + // 获取列字段的个数 + int colunmCount = rsmd.getColumnCount(); + for (int i = 1; i <= colunmCount; i++) { + // 获取所有的字段名称 + columnList.add(rsmd.getColumnName(i)); + } + while(rs.next()){ + Map map = new HashMap<>(); + for (int i = 1; i <= colunmCount; i++) { + // 获取列名 + String columnName = rsmd.getColumnName(i); + Object val = null; + switch (rsmd.getColumnType(i)) { + case Types.ARRAY: + val = rs.getArray(columnName); + break; + case Types.BIGINT: + val = rs.getLong(columnName); + break; + case Types.BOOLEAN: + case Types.BIT: + val = rs.getBoolean(columnName); + break; + case Types.DOUBLE: + val = rs.getDouble(columnName); + break; + case Types.FLOAT: + case Types.REAL: + val = rs.getFloat(columnName); + break; + case Types.INTEGER: + val = rs.getInt(columnName); + break; + case Types.NVARCHAR: + case Types.NCHAR: + case Types.LONGNVARCHAR: + val = rs.getNString(columnName); + break; + case Types.VARCHAR: + case Types.CHAR: + case Types.LONGVARCHAR: + val = rs.getString(columnName); + break; + case Types.TINYINT: + case Types.BINARY: + case Types.VARBINARY: + val = rs.getByte(columnName); + break; + case Types.SMALLINT: + val = rs.getShort(columnName); + break; + case Types.DATE: + val = rs.getDate(columnName); + break; + case Types.TIME: + val = rs.getTime(columnName); + break; + case Types.TIMESTAMP: + val = rs.getTimestamp(columnName); + break; + case Types.NUMERIC: + case Types.DECIMAL: + val = rs.getBigDecimal(columnName); + break; + case Types.BLOB: + case Types.CLOB: + case Types.LONGVARBINARY: + case Types.DATALINK: + case Types.REF: + case Types.STRUCT: + case Types.DISTINCT: + case Types.JAVA_OBJECT: + break; + default: + val = rs.getObject(columnName); + break; + } + map.put(columnName, val); + } + dataList.add(map); + } + } else { + // 执行新增、修改、删除受影响行数 + updateCount = stmt.getUpdateCount(); + } + conn.commit(); + } catch (SQLException e) { + sqlConsoleVo.setSuccess(false); + if(conn != null){ + try { + conn.rollback(); + } catch (SQLException e1) { + } + } + } finally { + try { + if(rs != null){ + rs.close(); + } + if (stmt != null) { + stmt.close(); + } + if (conn != null) { + conn.close(); + } + } catch (SQLException e) {} + } + latch.countDown(); + long end = System.currentTimeMillis(); + log.info("线程查询数据用时:" + (end - start) + "ms"); + sqlConsoleVo.setSql(sql); + sqlConsoleVo.setCount(updateCount); + sqlConsoleVo.setColumnList(columnList); + sqlConsoleVo.setDataList(dataList); + sqlConsoleVo.setTime(end - start); + return sqlConsoleVo; + } +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/dto/DbSchema.java b/czsj-system/src/main/java/com/czsj/metadata/dto/DbSchema.java new file mode 100644 index 0000000..62361bb --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/dto/DbSchema.java @@ -0,0 +1,35 @@ +package com.czsj.metadata.dto; + + +import com.czsj.metadata.validate.ValidationGroups; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +@ApiModel(value = "数据源连接信息Model") +@Data +public class DbSchema implements Serializable { + + private static final long serialVersionUID=1L; + + @ApiModelProperty(value = "主机") + @NotBlank(message = "主机不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String host; + @ApiModelProperty(value = "端口") + @NotNull(message = "端口不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private Integer port; + @ApiModelProperty(value = "用户名") + @NotBlank(message = "用户名不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String username; + @ApiModelProperty(value = "密码") + @NotBlank(message = "密码不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String password; + @ApiModelProperty(value = "数据库") + private String dbName; + @ApiModelProperty(value = "服务名") + private String sid; +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/dto/MetadataChangeRecordDto.java b/czsj-system/src/main/java/com/czsj/metadata/dto/MetadataChangeRecordDto.java new file mode 100644 index 0000000..aef28fb --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/dto/MetadataChangeRecordDto.java @@ -0,0 +1,46 @@ +package com.czsj.metadata.dto; + +import com.czsj.metadata.validate.ValidationGroups; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +/** + *

+ * 元数据变更记录表 实体DTO + *

+ * + * @author yuwei + * @since 2020-07-30 + */ +@ApiModel(value = "元数据变更记录表Model") +@Data +public class MetadataChangeRecordDto implements Serializable { + + private static final long serialVersionUID=1L; + + @ApiModelProperty(value = "主键ID") + @NotBlank(message = "主键ID不能为空", groups = {ValidationGroups.Update.class}) + private String id; + @ApiModelProperty(value = "版本号") + private Integer version; + @ApiModelProperty(value = "源数据的表名或者能唯一对应的源数据表的标识(可废弃)") + private String objectType; + @ApiModelProperty(value = "源数据表主键") + private String objectId; + @ApiModelProperty(value = "修改的源数据表的字段名") + private String fieldName; + @ApiModelProperty(value = "该字段原来的值") + private String fieldOldValue; + @ApiModelProperty(value = "该字段最新的值") + private String fieldNewValue; + @ApiModelProperty(value = "状态") + @NotNull(message = "状态不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String status; + @ApiModelProperty(value = "备注") + private String remark; +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/dto/MetadataColumnDto.java b/czsj-system/src/main/java/com/czsj/metadata/dto/MetadataColumnDto.java new file mode 100644 index 0000000..df3bfe4 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/dto/MetadataColumnDto.java @@ -0,0 +1,52 @@ +package com.czsj.metadata.dto; + +import com.czsj.metadata.validate.ValidationGroups; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.io.Serializable; + +/** + *

+ * 元数据信息表 实体DTO + *

+ * + * @author yuwei + * @since 2020-07-29 + */ +@ApiModel(value = "元数据信息表Model") +@Data +public class MetadataColumnDto implements Serializable { + + private static final long serialVersionUID=1L; + + @ApiModelProperty(value = "主键ID") + @NotBlank(message = "主键ID不能为空", groups = {ValidationGroups.Update.class}) + private String id; + @ApiModelProperty(value = "所属数据源") + private String sourceId; + @ApiModelProperty(value = "所属数据表") + private String tableId; + @ApiModelProperty(value = "字段名称") + private String columnName; + @ApiModelProperty(value = "字段注释") + private String columnComment; + @ApiModelProperty(value = "字段是否主键(1是0否)") + private String columnKey; + @ApiModelProperty(value = "字段是否允许为空(1是0否)") + private String columnNullable; + @ApiModelProperty(value = "字段序号") + private Integer columnPosition; + @ApiModelProperty(value = "数据类型") + private String dataType; + @ApiModelProperty(value = "数据长度") + private String dataLength; + @ApiModelProperty(value = "数据精度") + private String dataPrecision; + @ApiModelProperty(value = "数据小数位") + private String dataScale; + @ApiModelProperty(value = "数据默认值") + private String dataDefault; +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/dto/MetadataSourceDto.java b/czsj-system/src/main/java/com/czsj/metadata/dto/MetadataSourceDto.java new file mode 100644 index 0000000..4bbca5d --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/dto/MetadataSourceDto.java @@ -0,0 +1,47 @@ +package com.czsj.metadata.dto; + +import com.czsj.metadata.validate.ValidationGroups; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +/** + *

+ * 数据源信息表 实体DTO + *

+ * + * @author yuwei + * @since 2020-03-14 + */ +@ApiModel(value = "数据源信息表Model") +@Data +public class MetadataSourceDto implements Serializable { + + private static final long serialVersionUID=1L; + + @ApiModelProperty(value = "主键ID") + @NotBlank(message = "主键ID不能为空", groups = {ValidationGroups.Update.class}) + private String id; + @ApiModelProperty(value = "数据源类型") + @NotBlank(message = "数据源类型不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String dbType; + @ApiModelProperty(value = "数据源名称") + @NotBlank(message = "数据源名称不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String sourceName; + @ApiModelProperty(value = "数据源连接信息") + @Valid + private DbSchema dbSchema; + @ApiModelProperty(value = "状态") + @NotNull(message = "状态不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) + private String status; + @ApiModelProperty(value = "备注") + private String remark; + + private String user; + +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/dto/MetadataTableDto.java b/czsj-system/src/main/java/com/czsj/metadata/dto/MetadataTableDto.java new file mode 100644 index 0000000..f2c1bbf --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/dto/MetadataTableDto.java @@ -0,0 +1,34 @@ +package com.czsj.metadata.dto; + +import com.czsj.metadata.validate.ValidationGroups; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.io.Serializable; + +/** + *

+ * 数据库表信息表 实体DTO + *

+ * + * @author yuwei + * @since 2020-07-29 + */ +@ApiModel(value = "数据库表信息表Model") +@Data +public class MetadataTableDto implements Serializable { + + private static final long serialVersionUID=1L; + + @ApiModelProperty(value = "主键ID") + @NotBlank(message = "主键ID不能为空", groups = {ValidationGroups.Update.class}) + private String id; + @ApiModelProperty(value = "所属数据源") + private String sourceId; + @ApiModelProperty(value = "表名") + private String tableName; + @ApiModelProperty(value = "表注释") + private String tableComment; +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/dto/SqlConsoleDto.java b/czsj-system/src/main/java/com/czsj/metadata/dto/SqlConsoleDto.java new file mode 100644 index 0000000..4503468 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/dto/SqlConsoleDto.java @@ -0,0 +1,26 @@ +package com.czsj.metadata.dto; + +import com.czsj.metadata.validate.ValidationGroups; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.io.Serializable; + +@Data +public class SqlConsoleDto implements Serializable { + + private static final long serialVersionUID=1L; + + @ApiModelProperty(value = "当前时间戳") + @NotBlank(message = "时间戳不能为空", groups = {ValidationGroups.Other.class}) + private String sqlKey; + + @ApiModelProperty(value = "数据源") + @NotBlank(message = "数据源不能为空") + private String sourceId; + + @ApiModelProperty(value = "SQL文本") + @NotBlank(message = "SQL不能为空") + private String sqlText; +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/entity/MetadataAuthorizeEntity.java b/czsj-system/src/main/java/com/czsj/metadata/entity/MetadataAuthorizeEntity.java new file mode 100644 index 0000000..97d2f9a --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/entity/MetadataAuthorizeEntity.java @@ -0,0 +1,46 @@ +package com.czsj.metadata.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + *

+ * 数据授权信息表 + *

+ * + * @author yuwei + * @since 2020-10-23 + */ +@Data +@Accessors(chain = true) +@TableName("metadata_authorize") +public class MetadataAuthorizeEntity implements Serializable { + + private static final long serialVersionUID=1L; + + /** + * 主键 + */ + @TableId(value = "id", type = IdType.ASSIGN_ID) + private String id; + + /** + * 目标表主键ID + */ + private String objectId; + + /** + * 角色ID + */ + private String roleId; + + /** + * 目标表类型 + */ + private String objectType; +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/entity/MetadataChangeRecordEntity.java b/czsj-system/src/main/java/com/czsj/metadata/entity/MetadataChangeRecordEntity.java new file mode 100644 index 0000000..bc4f872 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/entity/MetadataChangeRecordEntity.java @@ -0,0 +1,71 @@ +package com.czsj.metadata.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.czsj.core.database.base.DataScopeBaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + *

+ * 元数据变更记录表 + *

+ * + * @author yuwei + * @since 2020-07-30 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@Accessors(chain = true) +@TableName(value = "metadata_change_record", autoResultMap = true) +public class MetadataChangeRecordEntity extends DataScopeBaseEntity { + + private static final long serialVersionUID=1L; + + /** + * 版本号 + */ + private Integer version; + + /** + * 源数据的表名或者能唯一对应的源数据表的标识(可废弃) + */ + private String objectType; + + /** + * 源数据表主键 + */ + private String objectId; + + /** + * 修改的源数据表的字段名 + */ + private String fieldName; + + /** + * 该字段原来的值 + */ + private String fieldOldValue; + + /** + * 该字段最新的值 + */ + private String fieldNewValue; + + /** + * 数据源 + */ + @TableField(exist = false) + private String sourceId; + @TableField(exist = false) + private String sourceName; + + /** + * 数据库表 + */ + @TableField(exist = false) + private String tableId; + @TableField(exist = false) + private String tableName; +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/entity/MetadataColumnEntity.java b/czsj-system/src/main/java/com/czsj/metadata/entity/MetadataColumnEntity.java new file mode 100644 index 0000000..1cc19b3 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/entity/MetadataColumnEntity.java @@ -0,0 +1,101 @@ +package com.czsj.metadata.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + *

+ * 元数据信息表 + *

+ * + * @author yuwei + * @since 2020-07-29 + */ +@Data +@Accessors(chain = true) +@TableName(value = "metadata_column", autoResultMap = true) +public class MetadataColumnEntity implements Serializable { + + private static final long serialVersionUID=1L; + + /** + * 主键 + */ + @TableId(value = "id", type = IdType.ASSIGN_ID) + private String id; + + /** + * 所属数据源 + */ + private String sourceId; + + /** + * 所属数据表 + */ + private String tableId; + + /** + * 字段名称 + */ + private String columnName; + + /** + * 字段注释 + */ + private String columnComment; + + /** + * 字段是否主键(1是0否) + */ + private String columnKey; + + /** + * 字段是否允许为空(1是0否) + */ + private String columnNullable; + + /** + * 字段序号 + */ + private Integer columnPosition; + + /** + * 数据类型 + */ + private String dataType; + + /** + * 数据长度 + */ + private String dataLength; + + /** + * 数据精度 + */ + private String dataPrecision; + + /** + * 数据小数位 + */ + private String dataScale; + + /** + * 数据默认值 + */ + private String dataDefault; + + @TableField(exist = false) + private String sourceName; + + @TableField(exist = false) + private String tableName; + + @TableField(exist = false) + private String tableComment; +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/entity/MetadataSourceEntity.java b/czsj-system/src/main/java/com/czsj/metadata/entity/MetadataSourceEntity.java new file mode 100644 index 0000000..95d23ad --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/entity/MetadataSourceEntity.java @@ -0,0 +1,71 @@ +package com.czsj.metadata.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.czsj.metadata.dto.DbSchema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.Date; + +/** + *

+ * 数据源信息表 + *

+ * + * @author yuwei + * @since 2020-03-14 + */ +@Data +@Accessors(chain = true) +@TableName(value = "metadata_source", autoResultMap = true) +public class MetadataSourceEntity { + + private static final long serialVersionUID=1L; + + /** + * 数据源类型 + */ + private String dbType; + + /** + * 数据源名称 + */ + private String sourceName; + + /** + * 元数据同步(0否,1同步中, 2是) + */ + private String isSync; + + private String id; + + private String status; + + /** 创建者 */ + private String createBy; + + /** 创建时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + /** 更新者 */ + private String updateBy; + + /** 更新时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; + + /** 备注 */ + private String remark; + + private String createDept; + + /** + * 数据源连接信息 + */ + @TableField(typeHandler = JacksonTypeHandler.class) + private DbSchema dbSchema; +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/entity/MetadataTableEntity.java b/czsj-system/src/main/java/com/czsj/metadata/entity/MetadataTableEntity.java new file mode 100644 index 0000000..b706bfb --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/entity/MetadataTableEntity.java @@ -0,0 +1,50 @@ +package com.czsj.metadata.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + *

+ * 数据库表信息表 + *

+ * + * @author yuwei + * @since 2020-07-29 + */ +@Data +@Accessors(chain = true) +@TableName(value = "metadata_table", autoResultMap = true) +public class MetadataTableEntity implements Serializable { + + private static final long serialVersionUID=1L; + + /** + * 主键 + */ + @TableId(value = "id", type = IdType.ASSIGN_ID) + private String id; + + /** + * 所属数据源 + */ + private String sourceId; + + /** + * 表名 + */ + private String tableName; + + /** + * 表注释 + */ + private String tableComment; + + @TableField(exist = false) + private String sourceName; +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/enums/DataLevel.java b/czsj-system/src/main/java/com/czsj/metadata/enums/DataLevel.java new file mode 100644 index 0000000..a0334dc --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/enums/DataLevel.java @@ -0,0 +1,34 @@ +package com.czsj.metadata.enums; + +public enum DataLevel { + + DATABASE("database", 1), + TABLE("table", 2), + COLUMN("column", 3); + + private final String key; + + private final Integer level; + + DataLevel(String key, Integer level) { + this.key = key; + this.level = level; + } + + public String getKey() { + return key; + } + + public Integer getLevel() { + return level; + } + + public static DataLevel getLevel(String key) { + for (DataLevel type : DataLevel.values()) { + if (type.key.equals(key)) { + return type; + } + } + return DATABASE; + } +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/enums/SyncStatus.java b/czsj-system/src/main/java/com/czsj/metadata/enums/SyncStatus.java new file mode 100644 index 0000000..23da054 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/enums/SyncStatus.java @@ -0,0 +1,18 @@ +package com.czsj.metadata.enums; + +public enum SyncStatus { + + NotSync("0"), + InSync("1"), + IsSync("2"), + ErrSync("3"); + private final String key; + + SyncStatus(String key) { + this.key = key; + } + + public String getKey() { + return key; + } +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/mapper/MetadataChangeRecordDao.java b/czsj-system/src/main/java/com/czsj/metadata/mapper/MetadataChangeRecordDao.java new file mode 100644 index 0000000..3831656 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/mapper/MetadataChangeRecordDao.java @@ -0,0 +1,30 @@ +package com.czsj.metadata.mapper; + + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.czsj.core.database.base.BaseDao; +import com.czsj.metadata.entity.MetadataChangeRecordEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.io.Serializable; + +/** + *

+ * 元数据变更记录表 Mapper 接口 + *

+ * + * @author yuwei + * @since 2020-07-30 + */ +@Mapper +public interface MetadataChangeRecordDao extends BaseDao { + + @Override + MetadataChangeRecordEntity selectById(Serializable id); + + @Override + > E selectPage(E page, @Param(Constants.WRAPPER) Wrapper queryWrapper); +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/mapper/MetadataColumnDao.java b/czsj-system/src/main/java/com/czsj/metadata/mapper/MetadataColumnDao.java new file mode 100644 index 0000000..251262b --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/mapper/MetadataColumnDao.java @@ -0,0 +1,39 @@ +package com.czsj.metadata.mapper; + + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.czsj.core.database.base.BaseDao; +import com.czsj.metadata.entity.MetadataColumnEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 元数据信息表 Mapper 接口 + *

+ * + * @author yuwei + * @since 2020-07-29 + */ +@Mapper +public interface MetadataColumnDao extends BaseDao { + + > E selectPageWithAuth(E page, @Param(Constants.WRAPPER) Wrapper queryWrapper, @Param("roles") List roles); + + void deleteBysourceId(@Param("sourceId") String sourceId); + + Integer countByColumnName(@Param("columnName") String columnName,@Param("tableId") String tableId,@Param("sourceId") String sourceId); + + String selectIdByColumnName(@Param("columnName") String columnName,@Param("tableId") String tableId,@Param("sourceId") String sourceId); + + List selectColumnNameByTableId(@Param("tableId") String tableId,@Param("sourceId") String sourceId); + + void deleteBysourceIdAndTidAndColName(@Param("tableId") String tableId,@Param("sourceId") String sourceId, @Param("columnName") String columnName); + + + +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/mapper/MetadataSourceDao.java b/czsj-system/src/main/java/com/czsj/metadata/mapper/MetadataSourceDao.java new file mode 100644 index 0000000..a970592 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/mapper/MetadataSourceDao.java @@ -0,0 +1,33 @@ +package com.czsj.metadata.mapper; + + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.czsj.core.database.base.BaseDao; +import com.czsj.metadata.entity.MetadataSourceEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.io.Serializable; +import java.util.List; + +/** + *

+ * 数据源信息表 Mapper 接口 + *

+ * + * @author yuwei + * @since 2020-03-14 + */ +@Mapper +public interface MetadataSourceDao extends BaseDao { + + @Override + MetadataSourceEntity selectById(Serializable id); + + @Override + List selectList(@Param(Constants.WRAPPER) Wrapper queryWrapper); + + > E selectPageWithAuth(E page, @Param(Constants.WRAPPER) Wrapper queryWrapper, @Param("roles") List roles); +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/mapper/MetadataTableDao.java b/czsj-system/src/main/java/com/czsj/metadata/mapper/MetadataTableDao.java new file mode 100644 index 0000000..cc5ac0b --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/mapper/MetadataTableDao.java @@ -0,0 +1,35 @@ +package com.czsj.metadata.mapper; + + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.czsj.core.database.base.BaseDao; +import com.czsj.metadata.entity.MetadataTableEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 数据库表信息表 Mapper 接口 + *

+ * + * @author yuwei + * @since 2020-07-29 + */ +@Mapper +public interface MetadataTableDao extends BaseDao { + + > E selectPageWithAuth(E page, @Param(Constants.WRAPPER) Wrapper queryWrapper, @Param("roles") List roles); + + + void deleteBysourceId(@Param("sourceId") String sourceId,@Param("tableName") String tableName); + + List selectTableBySourceId(@Param("sourceId") String sourceId); + + Integer countByTableName(@Param("tableName") String tableName,@Param("sourceId") String sourceId); + + String selectIdByTableName(@Param("tableName") String tableName,@Param("sourceId") String sourceId); +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/mapstruct/EntityMapper.java b/czsj-system/src/main/java/com/czsj/metadata/mapstruct/EntityMapper.java new file mode 100644 index 0000000..5b021fd --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/mapstruct/EntityMapper.java @@ -0,0 +1,56 @@ +package com.czsj.metadata.mapstruct; + +import java.util.List; + +/** + * + * Mapper文件基类 + * 更多的用法需自行实现 + * @param 目标对象,一般为DTO对象 + * @param 源对象,一般为需要转换的对象 + * @param 目标对象,一般为VO对象 + */ +public interface EntityMapper { + + /** + * 将源对象转换为DTO对象 + * @param e + * @return D + */ + D toDTO(E e); + + /** + * 将源对象集合转换为DTO对象集合 + * @param es + * @return List + */ + List toDTO(List es); + + /** + * 将源对象转换为VO对象 + * @param e + * @return D + */ + V toVO(E e); + + /** + * 将源对象集合转换为VO对象集合 + * @param es + * @return List + */ + List toVO(List es); + + /** + * 将目标对象转换为源对象 + * @param d + * @return E + */ + E toEntity(D d); + + /** + * 将目标对象集合转换为源对象集合 + * @param ds + * @return List + */ + List toEntity(List ds); +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/mapstruct/MetadataChangeRecordMapper.java b/czsj-system/src/main/java/com/czsj/metadata/mapstruct/MetadataChangeRecordMapper.java new file mode 100644 index 0000000..3cad5fa --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/mapstruct/MetadataChangeRecordMapper.java @@ -0,0 +1,20 @@ +package com.czsj.metadata.mapstruct; + + +import com.czsj.metadata.dto.MetadataChangeRecordDto; +import com.czsj.metadata.entity.MetadataChangeRecordEntity; +import com.czsj.metadata.vo.MetadataChangeRecordVo; +import org.mapstruct.Mapper; + +/** + *

+ * 元数据变更记录表 Mapper 实体映射 + *

+ * + * @author yuwei + * @since 2020-07-30 + */ +@Mapper(componentModel = "spring") +public interface MetadataChangeRecordMapper extends EntityMapper { + +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/mapstruct/MetadataTableMapper.java b/czsj-system/src/main/java/com/czsj/metadata/mapstruct/MetadataTableMapper.java new file mode 100644 index 0000000..72a3897 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/mapstruct/MetadataTableMapper.java @@ -0,0 +1,19 @@ +package com.czsj.metadata.mapstruct; + +import com.czsj.metadata.dto.MetadataTableDto; +import com.czsj.metadata.entity.MetadataTableEntity; +import com.czsj.metadata.vo.MetadataTableVo; +import org.mapstruct.Mapper; + +/** + *

+ * 数据库表信息表 Mapper 实体映射 + *

+ * + * @author yuwei + * @since 2020-07-29 + */ +@Mapper(componentModel = "spring") +public interface MetadataTableMapper extends EntityMapper { + +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/mapstruct/impl/MetadataChangeRecordMapperImpl.java b/czsj-system/src/main/java/com/czsj/metadata/mapstruct/impl/MetadataChangeRecordMapperImpl.java new file mode 100644 index 0000000..159520d --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/mapstruct/impl/MetadataChangeRecordMapperImpl.java @@ -0,0 +1,124 @@ +package com.czsj.metadata.mapstruct.impl; + + +import com.czsj.metadata.dto.MetadataChangeRecordDto; +import com.czsj.metadata.entity.MetadataChangeRecordEntity; +import com.czsj.metadata.mapstruct.MetadataChangeRecordMapper; +import com.czsj.metadata.vo.MetadataChangeRecordVo; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +@Component +public class MetadataChangeRecordMapperImpl implements MetadataChangeRecordMapper { + + @Override + public MetadataChangeRecordDto toDTO(MetadataChangeRecordEntity e) { + if ( e == null ) { + return null; + } + + MetadataChangeRecordDto metadataChangeRecordDto = new MetadataChangeRecordDto(); + + metadataChangeRecordDto.setId( e.getId() ); + metadataChangeRecordDto.setVersion( e.getVersion() ); + metadataChangeRecordDto.setObjectType( e.getObjectType() ); + metadataChangeRecordDto.setObjectId( e.getObjectId() ); + metadataChangeRecordDto.setFieldName( e.getFieldName() ); + metadataChangeRecordDto.setFieldOldValue( e.getFieldOldValue() ); + metadataChangeRecordDto.setFieldNewValue( e.getFieldNewValue() ); + metadataChangeRecordDto.setStatus( e.getStatus() ); + metadataChangeRecordDto.setRemark( e.getRemark() ); + + return metadataChangeRecordDto; + } + + @Override + public List toDTO(List es) { + if ( es == null ) { + return null; + } + + List list = new ArrayList( es.size() ); + for ( MetadataChangeRecordEntity metadataChangeRecordEntity : es ) { + list.add( toDTO( metadataChangeRecordEntity ) ); + } + + return list; + } + + @Override + public MetadataChangeRecordVo toVO(MetadataChangeRecordEntity e) { + if ( e == null ) { + return null; + } + + MetadataChangeRecordVo metadataChangeRecordVo = new MetadataChangeRecordVo(); + + metadataChangeRecordVo.setId( e.getId() ); + metadataChangeRecordVo.setStatus( e.getStatus() ); + metadataChangeRecordVo.setCreateTime( e.getCreateTime() ); + metadataChangeRecordVo.setVersion( e.getVersion() ); + metadataChangeRecordVo.setObjectType( e.getObjectType() ); + metadataChangeRecordVo.setObjectId( e.getObjectId() ); + metadataChangeRecordVo.setFieldName( e.getFieldName() ); + metadataChangeRecordVo.setFieldOldValue( e.getFieldOldValue() ); + metadataChangeRecordVo.setFieldNewValue( e.getFieldNewValue() ); + metadataChangeRecordVo.setSourceId( e.getSourceId() ); + metadataChangeRecordVo.setSourceName( e.getSourceName() ); + metadataChangeRecordVo.setTableId( e.getTableId() ); + metadataChangeRecordVo.setTableName( e.getTableName() ); + + return metadataChangeRecordVo; + } + + @Override + public List toVO(List es) { + if ( es == null ) { + return null; + } + + List list = new ArrayList( es.size() ); + for ( MetadataChangeRecordEntity metadataChangeRecordEntity : es ) { + list.add( toVO( metadataChangeRecordEntity ) ); + } + + return list; + } + + @Override + public MetadataChangeRecordEntity toEntity(MetadataChangeRecordDto d) { + if ( d == null ) { + return null; + } + + MetadataChangeRecordEntity metadataChangeRecordEntity = new MetadataChangeRecordEntity(); + + metadataChangeRecordEntity.setId( d.getId() ); + metadataChangeRecordEntity.setStatus( d.getStatus() ); + metadataChangeRecordEntity.setRemark( d.getRemark() ); + metadataChangeRecordEntity.setVersion( d.getVersion() ); + metadataChangeRecordEntity.setObjectType( d.getObjectType() ); + metadataChangeRecordEntity.setObjectId( d.getObjectId() ); + metadataChangeRecordEntity.setFieldName( d.getFieldName() ); + metadataChangeRecordEntity.setFieldOldValue( d.getFieldOldValue() ); + metadataChangeRecordEntity.setFieldNewValue( d.getFieldNewValue() ); + + return metadataChangeRecordEntity; + } + + @Override + public List toEntity(List ds) { + if ( ds == null ) { + return null; + } + + List list = new ArrayList( ds.size() ); + for ( MetadataChangeRecordDto metadataChangeRecordDto : ds ) { + list.add( toEntity( metadataChangeRecordDto ) ); + } + + return list; + } +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/mapstruct/impl/MetadataColumnMapperImpl.java b/czsj-system/src/main/java/com/czsj/metadata/mapstruct/impl/MetadataColumnMapperImpl.java new file mode 100644 index 0000000..ef09349 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/mapstruct/impl/MetadataColumnMapperImpl.java @@ -0,0 +1,136 @@ +package com.czsj.metadata.mapstruct.impl; + + +import com.czsj.metadata.dto.MetadataColumnDto; +import com.czsj.metadata.entity.MetadataColumnEntity; +import com.czsj.metadata.service.MetadataColumnMapper; +import com.czsj.metadata.vo.MetadataColumnVo; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + + +@Component +public class MetadataColumnMapperImpl implements MetadataColumnMapper { + + @Override + public MetadataColumnDto toDTO(MetadataColumnEntity e) { + if ( e == null ) { + return null; + } + + MetadataColumnDto metadataColumnDto = new MetadataColumnDto(); + + metadataColumnDto.setId( e.getId() ); + metadataColumnDto.setSourceId( e.getSourceId() ); + metadataColumnDto.setTableId( e.getTableId() ); + metadataColumnDto.setColumnName( e.getColumnName() ); + metadataColumnDto.setColumnComment( e.getColumnComment() ); + metadataColumnDto.setColumnKey( e.getColumnKey() ); + metadataColumnDto.setColumnNullable( e.getColumnNullable() ); + metadataColumnDto.setColumnPosition( e.getColumnPosition() ); + metadataColumnDto.setDataType( e.getDataType() ); + metadataColumnDto.setDataLength( e.getDataLength() ); + metadataColumnDto.setDataPrecision( e.getDataPrecision() ); + metadataColumnDto.setDataScale( e.getDataScale() ); + metadataColumnDto.setDataDefault( e.getDataDefault() ); + + return metadataColumnDto; + } + + @Override + public List toDTO(List es) { + if ( es == null ) { + return null; + } + + List list = new ArrayList( es.size() ); + for ( MetadataColumnEntity metadataColumnEntity : es ) { + list.add( toDTO( metadataColumnEntity ) ); + } + + return list; + } + + @Override + public MetadataColumnVo toVO(MetadataColumnEntity e) { + if ( e == null ) { + return null; + } + + MetadataColumnVo metadataColumnVo = new MetadataColumnVo(); + + metadataColumnVo.setId( e.getId() ); + metadataColumnVo.setSourceId( e.getSourceId() ); + metadataColumnVo.setTableId( e.getTableId() ); + metadataColumnVo.setColumnName( e.getColumnName() ); + metadataColumnVo.setColumnComment( e.getColumnComment() ); + metadataColumnVo.setColumnKey( e.getColumnKey() ); + metadataColumnVo.setColumnNullable( e.getColumnNullable() ); + metadataColumnVo.setColumnPosition( e.getColumnPosition() ); + metadataColumnVo.setDataType( e.getDataType() ); + metadataColumnVo.setDataLength( e.getDataLength() ); + metadataColumnVo.setDataPrecision( e.getDataPrecision() ); + metadataColumnVo.setDataScale( e.getDataScale() ); + metadataColumnVo.setDataDefault( e.getDataDefault() ); + metadataColumnVo.setSourceName( e.getSourceName() ); + metadataColumnVo.setTableName( e.getTableName() ); + metadataColumnVo.setTableComment( e.getTableComment() ); + + return metadataColumnVo; + } + + @Override + public List toVO(List es) { + if ( es == null ) { + return null; + } + + List list = new ArrayList( es.size() ); + for ( MetadataColumnEntity metadataColumnEntity : es ) { + list.add( toVO( metadataColumnEntity ) ); + } + + return list; + } + + @Override + public MetadataColumnEntity toEntity(MetadataColumnDto d) { + if ( d == null ) { + return null; + } + + MetadataColumnEntity metadataColumnEntity = new MetadataColumnEntity(); + + metadataColumnEntity.setId( d.getId() ); + metadataColumnEntity.setSourceId( d.getSourceId() ); + metadataColumnEntity.setTableId( d.getTableId() ); + metadataColumnEntity.setColumnName( d.getColumnName() ); + metadataColumnEntity.setColumnComment( d.getColumnComment() ); + metadataColumnEntity.setColumnKey( d.getColumnKey() ); + metadataColumnEntity.setColumnNullable( d.getColumnNullable() ); + metadataColumnEntity.setColumnPosition( d.getColumnPosition() ); + metadataColumnEntity.setDataType( d.getDataType() ); + metadataColumnEntity.setDataLength( d.getDataLength() ); + metadataColumnEntity.setDataPrecision( d.getDataPrecision() ); + metadataColumnEntity.setDataScale( d.getDataScale() ); + metadataColumnEntity.setDataDefault( d.getDataDefault() ); + + return metadataColumnEntity; + } + + @Override + public List toEntity(List ds) { + if ( ds == null ) { + return null; + } + + List list = new ArrayList( ds.size() ); + for ( MetadataColumnDto metadataColumnDto : ds ) { + list.add( toEntity( metadataColumnDto ) ); + } + + return list; + } +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/mapstruct/impl/MetadataSourceMapperImpl.java b/czsj-system/src/main/java/com/czsj/metadata/mapstruct/impl/MetadataSourceMapperImpl.java new file mode 100644 index 0000000..ad3c029 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/mapstruct/impl/MetadataSourceMapperImpl.java @@ -0,0 +1,113 @@ +package com.czsj.metadata.mapstruct.impl; + +import com.czsj.metadata.dto.MetadataSourceDto; +import com.czsj.metadata.entity.MetadataSourceEntity; +import com.czsj.metadata.service.MetadataSourceMapper; +import com.czsj.metadata.vo.MetadataSourceVo; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + + +@Component +public class MetadataSourceMapperImpl implements MetadataSourceMapper { + + @Override + public MetadataSourceDto toDTO(MetadataSourceEntity e) { + if ( e == null ) { + return null; + } + + MetadataSourceDto metadataSourceDto = new MetadataSourceDto(); + + metadataSourceDto.setId( e.getId() ); + metadataSourceDto.setDbType( e.getDbType() ); + metadataSourceDto.setSourceName( e.getSourceName() ); + metadataSourceDto.setDbSchema( e.getDbSchema() ); + metadataSourceDto.setStatus( e.getStatus() ); + metadataSourceDto.setRemark( e.getRemark() ); + + return metadataSourceDto; + } + + @Override + public List toDTO(List es) { + if ( es == null ) { + return null; + } + + List list = new ArrayList( es.size() ); + for ( MetadataSourceEntity metadataSourceEntity : es ) { + list.add( toDTO( metadataSourceEntity ) ); + } + + return list; + } + + @Override + public MetadataSourceVo toVO(MetadataSourceEntity e) { + if ( e == null ) { + return null; + } + + MetadataSourceVo metadataSourceVo = new MetadataSourceVo(); + + metadataSourceVo.setId( e.getId() ); + metadataSourceVo.setStatus( e.getStatus() ); + metadataSourceVo.setCreateTime( e.getCreateTime() ); + metadataSourceVo.setRemark( e.getRemark() ); + metadataSourceVo.setDbType( e.getDbType() ); + metadataSourceVo.setSourceName( e.getSourceName() ); + metadataSourceVo.setDbSchema( e.getDbSchema() ); + metadataSourceVo.setIsSync( e.getIsSync() ); + + return metadataSourceVo; + } + + @Override + public List toVO(List es) { + if ( es == null ) { + return null; + } + + List list = new ArrayList( es.size() ); + for ( MetadataSourceEntity metadataSourceEntity : es ) { + list.add( toVO( metadataSourceEntity ) ); + } + + return list; + } + + @Override + public MetadataSourceEntity toEntity(MetadataSourceDto d) { + if ( d == null ) { + return null; + } + + MetadataSourceEntity metadataSourceEntity = new MetadataSourceEntity(); + + metadataSourceEntity.setId( d.getId() ); + metadataSourceEntity.setStatus( d.getStatus() ); + metadataSourceEntity.setRemark( d.getRemark() ); + metadataSourceEntity.setDbType( d.getDbType() ); + metadataSourceEntity.setSourceName( d.getSourceName() ); + metadataSourceEntity.setDbSchema( d.getDbSchema() ); + + return metadataSourceEntity; + } + + @Override + public List toEntity(List ds) { + if ( ds == null ) { + return null; + } + + List list = new ArrayList( ds.size() ); + for ( MetadataSourceDto metadataSourceDto : ds ) { + list.add( toEntity( metadataSourceDto ) ); + } + + return list; + } +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/mapstruct/impl/MetadataTableMapperImpl.java b/czsj-system/src/main/java/com/czsj/metadata/mapstruct/impl/MetadataTableMapperImpl.java new file mode 100644 index 0000000..79f6f56 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/mapstruct/impl/MetadataTableMapperImpl.java @@ -0,0 +1,106 @@ +package com.czsj.metadata.mapstruct.impl; + + +import com.czsj.metadata.dto.MetadataTableDto; +import com.czsj.metadata.entity.MetadataTableEntity; +import com.czsj.metadata.mapstruct.MetadataTableMapper; +import com.czsj.metadata.vo.MetadataTableVo; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +@Component +public class MetadataTableMapperImpl implements MetadataTableMapper { + + @Override + public MetadataTableDto toDTO(MetadataTableEntity e) { + if ( e == null ) { + return null; + } + + MetadataTableDto metadataTableDto = new MetadataTableDto(); + + metadataTableDto.setId( e.getId() ); + metadataTableDto.setSourceId( e.getSourceId() ); + metadataTableDto.setTableName( e.getTableName() ); + metadataTableDto.setTableComment( e.getTableComment() ); + + return metadataTableDto; + } + + @Override + public List toDTO(List es) { + if ( es == null ) { + return null; + } + + List list = new ArrayList( es.size() ); + for ( MetadataTableEntity metadataTableEntity : es ) { + list.add( toDTO( metadataTableEntity ) ); + } + + return list; + } + + @Override + public MetadataTableVo toVO(MetadataTableEntity e) { + if ( e == null ) { + return null; + } + + MetadataTableVo metadataTableVo = new MetadataTableVo(); + + metadataTableVo.setId( e.getId() ); + metadataTableVo.setSourceId( e.getSourceId() ); + metadataTableVo.setTableName( e.getTableName() ); + metadataTableVo.setTableComment( e.getTableComment() ); + metadataTableVo.setSourceName( e.getSourceName() ); + + return metadataTableVo; + } + + @Override + public List toVO(List es) { + if ( es == null ) { + return null; + } + + List list = new ArrayList( es.size() ); + for ( MetadataTableEntity metadataTableEntity : es ) { + list.add( toVO( metadataTableEntity ) ); + } + + return list; + } + + @Override + public MetadataTableEntity toEntity(MetadataTableDto d) { + if ( d == null ) { + return null; + } + + MetadataTableEntity metadataTableEntity = new MetadataTableEntity(); + + metadataTableEntity.setId( d.getId() ); + metadataTableEntity.setSourceId( d.getSourceId() ); + metadataTableEntity.setTableName( d.getTableName() ); + metadataTableEntity.setTableComment( d.getTableComment() ); + + return metadataTableEntity; + } + + @Override + public List toEntity(List ds) { + if ( ds == null ) { + return null; + } + + List list = new ArrayList( ds.size() ); + for ( MetadataTableDto metadataTableDto : ds ) { + list.add( toEntity( metadataTableDto ) ); + } + + return list; + } +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/query/DbDataQuery.java b/czsj-system/src/main/java/com/czsj/metadata/query/DbDataQuery.java new file mode 100644 index 0000000..72c4d63 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/query/DbDataQuery.java @@ -0,0 +1,36 @@ +package com.czsj.metadata.query; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.io.Serializable; + +/** + *

+ * 数据查询 查询实体 + *

+ * + * @author yuwei + * @since 2020-03-14 + */ +@Data +public class DbDataQuery implements Serializable { + + private static final long serialVersionUID = 1L; + + @NotBlank(message = "数据源不能为空") + private String dataSourceId; + @NotBlank(message = "查询sql不能为空") + private String sql; + // 当前页码 + private Integer pageNum = 1; + // 分页条数 + private Integer pageSize = 20; + + public Integer getOffset() { + pageSize = pageSize == null ? 20 : pageSize; + pageNum = pageNum == null ? 1 : pageNum; + int offset = pageNum > 0 ? (pageNum - 1) * pageSize : 0; + return offset; + } +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/query/MetadataChangeRecordQuery.java b/czsj-system/src/main/java/com/czsj/metadata/query/MetadataChangeRecordQuery.java new file mode 100644 index 0000000..89f0c2d --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/query/MetadataChangeRecordQuery.java @@ -0,0 +1,24 @@ +package com.czsj.metadata.query; + + +import com.czsj.core.database.base.BaseQueryParams; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * 元数据变更记录表 查询实体 + *

+ * + * @author yuwei + * @since 2020-07-30 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class MetadataChangeRecordQuery extends BaseQueryParams { + + private static final long serialVersionUID=1L; + + private String objectId; + private String fieldName; +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/query/MetadataColumnQuery.java b/czsj-system/src/main/java/com/czsj/metadata/query/MetadataColumnQuery.java new file mode 100644 index 0000000..b6a800d --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/query/MetadataColumnQuery.java @@ -0,0 +1,27 @@ +package com.czsj.metadata.query; + + +import com.czsj.core.database.base.BaseQueryParams; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * 元数据信息表 查询实体 + *

+ * + * @author yuwei + * @since 2020-07-29 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class MetadataColumnQuery extends BaseQueryParams { + + private static final long serialVersionUID=1L; + + private String sourceId; + + private String tableId; + + private String columnName; +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/query/MetadataSourceQuery.java b/czsj-system/src/main/java/com/czsj/metadata/query/MetadataSourceQuery.java new file mode 100644 index 0000000..f8aa948 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/query/MetadataSourceQuery.java @@ -0,0 +1,23 @@ +package com.czsj.metadata.query; + + +import com.czsj.core.database.base.BaseQueryParams; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * 数据源信息表 查询实体 + *

+ * + * @author yuwei + * @since 2020-03-14 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class MetadataSourceQuery extends BaseQueryParams { + + private static final long serialVersionUID=1L; + + private String sourceName; +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/query/MetadataTableQuery.java b/czsj-system/src/main/java/com/czsj/metadata/query/MetadataTableQuery.java new file mode 100644 index 0000000..de97dc2 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/query/MetadataTableQuery.java @@ -0,0 +1,24 @@ +package com.czsj.metadata.query; + +import com.czsj.core.database.base.BaseQueryParams; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * 数据库表信息表 查询实体 + *

+ * + * @author yuwei + * @since 2020-07-29 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class MetadataTableQuery extends BaseQueryParams { + + private static final long serialVersionUID=1L; + + private String sourceId; + + private String tableName; +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/service/MetadataChangeRecordService.java b/czsj-system/src/main/java/com/czsj/metadata/service/MetadataChangeRecordService.java new file mode 100644 index 0000000..a860b24 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/service/MetadataChangeRecordService.java @@ -0,0 +1,30 @@ +package com.czsj.metadata.service; + + + +import com.czsj.core.database.base.BaseService; +import com.czsj.metadata.dto.MetadataChangeRecordDto; +import com.czsj.metadata.entity.MetadataChangeRecordEntity; + +import java.util.List; + +/** + *

+ * 元数据变更记录表 服务类 + *

+ * + * @author yuwei + * @since 2020-07-30 + */ +public interface MetadataChangeRecordService extends BaseService { + + MetadataChangeRecordEntity saveMetadataChangeRecord(MetadataChangeRecordDto metadataChangeRecord); + + MetadataChangeRecordEntity updateMetadataChangeRecord(MetadataChangeRecordDto metadataChangeRecord); + + MetadataChangeRecordEntity getMetadataChangeRecordById(String id); + + void deleteMetadataChangeRecordById(String id); + + void deleteMetadataChangeRecordBatch(List ids); +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/service/MetadataColumnMapper.java b/czsj-system/src/main/java/com/czsj/metadata/service/MetadataColumnMapper.java new file mode 100644 index 0000000..5a1f9de --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/service/MetadataColumnMapper.java @@ -0,0 +1,20 @@ +package com.czsj.metadata.service; + + +import com.czsj.metadata.dto.MetadataColumnDto; +import com.czsj.metadata.entity.MetadataColumnEntity; +import com.czsj.metadata.mapstruct.EntityMapper; +import com.czsj.metadata.vo.MetadataColumnVo; + + +/** + *

+ * 元数据信息表 Mapper 实体映射 + *

+ * + * @author yuwei + * @since 2020-07-29 + */ +public interface MetadataColumnMapper extends EntityMapper { + +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/service/MetadataColumnService.java b/czsj-system/src/main/java/com/czsj/metadata/service/MetadataColumnService.java new file mode 100644 index 0000000..20cbc2b --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/service/MetadataColumnService.java @@ -0,0 +1,39 @@ +package com.czsj.metadata.service; + + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.czsj.core.database.base.BaseService; +import com.czsj.metadata.dto.MetadataColumnDto; +import com.czsj.metadata.entity.MetadataColumnEntity; +import com.czsj.metadata.query.MetadataColumnQuery; +import com.czsj.metadata.vo.MetadataTreeVo; + +import java.util.List; + +/** + *

+ * 元数据信息表 服务类 + *

+ * + * @author yuwei + * @since 2020-07-29 + */ +public interface MetadataColumnService extends BaseService { + + MetadataColumnEntity saveMetadataColumn(MetadataColumnDto metadataColumn); + + MetadataColumnEntity updateMetadataColumn(MetadataColumnDto metadataColumn); + + MetadataColumnEntity getMetadataColumnById(String id); + + void deleteMetadataColumnById(String id); + + void deleteMetadataColumnBatch(List ids); + + List getDataMetadataTree(String level, MetadataColumnQuery metadataColumnQuery); + + List getDataMetadataColumnList(MetadataColumnQuery metadataColumnQuery); + + > E pageWithAuth(E page, Wrapper queryWrapper); +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/service/MetadataSourceMapper.java b/czsj-system/src/main/java/com/czsj/metadata/service/MetadataSourceMapper.java new file mode 100644 index 0000000..7add705 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/service/MetadataSourceMapper.java @@ -0,0 +1,19 @@ +package com.czsj.metadata.service; + + +import com.czsj.metadata.dto.MetadataSourceDto; +import com.czsj.metadata.entity.MetadataSourceEntity; +import com.czsj.metadata.mapstruct.EntityMapper; +import com.czsj.metadata.vo.MetadataSourceVo; + +/** + *

+ * 数据源信息表 Mapper 实体映射 + *

+ * + * @author yuwei + * @since 2020-03-14 + */ +public interface MetadataSourceMapper extends EntityMapper { + +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/service/MetadataSourceService.java b/czsj-system/src/main/java/com/czsj/metadata/service/MetadataSourceService.java new file mode 100644 index 0000000..1def893 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/service/MetadataSourceService.java @@ -0,0 +1,53 @@ +package com.czsj.metadata.service; + + +import com.aspose.words.Document; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.czsj.common.database.service.DbQuery; +import com.czsj.core.database.base.BaseService; +import com.czsj.core.database.core.DbColumn; +import com.czsj.core.database.core.DbTable; +import com.czsj.metadata.dto.MetadataSourceDto; +import com.czsj.metadata.entity.MetadataSourceEntity; + +import java.util.List; + +/** + *

+ * 数据源信息表 服务类 + *

+ * + * @author yuwei + * @since 2020-03-14 + */ +public interface MetadataSourceService extends BaseService { + + void saveMetadataSource(MetadataSourceDto metadataSourceDto); + + void updateMetadataSource(MetadataSourceDto metadataSourceDto); + + MetadataSourceEntity getMetadataSourceById(String id); + + void deleteMetadataSourceById(String id); + + void deleteMetadataSourceBatch(List ids); + + DbQuery checkConnection(MetadataSourceDto metadataSourceDto); + + DbQuery getDbQuery(String id); + + List getDbTables(String id); + + List getDbTableColumns(String id, String tableName); + + void syncMetadata(String id); + + Document wordMetadata(String id) throws Exception; + + void refreshMetadata(); + + List getMetadataSourceList(); + + > E pageWithAuth(E page, Wrapper queryWrapper); +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/service/MetadataTableService.java b/czsj-system/src/main/java/com/czsj/metadata/service/MetadataTableService.java new file mode 100644 index 0000000..6273557 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/service/MetadataTableService.java @@ -0,0 +1,36 @@ +package com.czsj.metadata.service; + + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.czsj.core.database.base.BaseService; +import com.czsj.metadata.dto.MetadataTableDto; +import com.czsj.metadata.entity.MetadataTableEntity; +import com.czsj.metadata.query.MetadataTableQuery; + +import java.util.List; + +/** + *

+ * 数据库表信息表 服务类 + *

+ * + * @author yuwei + * @since 2020-07-29 + */ +public interface MetadataTableService extends BaseService { + + MetadataTableEntity saveMetadataTable(MetadataTableDto metadataTable); + + MetadataTableEntity updateMetadataTable(MetadataTableDto metadataTable); + + MetadataTableEntity getMetadataTableById(String id); + + void deleteMetadataTableById(String id); + + void deleteMetadataTableBatch(List ids); + + List getDataMetadataTableList(MetadataTableQuery metadataTableQuery); + + > E pageWithAuth(E page, Wrapper queryWrapper); +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/service/SqlConsoleService.java b/czsj-system/src/main/java/com/czsj/metadata/service/SqlConsoleService.java new file mode 100644 index 0000000..ab11c4c --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/service/SqlConsoleService.java @@ -0,0 +1,16 @@ +package com.czsj.metadata.service; + + + +import com.czsj.metadata.dto.SqlConsoleDto; +import com.czsj.metadata.vo.SqlConsoleVo; + +import java.sql.SQLException; +import java.util.List; + +public interface SqlConsoleService { + + List sqlRun(SqlConsoleDto sqlConsoleDto) throws SQLException; + + void sqlStop(SqlConsoleDto sqlConsoleDto); +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/service/impl/MetadataChangeRecordServiceImpl.java b/czsj-system/src/main/java/com/czsj/metadata/service/impl/MetadataChangeRecordServiceImpl.java new file mode 100644 index 0000000..2e4ce9c --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/service/impl/MetadataChangeRecordServiceImpl.java @@ -0,0 +1,72 @@ +package com.czsj.metadata.service.impl; + + +import com.czsj.core.database.base.BaseServiceImpl; +import com.czsj.metadata.dto.MetadataChangeRecordDto; +import com.czsj.metadata.entity.MetadataChangeRecordEntity; +import com.czsj.metadata.mapper.MetadataChangeRecordDao; +import com.czsj.metadata.mapstruct.MetadataChangeRecordMapper; +import com.czsj.metadata.service.MetadataChangeRecordService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +import static com.czsj.common.utils.SecurityUtils.getUsername; + +/** + *

+ * 元数据变更记录表 服务实现类 + *

+ * + * @author yuwei + * @since 2020-07-30 + */ +@Service +@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class) +public class MetadataChangeRecordServiceImpl extends BaseServiceImpl implements MetadataChangeRecordService { + + @Autowired + private MetadataChangeRecordDao metadataChangeRecordDao; + + @Autowired + private MetadataChangeRecordMapper metadataChangeRecordMapper; + + @Override + @Transactional(rollbackFor = Exception.class) + public MetadataChangeRecordEntity saveMetadataChangeRecord(MetadataChangeRecordDto metadataChangeRecordDto) { + MetadataChangeRecordEntity metadataChangeRecord = metadataChangeRecordMapper.toEntity(metadataChangeRecordDto); + metadataChangeRecord.setCreateBy(getUsername()); + metadataChangeRecordDao.insert(metadataChangeRecord); + return metadataChangeRecord; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public MetadataChangeRecordEntity updateMetadataChangeRecord(MetadataChangeRecordDto metadataChangeRecordDto) { + MetadataChangeRecordEntity metadataChangeRecord = metadataChangeRecordMapper.toEntity(metadataChangeRecordDto); + metadataChangeRecord.setUpdateBy(getUsername()); + metadataChangeRecordDao.updateById(metadataChangeRecord); + return metadataChangeRecord; + } + + @Override + public MetadataChangeRecordEntity getMetadataChangeRecordById(String id) { + MetadataChangeRecordEntity metadataChangeRecordEntity = super.getById(id); + return metadataChangeRecordEntity; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteMetadataChangeRecordById(String id) { + metadataChangeRecordDao.deleteById(id); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteMetadataChangeRecordBatch(List ids) { + metadataChangeRecordDao.deleteBatchIds(ids); + } +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/service/impl/MetadataColumnServiceImpl.java b/czsj-system/src/main/java/com/czsj/metadata/service/impl/MetadataColumnServiceImpl.java new file mode 100644 index 0000000..565b750 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/service/impl/MetadataColumnServiceImpl.java @@ -0,0 +1,165 @@ +package com.czsj.metadata.service.impl; + + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.czsj.common.core.redis.RedisCache; +import com.czsj.common.database.utils.SecurityUtil; +import com.czsj.core.database.base.BaseServiceImpl; +import com.czsj.core.database.core.RedisConstant; +import com.czsj.metadata.dto.MetadataColumnDto; +import com.czsj.metadata.entity.MetadataColumnEntity; +import com.czsj.metadata.entity.MetadataSourceEntity; +import com.czsj.metadata.entity.MetadataTableEntity; +import com.czsj.metadata.enums.DataLevel; +import com.czsj.metadata.mapper.MetadataColumnDao; +import com.czsj.metadata.query.MetadataColumnQuery; +import com.czsj.metadata.service.MetadataColumnMapper; +import com.czsj.metadata.service.MetadataColumnService; +import com.czsj.metadata.vo.MetadataTreeVo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + *

+ * 元数据信息表 服务实现类 + *

+ * + * @author yuwei + * @since 2020-07-29 + */ +@Service +@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class) +public class MetadataColumnServiceImpl extends BaseServiceImpl implements MetadataColumnService { + + @Autowired + private MetadataColumnDao metadataColumnDao; + + @Autowired + private MetadataColumnMapper metadataColumnMapper; + + @Autowired + private RedisCache redisService; + + @Override + @Transactional(rollbackFor = Exception.class) + public MetadataColumnEntity saveMetadataColumn(MetadataColumnDto metadataColumnDto) { + MetadataColumnEntity metadataColumn = metadataColumnMapper.toEntity(metadataColumnDto); + metadataColumnDao.insert(metadataColumn); + return metadataColumn; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public MetadataColumnEntity updateMetadataColumn(MetadataColumnDto metadataColumnDto) { + MetadataColumnEntity metadataColumn = metadataColumnMapper.toEntity(metadataColumnDto); + metadataColumnDao.updateById(metadataColumn); + return metadataColumn; + } + + @Override + public MetadataColumnEntity getMetadataColumnById(String id) { + MetadataColumnEntity metadataColumnEntity = super.getById(id); + return metadataColumnEntity; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteMetadataColumnById(String id) { + metadataColumnDao.deleteById(id); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteMetadataColumnBatch(List ids) { + metadataColumnDao.deleteBatchIds(ids); + } + + @Override + public List getDataMetadataTree(String level, MetadataColumnQuery metadataColumnQuery) { + List sourceList = (List) redisService.getCacheObject(RedisConstant.METADATA_SOURCE_KEY); + List list = new ArrayList<>(); + if(sourceList != null && sourceList.size()>0){ + for(int i=0;i= DataLevel.TABLE.getLevel()) { + tree.setChildren(getTableChildrens(sourceList.get(i).getId(), level, metadataColumnQuery.getTableId())); + } + list.add(tree); + } + }else{ + throw new RuntimeException("数据源为空,请到数据源管理中添加数据源,再到详情同步数据源,最后刷新缓存!"); + } + return list; + } + + private List getTableChildrens(String id, String level, String tableId) { + List tableList = (List) redisService.hget(RedisConstant.METADATA_TABLE_KEY, id); + List children = new ArrayList<>(); + if(tableList!=null && tableList.size()>0){ + for(int i=0;i= DataLevel.COLUMN.getLevel()) { + tree.setChildren(getColumnChildrens(tableList.get(i).getId())); + } + children.add(tree); + } + } + return children; + } + + private List getColumnChildrens(String id) { + List columnList = (List) redisService.hget(RedisConstant.METADATA_COLUMN_KEY, id); + List children = new ArrayList<>(); + if(null !=columnList && columnList.size()>0){ + for(int i=0;i getDataMetadataColumnList(MetadataColumnQuery metadataColumnQuery) { + if (StrUtil.isBlank(metadataColumnQuery.getTableId())) { + throw new RuntimeException("数据表不能为空"); + } + List columnList = (List) redisService.hget(RedisConstant.METADATA_COLUMN_KEY, metadataColumnQuery.getTableId()); + Stream stream = Optional.ofNullable(columnList).orElseGet(ArrayList::new).stream(); + return stream.collect(Collectors.toList()); + } + + @Override + public > E pageWithAuth(E page, Wrapper queryWrapper) { + boolean admin = SecurityUtil.isAdmin(); + List roles = new ArrayList<>(); + if (!admin) { + roles = SecurityUtil.getUserRoleIds(); + } + return metadataColumnDao.selectPageWithAuth(page, queryWrapper, roles); + } +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/service/impl/MetadataSourceServiceImpl.java b/czsj-system/src/main/java/com/czsj/metadata/service/impl/MetadataSourceServiceImpl.java new file mode 100644 index 0000000..6b06de9 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/service/impl/MetadataSourceServiceImpl.java @@ -0,0 +1,300 @@ +package com.czsj.metadata.service.impl; + + +import cn.hutool.core.util.StrUtil; +import com.aspose.words.Document; +import com.aspose.words.MailMerge; +import com.aspose.words.net.System.Data.*; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.czsj.async.AsyncTask; +import com.czsj.common.core.redis.RedisCache; +import com.czsj.common.database.constants.DbQueryProperty; +import com.czsj.common.database.service.DataSourceFactory; +import com.czsj.common.database.service.DbQuery; +import com.czsj.common.database.utils.SecurityUtil; +import com.czsj.common.database.utils.WordUtil; +import com.czsj.core.database.base.BaseServiceImpl; +import com.czsj.core.database.core.DataConstant; +import com.czsj.core.database.core.DbColumn; +import com.czsj.core.database.core.DbTable; +import com.czsj.core.database.core.RedisConstant; +import com.czsj.metadata.dto.DbSchema; +import com.czsj.metadata.dto.MetadataSourceDto; +import com.czsj.metadata.entity.MetadataColumnEntity; +import com.czsj.metadata.entity.MetadataSourceEntity; +import com.czsj.metadata.entity.MetadataTableEntity; +import com.czsj.metadata.enums.SyncStatus; +import com.czsj.metadata.mapper.MetadataColumnDao; +import com.czsj.metadata.mapper.MetadataSourceDao; +import com.czsj.metadata.mapper.MetadataTableDao; +import com.czsj.metadata.service.MetadataSourceMapper; +import com.czsj.metadata.service.MetadataSourceService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.ClassPathResource; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.io.InputStream; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static com.czsj.common.utils.SecurityUtils.getUsername; + +/** + *

+ * 数据源信息表 服务实现类 + *

+ * + * @author yuwei + * @since 2020-03-14 + */ +@Service +@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class) +public class MetadataSourceServiceImpl extends BaseServiceImpl implements MetadataSourceService { + + @Autowired + private MetadataSourceDao metadataSourceDao; + + @Autowired + private MetadataSourceMapper metadataSourceMapper; + + @Autowired + private DataSourceFactory dataSourceFactory; + + @Autowired + private AsyncTask asyncTask; + + @Autowired + private MetadataTableDao metadataTableDao; + + @Autowired + private MetadataColumnDao metadataColumnDao; + + @Resource + private RedisCache redisCache; + + @Override + @Transactional(rollbackFor = Exception.class) + public void saveMetadataSource(MetadataSourceDto metadataSourceDto) { + + MetadataSourceEntity dataSource = metadataSourceMapper.toEntity(metadataSourceDto); + dataSource.setIsSync(SyncStatus.NotSync.getKey()); + dataSource.setCreateBy(getUsername()); + dataSource.setCreateTime(new Date()); + metadataSourceDao.insert(dataSource); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateMetadataSource(MetadataSourceDto metadataSourceDto) { + + MetadataSourceEntity dataSource = metadataSourceMapper.toEntity(metadataSourceDto); + dataSource.setUpdateBy(getUsername()); + dataSource.setUpdateTime(new Date()); + metadataSourceDao.updateById(dataSource); + } + + @Override + public MetadataSourceEntity getMetadataSourceById(String id) { + MetadataSourceEntity metadataSourceEntity = super.getById(id); + return metadataSourceEntity; + } + + @Override + public List getMetadataSourceList() { + List sourceList = (List) redisCache.get(RedisConstant.METADATA_SOURCE_KEY); + Stream stream = Optional.ofNullable(sourceList).orElseGet(ArrayList::new).stream() + .filter(s -> DataConstant.EnableState.ENABLE.getKey().equals(s.getStatus())); + return stream.collect(Collectors.toList()); + } + + @Override + public > E pageWithAuth(E page, Wrapper queryWrapper) { + boolean admin = SecurityUtil.isAdmin(); + List roles = new ArrayList<>(); + if (!admin) { + roles = SecurityUtil.getUserRoleIds(); + } + return metadataSourceDao.selectPageWithAuth(page, queryWrapper, roles); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteMetadataSourceById(String id) { + metadataSourceDao.deleteById(id); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteMetadataSourceBatch(List ids) { + metadataSourceDao.deleteBatchIds(ids); + } + + @Override + public DbQuery checkConnection(MetadataSourceDto metadataSourceDto) { + MetadataSourceEntity dataSource = metadataSourceMapper.toEntity(metadataSourceDto); + DbSchema dbSchema = dataSource.getDbSchema(); + DbQueryProperty dbQueryProperty = new DbQueryProperty(dataSource.getDbType(), dbSchema.getHost(), + dbSchema.getUsername(), dbSchema.getPassword(), dbSchema.getPort(), dbSchema.getDbName(), dbSchema.getSid()); + DbQuery dbQuery = dataSourceFactory.createDbQuery(dbQueryProperty); + return dbQuery; + } + + @Override + public DbQuery getDbQuery(String id) { + MetadataSourceEntity dataSource = super.getById(id); + DbSchema dbSchema = dataSource.getDbSchema(); + DbQueryProperty dbQueryProperty = new DbQueryProperty(dataSource.getDbType(), dbSchema.getHost(), + dbSchema.getUsername(), dbSchema.getPassword(), dbSchema.getPort(), dbSchema.getDbName(), dbSchema.getSid()); + DbQuery dbQuery = dataSourceFactory.createDbQuery(dbQueryProperty); + return dbQuery; + } + + @Override + public List getDbTables(String id) { + MetadataSourceEntity dataSource = super.getById(id); + DbSchema dbSchema = dataSource.getDbSchema(); + DbQueryProperty dbQueryProperty = new DbQueryProperty(dataSource.getDbType(), dbSchema.getHost(), + dbSchema.getUsername(), dbSchema.getPassword(), dbSchema.getPort(), dbSchema.getDbName(), dbSchema.getSid()); + DbQuery dbQuery = dataSourceFactory.createDbQuery(dbQueryProperty); + List tables = dbQuery.getTables(dbSchema.getDbName()); + return tables; + } + + @Override + public List getDbTableColumns(String id, String tableName) { + MetadataSourceEntity dataSource = super.getById(id); + DbSchema dbSchema = dataSource.getDbSchema(); + DbQueryProperty dbQueryProperty = new DbQueryProperty(dataSource.getDbType(), dbSchema.getHost(), + dbSchema.getUsername(), dbSchema.getPassword(), dbSchema.getPort(), dbSchema.getDbName(), dbSchema.getSid()); + DbQuery dbQuery = dataSourceFactory.createDbQuery(dbQueryProperty); + List columns = dbQuery.getTableColumns(dbSchema.getDbName(), tableName); + return columns; + } + + @Override + public void syncMetadata(String id) { + MetadataSourceEntity metadataSourceEntity = super.getById(id); + if (!SyncStatus.NotSync.getKey().equals(metadataSourceEntity.getIsSync())&&!SyncStatus.ErrSync.getKey().equals(metadataSourceEntity.getIsSync())&&!SyncStatus.IsSync.getKey().equals(metadataSourceEntity.getIsSync())) { + throw new DataException("元数据同步中"); + } + metadataSourceEntity.setIsSync(SyncStatus.InSync.getKey()); + metadataSourceDao.updateById(metadataSourceEntity); + // 异步执行同步任务 + asyncTask.doTask(metadataSourceEntity); + } + + @Override + public Document wordMetadata(String id) throws Exception { + MetadataSourceEntity metadataSourceEntity = super.getById(id); + DbSchema dbSchema = metadataSourceEntity.getDbSchema(); + String dbName = dbSchema.getDbName(); + if (StrUtil.isBlank(dbName)) { + dbName = dbSchema.getUsername(); + } + QueryWrapper tableQueryWrapper = new QueryWrapper<>(); + tableQueryWrapper.eq("source_id", id); + List tableEntityList = metadataTableDao.selectList(tableQueryWrapper); + // 数据表(主表) TableStart:TableList TableEnd:TableList + DataTable tableTable = new DataTable("TableList"); + tableTable.getColumns().add("id"); + tableTable.getColumns().add("tableName"); + tableTable.getColumns().add("tableComment"); + for (int i = 0; i < tableEntityList.size(); i++) { + DataRow row = tableTable.newRow(); + MetadataTableEntity table = tableEntityList.get(i); + row.set(0, table.getId()); + row.set(1, table.getTableName()); + row.set(2, table.getTableComment()); + tableTable.getRows().add(row); + } + QueryWrapper columnQueryWrapper = new QueryWrapper<>(); + columnQueryWrapper.eq("source_id", id); + columnQueryWrapper.orderByAsc("column_position"); + List columnEntityList = metadataColumnDao.selectList(columnQueryWrapper); + // 元数据(子表) TableStart:ColumnList TableEnd:ColumnList + DataTable columnTable = new DataTable("ColumnList"); + columnTable.getColumns().add("id"); + columnTable.getColumns().add("tid"); + columnTable.getColumns().add("columnPosition"); + columnTable.getColumns().add("columnName"); + columnTable.getColumns().add("dataType"); + columnTable.getColumns().add("dataLength"); + columnTable.getColumns().add("dataPrecision"); + columnTable.getColumns().add("dataScale"); + columnTable.getColumns().add("columnNullable"); + columnTable.getColumns().add("columnKey"); + columnTable.getColumns().add("dataDefault"); + columnTable.getColumns().add("columnComment"); + for (int i = 0; i < columnEntityList.size(); i++) { + DataRow row = columnTable.newRow(); + MetadataColumnEntity column = columnEntityList.get(i); + row.set(0, column.getId()); + row.set(1, column.getTableId()); + row.set(2, column.getColumnPosition()); + row.set(3, column.getColumnName()); + row.set(4, column.getDataType()); + row.set(5, column.getDataLength()); + row.set(6, column.getDataPrecision()); + row.set(7, column.getDataScale()); + row.set(8, "1".equals(column.getColumnNullable()) ? "Y" : "N"); + row.set(9, "1".equals(column.getColumnKey()) ? "Y" : "N"); + row.set(10, column.getDataDefault()); + row.set(11, column.getColumnComment()); + columnTable.getRows().add(row); + } + // 提供数据源 + DataSet dataSet = new DataSet(); + dataSet.getTables().add(tableTable); + dataSet.getTables().add(columnTable); + DataRelation dataRelation = new DataRelation("TableColumnRelation", tableTable.getColumns().get("id"), columnTable.getColumns().get("tid")); + dataSet.getRelations().add(dataRelation); + // 合并模版 + ClassPathResource classPathResource = new ClassPathResource("templates/metadata_1.0.0.doc"); + InputStream inputStream = classPathResource.getInputStream(); + Document doc = WordUtil.getInstance().getDocument(inputStream); + // 提供数据源 + String[] fieldNames = new String[] {"database"}; + Object[] fieldValues = new Object[] {dbName.toUpperCase()}; + MailMerge mailMerge = doc.getMailMerge(); + mailMerge.execute(fieldNames, fieldValues); + mailMerge.executeWithRegions(dataSet); + WordUtil.getInstance().insertWatermarkText(doc, SecurityUtil.getUserName()); + return doc; + } + + @Override + public void refreshMetadata() { + String sourceKey = RedisConstant.METADATA_SOURCE_KEY; + Boolean hasSourceKey = redisCache.hasKey(sourceKey); + if (hasSourceKey) { + redisCache.deleteObject(sourceKey); + } + List sourceEntityList = metadataSourceDao.selectList(Wrappers.emptyWrapper()); + redisCache.setCacheObject(sourceKey, sourceEntityList); + + String tableKey = RedisConstant.METADATA_TABLE_KEY; + Boolean hasTableKey = redisCache.hasKey(tableKey); + if (hasTableKey) { + redisCache.deleteObject(tableKey); + } + List tableEntityList = metadataTableDao.selectList(Wrappers.emptyWrapper()); + Map> tableListMap = tableEntityList.stream().collect(Collectors.groupingBy(MetadataTableEntity::getSourceId)); + redisCache.putAll(tableKey, tableListMap); + + String columnKey = RedisConstant.METADATA_COLUMN_KEY; + Boolean hasColumnKey = redisCache.hasKey(columnKey); + if (hasColumnKey) { + redisCache.deleteObject(columnKey); + } + List columnEntityList = metadataColumnDao.selectList(Wrappers.emptyWrapper()); + Map> columnListMap = columnEntityList.stream().collect(Collectors.groupingBy(MetadataColumnEntity::getTableId)); + redisCache.putAll(columnKey, columnListMap); + } +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/service/impl/MetadataTableServiceImpl.java b/czsj-system/src/main/java/com/czsj/metadata/service/impl/MetadataTableServiceImpl.java new file mode 100644 index 0000000..ca0cf2c --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/service/impl/MetadataTableServiceImpl.java @@ -0,0 +1,99 @@ +package com.czsj.metadata.service.impl; + + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.czsj.common.core.redis.RedisCache; +import com.czsj.core.database.base.BaseServiceImpl; +import com.czsj.core.database.core.RedisConstant; +import com.czsj.metadata.dto.MetadataTableDto; +import com.czsj.metadata.entity.MetadataTableEntity; +import com.czsj.metadata.mapper.MetadataTableDao; +import com.czsj.metadata.mapstruct.MetadataTableMapper; +import com.czsj.metadata.query.MetadataTableQuery; +import com.czsj.metadata.service.MetadataTableService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + *

+ * 数据库表信息表 服务实现类 + *

+ * + * @author yuwei + * @since 2020-07-29 + */ +@Service +@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class) +public class MetadataTableServiceImpl extends BaseServiceImpl implements MetadataTableService { + + @Autowired + private MetadataTableDao metadataTableDao; + + @Autowired + private MetadataTableMapper metadataTableMapper; + + @Resource + private RedisCache redisCache; + + @Override + @Transactional(rollbackFor = Exception.class) + public MetadataTableEntity saveMetadataTable(MetadataTableDto metadataTableDto) { + MetadataTableEntity metadataTableEntity = metadataTableMapper.toEntity(metadataTableDto); + metadataTableDao.insert(metadataTableEntity); + return metadataTableEntity; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public MetadataTableEntity updateMetadataTable(MetadataTableDto metadataTableDto) { + MetadataTableEntity metadataTableEntity = metadataTableMapper.toEntity(metadataTableDto); + metadataTableDao.updateById(metadataTableEntity); + return metadataTableEntity; + } + + @Override + public MetadataTableEntity getMetadataTableById(String id) { + MetadataTableEntity metadataTableEntity = super.getById(id); + return metadataTableEntity; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteMetadataTableById(String id) { + metadataTableDao.deleteById(id); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteMetadataTableBatch(List ids) { + metadataTableDao.deleteBatchIds(ids); + } + + @Override + public List getDataMetadataTableList(MetadataTableQuery metadataTableQuery) { + + if (StrUtil.isBlank(metadataTableQuery.getSourceId())) { + throw new RuntimeException("数据源不能为空"); + } + List tableList = (List) redisCache.hget(RedisConstant.METADATA_TABLE_KEY, metadataTableQuery.getSourceId()); + Stream stream = Optional.ofNullable(tableList).orElseGet(ArrayList::new).stream(); + return stream.collect(Collectors.toList()); + } + + @Override + public > E pageWithAuth(E page, Wrapper queryWrapper) { + List roles = new ArrayList<>(); + return metadataTableDao.selectPageWithAuth(page, queryWrapper, roles); + } +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/service/impl/SqlConsoleServiceImpl.java b/czsj-system/src/main/java/com/czsj/metadata/service/impl/SqlConsoleServiceImpl.java new file mode 100644 index 0000000..5477fd9 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/service/impl/SqlConsoleServiceImpl.java @@ -0,0 +1,120 @@ +package com.czsj.metadata.service.impl; + + +import cn.hutool.core.collection.CollUtil; +import com.czsj.common.database.constants.DbQueryProperty; +import com.czsj.common.database.service.DataSourceFactory; +import com.czsj.common.database.service.DbQuery; +import com.czsj.common.utils.ThrowableUtil; +import com.czsj.metadata.concurrent.CallableTemplate; +import com.czsj.metadata.concurrent.DateHander; +import com.czsj.metadata.dto.DbSchema; +import com.czsj.metadata.dto.SqlConsoleDto; +import com.czsj.metadata.entity.MetadataSourceEntity; +import com.czsj.metadata.service.MetadataSourceService; +import com.czsj.metadata.service.SqlConsoleService; +import com.czsj.metadata.vo.SqlConsoleVo; +import lombok.extern.slf4j.Slf4j; +import net.sf.jsqlparser.JSQLParserException; +import net.sf.jsqlparser.parser.CCJSqlParserUtil; +import net.sf.jsqlparser.statement.Statement; +import net.sf.jsqlparser.statement.Statements; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.*; + +@Slf4j +@Service +public class SqlConsoleServiceImpl implements SqlConsoleService { + + @Autowired + private DataSourceFactory dataSourceFactory; + + @Autowired + private MetadataSourceService metadataSourceServiceFeign; + + private static Map> connectionMap = new ConcurrentHashMap<>(); + + @Override + public List sqlRun(SqlConsoleDto sqlConsoleDto) throws SQLException { + String sqlKey = sqlConsoleDto.getSqlKey(); + Statements stmts; + try { + stmts = CCJSqlParserUtil.parseStatements(sqlConsoleDto.getSqlText()); + } catch (JSQLParserException e) { + log.error("全局异常信息ex={}, StackTrace={}", e.getMessage(), ThrowableUtil.getStackTrace(e)); + throw new RuntimeException("SQL语法有问题,解析出错"); + } + List sqls = stmts.getStatements(); + if (CollUtil.isEmpty(sqls)) { + throw new RuntimeException("未解析到SQL语句"); + } + MetadataSourceEntity dataSource = metadataSourceServiceFeign.getMetadataSourceById(sqlConsoleDto.getSourceId()); + if(dataSource == null){ + throw new RuntimeException("SQL工作台查询数据源出错"); + } + DbSchema dbSchema = dataSource.getDbSchema(); + DbQueryProperty dbQueryProperty = new DbQueryProperty(dataSource.getDbType(), dbSchema.getHost(), + dbSchema.getUsername(), dbSchema.getPassword(), dbSchema.getPort(), dbSchema.getDbName(), dbSchema.getSid()); + DbQuery dbQuery = dataSourceFactory.createDbQuery(dbQueryProperty); + // 定义计数器 + final CountDownLatch latch = new CountDownLatch(sqls.size()); + // 定义固定长度的线程池 + ExecutorService executorService = Executors.newFixedThreadPool(sqls.size()); + // Callable用于产生结果 + List> tasks = new ArrayList<>(); + List conns = new ArrayList<>(); + for (int i = 0; i < sqls.size(); i++) { + Connection conn = dbQuery.getConnection(); + conns.add(conn); + DateHander dateHander = new DateHander(latch, conn, sqls.get(i).toString()); + tasks.add(dateHander); + } + connectionMap.put(sqlKey, conns); + // Future用于获取结果 + List result = new ArrayList<>(); + List> futures; + try { + futures = executorService.invokeAll(tasks); + // 主线程阻塞,等待所有子线程执行完成 + latch.await(); + // 处理线程返回结果 + for (Future future : futures) { + result.add(future.get()); + } + } catch (Exception e) { + log.error("全局异常信息ex={}, StackTrace={}", e.getMessage(), ThrowableUtil.getStackTrace(e)); + } + + dbQuery.close(); + // 关闭线程池 + executorService.shutdown(); + // 执行完清除 + connectionMap.remove(sqlKey); + return result; + } + + @Override + public void sqlStop(SqlConsoleDto sqlConsoleDto) { + String sqlKey = sqlConsoleDto.getSqlKey(); + List conns = connectionMap.get(sqlKey); + if (CollUtil.isNotEmpty(conns)) { + for (int i = 0; i < conns.size(); i++) { + Connection conn = conns.get(i); + try { + if (null != conn && !conn.isClosed()) { + conn.close(); + } + } catch (SQLException e) { + throw new RuntimeException("SQL工作台停止出错"); + } + } + } + } +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/validate/ValidationGroups.java b/czsj-system/src/main/java/com/czsj/metadata/validate/ValidationGroups.java new file mode 100644 index 0000000..6ade733 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/validate/ValidationGroups.java @@ -0,0 +1,12 @@ +package com.czsj.metadata.validate; + +public class ValidationGroups { + + public interface Insert{}; + + public interface Update{}; + + public interface Status{}; + + public interface Other{}; +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/vo/MetadataChangeRecordVo.java b/czsj-system/src/main/java/com/czsj/metadata/vo/MetadataChangeRecordVo.java new file mode 100644 index 0000000..278717b --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/vo/MetadataChangeRecordVo.java @@ -0,0 +1,36 @@ +package com.czsj.metadata.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * 元数据变更记录表 实体VO + *

+ * + * @author yuwei + * @since 2020-07-30 + */ +@Data +public class MetadataChangeRecordVo implements Serializable { + + private static final long serialVersionUID=1L; + + private String id; + private String status; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date createTime; + private Integer version; + private String objectType; + private String objectId; + private String fieldName; + private String fieldOldValue; + private String fieldNewValue; + private String sourceId; + private String sourceName; + private String tableId; + private String tableName; +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/vo/MetadataColumnVo.java b/czsj-system/src/main/java/com/czsj/metadata/vo/MetadataColumnVo.java new file mode 100644 index 0000000..b41e5e8 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/vo/MetadataColumnVo.java @@ -0,0 +1,36 @@ +package com.czsj.metadata.vo; + +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 元数据信息表 实体VO + *

+ * + * @author yuwei + * @since 2020-07-29 + */ +@Data +public class MetadataColumnVo implements Serializable { + + private static final long serialVersionUID=1L; + + private String id; + private String sourceId; + private String tableId; + private String columnName; + private String columnComment; + private String columnKey; + private String columnNullable; + private Integer columnPosition; + private String dataType; + private String dataLength; + private String dataPrecision; + private String dataScale; + private String dataDefault; + private String sourceName; + private String tableName; + private String tableComment; +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/vo/MetadataSourceVo.java b/czsj-system/src/main/java/com/czsj/metadata/vo/MetadataSourceVo.java new file mode 100644 index 0000000..be5a3a3 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/vo/MetadataSourceVo.java @@ -0,0 +1,32 @@ +package com.czsj.metadata.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.czsj.metadata.dto.DbSchema; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * 数据源信息表 实体VO + *

+ * + * @author yuwei + * @since 2020-03-14 + */ +@Data +public class MetadataSourceVo implements Serializable { + + private static final long serialVersionUID=1L; + + private String id; + private String status; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date createTime; + private String remark; + private String dbType; + private String sourceName; + private DbSchema dbSchema; + private String isSync; +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/vo/MetadataTableVo.java b/czsj-system/src/main/java/com/czsj/metadata/vo/MetadataTableVo.java new file mode 100644 index 0000000..1c98e8f --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/vo/MetadataTableVo.java @@ -0,0 +1,25 @@ +package com.czsj.metadata.vo; + +import lombok.Data; + +import java.io.Serializable; + +/** + *

+ * 数据库表信息表 实体VO + *

+ * + * @author yuwei + * @since 2020-07-29 + */ +@Data +public class MetadataTableVo implements Serializable { + + private static final long serialVersionUID=1L; + + private String id; + private String sourceId; + private String tableName; + private String tableComment; + private String sourceName; +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/vo/MetadataTreeVo.java b/czsj-system/src/main/java/com/czsj/metadata/vo/MetadataTreeVo.java new file mode 100644 index 0000000..6708d65 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/vo/MetadataTreeVo.java @@ -0,0 +1,22 @@ +package com.czsj.metadata.vo; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +@Data +public class MetadataTreeVo implements Serializable { + + private static final long serialVersionUID=1L; + + private String id; + /** + * 数据层级 database、table、column + */ + private String type; + private String label; + private String name; + private String code; + private List children; +} diff --git a/czsj-system/src/main/java/com/czsj/metadata/vo/SqlConsoleVo.java b/czsj-system/src/main/java/com/czsj/metadata/vo/SqlConsoleVo.java new file mode 100644 index 0000000..80b7f65 --- /dev/null +++ b/czsj-system/src/main/java/com/czsj/metadata/vo/SqlConsoleVo.java @@ -0,0 +1,20 @@ +package com.czsj.metadata.vo; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +@Data +public class SqlConsoleVo implements Serializable { + + private static final long serialVersionUID=1L; + + private String sql; + private Long time; + private Boolean success; + private Integer count; + private List columnList; + private List> dataList; +} diff --git a/czsj-system/src/main/resources/mapper/flink/AlartLogMapper.xml b/czsj-system/src/main/resources/mapper/flink/AlartLogMapper.xml new file mode 100644 index 0000000..9fa7ba0 --- /dev/null +++ b/czsj-system/src/main/resources/mapper/flink/AlartLogMapper.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + id, job_config_id, job_name,message, type, status, is_deleted, create_time, edit_time, creator, + editor + + + fail_log + + + + + + SELECT LAST_INSERT_ID() + + insert into alart_log (job_config_id, message,job_name, type, + status, is_deleted, create_time, + edit_time, creator, editor, + fail_log) + values (#{jobConfigId,jdbcType=BIGINT}, #{message,jdbcType=VARCHAR},#{jobName,jdbcType=VARCHAR}, #{type,jdbcType=BIT}, + #{status,jdbcType=BIT}, 0, now(), + now(), 'sys', 'sys', + #{failLog,jdbcType=LONGVARCHAR}) + + + + + + + + + + diff --git a/czsj-system/src/main/resources/mapper/flink/IpStatusMapper.xml b/czsj-system/src/main/resources/mapper/flink/IpStatusMapper.xml new file mode 100644 index 0000000..ce915a5 --- /dev/null +++ b/czsj-system/src/main/resources/mapper/flink/IpStatusMapper.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + id, ip, status, last_time, is_deleted, create_time, edit_time, creator, editor + + + + + SELECT LAST_INSERT_ID() + + insert into ip_status (ip, status, last_time, + is_deleted, create_time, edit_time, + creator, editor) + values ( + #{ip,jdbcType=VARCHAR}, #{status,jdbcType=INTEGER}, #{lastTime,jdbcType=TIMESTAMP}, + 0, now(), now(), + 'sys', 'sys') + + + + + + + + + + + + + update ip_status + + + status = #{status,jdbcType=INTEGER}, + + + last_time = #{lastTime,jdbcType=TIMESTAMP}, + + + is_deleted = #{isDeleted,jdbcType=BIT}, + + + where ip = #{ip,jdbcType=VARCHAR} + + + + + diff --git a/czsj-system/src/main/resources/mapper/flink/JobAlarmConfigMapper.xml b/czsj-system/src/main/resources/mapper/flink/JobAlarmConfigMapper.xml new file mode 100644 index 0000000..3d9a79d --- /dev/null +++ b/czsj-system/src/main/resources/mapper/flink/JobAlarmConfigMapper.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + id, job_id, type, version, is_deleted, create_time, edit_time, creator, editor,cron + + + + + insert into job_alarm_config (job_id, type, version, + is_deleted, create_time, edit_time, + creator, editor) + values + + (#{item.jobId}, #{item.type}, 0, + 0, now(), now(), + 'sys', 'sys') + + + + + + + + + + + + + update job_alarm_config + set is_deleted=1 + where job_id = #{jobId,jdbcType=BIGINT} and is_deleted=0 + + + + diff --git a/czsj-system/src/main/resources/mapper/flink/JobConfigHistoryMapper.xml b/czsj-system/src/main/resources/mapper/flink/JobConfigHistoryMapper.xml new file mode 100644 index 0000000..7c770c2 --- /dev/null +++ b/czsj-system/src/main/resources/mapper/flink/JobConfigHistoryMapper.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + id, job_config_id, job_name, job_desc, deploy_mode, flink_run_config, flink_checkpoint_config, + ext_jar_path, version, job_type, is_deleted, create_time, edit_time, creator, editor + + + flink_sql + + + + + + SELECT LAST_INSERT_ID() + + insert into job_config_history (job_config_id, job_name, job_desc, deploy_mode, + flink_run_config, flink_checkpoint_config, + ext_jar_path, version, job_type, is_deleted, + create_time, edit_time, creator, + editor, flink_sql) + values (#{jobConfigId,jdbcType=BIGINT}, #{jobName,jdbcType=VARCHAR}, #{jobDesc,jdbcType=VARCHAR}, #{deployMode,jdbcType=VARCHAR}, + #{flinkRunConfig,jdbcType=VARCHAR}, #{flinkCheckpointConfig,jdbcType=VARCHAR}, + #{extJarPath,jdbcType=VARCHAR}, #{version,jdbcType=INTEGER}, #{jobType,jdbcType=INTEGER}, 0, + now(), now(), #{creator,jdbcType=VARCHAR}, + #{editor,jdbcType=VARCHAR}, #{flinkSql,jdbcType=LONGVARCHAR}) + + + + + + + + + diff --git a/czsj-system/src/main/resources/mapper/flink/JobConfigMapper.xml b/czsj-system/src/main/resources/mapper/flink/JobConfigMapper.xml new file mode 100644 index 0000000..f53752d --- /dev/null +++ b/czsj-system/src/main/resources/mapper/flink/JobConfigMapper.xml @@ -0,0 +1,325 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, + job_name, + job_desc, + deploy_mode, + flink_run_config, + flink_checkpoint_config, + job_id, + is_open, + status, + ext_jar_path, + last_start_time, + last_run_log_id, + version, + job_type, + custom_args, + custom_main_class, + custom_jar_url, + is_deleted, + create_time, + edit_time, + creator, + editor, + cron, + flinkCluster + + + flink_sql + + + + + SELECT LAST_INSERT_ID() + + insert into job_config (job_name, job_desc, deploy_mode, flink_run_config, + flink_checkpoint_config, job_id, is_open, + status, last_start_time, version, job_type,custom_args,custom_main_class,custom_jar_url, + is_deleted, create_time, edit_time, + creator, editor, flink_sql,ext_jar_path,flinkCluster,cron + ) + values (#{jobName,jdbcType=VARCHAR}, #{jobDesc,jdbcType=VARCHAR}, + #{deployMode,jdbcType=VARCHAR}, #{flinkRunConfig,jdbcType=VARCHAR}, + #{flinkCheckpointConfig,jdbcType=VARCHAR}, #{jobId,jdbcType=VARCHAR}, #{isOpen,jdbcType=BIT}, + #{status,jdbcType=BIT}, #{lastStartTime,jdbcType=TIMESTAMP}, 0,#{jobType,jdbcType=BIT}, + #{customArgs,jdbcType=VARCHAR},#{customMainClass,jdbcType=VARCHAR},#{customJarUrl,jdbcType=VARCHAR}, + 0, now(), now(), + #{creator,jdbcType=VARCHAR}, #{editor,jdbcType=VARCHAR}, #{flinkSql,jdbcType=LONGVARCHAR}, + #{extJarPath,jdbcType=VARCHAR},#{flinkCluster,jdbcType=BIGINT},#{cron,jdbcType=VARCHAR} + ) + + + + insert into job_config (id, job_name, job_desc, deploy_mode, flink_run_config, + flink_checkpoint_config, job_id, is_open, + status, last_start_time, version, job_type,custom_args,custom_main_class,custom_jar_url, + is_deleted, create_time, edit_time, + creator, editor, flink_sql,ext_jar_path,flinkCluster,cron + ) + values (#{id,jdbcType=BIGINT}, #{jobName,jdbcType=VARCHAR}, #{jobDesc,jdbcType=VARCHAR}, + #{deployMode,jdbcType=VARCHAR}, #{flinkRunConfig,jdbcType=VARCHAR}, + #{flinkCheckpointConfig,jdbcType=VARCHAR}, #{jobId,jdbcType=VARCHAR}, #{isOpen,jdbcType=BIT}, + #{status,jdbcType=BIT}, #{lastStartTime,jdbcType=TIMESTAMP}, 0,#{jobType,jdbcType=BIT}, + #{customArgs,jdbcType=VARCHAR},#{customMainClass,jdbcType=VARCHAR},#{customJarUrl,jdbcType=VARCHAR}, + 0, now(), now(), + #{creator,jdbcType=VARCHAR}, #{editor,jdbcType=VARCHAR}, #{flinkSql,jdbcType=LONGVARCHAR}, + #{extJarPath,jdbcType=VARCHAR},#{flinkCluster,jdbcType=BIGINT},#{cron,jdbcType=VARCHAR} + ) + + + + + + + + + + + + + + + + + + + + update job_config + + version=version+1, + editor = #{userName,jdbcType=VARCHAR}, + status = #{status,jdbcType=BIT}, + last_run_log_id = #{jobRunLogId,jdbcType=BIT} + + where id = #{id,jdbcType=BIGINT} and is_deleted=0 and version=#{oldVersion,jdbcType=INTEGER} + + + + + update job_config + + version=version+1, + + + job_name = #{jobName,jdbcType=VARCHAR}, + + + + flinkCluster = #{flinkCluster,jdbcType=BIGINT}, + + + + job_desc = #{jobDesc,jdbcType=VARCHAR}, + + + deploy_mode = #{deployMode,jdbcType=VARCHAR}, + + + flink_run_config = #{flinkRunConfig,jdbcType=VARCHAR}, + + + flink_checkpoint_config = #{flinkCheckpointConfig,jdbcType=VARCHAR}, + + + job_id = #{jobId,jdbcType=VARCHAR}, + + + is_open = #{isOpen,jdbcType=BIT}, + + + status = #{status,jdbcType=BIT}, + + + + ext_jar_path = #{extJarPath,jdbcType=VARCHAR}, + + + + last_start_time = #{lastStartTime,jdbcType=TIMESTAMP}, + + + + custom_args = #{customArgs,jdbcType=VARCHAR}, + + + custom_main_class = #{customMainClass,jdbcType=VARCHAR}, + + + custom_jar_url = #{customJarUrl,jdbcType=VARCHAR}, + + + + is_deleted = #{isDeleted,jdbcType=BIT}, + + + + editor = #{editor,jdbcType=VARCHAR}, + + + flink_sql = #{flinkSql,jdbcType=LONGVARCHAR}, + + + + last_run_log_id = #{lastRunLogId,jdbcType=BIT}, + + + + cron = #{cron,jdbcType=VARCHAR}, + + + where id = #{id,jdbcType=BIGINT} and is_deleted=0 + + + + update job_config + set is_deleted=1, + editor = #{userName,jdbcType=VARCHAR} + where id = #{id,jdbcType=BIGINT} + and is_deleted = 0 + + + + update job_config + set is_deleted=0, editor=#{userName,jdbcType=VARCHAR} + where id=#{id,jdbcType=BIGINT} and is_deleted=1 + + + diff --git a/czsj-system/src/main/resources/mapper/flink/JobRunLogMapper.xml b/czsj-system/src/main/resources/mapper/flink/JobRunLogMapper.xml new file mode 100644 index 0000000..2a3d82a --- /dev/null +++ b/czsj-system/src/main/resources/mapper/flink/JobRunLogMapper.xml @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + id, + job_config_id, + job_name, + job_desc, + deploy_mode, + job_id, + remote_log_url, + run_ip, + start_time, + end_time, + job_status, + is_deleted, + create_time, + edit_time, + creator, + editor + + + local_log + + + + + + SELECT LAST_INSERT_ID() + + insert into job_run_log (job_config_id, job_name, job_desc, deploy_mode, + job_id, remote_log_url, start_time, + end_time, job_status, is_deleted, + create_time, edit_time, creator, + editor, local_log, run_ip) + values (#{jobConfigId,jdbcType=BIGINT}, #{jobName,jdbcType=VARCHAR}, #{jobDesc,jdbcType=VARCHAR}, #{deployMode,jdbcType=VARCHAR}, + #{jobId,jdbcType=VARCHAR}, #{remoteLogUrl,jdbcType=VARCHAR}, #{startTime,jdbcType=TIMESTAMP}, + #{endTime,jdbcType=TIMESTAMP}, #{jobStatus,jdbcType=VARCHAR}, 0, + now(), now(), #{creator,jdbcType=VARCHAR}, + #{editor,jdbcType=VARCHAR}, #{localLog,jdbcType=LONGVARCHAR},#{runIp,jdbcType=VARCHAR}) + + + + + update job_run_log + + + remote_log_url = #{remoteLogUrl,jdbcType=VARCHAR}, + + + start_time = #{startTime,jdbcType=TIMESTAMP}, + + + end_time = #{endTime,jdbcType=TIMESTAMP}, + + + job_status = #{jobStatus,jdbcType=VARCHAR}, + + + job_id = #{jobId,jdbcType=VARCHAR}, + + + + local_log = #{localLog,jdbcType=LONGVARCHAR}, + + + where id = #{id,jdbcType=BIGINT} + + + + + + + + + + + update job_run_log + set is_deleted=1 + where is_deleted = 0 + and job_config_id = #{jobConfigId,jdbcType=BIGINT} + + + + diff --git a/czsj-system/src/main/resources/mapper/flink/SavepointBackupMapper.xml b/czsj-system/src/main/resources/mapper/flink/SavepointBackupMapper.xml new file mode 100644 index 0000000..6d1e6b6 --- /dev/null +++ b/czsj-system/src/main/resources/mapper/flink/SavepointBackupMapper.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + id, job_config_id, savepoint_path,backup_time, is_deleted, create_time, edit_time, creator, editor + + + + + SELECT LAST_INSERT_ID() + + insert into savepoint_backup (job_config_id, savepoint_path,backup_time, is_deleted, + create_time, edit_time, creator, + editor) + values (#{jobConfigId,jdbcType=BIGINT}, #{savepointPath,jdbcType=VARCHAR},#{backupTime,jdbcType=TIMESTAMP}, 0, + now(), now(), 'sys', + 'sys') + + + + + + + + + + diff --git a/czsj-system/src/main/resources/mapper/flink/SystemConfigMapper.xml b/czsj-system/src/main/resources/mapper/flink/SystemConfigMapper.xml new file mode 100644 index 0000000..9aec3fb --- /dev/null +++ b/czsj-system/src/main/resources/mapper/flink/SystemConfigMapper.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + id, `key`, val,type, is_deleted, create_time, edit_time, creator, editor + + + + insert into system_config (id, `key`, val,type, is_deleted, + create_time, edit_time, creator, + editor) + values (#{id,jdbcType=BIGINT}, #{key,jdbcType=VARCHAR}, #{val,jdbcType=VARCHAR}, #{type,jdbcType=VARCHAR}, 0, + now(), now(), 'sys', + 'sys') + + + + update system_config set is_deleted=1 where `key`= #{key,jdbcType=VARCHAR} and is_deleted=0 + + + + + + + + + + + + + + update system_config + + + val = #{val,jdbcType=VARCHAR}, + + + where is_deleted=0 and `key`= #{key,jdbcType=VARCHAR} + + diff --git a/czsj-system/src/main/resources/mapper/flink/UploadFileMapper.xml b/czsj-system/src/main/resources/mapper/flink/UploadFileMapper.xml new file mode 100644 index 0000000..681e27d --- /dev/null +++ b/czsj-system/src/main/resources/mapper/flink/UploadFileMapper.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + id, file_name, file_path, `type`, is_deleted, create_time, edit_time, creator, editor,url,resource_type,resource_name,resource_id,remarks + + + + + SELECT LAST_INSERT_ID() + + insert into upload_file (file_name, file_path, `type`, + is_deleted, create_time, edit_time, + creator, editor,url,resource_name,resource_type,resource_id,remarks) + values (#{fileName,jdbcType=VARCHAR}, #{filePath,jdbcType=VARCHAR}, #{type,jdbcType=INTEGER}, + 0, now(), now(), + #{creator,jdbcType=VARCHAR}, #{editor,jdbcType=VARCHAR},#{url,jdbcType=VARCHAR},#{resourceName,jdbcType=VARCHAR},#{resourceType,jdbcType=VARCHAR},#{resourceId,jdbcType=INTEGER},#{remarks,jdbcType=VARCHAR}) + + + + update upload_file + set is_deleted=1 + where id = #{id,jdbcType=BIGINT} and is_deleted=0 + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/czsj-system/src/main/resources/mapper/flink/UserMapper.xml b/czsj-system/src/main/resources/mapper/flink/UserMapper.xml new file mode 100644 index 0000000..63989a0 --- /dev/null +++ b/czsj-system/src/main/resources/mapper/flink/UserMapper.xml @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + id, username, name, password, status, is_deleted, create_time, edit_time, creator, editor + + + + + + + + + SELECT LAST_INSERT_ID() + + insert into user (username, name, password, status, is_deleted, create_time, edit_time, creator, editor) + values (#{username,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, #{status,jdbcType=BIT}, + 0, now(), now(), #{creator,jdbcType=VARCHAR}, #{editor,jdbcType=VARCHAR}) + + + + + update user + + + name = #{name,jdbcType=VARCHAR}, + + + password = #{password,jdbcType=VARCHAR}, + + + status = #{status,jdbcType=BIT}, + + + edit_time = #{editTime,jdbcType=TIMESTAMP}, + + + editor = #{editor,jdbcType=VARCHAR}, + + + where username = #{username,jdbcType=VARCHAR} and is_deleted=0 + + + + update user + + + name = #{name,jdbcType=VARCHAR}, + + + password = #{password,jdbcType=VARCHAR}, + + + status = #{status,jdbcType=BIT}, + + + edit_time = #{editTime,jdbcType=TIMESTAMP}, + + + editor = #{editor,jdbcType=VARCHAR}, + + + where id = #{id,jdbcType=INTEGER} and is_deleted=0 + + + + + + + + diff --git a/czsj-system/src/main/resources/mapper/market/ApiLogMapper.xml b/czsj-system/src/main/resources/mapper/market/ApiLogMapper.xml new file mode 100644 index 0000000..a85a8fb --- /dev/null +++ b/czsj-system/src/main/resources/mapper/market/ApiLogMapper.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + id, + status, + api_id, caller_id, caller_ip, caller_url, caller_params, caller_date, caller_size, time, msg + + + + ${alias}.id, + ${alias}.status, + ${alias}.api_id, ${alias}.caller_id, ${alias}.caller_ip, ${alias}.caller_url, ${alias}.caller_params, + ${alias}.caller_date, ${alias}.caller_size, ${alias}.time, ${alias}.msg + + + + + + diff --git a/czsj-system/src/main/resources/mapper/market/ApiMaskMapper.xml b/czsj-system/src/main/resources/mapper/market/ApiMaskMapper.xml new file mode 100644 index 0000000..169f06c --- /dev/null +++ b/czsj-system/src/main/resources/mapper/market/ApiMaskMapper.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + id, + status, + create_by, + create_time, + create_dept, + update_by, + update_time, + api_id, mask_name, remark + + + + id, + status, + create_by, + create_time, + create_dept, + update_by, + update_time, + api_id, mask_name, remark, config_json + + + + + + + diff --git a/czsj-system/src/main/resources/mapper/market/DataApiMapper.xml b/czsj-system/src/main/resources/mapper/market/DataApiMapper.xml new file mode 100644 index 0000000..004ae77 --- /dev/null +++ b/czsj-system/src/main/resources/mapper/market/DataApiMapper.xml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, + status, + create_by, + create_time, + create_dept, + update_by, + update_time, + api_name, api_version, api_url, remark, req_method, res_type, deny,api_code + + + + id, + status, + create_by, + create_time, + create_dept, + update_by, + update_time, + api_name, api_version, api_url, remark, req_method, res_type, deny, limit_json, config_json, req_json, res_json,api_code + + + + + + + + + + + + diff --git a/czsj-system/src/main/resources/mapper/metadata/MetadataChangeRecordMapper.xml b/czsj-system/src/main/resources/mapper/metadata/MetadataChangeRecordMapper.xml new file mode 100644 index 0000000..b80e910 --- /dev/null +++ b/czsj-system/src/main/resources/mapper/metadata/MetadataChangeRecordMapper.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, + status, + create_by, + create_time, + create_dept, + update_by, + update_time, + remark, + version, object_type, object_id, field_name, field_old_value, field_new_value + + + + ${alias}.id, + ${alias}.status, + ${alias}.create_by, + ${alias}.create_time, + ${alias}.create_dept, + ${alias}.update_by, + ${alias}.update_time, + ${alias}.remark, + ${alias}.version, ${alias}.object_type, ${alias}.object_id, ${alias}.field_name, ${alias}.field_old_value, ${alias}.field_new_value + + + + + + + diff --git a/czsj-system/src/main/resources/mapper/metadata/MetadataColumnMapper.xml b/czsj-system/src/main/resources/mapper/metadata/MetadataColumnMapper.xml new file mode 100644 index 0000000..c636742 --- /dev/null +++ b/czsj-system/src/main/resources/mapper/metadata/MetadataColumnMapper.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, + source_id, table_id, column_name, column_comment, column_key, column_nullable, column_position, data_type, data_length, data_precision, data_scale, data_default + + + + ${alias}.id, + ${alias}.source_id, ${alias}.table_id, ${alias}.column_name, ${alias}.column_comment, ${alias}.column_key, ${alias}.column_nullable, ${alias}.column_position, ${alias}.data_type, ${alias}.data_length, ${alias}.data_precision, ${alias}.data_scale, ${alias}.data_default + + + delete from metadata_column where source_id = #{sourceId} + + + delete from metadata_column where source_id = #{sourceId} and table_id = #{tableId} and column_name = #{columnName} + + + + + + + + diff --git a/czsj-system/src/main/resources/mapper/metadata/MetadataSourceMapper.xml b/czsj-system/src/main/resources/mapper/metadata/MetadataSourceMapper.xml new file mode 100644 index 0000000..86f1e0c --- /dev/null +++ b/czsj-system/src/main/resources/mapper/metadata/MetadataSourceMapper.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, + status, + create_by, + create_time, + create_dept, + update_by, + update_time, + remark, + db_type, source_name, is_sync + + + + ${alias}.id, + ${alias}.status, + ${alias}.create_by, + ${alias}.create_time, + ${alias}.create_dept, + ${alias}.update_by, + ${alias}.update_time, + ${alias}.remark, + ${alias}.db_type, ${alias}.source_name, ${alias}.is_sync, ${alias}.db_schema + + + + + + + + + + + + + diff --git a/czsj-system/src/main/resources/mapper/metadata/MetadataTableMapper.xml b/czsj-system/src/main/resources/mapper/metadata/MetadataTableMapper.xml new file mode 100644 index 0000000..261eb69 --- /dev/null +++ b/czsj-system/src/main/resources/mapper/metadata/MetadataTableMapper.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + id, + source_id, table_name, table_comment + + + + ${alias}.id, + ${alias}.source_id, ${alias}.table_name, ${alias}.table_comment + + + delete from metadata_table where source_id = #{sourceId} and table_name = #{tableName} + + + + + + + + + + diff --git a/packages/czsj-datax-executor_3.8.8_1.tar.gz b/packages/czsj-datax-executor_3.8.8_1.tar.gz index 16a0614..04497ec 100644 Binary files a/packages/czsj-datax-executor_3.8.8_1.tar.gz and b/packages/czsj-datax-executor_3.8.8_1.tar.gz differ diff --git a/pom.xml b/pom.xml index e185987..2e86300 100644 --- a/pom.xml +++ b/pom.xml @@ -25,8 +25,8 @@ czsj-flink-alarm czsj-flink-web-config czsj-flink-validation - czsj-flink-web-config czsj-flink-web-common + czsj-flink-core pom