feat: validate market opportunity selection step two

main
chenyuan 3 weeks ago
parent 38aa2bb68d
commit 6462dd13d2

@ -8,6 +8,8 @@ import com.sztzjy.linkCommerce.entity.dto.NewProductSurveyStepOneCheckRequest;
import com.sztzjy.linkCommerce.entity.dto.NewProductSurveyStepOneCheckResult;
import com.sztzjy.linkCommerce.entity.dto.MarketOpportunitySelectionStepOneCheckRequest;
import com.sztzjy.linkCommerce.entity.dto.MarketOpportunitySelectionStepOneCheckResult;
import com.sztzjy.linkCommerce.entity.dto.MarketOpportunitySelectionStepTwoValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.MarketOpportunitySelectionStepTwoValidationResult;
import com.sztzjy.linkCommerce.entity.dto.NewProductSurveyStepTwoValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.NewProductSurveyStepTwoValidationResult;
import com.sztzjy.linkCommerce.entity.dto.NewProductSurveyStepThreeValidationRequest;
@ -24,6 +26,7 @@ import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentFactorsStepFourValid
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentFactorsStepFourValidationResult;
import com.sztzjy.linkCommerce.service.NewProductSurveyStepOneService;
import com.sztzjy.linkCommerce.service.MarketOpportunitySelectionStepOneService;
import com.sztzjy.linkCommerce.service.MarketOpportunitySelectionStepTwoService;
import com.sztzjy.linkCommerce.service.NewProductSurveyStepTwoService;
import com.sztzjy.linkCommerce.service.NewProductSurveyStepThreeService;
import com.sztzjy.linkCommerce.service.NewProductSurveyStepFourService;
@ -54,6 +57,9 @@ public class StudentTrainingAnswerController {
@Autowired
private MarketOpportunitySelectionStepOneService marketOpportunitySelectionStepOneService;
@Autowired
private MarketOpportunitySelectionStepTwoService marketOpportunitySelectionStepTwoService;
@Autowired
private NewProductSurveyStepTwoService newProductSurveyStepTwoService;
@ -122,6 +128,17 @@ public class StudentTrainingAnswerController {
}
}
@PostMapping("/market-opportunity-selection/step-2/validate")
@ApiOperation("市场机会识别与选品第二步校验")
public ResultEntity<MarketOpportunitySelectionStepTwoValidationResult> validateMarketOpportunitySelectionStepTwo(
@RequestBody MarketOpportunitySelectionStepTwoValidationRequest answer, HttpServletRequest request) {
try {
return new ResultEntity<>(HttpStatus.OK, "校验通过", marketOpportunitySelectionStepTwoService.validate(answer, TokenProvider.getJWTUser(request)));
} catch (ServiceException e) {
return new ResultEntity<>(e.getCode(), e.getMessage());
}
}
@PostMapping("/new-product-survey/step-2/validate")
@ApiOperation("新产品调查与分析第二步校验")
public ResultEntity<NewProductSurveyStepTwoValidationResult> validateNewProductSurveyStepTwo(

@ -0,0 +1,17 @@
package com.sztzjy.linkCommerce.entity.dto;
import java.util.List;
public class MarketOpportunitySelectionStepTwoValidationRequest {
private List<Weight> weights;
public List<Weight> getWeights() { return weights; }
public void setWeights(List<Weight> weights) { this.weights = weights; }
public static class Weight {
private String id;
private Integer weight;
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public Integer getWeight() { return weight; }
public void setWeight(Integer weight) { this.weight = weight; }
}
}

@ -0,0 +1,10 @@
package com.sztzjy.linkCommerce.entity.dto;
public class MarketOpportunitySelectionStepTwoValidationResult {
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.MarketOpportunitySelectionStepTwoValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.MarketOpportunitySelectionStepTwoValidationResult;
public interface MarketOpportunitySelectionStepTwoService {
MarketOpportunitySelectionStepTwoValidationResult validate(MarketOpportunitySelectionStepTwoValidationRequest request, JwtUser user);
}

@ -0,0 +1,42 @@
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.MarketOpportunitySelectionStepTwoValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.MarketOpportunitySelectionStepTwoValidationResult;
import com.sztzjy.linkCommerce.service.MarketOpportunitySelectionStepTwoService;
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 MarketOpportunitySelectionStepTwoServiceImpl implements MarketOpportunitySelectionStepTwoService {
private static final String TASK_KEY = "market-opportunity-selection";
private static final Set<String> INDICATOR_IDS = new LinkedHashSet<>(Arrays.asList("search-count", "transaction-amount", "transaction-growth", "category-transaction-growth", "demand-supply-ratio", "online-products", "online-merchants", "organic-traffic-ratio"));
@Autowired private StudentTrainingAnswerService studentTrainingAnswerService;
@Override
public MarketOpportunitySelectionStepTwoValidationResult validate(MarketOpportunitySelectionStepTwoValidationRequest 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 savedAnswer = studentTrainingAnswerService.get(TASK_KEY, null, user);
if (savedAnswer == null || StringUtils.isBlank(savedAnswer.getStep1Answer())) throw new ServiceException(HttpStatus.BAD_REQUEST, "请先完成并保存第 1 步指标分类");
if (request == null || request.getWeights() == null || request.getWeights().size() != INDICATOR_IDS.size()) throw new ServiceException(HttpStatus.BAD_REQUEST, "请为全部二级指标填写权重");
Set<String> submittedIds = new LinkedHashSet<>(); int totalWeight = 0;
for (MarketOpportunitySelectionStepTwoValidationRequest.Weight item : request.getWeights()) {
String id = item == null ? "" : StringUtils.trimToEmpty(item.getId()); Integer weight = item == null ? null : item.getWeight();
if (!INDICATOR_IDS.contains(id) || !submittedIds.add(id) || weight == null || weight < 1 || weight > 100) throw new ServiceException(HttpStatus.BAD_REQUEST, "二级指标权重需为 1 至 100 的整数");
totalWeight += weight;
}
if (!submittedIds.equals(INDICATOR_IDS)) throw new ServiceException(HttpStatus.BAD_REQUEST, "提交的二级指标不完整");
if (totalWeight != 100) throw new ServiceException(HttpStatus.BAD_REQUEST, "二级指标权重合计必须为 100%");
MarketOpportunitySelectionStepTwoValidationResult result = new MarketOpportunitySelectionStepTwoValidationResult(); result.setValid(true); result.setMessage("校验通过"); return result;
}
}

@ -7,6 +7,8 @@ import com.sztzjy.linkCommerce.entity.dto.NewProductSurveyStepOneCheckRequest;
import com.sztzjy.linkCommerce.entity.dto.NewProductSurveyStepOneCheckResult;
import com.sztzjy.linkCommerce.entity.dto.MarketOpportunitySelectionStepOneCheckRequest;
import com.sztzjy.linkCommerce.entity.dto.MarketOpportunitySelectionStepOneCheckResult;
import com.sztzjy.linkCommerce.entity.dto.MarketOpportunitySelectionStepTwoValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.MarketOpportunitySelectionStepTwoValidationResult;
import com.sztzjy.linkCommerce.entity.dto.NewProductSurveyStepTwoValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.NewProductSurveyStepTwoValidationResult;
import com.sztzjy.linkCommerce.entity.dto.NewProductSurveyStepThreeValidationRequest;
@ -21,6 +23,7 @@ import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentFactorsStepThreeVali
import com.sztzjy.linkCommerce.entity.dto.ProductDevelopmentFactorsStepThreeValidationResult;
import com.sztzjy.linkCommerce.service.NewProductSurveyStepOneService;
import com.sztzjy.linkCommerce.service.MarketOpportunitySelectionStepOneService;
import com.sztzjy.linkCommerce.service.MarketOpportunitySelectionStepTwoService;
import com.sztzjy.linkCommerce.service.NewProductSurveyStepTwoService;
import com.sztzjy.linkCommerce.service.NewProductSurveyStepThreeService;
import com.sztzjy.linkCommerce.service.NewProductSurveyStepFourService;
@ -72,6 +75,18 @@ class StudentTrainingAnswerControllerTest {
verify(service).check(any(MarketOpportunitySelectionStepOneCheckRequest.class), any(JwtUser.class));
}
@Test
void validateMarketOpportunitySelectionStepTwoUsesTheAuthenticatedStudentAndReturnsTheValidationResult() {
StudentTrainingAnswerController controller = new StudentTrainingAnswerController();
MarketOpportunitySelectionStepTwoService service = mock(MarketOpportunitySelectionStepTwoService.class);
ReflectionTestUtils.setField(controller, "marketOpportunitySelectionStepTwoService", service);
MarketOpportunitySelectionStepTwoValidationResult validation = new MarketOpportunitySelectionStepTwoValidationResult(); validation.setValid(true);
when(service.validate(any(MarketOpportunitySelectionStepTwoValidationRequest.class), any(JwtUser.class))).thenReturn(validation);
ResultEntity<MarketOpportunitySelectionStepTwoValidationResult> result = controller.validateMarketOpportunitySelectionStepTwo(new MarketOpportunitySelectionStepTwoValidationRequest(), authenticatedStudentRequest());
assertEquals(HttpStatus.OK, result.getStatusCode()); assertEquals(validation, result.getBody().getData());
verify(service).validate(any(MarketOpportunitySelectionStepTwoValidationRequest.class), any(JwtUser.class));
}
@Test
void validateStepTwoUsesTheAuthenticatedStudentAndReturnsTheValidationResult() {
StudentTrainingAnswerController controller = new StudentTrainingAnswerController();

@ -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.MarketOpportunitySelectionStepTwoValidationRequest;
import com.sztzjy.linkCommerce.entity.dto.MarketOpportunitySelectionStepTwoValidationResult;
import com.sztzjy.linkCommerce.service.StudentTrainingAnswerService;
import org.junit.jupiter.api.Test;
import org.springframework.test.util.ReflectionTestUtils;
import java.util.ArrayList;
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 MarketOpportunitySelectionStepTwoServiceImplTest {
@Test
void validateAcceptsAllWeightsThatTotalOneHundredAfterStepOneIsSaved() {
MarketOpportunitySelectionStepTwoValidationResult result = serviceWithStepOne().validate(completedRequest(), student());
assertTrue(result.isValid());
}
@Test
void validateRejectsIncorrectTotalAndMissingStepOne() {
MarketOpportunitySelectionStepTwoValidationRequest invalid = completedRequest(); invalid.getWeights().get(0).setWeight(21);
assertThrows(ServiceException.class, () -> serviceWithStepOne().validate(invalid, student()));
MarketOpportunitySelectionStepTwoServiceImpl service = new MarketOpportunitySelectionStepTwoServiceImpl(); StudentTrainingAnswerService answers = mock(StudentTrainingAnswerService.class); ReflectionTestUtils.setField(service, "studentTrainingAnswerService", answers); when(answers.get(anyString(), any(), any(JwtUser.class))).thenReturn(null);
assertThrows(ServiceException.class, () -> service.validate(completedRequest(), student()));
}
private MarketOpportunitySelectionStepTwoServiceImpl serviceWithStepOne() { MarketOpportunitySelectionStepTwoServiceImpl service = new MarketOpportunitySelectionStepTwoServiceImpl(); StudentTrainingAnswerService answers = mock(StudentTrainingAnswerService.class); StudentTrainingAnswer answer = new StudentTrainingAnswer(); answer.setStep1Answer("{\"answers\":{}}"); when(answers.get(anyString(), any(), any(JwtUser.class))).thenReturn(answer); ReflectionTestUtils.setField(service, "studentTrainingAnswerService", answers); return service; }
private MarketOpportunitySelectionStepTwoValidationRequest completedRequest() { MarketOpportunitySelectionStepTwoValidationRequest request = new MarketOpportunitySelectionStepTwoValidationRequest(); ArrayList<MarketOpportunitySelectionStepTwoValidationRequest.Weight> weights = new ArrayList<>(); int[] values = {20, 15, 15, 15, 10, 10, 10, 5}; Arrays.asList("search-count", "transaction-amount", "transaction-growth", "category-transaction-growth", "demand-supply-ratio", "online-products", "online-merchants", "organic-traffic-ratio").forEach(id -> { MarketOpportunitySelectionStepTwoValidationRequest.Weight item = new MarketOpportunitySelectionStepTwoValidationRequest.Weight(); item.setId(id); item.setWeight(values[weights.size()]); weights.add(item); }); request.setWeights(weights); return request; }
private JwtUser student() { JwtUser user = new JwtUser(); user.setUserId("stu-1"); user.setRoleId(4); return user; }
}
Loading…
Cancel
Save