From 64e4a7dfec7b8e10e01c032669b22fdc33f2f0bd Mon Sep 17 00:00:00 2001 From: ArgonarioD Date: Fri, 8 Jul 2022 12:38:26 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E4=BA=86=E5=85=A8=E5=B1=80?= =?UTF-8?q?=E6=9D=83=E9=99=90=EF=BC=88=E6=9C=AA=E8=AF=A6=E7=BB=86=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=EF=BC=89=EF=BC=8C=E8=A7=84=E8=8C=83=E4=BA=86=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../advice/ExceptionHandlerAdvice.java | 18 ++++- .../AdditionalFunctionsController.java | 38 ----------- .../controller/AnnouncementController.java | 19 +++--- .../controller/ProjectController.java | 27 ++++---- .../controller/ProjectGroupController.java | 28 ++++---- .../controller/ProjectTypeController.java | 5 +- .../controller/StaffController.java | 27 ++++++-- .../controller/TaskController.java | 22 +++--- .../projectmanagement/entity/Staff.java | 1 + .../rmdjzz/projectmanagement/entity/Task.java | 33 +++++---- .../entity/dto/ProjectDTO.java | 1 - .../exception/BadRequestException.java | 4 ++ .../exception/ForbiddenException.java | 3 + .../exception/TokenException.java | 1 - .../service/IProjectGroupService.java | 6 +- .../service/IProjectService.java | 7 +- .../service/IProjectTypeService.java | 2 +- .../service/IStaffService.java | 5 +- .../service/ITaskService.java | 6 +- .../service/impl/AnnouncementServiceImpl.java | 17 +++-- .../service/impl/ProjectGroupServiceImpl.java | 29 ++++---- .../service/impl/ProjectServiceImpl.java | 39 +++++------ .../service/impl/ProjectTypeServiceImpl.java | 2 +- .../service/impl/StaffServiceImpl.java | 20 ++++-- .../service/impl/TaskServiceImpl.java | 67 ++++++++++--------- .../projectmanagement/utils/MapBuilder.java | 26 +++++++ .../projectmanagement/utils/TokenUtils.java | 22 +++--- .../utils/http/IResponse.java | 10 +++ .../utils/http/ResponseList.java | 15 ++++- .../utils/http/ResponseMap.java | 10 ++- src/main/resources/mapper/ProjectMapper.xml | 5 +- .../projectmanagement/MybatisPlusTests.java | 2 +- 32 files changed, 302 insertions(+), 215 deletions(-) delete mode 100644 src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/AdditionalFunctionsController.java create mode 100644 src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/MapBuilder.java create mode 100644 src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/http/IResponse.java diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/advice/ExceptionHandlerAdvice.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/advice/ExceptionHandlerAdvice.java index 3cdf852..c4ca39e 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/advice/ExceptionHandlerAdvice.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/advice/ExceptionHandlerAdvice.java @@ -5,11 +5,15 @@ import cn.edu.hfut.rmdjzz.projectmanagement.exception.ForbiddenException; import cn.edu.hfut.rmdjzz.projectmanagement.exception.UnauthorizedException; import cn.edu.hfut.rmdjzz.projectmanagement.utils.http.ResponseMap; import lombok.extern.slf4j.Slf4j; +import org.springframework.context.support.DefaultMessageSourceResolvable; import org.springframework.http.HttpStatus; +import org.springframework.validation.BindException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; +import java.util.stream.Collectors; + /** * @author 佘语殊 * @since 2022/6/29 1:00 @@ -21,14 +25,14 @@ public class ExceptionHandlerAdvice { @ResponseStatus(HttpStatus.UNAUTHORIZED) public ResponseMap handleUnauthorizedException(Exception e) { // log.error(ExceptionUtils.getStackTrace(e)); - log.error(e.getMessage()); + // log.error(e.getMessage()); return ResponseMap.of(HttpStatus.UNAUTHORIZED.value(), e.getMessage()); } @ExceptionHandler(BadRequestException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public ResponseMap handleBadRequestException(BadRequestException e) { - log.error(e.getMessage()); + // log.error(e.getMessage()); return ResponseMap.of(HttpStatus.BAD_REQUEST.value(), e.getMessage()); } @@ -37,4 +41,14 @@ public class ExceptionHandlerAdvice { public ResponseMap handleForbiddenException(ForbiddenException e) { return ResponseMap.of(HttpStatus.FORBIDDEN.value(), e.getMessage()); } + + @ExceptionHandler(BindException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ResponseMap handleBindException(BindException e) { + return ResponseMap.of(HttpStatus.BAD_REQUEST.value(), + e.getAllErrors().stream() + .map(DefaultMessageSourceResolvable::getDefaultMessage) + .collect(Collectors.joining(",")) + ); + } } diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/AdditionalFunctionsController.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/AdditionalFunctionsController.java deleted file mode 100644 index 2de659d..0000000 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/AdditionalFunctionsController.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.edu.hfut.rmdjzz.projectmanagement.controller; - -import cn.edu.hfut.rmdjzz.projectmanagement.exception.BadRequestException; -import cn.edu.hfut.rmdjzz.projectmanagement.service.IStaffService; -import cn.edu.hfut.rmdjzz.projectmanagement.utils.http.ResponseMap; -import lombok.SneakyThrows; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; - -import java.util.Objects; - -/** - * @author 张韬 - * created at 2022/7/7 17:08 - */ -@RestController -public class AdditionalFunctionsController { - @Autowired - private IStaffService staffService; - @SneakyThrows - @PostMapping(value = "/staff/import") - public ResponseMap upload(@RequestHeader("Token") String token, @RequestParam("uploadFile") MultipartFile uploadFile){ - if (null == uploadFile) { - throw new BadRequestException("空的文件参数"); - } - String fileName = Objects.requireNonNull(uploadFile.getOriginalFilename()).toLowerCase(); - if (!fileName.endsWith(".xlsx")) { - throw new BadRequestException("文件类型错误"); - } - Integer successCount=staffService.multiImport(token,uploadFile); - return ResponseMap.ofSuccess("成功导入"+successCount+"条数据"); - } - -} diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/AnnouncementController.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/AnnouncementController.java index 2ec330c..9954183 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/AnnouncementController.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/AnnouncementController.java @@ -6,7 +6,6 @@ import cn.edu.hfut.rmdjzz.projectmanagement.exception.BadRequestException; import cn.edu.hfut.rmdjzz.projectmanagement.exception.ForbiddenException; import cn.edu.hfut.rmdjzz.projectmanagement.service.IAnnouncementService; import cn.edu.hfut.rmdjzz.projectmanagement.service.IProjectGroupService; -import cn.edu.hfut.rmdjzz.projectmanagement.service.IProjectService; import cn.edu.hfut.rmdjzz.projectmanagement.utils.TokenUtils; import cn.edu.hfut.rmdjzz.projectmanagement.utils.http.ResponseList; import cn.edu.hfut.rmdjzz.projectmanagement.utils.http.ResponseMap; @@ -32,9 +31,9 @@ public class AnnouncementController { @GetMapping public ResponseList getAnnouncementList(@RequestHeader("Token") String token, @PathVariable Integer projectId) { if (projectGroupService.getProjectAccessLevel(token, projectId) == 0) { - throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS); + throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS_PROJECT); } - return ResponseList.ofSuccess("查询成功", announcementService.getAnnouncementList(projectId)); + return ResponseList.ofSuccess(announcementService.getAnnouncementList(projectId)); } @SneakyThrows @@ -45,9 +44,9 @@ public class AnnouncementController { @PathVariable Long announcementId ) { if (projectGroupService.getProjectAccessLevel(token, projectId) == 0) { - throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS); + throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS_PROJECT); } - return ResponseMap.ofSuccess("查询成功", announcementService.getAnnouncementById(announcementId)); + return ResponseMap.ofSuccess(announcementService.getAnnouncementById(announcementId)); } @SneakyThrows @@ -59,15 +58,15 @@ public class AnnouncementController { ) { Integer accessLevel = projectGroupService.getProjectAccessLevel(token, projectId); if (accessLevel == 0 || accessLevel > 2) { - throw new ForbiddenException("无该操作权限"); + throw new ForbiddenException(ForbiddenException.UNABLE_TO_OPERATE); } announcement.setProjectId(projectId); announcement.setAnnouncementPublisherId(TokenUtils.getStaffId(token)); announcement.setAnnouncementPublishTime(null); if (announcementService.save(announcement)) { - return ResponseMap.ofSuccess("创建成功"); + return ResponseMap.ofSuccess(); } - throw new BadRequestException("创建失败"); + throw new BadRequestException(BadRequestException.OPERATE_FAILED); } // 取消功能 @@ -94,9 +93,9 @@ public class AnnouncementController { @PathVariable Long announcementId ) { if (announcementService.deleteAnnouncement(token, projectId, announcementId)) { - return ResponseMap.ofSuccess("删除成功"); + return ResponseMap.ofSuccess(); } - throw new BadRequestException("删除失败"); + throw new BadRequestException(BadRequestException.OPERATE_FAILED); } } diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/ProjectController.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/ProjectController.java index a17edd0..8a550d9 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/ProjectController.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/ProjectController.java @@ -40,27 +40,27 @@ public class ProjectController { @Parameter(description = "参数列表见Project实体类,时间可以用xxxxStart与xxxxEnd来确定区间" , required = true) @RequestParam("paramMap") Map paramMap ) { - Page result = projectService.getOnePageProject(token, page, paramMap); - return ResponseList.ofSuccess("成功返回列表", result); + Page result = projectService.pageMyProjects(token, page, paramMap); + return ResponseList.ofSuccess(result); } @SneakyThrows @GetMapping("/{projectId}") - public ResponseMap getOneProject( + public ResponseMap getOneProjectBasicInfo( @RequestHeader("Token") String token, @PathVariable("projectId") Integer projectId ) { if (projectGroupService.getProjectAccessLevel(token, projectId) == 0) { - throw new BadRequestException("请求参数错误"); + throw new BadRequestException(BadRequestException.WRONG_PARAMETERS); } - return ResponseMap.ofSuccess("查询成功", projectService.getById(projectId)); + return ResponseMap.ofSuccess(projectService.getById(projectId)); } @Operation(description = "根据Token获取该员工的Project数") @SneakyThrows @GetMapping("/count") public ResponseMap getProjectNumOfStaff(@RequestHeader("Token") String token) { - return ResponseMap.ofSuccess("查询成功") + return ResponseMap.ofSuccess() .put("totalNum", projectService.countMyProjects(token)); } @@ -68,18 +68,19 @@ public class ProjectController { @PostMapping("/complete") public ResponseMap completeProject( @RequestHeader("Token") String token, + @Parameter(description = "只需要传projectId即可,例:{\"projectId\": 1}") @RequestBody Map map ) { Integer targetProjectId = (Integer) map.get("projectId"); projectService.setProjectCompleted(token, targetProjectId); - return ResponseMap.ofSuccess("操作成功"); + return ResponseMap.ofSuccess(); } @SneakyThrows @PostMapping public ResponseMap createProject(@RequestHeader("Token") String token, @RequestBody Project project) { projectService.createProject(token, project); - return ResponseMap.ofSuccess("操作成功"); + return ResponseMap.ofSuccess(); } @SneakyThrows @@ -91,17 +92,17 @@ public class ProjectController { ) { project.setProjectId(projectId); if (!projectService.checkOpenStatus(projectId)) - throw new BadRequestException("项目未开放"); + throw new BadRequestException(IProjectService.PROJECT_UNOPENED); projectService.updateProject(token, project); - return ResponseMap.ofSuccess("操作成功"); + return ResponseMap.ofSuccess(); } @SneakyThrows @GetMapping("/{projectId}/stats") public ResponseMap getProjectProcess( - @RequestHeader("Token") String token, - @PathVariable Integer projectId + @RequestHeader("Token") String token, + @PathVariable Integer projectId ) { - return ResponseMap.ofSuccess("查询成功", projectService.getProjectProcess(token, projectId)); + return ResponseMap.ofSuccess(projectService.getProjectProcess(token, projectId)); } } diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/ProjectGroupController.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/ProjectGroupController.java index 50c2dd5..b2a9c47 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/ProjectGroupController.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/ProjectGroupController.java @@ -46,12 +46,12 @@ public class ProjectGroupController { RequestPage page ) { if (projectGroupService.getProjectAccessLevel(token, projectId) == 0) { - throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS); + throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS_PROJECT); } if (validateUtils.validate(page).isEmpty()) { - return ResponseList.ofSuccess("查询成功", projectGroupService.pageProjectMembers(page, projectId)); + return ResponseList.ofSuccess(projectGroupService.pageProjectMembers(page, projectId)); } - return ResponseList.ofSuccess("查询成功", projectGroupService.listProjectMembers(projectId)); + return ResponseList.ofSuccess(projectGroupService.listProjectMembers(projectId)); } @@ -63,9 +63,9 @@ public class ProjectGroupController { @PathVariable Integer staffId ) { if (projectGroupService.getProjectAccessLevel(token, projectId) == 0) { - throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS); + throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS_PROJECT); } - return ResponseMap.ofSuccess("查询成功", projectGroupService.getOne( + return ResponseMap.ofSuccess(projectGroupService.getOne( Wrappers.lambdaQuery() .eq(ProjectGroup::getStaffId, staffId) .eq(ProjectGroup::getProjectId, projectId) @@ -80,8 +80,10 @@ public class ProjectGroupController { @PathVariable Integer projectId, @RequestBody GroupPositionVO groupPosition ) { - projectGroupService.insertNewMember(token, projectId, groupPosition.getStaffId(), groupPosition.getPositions()); - return ResponseMap.ofSuccess("创建成功"); + if (projectGroupService.insertNewMember(token, projectId, groupPosition.getStaffId(), groupPosition.getPositions())) { + return ResponseMap.ofSuccess(); + } + throw new BadRequestException(BadRequestException.OPERATE_FAILED); } //TODO: test @@ -93,8 +95,10 @@ public class ProjectGroupController { @PathVariable Integer staffId, @Parameter(description = "不需要在body中传递staffId,用path传递") @RequestBody GroupPositionVO groupPosition ) { - projectGroupService.updateStaffPositions(token, staffId, projectId, groupPosition.getPositions()); - return ResponseMap.ofSuccess("更新成功"); + if (projectGroupService.updateStaffPositions(token, staffId, projectId, groupPosition.getPositions())) { + return ResponseMap.ofSuccess(); + } + throw new BadRequestException(BadRequestException.OPERATE_FAILED); } @SneakyThrows @@ -103,7 +107,7 @@ public class ProjectGroupController { @RequestHeader("Token") String token, @PathVariable Integer projectId ) { - return ResponseMap.ofSuccess("统计成功", projectGroupService.collectStatsForGroupPositions(token, projectId)); + return ResponseMap.ofSuccess(projectGroupService.collectStatsForGroupPositions(token, projectId)); } @SneakyThrows @@ -114,8 +118,8 @@ public class ProjectGroupController { @PathVariable Integer staffId ) { if (!Objects.equals(TokenUtils.getStaffId(token), staffId)) { - throw new BadRequestException("错误请求"); + throw new BadRequestException(BadRequestException.WRONG_PARAMETERS); } - return ResponseList.ofSuccess("查询成功", taskService.getProjectProcessOfStaff(token, projectId)); + return ResponseList.ofSuccess(taskService.getProjectProcessOfStaff(token, projectId)); } } diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/ProjectTypeController.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/ProjectTypeController.java index 1ee927c..8e6b069 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/ProjectTypeController.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/ProjectTypeController.java @@ -8,8 +8,6 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.List; - /** * @author 阳勇权 * @since 2022/6/30 16:36 @@ -22,7 +20,6 @@ public class ProjectTypeController { @GetMapping public ResponseList getAllProjectType() { - List res = projectTypeService.findAllProjectType(); - return ResponseList.ofSuccess("获得所有类成功", res); + return ResponseList.ofSuccess(projectTypeService.listAllProjectType()); } } diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/StaffController.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/StaffController.java index 1a558d0..cef8b49 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/StaffController.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/StaffController.java @@ -1,6 +1,7 @@ package cn.edu.hfut.rmdjzz.projectmanagement.controller; import cn.edu.hfut.rmdjzz.projectmanagement.entity.Staff; +import cn.edu.hfut.rmdjzz.projectmanagement.exception.BadRequestException; import cn.edu.hfut.rmdjzz.projectmanagement.exception.TokenException; import cn.edu.hfut.rmdjzz.projectmanagement.service.IStaffService; import cn.edu.hfut.rmdjzz.projectmanagement.utils.http.ResponseMap; @@ -8,6 +9,9 @@ import io.swagger.v3.oas.annotations.Parameter; import lombok.SneakyThrows; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.util.Objects; /** * @author 张韬 @@ -25,16 +29,29 @@ public class StaffController { @Parameter(description = "只需要传入staffUsername和staffPassword两个属性即可,staffPassword需要md5加密后传输") @RequestBody Staff staff ) { - return staffService.login(staff.getStaffUsername(), staff.getStaffPassword()); + return ResponseMap.ofSuccess("登录成功", staffService.login(staff.getStaffUsername(), staff.getStaffPassword())); } @SneakyThrows @PostMapping("/logout") public ResponseMap logout(@RequestHeader("Token") String token) { - if (staffService.logout(token)) - return ResponseMap.ofSuccess("操作成功"); - else { - throw new TokenException("操作失败"); + if (staffService.logout(token)) { + return ResponseMap.ofSuccess("登出成功"); } + throw new TokenException("登出失败"); + } + + @SneakyThrows + @PostMapping(value = "/staff/import") + public ResponseMap upload(@RequestHeader("Token") String token, @RequestParam("uploadFile") MultipartFile uploadFile) { + if (null == uploadFile) { + throw new BadRequestException("空的文件参数"); + } + String fileName = Objects.requireNonNull(uploadFile.getOriginalFilename()).toLowerCase(); + if (!fileName.endsWith(".xlsx")) { + throw new BadRequestException("文件类型错误"); + } + Integer successCount = staffService.multiImport(token, uploadFile); + return ResponseMap.ofSuccess("成功导入" + successCount + "条数据"); } } diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/TaskController.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/TaskController.java index 05c0156..de27d6f 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/TaskController.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/controller/TaskController.java @@ -31,15 +31,15 @@ public class TaskController { @PathVariable("projectId") Integer projectId, @PathVariable("fatherId") Long fatherId ) { - List result = taskService.getSubTaskList(token, projectId, fatherId); - return ResponseList.ofSuccess("查询成功", result); + List result = taskService.listSubtasks(token, projectId, fatherId); + return ResponseList.ofSuccess(result); } @SneakyThrows @GetMapping("/mine") public ResponseList getMyTasks(@RequestHeader("Token") String token, @PathVariable("projectId") Integer projectId) { - List result = taskService.getMyTaskList(token, projectId); - return ResponseList.ofSuccess("查询成功", result); + List result = taskService.listMyTasks(token, projectId); + return ResponseList.ofSuccess(result); } @SneakyThrows @@ -49,7 +49,7 @@ public class TaskController { @PathVariable("projectId") Integer projectId, @RequestParam("taskId") Long taskId ) { - return ResponseMap.ofSuccess("返回成功") + return ResponseMap.ofSuccess() .put("existSubTask", taskService.existSubTask(token, projectId, taskId)); } @@ -61,10 +61,10 @@ public class TaskController { @RequestBody Task task ) { if(!projectService.checkOpenStatus(projectId)) - throw new BadRequestException("项目未开放"); + throw new BadRequestException(IProjectService.PROJECT_UNOPENED); task.setTaskProjectId(projectId); taskService.insertTask(token, task); - return ResponseMap.ofSuccess("操作成功"); + return ResponseMap.ofSuccess(); } @SneakyThrows @@ -76,11 +76,11 @@ public class TaskController { @RequestBody Task task ) { if(!projectService.checkOpenStatus(projectId)) - throw new BadRequestException("项目未开放"); + throw new BadRequestException(IProjectService.PROJECT_UNOPENED); task.setTaskProjectId(projectId); task.setTaskId(taskId); taskService.modifyTask(token, task); - return ResponseMap.ofSuccess("操作成功"); + return ResponseMap.ofSuccess(); } @SneakyThrows @@ -91,9 +91,9 @@ public class TaskController { @PathVariable("taskId") Long taskId ) { if(!projectService.checkOpenStatus(projectId)) - throw new BadRequestException("项目未开放"); + throw new BadRequestException(IProjectService.PROJECT_UNOPENED); taskService.deleteTaskAndSubTask(token, projectId, taskId); - return ResponseMap.ofSuccess("删除成功"); + return ResponseMap.ofSuccess(); } } diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/entity/Staff.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/entity/Staff.java index 11be2d8..44efd3b 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/entity/Staff.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/entity/Staff.java @@ -20,5 +20,6 @@ public class Staff { private String staffPassword; @DoNotSerialize private String staffSalt; + //TODO: 详细测试 private Integer staffGlobalLevel; } diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/entity/Task.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/entity/Task.java index 748c45e..b2f731d 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/entity/Task.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/entity/Task.java @@ -20,10 +20,19 @@ import java.util.Objects; @Data public class Task { - private static final String ATTACH_DEMAND_SOURCE = "demandSource"; - private static final String ATTACH_ESTIMATED_MAN_HOURS = "estimatedManHours"; - private static final String ATTACH_SEVERITY = "severity"; - private static final String ATTACH_RECURRENCE_PROBABILITY = "recurrenceProbability"; + public static final String ATTACH_DEMAND_SOURCE = "demandSource"; + public static final String ATTACH_ESTIMATED_MAN_HOURS = "estimatedManHours"; + public static final String ATTACH_SEVERITY = "severity"; + public static final String ATTACH_RECURRENCE_PROBABILITY = "recurrenceProbability"; + + public static final String TYPE_DEFECT = "缺陷"; + public static final String TYPE_DEMAND = "需求"; + public static final String TYPE_ASSIGNMENT = "任务"; + + public static final String STATUS_WAITING = "待进行"; + public static final String STATUS_PROCESSING = "进行中"; + public static final String STATUS_COMPLETED = "已完成"; + public static final String STATUS_CLOSED = "关闭"; @TableId(type = IdType.AUTO) private Long taskId; @@ -91,20 +100,20 @@ public class Task { return false; if (father.getTaskId() == 0) return true; - if (this.getTaskType().equals("缺陷")) { - return father.getTaskType().equals("需求"); - } else if (this.getTaskType().equals("需求")) { - return father.getTaskType().equals("需求"); - } else if (this.getTaskType().equals("任务")) { - return father.getTaskType().equals("需求") || father.getTaskType().equals("任务"); + if (this.getTaskType().equals(TYPE_DEFECT)) { + return father.getTaskType().equals(TYPE_DEMAND); + } else if (this.getTaskType().equals(TYPE_DEMAND)) { + return father.getTaskType().equals(TYPE_DEMAND); + } else if (this.getTaskType().equals(TYPE_ASSIGNMENT)) { + return father.getTaskType().equals(TYPE_DEMAND) || father.getTaskType().equals(TYPE_ASSIGNMENT); } return false; } public Boolean checkModification(Task rawTask) { - if (rawTask.getTaskStatus().equals("已完成") || rawTask.getTaskStatus().equals("关闭")) + if (rawTask.getTaskStatus().equals(STATUS_COMPLETED) || rawTask.getTaskStatus().equals(STATUS_CLOSED)) return false; - if (!rawTask.getTaskStatus().equals("待进行") && this.getTaskStatus().equals("待进行")) + if (!rawTask.getTaskStatus().equals(STATUS_WAITING) && this.getTaskStatus().equals(STATUS_WAITING)) return false; if (!Objects.equals(rawTask.getTaskId(), this.getTaskId())) return false; diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/entity/dto/ProjectDTO.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/entity/dto/ProjectDTO.java index d51503f..a09353c 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/entity/dto/ProjectDTO.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/entity/dto/ProjectDTO.java @@ -28,5 +28,4 @@ public class ProjectDTO { LocalDate projectClosedDate; Integer completeNum; Integer totalNum; - //TODO: 带加的进度 Double projectProcess; } diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/exception/BadRequestException.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/exception/BadRequestException.java index 11521ed..cbce79b 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/exception/BadRequestException.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/exception/BadRequestException.java @@ -5,6 +5,10 @@ package cn.edu.hfut.rmdjzz.projectmanagement.exception; * created at 2022/6/28 21:24 */ public class BadRequestException extends Exception { + + public static final String WRONG_PARAMETERS = "参数错误"; + public static final String OPERATE_FAILED = "操作失败"; + public BadRequestException(String message) { super(message); } diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/exception/ForbiddenException.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/exception/ForbiddenException.java index aab2273..7b354c7 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/exception/ForbiddenException.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/exception/ForbiddenException.java @@ -5,6 +5,9 @@ package cn.edu.hfut.rmdjzz.projectmanagement.exception; * @since 2022/7/6 20:14 */ public class ForbiddenException extends Exception { + + public static final String UNABLE_TO_OPERATE = "无该操作权限"; + public ForbiddenException(String message) { super(message); } diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/exception/TokenException.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/exception/TokenException.java index 60d3779..6de7990 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/exception/TokenException.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/exception/TokenException.java @@ -4,7 +4,6 @@ package cn.edu.hfut.rmdjzz.projectmanagement.exception; * @author 张韬 * created at 2022/6/28 23:34 */ -//FIXME: 是否加入RequestUrl与RequestMethod作为错误信息log到日志 public class TokenException extends UnauthorizedException { public TokenException(String message) { super(message); diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/IProjectGroupService.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/IProjectGroupService.java index fa87d00..5a20759 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/IProjectGroupService.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/IProjectGroupService.java @@ -16,16 +16,16 @@ import java.util.Map; */ public interface IProjectGroupService extends IService { - String UNABLE_TO_ACCESS = "无该项目访问权限"; + String UNABLE_TO_ACCESS_PROJECT = "无该项目访问权限"; String POSITION_1 = "项目经理"; String POSITION_2 = "项目主管"; Boolean addCreator(Integer projectId, Integer staffId); - void insertNewMember(String token, Integer projectId, Integer staffId, String positions) throws ForbiddenException; + Boolean insertNewMember(String token, Integer projectId, Integer staffId, String positions) throws ForbiddenException; - void updateStaffPositions(String token, Integer projectId, Integer targetId, String positions) throws ForbiddenException; + Boolean updateStaffPositions(String token, Integer projectId, Integer targetId, String positions) throws ForbiddenException; /** * @return 如果不存在就返回0,否则返回AccessLevel;对于全局权限为1的用户,直接返回1 diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/IProjectService.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/IProjectService.java index 019b80d..b1dd817 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/IProjectService.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/IProjectService.java @@ -17,13 +17,16 @@ import java.util.Map; */ public interface IProjectService extends IService { + String PROJECT_UNOPENED = "该项目未开放"; + String PROJECT_COMPLETED = "该项目已结项"; + Long countMyProjects(String token); ProjectProcessDTO getProjectProcess(String token, Integer projectId) throws ForbiddenException, BadRequestException; - Page getOnePageProject(String token, RequestPage page, Map params); + Page pageMyProjects(String token, RequestPage page, Map params); - Boolean setProjectCompleted(String token, Integer projectId) throws BadRequestException; + Boolean setProjectCompleted(String token, Integer projectId) throws BadRequestException, ForbiddenException; Boolean createProject(String token, Project project) throws BadRequestException, ForbiddenException; diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/IProjectTypeService.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/IProjectTypeService.java index 8cac24b..6b1752a 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/IProjectTypeService.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/IProjectTypeService.java @@ -10,6 +10,6 @@ import java.util.List; * @since 2022/6/30 16:27 */ public interface IProjectTypeService extends IService { - List findAllProjectType(); + List listAllProjectType(); } diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/IStaffService.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/IStaffService.java index 6f81318..7087c92 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/IStaffService.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/IStaffService.java @@ -4,16 +4,17 @@ import cn.edu.hfut.rmdjzz.projectmanagement.entity.Staff; import cn.edu.hfut.rmdjzz.projectmanagement.exception.BadRequestException; import cn.edu.hfut.rmdjzz.projectmanagement.exception.ForbiddenException; import cn.edu.hfut.rmdjzz.projectmanagement.exception.TokenException; -import cn.edu.hfut.rmdjzz.projectmanagement.utils.http.ResponseMap; import com.baomidou.mybatisplus.extension.service.IService; import org.springframework.web.multipart.MultipartFile; +import java.util.Map; + /** * @author 佘语殊 * @since 2022/6/28 17:28 */ public interface IStaffService extends IService { - ResponseMap login(String username, String password) throws BadRequestException, TokenException; + Map login(String username, String password) throws BadRequestException, TokenException; Boolean logout(String token) throws TokenException; diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/ITaskService.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/ITaskService.java index eb7f1ae..4aad1d5 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/ITaskService.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/ITaskService.java @@ -14,7 +14,7 @@ import java.util.List; * created at 2022/7/4 14:49 */ public interface ITaskService extends IService { - List getSubTaskList(String token, Integer projectId, Long fatherId) throws BadRequestException, ForbiddenException; + List listSubtasks(String token, Integer projectId, Long fatherId) throws BadRequestException, ForbiddenException; Boolean existSubTask(String token, Integer projectId, Long taskId) throws BadRequestException, ForbiddenException; @@ -34,11 +34,11 @@ public interface ITaskService extends IService { */ Integer getHolderLevel(String token, Long taskId); - List getMyTaskList(String token, Integer projectId) throws BadRequestException; + List listMyTasks(String token, Integer projectId) throws BadRequestException; Boolean canBeDone(Long taskId); Task insertTask(String token, Task task) throws BadRequestException, ForbiddenException; - Task modifyTask(String token, Task task) throws BadRequestException; + Task modifyTask(String token, Task task) throws BadRequestException, ForbiddenException; } diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/impl/AnnouncementServiceImpl.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/impl/AnnouncementServiceImpl.java index 2e25fa8..0f45eab 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/impl/AnnouncementServiceImpl.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/impl/AnnouncementServiceImpl.java @@ -7,7 +7,6 @@ import cn.edu.hfut.rmdjzz.projectmanagement.exception.ForbiddenException; import cn.edu.hfut.rmdjzz.projectmanagement.mapper.AnnouncementMapper; import cn.edu.hfut.rmdjzz.projectmanagement.service.IAnnouncementService; import cn.edu.hfut.rmdjzz.projectmanagement.service.IProjectGroupService; -import cn.edu.hfut.rmdjzz.projectmanagement.service.IProjectService; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.beans.factory.annotation.Autowired; @@ -40,29 +39,29 @@ public class AnnouncementServiceImpl extends ServiceImpl 2) { - throw new ForbiddenException("无权修改该公告"); + throw new ForbiddenException(ForbiddenException.UNABLE_TO_OPERATE); } Announcement rawAnnouncement = baseMapper.selectById(announcement.getAnnouncementId()); if (projectGroupService.compareProjectAccessLevel(projectId, token, rawAnnouncement.getAnnouncementPublisherId()) >= 0) { if (!announcement.checkModification(rawAnnouncement)) { - throw new BadRequestException("请求参数错误"); + throw new BadRequestException(BadRequestException.WRONG_PARAMETERS); } return updateById(announcement); } - throw new ForbiddenException("无权修改该公告"); + throw new ForbiddenException(ForbiddenException.UNABLE_TO_OPERATE); } @Override public Boolean deleteAnnouncement(String token, Integer projectId, Long announcementId) throws ForbiddenException, BadRequestException { Integer accessLevel = projectGroupService.getProjectAccessLevel(token, projectId); if (accessLevel == 0) { - throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS); + throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS_PROJECT); } if (accessLevel > 2) { - throw new ForbiddenException("无权修改该公告"); + throw new ForbiddenException(ForbiddenException.UNABLE_TO_OPERATE); } Announcement rawAnnouncement = baseMapper.selectOne(Wrappers.lambdaQuery() .select(Announcement::getProjectId) @@ -70,10 +69,10 @@ public class AnnouncementServiceImpl extends ServiceImpl 2) { - throw new ForbiddenException("无新增成员权限"); + throw new ForbiddenException(ForbiddenException.UNABLE_TO_OPERATE); } String[] positionArray = positions.split(","); for (String position : positionArray) { if (position.equals(POSITION_1)) { - throw new ForbiddenException("不能授予他人项目经理职位"); + throw new ForbiddenException(ForbiddenException.UNABLE_TO_OPERATE); } if (position.equals(POSITION_2)) { if (accessLevel != 1) { - throw new ForbiddenException("无授予项目主管职位权限"); + throw new ForbiddenException(ForbiddenException.UNABLE_TO_OPERATE); } targetLevel = 2; } } - baseMapper.insert(new ProjectGroup(targetId, projectId, positions, targetLevel)); + return baseMapper.insert(new ProjectGroup(targetId, projectId, positions, targetLevel)) == 1; } @Override - public void updateStaffPositions(String token, Integer projectId, Integer targetId, String positions) throws ForbiddenException { + public Boolean updateStaffPositions(String token, Integer projectId, Integer targetId, String positions) throws ForbiddenException { int accessLevel = getProjectAccessLevel(token, projectId); int targetLevel = getProjectAccessLevel(targetId, 2, projectId); //假定目标的全局level为2,防止get时出现问题 if (accessLevel == 0) { - throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS); + throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS_PROJECT); } if (accessLevel > 2 || accessLevel >= targetLevel) { - throw new ForbiddenException("无更改此人职位权限"); + throw new ForbiddenException(ForbiddenException.UNABLE_TO_OPERATE); } String[] positionArray = positions.split(","); for (String position : positionArray) { if (position.equals(POSITION_1)) { - throw new ForbiddenException("不能授予他人项目经理职位"); + throw new ForbiddenException(ForbiddenException.UNABLE_TO_OPERATE); } if (position.equals(POSITION_2) && accessLevel != 1) { - throw new ForbiddenException("无授予项目主管职位权限"); + throw new ForbiddenException(ForbiddenException.UNABLE_TO_OPERATE); } } - baseMapper.update( + return baseMapper.update( ProjectGroup.builder() .projectId(projectId) .staffId(targetId) .build(), Wrappers.lambdaUpdate().set(ProjectGroup::getProjectStaffPosition, positions) - ); + ) == 1; } @Override @@ -148,7 +147,7 @@ public class ProjectGroupServiceImpl extends ServiceImpl collectStatsForGroupPositions(String token, Integer projectId) throws ForbiddenException { if (getProjectAccessLevel(token, projectId) == 0) { - throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS); + throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS_PROJECT); } Map res = new HashMap<>(); List infos = baseMapper.selectList( diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/impl/ProjectServiceImpl.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/impl/ProjectServiceImpl.java index c43383b..ed378bf 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/impl/ProjectServiceImpl.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/impl/ProjectServiceImpl.java @@ -41,49 +41,49 @@ public class ProjectServiceImpl extends ServiceImpl impl @Override public ProjectProcessDTO getProjectProcess(String token, Integer projectId) throws ForbiddenException, BadRequestException { if (projectGroupService.getProjectAccessLevel(token, projectId) == 0) { - throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS); + throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS_PROJECT); } if (Objects.equals(projectId, 0)) { - throw new BadRequestException("参数非法"); + throw new BadRequestException(BadRequestException.WRONG_PARAMETERS); } return baseMapper.selectProjectProcess(projectId); } @Override - public Page getOnePageProject( + public Page pageMyProjects( String token, RequestPage page, Map params ) { - Integer staffId = TokenUtils.getStaffId(token); + Integer staffId = TokenUtils.getStaffGlobalLevel(token) == 1 ? null : TokenUtils.getStaffId(token); IPage userPage = baseMapper.selectMyProject(page.getPage(), staffId, WrapperUtils.allEqAndTimeIntervalQueryWrapper(params)); return (Page) userPage; } @Override - public Boolean setProjectCompleted(String token, Integer projectId) throws BadRequestException { - Integer staffId = TokenUtils.getStaffId(token); + public Boolean setProjectCompleted(String token, Integer projectId) throws BadRequestException, ForbiddenException { Project project = new Project(); project.setProjectId(projectId); Project targetProject = baseMapper.selectById(project.getProjectId()); if (targetProject == null) - throw new BadRequestException("项目不存在"); - if (!Objects.equals(staffId, targetProject.getProjectCreator())) - throw new BadRequestException("无该操作权限"); + throw new BadRequestException(BadRequestException.WRONG_PARAMETERS); + if (!Objects.equals(TokenUtils.getStaffId(token), targetProject.getProjectCreator()) + && !Objects.equals(TokenUtils.getStaffGlobalLevel(token), 1)) + throw new ForbiddenException(ForbiddenException.UNABLE_TO_OPERATE); if (targetProject.getCompleted()) - throw new BadRequestException("该项目已结项"); + throw new BadRequestException(PROJECT_COMPLETED); targetProject.setCompleted(true); targetProject.setProjectClosedDate(LocalDate.now()); if (baseMapper.updateById(targetProject) == 1) return true; - throw new BadRequestException("操作失败"); + throw new BadRequestException(BadRequestException.OPERATE_FAILED); } @Override public Boolean createProject(String token, Project project) throws BadRequestException, ForbiddenException { Integer staffGlobalLevel = TokenUtils.getStaffGlobalLevel(token); if (staffGlobalLevel == 0 || staffGlobalLevel > 2) { - throw new ForbiddenException("无该操作权限"); + throw new ForbiddenException(ForbiddenException.UNABLE_TO_OPERATE); } project.setProjectId(null); project.setCompleted(false); @@ -95,7 +95,7 @@ public class ProjectServiceImpl extends ServiceImpl impl } else if (project.getExpectedCompletion() < 0 || project.getExpectedCompletion() > 100 || !project.checkProjectDate() || project.getProjectManMonth().compareTo(new BigDecimal("0")) < 0 ) { - throw new BadRequestException("参数错误"); + throw new BadRequestException(BadRequestException.WRONG_PARAMETERS); } //FIXME: 改为特定Exception处理 @@ -104,8 +104,8 @@ public class ProjectServiceImpl extends ServiceImpl impl return projectGroupService.addCreator(project.getProjectId(), TokenUtils.getStaffId(token)); } } catch (Exception e) { - System.out.println(e); - throw new BadRequestException("新建失败"); + log.error(e.getMessage(), e); + throw new BadRequestException(BadRequestException.OPERATE_FAILED); } return false; } @@ -120,18 +120,19 @@ public class ProjectServiceImpl extends ServiceImpl impl public Boolean updateProject(String token, Project project) throws BadRequestException, ForbiddenException { Integer staffId = TokenUtils.getStaffId(token); if (!staffId.equals(project.getProjectCreator()) && TokenUtils.getStaffGlobalLevel(token) != 1) { - throw new ForbiddenException("无该操作权限"); + throw new ForbiddenException(ForbiddenException.UNABLE_TO_OPERATE); } Project rawProject = baseMapper.selectById(project.getProjectId()); if (!project.checkModification(rawProject)) { - throw new BadRequestException("参数错误"); + throw new BadRequestException(BadRequestException.WRONG_PARAMETERS); } try { if (baseMapper.updateById(project) == 1) return true; - throw new BadRequestException("修改失败"); + throw new BadRequestException(BadRequestException.OPERATE_FAILED); } catch (Exception e) { - throw new BadRequestException("修改失败"); + log.error(e.getMessage(), e); + throw new BadRequestException(BadRequestException.OPERATE_FAILED); } } } diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/impl/ProjectTypeServiceImpl.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/impl/ProjectTypeServiceImpl.java index f5b4a9b..33df936 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/impl/ProjectTypeServiceImpl.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/impl/ProjectTypeServiceImpl.java @@ -16,7 +16,7 @@ import java.util.List; @Service public class ProjectTypeServiceImpl extends ServiceImpl implements IProjectTypeService { @Override - public List findAllProjectType() { + public List listAllProjectType() { return baseMapper.selectList(Wrappers.lambdaQuery().ne(ProjectType::getProjectClassId, 0)); } } diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/impl/StaffServiceImpl.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/impl/StaffServiceImpl.java index 8550b9a..b1ba6e3 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/impl/StaffServiceImpl.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/impl/StaffServiceImpl.java @@ -5,10 +5,12 @@ import cn.edu.hfut.rmdjzz.projectmanagement.exception.BadRequestException; import cn.edu.hfut.rmdjzz.projectmanagement.exception.ForbiddenException; import cn.edu.hfut.rmdjzz.projectmanagement.mapper.StaffMapper; import cn.edu.hfut.rmdjzz.projectmanagement.service.IStaffService; +import cn.edu.hfut.rmdjzz.projectmanagement.utils.BeanUtils; +import cn.edu.hfut.rmdjzz.projectmanagement.utils.MapBuilder; import cn.edu.hfut.rmdjzz.projectmanagement.utils.TokenUtils; -import cn.edu.hfut.rmdjzz.projectmanagement.utils.http.ResponseMap; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.RandomStringUtils; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; @@ -21,6 +23,7 @@ import org.springframework.util.DigestUtils; import org.springframework.web.multipart.MultipartFile; import java.util.ArrayList; +import java.util.Map; import java.util.Objects; import java.util.concurrent.TimeUnit; @@ -28,6 +31,7 @@ import java.util.concurrent.TimeUnit; * @author 佘语殊 * @since 2022/6/28 17:29 */ +@Slf4j @Service public class StaffServiceImpl extends ServiceImpl implements IStaffService { private static final Long tokenDuration = 5 * 60 * 60L; @@ -36,8 +40,8 @@ public class StaffServiceImpl extends ServiceImpl implements private RedisTemplate redisTemplate; @Override - public ResponseMap login(String staffUsername, String password) throws BadRequestException { - if (staffUsername == null || staffUsername.trim().length() == 0) + public Map login(String staffUsername, String password) throws BadRequestException { + if (staffUsername == null || staffUsername.strip().length() == 0) throw new BadRequestException("用户名为空"); else if (!staffUsername.equals(staffUsername.replaceAll("[^a-zA-Z0-9]", ""))) throw new BadRequestException("用户名格式错误"); @@ -56,8 +60,10 @@ public class StaffServiceImpl extends ServiceImpl implements token, Objects.requireNonNull(TokenUtils.getDuration(token)), TimeUnit.SECONDS ); - return ResponseMap.ofSuccess("ok", staff) - .put("Token", token); + return new MapBuilder() + .put("Token", token) + .putAll(BeanUtils.beanToMap(staff)) + .build(); } @Override @@ -75,9 +81,8 @@ public class StaffServiceImpl extends ServiceImpl implements @Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class) @Override public Integer multiImport(String token, MultipartFile file) throws BadRequestException, ForbiddenException { - //TODO:check Token here if (TokenUtils.getStaffGlobalLevel(token) != 1) { - throw new ForbiddenException("无该操作权限"); + throw new ForbiddenException(ForbiddenException.UNABLE_TO_OPERATE); } try { @@ -150,6 +155,7 @@ public class StaffServiceImpl extends ServiceImpl implements } catch (BadRequestException e) { throw e; } catch (Exception e) { + log.error(e.getMessage(), e); throw new BadRequestException("导入失败"); } } diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/impl/TaskServiceImpl.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/impl/TaskServiceImpl.java index fdfbf6e..c4ac022 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/impl/TaskServiceImpl.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/service/impl/TaskServiceImpl.java @@ -11,6 +11,7 @@ import cn.edu.hfut.rmdjzz.projectmanagement.service.ITaskService; import cn.edu.hfut.rmdjzz.projectmanagement.utils.TokenUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; @@ -26,18 +27,19 @@ import java.util.stream.Collectors; * @author 张韬 * created at 2022/7/4 14:51 */ +@Slf4j @Service public class TaskServiceImpl extends ServiceImpl implements ITaskService { @Autowired private IProjectGroupService projectGroupService; @Override - public List getSubTaskList(String token, Integer projectId, Long fatherId) throws ForbiddenException, BadRequestException { + public List listSubtasks(String token, Integer projectId, Long fatherId) throws ForbiddenException, BadRequestException { if (projectGroupService.getProjectAccessLevel(token, projectId) == 0) { - throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS); + throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS_PROJECT); } if (fatherId == null) { - throw new BadRequestException("请求参数错误"); + throw new BadRequestException(BadRequestException.WRONG_PARAMETERS); } return baseMapper.selectSubTaskList(projectId, fatherId); } @@ -45,7 +47,7 @@ public class TaskServiceImpl extends ServiceImpl implements IT @Override public Boolean existSubTask(String token, Integer projectId, Long taskId) throws ForbiddenException { if (projectGroupService.getProjectAccessLevel(token, projectId) == 0) { - throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS); + throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS_PROJECT); } return baseMapper.exists(Wrappers.lambdaQuery().eq(Task::getTaskFatherId, taskId)); } @@ -55,10 +57,10 @@ public class TaskServiceImpl extends ServiceImpl implements IT public Boolean deleteTaskAndSubTask(String token, Integer projectId, Long taskId) throws BadRequestException, ForbiddenException { Integer level = getHolderLevel(token, taskId); if (projectGroupService.getProjectAccessLevel(token, projectId) == 0) { - throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS); + throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS_PROJECT); } if (level == 0 || level == 3) { - throw new BadRequestException("错误父级参数"); + throw new BadRequestException(BadRequestException.WRONG_PARAMETERS); } try { List res = new ArrayList<>(); @@ -73,6 +75,7 @@ public class TaskServiceImpl extends ServiceImpl implements IT } return true; } catch (Exception e) { + log.error(e.getMessage(), e); return false; } } @@ -82,10 +85,10 @@ public class TaskServiceImpl extends ServiceImpl implements IT public Boolean closeTaskAndSubTask(String token, Integer projectId, Long taskId) throws BadRequestException { Integer level = getHolderLevel(token, taskId); if (projectGroupService.getProjectAccessLevel(token, projectId) == 0) { - throw new BadRequestException(IProjectGroupService.UNABLE_TO_ACCESS); + throw new BadRequestException(IProjectGroupService.UNABLE_TO_ACCESS_PROJECT); } if (level == 0) { - throw new BadRequestException("父级参数错误"); + throw new BadRequestException(BadRequestException.WRONG_PARAMETERS); } try { List res = new ArrayList<>(); @@ -94,14 +97,14 @@ public class TaskServiceImpl extends ServiceImpl implements IT List list = baseMapper.selectList( Wrappers.lambdaQuery() .in(Task::getTaskFatherId, res) - .ne(Task::getTaskStatus, "已完成") - .ne(Task::getTaskStatus, "关闭") + .ne(Task::getTaskStatus, Task.STATUS_COMPLETED) + .ne(Task::getTaskStatus, Task.STATUS_CLOSED) ); baseMapper.update( null, Wrappers.lambdaUpdate() .in(Task::getTaskId, res) - .set(Task::getTaskStatus, "关闭") + .set(Task::getTaskStatus, Task.STATUS_CLOSED) .set(Task::getTaskClosedTime, LocalDateTime.now()) ); if (list == null || list.isEmpty()) break; @@ -109,6 +112,7 @@ public class TaskServiceImpl extends ServiceImpl implements IT } return true; } catch (Exception e) { + log.error(e.getMessage(), e); return false; } } @@ -117,7 +121,7 @@ public class TaskServiceImpl extends ServiceImpl implements IT public List getProjectProcessOfStaff(String token, Integer projectId) throws BadRequestException, ForbiddenException { Integer staffId = TokenUtils.getStaffId(token); if (projectGroupService.getProjectAccessLevel(token, projectId) == 0) { - throw new ForbiddenException("无查看权限"); + throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS_PROJECT); } return baseMapper.selectProjectProcessOfStaff(projectId, staffId); } @@ -142,6 +146,7 @@ public class TaskServiceImpl extends ServiceImpl implements IT } return count; } catch (Exception e) { + log.error(e.getMessage(), e); return 0; } } @@ -154,9 +159,9 @@ public class TaskServiceImpl extends ServiceImpl implements IT } @Override - public List getMyTaskList(String token, Integer projectId) throws BadRequestException { + public List listMyTasks(String token, Integer projectId) throws BadRequestException { if (projectGroupService.getProjectAccessLevel(token, projectId) == 0) { - throw new BadRequestException(IProjectGroupService.UNABLE_TO_ACCESS); + throw new BadRequestException(IProjectGroupService.UNABLE_TO_ACCESS_PROJECT); } Integer staffId = TokenUtils.getStaffId(token); return baseMapper.selectList(Wrappers.lambdaQuery() @@ -169,17 +174,18 @@ public class TaskServiceImpl extends ServiceImpl implements IT public Boolean canBeDone(Long taskId) { try { Task task = baseMapper.selectOne(Wrappers.lambdaQuery().eq(Task::getTaskId, taskId)); - if (task == null || (!"待进行".equals(task.getTaskStatus()) && !"进行中".equals(task.getTaskStatus()))) + if (task == null || (!Task.STATUS_WAITING.equals(task.getTaskStatus()) && !Task.STATUS_PROCESSING.equals(task.getTaskStatus()))) return false; List childTask = baseMapper.selectList(Wrappers.lambdaQuery().eq(Task::getTaskFatherId, task.getTaskId())); if (childTask == null || childTask.isEmpty()) return true; for (Task cTask : childTask) { - if (cTask.getTaskStatus().equals("待进行") || cTask.getTaskStatus().equals("进行中")) + if (cTask.getTaskStatus().equals(Task.STATUS_WAITING) || cTask.getTaskStatus().equals(Task.STATUS_PROCESSING)) return false; } return true; - } catch (Exception e) {//需要调整 + } catch (Exception e) { //TODO: 需要调整 + log.error(e.getMessage(), e); return false; } } @@ -190,10 +196,10 @@ public class TaskServiceImpl extends ServiceImpl implements IT Integer userLevel = projectGroupService.getProjectAccessLevel(token, task.getTaskProjectId()); if (userLevel == 0) { System.out.println(userLevel); - throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS); + throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS_PROJECT); } if (!task.checkInsert()) { - throw new BadRequestException("工作项参数错误"); + throw new BadRequestException(BadRequestException.WRONG_PARAMETERS); } try { Task father = baseMapper.selectOne(Wrappers.lambdaQuery().eq(Task::getTaskId, task.getTaskFatherId())); @@ -201,36 +207,36 @@ public class TaskServiceImpl extends ServiceImpl implements IT throw new BadRequestException("无法指定该父级"); } task.setTaskCreatedTime(LocalDateTime.now()); - task.setTaskStatus("待进行"); + task.setTaskStatus(Task.STATUS_WAITING); task.setTaskClosedTime(null); System.out.println("-------------------------\n"); if (baseMapper.insert(task) == 0) { - throw new BadRequestException("新建失败"); + throw new BadRequestException(BadRequestException.OPERATE_FAILED); } } catch (Exception e) { - System.out.println(e); - throw new BadRequestException("111"); + log.error(e.getMessage(), e); + throw new BadRequestException(BadRequestException.OPERATE_FAILED); } return task; } @Override - public Task modifyTask(String token, Task task) throws BadRequestException { + public Task modifyTask(String token, Task task) throws BadRequestException, ForbiddenException { Integer userLevel = projectGroupService.getProjectAccessLevel(token, task.getTaskProjectId()); Task rawTask = baseMapper.selectOne(Wrappers.lambdaQuery().eq(Task::getTaskId, task.getTaskId())); if (userLevel == 0 || (userLevel == 3 && getHolderLevel(token, task.getTaskId()) == 0)) { - throw new BadRequestException("没有权限"); + throw new ForbiddenException(ForbiddenException.UNABLE_TO_OPERATE); } int typeChangeValue = 0; if (!task.getTaskStatus().equals(rawTask.getTaskStatus())) { - if (task.getTaskStatus().equals("已完成")) + if (task.getTaskStatus().equals(Task.STATUS_COMPLETED)) typeChangeValue = 1; - if (task.getTaskStatus().equals("关闭")) + if (task.getTaskStatus().equals(Task.STATUS_CLOSED)) typeChangeValue = 2; } System.out.println(!task.checkModification(rawTask)); if (!task.checkModification(rawTask) || !task.checkInsert() || (typeChangeValue == 1 && !canBeDone(task.getTaskId()))) { - throw new BadRequestException("该修改无法应用"); + throw new BadRequestException(BadRequestException.WRONG_PARAMETERS); } try { @@ -241,10 +247,11 @@ public class TaskServiceImpl extends ServiceImpl implements IT closeTaskAndSubTask(token, task.getTaskProjectId(), task.getTaskId()); } if (baseMapper.update(task, Wrappers.lambdaQuery().eq(Task::getTaskId, task.getTaskId())) == 0) { - throw new BadRequestException("修改失败"); + throw new BadRequestException(BadRequestException.OPERATE_FAILED); } } catch (Exception e) { - throw new BadRequestException("修改失败"); + log.error(e.getMessage(), e); + throw new BadRequestException(BadRequestException.OPERATE_FAILED); } return task; } diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/MapBuilder.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/MapBuilder.java new file mode 100644 index 0000000..d70f90f --- /dev/null +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/MapBuilder.java @@ -0,0 +1,26 @@ +package cn.edu.hfut.rmdjzz.projectmanagement.utils; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author 佘语殊 + * @since 2022/7/8 11:41 + */ +public class MapBuilder { + private final Map innerMap = new HashMap<>(); + + public MapBuilder put(String key, Object value) { + innerMap.put(key, value); + return this; + } + + public MapBuilder putAll(Map map) { + innerMap.putAll(map); + return this; + } + + public Map build() { + return innerMap; + } +} diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/TokenUtils.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/TokenUtils.java index ab0fcb0..c41330e 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/TokenUtils.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/TokenUtils.java @@ -19,13 +19,17 @@ import java.util.Date; public final class TokenUtils { private final static String PV_KEY = "SignedByRMDJZZ"; - //TODO: 加个大权限 + private final static String STAFF_USERNAME = "staffUsername"; + private final static String STAFF_ID = "staffId"; + private final static String STAFF_GLOBAL_LEVEL = "staffGlobalLevel"; + private final static String DURATION = "duration"; + public static String getToken(String staffUsername, Integer staffId, Integer staffGlobalLevel, Long duration) { return JWT.create() - .withClaim("staffUsername", staffUsername) - .withClaim("staffId", staffId) - .withClaim("staffGlobalLevel", staffGlobalLevel) - .withClaim("duration", duration) + .withClaim(STAFF_USERNAME, staffUsername) + .withClaim(STAFF_ID, staffId) + .withClaim(STAFF_GLOBAL_LEVEL, staffGlobalLevel) + .withClaim(DURATION, duration) .withIssuedAt(new Date()) .withExpiresAt(new Date(System.currentTimeMillis() + duration * 1000L)) .sign(Algorithm.HMAC256(PV_KEY)); @@ -46,19 +50,19 @@ public final class TokenUtils { } public static String getUsername(String token) { - return JWT.decode(token).getClaim("staffUsername").asString(); + return JWT.decode(token).getClaim(STAFF_USERNAME).asString(); } public static Integer getStaffId(String token) { - return JWT.decode(token).getClaim("staffId").asInt(); + return JWT.decode(token).getClaim(STAFF_ID).asInt(); } public static Integer getStaffGlobalLevel(String token) { - return JWT.decode(token).getClaim("staffGlobalLevel").asInt(); + return JWT.decode(token).getClaim(STAFF_GLOBAL_LEVEL).asInt(); } public static Long getDuration(String token) { - return JWT.decode(token).getClaim("duration").asLong(); + return JWT.decode(token).getClaim(DURATION).asLong(); } public static String refreshToken(String token) { diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/http/IResponse.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/http/IResponse.java new file mode 100644 index 0000000..2ace3b0 --- /dev/null +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/http/IResponse.java @@ -0,0 +1,10 @@ +package cn.edu.hfut.rmdjzz.projectmanagement.utils.http; + +/** + * @author 佘语殊 + * @since 2022/7/8 11:58 + */ +public interface IResponse { + String SUCCESS = "操作成功"; + String FAILURE = "操作失败"; +} diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/http/ResponseList.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/http/ResponseList.java index 118c5bf..9ef1962 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/http/ResponseList.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/http/ResponseList.java @@ -19,7 +19,8 @@ import java.util.stream.Collectors; @SuppressWarnings({"unchecked", "varargs"}) @Data @AllArgsConstructor(access = AccessLevel.PRIVATE) -public class ResponseList { +public class ResponseList implements IResponse { + private Integer code; private String msg; private QueryPage data; @@ -51,14 +52,26 @@ public class ResponseList { return of(HttpStatus.OK.value(), msg, data); } + public static ResponseList ofSuccess(T... data) { + return of(HttpStatus.OK.value(), SUCCESS, data); + } + public static ResponseList ofSuccess(String msg, Collection data) { return of(HttpStatus.OK.value(), msg, data); } + public static ResponseList ofSuccess(Collection data) { + return of(HttpStatus.OK.value(), SUCCESS, data); + } + public static ResponseList ofSuccess(String msg, Page data) { return of(HttpStatus.OK.value(), msg, data); } + public static ResponseList ofSuccess(Page data) { + return of(HttpStatus.OK.value(), SUCCESS, data); + } + /** * 响应体内部类,包装用于分页查询 */ diff --git a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/http/ResponseMap.java b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/http/ResponseMap.java index 2013891..55f23c2 100644 --- a/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/http/ResponseMap.java +++ b/src/main/java/cn/edu/hfut/rmdjzz/projectmanagement/utils/http/ResponseMap.java @@ -20,7 +20,7 @@ import java.util.Map; */ @AllArgsConstructor(access = AccessLevel.PUBLIC) @Data -public class ResponseMap { +public class ResponseMap implements IResponse { private Integer code; private String msg; private Map data; @@ -75,6 +75,10 @@ public class ResponseMap { return of(HttpStatus.OK.value(), msg, data); } + public static ResponseMap ofSuccess(Object data) { + return of(HttpStatus.OK.value(), SUCCESS, data); + } + public static ResponseMap ofSuccess(String msg, Map data, boolean putNulls) { return of(HttpStatus.OK.value(), msg, data, putNulls); } @@ -83,6 +87,10 @@ public class ResponseMap { return of(HttpStatus.OK.value(), msg); } + public static ResponseMap ofSuccess() { + return of(HttpStatus.OK.value(), SUCCESS); + } + /** * 可以链式构造包装类里的Map */ diff --git a/src/main/resources/mapper/ProjectMapper.xml b/src/main/resources/mapper/ProjectMapper.xml index 927d498..f3429ed 100644 --- a/src/main/resources/mapper/ProjectMapper.xml +++ b/src/main/resources/mapper/ProjectMapper.xml @@ -28,13 +28,14 @@ SUM(IF(task_status = '已完成' OR task_status = '关闭', 1, 0)) AS complete_num, COUNT(task_status) AS total_num FROM task - WHERE is_deleted = false + WHERE is_deleted = 0 AND task_project_id != 0 GROUP BY task_project_id) AS t ON project.project_id = t.task_project_id + is_deleted = 0 - project_id IN (SELECT DISTINCT project_id FROM project_group WHERE staff_id = #{staffId} ) + AND project_id IN (SELECT DISTINCT project_id FROM project_group WHERE staff_id = #{staffId} ) ) AS T diff --git a/src/test/java/cn/edu/hfut/rmdjzz/projectmanagement/MybatisPlusTests.java b/src/test/java/cn/edu/hfut/rmdjzz/projectmanagement/MybatisPlusTests.java index bfdbbfa..14e0203 100644 --- a/src/test/java/cn/edu/hfut/rmdjzz/projectmanagement/MybatisPlusTests.java +++ b/src/test/java/cn/edu/hfut/rmdjzz/projectmanagement/MybatisPlusTests.java @@ -88,7 +88,7 @@ public class MybatisPlusTests { Map map = new HashMap<>(); map.put("completed", true); System.out.println(objectMapper.writeValueAsString(projectService - .getOnePageProject("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkdXJhdGlvbiI6MTgwMDAsInN0YWZmVXNlcm5hbWUiOiJtaWtlIiwiZXhwIjoxNjU3MDkzNTU1LCJpYXQiOjE2NTcwNzU1NTUsInN0YWZmSWQiOjF9.g8l01dnHglt223469Z03i9gqZL8P13Fo7KoaA1pf310", + .pageMyProjects("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkdXJhdGlvbiI6MTgwMDAsInN0YWZmVXNlcm5hbWUiOiJtaWtlIiwiZXhwIjoxNjU3MDkzNTU1LCJpYXQiOjE2NTcwNzU1NTUsInN0YWZmSWQiOjF9.g8l01dnHglt223469Z03i9gqZL8P13Fo7KoaA1pf310", page, map))); }