Commit 0ed098fff2617fadfe96a4de41c9114ea1fca368

Authored by qianbao
1 parent 38cc822b

添加未清选择 改成动态引导语

... ... @@ -18,228 +18,115 @@
18 18 <packaging>war</packaging>
19 19 <name>xlyAi</name>
20 20 <description>xlyAi</description>
  21 +
21 22 <properties>
22 23 <java.version>17</java.version>
23 24 <mybatis-spring.version>3.0.4</mybatis-spring.version>
24 25 <pagehelper.version>2.1.0</pagehelper.version>
25 26 <mapstruct.version>1.5.5.Final</mapstruct.version>
26 27 <fastjson.version>2.0.50</fastjson.version>
27   - <jsoup.version>2.0.50</jsoup.version>
28   - <langchain4j.version>0.35.0</langchain4j.version>
29   - <!-- AI 服务商 SDK 版本 -->
30   - <openai-java.version>0.20.0</openai-java.version>
31   - <anthropic-sdk.version>1.7.4</anthropic-sdk.version>
32   - <!-- 工具类 -->
  28 + <langchain4j.version>1.14.0</langchain4j.version>
  29 + <langchain4j-emb.version>1.14.0-beta24</langchain4j-emb.version>
33 30 <lombok.version>1.18.34</lombok.version>
34 31 <hutool.version>5.8.28</hutool.version>
35 32 <okhttp.version>4.10.0</okhttp.version>
36 33 <springdoc.version>2.5.0</springdoc.version>
37   - <mapstruct.version>1.5.5.Final</mapstruct.version>
38   - <!-- JSON 处理 -->
39 34 <jackson.version>2.17.2</jackson.version>
40   - <json-schema.version>1.17.2</json-schema.version>
41   - <!-- 向量数据 -->
42 35 <milvus.version>2.6.15</milvus.version>
43 36 <tess4j.version>5.18.0</tess4j.version>
  37 + <jakarta-validation.version>3.1.0</jakarta-validation.version>
44 38 </properties>
45 39  
46 40 <dependencies>
47   - <!-- Spring Boot Starters -->
  41 + <!-- Spring Boot -->
48 42 <dependency>
49 43 <groupId>org.springframework.boot</groupId>
50 44 <artifactId>spring-boot-starter-web</artifactId>
51 45 </dependency>
52   -
53   - <!-- Milvus Java SDK 核心依赖 -->
54   - <dependency>
55   - <groupId>io.milvus</groupId>
56   - <artifactId>milvus-sdk-java</artifactId>
57   - <version>${milvus.version}</version>
58   - </dependency>
59   -
60   - <dependency>
61   - <groupId>dev.langchain4j</groupId>
62   - <artifactId>langchain4j-embeddings-all-minilm-l6-v2</artifactId>
63   - <version>${langchain4j.version}</version>
64   - </dependency>
65   -
66   -<!-- <dependency>-->
67   -<!-- <groupId>com.baomidou</groupId>-->
68   -<!-- <artifactId>mybatis-plus-boot-starter</artifactId>-->
69   -<!-- <version>3.5.3.1</version>-->
70   -<!-- </dependency>-->
71   -
72 46 <dependency>
73 47 <groupId>org.springframework.boot</groupId>
74 48 <artifactId>spring-boot-starter-actuator</artifactId>
75 49 </dependency>
76   -
77 50 <dependency>
78 51 <groupId>org.springframework.boot</groupId>
79 52 <artifactId>spring-boot-starter-validation</artifactId>
80 53 </dependency>
81 54 <dependency>
82   - <groupId>com.alibaba</groupId>
83   - <artifactId>fastjson</artifactId>
84   - <version>2.0.47</version> <!-- 最新稳定版 -->
85   - </dependency>
86   - <dependency>
87 55 <groupId>org.springframework.boot</groupId>
88 56 <artifactId>spring-boot-starter-aop</artifactId>
89 57 </dependency>
90   -
91   - <dependency>
92   - <groupId>com.google.code.gson</groupId>
93   - <artifactId>gson</artifactId>
94   - <version>2.10.1</version>
95   - </dependency>
96   -
97   - <!-- Spring Cloud Context 依赖 -->
98   - <dependency>
99   - <groupId>org.springframework.cloud</groupId>
100   - <artifactId>spring-cloud-context</artifactId>
101   - <version>4.1.0</version> <!-- 根据你的Spring Boot版本选择 -->
102   - </dependency>
103   -
104 58 <dependency>
105 59 <groupId>org.springframework.boot</groupId>
106   - <artifactId>spring-boot-starter-webflux</artifactId>
107   - </dependency>
108   - <!-- pom.xml -->
109   - <dependency>
110   - <groupId>com.github.jsqlparser</groupId>
111   - <artifactId>jsqlparser</artifactId>
112   - <version>4.9</version>
113   - </dependency>
114   -
115   - <!-- Tess4J OCR -->
116   - <dependency>
117   - <groupId>net.sourceforge.tess4j</groupId>
118   - <artifactId>tess4j</artifactId>
119   - <version>${tess4j.version}</version>
120   - </dependency>
121   -
122   - <!-- 官方 PaddleOCR Java SDK(最新稳定版) -->
123   - <dependency>
124   - <groupId>io.github.mymonstercat</groupId>
125   - <artifactId>rapidocr</artifactId>
126   - <version>0.0.7</version>
  60 + <artifactId>spring-boot-starter-thymeleaf</artifactId>
127 61 </dependency>
128   -
129 62 <dependency>
130   - <groupId>io.github.mymonstercat</groupId>
131   - <artifactId>rapidocr-onnx-platform</artifactId>
132   - <version>0.0.7</version>
  63 + <groupId>org.springframework.boot</groupId>
  64 + <artifactId>spring-boot-starter-data-redis</artifactId>
133 65 </dependency>
134   -
135   - <!-- ONNX Runtime(必需) -->
136   -<!-- <dependency>-->
137   -<!-- <groupId>com.microsoft.onnxruntime</groupId>-->
138   -<!-- <artifactId>onnxruntime</artifactId>-->
139   -<!-- <version>1.17.0</version>-->
140   -<!-- </dependency>-->
141   -
142   - <!-- 图片处理 -->
143 66 <dependency>
144   - <groupId>commons-io</groupId>
145   - <artifactId>commons-io</artifactId>
146   - <version>2.15.1</version>
  67 + <groupId>org.apache.commons</groupId>
  68 + <artifactId>commons-pool2</artifactId>
147 69 </dependency>
148   -
149   -
150 70 <dependency>
151 71 <groupId>org.springframework.boot</groupId>
152   - <artifactId>spring-boot-starter-thymeleaf</artifactId>
  72 + <artifactId>spring-boot-starter-webflux</artifactId>
153 73 </dependency>
154 74 <dependency>
155 75 <groupId>org.springframework.boot</groupId>
156   - <artifactId>spring-boot-starter-data-redis</artifactId>
  76 + <artifactId>spring-boot-starter-test</artifactId>
  77 + <scope>test</scope>
157 78 </dependency>
158   - <!-- 如果需要连接池,可以引入 commons-pool2 (可选) -->
159 79 <dependency>
160   - <groupId>org.apache.commons</groupId>
161   - <artifactId>commons-pool2</artifactId>
  80 + <groupId>org.springframework.boot</groupId>
  81 + <artifactId>spring-boot-devtools</artifactId>
  82 + <optional>true</optional>
162 83 </dependency>
163 84  
164   - <!-- MyBatis -->
  85 + <!-- 数据库 & MyBatis -->
165 86 <dependency>
166 87 <groupId>org.mybatis.spring.boot</groupId>
167 88 <artifactId>mybatis-spring-boot-starter</artifactId>
168 89 <version>${mybatis-spring.version}</version>
169 90 </dependency>
170   -
171   - <!-- 数据库 -->
172 91 <dependency>
173 92 <groupId>com.mysql</groupId>
174 93 <artifactId>mysql-connector-j</artifactId>
175 94 <scope>runtime</scope>
176 95 </dependency>
177   -
178   - <!-- 连接池(Spring Boot 3.x 默认包含 HikariCP) -->
179 96 <dependency>
180 97 <groupId>com.zaxxer</groupId>
181 98 <artifactId>HikariCP</artifactId>
182 99 </dependency>
183   -
184   - <!-- 分页插件 -->
185 100 <dependency>
186 101 <groupId>com.github.pagehelper</groupId>
187 102 <artifactId>pagehelper-spring-boot-starter</artifactId>
188 103 <version>${pagehelper.version}</version>
189 104 </dependency>
190 105  
191   - <!-- Maven依赖 -->
192   - <dependency>
193   - <groupId>org.jsoup</groupId>
194   - <artifactId>jsoup</artifactId>
195   - <version>${json-schema.version}</version>
196   - </dependency>
197   -
198 106 <!-- 工具类 -->
199 107 <dependency>
200 108 <groupId>org.projectlombok</groupId>
201 109 <artifactId>lombok</artifactId>
202 110 <optional>true</optional>
203 111 </dependency>
204   -
205 112 <dependency>
206 113 <groupId>cn.hutool</groupId>
207 114 <artifactId>hutool-all</artifactId>
208 115 <version>${hutool.version}</version>
209 116 </dependency>
210   -
211 117 <dependency>
212   - <groupId>cglib</groupId>
213   - <artifactId>cglib</artifactId>
214   - <version>3.3.0</version>
215   - </dependency>
216   - <!-- pom.xml -->
217   - <dependency>
218   - <groupId>org.codehaus.groovy</groupId>
219   - <artifactId>groovy</artifactId>
220   - <version>3.0.20</version> <!-- 或者 4.0.0+ -->
221   - </dependency>
222   -
223   - <!-- 如果需要 Groovy 编译支持 -->
224   - <dependency>
225   - <groupId>org.codehaus.groovy</groupId>
226   - <artifactId>groovy-all</artifactId>
227   - <version>3.0.20</version>
228   - <type>pom</type>
  118 + <groupId>com.google.code.gson</groupId>
  119 + <artifactId>gson</artifactId>
229 120 </dependency>
230   -
231   - <!-- MapStruct -->
232 121 <dependency>
233   - <groupId>org.mapstruct</groupId>
234   - <artifactId>mapstruct</artifactId>
235   - <version>${mapstruct.version}</version>
  122 + <groupId>commons-io</groupId>
  123 + <artifactId>commons-io</artifactId>
  124 + <version>2.15.1</version>
236 125 </dependency>
237   -
238 126 <dependency>
239   - <groupId>org.mapstruct</groupId>
240   - <artifactId>mapstruct-processor</artifactId>
241   - <version>${mapstruct.version}</version>
242   - <scope>provided</scope>
  127 + <groupId>com.squareup.okhttp3</groupId>
  128 + <artifactId>okhttp</artifactId>
  129 + <version>${okhttp.version}</version>
243 130 </dependency>
244 131  
245 132 <!-- JSON -->
... ... @@ -248,72 +135,28 @@
248 135 <artifactId>fastjson2</artifactId>
249 136 <version>${fastjson.version}</version>
250 137 </dependency>
251   -
252   - <!-- 测试 -->
253   - <dependency>
254   - <groupId>org.springframework.boot</groupId>
255   - <artifactId>spring-boot-starter-test</artifactId>
256   - <scope>test</scope>
257   - </dependency>
258   -<!-- <dependency>-->
259   -<!-- <groupId>org.springframework.boot</groupId>-->
260   -<!-- <artifactId>spring-boot-starter-data-jpa</artifactId>-->
261   -<!-- </dependency>-->
262   -
263   - <!-- OpenAPI 3 UI (包含所有必要依赖) -->
264 138 <dependency>
265   - <groupId>org.springdoc</groupId>
266   - <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
267   - <version>${springdoc.version}</version>
  139 + <groupId>com.fasterxml.jackson.core</groupId>
  140 + <artifactId>jackson-databind</artifactId>
  141 + <version>${jackson.version}</version>
268 142 </dependency>
269   -
270   - <!-- Swagger 注解 -->
271 143 <dependency>
272   - <groupId>io.swagger.core.v3</groupId>
273   - <artifactId>swagger-annotations</artifactId>
274   - <version>2.2.20</version>
  144 + <groupId>com.fasterxml.jackson.core</groupId>
  145 + <artifactId>jackson-core</artifactId>
  146 + <version>${jackson.version}</version>
275 147 </dependency>
276   -
277   - <!-- 开发工具 -->
278 148 <dependency>
279   - <groupId>org.springframework.boot</groupId>
280   - <artifactId>spring-boot-devtools</artifactId>
281   - <optional>true</optional>
  149 + <groupId>com.fasterxml.jackson.core</groupId>
  150 + <artifactId>jackson-annotations</artifactId>
  151 + <version>${jackson.version}</version>
282 152 </dependency>
283   -
284   - <!-- 中文分词 -->
285 153 <dependency>
286   - <groupId>com.huaban</groupId>
287   - <artifactId>jieba-analysis</artifactId>
288   - <version>1.0.2</version>
  154 + <groupId>com.fasterxml.jackson.datatype</groupId>
  155 + <artifactId>jackson-datatype-jsr310</artifactId>
  156 + <version>${jackson.version}</version>
289 157 </dependency>
290 158  
291   - <!-- 向量数据库 -->
292   -<!-- <dependency>-->
293   -<!-- <groupId>io.weaviate</groupId>-->
294   -<!-- <artifactId>client</artifactId>-->
295   -<!-- <version>${weaviate.version}</version>-->
296   -<!-- </dependency>-->
297   - <!--向量存储 -->
298   - <!-- <dependency>-->
299   - <!-- <groupId>dev.langchain4j</groupId>-->
300   - <!-- <artifactId>langchain4j-chroma</artifactId>-->
301   - <!-- <version>${langchain4j.version}</version>-->
302   - <!-- </dependency>-->
303   - <!-- 内存管理 -->
304   - <!-- <dependency>-->
305   - <!-- <groupId>dev.langchain4j</groupId>-->
306   - <!-- <artifactId>langchain4j-memory</artifactId>-->
307   - <!-- <version>${langchain4j.version}</version>-->
308   - <!-- </dependency>-->
309   -
310   - <!-- 专为向量相似度搜索设计 向量数据库 -->
311   - <!-- <dependency>-->
312   - <!-- <groupId>io.qdrant</groupId>-->
313   - <!-- <artifactId>qdrant-java</artifactId>-->
314   - <!-- <version>1.7.0</version>-->
315   - <!-- </dependency>-->
316   - <!-- 支持的文件格式 -->
  159 + <!-- 文档处理 -->
317 160 <dependency>
318 161 <groupId>org.apache.tika</groupId>
319 162 <artifactId>tika-core</artifactId>
... ... @@ -330,183 +173,137 @@
330 173 <version>5.2.5</version>
331 174 </dependency>
332 175  
333   - <!-- 可选:文档处理 -->
  176 + <!-- OCR -->
334 177 <dependency>
335   - <groupId>com.fasterxml.jackson.core</groupId>
336   - <artifactId>jackson-databind</artifactId>
  178 + <groupId>net.sourceforge.tess4j</groupId>
  179 + <artifactId>tess4j</artifactId>
  180 + <version>${tess4j.version}</version>
337 181 </dependency>
338   - <!-- 注入-->
339 182 <dependency>
340   - <groupId>javax.annotation</groupId>
341   - <artifactId>javax.annotation-api</artifactId>
342   - <version>1.3.2</version>
  183 + <groupId>io.github.mymonstercat</groupId>
  184 + <artifactId>rapidocr</artifactId>
  185 + <version>0.0.7</version>
343 186 </dependency>
344   -
345 187 <dependency>
346   - <groupId>jakarta.persistence</groupId>
347   - <artifactId>jakarta.persistence-api</artifactId>
348   - <version>3.1.0</version>
  188 + <groupId>io.github.mymonstercat</groupId>
  189 + <artifactId>rapidocr-onnx-platform</artifactId>
  190 + <version>0.0.7</version>
349 191 </dependency>
350 192  
351   - <!-- ========== LangChain4j 1.10.0 ========== -->
352   - <!-- 核心库 -->
  193 + <!-- 向量数据库 -->
353 194 <dependency>
354   - <groupId>dev.langchain4j</groupId>
355   - <artifactId>langchain4j-core</artifactId>
356   - <version>${langchain4j.version}</version>
  195 + <groupId>io.milvus</groupId>
  196 + <artifactId>milvus-sdk-java</artifactId>
  197 + <version>${milvus.version}</version>
357 198 </dependency>
358 199  
359   -
  200 + <!-- LangChain4j 核心 + Ollama -->
360 201 <dependency>
361 202 <groupId>dev.langchain4j</groupId>
362 203 <artifactId>langchain4j</artifactId>
363 204 <version>${langchain4j.version}</version>
364 205 </dependency>
365   -
366 206 <dependency>
367 207 <groupId>dev.langchain4j</groupId>
368 208 <artifactId>langchain4j-ollama</artifactId>
369 209 <version>${langchain4j.version}</version>
370 210 </dependency>
371   -
372   -
373   -
374   -
375   - <!-- 或者使用 Apache Tika 直接 -->
376   - <dependency>
377   - <groupId>org.apache.tika</groupId>
378   - <artifactId>tika-core</artifactId>
379   - <version>2.9.1</version>
380   - </dependency>
381   -
382 211 <dependency>
383   - <groupId>org.apache.tika</groupId>
384   - <artifactId>tika-parsers-standard-package</artifactId>
385   - <version>2.9.1</version>
386   - </dependency>
387   -
388   -
389   - <!-- Spring Retry -->
390   - <dependency>
391   - <groupId>org.springframework.retry</groupId>
392   - <artifactId>spring-retry</artifactId>
393   - <version>2.0.5</version> <!-- 最新版本,根据Spring版本调整 -->
394   - </dependency>
395   -
396   - <!-- Spring AOP (必需) -->
397   - <dependency>
398   - <groupId>org.springframework</groupId>
399   - <artifactId>spring-aspects</artifactId>
400   - <version>5.3.30</version> <!-- 与你的Spring版本保持一致 -->
401   - </dependency>
402   -
403   - <dependency>
404   - <groupId>com.microsoft.cognitiveservices.speech</groupId>
405   - <artifactId>client-sdk</artifactId>
406   - <version>1.37.0</version>
407   - <scope>compile</scope>
  212 + <groupId>dev.langchain4j</groupId>
  213 + <artifactId>langchain4j-embeddings-all-minilm-l6-v2</artifactId>
  214 + <version>${langchain4j-emb.version}</version>
408 215 </dependency>
409 216  
410   - <!-- ========== 验证框架 ========== -->
  217 + <!-- 分词 -->
411 218 <dependency>
412   - <groupId>jakarta.validation</groupId>
413   - <artifactId>jakarta.validation-api</artifactId>
414   - <version>${jakarta-validation.version}</version>
  219 + <groupId>com.huaban</groupId>
  220 + <artifactId>jieba-analysis</artifactId>
  221 + <version>1.0.2</version>
415 222 </dependency>
416 223  
  224 + <!-- 接口文档 -->
417 225 <dependency>
418   - <groupId>org.glassfish</groupId>
419   - <artifactId>jakarta.el</artifactId>
420   - <version>4.0.2</version>
  226 + <groupId>org.springdoc</groupId>
  227 + <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
  228 + <version>${springdoc.version}</version>
421 229 </dependency>
422 230  
423   - <!-- ========== JSON 处理 ========== -->
  231 + <!-- MapStruct -->
424 232 <dependency>
425   - <groupId>com.fasterxml.jackson.core</groupId>
426   - <artifactId>jackson-databind</artifactId>
427   - <version>${jackson.version}</version>
  233 + <groupId>org.mapstruct</groupId>
  234 + <artifactId>mapstruct</artifactId>
  235 + <version>${mapstruct.version}</version>
428 236 </dependency>
429 237  
  238 + <!-- 其他工具 -->
430 239 <dependency>
431   - <groupId>com.fasterxml.jackson.core</groupId>
432   - <artifactId>jackson-core</artifactId>
433   - <version>${jackson.version}</version>
  240 + <groupId>com.github.jsqlparser</groupId>
  241 + <artifactId>jsqlparser</artifactId>
  242 + <version>4.9</version>
434 243 </dependency>
435   -
436 244 <dependency>
437   - <groupId>com.fasterxml.jackson.core</groupId>
438   - <artifactId>jackson-annotations</artifactId>
439   - <version>${jackson.version}</version>
  245 + <groupId>org.jsoup</groupId>
  246 + <artifactId>jsoup</artifactId>
  247 + <version>1.17.2</version>
440 248 </dependency>
441 249  
  250 + <!-- 删掉这两个错误的 -->
442 251 <dependency>
443   - <groupId>com.fasterxml.jackson.datatype</groupId>
444   - <artifactId>jackson-datatype-jsr310</artifactId>
445   - <version>${jackson.version}</version>
  252 + <groupId>org.codehaus.groovy</groupId>
  253 + <artifactId>groovy</artifactId>
  254 + <version>3.0.20</version>
446 255 </dependency>
447   -
448   -
449   - <!-- Jackson 数据绑定(最常用) -->
450 256 <dependency>
451   - <groupId>com.fasterxml.jackson.core</groupId>
452   - <artifactId>jackson-databind</artifactId>
453   - <version>${jackson.version}</version>
  257 + <groupId>org.codehaus.groovy</groupId>
  258 + <artifactId>groovy-all</artifactId>
  259 + <version>3.0.20</version>
  260 + <type>pom</type>
454 261 </dependency>
455 262  
456   - <!-- Jackson 注解支持 -->
  263 + <!-- 正确的 Fastjson2 -->
457 264 <dependency>
458   - <groupId>com.fasterxml.jackson.core</groupId>
459   - <artifactId>jackson-annotations</artifactId>
460   - <version>${jackson.version}</version>
  265 + <groupId>com.alibaba.fastjson2</groupId>
  266 + <artifactId>fastjson2</artifactId>
  267 + <version>2.0.50</version>
461 268 </dependency>
462 269  
463   - <!-- ========== 工具类 ========== -->
  270 + <!-- Spring Data JPA 核心依赖(自动包含 jakarta.persistence 包) -->
464 271 <dependency>
465   - <groupId>org.projectlombok</groupId>
466   - <artifactId>lombok</artifactId>
467   - <version>${lombok.version}</version>
468   - <optional>true</optional>
  272 + <groupId>org.springframework.boot</groupId>
  273 + <artifactId>spring-boot-starter-data-jpa</artifactId>
469 274 </dependency>
470 275  
  276 + <!-- 数据库驱动(以 MySQL 为例,根据你的数据库替换) -->
471 277 <dependency>
472   - <groupId>org.mapstruct</groupId>
473   - <artifactId>mapstruct</artifactId>
474   - <version>${mapstruct.version}</version>
  278 + <groupId>com.mysql</groupId>
  279 + <artifactId>mysql-connector-j</artifactId>
  280 + <scope>runtime</scope>
475 281 </dependency>
476 282  
477 283 <dependency>
478   - <groupId>org.mapstruct</groupId>
479   - <artifactId>mapstruct-processor</artifactId>
480   - <version>${mapstruct.version}</version>
481   - <scope>provided</scope>
  284 + <groupId>com.github.jnr</groupId>
  285 + <artifactId>jnr-ffi</artifactId>
  286 + <version>2.2.15</version> <!-- 稳定版 -->
482 287 </dependency>
483   -
484 288 <dependency>
485   - <groupId>com.squareup.okhttp3</groupId>
486   - <artifactId>okhttp</artifactId>
487   - <version>${okhttp.version}</version> <!-- 使用最新版本 -->
  289 + <groupId>jakarta.annotation</groupId>
  290 + <artifactId>jakarta.annotation-api</artifactId>
  291 + <version>2.1.1</version>
488 292 </dependency>
489   -
490   - <!-- Edge-TTS Python执行相关 -->
491 293 <dependency>
492   - <groupId>org.python</groupId>
493   - <artifactId>jython-standalone</artifactId>
494   - <version>2.7.3</version>
  294 + <groupId>org.springframework.retry</groupId>
  295 + <artifactId>spring-retry</artifactId>
495 296 </dependency>
496 297  
497   - <!-- 工具类 -->
  298 + <!-- 必须加:Spring Retry 需要 AOP 依赖 -->
498 299 <dependency>
499   - <groupId>org.apache.commons</groupId>
500   - <artifactId>commons-exec</artifactId>
501   - <version>1.3</version>
  300 + <groupId>org.springframework.boot</groupId>
  301 + <artifactId>spring-boot-starter-aop</artifactId>
502 302 </dependency>
503   -
504   -
505 303 </dependencies>
  304 +
506 305 <build>
507 306 <finalName>xlyAi</finalName>
508   -
509   - <!-- 添加资源目录 -->
510 307 <resources>
511 308 <resource>
512 309 <directory>src/main/resources</directory>
... ... @@ -518,7 +315,6 @@
518 315 </resources>
519 316  
520 317 <plugins>
521   - <!-- 编译插件 -->
522 318 <plugin>
523 319 <groupId>org.apache.maven.plugins</groupId>
524 320 <artifactId>maven-compiler-plugin</artifactId>
... ... @@ -533,14 +329,14 @@
533 329 <artifactId>lombok</artifactId>
534 330 <version>${lombok.version}</version>
535 331 </path>
  332 + <path>
  333 + <groupId>org.mapstruct</groupId>
  334 + <artifactId>mapstruct-processor</artifactId>
  335 + <version>${mapstruct.version}</version>
  336 + </path>
536 337 </annotationProcessorPaths>
537   - <!-- 详细输出 -->
538   - <verbose>true</verbose>
539   - <showWarnings>true</showWarnings>
540 338 </configuration>
541 339 </plugin>
542   -
543   - <!-- Spring Boot 插件 -->
544 340 <plugin>
545 341 <groupId>org.springframework.boot</groupId>
546 342 <artifactId>spring-boot-maven-plugin</artifactId>
... ...
src/main/java/com/xly/config/ModelConfig.java
... ... @@ -5,12 +5,10 @@ import com.fasterxml.jackson.databind.SerializationFeature;
5 5 import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
6 6 import com.xly.agent.DynamicTableNl2SqlAiAgent;
7 7 import com.xly.agent.SceneSelectorAiAgent;
8   -import dev.langchain4j.memory.chat.MessageWindowChatMemory;
9   -import dev.langchain4j.model.chat.ChatLanguageModel;
10   -import dev.langchain4j.model.chat.StreamingChatLanguageModel;
11 8 import dev.langchain4j.model.ollama.OllamaChatModel;
12 9 import dev.langchain4j.model.ollama.OllamaStreamingChatModel;
13 10 import dev.langchain4j.service.AiServices;
  11 +import dev.langchain4j.memory.chat.MessageWindowChatMemory;
14 12 import org.springframework.beans.factory.annotation.Qualifier;
15 13 import org.springframework.beans.factory.annotation.Value;
16 14 import org.springframework.context.annotation.Bean;
... ... @@ -19,111 +17,89 @@ import org.springframework.context.annotation.Primary;
19 17  
20 18 import java.time.Duration;
21 19  
22   -/**
23   - * 大模型初始化配置(单例复用,避免重复创建)
24   - */
25 20 @Configuration
26 21 public class ModelConfig {
27 22  
28   -
29 23 @Value("${langchain4j.ollama.base-url}")
30 24 private String chatModelUrl;
31 25  
32   - @Value("${langchain4j.ollama.base-url}")
33   - private String sqlModelUrl;
34   -
35 26 @Value("${langchain4j.ollama.chat-model-name}")
36 27 private String chatModelName;
37 28  
38 29 @Value("${langchain4j.ollama.sql-model-name}")
39 30 private String sqlModelName;
40 31  
41   - // 中文对话模型 qwen2.5:7b-instruct
  32 + // ====================== 主对话模型 ======================
42 33 @Bean
43 34 @Primary
44 35 public OllamaChatModel chatLanguageModel() {
45 36 return OllamaChatModel.builder()
46 37 .baseUrl(chatModelUrl)
47   - .modelName(chatModelName) // 使用聊天模型名称
48   - .temperature(0.0) // 建议调整为0.0太确定
49   - .topP(0.9)
50   -// .numPredict(2048) // 添加生成长度限制
51   - .timeout(Duration.ofSeconds(60)) // 缩短超时时间
  38 + .modelName(chatModelName)
  39 + .temperature(0.1)
  40 + .topP(0.95)
  41 + .timeout(Duration.ofSeconds(120))
52 42 .maxRetries(2)
  43 + .logRequests(true)
  44 + .logResponses(true)
53 45 .build();
54 46 }
55 47  
56   - /***
57   - * @Author 钱豹
58   - * @Date 13:25 2026/2/6
59   - * @Param []
60   - * @return dev.langchain4j.model.ollama.OllamaChatModel
61   - * @Description 聊天
62   - **/
  48 + // ====================== 自由闲聊模型 ======================
63 49 @Bean("chatiModel")
64   - public ChatLanguageModel chatiModel() {
  50 + public OllamaChatModel chatiModel() {
65 51 return OllamaChatModel.builder()
66 52 .baseUrl(chatModelUrl)
67   - .modelName(chatModelName) // 使用聊天模型名称
68   - .temperature(0.8) // 建议调整为0.8太确定
  53 + .modelName(chatModelName)
  54 + .temperature(0.7)
69 55 .topP(0.9)
70   -// .numPredict(2048) // 添加生成长度限制
71   - .timeout(Duration.ofSeconds(60)) // 缩短超时时间
  56 + .timeout(Duration.ofSeconds(60))
72 57 .maxRetries(2)
73 58 .build();
74 59 }
75 60  
76   - // SQL/代码专用模型 qwen2.5-coder:14b
77   - @Bean("sqlChatModel") // 明确指定bean名称
  61 + // ====================== SQL 专用模型 ======================
  62 + @Bean("sqlChatModel")
78 63 public OllamaChatModel sqlChatModel() {
79 64 return OllamaChatModel.builder()
80   - .baseUrl(sqlModelUrl)
81   - .modelName(sqlModelName) // 使用SQL模型名称
  65 + .baseUrl(chatModelUrl)
  66 + .modelName(sqlModelName)
82 67 .temperature(0.0)
83 68 .topP(0.95)
84   - .numPredict(4096) // 代码生成需要更长
  69 + .numPredict(4096)
85 70 .timeout(Duration.ofSeconds(120))
86 71 .maxRetries(3)
87   -// .repeatPenalty(1.1) // 减少重复
88 72 .build();
89 73 }
90 74  
91   - /***
92   - * @Author 钱豹
93   - * @Date 22:53 2026/2/3
94   - * @Param []
95   - * @return dev.langchain4j.model.chat.StreamingChatLanguageModel
96   - * @Description 流式聊天模型 - 使用 @Primary
97   - **/
  75 + // ====================== 流式对话模型 ======================
98 76 @Bean("streamingChatModel")
99 77 @Primary
100   - public StreamingChatLanguageModel streamingChatModel() {
  78 + public OllamaStreamingChatModel streamingChatModel() {
101 79 return OllamaStreamingChatModel.builder()
102 80 .baseUrl(chatModelUrl)
103 81 .modelName(chatModelName)
104   - .temperature(0.7)
  82 + .temperature(0.3)
105 83 .topP(0.9)
106 84 .numPredict(1024)
107 85 .timeout(Duration.ofSeconds(60))
108 86 .build();
109 87 }
110 88  
111   - // 流式SQL/代码模型 - 指定名称
  89 + // ====================== 流式 SQL 模型 ======================
112 90 @Bean("streamingSqlModel")
113   - public StreamingChatLanguageModel streamingSqlModel() {
  91 + public OllamaStreamingChatModel streamingSqlModel() {
114 92 return OllamaStreamingChatModel.builder()
115   - .baseUrl(sqlModelUrl)
  93 + .baseUrl(chatModelUrl)
116 94 .modelName(sqlModelName)
117   - .temperature(0.3)
  95 + .temperature(0.2)
118 96 .topP(0.95)
119 97 .numPredict(2048)
120 98 .timeout(Duration.ofSeconds(120))
121 99 .build();
122 100 }
123 101  
124   - /**
125   - * 全局ObjectMapper:支持LocalDate序列化
126   - */
  102 + // ====================== JSON ======================
127 103 @Bean
128 104 @Primary
129 105 public ObjectMapper objectMapper() {
... ... @@ -134,22 +110,22 @@ public class ModelConfig {
134 110 return mapper;
135 111 }
136 112  
137   - //动态SQL生成模型
  113 + // ====================== 动态 SQL Agent ======================
138 114 @Bean
139   - public DynamicTableNl2SqlAiAgent dynamicTableNl2SqlAiAgent(@Qualifier("sqlChatModel") ChatLanguageModel sqlModel) {
  115 + public DynamicTableNl2SqlAiAgent dynamicTableNl2SqlAiAgent(
  116 + @Qualifier("sqlChatModel") OllamaChatModel sqlModel) {
140 117 return AiServices.builder(DynamicTableNl2SqlAiAgent.class)
141   - .chatLanguageModel(sqlModel)
142   - // 会话记忆:每个用户最多保留10轮对话,避免记忆溢出
  118 + .chatModel(sqlModel)
143 119 .chatMemoryProvider(memoryId -> MessageWindowChatMemory.withMaxMessages(10))
144 120 .build();
145 121 }
146 122  
147   - //场景意图解析AI服务
  123 + // ====================== 场景选择 Agent ======================
148 124 @Bean
149   - public SceneSelectorAiAgent sceneSelectorAiAgent(OllamaChatModel sqlModel) {
  125 + public SceneSelectorAiAgent sceneSelectorAiAgent(
  126 + @Qualifier("chatLanguageModel") OllamaChatModel chatLanguageModel) {
150 127 return AiServices.builder(SceneSelectorAiAgent.class)
151   - .chatLanguageModel(sqlModel)
152   - // 会话记忆:每个用户最多保留10轮对话,避免记忆溢出
  128 + .chatModel(chatLanguageModel)
153 129 .chatMemoryProvider(memoryId -> MessageWindowChatMemory.withMaxMessages(10))
154 130 .build();
155 131 }
... ...
src/main/java/com/xly/milvus/web/MilvusController.java
1 1 package com.xly.milvus.web;
2 2  
3 3 import com.xly.milvus.service.MilvusService;
4   -import com.xly.runner.AppStartupRunner;
5   -import com.xly.service.DynamicExeDbService;
6   -import com.xly.service.UserSceneSessionService;
7   -import com.xly.tool.DynamicToolProvider;
8 4 import com.xly.tts.bean.*;
9   -import com.xly.tts.service.LocalAudioCache;
10   -import com.xly.tts.service.PythonTtsProxyService;
11   -import jakarta.validation.Valid;
12 5 import lombok.RequiredArgsConstructor;
13 6 import lombok.extern.slf4j.Slf4j;
14   -import org.springframework.core.io.InputStreamResource;
15   -import org.springframework.http.MediaType;
16 7 import org.springframework.http.ResponseEntity;
17 8 import org.springframework.web.bind.annotation.*;
18   -import reactor.core.publisher.Flux;
19   -import reactor.core.publisher.Mono;
20   -
21   -import javax.annotation.PostConstruct;
22   -import javax.annotation.PreDestroy;
23   -import java.util.List;
24 9 import java.util.Map;
25   -import java.util.concurrent.CompletableFuture;
26 10  
27 11 @Slf4j
28 12 @RestController
... ...
src/main/java/com/xly/service/DynamicExeDbService.java
... ... @@ -4,7 +4,7 @@ import cn.hutool.core.text.CharSequenceUtil;
4 4 import cn.hutool.core.util.ObjectUtil;
5 5 import cn.hutool.core.util.StrUtil;
6 6 import cn.hutool.json.JSONUtil;
7   -import com.alibaba.fastjson.JSONObject;
  7 +import com.alibaba.fastjson2.JSONObject;
8 8 import com.xly.constant.ErrorCode;
9 9 import com.xly.constant.ProcedureConstant;
10 10 import com.xly.exception.dto.BusinessException;
... ... @@ -145,7 +145,7 @@ public class DynamicExeDbService {
145 145 if(JSONUtil.isJsonObj(searMap.get(out).toString())){
146 146 outMapData.put(out, JSONObject.parseObject(searMap.get(out).toString()));
147 147 }else if(JSONUtil.isJsonArray(searMap.get(out).toString())){
148   - outMapData.put(out, JSONObject.parseArray(searMap.get(out).toString()));
  148 + outMapData.put(out, JSONUtil.parseArray(searMap.get(out).toString()));
149 149 }
150 150 }else{
151 151 outMapData.put(out, searMap.get(out));
... ...
src/main/java/com/xly/service/XlyErpService.java
... ... @@ -26,15 +26,9 @@ import com.xly.util.*;
26 26 import dev.langchain4j.agent.tool.ToolExecutionRequest;
27 27 import dev.langchain4j.data.message.AiMessage;
28 28 import dev.langchain4j.data.message.ChatMessage;
29   -import dev.langchain4j.data.message.ChatMessageType;
30   -import dev.langchain4j.model.chat.ChatLanguageModel;
  29 +
31 30 import dev.langchain4j.model.ollama.OllamaChatModel;
32 31 import dev.langchain4j.service.AiServices;
33   -import dev.langchain4j.service.MemoryId;
34   -import dev.langchain4j.service.V;
35   -import io.milvus.v2.common.DataType;
36   -import io.milvus.v2.service.collection.request.CreateCollectionReq;
37   -import jnr.ffi.annotations.In;
38 32 import lombok.RequiredArgsConstructor;
39 33 import lombok.extern.slf4j.Slf4j;
40 34 import org.apache.commons.lang3.time.DateFormatUtils;
... ... @@ -54,7 +48,7 @@ import java.util.stream.IntStream;
54 48 public class XlyErpService {
55 49 //中文对话模型
56 50 private final OllamaChatModel chatModel;
57   - private final ChatLanguageModel chatiModel;
  51 + private final OllamaChatModel chatiModel;
58 52 private final SceneSelectorAiAgent sceneSelectorAiAgent;
59 53 private final UserSceneSessionService userSceneSessionService;
60 54 private final DynamicToolProvider dynamicToolProvider;
... ... @@ -923,7 +917,7 @@ public class XlyErpService {
923 917 // .repeatPenalty(1.1) // 减少重复
924 918 .build();
925 919 aiAgent = AiServices.builder(DynamicTableNl2SqlAiAgent.class)
926   - .chatLanguageModel(ol)
  920 + .chatModel(ol)
927 921 .chatMemoryProvider(operableChatMemoryProvider)
928 922 .toolProvider(dynamicToolProvider)
929 923 .build();
... ... @@ -952,7 +946,7 @@ public class XlyErpService {
952 946 ErpAiAgent aiAgent = UserSceneSessionService.ERP_AGENT_CACHE.get(userId);
953 947 if(ObjectUtil.isEmpty(aiAgent)){
954 948 aiAgent = AiServices.builder(ErpAiAgent.class)
955   - .chatLanguageModel(chatModel)
  949 + .chatModel(chatModel)
956 950 .chatMemoryProvider(operableChatMemoryProvider)
957 951 .toolProvider(dynamicToolProvider)
958 952 // .toolChoice(ChatCompletionToolChoice.ofRequired()) // 👈 必须调用一个工具
... ... @@ -1174,7 +1168,7 @@ public class XlyErpService {
1174 1168 ChatiAgent chatiAgent = UserSceneSessionService.CHAT_AGENT_CACHE.get(session.getUserId());
1175 1169 if (ObjectUtil.isEmpty(chatiAgent)) {
1176 1170 chatiAgent = AiServices.builder(ChatiAgent.class)
1177   - .chatLanguageModel(chatiModel)
  1171 + .chatModel(chatiModel)
1178 1172 .chatMemoryProvider(operableChatMemoryProvider)
1179 1173 .build();
1180 1174 UserSceneSessionService.CHAT_AGENT_CACHE.put(session.getUserId(), chatiAgent);
... ... @@ -1204,7 +1198,7 @@ public class XlyErpService {
1204 1198 ChatiAgent chatiAgent = UserSceneSessionService.CHAT_AGENT_CACHE.get(session.getUserId());
1205 1199 if(ObjectUtil.isEmpty(chatiAgent)){
1206 1200 chatiAgent = AiServices.builder(ChatiAgent.class)
1207   - .chatLanguageModel(chatiModel)
  1201 + .chatModel(chatiModel)
1208 1202 .chatMemoryProvider(operableChatMemoryProvider)
1209 1203 .build();
1210 1204 UserSceneSessionService.CHAT_AGENT_CACHE.put(session.getUserId(), chatiAgent); }
... ...
src/main/java/com/xly/thread/AiUserAgentQuestionThread.java
... ... @@ -67,21 +67,6 @@ public class AiUserAgentQuestionThread implements Runnable {
67 67 dynamicExeDbService.getCallPro(searMap, sProName);
68 68 }
69 69  
70   - //获取组ID
71   - private String getQuestionGroupNo(){
72   - String sQuestionGroupNo = userMessage.stream()
73   - .filter(one -> one.type().equals(ChatMessageType.USER) && !"用户输入:initAiService".equals(one.text()))
74   - .findFirst()
75   - .map(one->one.text())
76   - .orElse(StrUtil.EMPTY);
77   - sQuestionGroupNo = sQuestionGroupNo.replace("用户输入:",StrUtil.EMPTY);
78   - sQuestionGroupNo = sQuestionGroupNo.replace(" ",StrUtil.EMPTY);
79   - sQuestionGroupNo = sQuestionGroupNo.replace("\\t",StrUtil.EMPTY);
80   - sQuestionGroupNo = sQuestionGroupNo.replace("\\n",StrUtil.EMPTY);
81   - sQuestionGroupNo = sQuestionGroupNo.toLowerCase();
82   - return sQuestionGroupNo;
83   - }
84   -
85 70  
86 71 /***
87 72 * @Author 钱豹
... ...
src/main/java/com/xly/thread/MultiThreadPoolServer.java
... ... @@ -8,8 +8,8 @@ import java.util.concurrent.ThreadFactory;
8 8 import java.util.concurrent.ThreadPoolExecutor;
9 9 import java.util.concurrent.TimeUnit;
10 10  
  11 +import com.google.common.util.concurrent.ThreadFactoryBuilder;
11 12 import org.apache.poi.ss.formula.functions.T;
12   -import org.python.google.common.util.concurrent.ThreadFactoryBuilder;
13 13  
14 14  
15 15 /**
... ...
src/main/java/com/xly/tool/DynamicToolProvider.java
1 1 package com.xly.tool;
2 2  
3 3  
4   -import cn.hutool.core.util.NumberUtil;
5 4 import cn.hutool.core.util.ObjectUtil;
6 5 import cn.hutool.core.util.StrUtil;
7 6 import cn.hutool.json.JSONUtil;
8   -import com.alibaba.fastjson.JSONObject;
  7 +import com.alibaba.fastjson2.JSONObject;
9 8 import com.fasterxml.jackson.core.type.TypeReference;
10 9  
11 10 import com.fasterxml.jackson.databind.ObjectMapper;
... ... @@ -29,6 +28,8 @@ import dev.langchain4j.data.message.ToolExecutionResultMessage;
29 28 import dev.langchain4j.data.message.UserMessage;
30 29 import dev.langchain4j.memory.ChatMemory;
31 30  
  31 +import dev.langchain4j.model.chat.request.json.JsonObjectSchema;
  32 +import dev.langchain4j.model.chat.request.json.JsonSchema;
32 33 import dev.langchain4j.service.tool.ToolExecutor;
33 34 import dev.langchain4j.service.tool.ToolProvider;
34 35  
... ... @@ -255,17 +256,15 @@ public class DynamicToolProvider implements ToolProvider {
255 256 StringBuffer stoolDesc = new StringBuffer();
256 257 StringBuffer sbt = new StringBuffer();
257 258 StringBuffer xt = new StringBuffer();
258   - StringBuffer sl = new StringBuffer();
259 259  
260   - // ====================== 【超级强制:必须调用工具】 ======================
  260 + // 强制指令【完全保留】
261 261 String forceToolPrompt = """
262 262 【重要·强制指令】
263 263 1. 这是当前唯一可用工具,必须调用,禁止直接回答
264 264 2. 用户输入包含:确认、全部确认、合并确认、行号(第1行/第一行等)
265   - 3. 必须调用本工具,必须调用,并且只调用一次,不要重复调用
  265 + 3. 必须调用本工具,只调用一次
266 266 """;
267 267 stoolDesc.append(forceToolPrompt);
268   - // ========================================================================
269 268  
270 269 if (ObjectUtil.isNotEmpty(meta.getStoolDesc())) {
271 270 stoolDesc.append("MethodNo:").append(meta.getSMethodNo())
... ... @@ -274,130 +273,79 @@ public class DynamicToolProvider implements ToolProvider {
274 273 .append(",").append(meta.getStoolDesc());
275 274 }
276 275  
  276 + JsonObjectSchema.Builder schemaBuilder = JsonObjectSchema.builder();
  277 + List<String> requiredParams = new ArrayList<>();
  278 +
277 279 try {
278 280 List<ParamRule> paramRuleData = meta.getParamRuleList();
279   - Map<String, Object> slMap = new HashMap<>();
280 281  
281 282 for (ParamRule paramRule : paramRuleData) {
282   - String paramDesc = ObjectUtil.isEmpty(paramRule.getSParam()) ? null : paramRule.getSParam();
  283 + String paramDesc = paramRule.getSParam();
283 284 String paramType = paramRule.getSType();
284 285 Boolean bEmpty = paramRule.getBEmpty();
285   - String sExampleValue = paramRule.getSExampleValue();
286 286  
287   - if (ObjectUtil.isNotEmpty(sExampleValue) && "enum".equals(paramType.toLowerCase())) {
288   - slMap.put(paramDesc, sExampleValue);
289   - }
290   - if (paramDesc == null || paramDesc.trim().isEmpty()) {
  287 + if (paramDesc == null || paramDesc.isEmpty()) {
291 288 continue;
292 289 }
293 290  
294   - List<JsonSchemaProperty> properties = new ArrayList<>();
295 291 String sRuleCost = getConstMeg(paramRule.getSParamConfig(), paramRule);
296 292  
  293 + // ===================== 修复后:安全不报错 =====================
297 294 switch (paramType.toLowerCase()) {
298 295 case "string":
299   - if (bEmpty) {
300   - sbt.append(paramDesc).append("(字符串").append(sRuleCost).append(")、");
301   - } else {
302   - xt.append(paramDesc).append("(字符串").append(sRuleCost).append(")、");
303   - }
304   - properties.add(JsonSchemaProperty.STRING);
  296 + if (bEmpty) sbt.append(paramDesc).append("(字符串)、");
  297 + else xt.append(paramDesc).append("(字符串)、");
  298 + schemaBuilder.addStringProperty(paramDesc, paramDesc);
305 299 break;
  300 +
306 301 case "integer":
307 302 case "int":
308   - if (bEmpty) {
309   - sbt.append(paramDesc).append("(数字").append(sRuleCost).append(")、");
310   - } else {
311   - xt.append(paramDesc).append("(数字").append(sRuleCost).append(")、");
312   - }
313   - properties.add(JsonSchemaProperty.INTEGER);
  303 + if (bEmpty) sbt.append(paramDesc).append("(数字)、");
  304 + else xt.append(paramDesc).append("(数字)、");
  305 + schemaBuilder.addIntegerProperty(paramDesc, paramDesc);
314 306 break;
  307 +
315 308 case "number":
316 309 case "double":
317 310 case "float":
318   - properties.add(JsonSchemaProperty.NUMBER);
319   - if (bEmpty) {
320   - sbt.append(paramDesc).append("(浮点").append(sRuleCost).append(")、");
321   - } else {
322   - xt.append(paramDesc).append("(浮点").append(sRuleCost).append(")、");
323   - }
  311 + if (bEmpty) sbt.append(paramDesc).append("(浮点)、");
  312 + else xt.append(paramDesc).append("(浮点)、");
  313 + schemaBuilder.addNumberProperty(paramDesc, paramDesc);
324 314 break;
  315 +
325 316 case "boolean":
326 317 case "bool":
327   - if (bEmpty) {
328   - sbt.append(paramDesc).append("(布尔型").append(sRuleCost).append(")、");
329   - } else {
330   - xt.append(paramDesc).append("(布尔型").append(sRuleCost).append(")、");
331   - }
332   - properties.add(JsonSchemaProperty.BOOLEAN);
  318 + if (bEmpty) sbt.append(paramDesc).append("(布尔)、");
  319 + else xt.append(paramDesc).append("(布尔)、");
  320 + schemaBuilder.addBooleanProperty(paramDesc, paramDesc);
333 321 break;
  322 +
334 323 case "array":
335   - String sRuleArray = getArrrayBySql(paramRule);
336   - if (ObjectUtil.isNotEmpty(sRuleArray)) {
337   - sRuleArray = StrUtil.replace(sRuleArray, ",", "/");
338   - properties.add(JsonSchemaProperty.enums(sRuleArray.split("/")));
339   - }
340   - if (bEmpty) {
341   - sbt.append(paramDesc).append("(数组类型,可多选枚举值 [").append(sRuleArray).append("]");
342   - if (ObjectUtil.isNotEmpty(paramRule.getSDefaultValue()) || (ObjectUtil.isNotEmpty(sRuleArray) && sRuleArray.split("/").length == 1)) {
343   - String sDefaultVal = (ObjectUtil.isNotEmpty(sRuleArray) && sRuleArray.split("/").length == 1) ? sRuleArray : paramRule.getSDefaultValue();
344   - sbt.append(",默认值[").append(sDefaultVal).append("]");
345   - } else {
346   - sbt.append(",无默认值");
347   - }
348   - sbt.append(")、");
349   - } else {
350   - xt.append(paramDesc).append("(数组类型,可多选枚举值 [").append(sRuleArray).append("]");
351   - if (ObjectUtil.isNotEmpty(paramRule.getSDefaultValue())) {
352   - xt.append(",默认值[").append(paramRule.getSDefaultValue()).append("]");
353   - } else {
354   - xt.append(",无默认值");
355   - }
356   - xt.append(")、");
357   - }
358   - properties.add(JsonSchemaProperty.ARRAY);
359   - properties.add(JsonSchemaProperty.items(JsonSchemaProperty.STRING));
  324 + schemaBuilder.addStringProperty(paramDesc, paramDesc);
360 325 break;
  326 +
361 327 case "enum":
362   - if (ObjectUtil.isNotEmpty(sRuleCost)) {
363   - properties.add(JsonSchemaProperty.enums(sRuleCost.split("/")));
364   - } else {
365   - sRuleCost = getArrrayBySql(paramRule);
  328 + List<String> enums = new ArrayList<>();
  329 + if (StrUtil.isNotBlank(sRuleCost)) {
  330 + enums = Arrays.asList(sRuleCost.split("/"));
366 331 }
367   - if (bEmpty) {
368   - sbt.append(paramDesc).append("(字符串,互斥枚举值 [").append(sRuleCost).append("]");
369   - if (ObjectUtil.isNotEmpty(paramRule.getSDefaultValue())) {
370   - sbt.append(",默认值[").append(paramRule.getSDefaultValue()).append("]");
371   - } else {
372   - sbt.append(",无默认值");
373   - }
374   - sbt.append(")、");
  332 +
  333 + // ===================== 核心修复 =====================
  334 + if (enums.isEmpty()) {
  335 + // 空枚举 → 自动转字符串,绝对不报错
  336 + schemaBuilder.addStringProperty(paramDesc, paramDesc);
375 337 } else {
376   - xt.append(paramDesc).append("(字符串,互斥枚举值 [").append(sRuleCost).append("]");
377   - if (ObjectUtil.isNotEmpty(paramRule.getSDefaultValue())) {
378   - xt.append(",默认值[").append(paramRule.getSDefaultValue()).append("]");
379   - } else {
380   - xt.append(",无默认值");
381   - }
382   - xt.append(")、");
  338 + schemaBuilder.addEnumProperty(paramDesc, enums, paramDesc);
383 339 }
384   - properties.add(JsonSchemaProperty.ARRAY);
385   - properties.add(JsonSchemaProperty.items(JsonSchemaProperty.STRING));
386 340 break;
  341 +
387 342 default:
388   - properties.add(JsonSchemaProperty.STRING);
  343 + schemaBuilder.addStringProperty(paramDesc, paramDesc);
389 344 break;
390 345 }
391 346  
392   - if (!paramDesc.isEmpty()) {
393   - properties.add(JsonSchemaProperty.description(paramDesc));
394   - }
395   -
396   - boolean required = bEmpty;
397   - if (required) {
398   - builder.addParameter(paramDesc, properties);
399   - } else {
400   - builder.addOptionalParameter(paramDesc, properties);
  347 + if (bEmpty) {
  348 + requiredParams.add(paramDesc);
401 349 }
402 350 }
403 351  
... ... @@ -407,29 +355,24 @@ public class DynamicToolProvider implements ToolProvider {
407 355 if (ObjectUtil.isNotEmpty(xt)) {
408 356 stoolDesc.append(System.lineSeparator()).append("2.选填参数:").append(xt);
409 357 }
410   - if (ObjectUtil.isNotEmpty(slMap)) {
411   - stoolDesc.append(System.lineSeparator()).append(sl).append("**强制输出标准JSON对象**:")
412   - .append(System.lineSeparator()).append("示例:").append(JSONUtil.toJsonStr(slMap));
413   - }
414 358  
415   - log.info("方法描述========================{}", stoolDesc);
416 359 } catch (Exception e) {
417 360 e.printStackTrace();
418   - log.error("Failed to parse parameter rules: {}", meta.getSMethodName(), e);
419 361 }
420 362  
421   - // ====================== 【关键修复:强制添加两个参数】 ======================
  363 + // 固定添加 operateType
422 364 if (meta.getIBizType() == 4 || meta.getIBizType() == 5) {
423   - // 强制添加 operateType(必填)
424   - builder.addParameter("operateType",
425   - JsonSchemaProperty.STRING,
426   - JsonSchemaProperty.description("操作类型:全部确认/合并确认/单行确认")
427   - );
  365 + schemaBuilder.addStringProperty("operateType", "操作类型:全部确认/合并确认/单行确认");
  366 + requiredParams.add("operateType");
428 367 }
429   - // ============================================================================
430   -
431   - builder.description(stoolDesc.toString());
432   - return builder.build();
  368 + if (!requiredParams.isEmpty()) {
  369 + schemaBuilder.required(requiredParams);
  370 + }
  371 + JsonObjectSchema parameters = schemaBuilder.build();
  372 + return builder
  373 + .description(stoolDesc.toString())
  374 + .parameters(parameters)
  375 + .build();
433 376 }
434 377  
435 378 /***
... ... @@ -615,8 +558,11 @@ public class DynamicToolProvider implements ToolProvider {
615 558  
616 559 // 6. 【最终确认信息】所有检测通过后,需要和客户确认交互
617 560 List<ChatMessage> chatMessage = operableChatMemoryProvider.getCurrentChatMessages(session.getUserId());
618   - ChatMessage userMessage = getLasterUserMssage(chatMessage);
619   - String input = StrUtil.replace(userMessage.text(),"用户输入:",StrUtil.EMPTY);
  561 + ChatMessage userMessage = getLastUserMessage(chatMessage);
  562 + String input = "";
  563 + if (userMessage != null) {
  564 + input = StrUtil.replace(getChatMessageContent(userMessage), "用户输入:", StrUtil.EMPTY);
  565 + }
620 566 // {"0":"查询","1":"执行"} 查询不需要确认
621 567 Boolean isConfirmed = isConfirmed(input) || input.contains("生成") || input.contains("确认");
622 568 // //判断是否生成数据
... ... @@ -661,6 +607,37 @@ public class DynamicToolProvider implements ToolProvider {
661 607 return executeWithConfirmation(askconfirmMsg, session, meta);
662 608 }
663 609  
  610 + /**
  611 + * 安全获取 ChatMessage 内容,适配你当前所有版本
  612 + * 不依赖 UserMessage / .text()
  613 + */
  614 + private String getChatMessageContent(ChatMessage message) {
  615 + if (message == null) return "";
  616 +
  617 + try {
  618 + // 通用反射获取内容(兼容所有版本)
  619 + return message.toString()
  620 + .replace("ChatMessage{", "")
  621 + .replace("}", "")
  622 + .replace("text=", "")
  623 + .trim();
  624 + } catch (Exception e) {
  625 + return "";
  626 + }
  627 + }
  628 + private ChatMessage getLastUserMessage(List<ChatMessage> messages) {
  629 + if (messages == null || messages.isEmpty()) return null;
  630 +
  631 + for (int i = messages.size() - 1; i >= 0; i--) {
  632 + ChatMessage msg = messages.get(i);
  633 + if (msg.type() == ChatMessageType.USER) {
  634 + return msg;
  635 + }
  636 + }
  637 + return null;
  638 + }
  639 +
  640 +
664 641 /***
665 642 * @Author 钱豹
666 643 * @Date 15:16 2026/2/9
... ... @@ -983,7 +960,7 @@ public class DynamicToolProvider implements ToolProvider {
983 960 args.put("sToolId", meta.getSId());
984 961 if (iBizType == 1 || iBizType == 4) {
985 962 Map<String, Object> data = new HashMap<>(args);
986   - data.put("sData", JSONObject.toJSONString(data));
  963 + data.put("sData", JSONObject.toJSONString((data)));
987 964 if(ObjectUtil.isEmpty(sBizContent) && iBizType == 4){
988 965 sBizContent ="Sp_Ai_AddCommonAfterNew";
989 966 //获取未清数据
... ...
src/main/java/com/xly/tts/service/PythonTtsProxyService.java
... ... @@ -11,6 +11,7 @@ import com.xly.service.UserSceneSessionService;
11 11 import com.xly.service.XlyErpService;
12 12 import com.xly.tts.bean.*;
13 13 import com.xly.util.AdvancedSymbolRemover;
  14 +import jakarta.annotation.PostConstruct;
14 15 import lombok.RequiredArgsConstructor;
15 16 import lombok.extern.slf4j.Slf4j;
16 17 import org.springframework.beans.factory.annotation.Value;
... ... @@ -20,7 +21,7 @@ import org.springframework.stereotype.Service;
20 21 import org.springframework.web.client.RestTemplate;
21 22 import reactor.core.publisher.Flux;
22 23  
23   -import javax.annotation.PostConstruct;
  24 +
24 25 import java.io.*;
25 26 import java.time.Duration;
26 27 import java.util.*;
... ...
src/main/java/com/xly/util/SqlExecuteUtil.java
... ... @@ -2,16 +2,14 @@ package com.xly.util;
2 2  
3 3  
4 4 import com.xly.exception.sqlexception.SqlExecuteException;
  5 +import jakarta.annotation.Resource;
5 6 import org.slf4j.Logger;
6 7 import org.slf4j.LoggerFactory;
7 8 import org.springframework.jdbc.core.JdbcTemplate;
8 9 import org.springframework.jdbc.core.RowMapper;
9 10 import org.springframework.stereotype.Component;
10 11  
11   -import javax.annotation.Resource;
12   -import java.sql.ResultSet;
13 12 import java.sql.ResultSetMetaData;
14   -import java.sql.SQLException;
15 13 import java.util.LinkedHashMap;
16 14 import java.util.List;
17 15 import java.util.Map;
... ...
src/main/java/com/xly/web/TTSStreamController.java
... ... @@ -7,6 +7,8 @@ import com.xly.tool.DynamicToolProvider;
7 7 import com.xly.tts.bean.*;
8 8 import com.xly.tts.service.LocalAudioCache;
9 9 import com.xly.tts.service.PythonTtsProxyService;
  10 +import jakarta.annotation.PostConstruct;
  11 +import jakarta.annotation.PreDestroy;
10 12 import jakarta.validation.Valid;
11 13 import lombok.RequiredArgsConstructor;
12 14 import lombok.extern.slf4j.Slf4j;
... ... @@ -14,13 +16,8 @@ import org.springframework.core.io.InputStreamResource;
14 16 import org.springframework.http.MediaType;
15 17 import org.springframework.http.ResponseEntity;
16 18 import org.springframework.web.bind.annotation.*;
17   -import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
18 19 import reactor.core.publisher.Flux;
19   -import reactor.core.publisher.Mono;
20 20  
21   -import javax.annotation.PostConstruct;
22   -import javax.annotation.PreDestroy;
23   -import java.io.InputStream;
24 21 import java.util.List;
25 22 import java.util.Map;
26 23 import java.util.concurrent.CompletableFuture;
... ...
src/main/resources/application.yml
... ... @@ -48,7 +48,7 @@ spring:
48 48 add-mappings: false
49 49 datasource:
50 50 driver-class-name: com.mysql.cj.jdbc.Driver
51   - url: jdbc:mysql://8.130.144.93:3306/xlyweberp_saas?allowPublicKeyRetrieval=true&keepAlive=true&autoReconnect=true&autoReconnectForPools=true&connectTimeout=30000&socketTimeout=180000&nullCatalogMeansCurrent=true&&allowMultiQueries=true&useSSL=false&useUnicode=true&characterEncoding=utf-8&failOverReadOnly=false&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=CONVERT_TO_NULL
  51 + url: jdbc:mysql://118.178.19.35:3318/xlyweberp_saas?allowPublicKeyRetrieval=true&keepAlive=true&autoReconnect=true&autoReconnectForPools=true&connectTimeout=30000&socketTimeout=180000&nullCatalogMeansCurrent=true&&allowMultiQueries=true&useSSL=false&useUnicode=true&characterEncoding=utf-8&failOverReadOnly=false&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=CONVERT_TO_NULL
52 52 username: xlyprint
53 53 password: xlyXLYprint2016
54 54 # 连接池配置(使用HikariCP)
... ...