更改了Dto的命名与包路径,更改了关闭和删除任务的uri,新增了添加项目成员与修改职位的功能,删除了TokenUtils中一般方法的check与throw,更改了很多抛出异常的类型和信息,修改了readme

master
ArgonarioD 2022-07-07 09:14:10 +08:00
parent 7f8b244435
commit cd02c7c1b8
25 changed files with 316 additions and 175 deletions

View File

@ -19,7 +19,7 @@ group /project/{projectId}/group
- [ ] 加人
- [ ] 改岗位
---
项目日志 项目统计
项目日志 项目统计 克隆项目 项目公告
---
导入账户 大权限

View File

@ -159,9 +159,10 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<source>15</source>
<target>15</target>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
</plugins>

View File

@ -1,6 +1,7 @@
package cn.edu.hfut.rmdjzz.projectmanagement.advice;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.BadRequestException;
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;
@ -30,4 +31,10 @@ public class ExceptionHandlerAdvice {
log.error(e.getMessage());
return ResponseMap.of(HttpStatus.BAD_REQUEST.value(), e.getMessage());
}
@ExceptionHandler(ForbiddenException.class)
@ResponseStatus(HttpStatus.FORBIDDEN)
public ResponseMap handleForbiddenException(ForbiddenException e) {
return ResponseMap.of(HttpStatus.FORBIDDEN.value(), e.getMessage());
}
}

View File

@ -2,10 +2,7 @@ package cn.edu.hfut.rmdjzz.projectmanagement.annotation;
import cn.edu.hfut.rmdjzz.projectmanagement.utils.BeanUtils;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.*;
/**
* {@link BeanUtils#beanToMap(Object, boolean, boolean)}Map
@ -14,6 +11,7 @@ import java.lang.annotation.Target;
* @since 2022/6/28 21:42
*/
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target({ElementType.FIELD})
public @interface DoNotDeserialize {
}

View File

@ -1,5 +1,6 @@
package cn.edu.hfut.rmdjzz.projectmanagement.config;
import com.fasterxml.classmate.TypeResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.PathSelectors;
@ -24,18 +25,19 @@ public class SwaggerConfig {
//配置 Swagger的Docket的Bean实例
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
public Docket docket(TypeResolver typeResolver){
return new Docket(DocumentationType.OAS_30)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("cn.edu.hfut.rmdjzz.projectmanagement"))
.paths(PathSelectors.any())
.build();
.build()
.additionalModels(typeResolver.resolve(Integer.class));
}
//配置Swagger 信息apiInfo
private ApiInfo apiInfo(){
//作者信息
Contact DEFAULT_CONTACT = new Contact("项目管理系统", "http://wuyize.ml/", "");
Contact DEFAULT_CONTACT = new Contact("项目管理系统", "http://101.34.228.45:8080/", "");
return new ApiInfo("前后端接口文档",
"",
"1.0",

View File

@ -30,6 +30,6 @@ public class WebConfig implements WebMvcConfigurer {
.addPathPatterns("/**")
.excludePathPatterns("/hello", "/error") //测试
.excludePathPatterns("/staff/login") //登录
.excludePathPatterns("/swagger-resources/**", "/swagger-ui/**", "/v3/**", "/v2/**"); //swagger
.excludePathPatterns("/swagger-resources/**", "/swagger-ui/**", "/v2/**", "/v3/**", "/webjars/**", "/doc.html"); //swagger
}
}

View File

@ -1,7 +1,7 @@
package cn.edu.hfut.rmdjzz.projectmanagement.controller;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.Project;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.query.ResultProject;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.ProjectDto;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.BadRequestException;
import cn.edu.hfut.rmdjzz.projectmanagement.service.IProjectGroupService;
import cn.edu.hfut.rmdjzz.projectmanagement.service.IProjectService;
@ -12,9 +12,12 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
import javax.validation.Valid;
import java.util.Map;
@ -39,12 +42,12 @@ public class ProjectController {
})
@SneakyThrows
@GetMapping
public ResponseList<ResultProject> getProjectListOfStaff(
public ResponseList<ProjectDto> getProjectListOfStaff(
@RequestHeader("Token") String token,
@Valid RequestPage page,
@RequestParam("paramMap") Map<String, Object> paramMap
) {
Page<ResultProject> result = projectService.getOnePageProject(token, page, paramMap);
Page<ProjectDto> result = projectService.getOnePageProject(token, page, paramMap);
return ResponseList.ofSuccess("成功返回列表", result);
}
@ -52,9 +55,9 @@ public class ProjectController {
@GetMapping("/{projectId}")
public ResponseMap getOneProject(
@RequestHeader("Token") String token,
@PathVariable ("projectId") Integer projectId
@PathVariable("projectId") Integer projectId
) {
if(projectGroupService.getUserLevelInGroup(token, projectId) == 0) {
if (projectGroupService.getProjectAccessLevel(token, projectId) == 0) {
throw new BadRequestException("请求参数错误");
}
return ResponseMap.ofSuccess("查询成功", projectService.getById(projectId));
@ -68,13 +71,12 @@ public class ProjectController {
.put("totalNum", projectService.getAllProjectOfStaff(token));
}
@ApiImplicitParams({
@ApiImplicitParam(name = "map", value = "用于读取整个RequestBody实际传参时无意义请忽略"),
@ApiImplicitParam(paramType = "body", dataTypeClass = Integer.class, name = "projectId", required = true)
})
@SneakyThrows
@PostMapping("/complete")
public ResponseMap completeProject(@RequestHeader("Token") String token, @RequestBody Map<String, Object> map) {
public ResponseMap completeProject(
@RequestHeader("Token") String token,
@RequestBody Map<String, Object> map
) {
Integer targetProjectId = (Integer) map.get("projectId");
projectService.setProjectCompleted(token, targetProjectId);
return ResponseMap.ofSuccess("操作成功");

View File

@ -1,19 +1,20 @@
package cn.edu.hfut.rmdjzz.projectmanagement.controller;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.ProjectGroup;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.BadRequestException;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.UnauthorizedException;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.vo.GroupPositionVo;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.ForbiddenException;
import cn.edu.hfut.rmdjzz.projectmanagement.service.IProjectGroupService;
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;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiParam;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Objects;
/**
* @author
@ -37,14 +38,11 @@ public class ProjectGroupController {
@GetMapping("/{staffId}")
public ResponseMap getDesignatedStaffPosition(
@RequestHeader("Token") String token,
@PathVariable Integer staffId,
@PathVariable Integer projectId
@PathVariable Integer projectId,
@PathVariable Integer staffId
) {
if (!Objects.equals(TokenUtils.getStaffId(token), staffId)) {
throw new BadRequestException("用户访问错误");
}
if (projectGroupService.getUserLevelInGroup(token, projectId) == 0) {
throw new UnauthorizedException("无该项目访问权限");
if (projectGroupService.getProjectAccessLevel(token, projectId) == 0) {
throw new ForbiddenException("无该项目访问权限");
}
return ResponseMap.ofSuccess("查询成功", projectGroupService.getOne(
Wrappers.<ProjectGroup>lambdaQuery()
@ -53,12 +51,41 @@ public class ProjectGroupController {
));
}
@PutMapping("/{staffId}")
public ResponseMap updateDesignatedStaffPosition(
//TODO: test
@SneakyThrows
@PostMapping
public ResponseMap addGroupMember(
@RequestHeader("Token") String token,
@PathVariable Integer staffId,
@PathVariable Integer projectId
@PathVariable Integer projectId,
@RequestBody GroupPositionVo groupPosition
) {
projectGroupService.insertNewMember(token, projectId, groupPosition.getStaffId(), groupPosition.getPositions());
return ResponseMap.ofSuccess("创建成功");
}
//TODO: test
@ApiImplicitParams(
@ApiImplicitParam(paramType = "body", name = "positions", dataTypeClass = String.class, required = true)
)
@SneakyThrows
@PutMapping("/{staffId}")
public ResponseMap modifyDesignatedStaffPosition(
@RequestHeader("Token") String token,
@PathVariable Integer projectId,
@PathVariable Integer staffId,
@ApiParam(hidden = true) @RequestBody GroupPositionVo groupPosition
) {
projectGroupService.updateStaffPositions(token, staffId, projectId, groupPosition.getPositions());
return ResponseMap.ofSuccess("更新成功");
}
//TODO: test
@SneakyThrows
@GetMapping("/stats")
public ResponseMap getGroupPositionsStatistics(
@RequestHeader("Token") String token,
@PathVariable Integer projectId
) {
return ResponseMap.ofSuccess("统计成功", projectGroupService.collectStatsForGroupPositions(token, projectId));
}
}

View File

@ -1,8 +1,7 @@
package cn.edu.hfut.rmdjzz.projectmanagement.controller;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.Task;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.query.ResultTask;
import cn.edu.hfut.rmdjzz.projectmanagement.service.IProjectGroupService;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.TaskDto;
import cn.edu.hfut.rmdjzz.projectmanagement.service.ITaskService;
import cn.edu.hfut.rmdjzz.projectmanagement.utils.http.ResponseList;
import cn.edu.hfut.rmdjzz.projectmanagement.utils.http.ResponseMap;
@ -22,17 +21,14 @@ public class TaskController {
@Autowired
private ITaskService taskService;
@Autowired
private IProjectGroupService projectGroupService;
@SneakyThrows
@GetMapping("/{fatherId}/subtask")
public ResponseList<ResultTask> getSubTaskList(
public ResponseList<TaskDto> getSubTaskList(
@RequestHeader("Token") String token,
@PathVariable("projectId") Integer projectId,
@PathVariable("fatherId") Long fatherId
) {
List<ResultTask> result = taskService.getSubTaskList(token, projectId, fatherId);
List<TaskDto> result = taskService.getSubTaskList(token, projectId, fatherId);
return ResponseList.ofSuccess("查询成功", result);
}
@ -51,7 +47,7 @@ public class TaskController {
@RequestParam("taskId") Long taskId
) {
return ResponseMap.ofSuccess("返回成功")
.put("existSubTask" ,taskService.existSubTask(token, projectId, taskId));
.put("existSubTask", taskService.existSubTask(token, projectId, taskId));
}
@SneakyThrows
@ -62,27 +58,30 @@ public class TaskController {
@RequestBody Task task
) {
task.setTaskProjectId(projectId);
taskService.insertTask(token,task);
taskService.insertTask(token, task);
return ResponseMap.ofSuccess("操作成功");
}
@SneakyThrows
@PutMapping
@PutMapping("/{taskId}")
public ResponseMap modifyTask(
@RequestHeader("Token") String token,
@PathVariable("projectId") Integer projectId,
@PathVariable("taskId") Long taskId,
@RequestBody Task task
) {
task.setTaskProjectId(projectId);
taskService.modifyTask(token,task);
task.setTaskId(taskId);
taskService.modifyTask(token, task);
return ResponseMap.ofSuccess("操作成功");
}
@SneakyThrows
@DeleteMapping
@DeleteMapping("/{taskId}")
public ResponseMap deleteTaskAndSubTask(
@RequestHeader("Token") String token,
@PathVariable("projectId") Integer projectId,
@RequestParam("taskId") Long taskId
@PathVariable("taskId") Long taskId
) {
taskService.deleteTaskAndSubTask(token, projectId, taskId);
return ResponseMap.ofSuccess("删除成功");

View File

@ -2,12 +2,18 @@ package cn.edu.hfut.rmdjzz.projectmanagement.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
/**
* @author
* created at 2022/6/30 21:31
*/
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@Data
public class ProjectGroup {
@TableId(type = IdType.AUTO)

View File

@ -1,4 +1,4 @@
package cn.edu.hfut.rmdjzz.projectmanagement.entity.query;
package cn.edu.hfut.rmdjzz.projectmanagement.entity.dto;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.AllArgsConstructor;
@ -12,7 +12,7 @@ import java.time.LocalDate;
*/
@Data
@AllArgsConstructor
public class ResultProject {
public class ProjectDto {
@TableId
Integer projectId;
String projectName;
@ -27,9 +27,9 @@ public class ResultProject {
Integer completeNum;
Integer totalNum;
ResultProject() {
ProjectDto() {
completeNum = 50;
totalNum = 100;
}
// 带加的进度 Double projectProcess;
//TODO: 带加的进度 Double projectProcess;
}

View File

@ -1,4 +1,4 @@
package cn.edu.hfut.rmdjzz.projectmanagement.entity.query;
package cn.edu.hfut.rmdjzz.projectmanagement.entity.dto;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
@ -12,7 +12,7 @@ import java.util.Map;
* @since 2022/7/6 10:25
*/
@Data
public class ResultTask {
public class TaskDto {
private Long taskId;
private String taskName;
private Integer taskProjectId;

View File

@ -0,0 +1,13 @@
package cn.edu.hfut.rmdjzz.projectmanagement.entity.vo;
import lombok.Data;
/**
* @author
* @since 2022/7/7 0:27
*/
@Data
public class GroupPositionVo {
private Integer staffId;
private String positions;
}

View File

@ -0,0 +1,11 @@
package cn.edu.hfut.rmdjzz.projectmanagement.exception;
/**
* @author
* @since 2022/7/6 20:14
*/
public class ForbiddenException extends Exception {
public ForbiddenException(String message) {
super(message);
}
}

View File

@ -1,7 +1,7 @@
package cn.edu.hfut.rmdjzz.projectmanagement.mapper;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.Project;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.query.ResultProject;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.ProjectDto;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
@ -21,5 +21,5 @@ public interface ProjectMapper extends BaseMapper<Project> {
""")
Long findProjectCount(@Param("id") Integer staffId);
IPage<ResultProject> findMyProject(IPage<ResultProject> pg, @Param("id") Integer staff_id, @Param(Constants.WRAPPER) Wrapper<Project> wrapper);
IPage<ProjectDto> findMyProject(IPage<ProjectDto> pg, @Param("id") Integer staff_id, @Param(Constants.WRAPPER) Wrapper<Project> wrapper);
}

View File

@ -1,7 +1,7 @@
package cn.edu.hfut.rmdjzz.projectmanagement.mapper;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.Task;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.query.ResultTask;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.TaskDto;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
@ -12,5 +12,5 @@ import java.util.List;
* created at 2022/7/4 14:52
*/
public interface TaskMapper extends BaseMapper<Task> {
List<ResultTask> selectSubTaskList(@Param("projectId") Integer projectId, @Param("fatherId") Long fatherId);
List<TaskDto> selectSubTaskList(@Param("projectId") Integer projectId, @Param("fatherId") Long fatherId);
}

View File

@ -2,10 +2,11 @@ package cn.edu.hfut.rmdjzz.projectmanagement.service;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.ProjectGroup;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.BadRequestException;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.TokenException;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.ForbiddenException;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
import java.util.Map;
/**
* @author
@ -14,10 +15,24 @@ import java.util.List;
public interface IProjectGroupService extends IService<ProjectGroup> {
Boolean addCreator(Integer projectId, Integer staffId);
void insertNewMember(String token, Integer projectId, Integer staffId, String positions) throws ForbiddenException;
void updateStaffPositions(String token, Integer projectId, Integer targetId, String positions) throws ForbiddenException;
/**
* @return 0AccessLevel
*/
Integer getUserLevelInGroup(String token, Integer projectId);
Integer getProjectAccessLevel(String token, Integer projectId);
Integer getProjectAccessLevel(Integer staffId, Integer projectId);
List<Integer> findAllProjectNumber(String token, Integer projectId) throws BadRequestException;
/**
*
*
* @return <, >
*/
Map<String, Integer> collectStatsForGroupPositions(String token, Integer projectId) throws ForbiddenException;
List<Integer> findAllProjectNumber(String token, Integer projectId) throws TokenException, BadRequestException;
}

View File

@ -1,9 +1,8 @@
package cn.edu.hfut.rmdjzz.projectmanagement.service;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.Project;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.query.ResultProject;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.ProjectDto;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.BadRequestException;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.TokenException;
import cn.edu.hfut.rmdjzz.projectmanagement.utils.http.RequestPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
@ -16,11 +15,11 @@ import java.util.Map;
*/
public interface IProjectService extends IService<Project> {
Long getAllProjectOfStaff(String token) throws TokenException;
Long getAllProjectOfStaff(String token);
Page<ResultProject> getOnePageProject(String token, RequestPage page, Map<String, Object> params) throws TokenException;
Page<ProjectDto> getOnePageProject(String token, RequestPage page, Map<String, Object> params);
Boolean setProjectCompleted(String token, Integer projectId) throws TokenException, BadRequestException;
Boolean setProjectCompleted(String token, Integer projectId) throws BadRequestException;
Boolean createProject(String token, Project project) throws TokenException, BadRequestException;
Boolean createProject(String token, Project project) throws BadRequestException;
}

View File

@ -1,8 +1,9 @@
package cn.edu.hfut.rmdjzz.projectmanagement.service;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.Task;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.query.ResultTask;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.TaskDto;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.BadRequestException;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.ForbiddenException;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
@ -12,23 +13,29 @@ import java.util.List;
* created at 2022/7/4 14:49
*/
public interface ITaskService extends IService<Task> {
List<ResultTask> getSubTaskList(String token, Integer projectId, Long fatherId) throws BadRequestException;
List<TaskDto> getSubTaskList(String token, Integer projectId, Long fatherId) throws BadRequestException, ForbiddenException;
Boolean existSubTask(String token, Integer projectId, Long taskId) throws BadRequestException;
Boolean existSubTask(String token, Integer projectId, Long taskId) throws BadRequestException, ForbiddenException;
Boolean deleteTaskAndSubTask(String token, Integer projectId, Long taskId) throws BadRequestException;
Boolean deleteTaskAndSubTask(String token, Integer projectId, Long taskId) throws BadRequestException, ForbiddenException;
Boolean closeTaskAndSubTask(String token, Integer projectId, Long taskId) throws BadRequestException;
Integer checkHolder(Integer staffId, Long taskId);
/**
* @return 1:all rights 2:father holder 3:current holder 0:no right
*/
Integer getHolderLevel(Integer staffId, Long taskId);
Integer checkHolder(String token, Long taskId);
/**
* @return 1:all rights 2:father holder 3:current holder 0:no right
*/
Integer getHolderLevel(String token, Long taskId);
List<Task> getMyTaskList(String token, Integer projectId) throws BadRequestException;
Boolean canBeDone(Long taskId);
Task insertTask(String token, Task task) throws BadRequestException;
Task insertTask(String token, Task task) throws BadRequestException, ForbiddenException;
Task modifyTask(String token, Task task) throws BadRequestException;
}

View File

@ -2,7 +2,7 @@ package cn.edu.hfut.rmdjzz.projectmanagement.service.impl;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.ProjectGroup;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.BadRequestException;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.TokenException;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.ForbiddenException;
import cn.edu.hfut.rmdjzz.projectmanagement.mapper.ProjectGroupMapper;
import cn.edu.hfut.rmdjzz.projectmanagement.service.IProjectGroupService;
import cn.edu.hfut.rmdjzz.projectmanagement.utils.TokenUtils;
@ -11,7 +11,9 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author
@ -31,11 +33,71 @@ public class ProjectGroupServiceImpl extends ServiceImpl<ProjectGroupMapper, Pro
return baseMapper.insert(projectGroup) == 1;
}
//FIXME: 应该抛错返回信息而不是catch
@Override
public Integer getUserLevelInGroup(String token, Integer projectId) {
try {
public void insertNewMember(String token, Integer projectId, Integer targetId, String positions) throws ForbiddenException {
int accessLevel = getProjectAccessLevel(token, projectId);
int targetLevel = 3;
if (accessLevel == 0) {
throw new ForbiddenException("无该项目访问权限");
}
if (accessLevel > 2) {
throw new ForbiddenException("无新增成员权限");
}
String[] positionArray = positions.split(",");
for (String position : positionArray) {
if (position.equals("项目经理")) {
throw new ForbiddenException("不能授予他人项目经理职位");
}
if (position.equals("项目主管")) {
if (accessLevel != 1) {
throw new ForbiddenException("无授予项目主管职位权限");
}
targetLevel = 2;
}
}
baseMapper.insert(new ProjectGroup(targetId, projectId, positions, targetLevel));
}
@Override
public void updateStaffPositions(String token, Integer projectId, Integer targetId, String positions) throws ForbiddenException {
int accessLevel = getProjectAccessLevel(token, projectId);
int targetLevel = getProjectAccessLevel(targetId, projectId);
if (accessLevel == 0) {
throw new ForbiddenException("无该项目访问权限");
}
if (accessLevel > 2 || accessLevel >= targetLevel) {
throw new ForbiddenException("无更改此人职位权限");
}
String[] positionArray = positions.split(",");
for (String position : positionArray) {
if (position.equals("项目经理")) {
throw new ForbiddenException("不能授予他人项目经理职位");
}
if (position.equals("项目主管") && accessLevel != 1) {
throw new ForbiddenException("无授予项目主管职位权限");
}
}
baseMapper.update(
new ProjectGroup()
.setProjectId(projectId)
.setStaffId(targetId),
Wrappers.<ProjectGroup>lambdaUpdate().set(ProjectGroup::getProjectStaffPosition, positions)
);
}
@Override
public Integer getProjectAccessLevel(String token, Integer projectId) {
Integer staffId = TokenUtils.getStaffId(token);
return getProjectAccessLevel(staffId, projectId);
}
@Override
public Integer getProjectAccessLevel(Integer staffId, Integer projectId) {
try {
ProjectGroup projectGroup = baseMapper.selectOne(Wrappers.<ProjectGroup>lambdaQuery()
.eq(ProjectGroup::getStaffId, staffId)
.eq(ProjectGroup::getProjectId, projectId)
@ -49,19 +111,38 @@ public class ProjectGroupServiceImpl extends ServiceImpl<ProjectGroupMapper, Pro
}
@Override
public List<Integer> findAllProjectNumber(String token, Integer projectId) throws TokenException, BadRequestException {
public List<Integer> findAllProjectNumber(String token, Integer projectId) throws BadRequestException {
List<Integer> res = new ArrayList<>();
Integer staffId = TokenUtils.getStaffId(token);
List<ProjectGroup> targetProject = baseMapper.selectList(Wrappers.<ProjectGroup>lambdaQuery().eq(ProjectGroup::getProjectId, projectId));
if (targetProject.size() == 0)
throw new BadRequestException("项目不存在");
for (ProjectGroup projectGroup : targetProject) {
res.add(projectGroup.getStaffId());
}
if(!res.contains(staffId))
if (!res.contains(staffId))
throw new BadRequestException("用户请求非法");
return res;
}
@Override
public Map<String, Integer> collectStatsForGroupPositions(String token, Integer projectId) throws ForbiddenException {
if (getProjectAccessLevel(token, projectId) == 0) {
throw new ForbiddenException("无该项目访问权限");
}
Map<String, Integer> res = new HashMap<>();
List<ProjectGroup> infos = baseMapper.selectList(
Wrappers.<ProjectGroup>lambdaQuery()
.select(ProjectGroup::getProjectStaffPosition)
.eq(ProjectGroup::getProjectId, projectId)
);
infos.forEach(info -> {
String[] positions = info.getProjectStaffPosition().split(",");
for (String position : positions) {
res.merge(position, 1, Integer::sum);
}
});
return res;
}
}

View File

@ -1,9 +1,8 @@
package cn.edu.hfut.rmdjzz.projectmanagement.service.impl;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.Project;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.query.ResultProject;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.ProjectDto;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.BadRequestException;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.TokenException;
import cn.edu.hfut.rmdjzz.projectmanagement.mapper.ProjectMapper;
import cn.edu.hfut.rmdjzz.projectmanagement.service.IProjectGroupService;
import cn.edu.hfut.rmdjzz.projectmanagement.service.IProjectService;
@ -31,24 +30,24 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
private IProjectGroupService projectGroupService;
@Override
public Long getAllProjectOfStaff(String token) throws TokenException {
public Long getAllProjectOfStaff(String token) {
Integer staffId = TokenUtils.getStaffId(token);
return baseMapper.findProjectCount(staffId);
}
@Override
public Page<ResultProject> getOnePageProject(
public Page<ProjectDto> getOnePageProject(
String token,
RequestPage page,
Map<String, Object> params
) throws TokenException {
) {
Integer staffId = TokenUtils.getStaffId(token);
IPage<ResultProject> userPage = baseMapper.findMyProject(page.getPage(), staffId, WrapperUtils.allEqAndTimeIntervalQueryWrapper(params));
return (Page<ResultProject>) userPage;
IPage<ProjectDto> userPage = baseMapper.findMyProject(page.getPage(), staffId, WrapperUtils.allEqAndTimeIntervalQueryWrapper(params));
return (Page<ProjectDto>) userPage;
}
@Override
public Boolean setProjectCompleted(String token, Integer projectId) throws TokenException, BadRequestException {
public Boolean setProjectCompleted(String token, Integer projectId) throws BadRequestException {
Integer staffId = TokenUtils.getStaffId(token);
Project project = new Project();
project.setProjectId(projectId);
@ -66,8 +65,9 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
throw new BadRequestException("操作失败");
}
//FIXME: 时间线判断?
@Override
public Boolean createProject(String token, Project project) throws TokenException, BadRequestException {
public Boolean createProject(String token, Project project) throws BadRequestException {
project.setProjectId(null);
project.setCompleted(false);
project.setProjectCreatedTime(null);

View File

@ -1,9 +1,9 @@
package cn.edu.hfut.rmdjzz.projectmanagement.service.impl;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.Task;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.query.ResultTask;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.TaskDto;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.BadRequestException;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.TokenException;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.ForbiddenException;
import cn.edu.hfut.rmdjzz.projectmanagement.mapper.TaskMapper;
import cn.edu.hfut.rmdjzz.projectmanagement.service.ITaskService;
import cn.edu.hfut.rmdjzz.projectmanagement.utils.TokenUtils;
@ -31,27 +31,30 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements IT
//FIXME: 抛出未授权异常
@Override
public List<ResultTask> getSubTaskList(String token, Integer projectId, Long fatherId) throws BadRequestException {
if (projectGroupService.getUserLevelInGroup(token, projectId) == 0 || fatherId == null) {
throw new BadRequestException("错误的访问参数");
public List<TaskDto> getSubTaskList(String token, Integer projectId, Long fatherId) throws ForbiddenException, BadRequestException {
if (projectGroupService.getProjectAccessLevel(token, projectId) == 0) {
throw new ForbiddenException("无该项目访问权限");
}
if (fatherId == null) {
throw new BadRequestException("请求参数错误");
}
return baseMapper.selectSubTaskList(projectId, fatherId);
}
@Override
public Boolean existSubTask(String token, Integer projectId, Long taskId) throws BadRequestException {
if (projectGroupService.getUserLevelInGroup(token, projectId) == 0) {
throw new BadRequestException("请求参数错误");
public Boolean existSubTask(String token, Integer projectId, Long taskId) throws ForbiddenException {
if (projectGroupService.getProjectAccessLevel(token, projectId) == 0) {
throw new ForbiddenException("无该项目访问权限");
}
return baseMapper.exists(Wrappers.<Task>lambdaQuery().eq(Task::getTaskFatherId, taskId));
}
@Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class)
@Override
public Boolean deleteTaskAndSubTask(String token, Integer projectId, Long taskId) throws BadRequestException {
Integer level = checkHolder(token, taskId);
if (projectGroupService.getUserLevelInGroup(token, projectId) == 0) {
throw new BadRequestException("错误参数");
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("无该项目访问权限");
}
if (level == 0 || level == 3) {
throw new BadRequestException("错误父级参数");
@ -76,12 +79,12 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements IT
@Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class)
@Override
public Boolean closeTaskAndSubTask(String token, Integer projectId, Long taskId) throws BadRequestException {
Integer level = checkHolder(token, taskId);
if (projectGroupService.getUserLevelInGroup(token, projectId) == 0) {
throw new BadRequestException("错误参数");
Integer level = getHolderLevel(token, taskId);
if (projectGroupService.getProjectAccessLevel(token, projectId) == 0) {
throw new BadRequestException("无该项目访问权限");
}
if (level == 0) {
throw new BadRequestException("错误父级参数");
throw new BadRequestException("父级参数错误");
}
try {
List<Long> res = new ArrayList<>();
@ -109,11 +112,8 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements IT
}
}
/**
* @return 1:all rights 2:father holder 3:current holder 0:no right
*/
@Override
public Integer checkHolder(Integer staffId, Long taskId) {
public Integer getHolderLevel(Integer staffId, Long taskId) {
try {
Task task = baseMapper.selectOne(Wrappers.<Task>lambdaQuery().eq(Task::getTaskId, taskId));
if (task == null || staffId <= 0)
@ -133,30 +133,18 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements IT
}
}
/**
* @return 1:all rights 2:father holder 3:current holder 0:no right
*/
@Override
public Integer checkHolder(String token, Long taskId) {
try {
public Integer getHolderLevel(String token, Long taskId) {
Integer staffId = TokenUtils.getStaffId(token);
return checkHolder(staffId, taskId);
} catch (Exception e) {
return 0;
}
return getHolderLevel(staffId, taskId);
}
@Override
public List<Task> getMyTaskList(String token, Integer projectId) throws BadRequestException {
if (projectGroupService.getUserLevelInGroup(token, projectId) == 0) {
throw new BadRequestException("错误的访问参数");
}
Integer staffId = 0;
try {
staffId = TokenUtils.getStaffId(token);
} catch (TokenException e) {
//impossible
if (projectGroupService.getProjectAccessLevel(token, projectId) == 0) {
throw new BadRequestException("无该项目访问权限");
}
Integer staffId = TokenUtils.getStaffId(token);
return baseMapper.selectList(Wrappers.<Task>lambdaQuery()
.eq(Task::getTaskHolderId, staffId)
.eq(Task::getTaskProjectId, projectId)
@ -183,19 +171,19 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements IT
}
@Override
public Task insertTask(String token, Task task) throws BadRequestException {
public Task insertTask(String token, Task task) throws BadRequestException, ForbiddenException {
task.setTaskId(null);
Integer userLevel = projectGroupService.getUserLevelInGroup(token, task.getTaskProjectId());
Integer userLevel = projectGroupService.getProjectAccessLevel(token, task.getTaskProjectId());
if (userLevel == 0) {
System.out.println(userLevel);
throw new BadRequestException("错误的操作");
throw new ForbiddenException("无该项目访问权限");
}
if (!task.checkInsert()) {
throw new BadRequestException("工作项参数错误");
}
try {
Task father = baseMapper.selectOne(Wrappers.<Task>lambdaQuery().eq(Task::getTaskId, task.getTaskFatherId()));
if (!task.checkLegalFather(father) || (checkHolder(token, task.getTaskFatherId()) == 0 && userLevel == 3)) {
if (!task.checkLegalFather(father) || (getHolderLevel(token, task.getTaskFatherId()) == 0 && userLevel == 3)) {
throw new BadRequestException("无法指定该父级");
}
task.setTaskCreatedTime(LocalDateTime.now());
@ -214,9 +202,9 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements IT
@Override
public Task modifyTask(String token, Task task) throws BadRequestException {
Integer userLevel = projectGroupService.getUserLevelInGroup(token, task.getTaskProjectId());
Integer userLevel = projectGroupService.getProjectAccessLevel(token, task.getTaskProjectId());
Task rawTask = baseMapper.selectOne(Wrappers.<Task>lambdaQuery().eq(Task::getTaskId, task.getTaskId()));
if (userLevel == 0 || (userLevel == 3 && checkHolder(token, task.getTaskId()) == 0)) {
if (userLevel == 0 || (userLevel == 3 && getHolderLevel(token, task.getTaskId()) == 0)) {
throw new BadRequestException("没有权限");
}
int typeChangeValue = 0;

View File

@ -6,30 +6,26 @@ import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Date;
import java.util.concurrent.TimeUnit;
/**
* @author
* created at 2022/6/28 18:20
*/
//TODO: 演示的时候把expireTime改短点儿
@Component
public final class TokenUtils {
public final static String pvKey = "SignedByRMDJZZ";
public static String getToken(String staffUsername, Integer staffId,Long duration) {
public static String getToken(String staffUsername, Integer staffId, Long duration) {
return JWT.create()
.withClaim("staffUsername", staffUsername)
.withClaim("staffId", staffId)
.withClaim("duration",duration)
.withClaim("duration", duration)
.withIssuedAt(new Date())
.withExpiresAt(new Date(System.currentTimeMillis() + duration*1000L))
.withExpiresAt(new Date(System.currentTimeMillis() + duration * 1000L))
.sign(Algorithm.HMAC256(pvKey));
}
@ -43,35 +39,27 @@ public final class TokenUtils {
}
}
public static boolean checkTimeOut(String token) throws TokenException {
if (!checkToken(token))
return true;
public static boolean checkTimeOut(String token) {
return JWT.decode(token).getClaim("exp").asLong() < (System.currentTimeMillis() / 1000);
}
public static String getUsername(String token) throws TokenException {
if (!checkToken(token))
return null;
public static String getUsername(String token) {
return JWT.decode(token).getClaim("staffUsername").asString();
}
public static Integer getStaffId(String token) throws TokenException {
if (!checkToken(token))
return null;
public static Integer getStaffId(String token) {
return JWT.decode(token).getClaim("staffId").asInt();
}
public static Long getDuration(String token) throws TokenException {
if (!checkToken(token))
return null;
public static Long getDuration(String token) {
return JWT.decode(token).getClaim("duration").asLong();
}
public static String refreshToken(String token) throws TokenException {
return getToken(getUsername(token), getStaffId(token),getDuration(token));
public static String refreshToken(String token) {
return getToken(getUsername(token), getStaffId(token), getDuration(token));
}
public static String autoRequire(String token) throws TokenException {
boolean check = checkToken(token);
if (check) {
public static String autoRequire(String token) {
DecodedJWT jwt = JWT.decode(token);
long current = System.currentTimeMillis() / 1000;
Long start = jwt.getClaim("iat").asLong();
@ -81,8 +69,5 @@ public final class TokenUtils {
} else {
return token;
}
} else {
return "";
}
}
}

View File

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.edu.hfut.rmdjzz.projectmanagement.mapper.ProjectMapper">
<resultMap id="resultProject" type="cn.edu.hfut.rmdjzz.projectmanagement.entity.query.ResultProject">
<resultMap id="projectDto" type="cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.ProjectDto">
<id property="projectId" column="project_id"/>
<result property="completed" column="is_completed"/>
<result property="deleted" column="is_deleted"/>
</resultMap>
<select id="findMyProject" resultMap="resultProject">
<select id="findMyProject" resultMap="projectDto">
SELECT *
FROM (SELECT project_id,
project_name,

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.edu.hfut.rmdjzz.projectmanagement.mapper.TaskMapper">
<select id="selectSubTaskList" resultType="cn.edu.hfut.rmdjzz.projectmanagement.entity.query.ResultTask">
<select id="selectSubTaskList" resultType="cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.TaskDto">
SELECT task_id,
task_name,
task_project_id,