feat: validate product development process step four

main
chenyuan 3 weeks ago
parent 46fa9321be
commit eada1aef10

@ -26,6 +26,8 @@ import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepTwoValida
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepTwoValidationResult; import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepTwoValidationResult;
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepThreeValidationRequest; import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepThreeValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepThreeValidationResult; import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepThreeValidationResult;
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepFourValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepFourValidationResult;
import com.sztzjy.linkCommerce.service.NewProductSurveyStepOneService; import com.sztzjy.linkCommerce.service.NewProductSurveyStepOneService;
import com.sztzjy.linkCommerce.service.NewProductSurveyStepTwoService; import com.sztzjy.linkCommerce.service.NewProductSurveyStepTwoService;
import com.sztzjy.linkCommerce.service.NewProductSurveyStepThreeService; import com.sztzjy.linkCommerce.service.NewProductSurveyStepThreeService;
@ -37,6 +39,7 @@ import com.sztzjy.linkCommerce.service.ProductDevelopmentFactorsStepFourService;
import com.sztzjy.linkCommerce.service.ProductDevelopmentProcessStepOneService; import com.sztzjy.linkCommerce.service.ProductDevelopmentProcessStepOneService;
import com.sztzjy.linkCommerce.service.ProductDevelopmentProcessStepTwoService; import com.sztzjy.linkCommerce.service.ProductDevelopmentProcessStepTwoService;
import com.sztzjy.linkCommerce.service.ProductDevelopmentProcessStepThreeService; import com.sztzjy.linkCommerce.service.ProductDevelopmentProcessStepThreeService;
import com.sztzjy.linkCommerce.service.ProductDevelopmentProcessStepFourService;
import com.sztzjy.linkCommerce.service.StudentTrainingAnswerService; import com.sztzjy.linkCommerce.service.StudentTrainingAnswerService;
import com.sztzjy.linkCommerce.util.ResultEntity; import com.sztzjy.linkCommerce.util.ResultEntity;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
@ -85,6 +88,9 @@ public class StudentTrainingAnswerController {
@Autowired @Autowired
private ProductDevelopmentProcessStepThreeService productDevelopmentProcessStepThreeService; private ProductDevelopmentProcessStepThreeService productDevelopmentProcessStepThreeService;
@Autowired
private ProductDevelopmentProcessStepFourService productDevelopmentProcessStepFourService;
@GetMapping("/{taskKey}") @GetMapping("/{taskKey}")
@ApiOperation("查询当前学生指定实训任务答案") @ApiOperation("查询当前学生指定实训任务答案")
public ResultEntity<StudentTrainingAnswer> detail(@PathVariable String taskKey, public ResultEntity<StudentTrainingAnswer> detail(@PathVariable String taskKey,
@ -234,6 +240,17 @@ public class StudentTrainingAnswerController {
} }
} }
@PostMapping("/product-development-process/step-4/validate")
@ApiOperation("产品开发主要流程第四步校验")
public ResultEntity<ProductDevelopmentProcessStepFourValidationResult> validateProductDevelopmentProcessStepFour(
@RequestBody ProductDevelopmentProcessStepFourValidationRequest answer, HttpServletRequest request) {
try {
return new ResultEntity<>(HttpStatus.OK, "校验通过", productDevelopmentProcessStepFourService.validate(answer, TokenProvider.getJWTUser(request)));
} catch (ServiceException e) {
return new ResultEntity<>(e.getCode(), e.getMessage());
}
}
@DeleteMapping("/{taskKey}") @DeleteMapping("/{taskKey}")
@ApiOperation("删除当前学生指定实训任务答案") @ApiOperation("删除当前学生指定实训任务答案")
public ResultEntity delete(@PathVariable String taskKey, public ResultEntity delete(@PathVariable String taskKey,

@ -0,0 +1,14 @@
package com.sztzjy.linkCommerce.entity.dto;
public class ProductDevelopmentProcessStepFourValidationRequest {
private String parallelWorkAnalysis;
private String aiScenarioOne;
private String aiScenarioTwo;
public String getParallelWorkAnalysis() { return parallelWorkAnalysis; }
public void setParallelWorkAnalysis(String parallelWorkAnalysis) { this.parallelWorkAnalysis = parallelWorkAnalysis; }
public String getAiScenarioOne() { return aiScenarioOne; }
public void setAiScenarioOne(String aiScenarioOne) { this.aiScenarioOne = aiScenarioOne; }
public String getAiScenarioTwo() { return aiScenarioTwo; }
public void setAiScenarioTwo(String aiScenarioTwo) { this.aiScenarioTwo = aiScenarioTwo; }
}

@ -0,0 +1,10 @@
package com.sztzjy.linkCommerce.entity.dto;
public class ProductDevelopmentProcessStepFourValidationResult {
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.ProductDevelopmentProcessStepFourValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepFourValidationResult;
public interface ProductDevelopmentProcessStepFourService {
ProductDevelopmentProcessStepFourValidationResult validate(ProductDevelopmentProcessStepFourValidationRequest request, JwtUser user);
}

@ -0,0 +1,52 @@
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.ProductDevelopmentProcessStepFourValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepFourValidationResult;
import com.sztzjy.linkCommerce.service.ProductDevelopmentProcessStepFourService;
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;
@Service
public class ProductDevelopmentProcessStepFourServiceImpl implements ProductDevelopmentProcessStepFourService {
private static final String TASK_KEY = "product-development-process";
private final StudentTrainingAnswerService studentTrainingAnswerService;
@Autowired
public ProductDevelopmentProcessStepFourServiceImpl(StudentTrainingAnswerService studentTrainingAnswerService) {
this.studentTrainingAnswerService = studentTrainingAnswerService;
}
@Override
public ProductDevelopmentProcessStepFourValidationResult validate(ProductDevelopmentProcessStepFourValidationRequest request, JwtUser user) {
requireStudent(user);
requireStepThreeCompleted(user);
if (StringUtils.isBlank(request == null ? null : request.getParallelWorkAnalysis())) {
throw new ServiceException(HttpStatus.BAD_REQUEST, "请填写可提前介入并同步完成的电商运营工作");
}
if (StringUtils.isBlank(request.getAiScenarioOne()) || StringUtils.isBlank(request.getAiScenarioTwo())) {
throw new ServiceException(HttpStatus.BAD_REQUEST, "请至少填写 2 个 AI 工具提效应用场景");
}
ProductDevelopmentProcessStepFourValidationResult result = new ProductDevelopmentProcessStepFourValidationResult();
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 requireStepThreeCompleted(JwtUser user) {
StudentTrainingAnswer answer = studentTrainingAnswerService.get(TASK_KEY, null, user);
if (answer == null || StringUtils.isBlank(answer.getStep3Answer())) {
throw new ServiceException(HttpStatus.BAD_REQUEST, "请先上传并保存第三步甘特图");
}
}
}

@ -23,6 +23,8 @@ import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepTwoValida
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepTwoValidationResult; import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepTwoValidationResult;
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepThreeValidationRequest; import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepThreeValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepThreeValidationResult; import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepThreeValidationResult;
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepFourValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepFourValidationResult;
import com.sztzjy.linkCommerce.service.NewProductSurveyStepOneService; import com.sztzjy.linkCommerce.service.NewProductSurveyStepOneService;
import com.sztzjy.linkCommerce.service.NewProductSurveyStepTwoService; import com.sztzjy.linkCommerce.service.NewProductSurveyStepTwoService;
import com.sztzjy.linkCommerce.service.NewProductSurveyStepThreeService; import com.sztzjy.linkCommerce.service.NewProductSurveyStepThreeService;
@ -33,6 +35,7 @@ import com.sztzjy.linkCommerce.service.ProductDevelopmentFactorsStepThreeService
import com.sztzjy.linkCommerce.service.ProductDevelopmentProcessStepOneService; import com.sztzjy.linkCommerce.service.ProductDevelopmentProcessStepOneService;
import com.sztzjy.linkCommerce.service.ProductDevelopmentProcessStepTwoService; import com.sztzjy.linkCommerce.service.ProductDevelopmentProcessStepTwoService;
import com.sztzjy.linkCommerce.service.ProductDevelopmentProcessStepThreeService; import com.sztzjy.linkCommerce.service.ProductDevelopmentProcessStepThreeService;
import com.sztzjy.linkCommerce.service.ProductDevelopmentProcessStepFourService;
import com.sztzjy.linkCommerce.util.ResultEntity; import com.sztzjy.linkCommerce.util.ResultEntity;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
@ -215,6 +218,23 @@ class StudentTrainingAnswerControllerTest {
verify(service).validate(any(ProductDevelopmentProcessStepThreeValidationRequest.class), any(JwtUser.class)); verify(service).validate(any(ProductDevelopmentProcessStepThreeValidationRequest.class), any(JwtUser.class));
} }
@Test
void validateProductDevelopmentProcessStepFourUsesTheAuthenticatedStudentAndReturnsTheValidationResult() {
StudentTrainingAnswerController controller = new StudentTrainingAnswerController();
ProductDevelopmentProcessStepFourService service = mock(ProductDevelopmentProcessStepFourService.class);
ReflectionTestUtils.setField(controller, "productDevelopmentProcessStepFourService", service);
ProductDevelopmentProcessStepFourValidationResult validation = new ProductDevelopmentProcessStepFourValidationResult();
validation.setValid(true);
when(service.validate(any(ProductDevelopmentProcessStepFourValidationRequest.class), any(JwtUser.class))).thenReturn(validation);
ResultEntity<ProductDevelopmentProcessStepFourValidationResult> result = controller
.validateProductDevelopmentProcessStepFour(new ProductDevelopmentProcessStepFourValidationRequest(), authenticatedStudentRequest());
assertEquals(HttpStatus.OK, result.getStatusCode());
assertEquals(validation, result.getBody().getData());
verify(service).validate(any(ProductDevelopmentProcessStepFourValidationRequest.class), any(JwtUser.class));
}
private HttpServletRequest authenticatedStudentRequest() { private HttpServletRequest authenticatedStudentRequest() {
JwtUser user = new JwtUser(); JwtUser user = new JwtUser();
user.setUserId("stu-1"); user.setUserId("stu-1");

@ -0,0 +1,58 @@
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.ProductDevelopmentProcessStepFourValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentProcessStepFourValidationResult;
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 ProductDevelopmentProcessStepFourServiceImplTest {
@Test
void validateAcceptsCompletedReflectionAfterGanttChartIsSaved() {
ProductDevelopmentProcessStepFourServiceImpl service = new ProductDevelopmentProcessStepFourServiceImpl(answerServiceWithStepThree());
ProductDevelopmentProcessStepFourValidationResult result = service.validate(completedRequest(), student());
assertTrue(result.isValid());
}
@Test
void validateRejectsMissingFieldsOrMissingGanttChart() {
ProductDevelopmentProcessStepFourServiceImpl service = new ProductDevelopmentProcessStepFourServiceImpl(answerServiceWithStepThree());
ProductDevelopmentProcessStepFourValidationRequest missingScenario = completedRequest();
missingScenario.setAiScenarioTwo("");
assertThrows(ServiceException.class, () -> service.validate(missingScenario, student()));
StudentTrainingAnswerService emptyAnswerService = mock(StudentTrainingAnswerService.class);
when(emptyAnswerService.get(anyString(), any(), any(JwtUser.class))).thenReturn(new StudentTrainingAnswer());
ProductDevelopmentProcessStepFourServiceImpl noGanttService = new ProductDevelopmentProcessStepFourServiceImpl(emptyAnswerService);
assertThrows(ServiceException.class, () -> noGanttService.validate(completedRequest(), student()));
}
private StudentTrainingAnswerService answerServiceWithStepThree() {
StudentTrainingAnswerService answerService = mock(StudentTrainingAnswerService.class);
StudentTrainingAnswer answer = new StudentTrainingAnswer();
answer.setStep3Answer("{\"ganttImageUrl\":\"/profile/upload/gantt.png\"}");
when(answerService.get(anyString(), any(), any(JwtUser.class))).thenReturn(answer);
return answerService;
}
private ProductDevelopmentProcessStepFourValidationRequest completedRequest() {
ProductDevelopmentProcessStepFourValidationRequest request = new ProductDevelopmentProcessStepFourValidationRequest();
request.setParallelWorkAnalysis("在产品定义阶段提前准备内容种草素材和预热蓄水计划。");
request.setAiScenarioOne("使用AI归纳竞品评论与用户需求辅助产出PRD初稿。");
request.setAiScenarioTwo("使用AI生成详情页文案和主图脚本提高运营素材生产效率。");
return request;
}
private JwtUser student() { JwtUser user = new JwtUser(); user.setUserId("stu-1"); user.setRoleId(4); return user; }
}
Loading…
Cancel
Save