feat: validate product development process step three

main
chenyuan 3 weeks ago
parent 9c5ef5bb9d
commit 46fa9321be

@ -24,6 +24,8 @@ import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepOneCheckR
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepOneCheckResult;
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepTwoValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepTwoValidationResult;
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepThreeValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepThreeValidationResult;
import com.sztzjy.linkCommerce.service.NewProductSurveyStepOneService;
import com.sztzjy.linkCommerce.service.NewProductSurveyStepTwoService;
import com.sztzjy.linkCommerce.service.NewProductSurveyStepThreeService;
@ -34,6 +36,7 @@ import com.sztzjy.linkCommerce.service.ProductDevelopmentFactorsStepThreeService
import com.sztzjy.linkCommerce.service.ProductDevelopmentFactorsStepFourService;
import com.sztzjy.linkCommerce.service.ProductDevelopmentProcessStepOneService;
import com.sztzjy.linkCommerce.service.ProductDevelopmentProcessStepTwoService;
import com.sztzjy.linkCommerce.service.ProductDevelopmentProcessStepThreeService;
import com.sztzjy.linkCommerce.service.StudentTrainingAnswerService;
import com.sztzjy.linkCommerce.util.ResultEntity;
import io.swagger.annotations.Api;
@ -79,6 +82,9 @@ public class StudentTrainingAnswerController {
@Autowired
private ProductDevelopmentProcessStepTwoService productDevelopmentProcessStepTwoService;
@Autowired
private ProductDevelopmentProcessStepThreeService productDevelopmentProcessStepThreeService;
@GetMapping("/{taskKey}")
@ApiOperation("查询当前学生指定实训任务答案")
public ResultEntity<StudentTrainingAnswer> detail(@PathVariable String taskKey,
@ -217,6 +223,17 @@ public class StudentTrainingAnswerController {
}
}
@PostMapping("/product-development-process/step-3/validate")
@ApiOperation("产品开发主要流程第三步校验")
public ResultEntity<ProductDevelopmentProcessStepThreeValidationResult> validateProductDevelopmentProcessStepThree(
@RequestBody ProductDevelopmentProcessStepThreeValidationRequest answer, HttpServletRequest request) {
try {
return new ResultEntity<>(HttpStatus.OK, "校验通过", productDevelopmentProcessStepThreeService.validate(answer, TokenProvider.getJWTUser(request)));
} catch (ServiceException e) {
return new ResultEntity<>(e.getCode(), e.getMessage());
}
}
@DeleteMapping("/{taskKey}")
@ApiOperation("删除当前学生指定实训任务答案")
public ResultEntity delete(@PathVariable String taskKey,

@ -0,0 +1,11 @@
package com.sztzjy.linkCommerce.entity.dto;
public class ProductDevelopmentProcessStepThreeValidationRequest {
private String ganttImageUrl;
private String ganttImageName;
public String getGanttImageUrl() { return ganttImageUrl; }
public void setGanttImageUrl(String ganttImageUrl) { this.ganttImageUrl = ganttImageUrl; }
public String getGanttImageName() { return ganttImageName; }
public void setGanttImageName(String ganttImageName) { this.ganttImageName = ganttImageName; }
}

@ -0,0 +1,10 @@
package com.sztzjy.linkCommerce.entity.dto;
public class ProductDevelopmentProcessStepThreeValidationResult {
private boolean valid;
private String message;
public boolean isValid() { return valid; }
public void setValid(boolean valid) { this.valid = valid; }
public String getMessage() { return message; }
public void setMessage(String message) { this.message = message; }
}

@ -0,0 +1,9 @@
package com.sztzjy.linkCommerce.service;
import com.sztzjy.linkCommerce.config.security.JwtUser;
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepThreeValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepThreeValidationResult;
public interface ProductDevelopmentProcessStepThreeService {
ProductDevelopmentProcessStepThreeValidationResult validate(ProductDevelopmentProcessStepThreeValidationRequest request, JwtUser user);
}

@ -0,0 +1,59 @@
package com.sztzjy.linkCommerce.service.impl;
import com.sztzjy.linkCommerce.config.exception.handler.ServiceException;
import com.sztzjy.linkCommerce.config.security.JwtUser;
import com.sztzjy.linkCommerce.entity.StudentTrainingAnswer;
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepThreeValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepThreeValidationResult;
import com.sztzjy.linkCommerce.service.ProductDevelopmentProcessStepThreeService;
import com.sztzjy.linkCommerce.service.StudentTrainingAnswerService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import java.util.Locale;
@Service
public class ProductDevelopmentProcessStepThreeServiceImpl implements ProductDevelopmentProcessStepThreeService {
private static final String TASK_KEY = "product-development-process";
private final StudentTrainingAnswerService studentTrainingAnswerService;
@Autowired
public ProductDevelopmentProcessStepThreeServiceImpl(StudentTrainingAnswerService studentTrainingAnswerService) {
this.studentTrainingAnswerService = studentTrainingAnswerService;
}
@Override
public ProductDevelopmentProcessStepThreeValidationResult validate(ProductDevelopmentProcessStepThreeValidationRequest request, JwtUser user) {
requireStudent(user);
requireStepTwoCompleted(user);
String imageUrl = StringUtils.trimToEmpty(request == null ? null : request.getGanttImageUrl());
String imageName = StringUtils.trimToEmpty(request == null ? null : request.getGanttImageName());
if (imageUrl.isEmpty() || imageName.isEmpty() || !isImage(imageName)) {
throw new ServiceException(HttpStatus.BAD_REQUEST, "请上传甘特图图片PNG、JPG、JPEG、WEBP 或 GIF");
}
ProductDevelopmentProcessStepThreeValidationResult result = new ProductDevelopmentProcessStepThreeValidationResult();
result.setValid(true);
result.setMessage("校验通过");
return result;
}
private void requireStudent(JwtUser user) {
if (user == null || StringUtils.isBlank(user.getUserId())) throw new ServiceException(HttpStatus.UNAUTHORIZED, "请先登录后再校验");
if (user.getRoleId() != 4) throw new ServiceException(HttpStatus.FORBIDDEN, "仅学生可进行实训校验");
}
private void requireStepTwoCompleted(JwtUser user) {
StudentTrainingAnswer answer = studentTrainingAnswerService.get(TASK_KEY, null, user);
if (answer == null || StringUtils.isBlank(answer.getStep2Answer())) {
throw new ServiceException(HttpStatus.BAD_REQUEST, "请先完成第二步项目排期");
}
}
private boolean isImage(String filename) {
String normalized = filename.toLowerCase(Locale.ROOT);
return normalized.endsWith(".png") || normalized.endsWith(".jpg") || normalized.endsWith(".jpeg")
|| normalized.endsWith(".webp") || normalized.endsWith(".gif");
}
}

@ -21,6 +21,8 @@ import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepOneCheckR
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepOneCheckResult;
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepTwoValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepTwoValidationResult;
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepThreeValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepThreeValidationResult;
import com.sztzjy.linkCommerce.service.NewProductSurveyStepOneService;
import com.sztzjy.linkCommerce.service.NewProductSurveyStepTwoService;
import com.sztzjy.linkCommerce.service.NewProductSurveyStepThreeService;
@ -30,6 +32,7 @@ import com.sztzjy.linkCommerce.service.ProductDevelopmentFactorsStepTwoService;
import com.sztzjy.linkCommerce.service.ProductDevelopmentFactorsStepThreeService;
import com.sztzjy.linkCommerce.service.ProductDevelopmentProcessStepOneService;
import com.sztzjy.linkCommerce.service.ProductDevelopmentProcessStepTwoService;
import com.sztzjy.linkCommerce.service.ProductDevelopmentProcessStepThreeService;
import com.sztzjy.linkCommerce.util.ResultEntity;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpStatus;
@ -195,6 +198,23 @@ class StudentTrainingAnswerControllerTest {
verify(service).validate(any(ProductDevelopmentProcessStepTwoValidationRequest.class), any(JwtUser.class));
}
@Test
void validateProductDevelopmentProcessStepThreeUsesTheAuthenticatedStudentAndReturnsTheValidationResult() {
StudentTrainingAnswerController controller = new StudentTrainingAnswerController();
ProductDevelopmentProcessStepThreeService service = mock(ProductDevelopmentProcessStepThreeService.class);
ReflectionTestUtils.setField(controller, "productDevelopmentProcessStepThreeService", service);
ProductDevelopmentProcessStepThreeValidationResult validation = new ProductDevelopmentProcessStepThreeValidationResult();
validation.setValid(true);
when(service.validate(any(ProductDevelopmentProcessStepThreeValidationRequest.class), any(JwtUser.class))).thenReturn(validation);
ResultEntity<ProductDevelopmentProcessStepThreeValidationResult> result = controller
.validateProductDevelopmentProcessStepThree(new ProductDevelopmentProcessStepThreeValidationRequest(), authenticatedStudentRequest());
assertEquals(HttpStatus.OK, result.getStatusCode());
assertEquals(validation, result.getBody().getData());
verify(service).validate(any(ProductDevelopmentProcessStepThreeValidationRequest.class), any(JwtUser.class));
}
private HttpServletRequest authenticatedStudentRequest() {
JwtUser user = new JwtUser();
user.setUserId("stu-1");

@ -0,0 +1,56 @@
package com.sztzjy.linkCommerce.service.impl;
import com.sztzjy.linkCommerce.config.exception.handler.ServiceException;
import com.sztzjy.linkCommerce.config.security.JwtUser;
import com.sztzjy.linkCommerce.entity.StudentTrainingAnswer;
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepThreeValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepThreeValidationResult;
import com.sztzjy.linkCommerce.service.StudentTrainingAnswerService;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
class ProductDevelopmentProcessStepThreeServiceImplTest {
@Test
void validateAcceptsAnImageAfterStepTwoIsSaved() {
StudentTrainingAnswerService answerService = answerServiceWithStepTwo();
ProductDevelopmentProcessStepThreeServiceImpl service = new ProductDevelopmentProcessStepThreeServiceImpl(answerService);
ProductDevelopmentProcessStepThreeValidationResult result = service.validate(request("gantt.png"), student());
assertTrue(result.isValid());
}
@Test
void validateRejectsNonImageOrMissingStepTwoAnswer() {
ProductDevelopmentProcessStepThreeServiceImpl service = new ProductDevelopmentProcessStepThreeServiceImpl(answerServiceWithStepTwo());
assertThrows(ServiceException.class, () -> service.validate(request("gantt.xlsx"), student()));
StudentTrainingAnswerService emptyAnswerService = mock(StudentTrainingAnswerService.class);
when(emptyAnswerService.get(anyString(), any(), any(JwtUser.class))).thenReturn(new StudentTrainingAnswer());
ProductDevelopmentProcessStepThreeServiceImpl noStepTwoService = new ProductDevelopmentProcessStepThreeServiceImpl(emptyAnswerService);
assertThrows(ServiceException.class, () -> noStepTwoService.validate(request("gantt.png"), student()));
}
private StudentTrainingAnswerService answerServiceWithStepTwo() {
StudentTrainingAnswerService answerService = mock(StudentTrainingAnswerService.class);
StudentTrainingAnswer answer = new StudentTrainingAnswer();
answer.setStep2Answer("{\"items\":[{}]}");
when(answerService.get(anyString(), any(), any(JwtUser.class))).thenReturn(answer);
return answerService;
}
private ProductDevelopmentProcessStepThreeValidationRequest request(String imageName) {
ProductDevelopmentProcessStepThreeValidationRequest request = new ProductDevelopmentProcessStepThreeValidationRequest();
request.setGanttImageUrl("/profile/upload/2026/gantt.png");
request.setGanttImageName(imageName);
return request;
}
private JwtUser student() { JwtUser user = new JwtUser(); user.setUserId("stu-1"); user.setRoleId(4); return user; }
}
Loading…
Cancel
Save