commit 5224cfb1a75dcf5e65112bb52a39ab14e17c5944 Author: 中青华年 <2957899895@qq.com> Date: Mon Apr 14 17:01:00 2025 +0800 完工 diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..0e93d12 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml new file mode 100644 index 0000000..609fb19 --- /dev/null +++ b/.idea/dataSources.xml @@ -0,0 +1,17 @@ + + + + + mysql.8 + true + com.mysql.cj.jdbc.Driver + jdbc:mysql://62.234.217.137:3306/mbti + + + + + + $ProjectFileDir$ + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..63e9001 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..abb532a --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..15a25de --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..d58dfb7 --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +wrapperVersion=3.3.2 +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..e99f5f5 --- /dev/null +++ b/pom.xml @@ -0,0 +1,77 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.4.4 + + + com.yang + test + 0.0.1-SNAPSHOT + test + test + + + + + + + + + + + + + + + 17 + + + + org.springframework.boot + spring-boot-starter-web + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 3.0.4 + + + + com.mysql + mysql-connector-j + runtime + + + org.springframework.boot + spring-boot-starter-test + test + + + org.mybatis.spring.boot + mybatis-spring-boot-starter-test + 3.0.4 + test + + + org.projectlombok + lombok + 1.18.26 + provided + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/server.log b/server.log new file mode 100644 index 0000000..e69de29 diff --git a/src/main/java/com/yang/test/TestApplication.java b/src/main/java/com/yang/test/TestApplication.java new file mode 100644 index 0000000..60e6e34 --- /dev/null +++ b/src/main/java/com/yang/test/TestApplication.java @@ -0,0 +1,20 @@ +package com.yang.test; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.Environment; + +@Slf4j +@SpringBootApplication +public class TestApplication { + + public static void main(String[] args) { + ConfigurableApplicationContext context = SpringApplication.run(TestApplication.class, args); + Environment env = context.getEnvironment(); + String port = env.getProperty("server.port", "8080"); + log.info("MBTI测试系统启动成功! 服务运行在端口: {}", port); + } + +} diff --git a/src/main/java/com/yang/test/config/CorsConfig.java b/src/main/java/com/yang/test/config/CorsConfig.java new file mode 100644 index 0000000..92712d1 --- /dev/null +++ b/src/main/java/com/yang/test/config/CorsConfig.java @@ -0,0 +1,23 @@ +package com.yang.test.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class CorsConfig implements WebMvcConfigurer { + + @Value("${cors.allowed-origins}") + private String allowedOrigins; + + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/api/**") + .allowedOrigins(allowedOrigins.split(",")) + .allowedMethods("GET", "POST", "OPTIONS") + .allowedHeaders("Content-Type") + .allowCredentials(true) + .maxAge(3600); + } +} \ No newline at end of file diff --git a/src/main/java/com/yang/test/config/DatabaseConfig.java b/src/main/java/com/yang/test/config/DatabaseConfig.java new file mode 100644 index 0000000..62266dc --- /dev/null +++ b/src/main/java/com/yang/test/config/DatabaseConfig.java @@ -0,0 +1,46 @@ +package com.yang.test.config; + +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.core.JdbcTemplate; + +import javax.sql.DataSource; + +@Configuration +public class DatabaseConfig { + + @Value("${spring.datasource.url}") + private String jdbcUrl; + + @Value("${spring.datasource.username}") + private String username; + + @Value("${spring.datasource.password}") + private String password; + + @Value("${spring.datasource.driver-class-name}") + private String driverClassName; + + @Bean + public DataSource dataSource() { + HikariConfig config = new HikariConfig(); + config.setJdbcUrl(jdbcUrl); + config.setUsername(username); + config.setPassword(password); + config.setDriverClassName(driverClassName); + config.setMaximumPoolSize(10); + config.setMinimumIdle(5); + config.setConnectionTimeout(30000); + config.setIdleTimeout(600000); + config.setMaxLifetime(1800000); + return new HikariDataSource(config); + } + + @Bean + public JdbcTemplate jdbcTemplate(DataSource dataSource) { + return new JdbcTemplate(dataSource); + } +} \ No newline at end of file diff --git a/src/main/java/com/yang/test/config/RestTemplateConfig.java b/src/main/java/com/yang/test/config/RestTemplateConfig.java new file mode 100644 index 0000000..651a41c --- /dev/null +++ b/src/main/java/com/yang/test/config/RestTemplateConfig.java @@ -0,0 +1,18 @@ +package com.yang.test.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.SimpleClientHttpRequestFactory; +import org.springframework.web.client.RestTemplate; + +@Configuration +public class RestTemplateConfig { + + @Bean + public RestTemplate restTemplate() { + SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); + factory.setConnectTimeout(5000); + factory.setReadTimeout(300000); // 5分钟超时 + return new RestTemplate(factory); + } +} \ No newline at end of file diff --git a/src/main/java/com/yang/test/controller/HldzyController.java b/src/main/java/com/yang/test/controller/HldzyController.java new file mode 100644 index 0000000..039e8e1 --- /dev/null +++ b/src/main/java/com/yang/test/controller/HldzyController.java @@ -0,0 +1,52 @@ +package com.yang.test.controller; + +import com.yang.test.domain.DTO.ResultRequest; +import com.yang.test.domain.DTO.ResultResponse; +import com.yang.test.domain.QuestionH; +import com.yang.test.service.HldzyService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("/api") +public class HldzyController { + + @Autowired + private HldzyService hldzyService; + + /** + * 获取所有测试题目 + */ + @GetMapping("/questionsH") + public Map getAllQuestions() { + List questions = hldzyService.getAllQuestions(); + Collections.shuffle(questions); // 随机排序问题 + + Map response = new HashMap<>(); + response.put("code", 0); + response.put("message", "success"); + response.put("data", questions); + + return response; + } + + /** + * 提交测试结果并获取分析 + */ + @PostMapping("/results") + public Map submitResult(@RequestBody ResultRequest request) { + ResultResponse result = hldzyService.calculateResult(request.getAnswers()); + + Map response = new HashMap<>(); + response.put("code", 0); + response.put("message", "success"); + response.put("data", result); + + return response; + } +} \ No newline at end of file diff --git a/src/main/java/com/yang/test/controller/MbtiController.java b/src/main/java/com/yang/test/controller/MbtiController.java new file mode 100644 index 0000000..4abb168 --- /dev/null +++ b/src/main/java/com/yang/test/controller/MbtiController.java @@ -0,0 +1,82 @@ +package com.yang.test.controller; + +import com.yang.test.domain.Answer; +import com.yang.test.domain.VO.QuestionVO; +import com.yang.test.domain.VO.ResultVO; +import com.yang.test.service.MbtiService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.time.Duration; +import java.time.Instant; +import java.util.List; +import java.util.Map; + +@Slf4j +@RestController +@RequestMapping("/api") +public class MbtiController { + + @Autowired + private MbtiService mbtiService; + + @GetMapping("/questions") + public ResponseEntity getQuestions(@RequestParam(value = "type", defaultValue = "simple") String testType) { + Instant start = Instant.now(); + log.info("开始获取题目, 类型: {}", testType); + try { + List questions = mbtiService.getQuestions(testType); + + log.info("获取题目完成, 类型: {}, 题目数量: {}, 总耗时: {}", + testType, questions.size(), Duration.between(start, Instant.now())); + + return ResponseEntity.ok(questions); + } catch (Exception e) { + log.error("获取题目失败: {}", e.getMessage(), e); + return ResponseEntity.internalServerError().body(Map.of("error", "获取题目失败")); + } + } + + @PostMapping("/submit") + public ResponseEntity submitAnswers(@RequestBody Answer answer, + @RequestParam(value = "type", defaultValue = "simple") String testType) { + Instant start = Instant.now(); + log.info("开始处理答案提交请求"); + + try { + String resultId = mbtiService.processAnswers(answer.getAnswers(), testType); + + log.info("答案提交处理完成, 结果ID: {}, 总耗时: {}", + resultId, Duration.between(start, Instant.now())); + + return ResponseEntity.ok(Map.of("resultId", resultId)); + } catch (Exception e) { + log.error("处理答案提交请求失败: {}", e.getMessage(), e); + return ResponseEntity.internalServerError().body(Map.of("error", "处理请求失败")); + } + } + + @GetMapping("/result/{id}") + public ResponseEntity getResult(@PathVariable("id") String resultId) { + Instant start = Instant.now(); + log.info("开始获取结果, ID: {}", resultId); + + try { + ResultVO result = mbtiService.getResult(resultId); + + if (result == null) { + return ResponseEntity.notFound().build(); + } + + log.info("获取结果完成, ID: {}, 类型: {}, 总耗时: {}", + resultId, result.getType(), Duration.between(start, Instant.now())); + + return ResponseEntity.ok(result); + } catch (Exception e) { + log.error("获取结果失败: {}", e.getMessage(), e); + return ResponseEntity.internalServerError().body(Map.of("error", "获取结果失败")); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/yang/test/domain/Answer.java b/src/main/java/com/yang/test/domain/Answer.java new file mode 100644 index 0000000..21aa0fe --- /dev/null +++ b/src/main/java/com/yang/test/domain/Answer.java @@ -0,0 +1,9 @@ +package com.yang.test.domain; + +import lombok.Data; +import java.util.List; + +@Data +public class Answer { + private List answers; +} \ No newline at end of file diff --git a/src/main/java/com/yang/test/domain/Category.java b/src/main/java/com/yang/test/domain/Category.java new file mode 100644 index 0000000..c68bed7 --- /dev/null +++ b/src/main/java/com/yang/test/domain/Category.java @@ -0,0 +1,14 @@ +package com.yang.test.domain; + +import lombok.Data; +import java.util.Date; + +@Data +public class Category { + private Integer id; + private String cateKey; + private String cateName; + private String typeDesc; + private String info; + private Date createTime; +} \ No newline at end of file diff --git a/src/main/java/com/yang/test/domain/DTO/ResultRequest.java b/src/main/java/com/yang/test/domain/DTO/ResultRequest.java new file mode 100644 index 0000000..9ddfedd --- /dev/null +++ b/src/main/java/com/yang/test/domain/DTO/ResultRequest.java @@ -0,0 +1,9 @@ +package com.yang.test.domain.DTO; + +import lombok.Data; +import java.util.Map; + +@Data +public class ResultRequest { + private Map answers; +} \ No newline at end of file diff --git a/src/main/java/com/yang/test/domain/DTO/ResultResponse.java b/src/main/java/com/yang/test/domain/DTO/ResultResponse.java new file mode 100644 index 0000000..0de0af9 --- /dev/null +++ b/src/main/java/com/yang/test/domain/DTO/ResultResponse.java @@ -0,0 +1,12 @@ +package com.yang.test.domain.DTO; + +import com.yang.test.domain.Category; +import lombok.Data; +import java.util.Map; + +@Data +public class ResultResponse { + private String resultCode; + private Map scores; + private Category primaryType; +} \ No newline at end of file diff --git a/src/main/java/com/yang/test/domain/Dimension.java b/src/main/java/com/yang/test/domain/Dimension.java new file mode 100644 index 0000000..e41c1d9 --- /dev/null +++ b/src/main/java/com/yang/test/domain/Dimension.java @@ -0,0 +1,15 @@ +package com.yang.test.domain; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class Dimension { + private String left; + private String right; + private double leftValue; + private double rightValue; +} \ No newline at end of file diff --git a/src/main/java/com/yang/test/domain/Question.java b/src/main/java/com/yang/test/domain/Question.java new file mode 100644 index 0000000..15b4ffe --- /dev/null +++ b/src/main/java/com/yang/test/domain/Question.java @@ -0,0 +1,16 @@ +package com.yang.test.domain; + +import lombok.Data; +import java.util.List; +import java.util.Date; + +@Data +public class Question { + private Integer id; + private String question; + private String dimension; + private Integer direction; + private String type; + private Date createdAt; + private List options; +} \ No newline at end of file diff --git a/src/main/java/com/yang/test/domain/QuestionH.java b/src/main/java/com/yang/test/domain/QuestionH.java new file mode 100644 index 0000000..571ecd7 --- /dev/null +++ b/src/main/java/com/yang/test/domain/QuestionH.java @@ -0,0 +1,15 @@ +package com.yang.test.domain; + +import lombok.Data; +import java.util.Date; + +@Data +public class QuestionH { + private Long id; + private String title; + private String cateKey; + private Integer cateId; + private String cateName; + private Integer score; + private Date createTime; +} \ No newline at end of file diff --git a/src/main/java/com/yang/test/domain/Result.java b/src/main/java/com/yang/test/domain/Result.java new file mode 100644 index 0000000..36a5df5 --- /dev/null +++ b/src/main/java/com/yang/test/domain/Result.java @@ -0,0 +1,14 @@ +package com.yang.test.domain; + +import lombok.Data; +import java.util.Date; +import java.util.List; + +@Data +public class Result { + private String id; + private String type; + private List dimensions; + private String report; + private Date createdAt; +} \ No newline at end of file diff --git a/src/main/java/com/yang/test/domain/TestResult.java b/src/main/java/com/yang/test/domain/TestResult.java new file mode 100644 index 0000000..77feb6d --- /dev/null +++ b/src/main/java/com/yang/test/domain/TestResult.java @@ -0,0 +1,18 @@ +package com.yang.test.domain; + +import lombok.Data; +import java.util.Date; + +@Data +public class TestResult { + private Long id; + private Long userId; + private String resultCode; + private Integer rScore; + private Integer cScore; + private Integer eScore; + private Integer sScore; + private Integer aScore; + private Integer iScore; + private Date createTime; +} \ No newline at end of file diff --git a/src/main/java/com/yang/test/domain/VO/QuestionVO.java b/src/main/java/com/yang/test/domain/VO/QuestionVO.java new file mode 100644 index 0000000..988020e --- /dev/null +++ b/src/main/java/com/yang/test/domain/VO/QuestionVO.java @@ -0,0 +1,13 @@ +package com.yang.test.domain.VO; + +import lombok.Data; +import java.util.List; + +@Data +public class QuestionVO { + private Integer id; + private String question; + private List options; + private String dimension; + private Integer direction; +} \ No newline at end of file diff --git a/src/main/java/com/yang/test/domain/VO/ResultVO.java b/src/main/java/com/yang/test/domain/VO/ResultVO.java new file mode 100644 index 0000000..13cdc99 --- /dev/null +++ b/src/main/java/com/yang/test/domain/VO/ResultVO.java @@ -0,0 +1,14 @@ +package com.yang.test.domain.VO; + + +import com.yang.test.domain.Dimension; +import lombok.Data; +import java.util.List; + +@Data +public class ResultVO { + private String id; + private String type; + private List dimensions; + private String report; +} \ No newline at end of file diff --git a/src/main/java/com/yang/test/handler/GlobalExceptionHandler.java b/src/main/java/com/yang/test/handler/GlobalExceptionHandler.java new file mode 100644 index 0000000..cb138f1 --- /dev/null +++ b/src/main/java/com/yang/test/handler/GlobalExceptionHandler.java @@ -0,0 +1,25 @@ +package com.yang.test.handler; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import java.util.Map; + +@Slf4j +@RestControllerAdvice +public class GlobalExceptionHandler { + + @ExceptionHandler(MbtiException.class) + public ResponseEntity handleMbtiException(MbtiException e) { + log.error("业务异常: {}", e.getMessage(), e); + return ResponseEntity.badRequest().body(Map.of("error", e.getMessage())); + } + + @ExceptionHandler(Exception.class) + public ResponseEntity handleException(Exception e) { + log.error("系统异常: {}", e.getMessage(), e); + return ResponseEntity.internalServerError().body(Map.of("error", "系统内部错误")); + } +} \ No newline at end of file diff --git a/src/main/java/com/yang/test/handler/MbtiException.java b/src/main/java/com/yang/test/handler/MbtiException.java new file mode 100644 index 0000000..662701c --- /dev/null +++ b/src/main/java/com/yang/test/handler/MbtiException.java @@ -0,0 +1,12 @@ +package com.yang.test.handler; + +public class MbtiException extends RuntimeException { + + public MbtiException(String message) { + super(message); + } + + public MbtiException(String message, Throwable cause) { + super(message, cause); + } +} \ No newline at end of file diff --git a/src/main/java/com/yang/test/mapper/HldzyMapper.java b/src/main/java/com/yang/test/mapper/HldzyMapper.java new file mode 100644 index 0000000..fc9427d --- /dev/null +++ b/src/main/java/com/yang/test/mapper/HldzyMapper.java @@ -0,0 +1,28 @@ +package com.yang.test.mapper; + +import com.yang.test.domain.Category; +import com.yang.test.domain.QuestionH; +import com.yang.test.domain.TestResult; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +@Mapper +public interface HldzyMapper { + /** + * 查询所有问题 + */ + List selectAllQuestions(); + + + /** + * 根据键值查询类型 + */ + Category selectCategoryByKey(@Param("cateKey") String cateKey); + + /** + * 插入测试结果 + */ + int insertTestResult(TestResult testResult); +} \ No newline at end of file diff --git a/src/main/java/com/yang/test/mapper/MbtiMapper.java b/src/main/java/com/yang/test/mapper/MbtiMapper.java new file mode 100644 index 0000000..876d399 --- /dev/null +++ b/src/main/java/com/yang/test/mapper/MbtiMapper.java @@ -0,0 +1,41 @@ +package com.yang.test.mapper; + + + +import com.yang.test.domain.Question; +import com.yang.test.domain.Result; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; +import java.util.Map; + +@Mapper +public interface MbtiMapper { + /** + * 根据类型获取题目列表 + * @param types 题目类型 + * @return 题目列表 + */ + List getQuestionsByTypes(List types); + + /** + * 获取题目的维度和方向信息 + * @param types 题目类型 + * @return 维度和方向信息列表 + */ + List> getQuestionDimensionsAndDirections(List types); + + /** + * 保存测试结果 + * @param result 结果对象 + * @return 影响的行数 + */ + int saveResult(Result result); + + /** + * 根据ID获取结果 + * @param resultId 结果ID + * @return 结果对象 + */ + Result getResultById(String resultId); +} \ No newline at end of file diff --git a/src/main/java/com/yang/test/service/DeepseekService.java b/src/main/java/com/yang/test/service/DeepseekService.java new file mode 100644 index 0000000..3c4934c --- /dev/null +++ b/src/main/java/com/yang/test/service/DeepseekService.java @@ -0,0 +1,16 @@ +package com.yang.test.service; + + +import com.yang.test.domain.Dimension; + +import java.util.List; + +public interface DeepseekService { + /** + * 生成MBTI性格报告 + * @param mbtiType MBTI类型 + * @param dimensions 维度数据 + * @return 生成的报告 + */ + String generateReport(String mbtiType, List dimensions); +} \ No newline at end of file diff --git a/src/main/java/com/yang/test/service/HldzyService.java b/src/main/java/com/yang/test/service/HldzyService.java new file mode 100644 index 0000000..4f586b5 --- /dev/null +++ b/src/main/java/com/yang/test/service/HldzyService.java @@ -0,0 +1,31 @@ +package com.yang.test.service; + +import com.yang.test.domain.DTO.ResultResponse; +import com.yang.test.domain.Category; +import com.yang.test.domain.QuestionH; +import com.yang.test.domain.TestResult; + +import java.util.List; +import java.util.Map; + +public interface HldzyService { + /** + * 获取所有问题 + */ + List getAllQuestions(); + + /** + * 根据键值获取类型 + */ + Category getCategoryByKey(String cateKey); + + /** + * 计算测试结果 + */ + ResultResponse calculateResult(Map answers); + + /** + * 保存测试结果 + */ + Long saveResult(TestResult testResult); +} \ No newline at end of file diff --git a/src/main/java/com/yang/test/service/MbtiService.java b/src/main/java/com/yang/test/service/MbtiService.java new file mode 100644 index 0000000..e46c8f6 --- /dev/null +++ b/src/main/java/com/yang/test/service/MbtiService.java @@ -0,0 +1,48 @@ +package com.yang.test.service; + + + +import com.yang.test.domain.VO.QuestionVO; +import com.yang.test.domain.VO.ResultVO; + +import java.util.List; +import java.util.Map; + +public interface MbtiService { + /** + * 获取测试题目 + * @param testType 测试类型 + * @return 题目列表 + */ + List getQuestions(String testType); + + /** + * 处理用户提交的答案 + * @param answers 用户答案 + * @param testType 测试类型 + * @return 结果ID + */ + String processAnswers(List answers, String testType); + + /** + * 获取测试结果 + * @param resultId 结果ID + * @return 结果视图对象 + */ + ResultVO getResult(String resultId); + + /** + * 计算MBTI维度得分 + * @param answers 用户答案 + * @param testType 测试类型 + * @return 维度得分映射 + */ + Map calculateScores(List answers, String testType); + + /** + * 根据得分确定MBTI类型 + * @param scores 维度得分 + * @return MBTI类型 + */ + String determineMbtiType(Map scores); +} \ No newline at end of file diff --git a/src/main/java/com/yang/test/service/serviceImpl/DeepseekServiceImpl.java b/src/main/java/com/yang/test/service/serviceImpl/DeepseekServiceImpl.java new file mode 100644 index 0000000..c83a151 --- /dev/null +++ b/src/main/java/com/yang/test/service/serviceImpl/DeepseekServiceImpl.java @@ -0,0 +1,232 @@ +package com.yang.test.service.serviceImpl; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import com.yang.test.domain.Dimension; +import com.yang.test.service.DeepseekService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +@Slf4j +@Service +public class DeepseekServiceImpl implements DeepseekService { + + @Value("${deepseek.api.key}") + private String apiKey; + + @Value("${deepseek.api.url:https://api.deepseek.com/v1/chat/completions}") + private String apiUrl; + + @Value("${deepseek.model:deepseek-chat}") + private String model; + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private RestTemplate restTemplate; + + @Override + public String generateReport(String mbtiType, List dimensions) { + if (apiKey == null || apiKey.isEmpty()) { + log.error("[MBTI报告生成] 错误: DEEPSEEK_API_KEY未设置,将使用默认模板"); + return mbtiType + "类型的性格特点是..."; + } + + try { + // 构建维度倾向描述 + List dimensionDescriptions = new ArrayList<>(); + for (Dimension dim : dimensions) { + String tendency; + if (dim.getLeftValue() > dim.getRightValue()) { + tendency = String.format("偏向%s (%.0f%%)", dim.getRight(), dim.getLeftValue()); + } else { + tendency = String.format("偏向%s (%.0f%%)", dim.getLeft(), dim.getRightValue()); + } + dimensionDescriptions.add(String.format("%s vs %s: %s", dim.getLeft(), dim.getRight(), tendency)); + } + + // 构建提示词 + String prompt = buildPrompt(mbtiType, dimensionDescriptions); + + // 构建DeepSeek API请求 + ObjectNode requestBody = objectMapper.createObjectNode(); + requestBody.put("model", model); + + ArrayNode messagesArray = requestBody.putArray("messages"); + ObjectNode message = messagesArray.addObject(); + message.put("role", "user"); + message.put("content", prompt); + + requestBody.put("temperature", 0.5); + requestBody.put("max_tokens", 2500); + requestBody.put("stream", false); + requestBody.put("presence_penalty", 0.1); + requestBody.put("frequency_penalty", 0.1); + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.set("Authorization", "Bearer " + apiKey); + + HttpEntity entity = new HttpEntity<>(objectMapper.writeValueAsString(requestBody), headers); + + // 发送请求 + log.info("[MBTI报告生成] 调用DeepSeek API"); + ResponseEntity response = restTemplate.postForEntity(apiUrl, entity, String.class); + + // 处理响应 + if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) { + JsonNode responseJson = objectMapper.readTree(response.getBody()); + + // 提取生成的报告内容 + if (responseJson.has("choices") && responseJson.get("choices").isArray() && responseJson.get("choices").size() > 0) { + JsonNode choices = responseJson.get("choices"); + JsonNode messageNode = choices.get(0).get("message"); + + if (messageNode != null && messageNode.has("content")) { + String content = messageNode.get("content").asText(); + + // 清理内容,只保留HTML部分 + content = content.trim(); + if (content.startsWith("```html")) { + content = content.substring("```html".length()); + } + if (content.endsWith("```")) { + content = content.substring(0, content.length() - 3); + } + + return content.trim(); + } + } + + log.error("[MBTI报告生成] 错误: 无法从API响应中提取报告内容,将使用默认模板"); + } else { + log.error("[MBTI报告生成] 错误: API返回非200状态码 - {}", response.getStatusCodeValue()); + } + + } catch (Exception e) { + log.error("[MBTI报告生成] 错误: 调用DeepSeek API失败 - {}", e.getMessage(), e); + } + + return mbtiType + "类型的性格特点是..."; + } + + private String buildPrompt(String mbtiType, List dimensionDescriptions) { + String dimensionsText = dimensionDescriptions.stream().collect(Collectors.joining("\n")); + + return String.format(""" + 请以专业的心理学视角,对MBTI中的%s类型进行全面分析,并使用HTML标签组织内容。该用户在各维度上的具体倾向如下: + + %s + + 请按以下HTML结构组织内容: + +
+
+

核心特质概述

+
    +
  • 主要认知功能:[内容]
  • +
  • 思维方式特点:[内容]
  • +
  • 行为模式倾向:[内容]
  • +
+
+ +
+

人际关系分析

+
    +
  • 沟通风格:[内容]
  • +
  • 与他人互动方式:[内容]
  • +
  • 在团队中的角色:[内容]
  • +
  • 理想的社交环境:[内容]
  • +
+
+ +
+

职业发展洞察

+
    +
  • 最适合的工作环境:[内容]
  • +
  • 职业优势:[内容]
  • +
  • 潜在的职业挑战:[内容]
  • +
  • 理想的职业方向:[内容]
  • +
+
+ +
+

个人成长建议

+
    +
  • 需要培养的能力:[内容]
  • +
  • 潜在的发展盲点:[内容]
  • +
  • 压力管理方式:[内容]
  • +
  • 自我提升方向:[内容]
  • +
+
+ +
+

独特优势和劣势

+
    +
  • 核心优势:[内容]
  • +
  • 潜在劣势:[内容]
  • +
  • 如何发挥优势:[内容]
  • +
  • 如何克服劣势:[内容]
  • +
+
+ +
+

爱情关系分析

+
    +
  • 恋爱中的表现:[内容]
  • +
  • 理想伴侣特质:[内容]
  • +
  • 感情相处方式:[内容]
  • +
  • 维系感情建议:[内容]
  • +
+
+ +
+

友情互动特点

+
    +
  • 交友方式:[内容]
  • +
  • 理想友谊类型:[内容]
  • +
  • 友情维护特点:[内容]
  • +
  • 社交圈建议:[内容]
  • +
+
+ +
+

育儿方式建议

+
    +
  • 教育理念:[内容]
  • +
  • 亲子互动风格:[内容]
  • +
  • 可能的教育挑战:[内容]
  • +
  • 育儿建议:[内容]
  • +
+
+ +
+

工作习惯分析

+
    +
  • 工作节奏偏好:[内容]
  • +
  • 任务管理方式:[内容]
  • +
  • 工作环境需求:[内容]
  • +
  • 效率提升建议:[内容]
  • +
+
+
+ + 请根据用户在各维度上的具体倾向程度,用专业但易懂的语言填充上述HTML结构中的[内容]部分。特别注意根据维度分数的强弱来调整建议的针对性。请确保生成的HTML格式正确,可以直接在网页中显示。 + """, mbtiType, dimensionsText); + } +} \ No newline at end of file diff --git a/src/main/java/com/yang/test/service/serviceImpl/HldzyServiceImpl.java b/src/main/java/com/yang/test/service/serviceImpl/HldzyServiceImpl.java new file mode 100644 index 0000000..89a3cae --- /dev/null +++ b/src/main/java/com/yang/test/service/serviceImpl/HldzyServiceImpl.java @@ -0,0 +1,87 @@ +package com.yang.test.service.serviceImpl; + +import com.yang.test.mapper.HldzyMapper; +import com.yang.test.domain.DTO.ResultResponse; +import com.yang.test.domain.Category; +import com.yang.test.domain.QuestionH; +import com.yang.test.domain.TestResult; +import com.yang.test.service.HldzyService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +@Service +public class HldzyServiceImpl implements HldzyService { + + @Autowired + private HldzyMapper hldzyMapper; + + @Override + public List getAllQuestions() { + return hldzyMapper.selectAllQuestions(); + } + + + @Override + public Category getCategoryByKey(String cateKey) { + return hldzyMapper.selectCategoryByKey(cateKey); + } + + @Override + public ResultResponse calculateResult(Map answers) { + // 计算各类型分数 + Map scores = new HashMap<>(); + + // 确保所有类型都有分数,没有回答的默认为0 + scores.put("R", answers.getOrDefault("R", 0)); + scores.put("C", answers.getOrDefault("C", 0)); + scores.put("E", answers.getOrDefault("E", 0)); + scores.put("S", answers.getOrDefault("S", 0)); + scores.put("A", answers.getOrDefault("A", 0)); + scores.put("I", answers.getOrDefault("I", 0)); + + // 按分数排序并获取前三个类型 + List> sortedScores = scores.entrySet() + .stream() + .sorted(Map.Entry.comparingByValue().reversed()) + .collect(Collectors.toList()); + + // 构建结果代码(前三类型的组合) + StringBuilder resultCode = new StringBuilder(); + for (int i = 0; i < Math.min(3, sortedScores.size()); i++) { + resultCode.append(sortedScores.get(i).getKey()); + } + + // 获取主导类型 + String primaryTypeKey = sortedScores.get(0).getKey(); + Category primaryType = getCategoryByKey(primaryTypeKey); + + // 构建响应 + ResultResponse response = new ResultResponse(); + response.setResultCode(resultCode.toString()); + response.setScores(scores); + response.setPrimaryType(primaryType); + + // 保存结果到数据库 + TestResult testResult = new TestResult(); + testResult.setResultCode(resultCode.toString()); + testResult.setRScore(scores.get("R")); + testResult.setCScore(scores.get("C")); + testResult.setEScore(scores.get("E")); + testResult.setSScore(scores.get("S")); + testResult.setAScore(scores.get("A")); + testResult.setIScore(scores.get("I")); + + saveResult(testResult); + + return response; + } + + @Override + public Long saveResult(TestResult testResult) { + hldzyMapper.insertTestResult(testResult); + return testResult.getId(); + } +} \ No newline at end of file diff --git a/src/main/java/com/yang/test/service/serviceImpl/MbtiServiceImpl.java b/src/main/java/com/yang/test/service/serviceImpl/MbtiServiceImpl.java new file mode 100644 index 0000000..e8bdcaf --- /dev/null +++ b/src/main/java/com/yang/test/service/serviceImpl/MbtiServiceImpl.java @@ -0,0 +1,236 @@ +package com.yang.test.service.serviceImpl; + + +import com.yang.test.mapper.MbtiMapper; +import com.yang.test.domain.Dimension; +import com.yang.test.domain.Question; +import com.yang.test.domain.Result; +import com.yang.test.domain.VO.QuestionVO; +import com.yang.test.domain.VO.ResultVO; +import com.yang.test.service.DeepseekService; +import com.yang.test.service.MbtiService; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.time.Instant; +import java.util.*; + +@Slf4j +@Service +public class MbtiServiceImpl implements MbtiService { + + @Autowired + private MbtiMapper mbtiMapper; + + @Autowired + private DeepseekService deepseekService; + + @Override + public List getQuestions(String testType) { + List types; + switch (testType) { + case "simple": + types = Collections.singletonList("simple"); + break; + case "detailed": + types = Arrays.asList("simple", "detailed"); + break; + case "full": + types = Arrays.asList("simple", "detailed", "full"); + break; + default: + log.warn("无效的测试类型: {}, 使用simple类型", testType); + types = Collections.singletonList("simple"); + } + + List questions = mbtiMapper.getQuestionsByTypes(types); + List questionVOs = new ArrayList<>(); + + for (Question q : questions) { + QuestionVO vo = new QuestionVO(); + vo.setId(q.getId()); + vo.setQuestion(q.getQuestion()); + vo.setDimension(q.getDimension()); + vo.setDirection(q.getDirection()); + // 设置7级量表选项 + vo.setOptions(Arrays.asList("非常不符合", "不符合", "有点不符合", "中立", "有点符合", "符合", "非常符合")); + questionVOs.add(vo); + } + + return questionVOs; + } + + @Override + public String processAnswers(List answers, String testType) { + // 计算MBTI维度得分 + Map scores = calculateScores(answers, testType); + + // 生成结果ID + String resultId = generateResultId(); + + // 根据得分确定MBTI类型 + String mbtiType = determineMbtiType(scores); + log.info("计算得到MBTI类型: {}, 得分: {}", mbtiType, scores); + + // 生成维度数据 + List dimensions = Arrays.asList( + new Dimension("E", "I", Math.round(100 - scores.getOrDefault("EI", 0.0)), Math.round(scores.getOrDefault("EI", 0.0))), + new Dimension("S", "N", Math.round(100 - scores.getOrDefault("SN", 0.0)), Math.round(scores.getOrDefault("SN", 0.0))), + new Dimension("T", "F", Math.round(100 - scores.getOrDefault("TF", 0.0)), Math.round(scores.getOrDefault("TF", 0.0))), + new Dimension("J", "P", Math.round(100 - scores.getOrDefault("JP", 0.0)), Math.round(scores.getOrDefault("JP", 0.0))) + ); + + // 生成个性化报告 + String report = deepseekService.generateReport(mbtiType, dimensions); + + // 创建结果对象 + Result result = new Result(); + result.setId(resultId); + result.setType(mbtiType); + result.setDimensions(dimensions); + result.setReport(report); + result.setCreatedAt(new Date()); + + // 保存结果到数据库 + int rows = mbtiMapper.saveResult(result); + log.info("结果保存完成, 影响行数: {}", rows); + + return resultId; + } + + @Override + public ResultVO getResult(String resultId) { + Result result = mbtiMapper.getResultById(resultId); + + if (result == null) { + return null; + } + + // 转换为视图对象 + ResultVO resultVO = new ResultVO(); + resultVO.setId(result.getId()); + resultVO.setType(result.getType()); + resultVO.setDimensions(result.getDimensions()); + resultVO.setReport(result.getReport()); + + return resultVO; + } + + @Override + public Map calculateScores(List answers, String testType) { + Map scores = new HashMap<>(); + + // 根据测试类型确定题目范围 + List types; + switch (testType) { + case "simple": + types = Collections.singletonList("simple"); + break; + case "detailed": + types = Arrays.asList("simple", "detailed"); + break; + case "full": + types = Arrays.asList("simple", "detailed", "full"); + break; + default: + log.warn("无效的测试类型: {}", testType); + return scores; + } + + // 查询题目信息 + List> questions = mbtiMapper.getQuestionDimensionsAndDirections(types); + + // 计算每个维度的得分 + Map dimensionScores = new HashMap<>(); + + for (int i = 0; i < Math.min(answers.size(), questions.size()); i++) { + Map question = questions.get(i); + String dimension = (String) question.get("dimension"); + int direction = ((Number) question.get("direction")).intValue(); + + // 确保答案在1-7的范围内 + int answer = answers.get(i); + if (answer < 1) answer = 1; + if (answer > 7) answer = 7; + + // 计算得分(考虑题目方向) + double score; + if (direction == 1) { + score = (answer - 1) * (100.0 / 6.0); // 正向题目:将1-7线性映射到0-100 + } else { + score = (7 - answer) * (100.0 / 6.0); // 反向题目:将7-1线性映射到0-100 + } + + // 确保得分在0-100范围内 + if (score < 0) score = 0; + if (score > 100) score = 100; + + // 累加分数 + ScoreInfo scoreInfo = dimensionScores.getOrDefault(dimension, new ScoreInfo()); + scoreInfo.setTotal(scoreInfo.getTotal() + score); + scoreInfo.setCount(scoreInfo.getCount() + 1); + dimensionScores.put(dimension, scoreInfo); + } + + // 计算每个维度的最终得分 + for (Map.Entry entry : dimensionScores.entrySet()) { + String dim = entry.getKey(); + ScoreInfo info = entry.getValue(); + + if (info.getCount() > 0) { + // 计算平均分并确保在0-100范围内 + double avgScore = info.getTotal() / info.getCount(); + if (avgScore < 0) avgScore = 0; + if (avgScore > 100) avgScore = 100; + scores.put(dim, (double) Math.round(avgScore)); + } + } + + return scores; + } + + @Override + public String determineMbtiType(Map scores) { + StringBuilder mbtiType = new StringBuilder(); + + // 当分数等于50时,默认选择第二个类型 + if (scores.getOrDefault("EI", 0.0) >= 50) { + mbtiType.append("E"); + } else { + mbtiType.append("I"); + } + + if (scores.getOrDefault("SN", 0.0) >= 50) { + mbtiType.append("S"); + } else { + mbtiType.append("N"); + } + + if (scores.getOrDefault("TF", 0.0) >= 50) { + mbtiType.append("T"); + } else { + mbtiType.append("F"); + } + + if (scores.getOrDefault("JP", 0.0) >= 50) { + mbtiType.append("J"); + } else { + mbtiType.append("P"); + } + + return mbtiType.toString(); + } + + private String generateResultId() { + return "result_" + Instant.now().toEpochMilli(); + } + + // 内部类用于存储每个维度的分数信息 + @Data + private static class ScoreInfo { + private double total = 0; + private int count = 0; + } +} \ No newline at end of file diff --git a/src/main/java/com/yang/test/util/JsonTypeHandler.java b/src/main/java/com/yang/test/util/JsonTypeHandler.java new file mode 100644 index 0000000..a089c18 --- /dev/null +++ b/src/main/java/com/yang/test/util/JsonTypeHandler.java @@ -0,0 +1,71 @@ +package com.yang.test.util; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.ibatis.type.BaseTypeHandler; +import org.apache.ibatis.type.JdbcType; +import org.apache.ibatis.type.MappedTypes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.CallableStatement; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +/** + * JSON类型处理器,用于将Java对象与数据库JSON字段之间进行转换 + */ +@MappedTypes({List.class}) +public class JsonTypeHandler extends BaseTypeHandler { + private static final Logger logger = LoggerFactory.getLogger(JsonTypeHandler.class); + private static final ObjectMapper objectMapper = new ObjectMapper(); + private final Class type; + + public JsonTypeHandler(Class type) { + if (type == null) { + throw new IllegalArgumentException("Type argument cannot be null"); + } + this.type = type; + } + + @Override + public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException { + try { + String json = objectMapper.writeValueAsString(parameter); + ps.setString(i, json); + } catch (JsonProcessingException e) { + logger.error("Error converting object to JSON", e); + throw new SQLException("Error converting object to JSON", e); + } + } + + @Override + public T getNullableResult(ResultSet rs, String columnName) throws SQLException { + return parseJSON(rs.getString(columnName)); + } + + @Override + public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException { + return parseJSON(rs.getString(columnIndex)); + } + + @Override + public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { + return parseJSON(cs.getString(columnIndex)); + } + + private T parseJSON(String json) { + if (json == null) { + return null; + } + + try { + return objectMapper.readValue(json, type); + } catch (Exception e) { + logger.error("Error parsing JSON to object", e); + return null; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/yang/test/util/ResponseUtil.java b/src/main/java/com/yang/test/util/ResponseUtil.java new file mode 100644 index 0000000..529b6cd --- /dev/null +++ b/src/main/java/com/yang/test/util/ResponseUtil.java @@ -0,0 +1,22 @@ +package com.yang.test.util; + +import java.util.HashMap; +import java.util.Map; + +public class ResponseUtil { + + public static Map success(Object data) { + Map response = new HashMap<>(); + response.put("code", 0); + response.put("message", "success"); + response.put("data", data); + return response; + } + + public static Map error(String message) { + Map response = new HashMap<>(); + response.put("code", 1); + response.put("message", message); + return response; + } +} \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..e95f25f --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,41 @@ +# 数据库配置 +spring.datasource.url=jdbc:mysql://62.234.217.137:3306/mbti?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai +spring.datasource.username=root +spring.datasource.password=nWZpHMb8mNxWE5Xk +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver + +# 服务器配置 +server.port=8080 + +# HikariCP配置 +spring.datasource.hikari.pool-name=HikariPool-1 +spring.datasource.hikari.connection-timeout=3000 +spring.datasource.hikari.max-lifetime=540000 +spring.datasource.hikari.idle-timeout=600000 +spring.datasource.hikari.minimum-idle=5 +spring.datasource.hikari.maximum-pool-size=20 +spring.datasource.hikari.validation-timeout=3000 +spring.datasource.hikari.keepalive-time=30000 +spring.datasource.hikari.data-source-properties.socketTimeout=30 +spring.datasource.hikari.data-source-properties.autoReconnect=true + +# DeepSeek API配置 +deepseek.api.key=sk-1d3dd761c40045228547efb38ce59754 +deepseek.model=deepseek-chat +deepseek.api.url=https://api.deepseek.com/v1/chat/completions + +# 跨域配置 +cors.allowed-origins=http://localhost:8080,http://localhost:5173 + +# MyBatis配置 +mybatis.config-location=classpath:mybatis-config.xml +mybatis.mapper-locations=classpath:mapper/*.xml +mybatis.type-aliases-package=com.yang.test.pojo + +# 日志配置 +logging.level.root=INFO +logging.level.com.yang.test=DEBUG +logging.level.com.yang.test.mapper=DEBUG +logging.file.name=server.log +logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n +logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n \ No newline at end of file diff --git a/src/main/resources/mapper/HldzyMapper.xml b/src/main/resources/mapper/HldzyMapper.xml new file mode 100644 index 0000000..064ac03 --- /dev/null +++ b/src/main/resources/mapper/HldzyMapper.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + INSERT INTO t_test_result( + user_id, result_code, r_score, c_score, e_score, s_score, a_score, i_score + ) VALUES ( + #{userId}, #{resultCode}, #{rScore}, #{cScore}, #{eScore}, #{sScore}, #{aScore}, #{iScore} + ) + + \ No newline at end of file diff --git a/src/main/resources/mapper/MbtiMapper.xml b/src/main/resources/mapper/MbtiMapper.xml new file mode 100644 index 0000000..a512578 --- /dev/null +++ b/src/main/resources/mapper/MbtiMapper.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + INSERT INTO results (id, type, dimensions, report, created_at) + VALUES (#{id}, #{type}, #{dimensions, typeHandler=com.yang.test.util.JsonTypeHandler}, #{report}, #{createdAt}) + + + + + \ No newline at end of file diff --git a/src/main/resources/mybatis-config.xml b/src/main/resources/mybatis-config.xml new file mode 100644 index 0000000..5724891 --- /dev/null +++ b/src/main/resources/mybatis-config.xml @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/src/test/java/com/yang/test/TestApplicationTests.java b/src/test/java/com/yang/test/TestApplicationTests.java new file mode 100644 index 0000000..10a8542 --- /dev/null +++ b/src/test/java/com/yang/test/TestApplicationTests.java @@ -0,0 +1,13 @@ +package com.yang.test; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class TestApplicationTests { + + @Test + void contextLoads() { + } + +}