feat: validate feature conversion step one
parent
4f4798c42d
commit
766dde4d73
@ -0,0 +1,34 @@
|
|||||||
|
package com.sztzjy.linkCommerce.entity.dto;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class FeatureConversionStepOneValidationRequest {
|
||||||
|
private List<ConversionRow> rows;
|
||||||
|
|
||||||
|
public List<ConversionRow> getRows() {
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRows(List<ConversionRow> rows) {
|
||||||
|
this.rows = rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ConversionRow {
|
||||||
|
private String voice;
|
||||||
|
private String insight;
|
||||||
|
private String definition;
|
||||||
|
private String description;
|
||||||
|
private String acceptance;
|
||||||
|
|
||||||
|
public String getVoice() { return voice; }
|
||||||
|
public void setVoice(String voice) { this.voice = voice; }
|
||||||
|
public String getInsight() { return insight; }
|
||||||
|
public void setInsight(String insight) { this.insight = insight; }
|
||||||
|
public String getDefinition() { return definition; }
|
||||||
|
public void setDefinition(String definition) { this.definition = definition; }
|
||||||
|
public String getDescription() { return description; }
|
||||||
|
public void setDescription(String description) { this.description = description; }
|
||||||
|
public String getAcceptance() { return acceptance; }
|
||||||
|
public void setAcceptance(String acceptance) { this.acceptance = acceptance; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
package com.sztzjy.linkCommerce.entity.dto;
|
||||||
|
|
||||||
|
public class FeatureConversionStepOneValidationResult {
|
||||||
|
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.FeatureConversionStepOneValidationRequest;
|
||||||
|
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepOneValidationResult;
|
||||||
|
|
||||||
|
public interface FeatureConversionStepOneService {
|
||||||
|
FeatureConversionStepOneValidationResult validate(FeatureConversionStepOneValidationRequest request, JwtUser user);
|
||||||
|
}
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
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.FeatureConversionStepOneValidationRequest;
|
||||||
|
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepOneValidationResult;
|
||||||
|
import com.sztzjy.linkCommerce.service.FeatureConversionStepOneService;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class FeatureConversionStepOneServiceImpl implements FeatureConversionStepOneService {
|
||||||
|
private static final int MIN_ROWS = 8;
|
||||||
|
private static final int MAX_ROWS = 12;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FeatureConversionStepOneValidationResult validate(FeatureConversionStepOneValidationRequest request, JwtUser user) {
|
||||||
|
requireStudent(user);
|
||||||
|
List<FeatureConversionStepOneValidationRequest.ConversionRow> rows = request == null ? null : request.getRows();
|
||||||
|
if (rows == null || rows.size() < MIN_ROWS || rows.size() > MAX_ROWS || rows.stream().anyMatch(row -> row == null)) {
|
||||||
|
throw badRequest("请填写 8 至 12 行需求转化信息");
|
||||||
|
}
|
||||||
|
if (rows.stream().anyMatch(row -> StringUtils.isBlank(row.getVoice())
|
||||||
|
|| StringUtils.isBlank(row.getInsight())
|
||||||
|
|| StringUtils.isBlank(row.getDefinition())
|
||||||
|
|| StringUtils.isBlank(row.getDescription())
|
||||||
|
|| StringUtils.isBlank(row.getAcceptance()))) {
|
||||||
|
throw badRequest("请完整填写每行的用户原声、场景洞察、功能定义、功能描述和验收标准");
|
||||||
|
}
|
||||||
|
FeatureConversionStepOneValidationResult result = new FeatureConversionStepOneValidationResult();
|
||||||
|
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,60 @@
|
|||||||
|
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.FeatureConversionStepOneValidationRequest;
|
||||||
|
import com.sztzjy.linkCommerce.entity.dto.FeatureConversionStepOneValidationResult;
|
||||||
|
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 FeatureConversionStepOneServiceImplTest {
|
||||||
|
private final FeatureConversionStepOneServiceImpl service = new FeatureConversionStepOneServiceImpl();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void acceptsEightCompleteRows() {
|
||||||
|
FeatureConversionStepOneValidationResult result = service.validate(request(8), student());
|
||||||
|
|
||||||
|
assertTrue(result.isValid());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void rejectsTooFewRows() {
|
||||||
|
assertThrows(ServiceException.class, () -> service.validate(request(7), student()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void rejectsIncompleteRow() {
|
||||||
|
FeatureConversionStepOneValidationRequest request = request(8);
|
||||||
|
request.getRows().get(0).setAcceptance(" ");
|
||||||
|
|
||||||
|
assertThrows(ServiceException.class, () -> service.validate(request, student()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private FeatureConversionStepOneValidationRequest request(int count) {
|
||||||
|
FeatureConversionStepOneValidationRequest request = new FeatureConversionStepOneValidationRequest();
|
||||||
|
List<FeatureConversionStepOneValidationRequest.ConversionRow> rows = new ArrayList<>();
|
||||||
|
for (int index = 0; index < count; index++) {
|
||||||
|
FeatureConversionStepOneValidationRequest.ConversionRow row = new FeatureConversionStepOneValidationRequest.ConversionRow();
|
||||||
|
row.setVoice("用户原声");
|
||||||
|
row.setInsight("场景洞察");
|
||||||
|
row.setDefinition("功能定义");
|
||||||
|
row.setDescription("功能描述");
|
||||||
|
row.setAcceptance("验收标准");
|
||||||
|
rows.add(row);
|
||||||
|
}
|
||||||
|
request.setRows(rows);
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
private JwtUser student() {
|
||||||
|
JwtUser user = new JwtUser();
|
||||||
|
user.setUserId("stu-1");
|
||||||
|
user.setRoleId(4);
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue