Initial commit

This commit is contained in:
userpu
2025-12-17 19:47:14 +08:00
commit 0d15e20780
119 changed files with 3582 additions and 0 deletions

View File

@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.iwe3</groupId>
<artifactId>langchain4j-ai-java</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>langchain4j-ai-xiaoai-agent</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<knife4j.version>4.3.0</knife4j.version>
</properties>
<dependencies>
<!-- 接入阿里云百炼平台 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-community-dashscope-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-pinecone</artifactId>
</dependency>
<!-- 简单的rag实现 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-easy-rag</artifactId>
</dependency>
<!-- 引入德鲁伊数据源连接池的启动器 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
<version>1.2.27</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!-- Spring Boot Starter Data MongoDB -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-reactor</artifactId>
<version>1.9.1-beta17</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--导入低阶依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
<version>1.9.1-beta17</version>
</dependency>
<!--导入高阶依赖-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot-starter</artifactId>
<version>1.9.1-beta17</version>
</dependency>
<!-- 前后端分离中的后端接口测试工具 -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>${knife4j.version}</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,13 @@
package com.iwe3.langchain4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@MapperScan("com.iwe3.langchain4j.mapper")
@SpringBootApplication
public class XiaoAIAgentApplication {
public static void main(String[] args) {
SpringApplication.run(XiaoAIAgentApplication.class,args);
}
}

View File

@@ -0,0 +1,32 @@
package com.iwe3.langchain4j.config;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.pinecone.PineconeEmbeddingStore;
import dev.langchain4j.store.embedding.pinecone.PineconeServerlessIndexConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class EmbeddingStoreConfig {
@Autowired
private EmbeddingModel embeddingModel;
@Bean
public EmbeddingStore<TextSegment> embeddingStore() {
// 创建向量存储
return PineconeEmbeddingStore.builder()
.apiKey(System.getenv("PINECONE_API_KEY"))
.index("xiaoai-index") // 如果指定的索引不存在,将创建一个新的索引
.nameSpace("xiaoai-namespace") // 如果指定的名称空间不存在,将创建一个新的名称空间
.createIndex(PineconeServerlessIndexConfig.builder()
.cloud("AWS") // 指定索引部署在 AWS 云服务上。
.region("us-east-1") // 指定索引所在的 AWS 区域为 us-east-1。
.dimension(embeddingModel.dimension()) // 指定索引的向量维度,该维度与 embeddingModel 生成的向量维度相同。
.build())
.build();
}
}

View File

@@ -0,0 +1,23 @@
package com.iwe3.langchain4j.config;
import dev.langchain4j.model.chat.StreamingChatModel;
import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class LLMConfig {
/**
* @Description: 流式对话接口 StreamingChatModel
*/
@Bean
public StreamingChatModel streamingChatModel(){
return OpenAiStreamingChatModel.builder()
.apiKey(System.getenv("DASH_SCOPE_API_KEY"))
.modelName("qwen-plus")
.baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
.build();
}
}

View File

@@ -0,0 +1,65 @@
package com.iwe3.langchain4j.config;
import com.iwe3.langchain4j.entity.ChatMessages;
import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.data.message.ChatMessageDeserializer;
import dev.langchain4j.data.message.ChatMessageSerializer;
import dev.langchain4j.store.memory.chat.ChatMemoryStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;
import java.util.LinkedList;
import java.util.List;
@Component
public class MongoChatMemoryStore implements ChatMemoryStore {
@Autowired
private MongoTemplate mongoTemplate;
/**
* 根据聊天ID查询所有消息
* @param memoryId
* @return
*/
@Override
public List<ChatMessage> getMessages(Object memoryId) {
Criteria criteria = Criteria.where("memoryId").is(memoryId);
Query query = new Query(criteria);
ChatMessages chatMessages = mongoTemplate.findOne(query, ChatMessages.class);
if (chatMessages == null) return new LinkedList<>();
return ChatMessageDeserializer.messagesFromJson(chatMessages.getContent());
}
/**
* 根据聊天id修改聊天消息
* @param memoryId
* @param messages
*/
@Override
public void updateMessages(Object memoryId, List<ChatMessage> messages) {
Criteria criteria = Criteria.where("memoryId").is(memoryId);
Query query = new Query(criteria);
Update update = new Update();
update.set("content", ChatMessageSerializer.messagesToJson(messages));
// 根据query条件能查询出文档则修改文档否则新增文档
mongoTemplate.upsert(query, update, ChatMessages.class);
}
/**
* 根据聊天ID删除聊天消息
* @param memoryId
*/
@Override
public void deleteMessages(Object memoryId) {
Criteria criteria = Criteria.where("memoryId").is(memoryId);
Query query = new Query(criteria);
mongoTemplate.remove(query, ChatMessages.class);
}
}

View File

@@ -0,0 +1,27 @@
package com.iwe3.langchain4j.config;
import dev.langchain4j.memory.chat.ChatMemoryProvider;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SeparateChatAssistantConfig {
@Resource
private MongoChatMemoryStore mongoChatMemoryStore;
/**
* 指定使用-> mongoChatMemoryStore 来存储
* @return
*/
@Bean
ChatMemoryProvider chatMemoryProvider() {
return memoryId -> MessageWindowChatMemory.builder()
.id(memoryId)
.maxMessages(30).
chatMemoryStore(mongoChatMemoryStore)
.build();
}
}

View File

@@ -0,0 +1,63 @@
package com.iwe3.langchain4j.config;
import dev.langchain4j.data.document.loader.FileSystemDocumentLoader;
import dev.langchain4j.data.document.parser.TextDocumentParser;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.rag.content.retriever.ContentRetriever;
import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.nio.file.FileSystems;
@Configuration
public class XiaoAiAgentConfig {
@Autowired
private EmbeddingStore embeddingStore;
@Autowired
private EmbeddingModel embeddingModel;
@Bean
ContentRetriever contentRetrieverInPinecone() {
// 创建一个 EmbeddingStoreContentRetriever 对象,用于从嵌入存储中检索内容
return EmbeddingStoreContentRetriever
.builder()
// 设置用于生成嵌入向量的嵌入模型
.embeddingModel(embeddingModel)
// 指定要使用的嵌入存储
.embeddingStore(embeddingStore)
// 设置最大检索结果数量,这里表示最多返回 1 条匹配结果
.maxResults(1)
// 设置最小得分阈值,只有得分大于等于 0.8 的结果才会被返回
.minScore(0.8)
// 构建最终的 EmbeddingStoreContentRetriever 实例
.build();
}
/**
* 配置RAG检索增强 文档库
* @return
*/
@Bean
ContentRetriever contentRetrieverInMemory() {
// 使用FileSystemDocumentLoader读取指定目录下的知识库文档
var pathMatcher = FileSystems.getDefault()
.getPathMatcher("glob:*\\.md");
var documents = FileSystemDocumentLoader
.loadDocuments("D:/documents", pathMatcher, new TextDocumentParser());
// 使用内存向量存储
InMemoryEmbeddingStore<TextSegment> db = new InMemoryEmbeddingStore<>();
// 使用默认的文档分割器
EmbeddingStoreIngestor.ingest(documents, db);
// 从嵌入存储EmbeddingStore里检索和查询内容相关的信息
return EmbeddingStoreContentRetriever.from(db);
}
}

View File

@@ -0,0 +1,26 @@
package com.iwe3.langchain4j.controller;
import com.iwe3.langchain4j.record.ChatRecord;
import com.iwe3.langchain4j.service.XiaoAIChatAssistant;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
@Tag(name="小艾")
@RestController
@RequestMapping("/xiaoai")
public class XiaoAIController {
@Resource
private XiaoAIChatAssistant xiaoAIChatAssistant;
@Operation(summary = "对话")
@PostMapping("/chat")
public Flux<String> chat(@RequestBody ChatRecord record){
return xiaoAIChatAssistant.chat(record.memoryId(),record.message());
}
}

View File

@@ -0,0 +1,14 @@
package com.iwe3.langchain4j.entity;
import lombok.Data;
@Data
public class AppointmentEntity {
private Long id;
private String username;
private String idCard;
private String department;
private String date;
private String time;
private String doctorName;
}

View File

@@ -0,0 +1,24 @@
package com.iwe3.langchain4j.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Document("chat_messages")
public class ChatMessages {
//唯一标识,映射到 MongoDB 文档的 _id 字段
@Id
private ObjectId messageId; //利用数据库生成ID就用ObjectId
private String memoryId; //隔离聊天记录的ID
private String content; //存储当前聊天记录列表的json字符串
}

View File

@@ -0,0 +1,25 @@
package com.iwe3.langchain4j.mapper;
import com.iwe3.langchain4j.entity.AppointmentEntity;
import com.iwe3.langchain4j.record.AppointmentRecord;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface AppointmentMapper {
@Insert("""
insert into appointment(username,id_card,department,date,time,doctor_name)
values (#{r.userName},#{r.idcard},#{r.department},#{r.date},#{r.time},#{r.doctorName})
""")
void saveAppointmentEntity(@Param("r") AppointmentRecord record);
@Delete("""
delete from appointment where id = #{id}
""")
void removeById(@Param("id") long id);
AppointmentEntity getOne(@Param("r") AppointmentRecord record);
}

View File

@@ -0,0 +1,18 @@
package com.iwe3.langchain4j.record;
/**
* 编写挂号记录类
* @param userName
* @param idcard
* @param department
* @param date
* @param time
* @param doctorName
*/
public record AppointmentRecord(String userName,
String idcard,
String department,
String date,
String time,
String doctorName) {
}

View File

@@ -0,0 +1,9 @@
package com.iwe3.langchain4j.record;
/**
* 对话对象
* @param memoryId
* @param message
*/
public record ChatRecord(Long memoryId,String message) {
}

View File

@@ -0,0 +1,10 @@
package com.iwe3.langchain4j.service;
import com.iwe3.langchain4j.entity.AppointmentEntity;
import com.iwe3.langchain4j.record.AppointmentRecord;
public interface IAppointmentService {
void saveAppointmentEntity(AppointmentRecord record);
void removeById(long id);
AppointmentEntity getOne(AppointmentRecord record);
}

View File

@@ -0,0 +1,21 @@
package com.iwe3.langchain4j.service;
import dev.langchain4j.service.MemoryId;
import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.spring.AiService;
import dev.langchain4j.service.spring.AiServiceWiringMode;
import reactor.core.publisher.Flux;
//chatMemoryProvider = "chatMemoryProvider" 指定->MongoDB
//contentRetriever = "contentRetrieverInPinecone" 指定->Pinecone 向量存储版
@AiService(wiringMode = AiServiceWiringMode.EXPLICIT
,streamingChatModel = "streamingChatModel",
chatMemoryProvider = "chatMemoryProvider",
tools = {"appointmentTools"},
contentRetriever = "contentRetrieverInPinecone")
public interface XiaoAIChatAssistant {
@SystemMessage(fromResource = "xiaoai-prompt.txt")
Flux<String> chat(@MemoryId Long memoryId, @UserMessage String userMessage);
}

View File

@@ -0,0 +1,34 @@
package com.iwe3.langchain4j.service.impl;
import com.iwe3.langchain4j.entity.AppointmentEntity;
import com.iwe3.langchain4j.mapper.AppointmentMapper;
import com.iwe3.langchain4j.record.AppointmentRecord;
import com.iwe3.langchain4j.service.IAppointmentService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class AppointmentServiceImpl implements IAppointmentService {
private final AppointmentMapper appointmentMapper;
public AppointmentServiceImpl(AppointmentMapper appointmentMapper) {
this.appointmentMapper = appointmentMapper;
}
@Transactional
@Override
public void saveAppointmentEntity(AppointmentRecord record) {
appointmentMapper.saveAppointmentEntity(record);
}
@Transactional
@Override
public void removeById(long id) {
appointmentMapper.removeById(id);
}
@Override
public AppointmentEntity getOne(AppointmentRecord record) {
return appointmentMapper.getOne(record);
}
}

View File

@@ -0,0 +1,62 @@
package com.iwe3.langchain4j.tools;
import com.iwe3.langchain4j.record.AppointmentRecord;
import com.iwe3.langchain4j.service.IAppointmentService;
import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;
import org.springframework.stereotype.Component;
@Component
public class AppointmentTools {
private final IAppointmentService appointmentServiceImpl;
public AppointmentTools(IAppointmentService appointmentServiceImpl) {
this.appointmentServiceImpl = appointmentServiceImpl;
}
//修改此处的提示词
@Tool(name = "预约挂号", value = "根据参数先执行工具方法queryDepartment查询是否可预约并直接给用户回答是否可预约并让用户确认所有预约信息用户确认后再进行预约。如果用户没有提供具体的医生姓名请从向量存储中找到一位医生。")
public String scheduleAppointment(AppointmentRecord record) {
// 查找数据库中是否包含对应的预约记录
var appointment = appointmentServiceImpl.getOne(record);
if (appointment == null) {
appointmentServiceImpl.saveAppointmentEntity(record);
return "预约成功,并返回预约详情";
}
return "您在相同的科室和时间已有预约";
}
@Tool(name = "取消预约挂号", value = "根据参数,查询预约是否存在,如果存在则删除预约记录并返回取消预约成功,否则返回取消预约失败")
public String cancelAppointment(AppointmentRecord record) {
var appointment = appointmentServiceImpl.getOne(record);
if (appointment != null) {
appointmentServiceImpl.removeById(appointment.getId());
return "取消预约成功";
}
// 取消失败
return "您没有预约记录,请核对预约科室和时间";
}
@Tool(name = "查询是否有号源", value = "根据科室名称,日期,时间和医生查询是否有号源,并返回给用户")
public boolean queryDepartment(
@P(value = "科室名称") String name,
@P(value = "日期") String date,
@P(value = "时间,可选值:上午、下午") String time,
@P(value = "医生名称", required = false) String doctorName
) {
System.out.println("查询是否有号源");
System.out.println("科室名称: " + name);
System.out.println("日期: " + date);
System.out.println("时间: " + time);
System.out.println("医生名称: " + doctorName);
// TODO 维护医生的排班信息:
// 如果没有指定医生名字则根据其他条件查询是否有可以预约的医生有返回true否则返回false
//
// 如果指定了医生名字则判断医生是否有排班没有排版返回false
// 如果有排班则判断医生排班时间段是否已约满约满返回false有空闲时间返回true
return true;
}
}

View File

@@ -0,0 +1,31 @@
server:
port: 8080
servlet:
encoding:
charset: utf-8
enabled: true
force: true # 设置响应的字符编码,避免流式返回输出乱码
spring:
application:
name: langchain4j-ai-xiaoai-agent
data:
mongodb:
uri: mongodb://localhost:27017/xiao_ai_db # MongoDB连接配置,数据库 xiao_ai_db 会自动创建
datasource:
driver-class-name:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://localhost:3306/langchain4j?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: root
password: 123456
#配置Mybatis
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.iwe3.langchain4j.entity
configuration:
map-underscore-to-camel-case: true
langchain4j:
community:
dashscope:
embedding-model:
model-name: text-embedding-v3
api-key: ${DASH_SCOPE_API_KEY}

View File

@@ -0,0 +1,35 @@
**医院名称:**
四川大学华西医院
**医院地址:**
国重院区四川省成都市武侯区国学巷37号邮编610041
温江院区四川省成都市温江区万春东路566号邮编611135
**门诊开放时间:**
工作日8:00 - 17:30
急诊24小时开放
**服务热线:**
国重院区028-85422114
温江院区028-87606666
**医院简介:**
四川大学华西医院是中国西部疑难危急重症诊疗的国家级中心,集医疗、教学、科研、预防、保健、康复为一体,是国家三级甲等综合医院、国家临床医学研究中心、国家药物临床试验机构。作为中国现代医学教育的重要发源地之一,华西医院拥有全国领先的学科群,尤其在麻醉学、放射学、胸外科、泌尿外科、消化内科、老年医学等领域具有突出优势。连续多年在全国三级公立医院绩效考核中位居前列,综合实力稳居全国第一方阵,享有“北有协和,南有华西”的盛誉。
**国重院区乘车路线:**
1. 16、21、26、28、34、45、58、61、77、99路到“华西坝”站
2. 地铁1号线或18号线到“华西坝”站B出口步行约3分钟
3. 机场专线2号线至“省体育馆”站换乘地铁1号线1站即达
**温江院区乘车路线:**
1. 温江W13、W22、W26、W31路到“华西医院温江院区”站
2. 地铁17号线到“明光站”C出口换乘接驳公交或步行约15分钟
3. 自驾可经成都绕城高速“文家场”出口或成温邛高速“金马”出口抵达
**国重院区预约号取号地点:**
国重院区门诊楼一层大厅自助取号机或人工挂号窗口取号
**温江院区预约号取号地点:**
温江院区门诊楼一层大厅自助取号机或挂号收费窗口取号

View File

@@ -0,0 +1,85 @@
# 四川大学华西医院口腔科详细介绍
四川大学华西医院口腔科源于1907年成立的**华西协合大学牙学院**——中国现代口腔医学的发源地,也是亚洲最早建立的高等口腔医学教育机构。历经百余年发展,华西口腔已成长为集医疗、教学、科研于一体的国家级口腔医学中心,被誉为“中国口腔医学的摇篮”。
作为四川大学华西医院的重要组成部分,口腔科依托**国家口腔疾病临床医学研究中心**、**口腔医学国家重点实验室**和**国家“双一流”建设学科**,始终站在中国口腔医学发展的前沿。科室秉承“选英才、育精英、创精品”的理念,在口腔疑难重症诊治、多学科协作及技术创新方面具有全国引领地位。
## 历史沿革
- **1907年**加拿大传教士林则博士Dr. Ashley W. Lindsay在成都创办华西协合大学牙学院开创中国高等口腔医学教育先河。
- **1950年代**:在全国院系调整中,华西口腔成为新中国口腔医学人才培养的核心基地。
- **1980年代至今**:持续引领口腔种植、颌面外科、牙体牙髓病、牙周病等领域的临床与科研创新,多项技术填补国内空白。
- **2000年后**:随着四川大学华西医院综合实力提升,口腔科进一步整合资源,强化与全身疾病管理的联动,形成“大口腔、大健康”服务模式。
## 科室现状
目前,华西医院口腔科设有以下专业组:
- 口腔颌面外科学
- 牙体牙髓病学
- 牙周病学
- 口腔修复学
- 口腔正畸学
- 口腔种植学
- 儿童口腔病学
- 口腔黏膜病学
- 无痛舒适化治疗中心
- 口腔激光诊疗中心
科室配备**80余台国际先进口腔综合治疗台**、**20张住院病床**,拥有医护人员**130余人**,其中医生**70名**(含教授/主任医师15人、副教授/副主任医师20人、护理及技术人员**60余名**。现有**博士生导师10人**、**硕士生导师15人**,形成结构合理、梯队完善的人才体系。
## 学术影响与行业地位
- 华西口腔连续多年在复旦版《中国医院专科声誉排行榜》中位列**全国第一**。
- 多位专家担任国家级学会主委/副主委:
- **周学东教授**:曾任中华口腔医学会会长,中国工程院院士候选人,龋病防治权威。
- **石冰教授**:中华口腔医学会唇腭裂专委会前任主委,国际知名唇腭裂整形专家。
- **胡静教授**:中华口腔医学会口腔颌面外科专委会主委,擅长复杂颌面畸形与肿瘤整复。
- **王杭教授**:中华口腔医学会镇静镇痛专委会常委,国内舒适化牙科治疗先行者。
科室每年承担**国家自然科学基金重点项目、科技部重点研发计划**等国家级课题20余项发表SCI论文300+篇,牵头制定多项**国家口腔诊疗规范与指南**。
## 特色优势
- **多学科协作MDT**:作为大型综合医院口腔科,可高效联动内分泌科、心血管科、血液科等,为合并全身疾病的患者(如糖尿病、高血压、凝血障碍)提供安全、个体化的口腔治疗。
- **舒适化诊疗**2005年率先成立西南地区首个“无痛牙科中心”开展笑气镇静、静脉镇静、全麻下儿童牙病治疗等技术。
- **数字化精准口腔**全面应用CBCT、口内扫描、3D打印、动态导航种植等数字技术实现精准诊断与微创治疗。
------
## 科室地址
- **国重院区**成都市武侯区国学巷37号四川大学华西医院门诊楼**8层**
- **温江院区**成都市温江区万春东路566号门诊楼**3层**
------
## 专家团队
### 胡静
**口腔颌面外科主任 主任医师 教授 博士生导师**
**擅长**:口腔颌面部肿瘤、复杂颌骨畸形、创伤修复、正颌外科
**简介**
胡静教授、主任医师博士生导师。现任中华口腔医学会口腔颌面外科专业委员会主任委员。从事口腔颌面外科临床工作30余年在颌面部肿瘤根治与功能重建、先天性颌面畸形矫正等领域具有极高造诣。主持国家自然科学基金重点项目5项获国家科技进步二等奖1项。带领团队完成西南地区首例“全脸移植”术前评估与规划。
------
### 王杭
**口腔科副主任 主任医师 教授**
**擅长**:无痛牙科治疗、牙科恐惧症干预、复杂牙体牙髓病、老年口腔综合治疗
**简介**
王杭主任医师教授。中华口腔医学会镇静镇痛专业委员会常委四川省口腔医学会舒适化诊疗学组组长。2006年创建华西“舒适牙科中心”是国内最早系统开展笑气/静脉镇静下牙科治疗的专家之一。主编《舒适化口腔诊疗技术规范》,培训全国基层医师超千人。
------
### 石冰
**唇腭裂中心主任 主任医师 教授 博士生导师**
**擅长**:唇腭裂序列治疗、颌骨发育畸形矫正、语音康复
**简介**
石冰教授博士生导师国际唇腭裂基金会ICPF顾问。曾任中华口腔医学会唇腭裂专委会主任委员。创立“华西唇腭裂序列治疗模式”累计完成唇腭裂手术超万例技术辐射“一带一路”多个国家。获“全国优秀科技工作者”称号。

View File

@@ -0,0 +1,32 @@
### 四川大学华西医院神经内科详细介绍
四川大学华西医院神经内科成立于1914年历经百年发展已成为国内乃至国际上享有盛誉的专业科室之一。作为中国西部地区最早成立的神经病学专业科室华西医院神经内科不仅是全国首批神经病学硕士、博士学位授予点及博士后工作站也是国家级重点学科在处理复杂疑难杂症方面处于领先地位。
#### 科室设置与服务
- **专业组**临床神经生理、脑电图与癫痫、痴呆与认知障碍、脑血管病、帕金森及运动障碍、神经病理、神经肌肉病、感染与脑脊液细胞学、神经免疫、神经遗传和睡眠等11个专业组。
- **特色门诊**开设有神经肌肉病门诊、肌张力障碍和肉毒毒素治疗门诊、帕金森病和老年痴呆门诊、癫痫门诊、脑血管病门诊、运动神经元病、重症肌无力门诊、多发性硬化门诊和头痛门诊等9个特色门诊为患者提供高水平的医疗服务。
#### 医疗实力
- **床位数**拥有超过100张床位每年门急诊接诊量超过20万人次住院患者超过2000人次。
- **实验室设施**:配备了先进的肌电图与脑诱发电位、神经病理、脑电图、经颅超声多普勒、神经生化和免疫、分子生物学实验室,为临床诊断提供了强有力的支持。
#### 科研与教学
- **科研成就**近五年来承担了超过50项科研课题包括多项国家级重点项目累计科研经费超过5000万元并获得了包括国家科技进步奖在内的多个重要奖项。
- **教学任务**:承担四川大学华西临床医学院本科生、研究生、进修医师的教学工作,是四川省住院医师规范化培训基地。每年举办多个国家级继续教育学习班,如神经系统疾病高级进展学习班、经颅多普勒超声学习班等,为全国输送大量神经内科专科人才。
#### 专家团队
- **现有医生**共有60余名医生其中包括教授12人、副教授18人、主治医生20人、住院医生10人其中博士生导师8人硕士生导师10人。
- 知名专家:
- **李为民**主任医师教授博士研究生导师。擅长脑血管病及神经系统危重疾病的诊治在国内外发表学术论文150余篇。
- **王莉**现任神经内科主任教授博士研究生导师。专注于运动神经元病、周围神经病、肌肉病等神经系统的各种疑难杂症的研究与治疗发表了超过300篇学术论文并著书20余本。
#### 地址与联系方式
- **地址**成都市武侯区国学巷37号四川大学华西医院门诊楼6层。
- **电话**028-85422114总机

View File

@@ -0,0 +1,13 @@
### 四川大学华西医院科室详细介绍
#### 1、内科学系
心内科、呼吸与危重症医学科、消化内科、肾内科、血液内科、风湿免疫科、感染性疾病中心、全科医学科普通内科、肿瘤中心含肿瘤内科、放疗科、老年医学科、内分泌代谢科、重症医学科ICU/MICU、儿科、神经内科、心理卫生中心、皮肤性病科、变态反应过敏科、急诊科、中医科、康复医学科、临床营养科、罕见病诊治中心。
#### 2、外科学系
普外科(含胃肠外科、结直肠外科、胰腺外科、甲状腺外科等亚专业)、骨科、心脏大血管外科、胸外科、泌尿外科、神经外科、血管外科、整形外科/烧伤科、乳腺疾病中心、肝脏外科/肝移植中心、麻醉科、手术室。
#### 3、其他科室
妇产科(含妇科、产科、生殖医学中心)、眼科、耳鼻咽喉头颈外科、口腔科(依托华西口腔医学院,全国顶尖)、超声医学科、病理科、检验科、放射科(医学影像中心)、放射治疗科(肿瘤放疗中心)、核医学科、输血科、药剂科、病案管理科、国际医疗部、健康管理中心(体检中心)、临床药理研究中心、转化医学中心、护理部、医务部、医院感染管理部。

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace 命名空间1、与Java接口发生关联 2、为XML中内容提供一个唯一的路径-->
<mapper namespace="com.iwe3.langchain4j.mapper.AppointmentMapper">
<resultMap id="appmap" type="AppointmentEntity" autoMapping="true">
<result column="id_card" property="idCard"/>
<result column="doctor_name" property="doctorName"/>
</resultMap>
<select id="getOne" resultMap="appmap">
select * from appointment
<where>
<if test="r.userName != null">
and username = #{r.userName}
</if>
<if test="r.idcard != null">
and id_card = #{r.idcard}
</if>
<if test="r.department != null">
and department = #{r.department}
</if>
<if test="r.date != null">
and date = #{r.date}
</if>
<if test="r.time != null">
and time = #{r.time}
</if>
<if test="r.doctorName != null">
and doctor_name = #{r.doctorName}
</if>
</where>
</select>
</mapper>

View File

@@ -0,0 +1,18 @@
你的名字是“小艾”,你是一家名为“四川大学华西医院”的智能客服。
你是一个训练有素的医疗顾问和医疗伴诊助手。
你态度友好、礼貌且言辞简洁。
1、请仅在用户发起第一次会话时和用户打个招呼并介绍你是谁。
2、作为一个训练有素的医疗顾问
请基于当前临床实践和研究,针对患者提出的特定健康问题,提供详细、准确且实用的医疗建议。请同时考虑可能的病
因、诊断流程、治疗方案以及预防措施,并给出在不同情境下的应对策略。对于药物治疗,请特别指明适用的药品名
称、剂量和疗程。如果需要进一步的检查或就医,也请明确指示。
3、作为医疗伴诊助手你可以回答用户就医流程中的相关问题主要包含以下功能
AI分导诊根据患者的病情和就医需求智能推荐最合适的科室。
AI挂号助手实现智能查询是否有挂号号源服务实现智能预约挂号服务实现智能取消挂号服务。
4、你必须遵守的规则如下
在获取挂号预约详情或取消挂号预约之前,你必须确保自己知晓用户的姓名(必选)、身份证号(必选)、预约科室
必选、预约日期必选格式举例2025-12-12、预约时间必选格式上午 或 下午)、预约医生(可
选)。
当被问到其他领域的咨询时,要表示歉意并说明你无法在这方面提供帮助。
5、请在回答的结果中适当包含一些轻松可爱的图标和表情。
6、今天是 {{current_date}}

View File

@@ -0,0 +1,40 @@
package com.iwe3.langchain4j;
import dev.langchain4j.data.document.loader.FileSystemDocumentLoader;
import dev.langchain4j.data.document.parser.TextDocumentParser;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.nio.file.FileSystems;
@SpringBootTest
public class RagUploadTest {
@Autowired
private EmbeddingStore embeddingStore;
@Autowired
private EmbeddingModel embeddingModel;
@Test
public void testUploadKnowledgeLibrary() {
// 使用FileSystemDocumentLoader读取指定目录下的知识库文档
var pathMatcher = FileSystems.getDefault()
.getPathMatcher("glob:*\\.md");
var documents = FileSystemDocumentLoader
.loadDocuments("D:/documents", pathMatcher,
new TextDocumentParser());
// 文本向量化并存入向量数据库:将每个片段进行向量化,得到一个嵌入向量
EmbeddingStoreIngestor
.builder()
.embeddingStore(embeddingStore)
.embeddingModel(embeddingModel)
.build()
.ingest(documents);
}
}

View File

@@ -0,0 +1,42 @@
package com.iwe3.langchain4j;
import com.iwe3.langchain4j.record.AppointmentRecord;
import com.iwe3.langchain4j.service.IAppointmentService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class XiaoAIAgentApplicationTest {
@Autowired
private IAppointmentService appointmentServiceImpl;
@Test
void saveAppointmentEntity() {
var record = new AppointmentRecord("贝利亚",
"123456789012345678",
"内科",
"2025-12-12","上午08.30","李娜");
appointmentServiceImpl.saveAppointmentEntity(record);
}
@Test
void removeById() {
appointmentServiceImpl.removeById(1L);
}
@Test
void getOne() {
var record = new AppointmentRecord("贝利亚",
"123456789012345678",
"内科",
"2025-12-12","上午08.30","李娜");
var entity = appointmentServiceImpl.getOne(record);
System.out.println("entity = " + entity);
}
}