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 5f892de..db23151 100644 --- a/src/main/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerController.java +++ b/src/main/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerController.java @@ -28,6 +28,8 @@ import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentFactorsStepThreeVali import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentFactorsStepThreeValidationResult; import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentFactorsStepFourValidationRequest; import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentFactorsStepFourValidationResult; +import com.sztzjy.linkCommerce.entity.dto.TargetUserProfileStepOneValidationRequest; +import com.sztzjy.linkCommerce.entity.dto.TargetUserProfileStepOneValidationResult; import com.sztzjy.linkCommerce.service.NewProductSurveyStepOneService; import com.sztzjy.linkCommerce.service.MarketOpportunitySelectionStepOneService; import com.sztzjy.linkCommerce.service.MarketOpportunitySelectionStepTwoService; @@ -40,6 +42,7 @@ import com.sztzjy.linkCommerce.service.ProductDevelopmentFactorsStepOneService; import com.sztzjy.linkCommerce.service.ProductDevelopmentFactorsStepTwoService; import com.sztzjy.linkCommerce.service.ProductDevelopmentFactorsStepThreeService; import com.sztzjy.linkCommerce.service.ProductDevelopmentFactorsStepFourService; +import com.sztzjy.linkCommerce.service.TargetUserProfileStepOneService; import com.sztzjy.linkCommerce.service.StudentTrainingAnswerService; import com.sztzjy.linkCommerce.util.ResultEntity; import io.swagger.annotations.Api; @@ -91,6 +94,9 @@ public class StudentTrainingAnswerController { @Autowired private ProductDevelopmentFactorsStepFourService productDevelopmentFactorsStepFourService; + @Autowired + private TargetUserProfileStepOneService targetUserProfileStepOneService; + @GetMapping("/{taskKey}") @ApiOperation("查询当前学生指定实训任务答案") public ResultEntity detail(@PathVariable String taskKey, @@ -251,6 +257,17 @@ public class StudentTrainingAnswerController { catch (ServiceException e) { return new ResultEntity<>(e.getCode(), e.getMessage()); } } + @PostMapping("/target-user-profile/step-1/validate") + @ApiOperation("目标用户画像第一步校验") + public ResultEntity validateTargetUserProfileStepOne( + @RequestBody TargetUserProfileStepOneValidationRequest answer, HttpServletRequest request) { + try { + return new ResultEntity<>(HttpStatus.OK, "校验通过", targetUserProfileStepOneService.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/TargetUserProfileStepOneValidationRequest.java b/src/main/java/com/sztzjy/linkCommerce/entity/dto/TargetUserProfileStepOneValidationRequest.java new file mode 100644 index 0000000..4fc9cb9 --- /dev/null +++ b/src/main/java/com/sztzjy/linkCommerce/entity/dto/TargetUserProfileStepOneValidationRequest.java @@ -0,0 +1,17 @@ +package com.sztzjy.linkCommerce.entity.dto; + +public class TargetUserProfileStepOneValidationRequest { + private String excelUrl; + private String excelName; + private Integer previewRowCount; + private Integer previewColumnCount; + + public String getExcelUrl() { return excelUrl; } + public void setExcelUrl(String excelUrl) { this.excelUrl = excelUrl; } + public String getExcelName() { return excelName; } + public void setExcelName(String excelName) { this.excelName = excelName; } + public Integer getPreviewRowCount() { return previewRowCount; } + public void setPreviewRowCount(Integer previewRowCount) { this.previewRowCount = previewRowCount; } + public Integer getPreviewColumnCount() { return previewColumnCount; } + public void setPreviewColumnCount(Integer previewColumnCount) { this.previewColumnCount = previewColumnCount; } +} diff --git a/src/main/java/com/sztzjy/linkCommerce/entity/dto/TargetUserProfileStepOneValidationResult.java b/src/main/java/com/sztzjy/linkCommerce/entity/dto/TargetUserProfileStepOneValidationResult.java new file mode 100644 index 0000000..fd04039 --- /dev/null +++ b/src/main/java/com/sztzjy/linkCommerce/entity/dto/TargetUserProfileStepOneValidationResult.java @@ -0,0 +1,11 @@ +package com.sztzjy.linkCommerce.entity.dto; + +public class TargetUserProfileStepOneValidationResult { + 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/TargetUserProfileStepOneService.java b/src/main/java/com/sztzjy/linkCommerce/service/TargetUserProfileStepOneService.java new file mode 100644 index 0000000..1f5f119 --- /dev/null +++ b/src/main/java/com/sztzjy/linkCommerce/service/TargetUserProfileStepOneService.java @@ -0,0 +1,9 @@ +package com.sztzjy.linkCommerce.service; + +import com.sztzjy.linkCommerce.config.security.JwtUser; +import com.sztzjy.linkCommerce.entity.dto.TargetUserProfileStepOneValidationRequest; +import com.sztzjy.linkCommerce.entity.dto.TargetUserProfileStepOneValidationResult; + +public interface TargetUserProfileStepOneService { + TargetUserProfileStepOneValidationResult validate(TargetUserProfileStepOneValidationRequest request, JwtUser user); +} diff --git a/src/main/java/com/sztzjy/linkCommerce/service/impl/TargetUserProfileStepOneServiceImpl.java b/src/main/java/com/sztzjy/linkCommerce/service/impl/TargetUserProfileStepOneServiceImpl.java new file mode 100644 index 0000000..c1d349e --- /dev/null +++ b/src/main/java/com/sztzjy/linkCommerce/service/impl/TargetUserProfileStepOneServiceImpl.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.dto.TargetUserProfileStepOneValidationRequest; +import com.sztzjy.linkCommerce.entity.dto.TargetUserProfileStepOneValidationResult; +import com.sztzjy.linkCommerce.service.TargetUserProfileStepOneService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; + +import java.util.Locale; + +@Service +public class TargetUserProfileStepOneServiceImpl implements TargetUserProfileStepOneService { + @Override + public TargetUserProfileStepOneValidationResult validate(TargetUserProfileStepOneValidationRequest 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 || StringUtils.isBlank(request.getExcelUrl()) || StringUtils.isBlank(request.getExcelName())) { + throw new ServiceException(HttpStatus.BAD_REQUEST, "请上传 RFM 用户分层分析结果 Excel 数据"); + } + String excelName = request.getExcelName().trim().toLowerCase(Locale.ROOT); + if (!excelName.endsWith(".xls") && !excelName.endsWith(".xlsx")) { + throw new ServiceException(HttpStatus.BAD_REQUEST, "仅支持 .xls、.xlsx 格式的 Excel 文件"); + } + if (request.getPreviewRowCount() == null || request.getPreviewRowCount() < 1 + || request.getPreviewColumnCount() == null || request.getPreviewColumnCount() < 1) { + throw new ServiceException(HttpStatus.BAD_REQUEST, "Excel 文件需要包含可预览的表头和数据"); + } + TargetUserProfileStepOneValidationResult result = new TargetUserProfileStepOneValidationResult(); + result.setValid(true); + result.setMessage("校验通过"); + return result; + } +} diff --git a/src/test/java/com/sztzjy/linkCommerce/service/impl/TargetUserProfileStepOneServiceImplTest.java b/src/test/java/com/sztzjy/linkCommerce/service/impl/TargetUserProfileStepOneServiceImplTest.java new file mode 100644 index 0000000..6ab8f7a --- /dev/null +++ b/src/test/java/com/sztzjy/linkCommerce/service/impl/TargetUserProfileStepOneServiceImplTest.java @@ -0,0 +1,39 @@ +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.TargetUserProfileStepOneValidationRequest; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class TargetUserProfileStepOneServiceImplTest { + @Test + void validatesStudentRfmExcelWithPreview() { + assertTrue(new TargetUserProfileStepOneServiceImpl().validate(request("rfm.xlsx", 20, 6), student()).isValid()); + } + + @Test + void rejectsNonExcelFileAndUnpreviewableWorkbook() { + TargetUserProfileStepOneServiceImpl service = new TargetUserProfileStepOneServiceImpl(); + assertThrows(ServiceException.class, () -> service.validate(request("rfm.pdf", 2, 6), student())); + assertThrows(ServiceException.class, () -> service.validate(request("rfm.xlsx", 0, 0), student())); + } + + private TargetUserProfileStepOneValidationRequest request(String excelName, int rows, int columns) { + TargetUserProfileStepOneValidationRequest request = new TargetUserProfileStepOneValidationRequest(); + request.setExcelName(excelName); + request.setExcelUrl("/profile/" + excelName); + request.setPreviewRowCount(rows); + request.setPreviewColumnCount(columns); + return request; + } + + private JwtUser student() { + JwtUser user = new JwtUser(); + user.setUserId("stu-1"); + user.setRoleId(4); + return user; + } +}