Compare commits
5 Commits
ce59d63412
...
combine
| Author | SHA1 | Date | |
|---|---|---|---|
| 1da380ace3 | |||
| 5d888f648a | |||
| 19a93325b1 | |||
| d90029e7c2 | |||
| bfffbc9868 |
37
.idea/csv-editor.xml
generated
Normal file
37
.idea/csv-editor.xml
generated
Normal file
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CsvFileAttributes">
|
||||
<option name="attributeMap">
|
||||
<map>
|
||||
<entry key="/dumpDataPreview">
|
||||
<value>
|
||||
<Attribute>
|
||||
<option name="separator" value="," />
|
||||
</Attribute>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="/knowledge/data.csv">
|
||||
<value>
|
||||
<Attribute>
|
||||
<option name="separator" value="," />
|
||||
</Attribute>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="/knowledge/data2.csv">
|
||||
<value>
|
||||
<Attribute>
|
||||
<option name="separator" value="," />
|
||||
</Attribute>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="/knowledge/host_assets.csv">
|
||||
<value>
|
||||
<Attribute>
|
||||
<option name="separator" value="," />
|
||||
</Attribute>
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
13
.idea/dataSources.xml
generated
13
.idea/dataSources.xml
generated
@@ -13,5 +13,18 @@
|
||||
</jdbc-additional-properties>
|
||||
<working-dir>$ProjectFileDir$</working-dir>
|
||||
</data-source>
|
||||
<data-source source="LOCAL" name="main@192.168.100.139" uuid="eb4550b4-11dc-430c-9617-be74169dcc17">
|
||||
<driver-ref>mysql.8</driver-ref>
|
||||
<synchronize>true</synchronize>
|
||||
<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver>
|
||||
<jdbc-url>jdbc:mysql://192.168.100.139:3307/main?useSSL=false&allowPublicKeyRetrieval=true</jdbc-url>
|
||||
<jdbc-additional-properties>
|
||||
<property name="com.intellij.clouds.kubernetes.db.host.port" />
|
||||
<property name="com.intellij.clouds.kubernetes.db.enabled" value="false" />
|
||||
<property name="com.intellij.clouds.kubernetes.db.resource.type" value="Deployment" />
|
||||
<property name="com.intellij.clouds.kubernetes.db.container.port" />
|
||||
</jdbc-additional-properties>
|
||||
<working-dir>$ProjectFileDir$</working-dir>
|
||||
</data-source>
|
||||
</component>
|
||||
</project>
|
||||
10
.idea/jarRepositories.xml
generated
10
.idea/jarRepositories.xml
generated
@@ -6,6 +6,16 @@
|
||||
<option name="name" value="Central Repository" />
|
||||
<option name="url" value="https://repo.maven.apache.org/maven2" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="local-releases" />
|
||||
<option name="name" value="Local Releases" />
|
||||
<option name="url" value="http://localhost:3105/threepartrepo" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Central Repository" />
|
||||
<option name="url" value="http://localhost:3105/threepartrepo" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Maven Central repository" />
|
||||
|
||||
1
.idea/sqldialects.xml
generated
1
.idea/sqldialects.xml
generated
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="SqlDialectMappings">
|
||||
<file url="file://$PROJECT_DIR$/knowledge/host_assets.sql" dialect="MySQL" />
|
||||
<file url="PROJECT" dialect="MySQL" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -10,11 +10,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"chart.js": "^4.4.8",
|
||||
"chartjs-adapter-moment": "^1.0.1",
|
||||
"echarts": "^5.6.0",
|
||||
"eventsource-client": "^1.1.3",
|
||||
"licia": "^1.46.0",
|
||||
"markdown-it": "^14.1.0",
|
||||
"markdown-it-container": "^4.0.0",
|
||||
"mermaid": "^11.4.1",
|
||||
"mermaid-it-markdown": "^1.0.8",
|
||||
"vue": "^3.5.13"
|
||||
|
||||
29
client/pnpm-lock.yaml
generated
29
client/pnpm-lock.yaml
generated
@@ -11,6 +11,9 @@ importers:
|
||||
chart.js:
|
||||
specifier: ^4.4.8
|
||||
version: 4.4.8
|
||||
chartjs-adapter-moment:
|
||||
specifier: ^1.0.1
|
||||
version: 1.0.1(chart.js@4.4.8)(moment@2.30.1)
|
||||
echarts:
|
||||
specifier: ^5.6.0
|
||||
version: 5.6.0
|
||||
@@ -23,9 +26,6 @@ importers:
|
||||
markdown-it:
|
||||
specifier: ^14.1.0
|
||||
version: 14.1.0
|
||||
markdown-it-container:
|
||||
specifier: ^4.0.0
|
||||
version: 4.0.0
|
||||
mermaid:
|
||||
specifier: ^11.4.1
|
||||
version: 11.4.1
|
||||
@@ -758,6 +758,12 @@ packages:
|
||||
resolution: {integrity: sha512-IkGZlVpXP+83QpMm4uxEiGqSI7jFizwVtF3+n5Pc3k7sMO+tkd0qxh2OzLhenM0K80xtmAONWGBn082EiBQSDA==, tarball: https://registry.npmjs.org/chart.js/-/chart.js-4.4.8.tgz}
|
||||
engines: {pnpm: '>=8'}
|
||||
|
||||
chartjs-adapter-moment@1.0.1:
|
||||
resolution: {integrity: sha512-Uz+nTX/GxocuqXpGylxK19YG4R3OSVf8326D+HwSTsNw1LgzyIGRo+Qujwro1wy6X+soNSnfj5t2vZ+r6EaDmA==}
|
||||
peerDependencies:
|
||||
chart.js: '>=3.0.0'
|
||||
moment: ^2.10.2
|
||||
|
||||
chevrotain-allstar@0.3.1:
|
||||
resolution: {integrity: sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==}
|
||||
peerDependencies:
|
||||
@@ -1047,7 +1053,7 @@ packages:
|
||||
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
|
||||
|
||||
eventsource-client@1.1.3:
|
||||
resolution: {integrity: sha512-6GJGePDMxin/6VH1Dex7RqnZRguweO1BVKhXpBYwKcQbVLOZPLfeDr9vYSb9ra88kjs0NpT8FaEDz5rExedDkg==, tarball: https://registry.npmjs.org/eventsource-client/-/eventsource-client-1.1.3.tgz}
|
||||
resolution: {integrity: sha512-6GJGePDMxin/6VH1Dex7RqnZRguweO1BVKhXpBYwKcQbVLOZPLfeDr9vYSb9ra88kjs0NpT8FaEDz5rExedDkg==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
|
||||
eventsource-parser@3.0.0:
|
||||
@@ -1240,9 +1246,6 @@ packages:
|
||||
magic-string@0.30.17:
|
||||
resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
|
||||
|
||||
markdown-it-container@4.0.0:
|
||||
resolution: {integrity: sha512-HaNccxUH0l7BNGYbFbjmGpf5aLHAMTinqRZQAEQbMr2cdD3z91Q6kIo1oUn1CQndkT03jat6ckrdRYuwwqLlQw==}
|
||||
|
||||
markdown-it@13.0.2:
|
||||
resolution: {integrity: sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w==}
|
||||
hasBin: true
|
||||
@@ -1291,6 +1294,9 @@ packages:
|
||||
mlly@1.7.4:
|
||||
resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==}
|
||||
|
||||
moment@2.30.1:
|
||||
resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==}
|
||||
|
||||
mrmime@2.0.1:
|
||||
resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -2363,6 +2369,11 @@ snapshots:
|
||||
dependencies:
|
||||
'@kurkle/color': 0.3.4
|
||||
|
||||
chartjs-adapter-moment@1.0.1(chart.js@4.4.8)(moment@2.30.1):
|
||||
dependencies:
|
||||
chart.js: 4.4.8
|
||||
moment: 2.30.1
|
||||
|
||||
chevrotain-allstar@0.3.1(chevrotain@11.0.3):
|
||||
dependencies:
|
||||
chevrotain: 11.0.3
|
||||
@@ -2865,8 +2876,6 @@ snapshots:
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.5.0
|
||||
|
||||
markdown-it-container@4.0.0: {}
|
||||
|
||||
markdown-it@13.0.2:
|
||||
dependencies:
|
||||
argparse: 2.0.1
|
||||
@@ -2952,6 +2961,8 @@ snapshots:
|
||||
pkg-types: 1.3.1
|
||||
ufo: 1.5.4
|
||||
|
||||
moment@2.30.1: {}
|
||||
|
||||
mrmime@2.0.1: {}
|
||||
|
||||
ms@2.1.3: {}
|
||||
|
||||
@@ -1,9 +1,27 @@
|
||||
<script setup>
|
||||
import {onMounted, ref} from 'vue'
|
||||
import {onMounted, ref, toRaw} from 'vue'
|
||||
import MarkdownIt from 'markdown-it'
|
||||
import MarkDownMermaidPlugin from 'mermaid-it-markdown'
|
||||
import {createEventSource} from 'eventsource-client'
|
||||
import * as echarts from 'echarts'
|
||||
import {CategoryScale, Chart, LinearScale, LineController, LineElement, PointElement, Title,} from 'chart.js'
|
||||
import 'chartjs-adapter-moment'
|
||||
import mermaid from 'mermaid'
|
||||
import {each, isEqual, isNull, nextTick} from 'licia'
|
||||
|
||||
Chart.register(
|
||||
LineController,
|
||||
LineElement,
|
||||
PointElement,
|
||||
LinearScale,
|
||||
Title,
|
||||
CategoryScale
|
||||
)
|
||||
|
||||
const chartsMap = ref({
|
||||
echarts: {},
|
||||
chartjs: {},
|
||||
mermaid: {},
|
||||
})
|
||||
// 初始化 markdown-it 实例
|
||||
const md = new MarkdownIt({
|
||||
html: true, // 启用 HTML 标签
|
||||
@@ -11,7 +29,38 @@ const md = new MarkdownIt({
|
||||
linkify: true, // 自动转换 URL 为链接
|
||||
typographer: true, // 启用一些语言中性的替换 + 引号美化
|
||||
})
|
||||
md.use(MarkDownMermaidPlugin)
|
||||
md.use(function (md) {
|
||||
md.renderer.rules.fence = function (tokens, idx, options, env, slf) {
|
||||
// console.log('tokens', tokens, tokens[idx].info)
|
||||
const content = tokens[idx].content
|
||||
// 此处判断是否为 echarts 代码块
|
||||
if (tokens[idx].info === 'echarts') {
|
||||
try {
|
||||
chartsMap.value.echarts[idx] = JSON.parse(content)
|
||||
console.log('ok', content)
|
||||
} catch (e) {
|
||||
console.error(e, content)
|
||||
}
|
||||
return `<div id="echarts-${idx}" style="width: 600px;height:400px;"></div>`
|
||||
} else if (tokens[idx].info === 'chartjs') {
|
||||
// 此处判断是否为 chartjs 代码块
|
||||
try {
|
||||
chartsMap.value.chartjs[idx] = JSON.parse(content)
|
||||
} catch (e) {
|
||||
console.error(e, content)
|
||||
}
|
||||
return `<canvas id="chartjs-${idx}"></canvas>`
|
||||
} else if (tokens[idx].info === 'mermaid') {
|
||||
// 此处判断是否为 mermaidChart 代码块
|
||||
const code = content.trim()
|
||||
chartsMap.value.mermaid[idx] = code
|
||||
return `<div id="mermaid-${idx}">${code}</div>`
|
||||
} else {
|
||||
// 其他代码块
|
||||
return `<pre><code class='languge-${tokens[idx].info}'>${content}</code></pre>`
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const question = ref('')
|
||||
const answer = ref('')
|
||||
@@ -33,13 +82,27 @@ const showToast = ref(false)
|
||||
const toastMessage = ref('')
|
||||
const toastMessageType = ref('success')
|
||||
|
||||
const onEventSourceClose = (eventSource) => {
|
||||
console.log(answer.value)
|
||||
console.log(renderedAnswer.value)
|
||||
console.log(chartsMap.value)
|
||||
eventSource.close()
|
||||
renderCharts()
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!question.value.trim() || loading.value) return
|
||||
|
||||
loading.value = true
|
||||
answer.value = ''
|
||||
renderedAnswer.value = ''
|
||||
chartsMap.value = {
|
||||
echarts: {},
|
||||
chartjs: {},
|
||||
mermaid: {},
|
||||
}
|
||||
|
||||
let eventSource
|
||||
try {
|
||||
const url = 'http://localhost:7891/chat/stream'
|
||||
const formData = new FormData()
|
||||
@@ -55,25 +118,28 @@ const handleSubmit = async () => {
|
||||
formData.append('database_name', databaseName.value)
|
||||
}
|
||||
|
||||
const eventSource = createEventSource({
|
||||
eventSource = createEventSource({
|
||||
url: url,
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
onDisconnect: () => {
|
||||
console.log(answer.value)
|
||||
console.log(renderedAnswer.value)
|
||||
eventSource.close()
|
||||
},
|
||||
})
|
||||
for await (const { data } of eventSource) {
|
||||
if (isEqual(data, '#CLOSE#')) {
|
||||
onEventSourceClose(eventSource)
|
||||
break
|
||||
}
|
||||
answer.value += data.replaceAll(/#\/#/g, '')
|
||||
renderedAnswer.value = md.render(answer.value)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('请求出错:', error)
|
||||
console.log(answer.value)
|
||||
answer.value = '抱歉,请求出现错误'
|
||||
renderedAnswer.value = answer.value
|
||||
showToastMessage('请求失败,请检查服务器连接', 'error')
|
||||
if (!isNull(eventSource)) {
|
||||
eventSource.close()
|
||||
}
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
@@ -141,8 +207,25 @@ const handleCloseSettings = () => {
|
||||
showToastMessage('设置已保存', 'success')
|
||||
}
|
||||
|
||||
const renderCharts = () => {
|
||||
const map = toRaw(chartsMap.value)
|
||||
each(map.echarts, (value, key) => {
|
||||
echarts.init(document.getElementById(`echarts-${key}`)).setOption(value)
|
||||
})
|
||||
each(map.chartjs, (value, key) => {
|
||||
new Chart(document.getElementById(`chartjs-${key}`), value)
|
||||
})
|
||||
each(map.mermaid, (value, key) => {
|
||||
mermaid.initialize({ startOnLoad: true })
|
||||
mermaid.init(undefined, document.getElementById(`mermaid-${key}`))
|
||||
})
|
||||
}
|
||||
|
||||
// 在组件挂载时加载设置
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
renderCharts()
|
||||
})
|
||||
loadSettingsFromStorage()
|
||||
})
|
||||
</script>
|
||||
@@ -150,7 +233,7 @@ onMounted(() => {
|
||||
<template>
|
||||
<div class="chat-container">
|
||||
<div class="chat-header">
|
||||
<h1>数据库助手</h1>
|
||||
<h1>知识库助手</h1>
|
||||
</div>
|
||||
|
||||
<div class="messages-container">
|
||||
@@ -350,6 +433,10 @@ onMounted(() => {
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.mermaid {
|
||||
font-family: 'Arial', sans-serif;
|
||||
}
|
||||
|
||||
.chat-container {
|
||||
margin: 0;
|
||||
height: 100vh;
|
||||
|
||||
4469
knowledge/host_assets.csv
Normal file
4469
knowledge/host_assets.csv
Normal file
File diff suppressed because it is too large
Load Diff
30
knowledge/host_assets.sql
Normal file
30
knowledge/host_assets.sql
Normal file
@@ -0,0 +1,30 @@
|
||||
CREATE TABLE `host_assets`
|
||||
(
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
|
||||
`host_ip` varchar(100) DEFAULT NULL COMMENT '业务IP地址,该地址表示对外暴露业务的主机IP,通常业务由1个或多个主机共同提供服务,其他不对外暴露的主机的IP记录在all_ip字段中',
|
||||
`all_ip` varchar(500) DEFAULT NULL COMMENT '提供业务支撑的所有主机的IP',
|
||||
`system_name` varchar(255) DEFAULT NULL COMMENT '所属业务系统名称',
|
||||
`location` varchar(255) DEFAULT NULL COMMENT '主机所在机房具体地址',
|
||||
`manager_ip` varchar(100) DEFAULT NULL COMMENT '如果业务提供对外的管理控制台,则控制台的IP地址记录在这里,如果没有则记录为空',
|
||||
`host_name` varchar(100) DEFAULT NULL COMMENT '主机host名称',
|
||||
`host_os` varchar(100) DEFAULT NULL COMMENT '主机操作系统',
|
||||
`manufacturer` varchar(255) DEFAULT NULL COMMENT '主机设备制造厂商',
|
||||
`host_model` varchar(255) DEFAULT NULL COMMENT '主机设备型号',
|
||||
`host_sn` varchar(100) DEFAULT NULL COMMENT '主机序列号',
|
||||
`cpu_model` varchar(100) DEFAULT NULL COMMENT 'cpu型号',
|
||||
`cpu_num` varchar(100) DEFAULT NULL COMMENT 'cpu数量',
|
||||
`memory` varchar(100) DEFAULT NULL COMMENT '内存大小,除非该字段记录标明单位,否则默认单位为GB',
|
||||
`system_disk` varchar(100) DEFAULT NULL COMMENT '系统盘容量,除非该字段记录标明单位,否则默认单位为GB',
|
||||
`data_disk` varchar(100) DEFAULT NULL COMMENT '数据盘容量,除非该字段记录标明单位,否则默认单位为GB',
|
||||
`start_date` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '设备生产日期',
|
||||
`monitor` varchar(100) DEFAULT NULL COMMENT '是否使用基础监控',
|
||||
`component` varchar(100) DEFAULT NULL COMMENT '主机上部署了哪些应用组件',
|
||||
`host_state` varchar(100) DEFAULT NULL COMMENT '主机状态',
|
||||
`state_remark` varchar(255) DEFAULT NULL COMMENT '主机状态详细说明',
|
||||
`responsible_person` varchar(100) DEFAULT NULL COMMENT '主机责任人',
|
||||
`manager` varchar(100) DEFAULT NULL COMMENT '主机所属业务的业务经理',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE = InnoDB
|
||||
AUTO_INCREMENT = 8532
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_0900_ai_ci COMMENT ='主机资产表,该表记录了主机的详细信息,包括配置、部署组件、业务等'
|
||||
4469
knowledge/host_assets_backup.csv
Normal file
4469
knowledge/host_assets_backup.csv
Normal file
File diff suppressed because it is too large
Load Diff
52
pom.xml
52
pom.xml
@@ -47,10 +47,56 @@
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>5.8.32</version>
|
||||
</dependency>
|
||||
<!-- <dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-qdrant-store-spring-boot-starter</artifactId>
|
||||
<dependency>
|
||||
<groupId>net.datafaker</groupId>
|
||||
<artifactId>datafaker</artifactId>
|
||||
<version>2.4.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.yomahub</groupId>
|
||||
<artifactId>liteflow-spring-boot-starter</artifactId>
|
||||
<version>2.13.0</version>
|
||||
</dependency>
|
||||
<!--<dependency>
|
||||
<groupId>io.projectreactor.netty</groupId>
|
||||
<artifactId>reactor-netty-http</artifactId>
|
||||
<version>1.2.3</version>
|
||||
</dependency>-->
|
||||
<!--<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-reactive-httpclient</artifactId>
|
||||
<version>4.0.8</version>
|
||||
</dependency>-->
|
||||
<!--<dependency>
|
||||
<groupId>org.apache.httpcomponents.client5</groupId>
|
||||
<artifactId>httpclient5</artifactId>
|
||||
<version>5.4.2</version>
|
||||
</dependency>-->
|
||||
<!--<dependency>
|
||||
<groupId>org.apache.httpcomponents.core5</groupId>
|
||||
<artifactId>httpcore5-reactive</artifactId>
|
||||
<version>5.3.3</version>
|
||||
</dependency>-->
|
||||
<!--<dependency>
|
||||
<groupId>com.openai</groupId>
|
||||
<artifactId>openai-java</artifactId>
|
||||
<version>0.30.0</version>
|
||||
</dependency>-->
|
||||
<!--<dependency>
|
||||
<groupId>com.agentsflex</groupId>
|
||||
<artifactId>agents-flex-bom</artifactId>
|
||||
<version>1.0.0-rc.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.agentsflex</groupId>
|
||||
<artifactId>agents-flex-spring-boot-starter</artifactId>
|
||||
<version>1.0.0-rc.6</version>
|
||||
</dependency>-->
|
||||
<!-- <dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-qdrant-store-spring-boot-starter</artifactId>
|
||||
</dependency>-->
|
||||
</dependencies>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
||||
@@ -1,11 +1,43 @@
|
||||
package com.lanyuanxiaoyao.ai.analysis;
|
||||
|
||||
import com.yomahub.liteflow.core.FlowExecutor;
|
||||
import com.yomahub.liteflow.flow.LiteflowResponse;
|
||||
import jakarta.annotation.Resource;
|
||||
import java.net.http.HttpClient;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.http.client.JdkClientHttpRequestFactory;
|
||||
import org.springframework.web.client.RestClient;
|
||||
|
||||
@Slf4j
|
||||
@SpringBootApplication
|
||||
public class AnalysisApplication {
|
||||
public class AnalysisApplication implements ApplicationRunner {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AnalysisApplication.class, args);
|
||||
}
|
||||
|
||||
@Resource
|
||||
private FlowExecutor flowExecutor;
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain_1");
|
||||
log.info(String.valueOf(response.isSuccess()));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
public RestClient.Builder clientBuilder() {
|
||||
return RestClient.builder()
|
||||
.requestFactory(new JdkClientHttpRequestFactory(
|
||||
HttpClient.newBuilder()
|
||||
.version(HttpClient.Version.HTTP_1_1)
|
||||
.build()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
package com.lanyuanxiaoyao.ai.analysis.controller;
|
||||
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.lanyuanxiaoyao.ai.analysis.tools.DatabaseTools;
|
||||
import com.lanyuanxiaoyao.ai.analysis.tools.DatetimeTools;
|
||||
import com.lanyuanxiaoyao.ai.analysis.tools.PromptTools;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -16,7 +14,6 @@ import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||
|
||||
@Slf4j
|
||||
@@ -30,25 +27,6 @@ public class ChatController {
|
||||
this.client = builder.build();
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@PostMapping(value = "", produces = MediaType.TEXT_PLAIN_VALUE)
|
||||
public String chat(
|
||||
@RequestParam("prompt") String prompt,
|
||||
@RequestParam(value = "use_tw", defaultValue = "false") Boolean useTw,
|
||||
@RequestParam(value = "use_database", defaultValue = "false") Boolean useDatabase,
|
||||
@RequestParam(value = "database_url", required = false) String databaseUrl,
|
||||
@RequestParam(value = "database_username", required = false) String databaseUsername,
|
||||
@RequestParam(value = "database_password", required = false) String databasePassword,
|
||||
@RequestParam(value = "database_name", required = false) String databaseName
|
||||
) {
|
||||
logParameters(prompt, useTw, useDatabase, databaseUrl, databaseUsername, databasePassword, databaseName);
|
||||
return client.prompt()
|
||||
.system("始终在中文语境下回答")
|
||||
.user(prompt)
|
||||
.call()
|
||||
.content();
|
||||
}
|
||||
|
||||
@PostMapping(value = "stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
|
||||
public SseEmitter chatStream(
|
||||
@RequestParam("prompt") String prompt,
|
||||
@@ -58,29 +36,162 @@ public class ChatController {
|
||||
@RequestParam(value = "database_username", required = false) String databaseUsername,
|
||||
@RequestParam(value = "database_password", required = false) String databasePassword,
|
||||
@RequestParam(value = "database_name", required = false) String databaseName
|
||||
) {
|
||||
log.info("chatStream");
|
||||
logParameters(prompt, useTw, useDatabase, databaseUrl, databaseUsername, databasePassword, databaseName);
|
||||
) throws IOException {
|
||||
log.info("prompt: {}", prompt);
|
||||
log.info("use_tw: {}", useTw);
|
||||
log.info("use_database: {}", useDatabase);
|
||||
if (useDatabase) {
|
||||
log.info("database_url: {}", databaseUrl);
|
||||
log.info("database_username: {}", databaseUsername);
|
||||
log.info("database_password: {}", databasePassword);
|
||||
log.info("database_name: {}", databaseName);
|
||||
}
|
||||
|
||||
SseEmitter emitter = new SseEmitter();
|
||||
StringBuilder systemPrompt = new StringBuilder("始终在中文语境下回答\n\n");
|
||||
systemPrompt
|
||||
.append("当遇到数据对比、占比、趋势等场景相关的提问,优先考虑使用mermaid绘制图表,图文结合来回答")
|
||||
.append(PromptTools.MERMAID_PROMPT)
|
||||
.append("\n\n");
|
||||
List<Object> tools = new ArrayList<>();
|
||||
tools.add(new DatetimeTools());
|
||||
|
||||
List<String> prompts = new ArrayList<>();
|
||||
// language=TEXT
|
||||
prompts.add("""
|
||||
你是一名服务器主机运维管理员,对于用户提出的问题,你会尝试从多个方面思考分析,通过多种角度进行研究,使用尽可能多的数据对比对用户的问题进行回答
|
||||
你会积极使用表格、echarts图表等形式对数据进行分类、统计,力求能直观表达数据之间的关系和趋势,当用户问题中出现“趋势”、“占比”、“对比”等字眼的时候,优先使用echarts图表进行分析
|
||||
你始终会在中文语境下回答,对于用户的每个问题,先提出4个和用户提问最为相关的问题,针对以上5个问题分别进行回答再并整合答案汇总成为最终的回答,至少500字以上
|
||||
|
||||
对于echarts图表,严格按照如下格式进行绘制,这部份代码必须新起一段
|
||||
```echarts
|
||||
(这里是echarts的json配置)
|
||||
```
|
||||
你能够生成echarts json配置以在回答中可视化数据。当您认为图表能更好地说明信息或增强回答的可理解性时,应创建相应的echarts json配置。
|
||||
请遵循以下步骤生成配置:
|
||||
1. 确定是否需要图表:评估用户的问题或任务是否涉及数据可视化,例如比较数据、展示趋势或比例。
|
||||
2. 选择合适的图表类型:根据数据特性和表达目的选择图表类型。例如:
|
||||
- 柱状图(bar):适合比较分类数据,如不同国家的销量。
|
||||
- 折线图(line):适合展示时间序列或趋势,如温度变化。
|
||||
- 饼图(pie):适合展示比例或百分比,如市场份额。
|
||||
3. 准备数据:将数据组织成echarts可理解的格式。例如:
|
||||
- 柱状图/折线图:x轴为类别或时间点,y轴为数值。
|
||||
- 饼图:包含名称(name)和值(value)的数组。
|
||||
4. 生成json配置:基于echarts的配置规则,创建有效的json对象,包括标题(title)、轴(xAxis/yAxis,如适用)、系列(series)等必要组件。
|
||||
5. 正确格式化输出:确保json配置是有效的字符串,使用双引号包裹字符串值,数值不加引号。
|
||||
|
||||
以下是不同图表类型的示例,帮助您理解如何构建配置:
|
||||
|
||||
示例1:柱状图
|
||||
场景:展示2023年五个城市的销售额。
|
||||
数据:北京5000、上海4500、广州3000、深圳2800、杭州2000。
|
||||
输出:
|
||||
```echarts
|
||||
{
|
||||
"title": {
|
||||
"text": "2023 年城市销售额"
|
||||
},
|
||||
"xAxis": {
|
||||
"type": "category",
|
||||
"data": ["北京", "上海", "广州", "深圳", "杭州"]
|
||||
},
|
||||
"yAxis": {
|
||||
"type": "value",
|
||||
"axisLabel": {
|
||||
"formatter": "{value} 万"
|
||||
}
|
||||
},
|
||||
"series": [
|
||||
{
|
||||
"data": [5000, 4500, 3000, 2800, 2000],
|
||||
"type": "bar"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
示例2:折线图
|
||||
场景:展示某地区过去6个月的平均温度。
|
||||
数据:1月 5°C、2月 8°C、3月 12°C、4月 18°C、5月 22°C、6月 25°C。
|
||||
输出:
|
||||
```echarts
|
||||
{
|
||||
"title": {
|
||||
"text": "过去 6 个月平均温度"
|
||||
},
|
||||
"xAxis": {
|
||||
"type": "category",
|
||||
"data": ["1月", "2月", "3月", "4月", "5月", "6月"]
|
||||
},
|
||||
"yAxis": {
|
||||
"type": "value",
|
||||
"axisLabel": {
|
||||
"formatter": "{value} °C"
|
||||
}
|
||||
},
|
||||
"series": [
|
||||
{
|
||||
"data": [5, 8, 12, 18, 22, 25],
|
||||
"type": "line"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
示例3:饼图
|
||||
场景:展示三种水果的市场份额。
|
||||
数据:苹果40%、橙子35%、香蕉25%。
|
||||
输出:
|
||||
```echarts
|
||||
{
|
||||
"title": {
|
||||
"text": "水果市场份额"
|
||||
},
|
||||
"series": [
|
||||
{
|
||||
"type": "pie",
|
||||
"radius": "50%",
|
||||
"data": [
|
||||
{ "name": "苹果", "value": 40 },
|
||||
{ "name": "橙子", "value": 35 },
|
||||
{ "name": "香蕉", "value": 25 }
|
||||
],
|
||||
"label": {
|
||||
"formatter": "{b}: {c}%"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
注意事项
|
||||
json格式:字符串值使用双引号(如"text"),数值不加引号(如5000),不能使用任何注释。
|
||||
有效性:确保json配置语法正确,可直接用于echarts。
|
||||
相关性:仅在图表能为回答增添价值时生成配置,避免不必要的可视化。""");
|
||||
|
||||
if (useDatabase) {
|
||||
log.info("use database");
|
||||
DatabaseTools databaseTools = new DatabaseTools(databaseUrl, databaseUsername, databasePassword);
|
||||
systemPrompt.append("以下是Hudi数据库中已有表的详细信息,包含表名、表描述、字段名和字段描述,任何与这些表数据相关的问题,都优先查询数据库获取答案\n");
|
||||
systemPrompt.append(databaseTools.getTableInformation(databaseName)).append("\n");
|
||||
systemPrompt.append("任何使用Hudi数据库的数据的回答都必须从实际的数据中获取,严禁虚构任何下列信息中不存在的表或表字段,没有描述的表或字段可以从表名或字段名中推测,如果找不到答案,就回复从数据库中没有找到相关数据\n");
|
||||
// language=TEXT
|
||||
prompts.add("""
|
||||
你将所管理的主机信息记录在据数据库中schema名为main、表名为host_assets的MySQL表中,任何关于主机的数据的回答都必须从实际的数据中获取,严禁虚构任何不存在的表或表字段,没有描述的表或字段可以从表名或字段名中推测,如果找不到答案,就回复“数据库中没有找到相关数据”
|
||||
任何时候你都只能查询数据库,不会对数据库进行任何修改操作,也不会查询除host_assets外的任何表,数据库查询结果中出现null表示没有数据
|
||||
用户问题中提到的关键词通常不是精准的字段名或字段内容,你需要结合精确匹配或模糊匹配等等多种方式综合查询数据,必要的时候可以多次查询数据库综合查询数据
|
||||
当用户的问题涉及到具体检索某一列的某个值时,如果该列不是主键、日期、时间等内容,先使用distinct语句查询该列的取值情况,再根据用户的需求选择具体的值进行查询,避免查询不存在的取值
|
||||
以下是host_assets表的详细信息,包含表名、表描述、字段名和字段描述""");
|
||||
prompts.add(databaseTools.getTableInformation(databaseName));
|
||||
prompts.add("");
|
||||
tools.add(databaseTools);
|
||||
}
|
||||
|
||||
client.prompt()
|
||||
.system(systemPrompt.toString())
|
||||
String content = client.prompt()
|
||||
.system(String.join("\n", prompts))
|
||||
.user(prompt)
|
||||
.tools(tools.toArray(new Object[]{}))
|
||||
.call()
|
||||
.content();
|
||||
log.info("{}", content);
|
||||
for (String line : content.split("\n")) {
|
||||
emitter.send(StrUtil.format("#/#{}#/#", line));
|
||||
emitter.send(StrUtil.format("#/#{}#/#", "\n"));
|
||||
}
|
||||
emitter.send("#CLOSE#");
|
||||
emitter.complete();
|
||||
|
||||
/* client.prompt()
|
||||
.system(String.join("\n", prompts))
|
||||
.user(prompt)
|
||||
.tools(tools.toArray(new Object[]{}))
|
||||
.stream()
|
||||
@@ -94,20 +205,15 @@ public class ChatController {
|
||||
}
|
||||
},
|
||||
emitter::completeWithError,
|
||||
emitter::complete
|
||||
);
|
||||
() -> {
|
||||
try {
|
||||
emitter.send("#CLOSE#");
|
||||
emitter.complete();
|
||||
} catch (IOException e) {
|
||||
emitter.completeWithError(e);
|
||||
}
|
||||
}
|
||||
); */
|
||||
return emitter;
|
||||
}
|
||||
|
||||
private void logParameters(String prompt, Boolean useTw, Boolean useDatabase, String databaseUrl, String databaseUsername, String databasePassword, String databaseName) {
|
||||
log.info("prompt: {}", prompt);
|
||||
log.info("use_tw: {}", useTw);
|
||||
log.info("use_database: {}", useDatabase);
|
||||
if (useDatabase) {
|
||||
log.info("database_url: {}", databaseUrl);
|
||||
log.info("database_username: {}", databaseUsername);
|
||||
log.info("database_password: {}", databasePassword);
|
||||
log.info("database_name: {}", databaseName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.lanyuanxiaoyao.ai.analysis.flow;
|
||||
|
||||
import com.yomahub.liteflow.annotation.LiteflowComponent;
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.ai.chat.client.ChatClient;
|
||||
|
||||
@Slf4j
|
||||
@LiteflowComponent
|
||||
public class ChartNode extends NodeComponent {
|
||||
private final ChatClient client;
|
||||
|
||||
public ChartNode(ChatClient.Builder builder) {
|
||||
this.client = builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process() throws Exception {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.lanyuanxiaoyao.ai.analysis.flow;
|
||||
|
||||
import com.yomahub.liteflow.annotation.LiteflowComponent;
|
||||
import com.yomahub.liteflow.annotation.LiteflowMethod;
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@LiteflowComponent
|
||||
public class RunningFlow {
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeId = "A")
|
||||
public void processA(NodeComponent bind){
|
||||
log.info("Process A");
|
||||
}
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeId = "B")
|
||||
public void processB(NodeComponent bind){
|
||||
log.info("Process B");
|
||||
}
|
||||
}
|
||||
@@ -52,6 +52,7 @@ public class DatabaseTools {
|
||||
}
|
||||
builder.append("\n");
|
||||
}
|
||||
log.info("\n{}", builder);
|
||||
return builder.toString();
|
||||
} catch (SQLException e) {
|
||||
return StrUtil.format("查询失败,失败提示:{}", e.getMessage());
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.lanyuanxiaoyao.ai.analysis.tools;
|
||||
import java.time.LocalDateTime;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.ai.tool.annotation.Tool;
|
||||
import org.springframework.ai.tool.function.FunctionToolCallback;
|
||||
|
||||
/**
|
||||
* @author lanyuanxiaoyao
|
||||
@@ -11,14 +10,8 @@ import org.springframework.ai.tool.function.FunctionToolCallback;
|
||||
*/
|
||||
@Slf4j
|
||||
public class DatetimeTools {
|
||||
public static final FunctionToolCallback<Void, LocalDateTime> call = FunctionToolCallback.builder("current_time", () -> LocalDateTime.now())
|
||||
.description("返回当前的日期时间")
|
||||
.inputType(Void.class)
|
||||
.build();
|
||||
|
||||
@Tool(description = "返回当前的日期时间")
|
||||
public String currentTime() {
|
||||
return LocalDateTime.now().toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,12 +4,33 @@ spring:
|
||||
application:
|
||||
name: ai-analysis
|
||||
ai:
|
||||
# openai:
|
||||
# base-url: https://api.deepseek.com
|
||||
# api-key: "sk-c338699912bb4ad891874a9ab713e735"
|
||||
# chat:
|
||||
# options:
|
||||
# model: "deepseek-chat"
|
||||
# ai:
|
||||
# openai:
|
||||
# base-url: http://132.121.116.79:31348
|
||||
# api-key: "nopassword"
|
||||
# chat:
|
||||
# options:
|
||||
# model: "deepseek-coder"
|
||||
# openai:
|
||||
# base-url: http://132.121.116.70:31409
|
||||
# api-key: "nopassword"
|
||||
# chat:
|
||||
# options:
|
||||
# model: "telechat2-7B"
|
||||
openai:
|
||||
base-url: https://api.siliconflow.cn
|
||||
api-key: "sk-xrguybusoqndpqvgzgvllddzgjamksuecyqdaygdwnrnqfwo"
|
||||
base-url: https://open.bigmodel.cn/api/paas/v4
|
||||
api-key: "d1e97306540d12bb2f834be961fcacb1.SNBShlCxWYJCx0qZ"
|
||||
chat:
|
||||
completions-path: /chat/completions
|
||||
options:
|
||||
model: "Qwen/Qwen2.5-32B-Instruct"
|
||||
model: "glm-4-flash"
|
||||
parallel-tool-calls: true
|
||||
ollama:
|
||||
chat:
|
||||
model: "qwen2.5:7b"
|
||||
@@ -20,12 +41,13 @@ spring:
|
||||
chat:
|
||||
options:
|
||||
model: "glm-4-flash"
|
||||
# openai:
|
||||
# base-url: http://173.0.59.240:8093
|
||||
# api-key: test
|
||||
mvc:
|
||||
async:
|
||||
request-timeout: -1
|
||||
logging:
|
||||
level:
|
||||
org.springframework.ai: trace
|
||||
# root: debug
|
||||
org.springframework.ai: debug
|
||||
liteflow:
|
||||
print-banner: false
|
||||
rule-source: config/flow.xml
|
||||
6
src/main/resources/config/flow.xml
Normal file
6
src/main/resources/config/flow.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<flow>
|
||||
<chain name="chain_1">
|
||||
SER(A,B)
|
||||
</chain>
|
||||
</flow>
|
||||
76
src/test/java/com/lanyuanxiaoyao/ai/analysis/FakeData.java
Normal file
76
src/test/java/com/lanyuanxiaoyao/ai/analysis/FakeData.java
Normal file
@@ -0,0 +1,76 @@
|
||||
package com.lanyuanxiaoyao.ai.analysis;
|
||||
|
||||
import cn.hutool.core.date.DateField;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.db.DbUtil;
|
||||
import cn.hutool.db.Entity;
|
||||
import cn.hutool.db.Session;
|
||||
import cn.hutool.db.ds.simple.SimpleDataSource;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.datafaker.Faker;
|
||||
|
||||
/**
|
||||
* @author lanyuanxiaoyao
|
||||
* @version 20250301
|
||||
*/
|
||||
@Slf4j
|
||||
public class FakeData {
|
||||
public static void main(String[] args) {
|
||||
Faker faker = new Faker(new Locale("zh-CN"));
|
||||
|
||||
/*try (Session session = DbUtil.newSession(new SimpleDataSource("jdbc:mysql://192.168.100.139:3307/main", "test", "test"))) {
|
||||
String fieldName = "system_name";
|
||||
List<String> items = new ArrayList<>();
|
||||
List<Entity> entities = session.query(StrUtil.format("select distinct {} as name from host_assets where {} is not null", fieldName, fieldName));
|
||||
for (Entity entity : entities) {
|
||||
*//* Set<String> fields = entity.getFieldNames();
|
||||
for (String field : fields) {
|
||||
items.add(entity.get(field).toString());
|
||||
} *//*
|
||||
items.add(entity.getStr("name"));
|
||||
}
|
||||
for (String item : items) {
|
||||
List<String> tags = List.of("数据治理", "数据安全管控", "区块链应用", "标签管理", "数据集市");
|
||||
String shadow = StrUtil.format("大数据湖{}-{}", RandomUtil.randomInt(50), tags.get(RandomUtil.randomInt(tags.size())));
|
||||
String domain = StrUtil.format("b{}.hdp.dc", RandomUtil.randomInt(10));
|
||||
String sql = StrUtil.format("update host_assets set {} = '{}', host_name = '{}' where {} = '{}'", fieldName, shadow, domain, fieldName, item);
|
||||
log.info("{}", sql);
|
||||
try (Statement statement = session.getConnection().createStatement()) {
|
||||
statement.execute(sql);
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}*/
|
||||
try (Session session = DbUtil.newSession(new SimpleDataSource("jdbc:mysql://192.168.100.139:3307/main?useSSL=false&allowPublicKeyRetrieval=true", "test", "test"))) {
|
||||
String fieldName = "id";
|
||||
List<String> items = new ArrayList<>();
|
||||
List<Entity> entities = session.query(StrUtil.format("select distinct {} as name from host_assets where {} is not null", fieldName, fieldName));
|
||||
for (Entity entity : entities) {
|
||||
Set<String> fields = entity.getFieldNames();
|
||||
for (String field : fields) {
|
||||
items.add(entity.get(field).toString());
|
||||
}
|
||||
items.add(entity.getStr("name"));
|
||||
}
|
||||
for (String item : items) {
|
||||
String dateText = RandomUtil.randomDate(DateUtil.parseDateTime("2024-12-31 00:00:00"), DateField.DAY_OF_YEAR, -200, -1).toString("yyyy-MM-dd");
|
||||
String sql = StrUtil.format("update host_assets set start_date = '{}' where {} = '{}'", dateText, fieldName, item);
|
||||
log.info("{}", sql);
|
||||
try (Statement statement = session.getConnection().createStatement()) {
|
||||
statement.execute(sql);
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
10
test.http
10
test.http
@@ -1,5 +1,11 @@
|
||||
### Chat
|
||||
POST http://localhost:7891/chat/stream
|
||||
POST http://localhost:7891/chat
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
prompt=tb_app_collect_table_info中src_schema字段各有多少记录&use_database=true&database_url=jdbc:mysql://localhost:3307/main&database_username=test&database_password=test&database_name=main
|
||||
prompt=你好
|
||||
|
||||
### Test local
|
||||
POST http://132.121.116.79:31348/v1/chat/completions
|
||||
Content-Type: application/json
|
||||
|
||||
{"messages":[{"content":"你好","role":"user"}],"model":"deepseek-coder","stream":true,"temperature":0.7}
|
||||
|
||||
Reference in New Issue
Block a user