7.29 自建知识库+本地部署deepseek

This commit is contained in:
zhangsan 2025-07-29 10:03:49 +08:00
commit 1ea68cb74f
61 changed files with 5485 additions and 0 deletions

49
.gitignore vendored Normal file
View File

@ -0,0 +1,49 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store
/.idea/
/data/
/xfg-dev-tech-app/data/
/xfg-dev-tech-app/cloned-repo/
/push_all_branches.sh
/docs/rag-dev-ops/ollama/models/
/docs/rag-dev-ops/ollama/id_ed25519
/docs/rag-dev-ops/ollama/id_ed25519.pub
/docs/tag/v1.0/ollama/models/
/docs/tag/v1.0/ollama/id_ed25519
/docs/tag/v1.0/ollama/id_ed25519.pub

100
.mvn/settings.xml Normal file
View File

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<mirrors>
<mirror>
<id>mirror</id>
<mirrorOf>central,jcenter,!2452122-release-dbuebF</mirrorOf>
<name>mirror</name>
<url>https://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
</mirrors>
<servers>
<server>
<id>2452122-release-dbuebF</id>
<username>65b081c2242105ca211dd310</username>
<password>gbO-rXbOv(VT</password>
</server>
</servers>
<profiles>
<profile>
<id>rdc</id>
<properties>
<altReleaseDeploymentRepository>
2452122-release-dbuebF::default::https://packages.aliyun.com/65b081d4076e069afe3d2f50/maven/2452122-release-dbuebf
</altReleaseDeploymentRepository>
</properties>
<repositories>
<repository>
<id>central</id>
<url>https://maven.aliyun.com/nexus/content/groups/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>snapshots</id>
<url>https://maven.aliyun.com/nexus/content/groups/public</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>2452122-release-dbuebF</id>
<url>https://packages.aliyun.com/65b081d4076e069afe3d2f50/maven/2452122-release-dbuebf</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<url>https://maven.aliyun.com/nexus/content/groups/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>snapshots</id>
<url>https://maven.aliyun.com/nexus/content/groups/public</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>2452122-release-dbuebF</id>
<url>https://packages.aliyun.com/65b081d4076e069afe3d2f50/maven/2452122-release-dbuebf</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>rdc</activeProfile>
</activeProfiles>
</settings>

View File

@ -0,0 +1,42 @@
<?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>edu.whut</groupId>
<artifactId>ai-rag-knowledge</artifactId>
<version>1.0</version>
</parent>
<artifactId>ai-rag-knowledge-api</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-core</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,14 @@
package edu.whut.api;
import org.springframework.ai.chat.ChatResponse;
import reactor.core.publisher.Flux;
public interface IAiService {
ChatResponse generate(String model, String message);
Flux<ChatResponse> generateStream(String model, String message);
Flux<ChatResponse> generateStreamRag(String model, String ragTag, String message);
}

View File

@ -0,0 +1,16 @@
package edu.whut.api;
import edu.whut.api.response.Response;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
public interface IRAGService {
Response<List<String>> queryRagTagList();
Response<String> uploadFile(String ragTag, List<MultipartFile> files);
Response<String> analyzeGitRepository(String repoUrl, String userName, String token) throws Exception;
}

View File

@ -0,0 +1,20 @@
package edu.whut.api.response;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Response<T> implements Serializable {
private String code;
private String info;
private T data;
}

View File

@ -0,0 +1,44 @@
# —— 第一阶段Maven 构建 ——
FROM maven:3.8.7-eclipse-temurin-17-alpine AS builder
WORKDIR /workspace
# 把项目级 settings.xml 复制到容器里
COPY .mvn/settings.xml /root/.m2/settings.xml
# 1. 先只拷贝父 POM 及各模块的 pom.xml加速依赖下载
COPY pom.xml ./pom.xml
COPY ai-rag-knowledge-api/pom.xml ./ai-rag-knowledge-api/pom.xml
COPY ai-rag-knowledge-trigger/pom.xml ./ai-rag-knowledge-trigger/pom.xml
COPY ai-rag-knowledge-app/pom.xml ./ai-rag-knowledge-app/pom.xml
# 离线下载所有依赖
RUN mvn dependency:go-offline -B
# 2. 只拷源码模块,不拷 data/docs
COPY ai-rag-knowledge-api ai-rag-knowledge-api
COPY ai-rag-knowledge-trigger ai-rag-knowledge-trigger
COPY ai-rag-knowledge-app ai-rag-knowledge-app
# 3. 只打包 main 应用模块(连带编译它依赖的模块),跳过测试,加速构建
RUN mvn \
-f pom.xml clean package \
-pl ai-rag-knowledge-app -am \
-DskipTests -B
# —— 第二阶段:运行时镜像 ——
FROM openjdk:17-jdk-slim
LABEL maintainer="smile"
# 可选:设置时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 把构建产物拷过来
COPY --from=builder \
/workspace/ai-rag-knowledge-app/target/ai-rag-knowledge-app.jar \
app.jar
# 暴露端口,按需改
EXPOSE 8095
ENTRYPOINT ["java", "-jar", "app.jar"]

View File

@ -0,0 +1,286 @@
25-07-28.16:50:31.794 [main ] WARN DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer -
Found multiple occurrences of org.json.JSONObject on the class path:
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/com/vaadin/external/google/android-json/0.0.20131108.vaadin1/android-json-0.0.20131108.vaadin1.jar!/org/json/JSONObject.class
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/org/json/json/20231013/json-20231013.jar!/org/json/JSONObject.class
You may wish to exclude one of them to ensure predictable runtime behavior
25-07-28.16:50:34.447 [main ] WARN OllamaApi - [500] Internal Server Error - {"error":"EOF"}
25-07-28.16:50:34.448 [main ] WARN PgVectorStore - Failed to obtain the embedding dimensions from the embedding client and fall backs to default:1536
java.lang.RuntimeException: [500] Internal Server Error - {"error":"EOF"}
at org.springframework.ai.ollama.api.OllamaApi$OllamaResponseErrorHandler.handleError(OllamaApi.java:78)
at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63)
at org.springframework.web.client.StatusHandler.lambda$fromErrorHandler$1(StatusHandler.java:71)
at org.springframework.web.client.StatusHandler.handle(StatusHandler.java:146)
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.applyStatusHandlers(DefaultRestClient.java:680)
at org.springframework.web.client.DefaultRestClient.readWithMessageConverters(DefaultRestClient.java:200)
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.readBody(DefaultRestClient.java:667)
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.body(DefaultRestClient.java:613)
at org.springframework.ai.ollama.api.OllamaApi.embeddings(OllamaApi.java:595)
at org.springframework.ai.ollama.OllamaEmbeddingClient.call(OllamaEmbeddingClient.java:101)
at org.springframework.ai.embedding.EmbeddingClient.embed(EmbeddingClient.java:56)
at org.springframework.ai.embedding.EmbeddingClient.embed(EmbeddingClient.java:39)
at org.springframework.ai.embedding.AbstractEmbeddingClient.dimensions(AbstractEmbeddingClient.java:56)
at org.springframework.ai.embedding.AbstractEmbeddingClient.dimensions(AbstractEmbeddingClient.java:78)
at org.springframework.ai.vectorstore.PgVectorStore.embeddingDimensions(PgVectorStore.java:367)
at org.springframework.ai.vectorstore.PgVectorStore.afterPropertiesSet(PgVectorStore.java:351)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1833)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1782)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1443)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1353)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:907)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:785)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:237)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1355)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1192)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:562)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:959)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:624)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:334)
at org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$3(SpringBootContextLoader.java:137)
at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58)
at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46)
at org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1454)
at org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:553)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:137)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:108)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:225)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:152)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:130)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:191)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:130)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:260)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)
25-07-28.16:50:36.909 [main ] WARN OllamaApi - [500] Internal Server Error - {"error":"EOF"}
25-07-28.16:50:46.757 [main ] WARN DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer -
Found multiple occurrences of org.json.JSONObject on the class path:
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/com/vaadin/external/google/android-json/0.0.20131108.vaadin1/android-json-0.0.20131108.vaadin1.jar!/org/json/JSONObject.class
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/org/json/json/20231013/json-20231013.jar!/org/json/JSONObject.class
You may wish to exclude one of them to ensure predictable runtime behavior
25-07-28.16:50:49.091 [main ] WARN OllamaApi - [500] Internal Server Error - {"error":"EOF"}
25-07-28.16:50:49.091 [main ] WARN PgVectorStore - Failed to obtain the embedding dimensions from the embedding client and fall backs to default:1536
java.lang.RuntimeException: [500] Internal Server Error - {"error":"EOF"}
at org.springframework.ai.ollama.api.OllamaApi$OllamaResponseErrorHandler.handleError(OllamaApi.java:78)
at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63)
at org.springframework.web.client.StatusHandler.lambda$fromErrorHandler$1(StatusHandler.java:71)
at org.springframework.web.client.StatusHandler.handle(StatusHandler.java:146)
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.applyStatusHandlers(DefaultRestClient.java:680)
at org.springframework.web.client.DefaultRestClient.readWithMessageConverters(DefaultRestClient.java:200)
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.readBody(DefaultRestClient.java:667)
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.body(DefaultRestClient.java:613)
at org.springframework.ai.ollama.api.OllamaApi.embeddings(OllamaApi.java:595)
at org.springframework.ai.ollama.OllamaEmbeddingClient.call(OllamaEmbeddingClient.java:101)
at org.springframework.ai.embedding.EmbeddingClient.embed(EmbeddingClient.java:56)
at org.springframework.ai.embedding.EmbeddingClient.embed(EmbeddingClient.java:39)
at org.springframework.ai.embedding.AbstractEmbeddingClient.dimensions(AbstractEmbeddingClient.java:56)
at org.springframework.ai.embedding.AbstractEmbeddingClient.dimensions(AbstractEmbeddingClient.java:78)
at org.springframework.ai.vectorstore.PgVectorStore.embeddingDimensions(PgVectorStore.java:367)
at org.springframework.ai.vectorstore.PgVectorStore.afterPropertiesSet(PgVectorStore.java:351)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1833)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1782)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1443)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1353)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:907)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:785)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:237)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1355)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1192)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:562)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:959)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:624)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:334)
at org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$3(SpringBootContextLoader.java:137)
at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58)
at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46)
at org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1454)
at org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:553)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:137)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:108)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:225)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:152)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:130)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:191)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:130)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:260)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)
25-07-28.16:50:52.300 [main ] WARN OllamaApi - [500] Internal Server Error - {"error":"EOF"}
25-07-28.18:45:40.910 [main ] WARN DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer -
Found multiple occurrences of org.json.JSONObject on the class path:
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/com/vaadin/external/google/android-json/0.0.20131108.vaadin1/android-json-0.0.20131108.vaadin1.jar!/org/json/JSONObject.class
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/org/json/json/20231013/json-20231013.jar!/org/json/JSONObject.class
You may wish to exclude one of them to ensure predictable runtime behavior
25-07-28.18:58:09.966 [main ] WARN DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer -
Found multiple occurrences of org.json.JSONObject on the class path:
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/com/vaadin/external/google/android-json/0.0.20131108.vaadin1/android-json-0.0.20131108.vaadin1.jar!/org/json/JSONObject.class
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/org/json/json/20231013/json-20231013.jar!/org/json/JSONObject.class
You may wish to exclude one of them to ensure predictable runtime behavior
25-07-28.18:58:32.158 [main ] WARN DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer -
Found multiple occurrences of org.json.JSONObject on the class path:
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/com/vaadin/external/google/android-json/0.0.20131108.vaadin1/android-json-0.0.20131108.vaadin1.jar!/org/json/JSONObject.class
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/org/json/json/20231013/json-20231013.jar!/org/json/JSONObject.class
You may wish to exclude one of them to ensure predictable runtime behavior
25-07-28.19:02:24.531 [main ] WARN DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer -
Found multiple occurrences of org.json.JSONObject on the class path:
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/com/vaadin/external/google/android-json/0.0.20131108.vaadin1/android-json-0.0.20131108.vaadin1.jar!/org/json/JSONObject.class
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/org/json/json/20231013/json-20231013.jar!/org/json/JSONObject.class
You may wish to exclude one of them to ensure predictable runtime behavior
25-07-28.19:03:08.882 [main ] WARN DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer -
Found multiple occurrences of org.json.JSONObject on the class path:
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/com/vaadin/external/google/android-json/0.0.20131108.vaadin1/android-json-0.0.20131108.vaadin1.jar!/org/json/JSONObject.class
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/org/json/json/20231013/json-20231013.jar!/org/json/JSONObject.class
You may wish to exclude one of them to ensure predictable runtime behavior
25-07-28.19:15:09.571 [main ] WARN DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer -
Found multiple occurrences of org.json.JSONObject on the class path:
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/com/vaadin/external/google/android-json/0.0.20131108.vaadin1/android-json-0.0.20131108.vaadin1.jar!/org/json/JSONObject.class
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/org/json/json/20231013/json-20231013.jar!/org/json/JSONObject.class
You may wish to exclude one of them to ensure predictable runtime behavior
25-07-28.19:16:19.489 [main ] WARN DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer -
Found multiple occurrences of org.json.JSONObject on the class path:
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/com/vaadin/external/google/android-json/0.0.20131108.vaadin1/android-json-0.0.20131108.vaadin1.jar!/org/json/JSONObject.class
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/org/json/json/20231013/json-20231013.jar!/org/json/JSONObject.class
You may wish to exclude one of them to ensure predictable runtime behavior
25-07-28.19:19:01.844 [main ] WARN DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer -
Found multiple occurrences of org.json.JSONObject on the class path:
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/com/vaadin/external/google/android-json/0.0.20131108.vaadin1/android-json-0.0.20131108.vaadin1.jar!/org/json/JSONObject.class
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/org/json/json/20231013/json-20231013.jar!/org/json/JSONObject.class
You may wish to exclude one of them to ensure predictable runtime behavior
25-07-28.19:20:07.900 [main ] WARN DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer -
Found multiple occurrences of org.json.JSONObject on the class path:
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/com/vaadin/external/google/android-json/0.0.20131108.vaadin1/android-json-0.0.20131108.vaadin1.jar!/org/json/JSONObject.class
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/org/json/json/20231013/json-20231013.jar!/org/json/JSONObject.class
You may wish to exclude one of them to ensure predictable runtime behavior
25-07-28.19:20:28.121 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\dev-ops\nginx\html\images\goods_info1.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:20:28.136 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\dev-ops\nginx\html\images\goods_info2.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:20:28.157 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\dev-ops\nginx\html\images\goods_info3.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:20:28.170 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\dev-ops\nginx\html\images\logo.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:20:28.182 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\dev-ops\nginx\html\images\placeholder.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:20:28.196 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\dev-ops\nginx\html\images\qrcode.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:22:04.635 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\tag\v1.0\nginx\html\images\goods_info1.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:22:04.651 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\tag\v1.0\nginx\html\images\goods_info2.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:22:04.664 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\tag\v1.0\nginx\html\images\goods_info3.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:22:04.680 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\tag\v1.0\nginx\html\images\qrcode.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:22:21.917 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\tag\v2.0\nginx\html\images\goods_info1.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:22:21.928 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\tag\v2.0\nginx\html\images\goods_info2.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:22:21.939 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\tag\v2.0\nginx\html\images\goods_info3.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:22:21.950 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\tag\v2.0\nginx\html\images\logo.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:22:21.960 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\tag\v2.0\nginx\html\images\placeholder.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:22:21.972 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\tag\v2.0\nginx\html\images\qrcode.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:22:41.574 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\group-buying-sys-app\src\main\resources\mybatis\config\mybatis-config.xml: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:23:12.982 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\tag\adapter\repository\package-info.java: org.apache.tika.exception.ZeroByteFileException: InputStream must have > 0 bytes
25-07-28.19:24:01.626 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\gateway\dto\package-info.java: org.apache.tika.exception.ZeroByteFileException: InputStream must have > 0 bytes

View File

@ -0,0 +1,776 @@
25-07-28.16:50:31.794 [main ] WARN DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer -
Found multiple occurrences of org.json.JSONObject on the class path:
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/com/vaadin/external/google/android-json/0.0.20131108.vaadin1/android-json-0.0.20131108.vaadin1.jar!/org/json/JSONObject.class
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/org/json/json/20231013/json-20231013.jar!/org/json/JSONObject.class
You may wish to exclude one of them to ensure predictable runtime behavior
25-07-28.16:50:31.816 [main ] INFO RAGTest - Starting RAGTest using Java 17.0.3.1 with PID 38616 (started by 张三 in D:\folder\ai-rag-knowledge\ai-rag-knowledge-app)
25-07-28.16:50:31.818 [main ] INFO RAGTest - The following 1 profile is active: "dev"
25-07-28.16:50:32.829 [main ] INFO RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
25-07-28.16:50:32.831 [main ] INFO RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
25-07-28.16:50:32.862 [main ] INFO RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 17 ms. Found 0 Redis repository interfaces.
25-07-28.16:50:33.890 [main ] INFO HikariDataSource - HikariCP - Starting...
25-07-28.16:50:34.098 [main ] INFO HikariPool - HikariCP - Added connection org.postgresql.jdbc.PgConnection@63326a3a
25-07-28.16:50:34.100 [main ] INFO HikariDataSource - HikariCP - Start completed.
25-07-28.16:50:34.447 [main ] WARN OllamaApi - [500] Internal Server Error - {"error":"EOF"}
25-07-28.16:50:34.448 [main ] WARN PgVectorStore - Failed to obtain the embedding dimensions from the embedding client and fall backs to default:1536
java.lang.RuntimeException: [500] Internal Server Error - {"error":"EOF"}
at org.springframework.ai.ollama.api.OllamaApi$OllamaResponseErrorHandler.handleError(OllamaApi.java:78)
at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63)
at org.springframework.web.client.StatusHandler.lambda$fromErrorHandler$1(StatusHandler.java:71)
at org.springframework.web.client.StatusHandler.handle(StatusHandler.java:146)
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.applyStatusHandlers(DefaultRestClient.java:680)
at org.springframework.web.client.DefaultRestClient.readWithMessageConverters(DefaultRestClient.java:200)
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.readBody(DefaultRestClient.java:667)
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.body(DefaultRestClient.java:613)
at org.springframework.ai.ollama.api.OllamaApi.embeddings(OllamaApi.java:595)
at org.springframework.ai.ollama.OllamaEmbeddingClient.call(OllamaEmbeddingClient.java:101)
at org.springframework.ai.embedding.EmbeddingClient.embed(EmbeddingClient.java:56)
at org.springframework.ai.embedding.EmbeddingClient.embed(EmbeddingClient.java:39)
at org.springframework.ai.embedding.AbstractEmbeddingClient.dimensions(AbstractEmbeddingClient.java:56)
at org.springframework.ai.embedding.AbstractEmbeddingClient.dimensions(AbstractEmbeddingClient.java:78)
at org.springframework.ai.vectorstore.PgVectorStore.embeddingDimensions(PgVectorStore.java:367)
at org.springframework.ai.vectorstore.PgVectorStore.afterPropertiesSet(PgVectorStore.java:351)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1833)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1782)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1443)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1353)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:907)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:785)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:237)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1355)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1192)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:562)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:959)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:624)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:334)
at org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$3(SpringBootContextLoader.java:137)
at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58)
at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46)
at org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1454)
at org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:553)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:137)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:108)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:225)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:152)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:130)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:191)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:130)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:260)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)
25-07-28.16:50:35.145 [main ] INFO Version - Redisson 3.44.0
25-07-28.16:50:35.386 [redisson-netty-1-4] INFO ConnectionsHolder - 1 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-28.16:50:35.414 [redisson-netty-1-13] INFO ConnectionsHolder - 5 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-28.16:50:36.199 [main ] INFO RAGTest - Started RAGTest in 4.88 seconds (process running for 5.721)
25-07-28.16:50:36.909 [main ] WARN OllamaApi - [500] Internal Server Error - {"error":"EOF"}
25-07-28.16:50:36.954 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown initiated...
25-07-28.16:50:36.958 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown completed.
25-07-28.16:50:46.757 [main ] WARN DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer -
Found multiple occurrences of org.json.JSONObject on the class path:
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/com/vaadin/external/google/android-json/0.0.20131108.vaadin1/android-json-0.0.20131108.vaadin1.jar!/org/json/JSONObject.class
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/org/json/json/20231013/json-20231013.jar!/org/json/JSONObject.class
You may wish to exclude one of them to ensure predictable runtime behavior
25-07-28.16:50:46.779 [main ] INFO RAGTest - Starting RAGTest using Java 17.0.3.1 with PID 46288 (started by 张三 in D:\folder\ai-rag-knowledge\ai-rag-knowledge-app)
25-07-28.16:50:46.780 [main ] INFO RAGTest - The following 1 profile is active: "dev"
25-07-28.16:50:47.760 [main ] INFO RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
25-07-28.16:50:47.763 [main ] INFO RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
25-07-28.16:50:47.786 [main ] INFO RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 12 ms. Found 0 Redis repository interfaces.
25-07-28.16:50:48.689 [main ] INFO HikariDataSource - HikariCP - Starting...
25-07-28.16:50:48.847 [main ] INFO HikariPool - HikariCP - Added connection org.postgresql.jdbc.PgConnection@6de84336
25-07-28.16:50:48.848 [main ] INFO HikariDataSource - HikariCP - Start completed.
25-07-28.16:50:49.091 [main ] WARN OllamaApi - [500] Internal Server Error - {"error":"EOF"}
25-07-28.16:50:49.091 [main ] WARN PgVectorStore - Failed to obtain the embedding dimensions from the embedding client and fall backs to default:1536
java.lang.RuntimeException: [500] Internal Server Error - {"error":"EOF"}
at org.springframework.ai.ollama.api.OllamaApi$OllamaResponseErrorHandler.handleError(OllamaApi.java:78)
at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63)
at org.springframework.web.client.StatusHandler.lambda$fromErrorHandler$1(StatusHandler.java:71)
at org.springframework.web.client.StatusHandler.handle(StatusHandler.java:146)
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.applyStatusHandlers(DefaultRestClient.java:680)
at org.springframework.web.client.DefaultRestClient.readWithMessageConverters(DefaultRestClient.java:200)
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.readBody(DefaultRestClient.java:667)
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.body(DefaultRestClient.java:613)
at org.springframework.ai.ollama.api.OllamaApi.embeddings(OllamaApi.java:595)
at org.springframework.ai.ollama.OllamaEmbeddingClient.call(OllamaEmbeddingClient.java:101)
at org.springframework.ai.embedding.EmbeddingClient.embed(EmbeddingClient.java:56)
at org.springframework.ai.embedding.EmbeddingClient.embed(EmbeddingClient.java:39)
at org.springframework.ai.embedding.AbstractEmbeddingClient.dimensions(AbstractEmbeddingClient.java:56)
at org.springframework.ai.embedding.AbstractEmbeddingClient.dimensions(AbstractEmbeddingClient.java:78)
at org.springframework.ai.vectorstore.PgVectorStore.embeddingDimensions(PgVectorStore.java:367)
at org.springframework.ai.vectorstore.PgVectorStore.afterPropertiesSet(PgVectorStore.java:351)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1833)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1782)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1443)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1353)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:907)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:785)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:237)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1355)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1192)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:562)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:959)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:624)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:334)
at org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$3(SpringBootContextLoader.java:137)
at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58)
at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46)
at org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1454)
at org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:553)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:137)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:108)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:225)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:152)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:130)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:191)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:130)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:260)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)
25-07-28.16:50:49.825 [main ] INFO Version - Redisson 3.44.0
25-07-28.16:50:50.066 [redisson-netty-1-4] INFO ConnectionsHolder - 1 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-28.16:50:50.086 [redisson-netty-1-13] INFO ConnectionsHolder - 5 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-28.16:50:51.228 [main ] INFO RAGTest - Started RAGTest in 4.879 seconds (process running for 5.777)
25-07-28.16:50:52.300 [main ] WARN OllamaApi - [500] Internal Server Error - {"error":"EOF"}
25-07-28.16:50:52.343 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown initiated...
25-07-28.16:50:52.346 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown completed.
25-07-28.18:45:40.910 [main ] WARN DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer -
Found multiple occurrences of org.json.JSONObject on the class path:
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/com/vaadin/external/google/android-json/0.0.20131108.vaadin1/android-json-0.0.20131108.vaadin1.jar!/org/json/JSONObject.class
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/org/json/json/20231013/json-20231013.jar!/org/json/JSONObject.class
You may wish to exclude one of them to ensure predictable runtime behavior
25-07-28.18:45:40.934 [main ] INFO RAGTest - Starting RAGTest using Java 17.0.3.1 with PID 49012 (started by 张三 in D:\folder\ai-rag-knowledge\ai-rag-knowledge-app)
25-07-28.18:45:40.935 [main ] INFO RAGTest - The following 1 profile is active: "dev"
25-07-28.18:45:41.671 [main ] INFO RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
25-07-28.18:45:41.674 [main ] INFO RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
25-07-28.18:45:41.697 [main ] INFO RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 12 ms. Found 0 Redis repository interfaces.
25-07-28.18:45:42.514 [main ] INFO HikariDataSource - HikariCP - Starting...
25-07-28.18:45:42.687 [main ] INFO HikariPool - HikariCP - Added connection org.postgresql.jdbc.PgConnection@7eee6c13
25-07-28.18:45:42.690 [main ] INFO HikariDataSource - HikariCP - Start completed.
25-07-28.18:45:43.459 [main ] INFO Version - Redisson 3.44.0
25-07-28.18:45:43.707 [redisson-netty-1-4] INFO ConnectionsHolder - 1 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-28.18:45:43.727 [redisson-netty-1-13] INFO ConnectionsHolder - 5 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-28.18:45:44.760 [main ] INFO RAGTest - Started RAGTest in 4.236 seconds (process running for 5.012)
25-07-28.18:45:45.955 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown initiated...
25-07-28.18:45:45.958 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown completed.
25-07-28.18:58:09.966 [main ] WARN DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer -
Found multiple occurrences of org.json.JSONObject on the class path:
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/com/vaadin/external/google/android-json/0.0.20131108.vaadin1/android-json-0.0.20131108.vaadin1.jar!/org/json/JSONObject.class
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/org/json/json/20231013/json-20231013.jar!/org/json/JSONObject.class
You may wish to exclude one of them to ensure predictable runtime behavior
25-07-28.18:58:09.985 [main ] INFO RAGTest - Starting RAGTest using Java 17.0.3.1 with PID 27948 (started by 张三 in D:\folder\ai-rag-knowledge\ai-rag-knowledge-app)
25-07-28.18:58:09.989 [main ] INFO RAGTest - The following 1 profile is active: "dev"
25-07-28.18:58:10.742 [main ] INFO RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
25-07-28.18:58:10.745 [main ] INFO RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
25-07-28.18:58:10.765 [main ] INFO RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 10 ms. Found 0 Redis repository interfaces.
25-07-28.18:58:11.540 [main ] INFO HikariDataSource - HikariCP - Starting...
25-07-28.18:58:11.653 [main ] INFO HikariPool - HikariCP - Added connection org.postgresql.jdbc.PgConnection@8432469
25-07-28.18:58:11.654 [main ] INFO HikariDataSource - HikariCP - Start completed.
25-07-28.18:58:14.463 [main ] INFO Version - Redisson 3.44.0
25-07-28.18:58:14.709 [redisson-netty-1-4] INFO ConnectionsHolder - 1 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-28.18:58:14.726 [redisson-netty-1-13] INFO ConnectionsHolder - 5 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-28.18:58:15.682 [main ] INFO RAGTest - Started RAGTest in 6.128 seconds (process running for 6.955)
25-07-28.18:58:16.786 [main ] INFO RAGTest - 上传完成
25-07-28.18:58:16.810 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown initiated...
25-07-28.18:58:16.813 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown completed.
25-07-28.18:58:32.158 [main ] WARN DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer -
Found multiple occurrences of org.json.JSONObject on the class path:
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/com/vaadin/external/google/android-json/0.0.20131108.vaadin1/android-json-0.0.20131108.vaadin1.jar!/org/json/JSONObject.class
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/org/json/json/20231013/json-20231013.jar!/org/json/JSONObject.class
You may wish to exclude one of them to ensure predictable runtime behavior
25-07-28.18:58:32.180 [main ] INFO RAGTest - Starting RAGTest using Java 17.0.3.1 with PID 42656 (started by 张三 in D:\folder\ai-rag-knowledge\ai-rag-knowledge-app)
25-07-28.18:58:32.181 [main ] INFO RAGTest - The following 1 profile is active: "dev"
25-07-28.18:58:33.024 [main ] INFO RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
25-07-28.18:58:33.027 [main ] INFO RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
25-07-28.18:58:33.052 [main ] INFO RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 14 ms. Found 0 Redis repository interfaces.
25-07-28.18:58:33.873 [main ] INFO HikariDataSource - HikariCP - Starting...
25-07-28.18:58:34.116 [main ] INFO HikariPool - HikariCP - Added connection org.postgresql.jdbc.PgConnection@60c96eb4
25-07-28.18:58:34.118 [main ] INFO HikariDataSource - HikariCP - Start completed.
25-07-28.18:58:34.845 [main ] INFO Version - Redisson 3.44.0
25-07-28.18:58:35.088 [redisson-netty-1-4] INFO ConnectionsHolder - 1 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-28.18:58:35.111 [redisson-netty-1-13] INFO ConnectionsHolder - 5 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-28.18:58:36.084 [main ] INFO RAGTest - Started RAGTest in 4.34 seconds (process running for 5.153)
25-07-28.18:58:53.877 [main ] INFO RAGTest - 测试结果:{"metadata":{"promptMetadata":{},"rateLimit":{"requestsLimit":0,"requestsRemaining":0,"requestsReset":{"nano":0,"negative":false,"seconds":0,"units":["SECONDS","NANOS"],"zero":true},"tokensLimit":0,"tokensRemaining":0,"tokensReset":{"$ref":"$.metadata.rateLimit.requestsReset"}},"usage":{"generationTokens":0,"promptTokens":0,"totalTokens":0}},"result":{"metadata":{"contentFilterMetadata":{"generationTokens":210,"promptTokens":76,"totalTokens":286},"finishReason":"unknown"},"output":{"content":"<think>\n嗯好的。用户给了我一段文本并让我以我已知的信息来回答同时必须用中文回复。如果不确定就简单说明就可以了还要确保最后的回答是中文的。\n\n首先用户提供的信息是“王大瓜 2000年出生”。这句可能来自“ DOCUMENTS”里的内容但原文没有显示出来。我的任务就是根据现有的信息来回答这个问题。\n\n用户的问题是“王大瓜哪年出生”看起来是在询问王大瓜的出生年份。我需要准确地回答但同时不能超出已知的信息范围也就是2000年。如果不确定可能需要告诉用户我没有相关的知识或者只能给出当前知道的信息。\n\n所以我会回复“王大瓜哪年出生我只知道他出生在2000年。” 这样既准确又符合要求,同时没有使用未知信息。\n</think>\n\n王大瓜哪年出生我只知道他出生在2000年。","media":[],"messageType":"ASSISTANT","properties":{}}},"results":[{"$ref":"$.metadata.rateLimit.result"}]}
25-07-28.18:58:53.906 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown initiated...
25-07-28.18:58:53.909 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown completed.
25-07-28.19:02:24.531 [main ] WARN DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer -
Found multiple occurrences of org.json.JSONObject on the class path:
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/com/vaadin/external/google/android-json/0.0.20131108.vaadin1/android-json-0.0.20131108.vaadin1.jar!/org/json/JSONObject.class
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/org/json/json/20231013/json-20231013.jar!/org/json/JSONObject.class
You may wish to exclude one of them to ensure predictable runtime behavior
25-07-28.19:02:24.551 [main ] INFO RAGTest - Starting RAGTest using Java 17.0.3.1 with PID 5592 (started by 张三 in D:\folder\ai-rag-knowledge\ai-rag-knowledge-app)
25-07-28.19:02:24.552 [main ] INFO RAGTest - The following 1 profile is active: "dev"
25-07-28.19:02:25.366 [main ] INFO RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
25-07-28.19:02:25.369 [main ] INFO RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
25-07-28.19:02:25.392 [main ] INFO RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 12 ms. Found 0 Redis repository interfaces.
25-07-28.19:02:26.217 [main ] INFO HikariDataSource - HikariCP - Starting...
25-07-28.19:02:26.336 [main ] INFO HikariPool - HikariCP - Added connection org.postgresql.jdbc.PgConnection@be6d228
25-07-28.19:02:26.337 [main ] INFO HikariDataSource - HikariCP - Start completed.
25-07-28.19:02:27.117 [main ] INFO Version - Redisson 3.44.0
25-07-28.19:02:27.389 [redisson-netty-1-4] INFO ConnectionsHolder - 1 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-28.19:02:27.407 [redisson-netty-1-13] INFO ConnectionsHolder - 5 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-28.19:02:28.286 [main ] INFO RAGTest - Started RAGTest in 4.192 seconds (process running for 5.061)
25-07-28.19:02:35.215 [main ] INFO RAGTest - 测试结果:{"metadata":{"promptMetadata":{},"rateLimit":{"requestsLimit":0,"requestsRemaining":0,"requestsReset":{"nano":0,"negative":false,"seconds":0,"units":["SECONDS","NANOS"],"zero":true},"tokensLimit":0,"tokensRemaining":0,"tokensReset":{"$ref":"$.metadata.rateLimit.requestsReset"}},"usage":{"generationTokens":0,"promptTokens":0,"totalTokens":0}},"result":{"metadata":{"contentFilterMetadata":{"generationTokens":241,"promptTokens":76,"totalTokens":317},"finishReason":"unknown"},"output":{"content":"<think>\n嗯用户给了一个查询是关于“王大瓜”和“2000年出生”的。我得先仔细看看文档内容。文档里明确写着“王大瓜 2000年出生”所以这是事实性的信息。\n\n用户的问题似乎是询问“王大瓜”在哪一年出生的但其实根据提供的信息我知道是2000年出生的。那我该怎么处理呢因为用户之前问了类似的问题可能需要按照同样的流程来回答。\n\n首先我要确定用户是否知道这一点。根据文档确实已知王大瓜2000年出生。所以用户或许是在测试我的知识或者确认信息。\n\n接下来我应该回复“王大瓜是哪年出生的”然后引导用户提供更多的信息比如出生地或其他相关数据以便更准确地回答。这样既符合用户的请求又保持了专业性同时确保他们能得到有用的信息。\n\n最后我要检查一下回应是否在中文并且结构清晰没有语法错误。确保回复直接对应用户的问题而不仅仅是为了填充空白。\n</think>\n\n王大瓜 是哪年出生的?","media":[],"messageType":"ASSISTANT","properties":{}}},"results":[{"$ref":"$.metadata.rateLimit.result"}]}
25-07-28.19:02:35.242 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown initiated...
25-07-28.19:02:35.245 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown completed.
25-07-28.19:03:08.882 [main ] WARN DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer -
Found multiple occurrences of org.json.JSONObject on the class path:
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/com/vaadin/external/google/android-json/0.0.20131108.vaadin1/android-json-0.0.20131108.vaadin1.jar!/org/json/JSONObject.class
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/org/json/json/20231013/json-20231013.jar!/org/json/JSONObject.class
You may wish to exclude one of them to ensure predictable runtime behavior
25-07-28.19:03:08.902 [main ] INFO RAGTest - Starting RAGTest using Java 17.0.3.1 with PID 35624 (started by 张三 in D:\folder\ai-rag-knowledge\ai-rag-knowledge-app)
25-07-28.19:03:08.903 [main ] INFO RAGTest - The following 1 profile is active: "dev"
25-07-28.19:03:09.893 [main ] INFO RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
25-07-28.19:03:09.896 [main ] INFO RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
25-07-28.19:03:09.923 [main ] INFO RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 12 ms. Found 0 Redis repository interfaces.
25-07-28.19:03:10.775 [main ] INFO HikariDataSource - HikariCP - Starting...
25-07-28.19:03:11.047 [main ] INFO HikariPool - HikariCP - Added connection org.postgresql.jdbc.PgConnection@2f86f9cf
25-07-28.19:03:11.051 [main ] INFO HikariDataSource - HikariCP - Start completed.
25-07-28.19:03:11.963 [main ] INFO Version - Redisson 3.44.0
25-07-28.19:03:12.205 [redisson-netty-1-4] INFO ConnectionsHolder - 1 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-28.19:03:12.227 [redisson-netty-1-13] INFO ConnectionsHolder - 5 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-28.19:03:13.364 [main ] INFO RAGTest - Started RAGTest in 4.899 seconds (process running for 5.798)
25-07-28.19:03:20.516 [main ] INFO RAGTest - 测试结果:{"metadata":{"promptMetadata":{},"rateLimit":{"requestsLimit":0,"requestsRemaining":0,"requestsReset":{"nano":0,"negative":false,"seconds":0,"units":["SECONDS","NANOS"],"zero":true},"tokensLimit":0,"tokensRemaining":0,"tokensReset":{"$ref":"$.metadata.rateLimit.requestsReset"}},"usage":{"generationTokens":0,"promptTokens":0,"totalTokens":0}},"result":{"metadata":{"contentFilterMetadata":{"generationTokens":245,"promptTokens":76,"totalTokens":321},"finishReason":"unknown"},"output":{"content":"<think>\n好我现在要解决用户的问题“王大瓜 2000年出生”。用户提供了“王大瓜”让我补充具体信息。首先我需要确认王大瓜的国籍和年龄。\n\n根据提供的文档“王大瓜”是1985年的运动员他出生于1967年现在30岁了。那问题中问的是他的出生年份也就是2000年这显然不正确因为王大瓜已经30岁了。\n\n接着我要检查是否有其他相关信息可以补充。比如是否还有其他来源提到王大瓜的年龄或出生年份文档里没有更多细节所以只能基于现有的信息来回答。\n\n另外我需要确保我的回复符合用户的要求用中文同时作为如果 knew 这样处理的答案。但在这里,因为已知信息不足,无法提供额外的解答。\n\n最后确认一下是否符合要求确保只给出出生年份和王大瓜的国籍并且在不遗漏重要信息的情况下回答。\n</think>\n\n王大瓜 1967 年出生。 \n如果需要进一步解释请提供更多上下文信息","media":[],"messageType":"ASSISTANT","properties":{}}},"results":[{"$ref":"$.metadata.rateLimit.result"}]}
25-07-28.19:03:20.539 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown initiated...
25-07-28.19:03:20.541 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown completed.
25-07-28.19:15:09.571 [main ] WARN DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer -
Found multiple occurrences of org.json.JSONObject on the class path:
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/com/vaadin/external/google/android-json/0.0.20131108.vaadin1/android-json-0.0.20131108.vaadin1.jar!/org/json/JSONObject.class
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/org/json/json/20231013/json-20231013.jar!/org/json/JSONObject.class
You may wish to exclude one of them to ensure predictable runtime behavior
25-07-28.19:15:09.586 [main ] INFO JGitTest - Starting JGitTest using Java 17.0.3.1 with PID 40180 (started by 张三 in D:\folder\ai-rag-knowledge\ai-rag-knowledge-app)
25-07-28.19:15:09.589 [main ] INFO JGitTest - The following 1 profile is active: "dev"
25-07-28.19:15:10.348 [main ] INFO RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
25-07-28.19:15:10.350 [main ] INFO RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
25-07-28.19:15:10.379 [main ] INFO RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 16 ms. Found 0 Redis repository interfaces.
25-07-28.19:15:11.124 [main ] INFO HikariDataSource - HikariCP - Starting...
25-07-28.19:15:11.246 [main ] INFO HikariPool - HikariCP - Added connection org.postgresql.jdbc.PgConnection@44864536
25-07-28.19:15:11.247 [main ] INFO HikariDataSource - HikariCP - Start completed.
25-07-28.19:15:14.004 [main ] INFO Version - Redisson 3.44.0
25-07-28.19:15:14.243 [redisson-netty-1-4] INFO ConnectionsHolder - 1 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-28.19:15:14.267 [redisson-netty-1-13] INFO ConnectionsHolder - 5 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-28.19:15:15.297 [main ] INFO JGitTest - Started JGitTest in 6.135 seconds (process running for 7.037)
25-07-28.19:15:15.821 [main ] INFO JGitTest - 克隆路径D:\folder\ai-rag-knowledge\ai-rag-knowledge-app\.\cloned-repo
25-07-28.19:15:21.875 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown initiated...
25-07-28.19:15:21.878 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown completed.
25-07-28.19:16:19.489 [main ] WARN DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer -
Found multiple occurrences of org.json.JSONObject on the class path:
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/com/vaadin/external/google/android-json/0.0.20131108.vaadin1/android-json-0.0.20131108.vaadin1.jar!/org/json/JSONObject.class
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/org/json/json/20231013/json-20231013.jar!/org/json/JSONObject.class
You may wish to exclude one of them to ensure predictable runtime behavior
25-07-28.19:16:19.510 [main ] INFO JGitTest - Starting JGitTest using Java 17.0.3.1 with PID 35312 (started by 张三 in D:\folder\ai-rag-knowledge\ai-rag-knowledge-app)
25-07-28.19:16:19.512 [main ] INFO JGitTest - The following 1 profile is active: "dev"
25-07-28.19:16:20.312 [main ] INFO RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
25-07-28.19:16:20.315 [main ] INFO RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
25-07-28.19:16:20.338 [main ] INFO RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 11 ms. Found 0 Redis repository interfaces.
25-07-28.19:16:21.122 [main ] INFO HikariDataSource - HikariCP - Starting...
25-07-28.19:16:21.314 [main ] INFO HikariPool - HikariCP - Added connection org.postgresql.jdbc.PgConnection@45d7495e
25-07-28.19:16:21.316 [main ] INFO HikariDataSource - HikariCP - Start completed.
25-07-28.19:16:22.038 [main ] INFO Version - Redisson 3.44.0
25-07-28.19:16:22.265 [redisson-netty-1-4] INFO ConnectionsHolder - 1 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-28.19:16:22.286 [redisson-netty-1-13] INFO ConnectionsHolder - 5 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-28.19:16:23.249 [main ] INFO JGitTest - Started JGitTest in 4.194 seconds (process running for 5.057)
25-07-28.19:16:23.770 [main ] INFO JGitTest - 文件路径:.\cloned-repo\.git\config
25-07-28.19:16:24.421 [main ] INFO JGitTest - 文件路径:.\cloned-repo\.git\FETCH_HEAD
25-07-28.19:16:24.547 [main ] INFO JGitTest - 文件路径:.\cloned-repo\.git\HEAD
25-07-28.19:16:24.646 [main ] INFO JGitTest - 文件路径:.\cloned-repo\.git\index
25-07-28.19:16:24.689 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown initiated...
25-07-28.19:16:24.691 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown completed.
25-07-28.19:19:01.844 [main ] WARN DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer -
Found multiple occurrences of org.json.JSONObject on the class path:
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/com/vaadin/external/google/android-json/0.0.20131108.vaadin1/android-json-0.0.20131108.vaadin1.jar!/org/json/JSONObject.class
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/org/json/json/20231013/json-20231013.jar!/org/json/JSONObject.class
You may wish to exclude one of them to ensure predictable runtime behavior
25-07-28.19:19:01.861 [main ] INFO JGitTest - Starting JGitTest using Java 17.0.3.1 with PID 48140 (started by 张三 in D:\folder\ai-rag-knowledge\ai-rag-knowledge-app)
25-07-28.19:19:01.863 [main ] INFO JGitTest - The following 1 profile is active: "dev"
25-07-28.19:19:02.640 [main ] INFO RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
25-07-28.19:19:02.642 [main ] INFO RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
25-07-28.19:19:02.666 [main ] INFO RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 12 ms. Found 0 Redis repository interfaces.
25-07-28.19:19:03.434 [main ] INFO HikariDataSource - HikariCP - Starting...
25-07-28.19:19:03.590 [main ] INFO HikariPool - HikariCP - Added connection org.postgresql.jdbc.PgConnection@6ea66c33
25-07-28.19:19:03.593 [main ] INFO HikariDataSource - HikariCP - Start completed.
25-07-28.19:19:04.282 [main ] INFO Version - Redisson 3.44.0
25-07-28.19:19:04.493 [redisson-netty-1-5] INFO ConnectionsHolder - 1 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-28.19:19:04.517 [redisson-netty-1-13] INFO ConnectionsHolder - 5 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-28.19:19:05.596 [main ] INFO JGitTest - Started JGitTest in 4.22 seconds (process running for 5.209)
25-07-28.19:19:06.146 [main ] INFO JGitTest - 文件路径:.\cloned-repo\.gitignore
25-07-28.19:19:06.611 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown initiated...
25-07-28.19:19:06.613 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown completed.
25-07-28.19:20:07.900 [main ] WARN DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer -
Found multiple occurrences of org.json.JSONObject on the class path:
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/com/vaadin/external/google/android-json/0.0.20131108.vaadin1/android-json-0.0.20131108.vaadin1.jar!/org/json/JSONObject.class
jar:file:/D:/folder/study/apache-maven-3.8.4/mvn_repo/org/json/json/20231013/json-20231013.jar!/org/json/JSONObject.class
You may wish to exclude one of them to ensure predictable runtime behavior
25-07-28.19:20:07.916 [main ] INFO JGitTest - Starting JGitTest using Java 17.0.3.1 with PID 50572 (started by 张三 in D:\folder\ai-rag-knowledge\ai-rag-knowledge-app)
25-07-28.19:20:07.918 [main ] INFO JGitTest - The following 1 profile is active: "dev"
25-07-28.19:20:08.786 [main ] INFO RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
25-07-28.19:20:08.789 [main ] INFO RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
25-07-28.19:20:08.813 [main ] INFO RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 11 ms. Found 0 Redis repository interfaces.
25-07-28.19:20:09.715 [main ] INFO HikariDataSource - HikariCP - Starting...
25-07-28.19:20:09.873 [main ] INFO HikariPool - HikariCP - Added connection org.postgresql.jdbc.PgConnection@59b447a4
25-07-28.19:20:09.874 [main ] INFO HikariDataSource - HikariCP - Start completed.
25-07-28.19:20:10.686 [main ] INFO Version - Redisson 3.44.0
25-07-28.19:20:10.957 [redisson-netty-1-4] INFO ConnectionsHolder - 1 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-28.19:20:10.981 [redisson-netty-1-13] INFO ConnectionsHolder - 5 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-28.19:20:12.113 [main ] INFO JGitTest - Started JGitTest in 4.636 seconds (process running for 5.531)
25-07-28.19:20:12.748 [main ] INFO JGitTest - 文件路径:.\cloned-repo\.gitignore
25-07-28.19:20:13.648 [main ] INFO JGitTest - 文件路径:.\cloned-repo\.mvn\settings.xml
25-07-28.19:20:13.908 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\app\start.sh
25-07-28.19:20:14.127 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\app\stop.sh
25-07-28.19:20:14.190 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\docker-compose-app.yml
25-07-28.19:20:14.712 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\docker-compose-elk.yml
25-07-28.19:20:15.464 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\docker-compose-environment.yml
25-07-28.19:20:16.375 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\kibana\config\kibana.yml
25-07-28.19:20:16.546 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\logstash\logstash.conf
25-07-28.19:20:16.698 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\mysql\my.cnf
25-07-28.19:20:16.962 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\mysql\sql\0725group_buying_sys.sql
25-07-28.19:20:17.015 [main ] INFO TextSplitter - Splitting up document into 8 chunks.
25-07-28.19:20:24.837 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\nginx\html\css\index.css
25-07-28.19:20:24.855 [main ] INFO TextSplitter - Splitting up document into 2 chunks.
25-07-28.19:20:26.957 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\nginx\html\css\login.css
25-07-28.19:20:28.068 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\nginx\html\images\goods_info1.png
25-07-28.19:20:28.121 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\dev-ops\nginx\html\images\goods_info1.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:20:28.121 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\nginx\html\images\goods_info2.png
25-07-28.19:20:28.136 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\dev-ops\nginx\html\images\goods_info2.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:20:28.137 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\nginx\html\images\goods_info3.png
25-07-28.19:20:28.157 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\dev-ops\nginx\html\images\goods_info3.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:20:28.158 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\nginx\html\images\logo.png
25-07-28.19:20:28.170 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\dev-ops\nginx\html\images\logo.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:20:28.171 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\nginx\html\images\placeholder.png
25-07-28.19:20:28.182 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\dev-ops\nginx\html\images\placeholder.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:20:28.182 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\nginx\html\images\qrcode.png
25-07-28.19:20:28.196 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\dev-ops\nginx\html\images\qrcode.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:20:28.196 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\nginx\html\index.html
25-07-28.19:20:28.400 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\nginx\html\js\index.js
25-07-28.19:20:28.421 [main ] INFO TextSplitter - Splitting up document into 5 chunks.
25-07-28.19:20:33.643 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\nginx\html\js\login.js
25-07-28.19:20:34.830 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\nginx\html\login.html
25-07-28.19:20:34.943 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\rabbitmq\enabled_plugins
25-07-28.19:20:35.003 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\sql-back\0619group_buying_sys.sql
25-07-28.19:20:35.015 [main ] INFO TextSplitter - Splitting up document into 2 chunks.
25-07-28.19:20:36.499 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\sql-back\0622group_buying_sys.sql
25-07-28.19:20:36.513 [main ] INFO TextSplitter - Splitting up document into 2 chunks.
25-07-28.19:20:38.259 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\sql-back\0625group_buying_sys.sql
25-07-28.19:20:38.272 [main ] INFO TextSplitter - Splitting up document into 3 chunks.
25-07-28.19:20:40.236 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\sql-back\0628group_buying_sys.sql
25-07-28.19:20:40.252 [main ] INFO TextSplitter - Splitting up document into 5 chunks.
25-07-28.19:20:45.100 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\sql-back\0630group_buying_sys.sql
25-07-28.19:20:45.115 [main ] INFO TextSplitter - Splitting up document into 7 chunks.
25-07-28.19:20:51.666 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\sql-back\0702group_buying_sys.sql
25-07-28.19:20:51.681 [main ] INFO TextSplitter - Splitting up document into 7 chunks.
25-07-28.19:20:58.693 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\sql-back\0704group_buying_sys.sql
25-07-28.19:20:58.708 [main ] INFO TextSplitter - Splitting up document into 8 chunks.
25-07-28.19:21:06.339 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\sql-back\0705group_buying_sys.sql
25-07-28.19:21:06.354 [main ] INFO TextSplitter - Splitting up document into 8 chunks.
25-07-28.19:21:14.782 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\sql-back\0707group_buying_sys.sql
25-07-28.19:21:14.800 [main ] INFO TextSplitter - Splitting up document into 10 chunks.
25-07-28.19:21:25.076 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\sql-back\0715group_buying_sys.sql
25-07-28.19:21:25.113 [main ] INFO TextSplitter - Splitting up document into 8 chunks.
25-07-28.19:21:32.847 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\sql-back\0716group_buying_sys.sql
25-07-28.19:21:32.893 [main ] INFO TextSplitter - Splitting up document into 9 chunks.
25-07-28.19:21:42.224 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\dev-ops\sql-back\0719group_buying_sys.sql
25-07-28.19:21:42.257 [main ] INFO TextSplitter - Splitting up document into 8 chunks.
25-07-28.19:21:50.212 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v1.0\docker-compose-app-v1.0.yml
25-07-28.19:21:50.223 [main ] INFO TextSplitter - Splitting up document into 2 chunks.
25-07-28.19:21:51.322 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v1.0\mysql\my.cnf
25-07-28.19:21:51.636 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v1.0\mysql\sql\0707group_buying_sys.sql
25-07-28.19:21:51.654 [main ] INFO TextSplitter - Splitting up document into 10 chunks.
25-07-28.19:22:01.694 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v1.0\nginx\html\css\index.css
25-07-28.19:22:01.707 [main ] INFO TextSplitter - Splitting up document into 2 chunks.
25-07-28.19:22:04.030 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v1.0\nginx\html\css\login.css
25-07-28.19:22:04.620 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v1.0\nginx\html\images\goods_info1.png
25-07-28.19:22:04.635 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\tag\v1.0\nginx\html\images\goods_info1.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:22:04.636 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v1.0\nginx\html\images\goods_info2.png
25-07-28.19:22:04.651 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\tag\v1.0\nginx\html\images\goods_info2.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:22:04.651 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v1.0\nginx\html\images\goods_info3.png
25-07-28.19:22:04.664 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\tag\v1.0\nginx\html\images\goods_info3.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:22:04.665 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v1.0\nginx\html\images\qrcode.png
25-07-28.19:22:04.680 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\tag\v1.0\nginx\html\images\qrcode.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:22:04.680 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v1.0\nginx\html\index.html
25-07-28.19:22:04.806 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v1.0\nginx\html\js\index.js
25-07-28.19:22:04.821 [main ] INFO TextSplitter - Splitting up document into 3 chunks.
25-07-28.19:22:08.606 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v1.0\nginx\html\js\login.js
25-07-28.19:22:08.999 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v1.0\nginx\html\login.html
25-07-28.19:22:09.106 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v2.0\docker-compose-app-v2.0.yml
25-07-28.19:22:09.119 [main ] INFO TextSplitter - Splitting up document into 2 chunks.
25-07-28.19:22:10.061 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v2.0\mysql\my.cnf
25-07-28.19:22:10.295 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v2.0\mysql\sql\group_buying_sys.sql
25-07-28.19:22:10.312 [main ] INFO TextSplitter - Splitting up document into 7 chunks.
25-07-28.19:22:17.387 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v2.0\mysql\sql\pay-mall.sql
25-07-28.19:22:18.316 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v2.0\nginx\conf\nginx.conf
25-07-28.19:22:18.771 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v2.0\nginx\html\css\index.css
25-07-28.19:22:18.783 [main ] INFO TextSplitter - Splitting up document into 2 chunks.
25-07-28.19:22:20.829 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v2.0\nginx\html\css\login.css
25-07-28.19:22:21.903 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v2.0\nginx\html\images\goods_info1.png
25-07-28.19:22:21.917 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\tag\v2.0\nginx\html\images\goods_info1.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:22:21.917 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v2.0\nginx\html\images\goods_info2.png
25-07-28.19:22:21.928 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\tag\v2.0\nginx\html\images\goods_info2.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:22:21.929 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v2.0\nginx\html\images\goods_info3.png
25-07-28.19:22:21.939 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\tag\v2.0\nginx\html\images\goods_info3.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:22:21.939 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v2.0\nginx\html\images\logo.png
25-07-28.19:22:21.950 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\tag\v2.0\nginx\html\images\logo.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:22:21.950 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v2.0\nginx\html\images\placeholder.png
25-07-28.19:22:21.960 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\tag\v2.0\nginx\html\images\placeholder.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:22:21.960 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v2.0\nginx\html\images\qrcode.png
25-07-28.19:22:21.972 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\docs\tag\v2.0\nginx\html\images\qrcode.png: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:22:21.972 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v2.0\nginx\html\index.html
25-07-28.19:22:22.111 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v2.0\nginx\html\js\index.js
25-07-28.19:22:22.127 [main ] INFO TextSplitter - Splitting up document into 5 chunks.
25-07-28.19:22:27.453 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v2.0\nginx\html\js\login.js
25-07-28.19:22:28.616 [main ] INFO JGitTest - 文件路径:.\cloned-repo\docs\tag\v2.0\nginx\html\login.html
25-07-28.19:22:28.709 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-api\pom.xml
25-07-28.19:22:28.839 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-api\src\main\java\edu\whut\api\dto\GoodsMarketRequestDTO.java
25-07-28.19:22:29.038 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-api\src\main\java\edu\whut\api\dto\GoodsMarketResponseDTO.java
25-07-28.19:22:29.963 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-api\src\main\java\edu\whut\api\dto\LockMarketPayOrderRequestDTO.java
25-07-28.19:22:30.507 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-api\src\main\java\edu\whut\api\dto\LockMarketPayOrderResponseDTO.java
25-07-28.19:22:30.752 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-api\src\main\java\edu\whut\api\dto\NotifyRequestDTO.java
25-07-28.19:22:30.971 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-api\src\main\java\edu\whut\api\dto\SettlementMarketPayOrderRequestDTO.java
25-07-28.19:22:31.125 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-api\src\main\java\edu\whut\api\dto\SettlementMarketPayOrderResponseDTO.java
25-07-28.19:22:31.316 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-api\src\main\java\edu\whut\api\IDCCService.java
25-07-28.19:22:31.455 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-api\src\main\java\edu\whut\api\IMarketIndexService.java
25-07-28.19:22:31.659 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-api\src\main\java\edu\whut\api\IMarketTradeService.java
25-07-28.19:22:31.980 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-api\src\main\java\edu\whut\api\response\Response.java
25-07-28.19:22:32.149 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\Dockerfile
25-07-28.19:22:32.722 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\pom.xml
25-07-28.19:22:33.123 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\main\java\edu\whut\Application.java
25-07-28.19:22:33.356 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\main\java\edu\whut\config\DCCValueBeanFactory.java
25-07-28.19:22:33.367 [main ] INFO TextSplitter - Splitting up document into 3 chunks.
25-07-28.19:22:35.394 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\main\java\edu\whut\config\GuavaConfig.java
25-07-28.19:22:35.611 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\main\java\edu\whut\config\OKHttpClientConfig.java
25-07-28.19:22:35.812 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\main\java\edu\whut\config\package-info.java
25-07-28.19:22:35.952 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\main\java\edu\whut\config\RabbitMQConfig.java
25-07-28.19:22:36.337 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\main\java\edu\whut\config\RateLimiterAutoConfig.java
25-07-28.19:22:36.517 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\main\java\edu\whut\config\RedisClientConfig.java
25-07-28.19:22:37.522 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\main\java\edu\whut\config\RedisClientConfigProperties.java
25-07-28.19:22:38.094 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\main\java\edu\whut\config\ThreadPoolConfig.java
25-07-28.19:22:38.653 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\main\java\edu\whut\config\ThreadPoolConfigProperties.java
25-07-28.19:22:38.998 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\main\java\edu\whut\config\TraceIdFilter.java
25-07-28.19:22:39.350 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\main\java\edu\whut\package-info.java
25-07-28.19:22:39.451 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\main\resources\application-dev.yml
25-07-28.19:22:39.479 [main ] INFO TextSplitter - Splitting up document into 2 chunks.
25-07-28.19:22:40.523 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\main\resources\application-prod.yml
25-07-28.19:22:41.146 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\main\resources\application.yml
25-07-28.19:22:41.210 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\main\resources\logback-spring.xml
25-07-28.19:22:41.548 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\main\resources\mybatis\config\mybatis-config.xml
25-07-28.19:22:41.574 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\group-buying-sys-app\src\main\resources\mybatis\config\mybatis-config.xml: java.lang.IllegalArgumentException: content must not be null
25-07-28.19:22:41.575 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\main\resources\mybatis\mapper\crowd_tags_detail_mapper.xml
25-07-28.19:22:41.678 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\main\resources\mybatis\mapper\crowd_tags_job_mapper.xml
25-07-28.19:22:41.781 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\main\resources\mybatis\mapper\crowd_tags_mapper.xml
25-07-28.19:22:41.851 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\main\resources\mybatis\mapper\group_buy_activity_mapper.xml
25-07-28.19:22:42.120 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\main\resources\mybatis\mapper\group_buy_discount_mapper.xml
25-07-28.19:22:42.246 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\main\resources\mybatis\mapper\group_buy_order_list_mapper.xml
25-07-28.19:22:43.010 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\main\resources\mybatis\mapper\group_buy_order_mapper.xml
25-07-28.19:22:43.845 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\main\resources\mybatis\mapper\notify_task_mapper.xml
25-07-28.19:22:44.297 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\main\resources\mybatis\mapper\sc_sku_activity_mapper.xml
25-07-28.19:22:44.505 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\main\resources\mybatis\mapper\sku_mapper.xml
25-07-28.19:22:44.600 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\test\java\edu\whut\test\ApiTest.java
25-07-28.19:22:45.222 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\test\java\edu\whut\test\domain\activity\IIndexGroupBuyMarketServiceTest.java
25-07-28.19:22:46.279 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\test\java\edu\whut\test\domain\tag\ITagServiceTest.java
25-07-28.19:22:46.975 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\test\java\edu\whut\test\domain\trade\ITradeLockOrderServiceTest.java
25-07-28.19:22:48.166 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\test\java\edu\whut\test\domain\trade\ITradeRefundOrderServiceTest.java
25-07-28.19:22:48.730 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\test\java\edu\whut\test\domain\trade\TradeSettlementOrderServiceTest.java
25-07-28.19:22:49.503 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\test\java\edu\whut\test\infrastructure\dao\GroupBuyActivityDaoTest.java
25-07-28.19:22:49.934 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\test\java\edu\whut\test\infrastructure\dao\GroupBuyDiscountDaoTest.java
25-07-28.19:22:50.266 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\test\java\edu\whut\test\infrastructure\gateway\GroupBuyNotifyServiceTest.java
25-07-28.19:22:50.952 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\test\java\edu\whut\test\trigger\DCCControllerTest.java
25-07-28.19:22:51.574 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\test\java\edu\whut\test\trigger\MarketIndexControllerTest.java
25-07-28.19:22:52.079 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\test\java\edu\whut\test\trigger\MarketTradeControllerTest.java
25-07-28.19:22:52.091 [main ] INFO TextSplitter - Splitting up document into 2 chunks.
25-07-28.19:22:53.954 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\test\java\edu\whut\test\types\Link01Test.java
25-07-28.19:22:54.325 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\test\java\edu\whut\test\types\Link02Test.java
25-07-28.19:22:54.841 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\test\java\edu\whut\test\types\rule01\factory\Rule01TradeRuleFactory.java
25-07-28.19:22:55.196 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\test\java\edu\whut\test\types\rule01\logic\RuleLogic101.java
25-07-28.19:22:55.452 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\test\java\edu\whut\test\types\rule01\logic\RuleLogic102.java
25-07-28.19:22:55.733 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\test\java\edu\whut\test\types\rule02\factory\Rule02TradeRuleFactory.java
25-07-28.19:22:56.234 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\test\java\edu\whut\test\types\rule02\logic\RuleLogic201.java
25-07-28.19:22:56.548 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\test\java\edu\whut\test\types\rule02\logic\RuleLogic202.java
25-07-28.19:22:56.804 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-app\src\test\java\edu\whut\test\types\rule02\logic\XxxResponse.java
25-07-28.19:22:56.951 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\pom.xml
25-07-28.19:22:57.185 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\adapter\port\package-info.java
25-07-28.19:22:57.338 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\adapter\repository\IActivityRepository.java
25-07-28.19:22:57.772 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\model\aggregate\package-info.java
25-07-28.19:22:57.933 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\model\entity\MarketProductEntity.java
25-07-28.19:22:58.166 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\model\entity\TrialBalanceEntity.java
25-07-28.19:22:58.586 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\model\entity\UserGroupBuyOrderDetailEntity.java
25-07-28.19:22:58.917 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\model\valobj\DiscountTypeEnum.java
25-07-28.19:22:59.169 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\model\valobj\GroupBuyActivityDiscountVO.java
25-07-28.19:22:59.189 [main ] INFO TextSplitter - Splitting up document into 2 chunks.
25-07-28.19:23:00.252 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\model\valobj\SCSkuActivityVO.java
25-07-28.19:23:00.471 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\model\valobj\SkuVO.java
25-07-28.19:23:00.668 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\model\valobj\TagScopeEnumVO.java
25-07-28.19:23:00.865 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\model\valobj\TeamStatisticVO.java
25-07-28.19:23:01.106 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\service\discount\AbstractDiscountCalculateService.java
25-07-28.19:23:01.737 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\service\discount\IDiscountCalculateService.java
25-07-28.19:23:01.964 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\service\discount\impl\MJCalculateService.java
25-07-28.19:23:02.594 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\service\discount\impl\NCalculateService.java
25-07-28.19:23:02.970 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\service\discount\impl\ZJCalculateService.java
25-07-28.19:23:03.437 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\service\discount\impl\ZKCalculateService.java
25-07-28.19:23:03.901 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\service\IIndexGroupBuyMarketService.java
25-07-28.19:23:04.330 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\service\IndexGroupBuyMarketServiceImpl.java
25-07-28.19:23:05.270 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\service\trial\AbstractGroupBuyMarketSupport.java
25-07-28.19:23:05.654 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\service\trial\factory\DefaultActivityStrategyFactory.java
25-07-28.19:23:06.113 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\service\trial\node\EndNode.java
25-07-28.19:23:06.967 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\service\trial\node\ErrorNode.java
25-07-28.19:23:07.613 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\service\trial\node\MarketNode.java
25-07-28.19:23:07.639 [main ] INFO TextSplitter - Splitting up document into 2 chunks.
25-07-28.19:23:09.680 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\service\trial\node\RootNode.java
25-07-28.19:23:10.491 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\service\trial\node\SwitchNode.java
25-07-28.19:23:11.216 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\service\trial\node\TagNode.java
25-07-28.19:23:11.986 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\service\trial\thread\QueryGroupBuyActivityDiscountVOThreadTask.java
25-07-28.19:23:12.481 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\activity\service\trial\thread\QuerySkuVOFromDBThreadTask.java
25-07-28.19:23:12.780 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\tag\adapter\repository\ITagRepository.java
25-07-28.19:23:12.971 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\tag\adapter\repository\package-info.java
25-07-28.19:23:12.982 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\tag\adapter\repository\package-info.java: org.apache.tika.exception.ZeroByteFileException: InputStream must have > 0 bytes
25-07-28.19:23:12.982 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\tag\model\aggregate\package-info.java
25-07-28.19:23:13.133 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\tag\model\entity\CrowdTagsJobEntity.java
25-07-28.19:23:13.364 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\tag\model\entity\package-info.java
25-07-28.19:23:13.522 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\tag\model\valobj\package-info.java
25-07-28.19:23:13.642 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\tag\service\ITagService.java
25-07-28.19:23:13.771 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\tag\service\TagService.java
25-07-28.19:23:14.440 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\adapter\port\ITradePort.java
25-07-28.19:23:14.582 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\adapter\repository\ITradeRepository.java
25-07-28.19:23:15.270 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\model\aggregate\GroupBuyOrderAggregate.java
25-07-28.19:23:15.584 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\model\aggregate\GroupBuyRefundAggregate.java
25-07-28.19:23:16.225 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\model\aggregate\GroupBuyTeamSettlementAggregate.java
25-07-28.19:23:16.511 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\model\entity\GroupBuyActivityEntity.java
25-07-28.19:23:16.913 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\model\entity\GroupBuyTeamEntity.java
25-07-28.19:23:17.279 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\model\entity\MarketPayOrderEntity.java
25-07-28.19:23:17.595 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\model\entity\NotifyTaskEntity.java
25-07-28.19:23:17.862 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\model\entity\PayActivityEntity.java
25-07-28.19:23:18.129 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\model\entity\PayDiscountEntity.java
25-07-28.19:23:18.478 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\model\entity\TradeLockRuleCommandEntity.java
25-07-28.19:23:18.676 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\model\entity\TradeLockRuleFilterBackEntity.java
25-07-28.19:23:18.875 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\model\entity\TradePaySettlementEntity.java
25-07-28.19:23:19.106 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\model\entity\TradePaySuccessEntity.java
25-07-28.19:23:19.336 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\model\entity\TradeRefundBehaviorEntity.java
25-07-28.19:23:19.577 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\model\entity\TradeRefundCommandEntity.java
25-07-28.19:23:19.805 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\model\entity\TradeRefundOrderEntity.java
25-07-28.19:23:19.995 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\model\entity\TradeSettlementRuleCommandEntity.java
25-07-28.19:23:20.208 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\model\entity\TradeSettlementRuleFilterBackEntity.java
25-07-28.19:23:20.596 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\model\entity\UserEntity.java
25-07-28.19:23:20.736 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\model\valobj\GroupBuyProgressVO.java
25-07-28.19:23:20.954 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\model\valobj\NotifyConfigVO.java
25-07-28.19:23:21.189 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\model\valobj\NotifyTypeEnumVO.java
25-07-28.19:23:21.375 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\model\valobj\RefundTypeEnumVO.java
25-07-28.19:23:22.238 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\model\valobj\TradeOrderStatusEnumVO.java
25-07-28.19:23:22.469 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\service\ITradeLockOrderService.java
25-07-28.19:23:22.973 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\service\ITradeRefundOrderService.java
25-07-28.19:23:23.134 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\service\ITradeSettlementOrderService.java
25-07-28.19:23:23.424 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\service\ITradeTaskService.java
25-07-28.19:23:23.705 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\service\lock\factory\TradeLockRuleFilterFactory.java
25-07-28.19:23:24.619 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\service\lock\filter\ActivityUsabilityRuleFilter.java
25-07-28.19:23:25.450 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\service\lock\filter\TeamStockOccupyRuleFilter.java
25-07-28.19:23:26.326 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\service\lock\filter\UserTakeLimitRuleFilter.java
25-07-28.19:23:27.046 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\service\lock\TradeLockLockOrderService.java
25-07-28.19:23:28.172 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\service\refund\business\impl\Paid2RefundStrategy.java
25-07-28.19:23:29.016 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\service\refund\business\impl\PaidTeam2RefundStrategy.java
25-07-28.19:23:29.273 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\service\refund\business\impl\Unpaid2RefundStrategy.java
25-07-28.19:23:29.746 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\service\refund\business\IRefundOrderStrategy.java
25-07-28.19:23:29.961 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\service\refund\TradeRefundOrderService.java
25-07-28.19:23:31.125 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\service\settlement\factory\TradeSettlementRuleFilterFactory.java
25-07-28.19:23:31.929 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\service\settlement\filter\EndRuleFilter.java
25-07-28.19:23:32.424 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\service\settlement\filter\OutTradeNoRuleFilter.java
25-07-28.19:23:33.161 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\service\settlement\filter\SCRuleFilter.java
25-07-28.19:23:33.775 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\service\settlement\filter\SettableRuleFilter.java
25-07-28.19:23:34.530 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\service\settlement\TradeSettlementOrderService.java
25-07-28.19:23:34.541 [main ] INFO TextSplitter - Splitting up document into 2 chunks.
25-07-28.19:23:36.067 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-domain\src\main\java\edu\whut\domain\trade\service\task\TradeTaskService.java
25-07-28.19:23:36.077 [main ] INFO TextSplitter - Splitting up document into 2 chunks.
25-07-28.19:23:37.416 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\pom.xml
25-07-28.19:23:37.649 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\adapter\port\package-info.java
25-07-28.19:23:37.734 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\adapter\port\TradePort.java
25-07-28.19:23:38.804 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\adapter\repository\AbstractRepository.java
25-07-28.19:23:39.692 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\adapter\repository\ActivityRepository.java
25-07-28.19:23:39.705 [main ] INFO TextSplitter - Splitting up document into 3 chunks.
25-07-28.19:23:42.748 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\adapter\repository\TagRepository.java
25-07-28.19:23:42.759 [main ] INFO TextSplitter - Splitting up document into 2 chunks.
25-07-28.19:23:44.090 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\adapter\repository\TradeRepository.java
25-07-28.19:23:44.106 [main ] INFO TextSplitter - Splitting up document into 8 chunks.
25-07-28.19:23:52.297 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\aop\RateLimiterAOP.java
25-07-28.19:23:52.326 [main ] INFO TextSplitter - Splitting up document into 2 chunks.
25-07-28.19:23:54.190 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\dao\ICrowdTagsDao.java
25-07-28.19:23:54.334 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\dao\ICrowdTagsDetailDao.java
25-07-28.19:23:54.481 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\dao\ICrowdTagsJobDao.java
25-07-28.19:23:54.673 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\dao\IGroupBuyActivityDao.java
25-07-28.19:23:54.919 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\dao\IGroupBuyDiscountDao.java
25-07-28.19:23:55.122 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\dao\IGroupBuyOrderDao.java
25-07-28.19:23:55.672 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\dao\IGroupBuyOrderListDao.java
25-07-28.19:23:56.151 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\dao\INotifyTaskDao.java
25-07-28.19:23:56.463 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\dao\ISCSkuActivityDao.java
25-07-28.19:23:56.635 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\dao\ISkuDao.java
25-07-28.19:23:56.779 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\dao\package-info.java
25-07-28.19:23:56.866 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\dao\po\base\Page.java
25-07-28.19:23:56.980 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\dao\po\CrowdTags.java
25-07-28.19:23:57.235 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\dao\po\CrowdTagsDetail.java
25-07-28.19:23:57.447 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\dao\po\CrowdTagsJob.java
25-07-28.19:23:57.843 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\dao\po\GroupBuyActivity.java
25-07-28.19:23:58.331 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\dao\po\GroupBuyDiscount.java
25-07-28.19:23:58.710 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\dao\po\GroupBuyOrder.java
25-07-28.19:23:59.207 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\dao\po\GroupBuyOrderList.java
25-07-28.19:23:59.711 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\dao\po\NotifyTask.java
25-07-28.19:24:00.062 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\dao\po\SCSkuActivity.java
25-07-28.19:24:00.313 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\dao\po\Sku.java
25-07-28.19:24:00.590 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\dcc\DCCService.java
25-07-28.19:24:01.235 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\event\EventPublisher.java
25-07-28.19:24:01.600 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\gateway\dto\package-info.java
25-07-28.19:24:01.626 [main ] WARN JGitTest - 跳过无法读取的文件 .\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\gateway\dto\package-info.java: org.apache.tika.exception.ZeroByteFileException: InputStream must have > 0 bytes
25-07-28.19:24:01.626 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\gateway\GroupBuyNotifyService.java
25-07-28.19:24:02.073 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\gateway\package-info.java
25-07-28.19:24:02.174 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\redis\IRedisService.java
25-07-28.19:24:02.202 [main ] INFO TextSplitter - Splitting up document into 3 chunks.
25-07-28.19:24:04.305 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-infrastructure\src\main\java\edu\whut\infrastructure\redis\RedissonService.java
25-07-28.19:24:04.328 [main ] INFO TextSplitter - Splitting up document into 2 chunks.
25-07-28.19:24:05.787 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-trigger\pom.xml
25-07-28.19:24:06.020 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-trigger\src\main\java\edu\whut\trigger\http\DCCController.java
25-07-28.19:24:06.649 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-trigger\src\main\java\edu\whut\trigger\http\MarketIndexController.java
25-07-28.19:24:06.673 [main ] INFO TextSplitter - Splitting up document into 2 chunks.
25-07-28.19:24:08.475 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-trigger\src\main\java\edu\whut\trigger\http\MarketTradeController.java
25-07-28.19:24:08.504 [main ] INFO TextSplitter - Splitting up document into 4 chunks.
25-07-28.19:24:12.572 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-trigger\src\main\java\edu\whut\trigger\http\TestApiClientController.java
25-07-28.19:24:12.900 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-trigger\src\main\java\edu\whut\trigger\job\GroupBuyNotifyJob.java
25-07-28.19:24:13.666 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-trigger\src\main\java\edu\whut\trigger\job\package-info.java
25-07-28.19:24:13.802 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-trigger\src\main\java\edu\whut\trigger\listener\package-info.java
25-07-28.19:24:13.989 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-trigger\src\main\java\edu\whut\trigger\listener\RefundSuccessTopicListener.java
25-07-28.19:24:14.352 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-trigger\src\main\java\edu\whut\trigger\listener\TeamSuccessTopicListener.java
25-07-28.19:24:14.730 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-types\pom.xml
25-07-28.19:24:14.878 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-types\src\main\java\edu\whut\types\annotations\DCCValue.java
25-07-28.19:24:15.004 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-types\src\main\java\edu\whut\types\annotations\RateLimiterAccessInterceptor.java
25-07-28.19:24:15.245 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-types\src\main\java\edu\whut\types\common\Constants.java
25-07-28.19:24:15.377 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-types\src\main\java\edu\whut\types\design\framework\link\model1\AbstractLogicLink.java
25-07-28.19:24:15.581 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-types\src\main\java\edu\whut\types\design\framework\link\model1\ILogicChainArmory.java
25-07-28.19:24:15.716 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-types\src\main\java\edu\whut\types\design\framework\link\model1\ILogicLink.java
25-07-28.19:24:15.838 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-types\src\main\java\edu\whut\types\design\framework\link\model2\chain\BusinessLinkedList.java
25-07-28.19:24:16.313 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-types\src\main\java\edu\whut\types\design\framework\link\model2\chain\ILink.java
25-07-28.19:24:16.449 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-types\src\main\java\edu\whut\types\design\framework\link\model2\chain\LinkedList.java
25-07-28.19:24:16.460 [main ] INFO TextSplitter - Splitting up document into 2 chunks.
25-07-28.19:24:17.408 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-types\src\main\java\edu\whut\types\design\framework\link\model2\handler\ILogicHandler.java
25-07-28.19:24:17.673 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-types\src\main\java\edu\whut\types\design\framework\link\model2\LinkArmory.java
25-07-28.19:24:18.023 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-types\src\main\java\edu\whut\types\design\framework\tree\AbstractMultiThreadStrategyRouter.java
25-07-28.19:24:18.596 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-types\src\main\java\edu\whut\types\design\framework\tree\AbstractStrategyRouter.java
25-07-28.19:24:18.834 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-types\src\main\java\edu\whut\types\design\framework\tree\package-info.java
25-07-28.19:24:18.931 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-types\src\main\java\edu\whut\types\design\framework\tree\StrategyHandler.java
25-07-28.19:24:19.064 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-types\src\main\java\edu\whut\types\design\framework\tree\StrategyMapper.java
25-07-28.19:24:19.224 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-types\src\main\java\edu\whut\types\enums\ActivityStatusEnumVO.java
25-07-28.19:24:19.467 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-types\src\main\java\edu\whut\types\enums\GroupBuyOrderStatusEnumVO.java
25-07-28.19:24:19.698 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-types\src\main\java\edu\whut\types\enums\NotifyTaskHTTPEnumVO.java
25-07-28.19:24:19.873 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-types\src\main\java\edu\whut\types\enums\ResponseCode.java
25-07-28.19:24:20.529 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-types\src\main\java\edu\whut\types\event\BaseEvent.java
25-07-28.19:24:20.730 [main ] INFO JGitTest - 文件路径:.\cloned-repo\group-buying-sys-types\src\main\java\edu\whut\types\exception\AppException.java
25-07-28.19:24:21.114 [main ] INFO JGitTest - 文件路径:.\cloned-repo\pom.xml
25-07-28.19:24:21.125 [main ] INFO TextSplitter - Splitting up document into 2 chunks.
25-07-28.19:24:22.376 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown initiated...
25-07-28.19:24:22.378 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown completed.

View File

@ -0,0 +1,130 @@
<?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>edu.whut</groupId>
<artifactId>ai-rag-knowledge</artifactId>
<version>1.0</version>
</parent>
<artifactId>ai-rag-knowledge-app</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 基于 Apache Tika 的文档解析器,用于从各类文件中提取文本内容 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-tika-document-reader</artifactId>
</dependency>
<!-- 将向量存储在 PostgreSQL pgvector 扩展中,便于持久化和检索嵌入向量 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-pgvector-store-spring-boot-starter</artifactId>
</dependency>
<!-- 提供与 Ollama 本地/远程 LLM 服务的集成支持 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-ollama</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.44.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>edu.whut</groupId>
<artifactId>ai-rag-knowledge-trigger</artifactId>
</dependency>
</dependencies>
<build>
<finalName>ai-rag-knowledge-app</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/**</include>
</includes>
</resource>
</resources>
<testResources>
<testResource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/**</include>
</includes>
</testResource>
</testResources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.6</version>
<configuration>
<skipTests>true</skipTests>
<testFailureIgnore>false</testFailureIgnore>
<includes>
<include>**/*Test.java</include>
</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>edu.whut.Application</mainClass>
<layout>JAR</layout>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,15 @@
package edu.whut;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@Configurable
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}

View File

@ -0,0 +1,80 @@
package edu.whut.config;
import org.springframework.ai.ollama.OllamaChatClient;
import org.springframework.ai.ollama.OllamaEmbeddingClient;
import org.springframework.ai.ollama.api.OllamaApi;
import org.springframework.ai.ollama.api.OllamaOptions;
import org.springframework.ai.transformer.splitter.TokenTextSplitter;
import org.springframework.ai.vectorstore.PgVectorStore;
import org.springframework.ai.vectorstore.SimpleVectorStore;
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;
/**
* 配置 Ollama OpenAI 客户端以及向量存储和文本拆分器等 Bean
*/
@Configuration
public class OllamaConfig {
/**
* 创建 Ollama API 客户端负责与 Ollama 服务的基础通信
*/
@Bean
public OllamaApi ollamaApi(
@Value("${spring.ai.ollama.base-url}") String baseUrl) {
return new OllamaApi(baseUrl);
}
/**
* 基于 OllamaApi 实例创建对话客户端用于与 Ollama 模型进行对话交互
*/
@Bean
public OllamaChatClient ollamaChatClient(OllamaApi ollamaApi) {
return new OllamaChatClient(ollamaApi);
}
/**
* 文本拆分器根据 Token 划分长文本便于分段处理或嵌入计算
*/
@Bean
public TokenTextSplitter tokenTextSplitter() {
return new TokenTextSplitter();
}
/**
* 创建一个简单的向量存储 (in-memory)可根据配置选择 Ollama OpenAI 的嵌入模型
*/
@Bean
public SimpleVectorStore vectorStore(
@Value("${spring.ai.rag.embed}") String model,
OllamaApi ollamaApi) {
// 固定使用 Ollama 的嵌入客户端不再走 OpenAI 分支
OllamaEmbeddingClient embeddingClient = new OllamaEmbeddingClient(ollamaApi);
embeddingClient.withDefaultOptions(
OllamaOptions.create().withModel(model)
);
return new SimpleVectorStore(embeddingClient);
}
/**
* 创建基于 PostgreSQL pgvector 扩展的持久化向量存储可根据配置选择 Ollama OpenAI 模型
*/
@Bean
public PgVectorStore pgVectorStore(
@Value("${spring.ai.rag.embed}") String model,
OllamaApi ollamaApi,
JdbcTemplate jdbcTemplate) {
// 固定使用 Ollama 的嵌入客户端不再走 OpenAI 分支
OllamaEmbeddingClient embeddingClient = new OllamaEmbeddingClient(ollamaApi);
embeddingClient.withDefaultOptions(
OllamaOptions.create().withModel(model)
);
return new PgVectorStore(jdbcTemplate, embeddingClient);
}
}

View File

@ -0,0 +1,42 @@
package edu.whut.config;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.codec.JsonJacksonCodec;
import org.redisson.config.Config;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Redis 客户端使用 Redisson <a href="https://github.com/redisson/redisson">Redisson</a>
*
*/
@Configuration
@EnableConfigurationProperties(RedisClientConfigProperties.class)
public class RedisClientConfig {
@Bean("redissonClient")
public RedissonClient redissonClient(ConfigurableApplicationContext applicationContext, RedisClientConfigProperties properties) {
Config config = new Config();
// 根据需要可以设定编解码器https://github.com/redisson/redisson/wiki/4.-%E6%95%B0%E6%8D%AE%E5%BA%8F%E5%88%97%E5%8C%96
config.setCodec(JsonJacksonCodec.INSTANCE);
config.useSingleServer()
.setAddress("redis://" + properties.getHost() + ":" + properties.getPort())
// .setPassword(properties.getPassword())
.setConnectionPoolSize(properties.getPoolSize())
.setConnectionMinimumIdleSize(properties.getMinIdleSize())
.setIdleConnectionTimeout(properties.getIdleTimeout())
.setConnectTimeout(properties.getConnectTimeout())
.setRetryAttempts(properties.getRetryAttempts())
.setRetryInterval(properties.getRetryInterval())
.setPingConnectionInterval(properties.getPingInterval())
.setKeepAlive(properties.isKeepAlive())
;
return Redisson.create(config);
}
}

View File

@ -0,0 +1,36 @@
package edu.whut.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Redis 连接配置 <a href="https://github.com/redisson/redisson/tree/master/redisson-spring-boot-starter">redisson-spring-boot-starter</a>
*/
@Data
@ConfigurationProperties(prefix = "redis.sdk.config", ignoreInvalidFields = true)
public class RedisClientConfigProperties {
/** host:ip */
private String host;
/** 端口 */
private int port;
/** 账密 */
private String password;
/** 设置连接池的大小默认为64 */
private int poolSize = 64;
/** 设置连接池的最小空闲连接数默认为10 */
private int minIdleSize = 10;
/** 设置连接的最大空闲时间单位毫秒超过该时间的空闲连接将被关闭默认为10000 */
private int idleTimeout = 10000;
/** 设置连接超时时间单位毫秒默认为10000 */
private int connectTimeout = 10000;
/** 设置连接重试次数默认为3 */
private int retryAttempts = 3;
/** 设置连接重试的间隔时间单位毫秒默认为1000 */
private int retryInterval = 1000;
/** 设置定期检查连接是否可用的时间间隔单位毫秒默认为0表示不进行定期检查 */
private int pingInterval = 0;
/** 设置是否保持长连接默认为true */
private boolean keepAlive = true;
}

View File

@ -0,0 +1,56 @@
server:
port: 8095
spring:
datasource:
driver-class-name: org.postgresql.Driver
username: postgres
password: postgres
url: jdbc:postgresql://192.168.10.218:15432/ai-rag-knowledge
type: com.zaxxer.hikari.HikariDataSource
# hikari连接池配置
hikari:
#连接池名
pool-name: HikariCP
#最小空闲连接数
minimum-idle: 5
# 空闲连接存活最大时间默认10分钟
idle-timeout: 600000
# 连接池最大连接数默认是10
maximum-pool-size: 10
# 此属性控制从池返回的连接的默认自动提交行为,默认值true
auto-commit: true
# 此属性控制池中连接的最长生命周期值0表示无限生命周期默认30分钟
max-lifetime: 1800000
# 数据库连接超时时间,默认30秒
connection-timeout: 30000
# 连接测试query
connection-test-query: SELECT 1
ai:
ollama:
base-url: http://192.168.10.218:11434
embedding:
model: nomic-embed-text
rag:
embed: nomic-embed-text
# Redis
redis:
sdk:
config:
host: 192.168.10.218
port: 26379
pool-size: 10
min-idle-size: 5
idle-timeout: 30000
connect-timeout: 5000
retry-attempts: 3
retry-interval: 1000
ping-interval: 60000
keep-alive: true
logging:
level:
root: info
config: classpath:logback-spring.xml

View File

@ -0,0 +1,62 @@
server:
port: 8090
spring:
datasource:
driver-class-name: org.postgresql.Driver
username: postgres
password: postgres
url: jdbc:postgresql://192.168.1.109:15432/ai-rag-knowledge
type: com.zaxxer.hikari.HikariDataSource
# hikari连接池配置
hikari:
#连接池名
pool-name: HikariCP
#最小空闲连接数
minimum-idle: 5
# 空闲连接存活最大时间默认10分钟
idle-timeout: 600000
# 连接池最大连接数默认是10
maximum-pool-size: 10
# 此属性控制从池返回的连接的默认自动提交行为,默认值true
auto-commit: true
# 此属性控制池中连接的最长生命周期值0表示无限生命周期默认30分钟
max-lifetime: 1800000
# 数据库连接超时时间,默认30秒
connection-timeout: 30000
# 连接测试query
connection-test-query: SELECT 1
ai:
ollama:
base-url: http://192.168.1.109:11434
embedding:
options:
num-batch: 512
model: nomic-embed-text
openai:
base-url: https://pro-share-aws-api.zcyai.com/
api-key: sk-eEyfxptPgbfXd3Z164260740E0494161Bd8**找小傅哥申请
embedding-model: text-embedding-ada-002
rag:
embed: nomic-embed-text #nomic-embed-text、text-embedding-ada-002
# Redis
redis:
sdk:
config:
host: 192.168.1.109
port: 16379
pool-size: 10
min-idle-size: 5
idle-timeout: 30000
connect-timeout: 5000
retry-attempts: 3
retry-interval: 1000
ping-interval: 60000
keep-alive: true
logging:
level:
root: info
config: classpath:logback-spring.xml

View File

@ -0,0 +1,5 @@
spring:
application:
name: ai-rag-knowledge
profiles:
active: dev

View File

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL如果设置为WARN则低于WARN的信息都不会输出 -->
<configuration scan="true" scanPeriod="10 seconds">
<contextName>logback</contextName>
<!-- 如需使用外部配置的路径,可通过 Spring 的属性注入:
<springProperty scope="context" name="log.path" source="logging.path"/>
然后把 ./data/log/ 改成 ${log.path}
-->
<!-- <springProperty scope="context" name="log.path" source="logging.path"/> -->
<!-- 日志格式相关的 converter保留你的设置 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<!-- 控制台输出 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>info</level>
</filter>
<encoder>
<pattern>%d{yy-MM-dd.HH:mm:ss.SSS} [%-16t] %-5p %-22c{0}%X{ServiceId} -%X{trace-id} %m%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 文件输出INFO 级别及以上) -->
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件 -->
<file>./data/log/log_info.log</file>
<append>true</append>
<!-- 输出格式 -->
<encoder>
<pattern>%d{yy-MM-dd.HH:mm:ss.SSS} [%-16t] %-5p %-22c{0}%X{ServiceId} -%X{trace-id} %m%n</pattern>
<charset>UTF-8</charset>
</encoder>
<!-- 新写法:按“时间 + 大小”滚动,无需再使用 SizeAndTimeBasedFNATP -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 每天一个目录 / 文件名中包含日期与递增序号 -->
<fileNamePattern>./data/log/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 单文件最大 100MB超过则在同一天内按 %i 递增 -->
<maxFileSize>100MB</maxFileSize>
<!-- 历史文件保留 15 天 -->
<maxHistory>15</maxHistory>
<!-- 总体积上限(超过会按时间从旧到新清理) -->
<totalSizeCap>10GB</totalSizeCap>
<!-- (可选)启动时按当前策略清理历史,避免旧策略残留 -->
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>
</appender>
<!-- 文件输出WARN 及以上,通常用于 ERROR 文件) -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>./data/log/log_error.log</file>
<append>true</append>
<encoder>
<pattern>%d{yy-MM-dd.HH:mm:ss.SSS} [%-16t] %-5p %-22c{0}%X{ServiceId} -%X{trace-id} %m%n</pattern>
<charset>UTF-8</charset>
</encoder>
<!-- 同样改为 SizeAndTimeBasedRollingPolicy -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>./data/log/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>7</maxHistory>
<totalSizeCap>5GB</totalSizeCap>
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>
<!-- 只写入 WARN 及以上的日志到该文件 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
</filter>
</appender>
<!-- 异步写 INFO 文件 -->
<appender name="ASYNC_FILE_INFO" class="ch.qos.logback.classic.AsyncAppender">
<!-- 0 表示不丢弃日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 队列深度 -->
<queueSize>8192</queueSize>
<!-- true不阻塞业务线程极端情况下可能丢日志false满了会阻塞 -->
<neverBlock>true</neverBlock>
<includeCallerData>false</includeCallerData>
<appender-ref ref="INFO_FILE"/>
</appender>
<!-- 异步写 ERROR 文件 -->
<appender name="ASYNC_FILE_ERROR" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>1024</queueSize>
<neverBlock>true</neverBlock>
<includeCallerData>false</includeCallerData>
<appender-ref ref="ERROR_FILE"/>
</appender>
<!-- 开发环境:调低指定包的日志级别 -->
<springProfile name="dev">
<logger name="com.nmys.view" level="debug"/>
</springProfile>
<!-- 根日志器 -->
<root level="info">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="ASYNC_FILE_INFO"/>
<appender-ref ref="ASYNC_FILE_ERROR"/>
</root>
</configuration>

View File

@ -0,0 +1,148 @@
package edu.whut.test;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.ai.document.Document;
import org.springframework.ai.ollama.OllamaChatClient;
import org.springframework.ai.reader.tika.TikaDocumentReader;
import org.springframework.ai.transformer.splitter.TokenTextSplitter;
import org.springframework.ai.vectorstore.PgVectorStore;
import org.springframework.ai.vectorstore.SimpleVectorStore;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.io.PathResource;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* 测试类演示如何使用 JGit 克隆 Git 仓库并将文件内容上传到向量存储
*/
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class JGitTest {
/**
* Ollama 聊天客户端用于后续可能的模型调用本例未使用
*/
@Resource
private OllamaChatClient ollamaChatClient;
/**
* 文本拆分器将长文档拆分成多个小段
*/
@Resource
private TokenTextSplitter tokenTextSplitter;
/**
* 简单的内存向量存储用于快速测试本例未使用
*/
@Resource
private SimpleVectorStore simpleVectorStore;
/**
* PostgreSQL 向量存储用于持久化文档向量
*/
@Resource
private PgVectorStore pgVectorStore;
/**
* 测试方法克隆远程 Git 仓库到本地目录
* @throws Exception 在克隆过程出错时抛出
*/
@Test
public void test() throws Exception {
// 远程仓库地址
String repoURL = "http://124.71.159.195:3000/zy123/group-buying.git";
// 认证用户名和密码如果仓库是私有的需要提供
String username = "zy123xxxx";
String password = "xxxxxxx";
// 指定本地克隆目录
String localPath = "./cloned-repo";
log.info("克隆路径:" + new File(localPath).getAbsolutePath());
// 如果目录已存在则删除确保每次都是全新克隆
FileUtils.deleteDirectory(new File(localPath));
// 使用 JGit 克隆仓库
Git git = Git.cloneRepository()
.setURI(repoURL)
.setDirectory(new File(localPath))
.setCredentialsProvider(
new UsernamePasswordCredentialsProvider(username, password)
)
.call();
// 关闭 Git 对象释放资源
git.close();
}
/**
* 测试方法遍历克隆下来的本地仓库文件将每个文件读取为文档拆分后存入向量库
* @throws IOException 在文件遍历或 IO 操作出错时抛出
*/
@Test
public void test_file() throws IOException {
Files.walkFileTree(Paths.get("./cloned-repo"), new SimpleFileVisitor<>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
// 跳过 .git 目录
if (dir.getFileName().toString().equals(".git")) {
return FileVisitResult.SKIP_SUBTREE;
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
log.info("文件路径:{}", file);
PathResource resource = new PathResource(file);
TikaDocumentReader reader = new TikaDocumentReader(resource);
// 1) 先拿到不可变的列表
List<Document> original = Collections.emptyList();
try {
original = reader.get();
} catch (Exception ex) {
log.warn("跳过无法读取的文件 {}: {}", file, ex.getMessage());
return FileVisitResult.CONTINUE;
}
// 2) 复制到可变列表
List<Document> docs = new ArrayList<>(original);
// 3) 去除 content 为空或纯空白的 Document
docs.removeIf(d -> d.getContent() == null || d.getContent().trim().isEmpty());
if (docs.isEmpty()) {
return FileVisitResult.CONTINUE;
}
// 4) 给文档打标签
docs.forEach(d -> d.getMetadata().put("knowledge", "group-buy-market"));
// 5) 拆分成更小的段落
List<Document> splits = tokenTextSplitter.apply(docs);
splits.forEach(d -> d.getMetadata().put("knowledge", "group-buy-market"));
// 6) 写入向量存储
pgVectorStore.accept(splits);
return FileVisitResult.CONTINUE;
}
});
}
}

View File

@ -0,0 +1,121 @@
package edu.whut.test;
import com.alibaba.fastjson.JSON;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.SystemPromptTemplate;
import org.springframework.ai.document.Document;
import org.springframework.ai.ollama.OllamaChatClient;
import org.springframework.ai.ollama.api.OllamaOptions;
import org.springframework.ai.reader.tika.TikaDocumentReader;
import org.springframework.ai.transformer.splitter.TokenTextSplitter;
import org.springframework.ai.vectorstore.PgVectorStore;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.SimpleVectorStore;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* RAG 测试类验证文档上传向量存储和 Ollama 回答流程
*/
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class RAGTest {
// 注入 Ollama 聊天客户端用于直接测试模型调用
@Resource
private OllamaChatClient ollamaChatClient;
// 注入 TokenTextSplitter用于将长文档拆分为小段
@Resource
private TokenTextSplitter tokenTextSplitter;
// 注入简单内存向量存储用于快速测试
@Resource
private SimpleVectorStore simpleVectorStore;
// 注入 PostgreSQL 向量存储用于持久化测试
@Resource
private PgVectorStore pgVectorStore;
/**
* 测试方法读取本地文件将其拆分并上传到 pgVectorStore
*/
@Test
public void upload() {
// 使用 TikaDocumentReader 读取本地文件并提取文档对象
TikaDocumentReader reader = new TikaDocumentReader("./data/file.text");
List<Document> documents = reader.get();
// 对提取的文档进行 Token 拆分
List<Document> documentSplitterList = tokenTextSplitter.apply(documents);
// 为原文档和拆分文档设置 "knowledge" 标签
documents.forEach(doc -> doc.getMetadata().put("knowledge", "测试知识库名称"));
documentSplitterList.forEach(doc -> doc.getMetadata().put("knowledge", "测试知识库名称"));
// 将拆分的文档批量存入 PostgreSQL pgvector 存储
pgVectorStore.accept(documentSplitterList);
log.info("上传完成");
}
/**
* 测试方法构造用户消息和系统提示检索向量存储并调用 Ollama 获取回答
*/
@Test
public void chat() {
// 设置用户提问
String message = "王大瓜,哪年出生";
// 定义系统提示模板将检索到的文档注入要求中文回答
String SYSTEM_PROMPT = """
Use the information from the DOCUMENTS section to provide accurate answers but act as if you knew this information innately.
If unsure, simply state that you don't know.
Another thing you need to note is that your reply must be in Chinese!
DOCUMENTS:
{documents}
""";
// 构建向量检索请求最大返回 5 "knowledge" 标签过滤
SearchRequest request = SearchRequest.query(message)
.withTopK(5)
.withFilterExpression("knowledge == '测试知识库名称'");
// 执行相似度搜索获取匹配的文档列表
List<Document> documents = pgVectorStore.similaritySearch(request);
// 拼接所有文档内容
String documentsCollectors = documents.stream()
.map(Document::getContent)
.collect(Collectors.joining());
// 创建带有文档内容的系统消息
Message ragMessage = new SystemPromptTemplate(SYSTEM_PROMPT)
.createMessage(Map.of("documents", documentsCollectors));
// 构造消息列表用户消息在前系统消息在后
ArrayList<Message> messages = new ArrayList<>();
messages.add(new UserMessage(message));
messages.add(ragMessage);
// 调用 Ollama 同步接口获取模型回答
ChatResponse chatResponse = ollamaChatClient.call(
new Prompt(messages, OllamaOptions.create().withModel("deepseek-r1:1.5b"))
);
// 打印测试结果
log.info("测试结果:{}", JSON.toJSONString(chatResponse));
}
}

View File

@ -0,0 +1 @@
王大瓜 2000年出生

View File

@ -0,0 +1 @@
王大瓜 2005年出生

View File

@ -0,0 +1,67 @@
<?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>edu.whut</groupId>
<artifactId>ai-rag-knowledge</artifactId>
<version>1.0</version>
</parent>
<artifactId>ai-rag-knowledge-trigger</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-tika-document-reader</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-pgvector-store</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-ollama</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>edu.whut</groupId>
<artifactId>ai-rag-knowledge-api</artifactId>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.44.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
</dependency>
</dependencies>
<build>
<finalName>xfg-dev-tech-trigger</finalName>
</build>
</project>

View File

@ -0,0 +1,120 @@
package edu.whut.trigger.http;
import edu.whut.api.IAiService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.SystemPromptTemplate;
import org.springframework.ai.document.Document;
import org.springframework.ai.ollama.OllamaChatClient;
import org.springframework.ai.ollama.api.OllamaOptions;
import org.springframework.ai.vectorstore.PgVectorStore;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Ollama 触发器 HTTP 控制器实现 IAiService 接口提供基于 Ollama AI 服务
*/
@RestController
@RequestMapping("/api/v1/ollama/")
@CrossOrigin("*")
@RequiredArgsConstructor
@Slf4j
public class OllamaController implements IAiService {
// 注入 Ollama 对话客户端用于向 Ollama 模型发起对话请求
private final OllamaChatClient chatClient;
// 注入 PostgreSQL 向量存储用于 RAG 检索
private final PgVectorStore pgVectorStore;
/**
* 普通生成接口返回一次性 ChatResponse
* 示例: GET /generate?model=deepseek-r1:1.5b&message=1+1
*/
@GetMapping("generate")
@Override
public ChatResponse generate(
@RequestParam("model") String model,
@RequestParam("message") String message) {
// 构建 Prompt 并调用 OllamaClient 同步获取响应
log.info("generate called!");
return chatClient.call(
new Prompt(message, OllamaOptions.create().withModel(model))
);
}
/**
* 流式生成接口返回 Flux&lt;ChatResponse&gt;
* 示例: GET /generate_stream?model=deepseek-r1:1.5b&message=hi
*/
@GetMapping("generate_stream")
@Override
public Flux<ChatResponse> generateStream(
@RequestParam("model") String model,
@RequestParam("message") String message) {
// 调用 OllamaClient stream 方法开启 SSE 或分块传输
log.info("generate_stream called!");
return chatClient.stream(
new Prompt(message, OllamaOptions.create().withModel(model))
);
}
/**
* RAG 流式生成接口先检索相关文档再附加系统提示最后流式调用模型
* 示例: GET /generate_stream_rag?model=deepseek-r1:1.5b&ragTag=xxx&message=内容
*/
@GetMapping("generate_stream_rag")
@Override
public Flux<ChatResponse> generateStreamRag(
@RequestParam("model") String model,
@RequestParam("ragTag") String ragTag,
@RequestParam("message") String message) {
log.info("generate_stream_rag called!");
// 系统提示模板嵌入检索到的文档内容并要求中文回复
String SYSTEM_PROMPT =
"""
Use the information from the DOCUMENTS section to provide accurate answers but act as if you knew this information innately.
If unsure, simply state that you don't know.
Another thing you need to note is that your reply must be in Chinese!
DOCUMENTS:
{documents}
""";
// 构建检索请求基于用户 message 检索 TopK 文档并使用 ragTag 过滤标签
SearchRequest request = SearchRequest.query(message)
.withTopK(5)
.withFilterExpression("knowledge == '" + ragTag + "'");
// 执行相似度搜索获取匹配文档列表
List<Document> documents = pgVectorStore.similaritySearch(request);
// 拼接文档内容
String documentContent = documents.stream()
.map(Document::getContent)
.collect(Collectors.joining());
// 使用 SystemPromptTemplate 注入文档到系统消息
Message ragMessage = new SystemPromptTemplate(SYSTEM_PROMPT)
.createMessage(Map.of("documents", documentContent));
// 构造消息列表先用户消息再系统消息
List<Message> messages = new ArrayList<>();
messages.add(new UserMessage(message));
messages.add(ragMessage);
// 发起流式调用
return chatClient.stream(
new Prompt(messages, OllamaOptions.create().withModel(model))
);
}
}

View File

@ -0,0 +1,206 @@
package edu.whut.trigger.http;
import edu.whut.api.IRAGService;
import edu.whut.api.response.Response;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.redisson.api.RList;
import org.redisson.api.RedissonClient;
import org.springframework.ai.document.Document;
import org.springframework.ai.ollama.OllamaChatClient;
import org.springframework.ai.reader.tika.TikaDocumentReader;
import org.springframework.ai.transformer.splitter.TokenTextSplitter;
import org.springframework.ai.vectorstore.PgVectorStore;
import org.springframework.ai.vectorstore.SimpleVectorStore;
import org.springframework.core.io.PathResource;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;
/**
* RAG 服务控制器实现 IRAGService 接口提供知识库管理和检索相关的 HTTP 接口
*/
@Slf4j
@RestController
@RequestMapping("/api/v1/rag/")
@CrossOrigin("*")
@RequiredArgsConstructor
public class RAGController implements IRAGService {
// Ollama 聊天客户端用于后续可能的对话调用此处暂无直接使用
private final OllamaChatClient ollamaChatClient;
// 文本拆分器将长文档切分为合适大小的段落或 Token
private final TokenTextSplitter tokenTextSplitter;
// 简易内存向量存储用于快速测试或小规模存储
private final SimpleVectorStore simpleVectorStore;
// PostgreSQL pgvector 存储用于持久化和检索嵌入向量
private final PgVectorStore pgVectorStore;
// Redisson 客户端用于操作 Redis 列表存储 RAG 标签
private final RedissonClient redissonClient;
/**
* 查询所有已上传的 RAG 标签列表
* GET /api/v1/rag/query_rag_tag_list
*/
@GetMapping("query_rag_tag_list")
@Override
public Response<List<String>> queryRagTagList() {
// Redis 列表获取所有标签
RList<String> elements = redissonClient.getList("ragTag");
return Response.<List<String>>builder()
.code("0000")
.info("调用成功")
.data(elements)
.build();
}
/**
* 上传文件到知识库
* - 使用 Tika 读取文档内容
* - 进行文本切分并贴上 ragTag 元数据
* - 存储到 pgVectorStore 并更新 Redis 标签列表
* POST /api/v1/rag/file/upload
*/
@PostMapping(path = "file/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@Override
public Response<String> uploadFile(
@RequestParam("ragTag") String ragTag,
@RequestParam("file") List<MultipartFile> files) {
log.info("上传知识库开始:{}", ragTag);
for (MultipartFile file : files) {
// 读取上传文件提取文档内容
TikaDocumentReader documentReader = new TikaDocumentReader(file.getResource());
List<Document> documents = documentReader.get();
// 对文档进行 Token 拆分
List<Document> documentSplitterList = tokenTextSplitter.apply(documents);
// 为原文档和拆分文档设置 ragTag 元数据
documents.forEach(doc -> doc.getMetadata().put("knowledge", ragTag));
documentSplitterList.forEach(doc -> doc.getMetadata().put("knowledge", ragTag));
// 存储拆分后的文档到 pgVectorStore
pgVectorStore.accept(documentSplitterList);
// 更新 Redis 标签列表避免重复
RList<String> elements = redissonClient.getList("ragTag");
if (!elements.contains(ragTag)) {
elements.add(ragTag);
}
}
log.info("上传知识库完成:{}", ragTag);
return Response.<String>builder().code("0000").info("调用成功").build();
}
/**
* 克隆并分析 Git 仓库
* - 克隆指定仓库到本地
* - 遍历文件使用 Tika 提取并拆分
* - 存储到 pgVectorStore 并更新 Redis 标签列表
* POST /api/v1/rag/analyze_git_repository
*/
@PostMapping("analyze_git_repository")
@Override
public Response<String> analyzeGitRepository(
@RequestParam("repoUrl") String repoUrl,
@RequestParam("userName") String userName,
@RequestParam("token") String token) throws Exception {
String localPath = "./git-cloned-repo";
String repoProjectName = extractProjectName(repoUrl);
log.info("克隆路径:{}", new File(localPath).getAbsolutePath());
// 1. 干净克隆
FileUtils.deleteDirectory(new File(localPath));
Git git = Git.cloneRepository()
.setURI(repoUrl)
.setDirectory(new File(localPath))
.setCredentialsProvider(new UsernamePasswordCredentialsProvider(userName, token))
.call();
// 2. 遍历并处理文件
Files.walkFileTree(Paths.get(localPath), new SimpleFileVisitor<>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
// 跳过 .git 目录
if (".git".equals(dir.getFileName().toString())) {
return FileVisitResult.SKIP_SUBTREE;
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
log.info("解析并上传文件:{} -> {}", repoProjectName, file.getFileName());
try {
// 2.1 读取原始文档不可变列表
List<Document> raw = new TikaDocumentReader(new PathResource(file)).get();
// 2.2 复制为可变列表并过滤掉空内容
List<Document> docs = new ArrayList<>(raw);
docs.removeIf(d -> d.getContent() == null || d.getContent().trim().isEmpty());
if (docs.isEmpty()) {
return FileVisitResult.CONTINUE;
}
// 2.3 打标签
docs.forEach(d -> d.getMetadata().put("knowledge", repoProjectName));
// 2.4 拆分并打标签
List<Document> splits = tokenTextSplitter.apply(docs);
splits.forEach(d -> d.getMetadata().put("knowledge", repoProjectName));
// 2.5 写入向量库
pgVectorStore.accept(splits);
} catch (Exception e) {
// 无法读取拆分或存储时记录错误并跳过
log.error("文件解析上传失败:{}", file.getFileName(), e);
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) {
// 文件访问失败时也不影响整体执行
log.warn("访问文件失败:{} - {}", file, exc.getMessage());
return FileVisitResult.CONTINUE;
}
});
// 3. 清理本地
FileUtils.deleteDirectory(new File(localPath));
git.close();
// 4. 更新 Redis 标签列表
RList<String> elements = redissonClient.getList("ragTag");
if (!elements.contains(repoProjectName)) {
elements.add(repoProjectName);
}
log.info("仓库分析并上传完成:{}", repoUrl);
return Response.<String>builder().code("0000").info("调用成功").build();
}
/**
* Git 仓库 URL 提取项目名称去除 .git 后缀
*/
private String extractProjectName(String repoUrl) {
String[] parts = repoUrl.split("/");
String projectNameWithGit = parts[parts.length - 1];
return projectNameWithGit.replace(".git", "");
}
}

View File

@ -0,0 +1,128 @@
[
{
"result": {
"output": {
"messageType": "ASSISTANT",
"properties": {
"id": "chatcmpl-B3HPw95SsqmhoWeJ8azGLxK1Vf4At",
"role": "ASSISTANT",
"finishReason": ""
},
"content": "1",
"media": []
},
"metadata": {
"finishReason": null,
"contentFilterMetadata": null
}
}
},
{
"result": {
"output": {
"messageType": "ASSISTANT",
"properties": {
"id": "chatcmpl-B3HPw95SsqmhoWeJ8azGLxK1Vf4At",
"role": "ASSISTANT",
"finishReason": ""
},
"content": " +",
"media": []
},
"metadata": {
"finishReason": null,
"contentFilterMetadata": null
}
}
},
{
"result": {
"output": {
"messageType": "ASSISTANT",
"properties": {
"id": "chatcmpl-B3HPw95SsqmhoWeJ8azGLxK1Vf4At",
"role": "ASSISTANT",
"finishReason": ""
},
"content": " ",
"media": []
},
"metadata": {
"finishReason": null,
"contentFilterMetadata": null
}
}
},
{
"result": {
"output": {
"messageType": "ASSISTANT",
"properties": {
"id": "chatcmpl-B3HPw95SsqmhoWeJ8azGLxK1Vf4At",
"role": "ASSISTANT",
"finishReason": ""
},
"content": "1",
"media": []
},
"metadata": {
"finishReason": null,
"contentFilterMetadata": null
}
}
},
{
"result": {
"output": {
"messageType": "ASSISTANT",
"properties": {
"id": "chatcmpl-B3HPw95SsqmhoWeJ8azGLxK1Vf4At",
"role": "ASSISTANT",
"finishReason": ""
},
"content": " equals",
"media": []
},
"metadata": {
"finishReason": null,
"contentFilterMetadata": null
}
}
},
{
"result": {
"output": {
"messageType": "ASSISTANT",
"properties": {
"id": "chatcmpl-B3HPw95SsqmhoWeJ8azGLxK1Vf4At",
"role": "ASSISTANT",
"finishReason": ""
},
"content": "2",
"media": []
},
"metadata": {
"finishReason": null,
"contentFilterMetadata": null
}
}
},
{
"result": {
"output": {
"messageType": "ASSISTANT",
"properties": {
"id": "chatcmpl-B3HPw95SsqmhoWeJ8azGLxK1Vf4At",
"role": "ASSISTANT",
"finishReason": "STOP"
},
"content": null,
"media": []
},
"metadata": {
"finishReason": "STOP",
"contentFilterMetadata": null
}
}
}
]

View File

@ -0,0 +1,9 @@
# A. 测试 embeddingsnomic-embed-text
curl -s http://localhost:11434/api/embeddings \
-H "Content-Type: application/json" \
-d '{"model":"nomic-embed-text","input":"hello"}'
# B. 测试 generatedeepseek-r1:1.5b
curl -s http://localhost:11434/api/generate \
-H "Content-Type: application/json" \
-d '{"model":"deepseek-r1:1.5b","prompt":"say hi"}'

View File

@ -0,0 +1,83 @@
# docker-compose -f docker-compose-environment-aliyun.yml up -d
version: '3'
services:
# 对话模型
# ollama pull deepseek-r1:1.5b
# 运行模型
# ollama run deepseek-r1:1.5b
# 联网模型
# ollama pull nomic-embed-text
ollama:
image: registry.cn-hangzhou.aliyuncs.com/xfg-studio/ollama:0.5.10
volumes:
- ./ollama:/root/.ollama
container_name: ollama
restart: unless-stopped
ports:
- "11434:11434"
networks:
- ai-rag-knowledge-network
redis:
image: registry.cn-hangzhou.aliyuncs.com/xfg-studio/redis:6.2
container_name: rag-redis
restart: unless-stopped
hostname: redis
privileged: true
ports:
- 26379:6379
volumes:
- ./redis/redis.conf:/usr/local/etc/redis/redis.conf
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- ai-rag-knowledge-network
healthcheck:
test: [ "CMD", "redis-cli", "ping" ]
interval: 10s
timeout: 5s
retries: 3
#向量库
vector_db:
image: registry.cn-hangzhou.aliyuncs.com/xfg-studio/pgvector:v0.5.0
container_name: vector_db
restart: unless-stopped
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=ai-rag-knowledge
- PGPASSWORD=postgres
volumes:
- ./pgvector/sql/init.sql:/docker-entrypoint-initdb.d/init.sql
logging:
options:
max-size: 10m
max-file: "3"
ports:
- '15432:5432'
healthcheck:
test: "pg_isready -U postgres -d ai-rag-knowledge"
interval: 2s
timeout: 20s
retries: 10
networks:
- ai-rag-knowledge-network
# pg 管理工具
pgadmin:
image: registry.cn-hangzhou.aliyuncs.com/xfg-studio/pgadmin4:9.1.0
container_name: vector_db_admin
restart: unless-stopped
ports:
- "5050:80"
environment:
PGADMIN_DEFAULT_EMAIL: admin@qq.com
PGADMIN_DEFAULT_PASSWORD: admin
depends_on:
- vector_db
networks:
- ai-rag-knowledge-network
networks:
ai-rag-knowledge-network:
driver: bridge

View File

@ -0,0 +1,62 @@
# docker-comopse -f docker-compose-environment.yml up -d
version: '3'
services:
# 对话模型
# ollama pull deepseek-r1:1.5b
# 运行模型
# ollama run deepseek-r1:1.5b
# 联网模型
# ollama pull nomic-embed-text
ollama:
image: ollama/ollama:0.5.10
container_name: ollama
restart: unless-stopped
ports:
- "11434:11434"
redis:
image: redis:6.2
container_name: redis
restart: always
hostname: redis
privileged: true
ports:
- 26379:6379
volumes:
- ./redis/redis.conf:/usr/local/etc/redis/redis.conf
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- ai-rag-knowledge-network
healthcheck:
test: [ "CMD", "redis-cli", "ping" ]
interval: 10s
timeout: 5s
retries: 3
vector_db:
image: pgvector/pgvector:v0.5.0
container_name: vector_db
restart: unless-stopped
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=springai
- PGPASSWORD=postgres
volumes:
- ./pgvector/sql/init.sql:/docker-entrypoint-initdb.d/init.sql
logging:
options:
max-size: 10m
max-file: "3"
ports:
- '5432:5432'
healthcheck:
test: "pg_isready -U postgres -d vector_store"
interval: 2s
timeout: 20s
retries: 10
networks:
- ai-rag-knowledge-network
networks:
ai-rag-knowledge-network:
driver: bridge

View File

@ -0,0 +1,86 @@
.chat-item {
@apply flex items-center gap-2 p-2 hover:bg-gray-100 rounded cursor-pointer transition-colors;
}
.chat-item.selected {
@apply bg-blue-50; /* 或使用深色背景如bg-gray-200 */
}
.chat-item-content {
@apply flex-1 truncate;
}
.chat-actions {
@apply flex items-center justify-end opacity-0 transition-opacity w-8;
}
.chat-item:hover.chat-actions {
@apply opacity-100;
}
.context-menu {
@apply absolute bg-white border rounded-lg shadow-lg py-1 z-50;
min-width: 120px;
}
.context-menu-item {
@apply px-4 py-2 hover:bg-gray-100 text-sm flex items-center gap-2;
}
.markdown-body {
font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji;
font-size: 16px;
line-height: 1.5;
word-wrap: break-word;
}
.markdown-body pre {
background-color: #f6f8fa;
border-radius: 6px;
padding: 16px;
overflow-x: auto;
}
.markdown-body code {
background-color: rgba(175,184,193,0.2);
border-radius: 6px;
padding: 0.2em 0.4em;
font-size: 85%;
}
.markdown-body pre code {
background-color: transparent;
padding: 0;
font-size: 100%;
}
.markdown-body h1,.markdown-body h2,.markdown-body h3,
.markdown-body h4,.markdown-body h5,.markdown-body h6 {
margin-top: 24px;
margin-bottom: 16px;
font-weight: 600;
line-height: 1.25;
}
.markdown-body h1 { font-size: 2em; }
.markdown-body h2 { font-size: 1.5em; }
.markdown-body h3 { font-size: 1.25em; }
.markdown-body ul,.markdown-body ol {
padding-left: 2em;
}
.markdown-body ul { list-style-type: disc; }
.markdown-body ol { list-style-type: decimal; }
.markdown-body table {
border-spacing: 0;
border-collapse: collapse;
margin-top: 0;
margin-bottom: 16px;
}
.markdown-body table th,.markdown-body table td {
padding: 6px 13px;
border: 1px solid #d0d7de;
}
.markdown-body table tr:nth-child(2n) {
background-color: #f6f8fa;
}
.chat-actions button {
margin-left: 4px; /* Add some space between buttons */
}
/* 下拉菜单过渡动画 */
#uploadMenu {
transition: all 0.2s ease-out;
transform-origin: top right;
}
#uploadMenu a {
transition: background-color 0.2s ease;
}

View File

@ -0,0 +1,146 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>解析仓库</title>
<style>
body {
font-family: 'Microsoft YaHei', '微软雅黑', sans-serif;
background-color: #f0f0f0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.container {
background-color: white;
padding: 2rem;
border-radius: 10px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
text-align: center;
width: 300px;
}
h1 {
color: #333;
margin-bottom: 1.5rem;
}
.form-group {
margin-bottom: 1rem;
}
input {
width: 100%;
padding: 0.5rem;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 1rem;
box-sizing: border-box;
}
button {
background-color: #1E90FF;
color: white;
border: none;
padding: 0.5rem 1rem;
font-size: 1rem;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s;
width: 100%;
}
button:hover {
background-color: #4169E1;
}
#status {
margin-top: 1rem;
font-weight: bold;
}
.overlay {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
z-index: 1000;
justify-content: center;
align-items: center;
}
.loading-spinner {
border: 5px solid #f3f3f3;
border-top: 5px solid #3498db;
border-radius: 50%;
width: 50px;
height: 50px;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
</head>
<body>
<div class="container">
<h1>上传Git仓库</h1>
<form id="uploadForm">
<div class="form-group">
<input type="text" id="repoUrl" placeholder="Git仓库地址" required>
</div>
<div class="form-group">
<input type="text" id="userName" placeholder="用户名" required>
</div>
<div class="form-group">
<input type="password" id="token" placeholder="密码/Token" required>
</div>
<button type="submit">提交</button>
</form>
<div id="status"></div>
</div>
<div class="overlay" id="loadingOverlay">
<div class="loading-spinner"></div>
</div>
<script>
const loadingOverlay = document.getElementById('loadingOverlay');
document.getElementById('uploadForm').addEventListener('submit', function(e) {
e.preventDefault();
const repoUrl = document.getElementById('repoUrl').value;
const userName = document.getElementById('userName').value;
const token = document.getElementById('token').value;
loadingOverlay.style.display = 'flex';
document.getElementById('status').textContent = '';
fetch('http://localhost:8090/api/v1/rag/analyze_git_repository', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `repoUrl=${encodeURIComponent(repoUrl)}&userName=${encodeURIComponent(userName)}&token=${encodeURIComponent(token)}`
})
.then(response => response.json())
.then(data => {
loadingOverlay.style.display = 'none';
if (data.code === '0000') {
document.getElementById('status').textContent = '上传成功';
// 成功提示并关闭窗口
setTimeout(() => {
alert('上传成功,窗口即将关闭');
window.close();
}, 500);
} else {
document.getElementById('status').textContent = '上传失败';
}
})
.catch(error => {
loadingOverlay.style.display = 'none';
document.getElementById('status').textContent = '上传仓库时出错';
});
});
</script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

View File

@ -0,0 +1,119 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AiRagKnowledge - By Smile</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/dompurify/dist/purify.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/highlight.js/highlight.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js/styles/github.min.css">
<link rel="stylesheet" href="css/index.css">
</head>
<body class="h-screen flex flex-col bg-gray-50">
<!-- Top Navigation -->
<nav class="border-b bg-white px-4 py-2 flex items-center gap-2">
<button id="toggleSidebar" class="p-2 hover:bg-gray-100 rounded-lg">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 sidebar-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path id="sidebarIconPath" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
</svg>
</button>
<button id="newChatBtn" class="flex items-center gap-2 px-3 py-2 hover:bg-gray-100 rounded-lg">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
</svg>
新聊天
</button>
<div class="flex-1 flex items-center gap-4">
<select id="aiModel" class="px-3 py-2 border rounded-lg flex-1 max-w-xs">
<option value="ollama" model="deepseek-r1:1.5b">deepseek-r1:1.5b</option>
<option value="openai" model="gpt-4o">gpt-4o</option>
</select>
<select id="ragSelect" class="px-3 py-2 border rounded-lg flex-1 max-w-xs">
<option value="">选择一个知识库</option>
</select>
</div>
<div class="flex items-center gap-2">
<div class="relative group">
<button id="uploadMenuButton" class="p-2 hover:bg-gray-100 rounded-lg flex items-center gap-1">
🐙上传知识
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" />
</svg>
</button>
<!-- 下拉菜单 -->
<div class="hidden absolute right-0 mt-2 w-48 bg-white border rounded-md shadow-lg z-50" id="uploadMenu">
<a href="upload.html" target="_blank" class="block px-4 py-2 text-gray-700 hover:bg-gray-100">
📁 上传文件
</a>
<a href="git.html" target="_blank" class="block px-4 py-2 text-gray-700 hover:bg-gray-100">
⎇ 解析仓库Git
</a>
</div>
</div>
</div>
</nav>
<div class="flex-1 flex overflow-hidden">
<!-- 侧边栏结构 -->
<aside id="sidebar" class="w-64 bg-white border-r overflow-y-auto transition-all duration-300 ease-in-out">
<div class="p-4">
<h2 class="font-bold mb-2 text-lg">聊天列表</h2>
<ul id="chatList" class="space-y-1">
<!-- 聊天列表项结构修改 -->
</ul>
</div>
</aside>
<!-- Main Content -->
<div class="flex-1 flex flex-col overflow-hidden">
<!-- Chat Area -->
<main class="flex-1 overflow-auto p-4" id="chatArea">
<div id="welcomeMessage" class="flex items-center justify-center h-full">
<div class="bg-white p-6 rounded-lg shadow-md text-center">
<div class="flex items-center gap-2 justify-center text-gray-500 mb-4">
<span class="w-2 h-2 bg-green-500 rounded-full"></span>
Ollama 正在运行 🐏
</div>
<p class="text-gray-600">开始新的对话吧!</p>
</div>
</div>
</main>
<!-- Input Area -->
<div class="p-4">
<div class="max-w-4xl mx-auto">
<div class="border rounded-lg bg-white">
<div class="flex flex-col">
<textarea
id="messageInput"
class="w-full px-3 py-2 min-h-[100px] focus:outline-none resize-none"
placeholder="输入一条消息..."></textarea>
<div class="flex items-center justify-between px-3 py-2 border-t">
<div class="flex items-center gap-2">
<button class="p-2 hover:bg-gray-100 rounded-lg">🌐</button>
</div>
<button
id="submitBtn"
class="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 flex items-center gap-2">
提交
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
</svg>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="js/index.js"></script>
</body>
</html>

View File

@ -0,0 +1,388 @@
const chatArea = document.getElementById('chatArea');
const messageInput = document.getElementById('messageInput');
const submitBtn = document.getElementById('submitBtn');
const newChatBtn = document.getElementById('newChatBtn');
const chatList = document.getElementById('chatList');
const welcomeMessage = document.getElementById('welcomeMessage');
const toggleSidebarBtn = document.getElementById('toggleSidebar');
const sidebar = document.getElementById('sidebar');
let currentEventSource = null;
let currentChatId = null;
// 获取知识库列表
document.addEventListener('DOMContentLoaded', function() {
// 获取知识库列表
const loadRagOptions = () => {
const ragSelect = document.getElementById('ragSelect');
fetch('http://localhost:8095/api/v1/rag/query_rag_tag_list')
.then(response => response.json())
.then(data => {
if (data.code === '0000' && data.data) {
// 清空现有选项(保留第一个默认选项)
while (ragSelect.options.length > 1) {
ragSelect.remove(1);
}
// 添加新选项
data.data.forEach(tag => {
const option = new Option(`Rag${tag}`, tag);
ragSelect.add(option);
});
}
})
.catch(error => {
console.error('获取知识库列表失败:', error);
});
};
// 初始化加载
loadRagOptions();
});
function createNewChat() {
const chatId = Date.now().toString();
currentChatId = chatId;
localStorage.setItem('currentChatId', chatId);
// 修改数据结构为包含name和messages的对象
localStorage.setItem(`chat_${chatId}`, JSON.stringify({
name: '新聊天',
messages: []
}));
updateChatList();
clearChatArea();
}
function deleteChat(chatId) {
if (confirm('确定要删除这个聊天记录吗?')) {
localStorage.removeItem(`chat_${chatId}`); // Remove the chat from localStorage
if (currentChatId === chatId) { // If the current chat is being deleted
createNewChat(); // Create a new chat
}
updateChatList(); // Update the chat list to reflect changes
}
}
function updateChatList() {
chatList.innerHTML = '';
const chats = Object.keys(localStorage)
.filter(key => key.startsWith('chat_'));
const currentChatIndex = chats.findIndex(key => key.split('_')[1] === currentChatId);
if (currentChatIndex!== -1) {
const currentChat = chats[currentChatIndex];
chats.splice(currentChatIndex, 1);
chats.unshift(currentChat);
}
chats.forEach(chatKey => {
let chatData = JSON.parse(localStorage.getItem(chatKey));
const chatId = chatKey.split('_')[1];
// 数据迁移:将旧数组格式转换为新对象格式
if (Array.isArray(chatData)) {
chatData = {
name: `聊天 ${new Date(parseInt(chatId)).toLocaleDateString()}`,
messages: chatData
};
localStorage.setItem(chatKey, JSON.stringify(chatData));
}
const li = document.createElement('li');
li.className = `chat-item flex items-center justify-between p-2 hover:bg-gray-100 rounded-lg cursor-pointer transition-colors ${chatId === currentChatId? 'bg-blue-50' : ''}`;
li.innerHTML = `
<div class="flex-1">
<div class="text-sm font-medium">${chatData.name}</div>
<div class="text-xs text-gray-400">${new Date(parseInt(chatId)).toLocaleDateString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit' })}</div>
</div>
<div class="chat-actions flex items-center gap-1 opacity-0 transition-opacity duration-200">
<button class="p-1 hover:bg-gray-200 rounded text-gray-500" onclick="renameChat('${chatId}')">重命名</button>
<button class="p-1 hover:bg-red-200 rounded text-red-500" onclick="deleteChat('${chatId}')">删除</button>
</div>
`;
li.addEventListener('click', (e) => {
if (!e.target.closest('.chat-actions')) {
loadChat(chatId);
}
});
li.addEventListener('mouseenter', () => {
li.querySelector('.chat-actions').classList.remove('opacity-0');
});
li.addEventListener('mouseleave', () => {
li.querySelector('.chat-actions').classList.add('opacity-0');
});
chatList.appendChild(li);
});
}
let currentContextMenu = null;
// 优化后的上下文菜单
function showChatContextMenu(event, chatId) {
event.stopPropagation();
closeContextMenu();
const buttonRect = event.target.closest('button').getBoundingClientRect();
const menu = document.createElement('div');
menu.className = 'context-menu';
menu.style.position = 'fixed';
menu.style.left = `${buttonRect.left}px`;
menu.style.top = `${buttonRect.bottom + 4}px`;
menu.innerHTML = `
<div class="context-menu-item" onclick="renameChat('${chatId}')">
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/>
</svg>
重命名
</div>
<div class="context-menu-item text-red-500" onclick="deleteChat('${chatId}')">
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
</svg>
删除
</div>
`;
document.body.appendChild(menu);
currentContextMenu = menu;
// 点击外部关闭菜单
setTimeout(() => {
document.addEventListener('click', closeContextMenu, { once: true });
});
}
function closeContextMenu() {
if (currentContextMenu) {
currentContextMenu.remove();
currentContextMenu = null;
}
}
function renameChat(chatId) {
const chatKey = `chat_${chatId}`;
const chatData = JSON.parse(localStorage.getItem(chatKey));
const currentName = chatData.name || `聊天 ${new Date(parseInt(chatId)).toLocaleString()}`;
const newName = prompt('请输入新的聊天名称', currentName);
if (newName) {
chatData.name = newName;
localStorage.setItem(chatKey, JSON.stringify(chatData));
updateChatList();
}
}
function loadChat(chatId) {
currentChatId = chatId;
localStorage.setItem('currentChatId', chatId);
clearChatArea();
const chatData = JSON.parse(localStorage.getItem(`chat_${chatId}`) || { messages: [] });
chatData.messages.forEach(msg => {
appendMessage(msg.content, msg.isAssistant, false);
});
updateChatList()
}
function clearChatArea() {
chatArea.innerHTML = '';
welcomeMessage.style.display = 'flex';
}
function appendMessage(content, isAssistant = false, saveToStorage = true) {
welcomeMessage.style.display = 'none';
const messageDiv = document.createElement('div');
messageDiv.className = `max-w-4xl mx-auto mb-4 p-4 rounded-lg ${isAssistant ? 'bg-gray-100' : 'bg-white border'} markdown-body relative`;
const renderedContent = DOMPurify.sanitize(marked.parse(content));
messageDiv.innerHTML = renderedContent;
// 添加复制按钮
const copyBtn = document.createElement('button');
copyBtn.className = 'absolute top-2 right-2 p-1 bg-gray-200 rounded-md text-xs';
copyBtn.textContent = '复制';
copyBtn.onclick = () => {
navigator.clipboard.writeText(content).then(() => {
copyBtn.textContent = '已复制';
setTimeout(() => copyBtn.textContent = '复制', 2000);
});
};
messageDiv.appendChild(copyBtn);
chatArea.appendChild(messageDiv);
chatArea.scrollTop = chatArea.scrollHeight;
// 仅在需要时保存到本地存储
if (saveToStorage && currentChatId) {
// 确保读取和保存完整的数据结构
const chatData = JSON.parse(localStorage.getItem(`chat_${currentChatId}`) || '{"name": "新聊天", "messages": []}');
chatData.messages.push({ content, isAssistant });
localStorage.setItem(`chat_${currentChatId}`, JSON.stringify(chatData));
}
}
function startEventStream(message) {
if (currentEventSource) {
currentEventSource.close();
}
// 选项值,
// 组装01http://localhost:8095/api/v1/ollama/generate_stream?message=Hello&model=deepseek-r1:1.5b
// 组装02http://localhost:8095/api/v1/openai/generate_stream?message=Hello&model=gpt-4o
const ragTag = document.getElementById('ragSelect').value;
const aiModelSelect = document.getElementById('aiModel');
const aiModelValue = aiModelSelect.value; // 获取选中的 aiModel 的 value
const aiModelModel = aiModelSelect.options[aiModelSelect.selectedIndex].getAttribute('model'); // 获取选中的 aiModel 的 model 属性
let url;
if (ragTag) {
url = `http://localhost:8095/api/v1/${aiModelValue}/generate_stream_rag?message=${encodeURIComponent(message)}&ragTag=${encodeURIComponent(ragTag)}&model=${encodeURIComponent(aiModelModel)}`;
} else {
url = `http://localhost:8095/api/v1/${aiModelValue}/generate_stream?message=${encodeURIComponent(message)}&model=${encodeURIComponent(aiModelModel)}`;
}
currentEventSource = new EventSource(url);
let accumulatedContent = '';
let tempMessageDiv = null;
currentEventSource.onmessage = function(event) {
try {
const data = JSON.parse(event.data);
if (data.result?.output?.content) {
const newContent = data.result.output.content;
accumulatedContent += newContent;
// 首次创建临时消息容器
if (!tempMessageDiv) {
tempMessageDiv = document.createElement('div');
tempMessageDiv.className = 'max-w-4xl mx-auto mb-4 p-4 rounded-lg bg-gray-100 markdown-body relative';
chatArea.appendChild(tempMessageDiv);
welcomeMessage.style.display = 'none';
}
// 直接更新文本内容先不解析Markdown
tempMessageDiv.textContent = accumulatedContent;
chatArea.scrollTop = chatArea.scrollHeight;
}
if (data.result?.output?.properties?.finishReason === 'STOP') {
currentEventSource.close();
// 流式传输完成后进行最终渲染
const finalContent = accumulatedContent;
tempMessageDiv.innerHTML = DOMPurify.sanitize(marked.parse(finalContent));
// 添加复制按钮
const copyBtn = document.createElement('button');
copyBtn.className = 'absolute top-2 right-2 p-1 bg-gray-200 rounded-md text-xs';
copyBtn.textContent = '复制';
copyBtn.onclick = () => {
navigator.clipboard.writeText(finalContent).then(() => {
copyBtn.textContent = '已复制';
setTimeout(() => copyBtn.textContent = '复制', 2000);
});
};
tempMessageDiv.appendChild(copyBtn);
// 保存到本地存储
if (currentChatId) {
// 正确的数据结构应该是对象包含messages数组
const chatData = JSON.parse(localStorage.getItem(`chat_${currentChatId}`) || '{"name": "新聊天", "messages": []}');
chatData.messages.push({ content: finalContent, isAssistant: true });
localStorage.setItem(`chat_${currentChatId}`, JSON.stringify(chatData));
}
}
} catch (e) {
console.error('Error parsing event data:', e);
}
};
currentEventSource.onerror = function(error) {
console.error('EventSource error:', error);
currentEventSource.close();
};
}
submitBtn.addEventListener('click', () => {
const message = messageInput.value.trim();
if (!message) return;
if (!currentChatId) {
createNewChat();
}
appendMessage(message, false);
messageInput.value = '';
startEventStream(message);
});
messageInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
submitBtn.click();
}
});
newChatBtn.addEventListener('click', createNewChat);
toggleSidebarBtn.addEventListener('click', () => {
sidebar.classList.toggle('-translate-x-full');
updateSidebarIcon();
});
function updateSidebarIcon() {
const iconPath = document.getElementById('sidebarIconPath');
if (sidebar.classList.contains('-translate-x-full')) {
iconPath.setAttribute('d', 'M4 6h16M4 12h4m12 0h-4M4 18h16');
} else {
iconPath.setAttribute('d', 'M4 6h16M4 12h16M4 18h16');
}
}
// Initialize
updateChatList();
const savedChatId = localStorage.getItem('currentChatId');
if (savedChatId) {
loadChat(savedChatId);
}
// Handle window resize for responsive design
window.addEventListener('resize', () => {
if (window.innerWidth > 768) {
sidebar.classList.remove('-translate-x-full');
} else {
sidebar.classList.add('-translate-x-full');
}
});
// Initial check for mobile devices
if (window.innerWidth <= 768) {
sidebar.classList.add('-translate-x-full');
}
updateSidebarIcon();
// 上传知识下拉菜单控制
const uploadMenuButton = document.getElementById('uploadMenuButton');
const uploadMenu = document.getElementById('uploadMenu');
// 切换菜单显示
uploadMenuButton.addEventListener('click', (e) => {
e.stopPropagation();
uploadMenu.classList.toggle('hidden');
});
// 点击外部区域关闭菜单
document.addEventListener('click', (e) => {
if (!uploadMenu.contains(e.target) && e.target !== uploadMenuButton) {
uploadMenu.classList.add('hidden');
}
});
// 菜单项点击后关闭菜单
document.querySelectorAll('#uploadMenu a').forEach(item => {
item.addEventListener('click', () => {
uploadMenu.classList.add('hidden');
});
});

View File

@ -0,0 +1,158 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>文件上传</title>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="https://cdn.tailwindcss.com"></script>
<style>
/* 加载动画 */
.loader {
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
</head>
<body class="flex justify-center items-center min-h-screen bg-gray-100">
<!-- 上传文件模态框 -->
<div class="bg-white p-6 rounded-lg shadow-lg w-96 relative">
<!-- 加载遮罩层 -->
<div id="loadingOverlay" class="hidden absolute inset-0 bg-white bg-opacity-90 flex flex-col items-center justify-center rounded-lg">
<div class="loader mb-4">
<svg class="h-8 w-8 text-blue-600" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 2V6" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
<path d="M12 18V22" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
<path d="M4.93 4.93L7.76 7.76" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
<path d="M16.24 16.24L19.07 19.07" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
<path d="M2 12H6" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
<path d="M18 12H22" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
<path d="M4.93 19.07L7.76 16.24" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
<path d="M16.24 7.76L19.07 4.93" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
</svg>
</div>
<p class="text-gray-600">文件上传中,请稍候...</p>
</div>
<h2 class="text-xl font-semibold text-center mb-4">添加知识</h2>
<form id="uploadForm" enctype="multipart/form-data">
<!-- 知识标题输入 -->
<div class="mb-4">
<label for="title" class="block text-sm font-medium text-gray-700">知识标题</label>
<input type="text" id="title" name="title" class="mt-1 block w-full p-2 border border-gray-300 rounded-md" placeholder="输入知识标题" required />
</div>
<!-- 上传文件区域 -->
<div class="mb-4">
<label for="file" class="block text-sm font-medium text-gray-700">上传文件</label>
<div class="mt-2 border-dashed border-2 border-gray-300 p-4 text-center text-gray-500">
<input type="file" id="file" name="file" accept=".pdf,.csv,.txt,.md,.sql,.java" class="hidden" multiple />
<label for="file" class="cursor-pointer">
<div>将文件拖到此处或点击上传</div>
<div class="mt-2 text-sm text-gray-400">支持的文件类型:.pdf, .csv, .txt, .md, .sql, .java</div>
</label>
</div>
</div>
<!-- 待上传文件列表 -->
<div class="mb-4" id="fileList">
<ul class="list-disc pl-5 text-gray-700"></ul>
</div>
<!-- 提交按钮 -->
<div class="flex justify-center">
<button type="submit" class="bg-blue-600 text-white py-2 px-4 rounded-lg hover:bg-blue-700">
提交
</button>
</div>
</form>
</div>
<script>
const fileListElement = document.querySelector('#fileList ul');
// 文件选择变更处理
document.getElementById('file').addEventListener('change', function (e) {
const files = Array.from(e.target.files);
fileListElement.innerHTML = ''; // 清空列表
files.forEach((file, index) => {
const listItem = document.createElement('li');
listItem.className = 'flex justify-between items-center';
listItem.innerHTML = `
<span>${file.name}</span>
<button type="button" class="text-red-500 hover:text-red-700" onclick="removeFile(${index})">删除</button>
`;
fileListElement.appendChild(listItem);
});
});
// 移除文件
function removeFile(index) {
const input = document.getElementById('file');
let files = Array.from(input.files);
files.splice(index, 1);
// 创建一个新的DataTransfer对象
const dataTransfer = new DataTransfer();
files.forEach(file => dataTransfer.items.add(file));
// 更新文件输入对象的文件列表
input.files = dataTransfer.files;
// 更新文件列表UI
const fileListItems = fileListElement.children;
fileListItems[index].remove();
}
// 提交事件处理
document.getElementById('uploadForm').addEventListener('submit', function (e) {
e.preventDefault();
const loadingOverlay = document.getElementById('loadingOverlay');
const input = document.getElementById('file');
const files = Array.from(input.files);
if (files.length === 0) {
alert('请先选择一个文件');
return;
}
// 显示加载状态
loadingOverlay.classList.remove('hidden');
const formData = new FormData();
formData.append('ragTag', document.getElementById('title').value);
files.forEach(file => formData.append('file', file));
axios.post('http://localhost:8090/api/v1/rag/file/upload', formData)
.then(response => {
if (response.data.code === '0000') {
// 成功提示并关闭窗口
setTimeout(() => {
alert('上传成功,窗口即将关闭');
window.close();
}, 500);
} else {
throw new Error(response.data.info || '上传失败');
}
})
.catch(error => {
alert(error.message);
})
.finally(() => {
// 隐藏加载状态
loadingOverlay.classList.add('hidden');
// 清空表单(无论成功与否)
input.value = '';
document.getElementById('title').value = '';
fileListElement.innerHTML = '';
});
});
</script>
</body>
</html>

View File

@ -0,0 +1,14 @@
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- Ollamanomic-embed-text768 维
CREATE SCHEMA IF NOT EXISTS ollama;
DROP TABLE IF EXISTS ollama.vector_store;
CREATE TABLE ollama.vector_store (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
content TEXT NOT NULL,
metadata JSONB,
embedding VECTOR(768)
);

View File

@ -0,0 +1,2 @@
bind 0.0.0.0
port 6379

128
docs/tag/v1.0/api/curl.json Normal file
View File

@ -0,0 +1,128 @@
[
{
"result": {
"output": {
"messageType": "ASSISTANT",
"properties": {
"id": "chatcmpl-B3HPw95SsqmhoWeJ8azGLxK1Vf4At",
"role": "ASSISTANT",
"finishReason": ""
},
"content": "1",
"media": []
},
"metadata": {
"finishReason": null,
"contentFilterMetadata": null
}
}
},
{
"result": {
"output": {
"messageType": "ASSISTANT",
"properties": {
"id": "chatcmpl-B3HPw95SsqmhoWeJ8azGLxK1Vf4At",
"role": "ASSISTANT",
"finishReason": ""
},
"content": " +",
"media": []
},
"metadata": {
"finishReason": null,
"contentFilterMetadata": null
}
}
},
{
"result": {
"output": {
"messageType": "ASSISTANT",
"properties": {
"id": "chatcmpl-B3HPw95SsqmhoWeJ8azGLxK1Vf4At",
"role": "ASSISTANT",
"finishReason": ""
},
"content": " ",
"media": []
},
"metadata": {
"finishReason": null,
"contentFilterMetadata": null
}
}
},
{
"result": {
"output": {
"messageType": "ASSISTANT",
"properties": {
"id": "chatcmpl-B3HPw95SsqmhoWeJ8azGLxK1Vf4At",
"role": "ASSISTANT",
"finishReason": ""
},
"content": "1",
"media": []
},
"metadata": {
"finishReason": null,
"contentFilterMetadata": null
}
}
},
{
"result": {
"output": {
"messageType": "ASSISTANT",
"properties": {
"id": "chatcmpl-B3HPw95SsqmhoWeJ8azGLxK1Vf4At",
"role": "ASSISTANT",
"finishReason": ""
},
"content": " equals",
"media": []
},
"metadata": {
"finishReason": null,
"contentFilterMetadata": null
}
}
},
{
"result": {
"output": {
"messageType": "ASSISTANT",
"properties": {
"id": "chatcmpl-B3HPw95SsqmhoWeJ8azGLxK1Vf4At",
"role": "ASSISTANT",
"finishReason": ""
},
"content": "2",
"media": []
},
"metadata": {
"finishReason": null,
"contentFilterMetadata": null
}
}
},
{
"result": {
"output": {
"messageType": "ASSISTANT",
"properties": {
"id": "chatcmpl-B3HPw95SsqmhoWeJ8azGLxK1Vf4At",
"role": "ASSISTANT",
"finishReason": "STOP"
},
"content": null,
"media": []
},
"metadata": {
"finishReason": "STOP",
"contentFilterMetadata": null
}
}
}
]

View File

@ -0,0 +1,9 @@
# A. 测试 embeddingsnomic-embed-text
curl -s http://localhost:11434/api/embeddings \
-H "Content-Type: application/json" \
-d '{"model":"nomic-embed-text","input":"hello"}'
# B. 测试 generatedeepseek-r1:1.5b
curl -s http://localhost:11434/api/generate \
-H "Content-Type: application/json" \
-d '{"model":"deepseek-r1:1.5b","prompt":"say hi"}'

View File

@ -0,0 +1,39 @@
version: '3.8'
# docker-compose -f docker-compose-app-v1.0.yml up -d
services:
# 部署前端项目
nginx:
image: nginx:alpine
container_name: nginx
restart: unless-stopped
ports:
- '8096:80'
volumes:
- ./nginx/html:/usr/share/nginx/html:ro
- ./nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro
privileged: true
networks:
- my-network
# ai-rag-knowledge
ai-rag-knowledge-app:
build:
context: ../../.. # 从 docs/tag/v1.0 回到项目根
dockerfile: ai-rag-knowledge-app/Dockerfile
image: smile/ai-rag-knowledge-app:latest
container_name: ai-rag-knowledge-app
restart: unless-stopped
ports:
- "8095:8095"
volumes:
- ./log:/data/log
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
networks:
- my-network
networks:
my-network:
driver: bridge

View File

@ -0,0 +1,68 @@
# docker-compose -f docker-compose-environment-aliyun.yml up -d
version: '3'
services:
# 对话模型
# ollama pull deepseek-r1:1.5b
# 运行模型
# ollama run deepseek-r1:1.5b
# 联网模型
# ollama pull nomic-embed-text
ollama:
image: registry.cn-hangzhou.aliyuncs.com/xfg-studio/ollama:0.5.10
volumes:
- ./ollama:/root/.ollama
container_name: ollama
restart: unless-stopped
ports:
- "11434:11434"
networks:
- ai-rag-knowledge-network
redis:
image: registry.cn-hangzhou.aliyuncs.com/xfg-studio/redis:6.2
container_name: rag-redis
restart: always
hostname: redis
privileged: true
ports:
- 26379:6379
volumes:
- ./redis/redis.conf:/usr/local/etc/redis/redis.conf
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- ai-rag-knowledge-network
healthcheck:
test: [ "CMD", "redis-cli", "ping" ]
interval: 10s
timeout: 5s
retries: 3
#向量库
vector_db:
image: registry.cn-hangzhou.aliyuncs.com/xfg-studio/pgvector:v0.5.0
container_name: vector_db
restart: always
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=ai-rag-knowledge
- PGPASSWORD=postgres
volumes:
- ./pgvector/sql/init.sql:/docker-entrypoint-initdb.d/init.sql
logging:
options:
max-size: 10m
max-file: "3"
ports:
- '15432:5432'
healthcheck:
test: "pg_isready -U postgres -d ai-rag-knowledge"
interval: 2s
timeout: 20s
retries: 10
networks:
- ai-rag-knowledge-network
networks:
ai-rag-knowledge-network:
driver: bridge

View File

@ -0,0 +1,62 @@
# docker-comopse -f docker-compose-environment.yml up -d
version: '3'
services:
# 对话模型
# ollama pull deepseek-r1:1.5b
# 运行模型
# ollama run deepseek-r1:1.5b
# 联网模型
# ollama pull nomic-embed-text
ollama:
image: ollama/ollama:0.5.10
container_name: ollama
restart: unless-stopped
ports:
- "11434:11434"
redis:
image: redis:6.2
container_name: redis
restart: always
hostname: redis
privileged: true
ports:
- 26379:6379
volumes:
- ./redis/redis.conf:/usr/local/etc/redis/redis.conf
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- ai-rag-knowledge-network
healthcheck:
test: [ "CMD", "redis-cli", "ping" ]
interval: 10s
timeout: 5s
retries: 3
vector_db:
image: pgvector/pgvector:v0.5.0
container_name: vector_db
restart: always
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=springai
- PGPASSWORD=postgres
volumes:
- ./pgvector/sql/init.sql:/docker-entrypoint-initdb.d/init.sql
logging:
options:
max-size: 10m
max-file: "3"
ports:
- '5432:5432'
healthcheck:
test: "pg_isready -U postgres -d vector_store"
interval: 2s
timeout: 20s
retries: 10
networks:
- ai-rag-knowledge-network
networks:
ai-rag-knowledge-network:
driver: bridge

View File

@ -0,0 +1,20 @@
25-07-28.21:24:55.145 [main ] INFO Application - Starting Application v1.0 using Java 17.0.2 with PID 1 (/app.jar started by root in /)
25-07-28.21:24:55.150 [main ] INFO Application - The following 1 profile is active: "dev"
25-07-28.21:24:56.064 [main ] INFO RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
25-07-28.21:24:56.067 [main ] INFO RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
25-07-28.21:24:56.097 [main ] INFO RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 14 ms. Found 0 Redis repository interfaces.
25-07-28.21:24:56.879 [main ] INFO TomcatWebServer - Tomcat initialized with port 8095 (http)
25-07-28.21:24:56.891 [main ] INFO Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8095"]
25-07-28.21:24:56.893 [main ] INFO StandardService - Starting service [Tomcat]
25-07-28.21:24:56.894 [main ] INFO StandardEngine - Starting Servlet engine: [Apache Tomcat/10.1.19]
25-07-28.21:24:56.936 [main ] INFO [/] - Initializing Spring embedded WebApplicationContext
25-07-28.21:24:56.936 [main ] INFO ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 1688 ms
25-07-28.21:24:57.400 [main ] INFO HikariDataSource - HikariCP - Starting...
25-07-28.21:24:57.627 [main ] INFO HikariPool - HikariCP - Added connection org.postgresql.jdbc.PgConnection@1c2dd89b
25-07-28.21:24:57.629 [main ] INFO HikariDataSource - HikariCP - Start completed.
25-07-28.21:25:01.124 [main ] INFO Version - Redisson 3.44.0
25-07-28.21:25:01.444 [redisson-netty-1-5] INFO ConnectionsHolder - 1 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-28.21:25:01.491 [redisson-netty-1-13] INFO ConnectionsHolder - 5 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-28.21:25:02.123 [main ] INFO Http11NioProtocol - Starting ProtocolHandler ["http-nio-8095"]
25-07-28.21:25:02.135 [main ] INFO TomcatWebServer - Tomcat started on port 8095 (http) with context path ''
25-07-28.21:25:02.146 [main ] INFO Application - Started Application in 7.872 seconds (process running for 8.608)

View File

View File

@ -0,0 +1,166 @@
25-07-29.08:46:26.334 [main ] INFO Application - Starting Application v1.0 using Java 17.0.2 with PID 1 (/app.jar started by root in /)
25-07-29.08:46:26.343 [main ] INFO Application - The following 1 profile is active: "dev"
25-07-29.08:46:27.850 [main ] INFO RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
25-07-29.08:46:27.857 [main ] INFO RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
25-07-29.08:46:27.927 [main ] INFO RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 27 ms. Found 0 Redis repository interfaces.
25-07-29.08:46:29.637 [main ] INFO TomcatWebServer - Tomcat initialized with port 8095 (http)
25-07-29.08:46:29.656 [main ] INFO Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8095"]
25-07-29.08:46:29.661 [main ] INFO StandardService - Starting service [Tomcat]
25-07-29.08:46:29.661 [main ] INFO StandardEngine - Starting Servlet engine: [Apache Tomcat/10.1.19]
25-07-29.08:46:29.739 [main ] INFO [/] - Initializing Spring embedded WebApplicationContext
25-07-29.08:46:29.741 [main ] INFO ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 3239 ms
25-07-29.08:46:30.753 [main ] INFO HikariDataSource - HikariCP - Starting...
25-07-29.08:46:31.046 [main ] INFO HikariPool - HikariCP - Added connection org.postgresql.jdbc.PgConnection@7dd45c93
25-07-29.08:46:31.049 [main ] INFO HikariDataSource - HikariCP - Start completed.
25-07-29.08:46:36.257 [main ] INFO Version - Redisson 3.44.0
25-07-29.08:46:36.850 [redisson-netty-1-4] INFO ConnectionsHolder - 1 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-29.08:46:36.921 [redisson-netty-1-13] INFO ConnectionsHolder - 5 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-29.08:46:38.094 [main ] INFO Http11NioProtocol - Starting ProtocolHandler ["http-nio-8095"]
25-07-29.08:46:38.110 [main ] INFO TomcatWebServer - Tomcat started on port 8095 (http) with context path ''
25-07-29.08:46:38.124 [main ] INFO Application - Started Application in 13.451 seconds (process running for 14.471)
25-07-29.08:51:25.055 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown initiated...
25-07-29.08:51:25.059 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown completed.
25-07-29.08:51:40.866 [main ] INFO Application - Starting Application v1.0 using Java 17.0.2 with PID 1 (/app.jar started by root in /)
25-07-29.08:51:40.876 [main ] INFO Application - The following 1 profile is active: "dev"
25-07-29.08:51:41.638 [main ] INFO RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
25-07-29.08:51:41.641 [main ] INFO RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
25-07-29.08:51:41.665 [main ] INFO RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 11 ms. Found 0 Redis repository interfaces.
25-07-29.08:51:42.318 [main ] INFO TomcatWebServer - Tomcat initialized with port 8095 (http)
25-07-29.08:51:42.326 [main ] INFO Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8095"]
25-07-29.08:51:42.328 [main ] INFO StandardService - Starting service [Tomcat]
25-07-29.08:51:42.329 [main ] INFO StandardEngine - Starting Servlet engine: [Apache Tomcat/10.1.19]
25-07-29.08:51:42.369 [main ] INFO [/] - Initializing Spring embedded WebApplicationContext
25-07-29.08:51:42.370 [main ] INFO ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 1395 ms
25-07-29.08:51:42.702 [main ] INFO HikariDataSource - HikariCP - Starting...
25-07-29.08:51:42.868 [main ] INFO HikariPool - HikariCP - Added connection org.postgresql.jdbc.PgConnection@7e3ee128
25-07-29.08:51:42.869 [main ] INFO HikariDataSource - HikariCP - Start completed.
25-07-29.08:51:46.030 [main ] INFO Version - Redisson 3.44.0
25-07-29.08:51:46.329 [redisson-netty-1-5] INFO ConnectionsHolder - 1 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-29.08:51:46.371 [redisson-netty-1-13] INFO ConnectionsHolder - 5 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-29.08:51:47.114 [main ] INFO Http11NioProtocol - Starting ProtocolHandler ["http-nio-8095"]
25-07-29.08:51:47.132 [main ] INFO TomcatWebServer - Tomcat started on port 8095 (http) with context path ''
25-07-29.08:51:47.148 [main ] INFO Application - Started Application in 7.034 seconds (process running for 7.668)
25-07-29.09:04:24.859 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown initiated...
25-07-29.09:04:24.865 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown completed.
25-07-29.09:04:35.408 [main ] INFO Application - Starting Application v1.0 using Java 17.0.2 with PID 1 (/app.jar started by root in /)
25-07-29.09:04:35.412 [main ] INFO Application - The following 1 profile is active: "dev"
25-07-29.09:04:36.258 [main ] INFO RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
25-07-29.09:04:36.261 [main ] INFO RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
25-07-29.09:04:36.291 [main ] INFO RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 13 ms. Found 0 Redis repository interfaces.
25-07-29.09:04:36.989 [main ] INFO TomcatWebServer - Tomcat initialized with port 8095 (http)
25-07-29.09:04:36.999 [main ] INFO Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8095"]
25-07-29.09:04:37.001 [main ] INFO StandardService - Starting service [Tomcat]
25-07-29.09:04:37.001 [main ] INFO StandardEngine - Starting Servlet engine: [Apache Tomcat/10.1.19]
25-07-29.09:04:37.043 [main ] INFO [/] - Initializing Spring embedded WebApplicationContext
25-07-29.09:04:37.044 [main ] INFO ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 1536 ms
25-07-29.09:04:37.484 [main ] INFO HikariDataSource - HikariCP - Starting...
25-07-29.09:04:37.701 [main ] INFO HikariPool - HikariCP - Added connection org.postgresql.jdbc.PgConnection@7e3ee128
25-07-29.09:04:37.702 [main ] INFO HikariDataSource - HikariCP - Start completed.
25-07-29.09:04:40.658 [main ] INFO Version - Redisson 3.44.0
25-07-29.09:04:40.910 [redisson-netty-1-4] INFO ConnectionsHolder - 1 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-29.09:04:40.948 [redisson-netty-1-13] INFO ConnectionsHolder - 5 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-29.09:04:41.615 [main ] INFO Http11NioProtocol - Starting ProtocolHandler ["http-nio-8095"]
25-07-29.09:04:41.624 [main ] INFO TomcatWebServer - Tomcat started on port 8095 (http) with context path ''
25-07-29.09:04:41.632 [main ] INFO Application - Started Application in 7.051 seconds (process running for 7.813)
25-07-29.09:26:52.922 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown initiated...
25-07-29.09:26:52.925 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown completed.
25-07-29.09:28:58.726 [main ] INFO Application - Starting Application v1.0 using Java 17.0.2 with PID 1 (/app.jar started by root in /)
25-07-29.09:28:58.730 [main ] INFO Application - The following 1 profile is active: "dev"
25-07-29.09:28:59.560 [main ] INFO RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
25-07-29.09:28:59.563 [main ] INFO RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
25-07-29.09:28:59.595 [main ] INFO RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 14 ms. Found 0 Redis repository interfaces.
25-07-29.09:29:00.294 [main ] INFO TomcatWebServer - Tomcat initialized with port 8095 (http)
25-07-29.09:29:00.306 [main ] INFO Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8095"]
25-07-29.09:29:00.308 [main ] INFO StandardService - Starting service [Tomcat]
25-07-29.09:29:00.308 [main ] INFO StandardEngine - Starting Servlet engine: [Apache Tomcat/10.1.19]
25-07-29.09:29:00.349 [main ] INFO [/] - Initializing Spring embedded WebApplicationContext
25-07-29.09:29:00.349 [main ] INFO ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 1535 ms
25-07-29.09:29:00.755 [main ] INFO HikariDataSource - HikariCP - Starting...
25-07-29.09:29:00.938 [main ] INFO HikariPool - HikariCP - Added connection org.postgresql.jdbc.PgConnection@8383a14
25-07-29.09:29:00.940 [main ] INFO HikariDataSource - HikariCP - Start completed.
25-07-29.09:29:04.144 [main ] INFO Version - Redisson 3.44.0
25-07-29.09:29:04.413 [redisson-netty-1-5] INFO ConnectionsHolder - 1 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-29.09:29:04.451 [redisson-netty-1-13] INFO ConnectionsHolder - 5 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-29.09:29:05.056 [main ] INFO Http11NioProtocol - Starting ProtocolHandler ["http-nio-8095"]
25-07-29.09:29:05.069 [main ] INFO TomcatWebServer - Tomcat started on port 8095 (http) with context path ''
25-07-29.09:29:05.078 [main ] INFO Application - Started Application in 7.161 seconds (process running for 7.867)
25-07-29.09:29:58.580 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown initiated...
25-07-29.09:29:58.582 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown completed.
25-07-29.09:30:20.134 [main ] INFO Application - Starting Application v1.0 using Java 17.0.2 with PID 1 (/app.jar started by root in /)
25-07-29.09:30:20.139 [main ] INFO Application - The following 1 profile is active: "dev"
25-07-29.09:30:20.995 [main ] INFO RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
25-07-29.09:30:20.998 [main ] INFO RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
25-07-29.09:30:21.032 [main ] INFO RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 14 ms. Found 0 Redis repository interfaces.
25-07-29.09:30:21.718 [main ] INFO TomcatWebServer - Tomcat initialized with port 8095 (http)
25-07-29.09:30:21.728 [main ] INFO Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8095"]
25-07-29.09:30:21.731 [main ] INFO StandardService - Starting service [Tomcat]
25-07-29.09:30:21.732 [main ] INFO StandardEngine - Starting Servlet engine: [Apache Tomcat/10.1.19]
25-07-29.09:30:21.771 [main ] INFO [/] - Initializing Spring embedded WebApplicationContext
25-07-29.09:30:21.772 [main ] INFO ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 1534 ms
25-07-29.09:30:22.137 [main ] INFO HikariDataSource - HikariCP - Starting...
25-07-29.09:30:22.308 [main ] INFO HikariPool - HikariCP - Added connection org.postgresql.jdbc.PgConnection@374b6e33
25-07-29.09:30:22.310 [main ] INFO HikariDataSource - HikariCP - Start completed.
25-07-29.09:30:22.970 [main ] INFO Version - Redisson 3.44.0
25-07-29.09:30:23.231 [redisson-netty-1-5] INFO ConnectionsHolder - 1 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-29.09:30:23.271 [redisson-netty-1-13] INFO ConnectionsHolder - 5 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-29.09:30:24.044 [main ] INFO Http11NioProtocol - Starting ProtocolHandler ["http-nio-8095"]
25-07-29.09:30:24.053 [main ] INFO TomcatWebServer - Tomcat started on port 8095 (http) with context path ''
25-07-29.09:30:24.063 [main ] INFO Application - Started Application in 4.689 seconds (process running for 5.236)
25-07-29.09:30:24.980 [http-nio-8095-exec-1] INFO [/] - Initializing Spring DispatcherServlet 'dispatcherServlet'
25-07-29.09:30:24.981 [http-nio-8095-exec-1] INFO DispatcherServlet - Initializing Servlet 'dispatcherServlet'
25-07-29.09:30:24.982 [http-nio-8095-exec-1] INFO DispatcherServlet - Completed initialization in 1 ms
25-07-29.09:31:54.384 [http-nio-8095-exec-2] INFO OllamaController - generate_stream called!
25-07-29.09:44:47.629 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown initiated...
25-07-29.09:44:47.633 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown completed.
25-07-29.09:45:42.997 [main ] INFO Application - Starting Application v1.0 using Java 17.0.2 with PID 1 (/app.jar started by root in /)
25-07-29.09:45:43.002 [main ] INFO Application - The following 1 profile is active: "dev"
25-07-29.09:45:43.847 [main ] INFO RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
25-07-29.09:45:43.850 [main ] INFO RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
25-07-29.09:45:43.880 [main ] INFO RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 12 ms. Found 0 Redis repository interfaces.
25-07-29.09:45:44.636 [main ] INFO TomcatWebServer - Tomcat initialized with port 8095 (http)
25-07-29.09:45:44.648 [main ] INFO Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8095"]
25-07-29.09:45:44.649 [main ] INFO StandardService - Starting service [Tomcat]
25-07-29.09:45:44.649 [main ] INFO StandardEngine - Starting Servlet engine: [Apache Tomcat/10.1.19]
25-07-29.09:45:44.693 [main ] INFO [/] - Initializing Spring embedded WebApplicationContext
25-07-29.09:45:44.693 [main ] INFO ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 1578 ms
25-07-29.09:45:45.142 [main ] INFO HikariDataSource - HikariCP - Starting...
25-07-29.09:45:45.363 [main ] INFO HikariPool - HikariCP - Added connection org.postgresql.jdbc.PgConnection@6ba060af
25-07-29.09:45:45.365 [main ] INFO HikariDataSource - HikariCP - Start completed.
25-07-29.09:45:48.289 [main ] INFO Version - Redisson 3.44.0
25-07-29.09:45:48.586 [redisson-netty-1-4] INFO ConnectionsHolder - 1 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-29.09:45:48.623 [redisson-netty-1-13] INFO ConnectionsHolder - 5 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-29.09:45:49.297 [main ] INFO Http11NioProtocol - Starting ProtocolHandler ["http-nio-8095"]
25-07-29.09:45:49.310 [main ] INFO TomcatWebServer - Tomcat started on port 8095 (http) with context path ''
25-07-29.09:45:49.321 [main ] INFO Application - Started Application in 7.098 seconds (process running for 7.853)
25-07-29.09:45:51.712 [http-nio-8095-exec-1] INFO [/] - Initializing Spring DispatcherServlet 'dispatcherServlet'
25-07-29.09:45:51.713 [http-nio-8095-exec-1] INFO DispatcherServlet - Initializing Servlet 'dispatcherServlet'
25-07-29.09:45:51.713 [http-nio-8095-exec-1] INFO DispatcherServlet - Completed initialization in 0 ms
25-07-29.09:51:07.030 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown initiated...
25-07-29.09:51:07.032 [SpringApplicationShutdownHook] INFO HikariDataSource - HikariCP - Shutdown completed.
25-07-29.09:51:16.935 [main ] INFO Application - Starting Application v1.0 using Java 17.0.2 with PID 1 (/app.jar started by root in /)
25-07-29.09:51:16.940 [main ] INFO Application - The following 1 profile is active: "dev"
25-07-29.09:51:17.677 [main ] INFO RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
25-07-29.09:51:17.680 [main ] INFO RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
25-07-29.09:51:17.708 [main ] INFO RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 12 ms. Found 0 Redis repository interfaces.
25-07-29.09:51:18.510 [main ] INFO TomcatWebServer - Tomcat initialized with port 8095 (http)
25-07-29.09:51:18.521 [main ] INFO Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8095"]
25-07-29.09:51:18.524 [main ] INFO StandardService - Starting service [Tomcat]
25-07-29.09:51:18.524 [main ] INFO StandardEngine - Starting Servlet engine: [Apache Tomcat/10.1.19]
25-07-29.09:51:18.572 [main ] INFO [/] - Initializing Spring embedded WebApplicationContext
25-07-29.09:51:18.572 [main ] INFO ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 1540 ms
25-07-29.09:51:18.994 [main ] INFO HikariDataSource - HikariCP - Starting...
25-07-29.09:51:19.185 [main ] INFO HikariPool - HikariCP - Added connection org.postgresql.jdbc.PgConnection@192b472d
25-07-29.09:51:19.187 [main ] INFO HikariDataSource - HikariCP - Start completed.
25-07-29.09:51:22.365 [main ] INFO Version - Redisson 3.44.0
25-07-29.09:51:22.643 [redisson-netty-1-4] INFO ConnectionsHolder - 1 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-29.09:51:22.681 [redisson-netty-1-13] INFO ConnectionsHolder - 5 connections initialized for 192.168.10.218/192.168.10.218:26379
25-07-29.09:51:23.441 [main ] INFO Http11NioProtocol - Starting ProtocolHandler ["http-nio-8095"]
25-07-29.09:51:23.451 [main ] INFO TomcatWebServer - Tomcat started on port 8095 (http) with context path ''
25-07-29.09:51:23.461 [main ] INFO Application - Started Application in 7.317 seconds (process running for 7.862)
25-07-29.09:51:35.181 [http-nio-8095-exec-1] INFO [/] - Initializing Spring DispatcherServlet 'dispatcherServlet'
25-07-29.09:51:35.181 [http-nio-8095-exec-1] INFO DispatcherServlet - Initializing Servlet 'dispatcherServlet'
25-07-29.09:51:35.182 [http-nio-8095-exec-1] INFO DispatcherServlet - Completed initialization in 0 ms
25-07-29.09:51:35.206 [http-nio-8095-exec-1] INFO OllamaController - generate_stream called!
25-07-29.09:53:05.853 [http-nio-8095-exec-5] INFO RAGController - 上传知识库开始草稿1
25-07-29.09:53:06.647 [http-nio-8095-exec-5] INFO RAGController - 上传知识库完成草稿1
25-07-29.09:53:30.890 [http-nio-8095-exec-7] INFO OllamaController - generate_stream_rag called!

View File

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<mirrors>
<mirror>
<id>mirror</id>
<mirrorOf>central,jcenter,!2452122-release-dbuebF</mirrorOf>
<name>mirror</name>
<url>https://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
</mirrors>
<servers>
<server>
<id>2452122-release-dbuebF</id>
<username>65b081c2242105ca211dd310</username>
<password>gbO-rXbOv(VT</password>
</server>
</servers>
<profiles>
<profile>
<id>rdc</id>
<properties>
<altReleaseDeploymentRepository>
2452122-release-dbuebF::default::https://packages.aliyun.com/65b081d4076e069afe3d2f50/maven/2452122-release-dbuebf
</altReleaseDeploymentRepository>
</properties>
<repositories>
<repository>
<id>central</id>
<url>https://maven.aliyun.com/nexus/content/groups/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>snapshots</id>
<url>https://maven.aliyun.com/nexus/content/groups/public</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>2452122-release-dbuebF</id>
<url>https://packages.aliyun.com/65b081d4076e069afe3d2f50/maven/2452122-release-dbuebf</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<url>https://maven.aliyun.com/nexus/content/groups/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>snapshots</id>
<url>https://maven.aliyun.com/nexus/content/groups/public</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>2452122-release-dbuebF</id>
<url>https://packages.aliyun.com/65b081d4076e069afe3d2f50/maven/2452122-release-dbuebf</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>rdc</activeProfile>
</activeProfiles>
</settings>

View File

@ -0,0 +1,41 @@
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# (可选)如果你有上游定义,也写在这里
upstream ai_rag_backend {
server ai-rag-knowledge-app:8095;
}
# 你的 server
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
location /api/ {
proxy_pass http://ai-rag-knowledge-app:8095;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location / {
try_files $uri /index.html;
}
}
}

View File

@ -0,0 +1,10 @@
pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*!
Theme: GitHub
Description: Light theme as seen on github.com
Author: github.com
Maintainer: @Hirse
Updated: 2021-05-15
Outdated base version: https://github.com/primer/github-syntax-light
Current colors taken from GitHub's CSS
*/.hljs{color:#24292e;background:#fff}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#005cc5}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-code,.hljs-comment,.hljs-formula{color:#6a737d}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{color:#005cc5;font-weight:700}.hljs-bullet{color:#735c0f}.hljs-emphasis{color:#24292e;font-style:italic}.hljs-strong{color:#24292e;font-weight:700}.hljs-addition{color:#22863a;background-color:#f0fff4}.hljs-deletion{color:#b31d28;background-color:#ffeef0}

View File

@ -0,0 +1,86 @@
.chat-item {
@apply flex items-center gap-2 p-2 hover:bg-gray-100 rounded cursor-pointer transition-colors;
}
.chat-item.selected {
@apply bg-blue-50; /* 或使用深色背景如bg-gray-200 */
}
.chat-item-content {
@apply flex-1 truncate;
}
.chat-actions {
@apply flex items-center justify-end opacity-0 transition-opacity w-8;
}
.chat-item:hover.chat-actions {
@apply opacity-100;
}
.context-menu {
@apply absolute bg-white border rounded-lg shadow-lg py-1 z-50;
min-width: 120px;
}
.context-menu-item {
@apply px-4 py-2 hover:bg-gray-100 text-sm flex items-center gap-2;
}
.markdown-body {
font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji;
font-size: 16px;
line-height: 1.5;
word-wrap: break-word;
}
.markdown-body pre {
background-color: #f6f8fa;
border-radius: 6px;
padding: 16px;
overflow-x: auto;
}
.markdown-body code {
background-color: rgba(175,184,193,0.2);
border-radius: 6px;
padding: 0.2em 0.4em;
font-size: 85%;
}
.markdown-body pre code {
background-color: transparent;
padding: 0;
font-size: 100%;
}
.markdown-body h1,.markdown-body h2,.markdown-body h3,
.markdown-body h4,.markdown-body h5,.markdown-body h6 {
margin-top: 24px;
margin-bottom: 16px;
font-weight: 600;
line-height: 1.25;
}
.markdown-body h1 { font-size: 2em; }
.markdown-body h2 { font-size: 1.5em; }
.markdown-body h3 { font-size: 1.25em; }
.markdown-body ul,.markdown-body ol {
padding-left: 2em;
}
.markdown-body ul { list-style-type: disc; }
.markdown-body ol { list-style-type: decimal; }
.markdown-body table {
border-spacing: 0;
border-collapse: collapse;
margin-top: 0;
margin-bottom: 16px;
}
.markdown-body table th,.markdown-body table td {
padding: 6px 13px;
border: 1px solid #d0d7de;
}
.markdown-body table tr:nth-child(2n) {
background-color: #f6f8fa;
}
.chat-actions button {
margin-left: 4px; /* Add some space between buttons */
}
/* 下拉菜单过渡动画 */
#uploadMenu {
transition: all 0.2s ease-out;
transform-origin: top right;
}
#uploadMenu a {
transition: background-color 0.2s ease;
}

View File

@ -0,0 +1,146 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>解析仓库</title>
<style>
body {
font-family: 'Microsoft YaHei', '微软雅黑', sans-serif;
background-color: #f0f0f0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.container {
background-color: white;
padding: 2rem;
border-radius: 10px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
text-align: center;
width: 300px;
}
h1 {
color: #333;
margin-bottom: 1.5rem;
}
.form-group {
margin-bottom: 1rem;
}
input {
width: 100%;
padding: 0.5rem;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 1rem;
box-sizing: border-box;
}
button {
background-color: #1E90FF;
color: white;
border: none;
padding: 0.5rem 1rem;
font-size: 1rem;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s;
width: 100%;
}
button:hover {
background-color: #4169E1;
}
#status {
margin-top: 1rem;
font-weight: bold;
}
.overlay {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
z-index: 1000;
justify-content: center;
align-items: center;
}
.loading-spinner {
border: 5px solid #f3f3f3;
border-top: 5px solid #3498db;
border-radius: 50%;
width: 50px;
height: 50px;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
</head>
<body>
<div class="container">
<h1>上传Git仓库</h1>
<form id="uploadForm">
<div class="form-group">
<input type="text" id="repoUrl" placeholder="Git仓库地址" required>
</div>
<div class="form-group">
<input type="text" id="userName" placeholder="用户名" required>
</div>
<div class="form-group">
<input type="password" id="token" placeholder="密码/Token" required>
</div>
<button type="submit">提交</button>
</form>
<div id="status"></div>
</div>
<div class="overlay" id="loadingOverlay">
<div class="loading-spinner"></div>
</div>
<script>
const loadingOverlay = document.getElementById('loadingOverlay');
document.getElementById('uploadForm').addEventListener('submit', function(e) {
e.preventDefault();
const repoUrl = document.getElementById('repoUrl').value;
const userName = document.getElementById('userName').value;
const token = document.getElementById('token').value;
loadingOverlay.style.display = 'flex';
document.getElementById('status').textContent = '';
fetch('/api/v1/rag/analyze_git_repository', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `repoUrl=${encodeURIComponent(repoUrl)}&userName=${encodeURIComponent(userName)}&token=${encodeURIComponent(token)}`
})
.then(response => response.json())
.then(data => {
loadingOverlay.style.display = 'none';
if (data.code === '0000') {
document.getElementById('status').textContent = '上传成功';
// 成功提示并关闭窗口
setTimeout(() => {
alert('上传成功,窗口即将关闭');
window.close();
}, 500);
} else {
document.getElementById('status').textContent = '上传失败';
}
})
.catch(error => {
loadingOverlay.style.display = 'none';
document.getElementById('status').textContent = '上传仓库时出错';
});
});
</script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

View File

@ -0,0 +1,119 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AiRagKnowledge - By Smile</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="js/marked.min.js"></script>
<script src="js/purify.min.js"></script>
<script src="js/highlight.min.js"></script>
<link rel="stylesheet" href="css/github.min.css">
<link rel="stylesheet" href="css/index.css">
</head>
<body class="h-screen flex flex-col bg-gray-50">
<!-- Top Navigation -->
<nav class="border-b bg-white px-4 py-2 flex items-center gap-2">
<button id="toggleSidebar" class="p-2 hover:bg-gray-100 rounded-lg">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 sidebar-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path id="sidebarIconPath" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
</svg>
</button>
<button id="newChatBtn" class="flex items-center gap-2 px-3 py-2 hover:bg-gray-100 rounded-lg">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
</svg>
新聊天
</button>
<div class="flex-1 flex items-center gap-4">
<select id="aiModel" class="px-3 py-2 border rounded-lg flex-1 max-w-xs">
<option value="ollama" model="deepseek-r1:1.5b">deepseek-r1:1.5b</option>
<option value="openai" model="gpt-4o">gpt-4o</option>
</select>
<select id="ragSelect" class="px-3 py-2 border rounded-lg flex-1 max-w-xs">
<option value="">选择一个知识库</option>
</select>
</div>
<div class="flex items-center gap-2">
<div class="relative group">
<button id="uploadMenuButton" class="p-2 hover:bg-gray-100 rounded-lg flex items-center gap-1">
🐙上传知识
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" />
</svg>
</button>
<!-- 下拉菜单 -->
<div class="hidden absolute right-0 mt-2 w-48 bg-white border rounded-md shadow-lg z-50" id="uploadMenu">
<a href="upload.html" target="_blank" class="block px-4 py-2 text-gray-700 hover:bg-gray-100">
📁 上传文件
</a>
<a href="git.html" target="_blank" class="block px-4 py-2 text-gray-700 hover:bg-gray-100">
⎇ 解析仓库Git
</a>
</div>
</div>
</div>
</nav>
<div class="flex-1 flex overflow-hidden">
<!-- 侧边栏结构 -->
<aside id="sidebar" class="w-64 bg-white border-r overflow-y-auto transition-all duration-300 ease-in-out">
<div class="p-4">
<h2 class="font-bold mb-2 text-lg">聊天列表</h2>
<ul id="chatList" class="space-y-1">
<!-- 聊天列表项结构修改 -->
</ul>
</div>
</aside>
<!-- Main Content -->
<div class="flex-1 flex flex-col overflow-hidden">
<!-- Chat Area -->
<main class="flex-1 overflow-auto p-4" id="chatArea">
<div id="welcomeMessage" class="flex items-center justify-center h-full">
<div class="bg-white p-6 rounded-lg shadow-md text-center">
<div class="flex items-center gap-2 justify-center text-gray-500 mb-4">
<span class="w-2 h-2 bg-green-500 rounded-full"></span>
Ollama 正在运行 🐏
</div>
<p class="text-gray-600">开始新的对话吧!</p>
</div>
</div>
</main>
<!-- Input Area -->
<div class="p-4">
<div class="max-w-4xl mx-auto">
<div class="border rounded-lg bg-white">
<div class="flex flex-col">
<textarea
id="messageInput"
class="w-full px-3 py-2 min-h-[100px] focus:outline-none resize-none"
placeholder="输入一条消息..."></textarea>
<div class="flex items-center justify-between px-3 py-2 border-t">
<div class="flex items-center gap-2">
<button class="p-2 hover:bg-gray-100 rounded-lg">🌐</button>
</div>
<button
id="submitBtn"
class="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 flex items-center gap-2">
提交
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
</svg>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="js/index.js"></script>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,394 @@
const chatArea = document.getElementById('chatArea');
const messageInput = document.getElementById('messageInput');
const submitBtn = document.getElementById('submitBtn');
const newChatBtn = document.getElementById('newChatBtn');
const chatList = document.getElementById('chatList');
const welcomeMessage = document.getElementById('welcomeMessage');
const toggleSidebarBtn = document.getElementById('toggleSidebar');
const sidebar = document.getElementById('sidebar');
let currentEventSource = null;
let currentChatId = null;
// 获取知识库列表
document.addEventListener('DOMContentLoaded', function() {
// 获取知识库列表
const loadRagOptions = () => {
const ragSelect = document.getElementById('ragSelect');
fetch('/api/v1/rag/query_rag_tag_list')
.then(response => response.json())
.then(data => {
if (data.code === '0000' && data.data) {
// 清空现有选项(保留第一个默认选项)
while (ragSelect.options.length > 1) {
ragSelect.remove(1);
}
// 添加新选项
data.data.forEach(tag => {
const option = new Option(`Rag${tag}`, tag);
ragSelect.add(option);
});
}
})
.catch(error => {
console.error('获取知识库列表失败:', error);
});
};
// 初始化加载
loadRagOptions();
});
function createNewChat() {
const chatId = Date.now().toString();
currentChatId = chatId;
localStorage.setItem('currentChatId', chatId);
// 修改数据结构为包含name和messages的对象
localStorage.setItem(`chat_${chatId}`, JSON.stringify({
name: '新聊天',
messages: []
}));
updateChatList();
clearChatArea();
}
function deleteChat(chatId) {
if (confirm('确定要删除这个聊天记录吗?')) {
localStorage.removeItem(`chat_${chatId}`); // Remove the chat from localStorage
if (currentChatId === chatId) { // If the current chat is being deleted
createNewChat(); // Create a new chat
}
updateChatList(); // Update the chat list to reflect changes
}
}
function updateChatList() {
chatList.innerHTML = '';
const chats = Object.keys(localStorage)
.filter(key => key.startsWith('chat_'));
const currentChatIndex = chats.findIndex(key => key.split('_')[1] === currentChatId);
if (currentChatIndex!== -1) {
const currentChat = chats[currentChatIndex];
chats.splice(currentChatIndex, 1);
chats.unshift(currentChat);
}
chats.forEach(chatKey => {
let chatData = JSON.parse(localStorage.getItem(chatKey));
const chatId = chatKey.split('_')[1];
// 数据迁移:将旧数组格式转换为新对象格式
if (Array.isArray(chatData)) {
chatData = {
name: `聊天 ${new Date(parseInt(chatId)).toLocaleDateString()}`,
messages: chatData
};
localStorage.setItem(chatKey, JSON.stringify(chatData));
}
const li = document.createElement('li');
li.className = `chat-item flex items-center justify-between p-2 hover:bg-gray-100 rounded-lg cursor-pointer transition-colors ${chatId === currentChatId? 'bg-blue-50' : ''}`;
li.innerHTML = `
<div class="flex-1">
<div class="text-sm font-medium">${chatData.name}</div>
<div class="text-xs text-gray-400">${new Date(parseInt(chatId)).toLocaleDateString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit' })}</div>
</div>
<div class="chat-actions flex items-center gap-1 opacity-0 transition-opacity duration-200">
<button class="p-1 hover:bg-gray-200 rounded text-gray-500" onclick="renameChat('${chatId}')">重命名</button>
<button class="p-1 hover:bg-red-200 rounded text-red-500" onclick="deleteChat('${chatId}')">删除</button>
</div>
`;
li.addEventListener('click', (e) => {
if (!e.target.closest('.chat-actions')) {
loadChat(chatId);
}
});
li.addEventListener('mouseenter', () => {
li.querySelector('.chat-actions').classList.remove('opacity-0');
});
li.addEventListener('mouseleave', () => {
li.querySelector('.chat-actions').classList.add('opacity-0');
});
chatList.appendChild(li);
});
}
let currentContextMenu = null;
// 优化后的上下文菜单
function showChatContextMenu(event, chatId) {
event.stopPropagation();
closeContextMenu();
const buttonRect = event.target.closest('button').getBoundingClientRect();
const menu = document.createElement('div');
menu.className = 'context-menu';
menu.style.position = 'fixed';
menu.style.left = `${buttonRect.left}px`;
menu.style.top = `${buttonRect.bottom + 4}px`;
menu.innerHTML = `
<div class="context-menu-item" onclick="renameChat('${chatId}')">
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/>
</svg>
重命名
</div>
<div class="context-menu-item text-red-500" onclick="deleteChat('${chatId}')">
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
</svg>
删除
</div>
`;
document.body.appendChild(menu);
currentContextMenu = menu;
// 点击外部关闭菜单
setTimeout(() => {
document.addEventListener('click', closeContextMenu, { once: true });
});
}
function closeContextMenu() {
if (currentContextMenu) {
currentContextMenu.remove();
currentContextMenu = null;
}
}
function renameChat(chatId) {
const chatKey = `chat_${chatId}`;
const chatData = JSON.parse(localStorage.getItem(chatKey));
const currentName = chatData.name || `聊天 ${new Date(parseInt(chatId)).toLocaleString()}`;
const newName = prompt('请输入新的聊天名称', currentName);
if (newName) {
chatData.name = newName;
localStorage.setItem(chatKey, JSON.stringify(chatData));
updateChatList();
}
}
function loadChat(chatId) {
currentChatId = chatId;
localStorage.setItem('currentChatId', chatId);
clearChatArea();
const chatData = JSON.parse(localStorage.getItem(`chat_${chatId}`) || { messages: [] });
chatData.messages.forEach(msg => {
appendMessage(msg.content, msg.isAssistant, false);
});
updateChatList()
}
function clearChatArea() {
chatArea.innerHTML = '';
welcomeMessage.style.display = 'flex';
}
function appendMessage(content, isAssistant = false, saveToStorage = true) {
welcomeMessage.style.display = 'none';
const messageDiv = document.createElement('div');
messageDiv.className = `max-w-4xl mx-auto mb-4 p-4 rounded-lg ${isAssistant ? 'bg-gray-100' : 'bg-white border'} markdown-body relative`;
const renderedContent = DOMPurify.sanitize(marked.parse(content));
messageDiv.innerHTML = renderedContent;
// 添加复制按钮
const copyBtn = document.createElement('button');
copyBtn.className = 'absolute top-2 right-2 p-1 bg-gray-200 rounded-md text-xs';
copyBtn.textContent = '复制';
copyBtn.onclick = () => {
navigator.clipboard.writeText(content).then(() => {
copyBtn.textContent = '已复制';
setTimeout(() => copyBtn.textContent = '复制', 2000);
});
};
messageDiv.appendChild(copyBtn);
chatArea.appendChild(messageDiv);
chatArea.scrollTop = chatArea.scrollHeight;
// 仅在需要时保存到本地存储
if (saveToStorage && currentChatId) {
// 确保读取和保存完整的数据结构
const chatData = JSON.parse(localStorage.getItem(`chat_${currentChatId}`) || '{"name": "新聊天", "messages": []}');
chatData.messages.push({ content, isAssistant });
localStorage.setItem(`chat_${currentChatId}`, JSON.stringify(chatData));
}
}
function startEventStream(message) {
if (currentEventSource) {
currentEventSource.close();
}
// 选项值,
// 组装01/api/v1/ollama/generate_stream?message=Hello&model=deepseek-r1:1.5b
// 组装02/api/v1/openai/generate_stream?message=Hello&model=gpt-4o
const ragTag = document.getElementById('ragSelect').value;
const aiModelSelect = document.getElementById('aiModel');
const aiModelValue = aiModelSelect.value; // 获取选中的 aiModel 的 value
const aiModelModel = aiModelSelect.options[aiModelSelect.selectedIndex].getAttribute('model'); // 获取选中的 aiModel 的 model 属性
let url;
const base = `/api/v1/${aiModelValue}`;
const params = new URLSearchParams({
message,
model: aiModelModel
});
if (ragTag) {
params.append('ragTag', ragTag);
url = `${base}/generate_stream_rag?${params.toString()}`;
} else {
url = `${base}/generate_stream?${params.toString()}`;
}
currentEventSource = new EventSource(url);
let accumulatedContent = '';
let tempMessageDiv = null;
currentEventSource.onmessage = function(event) {
try {
const data = JSON.parse(event.data);
if (data.result?.output?.content) {
const newContent = data.result.output.content;
accumulatedContent += newContent;
// 首次创建临时消息容器
if (!tempMessageDiv) {
tempMessageDiv = document.createElement('div');
tempMessageDiv.className = 'max-w-4xl mx-auto mb-4 p-4 rounded-lg bg-gray-100 markdown-body relative';
chatArea.appendChild(tempMessageDiv);
welcomeMessage.style.display = 'none';
}
// 直接更新文本内容先不解析Markdown
tempMessageDiv.textContent = accumulatedContent;
chatArea.scrollTop = chatArea.scrollHeight;
}
if (data.result?.output?.properties?.finishReason === 'STOP') {
currentEventSource.close();
// 流式传输完成后进行最终渲染
const finalContent = accumulatedContent;
tempMessageDiv.innerHTML = DOMPurify.sanitize(marked.parse(finalContent));
// 添加复制按钮
const copyBtn = document.createElement('button');
copyBtn.className = 'absolute top-2 right-2 p-1 bg-gray-200 rounded-md text-xs';
copyBtn.textContent = '复制';
copyBtn.onclick = () => {
navigator.clipboard.writeText(finalContent).then(() => {
copyBtn.textContent = '已复制';
setTimeout(() => copyBtn.textContent = '复制', 2000);
});
};
tempMessageDiv.appendChild(copyBtn);
// 保存到本地存储
if (currentChatId) {
// 正确的数据结构应该是对象包含messages数组
const chatData = JSON.parse(localStorage.getItem(`chat_${currentChatId}`) || '{"name": "新聊天", "messages": []}');
chatData.messages.push({ content: finalContent, isAssistant: true });
localStorage.setItem(`chat_${currentChatId}`, JSON.stringify(chatData));
}
}
} catch (e) {
console.error('Error parsing event data:', e);
}
};
currentEventSource.onerror = function(error) {
console.error('EventSource error:', error);
currentEventSource.close();
};
}
submitBtn.addEventListener('click', () => {
const message = messageInput.value.trim();
if (!message) return;
if (!currentChatId) {
createNewChat();
}
appendMessage(message, false);
messageInput.value = '';
startEventStream(message);
});
messageInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
submitBtn.click();
}
});
newChatBtn.addEventListener('click', createNewChat);
toggleSidebarBtn.addEventListener('click', () => {
sidebar.classList.toggle('-translate-x-full');
updateSidebarIcon();
});
function updateSidebarIcon() {
const iconPath = document.getElementById('sidebarIconPath');
if (sidebar.classList.contains('-translate-x-full')) {
iconPath.setAttribute('d', 'M4 6h16M4 12h4m12 0h-4M4 18h16');
} else {
iconPath.setAttribute('d', 'M4 6h16M4 12h16M4 18h16');
}
}
// Initialize
updateChatList();
const savedChatId = localStorage.getItem('currentChatId');
if (savedChatId) {
loadChat(savedChatId);
}
// Handle window resize for responsive design
window.addEventListener('resize', () => {
if (window.innerWidth > 768) {
sidebar.classList.remove('-translate-x-full');
} else {
sidebar.classList.add('-translate-x-full');
}
});
// Initial check for mobile devices
if (window.innerWidth <= 768) {
sidebar.classList.add('-translate-x-full');
}
updateSidebarIcon();
// 上传知识下拉菜单控制
const uploadMenuButton = document.getElementById('uploadMenuButton');
const uploadMenu = document.getElementById('uploadMenu');
// 切换菜单显示
uploadMenuButton.addEventListener('click', (e) => {
e.stopPropagation();
uploadMenu.classList.toggle('hidden');
});
// 点击外部区域关闭菜单
document.addEventListener('click', (e) => {
if (!uploadMenu.contains(e.target) && e.target !== uploadMenuButton) {
uploadMenu.classList.add('hidden');
}
});
// 菜单项点击后关闭菜单
document.querySelectorAll('#uploadMenu a').forEach(item => {
item.addEventListener('click', () => {
uploadMenu.classList.add('hidden');
});
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,158 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>文件上传</title>
<script src="js/axios.min.js"></script>
<script src="https://cdn.tailwindcss.com"></script>
<style>
/* 加载动画 */
.loader {
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
</head>
<body class="flex justify-center items-center min-h-screen bg-gray-100">
<!-- 上传文件模态框 -->
<div class="bg-white p-6 rounded-lg shadow-lg w-96 relative">
<!-- 加载遮罩层 -->
<div id="loadingOverlay" class="hidden absolute inset-0 bg-white bg-opacity-90 flex flex-col items-center justify-center rounded-lg">
<div class="loader mb-4">
<svg class="h-8 w-8 text-blue-600" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 2V6" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
<path d="M12 18V22" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
<path d="M4.93 4.93L7.76 7.76" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
<path d="M16.24 16.24L19.07 19.07" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
<path d="M2 12H6" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
<path d="M18 12H22" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
<path d="M4.93 19.07L7.76 16.24" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
<path d="M16.24 7.76L19.07 4.93" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
</svg>
</div>
<p class="text-gray-600">文件上传中,请稍候...</p>
</div>
<h2 class="text-xl font-semibold text-center mb-4">添加知识</h2>
<form id="uploadForm" enctype="multipart/form-data">
<!-- 知识标题输入 -->
<div class="mb-4">
<label for="title" class="block text-sm font-medium text-gray-700">知识标题</label>
<input type="text" id="title" name="title" class="mt-1 block w-full p-2 border border-gray-300 rounded-md" placeholder="输入知识标题" required />
</div>
<!-- 上传文件区域 -->
<div class="mb-4">
<label for="file" class="block text-sm font-medium text-gray-700">上传文件</label>
<div class="mt-2 border-dashed border-2 border-gray-300 p-4 text-center text-gray-500">
<input type="file" id="file" name="file" accept=".pdf,.csv,.txt,.md,.sql,.java" class="hidden" multiple />
<label for="file" class="cursor-pointer">
<div>将文件拖到此处或点击上传</div>
<div class="mt-2 text-sm text-gray-400">支持的文件类型:.pdf, .csv, .txt, .md, .sql, .java</div>
</label>
</div>
</div>
<!-- 待上传文件列表 -->
<div class="mb-4" id="fileList">
<ul class="list-disc pl-5 text-gray-700"></ul>
</div>
<!-- 提交按钮 -->
<div class="flex justify-center">
<button type="submit" class="bg-blue-600 text-white py-2 px-4 rounded-lg hover:bg-blue-700">
提交
</button>
</div>
</form>
</div>
<script>
const fileListElement = document.querySelector('#fileList ul');
// 文件选择变更处理
document.getElementById('file').addEventListener('change', function (e) {
const files = Array.from(e.target.files);
fileListElement.innerHTML = ''; // 清空列表
files.forEach((file, index) => {
const listItem = document.createElement('li');
listItem.className = 'flex justify-between items-center';
listItem.innerHTML = `
<span>${file.name}</span>
<button type="button" class="text-red-500 hover:text-red-700" onclick="removeFile(${index})">删除</button>
`;
fileListElement.appendChild(listItem);
});
});
// 移除文件
function removeFile(index) {
const input = document.getElementById('file');
let files = Array.from(input.files);
files.splice(index, 1);
// 创建一个新的DataTransfer对象
const dataTransfer = new DataTransfer();
files.forEach(file => dataTransfer.items.add(file));
// 更新文件输入对象的文件列表
input.files = dataTransfer.files;
// 更新文件列表UI
const fileListItems = fileListElement.children;
fileListItems[index].remove();
}
// 提交事件处理
document.getElementById('uploadForm').addEventListener('submit', function (e) {
e.preventDefault();
const loadingOverlay = document.getElementById('loadingOverlay');
const input = document.getElementById('file');
const files = Array.from(input.files);
if (files.length === 0) {
alert('请先选择一个文件');
return;
}
// 显示加载状态
loadingOverlay.classList.remove('hidden');
const formData = new FormData();
formData.append('ragTag', document.getElementById('title').value);
files.forEach(file => formData.append('file', file));
axios.post('/api/v1/rag/file/upload', formData)
.then(response => {
if (response.data.code === '0000') {
// 成功提示并关闭窗口
setTimeout(() => {
alert('上传成功,窗口即将关闭');
window.close();
}, 500);
} else {
throw new Error(response.data.info || '上传失败');
}
})
.catch(error => {
alert(error.message);
})
.finally(() => {
// 隐藏加载状态
loadingOverlay.classList.add('hidden');
// 清空表单(无论成功与否)
input.value = '';
document.getElementById('title').value = '';
fileListElement.innerHTML = '';
});
});
</script>
</body>
</html>

View File

@ -0,0 +1,14 @@
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- Ollamanomic-embed-text768 维
CREATE SCHEMA IF NOT EXISTS ollama;
DROP TABLE IF EXISTS ollama.vector_store;
CREATE TABLE ollama.vector_store (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
content TEXT NOT NULL,
metadata JSONB,
embedding VECTOR(768)
);

View File

@ -0,0 +1,2 @@
bind 0.0.0.0
port 6379

162
pom.xml Normal file
View File

@ -0,0 +1,162 @@
<?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>
<groupId>edu.whut</groupId>
<artifactId>ai-rag-knowledge</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<modules>
<module>ai-rag-knowledge-api</module>
<module>ai-rag-knowledge-app</module>
<module>ai-rag-knowledge-trigger</module>
</modules>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-ai.version>0.8.1</spring-ai.version>
</properties>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.3</version>
<relativePath/>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.28</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.3-jre</version>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.44.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>5.13.0.202109080827-r</version>
</dependency>
<dependency>
<groupId>edu.whut</groupId>
<artifactId>ai-rag-knowledge-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>edu.whut</groupId>
<artifactId>ai-rag-knowledge-trigger</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.7</version>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<java_jvm>-Xms1G -Xmx1G -server -XX:MaxPermSize=256M -Xss256K -Dspring.profiles.active=test -XX:+DisableExplicitGC -XX:+UseG1GC -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/export/Logs/xfg-frame-archetype-lite-boot -Xloggc:/export/Logs/xfg-frame-archetype-lite-boot/gc-xfg-frame-archetype-lite-boot.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps</java_jvm>
<profileActive>dev</profileActive>
</properties>
</profile>
<profile>
<id>test</id>
<properties>
<java_jvm>-Xms1G -Xmx1G -server -XX:MaxPermSize=256M -Xss256K -Dspring.profiles.active=test -XX:+DisableExplicitGC -XX:+UseG1GC -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/export/Logs/xfg-frame-archetype-lite-boot -Xloggc:/export/Logs/xfg-frame-archetype-lite-boot/gc-xfg-frame-archetype-lite-boot.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps</java_jvm>
<profileActive>test</profileActive>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<java_jvm>-Xms6G -Xmx6G -server -XX:MaxPermSize=256M -Xss256K -Dspring.profiles.active=release -XX:+DisableExplicitGC -XX:+UseG1GC -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/export/Logs/fq-mall-activity-app -Xloggc:/export/Logs/xfg-frame-archetype-lite-boot/gc-xfg-frame-archetype-lite-boot.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps</java_jvm>
<profileActive>prod</profileActive>
</properties>
</profile>
</profiles>
</project>