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.dto.AfterSalesServiceStepOneCheckRequest; import com.sztzjy.linkCommerce.entity.dto.AfterSalesServiceStepOneCheckResult; import com.sztzjy.linkCommerce.entity.dto.AfterSalesServiceStepOneFaultClassification; import com.sztzjy.linkCommerce.service.AfterSalesServiceStepOneService; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; 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 AfterSalesServiceStepOneServiceImpl implements AfterSalesServiceStepOneService { private static final String TASK_KEY = "after-sales-service"; private static final int STEP_NO = 1; private static final Map DEFAULT_ANSWER = createDefaultAnswer(); private final JdbcTemplate jdbcTemplate; @Autowired public AfterSalesServiceStepOneServiceImpl(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } @PostConstruct public void initializeStandardAnswer() { jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS training_step_standard_answer (" + "id varchar(64) NOT NULL COMMENT 'primary id'," + "task_key varchar(128) NOT NULL COMMENT 'training task key'," + "step_no int NOT NULL COMMENT 'step number'," + "answer_json longtext NOT NULL COMMENT 'standard answer json'," + "create_time datetime NULL COMMENT 'create time'," + "update_time datetime NULL COMMENT 'update time'," + "PRIMARY KEY (id)," + "UNIQUE KEY uk_training_step_standard_answer (task_key, step_no)" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='training step standard answer'"); jdbcTemplate.update("INSERT IGNORE INTO training_step_standard_answer " + "(id, task_key, step_no, answer_json, create_time, update_time) VALUES (?, ?, ?, ?, NOW(), NOW())", "after-sales-service-step-1", TASK_KEY, STEP_NO, JSON.toJSONString(DEFAULT_ANSWER)); } @Override public AfterSalesServiceStepOneCheckResult check(AfterSalesServiceStepOneCheckRequest request, JwtUser user) { requireStudent(user); Map submitted = normalizeSubmitted(request == null ? null : request.getItems()); Map answer = loadStandardAnswer(); int correctCount = 0; for (Map.Entry entry : answer.entrySet()) { if (entry.getValue().equals(submitted.get(entry.getKey()))) correctCount++; } AfterSalesServiceStepOneCheckResult result = new AfterSalesServiceStepOneCheckResult(); result.setCorrectCount(correctCount); result.setTotalCount(answer.size()); result.setAllCorrect(correctCount == answer.size()); result.setMessage(result.isAllCorrect() ? "分类正确,已解锁下一步。" : "分类尚未完全正确,请继续调整。"); 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 Map normalizeSubmitted(List items) { if (items == null || items.size() != DEFAULT_ANSWER.size()) throw new ServiceException(HttpStatus.BAD_REQUEST, "请完成全部故障现象的分类后再判题"); Map submitted = new LinkedHashMap<>(); for (AfterSalesServiceStepOneFaultClassification item : items) { String faultId = StringUtils.trimToEmpty(item == null ? null : item.getFaultId()); String categoryId = StringUtils.trimToEmpty(item == null ? null : item.getCategoryId()); if (!DEFAULT_ANSWER.containsKey(faultId) || !DEFAULT_ANSWER.containsValue(categoryId) || submitted.put(faultId, categoryId) != null) { throw new ServiceException(HttpStatus.BAD_REQUEST, "提交的故障分类数据不合法"); } } if (submitted.size() != DEFAULT_ANSWER.size()) throw new ServiceException(HttpStatus.BAD_REQUEST, "提交的故障分类数据不完整"); return submitted; } @SuppressWarnings("unchecked") private Map loadStandardAnswer() { String answerJson = jdbcTemplate.queryForObject("SELECT answer_json FROM training_step_standard_answer WHERE task_key = ? AND step_no = ?", String.class, TASK_KEY, STEP_NO); Map raw = JSON.parseObject(answerJson, Map.class); Map answer = new LinkedHashMap<>(); if (raw != null) for (Map.Entry entry : raw.entrySet()) answer.put(entry.getKey(), String.valueOf(entry.getValue())); if (!DEFAULT_ANSWER.equals(answer)) throw new ServiceException(HttpStatus.INTERNAL_SERVER_ERROR, "第一步标准答案未正确配置"); return answer; } private static Map createDefaultAnswer() { Map answer = new LinkedHashMap<>(); answer.put("voice-wake-no-response", "local-hardware-simple"); answer.put("voice-control-cannot-switch", "local-hardware-simple"); answer.put("app-cannot-find-device", "operation-network"); answer.put("network-setup-timeout", "operation-network"); answer.put("remote-control-intermittent", "cloud-connection"); answer.put("frequent-disconnection", "cloud-connection"); answer.put("indicator-no-response", "severe-fault"); answer.put("water-damage-no-response", "severe-fault"); return answer; } }