From bd20deca35876f7ae56e8e3c98c93d91fa91d379 Mon Sep 17 00:00:00 2001 From: spllzh <28668817@qq.com> Date: Thu, 7 Aug 2025 20:51:29 +0800 Subject: [PATCH] =?UTF-8?q?embeddign=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Langchain4jHeima20250803Application.java | 4 + .../aiservice/CstAIStreamingService.java | 5 +- .../controller/ReservationController.java | 21 +++++ .../embedding/EnbedingModelConfig.java | 8 +- .../mapper/ReservationMapper.java | 22 +++++ .../langchain4jheima/pojo/Reservation.java | 52 ++++++++++++ .../service/IReservationService.java | 23 ++++++ .../service/impl/ReservationServiceImpl.java | 44 ++++++++++ .../tools/ReservationTool.java | 42 ++++++++++ src/main/resources/application.yml | 21 ++++- .../resources/mapper/ReservationMapper.xml | 20 +++++ .../service/ReservationServiceTest.java | 81 +++++++++++++++++++ 12 files changed, 336 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/cst/langchain4jheima/controller/ReservationController.java create mode 100644 src/main/java/com/cst/langchain4jheima/mapper/ReservationMapper.java create mode 100644 src/main/java/com/cst/langchain4jheima/pojo/Reservation.java create mode 100644 src/main/java/com/cst/langchain4jheima/service/IReservationService.java create mode 100644 src/main/java/com/cst/langchain4jheima/service/impl/ReservationServiceImpl.java create mode 100644 src/main/java/com/cst/langchain4jheima/tools/ReservationTool.java create mode 100644 src/main/resources/mapper/ReservationMapper.xml create mode 100644 src/test/java/com/cst/langchain4jheima/service/ReservationServiceTest.java diff --git a/src/main/java/com/cst/langchain4jheima/Langchain4jHeima20250803Application.java b/src/main/java/com/cst/langchain4jheima/Langchain4jHeima20250803Application.java index c0ec45d..dba3032 100644 --- a/src/main/java/com/cst/langchain4jheima/Langchain4jHeima20250803Application.java +++ b/src/main/java/com/cst/langchain4jheima/Langchain4jHeima20250803Application.java @@ -1,8 +1,12 @@ package com.cst.langchain4jheima; +import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.FilterType; +@MapperScan("com.cst.langchain4jheima.mapper") @SpringBootApplication public class Langchain4jHeima20250803Application { diff --git a/src/main/java/com/cst/langchain4jheima/aiservice/CstAIStreamingService.java b/src/main/java/com/cst/langchain4jheima/aiservice/CstAIStreamingService.java index 9e261de..113295a 100644 --- a/src/main/java/com/cst/langchain4jheima/aiservice/CstAIStreamingService.java +++ b/src/main/java/com/cst/langchain4jheima/aiservice/CstAIStreamingService.java @@ -17,7 +17,8 @@ import reactor.core.publisher.Flux; streamingChatModel = "openAiStreamingChatModel", //配置流式 输出模型 // chatMemory = "chatMemory", // 配置聊天记忆对象 ,基于内存 chatMemoryProvider = "chatMemoryProvider",//配置会话记忆 提供者对象 , 基于Redis - contentRetriever = "contentRetriever" // 配置向量数据库检索对象 + contentRetriever = "contentRetriever", // 配置向量数据库检索对象 + tools = "reservationTool" // 配置工具对象 ) public interface CstAIStreamingService { @@ -28,7 +29,7 @@ public interface CstAIStreamingService { public Flux chatMemoryId(@MemoryId String memoryId, @UserMessage String message); -// @SystemMessage(fromResource = "system.txt") + @SystemMessage(fromResource = "system.txt") public Flux chatMemoryIdRAG(@MemoryId String memoryId, @UserMessage String message); } diff --git a/src/main/java/com/cst/langchain4jheima/controller/ReservationController.java b/src/main/java/com/cst/langchain4jheima/controller/ReservationController.java new file mode 100644 index 0000000..556a48c --- /dev/null +++ b/src/main/java/com/cst/langchain4jheima/controller/ReservationController.java @@ -0,0 +1,21 @@ +package com.cst.langchain4jheima.controller; + + +import org.springframework.web.bind.annotation.RequestMapping; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RestController; + +/** + *

+ * 前端控制器 + *

+ * + * @author 李中华 ,spllzh + * @since 2025-08-05 + */ +@RestController +@RequestMapping("/reservation") +public class ReservationController { + +} diff --git a/src/main/java/com/cst/langchain4jheima/embedding/EnbedingModelConfig.java b/src/main/java/com/cst/langchain4jheima/embedding/EnbedingModelConfig.java index e993526..f3b34f1 100644 --- a/src/main/java/com/cst/langchain4jheima/embedding/EnbedingModelConfig.java +++ b/src/main/java/com/cst/langchain4jheima/embedding/EnbedingModelConfig.java @@ -62,7 +62,7 @@ public class EnbedingModelConfig { return embeddingStore; } - @Bean("myEmbeddingStoreInMemory2") + // @Bean("myEmbeddingStoreInMemory2") // @Primary public EmbeddingStore embeddingStoreInMemory2() throws IOException { //1 , 加载知识库文档进 内存 @@ -79,14 +79,14 @@ public class EnbedingModelConfig { EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder() .embeddingStore(embeddingStore) .documentSplitter(recursiveSplitter) //设置文档分割器 - .embeddingModel(embeddingModel) +// .embeddingModel(embeddingModel) .build(); ingestor.ingest( documents1); return embeddingStore; } - @Bean("myEmbeddingStoreInRedis") +// @Bean("myEmbeddingStoreInRedis") 不要打开,否则每次都会调用 阿里云的向量化模型 ,消耗token // @Primary public EmbeddingStore embeddingStoreInRedis() throws IOException { //1 , 加载知识库文档进 内存 @@ -107,7 +107,7 @@ public class EnbedingModelConfig { } @Bean - public ContentRetriever contentRetriever(@Qualifier("myEmbeddingStoreInMemory2")EmbeddingStore store){ + public ContentRetriever contentRetriever(){ EmbeddingStoreContentRetriever contentRetriever = EmbeddingStoreContentRetriever.builder() .embeddingStore(redisEmbeddingStore) .embeddingModel(embeddingModel) diff --git a/src/main/java/com/cst/langchain4jheima/mapper/ReservationMapper.java b/src/main/java/com/cst/langchain4jheima/mapper/ReservationMapper.java new file mode 100644 index 0000000..a0aea02 --- /dev/null +++ b/src/main/java/com/cst/langchain4jheima/mapper/ReservationMapper.java @@ -0,0 +1,22 @@ +package com.cst.langchain4jheima.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.cst.langchain4jheima.pojo.Reservation; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * Mapper 接口 + *

+ * + * @author 李中华 ,spllzh + * @since 2025-08-05 + */ +@Mapper +public interface ReservationMapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/com/cst/langchain4jheima/pojo/Reservation.java b/src/main/java/com/cst/langchain4jheima/pojo/Reservation.java new file mode 100644 index 0000000..ca04490 --- /dev/null +++ b/src/main/java/com/cst/langchain4jheima/pojo/Reservation.java @@ -0,0 +1,52 @@ +package com.cst.langchain4jheima.pojo; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import java.time.LocalDateTime; +import com.baomidou.mybatisplus.annotation.TableField; +import java.io.Serializable; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * + *

+ * + * @author 李中华 ,spllzh + * @since 2025-08-05 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("reservation") + +public class Reservation implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + + @TableField("name") + private String name; + + + @TableField("gender") + private String gender; + + + @TableField("phone") + private String phone; + + + @TableField("province") + private String province; + + + @TableField("datetime") + private LocalDateTime datetime; + + +} diff --git a/src/main/java/com/cst/langchain4jheima/service/IReservationService.java b/src/main/java/com/cst/langchain4jheima/service/IReservationService.java new file mode 100644 index 0000000..93d5038 --- /dev/null +++ b/src/main/java/com/cst/langchain4jheima/service/IReservationService.java @@ -0,0 +1,23 @@ +package com.cst.langchain4jheima.service; + + +import com.baomidou.mybatisplus.extension.service.IService; +import com.cst.langchain4jheima.pojo.Reservation; + +import java.util.List; + +/** + *

+ * 服务类 + *

+ * + * @author 李中华 ,spllzh + * @since 2025-08-05 + */ +public interface IReservationService extends IService { + + + boolean saveReservation(Reservation reservation); + + List getReservationsByPhone(String phone); +} diff --git a/src/main/java/com/cst/langchain4jheima/service/impl/ReservationServiceImpl.java b/src/main/java/com/cst/langchain4jheima/service/impl/ReservationServiceImpl.java new file mode 100644 index 0000000..04e84c8 --- /dev/null +++ b/src/main/java/com/cst/langchain4jheima/service/impl/ReservationServiceImpl.java @@ -0,0 +1,44 @@ +package com.cst.langchain4jheima.service.impl; + + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.cst.langchain4jheima.mapper.ReservationMapper; +import com.cst.langchain4jheima.pojo.Reservation; +import com.cst.langchain4jheima.service.IReservationService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + *

+ * 服务实现类 + *

+ * + * @author 李中华 ,spllzh + * @since 2025-08-05 + */ +@Service +public class ReservationServiceImpl extends ServiceImpl implements IReservationService { + + + /** + * 保存预约信息 + * @param reservation 预约信息 + * @return 是否保存成功 + */ + public boolean saveReservation(Reservation reservation) { + return this.save(reservation); + } + + + /** + * 根据手机号查询预约信息 + * @param phone 手机号 + * @return 预约信息列表 + */ + public List getReservationsByPhone(String phone) { + return this.lambdaQuery().eq(Reservation::getPhone, phone).list(); + } + + +} diff --git a/src/main/java/com/cst/langchain4jheima/tools/ReservationTool.java b/src/main/java/com/cst/langchain4jheima/tools/ReservationTool.java new file mode 100644 index 0000000..0e5d78c --- /dev/null +++ b/src/main/java/com/cst/langchain4jheima/tools/ReservationTool.java @@ -0,0 +1,42 @@ +package com.cst.langchain4jheima.tools; + +import com.cst.langchain4jheima.pojo.Reservation; +import com.cst.langchain4jheima.service.IReservationService; +import dev.langchain4j.agent.tool.P; +import dev.langchain4j.agent.tool.Tool; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; + +/** + * Author: 李中华 wx: spllzh email(qq): 28668817@qq.com + * Date: 2025/8/5 20:36 + **/ +@Component +public class ReservationTool { + + @Autowired + private IReservationService reservationService; + + @Tool("根据手机号查询志愿填报预约信息") + public String getReservationsByPhone(String phone) { + return reservationService.getReservationsByPhone(phone).toString(); + } + + @Tool("保存志愿填报预约信息") + public String saveReservation(String name , + @P("考生姓名") String gender , + @P("考生手机号")String phone , + @P("考生手省份")String province , + @P("考生预约时间,格式为:yyy-MM-dd'T' HH:mm") String datetime) { + Reservation reservation = new Reservation(); + reservation.setName(name); + reservation.setGender(gender); + reservation.setPhone(phone); + reservation.setProvince(province); + reservation.setDatetime(LocalDateTime.parse(datetime)); + + return reservationService.saveReservation(reservation) ? "保存成功" : "保存失败"; + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 5a78517..df515f0 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -19,6 +19,7 @@ langchain4j: log-requests: true log-responses: true max-segments-per-batch: 10 +# redis 向量数据库 community: redis: host: 101.43.230.106 @@ -35,4 +36,22 @@ spring: port: 6389 host: 124.221.59.58 password: qwe123 - database: 0 \ No newline at end of file + database: 0 + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://124.221.59.58:3309/rj_user_clue?useUnicode=true&characterEncoding=utf8 + username: root + password: ChangAndb.123! + hikari: + maximumPoolSize: 10 + minimumIdle: 5 + idleTimeout: 300000 + maxLifetime: 600000 + connectionTestQuery: "SELECT 1" + output: + ansi: + enabled: always + +mybatis: + configuration: + map-underscore-to-camel-case: true \ No newline at end of file diff --git a/src/main/resources/mapper/ReservationMapper.xml b/src/main/resources/mapper/ReservationMapper.xml new file mode 100644 index 0000000..c0a0003 --- /dev/null +++ b/src/main/resources/mapper/ReservationMapper.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + id, name, gender, phone, province, datetime + + + diff --git a/src/test/java/com/cst/langchain4jheima/service/ReservationServiceTest.java b/src/test/java/com/cst/langchain4jheima/service/ReservationServiceTest.java new file mode 100644 index 0000000..3236e46 --- /dev/null +++ b/src/test/java/com/cst/langchain4jheima/service/ReservationServiceTest.java @@ -0,0 +1,81 @@ +package com.cst.langchain4jheima.service; + +/** + * Author: 李中华 wx: spllzh email(qq): 28668817@qq.com + * Date: 2025/8/5 19:02 + **/ + + +import com.cst.langchain4jheima.Langchain4jHeima20250803Application; +import com.cst.langchain4jheima.pojo.Reservation; + +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + + +import static org.junit.jupiter.api.Assertions.*; +import java.time.LocalDateTime; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + + +@SpringBootTest(classes = Langchain4jHeima20250803Application.class) +class ReservationServiceTest { + + @Autowired + private IReservationService reservationService; + + @Test + void testSaveReservation() { + // 创建测试数据 + Reservation reservation = new Reservation(); + reservation.setName("张三"); + reservation.setGender("男"); + reservation.setPhone("13800138000"); + reservation.setProvince("北京市"); + reservation.setDatetime(LocalDateTime.now()); + + // 测试保存功能 + boolean result = reservationService.save(reservation); + + // 验证保存成功 + assertTrue(result); + assertNotNull(reservation.getId()); + } + + @Test + void testGetReservationsByPhone() { + // 先保存一条测试数据 + Reservation reservation = new Reservation(); + reservation.setName("李四"); + reservation.setGender("女"); + reservation.setPhone("13900139000"); + reservation.setProvince("上海市"); + reservation.setDatetime(LocalDateTime.now()); + reservationService.save(reservation); + + // 测试根据手机号查询功能 + List reservations = ((com.cst.langchain4jheima.service.impl.ReservationServiceImpl) reservationService) + .getReservationsByPhone("13900139000"); + + // 验证查询结果 + assertNotNull(reservations); + assertFalse(reservations.isEmpty()); + assertEquals("李四", reservations.get(0).getName()); + assertEquals("13900139000", reservations.get(0).getPhone()); + } + + @Test + void testGetReservationsByPhoneWithNoResults() { + // 测试查询不存在的手机号 + List reservations = ((com.cst.langchain4jheima.service.impl.ReservationServiceImpl) reservationService) + .getReservationsByPhone("00000000000"); + + // 验证查询结果为空 + assertNotNull(reservations); + assertTrue(reservations.isEmpty()); + } +}