diff --git a/pom.xml b/pom.xml
index a3f2635..6316ee6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -125,6 +125,16 @@
+
+ org.apache.httpcomponents
+ httpclient
+ 4.5.13
+
+
+ com.google.code.gson
+ gson
+ 2.8.6
+
@@ -176,6 +186,7 @@
org.springframework.boot
spring-boot-starter-websocket
+
org.springframework.boot
spring-boot-starter-webflux
diff --git a/src/main/java/com/example/venue_reservation_service/config/InterceptorConfig.java b/src/main/java/com/example/venue_reservation_service/config/InterceptorConfig.java
index b4c42ed..8459220 100644
--- a/src/main/java/com/example/venue_reservation_service/config/InterceptorConfig.java
+++ b/src/main/java/com/example/venue_reservation_service/config/InterceptorConfig.java
@@ -21,6 +21,7 @@ public class InterceptorConfig implements WebMvcConfigurer {
.excludePathPatterns("/user/test")
.excludePathPatterns("/user/admin")
.excludePathPatterns("/user/reset")
+ .excludePathPatterns("/chat/**")
.excludePathPatterns("/reservation/excel")
.excludePathPatterns("/reservation/payment")
.excludePathPatterns("/swagger-ui/index.html")
diff --git a/src/main/java/com/example/venue_reservation_service/controller/ChatController.java b/src/main/java/com/example/venue_reservation_service/controller/ChatController.java
new file mode 100644
index 0000000..4df4df8
--- /dev/null
+++ b/src/main/java/com/example/venue_reservation_service/controller/ChatController.java
@@ -0,0 +1,39 @@
+package com.example.venue_reservation_service.controller;
+
+
+import com.example.venue_reservation_service.entity.ChatRequest;
+import com.example.venue_reservation_service.service.ChatService;
+import jakarta.annotation.Resource;
+import jakarta.servlet.ServletOutputStream;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.*;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+
+@RestController
+@RequestMapping("/chat")
+@CrossOrigin
+public class ChatController {
+
+ @Resource
+ private ChatService chatService;
+
+ @PostMapping(value = "/ask", produces = MediaType.TEXT_PLAIN_VALUE)
+ public void chat(@RequestBody ChatRequest request, HttpServletRequest httpRequest, HttpServletResponse response) throws IOException {
+
+ // 设置流式响应头
+ response.setContentType("text/event-stream");
+ response.setCharacterEncoding(StandardCharsets.UTF_8.name());
+ response.setHeader("Cache-Control", "no-cache");
+
+ // 获取输出流
+ ServletOutputStream outputStream = response.getOutputStream();
+
+ // 处理流式响应
+ chatService.streamChatResponse(request, outputStream, httpRequest);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/venue_reservation_service/controller/DeviceController.java b/src/main/java/com/example/venue_reservation_service/controller/DeviceController.java
index b1f4d48..e95b5c6 100644
--- a/src/main/java/com/example/venue_reservation_service/controller/DeviceController.java
+++ b/src/main/java/com/example/venue_reservation_service/controller/DeviceController.java
@@ -1,5 +1,6 @@
package com.example.venue_reservation_service.controller;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.example.venue_reservation_service.domain.Device;
import com.example.venue_reservation_service.mapper.DeviceMapper;
import com.example.venue_reservation_service.service.DeviceService;
@@ -39,17 +40,10 @@ public class DeviceController {
}
//
// 定时任务 - 每秒生成一条数据
-// @Scheduled(fixedRate = 1000)
+// @Scheduled(fixedRate = 3000)
// public void generateAndSendDeviceData() {
// // 生成并保存新数据
-// Device newDevice = deviceService.generateDeviceData();
-// deviceService.save(newDevice);
-//
-// // 检查并清理旧数据
-// long count = deviceService.count();
-// if (count > 100) {
-// deviceMapper.deleteOldestRecords(50);
-// }
+// Device newDevice = deviceService.getOne(Wrappers.query().orderByDesc("id").last("LIMIT 1"));
//
// // 推送新数据到前端
// messagingTemplate.convertAndSend("/topic/devices", newDevice);
diff --git a/src/main/java/com/example/venue_reservation_service/controller/SessionController.java b/src/main/java/com/example/venue_reservation_service/controller/SessionController.java
deleted file mode 100644
index 8735919..0000000
--- a/src/main/java/com/example/venue_reservation_service/controller/SessionController.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package com.example.venue_reservation_service.controller;
-
-import com.example.venue_reservation_service.domain.VeMessage;
-import com.example.venue_reservation_service.domain.VeSession;
-import com.example.venue_reservation_service.service.VeMessageService;
-import com.example.venue_reservation_service.service.VeSessionService;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import jakarta.annotation.Resource;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-@RestController
-@RequestMapping("/session")
-@Api("ai会话管理模块")
-@CrossOrigin
-public class SessionController {
-
- @Resource
- private VeSessionService sessionService;
-
- @Resource
- private VeMessageService messageService;
-
- @ApiOperation("创建新会话")
- @PostMapping("/create")
- public ResponseEntity createSession(@RequestBody VeSession session) {
- VeSession savedSession = sessionService.saveSession(session);
- return ResponseEntity.status(HttpStatus.CREATED).body(savedSession);
- }
-
- @ApiOperation("获取用户会话历史")
- @GetMapping("/list")
- public ResponseEntity> getUserSessions(@RequestParam(name = "userId") Integer userId) {
- List sessions = sessionService.getSessionsByUserId(userId);
- return ResponseEntity.ok(sessions);
- }
-
- @ApiOperation("获取会话详情")
- @GetMapping("/{sessionId}")
- public ResponseEntity getSession(@PathVariable("sessionId") Integer sessionId) {
- VeSession session = sessionService.getById(sessionId);
- if (session != null) {
- return ResponseEntity.ok(session);
- } else {
- return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
- }
- }
-
- @ApiOperation("获取指定会话的所有消息")
- @GetMapping("/message/{sessionId}")
- public ResponseEntity> getSessionMessages(@PathVariable("sessionId") Integer sessionId) {
- List messages = messageService.getMessagesBySessionId(sessionId);
- return ResponseEntity.ok(messages);
- }
-
- @ApiOperation("创建新消息")
- @PostMapping("/message/create")
- public ResponseEntity createMessage(@RequestBody VeMessage message) {
- VeMessage savedMessage = messageService.saveMessage(message);
- return ResponseEntity.status(HttpStatus.CREATED).body(savedMessage);
- }
-}
diff --git a/src/main/java/com/example/venue_reservation_service/controller/TypeController.java b/src/main/java/com/example/venue_reservation_service/controller/TypeController.java
index 5fe7fcb..cc7545b 100644
--- a/src/main/java/com/example/venue_reservation_service/controller/TypeController.java
+++ b/src/main/java/com/example/venue_reservation_service/controller/TypeController.java
@@ -1,5 +1,6 @@
package com.example.venue_reservation_service.controller;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.example.venue_reservation_service.domain.Type;
import com.example.venue_reservation_service.dto.PageDTO;
import com.example.venue_reservation_service.service.TypeService;
@@ -8,9 +9,12 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import jakarta.annotation.Resource;
import org.apache.commons.io.FilenameUtils;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
+import java.util.Optional;
+
@RestController
@RequestMapping("/type")
@CrossOrigin
@@ -20,10 +24,17 @@ public class TypeController {
@Resource
private TypeService typeService;
+ @Value("${access.url}")
+ private String imgPrefix;
+
@ApiOperation("查询某个场馆信息")
@GetMapping("/select/{id}")
public Result select(@PathVariable("id") Integer id){
- return Result.ok(typeService.getById(id)).message("查询成功");
+ Type type = typeService.getById(id);
+ if(Optional.ofNullable(type).isPresent() && StringUtils.isNotBlank(type.getImgUrl())){
+ type.setImgUrl(imgPrefix + type.getImgUrl());
+ }
+ return Result.ok(type).message("查询成功");
}
@ApiOperation("查看所有场馆信息")
diff --git a/src/main/java/com/example/venue_reservation_service/domain/VeMessage.java b/src/main/java/com/example/venue_reservation_service/domain/VeMessage.java
index d0886f0..8d5133f 100644
--- a/src/main/java/com/example/venue_reservation_service/domain/VeMessage.java
+++ b/src/main/java/com/example/venue_reservation_service/domain/VeMessage.java
@@ -38,7 +38,7 @@ public class VeMessage implements Serializable {
/**
* 发送者类型
*/
- private Object sender;
+ private String sender;
/**
* 创建时间
diff --git a/src/main/java/com/example/venue_reservation_service/domain/VeSession.java b/src/main/java/com/example/venue_reservation_service/domain/VeSession.java
index abf9469..a8c793e 100644
--- a/src/main/java/com/example/venue_reservation_service/domain/VeSession.java
+++ b/src/main/java/com/example/venue_reservation_service/domain/VeSession.java
@@ -8,7 +8,9 @@ import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
+import java.util.ArrayList;
import java.util.Date;
+import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
diff --git a/src/main/java/com/example/venue_reservation_service/entity/ChatRequest.java b/src/main/java/com/example/venue_reservation_service/entity/ChatRequest.java
new file mode 100644
index 0000000..681f9b0
--- /dev/null
+++ b/src/main/java/com/example/venue_reservation_service/entity/ChatRequest.java
@@ -0,0 +1,11 @@
+package com.example.venue_reservation_service.entity;
+
+import lombok.Data;
+@Data
+public class ChatRequest {
+
+ private String content;
+
+ private String sessionToken;
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/venue_reservation_service/entity/ChatResponse.java b/src/main/java/com/example/venue_reservation_service/entity/ChatResponse.java
new file mode 100644
index 0000000..8e5dea0
--- /dev/null
+++ b/src/main/java/com/example/venue_reservation_service/entity/ChatResponse.java
@@ -0,0 +1,14 @@
+package com.example.venue_reservation_service.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+@Data
+@AllArgsConstructor
+public class ChatResponse {
+
+ private String content;
+
+ private String sessionToken;
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/venue_reservation_service/mapper/VeMessageMapper.java b/src/main/java/com/example/venue_reservation_service/mapper/VeMessageMapper.java
index 30d0d0b..6fdde2a 100644
--- a/src/main/java/com/example/venue_reservation_service/mapper/VeMessageMapper.java
+++ b/src/main/java/com/example/venue_reservation_service/mapper/VeMessageMapper.java
@@ -2,6 +2,9 @@ package com.example.venue_reservation_service.mapper;
import com.example.venue_reservation_service.domain.VeMessage;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.*;
+
+import java.util.List;
/**
* @author 31586
@@ -9,7 +12,10 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
* @createDate 2025-06-17 15:36:33
* @Entity generator.domain.VeMessage
*/
+@Mapper
public interface VeMessageMapper extends BaseMapper {
+ @Select("SELECT * FROM venue_message WHERE session_id = #{sessionId} ORDER BY created_at ASC")
+ List selectMessagesBySessionId(@Param("sessionId") Integer sessionId);
}
diff --git a/src/main/java/com/example/venue_reservation_service/mapper/VeSessionMapper.java b/src/main/java/com/example/venue_reservation_service/mapper/VeSessionMapper.java
index cb7f950..ae5d962 100644
--- a/src/main/java/com/example/venue_reservation_service/mapper/VeSessionMapper.java
+++ b/src/main/java/com/example/venue_reservation_service/mapper/VeSessionMapper.java
@@ -2,11 +2,9 @@ package com.example.venue_reservation_service.mapper;
import com.example.venue_reservation_service.domain.VeSession;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import org.apache.ibatis.annotations.Insert;
-import org.apache.ibatis.annotations.Options;
-import org.apache.ibatis.annotations.Param;
-import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.annotations.*;
+import java.time.LocalDateTime;
import java.util.List;
/**
@@ -15,8 +13,12 @@ import java.util.List;
* @createDate 2025-06-17 15:36:33
* @Entity generator.domain.VeSession
*/
+@Mapper
public interface VeSessionMapper extends BaseMapper {
+
+ @Select("SELECT * FROM venue_session WHERE session_token = #{sessionToken}")
+ VeSession selectBySessionToken(@Param("sessionToken") String sessionToken);
}
diff --git a/src/main/java/com/example/venue_reservation_service/service/ChatService.java b/src/main/java/com/example/venue_reservation_service/service/ChatService.java
new file mode 100644
index 0000000..18b078d
--- /dev/null
+++ b/src/main/java/com/example/venue_reservation_service/service/ChatService.java
@@ -0,0 +1,10 @@
+package com.example.venue_reservation_service.service;
+
+import com.example.venue_reservation_service.entity.ChatRequest;
+import jakarta.servlet.ServletOutputStream;
+import jakarta.servlet.http.HttpServletRequest;
+
+// ChatService.java
+public interface ChatService {
+ void streamChatResponse(ChatRequest request, ServletOutputStream outputStream, HttpServletRequest httpRequest);
+}
diff --git a/src/main/java/com/example/venue_reservation_service/service/VeMessageService.java b/src/main/java/com/example/venue_reservation_service/service/VeMessageService.java
index 31ade0a..dbaf201 100644
--- a/src/main/java/com/example/venue_reservation_service/service/VeMessageService.java
+++ b/src/main/java/com/example/venue_reservation_service/service/VeMessageService.java
@@ -12,7 +12,6 @@ import java.util.List;
*/
public interface VeMessageService extends IService {
- VeMessage saveMessage(VeMessage message);
+ List getBySessionId(Integer sessionId);
- List getMessagesBySessionId(Integer sessionId);
}
diff --git a/src/main/java/com/example/venue_reservation_service/service/VeSessionService.java b/src/main/java/com/example/venue_reservation_service/service/VeSessionService.java
index f90e6b0..b8df891 100644
--- a/src/main/java/com/example/venue_reservation_service/service/VeSessionService.java
+++ b/src/main/java/com/example/venue_reservation_service/service/VeSessionService.java
@@ -3,8 +3,6 @@ package com.example.venue_reservation_service.service;
import com.example.venue_reservation_service.domain.VeSession;
import com.baomidou.mybatisplus.extension.service.IService;
-import java.util.List;
-
/**
* @author 31586
* @description 针对表【venue_session】的数据库操作Service
@@ -12,7 +10,7 @@ import java.util.List;
*/
public interface VeSessionService extends IService {
- VeSession saveSession(VeSession session);
+ VeSession createSession(Integer userId, String userIp);
+ VeSession getByToken(String token);
- List getSessionsByUserId(Integer userId);
}
diff --git a/src/main/java/com/example/venue_reservation_service/service/impl/ChatServiceImpl.java b/src/main/java/com/example/venue_reservation_service/service/impl/ChatServiceImpl.java
new file mode 100644
index 0000000..5ad9873
--- /dev/null
+++ b/src/main/java/com/example/venue_reservation_service/service/impl/ChatServiceImpl.java
@@ -0,0 +1,169 @@
+package com.example.venue_reservation_service.service.impl;
+
+import com.example.venue_reservation_service.domain.VeMessage;
+import com.example.venue_reservation_service.domain.VeSession;
+import com.example.venue_reservation_service.entity.ChatRequest;
+import com.example.venue_reservation_service.mapper.VeMessageMapper;
+import com.example.venue_reservation_service.mapper.VeSessionMapper;
+import com.example.venue_reservation_service.service.ChatService;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import jakarta.annotation.Resource;
+import jakarta.servlet.ServletOutputStream;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.RequiredArgsConstructor;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.time.LocalDateTime;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+@Service
+@RequiredArgsConstructor
+public class ChatServiceImpl implements ChatService {
+
+ @Resource
+ private VeSessionMapper sessionMapper;
+
+ @Resource
+ private VeMessageMapper messageMapper;
+ @Value("${internai.api-url}")
+ private String apiUrl;
+ @Value("${internai.api-key}")
+ private String apiKey;
+
+ @Override
+ @Transactional
+ public void streamChatResponse(ChatRequest request, ServletOutputStream outputStream, HttpServletRequest httpRequest) {
+ // 获取或创建会话
+ VeSession session = getOrCreateSession(request.getSessionToken(), httpRequest);
+ String sessionToken = session.getSessionToken();
+
+ // 保存用户消息
+ saveMessage(request.getContent(), "user", session.getId());
+
+ // 构建完整对话历史
+ List