From e8b4a058803ee24f38b20138b997d71e8f42130a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E7=AB=8B=E5=AE=8F?= <2198083211@qq.com> Date: Mon, 20 Nov 2023 18:24:40 +0800 Subject: [PATCH] =?UTF-8?q?feat(ExternalAppController):=20=E7=94=9F?= =?UTF-8?q?=E6=88=90=E5=A4=96=E9=83=A8App=E7=9A=84appKey,=E7=94=A8?= =?UTF-8?q?=E4=BA=8E=E6=A0=A1=E9=AA=8C=E8=87=AA=E5=AE=9A=E4=B9=89=E5=8A=A8?= =?UTF-8?q?=E6=80=81API=E7=9A=84=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/controller/ExternalAppController.java | 363 ++++++++++++++++++ .../ExternalAppCustomizeRouteController.java | 161 ++++++++ .../MyDynamicController.java | 26 +- .../dao/ExternalAppCustomizeRouteMapper.java | 35 ++ .../webadmin/app/dao/ExternalAppMapper.java | 50 +++ .../ExternalAppCustomizeRouteMapper.xml | 99 +++++ .../app/dao/mapper/ExternalAppMapper.xml | 139 +++++++ .../app/dto/ExternalAppCustomizeRouteDto.java | 77 ++++ .../webadmin/app/dto/ExternalAppDto.java | 100 +++++ .../supie/webadmin/app/model/ExternalApp.java | 167 ++++++++ .../app/model/ExternalAppCustomizeRoute.java | 86 +++++ .../app/service/CustomizeRouteService.java | 24 ++ .../ExternalAppCustomizeRouteService.java | 68 ++++ .../app/service/ExternalAppService.java | 124 ++++++ .../strategyImpl/BaseDataSource.java | 12 +- .../impl/CustomizeRouteServiceImpl.java | 30 ++ .../ExternalAppCustomizeRouteServiceImpl.java | 142 +++++++ .../service/impl/ExternalAppServiceImpl.java | 260 +++++++++++++ .../impl/ModelPhysicsScriptServiceImpl.java | 2 +- .../app/vo/ExternalAppCustomizeRouteVo.java | 51 +++ .../supie/webadmin/app/vo/ExternalAppVo.java | 69 ++++ .../ApiAuthenticationInterceptor.java | 19 + .../core/constant/ApplicationConstant.java | 5 + .../supie/common/core/util/RedisKeyUtil.java | 12 + 24 files changed, 2106 insertions(+), 15 deletions(-) create mode 100644 application-webadmin/src/main/java/supie/webadmin/app/controller/ExternalAppController.java create mode 100644 application-webadmin/src/main/java/supie/webadmin/app/controller/ExternalAppCustomizeRouteController.java create mode 100644 application-webadmin/src/main/java/supie/webadmin/app/dao/ExternalAppCustomizeRouteMapper.java create mode 100644 application-webadmin/src/main/java/supie/webadmin/app/dao/ExternalAppMapper.java create mode 100644 application-webadmin/src/main/java/supie/webadmin/app/dao/mapper/ExternalAppCustomizeRouteMapper.xml create mode 100644 application-webadmin/src/main/java/supie/webadmin/app/dao/mapper/ExternalAppMapper.xml create mode 100644 application-webadmin/src/main/java/supie/webadmin/app/dto/ExternalAppCustomizeRouteDto.java create mode 100644 application-webadmin/src/main/java/supie/webadmin/app/dto/ExternalAppDto.java create mode 100644 application-webadmin/src/main/java/supie/webadmin/app/model/ExternalApp.java create mode 100644 application-webadmin/src/main/java/supie/webadmin/app/model/ExternalAppCustomizeRoute.java create mode 100644 application-webadmin/src/main/java/supie/webadmin/app/service/ExternalAppCustomizeRouteService.java create mode 100644 application-webadmin/src/main/java/supie/webadmin/app/service/ExternalAppService.java create mode 100644 application-webadmin/src/main/java/supie/webadmin/app/service/impl/ExternalAppCustomizeRouteServiceImpl.java create mode 100644 application-webadmin/src/main/java/supie/webadmin/app/service/impl/ExternalAppServiceImpl.java create mode 100644 application-webadmin/src/main/java/supie/webadmin/app/vo/ExternalAppCustomizeRouteVo.java create mode 100644 application-webadmin/src/main/java/supie/webadmin/app/vo/ExternalAppVo.java diff --git a/application-webadmin/src/main/java/supie/webadmin/app/controller/ExternalAppController.java b/application-webadmin/src/main/java/supie/webadmin/app/controller/ExternalAppController.java new file mode 100644 index 0000000..445b245 --- /dev/null +++ b/application-webadmin/src/main/java/supie/webadmin/app/controller/ExternalAppController.java @@ -0,0 +1,363 @@ +package supie.webadmin.app.controller; + +import io.swagger.annotations.ApiOperation; +import supie.common.log.annotation.OperationLog; +import supie.common.log.model.constant.SysOperationLogType; +import com.github.pagehelper.page.PageMethod; +import supie.webadmin.app.vo.*; +import supie.webadmin.app.dto.*; +import supie.webadmin.app.model.*; +import supie.webadmin.app.service.*; +import supie.common.core.object.*; +import supie.common.core.util.*; +import supie.common.core.constant.*; +import supie.common.core.annotation.MyRequestBody; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import io.swagger.annotations.Api; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * 外部App表操作控制器类。 + * + * @author rm -rf .bug + * @date 2020-11-12 + */ +@Api(tags = "数据服务-外部App表管理接口") +@Slf4j +@RestController +@RequestMapping("/admin/app/externalApp") +public class ExternalAppController { + + @Autowired + private ExternalAppService externalAppService; + @Autowired + private CustomizeRouteService customizeRouteService; + + /** + * 新增外部App表数据。 + * + * @param externalAppDto 新增对象。 + * @return 应答结果对象,包含新增对象主键Id。 + */ + @ApiOperationSupport(ignoreParameters = { + "externalAppDto.id", + "externalAppDto.searchString", + "externalAppDto.updateTimeStart", + "externalAppDto.updateTimeEnd", + "externalAppDto.createTimeStart", + "externalAppDto.createTimeEnd"}) + @OperationLog(type = SysOperationLogType.ADD) + @PostMapping("/add") + public ResponseResult add(@MyRequestBody ExternalAppDto externalAppDto) { + String errorMessage = MyCommonUtil.getModelValidationError(externalAppDto, false); + if (errorMessage != null) { + return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage); + } + ExternalApp externalApp = MyModelUtil.copyTo(externalAppDto, ExternalApp.class); + externalApp = externalAppService.saveNew(externalApp); + return ResponseResult.success(externalApp.getId()); + } + + /** + * 更新外部App表数据。 + * + * @param externalAppDto 更新对象。 + * @return 应答结果对象。 + */ + @ApiOperationSupport(ignoreParameters = { + "externalAppDto.searchString", + "externalAppDto.updateTimeStart", + "externalAppDto.updateTimeEnd", + "externalAppDto.createTimeStart", + "externalAppDto.createTimeEnd"}) + @OperationLog(type = SysOperationLogType.UPDATE) + @PostMapping("/update") + public ResponseResult update(@MyRequestBody ExternalAppDto externalAppDto) { + String errorMessage = MyCommonUtil.getModelValidationError(externalAppDto, true); + if (errorMessage != null) { + return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage); + } + ExternalApp externalApp = MyModelUtil.copyTo(externalAppDto, ExternalApp.class); + ExternalApp originalExternalApp = externalAppService.getById(externalApp.getId()); + if (originalExternalApp == null) { + // NOTE: 修改下面方括号中的话述 + errorMessage = "数据验证失败,当前 [数据] 并不存在,请刷新后重试!"; + return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage); + } + if (!externalAppService.update(externalApp, originalExternalApp)) { + return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST); + } + return ResponseResult.success(); + } + + /** + * 删除外部App表数据。 + * + * @param id 删除对象主键Id。 + * @return 应答结果对象。 + */ + @OperationLog(type = SysOperationLogType.DELETE) + @PostMapping("/delete") + public ResponseResult delete(@MyRequestBody Long id) { + if (MyCommonUtil.existBlankArgument(id)) { + return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST); + } + return this.doDelete(id); + } + + /** + * 列出符合过滤条件的外部App表列表。 + * + * @param externalAppDtoFilter 过滤对象。 + * @param orderParam 排序参数。 + * @param pageParam 分页参数。 + * @return 应答结果对象,包含查询结果集。 + */ + @PostMapping("/list") + public ResponseResult> list( + @MyRequestBody ExternalAppDto externalAppDtoFilter, + @MyRequestBody MyOrderParam orderParam, + @MyRequestBody MyPageParam pageParam) { + if (pageParam != null) { + PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize()); + } + ExternalApp externalAppFilter = MyModelUtil.copyTo(externalAppDtoFilter, ExternalApp.class); + String orderBy = MyOrderParam.buildOrderBy(orderParam, ExternalApp.class); + List externalAppList = + externalAppService.getExternalAppListWithRelation(externalAppFilter, orderBy); + return ResponseResult.success(MyPageUtil.makeResponseData(externalAppList, ExternalApp.INSTANCE)); + } + + /** + * 分组列出符合过滤条件的外部App表列表。 + * + * @param externalAppDtoFilter 过滤对象。 + * @param groupParam 分组参数。 + * @param orderParam 排序参数。 + * @param pageParam 分页参数。 + * @return 应答结果对象,包含查询结果集。 + */ + @PostMapping("/listWithGroup") + public ResponseResult> listWithGroup( + @MyRequestBody ExternalAppDto externalAppDtoFilter, + @MyRequestBody(required = true) MyGroupParam groupParam, + @MyRequestBody MyOrderParam orderParam, + @MyRequestBody MyPageParam pageParam) { + String orderBy = MyOrderParam.buildOrderBy(orderParam, ExternalApp.class, false); + groupParam = MyGroupParam.buildGroupBy(groupParam, ExternalApp.class); + if (groupParam == null) { + return ResponseResult.error( + ErrorCodeEnum.INVALID_ARGUMENT_FORMAT, "数据参数错误,分组参数不能为空!"); + } + if (pageParam != null) { + PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize()); + } + ExternalApp externalAppFilter = MyModelUtil.copyTo(externalAppDtoFilter, ExternalApp.class); + MyGroupCriteria criteria = groupParam.getGroupCriteria(); + List resultList = externalAppService.getGroupedExternalAppListWithRelation( + externalAppFilter, criteria.getGroupSelect(), criteria.getGroupBy(), orderBy); + // 分页连同对象数据转换copy工作,下面的方法一并完成。 + return ResponseResult.success(MyPageUtil.makeResponseData(resultList, ExternalApp.INSTANCE)); + } + + /** + * 查看指定外部App表对象详情。 + * + * @param id 指定对象主键Id。 + * @return 应答结果对象,包含对象详情。 + */ + @GetMapping("/view") + public ResponseResult view(@RequestParam Long id) { + ExternalApp externalApp = externalAppService.getByIdWithRelation(id, MyRelationParam.full()); + if (externalApp == null) { + return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST); + } + ExternalAppVo externalAppVo = ExternalApp.INSTANCE.fromModel(externalApp); + return ResponseResult.success(externalAppVo); + } + + /** + * 列出不与指定外部App表存在多对多关系的 [自定义动态路由] 列表数据。通常用于查看添加新 [自定义动态路由] 对象的候选列表。 + * + * @param externalAppId 主表关联字段。 + * @param customizeRouteDtoFilter [自定义动态路由] 过滤对象。 + * @param orderParam 排序参数。 + * @param pageParam 分页参数。 + * @return 应答结果对象,返回符合条件的数据列表。 + */ + @ApiOperation(value = "列出不与指定外部App表存在多对多关系的 [自定义动态路由] 列表数据。通常用于查看添加新 [自定义动态路由] 对象的候选列表。") + @PostMapping("/listNotInExternalAppCustomizeRoute") + public ResponseResult> listNotInExternalAppCustomizeRoute( + @MyRequestBody Long externalAppId, + @MyRequestBody CustomizeRouteDto customizeRouteDtoFilter, + @MyRequestBody MyOrderParam orderParam, + @MyRequestBody MyPageParam pageParam) { + if (MyCommonUtil.isNotBlankOrNull(externalAppId) && !externalAppService.existId(externalAppId)) { + return ResponseResult.error(ErrorCodeEnum.INVALID_RELATED_RECORD_ID); + } + if (pageParam != null) { + PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize()); + } + CustomizeRoute customizeRouteFilter = MyModelUtil.copyTo(customizeRouteDtoFilter, CustomizeRoute.class); + String orderBy = MyOrderParam.buildOrderBy(orderParam, CustomizeRoute.class); + List customizeRouteList = + customizeRouteService.getNotInCustomizeRouteListByExternalAppId(externalAppId, customizeRouteFilter, orderBy); + return ResponseResult.success(MyPageUtil.makeResponseData(customizeRouteList, CustomizeRoute.INSTANCE)); + } + + /** + * 列出与指定外部App表存在多对多关系的 [自定义动态路由] 列表数据。 + * + * @param externalAppId 主表关联字段。 + * @param customizeRouteDtoFilter [自定义动态路由] 过滤对象。 + * @param orderParam 排序参数。 + * @param pageParam 分页参数。 + * @return 应答结果对象,返回符合条件的数据列表。 + */ + @ApiOperation("列出与指定外部App表存在多对多关系的 [自定义动态路由] 列表数据。") + @PostMapping("/listExternalAppCustomizeRoute") + public ResponseResult> listExternalAppCustomizeRoute( + @MyRequestBody(required = true) Long externalAppId, + @MyRequestBody CustomizeRouteDto customizeRouteDtoFilter, + @MyRequestBody MyOrderParam orderParam, + @MyRequestBody MyPageParam pageParam) { + if (!externalAppService.existId(externalAppId)) { + return ResponseResult.error(ErrorCodeEnum.INVALID_RELATED_RECORD_ID); + } + if (pageParam != null) { + PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize()); + } + CustomizeRoute customizeRouteFilter = MyModelUtil.copyTo(customizeRouteDtoFilter, CustomizeRoute.class); + String orderBy = MyOrderParam.buildOrderBy(orderParam, CustomizeRoute.class); + List customizeRouteList = + customizeRouteService.getCustomizeRouteListByExternalAppId(externalAppId, customizeRouteFilter, orderBy); + return ResponseResult.success(MyPageUtil.makeResponseData(customizeRouteList, CustomizeRoute.INSTANCE)); + } + + /** + * 批量添加外部App表和 [自定义动态路由] 对象的多对多关联关系数据。 + * + * @param externalAppId 主表主键Id。 + * @param externalAppCustomizeRouteDtoList 关联对象列表。 + * @return 应答结果对象。 + */ + @OperationLog(type = SysOperationLogType.ADD_M2M) + @ApiOperation("批量添加外部App表和 [自定义动态路由] 对象的多对多关联关系数据。") + @PostMapping("/addExternalAppCustomizeRoute") + public ResponseResult addExternalAppCustomizeRoute( + @MyRequestBody Long externalAppId, + @MyRequestBody List externalAppCustomizeRouteDtoList) { + if (MyCommonUtil.existBlankArgument(externalAppId, externalAppCustomizeRouteDtoList)) { + return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST); + } + Set customizeRouteIdSet = + externalAppCustomizeRouteDtoList.stream().map(ExternalAppCustomizeRouteDto::getCustomizeRouteId).collect(Collectors.toSet()); + if (!externalAppService.existId(externalAppId) + || !customizeRouteService.existUniqueKeyList("id", customizeRouteIdSet)) { + return ResponseResult.error(ErrorCodeEnum.INVALID_RELATED_RECORD_ID); + } + List externalAppCustomizeRouteList = + MyModelUtil.copyCollectionTo(externalAppCustomizeRouteDtoList, ExternalAppCustomizeRoute.class); + externalAppService.addExternalAppCustomizeRouteList(externalAppCustomizeRouteList, externalAppId); + return ResponseResult.success(); + } + + /** + * 更新指定外部App表和指定 [自定义动态路由] 的多对多关联数据。 + * + * @param externalAppCustomizeRouteDto 对多对中间表对象。 + * @return 应答结果对象。 + */ + @OperationLog(type = SysOperationLogType.UPDATE) + @ApiOperation("更新指定外部App表和指定 [自定义动态路由] 的多对多关联数据。") + @PostMapping("/updateExternalAppCustomizeRoute") + public ResponseResult updateExternalAppCustomizeRoute( + @MyRequestBody ExternalAppCustomizeRouteDto externalAppCustomizeRouteDto) { + String errorMessage = MyCommonUtil.getModelValidationError(externalAppCustomizeRouteDto); + if (errorMessage != null) { + return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage); + } + ExternalAppCustomizeRoute externalAppCustomizeRoute = MyModelUtil.copyTo(externalAppCustomizeRouteDto, ExternalAppCustomizeRoute.class); + if (!externalAppService.updateExternalAppCustomizeRoute(externalAppCustomizeRoute)) { + return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST); + } + return ResponseResult.success(); + } + + /** + * 显示外部App表和指定 [自定义动态路由] 的多对多关联详情数据。 + * + * @param externalAppId 主表主键Id。 + * @param customizeRouteId 从表主键Id。 + * @return 应答结果对象,包括中间表详情。 + */ + @ApiOperation("显示外部App表和指定 [自定义动态路由] 的多对多关联详情数据。") + @GetMapping("/viewExternalAppCustomizeRoute") + public ResponseResult viewExternalAppCustomizeRoute( + @RequestParam Long externalAppId, @RequestParam Long customizeRouteId) { + ExternalAppCustomizeRoute externalAppCustomizeRoute = externalAppService.getExternalAppCustomizeRoute(externalAppId, customizeRouteId); + if (externalAppCustomizeRoute == null) { + return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST); + } + ExternalAppCustomizeRouteVo externalAppCustomizeRouteVo = MyModelUtil.copyTo(externalAppCustomizeRoute, ExternalAppCustomizeRouteVo.class); + return ResponseResult.success(externalAppCustomizeRouteVo); + } + + /** + * 移除指定外部App表和指定 [自定义动态路由] 的多对多关联关系。 + * + * @param externalAppId 主表主键Id。 + * @param customizeRouteId 从表主键Id。 + * @return 应答结果对象。 + */ + @OperationLog(type = SysOperationLogType.DELETE_M2M) + @ApiOperation("移除指定外部App表和指定 [自定义动态路由] 的多对多关联关系。") + @PostMapping("/deleteExternalAppCustomizeRoute") + public ResponseResult deleteExternalAppCustomizeRoute( + @MyRequestBody Long externalAppId, @MyRequestBody Long customizeRouteId) { + if (MyCommonUtil.existBlankArgument(externalAppId, customizeRouteId)) { + return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST); + } + if (!externalAppService.removeExternalAppCustomizeRoute(externalAppId, customizeRouteId)) { + return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST); + } + return ResponseResult.success(); + } + + private ResponseResult doDelete(Long id) { + String errorMessage; + // 验证关联Id的数据合法性 + ExternalApp originalExternalApp = externalAppService.getById(id); + if (originalExternalApp == null) { + // NOTE: 修改下面方括号中的话述 + errorMessage = "数据验证失败,当前 [对象] 并不存在,请刷新后重试!"; + return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage); + } + if (!externalAppService.remove(id)) { + errorMessage = "数据操作失败,删除的对象不存在,请刷新后重试!"; + return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage); + } + return ResponseResult.success(); + } + + /** + * 生成 AppKey + */ + @ApiOperation("生成AppKey") + @GetMapping("/generateAppKey") + public ResponseResult generateAppKey(@RequestParam Long externalAppId) { + ExternalApp externalApp = externalAppService.getByIdWithRelation(externalAppId, MyRelationParam.full()); + if (externalApp == null) { + return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST); + } + externalApp = externalAppService.generateAppKey(externalApp); + if (externalApp == null) return ResponseResult.error(ErrorCodeEnum.NO_ERROR, "生成失败,请重试!"); + return ResponseResult.success(externalApp); + } + +} diff --git a/application-webadmin/src/main/java/supie/webadmin/app/controller/ExternalAppCustomizeRouteController.java b/application-webadmin/src/main/java/supie/webadmin/app/controller/ExternalAppCustomizeRouteController.java new file mode 100644 index 0000000..ba696f3 --- /dev/null +++ b/application-webadmin/src/main/java/supie/webadmin/app/controller/ExternalAppCustomizeRouteController.java @@ -0,0 +1,161 @@ +package supie.webadmin.app.controller; + +import supie.common.log.annotation.OperationLog; +import supie.common.log.model.constant.SysOperationLogType; +import com.github.pagehelper.page.PageMethod; +import supie.webadmin.app.vo.*; +import supie.webadmin.app.dto.*; +import supie.webadmin.app.model.*; +import supie.webadmin.app.service.*; +import supie.common.core.object.*; +import supie.common.core.util.*; +import supie.common.core.constant.*; +import supie.common.core.annotation.MyRequestBody; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import io.swagger.annotations.Api; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.*; + +/** + * 外部APP与动态路由关联表操作控制器类。 + * + * @author rm -rf .bug + * @date 2020-11-12 + */ +@Api(tags = "数据服务-外部APP与动态路由关联表管理接口") +@Slf4j +@RestController +@RequestMapping("/admin/app/externalAppCustomizeRoute") +public class ExternalAppCustomizeRouteController { + + @Autowired + private ExternalAppCustomizeRouteService externalAppCustomizeRouteService; + + /** + * 新增外部APP与动态路由关联表数据。 + * + * @param externalAppCustomizeRouteDto 新增对象。 + * @return 应答结果对象,包含新增对象主键Id。 + */ + @ApiOperationSupport(ignoreParameters = { + "externalAppCustomizeRouteDto.id", + "externalAppCustomizeRouteDto.updateTimeStart", + "externalAppCustomizeRouteDto.updateTimeEnd", + "externalAppCustomizeRouteDto.createTimeStart", + "externalAppCustomizeRouteDto.createTimeEnd"}) + @OperationLog(type = SysOperationLogType.ADD) + @PostMapping("/add") + public ResponseResult add(@MyRequestBody ExternalAppCustomizeRouteDto externalAppCustomizeRouteDto) { + String errorMessage = MyCommonUtil.getModelValidationError(externalAppCustomizeRouteDto, false); + if (errorMessage != null) { + return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage); + } + ExternalAppCustomizeRoute externalAppCustomizeRoute = MyModelUtil.copyTo(externalAppCustomizeRouteDto, ExternalAppCustomizeRoute.class); + externalAppCustomizeRoute = externalAppCustomizeRouteService.saveNew(externalAppCustomizeRoute); + return ResponseResult.success(externalAppCustomizeRoute.getId()); + } + + /** + * 更新外部APP与动态路由关联表数据。 + * + * @param externalAppCustomizeRouteDto 更新对象。 + * @return 应答结果对象。 + */ + @ApiOperationSupport(ignoreParameters = { + "externalAppCustomizeRouteDto.updateTimeStart", + "externalAppCustomizeRouteDto.updateTimeEnd", + "externalAppCustomizeRouteDto.createTimeStart", + "externalAppCustomizeRouteDto.createTimeEnd"}) + @OperationLog(type = SysOperationLogType.UPDATE) + @PostMapping("/update") + public ResponseResult update(@MyRequestBody ExternalAppCustomizeRouteDto externalAppCustomizeRouteDto) { + String errorMessage = MyCommonUtil.getModelValidationError(externalAppCustomizeRouteDto, true); + if (errorMessage != null) { + return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage); + } + ExternalAppCustomizeRoute externalAppCustomizeRoute = MyModelUtil.copyTo(externalAppCustomizeRouteDto, ExternalAppCustomizeRoute.class); + ExternalAppCustomizeRoute originalExternalAppCustomizeRoute = externalAppCustomizeRouteService.getById(externalAppCustomizeRoute.getId()); + if (originalExternalAppCustomizeRoute == null) { + // NOTE: 修改下面方括号中的话述 + errorMessage = "数据验证失败,当前 [数据] 并不存在,请刷新后重试!"; + return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage); + } + if (!externalAppCustomizeRouteService.update(externalAppCustomizeRoute, originalExternalAppCustomizeRoute)) { + return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST); + } + return ResponseResult.success(); + } + + /** + * 删除外部APP与动态路由关联表数据。 + * + * @param id 删除对象主键Id。 + * @return 应答结果对象。 + */ + @OperationLog(type = SysOperationLogType.DELETE) + @PostMapping("/delete") + public ResponseResult delete(@MyRequestBody Long id) { + if (MyCommonUtil.existBlankArgument(id)) { + return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST); + } + return this.doDelete(id); + } + + /** + * 列出符合过滤条件的外部APP与动态路由关联表列表。 + * + * @param externalAppCustomizeRouteDtoFilter 过滤对象。 + * @param orderParam 排序参数。 + * @param pageParam 分页参数。 + * @return 应答结果对象,包含查询结果集。 + */ + @PostMapping("/list") + public ResponseResult> list( + @MyRequestBody ExternalAppCustomizeRouteDto externalAppCustomizeRouteDtoFilter, + @MyRequestBody MyOrderParam orderParam, + @MyRequestBody MyPageParam pageParam) { + if (pageParam != null) { + PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize()); + } + ExternalAppCustomizeRoute externalAppCustomizeRouteFilter = MyModelUtil.copyTo(externalAppCustomizeRouteDtoFilter, ExternalAppCustomizeRoute.class); + String orderBy = MyOrderParam.buildOrderBy(orderParam, ExternalAppCustomizeRoute.class); + List externalAppCustomizeRouteList = + externalAppCustomizeRouteService.getExternalAppCustomizeRouteListWithRelation(externalAppCustomizeRouteFilter, orderBy); + return ResponseResult.success(MyPageUtil.makeResponseData(externalAppCustomizeRouteList, ExternalAppCustomizeRoute.INSTANCE)); + } + + /** + * 查看指定外部APP与动态路由关联表对象详情。 + * + * @param id 指定对象主键Id。 + * @return 应答结果对象,包含对象详情。 + */ + @GetMapping("/view") + public ResponseResult view(@RequestParam Long id) { + ExternalAppCustomizeRoute externalAppCustomizeRoute = externalAppCustomizeRouteService.getByIdWithRelation(id, MyRelationParam.full()); + if (externalAppCustomizeRoute == null) { + return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST); + } + ExternalAppCustomizeRouteVo externalAppCustomizeRouteVo = ExternalAppCustomizeRoute.INSTANCE.fromModel(externalAppCustomizeRoute); + return ResponseResult.success(externalAppCustomizeRouteVo); + } + + private ResponseResult doDelete(Long id) { + String errorMessage; + // 验证关联Id的数据合法性 + ExternalAppCustomizeRoute originalExternalAppCustomizeRoute = externalAppCustomizeRouteService.getById(id); + if (originalExternalAppCustomizeRoute == null) { + // NOTE: 修改下面方括号中的话述 + errorMessage = "数据验证失败,当前 [对象] 并不存在,请刷新后重试!"; + return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage); + } + if (!externalAppCustomizeRouteService.remove(id)) { + errorMessage = "数据操作失败,删除的对象不存在,请刷新后重试!"; + return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage); + } + return ResponseResult.success(); + } +} diff --git a/application-webadmin/src/main/java/supie/webadmin/app/controller/dynamicRoutingAPI/MyDynamicController.java b/application-webadmin/src/main/java/supie/webadmin/app/controller/dynamicRoutingAPI/MyDynamicController.java index f6034b5..9f468a8 100644 --- a/application-webadmin/src/main/java/supie/webadmin/app/controller/dynamicRoutingAPI/MyDynamicController.java +++ b/application-webadmin/src/main/java/supie/webadmin/app/controller/dynamicRoutingAPI/MyDynamicController.java @@ -8,6 +8,8 @@ import com.github.pagehelper.PageInfo; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.jetbrains.annotations.NotNull; +import org.redisson.api.RBucket; +import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.RequestBody; @@ -24,6 +26,7 @@ import supie.webadmin.app.service.databasemanagement.StrategyFactory; import javax.servlet.http.HttpServletRequest; import java.util.*; +import java.util.concurrent.TimeUnit; /** * 描述: @@ -37,7 +40,7 @@ import java.util.*; public class MyDynamicController { @Autowired - private CustomizeRouteMapper customizeRouteMapper; + private RedissonClient redissonClient; @Autowired private ProjectEngineMapper projectEngineMapper; @Autowired @@ -49,9 +52,9 @@ public class MyDynamicController { @ResponseBody public ResponseResult executeSql(@RequestBody Map params, HttpServletRequest request) { String url = request.getRequestURI(); - QueryWrapper customizeRouteQueryWrapper = new QueryWrapper<>(); - customizeRouteQueryWrapper.eq("url", url); - CustomizeRoute customizeRoute = customizeRouteMapper.selectOne(customizeRouteQueryWrapper); + RBucket customizeRouteData = redissonClient.getBucket("CustomizeRoute:" + url); + CustomizeRoute customizeRoute = customizeRouteData.get(); + customizeRouteData.delete(); return performCustomizeRouteBusiness(params, customizeRoute); } @@ -65,9 +68,16 @@ public class MyDynamicController { return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST, "缺少[" + parameter.getName() + "]变量!"); } String name = "${" + parameter.getName() + "}"; - String defaultValue = params.get(parameter.getName()).toString(); - if (StrUtil.isBlank(defaultValue)) { - defaultValue = parameter.getDefaultValue(); + String defaultValue = null; + Object value = params.get(parameter.getName()); + if (value != null) { + defaultValue = value.toString(); + } else { + if (StrUtil.isBlank(defaultValue)) { + defaultValue = parameter.getDefaultValue(); + } else { + defaultValue = "null"; + } } sqlScript = sqlScript.replace(name, defaultValue); } @@ -82,7 +92,7 @@ public class MyDynamicController { PageHelper.startPage(pageParam.getPageNum(), pageParam.getPageSize()); resultData = strategy.executeSql(sqlScript); strategy.closeAll(); - if (Boolean.FALSE.equals(resultData.get("isSuccess"))) { + if (Boolean.FALSE.equals(resultData.get("success"))) { return ResponseResult.error(ErrorCodeEnum.NO_ERROR, "(" + resultData.get("sql").toString() + ")" + resultData.get("message").toString()); } diff --git a/application-webadmin/src/main/java/supie/webadmin/app/dao/ExternalAppCustomizeRouteMapper.java b/application-webadmin/src/main/java/supie/webadmin/app/dao/ExternalAppCustomizeRouteMapper.java new file mode 100644 index 0000000..ed35c47 --- /dev/null +++ b/application-webadmin/src/main/java/supie/webadmin/app/dao/ExternalAppCustomizeRouteMapper.java @@ -0,0 +1,35 @@ +package supie.webadmin.app.dao; + +import supie.common.core.annotation.EnableDataPerm; +import supie.common.core.base.dao.BaseDaoMapper; +import supie.webadmin.app.model.ExternalAppCustomizeRoute; +import org.apache.ibatis.annotations.Param; + +import java.util.*; + +/** + * 外部APP与动态路由关联表数据操作访问接口。 + * + * @author rm -rf .bug + * @date 2020-11-12 + */ +@EnableDataPerm +public interface ExternalAppCustomizeRouteMapper extends BaseDaoMapper { + + /** + * 批量插入对象列表。 + * + * @param externalAppCustomizeRouteList 新增对象列表。 + */ + void insertList(List externalAppCustomizeRouteList); + + /** + * 获取过滤后的对象列表。 + * + * @param externalAppCustomizeRouteFilter 主表过滤对象。 + * @param orderBy 排序字符串,order by从句的参数。 + * @return 对象列表。 + */ + List getExternalAppCustomizeRouteList( + @Param("externalAppCustomizeRouteFilter") ExternalAppCustomizeRoute externalAppCustomizeRouteFilter, @Param("orderBy") String orderBy); +} diff --git a/application-webadmin/src/main/java/supie/webadmin/app/dao/ExternalAppMapper.java b/application-webadmin/src/main/java/supie/webadmin/app/dao/ExternalAppMapper.java new file mode 100644 index 0000000..e932970 --- /dev/null +++ b/application-webadmin/src/main/java/supie/webadmin/app/dao/ExternalAppMapper.java @@ -0,0 +1,50 @@ +package supie.webadmin.app.dao; + +import supie.common.core.annotation.EnableDataPerm; +import supie.common.core.base.dao.BaseDaoMapper; +import supie.webadmin.app.model.ExternalApp; +import org.apache.ibatis.annotations.Param; + +import java.util.*; + +/** + * 外部App表数据操作访问接口。 + * + * @author rm -rf .bug + * @date 2020-11-12 + */ +@EnableDataPerm +public interface ExternalAppMapper extends BaseDaoMapper { + + /** + * 批量插入对象列表。 + * + * @param externalAppList 新增对象列表。 + */ + void insertList(List externalAppList); + + /** + * 获取分组计算后的数据对象列表。 + * + * @param externalAppFilter 主表过滤对象。 + * @param groupSelect 分组显示字段列表字符串,SELECT从句的参数。 + * @param groupBy 分组字段列表字符串,GROUP BY从句的参数。 + * @param orderBy 排序字符串,ORDER BY从句的参数。 + * @return 对象列表。 + */ + List getGroupedExternalAppList( + @Param("externalAppFilter") ExternalApp externalAppFilter, + @Param("groupSelect") String groupSelect, + @Param("groupBy") String groupBy, + @Param("orderBy") String orderBy); + + /** + * 获取过滤后的对象列表。 + * + * @param externalAppFilter 主表过滤对象。 + * @param orderBy 排序字符串,order by从句的参数。 + * @return 对象列表。 + */ + List getExternalAppList( + @Param("externalAppFilter") ExternalApp externalAppFilter, @Param("orderBy") String orderBy); +} diff --git a/application-webadmin/src/main/java/supie/webadmin/app/dao/mapper/ExternalAppCustomizeRouteMapper.xml b/application-webadmin/src/main/java/supie/webadmin/app/dao/mapper/ExternalAppCustomizeRouteMapper.xml new file mode 100644 index 0000000..c16786a --- /dev/null +++ b/application-webadmin/src/main/java/supie/webadmin/app/dao/mapper/ExternalAppCustomizeRouteMapper.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + INSERT INTO sdt_external_app_customize_route + (id, + update_time, + create_time, + create_user_id, + update_user_id, + data_user_id, + data_dept_id, + is_delete, + customize_route_id, + external_app_id) + VALUES + + (#{item.id}, + #{item.updateTime}, + #{item.createTime}, + #{item.createUserId}, + #{item.updateUserId}, + #{item.dataUserId}, + #{item.dataDeptId}, + #{item.isDelete}, + #{item.customizeRouteId}, + #{item.externalAppId}) + + + + + + + + AND sdt_external_app_customize_route.is_delete = ${@supie.common.core.constant.GlobalDeletedFlag@NORMAL} + + + + + + + AND sdt_external_app_customize_route.id = #{externalAppCustomizeRouteFilter.id} + + + AND sdt_external_app_customize_route.update_time >= #{externalAppCustomizeRouteFilter.updateTimeStart} + + + AND sdt_external_app_customize_route.update_time <= #{externalAppCustomizeRouteFilter.updateTimeEnd} + + + AND sdt_external_app_customize_route.create_time >= #{externalAppCustomizeRouteFilter.createTimeStart} + + + AND sdt_external_app_customize_route.create_time <= #{externalAppCustomizeRouteFilter.createTimeEnd} + + + AND sdt_external_app_customize_route.create_user_id = #{externalAppCustomizeRouteFilter.createUserId} + + + AND sdt_external_app_customize_route.update_user_id = #{externalAppCustomizeRouteFilter.updateUserId} + + + AND sdt_external_app_customize_route.data_user_id = #{externalAppCustomizeRouteFilter.dataUserId} + + + AND sdt_external_app_customize_route.data_dept_id = #{externalAppCustomizeRouteFilter.dataDeptId} + + + AND sdt_external_app_customize_route.customize_route_id = #{externalAppCustomizeRouteFilter.customizeRouteId} + + + AND sdt_external_app_customize_route.external_app_id = #{externalAppCustomizeRouteFilter.externalAppId} + + + + + + diff --git a/application-webadmin/src/main/java/supie/webadmin/app/dao/mapper/ExternalAppMapper.xml b/application-webadmin/src/main/java/supie/webadmin/app/dao/mapper/ExternalAppMapper.xml new file mode 100644 index 0000000..c6a073c --- /dev/null +++ b/application-webadmin/src/main/java/supie/webadmin/app/dao/mapper/ExternalAppMapper.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + INSERT INTO sdt_external_app + (id, + app_name, + app_describe, + app_key, + authentication_method, + process_id, + is_delete, + update_time, + create_time, + create_user_id, + update_user_id, + data_user_id, + data_dept_id) + VALUES + + (#{item.id}, + #{item.appName}, + #{item.appDescribe}, + #{item.appKey}, + #{item.authenticationMethod}, + #{item.processId}, + #{item.isDelete}, + #{item.updateTime}, + #{item.createTime}, + #{item.createUserId}, + #{item.updateUserId}, + #{item.dataUserId}, + #{item.dataDeptId}) + + + + + + + + AND sdt_external_app.is_delete = ${@supie.common.core.constant.GlobalDeletedFlag@NORMAL} + + + + + + + AND sdt_external_app.id = #{externalAppFilter.id} + + + + AND sdt_external_app.app_name LIKE #{safeExternalAppAppName} + + + + AND sdt_external_app.app_describe LIKE #{safeExternalAppAppDescribe} + + + + AND sdt_external_app.app_key LIKE #{safeExternalAppAppKey} + + + AND sdt_external_app.authentication_method = #{externalAppFilter.authenticationMethod} + + + AND sdt_external_app.process_id = #{externalAppFilter.processId} + + + AND sdt_external_app.update_time >= #{externalAppFilter.updateTimeStart} + + + AND sdt_external_app.update_time <= #{externalAppFilter.updateTimeEnd} + + + AND sdt_external_app.create_time >= #{externalAppFilter.createTimeStart} + + + AND sdt_external_app.create_time <= #{externalAppFilter.createTimeEnd} + + + AND sdt_external_app.create_user_id = #{externalAppFilter.createUserId} + + + AND sdt_external_app.update_user_id = #{externalAppFilter.updateUserId} + + + AND sdt_external_app.data_user_id = #{externalAppFilter.dataUserId} + + + AND sdt_external_app.data_dept_id = #{externalAppFilter.dataDeptId} + + + + AND CONCAT(IFNULL(sdt_external_app.app_name,''), IFNULL(sdt_external_app.app_describe,''), IFNULL(sdt_external_app.app_key,'')) LIKE #{safeExternalAppSearchString} + + + + + + + + diff --git a/application-webadmin/src/main/java/supie/webadmin/app/dto/ExternalAppCustomizeRouteDto.java b/application-webadmin/src/main/java/supie/webadmin/app/dto/ExternalAppCustomizeRouteDto.java new file mode 100644 index 0000000..30b2161 --- /dev/null +++ b/application-webadmin/src/main/java/supie/webadmin/app/dto/ExternalAppCustomizeRouteDto.java @@ -0,0 +1,77 @@ +package supie.webadmin.app.dto; + +import supie.common.core.validator.UpdateGroup; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.*; + +/** + * ExternalAppCustomizeRouteDto对象。 + * + * @author rm -rf .bug + * @date 2020-11-12 + */ +@ApiModel("ExternalAppCustomizeRouteDto对象") +@Data +public class ExternalAppCustomizeRouteDto { + + /** + * 主键ID。 + */ + @ApiModelProperty(value = "主键ID", required = true) + @NotNull(message = "数据验证失败,主键ID不能为空!", groups = {UpdateGroup.class}) + private Long id; + + /** + * 数据所属人。 + */ + @ApiModelProperty(value = "数据所属人") + private Long dataUserId; + + /** + * 数据所属部门。 + */ + @ApiModelProperty(value = "数据所属部门") + private Long dataDeptId; + + /** + * 动态路由ID。 + */ + @ApiModelProperty(value = "动态路由ID", required = true) + @NotNull(message = "数据验证失败,动态路由ID不能为空!") + private Long customizeRouteId; + + /** + * 外部APP ID。 + */ + @ApiModelProperty(value = "外部APP ID", required = true) + @NotNull(message = "数据验证失败,外部APP ID不能为空!") + private Long externalAppId; + + /** + * updateTime 范围过滤起始值(>=)。 + */ + @ApiModelProperty(value = "updateTime 范围过滤起始值(>=)") + private String updateTimeStart; + + /** + * updateTime 范围过滤结束值(<=)。 + */ + @ApiModelProperty(value = "updateTime 范围过滤结束值(<=)") + private String updateTimeEnd; + + /** + * createTime 范围过滤起始值(>=)。 + */ + @ApiModelProperty(value = "createTime 范围过滤起始值(>=)") + private String createTimeStart; + + /** + * createTime 范围过滤结束值(<=)。 + */ + @ApiModelProperty(value = "createTime 范围过滤结束值(<=)") + private String createTimeEnd; +} diff --git a/application-webadmin/src/main/java/supie/webadmin/app/dto/ExternalAppDto.java b/application-webadmin/src/main/java/supie/webadmin/app/dto/ExternalAppDto.java new file mode 100644 index 0000000..9fa3916 --- /dev/null +++ b/application-webadmin/src/main/java/supie/webadmin/app/dto/ExternalAppDto.java @@ -0,0 +1,100 @@ +package supie.webadmin.app.dto; + +import supie.common.core.validator.UpdateGroup; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.*; + +/** + * ExternalAppDto对象。 + * + * @author rm -rf .bug + * @date 2020-11-12 + */ +@ApiModel("ExternalAppDto对象") +@Data +public class ExternalAppDto { + + /** + * 主键ID。 + */ + @ApiModelProperty(value = "主键ID", required = true) + @NotNull(message = "数据验证失败,主键ID不能为空!", groups = {UpdateGroup.class}) + private Long id; + + /** + * 应用名称。 + */ + @ApiModelProperty(value = "应用名称") + private String appName; + + /** + * App描述。 + */ + @ApiModelProperty(value = "App描述") + private String appDescribe; + + /** + * AppKey。 + */ + @ApiModelProperty(value = "AppKey") + private String appKey; + + /** + * 认证方式(1:key认证。2:无认证)。 + */ + @ApiModelProperty(value = "认证方式(1:key认证。2:无认证)", required = true) + @NotNull(message = "数据验证失败,认证方式(1:key认证。2:无认证)不能为空!") + private Integer authenticationMethod; + + /** + * 过程ID。 + */ + @ApiModelProperty(value = "过程ID") + private Long processId; + + /** + * 数据所属人。 + */ + @ApiModelProperty(value = "数据所属人") + private Long dataUserId; + + /** + * 数据所属部门。 + */ + @ApiModelProperty(value = "数据所属部门") + private Long dataDeptId; + + /** + * updateTime 范围过滤起始值(>=)。 + */ + @ApiModelProperty(value = "updateTime 范围过滤起始值(>=)") + private String updateTimeStart; + + /** + * updateTime 范围过滤结束值(<=)。 + */ + @ApiModelProperty(value = "updateTime 范围过滤结束值(<=)") + private String updateTimeEnd; + + /** + * createTime 范围过滤起始值(>=)。 + */ + @ApiModelProperty(value = "createTime 范围过滤起始值(>=)") + private String createTimeStart; + + /** + * createTime 范围过滤结束值(<=)。 + */ + @ApiModelProperty(value = "createTime 范围过滤结束值(<=)") + private String createTimeEnd; + + /** + * app_name / app_describe / app_key LIKE搜索字符串。 + */ + @ApiModelProperty(value = "LIKE模糊搜索字符串") + private String searchString; +} diff --git a/application-webadmin/src/main/java/supie/webadmin/app/model/ExternalApp.java b/application-webadmin/src/main/java/supie/webadmin/app/model/ExternalApp.java new file mode 100644 index 0000000..48b1587 --- /dev/null +++ b/application-webadmin/src/main/java/supie/webadmin/app/model/ExternalApp.java @@ -0,0 +1,167 @@ +package supie.webadmin.app.model; + +import cn.hutool.core.util.RandomUtil; +import com.baomidou.mybatisplus.annotation.*; +import supie.common.core.constant.ApplicationConstant; +import supie.common.core.util.MyCommonUtil; +import supie.common.core.annotation.*; +import supie.common.core.base.model.BaseModel; +import supie.common.core.base.mapper.BaseModelMapper; +import supie.common.core.util.RsaUtil; +import supie.webadmin.app.vo.ExternalAppVo; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.mapstruct.*; +import org.mapstruct.factory.Mappers; + +import java.nio.charset.StandardCharsets; + +/** + * ExternalApp实体对象。 + * + * @author rm -rf .bug + * @date 2020-11-12 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName(value = "sdt_external_app") +public class ExternalApp extends BaseModel implements Cloneable { + + @TableField(exist = false) + public static final String APP_KEY_PREFIX = "data_harness_cloud:"; + + /** + * 主键ID。 + */ + @TableId(value = "id") + private Long id; + + /** + * 应用名称。 + */ + private String appName; + + /** + * App描述。 + */ + private String appDescribe; + + /** + * AppKey。 + */ + private String appKey; + + /** + * 认证方式(1:key认证。2:无认证)。 + */ + private Integer authenticationMethod; + + /** + * 业务过程ID + */ + private Long processId; + + /** + * 数据所属人。 + */ + @UserFilterColumn + private Long dataUserId; + + /** + * 数据所属部门。 + */ + @DeptFilterColumn + private Long dataDeptId; + + /** + * 逻辑删除标记字段(1: 正常 -1: 已删除)。 + */ + @TableLogic + private Integer isDelete; + + /** + * updateTime 范围过滤起始值(>=)。 + */ + @TableField(exist = false) + private String updateTimeStart; + + /** + * updateTime 范围过滤结束值(<=)。 + */ + @TableField(exist = false) + private String updateTimeEnd; + + /** + * createTime 范围过滤起始值(>=)。 + */ + @TableField(exist = false) + private String createTimeStart; + + /** + * createTime 范围过滤结束值(<=)。 + */ + @TableField(exist = false) + private String createTimeEnd; + + /** + * app_name / app_describe / app_key LIKE搜索字符串。 + */ + @TableField(exist = false) + private String searchString; + + @RelationOneToOne( + masterIdField = "processId", + slaveModelClass = PlanningProcess.class, + slaveIdField = "id") + @TableField(exist = false) + private PlanningProcess planningProcess; + + public void setSearchString(String searchString) { + this.searchString = MyCommonUtil.replaceSqlWildcard(searchString); + } + + @Mapper + public interface ExternalAppModelMapper extends BaseModelMapper { + } + public static final ExternalAppModelMapper INSTANCE = Mappers.getMapper(ExternalAppModelMapper.class); + + /** + * 生成 AppKey 并且加密 + * + * @param keySuffix 应用密钥 + * @return 字符串 + * @author 王立宏 + * @date 2023/11/20 03:35 + */ + public static String generateAppKey(String keySuffix) { + if (keySuffix == null) { + keySuffix = new String(RandomUtil.randomBytes(10), StandardCharsets.UTF_8); + } + String appKey = ExternalApp.APP_KEY_PREFIX + keySuffix; + appKey = RsaUtil.encrypt(appKey, ApplicationConstant.PUBLIC_KEY); + return appKey; + } + + /** + * 验证 AppKey 是否为本平台发放的 Key + * @return 合法返回 true + */ + public static boolean verifyAppKey(String appKey) { + // 解密 + try { + appKey = RsaUtil.decrypt(appKey, ApplicationConstant.PRIVATE_KEY); + return appKey.startsWith(ExternalApp.APP_KEY_PREFIX); + } catch (Exception e) { + return false; + } + } + + @Override + public ExternalApp clone() { + try { + return (ExternalApp) super.clone(); + } catch (CloneNotSupportedException e) { + throw new RuntimeException("对象克隆失败!" + e); + } + } +} diff --git a/application-webadmin/src/main/java/supie/webadmin/app/model/ExternalAppCustomizeRoute.java b/application-webadmin/src/main/java/supie/webadmin/app/model/ExternalAppCustomizeRoute.java new file mode 100644 index 0000000..8a85ffb --- /dev/null +++ b/application-webadmin/src/main/java/supie/webadmin/app/model/ExternalAppCustomizeRoute.java @@ -0,0 +1,86 @@ +package supie.webadmin.app.model; + +import com.baomidou.mybatisplus.annotation.*; +import supie.common.core.annotation.*; +import supie.common.core.base.model.BaseModel; +import supie.common.core.base.mapper.BaseModelMapper; +import supie.webadmin.app.vo.ExternalAppCustomizeRouteVo; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.mapstruct.*; +import org.mapstruct.factory.Mappers; + +/** + * ExternalAppCustomizeRoute实体对象。 + * + * @author rm -rf .bug + * @date 2020-11-12 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName(value = "sdt_external_app_customize_route") +public class ExternalAppCustomizeRoute extends BaseModel { + + /** + * 主键ID。 + */ + @TableId(value = "id") + private Long id; + + /** + * 数据所属人。 + */ + @UserFilterColumn + private Long dataUserId; + + /** + * 数据所属部门。 + */ + @DeptFilterColumn + private Long dataDeptId; + + /** + * 逻辑删除标记字段(1: 正常 -1: 已删除)。 + */ + @TableLogic + private Integer isDelete; + + /** + * 动态路由ID。 + */ + private Long customizeRouteId; + + /** + * 外部APP ID。 + */ + private Long externalAppId; + + /** + * updateTime 范围过滤起始值(>=)。 + */ + @TableField(exist = false) + private String updateTimeStart; + + /** + * updateTime 范围过滤结束值(<=)。 + */ + @TableField(exist = false) + private String updateTimeEnd; + + /** + * createTime 范围过滤起始值(>=)。 + */ + @TableField(exist = false) + private String createTimeStart; + + /** + * createTime 范围过滤结束值(<=)。 + */ + @TableField(exist = false) + private String createTimeEnd; + + @Mapper + public interface ExternalAppCustomizeRouteModelMapper extends BaseModelMapper { + } + public static final ExternalAppCustomizeRouteModelMapper INSTANCE = Mappers.getMapper(ExternalAppCustomizeRouteModelMapper.class); +} diff --git a/application-webadmin/src/main/java/supie/webadmin/app/service/CustomizeRouteService.java b/application-webadmin/src/main/java/supie/webadmin/app/service/CustomizeRouteService.java index 61dc0e4..618c098 100644 --- a/application-webadmin/src/main/java/supie/webadmin/app/service/CustomizeRouteService.java +++ b/application-webadmin/src/main/java/supie/webadmin/app/service/CustomizeRouteService.java @@ -96,4 +96,28 @@ public interface CustomizeRouteService extends IBaseService getNotInCustomizeRouteListByExternalAppId(Long externalAppId, CustomizeRoute customizeRouteFilter, String orderBy); + + /** + * 列出与指定外部App表存在多对多关系的 [自定义动态路由] 列表数据。 + * + * @param externalAppId 主表关联字段。 + * @param customizeRouteFilter 自定义路由过滤器。 + * @param orderBy 排序方式。 + * @return 应答结果对象,返回符合条件的数据列表。 + * @return 列表<自定义路由> + * @author 王立宏 + * @date 2023/11/20 10:34 + */ + List getCustomizeRouteListByExternalAppId(Long externalAppId, CustomizeRoute customizeRouteFilter, String orderBy); } diff --git a/application-webadmin/src/main/java/supie/webadmin/app/service/ExternalAppCustomizeRouteService.java b/application-webadmin/src/main/java/supie/webadmin/app/service/ExternalAppCustomizeRouteService.java new file mode 100644 index 0000000..3a916ef --- /dev/null +++ b/application-webadmin/src/main/java/supie/webadmin/app/service/ExternalAppCustomizeRouteService.java @@ -0,0 +1,68 @@ +package supie.webadmin.app.service; + +import supie.webadmin.app.model.*; +import supie.common.core.base.service.IBaseService; + +import java.util.*; + +/** + * 外部APP与动态路由关联表数据操作服务接口。 + * + * @author rm -rf .bug + * @date 2020-11-12 + */ +public interface ExternalAppCustomizeRouteService extends IBaseService { + + /** + * 保存新增对象。 + * + * @param externalAppCustomizeRoute 新增对象。 + * @return 返回新增对象。 + */ + ExternalAppCustomizeRoute saveNew(ExternalAppCustomizeRoute externalAppCustomizeRoute); + + /** + * 利用数据库的insertList语法,批量插入对象列表。 + * + * @param externalAppCustomizeRouteList 新增对象列表。 + */ + void saveNewBatch(List externalAppCustomizeRouteList); + + /** + * 更新数据对象。 + * + * @param externalAppCustomizeRoute 更新的对象。 + * @param originalExternalAppCustomizeRoute 原有数据对象。 + * @return 成功返回true,否则false。 + */ + boolean update(ExternalAppCustomizeRoute externalAppCustomizeRoute, ExternalAppCustomizeRoute originalExternalAppCustomizeRoute); + + /** + * 删除指定数据。 + * + * @param id 主键Id。 + * @return 成功返回true,否则false。 + */ + boolean remove(Long id); + + /** + * 获取单表查询结果。由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。 + * 如果需要同时获取关联数据,请移步(getExternalAppCustomizeRouteListWithRelation)方法。 + * + * @param filter 过滤对象。 + * @param orderBy 排序参数。 + * @return 查询结果集。 + */ + List getExternalAppCustomizeRouteList(ExternalAppCustomizeRoute filter, String orderBy); + + /** + * 获取主表的查询结果,以及主表关联的字典数据和一对一从表数据,以及一对一从表的字典数据。 + * 该查询会涉及到一对一从表的关联过滤,或一对多从表的嵌套关联过滤,因此性能不如单表过滤。 + * 如果仅仅需要获取主表数据,请移步(getExternalAppCustomizeRouteList),以便获取更好的查询性能。 + * + * @param filter 主表过滤对象。 + * @param orderBy 排序参数。 + * @return 查询结果集。 + */ + List getExternalAppCustomizeRouteListWithRelation(ExternalAppCustomizeRoute filter, String orderBy); +} diff --git a/application-webadmin/src/main/java/supie/webadmin/app/service/ExternalAppService.java b/application-webadmin/src/main/java/supie/webadmin/app/service/ExternalAppService.java new file mode 100644 index 0000000..745e944 --- /dev/null +++ b/application-webadmin/src/main/java/supie/webadmin/app/service/ExternalAppService.java @@ -0,0 +1,124 @@ +package supie.webadmin.app.service; + +import supie.webadmin.app.model.*; +import supie.common.core.base.service.IBaseService; + +import java.util.*; + +/** + * 外部App表数据操作服务接口。 + * + * @author rm -rf .bug + * @date 2020-11-12 + */ +public interface ExternalAppService extends IBaseService { + + /** + * 保存新增对象。 + * + * @param externalApp 新增对象。 + * @return 返回新增对象。 + */ + ExternalApp saveNew(ExternalApp externalApp); + + /** + * 利用数据库的insertList语法,批量插入对象列表。 + * + * @param externalAppList 新增对象列表。 + */ + void saveNewBatch(List externalAppList); + + /** + * 更新数据对象。 + * + * @param externalApp 更新的对象。 + * @param originalExternalApp 原有数据对象。 + * @return 成功返回true,否则false。 + */ + boolean update(ExternalApp externalApp, ExternalApp originalExternalApp); + + /** + * 删除指定数据。 + * + * @param id 主键Id。 + * @return 成功返回true,否则false。 + */ + boolean remove(Long id); + + /** + * 获取单表查询结果。由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。 + * 如果需要同时获取关联数据,请移步(getExternalAppListWithRelation)方法。 + * + * @param filter 过滤对象。 + * @param orderBy 排序参数。 + * @return 查询结果集。 + */ + List getExternalAppList(ExternalApp filter, String orderBy); + + /** + * 获取主表的查询结果,以及主表关联的字典数据和一对一从表数据,以及一对一从表的字典数据。 + * 该查询会涉及到一对一从表的关联过滤,或一对多从表的嵌套关联过滤,因此性能不如单表过滤。 + * 如果仅仅需要获取主表数据,请移步(getExternalAppList),以便获取更好的查询性能。 + * + * @param filter 主表过滤对象。 + * @param orderBy 排序参数。 + * @return 查询结果集。 + */ + List getExternalAppListWithRelation(ExternalApp filter, String orderBy); + + /** + * 获取分组过滤后的数据查询结果,以及关联的字典数据和一对一从表数据,以及一对一从表的字典数据。 + * + * @param filter 过滤对象。 + * @param groupSelect 分组显示列表参数。位于SQL语句SELECT的后面。 + * @param groupBy 分组参数。位于SQL语句的GROUP BY后面。 + * @param orderBy 排序字符串,ORDER BY从句的参数。 + * @return 分组过滤结果集。 + */ + List getGroupedExternalAppListWithRelation( + ExternalApp filter, String groupSelect, String groupBy, String orderBy); + + /** + * 批量添加多对多关联关系。 + * + * @param externalAppCustomizeRouteList 多对多关联表对象集合。 + * @param externalAppId 主表Id。 + */ + void addExternalAppCustomizeRouteList(List externalAppCustomizeRouteList, Long externalAppId); + + /** + * 更新中间表数据。 + * + * @param externalAppCustomizeRoute 中间表对象。 + * @return 更新成功与否。 + */ + boolean updateExternalAppCustomizeRoute(ExternalAppCustomizeRoute externalAppCustomizeRoute); + + /** + * 获取中间表数据。 + * + * @param externalAppId 主表Id。 + * @param customizeRouteId 从表Id。 + * @return 中间表对象。 + */ + ExternalAppCustomizeRoute getExternalAppCustomizeRoute(Long externalAppId, Long customizeRouteId); + + /** + * 移除单条多对多关系。 + * + * @param externalAppId 主表Id。 + * @param customizeRouteId 从表Id。 + * @return 成功返回true,否则false。 + */ + boolean removeExternalAppCustomizeRoute(Long externalAppId, Long customizeRouteId); + + /** + * 生成 AppKey + * + * @param externalApp 外部应用程序信息 + * @return 外部应用程序 + * @author 王立宏 + * @date 2023/11/20 02:49 + */ + ExternalApp generateAppKey(ExternalApp externalApp); +} diff --git a/application-webadmin/src/main/java/supie/webadmin/app/service/databasemanagement/strategyImpl/BaseDataSource.java b/application-webadmin/src/main/java/supie/webadmin/app/service/databasemanagement/strategyImpl/BaseDataSource.java index 53b0e70..9693778 100644 --- a/application-webadmin/src/main/java/supie/webadmin/app/service/databasemanagement/strategyImpl/BaseDataSource.java +++ b/application-webadmin/src/main/java/supie/webadmin/app/service/databasemanagement/strategyImpl/BaseDataSource.java @@ -139,10 +139,10 @@ public class BaseDataSource { int affectedDataNumber = statement.getUpdateCount(); // 影响的行数 resultMapData.put("updateResultData", affectedDataNumber); } - resultMapData.put("isSuccess", true); + resultMapData.put("success", true); resultMapData.put("message", "SUCCESS"); } catch (SQLException e) { - resultMapData.put("isSuccess", false); + resultMapData.put("success", false); resultMapData.put("message", e.getMessage()); } statement.close(); @@ -157,7 +157,7 @@ public class BaseDataSource { * @param sql 字符(会将SQl以“;”切开成List来执行,结果也会按照语句的顺序来显示) * @return [ * { - * "isSuccess": true, + * "success": true, * "sql": "该信息所属的SQL语句。", * "message": "执行信息,主要为错误时的错误消息。", * "queryResultData": "查询语句查询到的数据集", @@ -215,10 +215,10 @@ public class BaseDataSource { int affectedDataNumber = statement.getUpdateCount(); // 影响的行数 resultMapData.put("updateResultData", affectedDataNumber); } - resultMapData.put("isSuccess", true); + resultMapData.put("success", true); resultMapData.put("message", "SUCCESS"); } catch (SQLException e) { - resultMapData.put("isSuccess", false); + resultMapData.put("success", false); resultMapData.put("message", e.getMessage()); log.error(e.toString()); } @@ -242,7 +242,7 @@ public class BaseDataSource { String createDatabaseSql = "CREATE DATABASE " + databaseName + ";"; List> resultDataList = executeSqlList(createDatabaseSql); Map resultMap = resultDataList.get(0); - if (Boolean.TRUE.equals(resultMap.get("isSuccess")) && ((int) resultMap.get("updateResultData") == 1)) return; + if (Boolean.TRUE.equals(resultMap.get("success")) && ((int) resultMap.get("updateResultData") == 1)) return; throw new RuntimeException("数据库创建[" + resultMap.get("sql") + "]失败!" + resultMap.get("message").toString()); } diff --git a/application-webadmin/src/main/java/supie/webadmin/app/service/impl/CustomizeRouteServiceImpl.java b/application-webadmin/src/main/java/supie/webadmin/app/service/impl/CustomizeRouteServiceImpl.java index 13c9e29..0621d41 100644 --- a/application-webadmin/src/main/java/supie/webadmin/app/service/impl/CustomizeRouteServiceImpl.java +++ b/application-webadmin/src/main/java/supie/webadmin/app/service/impl/CustomizeRouteServiceImpl.java @@ -272,4 +272,34 @@ public class CustomizeRouteServiceImpl extends BaseService customizeRouteMapper.update(originalCustomizeRoute, uw); } + /** + * TODO 列出不与指定外部App表存在多对多关系的 [自定义动态路由] 列表数据。通常用于查看添加新 [自定义动态路由] 对象的候选列表。 + * + * @param externalAppId 主表关联字段。 + * @param customizeRouteFilter [自定义动态路由] 过滤对象。 + * @param orderBy 排序参数。 + * @return 应答结果对象,返回符合条件的数据列表。 + * @author 王立宏 + * @date 2023/11/20 10:28 + */ + @Override + public List getNotInCustomizeRouteListByExternalAppId(Long externalAppId, CustomizeRoute customizeRouteFilter, String orderBy) { + throw new RuntimeException("该功能待完成[急需请与管理员联系]..."); + } + + /** + * TODO 列出与指定外部App表存在多对多关系的 [自定义动态路由] 列表数据。 + * + * @param externalAppId 主表关联字段。 + * @param customizeRouteFilter 自定义路由过滤器。 + * @param orderBy 排序方式。 + * @return 应答结果对象,返回符合条件的数据列表。 + * @return 列表<自定义路由> + * @author 王立宏 + * @date 2023/11/20 10:34 + */ + @Override + public List getCustomizeRouteListByExternalAppId(Long externalAppId, CustomizeRoute customizeRouteFilter, String orderBy) { + throw new RuntimeException("该功能待完成[急需请与管理员联系]..."); + } } diff --git a/application-webadmin/src/main/java/supie/webadmin/app/service/impl/ExternalAppCustomizeRouteServiceImpl.java b/application-webadmin/src/main/java/supie/webadmin/app/service/impl/ExternalAppCustomizeRouteServiceImpl.java new file mode 100644 index 0000000..50716a3 --- /dev/null +++ b/application-webadmin/src/main/java/supie/webadmin/app/service/impl/ExternalAppCustomizeRouteServiceImpl.java @@ -0,0 +1,142 @@ +package supie.webadmin.app.service.impl; + +import cn.hutool.core.collection.CollUtil; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import supie.webadmin.app.service.*; +import supie.webadmin.app.dao.*; +import supie.webadmin.app.model.*; +import supie.common.core.base.dao.BaseDaoMapper; +import supie.common.core.constant.GlobalDeletedFlag; +import supie.common.core.object.MyRelationParam; +import supie.common.core.base.service.BaseService; +import supie.common.core.util.MyModelUtil; +import supie.common.sequence.wrapper.IdGeneratorWrapper; +import com.github.pagehelper.Page; +import lombok.extern.slf4j.Slf4j; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; + +/** + * 外部APP与动态路由关联表数据操作服务类。 + * + * @author rm -rf .bug + * @date 2020-11-12 + */ +@Slf4j +@Service("externalAppCustomizeRouteService") +public class ExternalAppCustomizeRouteServiceImpl extends BaseService implements ExternalAppCustomizeRouteService { + + @Autowired + private ExternalAppCustomizeRouteMapper externalAppCustomizeRouteMapper; + @Autowired + private IdGeneratorWrapper idGenerator; + + /** + * 返回当前Service的主表Mapper对象。 + * + * @return 主表Mapper对象。 + */ + @Override + protected BaseDaoMapper mapper() { + return externalAppCustomizeRouteMapper; + } + + /** + * 保存新增对象。 + * + * @param externalAppCustomizeRoute 新增对象。 + * @return 返回新增对象。 + */ + @Transactional(rollbackFor = Exception.class) + @Override + public ExternalAppCustomizeRoute saveNew(ExternalAppCustomizeRoute externalAppCustomizeRoute) { + externalAppCustomizeRouteMapper.insert(this.buildDefaultValue(externalAppCustomizeRoute)); + return externalAppCustomizeRoute; + } + + /** + * 利用数据库的insertList语法,批量插入对象列表。 + * + * @param externalAppCustomizeRouteList 新增对象列表。 + */ + @Transactional(rollbackFor = Exception.class) + @Override + public void saveNewBatch(List externalAppCustomizeRouteList) { + if (CollUtil.isNotEmpty(externalAppCustomizeRouteList)) { + externalAppCustomizeRouteList.forEach(this::buildDefaultValue); + externalAppCustomizeRouteMapper.insertList(externalAppCustomizeRouteList); + } + } + + /** + * 更新数据对象。 + * + * @param externalAppCustomizeRoute 更新的对象。 + * @param originalExternalAppCustomizeRoute 原有数据对象。 + * @return 成功返回true,否则false。 + */ + @Transactional(rollbackFor = Exception.class) + @Override + public boolean update(ExternalAppCustomizeRoute externalAppCustomizeRoute, ExternalAppCustomizeRoute originalExternalAppCustomizeRoute) { + MyModelUtil.fillCommonsForUpdate(externalAppCustomizeRoute, originalExternalAppCustomizeRoute); + // 这里重点提示,在执行主表数据更新之前,如果有哪些字段不支持修改操作,请用原有数据对象字段替换当前数据字段。 + UpdateWrapper uw = this.createUpdateQueryForNullValue(externalAppCustomizeRoute, externalAppCustomizeRoute.getId()); + return externalAppCustomizeRouteMapper.update(externalAppCustomizeRoute, uw) == 1; + } + + /** + * 删除指定数据。 + * + * @param id 主键Id。 + * @return 成功返回true,否则false。 + */ + @Transactional(rollbackFor = Exception.class) + @Override + public boolean remove(Long id) { + return externalAppCustomizeRouteMapper.deleteById(id) == 1; + } + + /** + * 获取单表查询结果。由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。 + * 如果需要同时获取关联数据,请移步(getExternalAppCustomizeRouteListWithRelation)方法。 + * + * @param filter 过滤对象。 + * @param orderBy 排序参数。 + * @return 查询结果集。 + */ + @Override + public List getExternalAppCustomizeRouteList(ExternalAppCustomizeRoute filter, String orderBy) { + return externalAppCustomizeRouteMapper.getExternalAppCustomizeRouteList(filter, orderBy); + } + + /** + * 获取主表的查询结果,以及主表关联的字典数据和一对一从表数据,以及一对一从表的字典数据。 + * 该查询会涉及到一对一从表的关联过滤,或一对多从表的嵌套关联过滤,因此性能不如单表过滤。 + * 如果仅仅需要获取主表数据,请移步(getExternalAppCustomizeRouteList),以便获取更好的查询性能。 + * + * @param filter 主表过滤对象。 + * @param orderBy 排序参数。 + * @return 查询结果集。 + */ + @Override + public List getExternalAppCustomizeRouteListWithRelation(ExternalAppCustomizeRoute filter, String orderBy) { + List resultList = externalAppCustomizeRouteMapper.getExternalAppCustomizeRouteList(filter, orderBy); + // 在缺省生成的代码中,如果查询结果resultList不是Page对象,说明没有分页,那么就很可能是数据导出接口调用了当前方法。 + // 为了避免一次性的大量数据关联,规避因此而造成的系统运行性能冲击,这里手动进行了分批次读取,开发者可按需修改该值。 + int batchSize = resultList instanceof Page ? 0 : 1000; + this.buildRelationForDataList(resultList, MyRelationParam.normal(), batchSize); + return resultList; + } + + private ExternalAppCustomizeRoute buildDefaultValue(ExternalAppCustomizeRoute externalAppCustomizeRoute) { + if (externalAppCustomizeRoute.getId() == null) { + externalAppCustomizeRoute.setId(idGenerator.nextLongId()); + } + MyModelUtil.fillCommonsForInsert(externalAppCustomizeRoute); + externalAppCustomizeRoute.setIsDelete(GlobalDeletedFlag.NORMAL); + return externalAppCustomizeRoute; + } +} diff --git a/application-webadmin/src/main/java/supie/webadmin/app/service/impl/ExternalAppServiceImpl.java b/application-webadmin/src/main/java/supie/webadmin/app/service/impl/ExternalAppServiceImpl.java new file mode 100644 index 0000000..3da09bf --- /dev/null +++ b/application-webadmin/src/main/java/supie/webadmin/app/service/impl/ExternalAppServiceImpl.java @@ -0,0 +1,260 @@ +package supie.webadmin.app.service.impl; + +import cn.hutool.core.collection.CollUtil; +import com.baomidou.mybatisplus.core.conditions.query.*; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import supie.webadmin.app.service.*; +import supie.webadmin.app.dao.*; +import supie.webadmin.app.model.*; +import supie.common.core.base.dao.BaseDaoMapper; +import supie.common.core.constant.GlobalDeletedFlag; +import supie.common.core.object.MyRelationParam; +import supie.common.core.base.service.BaseService; +import supie.common.core.util.MyModelUtil; +import supie.common.sequence.wrapper.IdGeneratorWrapper; +import com.github.pagehelper.Page; +import lombok.extern.slf4j.Slf4j; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; + +/** + * 外部App表数据操作服务类。 + * + * @author rm -rf .bug + * @date 2020-11-12 + */ +@Slf4j +@Service("externalAppService") +public class ExternalAppServiceImpl extends BaseService implements ExternalAppService { + + @Autowired + private ExternalAppMapper externalAppMapper; + @Autowired + private ExternalAppCustomizeRouteMapper externalAppCustomizeRouteMapper; + @Autowired + private IdGeneratorWrapper idGenerator; + + /** + * 返回当前Service的主表Mapper对象。 + * + * @return 主表Mapper对象。 + */ + @Override + protected BaseDaoMapper mapper() { + return externalAppMapper; + } + + /** + * 保存新增对象。 + * + * @param externalApp 新增对象。 + * @return 返回新增对象。 + */ + @Transactional(rollbackFor = Exception.class) + @Override + public ExternalApp saveNew(ExternalApp externalApp) { + externalAppMapper.insert(this.buildDefaultValue(externalApp)); + return externalApp; + } + + /** + * 利用数据库的insertList语法,批量插入对象列表。 + * + * @param externalAppList 新增对象列表。 + */ + @Transactional(rollbackFor = Exception.class) + @Override + public void saveNewBatch(List externalAppList) { + if (CollUtil.isNotEmpty(externalAppList)) { + externalAppList.forEach(this::buildDefaultValue); + externalAppMapper.insertList(externalAppList); + } + } + + /** + * 更新数据对象。 + * + * @param externalApp 更新的对象。 + * @param originalExternalApp 原有数据对象。 + * @return 成功返回true,否则false。 + */ + @Transactional(rollbackFor = Exception.class) + @Override + public boolean update(ExternalApp externalApp, ExternalApp originalExternalApp) { + MyModelUtil.fillCommonsForUpdate(externalApp, originalExternalApp); + // 这里重点提示,在执行主表数据更新之前,如果有哪些字段不支持修改操作,请用原有数据对象字段替换当前数据字段。 + UpdateWrapper uw = this.createUpdateQueryForNullValue(externalApp, externalApp.getId()); + return externalAppMapper.update(externalApp, uw) == 1; + } + + /** + * 删除指定数据。 + * + * @param id 主键Id。 + * @return 成功返回true,否则false。 + */ + @Transactional(rollbackFor = Exception.class) + @Override + public boolean remove(Long id) { + if (externalAppMapper.deleteById(id) == 0) { + return false; + } + // 开始删除多对多子表的关联 + ExternalAppCustomizeRoute externalAppCustomizeRoute = new ExternalAppCustomizeRoute(); + externalAppCustomizeRoute.setExternalAppId(id); + externalAppCustomizeRouteMapper.delete(new QueryWrapper<>(externalAppCustomizeRoute)); + return true; + } + + /** + * 获取单表查询结果。由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。 + * 如果需要同时获取关联数据,请移步(getExternalAppListWithRelation)方法。 + * + * @param filter 过滤对象。 + * @param orderBy 排序参数。 + * @return 查询结果集。 + */ + @Override + public List getExternalAppList(ExternalApp filter, String orderBy) { + return externalAppMapper.getExternalAppList(filter, orderBy); + } + + /** + * 获取主表的查询结果,以及主表关联的字典数据和一对一从表数据,以及一对一从表的字典数据。 + * 该查询会涉及到一对一从表的关联过滤,或一对多从表的嵌套关联过滤,因此性能不如单表过滤。 + * 如果仅仅需要获取主表数据,请移步(getExternalAppList),以便获取更好的查询性能。 + * + * @param filter 主表过滤对象。 + * @param orderBy 排序参数。 + * @return 查询结果集。 + */ + @Override + public List getExternalAppListWithRelation(ExternalApp filter, String orderBy) { + List resultList = externalAppMapper.getExternalAppList(filter, orderBy); + // 在缺省生成的代码中,如果查询结果resultList不是Page对象,说明没有分页,那么就很可能是数据导出接口调用了当前方法。 + // 为了避免一次性的大量数据关联,规避因此而造成的系统运行性能冲击,这里手动进行了分批次读取,开发者可按需修改该值。 + int batchSize = resultList instanceof Page ? 0 : 1000; + this.buildRelationForDataList(resultList, MyRelationParam.normal(), batchSize); + return resultList; + } + + /** + * 获取分组过滤后的数据查询结果,以及关联的字典数据和一对一从表数据,以及一对一从表的字典数据。 + * + * @param filter 过滤对象。 + * @param groupSelect 分组显示列表参数。位于SQL语句SELECT的后面。 + * @param groupBy 分组参数。位于SQL语句的GROUP BY后面。 + * @param orderBy 排序字符串,ORDER BY从句的参数。 + * @return 分组过滤结果集。 + */ + @Override + public List getGroupedExternalAppListWithRelation( + ExternalApp filter, String groupSelect, String groupBy, String orderBy) { + List resultList = + externalAppMapper.getGroupedExternalAppList(filter, groupSelect, groupBy, orderBy); + // 在缺省生成的代码中,如果查询结果resultList不是Page对象,说明没有分页,那么就很可能是数据导出接口调用了当前方法。 + // 为了避免一次性的大量数据关联,规避因此而造成的系统运行性能冲击,这里手动进行了分批次读取,开发者可按需修改该值。 + int batchSize = resultList instanceof Page ? 0 : 1000; + // NOTE: 这里只是包含了关联数据,聚合计算数据没有包含。 + // 主要原因是,由于聚合字段通常被视为普通字段使用,不会在group by的从句中出现,语义上也不会在此关联。 + this.buildRelationForDataList(resultList, MyRelationParam.normal(), batchSize); + return resultList; + } + + /** + * 批量添加多对多关联关系。 + * + * @param externalAppCustomizeRouteList 多对多关联表对象集合。 + * @param externalAppId 主表Id。 + */ + @Transactional(rollbackFor = Exception.class) + @Override + public void addExternalAppCustomizeRouteList(List externalAppCustomizeRouteList, Long externalAppId) { + for (ExternalAppCustomizeRoute externalAppCustomizeRoute : externalAppCustomizeRouteList) { + externalAppCustomizeRoute.setId(idGenerator.nextLongId()); + externalAppCustomizeRoute.setExternalAppId(externalAppId); + externalAppCustomizeRouteMapper.insert(externalAppCustomizeRoute); + } + } + + /** + * 更新中间表数据。 + * + * @param externalAppCustomizeRoute 中间表对象。 + * @return 更新成功与否。 + */ + @Transactional(rollbackFor = Exception.class) + @Override + public boolean updateExternalAppCustomizeRoute(ExternalAppCustomizeRoute externalAppCustomizeRoute) { + ExternalAppCustomizeRoute filter = new ExternalAppCustomizeRoute(); + filter.setExternalAppId(externalAppCustomizeRoute.getExternalAppId()); + filter.setCustomizeRouteId(externalAppCustomizeRoute.getCustomizeRouteId()); + UpdateWrapper uw = + BaseService.createUpdateQueryForNullValue(externalAppCustomizeRoute, ExternalAppCustomizeRoute.class); + uw.setEntity(filter); + return externalAppCustomizeRouteMapper.update(externalAppCustomizeRoute, uw) > 0; + } + + /** + * 获取中间表数据。 + * + * @param externalAppId 主表Id。 + * @param customizeRouteId 从表Id。 + * @return 中间表对象。 + */ + @Override + public ExternalAppCustomizeRoute getExternalAppCustomizeRoute(Long externalAppId, Long customizeRouteId) { + ExternalAppCustomizeRoute filter = new ExternalAppCustomizeRoute(); + filter.setExternalAppId(externalAppId); + filter.setCustomizeRouteId(customizeRouteId); + return externalAppCustomizeRouteMapper.selectOne(new QueryWrapper<>(filter)); + } + + /** + * 移除单条多对多关系。 + * + * @param externalAppId 主表Id。 + * @param customizeRouteId 从表Id。 + * @return 成功返回true,否则false。 + */ + @Transactional(rollbackFor = Exception.class) + @Override + public boolean removeExternalAppCustomizeRoute(Long externalAppId, Long customizeRouteId) { + ExternalAppCustomizeRoute filter = new ExternalAppCustomizeRoute(); + filter.setExternalAppId(externalAppId); + filter.setCustomizeRouteId(customizeRouteId); + return externalAppCustomizeRouteMapper.delete(new QueryWrapper<>(filter)) > 0; + } + + private ExternalApp buildDefaultValue(ExternalApp externalApp) { + if (externalApp.getId() == null) { + externalApp.setId(idGenerator.nextLongId()); + } + MyModelUtil.fillCommonsForInsert(externalApp); + externalApp.setIsDelete(GlobalDeletedFlag.NORMAL); + return externalApp; + } + + /** + * 生成 AppKey + * + * @param externalApp 外部应用程序信息 + * @return 外部应用程序 + * @author 王立宏 + * @date 2023/11/20 02:49 + */ + @Override + public ExternalApp generateAppKey(ExternalApp externalApp) { + ExternalApp originalExternalApp = externalApp.clone(); + // 生成AppKey,新key覆盖原有key + String appKey = ExternalApp.generateAppKey(null); + externalApp.setAppKey(appKey); + if (update(externalApp, originalExternalApp)) { + return externalApp; + } + return null; + } +} diff --git a/application-webadmin/src/main/java/supie/webadmin/app/service/impl/ModelPhysicsScriptServiceImpl.java b/application-webadmin/src/main/java/supie/webadmin/app/service/impl/ModelPhysicsScriptServiceImpl.java index 4e22ea8..38dac3c 100644 --- a/application-webadmin/src/main/java/supie/webadmin/app/service/impl/ModelPhysicsScriptServiceImpl.java +++ b/application-webadmin/src/main/java/supie/webadmin/app/service/impl/ModelPhysicsScriptServiceImpl.java @@ -219,7 +219,7 @@ public class ModelPhysicsScriptServiceImpl extends BaseService> mapList = strategy.executeSqlList(createTableSql); if (mapList.size() == 2) { Map createTableResult = mapList.get(1); - if (Boolean.FALSE.equals(createTableResult.get("isSuccess"))) { + if (Boolean.FALSE.equals(createTableResult.get("success"))) { throw new RuntimeException(createTableResult.get("message").toString()); } } diff --git a/application-webadmin/src/main/java/supie/webadmin/app/vo/ExternalAppCustomizeRouteVo.java b/application-webadmin/src/main/java/supie/webadmin/app/vo/ExternalAppCustomizeRouteVo.java new file mode 100644 index 0000000..6244ca1 --- /dev/null +++ b/application-webadmin/src/main/java/supie/webadmin/app/vo/ExternalAppCustomizeRouteVo.java @@ -0,0 +1,51 @@ +package supie.webadmin.app.vo; + +import supie.common.core.base.vo.BaseVo; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * ExternalAppCustomizeRouteVO视图对象。 + * + * @author rm -rf .bug + * @date 2020-11-12 + */ +@ApiModel("ExternalAppCustomizeRouteVO视图对象") +@Data +@EqualsAndHashCode(callSuper = true) +public class ExternalAppCustomizeRouteVo extends BaseVo { + + /** + * 主键ID。 + */ + @ApiModelProperty(value = "主键ID") + private Long id; + + /** + * 数据所属人。 + */ + @ApiModelProperty(value = "数据所属人") + private Long dataUserId; + + /** + * 数据所属部门。 + */ + @ApiModelProperty(value = "数据所属部门") + private Long dataDeptId; + + /** + * 动态路由ID。 + */ + @ApiModelProperty(value = "动态路由ID") + private Long customizeRouteId; + + /** + * 外部APP ID。 + */ + @ApiModelProperty(value = "外部APP ID") + private Long externalAppId; +} diff --git a/application-webadmin/src/main/java/supie/webadmin/app/vo/ExternalAppVo.java b/application-webadmin/src/main/java/supie/webadmin/app/vo/ExternalAppVo.java new file mode 100644 index 0000000..1659e88 --- /dev/null +++ b/application-webadmin/src/main/java/supie/webadmin/app/vo/ExternalAppVo.java @@ -0,0 +1,69 @@ +package supie.webadmin.app.vo; + +import supie.common.core.base.vo.BaseVo; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * ExternalAppVO视图对象。 + * + * @author rm -rf .bug + * @date 2020-11-12 + */ +@ApiModel("ExternalAppVO视图对象") +@Data +@EqualsAndHashCode(callSuper = true) +public class ExternalAppVo extends BaseVo { + + /** + * 主键ID。 + */ + @ApiModelProperty(value = "主键ID") + private Long id; + + /** + * 应用名称。 + */ + @ApiModelProperty(value = "应用名称") + private String appName; + + /** + * App描述。 + */ + @ApiModelProperty(value = "App描述") + private String appDescribe; + + /** + * AppKey。 + */ + @ApiModelProperty(value = "AppKey") + private String appKey; + + /** + * 认证方式(1:key认证。2:无认证)。 + */ + @ApiModelProperty(value = "认证方式(1:key认证。2:无认证)") + private Integer authenticationMethod; + + /** + * 过程ID。 + */ + @ApiModelProperty(value = "过程ID") + private Long processId; + + /** + * 数据所属人。 + */ + @ApiModelProperty(value = "数据所属人") + private Long dataUserId; + + /** + * 数据所属部门。 + */ + @ApiModelProperty(value = "数据所属部门") + private Long dataDeptId; +} diff --git a/application-webadmin/src/main/java/supie/webadmin/interceptor/ApiAuthenticationInterceptor.java b/application-webadmin/src/main/java/supie/webadmin/interceptor/ApiAuthenticationInterceptor.java index f32e220..2e62941 100644 --- a/application-webadmin/src/main/java/supie/webadmin/interceptor/ApiAuthenticationInterceptor.java +++ b/application-webadmin/src/main/java/supie/webadmin/interceptor/ApiAuthenticationInterceptor.java @@ -7,12 +7,14 @@ import cn.hutool.http.HttpResponse; import cn.hutool.http.HttpUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.TypeReference; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import io.jsonwebtoken.Claims; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.redisson.api.RBucket; import org.redisson.api.RSet; import org.redisson.api.RedissonClient; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; import org.springframework.util.Assert; @@ -30,6 +32,8 @@ import supie.common.core.object.TokenData; import supie.common.core.util.ApplicationContextHolder; import supie.common.core.util.JwtUtil; import supie.common.core.util.RedisKeyUtil; +import supie.webadmin.app.dao.CustomizeRouteMapper; +import supie.webadmin.app.model.CustomizeRoute; import supie.webadmin.config.ApplicationConfig; import supie.webadmin.config.ThirdPartyAuthConfig; @@ -61,11 +65,26 @@ public class ApiAuthenticationInterceptor implements HandlerInterceptor { private final CacheManager cacheManager = ApplicationContextHolder.getBean("caffeineCacheManager"); + private final CustomizeRouteMapper customizeRouteMapper = + ApplicationContextHolder.getBean("customizeRouteMapper"); + @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String url = request.getRequestURI(); log.error("请求了自定义地址[" + url + "]"); +// QueryWrapper customizeRouteQueryWrapper = new QueryWrapper<>(); +// customizeRouteQueryWrapper.eq("url", url); +// CustomizeRoute customizeRoute = customizeRouteMapper.selectOne(customizeRouteQueryWrapper); +// if (customizeRoute == null) return false; +// // 判断相关权限(先查询redis,redis中没有再查询数据库中的权限,并存入redis。TODO 相应的权限有变动修改则删除redis中缓存的权限信息。) +// String customizeRouteRightKey = RedisKeyUtil.makeCustomizeRouteRightKey(customizeRoute.getId()); +// RBucket> customizeRouteRight = redissonClient.getBucket(customizeRouteRightKey); +// +// +// // 权限判断通过,自定义路由信息存储至redis,以供业务代码获取 +// RBucket customizeRouteData = redissonClient.getBucket("CustomizeRoute:" + url); +// customizeRouteData.set(customizeRoute, 30, TimeUnit.SECONDS); return true; // String token = this.getTokenFromRequest(request); diff --git a/common/common-core/src/main/java/supie/common/core/constant/ApplicationConstant.java b/common/common-core/src/main/java/supie/common/core/constant/ApplicationConstant.java index c41fda9..a7192ea 100644 --- a/common/common-core/src/main/java/supie/common/core/constant/ApplicationConstant.java +++ b/common/common-core/src/main/java/supie/common/core/constant/ApplicationConstant.java @@ -135,6 +135,11 @@ public final class ApplicationConstant { * 密钥的生成方式,可通过执行common.core.util.RsaUtil类的main函数动态生成。 */ public static final String PRIVATE_KEY = "MIICXgIBAAKBgQC0XJx6AHME41GzcSW/MUFZkKOgfhyWckrMwDKXZXIFCFbwpYgNDDQ1qzHmxqdpmGAIgtitQluIO78m1K+eXY5iyYgp5o0/1pH4/X1DXpF85TVSkKycNrovhEjDHxjZg4i8jWR2UX53YaEDgS+Ki9wJkRBL2OFjMrgyRqIVronNhwIDAQABAoGASuRNwUcge34ctcMc5mgAd71chE75desdbim8mCryjm5pE2HYvXo8z7A3d1kzuOAhuEcEy+TK9yW/+NLF3Z+BeIcpY88FMEW8x1JOLrzZ5TMH9E8RJ7mqMnFMWEoPkqArepLtJ88ZeJtyxZresrBWHylk1WpE2Iv19GJEb9p+XykCQQDdRjCKF1YncAefmjW6UQS3jLMWUjvATaUo6ZRBDY/zGRfFgfvzmk08FtIKDXKrDt5L1/Ypj+YZU99+zypXecXVAkEA0Kq+O43SxzImqHtY3wgqnbndAFO1gYjiMBwajaHOfcfPniDcLl9db5JK2Xu62W2Mgit3pOSB1573DFa2yEbn6wJBAKwsG0S318+j+iqT4U5yEAuKLScnIVsGj4aACV184g8z7S0/cP4hiAtDbndn81tqnEnDZsT8NPxsKLERHU8nb2kCQQClcQq8+xhIGQovgQSYaMgpH+kKTlRVbKsxS8b9znGCpn6FODZ6id/yCwJPZtthcor51e7ZjNcplv73CHWJWzabAkEAnRLFlUui5wMFHlYlx/jOOlaLhnSkxtLPKnu1I/2skz+uQSemr8f9v7nCADcw7IglI2r80K0d6NUyNvecoUFmBA=="; + /** + * 私钥(与 PRIVATE_KEY 成对) + */ + public static final String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC0XJx6AHME41GzcSW/MUFZkKOgfhyWckrMwDKXZXIFCFbwpYgNDDQ1qzHmxqdpmGAIgtitQluIO78m1K+eXY5iyYgp5o0/1pH4/X1DXpF85TVSkKycNrovhEjDHxjZg4i8jWR2UX53YaEDgS+Ki9wJkRBL2OFjMrgyRqIVronNhwIDAQAB"; + /** * SQL注入检测的正则对象。 */ diff --git a/common/common-core/src/main/java/supie/common/core/util/RedisKeyUtil.java b/common/common-core/src/main/java/supie/common/core/util/RedisKeyUtil.java index 330b013..074d356 100644 --- a/common/common-core/src/main/java/supie/common/core/util/RedisKeyUtil.java +++ b/common/common-core/src/main/java/supie/common/core/util/RedisKeyUtil.java @@ -160,4 +160,16 @@ public class RedisKeyUtil { */ private RedisKeyUtil() { } + + /** + * 构建自定义路由权限Key + * + * @param customizeRouteId 自定义路由ID + * @return 字符串 + * @author 王立宏 + * @date 2023/11/20 10:08 + */ + public static String makeCustomizeRouteRightKey(Long customizeRouteId) { + return "CUSTOMIZE_ROUTE_RIGHT:" + customizeRouteId; + } } -- Gitee