From dd45d9c60aafa49a16f1d3bba95765bbf76e68a0 Mon Sep 17 00:00:00 2001 From: chenyuan Date: Fri, 7 Aug 2026 15:02:13 +0800 Subject: [PATCH] feat: validate product factors step three --- ...mentFactorsStepThreeValidationRequest.java | 23 ++++++++ ...pmentFactorsStepThreeValidationResult.java | 11 ++++ ...uctDevelopmentFactorsStepThreeService.java | 9 +++ ...evelopmentFactorsStepThreeServiceImpl.java | 44 +++++++++++++++ ...opmentFactorsStepThreeServiceImplTest.java | 55 +++++++++++++++++++ 5 files changed, 142 insertions(+) create mode 100644 src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductDevelopmentFactorsStepThreeValidationRequest.java create mode 100644 src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductDevelopmentFactorsStepThreeValidationResult.java create mode 100644 src/main/java/com/sztzjy/linkCommerce/service/ProductDevelopmentFactorsStepThreeService.java create mode 100644 src/main/java/com/sztzjy/linkCommerce/service/impl/ProductDevelopmentFactorsStepThreeServiceImpl.java create mode 100644 src/test/java/com/sztzjy/linkCommerce/service/impl/ProductDevelopmentFactorsStepThreeServiceImplTest.java diff --git a/src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductDevelopmentFactorsStepThreeValidationRequest.java b/src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductDevelopmentFactorsStepThreeValidationRequest.java new file mode 100644 index 0000000..ba903ec --- /dev/null +++ b/src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductDevelopmentFactorsStepThreeValidationRequest.java @@ -0,0 +1,23 @@ +package com.sztzjy.linkCommerce.entity.dto; + +import java.util.List; + +public class ProductDevelopmentFactorsStepThreeValidationRequest { + private List factors; + + public List getFactors() { return factors; } + public void setFactors(List factors) { this.factors = factors; } + + public static class Row { + private String dimension; + private String successAnalysis; + private String 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/ProductDevelopmentFactorsStepThreeValidationResult.java b/src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductDevelopmentFactorsStepThreeValidationResult.java new file mode 100644 index 0000000..98f1ac8 --- /dev/null +++ b/src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductDevelopmentFactorsStepThreeValidationResult.java @@ -0,0 +1,11 @@ +package com.sztzjy.linkCommerce.entity.dto; + +public class ProductDevelopmentFactorsStepThreeValidationResult { + 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/ProductDevelopmentFactorsStepThreeService.java b/src/main/java/com/sztzjy/linkCommerce/service/ProductDevelopmentFactorsStepThreeService.java new file mode 100644 index 0000000..8836b8a --- /dev/null +++ b/src/main/java/com/sztzjy/linkCommerce/service/ProductDevelopmentFactorsStepThreeService.java @@ -0,0 +1,9 @@ +package com.sztzjy.linkCommerce.service; + +import com.sztzjy.linkCommerce.config.security.JwtUser; +import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentFactorsStepThreeValidationRequest; +import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentFactorsStepThreeValidationResult; + +public interface ProductDevelopmentFactorsStepThreeService { + ProductDevelopmentFactorsStepThreeValidationResult validate(ProductDevelopmentFactorsStepThreeValidationRequest request, JwtUser user); +} diff --git a/src/main/java/com/sztzjy/linkCommerce/service/impl/ProductDevelopmentFactorsStepThreeServiceImpl.java b/src/main/java/com/sztzjy/linkCommerce/service/impl/ProductDevelopmentFactorsStepThreeServiceImpl.java new file mode 100644 index 0000000..f39362c --- /dev/null +++ b/src/main/java/com/sztzjy/linkCommerce/service/impl/ProductDevelopmentFactorsStepThreeServiceImpl.java @@ -0,0 +1,44 @@ +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.ProductDevelopmentFactorsStepThreeValidationRequest; +import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentFactorsStepThreeValidationResult; +import com.sztzjy.linkCommerce.service.ProductDevelopmentFactorsStepThreeService; +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 ProductDevelopmentFactorsStepThreeServiceImpl implements ProductDevelopmentFactorsStepThreeService { + private static final Set DIMENSIONS = new LinkedHashSet<>(Arrays.asList("供应链与成本控制", "商业模式", "市场反馈")); + + @Override + public ProductDevelopmentFactorsStepThreeValidationResult validate(ProductDevelopmentFactorsStepThreeValidationRequest 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 (ProductDevelopmentFactorsStepThreeValidationRequest.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("请完成供应链与成本控制、商业模式和市场反馈分析"); + + ProductDevelopmentFactorsStepThreeValidationResult result = new ProductDevelopmentFactorsStepThreeValidationResult(); + 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/service/impl/ProductDevelopmentFactorsStepThreeServiceImplTest.java b/src/test/java/com/sztzjy/linkCommerce/service/impl/ProductDevelopmentFactorsStepThreeServiceImplTest.java new file mode 100644 index 0000000..3a8f00f --- /dev/null +++ b/src/test/java/com/sztzjy/linkCommerce/service/impl/ProductDevelopmentFactorsStepThreeServiceImplTest.java @@ -0,0 +1,55 @@ +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.ProductDevelopmentFactorsStepThreeValidationRequest; +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 ProductDevelopmentFactorsStepThreeServiceImplTest { + @Test + void acceptsCompleteStudentAnalyses() { + assertTrue(new ProductDevelopmentFactorsStepThreeServiceImpl().validate(valid(), student()).isValid()); + } + + @Test + void rejectsBlankOrForgedAnalyses() { + ProductDevelopmentFactorsStepThreeServiceImpl service = new ProductDevelopmentFactorsStepThreeServiceImpl(); + ProductDevelopmentFactorsStepThreeValidationRequest blank = valid(); + blank.getFactors().get(2).setFailedAnalysis(" "); + assertThrows(ServiceException.class, () -> service.validate(blank, student())); + ProductDevelopmentFactorsStepThreeValidationRequest forged = valid(); + forged.getFactors().get(2).setDimension("伪造维度"); + assertThrows(ServiceException.class, () -> service.validate(forged, student())); + } + + @Test + void rejectsNonStudent() { + assertThrows(ServiceException.class, () -> new ProductDevelopmentFactorsStepThreeServiceImpl().validate(valid(), teacher())); + } + + private ProductDevelopmentFactorsStepThreeValidationRequest valid() { + ProductDevelopmentFactorsStepThreeValidationRequest request = new ProductDevelopmentFactorsStepThreeValidationRequest(); + request.setFactors(Arrays.asList( + row("供应链与成本控制", "成本可控且供应稳定", "关键器件单一供应"), + row("商业模式", "订阅服务形成闭环", "盈利模式不清晰"), + row("市场反馈", "用户留存高且复购稳定", "退货率高且反馈差") + )); + return request; + } + + private ProductDevelopmentFactorsStepThreeValidationRequest.Row row(String dimension, String success, String failed) { + ProductDevelopmentFactorsStepThreeValidationRequest.Row row = new ProductDevelopmentFactorsStepThreeValidationRequest.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; } +}