Bladeren bron

1.1 登录注册功能完善,数据库交互操作,增加security模块
1.2 完成随机疾病回复功能,输入日期即可回复随机的疾病,如果日期在数据库中存在则回复数据库中日期

zrh1922741520 1 week geleden
bovenliggende
commit
c66e0dd786

+ 1 - 1
src/main/java/ai/java/back/config/SecurityConfig.java

@@ -36,7 +36,7 @@ public class SecurityConfig {
             .csrf(AbstractHttpConfigurer::disable)
             .cors(Customizer.withDefaults())
             .authorizeHttpRequests(auth -> auth
-                .requestMatchers("/v1/auth/**").permitAll()
+                .requestMatchers("/v1/auth/**","/api/disease/by-date").permitAll()
                 .anyRequest().authenticated()
             )
             .sessionManagement(session -> session

+ 22 - 0
src/main/java/ai/java/back/controller/DailyQuestionInfoController.java

@@ -0,0 +1,22 @@
+package ai.java.back.controller;
+
+import ai.java.back.entity.DailyQuestionInfo;
+import ai.java.back.service.DailyQuestionInfoService;
+import ai.java.back.model.DateRequest;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalDate;
+
+@RestController
+@RequestMapping("/api/disease")
+public class DailyQuestionInfoController {
+    @Autowired
+    private DailyQuestionInfoService dailyQuestionInfoService;
+
+    @PostMapping("/by-date")
+    public DailyQuestionInfo getDiseaseByDate(@RequestBody DateRequest request) {
+        return dailyQuestionInfoService.getOrGenerateDiseaseByDate(request.getDate());
+    }
+}

+ 26 - 0
src/main/java/ai/java/back/entity/DailyQuestionInfo.java

@@ -0,0 +1,26 @@
+package ai.java.back.entity;
+
+import jakarta.persistence.*;
+import lombok.Getter;
+import lombok.Setter;
+import java.time.LocalDate;
+
+import org.hibernate.annotations.CreationTimestamp;
+
+@Getter
+@Setter
+@Entity
+@Table(name = "daily_question_info")
+public class DailyQuestionInfo {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "disease_id", nullable = false)
+    private Integer id;
+
+    @Column(name = "disease_name", nullable = false, columnDefinition = "text")
+    private String diseaseName;
+
+    
+    @Column(name = "date_time", nullable = false, unique = true)
+    private LocalDate dateTime;
+}

+ 2 - 2
src/main/java/ai/java/back/model/ChatRequest.java

@@ -11,9 +11,9 @@ public class ChatRequest {
     // 使用模型名称
     private String model="qwen2.5:0.5b";
     // 会话id
-    private Integer sessionId;
+    private Integer sessionId=0;
     // 历史记录
-    private History history; // 允许 history 为 null
+    private History history=null; // 允许 history 为 null
     // 问题信息
     private Message question;
 

+ 12 - 0
src/main/java/ai/java/back/model/DateRequest.java

@@ -0,0 +1,12 @@
+package ai.java.back.model;
+
+import org.springframework.format.annotation.DateTimeFormat;
+
+import lombok.Data;
+
+import java.time.LocalDate;
+@Data
+public class DateRequest {
+    @DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
+    private LocalDate date;
+}

+ 13 - 0
src/main/java/ai/java/back/repository/DailyQuestionInfoRepository.java

@@ -0,0 +1,13 @@
+package ai.java.back.repository;
+
+import ai.java.back.entity.DailyQuestionInfo;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.time.LocalDate;
+import java.util.Optional;
+
+@Repository
+public interface DailyQuestionInfoRepository extends JpaRepository<DailyQuestionInfo, Integer> {
+    Optional<DailyQuestionInfo> findByDateTime(LocalDate dateTime);
+}

+ 5 - 0
src/main/java/ai/java/back/service/ChatService.java

@@ -19,4 +19,9 @@ public interface ChatService {
 
     SseEmitter streamChat(ChatRequest requestDTO);
 
+    /**
+     * 发送问题给大模型并返回答复内容(只返回答复字符串,不做其他处理)
+     */
+    String askModel(String question) throws IOException;
+
 }

+ 8 - 0
src/main/java/ai/java/back/service/DailyQuestionInfoService.java

@@ -0,0 +1,8 @@
+package ai.java.back.service;
+
+import ai.java.back.entity.DailyQuestionInfo;
+import java.time.LocalDate;
+
+public interface DailyQuestionInfoService {
+    DailyQuestionInfo getOrGenerateDiseaseByDate(LocalDate dateTime);
+}

+ 42 - 1
src/main/java/ai/java/back/service/impl/ChatServiceImpl.java

@@ -9,6 +9,7 @@ import ai.java.back.service.ChatService;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
 
 import okhttp3.*;
 import org.jetbrains.annotations.NotNull;
@@ -222,7 +223,13 @@ public class ChatServiceImpl implements ChatService {
             }
         });
     }
-
+    /**
+     * 处理每个数据块
+     *
+     * @param emitter SseEmitter 对象
+     * @param chunk   数据块
+     * @throws IOException 处理数据块时发生的异常
+     */
     private void processChunk(SseEmitter emitter, OllamaChatResponse chunk) throws IOException {
         ChatStreamResponse chatStreamResponse = new ChatStreamResponse();
         chatStreamResponse.setContent(chunk.getMessage().getContent());
@@ -242,4 +249,38 @@ public class ChatServiceImpl implements ChatService {
             throw new RuntimeException(e);
         }
     }
+
+    @Override
+    public String askModel(String question) throws IOException {
+        // 构建请求体
+        ObjectNode requestBody = objectMapper.createObjectNode();
+        requestBody.put("model", "qwen2.5:0.5b");
+        requestBody.put("temperature", 0.8);
+        requestBody.put("prompt", question);
+        requestBody.put("stream", false);
+
+        Request request = new Request.Builder()
+                .url(String.format("http://%s:%d/api/generate", ollamaHost, ollamaPort))
+                .post(RequestBody.create(
+                        objectMapper.writeValueAsString(requestBody),
+                        MediaType.parse("application/json")
+                ))
+                .build();
+        Response response = client.newCall(request).execute();
+
+
+        // 解析响应内容并提取嵌套的 content 字段
+        String responseBody = response.body().string();
+        System.out.println(responseBody);
+        String extractedContent;
+        try {
+            JsonNode rootNode = objectMapper.readTree(responseBody);
+            // 修正为提取 response 字段
+            extractedContent = rootNode.path("response").asText();
+        } catch (JsonProcessingException e) {
+            throw new RuntimeException("Failed to parse response body", e);
+        }
+
+        return extractedContent;
+    }
 }

+ 43 - 0
src/main/java/ai/java/back/service/impl/DailyQuestionInfoServiceImpl.java

@@ -0,0 +1,43 @@
+package ai.java.back.service.impl;
+
+import ai.java.back.entity.DailyQuestionInfo;
+import ai.java.back.repository.DailyQuestionInfoRepository;
+import ai.java.back.service.DailyQuestionInfoService;
+import ai.java.back.service.ChatService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.io.IOException;
+import java.time.LocalDate;
+
+@Service
+public class DailyQuestionInfoServiceImpl implements DailyQuestionInfoService {
+    @Autowired
+    private DailyQuestionInfoRepository dailyQuestionInfoRepository;
+
+    @Autowired
+    private ChatService chatService;
+
+    @Override
+    public DailyQuestionInfo getOrGenerateDiseaseByDate(LocalDate dateTime) {
+        return dailyQuestionInfoRepository.findByDateTime(dateTime)
+                .orElseGet(() -> {
+                    String diseaseName = generateDiseaseNameByLLM(dateTime);
+                    DailyQuestionInfo info = new DailyQuestionInfo();
+                    info.setDateTime(dateTime);
+                    info.setDiseaseName(diseaseName);
+                    return dailyQuestionInfoRepository.save(info);
+                });
+    }
+
+    // 只调用大模型API生成疾病名称,不做其他操作
+    private String generateDiseaseNameByLLM(LocalDate date) {
+        String prompt = String.format("请根据日期 %s 随机生成一个常见疾病名称,仅返回疾病名称,不要其他内容。", date.toString());
+        try {
+            String result = chatService.askModel(prompt);
+            return result != null ? result.trim() : null;
+        } catch (IOException e) {
+            throw new RuntimeException("调用大模型API生成疾病名称失败", e);
+        }
+    }
+}