From d4c238e9cab253a90d0082f49e7d006bca9a579c Mon Sep 17 00:00:00 2001 From: chenyuan Date: Tue, 11 Aug 2026 16:45:13 +0800 Subject: [PATCH] feat: validate business feasibility step two --- .../stu/StudentTrainingAnswerController.java | 17 ++++++++ ...ssFeasibilityStepTwoValidationRequest.java | 12 ++++++ ...essFeasibilityStepTwoValidationResult.java | 10 +++++ .../BusinessFeasibilityStepTwoService.java | 9 +++++ ...BusinessFeasibilityStepTwoServiceImpl.java | 40 +++++++++++++++++++ ...nessFeasibilityStepTwoServiceImplTest.java | 40 +++++++++++++++++++ 6 files changed, 128 insertions(+) create mode 100644 src/main/java/com/sztzjy/linkCommerce/entity/dto/BusinessFeasibilityStepTwoValidationRequest.java create mode 100644 src/main/java/com/sztzjy/linkCommerce/entity/dto/BusinessFeasibilityStepTwoValidationResult.java create mode 100644 src/main/java/com/sztzjy/linkCommerce/service/BusinessFeasibilityStepTwoService.java create mode 100644 src/main/java/com/sztzjy/linkCommerce/service/impl/BusinessFeasibilityStepTwoServiceImpl.java create mode 100644 src/test/java/com/sztzjy/linkCommerce/service/impl/BusinessFeasibilityStepTwoServiceImplTest.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 c1c3246..7712397 100644 --- a/src/main/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerController.java +++ b/src/main/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerController.java @@ -30,6 +30,8 @@ import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentFactorsStepFourValid import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentFactorsStepFourValidationResult; import com.sztzjy.linkCommerce.entity.dto.BusinessFeasibilityStepOneValidationRequest; import com.sztzjy.linkCommerce.entity.dto.BusinessFeasibilityStepOneValidationResult; +import com.sztzjy.linkCommerce.entity.dto.BusinessFeasibilityStepTwoValidationRequest; +import com.sztzjy.linkCommerce.entity.dto.BusinessFeasibilityStepTwoValidationResult; import com.sztzjy.linkCommerce.service.NewProductSurveyStepOneService; import com.sztzjy.linkCommerce.service.MarketOpportunitySelectionStepOneService; import com.sztzjy.linkCommerce.service.MarketOpportunitySelectionStepTwoService; @@ -43,6 +45,7 @@ import com.sztzjy.linkCommerce.service.ProductDevelopmentFactorsStepTwoService; import com.sztzjy.linkCommerce.service.ProductDevelopmentFactorsStepThreeService; import com.sztzjy.linkCommerce.service.ProductDevelopmentFactorsStepFourService; import com.sztzjy.linkCommerce.service.BusinessFeasibilityStepOneService; +import com.sztzjy.linkCommerce.service.BusinessFeasibilityStepTwoService; import com.sztzjy.linkCommerce.service.StudentTrainingAnswerService; import com.sztzjy.linkCommerce.util.ResultEntity; import io.swagger.annotations.Api; @@ -97,6 +100,9 @@ public class StudentTrainingAnswerController { @Autowired private BusinessFeasibilityStepOneService businessFeasibilityStepOneService; + @Autowired + private BusinessFeasibilityStepTwoService businessFeasibilityStepTwoService; + @GetMapping("/{taskKey}") @ApiOperation("查询当前学生指定实训任务答案") public ResultEntity detail(@PathVariable String taskKey, @@ -268,6 +274,17 @@ public class StudentTrainingAnswerController { } } + @PostMapping("/business-feasibility/step-2/validate") + @ApiOperation("商业可行性论证第二步校验") + public ResultEntity validateBusinessFeasibilityStepTwo( + @RequestBody BusinessFeasibilityStepTwoValidationRequest answer, HttpServletRequest request) { + try { + return new ResultEntity<>(HttpStatus.OK, "校验通过", businessFeasibilityStepTwoService.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/BusinessFeasibilityStepTwoValidationRequest.java b/src/main/java/com/sztzjy/linkCommerce/entity/dto/BusinessFeasibilityStepTwoValidationRequest.java new file mode 100644 index 0000000..1e1769f --- /dev/null +++ b/src/main/java/com/sztzjy/linkCommerce/entity/dto/BusinessFeasibilityStepTwoValidationRequest.java @@ -0,0 +1,12 @@ +package com.sztzjy.linkCommerce.entity.dto; + +import java.util.List; + +public class BusinessFeasibilityStepTwoValidationRequest { + private String decision; + private List priorities; + public String getDecision() { return decision; } + public void setDecision(String decision) { this.decision = decision; } + public List getPriorities() { return priorities; } + public void setPriorities(List priorities) { this.priorities = priorities; } +} diff --git a/src/main/java/com/sztzjy/linkCommerce/entity/dto/BusinessFeasibilityStepTwoValidationResult.java b/src/main/java/com/sztzjy/linkCommerce/entity/dto/BusinessFeasibilityStepTwoValidationResult.java new file mode 100644 index 0000000..1ebce60 --- /dev/null +++ b/src/main/java/com/sztzjy/linkCommerce/entity/dto/BusinessFeasibilityStepTwoValidationResult.java @@ -0,0 +1,10 @@ +package com.sztzjy.linkCommerce.entity.dto; + +public class BusinessFeasibilityStepTwoValidationResult { + 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/BusinessFeasibilityStepTwoService.java b/src/main/java/com/sztzjy/linkCommerce/service/BusinessFeasibilityStepTwoService.java new file mode 100644 index 0000000..904a1d5 --- /dev/null +++ b/src/main/java/com/sztzjy/linkCommerce/service/BusinessFeasibilityStepTwoService.java @@ -0,0 +1,9 @@ +package com.sztzjy.linkCommerce.service; + +import com.sztzjy.linkCommerce.config.security.JwtUser; +import com.sztzjy.linkCommerce.entity.dto.BusinessFeasibilityStepTwoValidationRequest; +import com.sztzjy.linkCommerce.entity.dto.BusinessFeasibilityStepTwoValidationResult; + +public interface BusinessFeasibilityStepTwoService { + BusinessFeasibilityStepTwoValidationResult validate(BusinessFeasibilityStepTwoValidationRequest request, JwtUser user); +} diff --git a/src/main/java/com/sztzjy/linkCommerce/service/impl/BusinessFeasibilityStepTwoServiceImpl.java b/src/main/java/com/sztzjy/linkCommerce/service/impl/BusinessFeasibilityStepTwoServiceImpl.java new file mode 100644 index 0000000..ebb96b3 --- /dev/null +++ b/src/main/java/com/sztzjy/linkCommerce/service/impl/BusinessFeasibilityStepTwoServiceImpl.java @@ -0,0 +1,40 @@ +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.BusinessFeasibilityStepTwoValidationRequest; +import com.sztzjy.linkCommerce.entity.dto.BusinessFeasibilityStepTwoValidationResult; +import com.sztzjy.linkCommerce.service.BusinessFeasibilityStepTwoService; +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.Arrays; +import java.util.LinkedHashSet; +import java.util.Set; + +@Service +public class BusinessFeasibilityStepTwoServiceImpl implements BusinessFeasibilityStepTwoService { + private static final String TASK_KEY = "business-feasibility"; + private static final Set DECISIONS = new LinkedHashSet<>(Arrays.asList("highly-feasible", "feasible-after-optimization", "observe", "not-feasible")); + private static final Set PRIORITIES = new LinkedHashSet<>(Arrays.asList("hardware-cost-control", "content-ecosystem", "channel-expansion", "brand-differentiation", "supply-chain-management", "capital-planning")); + @Autowired private StudentTrainingAnswerService studentTrainingAnswerService; + + @Override + public BusinessFeasibilityStepTwoValidationResult validate(BusinessFeasibilityStepTwoValidationRequest request, JwtUser user) { + if (user == null || StringUtils.isBlank(user.getUserId())) throw new ServiceException(HttpStatus.UNAUTHORIZED, "请先登录后再校验"); + if (user.getRoleId() != 4) throw new ServiceException(HttpStatus.FORBIDDEN, "仅学生可进行实训校验"); + StudentTrainingAnswer saved = studentTrainingAnswerService.get(TASK_KEY, null, user); + if (saved == null || StringUtils.isBlank(saved.getStep1Answer())) throw new ServiceException(HttpStatus.BAD_REQUEST, "请先完成并保存第 1 步商业可行性论证"); + String decision = request == null ? "" : StringUtils.trimToEmpty(request.getDecision()); + if (!DECISIONS.contains(decision)) throw new ServiceException(HttpStatus.BAD_REQUEST, "请选择项目商业可行性总体评估"); + Set selected = new LinkedHashSet<>(); + if (request.getPriorities() != null) for (String priority : request.getPriorities()) { String value = StringUtils.trimToEmpty(priority); if (!PRIORITIES.contains(value) || !selected.add(value)) throw new ServiceException(HttpStatus.BAD_REQUEST, "优先问题包含无效或重复项"); } + if ("not-feasible".equals(decision)) { if (!selected.isEmpty()) throw new ServiceException(HttpStatus.BAD_REQUEST, "选择不可行时无需勾选优先问题"); } + else if (selected.size() != 3) throw new ServiceException(HttpStatus.BAD_REQUEST, "请且仅选择 3 个需要优先解决的关键问题"); + BusinessFeasibilityStepTwoValidationResult result = new BusinessFeasibilityStepTwoValidationResult(); result.setValid(true); result.setMessage("校验通过"); return result; + } +} diff --git a/src/test/java/com/sztzjy/linkCommerce/service/impl/BusinessFeasibilityStepTwoServiceImplTest.java b/src/test/java/com/sztzjy/linkCommerce/service/impl/BusinessFeasibilityStepTwoServiceImplTest.java new file mode 100644 index 0000000..3df45e5 --- /dev/null +++ b/src/test/java/com/sztzjy/linkCommerce/service/impl/BusinessFeasibilityStepTwoServiceImplTest.java @@ -0,0 +1,40 @@ +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.BusinessFeasibilityStepTwoValidationRequest; +import com.sztzjy.linkCommerce.service.StudentTrainingAnswerService; +import org.junit.jupiter.api.Test; +import org.springframework.test.util.ReflectionTestUtils; + +import java.util.Arrays; + +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 BusinessFeasibilityStepTwoServiceImplTest { + @Test + void validatesThreePrioritiesForProjectDecision() { + assertTrue(serviceWithStepOne().validate(request("feasible-after-optimization", "hardware-cost-control", "channel-expansion", "capital-planning"), student()).isValid()); + } + + @Test + void acceptsNoPriorityForNotFeasibleAndRejectsOtherCounts() { + assertTrue(serviceWithStepOne().validate(request("not-feasible"), student()).isValid()); + assertThrows(ServiceException.class, () -> serviceWithStepOne().validate(request("observe", "hardware-cost-control", "channel-expansion"), student())); + assertThrows(ServiceException.class, () -> serviceWithStepOne().validate(request("not-feasible", "hardware-cost-control"), student())); + } + + private BusinessFeasibilityStepTwoServiceImpl serviceWithStepOne() { + BusinessFeasibilityStepTwoServiceImpl service = new BusinessFeasibilityStepTwoServiceImpl(); + StudentTrainingAnswerService answers = mock(StudentTrainingAnswerService.class); StudentTrainingAnswer answer = new StudentTrainingAnswer(); answer.setStep1Answer("{\"form\":{}}"); + when(answers.get(anyString(), any(), any(JwtUser.class))).thenReturn(answer); ReflectionTestUtils.setField(service, "studentTrainingAnswerService", answers); return service; + } + private BusinessFeasibilityStepTwoValidationRequest request(String decision, String... priorities) { BusinessFeasibilityStepTwoValidationRequest request = new BusinessFeasibilityStepTwoValidationRequest(); request.setDecision(decision); request.setPriorities(Arrays.asList(priorities)); return request; } + private JwtUser student() { JwtUser user = new JwtUser(); user.setUserId("stu-1"); user.setRoleId(4); return user; } +}