feat: add swagger annotation to api

This commit is contained in:
vran 2022-05-14 12:41:29 +08:00
parent 71ac0e521e
commit 110dd14ac7
20 changed files with 135 additions and 8 deletions

View File

@ -32,6 +32,11 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-quartz'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
// open api
implementation 'org.springdoc:springdoc-openapi-ui:1.6.8'
implementation 'io.swagger.core.v3:swagger-core:2.2.0'
implementation 'io.swagger.core.v3:swagger-annotations:2.2.0'
implementation 'org.flywaydb:flyway-core'
}

View File

@ -4,6 +4,8 @@ import com.databasir.common.JsonData;
import com.databasir.core.domain.log.data.OperationLogPageCondition;
import com.databasir.core.domain.log.data.OperationLogPageResponse;
import com.databasir.core.domain.log.service.OperationLogService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
@ -17,12 +19,14 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
@RequiredArgsConstructor
@Validated
public class OperationLogController {
@Tag(name = "AuditLogController", description = "操作日志 API")
public class AuditLogController {
private final OperationLogService operationLogService;
@GetMapping(Routes.OperationLog.LIST)
@PreAuthorize("hasAnyAuthority('SYS_OWNER')")
@Operation(summary = "查询操作日志")
public JsonData<Page<OperationLogPageResponse>> list(@PageableDefault(sort = "id", direction = Sort.Direction.DESC)
Pageable page,
OperationLogPageCondition condition) {

View File

@ -5,6 +5,8 @@ import com.databasir.common.JsonData;
import com.databasir.core.domain.database.data.*;
import com.databasir.core.domain.database.service.DatabaseTypeService;
import com.databasir.core.domain.log.annotation.AuditLog;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
@ -23,6 +25,7 @@ import static org.springframework.data.domain.Sort.Direction.DESC;
@RequiredArgsConstructor
@Validated
@RestController
@Tag(name = "DatabaseTypeController", description = "数据库类型 API")
public class DatabaseTypeController {
private final DatabaseTypeService databaseTypeService;
@ -30,11 +33,13 @@ public class DatabaseTypeController {
private final DatabaseTypeValidator databaseTypeValidator;
@GetMapping(Routes.DatabaseType.LIST_SIMPLE)
@Operation(summary = "获取所有数据库类型")
public JsonData<List<DatabaseTypeSimpleResponse>> listSimpleDatabaseTypes() {
return JsonData.ok(databaseTypeService.listSimpleDatabaseTypes());
}
@GetMapping(Routes.DatabaseType.LIST_PAGE)
@Operation(summary = "分页获取数据库类型")
public JsonData<Page<DatabaseTypePageResponse>> listPage(@PageableDefault(sort = "id", direction = DESC)
Pageable page,
DatabaseTypePageCondition condition) {
@ -45,6 +50,7 @@ public class DatabaseTypeController {
@PostMapping(Routes.DatabaseType.CREATE)
@AuditLog(module = AuditLog.Modules.DATABASE_TYPE, name = "创建数据库类型")
@PreAuthorize("hasAnyAuthority('SYS_OWNER')")
@Operation(summary = "创建数据库类型")
public JsonData<Integer> create(@RequestBody @Valid DatabaseTypeCreateRequest request) {
databaseTypeValidator.isValidUrlPattern(request.getUrlPattern());
Integer id = databaseTypeService.create(request);
@ -54,6 +60,7 @@ public class DatabaseTypeController {
@PatchMapping(Routes.DatabaseType.UPDATE)
@AuditLog(module = AuditLog.Modules.DATABASE_TYPE, name = "更新数据库类型")
@PreAuthorize("hasAnyAuthority('SYS_OWNER')")
@Operation(summary = "更新数据库类型")
public JsonData<Void> update(@RequestBody @Valid DatabaseTypeUpdateRequest request) {
databaseTypeValidator.isValidUrlPattern(request.getUrlPattern());
databaseTypeService.update(request);
@ -63,12 +70,14 @@ public class DatabaseTypeController {
@DeleteMapping(Routes.DatabaseType.DELETE_ONE)
@AuditLog(module = AuditLog.Modules.DATABASE_TYPE, name = "删除数据库类型")
@PreAuthorize("hasAnyAuthority('SYS_OWNER')")
@Operation(summary = "删除数据库类型")
public JsonData<Void> delete(@PathVariable Integer id) {
databaseTypeService.deleteById(id);
return JsonData.ok();
}
@GetMapping(Routes.DatabaseType.GET_ONE)
@Operation(summary = "获取数据库类型")
public JsonData<DatabaseTypeDetailResponse> getOne(@PathVariable Integer id) {
Optional<DatabaseTypeDetailResponse> data = databaseTypeService.selectOne(id);
return JsonData.ok(data);
@ -76,6 +85,7 @@ public class DatabaseTypeController {
@PostMapping(Routes.DatabaseType.RESOLVE_DRIVER_CLASS_NAME)
@PreAuthorize("hasAnyAuthority('SYS_OWNER')")
@Operation(summary = "解析数据库驱动类名")
public JsonData<String> resolveDriverClassName(@RequestBody @Valid DriverClassNameResolveRequest request) {
String driverClassName = databaseTypeService.resolveDriverClassName(request);
return JsonData.ok(driverClassName);
@ -83,6 +93,7 @@ public class DatabaseTypeController {
@PostMapping(Routes.DatabaseType.UPLOAD_DRIVER)
@PreAuthorize("hasAnyAuthority('SYS_OWNER')")
@Operation(summary = "上传数据库驱动")
public JsonData<String> uploadDriver(@RequestPart MultipartFile file) {
String driverPath = databaseTypeService.uploadDriver(file);
return JsonData.ok(driverPath);

View File

@ -7,6 +7,8 @@ import com.databasir.core.domain.document.generator.DocumentFileType;
import com.databasir.core.domain.document.service.DocumentService;
import com.databasir.core.domain.log.annotation.AuditLog;
import com.databasir.core.domain.project.service.ProjectService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
@ -29,6 +31,7 @@ import static org.springframework.data.domain.Sort.Direction.DESC;
@RequiredArgsConstructor
@Validated
@RestController
@Tag(name = "DocumentController", description = "数据库文档 API")
public class DocumentController {
private final DocumentService documentService;
@ -37,6 +40,7 @@ public class DocumentController {
@PostMapping(Routes.Document.SYNC_ONE)
@AuditLog(module = AuditLog.Modules.PROJECT, name = "文档同步", involvedProjectId = "#projectId")
@Operation(summary = "同步文档")
public JsonData<Integer> sync(@PathVariable Integer projectId) {
Integer userId = LoginUserContext.getLoginUserId();
Optional<Integer> taskIdOpt = projectService.createSyncTask(projectId, userId, false);
@ -44,6 +48,7 @@ public class DocumentController {
}
@GetMapping(Routes.Document.GET_ONE)
@Operation(summary = "获取文档")
public JsonData<DatabaseDocumentResponse> getByProjectId(@PathVariable Integer projectId,
@RequestParam(required = false) Long version) {
return documentService.getOneByProjectId(projectId, version)
@ -52,6 +57,7 @@ public class DocumentController {
}
@GetMapping(Routes.Document.LIST_VERSIONS)
@Operation(summary = "获取文档版本列表")
public JsonData<Page<DatabaseDocumentVersionResponse>> getVersionsByProjectId(@PathVariable Integer projectId,
@PageableDefault(sort = "id",
direction = DESC)
@ -60,6 +66,7 @@ public class DocumentController {
}
@GetMapping(Routes.Document.EXPORT)
@Operation(summary = "导出文档")
public ResponseEntity<StreamingResponseBody> getDocumentFiles(@PathVariable Integer projectId,
@RequestParam(required = false)
Long version,
@ -76,6 +83,7 @@ public class DocumentController {
}
@GetMapping(Routes.Document.GET_SIMPLE_ONE)
@Operation(summary = "获取文档(无详情信息)")
public JsonData<DatabaseDocumentSimpleResponse> getSimpleByProjectId(@PathVariable Integer projectId,
@RequestParam(required = false)
Long version,
@ -85,6 +93,7 @@ public class DocumentController {
}
@PostMapping(Routes.Document.GET_TABLE_DETAIL)
@Operation(summary = "获取表详情")
public JsonData<List<TableDocumentResponse>> getTableDocument(@PathVariable Integer projectId,
@PathVariable Integer documentId,
@RequestBody @Valid TableDocumentRequest request) {
@ -92,6 +101,7 @@ public class DocumentController {
}
@GetMapping(Routes.Document.LIST_TABLES)
@Operation(summary = "获取表列表")
public JsonData<List<TableResponse>> listTables(@PathVariable Integer projectId,
@RequestParam(required = false) Long version) {
return JsonData.ok(documentService.getTableAndColumns(projectId, version));

View File

@ -5,6 +5,8 @@ import com.databasir.common.JsonData;
import com.databasir.core.domain.description.data.DocumentDescriptionSaveRequest;
import com.databasir.core.domain.description.service.DocumentDescriptionService;
import com.databasir.core.domain.log.annotation.AuditLog;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
@ -19,6 +21,7 @@ import javax.validation.Valid;
@RestController
@Validated
@RequiredArgsConstructor
@Tag(name = "DocumentDescriptionController", description = "文档描述 API")
public class DocumentDescriptionController {
private final DocumentDescriptionService documentDescriptionService;
@ -28,6 +31,7 @@ public class DocumentDescriptionController {
@AuditLog(module = AuditLog.Modules.PROJECT,
name = "更新描述",
involvedProjectId = "#projectId")
@Operation(summary = "更新描述")
public JsonData<Void> save(@PathVariable Integer groupId,
@PathVariable Integer projectId,
@RequestBody @Valid DocumentDescriptionSaveRequest request) {

View File

@ -2,11 +2,13 @@ package com.databasir.api;
import com.databasir.api.config.security.DatabasirUserDetails;
import com.databasir.common.JsonData;
import com.databasir.core.domain.log.annotation.AuditLog;
import com.databasir.core.domain.discussion.data.DiscussionCreateRequest;
import com.databasir.core.domain.discussion.data.DiscussionListCondition;
import com.databasir.core.domain.discussion.data.DiscussionResponse;
import com.databasir.core.domain.discussion.service.DocumentDiscussionService;
import com.databasir.core.domain.log.annotation.AuditLog;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
@ -22,11 +24,13 @@ import javax.validation.Valid;
@RestController
@Validated
@RequiredArgsConstructor
@Tag(name = "DocumentDiscussionController", description = "文档讨论 API")
public class DocumentDiscussionController {
private final DocumentDiscussionService documentDiscussionService;
@GetMapping(Routes.DocumentDiscussion.LIST)
@Operation(summary = "获取文档评论列表")
public JsonData<Page<DiscussionResponse>> listByProjectId(@PathVariable Integer groupId,
@PathVariable Integer projectId,
@PageableDefault(sort = "id",
@ -42,6 +46,7 @@ public class DocumentDiscussionController {
@AuditLog(module = AuditLog.Modules.PROJECT,
name = "删除评论",
involvedProjectId = "#projectId")
@Operation(summary = "删除评论")
public JsonData<Void> delete(@PathVariable Integer groupId,
@PathVariable Integer projectId,
@PathVariable Integer discussionId) {
@ -54,6 +59,7 @@ public class DocumentDiscussionController {
@AuditLog(module = AuditLog.Modules.PROJECT,
name = "新增评论",
involvedProjectId = "#projectId")
@Operation(summary = "新增评论")
public JsonData<Void> create(@PathVariable Integer groupId,
@PathVariable Integer projectId,
@RequestBody @Valid DiscussionCreateRequest request) {

View File

@ -5,6 +5,8 @@ import com.databasir.core.domain.document.data.DocumentTemplatePropertiesRespons
import com.databasir.core.domain.document.data.DocumentTemplatePropertiesUpdateRequest;
import com.databasir.core.domain.document.service.DocumentTemplateService;
import com.databasir.core.domain.log.annotation.AuditLog;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
@ -18,11 +20,13 @@ import javax.validation.Valid;
@RequiredArgsConstructor
@Validated
@RestController
@Tag(name = "DocumentTemplateController", description = "文档模板 API")
public class DocumentTemplateController {
private final DocumentTemplateService documentTemplateService;
@GetMapping(Routes.DocumentTemplateProperty.API)
@Operation(summary = "获取模板属性")
public JsonData<DocumentTemplatePropertiesResponse> getAllProperties() {
return JsonData.ok(documentTemplateService.getAllProperties());
}
@ -30,6 +34,7 @@ public class DocumentTemplateController {
@PatchMapping(Routes.DocumentTemplateProperty.API)
@PreAuthorize("hasAnyAuthority('SYS_OWNER')")
@AuditLog(module = AuditLog.Modules.SETTING, name = "更新模板")
@Operation(summary = "更新模板属性")
public JsonData<Void> updateByType(@RequestBody @Valid DocumentTemplatePropertiesUpdateRequest request) {
documentTemplateService.updateByType(request);
return JsonData.ok();

View File

@ -5,6 +5,8 @@ import com.databasir.common.JsonData;
import com.databasir.core.domain.group.data.*;
import com.databasir.core.domain.group.service.GroupService;
import com.databasir.core.domain.log.annotation.AuditLog;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
@ -24,6 +26,7 @@ import static org.springframework.data.domain.Sort.Direction.DESC;
@RestController
@RequiredArgsConstructor
@Validated
@Tag(name = "GroupController", description = "分组 API")
public class GroupController {
private final GroupService groupService;
@ -33,6 +36,7 @@ public class GroupController {
@PostMapping(Routes.Group.CREATE)
@PreAuthorize("hasAnyAuthority('SYS_OWNER')")
@AuditLog(module = AuditLog.Modules.GROUP, name = "创建分组")
@Operation(summary = "创建分组")
public JsonData<Void> create(@RequestBody @Valid GroupCreateRequest request) {
groupService.create(request);
return JsonData.ok();
@ -43,12 +47,14 @@ public class GroupController {
@AuditLog(module = AuditLog.Modules.GROUP,
name = "更新分组",
involvedGroupId = "#request.id")
@Operation(summary = "更新分组")
public JsonData<Void> update(@RequestBody @Valid GroupUpdateRequest request) {
groupService.update(request);
return JsonData.ok();
}
@GetMapping(Routes.Group.LIST)
@Operation(summary = "分页查询分组")
public JsonData<Page<GroupPageResponse>> list(@PageableDefault(sort = "id", direction = DESC)
Pageable page,
GroupPageCondition condition) {
@ -60,17 +66,20 @@ public class GroupController {
@AuditLog(module = AuditLog.Modules.GROUP,
name = "删除分组",
involvedGroupId = "#groupId")
@Operation(summary = "删除分组")
public JsonData<Void> deleteById(@PathVariable Integer groupId) {
groupService.delete(groupId);
return JsonData.ok();
}
@GetMapping(Routes.Group.GET_ONE)
@Operation(summary = "查询分组")
public JsonData<GroupResponse> getOne(@PathVariable Integer groupId) {
return JsonData.ok(groupService.get(groupId));
}
@GetMapping(Routes.Group.MEMBERS)
@Operation(summary = "查询分组成员")
public JsonData<Page<GroupMemberPageResponse>> listGroupMembers(@PathVariable Integer groupId,
@PageableDefault(sort = "user_role.create_at",
direction = DESC)
@ -85,6 +94,7 @@ public class GroupController {
name = "添加组员",
involvedGroupId = "#groupId",
involvedUserId = "#request.userId")
@Operation(summary = "添加组员")
public JsonData<Void> addGroupMember(@PathVariable Integer groupId,
@RequestBody @Valid GroupMemberCreateRequest request) {
userOperationValidator.forbiddenIfUpdateSelfRole(request.getUserId());
@ -102,6 +112,7 @@ public class GroupController {
name = "移除组员",
involvedGroupId = "#groupId",
involvedUserId = "#userId")
@Operation(summary = "移除组员")
public JsonData<Void> removeGroupMember(@PathVariable Integer groupId,
@PathVariable Integer userId) {
userOperationValidator.forbiddenIfUpdateSelfRole(userId);
@ -115,6 +126,7 @@ public class GroupController {
name = "更新组员角色",
involvedGroupId = "#groupId",
involvedUserId = "#userId")
@Operation(summary = "更新组员角色")
public JsonData<Void> updateGroupMemberRole(@PathVariable Integer groupId,
@PathVariable Integer userId,
@RequestBody GroupMemberRoleUpdateRequest request) {

View File

@ -1,6 +1,8 @@
package com.databasir.api;
import com.databasir.common.JsonData;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@ -8,10 +10,12 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
@Controller
@Tag(name = "IndexController", description = "测活 API")
public class IndexController {
@GetMapping("/live")
@ResponseBody
@Operation(summary = "测活")
public JsonData<String> live() {
return JsonData.ok("ok");
}
@ -22,6 +26,7 @@ public class IndexController {
}
@ResponseStatus(HttpStatus.NOT_FOUND)
@Operation(summary = "404 统一跳转")
public String handleResourceNotFoundException() {
return "/index.html";
}

View File

@ -5,12 +5,15 @@ import com.databasir.core.domain.app.OpenAuthAppService;
import com.databasir.core.domain.app.data.*;
import com.databasir.core.domain.app.handler.OpenAuthHandlers;
import com.databasir.core.domain.log.annotation.AuditLog;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
@ -22,6 +25,8 @@ import static org.springframework.data.domain.Sort.Direction.DESC;
@Controller
@RequiredArgsConstructor
@Validated
@Tag(name = "LoginAppController", description = "OAuth2 应用 API")
public class LoginAppController {
private final OpenAuthAppService openAuthAppService;
@ -33,6 +38,7 @@ public class LoginAppController {
*/
@GetMapping("/oauth2/apps")
@ResponseBody
@Operation(summary = "获取登录应用")
public JsonData<List<OAuthAppResponse>> listApps() {
return JsonData.ok(openAuthAppService.listAll());
}
@ -42,6 +48,7 @@ public class LoginAppController {
*/
@GetMapping("/oauth2/authorization/{registrationId}")
@ResponseBody
@Operation(summary = "OAuth2 授权回调")
public JsonData<String> authorization(@PathVariable String registrationId,
HttpServletRequest request) {
Map<String, String[]> parameters = request.getParameterMap();
@ -52,6 +59,7 @@ public class LoginAppController {
@GetMapping(Routes.OAuth2App.LIST_PAGE)
@PreAuthorize("hasAnyAuthority('SYS_OWNER')")
@ResponseBody
@Operation(summary = "分页查询登录应用")
public JsonData<Page<OAuthAppPageResponse>> listPage(@PageableDefault(sort = "id", direction = DESC)
Pageable page,
OAuthAppPageCondition condition) {
@ -61,6 +69,7 @@ public class LoginAppController {
@GetMapping(Routes.OAuth2App.GET_ONE)
@PreAuthorize("hasAnyAuthority('SYS_OWNER')")
@ResponseBody
@Operation(summary = "查询登录应用详情")
public JsonData<OAuthAppDetailResponse> getOne(@PathVariable Integer id) {
return JsonData.ok(openAuthAppService.getOne(id));
@ -70,6 +79,7 @@ public class LoginAppController {
@PreAuthorize("hasAnyAuthority('SYS_OWNER')")
@ResponseBody
@AuditLog(module = AuditLog.Modules.LOGIN_APP, name = "创建登录应用")
@Operation(summary = "创建登录应用")
public JsonData<Integer> create(@RequestBody @Valid OAuthAppCreateRequest request) {
Integer id = openAuthAppService.create(request);
return JsonData.ok(id);
@ -79,6 +89,7 @@ public class LoginAppController {
@PreAuthorize("hasAnyAuthority('SYS_OWNER')")
@ResponseBody
@AuditLog(module = AuditLog.Modules.LOGIN_APP, name = "更新登录应用")
@Operation(summary = "更新登录应用")
public JsonData<Void> updateById(@RequestBody @Valid OAuthAppUpdateRequest request) {
openAuthAppService.updateById(request);
return JsonData.ok();
@ -88,6 +99,7 @@ public class LoginAppController {
@PreAuthorize("hasAnyAuthority('SYS_OWNER')")
@ResponseBody
@AuditLog(module = AuditLog.Modules.LOGIN_APP, name = "删除登录应用")
@Operation(summary = "删除登录应用")
public JsonData<Void> deleteById(@PathVariable Integer id) {
openAuthAppService.deleteById(id);
return JsonData.ok();

View File

@ -10,6 +10,8 @@ import com.databasir.core.domain.login.data.AccessTokenRefreshRequest;
import com.databasir.core.domain.login.data.AccessTokenRefreshResponse;
import com.databasir.core.domain.login.data.UserLoginResponse;
import com.databasir.core.domain.login.service.LoginService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.context.SecurityContextHolder;
@ -26,18 +28,21 @@ import java.util.Objects;
@RequiredArgsConstructor
@Validated
@Slf4j
@Tag(name = "LoginController", description = "登录 API")
public class LoginController {
private final LoginService loginService;
@GetMapping(Routes.Login.LOGOUT)
@AuditLog(module = AuditLog.Modules.USER, name = "注销登录")
@Operation(summary = "注销登录")
public JsonData<Void> logout() {
SecurityContextHolder.clearContext();
return JsonData.ok();
}
@PostMapping(Routes.Login.REFRESH_ACCESS_TOKEN)
@Operation(summary = "刷新 Access Token")
public JsonData<AccessTokenRefreshResponse> refreshAccessTokens(@RequestBody
@Valid AccessTokenRefreshRequest request) {
try {
@ -54,6 +59,7 @@ public class LoginController {
}
@GetMapping(Routes.Login.LOGIN_INFO)
@Operation(summary = "获取登录信息")
public JsonData<UserLoginResponse> getUserLoginData() {
DatabasirUserDetails user = (DatabasirUserDetails) SecurityContextHolder.getContext()
.getAuthentication()

View File

@ -6,6 +6,8 @@ import com.databasir.core.domain.mock.data.ColumnMockRuleSaveRequest;
import com.databasir.core.domain.mock.data.MockDataGenerateCondition;
import com.databasir.core.domain.mock.data.MockDataRuleListCondition;
import com.databasir.core.domain.mock.data.MockDataRuleResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
@ -17,11 +19,13 @@ import java.util.List;
@RestController
@RequiredArgsConstructor
@Validated
@Tag(name = "MockDataController", description = "MOCK SQL API")
public class MockDataController {
private final MockDataService mockDataService;
@GetMapping(Routes.MockData.GET_SQL_MOCK_DATA)
@Operation(summary = "获取 Mock Insert SQL")
public JsonData<String> getMockSql(@PathVariable("groupId") Integer groupId,
@PathVariable("projectId") Integer projectId,
@Valid MockDataGenerateCondition condition) {
@ -30,6 +34,7 @@ public class MockDataController {
}
@GetMapping(Routes.MockData.GET_MOCK_RULE)
@Operation(summary = "获取 Mock Rule")
public JsonData<List<MockDataRuleResponse>> getMockRules(@PathVariable("groupId") Integer groupId,
@PathVariable("projectId") Integer projectId,
@Valid MockDataRuleListCondition condition) {
@ -39,6 +44,7 @@ public class MockDataController {
@PostMapping(Routes.MockData.SAVE_MOCK_RULE)
@PreAuthorize("hasAnyAuthority('SYS_OWNER', 'GROUP_OWNER?groupId='+#groupId, 'GROUP_MEMBER?groupId='+#groupId)")
@Operation(summary = "保存 Mock Rule")
public JsonData<Void> saveMockRules(@PathVariable Integer groupId,
@PathVariable Integer projectId,
@PathVariable Integer tableId,

View File

@ -8,6 +8,8 @@ import com.databasir.core.domain.project.data.*;
import com.databasir.core.domain.project.data.task.ProjectSimpleTaskResponse;
import com.databasir.core.domain.project.data.task.ProjectTaskListCondition;
import com.databasir.core.domain.project.service.ProjectService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
@ -24,6 +26,7 @@ import java.util.List;
@RestController
@RequiredArgsConstructor
@Validated
@Tag(name = "ProjectController", description = "项目 API")
public class ProjectController {
private final ProjectService projectService;
@ -36,6 +39,7 @@ public class ProjectController {
@AuditLog(module = AuditLog.Modules.PROJECT,
name = "创建项目",
involvedGroupId = "#request.groupId")
@Operation(summary = "创建项目")
public JsonData<Void> create(@RequestBody @Valid ProjectCreateRequest request) {
cronExpressionValidator.isValidCron(request);
projectService.create(request);
@ -48,6 +52,7 @@ public class ProjectController {
name = "更新项目",
involvedGroupId = "#groupId",
involvedProjectId = "#request.id")
@Operation(summary = "更新项目")
public JsonData<Void> update(@RequestBody @Valid ProjectUpdateRequest request,
@PathVariable Integer groupId) {
cronExpressionValidator.isValidCron(request);
@ -61,6 +66,7 @@ public class ProjectController {
name = "删除项目",
involvedGroupId = "#groupId",
involvedProjectId = "#projectId")
@Operation(summary = "删除项目")
public JsonData<Void> delete(@PathVariable Integer groupId,
@PathVariable Integer projectId) {
projectService.delete(projectId);
@ -68,11 +74,13 @@ public class ProjectController {
}
@GetMapping(Routes.GroupProject.GET_ONE)
@Operation(summary = "获取项目详情")
public JsonData<ProjectDetailResponse> getOne(@PathVariable Integer projectId) {
return JsonData.ok(projectService.getOne(projectId));
}
@GetMapping(Routes.GroupProject.LIST)
@Operation(summary = "获取项目列表")
public JsonData<Page<ProjectSimpleResponse>> list(@PageableDefault(sort = "id", direction = Sort.Direction.DESC)
Pageable page,
ProjectListCondition condition) {
@ -84,18 +92,21 @@ public class ProjectController {
}
@PostMapping(Routes.GroupProject.TEST_CONNECTION)
@Operation(summary = "测试连接")
public JsonData<Void> testConnection(@RequestBody @Valid ProjectTestConnectionRequest request) {
projectService.testConnection(request);
return JsonData.ok();
}
@PostMapping(Routes.GroupProject.LIST_MANUAL_TASKS)
@Operation(summary = "获取同步任务列表")
public JsonData<List<ProjectSimpleTaskResponse>> listManualTasks(@PathVariable Integer projectId,
@RequestBody ProjectTaskListCondition condition) {
return JsonData.ok(projectService.listManualTasks(projectId, condition));
}
@PatchMapping(Routes.GroupProject.CANCEL_MANUAL_TASK)
@Operation(summary = "取消同步任务")
public JsonData<Void> cancelTask(@PathVariable Integer projectId,
@PathVariable Integer taskId) {
projectService.cancelTask(projectId, taskId);

View File

@ -5,6 +5,8 @@ import com.databasir.core.domain.log.annotation.AuditLog;
import com.databasir.core.domain.system.data.SystemEmailResponse;
import com.databasir.core.domain.system.data.SystemEmailUpdateRequest;
import com.databasir.core.domain.system.service.SystemService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
@ -16,11 +18,13 @@ import javax.validation.Valid;
@RequiredArgsConstructor
@Validated
@PreAuthorize("hasAnyAuthority('SYS_OWNER')")
@Tag(name = "SettingController", description = "系统设置 API")
public class SettingController {
private final SystemService systemService;
@GetMapping(Routes.Setting.GET_SYS_EMAIL)
@Operation(summary = "获取系统邮箱配置")
public JsonData<SystemEmailResponse> getSystemEmailSetting() {
return systemService.getEmailSetting()
.map(JsonData::ok)
@ -29,6 +33,7 @@ public class SettingController {
@DeleteMapping(Routes.Setting.DELETE_SYS_EMAIL)
@AuditLog(module = AuditLog.Modules.SETTING, name = "重置系统邮箱")
@Operation(summary = "重置系统邮箱")
public JsonData<Void> deleteSysEmail() {
systemService.deleteSystemEmail();
return JsonData.ok();
@ -36,6 +41,7 @@ public class SettingController {
@PostMapping(Routes.Setting.UPDATE_SYS_EMAIL)
@AuditLog(module = AuditLog.Modules.SETTING, name = "更新邮件配置")
@Operation(summary = "更新邮件配置")
public JsonData<Void> updateSystemEmailSetting(@RequestBody @Valid SystemEmailUpdateRequest request) {
systemService.updateEmailSetting(request);
return JsonData.ok();

View File

@ -8,6 +8,8 @@ import com.databasir.core.domain.DomainErrors;
import com.databasir.core.domain.log.annotation.AuditLog;
import com.databasir.core.domain.user.data.*;
import com.databasir.core.domain.user.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
@ -22,6 +24,7 @@ import javax.validation.Valid;
@RestController
@RequiredArgsConstructor
@Validated
@Tag(name = "UserController", description = "用户 API")
public class UserController {
private final UserService userService;
@ -29,6 +32,7 @@ public class UserController {
private final UserOperationValidator userOperationValidator;
@GetMapping(Routes.User.LIST)
@Operation(summary = "分页查询用户")
public JsonData<Page<UserPageResponse>> list(@PageableDefault(sort = "id", direction = Sort.Direction.DESC)
Pageable pageable,
UserPageCondition condition) {
@ -38,6 +42,7 @@ public class UserController {
@PostMapping(Routes.User.DISABLE)
@PreAuthorize("hasAnyAuthority('SYS_OWNER')")
@AuditLog(module = AuditLog.Modules.USER, name = "禁用用户", involvedUserId = "#userId")
@Operation(summary = "禁用用户")
public JsonData<Void> disableUser(@PathVariable Integer userId) {
if (userOperationValidator.isMyself(userId)) {
throw DomainErrors.CANNOT_UPDATE_SELF_ENABLED_STATUS.exception();
@ -49,6 +54,7 @@ public class UserController {
@PostMapping(Routes.User.ENABLE)
@PreAuthorize("hasAnyAuthority('SYS_OWNER')")
@AuditLog(module = AuditLog.Modules.USER, name = "启用用户", involvedUserId = "#userId")
@Operation(summary = "启用用户")
public JsonData<Void> enableUser(@PathVariable Integer userId) {
if (userOperationValidator.isMyself(userId)) {
throw DomainErrors.CANNOT_UPDATE_SELF_ENABLED_STATUS.exception();
@ -60,18 +66,21 @@ public class UserController {
@PostMapping(Routes.User.CREATE)
@PreAuthorize("hasAnyAuthority('SYS_OWNER')")
@AuditLog(module = AuditLog.Modules.USER, name = "创建用户")
@Operation(summary = "创建用户")
public JsonData<Void> create(@RequestBody @Valid UserCreateRequest request) {
userService.create(request, UserSource.MANUAL);
return JsonData.ok();
}
@GetMapping(Routes.User.GET_ONE)
@Operation(summary = "根据 ID 查询用户")
public JsonData<UserDetailResponse> getOne(@PathVariable Integer userId) {
return JsonData.ok(userService.get(userId));
}
@DeleteMapping(Routes.User.DELETE_ONE)
@PreAuthorize("hasAnyAuthority('SYS_OWNER')")
@Operation(summary = "根据 ID 删除用户")
public JsonData<Void> deleteOne(@PathVariable Integer userId) {
if (userOperationValidator.isMyself(userId)) {
throw DomainErrors.CANNOT_DELETE_SELF.exception();
@ -83,6 +92,7 @@ public class UserController {
@PostMapping(Routes.User.RENEW_PASSWORD)
@PreAuthorize("hasAnyAuthority('SYS_OWNER')")
@AuditLog(module = AuditLog.Modules.USER, name = "重置用户密码", involvedUserId = "#userId")
@Operation(summary = "重置用户密码")
public JsonData<Void> renewPassword(@PathVariable Integer userId) {
Integer operatorUserId = LoginUserContext.getLoginUserId();
userService.renewPassword(operatorUserId, userId);
@ -92,6 +102,7 @@ public class UserController {
@PostMapping(Routes.User.ADD_OR_REMOVE_SYS_OWNER)
@PreAuthorize("hasAnyAuthority('SYS_OWNER')")
@AuditLog(module = AuditLog.Modules.USER, name = "添加系统管理员", involvedUserId = "#userId")
@Operation(summary = "添加系统管理员")
public JsonData<Void> addSysOwner(@PathVariable Integer userId) {
userOperationValidator.forbiddenIfUpdateSelfRole(userId);
userService.addSysOwnerTo(userId);
@ -101,6 +112,7 @@ public class UserController {
@DeleteMapping(Routes.User.ADD_OR_REMOVE_SYS_OWNER)
@PreAuthorize("hasAnyAuthority('SYS_OWNER')")
@AuditLog(module = AuditLog.Modules.USER, name = "移除系统管理员", involvedUserId = "#userId")
@Operation(summary = "移除系统管理员")
public JsonData<Void> removeSysOwner(@PathVariable Integer userId) {
userOperationValidator.forbiddenIfUpdateSelfRole(userId);
userService.removeSysOwnerFrom(userId);
@ -109,6 +121,7 @@ public class UserController {
@PostMapping(Routes.User.UPDATE_PASSWORD)
@AuditLog(module = AuditLog.Modules.USER, name = "更新密码", involvedUserId = "#userId")
@Operation(summary = "更新密码")
public JsonData<Void> updatePassword(@PathVariable Integer userId,
@RequestBody @Valid UserPasswordUpdateRequest request) {
if (userOperationValidator.isMyself(userId)) {
@ -121,6 +134,7 @@ public class UserController {
@PostMapping(Routes.User.UPDATE_NICKNAME)
@AuditLog(module = AuditLog.Modules.USER, name = "更新昵称", involvedUserId = "#userId")
@Operation(summary = "更新昵称")
public JsonData<Void> updateNickname(@PathVariable Integer userId,
@RequestBody @Valid UserNicknameUpdateRequest request) {
if (userOperationValidator.isMyself(userId)) {

View File

@ -5,6 +5,8 @@ import com.databasir.common.JsonData;
import com.databasir.core.domain.user.data.FavoriteProjectPageCondition;
import com.databasir.core.domain.user.data.FavoriteProjectPageResponse;
import com.databasir.core.domain.user.service.UserProjectService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
@ -18,11 +20,13 @@ import static org.springframework.data.domain.Sort.Direction.DESC;
@RestController
@RequiredArgsConstructor
@Validated
@Tag(name = "UserProjectController", description = "用户关注项目 API")
public class UserProjectController {
private final UserProjectService userProjectService;
@GetMapping(Routes.UserProject.LIST)
@Operation(summary = "获取用户关注项目列表")
public JsonData<Page<FavoriteProjectPageResponse>> listFavorites(
@PageableDefault(sort = "id", direction = DESC) Pageable pageable,
FavoriteProjectPageCondition condition) {
@ -34,6 +38,7 @@ public class UserProjectController {
}
@PostMapping(Routes.UserProject.ADD)
@Operation(summary = "添加用户关注项目")
public JsonData<Void> addFavorite(@PathVariable Integer projectId) {
DatabasirUserDetails user = (DatabasirUserDetails) SecurityContextHolder.getContext()
.getAuthentication()
@ -44,6 +49,7 @@ public class UserProjectController {
}
@DeleteMapping(Routes.UserProject.REMOVE)
@Operation(summary = "删除用户关注项目")
public JsonData<Void> removeFavorite(@PathVariable Integer projectId) {
DatabasirUserDetails user = (DatabasirUserDetails) SecurityContextHolder.getContext()
.getAuthentication()

View File

@ -1,6 +1,7 @@
server.port=8080
logging.level.org.jooq=INFO
spring.jooq.sql-dialect=mysql
springdoc.swagger-ui.path=/open-api.html
# flyway
spring.flyway.enabled=true
spring.flyway.baseline-on-migrate=true

View File

@ -15,3 +15,5 @@ spring.flyway.locations=classpath:db/migration
# driver directory
databasir.db.driver-directory=drivers
databasir.jwt.secret=${DATABASIR_JWT_SECRET:${random.uuid}}
# api doc
springdoc.api-docs.enabled=false

View File

@ -39,6 +39,7 @@ subprojects {
freemarkerVersion = '2.3.31'
retrofitVersion = '2.9.0'
commonsIoVersion = '2.11.0'
springDocVersion = '1.6.8'
}
dependencies {

@ -1 +1 @@
Subproject commit db483af6ed4b2b1571f756403b52158b123e6023
Subproject commit 2de726a650c5ea6641a175090220ec19bafe8296