|
|
|
|
@ -1,5 +1,6 @@
|
|
|
|
|
package com.sztzjy.linkCommerce.service.impl;
|
|
|
|
|
|
|
|
|
|
import com.alibaba.fastjson.JSON;
|
|
|
|
|
import com.sztzjy.linkCommerce.config.exception.handler.ServiceException;
|
|
|
|
|
import com.sztzjy.linkCommerce.config.security.JwtUser;
|
|
|
|
|
import com.sztzjy.linkCommerce.entity.StudentTrainingAnswer;
|
|
|
|
|
@ -13,13 +14,18 @@ import org.springframework.http.HttpStatus;
|
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
|
|
import java.util.Arrays;
|
|
|
|
|
import java.util.LinkedHashMap;
|
|
|
|
|
import java.util.LinkedHashSet;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
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"));
|
|
|
|
|
private static final Set<String> INDICATOR_IDS = new LinkedHashSet<>(Arrays.asList("search-count", "demand-supply-ratio", "transaction-amount", "transaction-growth", "category-transaction-growth", "online-products", "online-merchants", "organic-traffic-ratio", "return-rate"));
|
|
|
|
|
private static final Set<String> PRIMARY_GROUPS = new LinkedHashSet<>(Arrays.asList("市场规模", "市场潜力", "竞争强度", "运营难度"));
|
|
|
|
|
private static final Map<String, String> INDICATOR_GROUPS = createIndicatorGroups();
|
|
|
|
|
@Autowired private StudentTrainingAnswerService studentTrainingAnswerService;
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@ -28,15 +34,60 @@ public class MarketOpportunitySelectionStepTwoServiceImpl implements MarketOppor
|
|
|
|
|
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()) {
|
|
|
|
|
requireCompletedStepOne(savedAnswer.getStep1Answer());
|
|
|
|
|
if (request == null || request.getPrimaryWeights() == null || request.getDimensionWeights() == null) throw new ServiceException(HttpStatus.BAD_REQUEST, "请填写一级指标与维度内权重");
|
|
|
|
|
Map<String, Integer> primaryWeights = validatePrimaryWeights(request.getPrimaryWeights());
|
|
|
|
|
Map<String, Integer> dimensionWeights = validateDimensionWeights(request.getDimensionWeights());
|
|
|
|
|
validateCorrespondingWeightTotal(primaryWeights, dimensionWeights);
|
|
|
|
|
MarketOpportunitySelectionStepTwoValidationResult result = new MarketOpportunitySelectionStepTwoValidationResult(); result.setValid(true); result.setMessage("校验通过"); return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Map<String, Integer> validatePrimaryWeights(List<MarketOpportunitySelectionStepTwoValidationRequest.PrimaryWeight> items) {
|
|
|
|
|
if (items.size() != PRIMARY_GROUPS.size()) throw new ServiceException(HttpStatus.BAD_REQUEST, "请为四类一级指标填写权重");
|
|
|
|
|
Map<String, Integer> weights = new LinkedHashMap<>(); int total = 0;
|
|
|
|
|
for (MarketOpportunitySelectionStepTwoValidationRequest.PrimaryWeight item : items) {
|
|
|
|
|
String group = item == null ? "" : StringUtils.trimToEmpty(item.getGroup()); Integer weight = item == null ? null : item.getWeight();
|
|
|
|
|
if (!PRIMARY_GROUPS.contains(group) || weights.put(group, weight) != null || !isValidWeight(weight)) throw new ServiceException(HttpStatus.BAD_REQUEST, "一级指标权重需为 1 至 100 的整数");
|
|
|
|
|
total += weight;
|
|
|
|
|
}
|
|
|
|
|
if (!weights.keySet().equals(PRIMARY_GROUPS) || total != 100) throw new ServiceException(HttpStatus.BAD_REQUEST, "一级指标权重合计必须为 100%");
|
|
|
|
|
return weights;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Map<String, Integer> validateDimensionWeights(List<MarketOpportunitySelectionStepTwoValidationRequest.Weight> items) {
|
|
|
|
|
if (items.size() != INDICATOR_IDS.size()) throw new ServiceException(HttpStatus.BAD_REQUEST, "请为全部二级指标填写维度内权重");
|
|
|
|
|
Map<String, Integer> weights = new LinkedHashMap<>();
|
|
|
|
|
for (MarketOpportunitySelectionStepTwoValidationRequest.Weight item : items) {
|
|
|
|
|
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 (!INDICATOR_IDS.contains(id) || weights.put(id, weight) != null || !isValidWeight(weight)) throw new ServiceException(HttpStatus.BAD_REQUEST, "维度内权重需为 1 至 100 的整数");
|
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
if (!weights.keySet().equals(INDICATOR_IDS)) throw new ServiceException(HttpStatus.BAD_REQUEST, "提交的二级指标不完整");
|
|
|
|
|
for (String group : PRIMARY_GROUPS) {
|
|
|
|
|
int total = INDICATOR_IDS.stream().filter((id) -> group.equals(INDICATOR_GROUPS.get(id))).mapToInt(weights::get).sum();
|
|
|
|
|
if (total != 100) throw new ServiceException(HttpStatus.BAD_REQUEST, group + "的维度内权重合计必须为 100%");
|
|
|
|
|
}
|
|
|
|
|
return weights;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void validateCorrespondingWeightTotal(Map<String, Integer> primaryWeights, Map<String, Integer> dimensionWeights) {
|
|
|
|
|
int totalHundredths = INDICATOR_IDS.stream().mapToInt((id) -> primaryWeights.get(INDICATOR_GROUPS.get(id)) * dimensionWeights.get(id)).sum();
|
|
|
|
|
if (totalHundredths != 10000) throw new ServiceException(HttpStatus.BAD_REQUEST, "对应总权重合计必须为 100%");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
|
private void requireCompletedStepOne(String answerJson) {
|
|
|
|
|
Map<String, Object> outcome = JSON.parseObject(answerJson, LinkedHashMap.class);
|
|
|
|
|
Object rawAnswers = outcome == null ? null : outcome.get("answers");
|
|
|
|
|
if (!(rawAnswers instanceof Map)) throw new ServiceException(HttpStatus.BAD_REQUEST, "请先完成并通过第 1 步指标分类");
|
|
|
|
|
Map<String, Object> answers = (Map<String, Object>) rawAnswers;
|
|
|
|
|
if (answers.size() != INDICATOR_IDS.size()) throw new ServiceException(HttpStatus.BAD_REQUEST, "请先完成并通过第 1 步指标分类");
|
|
|
|
|
for (String id : INDICATOR_IDS) if (!INDICATOR_GROUPS.get(id).equals(String.valueOf(answers.get(id)))) throw new ServiceException(HttpStatus.BAD_REQUEST, "请先完成并通过第 1 步指标分类");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean isValidWeight(Integer weight) { return weight != null && weight >= 1 && weight <= 100; }
|
|
|
|
|
private static Map<String, String> createIndicatorGroups() {
|
|
|
|
|
Map<String, String> groups = new LinkedHashMap<>();
|
|
|
|
|
groups.put("search-count", "市场规模"); groups.put("demand-supply-ratio", "竞争强度"); groups.put("transaction-amount", "市场规模"); groups.put("transaction-growth", "市场潜力"); groups.put("category-transaction-growth", "市场潜力"); groups.put("online-products", "竞争强度"); groups.put("online-merchants", "竞争强度"); groups.put("organic-traffic-ratio", "运营难度"); groups.put("return-rate", "运营难度");
|
|
|
|
|
return groups;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|