feat: validate feature conversion priorities

main
chenyuan 3 weeks ago
parent f5c61f8035
commit bc263e93ab

@ -41,6 +41,8 @@ import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepOneValidationRequ
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepOneValidationResult; import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepOneValidationResult;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepTwoValidationRequest; import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepTwoValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepTwoValidationResult; import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepTwoValidationResult;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepThreeValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepThreeValidationResult;
import com.sztzjy.linkCommerce.service.NewProductSurveyStepOneService; import com.sztzjy.linkCommerce.service.NewProductSurveyStepOneService;
import com.sztzjy.linkCommerce.service.MarketOpportunitySelectionStepOneService; import com.sztzjy.linkCommerce.service.MarketOpportunitySelectionStepOneService;
import com.sztzjy.linkCommerce.service.MarketOpportunitySelectionStepTwoService; 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.ConsumerBehaviorStepFourService;
import com.sztzjy.linkCommerce.service.FeatureConversionStepOneService; import com.sztzjy.linkCommerce.service.FeatureConversionStepOneService;
import com.sztzjy.linkCommerce.service.FeatureConversionStepTwoService; import com.sztzjy.linkCommerce.service.FeatureConversionStepTwoService;
import com.sztzjy.linkCommerce.service.FeatureConversionStepThreeService;
import com.sztzjy.linkCommerce.service.StudentTrainingAnswerService; import com.sztzjy.linkCommerce.service.StudentTrainingAnswerService;
import com.sztzjy.linkCommerce.util.ResultEntity; import com.sztzjy.linkCommerce.util.ResultEntity;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
@ -129,6 +132,9 @@ public class StudentTrainingAnswerController {
@Autowired @Autowired
private FeatureConversionStepTwoService featureConversionStepTwoService; private FeatureConversionStepTwoService featureConversionStepTwoService;
@Autowired
private FeatureConversionStepThreeService featureConversionStepThreeService;
@GetMapping("/{taskKey}") @GetMapping("/{taskKey}")
@ApiOperation("查询当前学生指定实训任务答案") @ApiOperation("查询当前学生指定实训任务答案")
public ResultEntity<StudentTrainingAnswer> detail(@PathVariable String taskKey, public ResultEntity<StudentTrainingAnswer> detail(@PathVariable String taskKey,
@ -355,6 +361,17 @@ public class StudentTrainingAnswerController {
} }
} }
@PostMapping("/feature-conversion/step-3/validate")
@ApiOperation("需求转化为功能第三步校验")
public ResultEntity<FeatureConversionStepThreeValidationResult> validateFeatureConversionStepThree(
@RequestBody FeatureConversionStepThreeValidationRequest answer, HttpServletRequest request) {
try {
return new ResultEntity<>(HttpStatus.OK, "校验完成", featureConversionStepThreeService.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") @PostMapping(value = "/consumer-behavior/step-3/word-preview", consumes = "multipart/form-data")
@ApiOperation("消费者需求与行为第三步Word预览") @ApiOperation("消费者需求与行为第三步Word预览")
public ResultEntity<ConsumerBehaviorWordPreviewResult> previewConsumerBehaviorStepThreeWord( public ResultEntity<ConsumerBehaviorWordPreviewResult> previewConsumerBehaviorStepThreeWord(

@ -0,0 +1,37 @@
package com.sztzjy.linkCommerce.entity.dto;
import java.util.List;
public class FeatureConversionStepThreeValidationRequest {
private List<FeatureConversionStepTwoValidationRequest.RiceScoreRow> scoreRows;
private List<PriorityRow> rows;
public List<FeatureConversionStepTwoValidationRequest.RiceScoreRow> getScoreRows() {
return scoreRows;
}
public void setScoreRows(List<FeatureConversionStepTwoValidationRequest.RiceScoreRow> scoreRows) {
this.scoreRows = scoreRows;
}
public List<PriorityRow> getRows() {
return rows;
}
public void setRows(List<PriorityRow> rows) {
this.rows = rows;
}
public static class PriorityRow {
private String name;
private String priority;
private String reason;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getPriority() { return priority; }
public void setPriority(String priority) { this.priority = priority; }
public String getReason() { return reason; }
public void setReason(String reason) { this.reason = reason; }
}
}

@ -0,0 +1,11 @@
package com.sztzjy.linkCommerce.entity.dto;
public class FeatureConversionStepThreeValidationResult {
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; }
}

@ -0,0 +1,9 @@
package com.sztzjy.linkCommerce.service;
import com.sztzjy.linkCommerce.config.security.JwtUser;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepThreeValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepThreeValidationResult;
public interface FeatureConversionStepThreeService {
FeatureConversionStepThreeValidationResult validate(FeatureConversionStepThreeValidationRequest request, JwtUser user);
}

@ -0,0 +1,58 @@
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.FeatureConversionStepThreeValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepThreeValidationResult;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepTwoValidationRequest;
import com.sztzjy.linkCommerce.service.FeatureConversionStepThreeService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
@Service
public class FeatureConversionStepThreeServiceImpl implements FeatureConversionStepThreeService {
private static final int MIN_ROWS = 8;
private static final int MAX_ROWS = 12;
private static final List<String> PRIORITIES = Arrays.asList("P0", "P1", "P2", "P3");
@Override
public FeatureConversionStepThreeValidationResult validate(FeatureConversionStepThreeValidationRequest request, JwtUser user) {
requireStudent(user);
List<FeatureConversionStepTwoValidationRequest.RiceScoreRow> scoreRows = request == null ? null : request.getScoreRows();
List<FeatureConversionStepThreeValidationRequest.PriorityRow> rows = request == null ? null : request.getRows();
if (scoreRows == null || rows == null || scoreRows.size() < MIN_ROWS || scoreRows.size() > MAX_ROWS || scoreRows.size() != rows.size()) {
throw badRequest("功能优先级表必须与第二步 RICE 评分表保持一致,且为 8 至 12 行");
}
for (int index = 0; index < rows.size(); index++) {
FeatureConversionStepTwoValidationRequest.RiceScoreRow scoreRow = scoreRows.get(index);
FeatureConversionStepThreeValidationRequest.PriorityRow row = rows.get(index);
if (scoreRow == null || row == null || StringUtils.isBlank(scoreRow.getName()) || !scoreRow.getName().equals(row.getName())) {
throw badRequest("功能名称和行数必须与第二步 RICE 评分表保持一致");
}
if (!PRIORITIES.contains(row.getPriority()) || StringUtils.isBlank(row.getReason())) {
throw badRequest("请为每项功能选择 P0-P3 优先级并填写划分理由");
}
}
FeatureConversionStepThreeValidationResult result = new FeatureConversionStepThreeValidationResult();
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);
}
}

@ -0,0 +1,69 @@
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.FeatureConversionStepThreeValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepThreeValidationResult;
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepTwoValidationRequest;
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 FeatureConversionStepThreeServiceImplTest {
private final FeatureConversionStepThreeServiceImpl service = new FeatureConversionStepThreeServiceImpl();
@Test
void acceptsPriorityRowsSynchronizedWithRiceRows() {
FeatureConversionStepThreeValidationResult result = service.validate(request(), student());
assertTrue(result.isValid());
}
@Test
void rejectsPriorityNameNotSynchronizedWithRiceRows() {
FeatureConversionStepThreeValidationRequest request = request();
request.getRows().get(0).setName("被篡改的功能名称");
assertThrows(ServiceException.class, () -> service.validate(request, student()));
}
@Test
void rejectsBlankPriorityReason() {
FeatureConversionStepThreeValidationRequest request = request();
request.getRows().get(0).setReason(" ");
assertThrows(ServiceException.class, () -> service.validate(request, student()));
}
private FeatureConversionStepThreeValidationRequest request() {
FeatureConversionStepThreeValidationRequest request = new FeatureConversionStepThreeValidationRequest();
List<FeatureConversionStepTwoValidationRequest.RiceScoreRow> scoreRows = new ArrayList<>();
List<FeatureConversionStepThreeValidationRequest.PriorityRow> rows = new ArrayList<>();
for (int index = 0; index < 8; index++) {
String name = "功能定义" + (index + 1);
FeatureConversionStepTwoValidationRequest.RiceScoreRow scoreRow = new FeatureConversionStepTwoValidationRequest.RiceScoreRow();
scoreRow.setName(name);
scoreRows.add(scoreRow);
FeatureConversionStepThreeValidationRequest.PriorityRow row = new FeatureConversionStepThreeValidationRequest.PriorityRow();
row.setName(name);
row.setPriority(index == 0 ? "P0" : "P1");
row.setReason("结合 RICE 评分确定开发优先级");
rows.add(row);
}
request.setScoreRows(scoreRows);
request.setRows(rows);
return request;
}
private JwtUser student() {
JwtUser user = new JwtUser();
user.setUserId("student-id");
user.setRoleId(4);
return user;
}
}
Loading…
Cancel
Save