From 5b7602bca3a3e617343cd6dd6eb506d707851f4b Mon Sep 17 00:00:00 2001 From: chenyuan Date: Wed, 12 Aug 2026 08:08:27 +0800 Subject: [PATCH] feat: validate value positioning statements --- .../stu/StudentTrainingAnswerController.java | 17 ++++++ ...PositioningStepThreeValidationRequest.java | 32 +++++++++++ ...ePositioningStepThreeValidationResult.java | 11 ++++ ...oductValuePositioningStepThreeService.java | 9 ++++ ...tValuePositioningStepThreeServiceImpl.java | 42 +++++++++++++++ ...uePositioningStepThreeServiceImplTest.java | 54 +++++++++++++++++++ 6 files changed, 165 insertions(+) create mode 100644 src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductValuePositioningStepThreeValidationRequest.java create mode 100644 src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductValuePositioningStepThreeValidationResult.java create mode 100644 src/main/java/com/sztzjy/linkCommerce/service/ProductValuePositioningStepThreeService.java create mode 100644 src/main/java/com/sztzjy/linkCommerce/service/impl/ProductValuePositioningStepThreeServiceImpl.java create mode 100644 src/test/java/com/sztzjy/linkCommerce/service/impl/ProductValuePositioningStepThreeServiceImplTest.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 0318a80..0702a84 100644 --- a/src/main/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerController.java +++ b/src/main/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerController.java @@ -41,6 +41,8 @@ import com.sztzjy.linkCommerce.entity.dto.ProductValuePositioningStepOneValidati import com.sztzjy.linkCommerce.entity.dto.ProductValuePositioningStepOneValidationResult; import com.sztzjy.linkCommerce.entity.dto.ProductValuePositioningStepTwoValidationRequest; import com.sztzjy.linkCommerce.entity.dto.ProductValuePositioningStepTwoValidationResult; +import com.sztzjy.linkCommerce.entity.dto.ProductValuePositioningStepThreeValidationRequest; +import com.sztzjy.linkCommerce.entity.dto.ProductValuePositioningStepThreeValidationResult; import com.sztzjy.linkCommerce.service.NewProductSurveyStepOneService; import com.sztzjy.linkCommerce.service.MarketOpportunitySelectionStepOneService; import com.sztzjy.linkCommerce.service.MarketOpportunitySelectionStepTwoService; @@ -59,6 +61,7 @@ import com.sztzjy.linkCommerce.service.ConsumerBehaviorStepThreeService; import com.sztzjy.linkCommerce.service.ConsumerBehaviorStepFourService; import com.sztzjy.linkCommerce.service.ProductValuePositioningStepOneService; import com.sztzjy.linkCommerce.service.ProductValuePositioningStepTwoService; +import com.sztzjy.linkCommerce.service.ProductValuePositioningStepThreeService; import com.sztzjy.linkCommerce.service.StudentTrainingAnswerService; import com.sztzjy.linkCommerce.util.ResultEntity; import io.swagger.annotations.Api; @@ -129,6 +132,9 @@ public class StudentTrainingAnswerController { @Autowired private ProductValuePositioningStepTwoService productValuePositioningStepTwoService; + @Autowired + private ProductValuePositioningStepThreeService productValuePositioningStepThreeService; + @GetMapping("/{taskKey}") @ApiOperation("查询当前学生指定实训任务答案") public ResultEntity detail(@PathVariable String taskKey, @@ -355,6 +361,17 @@ public class StudentTrainingAnswerController { } } + @PostMapping("/product-value-positioning/step-3/validate") + @ApiOperation("产品价值主张及定位第三步校验") + public ResultEntity validateProductValuePositioningStepThree( + @RequestBody ProductValuePositioningStepThreeValidationRequest answer, HttpServletRequest request) { + try { + return new ResultEntity<>(HttpStatus.OK, "校验完成", productValuePositioningStepThreeService.validate(answer, TokenProvider.getJWTUser(request))); + } catch (ServiceException e) { + return new ResultEntity<>(e.getCode(), e.getMessage()); + } + } + @PostMapping(value = "/consumer-behavior/step-3/word-preview", consumes = "multipart/form-data") @ApiOperation("消费者需求与行为第三步Word预览") public ResultEntity previewConsumerBehaviorStepThreeWord( diff --git a/src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductValuePositioningStepThreeValidationRequest.java b/src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductValuePositioningStepThreeValidationRequest.java new file mode 100644 index 0000000..221cebb --- /dev/null +++ b/src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductValuePositioningStepThreeValidationRequest.java @@ -0,0 +1,32 @@ +package com.sztzjy.linkCommerce.entity.dto; + +import java.util.List; + +public class ProductValuePositioningStepThreeValidationRequest { + private List statements; + + public List getStatements() { return statements; } + public void setStatements(List statements) { this.statements = statements; } + + public static class PositioningStatement { + private Integer id; + private String targetUser; + private String productName; + private String productCategory; + private String coreValue; + private String differentiationReason; + + public Integer getId() { return id; } + public void setId(Integer id) { this.id = id; } + public String getTargetUser() { return targetUser; } + public void setTargetUser(String targetUser) { this.targetUser = targetUser; } + public String getProductName() { return productName; } + public void setProductName(String productName) { this.productName = productName; } + public String getProductCategory() { return productCategory; } + public void setProductCategory(String productCategory) { this.productCategory = productCategory; } + public String getCoreValue() { return coreValue; } + public void setCoreValue(String coreValue) { this.coreValue = coreValue; } + public String getDifferentiationReason() { return differentiationReason; } + public void setDifferentiationReason(String differentiationReason) { this.differentiationReason = differentiationReason; } + } +} diff --git a/src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductValuePositioningStepThreeValidationResult.java b/src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductValuePositioningStepThreeValidationResult.java new file mode 100644 index 0000000..6fdad78 --- /dev/null +++ b/src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductValuePositioningStepThreeValidationResult.java @@ -0,0 +1,11 @@ +package com.sztzjy.linkCommerce.entity.dto; + +public class ProductValuePositioningStepThreeValidationResult { + 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; } +} diff --git a/src/main/java/com/sztzjy/linkCommerce/service/ProductValuePositioningStepThreeService.java b/src/main/java/com/sztzjy/linkCommerce/service/ProductValuePositioningStepThreeService.java new file mode 100644 index 0000000..647f018 --- /dev/null +++ b/src/main/java/com/sztzjy/linkCommerce/service/ProductValuePositioningStepThreeService.java @@ -0,0 +1,9 @@ +package com.sztzjy.linkCommerce.service; + +import com.sztzjy.linkCommerce.config.security.JwtUser; +import com.sztzjy.linkCommerce.entity.dto.ProductValuePositioningStepThreeValidationRequest; +import com.sztzjy.linkCommerce.entity.dto.ProductValuePositioningStepThreeValidationResult; + +public interface ProductValuePositioningStepThreeService { + ProductValuePositioningStepThreeValidationResult validate(ProductValuePositioningStepThreeValidationRequest request, JwtUser user); +} diff --git a/src/main/java/com/sztzjy/linkCommerce/service/impl/ProductValuePositioningStepThreeServiceImpl.java b/src/main/java/com/sztzjy/linkCommerce/service/impl/ProductValuePositioningStepThreeServiceImpl.java new file mode 100644 index 0000000..b7adf7c --- /dev/null +++ b/src/main/java/com/sztzjy/linkCommerce/service/impl/ProductValuePositioningStepThreeServiceImpl.java @@ -0,0 +1,42 @@ +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.ProductValuePositioningStepThreeValidationRequest; +import com.sztzjy.linkCommerce.entity.dto.ProductValuePositioningStepThreeValidationResult; +import com.sztzjy.linkCommerce.service.ProductValuePositioningStepThreeService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class ProductValuePositioningStepThreeServiceImpl implements ProductValuePositioningStepThreeService { + @Override + public ProductValuePositioningStepThreeValidationResult validate(ProductValuePositioningStepThreeValidationRequest request, JwtUser user) { + requireStudent(user); + List statements = request == null ? null : request.getStatements(); + if (statements == null || statements.size() != 2) throw badRequest("请填写两个产品价值定位陈述版本"); + for (int index = 0; index < statements.size(); index++) { + ProductValuePositioningStepThreeValidationRequest.PositioningStatement statement = statements.get(index); + if (statement == null || statement.getId() == null || statement.getId() != index + 1 + || StringUtils.isBlank(statement.getTargetUser()) || StringUtils.isBlank(statement.getProductName()) + || StringUtils.isBlank(statement.getProductCategory()) || StringUtils.isBlank(statement.getCoreValue()) + || StringUtils.isBlank(statement.getDifferentiationReason())) { + throw badRequest("请完整填写两个产品价值定位陈述版本"); + } + } + ProductValuePositioningStepThreeValidationResult result = new ProductValuePositioningStepThreeValidationResult(); + 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 ServiceException badRequest(String message) { return new ServiceException(HttpStatus.BAD_REQUEST, message); } +} diff --git a/src/test/java/com/sztzjy/linkCommerce/service/impl/ProductValuePositioningStepThreeServiceImplTest.java b/src/test/java/com/sztzjy/linkCommerce/service/impl/ProductValuePositioningStepThreeServiceImplTest.java new file mode 100644 index 0000000..168d7d1 --- /dev/null +++ b/src/test/java/com/sztzjy/linkCommerce/service/impl/ProductValuePositioningStepThreeServiceImplTest.java @@ -0,0 +1,54 @@ +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.ProductValuePositioningStepThreeValidationRequest; +import com.sztzjy.linkCommerce.entity.dto.ProductValuePositioningStepThreeValidationResult; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class ProductValuePositioningStepThreeServiceImplTest { + private final ProductValuePositioningStepThreeServiceImpl service = new ProductValuePositioningStepThreeServiceImpl(); + + @Test + void acceptsTwoCompleteStatements() { + ProductValuePositioningStepThreeValidationResult result = service.validate(request(), student()); + assertTrue(result.isValid()); + } + + @Test + void rejectsAnIncompleteStatement() { + ProductValuePositioningStepThreeValidationRequest request = request(); + request.getStatements().get(1).setCoreValue(" "); + assertThrows(ServiceException.class, () -> service.validate(request, student())); + } + + private ProductValuePositioningStepThreeValidationRequest request() { + List statements = new ArrayList<>(); + for (int index = 1; index <= 2; index++) { + ProductValuePositioningStepThreeValidationRequest.PositioningStatement statement = new ProductValuePositioningStepThreeValidationRequest.PositioningStatement(); + statement.setId(index); + statement.setTargetUser("目标用户" + index); + statement.setProductName("产品名称" + index); + statement.setProductCategory("产品类别" + index); + statement.setCoreValue("核心价值" + index); + statement.setDifferentiationReason("差异化理由" + index); + statements.add(statement); + } + ProductValuePositioningStepThreeValidationRequest request = new ProductValuePositioningStepThreeValidationRequest(); + request.setStatements(statements); + return request; + } + + private JwtUser student() { + JwtUser user = new JwtUser(); + user.setUserId("student-id"); + user.setRoleId(4); + return user; + } +}