feat: add role scoped training task APIs

main
chenyuan 2 months ago
parent a1306bd9ad
commit ac71703e62

@ -0,0 +1,237 @@
package com.sztzjy.linkCommerce.controller.stu;
import com.alibaba.excel.EasyExcel;
import com.sztzjy.linkCommerce.config.exception.UnAuthorizedException;
import com.sztzjy.linkCommerce.config.security.JwtUser;
import com.sztzjy.linkCommerce.config.security.TokenProvider;
import com.sztzjy.linkCommerce.entity.TrainingTask;
import com.sztzjy.linkCommerce.entity.importDto.TrainingTaskImportDTO;
import com.sztzjy.linkCommerce.service.TrainingTaskService;
import com.sztzjy.linkCommerce.util.ResultEntity;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
@Api(tags = "Training task management")
@RequestMapping("api/training-tasks")
@RestController
public class TrainingTaskController {
@Autowired
private TrainingTaskService trainingTaskService;
@GetMapping
@ApiOperation("Training task list")
public ResultEntity<List<TrainingTask>> list(@RequestParam(required = false) String projectName,
@RequestParam(required = false) String taskName,
@RequestParam(required = false) Boolean enabledOnly,
HttpServletRequest request) {
JwtUser user = TokenProvider.getJWTUser(request);
if (isStudent(user)) {
return new ResultEntity<>(HttpStatus.OK, "Query success",
trainingTaskService.listForStudent(user.getUserId(), enabledOnly));
}
return new ResultEntity<>(HttpStatus.OK, "Query success",
trainingTaskService.listDefaults(projectName, taskName, enabledOnly));
}
@GetMapping("/{id}")
@ApiOperation("Training task detail")
public ResultEntity<TrainingTask> detail(@PathVariable String id, HttpServletRequest request) {
requireAdmin(request);
TrainingTask task = trainingTaskService.getById(id);
if (task == null) {
return new ResultEntity<>(HttpStatus.NOT_FOUND, "Training task not found");
}
return new ResultEntity<>(HttpStatus.OK, "Query success", task);
}
@GetMapping("/key/{taskKey}")
@ApiOperation("Training task detail by key")
public ResultEntity<TrainingTask> detailByTaskKey(@PathVariable String taskKey, HttpServletRequest request) {
JwtUser user = TokenProvider.getJWTUser(request);
TrainingTask task = isStudent(user)
? trainingTaskService.getStudentTaskByTaskKey(taskKey, user.getUserId())
: trainingTaskService.getByTaskKey(taskKey);
if (task == null) {
return new ResultEntity<>(HttpStatus.OK, "Training task not configured", null);
}
return new ResultEntity<>(HttpStatus.OK, "Query success", task);
}
@GetMapping("/classes/{teachingClassId}")
@ApiOperation("Training task list for teaching class")
public ResultEntity<List<TrainingTask>> listForTeachingClass(@PathVariable String teachingClassId,
@RequestParam(required = false) Boolean enabledOnly,
HttpServletRequest request) {
JwtUser user = requireTeacher(request);
try {
return new ResultEntity<>(HttpStatus.OK, "Query success",
trainingTaskService.listForTeachingClass(teachingClassId, enabledOnly, user.getUserId()));
} catch (IllegalArgumentException e) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, e.getMessage());
}
}
@GetMapping("/classes/{teachingClassId}/key/{taskKey}")
@ApiOperation("Training task detail for teaching class by key")
public ResultEntity<TrainingTask> getClassTaskByTaskKey(@PathVariable String teachingClassId,
@PathVariable String taskKey,
HttpServletRequest request) {
JwtUser user = requireTeacher(request);
try {
TrainingTask task = trainingTaskService.getClassTaskByTaskKey(teachingClassId, taskKey, user.getUserId());
if (task == null) {
return new ResultEntity<>(HttpStatus.OK, "Training task not configured", null);
}
return new ResultEntity<>(HttpStatus.OK, "Query success", task);
} catch (IllegalArgumentException e) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, e.getMessage());
}
}
@PutMapping("/classes/{teachingClassId}/{taskKey}")
@ApiOperation("Save training task for teaching class")
public ResultEntity<TrainingTask> saveClassTask(@PathVariable String teachingClassId,
@PathVariable String taskKey,
@RequestBody TrainingTask task,
HttpServletRequest request) {
JwtUser user = requireTeacher(request);
try {
return new ResultEntity<>(HttpStatus.OK, "Save success",
trainingTaskService.saveClassTask(teachingClassId, taskKey, task, user.getUserId()));
} catch (IllegalArgumentException e) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, e.getMessage());
}
}
@PostMapping
@ApiOperation("Create training task")
public ResultEntity<TrainingTask> create(@RequestBody TrainingTask task, HttpServletRequest request) {
JwtUser user = requireAdmin(request);
try {
return new ResultEntity<>(HttpStatus.OK, "Create success", trainingTaskService.create(task, user.getUserId()));
} catch (IllegalArgumentException e) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, e.getMessage());
}
}
@PutMapping("/{id}")
@ApiOperation("Update training task")
public ResultEntity<TrainingTask> update(@PathVariable String id,
@RequestBody TrainingTask task,
HttpServletRequest request) {
requireAdmin(request);
if (trainingTaskService.getById(id) == null) {
return new ResultEntity<>(HttpStatus.NOT_FOUND, "Training task not found");
}
try {
return new ResultEntity<>(HttpStatus.OK, "Update success", trainingTaskService.update(id, task));
} catch (IllegalArgumentException e) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, e.getMessage());
}
}
@DeleteMapping("/{id}")
@ApiOperation("Delete training task")
public ResultEntity delete(@PathVariable String id, HttpServletRequest request) {
requireAdmin(request);
if (trainingTaskService.getById(id) == null) {
return new ResultEntity<>(HttpStatus.NOT_FOUND, "Training task not found");
}
try {
trainingTaskService.delete(id);
return new ResultEntity<>(HttpStatus.OK, "Delete success");
} catch (IllegalArgumentException e) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, e.getMessage());
}
}
@PostMapping("/import")
@ApiOperation("Import training tasks")
@Transactional(rollbackFor = Exception.class)
public ResultEntity importTasks(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
JwtUser user = requireAdmin(request);
ResultEntity fileError = validateImportFile(file);
if (fileError != null) {
return fileError;
}
try (InputStream inputStream = file.getInputStream()) {
List<TrainingTaskImportDTO> rows = EasyExcel.read(inputStream)
.head(TrainingTaskImportDTO.class)
.sheet()
.doReadSync();
List<String> errors = new ArrayList<>();
int count = trainingTaskService.importTasks(rows, user.getUserId(), errors);
if (!errors.isEmpty()) {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "Data validation failed", errors);
}
return new ResultEntity<>(HttpStatus.OK, "Import success, total " + count + " rows");
} catch (IllegalArgumentException e) {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return new ResultEntity<>(HttpStatus.BAD_REQUEST, e.getMessage());
} catch (Exception e) {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return new ResultEntity<>(HttpStatus.ACCEPTED, "Import failed: " + e.getMessage());
}
}
@GetMapping("/template")
@ApiOperation("Download training task import template")
public void downloadTemplate(HttpServletRequest request, HttpServletResponse response) throws Exception {
requireAdmin(request);
String filename = URLEncoder.encode("training-task-import-template.xlsx", StandardCharsets.UTF_8.name()).replaceAll("\\+", "%20");
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-Disposition", "attachment;filename*=UTF-8''" + filename);
EasyExcel.write(response.getOutputStream(), TrainingTaskImportDTO.class)
.sheet("training-tasks")
.doWrite(trainingTaskService.templateRows());
}
private boolean isStudent(JwtUser user) {
return user != null && user.getRoleId() == 4;
}
private JwtUser requireAdmin(HttpServletRequest request) {
JwtUser user = TokenProvider.getJWTUser(request);
if (user == null || user.getRoleId() != 1) {
throw new UnAuthorizedException("Admin only");
}
return user;
}
private JwtUser requireTeacher(HttpServletRequest request) {
JwtUser user = TokenProvider.getJWTUser(request);
if (user == null || (user.getRoleId() != 1 && user.getRoleId() != 3)) {
throw new UnAuthorizedException("Teacher only");
}
return user;
}
private ResultEntity validateImportFile(MultipartFile file) {
if (file == null || file.isEmpty()) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "Please select an Excel file");
}
String filename = StringUtils.defaultString(file.getOriginalFilename());
if (!StringUtils.endsWithIgnoreCase(filename, ".xls") && !StringUtils.endsWithIgnoreCase(filename, ".xlsx")) {
return new ResultEntity<>(HttpStatus.BAD_REQUEST, "Only xls or xlsx files are supported");
}
return null;
}
}
Loading…
Cancel
Save