Skip to content

基础API接口

BegCode对JHipster默认模板代码的API接口进行了拓展和增强,但这些接口不是默认全部生成的,根据不同的条件才会有相应的接口。

1. 改进分页列表接口

JHipster原始分页接口采用headers来处理分页相关的参数和数据,与国内常用方式不同。

BegCode设置了PageRecord接口。同时该接口仅做为返回结果使用,其他如排序等接收参数,继续使用Spring的Pageable接口。

java
public class PageRecord<T> {

  private long total = 0;

  private long page = 0;

  private long size = 15;

  private long pages = 0;

  private List<T> records = new ArrayList<>();
}

生成代码示例:

java
    @GetMapping("")
    @Operation(tags = "获取系统日志分页列表", description = "获取系统日志的分页列表数据")
    @AutoLog(value = "获取系统日志分页列表", logType = LogType.OPERATE, operateType = OperateType.LIST)
    public ResponseEntity<PageRecord<SysLogDTO>> getAllSysLogs(
        SysLogCriteria criteria,
        @org.springdoc.core.annotations.ParameterObject Pageable pageable
    ) {
        log.debug("REST request to get SysLogs by criteria: {}", criteria);

        IPage<SysLogDTO> page;
        page = sysLogQueryService.findByCriteria(criteria, PageableUtils.toPage(pageable));
        PageRecord<SysLogDTO> result = new PageRecord<>();
        result.records(page.getRecords()).size(page.getSize()).total(page.getTotal()).page(page.getCurrent());
        HttpHeaders headers = IPageUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page);
        return ResponseEntity.ok().headers(headers).body(result);
    }

2. 树形结构实体增加了2个新的接口

BegCode根据实体的关联关系配置,判断是否为树形结构,并增加相应的接口。

jdl示例

md
relationship OneToMany {

    /** 子节点 */
    ViewPermission{children(text)}
    to
    /** 上级 */
    ViewPermission{parent(text)}

    /** 子节点 */
    Authority{children(name)}
    to
    /** 上级 */
    Authority{parent(name)}

}

2.1 /tree 直接返回树形结构列表数据接口。

代码示例:

java
    @GetMapping("/tree")
    @Operation(tags = "获取API权限树形列表", description = "获取API权限的树形列表数据")
    @AutoLog(value = "获取API权限树形列表", logType = LogType.OPERATE, operateType = OperateType.LIST)
    public ResponseEntity<PageRecord<ApiPermissionDTO>> getAllApiPermissionsofTree(ApiPermissionCriteria criteria, Pageable pageable) {
        log.debug("REST request to get a page of ApiPermissions");
        IPage<ApiPermissionDTO> page = apiPermissionQueryService.findAllTop(criteria, PageableUtils.toPage(pageable));
        PageRecord<ApiPermissionDTO> result = new PageRecord<>();
        result.records(page.getRecords()).size((int) page.getSize()).total(page.getTotal()).page(page.getCurrent());
        HttpHeaders headers = IPageUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page);
        return ResponseEntity.ok().headers(headers).body(result);
    }

2.2 {parentId}/tree 返回指定父节点下的所有列表数据接口。

代码示例:

java
    @GetMapping("/{parentId}/tree")
    @Operation(tags = "获取API权限指定节点下的树形列表", description = "获取API权限指定节点下的树形列表数据")
    @AutoLog(value = "获取API权限指定节点下的树形列表", logType = LogType.OPERATE, operateType = OperateType.LIST)
    public ResponseEntity<List<ApiPermissionDTO>> getAllApiPermissionsofParent(@PathVariable Long parentId) {
        log.debug("REST request to get all ApiPermissions of parentId");
        List<ApiPermissionDTO> list = apiPermissionQueryService.findChildrenByParentId(parentId);
        return ResponseEntity.ok().body(list);
    }

2.3 树形结构前端代码

table列表配置:

javascript
return {
  treeConfig: {
    childrenField: 'children',
    indent: 20,
    line: false,
    expandAll: false,
    accordion: false,
    trigger: 'default',
  },
};

2.4 最终效果:

view_permission.png

3. 修改delete接口支持多个id删除。

有时可能涉及到批量操作。

java
    @DeleteMapping("")
    @Operation(tags = "删除多个API权限", description = "根据主键删除多个API权限")
    @AutoLog(value = "删除多个API权限", logType = LogType.OPERATE, operateType = OperateType.DELETE)
    public ResponseEntity<Void> deleteApiPermissionsByIds(@RequestParam("ids") ArrayList<Long> ids) {
        log.debug("REST request to delete ApiPermissions : {}", ids);
        if (ids != null) {
            ids.forEach(apiPermissionService::delete);
        }
        return ResponseEntity
            .noContent()
            .headers(HeaderUtil.createEntityDeletionAlert(applicationName, true, ENTITY_NAME, (ids != null ? ids.toString() : "NoIds")))
            .build();
    }

4. /count 动态条件的统计接口。

该接口由前端组装复用为exist判断接口,像唯一性验证等可以使用。

java
    @GetMapping("/count")
    public ResponseEntity<Long> countApiPermissions(ApiPermissionCriteria criteria) {
        log.debug("REST request to count ApiPermissions by criteria: {}", criteria);
        return ResponseEntity.ok().body(apiPermissionQueryService.countByCriteria(criteria));
    }

5. /import 使用excel导入文件接口。

java
    @PostMapping("/import")
    @Operation(tags = "API权限EXCEL导入", description = "根据API权限EXCEL文件导入全部数据")
    @AutoLog(value = "API权限EXCEL导入", logType = LogType.OPERATE, operateType = OperateType.IMPORT)
    public ResponseEntity<Void> exportToExcel(MultipartFile file) throws Exception {
        ImportParams params = new ImportParams();
        params.setTitleRows(1);
        params.setHeadRows(1);
        List<ApiPermissionDTO> list = ExcelImportUtil.importExcel(file.getInputStream(), ApiPermissionDTO.class, params);
        list.forEach(apiPermissionService::save);
        return ResponseEntity.ok().build();
    }

6. /export 导出excel文件接口。

java
    @GetMapping("/export")
    @Operation(tags = "API权限EXCEL导出", description = "导出全部API权限为EXCEL文件")
    @AutoLog(value = "API权限EXCEL导出", logType = LogType.OPERATE, operateType = OperateType.EXPORT)
    public void exportToExcel(HttpServletResponse response) {
        List<ApiPermissionDTO> data = apiPermissionService.findAll(new Page<>(1, Integer.MAX_VALUE)).getRecords();
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("API权限一览表", "API权限"), ApiPermissionDTO.class, data);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String filename = "API权限_" + sdf.format(new Date()) + ".xlsx";
        try {
            ExportUtil.excel(workbook, filename, response);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

7. 统计汇总接口

java
    @GetMapping("/stats")
    @Operation(tags = "根据条件对API权限进行统计", description = "条件和统计的配置通过API权限的Criteria类来实现")
    @AutoLog(value = "根据条件对API权限进行统计", logType = LogType.OPERATE, operateType = OperateType.STATS)
    public ResponseEntity<List<Map<String, Object>>> stats(ApiPermissionCriteria criteria) {
        log.debug("REST request to get stats by criteria: {}", criteria);
        List<Map<String, Object>> statsMapList = apiPermissionQueryService.statsByAggregateCriteria(criteria);
        return ResponseEntity.ok().body(statsMapList);
    }

8. 更新记录接口

本接口对原有功能进行了增强,支持单个记录的所有字段更新,也支持多条记录指定多个字段的更新。

java
    @PutMapping("/{id}")
    @Operation(tags = "更新API权限", description = "根据主键更新并返回一个更新后的API权限")
    @AutoLog(value = "更新API权限", logType = LogType.OPERATE, operateType = OperateType.EDIT)
    public ResponseEntity<ApiPermissionDTO> updateApiPermission(
        @PathVariable(value = "id", required = false) final Long id,
        @RequestBody ApiPermissionDTO apiPermissionDTO,
        @RequestParam(value = "batchIds", required = false) ArrayList<Long> batchIds,
        @RequestParam(value = "batchFields", required = false) ArrayList<String> batchFields
    ) {
        log.debug("REST request to update ApiPermission : {}, {}", id, apiPermissionDTO);
        if (apiPermissionDTO.getId() == null) {
            throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull");
        }
        if (!Objects.equals(id, apiPermissionDTO.getId())) {
            throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid");
        }

        if (apiPermissionRepository.findById(id).isEmpty()) {
            throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound");
        }

        ApiPermissionDTO result = null;
        if (CollectionUtils.isNotEmpty(batchFields) && CollectionUtils.isNotEmpty(batchIds)) {
            batchIds = new ArrayList<>(batchIds);
            if (!batchIds.contains(id)) {
                batchIds.add(id);
            }
            apiPermissionService.updateBatch(apiPermissionDTO, batchFields, batchIds);
            result = apiPermissionService.findOne(id).orElseThrow();
        } else {
            result = apiPermissionService.update(apiPermissionDTO);
        }
        return ResponseEntity
            .ok()
            .headers(HeaderUtil.createEntityUpdateAlert(applicationName, true, ENTITY_NAME, apiPermissionDTO.getId().toString()))
            .body(result);
    }

9. 部分更新记录接口

为JHipster原始接口实现方式,未做改动。

java
    @PatchMapping(value = "/{id}", consumes = { "application/json", "application/merge-patch+json" })
    @Operation(tags = "部分更新API权限", description = "根据主键及实体信息实现部分更新,值为null的属性将忽略,并返回一个更新后的API权限")
    @AutoLog(value = "部分更新API权限", logType = LogType.OPERATE, operateType = OperateType.EDIT)
    public ResponseEntity<ApiPermissionDTO> partialUpdateApiPermission(
        @PathVariable(value = "id", required = false) final Long id,
        @RequestBody ApiPermissionDTO apiPermissionDTO
    ) throws URISyntaxException {
        log.debug("REST request to partial update ApiPermission partially : {}, {}", id, apiPermissionDTO);
        if (apiPermissionDTO.getId() == null) {
            throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull");
        }
        if (!Objects.equals(id, apiPermissionDTO.getId())) {
            throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid");
        }

        if (apiPermissionRepository.findById(id).isEmpty()) {
            throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound");
        }

        Optional<ApiPermissionDTO> result = apiPermissionService.partialUpdate(apiPermissionDTO);

        return ResponseUtil.wrapOrNotFound(
            result,
            HeaderUtil.createEntityUpdateAlert(applicationName, true, ENTITY_NAME, apiPermissionDTO.getId().toString())
        );
    }

10. 新建记录接口

为JHipster原始接口实现方式,未做改动。

java
    @PostMapping("")
    @Operation(tags = "新建API权限", description = "创建并返回一个新的API权限")
    @AutoLog(value = "新建API权限", logType = LogType.OPERATE, operateType = OperateType.ADD)
    public ResponseEntity<ApiPermissionDTO> createApiPermission(@RequestBody ApiPermissionDTO apiPermissionDTO) throws URISyntaxException {
        log.debug("REST request to save ApiPermission : {}", apiPermissionDTO);
        if (apiPermissionDTO.getId() != null) {
            throw new BadRequestAlertException("A new apiPermission cannot already have an ID", ENTITY_NAME, "idexists");
        }
        ApiPermissionDTO result = apiPermissionService.save(apiPermissionDTO);
        return ResponseEntity
            .created(new URI("/api/api-permissions/" + result.getId()))
            .headers(HeaderUtil.createEntityCreationAlert(applicationName, true, ENTITY_NAME, result.getId().toString()))
            .body(result);
    }

11. 更新关联关系接口

通过相关的id进行关联维护的接口。主要提供单独关联关系维护使用,大部分关联关系可通过新建接口或更新接口处理。

这里一般通过关联关系右侧的实体进行关系维护。

java
    @PutMapping("/relations/{operateType}")
    @Operation(tags = "更新API权限关联关系", description = "根据主键更新API权限关联关系")
    @AutoLog(value = "更新API权限关联关系", logType = LogType.OPERATE, operateType = OperateType.EDIT)
    public ResponseEntity<Boolean> updateRelationships(
        @PathVariable(value = "operateType") final String operateType,
        @RequestParam(value = "otherEntityIds") ArrayList<String> otherEntityIds,
        @RequestParam(value = "relationshipName") String relationshipName,
        @RequestParam(value = "relatedIds") ArrayList<Long> relatedIds
    ) {
        log.debug("REST request to update ApiPermission : {}, {}", otherEntityIds, operateType);
        if (CollectionUtils.isEmpty(relatedIds)) {
            return ResponseEntity.ok(true);
        }
        apiPermissionService.updateRelationships(otherEntityIds, relationshipName, relatedIds, operateType);
        return ResponseEntity.ok(true);
    }

12. 排序字段更新接口

java
    @PutMapping("/sort-value/{id}/{type}")
    @Operation(tags = "更新排序字段值", description = "根据移动记录ID和插入点前后记录ID更新排序值")
    @AutoLog(value = "更新排序字段值", logType = LogType.OPERATE, operateType = OperateType.EDIT)
    public ResponseEntity<Boolean> updateSortValue(
        @PathVariable(value = "id", required = false) final Long id,
        @PathVariable(value = "type") SortValueOperateType type,
        @RequestParam(value = "beforeId", required = false) Long beforeId,
        @RequestParam(value = "afterId", required = false) Long afterId,
        @RequestParam(value = "newSortValue", required = false) Integer newSortValue,
        @RequestBody(required = false) PositionCriteria criteria
    ) {
        log.debug("REST request to update SortValue : {}, {}, {}", id, beforeId, afterId);
        if (ObjectUtils.allNull(beforeId, afterId) && !type.equals(SortValueOperateType.VALUE)) {
            throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull");
        }
        if (positionRepository.findById(id).isEmpty()) {
            throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound");
        }
        QueryWrapper<Position> queryWrapper = null;
        if (type.equals(SortValueOperateType.DROP)) {
            queryWrapper = positionQueryService.createQueryWrapper(criteria);
        }
        Boolean result = positionService.updateSortValue(id, beforeId, afterId, newSortValue, queryWrapper, type);
        return ResponseEntity.ok().body(result);
    }

13. 公开访问接口

此接口可以在baseCriteria中设置必要的限制条件。

java
    @GetMapping("/courses/public")
    @Operation(tags = "获取课程分页列表", description = "获取课程的分页列表数据")
    @AutoLog(value = "获取课程分页列表", logType = LogType.OPERATE, operateType = OperateType.LIST)
    public ResponseEntity<PageRecord<CourseDTO>> getPublicCourses(
        CourseCriteria criteria,
        @org.springdoc.core.annotations.ParameterObject Pageable pageable
    ) {
        log.debug("REST request to get Courses by criteria: {}", criteria);
        CourseCriteria baseCriteria = new CourseCriteria();
        baseCriteria.available().setEquals(true);
        baseCriteria.setAnd(criteria);

        IPage<CourseDTO> page;
        page = courseQueryService.findByCriteria(baseCriteria, PageableUtils.toPage(pageable));
        PageRecord<CourseDTO> result = new PageRecord<>();
        result.records(page.getRecords()).size(page.getSize()).total(page.getTotal()).page(page.getCurrent());
        HttpHeaders headers = IPageUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page);
        return ResponseEntity.ok().headers(headers).body(result);
    }

14. 逻辑删除相关接口

支持恢复操作(restore)、列表操作、实际删除操作、清空操作、查看详情等。

恢复接口代码:

java
    @PutMapping("/recycle-bin/restore")
    @Operation(tags = "从回收站恢复多个对象存储配置", description = "根据主键从回收站恢复多个对象存储配置")
    @AutoLog(value = "从回收站恢复多个对象存储配置", logType = LogType.OPERATE, operateType = OperateType.DELETE)
    public ResponseEntity<Void> restoreOssConfigsByIds(@RequestParam("ids") ArrayList<Long> ids) {
        log.debug("REST request to delete OssConfigs : {}", ids);
        ossConfigService.restoreByIdsInRecycleBin(ids);
        return ResponseEntity
            .noContent()
            .headers(HeaderUtil.createEntityDeletionAlert(applicationName, true, ENTITY_NAME, (ids != null ? ids.toString() : "NoIds")))
            .build();
    }