规范了代码,修复了closeTask没法正常工作的bug,增加了限流控制(未测试)
parent
16200365d9
commit
1afafa8818
10
pom.xml
10
pom.xml
|
@ -39,6 +39,10 @@
|
|||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
@ -71,6 +75,7 @@
|
|||
<artifactId>spring-security-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
|
@ -117,6 +122,11 @@
|
|||
<artifactId>poi-ooxml</artifactId>
|
||||
<version>5.2.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>31.1-jre</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -2,6 +2,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.TooManyRequestException;
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.exception.UnauthorizedException;
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.utils.http.ResponseMap;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
@ -51,4 +52,10 @@ public class ExceptionHandlerAdvice {
|
|||
.collect(Collectors.joining(","))
|
||||
);
|
||||
}
|
||||
|
||||
@ExceptionHandler(TooManyRequestException.class)
|
||||
@ResponseStatus(HttpStatus.TOO_MANY_REQUESTS)
|
||||
public ResponseMap handleTooManyRequestException(TooManyRequestException e) {
|
||||
return ResponseMap.of(HttpStatus.TOO_MANY_REQUESTS.value(), e.getMessage());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package cn.edu.hfut.rmdjzz.projectmanagement.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author 佘语殊
|
||||
* @since 2022/7/11 16:57
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Target({ElementType.METHOD})
|
||||
public @interface RateLimit {
|
||||
|
||||
/**
|
||||
* 流量控制令牌桶标识符
|
||||
*/
|
||||
String key() default "";
|
||||
|
||||
int permitsPerSecond();
|
||||
|
||||
long timeout() default 0;
|
||||
|
||||
TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
|
||||
|
||||
long maxBurstSeconds() default 1;
|
||||
|
||||
String msg() default "系统繁忙,请稍后再试";
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package cn.edu.hfut.rmdjzz.projectmanagement.aop;
|
||||
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.annotation.RateLimit;
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.exception.TooManyRequestException;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.util.concurrent.RateLimiter;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author 佘语殊
|
||||
* @since 2022/7/11 17:23
|
||||
*/
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
@Aspect
|
||||
@Component
|
||||
public class RateLimitAOP {
|
||||
private final Map<String, RateLimiter> rateLimitMap = Maps.newConcurrentMap();
|
||||
|
||||
@Around("@annotation(cn.edu.hfut.rmdjzz.projectmanagement.annotation.RateLimit)")
|
||||
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
Method method = signature.getMethod();
|
||||
RateLimit limit = method.getAnnotation(RateLimit.class);
|
||||
if (limit == null) {
|
||||
return joinPoint.proceed();
|
||||
}
|
||||
|
||||
String key = limit.key();
|
||||
RateLimiter limiter = rateLimitMap.get(key);
|
||||
if (limiter == null) {
|
||||
limiter = RateLimiter.create(limit.permitsPerSecond());
|
||||
Class<? extends RateLimiter> clazz = limiter.getClass();
|
||||
//TODO: DEBUG TEST
|
||||
Field burstSecondsField = clazz.getDeclaredField("maxBurstSeconds");
|
||||
burstSecondsField.setAccessible(true);
|
||||
burstSecondsField.set(limiter, limit.maxBurstSeconds());
|
||||
rateLimitMap.put(key, limiter);
|
||||
}
|
||||
|
||||
if (!limiter.tryAcquire(limit.timeout(), limit.timeUnit())) {
|
||||
throw new TooManyRequestException(limit.msg());
|
||||
}
|
||||
return joinPoint.proceed();
|
||||
}
|
||||
}
|
|
@ -29,7 +29,7 @@ public class AnnouncementController {
|
|||
|
||||
@SneakyThrows
|
||||
@GetMapping
|
||||
public ResponseList<AnnouncementDTO> getAnnouncementList(@RequestHeader("Token") String token, @PathVariable Integer projectId) {
|
||||
public ResponseList<AnnouncementDTO> getAnnouncementList(@RequestHeader(TokenUtils.HEADER_TOKEN) String token, @PathVariable Integer projectId) {
|
||||
if (projectGroupService.getProjectAccessLevel(token, projectId) == 0) {
|
||||
throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS_PROJECT);
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ public class AnnouncementController {
|
|||
@SneakyThrows
|
||||
@GetMapping("/{announcementId}")
|
||||
public ResponseMap getAnnouncementById(
|
||||
@RequestHeader("Token") String token,
|
||||
@RequestHeader(TokenUtils.HEADER_TOKEN) String token,
|
||||
@PathVariable Integer projectId,
|
||||
@PathVariable Long announcementId
|
||||
) {
|
||||
|
@ -52,7 +52,7 @@ public class AnnouncementController {
|
|||
@SneakyThrows
|
||||
@PostMapping
|
||||
public ResponseMap createAnnouncement(
|
||||
@RequestHeader("Token") String token,
|
||||
@RequestHeader(TokenUtils.HEADER_TOKEN) String token,
|
||||
@PathVariable Integer projectId,
|
||||
@RequestBody Announcement announcement
|
||||
) {
|
||||
|
@ -73,7 +73,7 @@ public class AnnouncementController {
|
|||
/*@SneakyThrows
|
||||
@PutMapping("/{announcementId}")
|
||||
public ResponseMap modifyAnnouncement(
|
||||
@RequestHeader("Token") String token,
|
||||
@RequestHeader(TokenUtils.HEADER_TOKEN) String token,
|
||||
@PathVariable Integer projectId,
|
||||
@PathVariable Long announcementId,
|
||||
@RequestBody Announcement announcement
|
||||
|
@ -88,7 +88,7 @@ public class AnnouncementController {
|
|||
@SneakyThrows
|
||||
@DeleteMapping("/{announcementId}")
|
||||
public ResponseMap deleteAnnouncement(
|
||||
@RequestHeader("Token") String token,
|
||||
@RequestHeader(TokenUtils.HEADER_TOKEN) String token,
|
||||
@PathVariable Integer projectId,
|
||||
@PathVariable Long announcementId
|
||||
) {
|
||||
|
|
|
@ -5,6 +5,7 @@ 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;
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.utils.TokenUtils;
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.utils.http.RequestPage;
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.utils.http.ResponseList;
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.utils.http.ResponseMap;
|
||||
|
@ -35,7 +36,7 @@ public class ProjectController {
|
|||
@SneakyThrows
|
||||
@GetMapping
|
||||
public ResponseList<ProjectDTO> getProjectListOfStaff(
|
||||
@RequestHeader("Token") String token,
|
||||
@RequestHeader(TokenUtils.HEADER_TOKEN) String token,
|
||||
@Valid RequestPage page,
|
||||
@Parameter(description = "参数列表见Project实体类,时间可以用xxxxStart与xxxxEnd来确定区间"
|
||||
, required = true) @RequestParam("paramMap") Map<String, Object> paramMap
|
||||
|
@ -47,7 +48,7 @@ public class ProjectController {
|
|||
@SneakyThrows
|
||||
@GetMapping("/{projectId}")
|
||||
public ResponseMap getOneProjectBasicInfo(
|
||||
@RequestHeader("Token") String token,
|
||||
@RequestHeader(TokenUtils.HEADER_TOKEN) String token,
|
||||
@PathVariable("projectId") Integer projectId
|
||||
) {
|
||||
if (projectGroupService.getProjectAccessLevel(token, projectId) == 0) {
|
||||
|
@ -59,7 +60,7 @@ public class ProjectController {
|
|||
@Operation(description = "根据Token获取该员工的Project数")
|
||||
@SneakyThrows
|
||||
@GetMapping("/count")
|
||||
public ResponseMap getProjectNumOfStaff(@RequestHeader("Token") String token) {
|
||||
public ResponseMap getProjectNumOfStaff(@RequestHeader(TokenUtils.HEADER_TOKEN) String token) {
|
||||
return ResponseMap.ofSuccess()
|
||||
.put("totalNum", projectService.countMyProjects(token));
|
||||
}
|
||||
|
@ -67,7 +68,7 @@ public class ProjectController {
|
|||
@SneakyThrows
|
||||
@PostMapping("/complete")
|
||||
public ResponseMap completeProject(
|
||||
@RequestHeader("Token") String token,
|
||||
@RequestHeader(TokenUtils.HEADER_TOKEN) String token,
|
||||
@Parameter(description = "只需要传projectId即可,例:{\"projectId\": 1}")
|
||||
@RequestBody Map<String, Object> map
|
||||
) {
|
||||
|
@ -78,7 +79,7 @@ public class ProjectController {
|
|||
|
||||
@SneakyThrows
|
||||
@PostMapping
|
||||
public ResponseMap createProject(@RequestHeader("Token") String token, @RequestBody Project project) {
|
||||
public ResponseMap createProject(@RequestHeader(TokenUtils.HEADER_TOKEN) String token, @RequestBody Project project) {
|
||||
projectService.createProject(token, project);
|
||||
return ResponseMap.ofSuccess();
|
||||
}
|
||||
|
@ -86,7 +87,7 @@ public class ProjectController {
|
|||
@SneakyThrows
|
||||
@PutMapping("/{projectId}")
|
||||
public ResponseMap updateProject(
|
||||
@RequestHeader("Token") String token,
|
||||
@RequestHeader(TokenUtils.HEADER_TOKEN) String token,
|
||||
@PathVariable Integer projectId,
|
||||
@RequestBody Project project
|
||||
) {
|
||||
|
@ -100,7 +101,7 @@ public class ProjectController {
|
|||
@SneakyThrows
|
||||
@GetMapping("/{projectId}/stats")
|
||||
public ResponseMap getProjectProcess(
|
||||
@RequestHeader("Token") String token,
|
||||
@RequestHeader(TokenUtils.HEADER_TOKEN) String token,
|
||||
@PathVariable Integer projectId
|
||||
) {
|
||||
return ResponseMap.ofSuccess(projectService.getProjectProcess(token, projectId));
|
||||
|
|
|
@ -43,7 +43,7 @@ public class ProjectGroupController {
|
|||
@GetMapping
|
||||
public ResponseList<ProjectGroupDTO> getGroupMembers(
|
||||
@PathVariable Integer projectId,
|
||||
@RequestHeader("Token") String token,
|
||||
@RequestHeader(TokenUtils.HEADER_TOKEN) String token,
|
||||
RequestPage page
|
||||
) {
|
||||
if (projectGroupService.getProjectAccessLevel(token, projectId) == 0) {
|
||||
|
@ -59,7 +59,7 @@ public class ProjectGroupController {
|
|||
@SneakyThrows
|
||||
@GetMapping("/{staffId}")
|
||||
public ResponseMap getDesignatedStaffPosition(
|
||||
@RequestHeader("Token") String token,
|
||||
@RequestHeader(TokenUtils.HEADER_TOKEN) String token,
|
||||
@PathVariable Integer projectId,
|
||||
@PathVariable Integer staffId
|
||||
) {
|
||||
|
@ -77,7 +77,7 @@ public class ProjectGroupController {
|
|||
@SneakyThrows
|
||||
@PostMapping
|
||||
public ResponseMap addGroupMember(
|
||||
@RequestHeader("Token") String token,
|
||||
@RequestHeader(TokenUtils.HEADER_TOKEN) String token,
|
||||
@PathVariable Integer projectId,
|
||||
@Parameter(description = "只传staffUsername和projectStaffPosition") @RequestBody GroupPositionVO groupPosition
|
||||
) {
|
||||
|
@ -91,7 +91,7 @@ public class ProjectGroupController {
|
|||
@SneakyThrows
|
||||
@PutMapping("/{staffId}")
|
||||
public ResponseMap modifyDesignatedStaffPosition(
|
||||
@RequestHeader("Token") String token,
|
||||
@RequestHeader(TokenUtils.HEADER_TOKEN) String token,
|
||||
@PathVariable Integer projectId,
|
||||
@PathVariable Integer staffId,
|
||||
@Parameter(description = "在body中只传projectStaffPosition") @RequestBody GroupPositionVO groupPosition
|
||||
|
@ -105,7 +105,7 @@ public class ProjectGroupController {
|
|||
@SneakyThrows
|
||||
@GetMapping("/stats")
|
||||
public ResponseMap getGroupPositionsStatistics(
|
||||
@RequestHeader("Token") String token,
|
||||
@RequestHeader(TokenUtils.HEADER_TOKEN) String token,
|
||||
@PathVariable Integer projectId
|
||||
) {
|
||||
return ResponseMap.ofSuccess(projectGroupService.collectStatsForGroupPositions(token, projectId));
|
||||
|
@ -114,7 +114,7 @@ public class ProjectGroupController {
|
|||
@SneakyThrows
|
||||
@GetMapping("/{staffId}/stats")
|
||||
public ResponseList<StaffProcessDTO> getProjectProcessOfStaff(
|
||||
@RequestHeader("Token") String token,
|
||||
@RequestHeader(TokenUtils.HEADER_TOKEN) String token,
|
||||
@PathVariable Integer projectId,
|
||||
@PathVariable Integer staffId
|
||||
) {
|
||||
|
@ -129,7 +129,7 @@ public class ProjectGroupController {
|
|||
@SneakyThrows
|
||||
@PutMapping("/{staffId}/transfer")
|
||||
public ResponseMap transferStaffTasks(
|
||||
@RequestHeader("Token") String token,
|
||||
@RequestHeader(TokenUtils.HEADER_TOKEN) String token,
|
||||
@PathVariable Integer projectId,
|
||||
@PathVariable Integer staffId,
|
||||
@RequestBody Map<Long, Integer> transferMap
|
||||
|
|
|
@ -39,7 +39,7 @@ public class StaffController {
|
|||
|
||||
@SneakyThrows
|
||||
@PostMapping("/logout")
|
||||
public ResponseMap logout(@RequestHeader("Token") String token) {
|
||||
public ResponseMap logout(@RequestHeader(TokenUtils.HEADER_TOKEN) String token) {
|
||||
if (staffService.logout(token)) {
|
||||
return ResponseMap.ofSuccess("登出成功");
|
||||
}
|
||||
|
@ -49,8 +49,8 @@ public class StaffController {
|
|||
@SneakyThrows
|
||||
@PostMapping(value = "/import")
|
||||
public ResponseMap importStaffs(
|
||||
@RequestHeader("Token") String token,
|
||||
@RequestHeader("File-Digest") String digest,
|
||||
@RequestHeader(TokenUtils.HEADER_TOKEN) String token,
|
||||
@RequestHeader(FileUtils.HEADER_FILE_DIGEST) String digest,
|
||||
@RequestParam("uploadFile") MultipartFile uploadFile
|
||||
) {
|
||||
if (null == uploadFile) {
|
||||
|
@ -69,15 +69,15 @@ public class StaffController {
|
|||
|
||||
@SneakyThrows
|
||||
@GetMapping("/import/template")
|
||||
public ResponseMap downloadTemplate(
|
||||
@RequestHeader("Token") String token,
|
||||
public void downloadTemplate(
|
||||
@RequestHeader(TokenUtils.HEADER_TOKEN) String token,
|
||||
HttpServletResponse response
|
||||
) {
|
||||
if (TokenUtils.getStaffGlobalLevel(token) > 2) {
|
||||
throw new ForbiddenException(ForbiddenException.UNABLE_TO_OPERATE);
|
||||
}
|
||||
if (FileUtils.downloadResource("static/账户导入模板.xlsx", response)) {
|
||||
return ResponseMap.ofSuccess();
|
||||
return;
|
||||
}
|
||||
throw new BadRequestException(BadRequestException.OPERATE_FAILED);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import cn.edu.hfut.rmdjzz.projectmanagement.entity.dto.TaskDTO;
|
|||
import cn.edu.hfut.rmdjzz.projectmanagement.exception.BadRequestException;
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.service.IProjectService;
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.service.ITaskService;
|
||||
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 lombok.SneakyThrows;
|
||||
|
@ -27,7 +28,7 @@ public class TaskController {
|
|||
@SneakyThrows
|
||||
@GetMapping("/{fatherId}/subtask")
|
||||
public ResponseList<TaskDTO> getSubTaskList(
|
||||
@RequestHeader("Token") String token,
|
||||
@RequestHeader(TokenUtils.HEADER_TOKEN) String token,
|
||||
@PathVariable("projectId") Integer projectId,
|
||||
@PathVariable("fatherId") Long fatherId
|
||||
) {
|
||||
|
@ -37,7 +38,7 @@ public class TaskController {
|
|||
|
||||
@SneakyThrows
|
||||
@GetMapping("/mine")
|
||||
public ResponseList<Task> getMyTasks(@RequestHeader("Token") String token, @PathVariable("projectId") Integer projectId) {
|
||||
public ResponseList<Task> getMyTasks(@RequestHeader(TokenUtils.HEADER_TOKEN) String token, @PathVariable("projectId") Integer projectId) {
|
||||
List<Task> result = taskService.listMyTasks(token, projectId);
|
||||
return ResponseList.ofSuccess(result);
|
||||
}
|
||||
|
@ -45,7 +46,7 @@ public class TaskController {
|
|||
@SneakyThrows
|
||||
@GetMapping("/subtask/exist")
|
||||
public ResponseMap existSubTask(
|
||||
@RequestHeader("Token") String token,
|
||||
@RequestHeader(TokenUtils.HEADER_TOKEN) String token,
|
||||
@PathVariable("projectId") Integer projectId,
|
||||
@RequestParam("taskId") Long taskId
|
||||
) {
|
||||
|
@ -56,7 +57,7 @@ public class TaskController {
|
|||
@SneakyThrows
|
||||
@PostMapping
|
||||
public ResponseMap createTask(
|
||||
@RequestHeader("Token") String token,
|
||||
@RequestHeader(TokenUtils.HEADER_TOKEN) String token,
|
||||
@PathVariable("projectId") Integer projectId,
|
||||
@RequestBody Task task
|
||||
) {
|
||||
|
@ -70,7 +71,7 @@ public class TaskController {
|
|||
@SneakyThrows
|
||||
@PutMapping("/{taskId}")
|
||||
public ResponseMap modifyTask(
|
||||
@RequestHeader("Token") String token,
|
||||
@RequestHeader(TokenUtils.HEADER_TOKEN) String token,
|
||||
@PathVariable("projectId") Integer projectId,
|
||||
@PathVariable("taskId") Long taskId,
|
||||
@RequestBody Task task
|
||||
|
@ -86,7 +87,7 @@ public class TaskController {
|
|||
@SneakyThrows
|
||||
@DeleteMapping("/{taskId}")
|
||||
public ResponseMap deleteTaskAndSubTask(
|
||||
@RequestHeader("Token") String token,
|
||||
@RequestHeader(TokenUtils.HEADER_TOKEN) String token,
|
||||
@PathVariable("projectId") Integer projectId,
|
||||
@PathVariable("taskId") Long taskId
|
||||
) {
|
||||
|
@ -99,7 +100,7 @@ public class TaskController {
|
|||
@SneakyThrows
|
||||
@GetMapping("/stats")
|
||||
public ResponseMap getTaskTrend(
|
||||
@RequestHeader("Token") String token,
|
||||
@RequestHeader(TokenUtils.HEADER_TOKEN) String token,
|
||||
@PathVariable Integer projectId
|
||||
) {
|
||||
if(!projectService.checkOpenStatus(projectId)) {
|
||||
|
|
|
@ -57,6 +57,7 @@ public class Task {
|
|||
"demandSource:需求来源 (String), estimatedManHours:预估工时 (Integer), severity:严重程度 (String), recurrenceProbability:复现概率 (String)")
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private Map<String, Object> attachedInfo;
|
||||
private Integer childrenCount;
|
||||
@TableField("is_deleted")
|
||||
@TableLogic
|
||||
private Boolean deleted;
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
package cn.edu.hfut.rmdjzz.projectmanagement.exception;
|
||||
|
||||
/**
|
||||
* @author 佘语殊
|
||||
* @since 2022/7/11 17:35
|
||||
*/
|
||||
public class TooManyRequestException extends Exception {
|
||||
public TooManyRequestException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
|
@ -27,7 +27,7 @@ public class TokenInterceptor implements HandlerInterceptor {
|
|||
@Override
|
||||
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws TokenException {
|
||||
System.out.println(httpServletRequest.getRequestURL() + " " + httpServletRequest.getMethod());
|
||||
String token = httpServletRequest.getHeader("Token");
|
||||
String token = httpServletRequest.getHeader(TokenUtils.HEADER_TOKEN);
|
||||
if (null == token || "".equals(token.trim())) {
|
||||
throw new TokenException("缺少Token");
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ public class TokenInterceptor implements HandlerInterceptor {
|
|||
Objects.requireNonNull(TokenUtils.getDuration(token)), TimeUnit.SECONDS
|
||||
);
|
||||
}
|
||||
httpServletResponse.setHeader("Token", newToken);
|
||||
httpServletResponse.setHeader(TokenUtils.HEADER_TOKEN, newToken);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ public interface ITaskService extends IService<Task> {
|
|||
|
||||
Task modifyTask(String token, Task task) throws BadRequestException, ForbiddenException;
|
||||
|
||||
Map<String, List<TaskTrendDTO>> getProjectTaskTrend(String token, Integer projectId) throws BadRequestException, ForbiddenException;
|
||||
Map<String, List<TaskTrendDTO>> getProjectTaskTrend(String token, Integer projectId) throws ForbiddenException;
|
||||
|
||||
Boolean transferStaffTasks(String token, Integer projectId, Integer transferredStaffId, Map<Long, Integer> transferMap) throws ForbiddenException, BadRequestException;
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ public class StaffServiceImpl extends ServiceImpl<StaffMapper, Staff> implements
|
|||
Objects.requireNonNull(TokenUtils.getDuration(token)), TimeUnit.SECONDS
|
||||
);
|
||||
return new MapBuilder()
|
||||
.put("Token", token)
|
||||
.put(TokenUtils.HEADER_TOKEN, token)
|
||||
.putAll(BeanUtils.beanToMap(staff, false))
|
||||
.build();
|
||||
}
|
||||
|
|
|
@ -246,13 +246,14 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements IT
|
|||
throw new BadRequestException("还有子工作尚未完成");
|
||||
}
|
||||
try {
|
||||
boolean closed = false;
|
||||
if (typeChangeValue != 0) {
|
||||
task.setTaskClosedTime(LocalDateTime.now());
|
||||
}
|
||||
if (typeChangeValue == 2) {
|
||||
closeTaskAndSubTask(token, task.getTaskProjectId(), task.getTaskId());
|
||||
closed = closeTaskAndSubTask(token, task.getTaskProjectId(), task.getTaskId());
|
||||
}
|
||||
if (baseMapper.update(task, Wrappers.<Task>lambdaQuery().eq(Task::getTaskId, task.getTaskId())) == 0) {
|
||||
if (!closed && baseMapper.update(task, Wrappers.<Task>lambdaQuery().eq(Task::getTaskId, task.getTaskId())) == 0) {
|
||||
throw new BadRequestException(BadRequestException.OPERATE_FAILED);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -263,7 +264,7 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements IT
|
|||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<TaskTrendDTO>> getProjectTaskTrend(String token, Integer projectId) throws BadRequestException, ForbiddenException {
|
||||
public Map<String, List<TaskTrendDTO>> getProjectTaskTrend(String token, Integer projectId) throws ForbiddenException {
|
||||
if (projectGroupService.getProjectAccessLevel(token, projectId) == 0) {
|
||||
throw new ForbiddenException(ForbiddenException.UNABLE_TO_OPERATE);
|
||||
}
|
||||
|
|
|
@ -6,25 +6,36 @@ import org.springframework.util.MimeTypeUtils;
|
|||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.*;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* @author 佘语殊
|
||||
* @since 2022/7/11 9:32
|
||||
*/
|
||||
public class FileUtils {
|
||||
|
||||
public static final String HEADER_FILE_DIGEST = "File-Digest";
|
||||
|
||||
/**
|
||||
* 直接在响应体中用八位字节流输出文件内容,并在响应头中加入File-Digest作为md5文件摘要校验码
|
||||
* <p>
|
||||
* 在Controller层调用时需要返回void
|
||||
*/
|
||||
public static Boolean downloadResource(String resourceName, HttpServletResponse response) throws IOException {
|
||||
@Cleanup InputStream is = FileUtils.class.getResourceAsStream(resourceName);
|
||||
if (is == null) {
|
||||
throw new FileNotFoundException("该文件不存在");
|
||||
}
|
||||
@Cleanup BufferedInputStream bis = new BufferedInputStream(is);
|
||||
@Cleanup InputStream is = FileUtils.class.getClassLoader().getResourceAsStream(resourceName);
|
||||
BufferedInputStream bis = new BufferedInputStream(is);
|
||||
bis.mark(bis.available() + 1);
|
||||
response.setContentType(MimeTypeUtils.APPLICATION_OCTET_STREAM_VALUE);
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
ServletOutputStream out = response.getOutputStream();
|
||||
response.addHeader("File-Digest", DigestUtils.md5DigestAsHex(bis));
|
||||
response.addHeader(HEADER_FILE_DIGEST, DigestUtils.md5DigestAsHex(bis));
|
||||
bis.reset();
|
||||
@Cleanup BufferedOutputStream bos = new BufferedOutputStream(out);
|
||||
bis.transferTo(bos);
|
||||
bis.close();
|
||||
bos.flush();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import java.util.Date;
|
|||
public final class TokenUtils {
|
||||
private final static String PV_KEY = "SignedByRMDJZZ";
|
||||
|
||||
public final static String HEADER_TOKEN = "Token";
|
||||
private final static String STAFF_USERNAME = "staffUsername";
|
||||
private final static String STAFF_ID = "staffId";
|
||||
private final static String STAFF_GLOBAL_LEVEL = "staffGlobalLevel";
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue