Compare commits
4 Commits
deb17f2f6c
...
5d62c9af3a
Author | SHA1 | Date |
---|---|---|
ArgonarioD | 5d62c9af3a | |
ArgonarioD | 90090bedf6 | |
ArgonarioD | 8ed85fade0 | |
ArgonarioD | fc481bdd17 |
|
@ -11,6 +11,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
* @author 张韬
|
* @author 张韬
|
||||||
* created at 2022/6/28 19:44
|
* created at 2022/6/28 19:44
|
||||||
*/
|
*/
|
||||||
|
//TODO: 整机限流
|
||||||
@Configuration
|
@Configuration
|
||||||
public class WebConfig implements WebMvcConfigurer {
|
public class WebConfig implements WebMvcConfigurer {
|
||||||
@Bean
|
@Bean
|
||||||
|
|
|
@ -20,6 +20,7 @@ import lombok.SneakyThrows;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -122,4 +123,20 @@ public class ProjectGroupController {
|
||||||
}
|
}
|
||||||
return ResponseList.ofSuccess(taskService.getProjectProcessOfStaff(token, projectId));
|
return ResponseList.ofSuccess(taskService.getProjectProcessOfStaff(token, projectId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: TEST
|
||||||
|
@Operation(description = "请求体是一个key为taskId,value为staffId的map")
|
||||||
|
@SneakyThrows
|
||||||
|
@PutMapping("/{staffId}/transfer")
|
||||||
|
public ResponseMap transferStaffTasks(
|
||||||
|
@RequestHeader("Token") String token,
|
||||||
|
@PathVariable Integer projectId,
|
||||||
|
@PathVariable Integer staffId,
|
||||||
|
@RequestBody Map<Long, Integer> transferMap
|
||||||
|
) {
|
||||||
|
if (taskService.transferStaffTasks(token, projectId, staffId, transferMap)) {
|
||||||
|
return ResponseMap.ofSuccess();
|
||||||
|
}
|
||||||
|
throw new BadRequestException(BadRequestException.OPERATE_FAILED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,11 @@ package cn.edu.hfut.rmdjzz.projectmanagement.controller;
|
||||||
|
|
||||||
import cn.edu.hfut.rmdjzz.projectmanagement.entity.Staff;
|
import cn.edu.hfut.rmdjzz.projectmanagement.entity.Staff;
|
||||||
import cn.edu.hfut.rmdjzz.projectmanagement.exception.BadRequestException;
|
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.exception.TokenException;
|
||||||
import cn.edu.hfut.rmdjzz.projectmanagement.service.IStaffService;
|
import cn.edu.hfut.rmdjzz.projectmanagement.service.IStaffService;
|
||||||
|
import cn.edu.hfut.rmdjzz.projectmanagement.utils.FileUtils;
|
||||||
|
import cn.edu.hfut.rmdjzz.projectmanagement.utils.TokenUtils;
|
||||||
import cn.edu.hfut.rmdjzz.projectmanagement.utils.http.ResponseMap;
|
import cn.edu.hfut.rmdjzz.projectmanagement.utils.http.ResponseMap;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
|
@ -12,6 +15,7 @@ import org.springframework.util.DigestUtils;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,8 +47,12 @@ public class StaffController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
@PostMapping(value = "/staff/import")
|
@PostMapping(value = "/import")
|
||||||
public ResponseMap upload(@RequestHeader("Token") String token, @RequestParam("uploadFile") MultipartFile uploadFile,@RequestParam("digest") String digest) {
|
public ResponseMap importStaffs(
|
||||||
|
@RequestHeader("Token") String token,
|
||||||
|
@RequestParam("File-Digest") String digest,
|
||||||
|
@RequestParam("uploadFile") MultipartFile uploadFile
|
||||||
|
) {
|
||||||
if (null == uploadFile) {
|
if (null == uploadFile) {
|
||||||
throw new BadRequestException("文件传输错误");
|
throw new BadRequestException("文件传输错误");
|
||||||
}
|
}
|
||||||
|
@ -58,4 +66,19 @@ public class StaffController {
|
||||||
Integer successCount = staffService.multiImport(token, uploadFile);
|
Integer successCount = staffService.multiImport(token, uploadFile);
|
||||||
return ResponseMap.ofSuccess("成功导入" + successCount + "条数据");
|
return ResponseMap.ofSuccess("成功导入" + successCount + "条数据");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
@GetMapping("/import/template")
|
||||||
|
public ResponseMap downloadTemplate(
|
||||||
|
@RequestHeader("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();
|
||||||
|
}
|
||||||
|
throw new BadRequestException(BadRequestException.OPERATE_FAILED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package cn.edu.hfut.rmdjzz.projectmanagement.entity;
|
package cn.edu.hfut.rmdjzz.projectmanagement.entity;
|
||||||
|
|
||||||
import cn.edu.hfut.rmdjzz.projectmanagement.service.IProjectGroupService;
|
|
||||||
import cn.edu.hfut.rmdjzz.projectmanagement.utils.BeanUtils;
|
import cn.edu.hfut.rmdjzz.projectmanagement.utils.BeanUtils;
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
@ -8,8 +7,8 @@ import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -19,19 +18,17 @@ import java.util.Objects;
|
||||||
* @author 阳勇权
|
* @author 阳勇权
|
||||||
* @since 2022/7/4 11:07
|
* @since 2022/7/4 11:07
|
||||||
*/
|
*/
|
||||||
|
@Builder
|
||||||
@Data
|
@Data
|
||||||
public class Task {
|
public class Task {
|
||||||
@Autowired
|
|
||||||
private IProjectGroupService projectGroupService;
|
|
||||||
public static final String ATTACH_DEMAND_SOURCE = "demandSource";
|
public static final String ATTACH_DEMAND_SOURCE = "demandSource";
|
||||||
public static final String ATTACH_ESTIMATED_MAN_HOURS = "estimatedManHours";
|
public static final String ATTACH_ESTIMATED_MAN_HOURS = "estimatedManHours";
|
||||||
public static final String ATTACH_SEVERITY = "severity";
|
public static final String ATTACH_SEVERITY = "severity";
|
||||||
public static final String ATTACH_RECURRENCE_PROBABILITY = "recurrenceProbability";
|
public static final String ATTACH_RECURRENCE_PROBABILITY = "recurrenceProbability";
|
||||||
|
|
||||||
public static final String TYPE_DEFECT = "缺陷";
|
public static final String TYPE_DEFECT = "缺陷";
|
||||||
public static final String TYPE_DEMAND = "需求";
|
public static final String TYPE_DEMAND = "需求";
|
||||||
public static final String TYPE_ASSIGNMENT = "任务";
|
public static final String TYPE_ASSIGNMENT = "任务";
|
||||||
|
|
||||||
public static final String STATUS_WAITING = "待进行";
|
public static final String STATUS_WAITING = "待进行";
|
||||||
public static final String STATUS_PROCESSING = "进行中";
|
public static final String STATUS_PROCESSING = "进行中";
|
||||||
public static final String STATUS_COMPLETED = "已完成";
|
public static final String STATUS_COMPLETED = "已完成";
|
||||||
|
@ -117,8 +114,6 @@ public class Task {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean checkModification(Task rawTask) {
|
public Boolean checkModification(Task rawTask) {
|
||||||
if (projectGroupService.getProjectAccessLevel(this.getTaskHolderId(), 3, this.getTaskProjectId()) == 0)
|
|
||||||
return false;
|
|
||||||
if (rawTask.getTaskStatus().equals(STATUS_COMPLETED) || rawTask.getTaskStatus().equals(STATUS_CLOSED))
|
if (rawTask.getTaskStatus().equals(STATUS_COMPLETED) || rawTask.getTaskStatus().equals(STATUS_CLOSED))
|
||||||
return false;
|
return false;
|
||||||
if (!rawTask.getTaskStatus().equals(STATUS_WAITING) && this.getTaskStatus().equals(STATUS_WAITING))
|
if (!rawTask.getTaskStatus().equals(STATUS_WAITING) && this.getTaskStatus().equals(STATUS_WAITING))
|
||||||
|
|
|
@ -45,4 +45,7 @@ public interface ITaskService extends IService<Task> {
|
||||||
Task modifyTask(String token, Task task) throws BadRequestException, ForbiddenException;
|
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 BadRequestException, ForbiddenException;
|
||||||
|
|
||||||
|
Boolean transferStaffTasks(String token, Integer projectId, Integer transferredStaffId, Map<Long, Integer> transferMap) throws ForbiddenException, BadRequestException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import cn.edu.hfut.rmdjzz.projectmanagement.service.ITaskService;
|
||||||
import cn.edu.hfut.rmdjzz.projectmanagement.utils.TokenUtils;
|
import cn.edu.hfut.rmdjzz.projectmanagement.utils.TokenUtils;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.baomidou.mybatisplus.extension.toolkit.SimpleQuery;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -353,4 +354,57 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements IT
|
||||||
return taskTrendDTO;
|
return taskTrendDTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//不需要定义为事务,因为updateBatch已经定义为事务
|
||||||
|
@Override
|
||||||
|
public Boolean transferStaffTasks(String token, Integer projectId, Integer transferredStaffId, Map<Long, Integer> transferMap) throws ForbiddenException, BadRequestException {
|
||||||
|
if (projectGroupService.getProjectAccessLevel(token, projectId) == 0
|
||||||
|
|| projectGroupService.getProjectAccessLevelIgnoreGlobalLevel(transferredStaffId, projectId) == 0) {
|
||||||
|
throw new ForbiddenException(IProjectGroupService.UNABLE_TO_ACCESS_PROJECT);
|
||||||
|
}
|
||||||
|
if (projectGroupService.compareProjectAccessLevel(projectId, token, transferredStaffId) < 0) {
|
||||||
|
throw new ForbiddenException(ForbiddenException.UNABLE_TO_OPERATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<Long, Task> originTransferTaskMap = SimpleQuery.keyMap(
|
||||||
|
Wrappers.<Task>lambdaQuery()
|
||||||
|
.eq(Task::getTaskProjectId, projectId)
|
||||||
|
.eq(Task::getTaskHolderId, transferredStaffId),
|
||||||
|
Task::getTaskId,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
if (originTransferTaskMap.size() != transferMap.size()) {
|
||||||
|
throw new BadRequestException("未交接该员工的全部项目");
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<Integer> targetStaffIdCache = new HashSet<>();
|
||||||
|
Set<Map.Entry<Long, Integer>> transferEntrySet = transferMap.entrySet();
|
||||||
|
for (Map.Entry<Long, Integer> transferEntry : transferEntrySet) {
|
||||||
|
Integer targetStaffId = transferEntry.getValue();
|
||||||
|
if (Objects.equals(targetStaffId, transferredStaffId)) {
|
||||||
|
throw new BadRequestException("不能将工作项交接给原员工");
|
||||||
|
}
|
||||||
|
if (!targetStaffIdCache.contains(targetStaffId)) {
|
||||||
|
if (projectGroupService.getProjectAccessLevelIgnoreGlobalLevel(targetStaffId, projectId) == 0) {
|
||||||
|
throw new BadRequestException("交接目标员工不在该项目组中");
|
||||||
|
}
|
||||||
|
targetStaffIdCache.add(targetStaffId);
|
||||||
|
}
|
||||||
|
Task targetTask = originTransferTaskMap.remove(transferEntry.getKey());
|
||||||
|
if (targetTask == null || !Objects.equals(targetTask.getTaskHolderId(), transferredStaffId)) {
|
||||||
|
throw new BadRequestException("指定的交接任务不属于该项目或被交接员工");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!originTransferTaskMap.isEmpty()) {
|
||||||
|
throw new BadRequestException("未交接该员工的全部项目");
|
||||||
|
}
|
||||||
|
|
||||||
|
return updateBatchById(
|
||||||
|
transferEntrySet.parallelStream()
|
||||||
|
.map(entry -> Task.builder()
|
||||||
|
.taskId(entry.getKey())
|
||||||
|
.taskHolderId(entry.getValue()).build())
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
package cn.edu.hfut.rmdjzz.projectmanagement.utils;
|
||||||
|
|
||||||
|
import lombok.Cleanup;
|
||||||
|
import org.springframework.util.DigestUtils;
|
||||||
|
import org.springframework.util.MimeTypeUtils;
|
||||||
|
|
||||||
|
import javax.servlet.ServletOutputStream;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 佘语殊
|
||||||
|
* @since 2022/7/11 9:32
|
||||||
|
*/
|
||||||
|
public class FileUtils {
|
||||||
|
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);
|
||||||
|
response.setContentType(MimeTypeUtils.APPLICATION_OCTET_STREAM_VALUE);
|
||||||
|
response.setCharacterEncoding("UTF-8");
|
||||||
|
ServletOutputStream out = response.getOutputStream();
|
||||||
|
response.addHeader("File-Digest", DigestUtils.md5DigestAsHex(bis));
|
||||||
|
@Cleanup BufferedOutputStream bos = new BufferedOutputStream(out);
|
||||||
|
bis.transferTo(bos);
|
||||||
|
bos.flush();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -75,7 +75,13 @@ public class ResponseMap implements IResponse {
|
||||||
return of(HttpStatus.OK.value(), msg, data);
|
return of(HttpStatus.OK.value(), msg, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param data 类型为String则填入msg,否则填入data
|
||||||
|
*/
|
||||||
public static ResponseMap ofSuccess(Object data) {
|
public static ResponseMap ofSuccess(Object data) {
|
||||||
|
if (data instanceof String msg) {
|
||||||
|
return of(HttpStatus.OK.value(), msg);
|
||||||
|
}
|
||||||
return of(HttpStatus.OK.value(), SUCCESS, data);
|
return of(HttpStatus.OK.value(), SUCCESS, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,10 +89,6 @@ public class ResponseMap implements IResponse {
|
||||||
return of(HttpStatus.OK.value(), msg, data, putNulls);
|
return of(HttpStatus.OK.value(), msg, data, putNulls);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ResponseMap ofSuccess(String msg) {
|
|
||||||
return of(HttpStatus.OK.value(), msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ResponseMap ofSuccess() {
|
public static ResponseMap ofSuccess() {
|
||||||
return of(HttpStatus.OK.value(), SUCCESS);
|
return of(HttpStatus.OK.value(), SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue