基础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 最终效果:
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();
}