From ff50d5789e623185a85c1d7d79e7dc20fd38b4d0 Mon Sep 17 00:00:00 2001 From: chenyuan Date: Fri, 7 Aug 2026 14:42:24 +0800 Subject: [PATCH] feat: validate product factors step two --- .../stu/StudentTrainingAnswerController.java | 16 ++++++++ ...opmentFactorsStepTwoValidationRequest.java | 13 +++++++ ...lopmentFactorsStepTwoValidationResult.java | 6 +++ ...oductDevelopmentFactorsStepTwoService.java | 5 +++ ...tDevelopmentFactorsStepTwoServiceImpl.java | 29 ++++++++++++++ .../StudentTrainingAnswerControllerTest.java | 15 ++++++++ ...elopmentFactorsStepTwoServiceImplTest.java | 38 +++++++++++++++++++ 7 files changed, 122 insertions(+) create mode 100644 src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductDevelopmentFactorsStepTwoValidationRequest.java create mode 100644 src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductDevelopmentFactorsStepTwoValidationResult.java create mode 100644 src/main/java/com/sztzjy/linkCommerce/service/ProductDevelopmentFactorsStepTwoService.java create mode 100644 src/main/java/com/sztzjy/linkCommerce/service/impl/ProductDevelopmentFactorsStepTwoServiceImpl.java create mode 100644 src/test/java/com/sztzjy/linkCommerce/service/impl/ProductDevelopmentFactorsStepTwoServiceImplTest.java diff --git a/src/main/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerController.java b/src/main/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerController.java index 9e8c151..1adb26e 100644 --- a/src/main/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerController.java +++ b/src/main/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerController.java @@ -14,11 +14,14 @@ import com.sztzjy.linkCommerce.entity.dto.NewProductSurveyStepFourValidationRequ import com.sztzjy.linkCommerce.entity.dto.NewProductSurveyStepFourValidationResult; import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentFactorsStepOneValidationRequest; import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentFactorsStepOneValidationResult; +import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentFactorsStepTwoValidationRequest; +import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentFactorsStepTwoValidationResult; import com.sztzjy.linkCommerce.service.NewProductSurveyStepOneService; import com.sztzjy.linkCommerce.service.NewProductSurveyStepTwoService; import com.sztzjy.linkCommerce.service.NewProductSurveyStepThreeService; import com.sztzjy.linkCommerce.service.NewProductSurveyStepFourService; import com.sztzjy.linkCommerce.service.ProductDevelopmentFactorsStepOneService; +import com.sztzjy.linkCommerce.service.ProductDevelopmentFactorsStepTwoService; import com.sztzjy.linkCommerce.service.StudentTrainingAnswerService; import com.sztzjy.linkCommerce.util.ResultEntity; import io.swagger.annotations.Api; @@ -50,6 +53,8 @@ public class StudentTrainingAnswerController { @Autowired private ProductDevelopmentFactorsStepOneService productDevelopmentFactorsStepOneService; + @Autowired + private ProductDevelopmentFactorsStepTwoService productDevelopmentFactorsStepTwoService; @GetMapping("/{taskKey}") @ApiOperation("查询当前学生指定实训任务答案") @@ -137,6 +142,17 @@ public class StudentTrainingAnswerController { } } + @PostMapping("/product-development-factors/step-2/validate") + @ApiOperation("产品开发关键因素第二步校验") + public ResultEntity validateProductDevelopmentFactorsStepTwo( + @RequestBody ProductDevelopmentFactorsStepTwoValidationRequest answer, HttpServletRequest request) { + try { + return new ResultEntity<>(HttpStatus.OK, "校验通过", productDevelopmentFactorsStepTwoService.validate(answer, TokenProvider.getJWTUser(request))); + } catch (ServiceException e) { + return new ResultEntity<>(e.getCode(), e.getMessage()); + } + } + @DeleteMapping("/{taskKey}") @ApiOperation("删除当前学生指定实训任务答案") public ResultEntity delete(@PathVariable String taskKey, diff --git a/src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductDevelopmentFactorsStepTwoValidationRequest.java b/src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductDevelopmentFactorsStepTwoValidationRequest.java new file mode 100644 index 0000000..6c1427f --- /dev/null +++ b/src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductDevelopmentFactorsStepTwoValidationRequest.java @@ -0,0 +1,13 @@ +package com.sztzjy.linkCommerce.entity.dto; +import java.util.List; +public class ProductDevelopmentFactorsStepTwoValidationRequest { + private List factors; + public List getFactors() { return factors; } + public void setFactors(List factors) { this.factors = factors; } + public static class Row { + private String dimension, successAnalysis, failedAnalysis; + public String getDimension() { return dimension; } public void setDimension(String value) { dimension = value; } + public String getSuccessAnalysis() { return successAnalysis; } public void setSuccessAnalysis(String value) { successAnalysis = value; } + public String getFailedAnalysis() { return failedAnalysis; } public void setFailedAnalysis(String value) { failedAnalysis = value; } + } +} diff --git a/src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductDevelopmentFactorsStepTwoValidationResult.java b/src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductDevelopmentFactorsStepTwoValidationResult.java new file mode 100644 index 0000000..5be80da --- /dev/null +++ b/src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductDevelopmentFactorsStepTwoValidationResult.java @@ -0,0 +1,6 @@ +package com.sztzjy.linkCommerce.entity.dto; +public class ProductDevelopmentFactorsStepTwoValidationResult { + private boolean valid; private String message; + public boolean isValid() { return valid; } public void setValid(boolean value) { valid = value; } + public String getMessage() { return message; } public void setMessage(String value) { message = value; } +} diff --git a/src/main/java/com/sztzjy/linkCommerce/service/ProductDevelopmentFactorsStepTwoService.java b/src/main/java/com/sztzjy/linkCommerce/service/ProductDevelopmentFactorsStepTwoService.java new file mode 100644 index 0000000..d2a50e8 --- /dev/null +++ b/src/main/java/com/sztzjy/linkCommerce/service/ProductDevelopmentFactorsStepTwoService.java @@ -0,0 +1,5 @@ +package com.sztzjy.linkCommerce.service; +import com.sztzjy.linkCommerce.config.security.JwtUser; +import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentFactorsStepTwoValidationRequest; +import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentFactorsStepTwoValidationResult; +public interface ProductDevelopmentFactorsStepTwoService { ProductDevelopmentFactorsStepTwoValidationResult validate(ProductDevelopmentFactorsStepTwoValidationRequest request, JwtUser user); } diff --git a/src/main/java/com/sztzjy/linkCommerce/service/impl/ProductDevelopmentFactorsStepTwoServiceImpl.java b/src/main/java/com/sztzjy/linkCommerce/service/impl/ProductDevelopmentFactorsStepTwoServiceImpl.java new file mode 100644 index 0000000..fa8be7f --- /dev/null +++ b/src/main/java/com/sztzjy/linkCommerce/service/impl/ProductDevelopmentFactorsStepTwoServiceImpl.java @@ -0,0 +1,29 @@ +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.dto.ProductDevelopmentFactorsStepTwoValidationRequest; +import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentFactorsStepTwoValidationResult; +import com.sztzjy.linkCommerce.service.ProductDevelopmentFactorsStepTwoService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; +import java.util.Arrays; import java.util.LinkedHashSet; import java.util.Set; +@Service +public class ProductDevelopmentFactorsStepTwoServiceImpl implements ProductDevelopmentFactorsStepTwoService { + private static final Set DIMENSIONS = new LinkedHashSet<>(Arrays.asList("技术应用", "合规与认证")); + @Override public ProductDevelopmentFactorsStepTwoValidationResult validate(ProductDevelopmentFactorsStepTwoValidationRequest request, JwtUser user) { + if (user == null || StringUtils.isBlank(user.getUserId())) throw new ServiceException(HttpStatus.UNAUTHORIZED, "请先登录后再提交"); + if (user.getRoleId() != 4) throw new ServiceException(HttpStatus.FORBIDDEN, "仅学生可提交实训答案"); + if (request == null || request.getFactors() == null || request.getFactors().size() != DIMENSIONS.size()) throw badRequest("请完成技术应用和合规与认证分析"); + Set submitted = new LinkedHashSet<>(); + for (ProductDevelopmentFactorsStepTwoValidationRequest.Row row : request.getFactors()) { + String dimension = row == null ? "" : StringUtils.trimToEmpty(row.getDimension()); + if (!DIMENSIONS.contains(dimension) || !submitted.add(dimension)) throw badRequest("提交的分析维度不完整或重复"); + if (!StringUtils.isNotBlank(row.getSuccessAnalysis())) throw badRequest("请填写" + dimension + "的成功产品分析"); + if (!StringUtils.isNotBlank(row.getFailedAnalysis())) throw badRequest("请填写" + dimension + "的失败产品分析"); + } + if (!submitted.equals(DIMENSIONS)) throw badRequest("请完成技术应用和合规与认证分析"); + ProductDevelopmentFactorsStepTwoValidationResult result = new ProductDevelopmentFactorsStepTwoValidationResult(); result.setValid(true); result.setMessage("校验通过"); return result; + } + private ServiceException badRequest(String message) { return new ServiceException(HttpStatus.BAD_REQUEST, message); } +} diff --git a/src/test/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerControllerTest.java b/src/test/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerControllerTest.java index 4416621..ee7c3c8 100644 --- a/src/test/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerControllerTest.java +++ b/src/test/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerControllerTest.java @@ -13,11 +13,14 @@ import com.sztzjy.linkCommerce.entity.dto.NewProductSurveyStepFourValidationRequ import com.sztzjy.linkCommerce.entity.dto.NewProductSurveyStepFourValidationResult; import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentFactorsStepOneValidationRequest; import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentFactorsStepOneValidationResult; +import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentFactorsStepTwoValidationRequest; +import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentFactorsStepTwoValidationResult; import com.sztzjy.linkCommerce.service.NewProductSurveyStepOneService; import com.sztzjy.linkCommerce.service.NewProductSurveyStepTwoService; import com.sztzjy.linkCommerce.service.NewProductSurveyStepThreeService; import com.sztzjy.linkCommerce.service.NewProductSurveyStepFourService; import com.sztzjy.linkCommerce.service.ProductDevelopmentFactorsStepOneService; +import com.sztzjy.linkCommerce.service.ProductDevelopmentFactorsStepTwoService; import com.sztzjy.linkCommerce.util.ResultEntity; import org.junit.jupiter.api.Test; import org.springframework.http.HttpStatus; @@ -120,6 +123,18 @@ class StudentTrainingAnswerControllerTest { verify(service).validate(any(ProductDevelopmentFactorsStepOneValidationRequest.class), any(JwtUser.class)); } + @Test + void validateProductDevelopmentFactorsStepTwoUsesTheAuthenticatedStudentAndReturnsTheValidationResult() { + StudentTrainingAnswerController controller = new StudentTrainingAnswerController(); + ProductDevelopmentFactorsStepTwoService service = mock(ProductDevelopmentFactorsStepTwoService.class); + ReflectionTestUtils.setField(controller, "productDevelopmentFactorsStepTwoService", service); + ProductDevelopmentFactorsStepTwoValidationResult validation = new ProductDevelopmentFactorsStepTwoValidationResult(); validation.setValid(true); + when(service.validate(any(ProductDevelopmentFactorsStepTwoValidationRequest.class), any(JwtUser.class))).thenReturn(validation); + ResultEntity result = controller.validateProductDevelopmentFactorsStepTwo(new ProductDevelopmentFactorsStepTwoValidationRequest(), authenticatedStudentRequest()); + assertEquals(HttpStatus.OK, result.getStatusCode()); assertEquals(validation, result.getBody().getData()); + verify(service).validate(any(ProductDevelopmentFactorsStepTwoValidationRequest.class), any(JwtUser.class)); + } + private HttpServletRequest authenticatedStudentRequest() { JwtUser user = new JwtUser(); user.setUserId("stu-1"); diff --git a/src/test/java/com/sztzjy/linkCommerce/service/impl/ProductDevelopmentFactorsStepTwoServiceImplTest.java b/src/test/java/com/sztzjy/linkCommerce/service/impl/ProductDevelopmentFactorsStepTwoServiceImplTest.java new file mode 100644 index 0000000..c46770a --- /dev/null +++ b/src/test/java/com/sztzjy/linkCommerce/service/impl/ProductDevelopmentFactorsStepTwoServiceImplTest.java @@ -0,0 +1,38 @@ +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.dto.ProductDevelopmentFactorsStepTwoValidationRequest; +import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentFactorsStepTwoValidationResult; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class ProductDevelopmentFactorsStepTwoServiceImplTest { + @Test void acceptsCompleteStudentAnalyses() { assertTrue(new ProductDevelopmentFactorsStepTwoServiceImpl().validate(valid(), student()).isValid()); } + + @Test void rejectsBlankOrForgedAnalyses() { + ProductDevelopmentFactorsStepTwoServiceImpl service = new ProductDevelopmentFactorsStepTwoServiceImpl(); + ProductDevelopmentFactorsStepTwoValidationRequest blank = valid(); blank.getFactors().get(1).setFailedAnalysis(" "); + assertThrows(ServiceException.class, () -> service.validate(blank, student())); + ProductDevelopmentFactorsStepTwoValidationRequest forged = valid(); forged.getFactors().get(1).setDimension("生态与兼容"); + assertThrows(ServiceException.class, () -> service.validate(forged, student())); + } + + @Test void rejectsNonStudent() { assertThrows(ServiceException.class, () -> new ProductDevelopmentFactorsStepTwoServiceImpl().validate(valid(), teacher())); } + + private ProductDevelopmentFactorsStepTwoValidationRequest valid() { + ProductDevelopmentFactorsStepTwoValidationRequest request = new ProductDevelopmentFactorsStepTwoValidationRequest(); + request.setFactors(Arrays.asList(row("技术应用", "技术成熟可量产", "技术未经验证"), row("合规与认证", "认证齐全", "存在合规风险"))); + return request; + } + private ProductDevelopmentFactorsStepTwoValidationRequest.Row row(String dimension, String success, String failed) { + ProductDevelopmentFactorsStepTwoValidationRequest.Row row = new ProductDevelopmentFactorsStepTwoValidationRequest.Row(); + row.setDimension(dimension); row.setSuccessAnalysis(success); row.setFailedAnalysis(failed); return row; + } + private JwtUser student() { JwtUser user = new JwtUser(); user.setUserId("stu-1"); user.setRoleId(4); return user; } + private JwtUser teacher() { JwtUser user = new JwtUser(); user.setUserId("tea-1"); user.setRoleId(2); return user; } +}