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 7712397..9c669bd 100644 --- a/src/main/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerController.java +++ b/src/main/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerController.java @@ -32,6 +32,8 @@ import com.sztzjy.linkCommerce.entity.dto.BusinessFeasibilityStepOneValidationRe 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.entity.dto.BusinessFeasibilityStepThreeValidationRequest; +import com.sztzjy.linkCommerce.entity.dto.BusinessFeasibilityStepThreeValidationResult; import com.sztzjy.linkCommerce.service.NewProductSurveyStepOneService; import com.sztzjy.linkCommerce.service.MarketOpportunitySelectionStepOneService; import com.sztzjy.linkCommerce.service.MarketOpportunitySelectionStepTwoService; @@ -46,6 +48,7 @@ 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.BusinessFeasibilityStepThreeService; import com.sztzjy.linkCommerce.service.StudentTrainingAnswerService; import com.sztzjy.linkCommerce.util.ResultEntity; import io.swagger.annotations.Api; @@ -103,6 +106,9 @@ public class StudentTrainingAnswerController { @Autowired private BusinessFeasibilityStepTwoService businessFeasibilityStepTwoService; + @Autowired + private BusinessFeasibilityStepThreeService businessFeasibilityStepThreeService; + @GetMapping("/{taskKey}") @ApiOperation("查询当前学生指定实训任务答案") public ResultEntity detail(@PathVariable String taskKey, @@ -285,6 +291,17 @@ public class StudentTrainingAnswerController { } } + @PostMapping("/business-feasibility/step-3/validate") + @ApiOperation("商业可行性论证第三步校验") + public ResultEntity validateBusinessFeasibilityStepThree( + @RequestBody BusinessFeasibilityStepThreeValidationRequest answer, HttpServletRequest request) { + try { + return new ResultEntity<>(HttpStatus.OK, "校验通过", businessFeasibilityStepThreeService.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/BusinessFeasibilityStepThreeValidationRequest.java b/src/main/java/com/sztzjy/linkCommerce/entity/dto/BusinessFeasibilityStepThreeValidationRequest.java new file mode 100644 index 0000000..fbf018c --- /dev/null +++ b/src/main/java/com/sztzjy/linkCommerce/entity/dto/BusinessFeasibilityStepThreeValidationRequest.java @@ -0,0 +1,10 @@ +package com.sztzjy.linkCommerce.entity.dto; + +public class BusinessFeasibilityStepThreeValidationRequest { + private String reportUrl; + private String reportName; + public String getReportUrl() { return reportUrl; } + public void setReportUrl(String reportUrl) { this.reportUrl = reportUrl; } + public String getReportName() { return reportName; } + public void setReportName(String reportName) { this.reportName = reportName; } +} diff --git a/src/main/java/com/sztzjy/linkCommerce/entity/dto/BusinessFeasibilityStepThreeValidationResult.java b/src/main/java/com/sztzjy/linkCommerce/entity/dto/BusinessFeasibilityStepThreeValidationResult.java new file mode 100644 index 0000000..20dbc05 --- /dev/null +++ b/src/main/java/com/sztzjy/linkCommerce/entity/dto/BusinessFeasibilityStepThreeValidationResult.java @@ -0,0 +1,10 @@ +package com.sztzjy.linkCommerce.entity.dto; + +public class BusinessFeasibilityStepThreeValidationResult { + 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/BusinessFeasibilityStepThreeService.java b/src/main/java/com/sztzjy/linkCommerce/service/BusinessFeasibilityStepThreeService.java new file mode 100644 index 0000000..3cfc224 --- /dev/null +++ b/src/main/java/com/sztzjy/linkCommerce/service/BusinessFeasibilityStepThreeService.java @@ -0,0 +1,9 @@ +package com.sztzjy.linkCommerce.service; + +import com.sztzjy.linkCommerce.config.security.JwtUser; +import com.sztzjy.linkCommerce.entity.dto.BusinessFeasibilityStepThreeValidationRequest; +import com.sztzjy.linkCommerce.entity.dto.BusinessFeasibilityStepThreeValidationResult; + +public interface BusinessFeasibilityStepThreeService { + BusinessFeasibilityStepThreeValidationResult validate(BusinessFeasibilityStepThreeValidationRequest request, JwtUser user); +} diff --git a/src/main/java/com/sztzjy/linkCommerce/service/impl/BusinessFeasibilityStepThreeServiceImpl.java b/src/main/java/com/sztzjy/linkCommerce/service/impl/BusinessFeasibilityStepThreeServiceImpl.java new file mode 100644 index 0000000..89fcc58 --- /dev/null +++ b/src/main/java/com/sztzjy/linkCommerce/service/impl/BusinessFeasibilityStepThreeServiceImpl.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.StudentTrainingAnswer; +import com.sztzjy.linkCommerce.entity.dto.BusinessFeasibilityStepThreeValidationRequest; +import com.sztzjy.linkCommerce.entity.dto.BusinessFeasibilityStepThreeValidationResult; +import com.sztzjy.linkCommerce.service.BusinessFeasibilityStepThreeService; +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.Locale; + +@Service +public class BusinessFeasibilityStepThreeServiceImpl implements BusinessFeasibilityStepThreeService { + private static final String TASK_KEY = "business-feasibility"; + @Autowired private StudentTrainingAnswerService studentTrainingAnswerService; + + @Override + public BusinessFeasibilityStepThreeValidationResult validate(BusinessFeasibilityStepThreeValidationRequest 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()) || StringUtils.isBlank(saved.getStep2Answer())) throw new ServiceException(HttpStatus.BAD_REQUEST, "请先完成并保存前两步商业可行性论证"); + String url = request == null ? "" : StringUtils.trimToEmpty(request.getReportUrl()); + String name = request == null ? "" : StringUtils.trimToEmpty(request.getReportName()); + if (StringUtils.isBlank(url) || !isSupported(url, name)) throw new ServiceException(HttpStatus.BAD_REQUEST, "请上传 PDF、Word、PNG 或 JPG 格式的可行性论证报告"); + BusinessFeasibilityStepThreeValidationResult result = new BusinessFeasibilityStepThreeValidationResult(); result.setValid(true); result.setMessage("校验通过"); return result; + } + + private boolean isSupported(String url, String name) { + String value = (url + " " + name).toLowerCase(Locale.ROOT); + return value.matches(".*\\.(pdf|doc|docx|png|jpg|jpeg)(?:[?\\s].*)?"); + } +} diff --git a/src/test/java/com/sztzjy/linkCommerce/service/impl/BusinessFeasibilityStepThreeServiceImplTest.java b/src/test/java/com/sztzjy/linkCommerce/service/impl/BusinessFeasibilityStepThreeServiceImplTest.java new file mode 100644 index 0000000..1e448ea --- /dev/null +++ b/src/test/java/com/sztzjy/linkCommerce/service/impl/BusinessFeasibilityStepThreeServiceImplTest.java @@ -0,0 +1,35 @@ +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.BusinessFeasibilityStepThreeValidationRequest; +import com.sztzjy.linkCommerce.service.StudentTrainingAnswerService; +import org.junit.jupiter.api.Test; +import org.springframework.test.util.ReflectionTestUtils; + +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 BusinessFeasibilityStepThreeServiceImplTest { + @Test + void validatesUploadedReportAfterFirstTwoSteps() { + BusinessFeasibilityStepThreeValidationRequest request = request("/profile/upload/feasibility-report.docx", "feasibility-report.docx"); + assertTrue(serviceWithFirstTwoSteps().validate(request, student()).isValid()); + } + + @Test + void rejectsUnsupportedReportAndMissingPrerequisite() { + assertThrows(ServiceException.class, () -> serviceWithFirstTwoSteps().validate(request("/profile/upload/report.zip", "report.zip"), student())); + BusinessFeasibilityStepThreeServiceImpl service = new BusinessFeasibilityStepThreeServiceImpl(); StudentTrainingAnswerService answers = mock(StudentTrainingAnswerService.class); when(answers.get(anyString(), any(), any(JwtUser.class))).thenReturn(new StudentTrainingAnswer()); ReflectionTestUtils.setField(service, "studentTrainingAnswerService", answers); + assertThrows(ServiceException.class, () -> service.validate(request("/profile/upload/report.pdf", "report.pdf"), student())); + } + + private BusinessFeasibilityStepThreeServiceImpl serviceWithFirstTwoSteps() { BusinessFeasibilityStepThreeServiceImpl service = new BusinessFeasibilityStepThreeServiceImpl(); StudentTrainingAnswerService answers = mock(StudentTrainingAnswerService.class); StudentTrainingAnswer answer = new StudentTrainingAnswer(); answer.setStep1Answer("{}"); answer.setStep2Answer("{}"); when(answers.get(anyString(), any(), any(JwtUser.class))).thenReturn(answer); ReflectionTestUtils.setField(service, "studentTrainingAnswerService", answers); return service; } + private BusinessFeasibilityStepThreeValidationRequest request(String url, String name) { BusinessFeasibilityStepThreeValidationRequest request = new BusinessFeasibilityStepThreeValidationRequest(); request.setReportUrl(url); request.setReportName(name); return request; } + private JwtUser student() { JwtUser user = new JwtUser(); user.setUserId("stu-1"); user.setRoleId(4); return user; } +}