提交 96c2e308 authored 作者: 王鹏飞's avatar 王鹏飞

chore: update

上级 9ebbee8a
...@@ -19,18 +19,23 @@ export function useAI(globalOptions?: InitOptions) { ...@@ -19,18 +19,23 @@ export function useAI(globalOptions?: InitOptions) {
const userMessages = data.messages.filter((item) => item.role !== 'system') const userMessages = data.messages.filter((item) => item.role !== 'system')
setMessages((prevMessages) => [...prevMessages, ...userMessages]) setMessages((prevMessages) => [...prevMessages, ...userMessages])
let latestMessage: AIMessage | null = null
const onComplete = options?.onComplete || globalOptions?.onComplete
await aiService.post(ai, data, { await aiService.post(ai, data, {
onMessage: (response) => { onMessage: (response) => {
setMessages((prevMessages) => { setMessages((prevMessages) => {
const messageIndex = prevMessages.findIndex((msg) => msg.id === response.id) const messageIndex = prevMessages.findIndex((msg) => msg.id === response.id)
if (messageIndex === -1) { if (messageIndex === -1) {
const newMessage: AIMessage = { id: response.id, role: 'assistant', content: response.content } latestMessage = { id: response.id, role: 'assistant', content: response.content }
setMessage(newMessage) // 更新最新消息 setMessage(latestMessage) // 更新最新消息
return [...prevMessages, newMessage] return [...prevMessages, latestMessage]
} else { } else {
return prevMessages.map((msg) => { return prevMessages.map((msg) => {
if (msg.id === response.id) { if (msg.id === response.id) {
const updatedMessage = { ...msg, content: msg.content + response.content } const updatedMessage = { ...msg, content: msg.content + response.content }
latestMessage = updatedMessage
setMessage(updatedMessage) // 更新最新消息 setMessage(updatedMessage) // 更新最新消息
return updatedMessage return updatedMessage
} }
...@@ -44,6 +49,7 @@ export function useAI(globalOptions?: InitOptions) { ...@@ -44,6 +49,7 @@ export function useAI(globalOptions?: InitOptions) {
}, },
onclose: () => { onclose: () => {
setIsLoading(false) setIsLoading(false)
if (latestMessage && onComplete) onComplete(latestMessage)
}, },
...globalOptions, ...globalOptions,
...options, ...options,
......
import { useState } from 'react' import { useEffect, useState } from 'react'
import { Button, Checkbox, Flex, Modal, Radio, Select, Input, Form, Row, Col, Divider } from 'antd' import { Button, Checkbox, Flex, Modal, Radio, Select, Input, Form, Row, Col, Divider } from 'antd'
import { useDataFieldQuery } from '@/hooks/useQuery' import { useDataFieldQuery } from '@/hooks/useQuery'
import AppProgressSteps from '@/components/AppProgressSteps' import AppProgressSteps from '@/components/AppProgressSteps'
import { useSearchParams } from 'react-router' import { useSearchParams } from 'react-router'
import { useAI } from '@/hooks/useAI'
import prompt from '@/utils/prompt'
export default function ButtonModal() { export default function ButtonModal() {
const [searchParams] = useSearchParams() const [searchParams] = useSearchParams()
const results = searchParams.get('results')?.split(',') || []
const { isLoading, post } = useAI({
onComplete: (message) => {
try {
const parse = JSON.parse(message.content)
console.log(parse)
if (parse.results.length) form.setFieldValue('checkedList', parse.results.map((item: any) => item.name) || [])
} catch (error) {
console.error(error)
}
},
})
const handleSearch = () => {
post({
response_format: { type: 'json_object' },
messages: [{ role: 'user', content: prompt.null }],
})
}
const { data: fields = [] } = useDataFieldQuery() const { data: fields = [] } = useDataFieldQuery()
const [open, setOpen] = useState(results.length > 0) const [open, setOpen] = useState(false)
useEffect(() => {
if (searchParams.get('results')) {
setOpen(true)
}
}, [searchParams])
const [current, setCurrent] = useState(0) const [current, setCurrent] = useState(0)
const [form] = Form.useForm() const [form] = Form.useForm()
const initialValues = { const initialValues = {
checkedList: results, checkedList: searchParams.get('results')?.split(',') || [],
method: 'unified', method: 'unified',
rule: '1', rule: '1',
} }
const checkedList = Form.useWatch('checkedList', form) || [] const checkedList: string[] = Form.useWatch('checkedList', form) || []
const method = Form.useWatch('method', form) const method = Form.useWatch('method', form)
const rule = Form.useWatch('rule', form) const rule = Form.useWatch('rule', form)
const rules = Form.useWatch('rules', form) || {} const rules = Form.useWatch('rules', form) || {}
...@@ -165,7 +190,11 @@ export default function ButtonModal() { ...@@ -165,7 +190,11 @@ export default function ButtonModal() {
open={open} open={open}
footer={ footer={
<Flex justify="center" gap={20}> <Flex justify="center" gap={20}>
{current === 0 && <Button type="primary">检查缺失值字段</Button>} {current === 0 && (
<Button type="primary" loading={isLoading} onClick={handleSearch}>
检查缺失值字段
</Button>
)}
{current > 0 && <Button onClick={() => setCurrent(current - 1)}>上一步</Button>} {current > 0 && <Button onClick={() => setCurrent(current - 1)}>上一步</Button>}
{current < steps.length - 1 && ( {current < steps.length - 1 && (
<Button type="primary" onClick={() => setCurrent(current + 1)} disabled={!checkedList.length}> <Button type="primary" onClick={() => setCurrent(current + 1)} disabled={!checkedList.length}>
......
import { useEffect, useState } from 'react' import { useState } from 'react'
import { Button, Radio, Flex, Modal, Empty } from 'antd' import { Button, Radio, Flex, Modal, Empty } from 'antd'
import type { RadioChangeEvent } from 'antd' import type { RadioChangeEvent } from 'antd'
import { useNavigate } from 'react-router' import { useNavigate } from 'react-router'
import AppSteps from '@/components/AppSteps' import AppSteps from '@/components/AppSteps'
import { useAI } from '@/hooks/useAI' import { useAI } from '@/hooks/useAI'
import prompt from '../prompt' import prompt from '@/utils/prompt'
interface ResultItem { interface ResultItem {
name: string name: string
...@@ -15,19 +15,14 @@ export default function ButtonModal() { ...@@ -15,19 +15,14 @@ export default function ButtonModal() {
const [results, setResults] = useState<ResultItem[]>([]) const [results, setResults] = useState<ResultItem[]>([])
const resultsOptions = results.map((result) => result.name) const resultsOptions = results.map((result) => result.name)
const { isLoading, messages, post } = useAI() const { isLoading, post } = useAI({
const lastMessage = messages[messages.length - 1] onComplete: (message) => {
useEffect(() => { if (!message.content) return
if (lastMessage?.role === 'assistant' && lastMessage?.content) { const parse = JSON.parse(message.content)
try { console.log(parse)
const parse = JSON.parse(lastMessage.content) setResults(parse.results || [])
console.log(parse) },
setResults(parse.results || []) })
} catch (error) {
console.error(error)
}
}
}, [lastMessage])
const handleSearch = () => { const handleSearch = () => {
post({ post({
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
......
import { useEffect, useState } from 'react' import { useState } from 'react'
import { Button, Radio, Flex, Modal, Empty } from 'antd' import { Button, Radio, Flex, Modal, Empty } from 'antd'
import type { RadioChangeEvent } from 'antd' import type { RadioChangeEvent } from 'antd'
import { useNavigate } from 'react-router' import { useNavigate } from 'react-router'
import AppSteps from '@/components/AppSteps' import AppSteps from '@/components/AppSteps'
import { useAI } from '@/hooks/useAI' import { useAI } from '@/hooks/useAI'
import prompt from '../prompt' import prompt from '@/utils/prompt'
interface ResultItem { interface ResultItem {
name: string name: string
...@@ -15,19 +15,14 @@ export default function ButtonModal() { ...@@ -15,19 +15,14 @@ export default function ButtonModal() {
const [results, setResults] = useState<ResultItem[]>([]) const [results, setResults] = useState<ResultItem[]>([])
const resultsOptions = results.map((result) => result.name) const resultsOptions = results.map((result) => result.name)
const { isLoading, messages, post } = useAI() const { isLoading, post } = useAI({
const lastMessage = messages[messages.length - 1] onComplete: (message) => {
useEffect(() => { if (!message.content) return
if (lastMessage?.role === 'assistant' && lastMessage?.content) { const parse = JSON.parse(message.content)
try { console.log(parse)
const parse = JSON.parse(lastMessage.content) setResults(parse.results || [])
console.log(parse) },
setResults(parse.results || []) })
} catch (error) {
console.error(error)
}
}
}, [lastMessage])
const handleSearch = () => { const handleSearch = () => {
post({ post({
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
......
import { useEffect, useState } from 'react' import { useState } from 'react'
import { Button, Radio, Flex, Modal, Empty } from 'antd' import { Button, Radio, Flex, Modal, Empty } from 'antd'
import type { RadioChangeEvent } from 'antd' import type { RadioChangeEvent } from 'antd'
import { useNavigate } from 'react-router' import { useNavigate } from 'react-router'
import AppSteps from '@/components/AppSteps' import AppSteps from '@/components/AppSteps'
import { useAI } from '@/hooks/useAI' import { useAI } from '@/hooks/useAI'
import prompt from '../prompt' import prompt from '@/utils/prompt'
interface ResultItem { interface ResultItem {
name: string name: string
...@@ -15,19 +15,14 @@ export default function ButtonModal() { ...@@ -15,19 +15,14 @@ export default function ButtonModal() {
const [results, setResults] = useState<ResultItem[]>([]) const [results, setResults] = useState<ResultItem[]>([])
const resultsOptions = results.map((result) => result.name) const resultsOptions = results.map((result) => result.name)
const { isLoading, messages, post } = useAI() const { isLoading, post } = useAI({
const lastMessage = messages[messages.length - 1] onComplete: (message) => {
useEffect(() => { if (!message.content) return
if (lastMessage?.role === 'assistant' && lastMessage?.content) { const parse = JSON.parse(message.content)
try { console.log(parse)
const parse = JSON.parse(lastMessage.content) setResults(parse.results || [])
console.log(parse) },
setResults(parse.results || []) })
} catch (error) {
console.error(error)
}
}
}, [lastMessage])
const handleSearch = () => { const handleSearch = () => {
post({ post({
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
......
import { useEffect, useState } from 'react' import { useState } from 'react'
import { Button, Checkbox, Empty, Flex, Modal } from 'antd' import { Button, Checkbox, Empty, Flex, Modal } from 'antd'
import type { CheckboxProps } from 'antd' import type { CheckboxProps } from 'antd'
import { useNavigate } from 'react-router' import { useNavigate } from 'react-router'
import AppSteps from '@/components/AppSteps' import AppSteps from '@/components/AppSteps'
import { useAI } from '@/hooks/useAI' import { useAI } from '@/hooks/useAI'
import prompt from '../prompt' import prompt from '@/utils/prompt'
const CheckboxGroup = Checkbox.Group const CheckboxGroup = Checkbox.Group
...@@ -17,19 +17,16 @@ export default function ButtonModal() { ...@@ -17,19 +17,16 @@ export default function ButtonModal() {
const [results, setResults] = useState<ResultItem[]>([]) const [results, setResults] = useState<ResultItem[]>([])
const resultsOptions = results.map((result) => result.name) const resultsOptions = results.map((result) => result.name)
const { isLoading, messages, post } = useAI() const { isLoading, post } = useAI({
const lastMessage = messages[messages.length - 1] onComplete: (message) => {
useEffect(() => { if (!message.content) return
if (lastMessage?.role === 'assistant' && lastMessage?.content) {
try { const parse = JSON.parse(message.content)
const parse = JSON.parse(lastMessage.content) console.log(parse)
console.log(parse) setResults(parse.results || [])
setResults(parse.results || []) },
} catch (error) { })
console.error(error)
}
}
}, [lastMessage])
const handleSearch = () => { const handleSearch = () => {
post({ post({
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
......
import { useState, useMemo, useEffect } from 'react' import { useState, useMemo } from 'react'
import { Button, Flex, Modal, Table, Checkbox } from 'antd' import { Button, Flex, Modal, Table, Checkbox } from 'antd'
import { DownloadOutlined } from '@ant-design/icons' import { DownloadOutlined } from '@ant-design/icons'
import { useDataFieldQuery } from '@/hooks/useQuery' import { useDataFieldQuery } from '@/hooks/useQuery'
...@@ -12,26 +12,22 @@ interface ResultItem { ...@@ -12,26 +12,22 @@ interface ResultItem {
const buttons = ['最大值', '最小值', '平均值', '中位数', '众数', '1/4位数', '3/4位数', '方差', '标准差', '极差'] const buttons = ['最大值', '最小值', '平均值', '中位数', '众数', '1/4位数', '3/4位数', '方差', '标准差', '极差']
export default function ButtonModal() { export default function ButtonModal() {
const { data } = useDataFieldQuery() const { data = [] } = useDataFieldQuery()
const [results, setResults] = useState<ResultItem[]>( const [results, setResults] = useState<ResultItem[]>(
data.filter((item: any) => { data.filter((item: any) => {
return item.type.includes('DECIMAL') || item.type.includes('SMALLINT') return item.type.includes('DECIMAL') || item.type.includes('SMALLINT')
}) })
) )
const { isLoading, messages, post } = useAI() const { isLoading, post } = useAI({
const lastMessage = messages[messages.length - 1] onComplete: (message) => {
useEffect(() => { if (!message.content) return
if (lastMessage?.role === 'assistant' && lastMessage?.content) { const parse = JSON.parse(message.content)
try { console.log(parse)
const parse = JSON.parse(lastMessage.content) setResults(parse.results || {})
console.log(parse) },
setResults(parse.results || {}) })
} catch (error) {
console.error(error)
}
}
}, [lastMessage])
const handleSearch = () => { const handleSearch = () => {
const names = results.map((item: any) => item.name).join(',') const names = results.map((item: any) => item.name).join(',')
post({ post({
......
import { useEffect, useState } from 'react' import { useState } from 'react'
import { Button, Empty, Flex, Modal } from 'antd' import { Button, Empty, Flex, Modal } from 'antd'
import { useNavigate } from 'react-router' import { useNavigate } from 'react-router'
import AppSteps from '@/components/AppSteps' import AppSteps from '@/components/AppSteps'
import { useAI } from '@/hooks/useAI' import { useAI } from '@/hooks/useAI'
import prompt from '../prompt' import prompt from '@/utils/prompt'
export default function ButtonModal() { export default function ButtonModal() {
const [results, setResults] = useState<Array<Array<number>>>([]) const [results, setResults] = useState<Array<Array<number>>>([])
const { isLoading, messages, post } = useAI() const { isLoading, post } = useAI({
const lastMessage = messages[messages.length - 1] onComplete: (message) => {
useEffect(() => { if (!message.content) return
if (lastMessage?.role === 'assistant' && lastMessage?.content) { const parse = JSON.parse(message.content)
try { console.log(parse)
const parse = JSON.parse(lastMessage.content) setResults(parse.results || [])
console.log(parse) },
setResults(parse.results || []) })
} catch (error) {
console.error(error)
}
}
}, [lastMessage])
const handleSearch = () => { const handleSearch = () => {
post({ post({
response_format: { type: 'json_object' }, response_format: { type: 'json_object' },
......
...@@ -26,6 +26,7 @@ export interface AIResponse { ...@@ -26,6 +26,7 @@ export interface AIResponse {
export interface InitOptions extends FetchEventSourceInit { export interface InitOptions extends FetchEventSourceInit {
onMessage?: (message: AIResponse) => void onMessage?: (message: AIResponse) => void
onComplete?: (message: AIMessage) => void
} }
// Available AI options for different implementations // Available AI options for different implementations
......
const prompt = { const prompt = {
// 缺失值处理
null: `找出数据集中有缺失值的字段,并返回 JSON 格式的结果。返回内容仅包含缺失字段的名称(name)及其对应的数据有哪些,字段像主键的数据(desc)。如果没有缺失值,则返回空数组 []。 null: `找出数据集中有缺失值的字段,并返回 JSON 格式的结果。返回内容仅包含缺失字段的名称(name)及其对应的数据有哪些,字段像主键的数据(desc)。如果没有缺失值,则返回空数组 []。
返回格式示例: 返回格式示例:
json json
...@@ -11,6 +12,7 @@ json ...@@ -11,6 +12,7 @@ json
要求: 要求:
仅包含缺失值的字段(为空、null、undefined 等视为缺失)。 仅包含缺失值的字段(为空、null、undefined 等视为缺失)。
如果所有字段都有值,则返回 { "results": [] }。`, 如果所有字段都有值,则返回 { "results": [] }。`,
// 重复值处理
repeat: `请根据我给你的数据集,帮我检查这个数据集里面是否存在有重复值数据的情况,即:所有字段的值出现完全相同的多条数据。如果存在,请告诉我。并返回 JSON 格式的结果。返回内容仅包重复数据所在的行,如果没有重复记录,则返回空数组 []。 repeat: `请根据我给你的数据集,帮我检查这个数据集里面是否存在有重复值数据的情况,即:所有字段的值出现完全相同的多条数据。如果存在,请告诉我。并返回 JSON 格式的结果。返回内容仅包重复数据所在的行,如果没有重复记录,则返回空数组 []。
返回格式示例: 返回格式示例:
json json
...@@ -19,6 +21,7 @@ json ...@@ -19,6 +21,7 @@ json
} }
要求: 要求:
如果没有重复数据,则返回 { "results": [] }。`, 如果没有重复数据,则返回 { "results": [] }。`,
// 最大值处理
max: `请根据我给你的数据集,帮我检查这个数据集里面是否存在有违反常规或者疑似不正常的过大值的情况。如果存在,请告诉我。 max: `请根据我给你的数据集,帮我检查这个数据集里面是否存在有违反常规或者疑似不正常的过大值的情况。如果存在,请告诉我。
返回格式示例: 返回格式示例:
json json
...@@ -27,6 +30,7 @@ json ...@@ -27,6 +30,7 @@ json
} }
要求: 要求:
如果没有重复数据,则返回 { "results": [] }。`, 如果没有重复数据,则返回 { "results": [] }。`,
// 最小值处理
min: `请根据我给你的数据集,帮我检查这个数据集里面是否存在有违反常规或者疑似不正常的过小值的情况。如果存在,请告诉我。 min: `请根据我给你的数据集,帮我检查这个数据集里面是否存在有违反常规或者疑似不正常的过小值的情况。如果存在,请告诉我。
返回格式示例: 返回格式示例:
json json
...@@ -35,6 +39,7 @@ json ...@@ -35,6 +39,7 @@ json
} }
要求: 要求:
如果没有重复数据,则返回 { "results": [] }。`, 如果没有重复数据,则返回 { "results": [] }。`,
// 逻辑错误处理
error: `请根据我给你的数据集,帮我检查这个数据集里面是否存在有违反常规或者疑似不正常的逻辑错误的情况。如果存在,请告诉我。 error: `请根据我给你的数据集,帮我检查这个数据集里面是否存在有违反常规或者疑似不正常的逻辑错误的情况。如果存在,请告诉我。
返回格式示例: 返回格式示例:
json json
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论